From bef91e7144efe6ce65f627c0ae94af2e7593f7f5 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 31 Mar 2013 23:14:46 +0200 Subject: [PATCH] MEDIUM: acl: support using sample fetches directly in ACLs Now it becomes possible to directly use sample fetches as the ACL fetch methods. In this case, the matching method is mandatory. This allows to form more ACL combinations from existing fetches and will limit the need for new ACLs when everything is available to form them from sample fetches and matches. --- doc/configuration.txt | 8 ++++++++ src/acl.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index da287f37f8..0b14d0ef0a 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -8288,6 +8288,14 @@ following situations : 7.5. Available matching criteria -------------------------------- +A number of predefined criteria may be used to form ACL expressions. The ones +that are ACL-specific are detailed here. In addition to these ones, all sample +fetch methods described in section 7.8 may be used. However, with these last +ones, no default pattern matching method is defined, so it is mandatory to pass +"-m" followed by a method. When a same keyword exists in both forms, the ACL +compatible form prevails. + + 7.5.1. Matching at Layer 4 and below ------------------------------------ diff --git a/src/acl.c b/src/acl.c index 50772733f3..4a53072024 100644 --- a/src/acl.c +++ b/src/acl.c @@ -1037,11 +1037,24 @@ struct acl_expr *parse_acl_expr(const char **args, char **err) struct acl_pattern *pattern; int opaque, patflags; const char *arg; + struct sample_fetch *smp = NULL; + /* First, we lookd for an ACL keyword. And if we don't find one, then + * we look for a sample fetch keyword. + */ aclkw = find_acl_kw(args[0]); if (!aclkw || !aclkw->parse) { - memprintf(err, "unknown ACL keyword '%s'", *args); - goto out_return; + const char *kwend; + + kwend = strchr(args[0], '('); + if (!kwend) + kwend = args[0] + strlen(args[0]); + smp = find_sample_fetch(args[0], kwend - args[0]); + + if (!smp) { + memprintf(err, "unknown ACL or sample keyword '%s'", *args); + goto out_return; + } } expr = (struct acl_expr *)calloc(1, sizeof(*expr)); @@ -1050,13 +1063,13 @@ struct acl_expr *parse_acl_expr(const char **args, char **err) goto out_return; } - expr->kw = aclkw->kw; + expr->kw = aclkw ? aclkw->kw : smp->kw; LIST_INIT(&expr->patterns); expr->pattern_tree = EB_ROOT_UNIQUE; - expr->parse = aclkw->parse; - expr->match = aclkw->match; + expr->parse = aclkw ? aclkw->parse : NULL; + expr->match = aclkw ? aclkw->match : NULL; expr->args = empty_arg_list; - expr->smp = aclkw->smp; + expr->smp = aclkw ? aclkw->smp : smp; arg = strchr(args[0], '('); if (expr->smp->arg_mask) { @@ -1146,6 +1159,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err) if ((*args)[1] == 'i') patflags |= ACL_PAT_F_IGNORE_CASE; else if ((*args)[1] == 'f') { + if (!expr->parse) { + memprintf(err, "matching method must be specified first (using '-m') when using a sample fetch ('%s')", expr->kw); + goto out_free_expr; + } + if (!acl_read_patterns_from_file(expr, args[1], patflags | ACL_PAT_F_FROM_FILE, err)) goto out_free_expr; args++; @@ -1198,6 +1216,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err) args++; } + if (!expr->parse) { + memprintf(err, "matching method must be specified first (using '-m') when using a sample fetch ('%s')", expr->kw); + goto out_free_expr; + } + /* now parse all patterns */ opaque = 0; while (**args) { -- 2.39.5