MINOR: acl: add types to ACL patterns

We cannot currently match IPv6 addresses in ACL simply because we don't
support types on the patterns. Let's introduce this notion. For now, we
rely on the SMP_TYPES though it doesn't seem like it will last forever
given that some types are not present there (eg: regex, meth). Still it
should be enough to support mixed matchings for most types.

We use the special impossible value SMP_TYPES for types that don't exist
in the SMP_T_* space.
This commit is contained in:
Willy Tarreau 2012-04-27 22:10:57 +02:00
parent cd3b094618
commit c92ddbc37d
2 changed files with 20 additions and 8 deletions

View File

@ -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 */

View File

@ -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;