mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-10-22 06:53:46 +00:00
Fix #863
This commit is contained in:
@@ -41,13 +41,23 @@ static int acl_mode = BLACK_LIST;
|
||||
|
||||
static struct cache *block_list;
|
||||
|
||||
void init_block_list()
|
||||
void
|
||||
init_block_list()
|
||||
{
|
||||
// Initialize cache
|
||||
cache_create(&block_list, 256, NULL);
|
||||
}
|
||||
|
||||
int check_block_list(char* addr, int err_level)
|
||||
int
|
||||
remove_from_block_list(char *addr)
|
||||
{
|
||||
size_t addr_len = strlen(addr);
|
||||
|
||||
return cache_remove(block_list, addr, addr_len);
|
||||
}
|
||||
|
||||
int
|
||||
check_block_list(char *addr, int err_level)
|
||||
{
|
||||
size_t addr_len = strlen(addr);
|
||||
|
||||
@@ -55,11 +65,12 @@ int check_block_list(char* addr, int err_level)
|
||||
int *count = NULL;
|
||||
cache_lookup(block_list, addr, addr_len, &count);
|
||||
if (count != NULL) {
|
||||
if (*count > MAX_TRIES) return 1;
|
||||
if (*count > MAX_TRIES)
|
||||
return 1;
|
||||
(*count) += err_level;
|
||||
}
|
||||
} else {
|
||||
int *count = (int*)ss_malloc(sizeof(int));
|
||||
int *count = (int *)ss_malloc(sizeof(int));
|
||||
*count = 1;
|
||||
cache_insert(block_list, addr, addr_len, count);
|
||||
}
|
||||
|
||||
@@ -42,5 +42,6 @@ int get_acl_mode(void);
|
||||
|
||||
void init_block_list();
|
||||
int check_block_list(char* addr, int err_level);
|
||||
int remove_from_block_list(char *addr);
|
||||
|
||||
#endif // _ACL_H
|
||||
|
||||
+1
-1
@@ -248,7 +248,7 @@ json_parse_ex(json_settings *settings,
|
||||
json_value *top, *root, *alloc = 0;
|
||||
json_state state = { 0UL, 0U, 0UL, { 0UL, 0, NULL, NULL, NULL }, 0 };
|
||||
long flags;
|
||||
long num_digits = 0, num_e = 0;
|
||||
long num_digits = 0, num_e = 0;
|
||||
json_int_t num_fraction = 0;
|
||||
|
||||
/* Skip UTF-8 BOM
|
||||
|
||||
+8
-8
@@ -467,13 +467,13 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
|
||||
memcpy(resp_buf->array, &response, sizeof(struct socks5_response));
|
||||
memcpy(resp_buf->array + sizeof(struct socks5_response),
|
||||
&sock_addr.sin_addr, sizeof(sock_addr.sin_addr));
|
||||
&sock_addr.sin_addr, sizeof(sock_addr.sin_addr));
|
||||
memcpy(resp_buf->array + sizeof(struct socks5_response) +
|
||||
sizeof(sock_addr.sin_addr),
|
||||
&sock_addr.sin_port, sizeof(sock_addr.sin_port));
|
||||
sizeof(sock_addr.sin_addr),
|
||||
&sock_addr.sin_port, sizeof(sock_addr.sin_port));
|
||||
|
||||
int reply_size = sizeof(struct socks5_response) +
|
||||
sizeof(sock_addr.sin_addr) + sizeof(sock_addr.sin_port);
|
||||
sizeof(sock_addr.sin_addr) + sizeof(sock_addr.sin_port);
|
||||
|
||||
int s = send(server->fd, resp_buf->array, reply_size, 0);
|
||||
|
||||
@@ -511,7 +511,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
if (acl || verbose) {
|
||||
uint16_t p = ntohs(*(uint16_t *)(buf->array + 4 + in_addr_len));
|
||||
dns_ntop(AF_INET, (const void *)(buf->array + 4),
|
||||
ip, INET_ADDRSTRLEN);
|
||||
ip, INET_ADDRSTRLEN);
|
||||
sprintf(port, "%d", p);
|
||||
}
|
||||
} else if (atyp == 3) {
|
||||
@@ -537,7 +537,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
if (acl || verbose) {
|
||||
uint16_t p = ntohs(*(uint16_t *)(buf->array + 4 + in6_addr_len));
|
||||
dns_ntop(AF_INET6, (const void *)(buf->array + 4),
|
||||
ip, INET6_ADDRSTRLEN);
|
||||
ip, INET6_ADDRSTRLEN);
|
||||
sprintf(port, "%d", p);
|
||||
}
|
||||
} else {
|
||||
@@ -557,10 +557,10 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
|
||||
int ret = 0;
|
||||
if (p == http_protocol->default_port)
|
||||
ret = http_protocol->parse_packet(buf->array + 3 + abuf->len,
|
||||
buf->len - 3 - abuf->len, &hostname);
|
||||
buf->len - 3 - abuf->len, &hostname);
|
||||
else if (p == tls_protocol->default_port)
|
||||
ret = tls_protocol->parse_packet(buf->array + 3 + abuf->len,
|
||||
buf->len - 3 - abuf->len, &hostname);
|
||||
buf->len - 3 - abuf->len, &hostname);
|
||||
if (ret == -1) {
|
||||
server->stage = 2;
|
||||
bfree(abuf);
|
||||
|
||||
@@ -435,7 +435,6 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
|
||||
memcpy(abuf->array + abuf->len, server->hostname, server->hostname_len);
|
||||
abuf->len += server->hostname_len;
|
||||
memcpy(abuf->array + abuf->len, &port, 2);
|
||||
|
||||
} else if (AF_INET6 == server->destaddr.ss_family) { // IPv6
|
||||
abuf->array[abuf->len++] = 4; // Type 4 is IPv6 address
|
||||
|
||||
|
||||
+19
-6
@@ -298,6 +298,16 @@ get_peer_name(int fd)
|
||||
return peer_name;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_addr(int fd)
|
||||
{
|
||||
char *peer_name;
|
||||
peer_name = get_peer_name(fd);
|
||||
if (peer_name != NULL) {
|
||||
remove_from_block_list(peer_name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
report_addr(int fd, int err_level)
|
||||
{
|
||||
@@ -305,10 +315,10 @@ report_addr(int fd, int err_level)
|
||||
peer_name = get_peer_name(fd);
|
||||
if (peer_name != NULL) {
|
||||
LOGE("failed to handshake with %s", peer_name);
|
||||
}
|
||||
// Block all requests from this IP, if the err# exceeds 128.
|
||||
if (check_block_list(peer_name, err_level)) {
|
||||
LOGE("add %s to block list", peer_name);
|
||||
// Block all requests from this IP, if the err# exceeds 128.
|
||||
if (check_block_list(peer_name, err_level)) {
|
||||
LOGE("add %s to block list", peer_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +993,7 @@ server_timeout_cb(EV_P_ ev_timer *watcher, int revents)
|
||||
if (server->stage < 2) {
|
||||
if (verbose) {
|
||||
size_t len = server->stage ?
|
||||
server->header_buf->len : server->buf->len;
|
||||
server->header_buf->len : server->buf->len;
|
||||
#ifdef __MINGW32__
|
||||
LOGI("incomplete header: %u", len);
|
||||
#else
|
||||
@@ -1166,6 +1176,9 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
remote_send_ctx->connected = 1;
|
||||
|
||||
// Clear the state of this address in the block list
|
||||
reset_addr(server->fd);
|
||||
|
||||
if (remote->buf->len == 0) {
|
||||
server->stage = 5;
|
||||
ev_io_stop(EV_A_ & remote_send_ctx->io);
|
||||
@@ -1429,7 +1442,7 @@ accept_cb(EV_P_ ev_io *w, int revents)
|
||||
}
|
||||
if (acl) {
|
||||
if ((get_acl_mode() == BLACK_LIST && acl_match_host(peer_name) == 1)
|
||||
|| (get_acl_mode() == WHITE_LIST && acl_match_host(peer_name) >= 0)) {
|
||||
|| (get_acl_mode() == WHITE_LIST && acl_match_host(peer_name) >= 0)) {
|
||||
LOGE("Access denied from %s", peer_name);
|
||||
close(serverfd);
|
||||
return;
|
||||
|
||||
+1
-1
@@ -215,7 +215,7 @@ void
|
||||
usage()
|
||||
{
|
||||
printf("\n");
|
||||
printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO);
|
||||
printf("shadowsocks-libev %s with %s\n\n", VERSION, USING_CRYPTO);
|
||||
printf(
|
||||
" maintained by Max Lv <max.c.lv@gmail.com> and Linus Yang <laokongzi@gmail.com>\n\n");
|
||||
printf(" usage:\n\n");
|
||||
|
||||
Reference in New Issue
Block a user