Skip to content

Commit a99c39c

Browse files
committed
Simplify the server auto blocking mechanism
1 parent 5e65dc0 commit a99c39c

5 files changed

Lines changed: 32 additions & 158 deletions

File tree

src/acl.c

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -49,75 +49,10 @@ static struct cork_dllist white_list_rules;
4949

5050
static int acl_mode = BLACK_LIST;
5151

52-
static struct cache *block_list;
53-
5452
static struct ip_set outbound_block_list_ipv4;
5553
static struct ip_set outbound_block_list_ipv6;
5654
static struct cork_dllist outbound_block_list_rules;
5755

58-
void
59-
init_block_list()
60-
{
61-
cache_create(&block_list, 256, NULL);
62-
}
63-
64-
void
65-
free_block_list()
66-
{
67-
cache_clear(block_list, 0); // Remove all items
68-
}
69-
70-
int
71-
remove_from_block_list(char *addr)
72-
{
73-
size_t addr_len = strlen(addr);
74-
return cache_remove(block_list, addr, addr_len);
75-
}
76-
77-
void
78-
clear_block_list()
79-
{
80-
cache_clear(block_list, 3600); // Clear items older than 1 hour
81-
}
82-
83-
int
84-
check_block_list(char *addr)
85-
{
86-
size_t addr_len = strlen(addr);
87-
88-
if (cache_key_exist(block_list, addr, addr_len)) {
89-
int *count = NULL;
90-
cache_lookup(block_list, addr, addr_len, &count);
91-
92-
if (count != NULL && *count > MAX_TRIES)
93-
return 1;
94-
}
95-
96-
return 0;
97-
}
98-
99-
int
100-
update_block_list(char *addr, int err_level)
101-
{
102-
size_t addr_len = strlen(addr);
103-
104-
if (cache_key_exist(block_list, addr, addr_len)) {
105-
int *count = NULL;
106-
cache_lookup(block_list, addr, addr_len, &count);
107-
if (count != NULL) {
108-
if (*count > MAX_TRIES)
109-
return 1;
110-
(*count) += err_level;
111-
}
112-
} else if (err_level > 0) {
113-
int *count = (int *)ss_malloc(sizeof(int));
114-
*count = 1;
115-
cache_insert(block_list, addr, addr_len, count);
116-
}
117-
118-
return 0;
119-
}
120-
12156
static void
12257
parse_addr_cidr(const char *str, char *host, int *cidr)
12358
{

src/acl.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,15 @@
2626
#define BLACK_LIST 0
2727
#define WHITE_LIST 1
2828

29-
#define MAX_TRIES 256
30-
#define MALICIOUS 8
31-
#define SUSPICIOUS 4
32-
#define BAD 2
33-
#define MALFORMED 1
34-
3529
int init_acl(const char *path);
3630
void free_acl(void);
37-
void clear_block_list(void);
3831

3932
int acl_match_host(const char *ip);
4033
int acl_add_ip(const char *ip);
4134
int acl_remove_ip(const char *ip);
4235

4336
int get_acl_mode(void);
4437

45-
void init_block_list();
46-
void free_block_list();
47-
int check_block_list(char *addr);
48-
int update_block_list(char *addr, int err_level);
49-
int remove_from_block_list(char *addr);
50-
5138
int outbound_block_match_host(const char *host);
5239

5340
#endif // _ACL_H

src/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ int send_traffic_stat(uint64_t tx, uint64_t rx);
5454
#define STAGE_SNI 3 /* Parse HTTP/SNI header */
5555
#define STAGE_RESOLVE 4 /* Resolve the hostname */
5656
#define STAGE_STREAM 5 /* Stream between client and server */
57+
#define STAGE_STOP 6 /* Server stop to response */
5758

5859
/* Vals for long options */
5960
enum {

src/jconf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#define MAX_DSCP_NUM 64
2828
#define MAX_CONF_SIZE 128 * 1024
2929
#define MAX_CONNECT_TIMEOUT 10
30-
#define MAX_REQUEST_TIMEOUT 60
30+
#define MAX_REQUEST_TIMEOUT 30
3131
#define MIN_UDP_TIMEOUT 10
3232

3333
#define DSCP_EF 0x2E

src/server.c

Lines changed: 30 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ static void server_recv_cb(EV_P_ ev_io *w, int revents);
9393
static void remote_recv_cb(EV_P_ ev_io *w, int revents);
9494
static void remote_send_cb(EV_P_ ev_io *w, int revents);
9595
static void server_timeout_cb(EV_P_ ev_timer *watcher, int revents);
96-
static void block_list_clear_cb(EV_P_ ev_timer *watcher, int revents);
9796

9897
static remote_t *new_remote(int fd);
9998
static server_t *new_server(int fd, listen_ctx_t *listener);
@@ -138,7 +137,6 @@ uint64_t rx = 0;
138137
#ifndef __MINGW32__
139138
ev_timer stat_update_watcher;
140139
#endif
141-
ev_timer block_list_watcher;
142140

143141
static struct ev_signal sigint_watcher;
144142
static struct ev_signal sigterm_watcher;
@@ -269,43 +267,19 @@ get_peer_name(int fd)
269267
return peer_name;
270268
}
271269

272-
#ifdef __linux__
273270
static void
274-
set_linger(int fd)
271+
stop_server(EV_P_ server_t *server)
275272
{
276-
struct linger so_linger;
277-
memset(&so_linger, 0, sizeof(struct linger));
278-
so_linger.l_onoff = 1;
279-
so_linger.l_linger = 0;
280-
setsockopt(fd, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger);
281-
}
282-
283-
#endif
284-
285-
static void
286-
reset_addr(int fd)
287-
{
288-
char *peer_name;
289-
peer_name = get_peer_name(fd);
290-
if (peer_name != NULL) {
291-
remove_from_block_list(peer_name);
292-
}
273+
server->stage = STAGE_STOP;
293274
}
294275

295276
static void
296-
report_addr(int fd, int err_level, const char *info)
277+
report_addr(int fd, const char *info)
297278
{
298-
#ifdef __linux__
299-
set_linger(fd);
300-
#endif
301-
302279
char *peer_name;
303280
peer_name = get_peer_name(fd);
304281
if (peer_name != NULL) {
305282
LOGE("failed to handshake with %s: %s", peer_name, info);
306-
// Avoid block local plugins
307-
if (strcmp(peer_name, "127.0.0.1") != 0)
308-
update_block_list(peer_name, err_level);
309283
}
310284
}
311285

@@ -724,10 +698,16 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
724698

725699
buffer_t *buf = server->buf;
726700

701+
// Ignore any new packet if the server is stopped
702+
if (server->stage == STAGE_STOP) {
703+
return;
704+
}
705+
727706
if (server->stage == STAGE_STREAM) {
728707
remote = server->remote;
729708
buf = remote->buf;
730709

710+
// Only timer the watcher if a valid connection is established
731711
ev_timer_again(EV_A_ & server->recv_ctx->watcher);
732712
}
733713

@@ -760,15 +740,13 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
760740
int err = crypto->decrypt(buf, server->d_ctx, SOCKET_BUF_SIZE);
761741

762742
if (err == CRYPTO_ERROR) {
763-
report_addr(server->fd, MALICIOUS, "authentication error");
764-
close_and_free_remote(EV_A_ remote);
765-
close_and_free_server(EV_A_ server);
743+
report_addr(server->fd, "authentication error");
744+
stop_server(EV_A_ server);
766745
return;
767746
} else if (err == CRYPTO_NEED_MORE) {
768747
if (server->stage != STAGE_STREAM && server->frag > MAX_FRAG) {
769-
report_addr(server->fd, MALICIOUS, "malicious fragmentation");
770-
close_and_free_remote(EV_A_ remote);
771-
close_and_free_server(EV_A_ server);
748+
report_addr(server->fd, "malicious fragmentation");
749+
stop_server(EV_A_ server);
772750
return;
773751
}
774752
server->frag++;
@@ -830,8 +808,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
830808
host, INET_ADDRSTRLEN);
831809
offset += in_addr_len;
832810
} else {
833-
report_addr(server->fd, MALFORMED, "invalid length for ipv4 address");
834-
close_and_free_server(EV_A_ server);
811+
report_addr(server->fd, "invalid length for ipv4 address");
812+
stop_server(EV_A_ server);
835813
return;
836814
}
837815
addr->sin_port = *(uint16_t *)(server->buf->data + offset);
@@ -847,8 +825,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
847825
memcpy(host, server->buf->data + offset + 1, name_len);
848826
offset += name_len + 1;
849827
} else {
850-
report_addr(server->fd, MALFORMED, "invalid host name length");
851-
close_and_free_server(EV_A_ server);
828+
report_addr(server->fd, "invalid host name length");
829+
stop_server(EV_A_ server);
852830
return;
853831
}
854832
if (acl && outbound_block_match_host(host) == 1) {
@@ -880,8 +858,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
880858
}
881859
} else {
882860
if (!validate_hostname(host, name_len)) {
883-
report_addr(server->fd, MALFORMED, "invalid host name");
884-
close_and_free_server(EV_A_ server);
861+
report_addr(server->fd, "invalid host name");
862+
stop_server(EV_A_ server);
885863
return;
886864
}
887865
need_query = 1;
@@ -898,8 +876,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
898876
offset += in6_addr_len;
899877
} else {
900878
LOGE("invalid header with addr type %d", atyp);
901-
report_addr(server->fd, MALFORMED, "invalid length for ipv6 address");
902-
close_and_free_server(EV_A_ server);
879+
report_addr(server->fd, "invalid length for ipv6 address");
880+
stop_server(EV_A_ server);
903881
return;
904882
}
905883
addr->sin6_port = *(uint16_t *)(server->buf->data + offset);
@@ -911,8 +889,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
911889
}
912890

913891
if (offset == 1) {
914-
report_addr(server->fd, MALFORMED, "invalid address type");
915-
close_and_free_server(EV_A_ server);
892+
report_addr(server->fd, "invalid address type");
893+
stop_server(EV_A_ server);
916894
return;
917895
}
918896

@@ -921,8 +899,8 @@ server_recv_cb(EV_P_ ev_io *w, int revents)
921899
offset += 2;
922900

923901
if (server->buf->len < offset) {
924-
report_addr(server->fd, MALFORMED, "invalid request length");
925-
close_and_free_server(EV_A_ server);
902+
report_addr(server->fd, "invalid request length");
903+
stop_server(EV_A_ server);
926904
return;
927905
} else {
928906
server->buf->len -= offset;
@@ -1036,12 +1014,6 @@ server_send_cb(EV_P_ ev_io *w, int revents)
10361014
}
10371015
}
10381016

1039-
static void
1040-
block_list_clear_cb(EV_P_ ev_timer *watcher, int revents)
1041-
{
1042-
clear_block_list();
1043-
}
1044-
10451017
static void
10461018
server_timeout_cb(EV_P_ ev_timer *watcher, int revents)
10471019
{
@@ -1135,6 +1107,11 @@ remote_recv_cb(EV_P_ ev_io *w, int revents)
11351107
remote_t *remote = remote_recv_ctx->remote;
11361108
server_t *server = remote->server;
11371109

1110+
// Ignore any new packet if the server is stopped
1111+
if (server->stage == STAGE_STOP) {
1112+
return;
1113+
}
1114+
11381115
if (server == NULL) {
11391116
LOGE("invalid server");
11401117
close_and_free_remote(EV_A_ remote);
@@ -1266,9 +1243,6 @@ remote_send_cb(EV_P_ ev_io *w, int revents)
12661243
}
12671244
remote_send_ctx->connected = 1;
12681245

1269-
// Clear the state of this address in the block list
1270-
reset_addr(server->fd);
1271-
12721246
if (remote->buf->len == 0) {
12731247
server->stage = STAGE_STREAM;
12741248
ev_io_stop(EV_A_ & remote_send_ctx->io);
@@ -1554,26 +1528,14 @@ accept_cb(EV_P_ ev_io *w, int revents)
15541528

15551529
char *peer_name = get_peer_name(serverfd);
15561530
if (peer_name != NULL) {
1557-
int in_white_list = 0;
15581531
if (acl) {
15591532
if ((get_acl_mode() == BLACK_LIST && acl_match_host(peer_name) == 1)
15601533
|| (get_acl_mode() == WHITE_LIST && acl_match_host(peer_name) >= 0)) {
15611534
LOGE("Access denied from %s", peer_name);
15621535
close(serverfd);
15631536
return;
1564-
} else if (acl_match_host(peer_name) == -1) {
1565-
in_white_list = 1;
15661537
}
15671538
}
1568-
if (!in_white_list && plugin == NULL
1569-
&& check_block_list(peer_name)) {
1570-
LOGE("block all requests from %s", peer_name);
1571-
#ifdef __linux__
1572-
set_linger(serverfd);
1573-
#endif
1574-
close(serverfd);
1575-
return;
1576-
}
15771539
}
15781540

15791541
int opt = 1;
@@ -2101,9 +2063,6 @@ main(int argc, char **argv)
21012063
}
21022064
#endif
21032065

2104-
ev_timer_init(&block_list_watcher, block_list_clear_cb, UPDATE_INTERVAL, UPDATE_INTERVAL);
2105-
ev_timer_start(EV_DEFAULT, &block_list_watcher);
2106-
21072066
#ifndef __MINGW32__
21082067
// setuid
21092068
if (user != NULL && !run_as(user)) {
@@ -2115,9 +2074,6 @@ main(int argc, char **argv)
21152074
}
21162075
#endif
21172076

2118-
// init block list
2119-
init_block_list();
2120-
21212077
// Init connections
21222078
cork_dllist_init(&connections);
21232079

@@ -2128,17 +2084,12 @@ main(int argc, char **argv)
21282084
LOGI("closed gracefully");
21292085
}
21302086

2131-
// Free block list
2132-
free_block_list();
2133-
21342087
#ifndef __MINGW32__
21352088
if (manager_addr != NULL) {
21362089
ev_timer_stop(EV_DEFAULT, &stat_update_watcher);
21372090
}
21382091
#endif
21392092

2140-
ev_timer_stop(EV_DEFAULT, &block_list_watcher);
2141-
21422093
if (plugin != NULL) {
21432094
stop_plugin();
21442095
}

0 commit comments

Comments
 (0)