Browse Source

Fix #863

pull/864/head
Max Lv 8 years ago
parent
commit
efafb59647
7 changed files with 45 additions and 21 deletions
  1. 19
      src/acl.c
  2. 1
      src/acl.h
  3. 2
      src/json.c
  4. 16
      src/local.c
  5. 1
      src/redir.c
  6. 25
      src/server.c
  7. 2
      src/utils.c

19
src/acl.c

@ -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);
}

1
src/acl.h

@ -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

2
src/json.c

@ -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

16
src/local.c

@ -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);

1
src/redir.c

@ -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

25
src/server.c

@ -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;

2
src/utils.c

@ -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");

Loading…
Cancel
Save