conf: speed up parsing 10x by using ragel if available
conf_regex.rl is generated from the output of conf_regex_print.c using re2r (https://github.com/rofl0r/re2r). if ragel is available on the build host, it is being used to generate finite state machines from the regexes used by the config file parser for an impressive speed boost, while only adding moderately to binary size. a stripped x86_64 tinyproxy binary compiled with -O2 is still only ~100KB.
This commit is contained in:
parent
3a920b7163
commit
417c258d14
10
configure.ac
10
configure.ac
@ -213,6 +213,16 @@ if test "x$GPERF" != "x" -a "x$GPERF" != "xno" ; then
|
|||||||
AC_DEFINE(HAVE_GPERF)
|
AC_DEFINE(HAVE_GPERF)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_PATH_PROG(RAGEL, ragel, no)
|
||||||
|
AM_CONDITIONAL(HAVE_RAGEL, test "x$RAGEL" != "x" -a "x$RAGEL" != "xno")
|
||||||
|
AH_TEMPLATE([HAVE_RAGEL],
|
||||||
|
[Whether you have ragel installed for faster config parsing.])
|
||||||
|
|
||||||
|
if test "x$RAGEL" != "x" -a "x$RAGEL" != "xno" ; then
|
||||||
|
AC_DEFINE(HAVE_RAGEL)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
@ -60,11 +60,22 @@ EXTRA_tinyproxy_SOURCES = filter.c filter.h \
|
|||||||
tinyproxy_DEPENDENCIES = @ADDITIONAL_OBJECTS@
|
tinyproxy_DEPENDENCIES = @ADDITIONAL_OBJECTS@
|
||||||
tinyproxy_LDADD = @ADDITIONAL_OBJECTS@ -lpthread
|
tinyproxy_LDADD = @ADDITIONAL_OBJECTS@ -lpthread
|
||||||
|
|
||||||
|
CLEANFILES =
|
||||||
|
|
||||||
if HAVE_GPERF
|
if HAVE_GPERF
|
||||||
conf-tokens.c: conf-tokens-gperf.inc
|
conf-tokens.c: conf-tokens-gperf.inc
|
||||||
conf-tokens-gperf.inc: conf-tokens.gperf
|
conf-tokens-gperf.inc: conf-tokens.gperf
|
||||||
$(GPERF) $< > $@
|
$(GPERF) $< > $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DIST = conf-tokens.gperf
|
if HAVE_RAGEL
|
||||||
|
conf.c: conf_regex.inc
|
||||||
|
conf_regex.inc: conf_regex.rl
|
||||||
|
$(RAGEL) $(RAGEL_FLAGS) -o $@ $<
|
||||||
|
|
||||||
|
CLEANFILES += conf_regex.inc
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
EXTRA_DIST = conf-tokens.gperf conf_regex.rl
|
||||||
|
|
||||||
|
32
src/conf.c
32
src/conf.c
@ -142,7 +142,14 @@ static void config_free_regex (void);
|
|||||||
* do not follow the pattern above. This macro is for convenience
|
* do not follow the pattern above. This macro is for convenience
|
||||||
* only.
|
* only.
|
||||||
*/
|
*/
|
||||||
#define STDCONF(d, re, func) [CD_ ## d] = { BEGIN re END, func, NULL }
|
#ifdef HAVE_RAGEL
|
||||||
|
#define RE2R_EXPORT static
|
||||||
|
#include "conf_regex.inc"
|
||||||
|
typedef int (*matchfunc)(const char*, const char*, size_t, regmatch_t[]);
|
||||||
|
#define STDCONF(d, re, func) [CD_ ## d] = { func, re2r_match_ ## d }
|
||||||
|
#else
|
||||||
|
#define STDCONF(d, re, func) [CD_ ## d] = { func, BEGIN re END, NULL }
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Holds the regular expression used to match the configuration directive,
|
* Holds the regular expression used to match the configuration directive,
|
||||||
@ -151,9 +158,13 @@ static void config_free_regex (void);
|
|||||||
* to be compiled one.
|
* to be compiled one.
|
||||||
*/
|
*/
|
||||||
struct {
|
struct {
|
||||||
const char *re;
|
|
||||||
CONFFILE_HANDLER handler;
|
CONFFILE_HANDLER handler;
|
||||||
|
#ifndef HAVE_RAGEL
|
||||||
|
const char *re;
|
||||||
regex_t *cre;
|
regex_t *cre;
|
||||||
|
#else
|
||||||
|
matchfunc mf;
|
||||||
|
#endif
|
||||||
} directives[] = {
|
} directives[] = {
|
||||||
#include "conf_regex.h"
|
#include "conf_regex.h"
|
||||||
};
|
};
|
||||||
@ -248,6 +259,8 @@ config_init (void)
|
|||||||
{
|
{
|
||||||
unsigned int i, r;
|
unsigned int i, r;
|
||||||
|
|
||||||
|
(void) r;
|
||||||
|
|
||||||
for (i = 0; i != ndirectives; ++i) {
|
for (i = 0; i != ndirectives; ++i) {
|
||||||
|
|
||||||
if (!directives[i].handler) {
|
if (!directives[i].handler) {
|
||||||
@ -255,6 +268,7 @@ config_init (void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_RAGEL
|
||||||
directives[i].cre = (regex_t *) safemalloc (sizeof (regex_t));
|
directives[i].cre = (regex_t *) safemalloc (sizeof (regex_t));
|
||||||
if (!directives[i].cre)
|
if (!directives[i].cre)
|
||||||
return -1;
|
return -1;
|
||||||
@ -264,6 +278,7 @@ config_init (void)
|
|||||||
REG_EXTENDED | REG_NEWLINE);
|
REG_EXTENDED | REG_NEWLINE);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
atexit (config_free_regex);
|
atexit (config_free_regex);
|
||||||
@ -278,6 +293,7 @@ config_init (void)
|
|||||||
static void
|
static void
|
||||||
config_free_regex (void)
|
config_free_regex (void)
|
||||||
{
|
{
|
||||||
|
#ifndef HAVE_RAGEL
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < ndirectives; i++) {
|
for (i = 0; i < ndirectives; i++) {
|
||||||
@ -287,6 +303,7 @@ config_free_regex (void)
|
|||||||
directives[i].cre = NULL;
|
directives[i].cre = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -297,18 +314,25 @@ config_free_regex (void)
|
|||||||
* Returns 0 if a match was found and successfully processed; otherwise,
|
* Returns 0 if a match was found and successfully processed; otherwise,
|
||||||
* a negative number is returned.
|
* a negative number is returned.
|
||||||
*/
|
*/
|
||||||
static int check_match (struct config_s *conf, const char *line,
|
static int check_match (struct config_s *conf,
|
||||||
|
const char *line, const char* lineend,
|
||||||
unsigned long lineno, enum config_directive cd)
|
unsigned long lineno, enum config_directive cd)
|
||||||
{
|
{
|
||||||
regmatch_t match[RE_MAX_MATCHES];
|
regmatch_t match[RE_MAX_MATCHES];
|
||||||
unsigned int i = cd;
|
unsigned int i = cd;
|
||||||
|
|
||||||
|
#ifndef HAVE_RAGEL
|
||||||
|
(void) lineend;
|
||||||
if (!directives[i].cre)
|
if (!directives[i].cre)
|
||||||
return (*directives[i].handler) (conf, line, lineno, match);
|
return (*directives[i].handler) (conf, line, lineno, match);
|
||||||
|
|
||||||
if (!regexec
|
if (!regexec
|
||||||
(directives[i].cre, line, RE_MAX_MATCHES, match, 0))
|
(directives[i].cre, line, RE_MAX_MATCHES, match, 0))
|
||||||
return (*directives[i].handler) (conf, line, lineno, match);
|
return (*directives[i].handler) (conf, line, lineno, match);
|
||||||
|
#else
|
||||||
|
if (!directives[i].mf(line, lineend, RE_MAX_MATCHES, match))
|
||||||
|
return (*directives[i].handler) (conf, line, lineno, match);
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +359,7 @@ static int config_parse (struct config_s *conf, FILE * f)
|
|||||||
p = q;
|
p = q;
|
||||||
while(*p && *p != '\n') ++p;
|
while(*p && *p != '\n') ++p;
|
||||||
while(isspace(*p)) *(p--) = 0;
|
while(isspace(*p)) *(p--) = 0;
|
||||||
if (!e || e->value == CD_NIL || check_match (conf, q, lineno, e->value)) {
|
if (!e || e->value == CD_NIL || check_match (conf, q, ++p, lineno, e->value)) {
|
||||||
fprintf (stderr, "ERROR: Syntax error on line %lu\n", lineno);
|
fprintf (stderr, "ERROR: Syntax error on line %lu\n", lineno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
512
src/conf_regex.rl
Normal file
512
src/conf_regex.rl
Normal file
@ -0,0 +1,512 @@
|
|||||||
|
/* automatically generated with re2r by rofl0r */
|
||||||
|
%%{
|
||||||
|
machine logfile;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
main := '"'([^"]+) >A1 %E1 '"' ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_logfile(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_pidfile(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_anonymous(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_viaproxyname(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_defaulterrorfile(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_statfile(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_stathost(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine xtinyproxy;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
main := ([Yy][Ee][Ss]|[Oo][Nn]|[Nn][Oo]|[Oo][Ff][Ff]) >A1 %E1 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_xtinyproxy(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_syslog(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_bindsame(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_disableviaheader(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine port;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
main := ([0-9]+) >A1 %E1 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_port(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_maxclients(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_maxspareservers(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_minspareservers(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_startservers(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_maxrequestsperchild(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_timeout(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_connectport(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_port(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine user;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
main := (('-'|[A-Za-z0-9._])+) >A1 %E1 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_user(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_group(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_user(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine listen;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action A3 { matches[3].rm_so = p-start; }
|
||||||
|
action A4 { matches[4].rm_so = p-start; }
|
||||||
|
action A5 { matches[5].rm_so = p-start; }
|
||||||
|
action A6 { matches[6].rm_so = p-start; }
|
||||||
|
action A7 { matches[7].rm_so = p-start; }
|
||||||
|
action A8 { matches[8].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
action E3 { matches[3].rm_eo = p-start; }
|
||||||
|
action E4 { matches[4].rm_eo = p-start; }
|
||||||
|
action E5 { matches[5].rm_eo = p-start; }
|
||||||
|
action E6 { matches[6].rm_eo = p-start; }
|
||||||
|
action E7 { matches[7].rm_eo = p-start; }
|
||||||
|
action E8 { matches[8].rm_eo = p-start; }
|
||||||
|
main := (([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+) >A2 %E2 |((([0-9a-fA-F:]{2,39}) >A5 %E5 ) >A4 %E4 |(([0-9a-fA-F:]{0,29} ":" ([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+) >A8 %E8 ) >A7 %E7 ) >A6 %E6 ) >A3 %E3 ) >A1 %E1 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_listen(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=1,[3]=1,[4]=3,[5]=4,[6]=3,[7]=6,[8]=7,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine allow;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action A3 { matches[3].rm_so = p-start; }
|
||||||
|
action A4 { matches[4].rm_so = p-start; }
|
||||||
|
action A5 { matches[5].rm_so = p-start; }
|
||||||
|
action A6 { matches[6].rm_so = p-start; }
|
||||||
|
action A7 { matches[7].rm_so = p-start; }
|
||||||
|
action A8 { matches[8].rm_so = p-start; }
|
||||||
|
action A9 { matches[9].rm_so = p-start; }
|
||||||
|
action A10 { matches[10].rm_so = p-start; }
|
||||||
|
action A11 { matches[11].rm_so = p-start; }
|
||||||
|
action A12 { matches[12].rm_so = p-start; }
|
||||||
|
action A13 { matches[13].rm_so = p-start; }
|
||||||
|
action A14 { matches[14].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
action E3 { matches[3].rm_eo = p-start; }
|
||||||
|
action E4 { matches[4].rm_eo = p-start; }
|
||||||
|
action E5 { matches[5].rm_eo = p-start; }
|
||||||
|
action E6 { matches[6].rm_eo = p-start; }
|
||||||
|
action E7 { matches[7].rm_eo = p-start; }
|
||||||
|
action E8 { matches[8].rm_eo = p-start; }
|
||||||
|
action E9 { matches[9].rm_eo = p-start; }
|
||||||
|
action E10 { matches[10].rm_eo = p-start; }
|
||||||
|
action E11 { matches[11].rm_eo = p-start; }
|
||||||
|
action E12 { matches[12].rm_eo = p-start; }
|
||||||
|
action E13 { matches[13].rm_eo = p-start; }
|
||||||
|
action E14 { matches[14].rm_eo = p-start; }
|
||||||
|
main := (((([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+) >A4 %E4 ( "/" [0-9]+)? >A5 %E5 ) >A3 %E3 |(((([0-9a-fA-F:]{2,39}) >A9 %E9 ) >A8 %E8 |(([0-9a-fA-F:]{0,29} ":" ([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+) >A12 %E12 ) >A11 %E11 ) >A10 %E10 ) >A7 %E7 ( "/" [0-9]+)? >A13 %E13 ) >A6 %E6 ) >A2 %E2 |(('-'|[A-Za-z0-9._])+) >A14 %E14 ) >A1 %E1 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_allow(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=1,[3]=2,[4]=3,[5]=3,[6]=2,[7]=6,[8]=7,[9]=8,[10]=7,[11]=10,[12]=11,[13]=6,[14]=1,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_deny(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_allow(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_bind(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_listen(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine basicauth;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
main := (('-'|[A-Za-z0-9._])+) >A1 %E1 [ \t]+(('-'|[A-Za-z0-9._])+) >A2 %E2 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_basicauth(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine errorfile;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
main := ([0-9]+) >A1 %E1 [ \t]+'"'([^"]+) >A2 %E2 '"' ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_errorfile(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine addheader;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
main := '"'([^"]+) >A1 %E1 '"'[ \t]+'"'([^"]+) >A2 %E2 '"' ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_addheader(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_filter(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_filterurls(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_filterextended(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_filterdefaultdeny(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_filtercasesensitive(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_reversebaseurl(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_logfile(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_reverseonly(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_reversemagic(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
return re2r_match_xtinyproxy(p, pe, nmatch, matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine reversepath;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action A3 { matches[3].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
action E3 { matches[3].rm_eo = p-start; }
|
||||||
|
main := '"'([^"]+) >A1 %E1 '"'([ \t]+'"'([^"]+) >A3 %E3 '"')? >A2 %E2 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_reversepath(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=0,[3]=2,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine upstream;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action A2 { matches[2].rm_so = p-start; }
|
||||||
|
action A3 { matches[3].rm_so = p-start; }
|
||||||
|
action A4 { matches[4].rm_so = p-start; }
|
||||||
|
action A5 { matches[5].rm_so = p-start; }
|
||||||
|
action A6 { matches[6].rm_so = p-start; }
|
||||||
|
action A7 { matches[7].rm_so = p-start; }
|
||||||
|
action A8 { matches[8].rm_so = p-start; }
|
||||||
|
action A9 { matches[9].rm_so = p-start; }
|
||||||
|
action A10 { matches[10].rm_so = p-start; }
|
||||||
|
action A11 { matches[11].rm_so = p-start; }
|
||||||
|
action A12 { matches[12].rm_so = p-start; }
|
||||||
|
action A13 { matches[13].rm_so = p-start; }
|
||||||
|
action A14 { matches[14].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
action E2 { matches[2].rm_eo = p-start; }
|
||||||
|
action E3 { matches[3].rm_eo = p-start; }
|
||||||
|
action E4 { matches[4].rm_eo = p-start; }
|
||||||
|
action E5 { matches[5].rm_eo = p-start; }
|
||||||
|
action E6 { matches[6].rm_eo = p-start; }
|
||||||
|
action E7 { matches[7].rm_eo = p-start; }
|
||||||
|
action E8 { matches[8].rm_eo = p-start; }
|
||||||
|
action E9 { matches[9].rm_eo = p-start; }
|
||||||
|
action E10 { matches[10].rm_eo = p-start; }
|
||||||
|
action E11 { matches[11].rm_eo = p-start; }
|
||||||
|
action E12 { matches[12].rm_eo = p-start; }
|
||||||
|
action E13 { matches[13].rm_eo = p-start; }
|
||||||
|
action E14 { matches[14].rm_eo = p-start; }
|
||||||
|
main := (( "none" ) >A2 %E2 [ \t]+'"'([^"]+) >A3 %E3 '"') >A1 %E1 |(( "http" | "socks4" | "socks5" ) >A5 %E5 [ \t]+(([^:]*) >A7 %E7 ":" ([^@]*) >A8 %E8 "@" )? >A6 %E6 (([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+) >A10 %E10 |(('-'|[A-Za-z0-9._])+) >A11 %E11 ) >A9 %E9 ":" ([0-9]+) >A12 %E12 ([ \t]+'"'([^"]+) >A14 %E14 '"')? >A13 %E13 ) >A4 %E4 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_upstream(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,[2]=1,[3]=1,[4]=0,[5]=4,[6]=4,[7]=6,[8]=6,[9]=4,[10]=9,[11]=9,[12]=4,[13]=4,[14]=13,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine loglevel;
|
||||||
|
action A1 { matches[1].rm_so = p-start; }
|
||||||
|
action E1 { matches[1].rm_eo = p-start; }
|
||||||
|
main := ([Cc] "ritical" |[Ee] "rror" |[Ww] "arning" |[Nn] "otice" |[Cc] "onnect" |[Ii] "nfo" ) >A1 %E1 ;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
RE2R_EXPORT int re2r_match_loglevel(const char *p, const char* pe, size_t nmatch, regmatch_t matches[])
|
||||||
|
{
|
||||||
|
size_t i, cs;
|
||||||
|
int par;
|
||||||
|
static const unsigned char parents[] = {[0]=0,[1]=0,};
|
||||||
|
const char *start = p, *eof = pe;
|
||||||
|
%% write data nofinal noerror noentry;
|
||||||
|
for(i=0;i<nmatch;++i) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
%% write init;
|
||||||
|
%% write exec;
|
||||||
|
if(cs < %%{ write first_final; }%% ) return -1;
|
||||||
|
matches[0] = (regmatch_t){.rm_so = 0, .rm_eo = eof-start};
|
||||||
|
for(i=1;i<nmatch;++i) if(matches[i].rm_eo == -1) matches[i].rm_so = -1;
|
||||||
|
else if(matches[i].rm_so == matches[i].rm_eo) matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1};
|
||||||
|
else { par = i; while((par = parents[par])) if(matches[par].rm_eo == -1) { matches[i] = (regmatch_t){.rm_so = -1, .rm_eo = -1}; break; }}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user