Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-14 06:13:09 +00:00

nfqws2: profile templates, remove stun_bindin_req detalisation

This commit is contained in:
bol-van
2025-12-04 23:17:45 +03:00
parent ee031db3a1
commit 807ad5953b
13 changed files with 458 additions and 204 deletions

View File

@@ -1,5 +1,10 @@
#pragma once
#define CTRACK_T_SYN 60
#define CTRACK_T_FIN 60
#define CTRACK_T_EST 300
#define CTRACK_T_UDP 60
// SYN - SYN or SYN/ACK received
// ESTABLISHED - any except SYN or SYN/ACK received
// FIN - FIN or RST received

View File

@@ -1531,6 +1531,7 @@ static uint8_t dpi_desync_udp_packet_play(
t_protocol_probe testers[] = {
{L7P_DNS_RESPONSE,L7_DNS,IsDNSResponse,false},
{L7P_DHT,L7_DHT,IsDht,false},
{L7P_STUN,L7_STUN,IsStunMessage,false},
{L7P_WIREGUARD_INITIATION,L7_WIREGUARD,IsWireguardHandshakeInitiation,false},
{L7P_WIREGUARD_RESPONSE,L7_WIREGUARD,IsWireguardHandshakeResponse,false},
{L7P_WIREGUARD_COOKIE,L7_WIREGUARD,IsWireguardHandshakeCookie,false},
@@ -1682,7 +1683,7 @@ static uint8_t dpi_desync_udp_packet_play(
t_protocol_probe testers[] = {
{L7P_DISCORD_IP_DISCOVERY,L7_DISCORD,IsDiscordIpDiscoveryRequest,false},
{L7P_STUN_BINDING_REQ,L7_STUN,IsStunBindingRequest,false},
{L7P_STUN,L7_STUN,IsStunMessage,false},
{L7P_DNS_QUERY,L7_DNS,IsDNSQuery,false},
{L7P_DHT,L7_DHT,IsDht,false},
{L7P_WIREGUARD_INITIATION,L7_WIREGUARD,IsWireguardHandshakeInitiation,false},

View File

@@ -301,13 +301,34 @@ struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude,
filename);
}
static void HostlistsDebugProfile(const struct desync_profile *dp, const char *entity)
{
struct hostlist_item *hl_item;
LIST_FOREACH(hl_item, &dp->hl_collection, next)
if (hl_item->hfile!=dp->hostlist_auto)
{
if (hl_item->hfile->filename)
DLOG("%s %u (%s) include hostlist %s%s\n",entity, dp->n, PROFILE_NAME(dp), hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
else
DLOG("%s %u (%s) include fixed hostlist%s\n",entity, dp->n, PROFILE_NAME(dp), hl_item->hfile->hostlist ? "" : " (empty)");
}
LIST_FOREACH(hl_item, &dp->hl_collection_exclude, next)
{
if (hl_item->hfile->filename)
DLOG("%s %u (%s) exclude hostlist %s%s\n",entity, dp->n,PROFILE_NAME(dp),hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
else
DLOG("%s %u (%s) exclude fixed hostlist%s\n",entity, dp->n,PROFILE_NAME(dp),hl_item->hfile->hostlist ? "" : " (empty)");
}
if (dp->hostlist_auto)
DLOG("%s %u (%s) auto hostlist %s%s\n",entity, dp->n,PROFILE_NAME(dp),dp->hostlist_auto->filename,dp->hostlist_auto->hostlist ? "" : " (empty)");
}
void HostlistsDebug()
{
if (!params.debug) return;
struct hostlist_file *hfile;
struct desync_profile_list *dpl;
struct hostlist_item *hl_item;
LIST_FOREACH(hfile, &params.hostlists, next)
{
@@ -319,22 +340,10 @@ void HostlistsDebug()
LIST_FOREACH(dpl, &params.desync_profiles, next)
{
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
if (hl_item->hfile!=dpl->dp.hostlist_auto)
{
if (hl_item->hfile->filename)
DLOG("profile %u (%s) include hostlist %s%s\n",dpl->dp.n, PROFILE_NAME(&dpl->dp), hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
else
DLOG("profile %u (%s) include fixed hostlist%s\n",dpl->dp.n, PROFILE_NAME(&dpl->dp), hl_item->hfile->hostlist ? "" : " (empty)");
}
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
{
if (hl_item->hfile->filename)
DLOG("profile %u (%s) exclude hostlist %s%s\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
else
DLOG("profile %u (%s) exclude fixed hostlist%s\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),hl_item->hfile->hostlist ? "" : " (empty)");
}
if (dpl->dp.hostlist_auto)
DLOG("profile %u (%s) auto hostlist %s%s\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
HostlistsDebugProfile(&dpl->dp, "profile");
}
LIST_FOREACH(dpl, &params.desync_templates, next)
{
HostlistsDebugProfile(&dpl->dp, "template");
}
}

View File

@@ -287,13 +287,31 @@ static const char *dbg_ipset_fill(const ipset *ips)
else
return "empty";
}
void IpsetsDebugProfile(const struct desync_profile *dp, const char *entity)
{
struct ipset_item *ips_item;
LIST_FOREACH(ips_item, &dp->ips_collection, next)
{
if (ips_item->hfile->filename)
DLOG("%s %u (%s) include ipset %s (%s)\n",entity,dp->n,PROFILE_NAME(dp),ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
else
DLOG("%s %u (%s) include fixed ipset (%s)\n",entity,dp->n,PROFILE_NAME(dp),dbg_ipset_fill(&ips_item->hfile->ipset));
}
LIST_FOREACH(ips_item, &dp->ips_collection_exclude, next)
{
if (ips_item->hfile->filename)
DLOG("%s %u (%s) exclude ipset %s (%s)\n",entity,dp->n,PROFILE_NAME(dp),ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
else
DLOG("%s %u (%s) exclude fixed ipset (%s)\n",entity,dp->n,PROFILE_NAME(dp),dbg_ipset_fill(&ips_item->hfile->ipset));
}
}
void IpsetsDebug()
{
if (!params.debug) return;
struct ipset_file *hfile;
struct desync_profile_list *dpl;
struct ipset_item *ips_item;
LIST_FOREACH(hfile, &params.ipsets, next)
{
@@ -305,15 +323,10 @@ void IpsetsDebug()
LIST_FOREACH(dpl, &params.desync_profiles, next)
{
LIST_FOREACH(ips_item, &dpl->dp.ips_collection, next)
if (ips_item->hfile->filename)
DLOG("profile %u (%s) include ipset %s (%s)\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
else
DLOG("profile %u (%s) include fixed ipset (%s)\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),dbg_ipset_fill(&ips_item->hfile->ipset));
LIST_FOREACH(ips_item, &dpl->dp.ips_collection_exclude, next)
if (ips_item->hfile->filename)
DLOG("profile %u (%s) exclude ipset %s (%s)\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
else
DLOG("profile %u (%s) exclude fixed ipset (%s)\n",dpl->dp.n,PROFILE_NAME(&dpl->dp),dbg_ipset_fill(&ips_item->hfile->ipset));
IpsetsDebugProfile(&dpl->dp, "profile");
}
LIST_FOREACH(dpl, &params.desync_templates, next)
{
IpsetsDebugProfile(&dpl->dp, "template");
}
}

View File

@@ -1223,7 +1223,7 @@ void lua_pushf_ctrack(const t_ctrack *ctrack, const t_ctrack_position *pos)
LUA_STACK_GUARD_LEAVE(params.L, 0)
}
void lua_pushf_args(const struct ptr_list_head *args, int idx_desync)
void lua_pushf_args(const struct str2_list_head *args, int idx_desync)
{
// var=val - pass val string
// var=%val - subst 'val' blob
@@ -1233,7 +1233,7 @@ void lua_pushf_args(const struct ptr_list_head *args, int idx_desync)
LUA_STACK_GUARD_ENTER(params.L)
struct ptr_list *arg;
struct str2_list *arg;
const char *var, *val;
idx_desync = lua_absindex(params.L, idx_desync);
@@ -1242,8 +1242,8 @@ void lua_pushf_args(const struct ptr_list_head *args, int idx_desync)
lua_newtable(params.L);
LIST_FOREACH(arg, args, next)
{
var = (char*)arg->ptr1;
val = arg->ptr2 ? (char*)arg->ptr2 : "";
var = arg->str1;
val = arg->str2 ? arg->str2 : "";
if (val[0]=='\\' && (val[1]=='%' || val[1]=='#'))
// escape char
lua_pushf_str(var, val+1);

View File

@@ -72,7 +72,7 @@ void lua_pushf_ip6hdr(const struct ip6_hdr *ip6, size_t len);
void lua_push_dissect(const struct dissect *dis);
void lua_pushf_dissect(const struct dissect *dis);
void lua_pushf_ctrack(const t_ctrack *ctrack, const t_ctrack_position *pos);
void lua_pushf_args(const struct ptr_list_head *args, int idx_desync);
void lua_pushf_args(const struct str2_list_head *args, int idx_desync);
void lua_pushf_pos(const char *name, const struct packet_pos *pos);
void lua_pushf_range(const char *name, const struct packet_range *range);
void lua_pushf_global(const char *field, const char *global);

View File

@@ -48,11 +48,6 @@
#define NF_ACCEPT 1
#endif
#define CTRACK_T_SYN 60
#define CTRACK_T_FIN 60
#define CTRACK_T_EST 300
#define CTRACK_T_UDP 60
#define MAX_CONFIG_FILE_SIZE 16384
struct params_s params;
@@ -1007,27 +1002,27 @@ static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
return true;
}
bool lua_call_param_add(char *opt, struct ptr_list_head *args)
bool lua_call_param_add(char *opt, struct str2_list_head *args)
{
char c,*p;
struct ptr_list *arg;
struct str2_list *arg;
if ((p = strchr(opt,'=')))
{
c = *p; *p = 0;
}
if (!is_identifier(opt) || !(arg=ptrlist_add(args)))
if (!is_identifier(opt) || !(arg=str2list_add(args)))
{
if (p) *p = c;
return false;
}
arg->ptr1 = strdup(opt);
arg->str1 = strdup(opt);
if (p)
{
arg->ptr2 = strdup(p+1);
arg->str2 = strdup(p+1);
*p = c;
}
return arg->ptr1;
return !!arg->str2;
}
struct func_list *parse_lua_call(char *opt, struct func_list_head *flist)
@@ -1156,21 +1151,21 @@ static void BlobDebug()
}
}
static void LuaDesyncDebug(struct desync_profile *dp)
static void LuaDesyncDebug(struct desync_profile *dp, const char *entity)
{
if (params.debug)
{
struct func_list *func;
struct ptr_list *arg;
struct str2_list *arg;
int n,i;
LIST_FOREACH(func, &dp->lua_desync, next)
{
DLOG("profile %u (%s) lua %s(",dp->n,PROFILE_NAME(dp),func->func);
DLOG("%s %u (%s) lua %s(",entity,dp->n,PROFILE_NAME(dp),func->func);
n=0;
LIST_FOREACH(arg, &func->args, next)
{
if (n) DLOG(",");
DLOG(arg->ptr2 ? "%s=\"%s\"" : "%s=\"\"", (char*)arg->ptr1, (char*)arg->ptr2);
DLOG(arg->str2 ? "%s=\"%s\"" : "%s=\"\"", arg->str1, arg->str2);
n++;
}
DLOG(" range_in=%c%u%c%c%u range_out=%c%u%c%c%u payload_type=",
@@ -1415,6 +1410,8 @@ static void exithelp(void)
" --new\t\t\t\t\t\t\t; begin new profile\n"
" --skip\t\t\t\t\t\t\t; do not use this profile\n"
" --name\t\t\t\t\t\t\t; set profile name\n"
" --template\t\t\t\t\t\t; use this profile as template (must be named or will be useless)\n"
" --import=<name>\t\t\t\t\t; populate current profile with template data\n"
" --filter-l3=ipv4|ipv6\t\t\t\t\t; L3 protocol filter. multiple comma separated values allowed.\n"
" --filter-tcp=[~]port1[-port2]|*\t\t\t; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list allowed.\n"
" --filter-udp=[~]port1[-port2]|*\t\t\t; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list allowed.\n"
@@ -1565,6 +1562,8 @@ enum opt_indices {
IDX_NEW,
IDX_SKIP,
IDX_NAME,
IDX_TEMPLATE,
IDX_IMPORT,
IDX_FILTER_L3,
IDX_FILTER_TCP,
IDX_FILTER_UDP,
@@ -1646,6 +1645,8 @@ static const struct option long_options[] = {
[IDX_NEW] = {"new", no_argument, 0, 0},
[IDX_SKIP] = {"skip", no_argument, 0, 0},
[IDX_NAME] = {"name", required_argument, 0, 0},
[IDX_TEMPLATE] = {"template", no_argument, 0, 0},
[IDX_IMPORT] = {"import", required_argument, 0, 0},
[IDX_FILTER_L3] = {"filter-l3", required_argument, 0, 0},
[IDX_FILTER_TCP] = {"filter-tcp", required_argument, 0, 0},
[IDX_FILTER_UDP] = {"filter-udp", required_argument, 0, 0},
@@ -1684,15 +1685,7 @@ static const struct option long_options[] = {
int main(int argc, char **argv)
{
if (argc < 2) exithelp();
aes_init_keygen_tables(); // required for aes
set_console_io_buffering();
set_env_exedir(argv[0]);
#ifdef __CYGWIN__
prepare_low_appdata();
if (service_run(argc, argv))
{
// we were running as service. now exit.
@@ -1701,7 +1694,7 @@ int main(int argc, char **argv)
#endif
int result, v;
int option_index = 0;
bool bSkip = false, bDry = false;
bool bSkip = false, bDry = false, bTemplate;
struct hostlist_file *anon_hl = NULL, *anon_hl_exclude = NULL;
struct ipset_file *anon_ips = NULL, *anon_ips_exclude = NULL;
uint64_t payload_type=0;
@@ -1713,17 +1706,27 @@ int main(int argc, char **argv)
unsigned int hash_wf_tcp_in = 0, hash_wf_udp_in = 0, hash_wf_tcp_out = 0, hash_wf_udp_out = 0, hash_wf_raw = 0, hash_wf_raw_part = 0, hash_ssid_filter = 0, hash_nlm_filter = 0;
#endif
if (argc < 2) exithelp();
srandom(time(NULL));
aes_init_keygen_tables(); // required for aes
mask_from_preflen6_prepare();
set_env_exedir(argv[0]);
set_console_io_buffering();
#ifdef __CYGWIN__
prepare_low_appdata();
#endif
PRINT_VER;
memset(&params, 0, sizeof(params));
init_params(&params);
ApplyDefaultBlobs(&params.blobs);
struct desync_profile_list *dpl;
struct desync_profile *dp;
unsigned int desync_profile_count = 0;
unsigned int desync_profile_count = 0, desync_template_count = 0;
bTemplate = false;
if (!(dpl = dp_list_add(&params.desync_profiles)))
{
DLOG_ERR("desync_profile_add: out of memory\n");
@@ -1732,39 +1735,6 @@ int main(int argc, char **argv)
dp = &dpl->dp;
dp->n = ++desync_profile_count;
#ifdef __linux__
params.qnum = -1;
#elif defined(BSD)
params.port = 0;
#endif
params.desync_fwmark = DPI_DESYNC_FWMARK_DEFAULT;
params.ctrack_t_syn = CTRACK_T_SYN;
params.ctrack_t_est = CTRACK_T_EST;
params.ctrack_t_fin = CTRACK_T_FIN;
params.ctrack_t_udp = CTRACK_T_UDP;
params.ipcache_lifetime = IPCACHE_LIFETIME;
params.lua_gc = LUA_GC_INTERVAL;
LIST_INIT(&params.hostlists);
LIST_INIT(&params.ipsets);
LIST_INIT(&params.blobs);
LIST_INIT(&params.lua_init_scripts);
ApplyDefaultBlobs(&params.blobs);
#ifdef __CYGWIN__
LIST_INIT(&params.ssid_filter);
LIST_INIT(&params.nlm_filter);
LIST_INIT(&params.wf_raw_part);
#else
if (can_drop_root())
{
params.uid = params.gid[0] = 0x7FFFFFFF; // default uid:gid
params.gid_count = 1;
params.droproot = true;
}
#endif
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
if (argc >= 2 && (argv[1][0] == '@' || argv[1][0] == '$'))
{
@@ -2124,19 +2094,35 @@ int main(int argc, char **argv)
else
{
check_dp(dp);
if (bTemplate)
{
if (dp->name && dp_list_search_name(&params.desync_templates, dp->name))
{
DLOG_ERR("template '%s' already present\n", dp->name);
exit_clean(1);
}
dpl->dp.n = ++desync_template_count;
dp_list_move(&params.desync_templates, dpl);
}
else
{
desync_profile_count++;
}
if (!(dpl = dp_list_add(&params.desync_profiles)))
{
DLOG_ERR("desync_profile_add: out of memory\n");
exit_clean(1);
}
dp = &dpl->dp;
dp->n = ++desync_profile_count;
dp->n = desync_profile_count;
}
anon_hl = anon_hl_exclude = NULL;
anon_ips = anon_ips_exclude = NULL;
payload_type = 0;
range_in = PACKET_RANGE_NEVER;
range_out = PACKET_RANGE_ALWAYS;
bTemplate = false;
break;
case IDX_SKIP:
bSkip = true;
@@ -2149,6 +2135,25 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case IDX_TEMPLATE:
bTemplate = true;
break;
case IDX_IMPORT:
{
struct desync_profile_list *tpl = dp_list_search_name(&params.desync_templates, optarg);
if (!tpl)
{
DLOG_ERR("template '%s' not found\n", optarg);
exit_clean(1);
}
if (!dp_list_copy(dp, &tpl->dp))
{
DLOG_ERR("could not copy template\n");
exit_clean(1);
}
dp->n = desync_profile_count;
}
break;
case IDX_FILTER_L3:
if (!wf_make_l3(optarg, &dp->filter_ipv4, &dp->filter_ipv6))
@@ -2411,7 +2416,20 @@ int main(int argc, char **argv)
desync_profile_count--;
}
else
{
check_dp(dp);
if (bTemplate)
{
if (dp->name && dp_list_search_name(&params.desync_templates, dp->name))
{
DLOG_ERR("template '%s' already present\n", dp->name);
exit_clean(1);
}
dpl->dp.n = ++desync_template_count;
dp_list_move(&params.desync_templates, dpl);
desync_profile_count--;
}
}
// do not need args from file anymore
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
@@ -2441,7 +2459,8 @@ int main(int argc, char **argv)
exit_clean(1);
}
DLOG_CONDUP("we have %d user defined desync profile(s) and default low priority profile 0\n", desync_profile_count);
DLOG_CONDUP("we have %u user defined desync profile(s) and default low priority profile 0\n", desync_profile_count);
DLOG_CONDUP("we have %u user defined desync template(s)\n", desync_template_count);
if (params.writeable_dir_enable)
{
@@ -2479,7 +2498,12 @@ int main(int argc, char **argv)
DLOG_ERR("could not make '%s' accessible. auto hostlist file may not be writable after privilege drop\n", dp->hostlist_auto->filename);
}
LuaDesyncDebug(dp);
LuaDesyncDebug(dp,"profile");
}
LIST_FOREACH(dpl, &params.desync_templates, next)
{
dp = &dpl->dp;
LuaDesyncDebug(dp,"template");
}
if (!test_list_files())
@@ -2505,6 +2529,9 @@ int main(int argc, char **argv)
BlobDebug();
DLOG("\n");
// not required anymore. free memory
dp_list_destroy(&params.desync_templates);
#ifdef __CYGWIN__
if (!*params.windivert_filter)
{

View File

@@ -322,7 +322,7 @@ void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
}
}
void dp_init(struct desync_profile *dp)
void dp_init_dynamic(struct desync_profile *dp)
{
LIST_INIT(&dp->hl_collection);
LIST_INIT(&dp->hl_collection_exclude);
@@ -331,31 +331,19 @@ void dp_init(struct desync_profile *dp)
LIST_INIT(&dp->pf_tcp);
LIST_INIT(&dp->pf_udp);
LIST_INIT(&dp->lua_desync);
#ifdef HAS_FILTER_SSID
LIST_INIT(&dp->filter_ssid);
#endif
}
void dp_init(struct desync_profile *dp)
{
dp_init_dynamic(dp);
dp->hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
dp->hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
dp->hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
dp->filter_ipv4 = dp->filter_ipv6 = true;
}
struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
{
struct desync_profile_list *entry = calloc(1,sizeof(struct desync_profile_list));
if (!entry) return NULL;
dp_init(&entry->dp);
// add to the tail
struct desync_profile_list *dpn,*dpl=LIST_FIRST(&params.desync_profiles);
if (dpl)
{
while ((dpn=LIST_NEXT(dpl,next))) dpl = dpn;
LIST_INSERT_AFTER(dpl, entry, next);
}
else
LIST_INSERT_HEAD(&params.desync_profiles, entry, next);
return entry;
}
static void dp_clear_dynamic(struct desync_profile *dp)
{
hostlist_collection_destroy(&dp->hl_collection);
@@ -390,6 +378,66 @@ void dp_list_destroy(struct desync_profile_list_head *head)
dp_entry_destroy(entry);
}
}
static struct desync_profile_list *desync_profile_entry_alloc()
{
struct desync_profile_list *entry = calloc(1,sizeof(struct desync_profile_list));
if (entry) dp_init(&entry->dp);
return entry;
}
struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
{
struct desync_profile_list *entry = desync_profile_entry_alloc();
if (!entry) return false;
struct desync_profile_list *tail, *item;
LIST_TAIL(head, tail, item);
LIST_INSERT_TAIL(head, tail, entry, next);
return entry;
}
bool dp_list_copy(struct desync_profile *to, const struct desync_profile *from)
{
// clear everything in target
dp_clear(to);
// first copy all simple type values
*to = *from;
// prepare empty dynamic structures
dp_init_dynamic(to);
// copy dynamic structures
to->name = strdup(from->name);
if (
!to->name ||
#ifdef HAS_FILTER_SSID
!strlist_copy(&to->filter_ssid, &from->filter_ssid) ||
#endif
!funclist_copy(&to->lua_desync, &from->lua_desync) ||
!ipset_collection_copy(&to->ips_collection, &from->ips_collection) ||
!ipset_collection_copy(&to->ips_collection_exclude, &from->ips_collection_exclude) ||
!hostlist_collection_copy(&to->hl_collection, &from->hl_collection) ||
!hostlist_collection_copy(&to->hl_collection_exclude, &from->hl_collection_exclude))
{
return false;
}
return true;
}
void dp_list_move(struct desync_profile_list_head *target, struct desync_profile_list *dpl)
{
struct desync_profile_list *tail, *item;
LIST_TAIL(target, tail, item);
LIST_REMOVE(dpl, next);
LIST_INSERT_TAIL(target, tail, dpl, next);
}
struct desync_profile_list *dp_list_search_name(struct desync_profile_list_head *head, const char *name)
{
struct desync_profile_list *dpl;
if (name)
LIST_FOREACH(dpl, head, next)
if (dpl->dp.name && !strcmp(dpl->dp.name, name))
return dpl;
return NULL;
}
bool dp_list_have_autohostlist(struct desync_profile_list_head *head)
{
struct desync_profile_list *dpl;
@@ -428,6 +476,7 @@ void cleanup_params(struct params_s *params)
ConntrackPoolDestroy(&params->conntrack);
dp_list_destroy(&params->desync_profiles);
dp_list_destroy(&params->desync_templates);
hostlist_files_destroy(&params->hostlists);
ipset_files_destroy(&params->ipsets);
ipcacheDestroy(&params->ipcache);
@@ -441,3 +490,40 @@ void cleanup_params(struct params_s *params)
free(params->user); params->user=NULL;
#endif
}
void init_params(struct params_s *params)
{
memset(params, 0, sizeof(*params));
#ifdef __linux__
params->qnum = -1;
#elif defined(BSD)
params->port = 0;
#endif
params->desync_fwmark = DPI_DESYNC_FWMARK_DEFAULT;
params->ctrack_t_syn = CTRACK_T_SYN;
params->ctrack_t_est = CTRACK_T_EST;
params->ctrack_t_fin = CTRACK_T_FIN;
params->ctrack_t_udp = CTRACK_T_UDP;
params->ipcache_lifetime = IPCACHE_LIFETIME;
params->lua_gc = LUA_GC_INTERVAL;
LIST_INIT(&params->hostlists);
LIST_INIT(&params->ipsets);
LIST_INIT(&params->blobs);
LIST_INIT(&params->lua_init_scripts);
#ifdef __CYGWIN__
LIST_INIT(&params->ssid_filter);
LIST_INIT(&params->nlm_filter);
LIST_INIT(&params->wf_raw_part);
#else
if (can_drop_root())
{
params->uid = params->gid[0] = 0x7FFFFFFF; // default uid:gid
params->gid_count = 1;
params->droproot = true;
}
#endif
}

View File

@@ -6,6 +6,7 @@
#include "desync.h"
#include "protocol.h"
#include "helpers.h"
#include "sec.h"
#include <sys/param.h>
#include <sys/types.h>
@@ -91,6 +92,9 @@ struct desync_profile_list {
};
LIST_HEAD(desync_profile_list_head, desync_profile_list);
struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head);
void dp_list_move(struct desync_profile_list_head *target, struct desync_profile_list *dpl);
bool dp_list_copy(struct desync_profile *to, const struct desync_profile *from);
struct desync_profile_list *dp_list_search_name(struct desync_profile_list_head *head, const char *name);
void dp_entry_destroy(struct desync_profile_list *entry);
void dp_list_destroy(struct desync_profile_list_head *head);
bool dp_list_have_autohostlist(struct desync_profile_list_head *head);
@@ -121,7 +125,7 @@ struct params_s
bool bind_fix4,bind_fix6;
uint32_t desync_fwmark; // unused in BSD
struct desync_profile_list_head desync_profiles;
struct desync_profile_list_head desync_profiles, desync_templates;
#ifdef __CYGWIN__
struct str_list_head ssid_filter,nlm_filter;
@@ -172,6 +176,8 @@ struct params_s
extern struct params_s params;
extern const char *progname;
void init_params(struct params_s *params);
#if !defined( __OpenBSD__) && !defined(__ANDROID__)
void cleanup_args(struct params_s *params);
#endif

View File

@@ -155,20 +155,33 @@ bool strlist_add(struct str_list_head *head, const char *str)
LIST_INSERT_HEAD(head, entry, next);
return true;
}
static struct str_list *strlist_entry_copy(const struct str_list *entry)
{
return strlist_entry_alloc(entry->str);
}
bool strlist_copy(struct str_list_head *to, const struct str_list_head *from)
{
struct str_list *tail, *item, *entry;
LIST_TAIL(to, tail, item);
LIST_FOREACH(item, from, next)
{
if (!(entry = strlist_entry_copy(item))) return false;
LIST_INSERT_TAIL(to, tail, entry, next);
tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to);
}
return true;
}
bool strlist_add_tail(struct str_list_head *head, const char *str)
{
struct str_list *entry = strlist_entry_alloc(str);
if (!entry) return false;
// add to the tail
struct str_list *strn,*strl=LIST_FIRST(head);
if (strl)
{
while ((strn=LIST_NEXT(strl,next))) strl = strn;
LIST_INSERT_AFTER(strl, entry, next);
}
else
LIST_INSERT_HEAD(head, entry, next);
struct str_list *tail, *item;
LIST_TAIL(head, tail, item);
LIST_INSERT_TAIL(head, tail, entry, next);
return true;
}
static void strlist_entry_destroy(struct str_list *entry)
@@ -200,35 +213,77 @@ bool strlist_search(const struct str_list_head *head, const char *str)
}
static struct ptr_list *ptrlist_entry_alloc()
static void str2list_entry_destroy(struct str2_list *entry)
{
return (struct ptr_list*)calloc(1,sizeof(struct ptr_list));
free(entry->str1);
free(entry->str2);
free(entry);
}
void str2list_destroy(struct str2_list_head *head)
{
struct str2_list *entry;
while ((entry = LIST_FIRST(head)))
{
LIST_REMOVE(entry, next);
str2list_entry_destroy(entry);
}
}
static struct str2_list *str2list_entry_alloc()
{
return (struct str2_list*)calloc(1,sizeof(struct str2_list));
}
struct ptr_list *ptrlist_add(struct ptr_list_head *head)
struct str2_list *str2list_add(struct str2_list_head *head)
{
struct ptr_list *entry = ptrlist_entry_alloc();
struct str2_list *entry = str2list_entry_alloc();
if (!entry) return NULL;
LIST_INSERT_HEAD(head, entry, next);
return entry;
}
static void ptrlist_entry_destroy(struct ptr_list *entry)
static struct str2_list *str2list_entry_copy(const struct str2_list *entry)
{
free(entry->ptr1);
free(entry->ptr2);
struct str2_list *e2 = str2list_entry_alloc();
if (!e2) return NULL;
e2->str1 = strdup(entry->str1);
e2->str2 = strdup(entry->str2);
if (!e2->str1 || !e2->str2)
{
str2list_entry_destroy(e2);
return false;
}
return e2;
}
bool str2list_copy(struct str2_list_head *to, const struct str2_list_head *from)
{
struct str2_list *tail, *item, *entry;
LIST_TAIL(to, tail, item);
LIST_FOREACH(item, from, next)
{
if (!(entry = str2list_entry_copy(item))) return false;
LIST_INSERT_TAIL(to, tail, entry, next);
tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to);
}
return true;
}
static void funclist_entry_destroy(struct func_list *entry)
{
free(entry->func);
str2list_destroy(&entry->args);
free(entry);
}
void ptrlist_destroy(struct ptr_list_head *head)
void funclist_destroy(struct func_list_head *head)
{
struct ptr_list *entry;
struct func_list *entry;
while ((entry = LIST_FIRST(head)))
{
LIST_REMOVE(entry, next);
ptrlist_entry_destroy(entry);
funclist_entry_destroy(entry);
}
}
static struct func_list *funclist_entry_alloc(const char *func)
{
struct func_list *entry = malloc(sizeof(struct func_list));
@@ -250,31 +305,38 @@ struct func_list *funclist_add_tail(struct func_list_head *head, const char *fun
struct func_list *entry = funclist_entry_alloc(func);
if (!entry) return NULL;
// add to the tail
struct func_list *funcn,*funcl=LIST_FIRST(head);
if (funcl)
{
while ((funcn=LIST_NEXT(funcl,next))) funcl = funcn;
LIST_INSERT_AFTER(funcl, entry, next);
}
else
LIST_INSERT_HEAD(head, entry, next);
struct func_list *tail, *item;
LIST_TAIL(head, tail, item);
LIST_INSERT_TAIL(head, tail, entry, next);
return entry;
}
static void funclist_entry_destroy(struct func_list *entry)
static struct func_list *funclist_entry_copy(const struct func_list *entry)
{
free(entry->func);
ptrlist_destroy(&entry->args);
free(entry);
}
void funclist_destroy(struct func_list_head *head)
{
struct func_list *entry;
while ((entry = LIST_FIRST(head)))
struct func_list *e2 = funclist_entry_alloc(entry->func);
if (!e2) return NULL;
e2->payload_type = entry->payload_type;
e2->range_in = entry->range_in;
e2->range_out = entry->range_out;
if (!str2list_copy(&e2->args, &entry->args))
{
LIST_REMOVE(entry, next);
funclist_entry_destroy(entry);
funclist_entry_destroy(e2);
return false;
}
return e2;
}
bool funclist_copy(struct func_list_head *to, const struct func_list_head *from)
{
struct func_list *tail, *item, *entry;
LIST_TAIL(to, tail, item);
LIST_FOREACH(item, from, next)
{
if (!(entry = funclist_entry_copy(item))) return false;
LIST_INSERT_TAIL(to, tail, entry, next);
tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to);
}
return true;
}
@@ -333,16 +395,36 @@ void hostlist_files_reset_modtime(struct hostlist_files_head *list)
FILE_MOD_RESET(&hfile->mod_sig);
}
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
static struct hostlist_item *hostlist_collection_entry_alloc(struct hostlist_file *hfile)
{
struct hostlist_item *entry = malloc(sizeof(struct hostlist_item));
if (entry)
{
entry->hfile = hfile;
LIST_INSERT_HEAD(head, entry, next);
}
if (entry) entry->hfile = hfile;
return entry;
}
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
{
struct hostlist_item *entry = hostlist_collection_entry_alloc(hfile);
if (entry) LIST_INSERT_HEAD(head, entry, next);
return entry;
}
static struct hostlist_item *hostlist_collection_entry_copy(const struct hostlist_item *entry)
{
return hostlist_collection_entry_alloc(entry->hfile);
}
bool hostlist_collection_copy(struct hostlist_collection_head *to, const struct hostlist_collection_head *from)
{
struct hostlist_item *tail, *item, *entry;
LIST_TAIL(to, tail, item);
LIST_FOREACH(item, from, next)
{
if (!(entry = hostlist_collection_entry_copy(item))) return false;
LIST_INSERT_TAIL(to, tail, entry, next);
tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to);
}
return true;
}
void hostlist_collection_destroy(struct hostlist_collection_head *head)
{
struct hostlist_item *entry;
@@ -579,16 +661,36 @@ void ipset_files_reset_modtime(struct ipset_files_head *list)
FILE_MOD_RESET(&hfile->mod_sig);
}
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
static struct ipset_item *ipset_collection_entry_alloc(struct ipset_file *hfile)
{
struct ipset_item *entry = malloc(sizeof(struct ipset_item));
if (entry)
{
entry->hfile = hfile;
LIST_INSERT_HEAD(head, entry, next);
}
if (entry) entry->hfile = hfile;
return entry;
}
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
{
struct ipset_item *entry = ipset_collection_entry_alloc(hfile);
if (entry) LIST_INSERT_HEAD(head, entry, next);
return entry;
}
static struct ipset_item *ipset_collection_entry_copy(const struct ipset_item *entry)
{
return ipset_collection_entry_alloc(entry->hfile);
}
bool ipset_collection_copy(struct ipset_collection_head *to, const struct ipset_collection_head *from)
{
struct ipset_item *tail, *item, *entry;
LIST_TAIL(to, tail, item);
LIST_FOREACH(item, from, next)
{
if (!(entry = ipset_collection_entry_copy(item))) return false;
LIST_INSERT_TAIL(to, tail, entry, next);
tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to);
}
return true;
}
void ipset_collection_destroy(struct ipset_collection_head *head)
{
struct ipset_item *entry;
@@ -645,7 +747,7 @@ bool port_filters_in_range(const struct port_filters_head *head, uint16_t port)
{
const struct port_filter_item *item;
if (!LIST_FIRST(head)) return true;
if (LIST_EMPTY(head)) return true;
LIST_FOREACH(item, head, next)
{
if (pf_in_range(port, &item->pf))
@@ -656,7 +758,7 @@ bool port_filters_in_range(const struct port_filters_head *head, uint16_t port)
bool port_filters_deny_if_empty(struct port_filters_head *head)
{
port_filter pf;
if (LIST_FIRST(head)) return true;
if (!LIST_EMPTY(head)) return true;
return pf_parse("0",&pf) && port_filter_add(head,&pf);
}
@@ -667,15 +769,9 @@ struct blob_item *blob_collection_add(struct blob_collection_head *head)
struct blob_item *entry = calloc(1,sizeof(struct blob_item));
if (entry)
{
// insert to the end
struct blob_item *itemc,*iteml=LIST_FIRST(head);
if (iteml)
{
while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc;
LIST_INSERT_AFTER(iteml, entry, next);
}
else
LIST_INSERT_HEAD(head, entry, next);
struct blob_item *tail, *item;
LIST_TAIL(head, tail, item);
LIST_INSERT_TAIL(head, tail, entry, next);
}
return entry;
}
@@ -693,14 +789,9 @@ struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, co
entry->size_buf = size+size_reserve;
// insert to the end
struct blob_item *itemc,*iteml=LIST_FIRST(head);
if (iteml)
{
while ((itemc=LIST_NEXT(iteml,next))) iteml = itemc;
LIST_INSERT_AFTER(iteml, entry, next);
}
else
LIST_INSERT_HEAD(head, entry, next);
struct blob_item *tail, *item;
LIST_TAIL(head, tail, item);
LIST_INSERT_TAIL(head, tail, entry, next);
return entry;
}
@@ -725,7 +816,7 @@ void blob_collection_destroy(struct blob_collection_head *head)
}
bool blob_collection_empty(const struct blob_collection_head *head)
{
return !LIST_FIRST(head);
return LIST_EMPTY(head);
}
struct blob_item *blob_collection_search_name(struct blob_collection_head *head, const char *name)
{

View File

@@ -17,6 +17,17 @@
#define HOSTLIST_POOL_FLAG_STRICT_MATCH 1
#define LIST_TAIL(head, tail, temp) {\
tail=LIST_FIRST(head); \
if (tail) while ((temp=LIST_NEXT(tail,next))) tail = temp; }
#define LIST_INSERT_TAIL(head, tail, elm, field) { \
if (LIST_FIRST(head)) \
LIST_INSERT_AFTER(tail, elm, field); \
else \
LIST_INSERT_HEAD(head, elm, field); }
typedef struct hostlist_pool {
char *str; /* key */
uint32_t flags; /* custom data */
@@ -38,25 +49,28 @@ bool strlist_add(struct str_list_head *head, const char *str);
bool strlist_add_tail(struct str_list_head *head, const char *str);
void strlist_destroy(struct str_list_head *head);
bool strlist_search(const struct str_list_head *head, const char *str);
bool strlist_copy(struct str_list_head *to, const struct str_list_head *from);
struct ptr_list {
void *ptr1,*ptr2;
LIST_ENTRY(ptr_list) next;
struct str2_list {
char *str1,*str2;
LIST_ENTRY(str2_list) next;
};
LIST_HEAD(ptr_list_head, ptr_list);
LIST_HEAD(str2_list_head, str2_list);
struct ptr_list *ptrlist_add(struct ptr_list_head *head);
void ptrlist_destroy(struct ptr_list_head *head);
struct str2_list *str2list_add(struct str2_list_head *head);
bool str2list_copy(struct str2_list_head *to, const struct str2_list_head *from);
void str2list_destroy(struct str2_list_head *head);
struct func_list {
char *func;
uint64_t payload_type;
struct packet_range range_in, range_out;
struct ptr_list_head args;
struct str2_list_head args;
LIST_ENTRY(func_list) next;
};
LIST_HEAD(func_list_head, func_list);
struct func_list *funclist_add_tail(struct func_list_head *head, const char *func);
bool funclist_copy(struct func_list_head *to, const struct func_list_head *from);
void funclist_destroy(struct func_list_head *head);
@@ -96,6 +110,7 @@ struct hostlist_item {
LIST_HEAD(hostlist_collection_head, hostlist_item);
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile);
void hostlist_collection_destroy(struct hostlist_collection_head *head);
bool hostlist_collection_copy(struct hostlist_collection_head *to, const struct hostlist_collection_head *from);
struct hostlist_item *hostlist_collection_search(struct hostlist_collection_head *head, const char *filename);
bool hostlist_collection_is_empty(const struct hostlist_collection_head *head);
@@ -158,6 +173,7 @@ struct ipset_item {
};
LIST_HEAD(ipset_collection_head, ipset_item);
struct ipset_item * ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile);
bool ipset_collection_copy(struct ipset_collection_head *to, const struct ipset_collection_head *from);
void ipset_collection_destroy(struct ipset_collection_head *head);
struct ipset_item *ipset_collection_search(struct ipset_collection_head *head, const char *filename);
bool ipset_collection_is_empty(const struct ipset_collection_head *head);

View File

@@ -48,7 +48,7 @@ bool l7_proto_match(t_l7proto l7proto, uint64_t filter_l7)
static const char *l7payload_name[] = {
"all","unknown","empty","known","http_req","http_reply","tls_client_hello","tls_server_hello","quic_initial",
"wireguard_initiation","wireguard_response","wireguard_cookie","wireguard_keepalive","wireguard_data",
"dht","discord_ip_discovery","stun_binding_req",
"dht","discord_ip_discovery","stun",
"xmpp_stream", "xmpp_starttls", "xmpp_proceed", "xmpp_features",
"dns_query", "dns_response",
"mtproto_initial"};
@@ -1409,11 +1409,11 @@ bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len)
!memcmp(data+8,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",64);
// address is not set in request
}
bool IsStunBindingRequest(const uint8_t *data, size_t len)
bool IsStunMessage(const uint8_t *data, size_t len)
{
return len>=20 && // header size
data[0]==0 && data[1]==1 &&
(data[3]&0b11)==0 && // length must be a multiple of 4
(data[0]&0xC0)==0 && // 2 most significant bits must be zeroes
(data[3]&3)==0 && // length must be a multiple of 4
ntohl(*(uint32_t*)(&data[4]))==0x2112A442 && // magic cookie
ntohs(*(uint16_t*)(&data[2]))==len-20;
}

View File

@@ -42,7 +42,7 @@ typedef enum {
L7P_WIREGUARD_DATA,
L7P_DHT,
L7P_DISCORD_IP_DISCOVERY,
L7P_STUN_BINDING_REQ,
L7P_STUN,
L7P_XMPP_STREAM,
L7P_XMPP_STARTTLS,
L7P_XMPP_PROCEED,
@@ -153,7 +153,7 @@ bool IsWireguardKeepalive(const uint8_t *data, size_t len);
bool IsWireguardData(const uint8_t *data, size_t len);
bool IsDht(const uint8_t *data, size_t len);
bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len);
bool IsStunBindingRequest(const uint8_t *data, size_t len);
bool IsStunMessage(const uint8_t *data, size_t len);
bool IsMTProto(const uint8_t *data, size_t len);
#define QUIC_MAX_CID_LENGTH 20