|
@ -45,18 +45,96 @@ static struct ip_set outbound_block_list_ipv4; |
|
|
static struct ip_set outbound_block_list_ipv6; |
|
|
static struct ip_set outbound_block_list_ipv6; |
|
|
static struct cork_dllist outbound_block_list_rules; |
|
|
static struct cork_dllist outbound_block_list_rules; |
|
|
|
|
|
|
|
|
|
|
|
#ifdef __linux__ |
|
|
|
|
|
|
|
|
|
|
|
#include <unistd.h> |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
|
run_cmd(const char *cmdstring) |
|
|
|
|
|
{ |
|
|
|
|
|
pid_t pid; |
|
|
|
|
|
int status; |
|
|
|
|
|
if (cmdstring == NULL) { |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
if ((pid = fork()) < 0) { |
|
|
|
|
|
status = -1; |
|
|
|
|
|
} else if (pid == 0) { |
|
|
|
|
|
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); |
|
|
|
|
|
_exit(127); |
|
|
|
|
|
} |
|
|
|
|
|
return status; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
|
init_iptables() |
|
|
|
|
|
{ |
|
|
|
|
|
if (geteuid() != 0) |
|
|
|
|
|
return -1; |
|
|
|
|
|
char cli[256]; |
|
|
|
|
|
sprintf(cli, "iptables -N SHADOWSOCKS_LIBEV; \ |
|
|
|
|
|
iptables -F SHADOWSOCKS_LIBEV; \ |
|
|
|
|
|
iptables -A OUTPUT -p tcp --tcp-flags FIN FIN -j SHADOWSOCKS_LIBEV"); |
|
|
|
|
|
return run_cmd(cli); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
|
clean_iptables() |
|
|
|
|
|
{ |
|
|
|
|
|
if (geteuid() != 0) |
|
|
|
|
|
return -1; |
|
|
|
|
|
char cli[256]; |
|
|
|
|
|
sprintf(cli, "iptables -D OUTPUT -p tcp --tcp-flags FIN FIN -j SHADOWSOCKS_LIBEV; \ |
|
|
|
|
|
iptables -F SHADOWSOCKS_LIBEV; \ |
|
|
|
|
|
iptables -X SHADOWSOCKS_LIBEV"); |
|
|
|
|
|
return run_cmd(cli); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
|
set_iptables_rules(char *addr, int add) |
|
|
|
|
|
{ |
|
|
|
|
|
if (geteuid() != 0) |
|
|
|
|
|
return -1; |
|
|
|
|
|
char cli[256]; |
|
|
|
|
|
if (add) |
|
|
|
|
|
sprintf(cli, "iptables -A SHADOWSOCKS_LIBEV -d %s -j DROP", addr); |
|
|
|
|
|
else |
|
|
|
|
|
sprintf(cli, "iptables -D SHADOWSOCKS_LIBEV -d %s -j DROP", addr); |
|
|
|
|
|
return run_cmd(cli); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
void |
|
|
void |
|
|
init_block_list() |
|
|
init_block_list() |
|
|
{ |
|
|
{ |
|
|
// Initialize cache |
|
|
// Initialize cache |
|
|
|
|
|
#ifdef __linux__ |
|
|
|
|
|
init_iptables(); |
|
|
|
|
|
#endif |
|
|
cache_create(&block_list, 256, NULL); |
|
|
cache_create(&block_list, 256, NULL); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
free_block_list() |
|
|
|
|
|
{ |
|
|
|
|
|
#ifdef __linux__ |
|
|
|
|
|
clean_iptables(); |
|
|
|
|
|
#endif |
|
|
|
|
|
cache_clear(block_list, 0); // Remove all items |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
int |
|
|
remove_from_block_list(char *addr) |
|
|
remove_from_block_list(char *addr) |
|
|
{ |
|
|
{ |
|
|
size_t addr_len = strlen(addr); |
|
|
size_t addr_len = strlen(addr); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef __linux__ |
|
|
|
|
|
if (cache_key_exist(block_list, addr, addr_len)) |
|
|
|
|
|
set_iptables_rules(addr, 0); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return cache_remove(block_list, addr, addr_len); |
|
|
return cache_remove(block_list, addr, addr_len); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -83,6 +161,9 @@ check_block_list(char *addr, int err_level) |
|
|
int *count = (int *)ss_malloc(sizeof(int)); |
|
|
int *count = (int *)ss_malloc(sizeof(int)); |
|
|
*count = 1; |
|
|
*count = 1; |
|
|
cache_insert(block_list, addr, addr_len, count); |
|
|
cache_insert(block_list, addr, addr_len, count); |
|
|
|
|
|
#ifdef __linux__ |
|
|
|
|
|
set_iptables_rules(addr, 1); |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return 0; |
|
|
return 0; |
|
|