diff --git a/include/types/acl.h b/include/types/acl.h index ed8582b7c..492e9639f 100644 --- a/include/types/acl.h +++ b/include/types/acl.h @@ -181,9 +181,16 @@ struct acl_time { int h2:5, m2:6; /* 0..24:0..60. Use 24:0 for all day. */ }; -/* The acl will be linked to from the proxy where it is declared */ +/* This describes one ACL pattern, which might be a single value or a tree of + * values. All patterns for a single ACL expression are linked together. Some + * of them might have a type (eg: IP). Right now, the types are shared with + * the samples, though it is possible that in the future this will change to + * accommodate for other types (eg: meth, regex). Unsigned and constant types + * are preferred when there is a doubt. + */ struct acl_pattern { struct list list; /* chaining */ + int type; /* type of the ACL pattern (SMP_T_*) */ union { int i; /* integer value */ struct { @@ -209,14 +216,13 @@ struct acl_pattern { int flags; /* expr or pattern flags. */ }; -/* - * ACL keyword: Associates keywords with parsers, methods to retrieve the value and testers. - */ - /* some dummy declarations to silent the compiler */ struct proxy; struct session; +/* + * ACL keyword: Associates keywords with parsers, methods to retrieve the value and testers. + */ /* * NOTE: * The 'parse' function is called to parse words in the configuration. It must @@ -268,6 +274,7 @@ struct acl_expr { struct eb_root pattern_tree; /* may be used for lookup in large datasets */ }; +/* The acl will be linked to from the proxy where it is declared */ struct acl { struct list list; /* chaining */ char *name; /* acl name */ diff --git a/src/acl.c b/src/acl.c index a1346b8c8..013820364 100644 --- a/src/acl.c +++ b/src/acl.c @@ -709,7 +709,7 @@ int acl_match_ip(struct sample *smp, struct acl_pattern *pattern) { struct in_addr *s; - if (smp->type != SMP_T_IPV4) + if (smp->type != SMP_T_IPV4 || pattern->type != SMP_T_IPV4) return ACL_PAT_FAIL; s = &smp->data.ipv4; @@ -738,6 +738,7 @@ int acl_parse_str(const char **text, struct acl_pattern *pattern, int *opaque, c int len; len = strlen(*text); + pattern->type = SMP_T_CSTR; if (pattern->flags & ACL_PAT_F_TREE_OK) { /* we're allowed to put the data in a tree whose root is pointed @@ -779,6 +780,7 @@ acl_parse_strcat(const char **text, struct acl_pattern *pattern, int *opaque, ch for (i = 0; *text[i]; i++) len += strlen(text[i])+1; + pattern->type = SMP_T_CSTR; pattern->ptr.str = s = calloc(1, len); if (!pattern->ptr.str) { if (err) @@ -847,7 +849,7 @@ int acl_parse_int(const char **text, struct acl_pattern *pattern, int *opaque, c unsigned int j, last, skip = 0; const char *ptr = *text; - + pattern->type = SMP_T_UINT; while (!isdigit((unsigned char)*ptr)) { switch (get_std_op(ptr)) { case STD_OP_EQ: *opaque = 0; break; @@ -1023,7 +1025,7 @@ int acl_parse_dotted_ver(const char **text, struct acl_pattern *pattern, int *op /* Parse an IP address and an optional mask in the form addr[/mask]. * The addr may either be an IPv4 address or a hostname. The mask * may either be a dotted mask or a number of bits. Returns 1 if OK, - * otherwise 0. + * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6). */ int acl_parse_ip(const char **text, struct acl_pattern *pattern, int *opaque, char **err) { @@ -1031,6 +1033,7 @@ int acl_parse_ip(const char **text, struct acl_pattern *pattern, int *opaque, ch if (pattern->flags & ACL_PAT_F_TREE_OK) tree = pattern->val.tree; + pattern->type = SMP_T_IPV4; if (str2net(*text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) { unsigned int mask = ntohl(pattern->val.ipv4.mask.s_addr); struct ebmb_node *node; @@ -1248,6 +1251,7 @@ static int acl_read_patterns_from_file( struct acl_keyword *aclkw, pattern->val.tree = &expr->pattern_tree; } + pattern->type = SMP_TYPES; /* unspecified type by default */ if (!aclkw->parse(args, pattern, &opaque, err)) goto out_free_pattern; @@ -1416,6 +1420,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err) } pattern->flags = patflags; + pattern->type = SMP_TYPES; /* unspecified type */ ret = aclkw->parse(args, pattern, &opaque, err); if (!ret) goto out_free_pattern;