]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] acl: specify the direction during fetches
authorWilly Tarreau <w@1wt.eu>
Sun, 10 Jun 2007 08:06:18 +0000 (10:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 10 Jun 2007 08:06:18 +0000 (10:06 +0200)
Some fetches such as 'line' or 'hdr' need to know the direction of
the test (request or response). A new 'dir' parameter is now
propagated from the caller to achieve this.

include/proto/acl.h
include/types/acl.h
src/acl.c
src/client.c
src/proto_http.c

index 59c213926396b1bc873fef913ae9bb20e9c5993a..896872f2588074942bfb9b92f9c9a8997de5612d 100644 (file)
@@ -68,7 +68,7 @@ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int p
  * 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.
index 02c1258b00670ba2d52d8bd5701a1d8b2cbefff1..d67928897586a6f0a6401f88dfdcdbe0a89c73a2 100644 (file)
@@ -61,6 +61,12 @@ enum {
        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 */
@@ -127,7 +133,7 @@ struct session;
 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;
 };
index efa785319091790dfad8071ca67ef66d4120ebfe..4443ae9ade64a9d7bc718311fdf61f40358964c9 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -620,7 +620,7 @@ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int p
  * 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;
@@ -654,9 +654,10 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, v
                         */
                        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 */
index ddc630bf8e0e073251d1d2bb17eda71643f6f928..39d53221f1ad009543ec2b75ebc3cad4d040e492 100644 (file)
@@ -453,7 +453,8 @@ int event_accept(int fd) {
 /************************************************************************/
 
 /* 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)
@@ -466,7 +467,8 @@ static int acl_fetch_src(struct proxy *px, struct session *l4, void *l7, void *a
 
 
 /* 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);
@@ -478,7 +480,8 @@ static int acl_fetch_sport(struct proxy *px, struct session *l4, void *l7, void
 
 
 /* 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);
@@ -494,7 +497,8 @@ static int acl_fetch_dst(struct proxy *px, struct session *l4, void *l7, void *a
 
 
 /* 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);
@@ -508,7 +512,8 @@ static int acl_fetch_dport(struct proxy *px, struct session *l4, void *l7, void
 }
 
 /* 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;
index 839bc94d556faef5638d59111011c8d6909144be..5f991e57a099a8aa188f249ca699e422d3206fe8 100644 (file)
@@ -1681,7 +1681,7 @@ int process_cli(struct session *t)
 
                        /* 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;
 
@@ -5164,7 +5164,8 @@ static int acl_parse_meth(const char **text, struct acl_pattern *pattern, int *o
        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;
@@ -5207,7 +5208,8 @@ static int acl_parse_ver(const char **text, struct acl_pattern *pattern, int *op
        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;
@@ -5227,7 +5229,8 @@ static int acl_fetch_rqver(struct proxy *px, struct session *l4, void *l7, void
        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;
@@ -5248,7 +5251,8 @@ static int acl_fetch_stver(struct proxy *px, struct session *l4, void *l7, void
 }
 
 /* 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;
@@ -5263,7 +5267,8 @@ static int acl_fetch_stcode(struct proxy *px, struct session *l4, void *l7, void
 }
 
 /* 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;