* The function returns 1 if the processing is ok, return 0
* 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 */
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);
+/*
+ *
+ * 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.
const char *kw;
char *fetch_kw;
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);
/* must be after the config params */
struct sample_fetch *smp; /* the sample fetch we depend on */
*/
struct pattern_expr {
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);
struct list patterns; /* list of acl_patterns */
struct eb_root pattern_tree; /* may be used for lookup in large datasets */
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_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 int pat_match_types[PAT_MATCH_NUM];
*/
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_keyword *aclkw;
- struct pattern_list *pattern;
int patflags;
const char *arg;
struct sample_expr *smp = NULL;
expr->kw = aclkw ? aclkw->kw : smp->fetch->kw;
expr->pat.parse = aclkw ? aclkw->parse : NULL;
+ expr->pat.index = aclkw ? aclkw->index : NULL;
expr->pat.match = aclkw ? aclkw->match : NULL;
expr->smp = smp;
smp = NULL;
switch (expr->smp ? expr->smp->fetch->out_type : aclkw->smp->out_type) {
case SMP_T_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];
break;
case SMP_T_SINT:
case SMP_T_UINT:
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];
break;
case SMP_T_IPV4:
case SMP_T_IPV6:
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];
break;
}
goto out_free_expr;
}
expr->pat.parse = pat_parse_fcts[idx];
+ expr->pat.index = pat_index_fcts[idx];
expr->pat.match = pat_match_fcts[idx];
args++;
}
}
/* now parse all patterns */
- pattern = NULL;
while (**args) {
arg = *args;
if (expr->pat.parse == pat_parse_dotted_ver && have_dot) {
if (strl2llrc(dot+1, strlen(dot+1), &minor) != 0) {
memprintf(err, "'%s' is neither a number nor a supported operator", arg);
- goto out_free_pattern;
+ goto out_free_expr;
}
if (minor >= 65536) {
memprintf(err, "'%s' contains too large a minor value", arg);
- goto out_free_pattern;
+ goto out_free_expr;
}
}
*/
if (strl2llrc(arg, dot - arg, &value) != 0) {
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 (value >= 65536) {
memprintf(err, "'%s' contains too large a major value", arg);
- goto out_free_pattern;
+ goto out_free_expr;
}
value = (value << 16) | (minor & 0xffff);
}
case STD_OP_EQ: /* this case is not possible. */
memprintf(err, "internal error");
- goto out_free_pattern;
+ goto out_free_expr;
case STD_OP_GT:
value++; /* gt = ge + 1 */
}
}
- if (!pattern_register(&expr->pat, arg, NULL, &pattern, patflags, err))
- goto out_free_pattern;
+ if (!pattern_register(&expr->pat, arg, NULL, patflags, err))
+ goto out_free_expr;
args++;
}
return expr;
- out_free_pattern:
- pattern_free(pattern);
out_free_expr:
prune_acl_expr(expr);
free(expr);
}
else if (strcmp(args[0], "add") == 0) {
if (strcmp(args[1], "map") == 0) {
- struct pattern_list *pat;
struct map_entry *ent;
struct sample_storage *smp;
continue;
}
- /* If the value can be indexed, get the first pattern. If
- * 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)) {
+ if (!pattern_register(appctx->ctx.map.desc->pat, args[3], smp, 0, NULL)) {
free(smp);
continue;
}
* <patflags> must be PAT_F_*.
*/
static int map_parse_and_index(struct map_descriptor *desc,
- struct pattern_list **pattern,
struct map_entry *ent,
int patflags,
char **err)
}
/* 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 1;
{
struct map_reference *ref;
struct map_descriptor *desc;
- struct pattern_list *pattern;
struct map_entry *ent;
struct pattern_expr *pat = NULL;
/* set the match method */
desc->pat->match = pat_match_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 */
- pattern = NULL;
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;
}
[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 *) = {
[PAT_MATCH_FOUND] = NULL,
[PAT_MATCH_BOOL] = pat_match_nothing,
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)
+
+int pat_idx_list_val(struct pattern_expr *expr, struct pattern *pat, char **err)
{
- unsigned int mask = 0;
- struct pat_idx_elt *node;
- int len;
- int ret;
+ struct pattern_list *patl;
- /* 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");
+ /* allocate pattern */
+ patl = calloc(1, sizeof(*patl));
+ if (!patl) {
+ memprintf(err, "out of memory while indexing pattern");
return 0;
}
- memset(*pattern, 0, sizeof(**pattern));
- (*pattern)->pat.flags = patflags;
+ /* duplicate pattern */
+ memcpy(&patl->pat, pat, sizeof(*pat));
- ret = expr->parse(arg, &(*pattern)->pat, PAT_U_COMPILE, err);
- if (!ret)
+ /* 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;
- 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;
- }
+ /* 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);
- /* Process the key len */
- len = strlen((*pattern)->pat.ptr.str) + 1;
+ /* chain pattern in the expression */
+ LIST_ADDQ(&expr->patterns, &patl->list);
- /* node memory allocation */
- node = calloc(1, sizeof(*node) + len);
- if (!node) {
- memprintf(err, "out of memory while loading pattern");
- return 0;
- }
+ /* that's ok */
+ return 1;
+}
- /* copy the pointer to sample associated to this node */
- node->smp = smp;
+int pat_idx_list_str(struct pattern_expr *expr, struct pattern *pat, char **err)
+{
+ struct pattern_list *patl;
- /* copy the string */
- memcpy(node->node.key, (*pattern)->pat.ptr.str, len);
+ /* allocate pattern */
+ patl = calloc(1, sizeof(*patl));
+ if (!patl) {
+ memprintf(err, "out of memory while indexing pattern");
+ return 0;
+ }
- /* the "map_parser_str()" function always duplicate string information */
- free((*pattern)->pat.ptr.str);
- (*pattern)->pat.ptr.str = NULL;
+ /* 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';
- /* 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;
+ /* chain pattern in the expression */
+ LIST_ADDQ(&expr->patterns, &patl->list);
- /* index the new node */
- if (ebst_insert((*pattern)->pat.val.tree, &node->node) != &node->node)
- free(node); /* was a duplicate */
+ /* 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;
}
- else if (expr->match == pat_match_ip) {
- /* SMP_T_IPV4 tree indexation
- * The match "pat_match_ip()" can use tree.
- */
- if ((*pattern)->pat.type != SMP_T_IPV4) {
- /* Only IPv4 can be indexed */
- goto just_chain_the_pattern;
- }
+ /* 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 */
+ if (pat->type == SMP_T_IPV4) {
/* in IPv4 case, check if the mask is contiguous so that we can
* insert the network into the tree. A continuous mask has only
* ones on the left. This means that this mask + its lower bit
* added once again is null.
*/
- mask = ntohl((*pattern)->pat.val.ipv4.mask.s_addr);
- if (mask + (mask & -mask) != 0)
- goto just_chain_the_pattern;
- mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
-
- /* node memory allocation */
- node = calloc(1, sizeof(*node) + 4);
- if (!node) {
- memprintf(err, "out of memory while loading pattern");
- return 0;
- }
+ mask = ntohl(pat->val.ipv4.mask.s_addr);
+ if (mask + (mask & -mask) == 0) {
+ mask = mask ? 33 - flsnz(mask & -mask) : 0; /* equals cidr value */
- /* copy the pointer to sample associated to this node */
- node->smp = smp;
+ /* node memory allocation */
+ node = calloc(1, sizeof(*node) + 4);
+ if (!node) {
+ memprintf(err, "out of memory while loading pattern");
+ return 0;
+ }
- /* FIXME: insert <addr>/<mask> into the tree here */
- memcpy(node->node.key, &(*pattern)->pat.val.ipv4.addr, 4); /* network byte order */
+ /* copy the pointer to sample associated to this node */
+ node->smp = pat->smp;
- /* 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;
+ /* FIXME: insert <addr>/<mask> into the tree here */
+ memcpy(node->node.key, &pat->val.ipv4.addr, 4); /* network byte order */
+ node->node.node.pfx = mask;
+ if (ebmb_insert_prefix(&expr->pattern_tree, &node->node, 4) != &node->node)
+ free(node); /* was a duplicate */
- /* Index the new node
- * FIXME: insert <addr>/<mask> into the tree here
- */
- node->node.node.pfx = mask;
- if (ebmb_insert_prefix((*pattern)->pat.val.tree, &node->node, 4) != &node->node)
- free(node); /* was a duplicate */
+ /* that's ok */
+ return 1;
+ }
}
- 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 */
- (*pattern)->pat.smp = smp;
+ /* 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;
- /* get a new one */
- *pattern = NULL;
+ /* 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 = pat->smp;
+
+ /* copy the string */
+ 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;
}
FILE *file;
char *c;
char *arg;
- struct pattern_list *pattern;
int ret = 0;
int line = 0;
int code;
* line. If the line contains spaces, they will be part of the pattern.
* The pattern stops at the first CR, LF or EOF encountered.
*/
- pattern = NULL;
while (fgets(trash.str, trash.size, file) != NULL) {
line++;
c = trash.str;
if (c == arg)
continue;
- code = pattern_register(expr, arg, NULL, &pattern, patflags, err);
+ code = pattern_register(expr, arg, NULL, patflags, err);
if (code == -2) {
memprintf(err, "out of memory when loading patterns from file <%s>", filename);
goto out_close;
}
else if (code < 0) {
memprintf(err, "%s when loading patterns from file <%s>", *err, filename);
- goto out_free_pattern;
+ goto out_close;
}
}
ret = 1; /* success */
- out_free_pattern:
- pattern_free(pattern);
out_close:
fclose(file);
return ret;
* Please take care of keeping this list alphabetically sorted.
*/
static struct acl_kw_list acl_kws = {ILH, {
- { "payload", "req.payload", pat_parse_bin, pat_match_bin },
- { "payload_lv", "req.payload_lv", pat_parse_bin, pat_match_bin },
- { "req_rdp_cookie", "req.rdp_cookie", pat_parse_str, pat_match_str },
- { "req_rdp_cookie_cnt", "req.rdp_cookie_cnt", pat_parse_int, pat_match_int },
- { "req_ssl_sni", "req.ssl_sni", pat_parse_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_match_int },
+ { "payload", "req.payload", pat_parse_bin, pat_idx_list_ptr, 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_idx_tree_str, pat_match_str },
+ { "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_idx_tree_str, pat_match_str },
+ { "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_idx_list_val, pat_match_int },
{ /* END */ },
}};
* Please take care of keeping this list alphabetically sorted.
*/
static struct acl_kw_list acl_kws = {ILH, {
- { "base", "base", pat_parse_str, pat_match_str },
- { "base_beg", "base", pat_parse_str, pat_match_beg },
- { "base_dir", "base", pat_parse_str, pat_match_dir },
- { "base_dom", "base", pat_parse_str, pat_match_dom },
- { "base_end", "base", pat_parse_str, pat_match_end },
- { "base_len", "base", pat_parse_int, pat_match_len },
- { "base_reg", "base", pat_parse_reg, pat_match_reg },
- { "base_sub", "base", pat_parse_str, pat_match_sub },
-
- { "cook", "req.cook", pat_parse_str, pat_match_str },
- { "cook_beg", "req.cook", pat_parse_str, pat_match_beg },
- { "cook_dir", "req.cook", pat_parse_str, pat_match_dir },
- { "cook_dom", "req.cook", pat_parse_str, pat_match_dom },
- { "cook_end", "req.cook", pat_parse_str, pat_match_end },
- { "cook_len", "req.cook", pat_parse_int, pat_match_len },
- { "cook_reg", "req.cook", pat_parse_reg, pat_match_reg },
- { "cook_sub", "req.cook", pat_parse_str, pat_match_sub },
-
- { "hdr", "req.hdr", pat_parse_str, pat_match_str },
- { "hdr_beg", "req.hdr", pat_parse_str, pat_match_beg },
- { "hdr_dir", "req.hdr", pat_parse_str, pat_match_dir },
- { "hdr_dom", "req.hdr", pat_parse_str, pat_match_dom },
- { "hdr_end", "req.hdr", pat_parse_str, pat_match_end },
- { "hdr_len", "req.hdr", pat_parse_int, pat_match_len },
- { "hdr_reg", "req.hdr", pat_parse_reg, pat_match_reg },
- { "hdr_sub", "req.hdr", pat_parse_str, pat_match_sub },
-
- { "http_auth_group", NULL, pat_parse_str, pat_match_auth },
-
- { "method", NULL, pat_parse_meth, pat_match_meth },
-
- { "path", "path", pat_parse_str, pat_match_str },
- { "path_beg", "path", pat_parse_str, pat_match_beg },
- { "path_dir", "path", pat_parse_str, pat_match_dir },
- { "path_dom", "path", pat_parse_str, pat_match_dom },
- { "path_end", "path", pat_parse_str, pat_match_end },
- { "path_len", "path", pat_parse_int, pat_match_len },
- { "path_reg", "path", pat_parse_reg, pat_match_reg },
- { "path_sub", "path", pat_parse_str, pat_match_sub },
-
- { "req_ver", "req.ver", pat_parse_str, pat_match_str },
- { "resp_ver", "res.ver", pat_parse_str, pat_match_str },
-
- { "scook", "res.cook", pat_parse_str, pat_match_str },
- { "scook_beg", "res.cook", pat_parse_str, pat_match_beg },
- { "scook_dir", "res.cook", pat_parse_str, pat_match_dir },
- { "scook_dom", "res.cook", pat_parse_str, pat_match_dom },
- { "scook_end", "res.cook", pat_parse_str, pat_match_end },
- { "scook_len", "res.cook", pat_parse_int, pat_match_len },
- { "scook_reg", "res.cook", pat_parse_reg, pat_match_reg },
- { "scook_sub", "res.cook", pat_parse_str, pat_match_sub },
-
- { "shdr", "res.hdr", pat_parse_str, pat_match_str },
- { "shdr_beg", "res.hdr", pat_parse_str, pat_match_beg },
- { "shdr_dir", "res.hdr", pat_parse_str, pat_match_dir },
- { "shdr_dom", "res.hdr", pat_parse_str, pat_match_dom },
- { "shdr_end", "res.hdr", pat_parse_str, pat_match_end },
- { "shdr_len", "res.hdr", pat_parse_int, pat_match_len },
- { "shdr_reg", "res.hdr", pat_parse_reg, pat_match_reg },
- { "shdr_sub", "res.hdr", pat_parse_str, pat_match_sub },
-
- { "url", "url", pat_parse_str, pat_match_str },
- { "url_beg", "url", pat_parse_str, pat_match_beg },
- { "url_dir", "url", pat_parse_str, pat_match_dir },
- { "url_dom", "url", pat_parse_str, pat_match_dom },
- { "url_end", "url", pat_parse_str, pat_match_end },
- { "url_len", "url", pat_parse_int, pat_match_len },
- { "url_reg", "url", pat_parse_reg, pat_match_reg },
- { "url_sub", "url", pat_parse_str, pat_match_sub },
-
- { "urlp", "urlp", pat_parse_str, pat_match_str },
- { "urlp_beg", "urlp", pat_parse_str, pat_match_beg },
- { "urlp_dir", "urlp", pat_parse_str, pat_match_dir },
- { "urlp_dom", "urlp", pat_parse_str, pat_match_dom },
- { "urlp_end", "urlp", pat_parse_str, pat_match_end },
- { "urlp_len", "urlp", pat_parse_int, pat_match_len },
- { "urlp_reg", "urlp", pat_parse_reg, pat_match_reg },
- { "urlp_sub", "urlp", pat_parse_str, pat_match_sub },
+ { "base", "base", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "base_beg", "base", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "base_dir", "base", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "base_dom", "base", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "base_end", "base", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "base_len", "base", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "base_reg", "base", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "base_sub", "base", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "cook", "req.cook", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "cook_beg", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "cook_dir", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "cook_dom", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "cook_end", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "cook_len", "req.cook", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "cook_reg", "req.cook", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "cook_sub", "req.cook", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "hdr", "req.hdr", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "hdr_beg", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "hdr_dir", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "hdr_dom", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "hdr_end", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "hdr_len", "req.hdr", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "hdr_reg", "req.hdr", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "hdr_sub", "req.hdr", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "http_auth_group", NULL, pat_parse_str, pat_idx_list_str, pat_match_auth },
+
+ { "method", NULL, pat_parse_meth, pat_idx_list_str, pat_match_meth },
+
+ { "path", "path", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "path_beg", "path", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "path_dir", "path", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "path_dom", "path", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "path_end", "path", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "path_len", "path", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "path_reg", "path", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "path_sub", "path", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "req_ver", "req.ver", pat_parse_str, pat_idx_tree_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_idx_tree_str, pat_match_str },
+ { "scook_beg", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "scook_dir", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "scook_dom", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "scook_end", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "scook_len", "res.cook", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "scook_reg", "res.cook", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "scook_sub", "res.cook", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "shdr", "res.hdr", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "shdr_beg", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "shdr_dir", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "shdr_dom", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "shdr_end", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "shdr_len", "res.hdr", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "shdr_reg", "res.hdr", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "shdr_sub", "res.hdr", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "url", "url", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "url_beg", "url", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "url_dir", "url", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "url_dom", "url", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "url_end", "url", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "url_len", "url", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "url_reg", "url", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "url_sub", "url", pat_parse_str, pat_idx_list_str, pat_match_sub },
+
+ { "urlp", "urlp", pat_parse_str, pat_idx_tree_str, pat_match_str },
+ { "urlp_beg", "urlp", pat_parse_str, pat_idx_list_str, pat_match_beg },
+ { "urlp_dir", "urlp", pat_parse_str, pat_idx_list_str, pat_match_dir },
+ { "urlp_dom", "urlp", pat_parse_str, pat_idx_list_str, pat_match_dom },
+ { "urlp_end", "urlp", pat_parse_str, pat_idx_list_str, pat_match_end },
+ { "urlp_len", "urlp", pat_parse_int, pat_idx_list_val, pat_match_len },
+ { "urlp_reg", "urlp", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
+ { "urlp_sub", "urlp", pat_parse_str, pat_idx_list_str, pat_match_sub },
{ /* END */ },
}};
* Please take care of keeping this list alphabetically sorted.
*/
static struct acl_kw_list acl_kws = {ILH, {
- { "ssl_c_i_dn", NULL, pat_parse_str, pat_match_str },
- { "ssl_c_key_alg", NULL, pat_parse_str, pat_match_str },
- { "ssl_c_notafter", NULL, pat_parse_str, pat_match_str },
- { "ssl_c_notbefore", NULL, pat_parse_str, pat_match_str },
- { "ssl_c_sig_alg", NULL, pat_parse_str, pat_match_str },
- { "ssl_c_s_dn", NULL, pat_parse_str, pat_match_str },
- { "ssl_c_serial", NULL, pat_parse_bin, pat_match_bin },
- { "ssl_f_i_dn", NULL, pat_parse_str, pat_match_str },
- { "ssl_f_key_alg", NULL, pat_parse_str, pat_match_str },
- { "ssl_f_notafter", NULL, pat_parse_str, pat_match_str },
- { "ssl_f_notbefore", NULL, pat_parse_str, pat_match_str },
- { "ssl_f_sig_alg", NULL, pat_parse_str, pat_match_str },
- { "ssl_f_s_dn", NULL, pat_parse_str, pat_match_str },
- { "ssl_f_serial", NULL, pat_parse_bin, pat_match_bin },
- { "ssl_fc_cipher", 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_idx_tree_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_idx_tree_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_idx_tree_str, pat_match_str },
+ { "ssl_c_serial", NULL, pat_parse_bin, pat_idx_list_ptr, pat_match_bin },
+ { "ssl_f_i_dn", NULL, pat_parse_str, pat_idx_tree_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_idx_tree_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_idx_tree_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_idx_list_ptr, pat_match_bin },
+ { "ssl_fc_cipher", NULL, pat_parse_str, pat_idx_tree_str, pat_match_str },
#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
#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
- { "ssl_fc_protocol", NULL, pat_parse_str, pat_match_str },
- { "ssl_fc_sni", "ssl_fc_sni", pat_parse_str, pat_match_str },
- { "ssl_fc_sni_end", "ssl_fc_sni", pat_parse_str, pat_match_end },
- { "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_match_reg },
+ { "ssl_fc_protocol", NULL, pat_parse_str, pat_idx_tree_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_idx_list_str, pat_match_end },
+ { "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_idx_list_reg, pat_match_reg },
{ /* END */ },
}};