mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-11-02 16:03:45 +00:00
Refine SNI parser in ss-local
This commit is contained in:
+8
-4
@@ -9,6 +9,10 @@ endif ()
|
||||
set(SS_SNI_SOURCE
|
||||
http.c
|
||||
tls.c
|
||||
)
|
||||
|
||||
set(SS_ACL_SOURCE
|
||||
acl.c
|
||||
rule.c
|
||||
)
|
||||
|
||||
@@ -35,11 +39,12 @@ set(LIBSHADOWSOCKS_LIBEV_SOURCE
|
||||
${SS_SHARED_SOURCES}
|
||||
udprelay.c
|
||||
cache.c
|
||||
acl.c
|
||||
local.c
|
||||
${SS_CRYPTO_SOURCE}
|
||||
${SS_PLUGIN_SOURCE}
|
||||
${SS_SNI_SOURCE})
|
||||
${SS_SNI_SOURCE}
|
||||
${SS_ACL_SOURCE}
|
||||
)
|
||||
|
||||
set(SS_LOCAL_SOURCE
|
||||
${LIBSHADOWSOCKS_LIBEV_SOURCE}
|
||||
@@ -59,12 +64,12 @@ set(SS_SERVER_SOURCE
|
||||
${SS_SHARED_SOURCES}
|
||||
udprelay.c
|
||||
cache.c
|
||||
acl.c
|
||||
resolv.c
|
||||
server.c
|
||||
${SS_CRYPTO_SOURCE}
|
||||
${SS_PLUGIN_SOURCE}
|
||||
${SS_SNI_SOURCE}
|
||||
${SS_ACL_SOURCE}
|
||||
)
|
||||
|
||||
set(SS_MANAGER_SOURCE
|
||||
@@ -79,7 +84,6 @@ set(SS_REDIR_SOURCE
|
||||
redir.c
|
||||
${SS_CRYPTO_SOURCE}
|
||||
${SS_PLUGIN_SOURCE}
|
||||
${SS_SNI_SOURCE}
|
||||
)
|
||||
|
||||
|
||||
|
||||
+9
-8
@@ -22,8 +22,10 @@ SS_COMMON_LIBS += -lev -lsodium -lm
|
||||
bin_PROGRAMS = ss-local ss-tunnel ss-server ss-manager
|
||||
|
||||
sni_src = http.c \
|
||||
tls.c \
|
||||
rule.c
|
||||
tls.c
|
||||
|
||||
acl_src = rule.c \
|
||||
acl.c
|
||||
|
||||
crypto_src = crypto.c \
|
||||
aead.c \
|
||||
@@ -38,12 +40,12 @@ ss_local_SOURCES = utils.c \
|
||||
json.c \
|
||||
udprelay.c \
|
||||
cache.c \
|
||||
acl.c \
|
||||
netutils.c \
|
||||
local.c \
|
||||
$(crypto_src) \
|
||||
$(plugin_src) \
|
||||
$(sni_src)
|
||||
$(sni_src) \
|
||||
$(acl_src)
|
||||
|
||||
ss_tunnel_SOURCES = utils.c \
|
||||
jconf.c \
|
||||
@@ -61,12 +63,12 @@ ss_server_SOURCES = utils.c \
|
||||
json.c \
|
||||
udprelay.c \
|
||||
cache.c \
|
||||
acl.c \
|
||||
resolv.c \
|
||||
server.c \
|
||||
$(crypto_src) \
|
||||
$(plugin_src) \
|
||||
$(sni_src)
|
||||
$(sni_src) \
|
||||
${acl_src}
|
||||
|
||||
ss_manager_SOURCES = utils.c \
|
||||
jconf.c \
|
||||
@@ -99,8 +101,7 @@ ss_redir_SOURCES = utils.c \
|
||||
udprelay.c \
|
||||
redir.c \
|
||||
$(crypto_src) \
|
||||
$(plugin_src) \
|
||||
$(sni_src)
|
||||
$(plugin_src)
|
||||
|
||||
ss_redir_CFLAGS = $(AM_CFLAGS) -DMODULE_REDIR
|
||||
ss_redir_LDADD = $(SS_COMMON_LIBS)
|
||||
|
||||
+3
-3
@@ -53,10 +53,10 @@ int send_traffic_stat(uint64_t tx, uint64_t rx);
|
||||
#define STAGE_ERROR -1 /* Error detected */
|
||||
#define STAGE_INIT 0 /* Initial stage */
|
||||
#define STAGE_HANDSHAKE 1 /* Handshake with client */
|
||||
#define STAGE_PARSE 2 /* Parse the header */
|
||||
#define STAGE_PARSE 2 /* Parse the SOCKS5 header */
|
||||
#define STAGE_SNI 3 /* Parse HTTP/SNI header */
|
||||
#define STAGE_RESOLVE 4 /* Resolve the hostname */
|
||||
#define STAGE_WAIT 5 /* Wait for more data */
|
||||
#define STAGE_STREAM 6 /* Stream between client and server */
|
||||
#define STAGE_STREAM 5 /* Stream between client and server */
|
||||
|
||||
/* Vals for long options */
|
||||
enum {
|
||||
|
||||
+15
-12
@@ -253,7 +253,6 @@ delayed_connect_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
server_t *server = cork_container_of(watcher, server_t,
|
||||
delayed_connect_watcher);
|
||||
|
||||
server->stage = STAGE_WAIT;
|
||||
server_recv_cb(EV_A_ & server->recv_ctx->io, revents);
|
||||
}
|
||||
|
||||
@@ -266,13 +265,15 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
buffer_t *buf;
|
||||
ssize_t r;
|
||||
|
||||
ev_timer_stop(EV_A_ & server->delayed_connect_watcher);
|
||||
|
||||
if (remote == NULL) {
|
||||
buf = server->buf;
|
||||
} else {
|
||||
buf = remote->buf;
|
||||
}
|
||||
|
||||
if (server->stage != STAGE_WAIT) {
|
||||
if (revents != EV_TIMER) {
|
||||
r = recv(server->fd, buf->data + buf->len, BUF_SIZE - buf->len, 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -294,8 +295,6 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
}
|
||||
buf->len += r;
|
||||
} else {
|
||||
server->stage = STAGE_STREAM;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
@@ -307,8 +306,6 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
return;
|
||||
}
|
||||
|
||||
ev_timer_stop(EV_A_ & server->delayed_connect_watcher);
|
||||
|
||||
// insert shadowsocks header
|
||||
if (!remote->direct) {
|
||||
#ifdef __ANDROID__
|
||||
@@ -498,7 +495,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
buf->len = 0;
|
||||
return;
|
||||
} else if (server->stage == STAGE_HANDSHAKE || server->stage == STAGE_PARSE) {
|
||||
} else if (server->stage == STAGE_HANDSHAKE ||
|
||||
server->stage == STAGE_PARSE ||
|
||||
server->stage == STAGE_SNI) {
|
||||
struct socks5_request *request = (struct socks5_request *)buf->data;
|
||||
size_t request_len = sizeof(struct socks5_request);
|
||||
struct sockaddr_in sock_addr;
|
||||
@@ -568,9 +567,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
// Wait until client closes the connection
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
server->stage = STAGE_PARSE;
|
||||
server->stage = STAGE_PARSE;
|
||||
}
|
||||
|
||||
char host[257], ip[INET6_ADDRSTRLEN], port[16];
|
||||
|
||||
@@ -650,7 +649,9 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
else if (dst_port == tls_protocol->default_port)
|
||||
ret = tls_protocol->parse_packet(buf->data + 3 + abuf->len,
|
||||
buf->len - 3 - abuf->len, &hostname);
|
||||
if (ret == -1 && buf->len < BUF_SIZE) {
|
||||
if (ret == -1 && buf->len < BUF_SIZE && server->stage != STAGE_SNI) {
|
||||
server->stage = STAGE_SNI;
|
||||
ev_timer_start(EV_A_ & server->delayed_connect_watcher);
|
||||
return;
|
||||
} else if (ret > 0) {
|
||||
sni_detected = 1;
|
||||
@@ -683,13 +684,16 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
&& !(vpn && strcmp(port, "53") == 0)
|
||||
#endif
|
||||
) {
|
||||
int host_match = acl_match_host(host);
|
||||
int bypass = 0;
|
||||
int resolved = 0;
|
||||
struct sockaddr_storage storage;
|
||||
memset(&storage, 0, sizeof(struct sockaddr_storage));
|
||||
int err;
|
||||
|
||||
int host_match = 0;
|
||||
if (sni_detected || atyp == 3)
|
||||
host_match = acl_match_host(host);
|
||||
|
||||
if (host_match > 0)
|
||||
bypass = 1; // bypass hostnames in black list
|
||||
else if (host_match < 0)
|
||||
@@ -786,7 +790,6 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
remote->server = server;
|
||||
|
||||
if (buf->len > 0 || sni_detected) {
|
||||
server->stage = STAGE_STREAM;
|
||||
continue;
|
||||
} else {
|
||||
ev_timer_start(EV_A_ & server->delayed_connect_watcher);
|
||||
|
||||
@@ -47,8 +47,6 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "http.h"
|
||||
#include "tls.h"
|
||||
#include "plugin.h"
|
||||
#include "netutils.h"
|
||||
#include "utils.h"
|
||||
|
||||
Reference in New Issue
Block a user