mirror of
https://github.com/pi-hole/FTL.git
synced 2024-10-26 16:52:18 +02:00
Add shared per-client regex array. This ensures TCP and UDP workers know the same details about client/regex combinations. This commit also fixes an issue with regex group associations for configured clients that have no assigned group.
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
+33
-49
@@ -20,8 +20,9 @@
|
||||
#include "database/gravity-db.h"
|
||||
// bool startup
|
||||
#include "main.h"
|
||||
// add_per_client_regex_client()
|
||||
#include "shmem.h"
|
||||
|
||||
static int num_regex[2] = { 0 };
|
||||
static regex_t *regex[2] = { NULL };
|
||||
static bool *regex_available[2] = { NULL };
|
||||
static int *regex_id[2] = { NULL };
|
||||
@@ -63,19 +64,13 @@ static bool compile_regex(const char *regexin, const int index, const unsigned c
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_regex(const char *input, const clientsData *client, const unsigned char regexid)
|
||||
bool match_regex(const char *input, const int clientID, const unsigned char regexid)
|
||||
{
|
||||
bool matched = false;
|
||||
|
||||
if(client->regex_enabled[regexid] == NULL)
|
||||
{
|
||||
logg("Regex list %d for client not configured!", regexid);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start matching timer
|
||||
timer_start(REGEX_TIMER);
|
||||
for(int index = 0; index < num_regex[regexid]; index++)
|
||||
for(int index = 0; index < counters->num_regex[regexid]; index++)
|
||||
{
|
||||
// Only check regex which have been successfully compiled ...
|
||||
if(!regex_available[regexid][index])
|
||||
@@ -86,7 +81,11 @@ bool match_regex(const char *input, const clientsData *client, const unsigned ch
|
||||
continue;
|
||||
}
|
||||
// ... and are enabled for this client
|
||||
if(!client->regex_enabled[regexid][index])
|
||||
int regexID = index;
|
||||
if(regexid == REGEX_WHITELIST)
|
||||
regexID += counters->num_regex[REGEX_BLACKLIST];
|
||||
|
||||
if(!get_per_client_regex(clientID, regexID))
|
||||
{
|
||||
if(config.debug & DEBUG_REGEX)
|
||||
logg("Regex %s ID %d not enabled for this client", regextype[regexid], index);
|
||||
@@ -131,30 +130,15 @@ static void free_regex(void)
|
||||
return;
|
||||
|
||||
// Reset client configuration
|
||||
for(int i = 0; i < counters->clients; i++)
|
||||
for(int clientID = 0; clientID < counters->clients; clientID++)
|
||||
{
|
||||
// Get client pointer
|
||||
clientsData *client = getClient(i, true);
|
||||
if(client == NULL)
|
||||
continue;
|
||||
|
||||
if(client->regex_enabled[REGEX_WHITELIST] != NULL)
|
||||
{
|
||||
free(client->regex_enabled[REGEX_WHITELIST]);
|
||||
client->regex_enabled[REGEX_WHITELIST] = NULL;
|
||||
}
|
||||
|
||||
if(client->regex_enabled[REGEX_BLACKLIST] != NULL)
|
||||
{
|
||||
free(client->regex_enabled[REGEX_BLACKLIST]);
|
||||
client->regex_enabled[REGEX_BLACKLIST] = NULL;
|
||||
}
|
||||
reset_per_client_regex(clientID);
|
||||
}
|
||||
|
||||
// Free regex datastructure
|
||||
for(int regexid = 0; regexid < 2; regexid++)
|
||||
{
|
||||
for(int index = 0; index < num_regex[regexid]; index++)
|
||||
for(int index = 0; index < counters->num_regex[regexid]; index++)
|
||||
{
|
||||
if(!regex_available[regexid][index])
|
||||
continue;
|
||||
@@ -177,24 +161,23 @@ static void free_regex(void)
|
||||
}
|
||||
|
||||
// Reset counter for number of regex
|
||||
num_regex[regexid] = 0;
|
||||
counters->num_regex[regexid] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void allocate_regex_client_enabled(clientsData *client)
|
||||
void allocate_regex_client_enabled(clientsData *client, const int clientID)
|
||||
{
|
||||
client->regex_enabled[REGEX_BLACKLIST] = calloc(num_regex[REGEX_BLACKLIST], sizeof(bool));
|
||||
client->regex_enabled[REGEX_WHITELIST] = calloc(num_regex[REGEX_WHITELIST], sizeof(bool));
|
||||
add_per_client_regex(clientID);
|
||||
|
||||
// Only initialize regex associations when dnsmasq is ready (otherwise, we're still in history reading mode)
|
||||
if(!startup)
|
||||
{
|
||||
gravityDB_get_regex_client_groups(client, num_regex[REGEX_BLACKLIST],
|
||||
gravityDB_get_regex_client_groups(client, counters->num_regex[REGEX_BLACKLIST],
|
||||
regex_id[REGEX_BLACKLIST], REGEX_BLACKLIST,
|
||||
"vw_regex_blacklist");
|
||||
gravityDB_get_regex_client_groups(client, num_regex[REGEX_WHITELIST],
|
||||
"vw_regex_blacklist", clientID);
|
||||
gravityDB_get_regex_client_groups(client, counters->num_regex[REGEX_WHITELIST],
|
||||
regex_id[REGEX_WHITELIST], REGEX_WHITELIST,
|
||||
"vw_regex_whitelist");
|
||||
"vw_regex_whitelist", clientID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,28 +187,28 @@ static void read_regex_table(const unsigned char regexid)
|
||||
unsigned char databaseID = (regexid == REGEX_BLACKLIST) ? REGEX_BLACKLIST_TABLE : REGEX_WHITELIST_TABLE;
|
||||
|
||||
// Get number of lines in the regex table
|
||||
num_regex[regexid] = gravityDB_count(databaseID);
|
||||
counters->num_regex[regexid] = gravityDB_count(databaseID);
|
||||
|
||||
if(num_regex[regexid] == 0)
|
||||
if(counters->num_regex[regexid] == 0)
|
||||
{
|
||||
logg("INFO: No regex %s entries found", regextype[regexid]);
|
||||
return;
|
||||
}
|
||||
else if(num_regex[regexid] == DB_FAILED)
|
||||
else if(counters->num_regex[regexid] == DB_FAILED)
|
||||
{
|
||||
logg("WARN: Database query failed, assuming there are no regex %s entries", regextype[regexid]);
|
||||
num_regex[regexid] = 0;
|
||||
counters->num_regex[regexid] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate memory for regex
|
||||
regex[regexid] = calloc(num_regex[regexid], sizeof(regex_t));
|
||||
regex_id[regexid] = calloc(num_regex[regexid], sizeof(int));
|
||||
regex_available[regexid] = calloc(num_regex[regexid], sizeof(bool));
|
||||
regex[regexid] = calloc(counters->num_regex[regexid], sizeof(regex_t));
|
||||
regex_id[regexid] = calloc(counters->num_regex[regexid], sizeof(int));
|
||||
regex_available[regexid] = calloc(counters->num_regex[regexid], sizeof(bool));
|
||||
|
||||
// Buffer strings if in regex debug mode
|
||||
if(config.debug & DEBUG_REGEX)
|
||||
regexbuffer[regexid] = calloc(num_regex[regexid], sizeof(char*));
|
||||
regexbuffer[regexid] = calloc(counters->num_regex[regexid], sizeof(char*));
|
||||
|
||||
// Connect to regex table
|
||||
if(!gravityDB_getTable(databaseID))
|
||||
@@ -241,7 +224,7 @@ static void read_regex_table(const unsigned char regexid)
|
||||
{
|
||||
// Avoid buffer overflow if database table changed
|
||||
// since we counted its entries
|
||||
if(i >= num_regex[regexid])
|
||||
if(i >= counters->num_regex[regexid])
|
||||
break;
|
||||
|
||||
// Skip this entry if empty: an empty regex filter would match
|
||||
@@ -282,17 +265,18 @@ void read_regex_from_database(void)
|
||||
read_regex_table(REGEX_WHITELIST);
|
||||
|
||||
|
||||
for(int i = 0; i < counters->clients; i++)
|
||||
for(int clientID = 0; clientID < counters->clients; clientID++)
|
||||
{
|
||||
// Get client pointer
|
||||
clientsData *client = getClient(i, true);
|
||||
clientsData *client = getClient(clientID, true);
|
||||
if(client == NULL)
|
||||
continue;
|
||||
|
||||
allocate_regex_client_enabled(client);
|
||||
allocate_regex_client_enabled(client, clientID);
|
||||
}
|
||||
|
||||
// Print message to FTL's log after reloading regex filters
|
||||
logg("Compiled %i whitelist and %i blacklist regex filters in %.1f msec",
|
||||
num_regex[REGEX_WHITELIST], num_regex[REGEX_BLACKLIST], timer_elapsed_msec(REGEX_TIMER));
|
||||
counters->num_regex[REGEX_WHITELIST], counters->num_regex[REGEX_BLACKLIST],
|
||||
timer_elapsed_msec(REGEX_TIMER));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user