mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 06:11:32 +02:00
MEDIUM: pattern: add indexation function.
Before this patch, the indexation function check the declared patttern matching function and index the data according with this function. This is not useful to add some indexation mode. This commit adds dedicated indexation function. Each struct pattern is associated with one indexation function. This function permit to index data according with the type of pattern and with the type of match.
This commit is contained in:
parent
1cf8f08c17
commit
b9b08460a2
@ -40,7 +40,7 @@
|
|||||||
* The function returns 1 if the processing is ok, return 0
|
* The function returns 1 if the processing is ok, return 0
|
||||||
* if the parser fails, with <err> message filled.
|
* if the parser fails, with <err> message filled.
|
||||||
*/
|
*/
|
||||||
int pattern_register(struct pattern_expr *expr, const char *arg, struct sample_storage *smp, struct pattern_list **pattern, int patflags, char **err);
|
int pattern_register(struct pattern_expr *expr, const char *arg, struct sample_storage *smp, int patflags, char **err);
|
||||||
|
|
||||||
/* return the PAT_MATCH_* index for match name "name", or < 0 if not found */
|
/* return the PAT_MATCH_* index for match name "name", or < 0 if not found */
|
||||||
static inline int pat_find_match_name(const char *name)
|
static inline int pat_find_match_name(const char *name)
|
||||||
@ -60,6 +60,18 @@ static inline int pat_find_match_name(const char *name)
|
|||||||
*/
|
*/
|
||||||
enum pat_match_res pattern_exec_match(struct pattern_expr *expr, struct sample *smp, struct sample_storage **sample, struct pattern **pat, struct pat_idx_elt **elt);
|
enum pat_match_res pattern_exec_match(struct pattern_expr *expr, struct sample *smp, struct sample_storage **sample, struct pattern **pat, struct pat_idx_elt **elt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* The following function gets "pattern", duplicate it and index it in "expr"
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err);
|
||||||
|
int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err);
|
||||||
|
int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err);
|
||||||
|
int pat_idx_list_reg(struct pattern_expr *expr, struct pattern *pat, char **err);
|
||||||
|
int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err);
|
||||||
|
int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* The following functions are general purpose pattern matching functions.
|
* The following functions are general purpose pattern matching functions.
|
||||||
|
@ -93,6 +93,7 @@ struct acl_keyword {
|
|||||||
const char *kw;
|
const char *kw;
|
||||||
char *fetch_kw;
|
char *fetch_kw;
|
||||||
int (*parse)(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
|
int (*parse)(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
|
||||||
|
int (*index)(struct pattern_expr *expr, struct pattern *pattern, char **err);
|
||||||
enum pat_match_res (*match)(struct sample *smp, struct pattern *pattern);
|
enum pat_match_res (*match)(struct sample *smp, struct pattern *pattern);
|
||||||
/* must be after the config params */
|
/* must be after the config params */
|
||||||
struct sample_fetch *smp; /* the sample fetch we depend on */
|
struct sample_fetch *smp; /* the sample fetch we depend on */
|
||||||
|
@ -165,6 +165,7 @@ struct pattern_list {
|
|||||||
*/
|
*/
|
||||||
struct pattern_expr {
|
struct pattern_expr {
|
||||||
int (*parse)(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
|
int (*parse)(const char *text, struct pattern *pattern, enum pat_usage usage, char **err);
|
||||||
|
int (*index)(struct pattern_expr *, struct pattern *, char **);
|
||||||
enum pat_match_res (*match)(struct sample *smp, struct pattern *pattern);
|
enum pat_match_res (*match)(struct sample *smp, struct pattern *pattern);
|
||||||
struct list patterns; /* list of acl_patterns */
|
struct list patterns; /* list of acl_patterns */
|
||||||
struct eb_root pattern_tree; /* may be used for lookup in large datasets */
|
struct eb_root pattern_tree; /* may be used for lookup in large datasets */
|
||||||
@ -172,6 +173,7 @@ struct pattern_expr {
|
|||||||
|
|
||||||
extern char *pat_match_names[PAT_MATCH_NUM];
|
extern char *pat_match_names[PAT_MATCH_NUM];
|
||||||
extern int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, enum pat_usage, char **);
|
extern int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, enum pat_usage, char **);
|
||||||
|
extern int (*pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, char **);
|
||||||
extern enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *);
|
extern enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *);
|
||||||
extern int pat_match_types[PAT_MATCH_NUM];
|
extern int pat_match_types[PAT_MATCH_NUM];
|
||||||
|
|
||||||
|
25
src/acl.c
25
src/acl.c
@ -130,10 +130,9 @@ static struct acl_expr *prune_acl_expr(struct acl_expr *expr)
|
|||||||
*/
|
*/
|
||||||
struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *al)
|
struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *al)
|
||||||
{
|
{
|
||||||
__label__ out_return, out_free_expr, out_free_pattern;
|
__label__ out_return, out_free_expr;
|
||||||
struct acl_expr *expr;
|
struct acl_expr *expr;
|
||||||
struct acl_keyword *aclkw;
|
struct acl_keyword *aclkw;
|
||||||
struct pattern_list *pattern;
|
|
||||||
int patflags;
|
int patflags;
|
||||||
const char *arg;
|
const char *arg;
|
||||||
struct sample_expr *smp = NULL;
|
struct sample_expr *smp = NULL;
|
||||||
@ -350,6 +349,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
|
|
||||||
expr->kw = aclkw ? aclkw->kw : smp->fetch->kw;
|
expr->kw = aclkw ? aclkw->kw : smp->fetch->kw;
|
||||||
expr->pat.parse = aclkw ? aclkw->parse : NULL;
|
expr->pat.parse = aclkw ? aclkw->parse : NULL;
|
||||||
|
expr->pat.index = aclkw ? aclkw->index : NULL;
|
||||||
expr->pat.match = aclkw ? aclkw->match : NULL;
|
expr->pat.match = aclkw ? aclkw->match : NULL;
|
||||||
expr->smp = smp;
|
expr->smp = smp;
|
||||||
smp = NULL;
|
smp = NULL;
|
||||||
@ -360,16 +360,19 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
switch (expr->smp ? expr->smp->fetch->out_type : aclkw->smp->out_type) {
|
switch (expr->smp ? expr->smp->fetch->out_type : aclkw->smp->out_type) {
|
||||||
case SMP_T_BOOL:
|
case SMP_T_BOOL:
|
||||||
expr->pat.parse = pat_parse_fcts[PAT_MATCH_BOOL];
|
expr->pat.parse = pat_parse_fcts[PAT_MATCH_BOOL];
|
||||||
|
expr->pat.index = pat_index_fcts[PAT_MATCH_BOOL];
|
||||||
expr->pat.match = pat_match_fcts[PAT_MATCH_BOOL];
|
expr->pat.match = pat_match_fcts[PAT_MATCH_BOOL];
|
||||||
break;
|
break;
|
||||||
case SMP_T_SINT:
|
case SMP_T_SINT:
|
||||||
case SMP_T_UINT:
|
case SMP_T_UINT:
|
||||||
expr->pat.parse = pat_parse_fcts[PAT_MATCH_INT];
|
expr->pat.parse = pat_parse_fcts[PAT_MATCH_INT];
|
||||||
|
expr->pat.index = pat_index_fcts[PAT_MATCH_INT];
|
||||||
expr->pat.match = pat_match_fcts[PAT_MATCH_INT];
|
expr->pat.match = pat_match_fcts[PAT_MATCH_INT];
|
||||||
break;
|
break;
|
||||||
case SMP_T_IPV4:
|
case SMP_T_IPV4:
|
||||||
case SMP_T_IPV6:
|
case SMP_T_IPV6:
|
||||||
expr->pat.parse = pat_parse_fcts[PAT_MATCH_IP];
|
expr->pat.parse = pat_parse_fcts[PAT_MATCH_IP];
|
||||||
|
expr->pat.index = pat_index_fcts[PAT_MATCH_IP];
|
||||||
expr->pat.match = pat_match_fcts[PAT_MATCH_IP];
|
expr->pat.match = pat_match_fcts[PAT_MATCH_IP];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -429,6 +432,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
goto out_free_expr;
|
goto out_free_expr;
|
||||||
}
|
}
|
||||||
expr->pat.parse = pat_parse_fcts[idx];
|
expr->pat.parse = pat_parse_fcts[idx];
|
||||||
|
expr->pat.index = pat_index_fcts[idx];
|
||||||
expr->pat.match = pat_match_fcts[idx];
|
expr->pat.match = pat_match_fcts[idx];
|
||||||
args++;
|
args++;
|
||||||
}
|
}
|
||||||
@ -447,7 +451,6 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now parse all patterns */
|
/* now parse all patterns */
|
||||||
pattern = NULL;
|
|
||||||
while (**args) {
|
while (**args) {
|
||||||
arg = *args;
|
arg = *args;
|
||||||
|
|
||||||
@ -513,11 +516,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
if (expr->pat.parse == pat_parse_dotted_ver && have_dot) {
|
if (expr->pat.parse == pat_parse_dotted_ver && have_dot) {
|
||||||
if (strl2llrc(dot+1, strlen(dot+1), &minor) != 0) {
|
if (strl2llrc(dot+1, strlen(dot+1), &minor) != 0) {
|
||||||
memprintf(err, "'%s' is neither a number nor a supported operator", arg);
|
memprintf(err, "'%s' is neither a number nor a supported operator", arg);
|
||||||
goto out_free_pattern;
|
goto out_free_expr;
|
||||||
}
|
}
|
||||||
if (minor >= 65536) {
|
if (minor >= 65536) {
|
||||||
memprintf(err, "'%s' contains too large a minor value", arg);
|
memprintf(err, "'%s' contains too large a minor value", arg);
|
||||||
goto out_free_pattern;
|
goto out_free_expr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,12 +529,12 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
*/
|
*/
|
||||||
if (strl2llrc(arg, dot - arg, &value) != 0) {
|
if (strl2llrc(arg, dot - arg, &value) != 0) {
|
||||||
memprintf(err, "'%s' is neither a number nor a supported operator", arg);
|
memprintf(err, "'%s' is neither a number nor a supported operator", arg);
|
||||||
goto out_free_pattern;
|
goto out_free_expr;
|
||||||
}
|
}
|
||||||
if (expr->pat.parse == pat_parse_dotted_ver) {
|
if (expr->pat.parse == pat_parse_dotted_ver) {
|
||||||
if (value >= 65536) {
|
if (value >= 65536) {
|
||||||
memprintf(err, "'%s' contains too large a major value", arg);
|
memprintf(err, "'%s' contains too large a major value", arg);
|
||||||
goto out_free_pattern;
|
goto out_free_expr;
|
||||||
}
|
}
|
||||||
value = (value << 16) | (minor & 0xffff);
|
value = (value << 16) | (minor & 0xffff);
|
||||||
}
|
}
|
||||||
@ -540,7 +543,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
|
|
||||||
case STD_OP_EQ: /* this case is not possible. */
|
case STD_OP_EQ: /* this case is not possible. */
|
||||||
memprintf(err, "internal error");
|
memprintf(err, "internal error");
|
||||||
goto out_free_pattern;
|
goto out_free_expr;
|
||||||
|
|
||||||
case STD_OP_GT:
|
case STD_OP_GT:
|
||||||
value++; /* gt = ge + 1 */
|
value++; /* gt = ge + 1 */
|
||||||
@ -569,15 +572,13 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pattern_register(&expr->pat, arg, NULL, &pattern, patflags, err))
|
if (!pattern_register(&expr->pat, arg, NULL, patflags, err))
|
||||||
goto out_free_pattern;
|
goto out_free_expr;
|
||||||
args++;
|
args++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
|
|
||||||
out_free_pattern:
|
|
||||||
pattern_free(pattern);
|
|
||||||
out_free_expr:
|
out_free_expr:
|
||||||
prune_acl_expr(expr);
|
prune_acl_expr(expr);
|
||||||
free(expr);
|
free(expr);
|
||||||
|
@ -1920,7 +1920,6 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
|||||||
}
|
}
|
||||||
else if (strcmp(args[0], "add") == 0) {
|
else if (strcmp(args[0], "add") == 0) {
|
||||||
if (strcmp(args[1], "map") == 0) {
|
if (strcmp(args[1], "map") == 0) {
|
||||||
struct pattern_list *pat;
|
|
||||||
struct map_entry *ent;
|
struct map_entry *ent;
|
||||||
struct sample_storage *smp;
|
struct sample_storage *smp;
|
||||||
|
|
||||||
@ -1993,23 +1992,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the value can be indexed, get the first pattern. If
|
if (!pattern_register(appctx->ctx.map.desc->pat, args[3], smp, 0, NULL)) {
|
||||||
* the return entry is not the indexed entry, new 'pattern' is
|
|
||||||
* created by the function pattern_register(). If the 'pattern'
|
|
||||||
* is NULL, new entry is created. This is ugly because the
|
|
||||||
* following code interfers with the own code of the function
|
|
||||||
* pattern_register().
|
|
||||||
*/
|
|
||||||
if (appctx->ctx.map.desc->pat->match == pat_match_str ||
|
|
||||||
appctx->ctx.map.desc->pat->match == pat_match_ip) {
|
|
||||||
pat = LIST_NEXT(&appctx->ctx.map.desc->pat->patterns, struct pattern_list *, list);
|
|
||||||
if (&pat->list == &appctx->ctx.map.desc->pat->patterns)
|
|
||||||
pat = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pat = NULL;
|
|
||||||
|
|
||||||
if (!pattern_register(appctx->ctx.map.desc->pat, args[3], smp, &pat, 0, NULL)) {
|
|
||||||
free(smp);
|
free(smp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,6 @@ static int map_read_entries_from_file(const char *filename,
|
|||||||
* <patflags> must be PAT_F_*.
|
* <patflags> must be PAT_F_*.
|
||||||
*/
|
*/
|
||||||
static int map_parse_and_index(struct map_descriptor *desc,
|
static int map_parse_and_index(struct map_descriptor *desc,
|
||||||
struct pattern_list **pattern,
|
|
||||||
struct map_entry *ent,
|
struct map_entry *ent,
|
||||||
int patflags,
|
int patflags,
|
||||||
char **err)
|
char **err)
|
||||||
@ -321,7 +320,7 @@ static int map_parse_and_index(struct map_descriptor *desc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register key */
|
/* register key */
|
||||||
if (!pattern_register(desc->pat, ent->key, smp, pattern, patflags, err))
|
if (!pattern_register(desc->pat, ent->key, smp, patflags, err))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -337,7 +336,6 @@ static int sample_load_map(struct arg *arg, struct sample_conv *conv, char **err
|
|||||||
{
|
{
|
||||||
struct map_reference *ref;
|
struct map_reference *ref;
|
||||||
struct map_descriptor *desc;
|
struct map_descriptor *desc;
|
||||||
struct pattern_list *pattern;
|
|
||||||
struct map_entry *ent;
|
struct map_entry *ent;
|
||||||
struct pattern_expr *pat = NULL;
|
struct pattern_expr *pat = NULL;
|
||||||
|
|
||||||
@ -412,11 +410,11 @@ static int sample_load_map(struct arg *arg, struct sample_conv *conv, char **err
|
|||||||
/* set the match method */
|
/* set the match method */
|
||||||
desc->pat->match = pat_match_fcts[conv->private];
|
desc->pat->match = pat_match_fcts[conv->private];
|
||||||
desc->pat->parse = pat_parse_fcts[conv->private];
|
desc->pat->parse = pat_parse_fcts[conv->private];
|
||||||
|
desc->pat->index = pat_index_fcts[conv->private];
|
||||||
|
|
||||||
/* parse each line of the file */
|
/* parse each line of the file */
|
||||||
pattern = NULL;
|
|
||||||
list_for_each_entry(ent, &ref->entries, list)
|
list_for_each_entry(ent, &ref->entries, list)
|
||||||
if (!map_parse_and_index(desc, &pattern, ent, 0, err))
|
if (!map_parse_and_index(desc, ent, 0, err))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
320
src/pattern.c
320
src/pattern.c
@ -56,6 +56,22 @@ int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, enum pat_us
|
|||||||
[PAT_MATCH_REG] = pat_parse_reg,
|
[PAT_MATCH_REG] = pat_parse_reg,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int (*pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, char **) = {
|
||||||
|
[PAT_MATCH_FOUND] = pat_idx_list_val,
|
||||||
|
[PAT_MATCH_BOOL] = pat_idx_list_val,
|
||||||
|
[PAT_MATCH_INT] = pat_idx_list_val,
|
||||||
|
[PAT_MATCH_IP] = pat_idx_tree_ip,
|
||||||
|
[PAT_MATCH_BIN] = pat_idx_list_ptr,
|
||||||
|
[PAT_MATCH_LEN] = pat_idx_list_val,
|
||||||
|
[PAT_MATCH_STR] = pat_idx_tree_str,
|
||||||
|
[PAT_MATCH_BEG] = pat_idx_list_str,
|
||||||
|
[PAT_MATCH_SUB] = pat_idx_list_str,
|
||||||
|
[PAT_MATCH_DIR] = pat_idx_list_str,
|
||||||
|
[PAT_MATCH_DOM] = pat_idx_list_str,
|
||||||
|
[PAT_MATCH_END] = pat_idx_list_str,
|
||||||
|
[PAT_MATCH_REG] = pat_idx_list_reg,
|
||||||
|
};
|
||||||
|
|
||||||
enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *) = {
|
enum pat_match_res (*pat_match_fcts[PAT_MATCH_NUM])(struct sample *, struct pattern *) = {
|
||||||
[PAT_MATCH_FOUND] = NULL,
|
[PAT_MATCH_FOUND] = NULL,
|
||||||
[PAT_MATCH_BOOL] = pat_match_nothing,
|
[PAT_MATCH_BOOL] = pat_match_nothing,
|
||||||
@ -786,93 +802,141 @@ void pattern_init_expr(struct pattern_expr *expr)
|
|||||||
expr->pattern_tree = EB_ROOT_UNIQUE;
|
expr->pattern_tree = EB_ROOT_UNIQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 1 if the process is ok
|
/*
|
||||||
* return -1 if the parser fail. The err message is filled.
|
*
|
||||||
* return -2 if out of memory
|
* The following functions are used for the pattern indexation
|
||||||
*/
|
|
||||||
int pattern_register(struct pattern_expr *expr, const char *arg,
|
|
||||||
struct sample_storage *smp,
|
|
||||||
struct pattern_list **pattern,
|
|
||||||
int patflags, char **err)
|
|
||||||
{
|
|
||||||
unsigned int mask = 0;
|
|
||||||
struct pat_idx_elt *node;
|
|
||||||
int len;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* we keep the previous pattern along iterations as long as it's not used */
|
|
||||||
if (!*pattern)
|
|
||||||
*pattern = (struct pattern_list *)malloc(sizeof(**pattern));
|
|
||||||
if (!*pattern) {
|
|
||||||
memprintf(err, "out of memory while loading pattern");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(*pattern, 0, sizeof(**pattern));
|
|
||||||
(*pattern)->pat.flags = patflags;
|
|
||||||
|
|
||||||
ret = expr->parse(arg, &(*pattern)->pat, PAT_U_COMPILE, err);
|
|
||||||
if (!ret)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (expr->match == pat_match_str) {
|
|
||||||
/* SMP_T_CSTR tree indexation.
|
|
||||||
* The match "pat_match_str()" can use trees.
|
|
||||||
*/
|
|
||||||
if ((*pattern)->pat.flags & PAT_F_IGNORE_CASE) {
|
|
||||||
/* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
|
|
||||||
goto just_chain_the_pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Process the key len */
|
|
||||||
len = strlen((*pattern)->pat.ptr.str) + 1;
|
|
||||||
|
|
||||||
/* node memory allocation */
|
|
||||||
node = calloc(1, sizeof(*node) + len);
|
|
||||||
if (!node) {
|
|
||||||
memprintf(err, "out of memory while loading pattern");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the pointer to sample associated to this node */
|
|
||||||
node->smp = smp;
|
|
||||||
|
|
||||||
/* copy the string */
|
|
||||||
memcpy(node->node.key, (*pattern)->pat.ptr.str, len);
|
|
||||||
|
|
||||||
/* the "map_parser_str()" function always duplicate string information */
|
|
||||||
free((*pattern)->pat.ptr.str);
|
|
||||||
(*pattern)->pat.ptr.str = NULL;
|
|
||||||
|
|
||||||
/* we pre-set the data pointer to the tree's head so that functions
|
|
||||||
* which are able to insert in a tree know where to do that.
|
|
||||||
*
|
*
|
||||||
* because "val" is an "union", the previous data are crushed.
|
|
||||||
*/
|
*/
|
||||||
(*pattern)->pat.flags |= PAT_F_TREE;
|
|
||||||
(*pattern)->pat.val.tree = &expr->pattern_tree;
|
|
||||||
|
|
||||||
/* index the new node */
|
int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||||
if (ebst_insert((*pattern)->pat.val.tree, &node->node) != &node->node)
|
{
|
||||||
free(node); /* was a duplicate */
|
struct pattern_list *patl;
|
||||||
|
|
||||||
|
/* allocate pattern */
|
||||||
|
patl = calloc(1, sizeof(*patl));
|
||||||
|
if (!patl) {
|
||||||
|
memprintf(err, "out of memory while indexing pattern");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else if (expr->match == pat_match_ip) {
|
|
||||||
/* SMP_T_IPV4 tree indexation
|
/* duplicate pattern */
|
||||||
* The match "pat_match_ip()" can use tree.
|
memcpy(&patl->pat, pat, sizeof(*pat));
|
||||||
*/
|
|
||||||
if ((*pattern)->pat.type != SMP_T_IPV4) {
|
/* chain pattern in the expression */
|
||||||
|
LIST_ADDQ(&expr->patterns, &patl->list);
|
||||||
|
|
||||||
|
/* that's ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pat_idx_list_ptr(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||||
|
{
|
||||||
|
struct pattern_list *patl;
|
||||||
|
|
||||||
|
/* allocate pattern */
|
||||||
|
patl = calloc(1, sizeof(*patl));
|
||||||
|
if (!patl)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* duplicate pattern */
|
||||||
|
memcpy(&patl->pat, pat, sizeof(*pat));
|
||||||
|
patl->pat.ptr.ptr = malloc(patl->pat.len);
|
||||||
|
if (!patl->pat.ptr.ptr) {
|
||||||
|
free(patl);
|
||||||
|
memprintf(err, "out of memory while indexing pattern");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
|
||||||
|
|
||||||
|
/* chain pattern in the expression */
|
||||||
|
LIST_ADDQ(&expr->patterns, &patl->list);
|
||||||
|
|
||||||
|
/* that's ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||||
|
{
|
||||||
|
struct pattern_list *patl;
|
||||||
|
|
||||||
|
/* allocate pattern */
|
||||||
|
patl = calloc(1, sizeof(*patl));
|
||||||
|
if (!patl) {
|
||||||
|
memprintf(err, "out of memory while indexing pattern");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* duplicate pattern */
|
||||||
|
memcpy(&patl->pat, pat, sizeof(*pat));
|
||||||
|
patl->pat.ptr.str = malloc(patl->pat.len + 1);
|
||||||
|
if (!patl->pat.ptr.str) {
|
||||||
|
free(patl);
|
||||||
|
memprintf(err, "out of memory while indexing pattern");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(patl->pat.ptr.ptr, pat->ptr.ptr, pat->len);
|
||||||
|
patl->pat.ptr.str[patl->pat.len] = '\0';
|
||||||
|
|
||||||
|
/* chain pattern in the expression */
|
||||||
|
LIST_ADDQ(&expr->patterns, &patl->list);
|
||||||
|
|
||||||
|
/* that's ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pat_idx_list_reg(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||||
|
{
|
||||||
|
struct pattern_list *patl;
|
||||||
|
|
||||||
|
/* allocate pattern */
|
||||||
|
patl = calloc(1, sizeof(*patl));
|
||||||
|
if (!patl) {
|
||||||
|
memprintf(err, "out of memory while indexing pattern");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* duplicate pattern */
|
||||||
|
memcpy(&patl->pat, pat, sizeof(*pat));
|
||||||
|
|
||||||
|
/* allocate regex */
|
||||||
|
patl->pat.ptr.reg = calloc(1, sizeof(*patl->pat.ptr.reg));
|
||||||
|
if (!patl->pat.ptr.reg) {
|
||||||
|
free(patl);
|
||||||
|
memprintf(err, "out of memory while indexing pattern");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compile regex */
|
||||||
|
if (!regex_comp(pat->ptr.reg->regstr, patl->pat.ptr.reg, !(patl->pat.flags & PAT_F_IGNORE_CASE), 0, err)) {
|
||||||
|
free(patl);
|
||||||
|
free(patl->pat.ptr.reg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free pattern method */
|
||||||
|
patl->pat.freeptrbuf = &pat_free_reg;
|
||||||
|
|
||||||
|
/* chain pattern in the expression */
|
||||||
|
LIST_ADDQ(&expr->patterns, &patl->list);
|
||||||
|
|
||||||
|
/* that's ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pat_idx_tree_ip(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||||
|
{
|
||||||
|
unsigned int mask;
|
||||||
|
struct pat_idx_elt *node;
|
||||||
|
|
||||||
/* Only IPv4 can be indexed */
|
/* Only IPv4 can be indexed */
|
||||||
goto just_chain_the_pattern;
|
if (pat->type == SMP_T_IPV4) {
|
||||||
}
|
|
||||||
|
|
||||||
/* in IPv4 case, check if the mask is contiguous so that we can
|
/* in IPv4 case, check if the mask is contiguous so that we can
|
||||||
* insert the network into the tree. A continuous mask has only
|
* insert the network into the tree. A continuous mask has only
|
||||||
* ones on the left. This means that this mask + its lower bit
|
* ones on the left. This means that this mask + its lower bit
|
||||||
* added once again is null.
|
* added once again is null.
|
||||||
*/
|
*/
|
||||||
mask = ntohl((*pattern)->pat.val.ipv4.mask.s_addr);
|
mask = ntohl(pat->val.ipv4.mask.s_addr);
|
||||||
if (mask + (mask & -mask) != 0)
|
if (mask + (mask & -mask) == 0) {
|
||||||
goto just_chain_the_pattern;
|
|
||||||
mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
|
mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
|
||||||
|
|
||||||
/* node memory allocation */
|
/* node memory allocation */
|
||||||
@ -883,38 +947,88 @@ int pattern_register(struct pattern_expr *expr, const char *arg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy the pointer to sample associated to this node */
|
/* copy the pointer to sample associated to this node */
|
||||||
node->smp = smp;
|
node->smp = pat->smp;
|
||||||
|
|
||||||
/* FIXME: insert <addr>/<mask> into the tree here */
|
/* FIXME: insert <addr>/<mask> into the tree here */
|
||||||
memcpy(node->node.key, &(*pattern)->pat.val.ipv4.addr, 4); /* network byte order */
|
memcpy(node->node.key, &pat->val.ipv4.addr, 4); /* network byte order */
|
||||||
|
|
||||||
/* we pre-set the data pointer to the tree's head so that functions
|
|
||||||
* which are able to insert in a tree know where to do that.
|
|
||||||
*
|
|
||||||
* because "val" is an "union", the previous data are crushed.
|
|
||||||
*/
|
|
||||||
(*pattern)->pat.flags |= PAT_F_TREE;
|
|
||||||
(*pattern)->pat.val.tree = &expr->pattern_tree;
|
|
||||||
|
|
||||||
/* Index the new node
|
|
||||||
* FIXME: insert <addr>/<mask> into the tree here
|
|
||||||
*/
|
|
||||||
node->node.node.pfx = mask;
|
node->node.node.pfx = mask;
|
||||||
if (ebmb_insert_prefix((*pattern)->pat.val.tree, &node->node, 4) != &node->node)
|
if (ebmb_insert_prefix(&expr->pattern_tree, &node->node, 4) != &node->node)
|
||||||
free(node); /* was a duplicate */
|
free(node); /* was a duplicate */
|
||||||
|
|
||||||
|
/* that's ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the value cannot be indexed, just add it to the list */
|
||||||
|
return pat_idx_list_val(expr, pat, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
struct pat_idx_elt *node;
|
||||||
|
|
||||||
|
/* Only string can be indexed */
|
||||||
|
if (pat->type != SMP_T_CSTR && pat->type != SMP_T_STR) {
|
||||||
|
memprintf(err, "internal error: string expected, but the type is '%s'",
|
||||||
|
smp_to_type[pat->type]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
|
||||||
|
if (pat->flags & PAT_F_IGNORE_CASE)
|
||||||
|
return pat_idx_list_str(expr, pat, err);
|
||||||
|
|
||||||
|
/* Process the key len */
|
||||||
|
len = strlen(pat->ptr.str) + 1;
|
||||||
|
|
||||||
|
/* node memory allocation */
|
||||||
|
node = calloc(1, sizeof(*node) + len);
|
||||||
|
if (!node) {
|
||||||
|
memprintf(err, "out of memory while loading pattern");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
just_chain_the_pattern:
|
|
||||||
/* if the parser did not feed the tree, let's chain the pattern to the list */
|
|
||||||
LIST_ADDQ(&expr->patterns, &(*pattern)->list);
|
|
||||||
|
|
||||||
/* copy the pointer to sample associated to this node */
|
/* copy the pointer to sample associated to this node */
|
||||||
(*pattern)->pat.smp = smp;
|
node->smp = pat->smp;
|
||||||
|
|
||||||
/* get a new one */
|
/* copy the string */
|
||||||
*pattern = NULL;
|
memcpy(node->node.key, pat->ptr.str, len);
|
||||||
|
|
||||||
|
/* index the new node */
|
||||||
|
if (ebst_insert(&expr->pattern_tree, &node->node) != &node->node)
|
||||||
|
free(node); /* was a duplicate */
|
||||||
|
|
||||||
|
/* that's ok */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return 1 if the process is ok
|
||||||
|
* return -1 if the parser fail. The err message is filled.
|
||||||
|
* return -2 if out of memory
|
||||||
|
*/
|
||||||
|
int pattern_register(struct pattern_expr *expr, const char *arg,
|
||||||
|
struct sample_storage *smp,
|
||||||
|
int patflags, char **err)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct pattern pattern;
|
||||||
|
|
||||||
|
/* initialise pattern */
|
||||||
|
memset(&pattern, 0, sizeof(pattern));
|
||||||
|
pattern.flags = patflags;
|
||||||
|
pattern.smp = smp;
|
||||||
|
|
||||||
|
/* parse pattern */
|
||||||
|
ret = expr->parse(arg, &pattern, PAT_U_LOOKUP, err);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* index pattern */
|
||||||
|
if (!expr->index(expr, &pattern, err))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,7 +1042,6 @@ int pattern_read_from_file(struct pattern_expr *expr,
|
|||||||
FILE *file;
|
FILE *file;
|
||||||
char *c;
|
char *c;
|
||||||
char *arg;
|
char *arg;
|
||||||
struct pattern_list *pattern;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int code;
|
int code;
|
||||||
@ -943,7 +1056,6 @@ int pattern_read_from_file(struct pattern_expr *expr,
|
|||||||
* line. If the line contains spaces, they will be part of the pattern.
|
* line. If the line contains spaces, they will be part of the pattern.
|
||||||
* The pattern stops at the first CR, LF or EOF encountered.
|
* The pattern stops at the first CR, LF or EOF encountered.
|
||||||
*/
|
*/
|
||||||
pattern = NULL;
|
|
||||||
while (fgets(trash.str, trash.size, file) != NULL) {
|
while (fgets(trash.str, trash.size, file) != NULL) {
|
||||||
line++;
|
line++;
|
||||||
c = trash.str;
|
c = trash.str;
|
||||||
@ -966,21 +1078,19 @@ int pattern_read_from_file(struct pattern_expr *expr,
|
|||||||
if (c == arg)
|
if (c == arg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
code = pattern_register(expr, arg, NULL, &pattern, patflags, err);
|
code = pattern_register(expr, arg, NULL, patflags, err);
|
||||||
if (code == -2) {
|
if (code == -2) {
|
||||||
memprintf(err, "out of memory when loading patterns from file <%s>", filename);
|
memprintf(err, "out of memory when loading patterns from file <%s>", filename);
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
else if (code < 0) {
|
else if (code < 0) {
|
||||||
memprintf(err, "%s when loading patterns from file <%s>", *err, filename);
|
memprintf(err, "%s when loading patterns from file <%s>", *err, filename);
|
||||||
goto out_free_pattern;
|
goto out_close;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1; /* success */
|
ret = 1; /* success */
|
||||||
|
|
||||||
out_free_pattern:
|
|
||||||
pattern_free(pattern);
|
|
||||||
out_close:
|
out_close:
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -681,13 +681,13 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
|
|||||||
* Please take care of keeping this list alphabetically sorted.
|
* Please take care of keeping this list alphabetically sorted.
|
||||||
*/
|
*/
|
||||||
static struct acl_kw_list acl_kws = {ILH, {
|
static struct acl_kw_list acl_kws = {ILH, {
|
||||||
{ "payload", "req.payload", pat_parse_bin, pat_match_bin },
|
{ "payload", "req.payload", pat_parse_bin, pat_idx_list_ptr, pat_match_bin },
|
||||||
{ "payload_lv", "req.payload_lv", pat_parse_bin, pat_match_bin },
|
{ "payload_lv", "req.payload_lv", pat_parse_bin, pat_idx_list_ptr, pat_match_bin },
|
||||||
{ "req_rdp_cookie", "req.rdp_cookie", pat_parse_str, pat_match_str },
|
{ "req_rdp_cookie", "req.rdp_cookie", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "req_rdp_cookie_cnt", "req.rdp_cookie_cnt", pat_parse_int, pat_match_int },
|
{ "req_rdp_cookie_cnt", "req.rdp_cookie_cnt", pat_parse_int, pat_idx_list_val, pat_match_int },
|
||||||
{ "req_ssl_sni", "req.ssl_sni", pat_parse_str, pat_match_str },
|
{ "req_ssl_sni", "req.ssl_sni", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "req_ssl_ver", "req.ssl_ver", pat_parse_dotted_ver, pat_match_int },
|
{ "req_ssl_ver", "req.ssl_ver", pat_parse_dotted_ver, pat_idx_list_val, pat_match_int },
|
||||||
{ "req.ssl_ver", "req.ssl_ver", pat_parse_dotted_ver, pat_match_int },
|
{ "req.ssl_ver", "req.ssl_ver", pat_parse_dotted_ver, pat_idx_list_val, pat_match_int },
|
||||||
{ /* END */ },
|
{ /* END */ },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
136
src/proto_http.c
136
src/proto_http.c
@ -10346,84 +10346,84 @@ static int sample_conv_http_date(const struct arg *args, struct sample *smp)
|
|||||||
* Please take care of keeping this list alphabetically sorted.
|
* Please take care of keeping this list alphabetically sorted.
|
||||||
*/
|
*/
|
||||||
static struct acl_kw_list acl_kws = {ILH, {
|
static struct acl_kw_list acl_kws = {ILH, {
|
||||||
{ "base", "base", pat_parse_str, pat_match_str },
|
{ "base", "base", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "base_beg", "base", pat_parse_str, pat_match_beg },
|
{ "base_beg", "base", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "base_dir", "base", pat_parse_str, pat_match_dir },
|
{ "base_dir", "base", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "base_dom", "base", pat_parse_str, pat_match_dom },
|
{ "base_dom", "base", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "base_end", "base", pat_parse_str, pat_match_end },
|
{ "base_end", "base", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "base_len", "base", pat_parse_int, pat_match_len },
|
{ "base_len", "base", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "base_reg", "base", pat_parse_reg, pat_match_reg },
|
{ "base_reg", "base", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "base_sub", "base", pat_parse_str, pat_match_sub },
|
{ "base_sub", "base", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "cook", "req.cook", pat_parse_str, pat_match_str },
|
{ "cook", "req.cook", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "cook_beg", "req.cook", pat_parse_str, pat_match_beg },
|
{ "cook_beg", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "cook_dir", "req.cook", pat_parse_str, pat_match_dir },
|
{ "cook_dir", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "cook_dom", "req.cook", pat_parse_str, pat_match_dom },
|
{ "cook_dom", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "cook_end", "req.cook", pat_parse_str, pat_match_end },
|
{ "cook_end", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "cook_len", "req.cook", pat_parse_int, pat_match_len },
|
{ "cook_len", "req.cook", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "cook_reg", "req.cook", pat_parse_reg, pat_match_reg },
|
{ "cook_reg", "req.cook", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "cook_sub", "req.cook", pat_parse_str, pat_match_sub },
|
{ "cook_sub", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "hdr", "req.hdr", pat_parse_str, pat_match_str },
|
{ "hdr", "req.hdr", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "hdr_beg", "req.hdr", pat_parse_str, pat_match_beg },
|
{ "hdr_beg", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "hdr_dir", "req.hdr", pat_parse_str, pat_match_dir },
|
{ "hdr_dir", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "hdr_dom", "req.hdr", pat_parse_str, pat_match_dom },
|
{ "hdr_dom", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "hdr_end", "req.hdr", pat_parse_str, pat_match_end },
|
{ "hdr_end", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "hdr_len", "req.hdr", pat_parse_int, pat_match_len },
|
{ "hdr_len", "req.hdr", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "hdr_reg", "req.hdr", pat_parse_reg, pat_match_reg },
|
{ "hdr_reg", "req.hdr", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "hdr_sub", "req.hdr", pat_parse_str, pat_match_sub },
|
{ "hdr_sub", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "http_auth_group", NULL, pat_parse_str, pat_match_auth },
|
{ "http_auth_group", NULL, pat_parse_str, pat_idx_list_str, pat_match_auth },
|
||||||
|
|
||||||
{ "method", NULL, pat_parse_meth, pat_match_meth },
|
{ "method", NULL, pat_parse_meth, pat_idx_list_str, pat_match_meth },
|
||||||
|
|
||||||
{ "path", "path", pat_parse_str, pat_match_str },
|
{ "path", "path", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "path_beg", "path", pat_parse_str, pat_match_beg },
|
{ "path_beg", "path", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "path_dir", "path", pat_parse_str, pat_match_dir },
|
{ "path_dir", "path", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "path_dom", "path", pat_parse_str, pat_match_dom },
|
{ "path_dom", "path", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "path_end", "path", pat_parse_str, pat_match_end },
|
{ "path_end", "path", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "path_len", "path", pat_parse_int, pat_match_len },
|
{ "path_len", "path", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "path_reg", "path", pat_parse_reg, pat_match_reg },
|
{ "path_reg", "path", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "path_sub", "path", pat_parse_str, pat_match_sub },
|
{ "path_sub", "path", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "req_ver", "req.ver", pat_parse_str, pat_match_str },
|
{ "req_ver", "req.ver", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "resp_ver", "res.ver", pat_parse_str, pat_match_str },
|
{ "resp_ver", "res.ver", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
|
|
||||||
{ "scook", "res.cook", pat_parse_str, pat_match_str },
|
{ "scook", "res.cook", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "scook_beg", "res.cook", pat_parse_str, pat_match_beg },
|
{ "scook_beg", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "scook_dir", "res.cook", pat_parse_str, pat_match_dir },
|
{ "scook_dir", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "scook_dom", "res.cook", pat_parse_str, pat_match_dom },
|
{ "scook_dom", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "scook_end", "res.cook", pat_parse_str, pat_match_end },
|
{ "scook_end", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "scook_len", "res.cook", pat_parse_int, pat_match_len },
|
{ "scook_len", "res.cook", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "scook_reg", "res.cook", pat_parse_reg, pat_match_reg },
|
{ "scook_reg", "res.cook", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "scook_sub", "res.cook", pat_parse_str, pat_match_sub },
|
{ "scook_sub", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "shdr", "res.hdr", pat_parse_str, pat_match_str },
|
{ "shdr", "res.hdr", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "shdr_beg", "res.hdr", pat_parse_str, pat_match_beg },
|
{ "shdr_beg", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "shdr_dir", "res.hdr", pat_parse_str, pat_match_dir },
|
{ "shdr_dir", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "shdr_dom", "res.hdr", pat_parse_str, pat_match_dom },
|
{ "shdr_dom", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "shdr_end", "res.hdr", pat_parse_str, pat_match_end },
|
{ "shdr_end", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "shdr_len", "res.hdr", pat_parse_int, pat_match_len },
|
{ "shdr_len", "res.hdr", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "shdr_reg", "res.hdr", pat_parse_reg, pat_match_reg },
|
{ "shdr_reg", "res.hdr", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "shdr_sub", "res.hdr", pat_parse_str, pat_match_sub },
|
{ "shdr_sub", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "url", "url", pat_parse_str, pat_match_str },
|
{ "url", "url", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "url_beg", "url", pat_parse_str, pat_match_beg },
|
{ "url_beg", "url", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "url_dir", "url", pat_parse_str, pat_match_dir },
|
{ "url_dir", "url", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "url_dom", "url", pat_parse_str, pat_match_dom },
|
{ "url_dom", "url", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "url_end", "url", pat_parse_str, pat_match_end },
|
{ "url_end", "url", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "url_len", "url", pat_parse_int, pat_match_len },
|
{ "url_len", "url", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "url_reg", "url", pat_parse_reg, pat_match_reg },
|
{ "url_reg", "url", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "url_sub", "url", pat_parse_str, pat_match_sub },
|
{ "url_sub", "url", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ "urlp", "urlp", pat_parse_str, pat_match_str },
|
{ "urlp", "urlp", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "urlp_beg", "urlp", pat_parse_str, pat_match_beg },
|
{ "urlp_beg", "urlp", pat_parse_str, pat_idx_list_str, pat_match_beg },
|
||||||
{ "urlp_dir", "urlp", pat_parse_str, pat_match_dir },
|
{ "urlp_dir", "urlp", pat_parse_str, pat_idx_list_str, pat_match_dir },
|
||||||
{ "urlp_dom", "urlp", pat_parse_str, pat_match_dom },
|
{ "urlp_dom", "urlp", pat_parse_str, pat_idx_list_str, pat_match_dom },
|
||||||
{ "urlp_end", "urlp", pat_parse_str, pat_match_end },
|
{ "urlp_end", "urlp", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "urlp_len", "urlp", pat_parse_int, pat_match_len },
|
{ "urlp_len", "urlp", pat_parse_int, pat_idx_list_val, pat_match_len },
|
||||||
{ "urlp_reg", "urlp", pat_parse_reg, pat_match_reg },
|
{ "urlp_reg", "urlp", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ "urlp_sub", "urlp", pat_parse_str, pat_match_sub },
|
{ "urlp_sub", "urlp", pat_parse_str, pat_idx_list_str, pat_match_sub },
|
||||||
|
|
||||||
{ /* END */ },
|
{ /* END */ },
|
||||||
}};
|
}};
|
||||||
|
@ -3540,31 +3540,31 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
|||||||
* Please take care of keeping this list alphabetically sorted.
|
* Please take care of keeping this list alphabetically sorted.
|
||||||
*/
|
*/
|
||||||
static struct acl_kw_list acl_kws = {ILH, {
|
static struct acl_kw_list acl_kws = {ILH, {
|
||||||
{ "ssl_c_i_dn", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_c_i_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_c_key_alg", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_c_key_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_c_notafter", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_c_notafter", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_c_notbefore", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_c_notbefore", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_c_sig_alg", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_c_sig_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_c_s_dn", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_c_s_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_c_serial", NULL, pat_parse_bin, pat_match_bin },
|
{ "ssl_c_serial", NULL, pat_parse_bin, pat_idx_list_ptr, pat_match_bin },
|
||||||
{ "ssl_f_i_dn", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_f_i_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_f_key_alg", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_f_key_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_f_notafter", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_f_notafter", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_f_notbefore", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_f_notbefore", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_f_sig_alg", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_f_sig_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_f_s_dn", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_f_s_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_f_serial", NULL, pat_parse_bin, pat_match_bin },
|
{ "ssl_f_serial", NULL, pat_parse_bin, pat_idx_list_ptr, pat_match_bin },
|
||||||
{ "ssl_fc_cipher", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_fc_cipher", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
#ifdef OPENSSL_NPN_NEGOTIATED
|
#ifdef OPENSSL_NPN_NEGOTIATED
|
||||||
{ "ssl_fc_npn", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_fc_npn", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
#endif
|
#endif
|
||||||
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
{ "ssl_fc_alpn", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_fc_alpn", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
#endif
|
#endif
|
||||||
{ "ssl_fc_protocol", NULL, pat_parse_str, pat_match_str },
|
{ "ssl_fc_protocol", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_fc_sni", "ssl_fc_sni", pat_parse_str, pat_match_str },
|
{ "ssl_fc_sni", "ssl_fc_sni", pat_parse_str, pat_idx_tree_str, pat_match_str },
|
||||||
{ "ssl_fc_sni_end", "ssl_fc_sni", pat_parse_str, pat_match_end },
|
{ "ssl_fc_sni_end", "ssl_fc_sni", pat_parse_str, pat_idx_list_str, pat_match_end },
|
||||||
{ "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_match_reg },
|
{ "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
|
||||||
{ /* END */ },
|
{ /* END */ },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user