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.
diff --git a/include/types/acl.h b/include/types/acl.h
index 35a22a0..14e4f84 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -2,7 +2,7 @@
* include/types/acl.h
* 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
* modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include <common/config.h>
#include <common/mini-clist.h>
+#include <types/arg.h>
#include <types/auth.h>
#include <types/proxy.h>
#include <types/server.h>
@@ -302,12 +303,7 @@
struct acl_expr {
struct list list; /* chaining */
struct acl_keyword *kw; /* back-reference to the keyword */
- union { /* optional argument of the subject (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 arg *args; /* optional argument list (eg: header or cookie name) */
struct list patterns; /* list of acl_patterns */
struct eb_root pattern_tree; /* may be used for lookup in large datasets */
};
diff --git a/src/acl.c b/src/acl.c
index 507516f..84de6ac 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -22,6 +22,7 @@
#include <types/global.h>
#include <proto/acl.h>
+#include <proto/arg.h>
#include <proto/auth.h>
#include <proto/buffers.h>
#include <proto/log.h>
@@ -446,6 +447,8 @@
/* Fetch the RDP cookie identified in the expression.
* 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
acl_fetch_rdp_cookie(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -480,17 +483,17 @@
bleft--;
}
- if (expr->arg_len) {
+ if (expr->args) {
- if (bleft <= expr->arg_len)
+ if (bleft <= expr->args->data.str.len)
goto too_short;
- if ((data[expr->arg_len] != '=') ||
- strncasecmp(expr->arg.str, (const char *)data, expr->arg_len) != 0)
+ if ((data[expr->args->data.str.len] != '=') ||
+ strncasecmp(expr->args->data.str.str, (const char *)data, expr->args->data.str.len) != 0)
goto not_cookie;
- data += expr->arg_len + 1;
- bleft -= expr->arg_len + 1;
+ data += expr->args->data.str.len + 1;
+ bleft -= expr->args->data.str.len + 1;
} else {
while (bleft > 0 && *data != '=') {
if (*data == '\r' || *data == '\n')
@@ -1241,11 +1244,25 @@
static struct acl_expr *prune_acl_expr(struct acl_expr *expr)
{
+ struct arg *arg;
+
free_pattern_list(&expr->patterns);
free_pattern_tree(&expr->pattern_tree);
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--;
return expr;
}
@@ -1355,22 +1372,26 @@
aclkw->use_cnt++;
LIST_INIT(&expr->patterns);
expr->pattern_tree = EB_ROOT_UNIQUE;
- expr->arg.str = NULL;
- expr->arg_len = 0;
arg = strchr(args[0], '(');
if (arg != NULL) {
- char *end, *arg2;
- /* there is an argument in the form "subject(arg)" */
+ char *end;
+ int nbargs;
+
+ /* there is an argument in the form "subject(arg[,arg]*)" */
arg++;
end = strchr(arg, ')');
if (!end)
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;
- expr->arg_len = end - arg;
- expr->arg.str = arg2;
}
args++;
@@ -1935,14 +1956,17 @@
struct server *srv;
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",
p->id, acl->name, expr->kw->kw);
cfgerr++;
continue;
}
- pname = expr->arg.str;
+ pname = expr->args->data.str.str;
sname = strrchr(pname, '/');
if (sname)
@@ -1971,15 +1995,17 @@
continue;
}
- free(expr->arg.str);
- expr->arg_len = 0;
- expr->arg.srv = srv;
+ free(expr->args->data.str.str);
+ expr->args->data.srv = srv;
continue;
}
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",
p->id, acl->name, expr->kw->kw);
cfgerr++;
@@ -1987,20 +2013,20 @@
}
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;
else
- ul = auth_find_userlist(expr->arg.str);
+ ul = auth_find_userlist(expr->args->data.str.str);
if (!ul) {
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++;
continue;
}
- expr->arg_len = 0;
- expr->arg.ul = ul;
+ free(expr->args->data.str.str);
+ expr->args->data.usr = ul;
}
@@ -2014,7 +2040,7 @@
}
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);
pattern->ptr.str = NULL;
diff --git a/src/backend.c b/src/backend.c
index b4fa21d..74bee83 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -28,6 +28,7 @@
#include <types/global.h>
#include <proto/acl.h>
+#include <proto/arg.h>
#include <proto/backend.h>
#include <proto/frontend.h>
#include <proto/lb_chash.h>
@@ -393,6 +394,7 @@
return map_get_server_hash(px, hash);
}
+/* RDP Cookie HASH. */
struct server *get_server_rch(struct session *s)
{
unsigned long hash = 0;
@@ -402,6 +404,7 @@
int ret;
struct acl_expr expr;
struct acl_test test;
+ struct arg args[2];
/* tot_weight appears to mean srv_count */
if (px->lbprm.tot_weight == 0)
@@ -410,8 +413,12 @@
memset(&expr, 0, sizeof(expr));
memset(&test, 0, sizeof(test));
- expr.arg.str = px->hh_name;
- expr.arg_len = px->hh_len;
+ args[0].type = ARGT_STR;
+ 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);
len = temp_pattern.data.str.len;
@@ -1111,6 +1118,7 @@
struct server *srv = px->srv;
struct sockaddr_in addr;
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",
now_ms, __FUNCTION__,
@@ -1127,8 +1135,12 @@
memset(&expr, 0, sizeof(expr));
memset(&test, 0, sizeof(test));
+ args[0].type = ARGT_STR;
+ 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.arg.str = s->be->rdp_cookie_name;
- expr.arg_len = s->be->rdp_cookie_len;
+ expr.args = args;
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)
@@ -1365,16 +1377,19 @@
/* 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
acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -1392,12 +1407,14 @@
/* 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.
+ * Accepts exactly 1 argument. Argument is a server, other types will lead to
+ * undefined behaviour.
*/
static int
acl_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, int dir,
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;
if (!(srv->state & SRV_MAINTAIN) &&
@@ -1408,17 +1425,20 @@
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
acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
struct server *iterator;
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -1470,16 +1490,19 @@
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
acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -1489,16 +1512,19 @@
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
acl_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -1508,16 +1534,19 @@
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
acl_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -1532,6 +1561,8 @@
* 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
* back soon.
+ * Accepts either 0 or 1 argument. Argument is a string, other types will lead to
+ * undefined behaviour.
*/
static int
acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -1540,10 +1571,10 @@
int nbsrv;
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -1564,12 +1595,15 @@
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
acl_fetch_srv_conn(struct proxy *px, struct session *l4, void *l7, int dir,
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;
return 1;
diff --git a/src/frontend.c b/src/frontend.c
index c18cc66..ac6027c 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -506,16 +506,19 @@
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
acl_fetch_fe_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
@@ -525,16 +528,19 @@
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
acl_fetch_fe_conn(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
test->flags = ACL_TEST_F_VOL_TEST;
- if (expr->arg_len) {
+ if (expr->args) {
/* another proxy was designated, we must look for it */
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;
}
if (!px)
diff --git a/src/proto_http.c b/src/proto_http.c
index b8b0af6..7f65be4 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -7836,6 +7836,7 @@
}
/* 5. Check on HTTP header. A pointer to the beginning of the value is returned.
+ * Accepts exactly 1 argument of type string.
*/
static int
acl_fetch_hdr(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -7846,13 +7847,16 @@
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;
+ if (!expr->args || expr->args->type != ARGT_STR)
+ return 0;
+
CHECK_HTTP_MESSAGE_FIRST();
if (!(test->flags & ACL_TEST_F_FETCH_MORE))
/* search for header from the beginning */
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_VOL_HDR;
temp_pattern.data.str.str = (char *)ctx->line + ctx->val;
@@ -7867,6 +7871,7 @@
}
/* 6. Check on HTTP header count. The number of occurrences is returned.
+ * Accepts exactly 1 argument of type string.
*/
static int
acl_fetch_hdr_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -7878,11 +7883,14 @@
const struct http_msg *msg = ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) ? &txn->req : &txn->rsp;
int cnt;
+ if (!expr->args || expr->args->type != ARGT_STR)
+ return 0;
+
CHECK_HTTP_MESSAGE_FIRST();
ctx.idx = 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++;
temp_pattern.data.integer = cnt;
@@ -7982,17 +7990,21 @@
return 1;
}
+/* Accepts exactly 1 argument of type userlist */
static int
acl_fetch_http_auth(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
+ if (!expr->args || expr->args->type != ARGT_USR)
+ return 0;
+
CHECK_HTTP_MESSAGE_FIRST();
if (!get_http_auth(l4))
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[2] = l4->txn.auth.pass;
@@ -8100,7 +8112,8 @@
* 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
* 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
acl_fetch_cookie_value(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -8114,6 +8127,9 @@
int hdr_name_len;
char *sol;
+ if (!expr->args || expr->args->type != ARGT_STR)
+ return 0;
+
CHECK_HTTP_MESSAGE_FIRST();
if ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) {
@@ -8141,7 +8157,7 @@
if (!http_find_header2(hdr_name, hdr_name_len, sol, idx, ctx))
goto out;
- if (ctx->vlen < expr->arg_len + 1)
+ if (ctx->vlen < expr->args->data.str.len + 1)
continue;
test->ctx.a[0] = ctx->line + ctx->val;
@@ -8149,7 +8165,7 @@
}
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,
&temp_pattern.data.str.str,
&temp_pattern.data.str.len);
@@ -8168,8 +8184,9 @@
}
/* 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.
+ * Accepts exactly 1 argument of type string.
*/
static int
acl_fetch_cookie_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -8185,6 +8202,9 @@
char *val_beg, *val_end;
char *sol;
+ if (!expr->args || expr->args->type != ARGT_STR)
+ return 0;
+
CHECK_HTTP_MESSAGE_FIRST();
if ((dir & ACL_DIR_MASK) == ACL_DIR_REQ) {
@@ -8208,7 +8228,7 @@
if (!http_find_header2(hdr_name, hdr_name_len, sol, idx, &ctx))
break;
- if (ctx.vlen < expr->arg_len + 1)
+ if (ctx.vlen < expr->args->data.str.len + 1)
continue;
val_beg = ctx.line + ctx.val;
@@ -8216,7 +8236,7 @@
}
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,
&temp_pattern.data.str.str,
&temp_pattern.data.str.len))) {
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 1714416..d53cd52 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1569,6 +1569,7 @@
int ret;
struct acl_expr expr;
struct acl_test test;
+ struct arg args[2];
if (!l4)
return 0;
@@ -1576,8 +1577,12 @@
memset(&expr, 0, sizeof(expr));
memset(&test, 0, sizeof(test));
- expr.arg.str = arg_p[0].data.str.str;
- expr.arg_len = arg_p[0].data.str.len;
+ args[0].type = ARGT_STR;
+ 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);
if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)
diff --git a/src/session.c b/src/session.c
index e930daf..16b50c9 100644
--- a/src/session.c
+++ b/src/session.c
@@ -2346,6 +2346,7 @@
/* set temp integer to the General Purpose Counter 0 value from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_get_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2357,8 +2358,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2409,6 +2410,7 @@
/* 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.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_inc_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2420,8 +2422,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2473,6 +2475,7 @@
/* 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.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_clr_gpc0(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2484,8 +2487,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2532,6 +2535,7 @@
/* set temp integer to the cumulated number of connections from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2543,8 +2547,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2596,6 +2600,7 @@
/* set temp integer to the connection rate from the session's source address in the
* table pointed to by expr, over the configured period.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_conn_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2607,8 +2612,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2618,6 +2623,7 @@
/* set temp integer to the number of connections from the session's source address
* in the table pointed to by expr, after updating it.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_updt_conn_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2631,8 +2637,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2690,6 +2696,7 @@
/* set temp integer to the number of concurrent connections from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_conn_cur(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2701,8 +2708,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2749,6 +2756,7 @@
/* set temp integer to the cumulated number of session from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_sess_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2760,8 +2768,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2813,6 +2821,7 @@
/* set temp integer to the session rate from the session's source address in the
* table pointed to by expr, over the configured period.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2824,8 +2833,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2872,6 +2881,7 @@
/* set temp integer to the cumulated number of session from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_http_req_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2883,8 +2893,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2936,6 +2946,7 @@
/* set temp integer to the session rate from the session's source address in the
* table pointed to by expr, over the configured period.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_http_req_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -2947,8 +2958,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -2995,6 +3006,7 @@
/* set temp integer to the cumulated number of session from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_http_err_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -3006,8 +3018,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3059,6 +3071,7 @@
/* set temp integer to the session rate from the session's source address in the
* table pointed to by expr, over the configured period.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_http_err_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -3070,8 +3083,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3123,6 +3136,7 @@
/* set temp integer to the number of kbytes received from the session's source
* address in the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_kbytes_in(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -3134,8 +3148,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3189,6 +3203,7 @@
/* 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.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_bytes_in_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -3200,8 +3215,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3253,6 +3268,7 @@
/* set temp integer to the number of kbytes sent to the session's source address in
* the table pointed to by expr.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_kbytes_out(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -3264,8 +3280,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3319,6 +3335,7 @@
/* 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.
+ * Accepts 0 or 1 argument of type string.
*/
static int
acl_fetch_src_bytes_out_rate(struct proxy *px, struct session *l4, void *l7, int dir,
@@ -3330,8 +3347,8 @@
if (!key)
return 0;
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3339,13 +3356,15 @@
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
acl_fetch_table_cnt(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */
@@ -3355,13 +3374,15 @@
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
acl_fetch_table_avl(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
- if (expr->arg_len)
- px = find_stktable(expr->arg.str);
+ if (expr->args)
+ px = find_stktable(expr->args->data.str.str);
if (!px)
return 0; /* table not found */