mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-11-01 15:33:50 +00:00
Fix #494
This commit is contained in:
+55
-29
@@ -102,9 +102,10 @@ static void free_remote(remote_t *remote);
|
||||
static void close_and_free_remote(EV_P_ remote_t *remote);
|
||||
static void free_server(server_t *server);
|
||||
static void close_and_free_server(EV_P_ server_t *server);
|
||||
|
||||
static void server_resolve_cb(struct sockaddr *addr, void *data);
|
||||
|
||||
static size_t parse_header_len(const char atyp, const char *data, size_t offset);
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
static int white_list = 0;
|
||||
@@ -215,6 +216,24 @@ static void free_connections(struct ev_loop *loop)
|
||||
}
|
||||
}
|
||||
|
||||
static size_t parse_header_len(const char atyp, const char *data, size_t offset)
|
||||
{
|
||||
size_t len = 0;
|
||||
if ((atyp & ADDRTYPE_MASK) == 1) {
|
||||
// IP V4
|
||||
len += sizeof(struct in_addr);
|
||||
} else if ((atyp & ADDRTYPE_MASK) == 3) {
|
||||
// Domain name
|
||||
uint8_t name_len = *(uint8_t *)(data + offset);
|
||||
len += name_len + 1;
|
||||
} else if ((atyp & ADDRTYPE_MASK) == 4) {
|
||||
// IP V6
|
||||
len += sizeof(struct in6_addr);
|
||||
}
|
||||
len += 2;
|
||||
return len;
|
||||
}
|
||||
|
||||
static char *get_peer_name(int fd)
|
||||
{
|
||||
static char peer_name[INET6_ADDRSTRLEN] = { 0 };
|
||||
@@ -603,6 +622,39 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
memset(&info, 0, sizeof(struct addrinfo));
|
||||
memset(&storage, 0, sizeof(struct sockaddr_storage));
|
||||
|
||||
if (auth || (atyp & ONETIMEAUTH_FLAG)) {
|
||||
size_t header_len = parse_header_len(atyp, server->buf->array, offset);
|
||||
size_t len = server->buf->len;
|
||||
|
||||
if (len < offset + header_len + ONETIMEAUTH_BYTES) {
|
||||
report_addr(server->fd);
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
|
||||
server->buf->len = offset + header_len + ONETIMEAUTH_BYTES;
|
||||
if (ss_onetimeauth_verify(server->buf, server->d_ctx->evp.iv)) {
|
||||
char *peer_name = get_peer_name(server->fd);
|
||||
if (peer_name) {
|
||||
LOGE("authentication error from %s", peer_name);
|
||||
if (acl) {
|
||||
if (acl_get_mode() == BLACK_LIST) {
|
||||
acl_add_ip(peer_name);
|
||||
LOGE("add %s to the black list", peer_name);
|
||||
} else {
|
||||
acl_remove_ip(peer_name);
|
||||
LOGE("remove %s from the white list", peer_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
|
||||
server->buf->len = len;
|
||||
server->auth = 1;
|
||||
}
|
||||
|
||||
// get remote addr and port
|
||||
if ((atyp & ADDRTYPE_MASK) == 1) {
|
||||
// IP V4
|
||||
@@ -697,34 +749,8 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
offset += 2;
|
||||
|
||||
if (auth || (atyp & ONETIMEAUTH_FLAG)) {
|
||||
if (server->buf->len < offset + ONETIMEAUTH_BYTES) {
|
||||
report_addr(server->fd);
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
size_t len = server->buf->len;
|
||||
server->buf->len = offset + ONETIMEAUTH_BYTES;
|
||||
if (ss_onetimeauth_verify(server->buf, server->d_ctx->evp.iv)) {
|
||||
char *peer_name = get_peer_name(server->fd);
|
||||
if (peer_name) {
|
||||
LOGE("authentication error from %s", peer_name);
|
||||
if (acl) {
|
||||
if (acl_get_mode() == BLACK_LIST) {
|
||||
acl_add_ip(peer_name);
|
||||
LOGE("add %s to the black list", peer_name);
|
||||
} else {
|
||||
acl_remove_ip(peer_name);
|
||||
LOGE("remove %s from the white list", peer_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
close_and_free_server(EV_A_ server);
|
||||
return;
|
||||
}
|
||||
server->buf->len = len;
|
||||
offset += ONETIMEAUTH_BYTES;
|
||||
server->auth = 1;
|
||||
if (server->auth) {
|
||||
offset += ONETIMEAUTH_BYTES;
|
||||
}
|
||||
|
||||
if (server->buf->len < offset) {
|
||||
|
||||
Reference in New Issue
Block a user