diff --git a/src/acl.c b/src/acl.c index 34622977..cf33a947 100644 --- a/src/acl.c +++ b/src/acl.c @@ -47,7 +47,7 @@ void init_block_list() cache_create(&block_list, 256, NULL); } -int check_block_list(char* addr, int max_tries) +int check_block_list(char* addr, int err_level) { size_t addr_len = strlen(addr); @@ -55,8 +55,8 @@ int check_block_list(char* addr, int max_tries) int *count = NULL; cache_lookup(block_list, addr, addr_len, &count); if (count != NULL) { - if (*count > max_tries) return 1; - (*count)++; + if (*count > MAX_TRIES) return 1; + (*count) += err_level; } } else { int *count = (int*)ss_malloc(sizeof(int)); diff --git a/src/acl.h b/src/acl.h index 9be72e65..f8d70299 100644 --- a/src/acl.h +++ b/src/acl.h @@ -26,6 +26,11 @@ #define BLACK_LIST 0 #define WHITE_LIST 1 +#define MAX_TRIES 128 +#define ATTACK 32 +#define BAD 8 +#define MALFORMED 1 + int init_acl(const char *path); void free_acl(void); @@ -36,6 +41,6 @@ int acl_remove_ip(const char *ip); int get_acl_mode(void); void init_block_list(); -int check_block_list(char* addr, int max_tries); +int check_block_list(char* addr, int err_level); #endif // _ACL_H diff --git a/src/server.c b/src/server.c index 36449704..52fd21b3 100644 --- a/src/server.c +++ b/src/server.c @@ -299,7 +299,7 @@ get_peer_name(int fd) } static void -report_addr(int fd) +report_addr(int fd, int err_level) { char *peer_name; peer_name = get_peer_name(fd); @@ -307,7 +307,7 @@ report_addr(int fd) 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, 128)) { + if (check_block_list(peer_name, err_level)) { LOGE("block all requests from %s", peer_name); } } @@ -610,7 +610,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (err) { LOGE("invalid password or cipher"); - report_addr(server->fd); + report_addr(server->fd, ATTACK); close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; @@ -652,7 +652,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (server->stage == 5) { if (server->auth && !ss_check_hash(remote->buf, server->chunk, server->d_ctx, BUF_SIZE)) { LOGE("hash error"); - report_addr(server->fd); + report_addr(server->fd, BAD); close_and_free_server(EV_A_ server); close_and_free_remote(EV_A_ remote); return; @@ -721,14 +721,14 @@ server_recv_cb(EV_P_ ev_io *w, int revents) size_t len = server->buf->len; if (len < offset + header_len + ONETIMEAUTH_BYTES) { - report_addr(server->fd); + report_addr(server->fd, MALFORMED); 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)) { - report_addr(server->fd); + report_addr(server->fd, BAD); close_and_free_server(EV_A_ server); return; } @@ -750,7 +750,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) offset += in_addr_len; } else { LOGE("invalid header with addr type %d", atyp); - report_addr(server->fd); + report_addr(server->fd, MALFORMED); close_and_free_server(EV_A_ server); return; } @@ -768,7 +768,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) offset += name_len + 1; } else { LOGE("invalid name length: %d", name_len); - report_addr(server->fd); + report_addr(server->fd, MALFORMED); close_and_free_server(EV_A_ server); return; } @@ -796,7 +796,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } else { if (!validate_hostname(host, name_len)) { LOGE("invalid host name"); - report_addr(server->fd); + report_addr(server->fd, MALFORMED); close_and_free_server(EV_A_ server); return; } @@ -814,7 +814,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) offset += in6_addr_len; } else { LOGE("invalid header with addr type %d", atyp); - report_addr(server->fd); + report_addr(server->fd, MALFORMED); close_and_free_server(EV_A_ server); return; } @@ -828,7 +828,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (offset == 1) { LOGE("invalid header with addr type %d", atyp); - report_addr(server->fd); + report_addr(server->fd, MALFORMED); close_and_free_server(EV_A_ server); return; } @@ -842,7 +842,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } if (server->buf->len < offset) { - report_addr(server->fd); + report_addr(server->fd, MALFORMED); close_and_free_server(EV_A_ server); return; } else { @@ -859,7 +859,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (server->auth && !ss_check_hash(server->buf, server->chunk, server->d_ctx, BUF_SIZE)) { LOGE("hash error"); - report_addr(server->fd); + report_addr(server->fd, BAD); close_and_free_server(EV_A_ server); return; } @@ -990,7 +990,7 @@ server_timeout_cb(EV_P_ ev_timer *watcher, int revents) LOGI("incomplete header: %zu", len); #endif } - report_addr(server->fd); + report_addr(server->fd, ATTACK); } close_and_free_remote(EV_A_ remote);