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.
This commit is contained in:
Willy Tarreau 2013-03-31 23:14:46 +02:00
parent 93fddf1dbc
commit bef91e7144
2 changed files with 37 additions and 6 deletions

View File

@ -8288,6 +8288,14 @@ following situations :
7.5. Available matching criteria 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 7.5.1. Matching at Layer 4 and below
------------------------------------ ------------------------------------

View File

@ -1037,11 +1037,24 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
struct acl_pattern *pattern; struct acl_pattern *pattern;
int opaque, patflags; int opaque, patflags;
const char *arg; 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]); aclkw = find_acl_kw(args[0]);
if (!aclkw || !aclkw->parse) { if (!aclkw || !aclkw->parse) {
memprintf(err, "unknown ACL keyword '%s'", *args); const char *kwend;
goto out_return;
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)); 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; goto out_return;
} }
expr->kw = aclkw->kw; expr->kw = aclkw ? aclkw->kw : smp->kw;
LIST_INIT(&expr->patterns); LIST_INIT(&expr->patterns);
expr->pattern_tree = EB_ROOT_UNIQUE; expr->pattern_tree = EB_ROOT_UNIQUE;
expr->parse = aclkw->parse; expr->parse = aclkw ? aclkw->parse : NULL;
expr->match = aclkw->match; expr->match = aclkw ? aclkw->match : NULL;
expr->args = empty_arg_list; expr->args = empty_arg_list;
expr->smp = aclkw->smp; expr->smp = aclkw ? aclkw->smp : smp;
arg = strchr(args[0], '('); arg = strchr(args[0], '(');
if (expr->smp->arg_mask) { if (expr->smp->arg_mask) {
@ -1146,6 +1159,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
if ((*args)[1] == 'i') if ((*args)[1] == 'i')
patflags |= ACL_PAT_F_IGNORE_CASE; patflags |= ACL_PAT_F_IGNORE_CASE;
else if ((*args)[1] == 'f') { 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)) if (!acl_read_patterns_from_file(expr, args[1], patflags | ACL_PAT_F_FROM_FILE, err))
goto out_free_expr; goto out_free_expr;
args++; args++;
@ -1198,6 +1216,11 @@ struct acl_expr *parse_acl_expr(const char **args, char **err)
args++; 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 */ /* now parse all patterns */
opaque = 0; opaque = 0;
while (**args) { while (**args) {