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:
DL6ER
2019-12-30 17:13:57 +00:00
parent c9c7c27888
commit 4c74a29f87
11 changed files with 184 additions and 72 deletions
+33 -49
View File
@@ -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));
}