nfqws,tpws: ^ prefix in hostlist disables subdomain matches

This commit is contained in:
bol-van 2025-03-06 15:11:43 +03:00
parent 307d38f6af
commit 1065202349
12 changed files with 148 additions and 88 deletions

View File

@ -347,7 +347,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
{ {
DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename); DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename);
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename); HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename);
if (!StrPoolAddStr(&dp->hostlist_auto->hostlist, hostname)) if (!HostlistPoolAddStr(&dp->hostlist_auto->hostlist, hostname, 0))
{ {
DLOG_ERR("StrPoolAddStr out of memory\n"); DLOG_ERR("StrPoolAddStr out of memory\n");
return; return;

View File

@ -4,7 +4,7 @@
#include "helpers.h" #include "helpers.h"
// inplace tolower() and add to pool // inplace tolower() and add to pool
static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct)
{ {
char *p=*s; char *p=*s;
@ -17,10 +17,16 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
else else
{ {
// advance until eol lowering all chars // advance until eol lowering all chars
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p); uint32_t flags = 0;
if (!StrPoolAddStrLen(hostlist, *s, p-*s)) if (*p=='^')
{ {
StrPoolDestroy(hostlist); p = ++(*s);
flags |= HOSTLIST_POOL_FLAG_STRICT_MATCH;
}
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
if (!HostlistPoolAddStrLen(hostlist, *s, p-*s, flags))
{
HostlistPoolDestroy(hostlist);
*hostlist = NULL; *hostlist = NULL;
return false; return false;
} }
@ -32,12 +38,12 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
return true; return true;
} }
bool AppendHostlistItem(strpool **hostlist, char *s) bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
{ {
return addpool(hostlist,&s,s+strlen(s),NULL); return addpool(hostlist,&s,s+strlen(s),NULL);
} }
bool AppendHostList(strpool **hostlist, const char *filename) bool AppendHostList(hostlist_pool **hostlist, const char *filename)
{ {
char *p, *e, s[256], *zbuf; char *p, *e, s[256], *zbuf;
size_t zsize; size_t zsize;
@ -114,10 +120,10 @@ static bool LoadHostList(struct hostlist_file *hfile)
return true; return true;
} }
if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date
StrPoolDestroy(&hfile->hostlist); HostlistPoolDestroy(&hfile->hostlist);
if (!AppendHostList(&hfile->hostlist, hfile->filename)) if (!AppendHostList(&hfile->hostlist, hfile->filename))
{ {
StrPoolDestroy(&hfile->hostlist); HostlistPoolDestroy(&hfile->hostlist);
return false; return false;
} }
hfile->mod_sig=fsig; hfile->mod_sig=fsig;
@ -138,10 +144,10 @@ static bool LoadHostLists(struct hostlist_files_head *list)
return bres; return bres;
} }
bool NonEmptyHostlist(strpool **hostlist) bool NonEmptyHostlist(hostlist_pool **hostlist)
{ {
// add impossible hostname if the list is empty // add impossible hostname if the list is empty
return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4); return *hostlist ? true : HostlistPoolAddStrLen(hostlist, "@&()", 4, 0);
} }
static void MakeAutolistsNonEmpty() static void MakeAutolistsNonEmpty()
@ -164,19 +170,34 @@ bool LoadAllHostLists()
static bool SearchHostList(strpool *hostlist, const char *host) static bool SearchHostList(hostlist_pool *hostlist, const char *host)
{ {
if (hostlist) if (hostlist)
{ {
const char *p = host; const char *p = host;
bool bInHostList; const struct hostlist_pool *hp;
bool bHostFull=true;
while (p) while (p)
{ {
bInHostList = StrPoolCheckStr(hostlist, p); DLOG("hostlist check for %s : ", p);
DLOG("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); hp = HostlistPoolGetStr(hostlist, p);
if (bInHostList) return true; if (hp)
{
if ((hp->flags & HOSTLIST_POOL_FLAG_STRICT_MATCH) && !bHostFull)
{
DLOG("negative : strict_mismatch : %s != %s\n", p, host);
}
else
{
DLOG("positive\n");
return true;
}
}
else
DLOG("negative\n");
p = strchr(p, '.'); p = strchr(p, '.');
if (p) p++; if (p) p++;
bHostFull = false;
} }
} }
return false; return false;

View File

@ -4,10 +4,10 @@
#include "pools.h" #include "pools.h"
#include "params.h" #include "params.h"
bool AppendHostlistItem(strpool **hostlist, char *s); bool AppendHostlistItem(hostlist_pool **hostlist, char *s);
bool AppendHostList(strpool **hostlist, const char *filename); bool AppendHostList(hostlist_pool **hostlist, const char *filename);
bool LoadAllHostLists(); bool LoadAllHostLists();
bool NonEmptyHostlist(strpool **hostlist); bool NonEmptyHostlist(hostlist_pool **hostlist);
// return : true = apply fooling, false = do not apply // return : true = apply fooling, false = do not apply
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck); bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);

View File

@ -901,7 +901,7 @@ static bool parse_split_pos_list(char *opt, struct proto_pos *splits, int splits
return true; return true;
} }
static bool parse_domain_list(char *opt, strpool **pp) static bool parse_domain_list(char *opt, hostlist_pool **pp)
{ {
char *e,*p,c; char *e,*p,c;

View File

@ -31,6 +31,9 @@
free(elem); \ free(elem); \
return false; \ return false; \
} }
#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
elem->flags = flg;
#undef uthash_nonfatal_oom #undef uthash_nonfatal_oom
@ -42,27 +45,31 @@ static void ut_oom_recover(void *elem)
} }
// for not zero terminated strings // for not zero terminated strings
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen) bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags)
{ {
ADD_STR_POOL(strpool, pp, s, slen) ADD_HOSTLIST_POOL(hostlist_pool, pp, s, slen, flags)
return true; return true;
} }
// for zero terminated strings // for zero terminated strings
bool StrPoolAddStr(strpool **pp, const char *s) bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags)
{ {
return StrPoolAddStrLen(pp, s, strlen(s)); return HostlistPoolAddStrLen(pp, s, strlen(s), flags);
} }
bool StrPoolCheckStr(strpool *p, const char *s) hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s)
{ {
strpool *elem; hostlist_pool *elem;
HASH_FIND_STR(p, s, elem); HASH_FIND_STR(p, s, elem);
return elem != NULL; return elem;
}
bool HostlistPoolCheckStr(hostlist_pool *p, const char *s)
{
return !!HostlistPoolGetStr(p,s);
} }
void StrPoolDestroy(strpool **pp) void HostlistPoolDestroy(hostlist_pool **pp)
{ {
DESTROY_STR_POOL(strpool, pp) DESTROY_STR_POOL(hostlist_pool, pp)
} }
@ -178,7 +185,7 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const
static void hostlist_files_entry_destroy(struct hostlist_file *entry) static void hostlist_files_entry_destroy(struct hostlist_file *entry)
{ {
free(entry->filename); free(entry->filename);
StrPoolDestroy(&entry->hostlist); HostlistPoolDestroy(&entry->hostlist);
free(entry); free(entry);
} }
void hostlist_files_destroy(struct hostlist_files_head *head) void hostlist_files_destroy(struct hostlist_files_head *head)

View File

@ -12,15 +12,18 @@
#define HASH_FUNCTION HASH_BER #define HASH_FUNCTION HASH_BER
#include "uthash.h" #include "uthash.h"
typedef struct strpool { #define HOSTLIST_POOL_FLAG_STRICT_MATCH 1
char *str; /* key */
UT_hash_handle hh; /* makes this structure hashable */
} strpool;
void StrPoolDestroy(strpool **pp); typedef struct hostlist_pool {
bool StrPoolAddStr(strpool **pp,const char *s); char *str; /* key */
bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); uint32_t flags; /* custom data */
bool StrPoolCheckStr(strpool *p,const char *s); UT_hash_handle hh; /* makes this structure hashable */
} hostlist_pool;
void HostlistPoolDestroy(hostlist_pool **pp);
bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags);
bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags);
hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s);
struct str_list { struct str_list {
char *str; char *str;
@ -51,7 +54,7 @@ void strlist_destroy(struct str_list_head *head);
struct hostlist_file { struct hostlist_file {
char *filename; char *filename;
file_mod_sig mod_sig; file_mod_sig mod_sig;
strpool *hostlist; hostlist_pool *hostlist;
LIST_ENTRY(hostlist_file) next; LIST_ENTRY(hostlist_file) next;
}; };
LIST_HEAD(hostlist_files_head, hostlist_file); LIST_HEAD(hostlist_files_head, hostlist_file);

View File

@ -4,7 +4,7 @@
#include "helpers.h" #include "helpers.h"
// inplace tolower() and add to pool // inplace tolower() and add to pool
static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct)
{ {
char *p=*s; char *p=*s;
@ -17,10 +17,16 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
else else
{ {
// advance until eol lowering all chars // advance until eol lowering all chars
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p); uint32_t flags = 0;
if (!StrPoolAddStrLen(hostlist, *s, p-*s)) if (*p=='^')
{ {
StrPoolDestroy(hostlist); p = ++(*s);
flags |= HOSTLIST_POOL_FLAG_STRICT_MATCH;
}
for (; p<end && *p && *p!='\r' && *p != '\n'; p++) *p=tolower(*p);
if (!HostlistPoolAddStrLen(hostlist, *s, p-*s, flags))
{
HostlistPoolDestroy(hostlist);
*hostlist = NULL; *hostlist = NULL;
return false; return false;
} }
@ -32,12 +38,12 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct)
return true; return true;
} }
bool AppendHostlistItem(strpool **hostlist, char *s) bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
{ {
return addpool(hostlist,&s,s+strlen(s),NULL); return addpool(hostlist,&s,s+strlen(s),NULL);
} }
bool AppendHostList(strpool **hostlist, const char *filename) bool AppendHostList(hostlist_pool **hostlist, const char *filename)
{ {
char *p, *e, s[256], *zbuf; char *p, *e, s[256], *zbuf;
size_t zsize; size_t zsize;
@ -114,10 +120,10 @@ static bool LoadHostList(struct hostlist_file *hfile)
return true; return true;
} }
if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date if (FILE_MOD_COMPARE(&hfile->mod_sig,&fsig)) return true; // up to date
StrPoolDestroy(&hfile->hostlist); HostlistPoolDestroy(&hfile->hostlist);
if (!AppendHostList(&hfile->hostlist, hfile->filename)) if (!AppendHostList(&hfile->hostlist, hfile->filename))
{ {
StrPoolDestroy(&hfile->hostlist); HostlistPoolDestroy(&hfile->hostlist);
return false; return false;
} }
hfile->mod_sig=fsig; hfile->mod_sig=fsig;
@ -138,10 +144,10 @@ static bool LoadHostLists(struct hostlist_files_head *list)
return bres; return bres;
} }
bool NonEmptyHostlist(strpool **hostlist) bool NonEmptyHostlist(hostlist_pool **hostlist)
{ {
// add impossible hostname if the list is empty // add impossible hostname if the list is empty
return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4); return *hostlist ? true : HostlistPoolAddStrLen(hostlist, "@&()", 4, 0);
} }
static void MakeAutolistsNonEmpty() static void MakeAutolistsNonEmpty()
@ -164,19 +170,34 @@ bool LoadAllHostLists()
static bool SearchHostList(strpool *hostlist, const char *host) static bool SearchHostList(hostlist_pool *hostlist, const char *host)
{ {
if (hostlist) if (hostlist)
{ {
const char *p = host; const char *p = host;
bool bInHostList; const struct hostlist_pool *hp;
bool bHostFull=true;
while (p) while (p)
{ {
bInHostList = StrPoolCheckStr(hostlist, p); VPRINT("hostlist check for %s : ", p);
VPRINT("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); hp = HostlistPoolGetStr(hostlist, p);
if (bInHostList) return true; if (hp)
{
if ((hp->flags & HOSTLIST_POOL_FLAG_STRICT_MATCH) && !bHostFull)
{
VPRINT("negative : strict_mismatch : %s != %s\n", p, host);
}
else
{
VPRINT("positive\n");
return true;
}
}
else
VPRINT("negative\n");
p = strchr(p, '.'); p = strchr(p, '.');
if (p) p++; if (p) p++;
bHostFull = false;
} }
} }
return false; return false;

View File

@ -4,10 +4,10 @@
#include "pools.h" #include "pools.h"
#include "params.h" #include "params.h"
bool AppendHostlistItem(strpool **hostlist, char *s); bool AppendHostlistItem(hostlist_pool **hostlist, char *s);
bool AppendHostList(strpool **hostlist, const char *filename); bool AppendHostList(hostlist_pool **hostlist, const char *filename);
bool LoadAllHostLists(); bool LoadAllHostLists();
bool NonEmptyHostlist(strpool **hostlist); bool NonEmptyHostlist(hostlist_pool **hostlist);
// return : true = apply fooling, false = do not apply // return : true = apply fooling, false = do not apply
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck); bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);

View File

@ -31,6 +31,9 @@
free(elem); \ free(elem); \
return false; \ return false; \
} }
#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \
ADD_STR_POOL(etype,ppool,keystr,keystr_len); \
elem->flags = flg;
#undef uthash_nonfatal_oom #undef uthash_nonfatal_oom
@ -42,27 +45,31 @@ static void ut_oom_recover(void *elem)
} }
// for not zero terminated strings // for not zero terminated strings
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen) bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags)
{ {
ADD_STR_POOL(strpool, pp, s, slen) ADD_HOSTLIST_POOL(hostlist_pool, pp, s, slen, flags)
return true; return true;
} }
// for zero terminated strings // for zero terminated strings
bool StrPoolAddStr(strpool **pp, const char *s) bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags)
{ {
return StrPoolAddStrLen(pp, s, strlen(s)); return HostlistPoolAddStrLen(pp, s, strlen(s), flags);
} }
bool StrPoolCheckStr(strpool *p, const char *s) hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s)
{ {
strpool *elem; hostlist_pool *elem;
HASH_FIND_STR(p, s, elem); HASH_FIND_STR(p, s, elem);
return elem != NULL; return elem;
}
bool HostlistPoolCheckStr(hostlist_pool *p, const char *s)
{
return !!HostlistPoolGetStr(p,s);
} }
void StrPoolDestroy(strpool **pp) void HostlistPoolDestroy(hostlist_pool **pp)
{ {
DESTROY_STR_POOL(strpool, pp) DESTROY_STR_POOL(hostlist_pool, pp)
} }
@ -178,7 +185,7 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const
static void hostlist_files_entry_destroy(struct hostlist_file *entry) static void hostlist_files_entry_destroy(struct hostlist_file *entry)
{ {
free(entry->filename); free(entry->filename);
StrPoolDestroy(&entry->hostlist); HostlistPoolDestroy(&entry->hostlist);
free(entry); free(entry);
} }
void hostlist_files_destroy(struct hostlist_files_head *head) void hostlist_files_destroy(struct hostlist_files_head *head)

View File

@ -12,15 +12,18 @@
#define HASH_FUNCTION HASH_BER #define HASH_FUNCTION HASH_BER
#include "uthash.h" #include "uthash.h"
typedef struct strpool { #define HOSTLIST_POOL_FLAG_STRICT_MATCH 1
char *str; /* key */
UT_hash_handle hh; /* makes this structure hashable */
} strpool;
void StrPoolDestroy(strpool **pp); typedef struct hostlist_pool {
bool StrPoolAddStr(strpool **pp,const char *s); char *str; /* key */
bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); uint32_t flags; /* custom data */
bool StrPoolCheckStr(strpool *p,const char *s); UT_hash_handle hh; /* makes this structure hashable */
} hostlist_pool;
void HostlistPoolDestroy(hostlist_pool **pp);
bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags);
bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags);
hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s);
struct str_list { struct str_list {
char *str; char *str;
@ -51,7 +54,7 @@ void strlist_destroy(struct str_list_head *head);
struct hostlist_file { struct hostlist_file {
char *filename; char *filename;
file_mod_sig mod_sig; file_mod_sig mod_sig;
strpool *hostlist; hostlist_pool *hostlist;
LIST_ENTRY(hostlist_file) next; LIST_ENTRY(hostlist_file) next;
}; };
LIST_HEAD(hostlist_files_head, hostlist_file); LIST_HEAD(hostlist_files_head, hostlist_file);

View File

@ -433,7 +433,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
{ {
VPRINT("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename); VPRINT("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename);
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename); HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename);
if (!StrPoolAddStr(&dp->hostlist_auto->hostlist, hostname)) if (!HostlistPoolAddStr(&dp->hostlist_auto->hostlist, hostname, 0))
{ {
DLOG_ERR("StrPoolAddStr out of memory\n"); DLOG_ERR("StrPoolAddStr out of memory\n");
return; return;

View File

@ -121,7 +121,6 @@ static bool test_list_files()
struct hostlist_file *hfile; struct hostlist_file *hfile;
struct ipset_file *ifile; struct ipset_file *ifile;
printf("1\n");
LIST_FOREACH(hfile, &params.hostlists, next) LIST_FOREACH(hfile, &params.hostlists, next)
if (hfile->filename && !file_open_test(hfile->filename, O_RDONLY)) if (hfile->filename && !file_open_test(hfile->filename, O_RDONLY))
{ {
@ -136,7 +135,6 @@ printf("1\n");
DLOG_ERR("cannot access ipset file '%s'\n",ifile->filename); DLOG_ERR("cannot access ipset file '%s'\n",ifile->filename);
return false; return false;
} }
printf("2\n");
return true; return true;
} }
@ -535,7 +533,7 @@ static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
return true; return true;
} }
static bool parse_domain_list(char *opt, strpool **pp) static bool parse_domain_list(char *opt, hostlist_pool **pp)
{ {
char *e,*p,c; char *e,*p,c;