MAJOR: acl: make use of the new argument parsing framework

The ACL parser now uses the argument parser to build a typed argument list.
Right now arguments are all strings and only one argument is supported since
this is what ACLs currently support.
This commit is contained in:
Willy Tarreau
2012-04-19 17:16:54 +02:00
parent 2ac5718dbd
commit 34db108423
7 changed files with 224 additions and 116 deletions

View File

@ -2,7 +2,7 @@
* include/types/acl.h * include/types/acl.h
* This file provides structures and types for ACLs. * This file provides structures and types for ACLs.
* *
* Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu * Copyright (C) 2000-2012 Willy Tarreau - w@1wt.eu
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -26,6 +26,7 @@
#include <common/config.h> #include <common/config.h>
#include <common/mini-clist.h> #include <common/mini-clist.h>
#include <types/arg.h>
#include <types/auth.h> #include <types/auth.h>
#include <types/proxy.h> #include <types/proxy.h>
#include <types/server.h> #include <types/server.h>
@ -302,12 +303,7 @@ struct acl_kw_list {
struct acl_expr { struct acl_expr {
struct list list; /* chaining */ struct list list; /* chaining */
struct acl_keyword *kw; /* back-reference to the keyword */ struct acl_keyword *kw; /* back-reference to the keyword */
union { /* optional argument of the subject (eg: header or cookie name) */ struct arg *args; /* optional argument list (eg: header or cookie name) */
char *str;
struct userlist *ul;
struct server *srv; /* must be initialised by acl_find_targets */
} arg;
int arg_len; /* optional argument length */
struct list patterns; /* list of acl_patterns */ struct list patterns; /* list of acl_patterns */
struct eb_root pattern_tree; /* may be used for lookup in large datasets */ struct eb_root pattern_tree; /* may be used for lookup in large datasets */
}; };

View File

@ -22,6 +22,7 @@
#include <types/global.h> #include <types/global.h>
#include <proto/acl.h> #include <proto/acl.h>
#include <proto/arg.h>
#include <proto/auth.h> #include <proto/auth.h>
#include <proto/buffers.h> #include <proto/buffers.h>
#include <proto/log.h> #include <proto/log.h>
@ -446,6 +447,8 @@ acl_fetch_ssl_hello_sni(struct proxy *px, struct session *l4, void *l7, int dir,
/* Fetch the RDP cookie identified in the expression. /* Fetch the RDP cookie identified in the expression.
* Note: this decoder only works with non-wrapping data. * Note: this decoder only works with non-wrapping data.
* Accepts either 0 or 1 argument. Argument is a string (cookie name), other
* types will lead to undefined behaviour.
*/ */
int int
acl_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
@ -480,17 +483,17 @@ acl_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
bleft--; bleft--;
} }
if (expr->arg_len) { if (expr->args) {
if (bleft <= expr->arg_len) if (bleft <= expr->args->data.str.len)
goto too_short; goto too_short;
if ((data[expr->arg_len] != '=') || if ((data[expr->args->data.str.len] != '=') ||
strncasecmp(expr->arg.str, (const char *)data, expr->arg_len) != 0) strncasecmp(expr->args->data.str.str, (const char *)data, expr->args->data.str.len) != 0)
goto not_cookie; goto not_cookie;
data += expr->arg_len + 1; data += expr->args->data.str.len + 1;
bleft -= expr->arg_len + 1; bleft -= expr->args->data.str.len + 1;
} else { } else {
while (bleft > 0 && *data != '=') { while (bleft > 0 && *data != '=') {
if (*data == '\r' || *data == '\n') if (*data == '\r' || *data == '\n')
@ -1241,11 +1244,25 @@ static void free_pattern_tree(struct eb_root *root)
static struct acl_expr *prune_acl_expr(struct acl_expr *expr) static struct acl_expr *prune_acl_expr(struct acl_expr *expr)
{ {
struct arg *arg;
free_pattern_list(&expr->patterns); free_pattern_list(&expr->patterns);
free_pattern_tree(&expr->pattern_tree); free_pattern_tree(&expr->pattern_tree);
LIST_INIT(&expr->patterns); LIST_INIT(&expr->patterns);
if (expr->arg_len && expr->arg.str)
free(expr->arg.str); for (arg = expr->args; arg; arg++) {
if (arg->type == ARGT_STOP)
break;
if (arg->type == ARGT_FE || arg->type == ARGT_BE ||
arg->type == ARGT_TAB || arg->type == ARGT_SRV ||
arg->type == ARGT_USR || arg->type == ARGT_STR) {
free(arg->data.str.str);
arg->data.str.str = NULL;
}
arg++;
}
free(expr->args);
expr->kw->use_cnt--; expr->kw->use_cnt--;
return expr; return expr;
} }
@ -1355,22 +1372,26 @@ struct acl_expr *parse_acl_expr(const char **args)
aclkw->use_cnt++; aclkw->use_cnt++;
LIST_INIT(&expr->patterns); LIST_INIT(&expr->patterns);
expr->pattern_tree = EB_ROOT_UNIQUE; expr->pattern_tree = EB_ROOT_UNIQUE;
expr->arg.str = NULL;
expr->arg_len = 0;
arg = strchr(args[0], '('); arg = strchr(args[0], '(');
if (arg != NULL) { if (arg != NULL) {
char *end, *arg2; char *end;
/* there is an argument in the form "subject(arg)" */ int nbargs;
/* there is an argument in the form "subject(arg[,arg]*)" */
arg++; arg++;
end = strchr(arg, ')'); end = strchr(arg, ')');
if (!end) if (!end)
goto out_free_expr; goto out_free_expr;
arg2 = my_strndup(arg, end - arg);
if (!arg2) /* Parse the arguments. Note that currently we have no way to
* report parsing errors, hence the NULL in the error pointers.
* At the moment only one string arg is supported.
*/
nbargs = make_arg_list(arg, end - arg, ARG1(STR), &expr->args,
NULL, NULL, NULL);
if (nbargs < 0)
goto out_free_expr; goto out_free_expr;
expr->arg_len = end - arg;
expr->arg.str = arg2;
} }
args++; args++;
@ -1935,14 +1956,17 @@ acl_find_targets(struct proxy *p)
struct server *srv; struct server *srv;
char *pname, *sname; char *pname, *sname;
if (!expr->arg.str || !*expr->arg.str) { /* FIXME: at the moment we check argument types from the keyword,
* but later we'll simlpy inspect argument types.
*/
if (!expr->args || !expr->args->data.str.len) {
Alert("proxy %s: acl %s %s(): missing server name.\n", Alert("proxy %s: acl %s %s(): missing server name.\n",
p->id, acl->name, expr->kw->kw); p->id, acl->name, expr->kw->kw);
cfgerr++; cfgerr++;
continue; continue;
} }
pname = expr->arg.str; pname = expr->args->data.str.str;
sname = strrchr(pname, '/'); sname = strrchr(pname, '/');
if (sname) if (sname)
@ -1971,15 +1995,17 @@ acl_find_targets(struct proxy *p)
continue; continue;
} }
free(expr->arg.str); free(expr->args->data.str.str);
expr->arg_len = 0; expr->args->data.srv = srv;
expr->arg.srv = srv;
continue; continue;
} }
if (strstr(expr->kw->kw, "http_auth") == expr->kw->kw) { if (strstr(expr->kw->kw, "http_auth") == expr->kw->kw) {
if (!expr->arg.str || !*expr->arg.str) { /* FIXME: at the moment we check argument types from the keyword,
* but later we'll simlpy inspect argument types.
*/
if (!expr->args || !expr->args->data.str.len) {
Alert("proxy %s: acl %s %s(): missing userlist name.\n", Alert("proxy %s: acl %s %s(): missing userlist name.\n",
p->id, acl->name, expr->kw->kw); p->id, acl->name, expr->kw->kw);
cfgerr++; cfgerr++;
@ -1987,20 +2013,20 @@ acl_find_targets(struct proxy *p)
} }
if (p->uri_auth && p->uri_auth->userlist && if (p->uri_auth && p->uri_auth->userlist &&
!strcmp(p->uri_auth->userlist->name, expr->arg.str)) !strcmp(p->uri_auth->userlist->name, expr->args->data.str.str))
ul = p->uri_auth->userlist; ul = p->uri_auth->userlist;
else else
ul = auth_find_userlist(expr->arg.str); ul = auth_find_userlist(expr->args->data.str.str);
if (!ul) { if (!ul) {
Alert("proxy %s: acl %s %s(%s): unable to find userlist.\n", Alert("proxy %s: acl %s %s(%s): unable to find userlist.\n",
p->id, acl->name, expr->kw->kw, expr->arg.str); p->id, acl->name, expr->kw->kw, expr->args->data.str.str);
cfgerr++; cfgerr++;
continue; continue;
} }
expr->arg_len = 0; free(expr->args->data.str.str);
expr->arg.ul = ul; expr->args->data.usr = ul;
} }
@ -2014,7 +2040,7 @@ acl_find_targets(struct proxy *p)
} }
list_for_each_entry(pattern, &expr->patterns, list) { list_for_each_entry(pattern, &expr->patterns, list) {
pattern->val.group_mask = auth_resolve_groups(expr->arg.ul, pattern->ptr.str); pattern->val.group_mask = auth_resolve_groups(expr->args->data.usr, pattern->ptr.str);
free(pattern->ptr.str); free(pattern->ptr.str);
pattern->ptr.str = NULL; pattern->ptr.str = NULL;

View File

@ -28,6 +28,7 @@
#include <types/global.h> #include <types/global.h>
#include <proto/acl.h> #include <proto/acl.h>
#include <proto/arg.h>
#include <proto/backend.h> #include <proto/backend.h>
#include <proto/frontend.h> #include <proto/frontend.h>
#include <proto/lb_chash.h> #include <proto/lb_chash.h>
@ -393,6 +394,7 @@ struct server *get_server_hh(struct session *s)
return map_get_server_hash(px, hash); return map_get_server_hash(px, hash);
} }
/* RDP Cookie HASH. */
struct server *get_server_rch(struct session *s) struct server *get_server_rch(struct session *s)
{ {
unsigned long hash = 0; unsigned long hash = 0;
@ -402,6 +404,7 @@ struct server *get_server_rch(struct session *s)
int ret; int ret;
struct acl_expr expr; struct acl_expr expr;
struct acl_test test; struct acl_test test;
struct arg args[2];
/* tot_weight appears to mean srv_count */ /* tot_weight appears to mean srv_count */
if (px->lbprm.tot_weight == 0) if (px->lbprm.tot_weight == 0)
@ -410,8 +413,12 @@ struct server *get_server_rch(struct session *s)
memset(&expr, 0, sizeof(expr)); memset(&expr, 0, sizeof(expr));
memset(&test, 0, sizeof(test)); memset(&test, 0, sizeof(test));
expr.arg.str = px->hh_name; args[0].type = ARGT_STR;
expr.arg_len = px->hh_len; args[0].data.str.str = px->hh_name;
args[0].data.str.len = px->hh_len;
args[1].type = ARGT_STOP;
expr.args = args;
ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test); ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
len = temp_pattern.data.str.len; len = temp_pattern.data.str.len;
@ -1111,6 +1118,7 @@ int tcp_persist_rdp_cookie(struct session *s, struct buffer *req, int an_bit)
struct server *srv = px->srv; struct server *srv = px->srv;
struct sockaddr_in addr; struct sockaddr_in addr;
char *p; char *p;
struct arg args[2];
DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n", DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
now_ms, __FUNCTION__, now_ms, __FUNCTION__,
@ -1127,8 +1135,12 @@ int tcp_persist_rdp_cookie(struct session *s, struct buffer *req, int an_bit)
memset(&expr, 0, sizeof(expr)); memset(&expr, 0, sizeof(expr));
memset(&test, 0, sizeof(test)); memset(&test, 0, sizeof(test));
expr.arg.str = s->be->rdp_cookie_name; args[0].type = ARGT_STR;
expr.arg_len = s->be->rdp_cookie_len; args[0].data.str.str = s->be->rdp_cookie_name;
args[0].data.str.len = s->be->rdp_cookie_len;
args[1].type = ARGT_STOP;
expr.args = args;
ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test); ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0) if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)
@ -1365,16 +1377,19 @@ int backend_parse_balance(const char **args, char *err, int errlen, struct proxy
/* All supported keywords must be declared here. */ /* All supported keywords must be declared here. */
/************************************************************************/ /************************************************************************/
/* set temp integer to the number of enabled servers on the proxy */ /* set temp integer to the number of enabled servers on the proxy.
* Accepts either 0 or 1 argument. Argument is a string, other types will lead to
* undefined behaviour.
*/
static int static int
acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -1392,12 +1407,14 @@ acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, int dir,
/* report in test->flags a success or failure depending on the designated /* report in test->flags a success or failure depending on the designated
* server's state. There is no match function involved since there's no pattern. * server's state. There is no match function involved since there's no pattern.
* Accepts exactly 1 argument. Argument is a server, other types will lead to
* undefined behaviour.
*/ */
static int static int
acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
struct server *srv = expr->arg.srv; struct server *srv = expr->args->data.srv;
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (!(srv->state & SRV_MAINTAIN) && if (!(srv->state & SRV_MAINTAIN) &&
@ -1408,17 +1425,20 @@ acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the number of enabled servers on the proxy */ /* set temp integer to the number of enabled servers on the proxy.
* Accepts either 0 or 1 argument. Argument is a string, other types will lead to
* undefined behaviour.
*/
static int static int
acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
struct server *iterator; struct server *iterator;
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -1470,16 +1490,19 @@ acl_fetch_srv_id(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the number of connections per second reaching the backend */ /* set temp integer to the number of connections per second reaching the backend.
* Accepts either 0 or 1 argument. Argument is a string, other types will lead to
* undefined behaviour.
*/
static int static int
acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -1489,16 +1512,19 @@ acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the number of concurrent connections on the backend */ /* set temp integer to the number of concurrent connections on the backend.
* Accepts either 0 or 1 argument. Argument is a string, other types will lead to
* undefined behaviour.
*/
static int static int
acl_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -1508,16 +1534,19 @@ acl_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the total number of queued connections on the backend */ /* set temp integer to the total number of queued connections on the backend.
* Accepts either 0 or 1 argument. Argument is a string, other types will lead to
* undefined behaviour.
*/
static int static int
acl_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -1532,6 +1561,8 @@ acl_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
* server, we return twice the total, just as if we had half a running server. * server, we return twice the total, just as if we had half a running server.
* This is more or less correct anyway, since we expect the last server to come * This is more or less correct anyway, since we expect the last server to come
* back soon. * back soon.
* Accepts either 0 or 1 argument. Argument is a string, other types will lead to
* undefined behaviour.
*/ */
static int static int
acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
@ -1540,10 +1571,10 @@ acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir
int nbsrv; int nbsrv;
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -1564,12 +1595,15 @@ acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir
return 1; return 1;
} }
/* set temp integer to the number of concurrent connections on the server in the backend */ /* set temp integer to the number of concurrent connections on the server in the backend.
* Accepts exactly 1 argument. Argument is a server, other types will lead to
* undefined behaviour.
*/
static int static int
acl_fetch_srv_conn(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_srv_conn(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
struct server *srv = expr->arg.srv; struct server *srv = expr->args->data.srv;
temp_pattern.data.integer = srv->cur_sess; temp_pattern.data.integer = srv->cur_sess;
return 1; return 1;

View File

@ -506,16 +506,19 @@ acl_fetch_fe_id(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the number of connections per second reaching the frontend */ /* set temp integer to the number of connections per second reaching the frontend.
* Accepts either 0 or 1 argument. Argument is a string, other types will cause
* an undefined behaviour.
*/
static int static int
acl_fetch_fe_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_fe_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_FE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_FE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)
@ -525,16 +528,19 @@ acl_fetch_fe_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the number of concurrent connections on the frontend */ /* set temp integer to the number of concurrent connections on the frontend
* Accepts either 0 or 1 argument. Argument is a string, other types will cause
* an undefined behaviour.
*/
static int static int
acl_fetch_fe_conn(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_fe_conn(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
test->flags = ACL_TEST_F_VOL_TEST; test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) { if (expr->args) {
/* another proxy was designated, we must look for it */ /* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next) for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_FE) && !strcmp(px->id, expr->arg.str)) if ((px->cap & PR_CAP_FE) && !strcmp(px->id, expr->args->data.str.str))
break; break;
} }
if (!px) if (!px)

View File

@ -7836,6 +7836,7 @@ acl_fetch_url_port(struct proxy *px, struct session *l4, void *l7, int dir,
} }
/* 5. Check on HTTP header. A pointer to the beginning of the value is returned. /* 5. Check on HTTP header. A pointer to the beginning of the value is returned.
* Accepts exactly 1 argument of type string.
*/ */
static int static int
acl_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir,
@ -7846,13 +7847,16 @@ acl_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir,
struct hdr_ctx *ctx = (struct hdr_ctx *)test->ctx.a; struct hdr_ctx *ctx = (struct hdr_ctx *)test->ctx.a;
const struct http_msg *msg = ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) ? &txn->req : &txn->rsp; const struct http_msg *msg = ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) ? &txn->req : &txn->rsp;
if (!expr->args || expr->args->type != ARGT_STR)
return 0;
CHECK_HTTP_MESSAGE_FIRST(); CHECK_HTTP_MESSAGE_FIRST();
if (!(test->flags & ACL_TEST_F_FETCH_MORE)) if (!(test->flags & ACL_TEST_F_FETCH_MORE))
/* search for header from the beginning */ /* search for header from the beginning */
ctx->idx = 0; ctx->idx = 0;
if (http_find_header2(expr->arg.str, expr->arg_len, msg->buf->p + msg->sol, idx, ctx)) { if (http_find_header2(expr->args->data.str.str, expr->args->data.str.len, msg->buf->p + msg->sol, idx, ctx)) {
test->flags |= ACL_TEST_F_FETCH_MORE; test->flags |= ACL_TEST_F_FETCH_MORE;
test->flags |= ACL_TEST_F_VOL_HDR; test->flags |= ACL_TEST_F_VOL_HDR;
temp_pattern.data.str.str = (char *)ctx->line + ctx->val; temp_pattern.data.str.str = (char *)ctx->line + ctx->val;
@ -7867,6 +7871,7 @@ acl_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir,
} }
/* 6. Check on HTTP header count. The number of occurrences is returned. /* 6. Check on HTTP header count. The number of occurrences is returned.
* Accepts exactly 1 argument of type string.
*/ */
static int static int
acl_fetch_hdr_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_hdr_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -7878,11 +7883,14 @@ acl_fetch_hdr_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
const struct http_msg *msg = ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) ? &txn->req : &txn->rsp; const struct http_msg *msg = ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) ? &txn->req : &txn->rsp;
int cnt; int cnt;
if (!expr->args || expr->args->type != ARGT_STR)
return 0;
CHECK_HTTP_MESSAGE_FIRST(); CHECK_HTTP_MESSAGE_FIRST();
ctx.idx = 0; ctx.idx = 0;
cnt = 0; cnt = 0;
while (http_find_header2(expr->arg.str, expr->arg_len, msg->buf->p + msg->sol, idx, &ctx)) while (http_find_header2(expr->args->data.str.str, expr->args->data.str.len, msg->buf->p + msg->sol, idx, &ctx))
cnt++; cnt++;
temp_pattern.data.integer = cnt; temp_pattern.data.integer = cnt;
@ -7982,17 +7990,21 @@ acl_fetch_http_first_req(struct proxy *px, struct session *s, void *l7, int dir,
return 1; return 1;
} }
/* Accepts exactly 1 argument of type userlist */
static int static int
acl_fetch_http_auth(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_http_auth(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
if (!expr->args || expr->args->type != ARGT_USR)
return 0;
CHECK_HTTP_MESSAGE_FIRST(); CHECK_HTTP_MESSAGE_FIRST();
if (!get_http_auth(l4)) if (!get_http_auth(l4))
return 0; return 0;
test->ctx.a[0] = expr->arg.ul; test->ctx.a[0] = expr->args->data.usr;
test->ctx.a[1] = l4->txn.auth.user; test->ctx.a[1] = l4->txn.auth.user;
test->ctx.a[2] = l4->txn.auth.pass; test->ctx.a[2] = l4->txn.auth.pass;
@ -8100,7 +8112,8 @@ extract_cookie_value(char *hdr, const char *hdr_end,
* test->ctx.a[0] for the in-header position, test->ctx.a[1] for the * test->ctx.a[0] for the in-header position, test->ctx.a[1] for the
* end-of-header-value, and test->ctx.a[2] for the hdr_idx. Depending on * end-of-header-value, and test->ctx.a[2] for the hdr_idx. Depending on
* the direction, multiple cookies may be parsed on the same line or not. * the direction, multiple cookies may be parsed on the same line or not.
* The cookie name is in expr->arg and the name length in expr->arg_len. * The cookie name is in expr->arg and the name length in expr->args->data.str.len.
* Accepts exactly 1 argument of type string.
*/ */
static int static int
acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir,
@ -8114,6 +8127,9 @@ acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir,
int hdr_name_len; int hdr_name_len;
char *sol; char *sol;
if (!expr->args || expr->args->type != ARGT_STR)
return 0;
CHECK_HTTP_MESSAGE_FIRST(); CHECK_HTTP_MESSAGE_FIRST();
if ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) { if ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) {
@ -8141,7 +8157,7 @@ acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir,
if (!http_find_header2(hdr_name, hdr_name_len, sol, idx, ctx)) if (!http_find_header2(hdr_name, hdr_name_len, sol, idx, ctx))
goto out; goto out;
if (ctx->vlen < expr->arg_len + 1) if (ctx->vlen < expr->args->data.str.len + 1)
continue; continue;
test->ctx.a[0] = ctx->line + ctx->val; test->ctx.a[0] = ctx->line + ctx->val;
@ -8149,7 +8165,7 @@ acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir,
} }
test->ctx.a[0] = extract_cookie_value(test->ctx.a[0], test->ctx.a[1], test->ctx.a[0] = extract_cookie_value(test->ctx.a[0], test->ctx.a[1],
expr->arg.str, expr->arg_len, expr->args->data.str.str, expr->args->data.str.len,
(dir & ACL_DIR_MASK) == ACL_DIR_REQ, (dir & ACL_DIR_MASK) == ACL_DIR_REQ,
&temp_pattern.data.str.str, &temp_pattern.data.str.str,
&temp_pattern.data.str.len); &temp_pattern.data.str.len);
@ -8168,8 +8184,9 @@ acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir,
} }
/* Iterate over all cookies present in a request to count how many occurrences /* Iterate over all cookies present in a request to count how many occurrences
* match the name in expr->arg and expr->arg_len. If <multi> is non-null, then * match the name in expr->arg and expr->args->data.str.len. If <multi> is non-null, then
* multiple cookies may be parsed on the same line. * multiple cookies may be parsed on the same line.
* Accepts exactly 1 argument of type string.
*/ */
static int static int
acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -8185,6 +8202,9 @@ acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
char *val_beg, *val_end; char *val_beg, *val_end;
char *sol; char *sol;
if (!expr->args || expr->args->type != ARGT_STR)
return 0;
CHECK_HTTP_MESSAGE_FIRST(); CHECK_HTTP_MESSAGE_FIRST();
if ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) { if ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) {
@ -8208,7 +8228,7 @@ acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
if (!http_find_header2(hdr_name, hdr_name_len, sol, idx, &ctx)) if (!http_find_header2(hdr_name, hdr_name_len, sol, idx, &ctx))
break; break;
if (ctx.vlen < expr->arg_len + 1) if (ctx.vlen < expr->args->data.str.len + 1)
continue; continue;
val_beg = ctx.line + ctx.val; val_beg = ctx.line + ctx.val;
@ -8216,7 +8236,7 @@ acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
} }
while ((val_beg = extract_cookie_value(val_beg, val_end, while ((val_beg = extract_cookie_value(val_beg, val_end,
expr->arg.str, expr->arg_len, expr->args->data.str.str, expr->args->data.str.len,
(dir & ACL_DIR_MASK) == ACL_DIR_REQ, (dir & ACL_DIR_MASK) == ACL_DIR_REQ,
&temp_pattern.data.str.str, &temp_pattern.data.str.str,
&temp_pattern.data.str.len))) { &temp_pattern.data.str.len))) {

View File

@ -1569,6 +1569,7 @@ pattern_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir
int ret; int ret;
struct acl_expr expr; struct acl_expr expr;
struct acl_test test; struct acl_test test;
struct arg args[2];
if (!l4) if (!l4)
return 0; return 0;
@ -1576,8 +1577,12 @@ pattern_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir
memset(&expr, 0, sizeof(expr)); memset(&expr, 0, sizeof(expr));
memset(&test, 0, sizeof(test)); memset(&test, 0, sizeof(test));
expr.arg.str = arg_p[0].data.str.str; args[0].type = ARGT_STR;
expr.arg_len = arg_p[0].data.str.len; args[0].data.str.str = arg_p[0].data.str.str;
args[0].data.str.len = arg_p[0].data.str.len;
args[1].type = ARGT_STOP;
expr.args = args;
ret = acl_fetch_rdp_cookie(px, l4, NULL, ACL_DIR_REQ, &expr, &test); ret = acl_fetch_rdp_cookie(px, l4, NULL, ACL_DIR_REQ, &expr, &test);
if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0) if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)

View File

@ -2346,6 +2346,7 @@ acl_fetch_sc2_get_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the General Purpose Counter 0 value from the session's source /* set temp integer to the General Purpose Counter 0 value from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_get_gpc0(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_get_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2357,8 +2358,8 @@ acl_fetch_src_get_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2409,6 +2410,7 @@ acl_fetch_sc2_inc_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
/* Increment the General Purpose Counter 0 value from the session's source /* Increment the General Purpose Counter 0 value from the session's source
* address in the table pointed to by expr, and return it into temp integer. * address in the table pointed to by expr, and return it into temp integer.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_inc_gpc0(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_inc_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2420,8 +2422,8 @@ acl_fetch_src_inc_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2473,6 +2475,7 @@ acl_fetch_sc2_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
/* Clear the General Purpose Counter 0 value from the session's source address /* Clear the General Purpose Counter 0 value from the session's source address
* in the table pointed to by expr, and return its previous value into temp integer. * in the table pointed to by expr, and return its previous value into temp integer.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2484,8 +2487,8 @@ acl_fetch_src_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2532,6 +2535,7 @@ acl_fetch_sc2_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the cumulated number of connections from the session's source /* set temp integer to the cumulated number of connections from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2543,8 +2547,8 @@ acl_fetch_src_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2596,6 +2600,7 @@ acl_fetch_sc2_conn_rate(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the connection rate from the session's source address in the /* set temp integer to the connection rate from the session's source address in the
* table pointed to by expr, over the configured period. * table pointed to by expr, over the configured period.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_conn_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_conn_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2607,8 +2612,8 @@ acl_fetch_src_conn_rate(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2618,6 +2623,7 @@ acl_fetch_src_conn_rate(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the number of connections from the session's source address /* set temp integer to the number of connections from the session's source address
* in the table pointed to by expr, after updating it. * in the table pointed to by expr, after updating it.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_updt_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_updt_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2631,8 +2637,8 @@ acl_fetch_src_updt_conn_cnt(struct proxy *px, struct session *l4, void *l7, int
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2690,6 +2696,7 @@ acl_fetch_sc2_conn_cur(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the number of concurrent connections from the session's source /* set temp integer to the number of concurrent connections from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_conn_cur(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_conn_cur(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2701,8 +2708,8 @@ acl_fetch_src_conn_cur(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2749,6 +2756,7 @@ acl_fetch_sc2_sess_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the cumulated number of session from the session's source /* set temp integer to the cumulated number of session from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_sess_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_sess_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2760,8 +2768,8 @@ acl_fetch_src_sess_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2813,6 +2821,7 @@ acl_fetch_sc2_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the session rate from the session's source address in the /* set temp integer to the session rate from the session's source address in the
* table pointed to by expr, over the configured period. * table pointed to by expr, over the configured period.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2824,8 +2833,8 @@ acl_fetch_src_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2872,6 +2881,7 @@ acl_fetch_sc2_http_req_cnt(struct proxy *px, struct session *l4, void *l7, int d
/* set temp integer to the cumulated number of session from the session's source /* set temp integer to the cumulated number of session from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_http_req_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_http_req_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2883,8 +2893,8 @@ acl_fetch_src_http_req_cnt(struct proxy *px, struct session *l4, void *l7, int d
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2936,6 +2946,7 @@ acl_fetch_sc2_http_req_rate(struct proxy *px, struct session *l4, void *l7, int
/* set temp integer to the session rate from the session's source address in the /* set temp integer to the session rate from the session's source address in the
* table pointed to by expr, over the configured period. * table pointed to by expr, over the configured period.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_http_req_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_http_req_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@ -2947,8 +2958,8 @@ acl_fetch_src_http_req_rate(struct proxy *px, struct session *l4, void *l7, int
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -2995,6 +3006,7 @@ acl_fetch_sc2_http_err_cnt(struct proxy *px, struct session *l4, void *l7, int d
/* set temp integer to the cumulated number of session from the session's source /* set temp integer to the cumulated number of session from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_http_err_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_http_err_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@ -3006,8 +3018,8 @@ acl_fetch_src_http_err_cnt(struct proxy *px, struct session *l4, void *l7, int d
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3059,6 +3071,7 @@ acl_fetch_sc2_http_err_rate(struct proxy *px, struct session *l4, void *l7, int
/* set temp integer to the session rate from the session's source address in the /* set temp integer to the session rate from the session's source address in the
* table pointed to by expr, over the configured period. * table pointed to by expr, over the configured period.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_http_err_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_http_err_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@ -3070,8 +3083,8 @@ acl_fetch_src_http_err_rate(struct proxy *px, struct session *l4, void *l7, int
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3123,6 +3136,7 @@ acl_fetch_sc2_kbytes_in(struct proxy *px, struct session *l4, void *l7, int dir,
/* set temp integer to the number of kbytes received from the session's source /* set temp integer to the number of kbytes received from the session's source
* address in the table pointed to by expr. * address in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_kbytes_in(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_kbytes_in(struct proxy *px, struct session *l4, void *l7, int dir,
@ -3134,8 +3148,8 @@ acl_fetch_src_kbytes_in(struct proxy *px, struct session *l4, void *l7, int dir,
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3189,6 +3203,7 @@ acl_fetch_sc2_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, int
/* set temp integer to the bytes rate from clients from the session's source address /* set temp integer to the bytes rate from clients from the session's source address
* in the table pointed to by expr, over the configured period. * in the table pointed to by expr, over the configured period.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@ -3200,8 +3215,8 @@ acl_fetch_src_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, int
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3253,6 +3268,7 @@ acl_fetch_sc2_kbytes_out(struct proxy *px, struct session *l4, void *l7, int dir
/* set temp integer to the number of kbytes sent to the session's source address in /* set temp integer to the number of kbytes sent to the session's source address in
* the table pointed to by expr. * the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_kbytes_out(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_kbytes_out(struct proxy *px, struct session *l4, void *l7, int dir,
@ -3264,8 +3280,8 @@ acl_fetch_src_kbytes_out(struct proxy *px, struct session *l4, void *l7, int dir
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3319,6 +3335,7 @@ acl_fetch_sc2_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, int
/* set temp integer to the bytes rate to client from the session's source address in /* set temp integer to the bytes rate to client from the session's source address in
* the table pointed to by expr, over the configured period. * the table pointed to by expr, over the configured period.
* Accepts 0 or 1 argument of type string.
*/ */
static int static int
acl_fetch_src_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_src_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@ -3330,8 +3347,8 @@ acl_fetch_src_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, int
if (!key) if (!key)
return 0; return 0;
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3339,13 +3356,15 @@ acl_fetch_src_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, int
return acl_fetch_bytes_out_rate(&px->table, test, stktable_lookup_key(&px->table, key)); return acl_fetch_bytes_out_rate(&px->table, test, stktable_lookup_key(&px->table, key));
} }
/* set temp integer to the number of used entries in the table pointed to by expr. */ /* set temp integer to the number of used entries in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/
static int static int
acl_fetch_table_cnt(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_table_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */
@ -3355,13 +3374,15 @@ acl_fetch_table_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
return 1; return 1;
} }
/* set temp integer to the number of free entries in the table pointed to by expr. */ /* set temp integer to the number of free entries in the table pointed to by expr.
* Accepts 0 or 1 argument of type string.
*/
static int static int
acl_fetch_table_avl(struct proxy *px, struct session *l4, void *l7, int dir, acl_fetch_table_avl(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test) struct acl_expr *expr, struct acl_test *test)
{ {
if (expr->arg_len) if (expr->args)
px = find_stktable(expr->arg.str); px = find_stktable(expr->args->data.str.str);
if (!px) if (!px)
return 0; /* table not found */ return 0; /* table not found */