diff --git a/FTL.h b/FTL.h index aea76584..076a86df 100644 --- a/FTL.h +++ b/FTL.h @@ -206,8 +206,8 @@ typedef struct { } memoryStruct; // Prepare timers, used mainly for debugging purposes -#define NUMTIMERS 4 -enum { DATABASE_WRITE_TIMER, EXIT_TIMER, GC_TIMER, LISTS_TIMER }; +#define NUMTIMERS 5 +enum { DATABASE_WRITE_TIMER, EXIT_TIMER, GC_TIMER, LISTS_TIMER, REGEX_TIMER }; enum { QUERIES, FORWARDED, CLIENTS, DOMAINS, OVERTIME, WILDCARD }; enum { DNSSEC_UNSPECIFIED, DNSSEC_SECURE, DNSSEC_INSECURE, DNSSEC_BOGUS, DNSSEC_ABANDONED, DNSSEC_UNKNOWN }; diff --git a/config.c b/config.c index caf40e5a..c9f072fc 100644 --- a/config.c +++ b/config.c @@ -211,7 +211,7 @@ void read_FTLconf(void) // defaults to: (not set) buffer = parse_FTLconf(fp, "BLOCKINGREGEX"); config.blockingregex = false; - if(buffer != NULL && strlen(buffer) > 0 && init_regex(buffer)) + if(buffer != NULL && strlen(buffer) > 0 && init_regex(buffer,0)) config.blockingregex = true; if(config.blockingregex) diff --git a/regex.c b/regex.c index f44ab1cd..5d800922 100644 --- a/regex.c +++ b/regex.c @@ -10,57 +10,74 @@ #include "FTL.h" #include -static regex_t regex; -static void log_regex_error(char *where, int errcode) +#define NUM_REGEX 1 +static regex_t regex[NUM_REGEX]; + +static void log_regex_error(char *where, int errcode, int index) { // Regex failed for some reason (probably user syntax error) // Get error string and log it - size_t length = regerror(errcode, ®ex, NULL, 0); + size_t length = regerror(errcode, ®ex[index], NULL, 0); char *buffer = calloc(length,sizeof(char)); - (void) regerror (errcode, ®ex, buffer, length); - logg("Error when %s blocking RegEx: %s (%i)", where, buffer, errcode); + (void) regerror (errcode, ®ex[index], buffer, length); + logg("ERROR %s regex %i: %s (%i)", index, where, buffer, errcode); free(buffer); free_regex(); } -bool init_regex(char *regexin) +bool init_regex(char *regexin, int index) { - // compile a regular expression into a data structure that + // compile regular expressions into data structures that // can be used with regexec to match against a string - int errcode = regcomp(®ex, regexin, REG_EXTENDED); - if(errcode == 0) + if(index > NUM_REGEX) { - return true; + logg("ERROR: Increase NUM_REGEX"); + return false; } - - // else: failed - log_regex_error("compiling", errcode); - return false; + int errcode = regcomp(®ex[index], regexin, REG_EXTENDED); + if(errcode != 0) + { + log_regex_error("compiling", errcode, index); + return false; + } + // If we reach this point, then no regex compilation failed + return true; } bool match_regex(char *input) { // Try to match the compiled regular expression against input - int errcode = regexec(®ex, input, 0, NULL, 0); - if (errcode == 0) - { - // Match, return true - return true; - } - else if (errcode != REG_NOMATCH) - { - // Error, return false afterwards - log_regex_error("matching", errcode); - } + int index; + bool matched = false; + timer_start(REGEX_TIMER); + for(index = 0; index < NUM_REGEX; index++) + { + int errcode = regexec(®ex[index], input, 0, NULL, 0); + if (errcode == 0) + { + // Match, return true + matched = true; + break; + } + else if (errcode != REG_NOMATCH) + { + // Error, return false afterwards + log_regex_error("matching", errcode, index); + break; + } + } + logg("Regex evaluation took %.3f msec", timer_elapsed_msec(REGEX_TIMER)); // No match, no error, return false - return false; + return matched; } void free_regex(void) { // Disable blocking regex checking config.blockingregex = false; - regfree(®ex); + int index; + for(index = 0; index < NUM_REGEX; index++) + regfree(®ex[index]); } diff --git a/routines.h b/routines.h index eb49edb2..df954910 100644 --- a/routines.h +++ b/routines.h @@ -106,6 +106,6 @@ void resolveNewClients(void); void reresolveHostnames(void); // regex.c -bool init_regex(char *regexin); +bool init_regex(char *regexin, int index); bool match_regex(char *input); void free_regex(void);