* This function only computes the condition, it does not apply the polarity
* required by IF/UNLESS, it's up to the caller to do this.
*/
-int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7);
+int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7, int dir);
/* Return a pointer to the ACL <name> within the list starting at <head>, or
* NULL if not found.
ACL_TEST_F_FETCH_MORE = 1 << 7, /* if test does not match, retry with next entry */
};
+/* ACLs can be evaluated on requests and on responses. */
+enum {
+ ACL_DIR_REQ = 0, /* ACL evaluated on request */
+ ACL_DIR_RTR, /* ACL evaluated on response */
+};
+
/* How to store a time range and the valid days in 29 bits */
struct acl_time {
int dow:7; /* 1 bit per day of week: 0-6 */
struct acl_keyword {
const char *kw;
int (*parse)(const char **text, struct acl_pattern *pattern, int *opaque);
- int (*fetch)(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test);
+ int (*fetch)(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test);
int (*match)(struct acl_test *test, struct acl_pattern *pattern);
int use_cnt;
};
* This function only computes the condition, it does not apply the polarity
* required by IF/UNLESS, it's up to the caller to do this.
*/
-int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7)
+int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7, int dir)
{
__label__ fetch_next;
struct acl_term_suite *suite;
*/
acl_res = ACL_PAT_FAIL;
list_for_each_entry(expr, &acl->expr, list) {
- test.flags = test.len = 0;
+ /* we need to reset context and flags */
+ memset(&test, 0, sizeof(test));
fetch_next:
- if (!expr->kw->fetch(px, l4, l7, expr->arg.str, &test))
+ if (!expr->kw->fetch(px, l4, l7, dir, expr->arg.str, &test))
continue;
/* apply all tests to this value */
/************************************************************************/
/* set test->ptr to point to the source IPv4/IPv6 address and test->i to the family */
-static int acl_fetch_src(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_src(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
test->i = l4->cli_addr.ss_family;
if (test->i == AF_INET)
/* set test->i to the connexion's source port */
-static int acl_fetch_sport(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_sport(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
if (l4->cli_addr.ss_family == AF_INET)
test->i = ntohs(((struct sockaddr_in *)&l4->cli_addr)->sin_port);
/* set test->ptr to point to the frontend's IPv4/IPv6 address and test->i to the family */
-static int acl_fetch_dst(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_dst(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
if (!(l4->flags & SN_FRT_ADDR_SET))
get_frt_addr(l4);
/* set test->i to the frontend connexion's destination port */
-static int acl_fetch_dport(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_dport(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
if (!(l4->flags & SN_FRT_ADDR_SET))
get_frt_addr(l4);
}
/* set test->i to the number of connexions to the proxy */
-static int acl_fetch_dconn(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_dconn(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
test->i = px->feconn;
return 1;
/* first check whether we have some ACLs set to block this request */
list_for_each_entry(cond, &cur_proxy->block_cond, list) {
- int ret = acl_exec_cond(cond, cur_proxy, t, txn);
+ int ret = acl_exec_cond(cond, cur_proxy, t, txn, ACL_DIR_REQ);
if (cond->pol == ACL_COND_UNLESS)
ret = !ret;
return 1;
}
-static int acl_fetch_meth(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_meth(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
int meth;
struct http_txn *txn = l7;
return 1;
}
-static int acl_fetch_rqver(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_rqver(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
struct http_txn *txn = l7;
char *ptr;
return 1;
}
-static int acl_fetch_stver(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_stver(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
struct http_txn *txn = l7;
char *ptr;
}
/* 3. Check on Status Code. We manipulate integers here. */
-static int acl_fetch_stcode(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_stcode(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
struct http_txn *txn = l7;
char *ptr;
}
/* 4. Check on URL/URI. A pointer to the URI is stored. */
-static int acl_fetch_url(struct proxy *px, struct session *l4, void *l7, void *arg, struct acl_test *test)
+static int
+acl_fetch_url(struct proxy *px, struct session *l4, void *l7, int dir, void *arg, struct acl_test *test)
{
struct http_txn *txn = l7;