]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: tree-wide: define and use acl_match_cond() helper
authorAurelien DARRAGON <adarragon@haproxy.com>
Wed, 22 Jan 2025 13:15:47 +0000 (14:15 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Mon, 27 Jan 2025 10:11:43 +0000 (11:11 +0100)
acl_match_cond() combines acl_exec_cond() + acl_pass() and a check on the
condition->pol (to check if the cond is inverted) in order to return
either 0 if the cond doesn't match or 1 if it matches (or NULL).

Thanks to this we can actually simplify some redundant constructs that
iterate over rules and evaluate if the condition matches or not.

Conditions for tcp-request inspect-content and tcp-response
inspect-content couldn't be simplified because they perform an extra
check for missing data, and thus still need to leverage acl_exec_cond()

It's best to display the patch using "-w", like "git show xxxx -w",
because some blocks had to be re-indented after the cleanup, which
makes the patch hard to review by default.

include/haproxy/acl.h
src/fcgi-app.c
src/flt_spoe.c
src/http_ana.c
src/quic_rules.c
src/stream.c
src/tcp_rules.c

index b63b4fe8416e315477195d8a6588ab7830e855ce..af48dba38aff70b17091ead75b9b612632ed50ee 100644 (file)
@@ -104,6 +104,26 @@ struct acl_cond *build_acl_cond(const char *file, int line, struct list *known_a
  */
 enum acl_test_res acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *sess, struct stream *strm, unsigned int opt);
 
+
+/* helper that combines acl_exec_cond() and acl_pass(), and also takes into
+ * account cond->pol in order to return either 1 if the cond should pass and
+ * 0 otherwise
+ * <cond> may be NULL, in which case 1 is returned as the cond cannot fail
+ */
+static inline int acl_match_cond(struct acl_cond *cond, struct proxy *px, struct session *sess, struct stream *strm, unsigned int opt)
+{
+       int ret;
+
+       if (!cond)
+               return 1;
+
+       ret = acl_pass(acl_exec_cond(cond, px, sess, strm, opt));
+       if (cond->pol == ACL_COND_UNLESS)
+               ret = !ret;
+
+       return ret;
+}
+
 /* Returns a pointer to the first ACL conflicting with usage at place <where>
  * which is one of the SMP_VAL_* bits indicating a check place, or NULL if
  * no conflict is found. Only full conflicts are detected (ACL is not usable).
index 98077b9593276fcae377964307b10eec6fa02f1f..ab5284c50056b1af6b2f4a6686c37268248b4729 100644 (file)
@@ -311,7 +311,6 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct
        struct eb_root hdr_rules = EB_ROOT;
        struct htx *htx;
        struct http_hdr_ctx ctx;
-       int ret;
 
        htx = htxbuf(&msg->chn->buf);
 
@@ -368,16 +367,8 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct
                goto end;
 
        list_for_each_entry(rule, &fcgi_conf->param_rules, list) {
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-
-                       /* the rule does not match */
-                       if (!ret)
-                               continue;
-               }
+               if (!acl_match_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
 
                param_rule = NULL;
                node = ebis_lookup_len(&param_rules, rule->name.ptr, rule->name.len);
@@ -398,16 +389,8 @@ static int fcgi_flt_http_headers(struct stream *s, struct filter *filter, struct
        }
 
        list_for_each_entry(rule, &fcgi_conf->hdr_rules, list) {
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-
-                       /* the rule does not match */
-                       if (!ret)
-                               continue;
-               }
+               if (!acl_match_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
 
                hdr_rule = NULL;
                node = ebis_lookup_len(&hdr_rules, rule->name.ptr, rule->name.len);
index 49ff8966532e3e02d2629b3da0330b015a429d89..60c820c79b2e50a450f54b10d0f62b9fb3e47230 100644 (file)
@@ -592,16 +592,8 @@ static int spoe_encode_message(struct stream *s, struct spoe_context *ctx,
        struct spoe_arg *arg;
        int ret;
 
-       if (msg->cond) {
-               ret = acl_exec_cond(msg->cond, s->be, s->sess, s, dir|SMP_OPT_FINAL);
-               ret = acl_pass(ret);
-               if (msg->cond->pol == ACL_COND_UNLESS)
-                       ret = !ret;
-
-               /* the rule does not match */
-               if (!ret)
-                       goto next;
-       }
+       if (!acl_match_cond(msg->cond, s->be, s->sess, s, dir|SMP_OPT_FINAL))
+               goto next;
 
        /* Check if there is enough space for the message name and the
         * number of arguments. It implies <msg->id_len> is encoded on 2
index 144bb073eae7177b58582be9efc76659b105be4a..41c5effd65f15729453aee75a48671bfe82c10c8 100644 (file)
@@ -237,19 +237,14 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
 
                        /* Check if we want to fail this monitor request or not */
                        list_for_each_entry(cond, &sess->fe->mon_fail_cond, list) {
-                               int ret = acl_exec_cond(cond, sess->fe, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-
-                               ret = acl_pass(ret);
-                               if (cond->pol == ACL_COND_UNLESS)
-                                       ret = !ret;
-
-                               if (ret) {
-                                       /* we fail this request, let's return 503 service unavail */
-                                       txn->status = 503;
-                                       if (!(s->flags & SF_ERR_MASK))
-                                               s->flags |= SF_ERR_LOCAL; /* we don't want a real error here */
-                                       goto return_prx_cond;
-                               }
+                               if (!acl_match_cond(cond, sess->fe, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                                       continue;
+
+                               /* we fail this request, let's return 503 service unavail */
+                               txn->status = 503;
+                               if (!(s->flags & SF_ERR_MASK))
+                                       s->flags |= SF_ERR_LOCAL; /* we don't want a real error here */
+                               goto return_prx_cond;
                        }
 
                        /* nothing to fail, let's reply normally */
@@ -505,16 +500,8 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
 
        /* check whether we have some ACLs set to redirect this request */
        list_for_each_entry(rule, &px->redirect_rules, list) {
-               if (rule->cond) {
-                       int ret;
-
-                       ret = acl_exec_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-                       if (!ret)
-                               continue;
-               }
+               if (!acl_match_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
                if (!http_apply_redirect_rule(rule, s, txn)) {
                        goto return_int_err;
                }
@@ -2757,18 +2744,8 @@ static enum rule_result http_req_get_intercept_rule(struct proxy *px, struct lis
 
        list_for_each_entry(rule, s->current_rule_list, list) {
                /* check optional condition */
-               if (rule->cond) {
-                       int ret;
-
-                       ret = acl_exec_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-
-                       if (!ret) /* condition not matched */
-                               continue;
-               }
+               if (!acl_match_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
 
                act_opts |= ACT_OPT_FIRST;
   resume_execution:
@@ -2938,18 +2915,8 @@ static enum rule_result http_res_get_intercept_rule(struct proxy *px, struct lis
 
        list_for_each_entry(rule, s->current_rule_list, list) {
                /* check optional condition */
-               if (rule->cond) {
-                       int ret;
-
-                       ret = acl_exec_cond(rule->cond, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-
-                       if (!ret) /* condition not matched */
-                               continue;
-               }
+               if (!acl_match_cond(rule->cond, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL))
+                       continue;
 
                act_opts |= ACT_OPT_FIRST;
 resume_execution:
@@ -4122,20 +4089,12 @@ static int http_handle_stats(struct stream *s, struct channel *req, struct proxy
 
        /* now check whether we have some admin rules for this request */
        list_for_each_entry(stats_admin_rule, &uri_auth->admin_rules, list) {
-               int ret = 1;
-
-               if (stats_admin_rule->cond) {
-                       ret = acl_exec_cond(stats_admin_rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (stats_admin_rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
+               if (!acl_match_cond(stats_admin_rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
 
-               if (ret) {
-                       /* no rule, or the rule matches */
-                       ctx->flags |= STAT_F_ADMIN;
-                       break;
-               }
+               /* no rule, or the rule matches */
+               ctx->flags |= STAT_F_ADMIN;
+               break;
        }
 
        if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
index 4a9ad3d27d3de965dba4a48a747f1b3090e16ab2..050548a8e306850ea5be30d0f813eca836e60072 100644 (file)
@@ -18,7 +18,6 @@ int quic_init_exec_rules(struct listener *li, struct quic_dgram *dgram)
 {
        static THREAD_LOCAL struct session rule_sess;
        struct act_rule *rule;
-       enum acl_test_res ret;
        struct proxy *px;
        int result = 1;
 
@@ -34,41 +33,33 @@ int quic_init_exec_rules(struct listener *li, struct quic_dgram *dgram)
        rule_sess.origin = &dgram->obj_type;
 
        list_for_each_entry(rule, &px->quic_init_rules, list) {
-               ret = ACL_TEST_PASS;
-
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, px, &rule_sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
-
-               if (ret) {
-                       if (rule->action_ptr) {
-                               switch (rule->action_ptr(rule, px, &rule_sess, NULL, 0)) {
-                               case ACT_RET_CONT:
-                                       break;
-                               case ACT_RET_DONE:
-                               case ACT_RET_STOP:
-                                       goto end;
-                               case ACT_RET_ABRT:
-                               case ACT_RET_DENY:
-                               case ACT_RET_ERR:
-                               case ACT_RET_INV:
-                                       result = 0;
-                                       goto end;
-                               default:
-                                       ABORT_NOW("not implemented");
-                               }
-                       }
-                       else if (rule->action == ACT_ACTION_ALLOW) {
+               if (!acl_match_cond(rule->cond, px, &rule_sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
+
+               if (rule->action_ptr) {
+                       switch (rule->action_ptr(rule, px, &rule_sess, NULL, 0)) {
+                       case ACT_RET_CONT:
+                               break;
+                       case ACT_RET_DONE:
+                       case ACT_RET_STOP:
                                goto end;
-                       }
-                       else if (rule->action == ACT_ACTION_DENY) {
+                       case ACT_RET_ABRT:
+                       case ACT_RET_DENY:
+                       case ACT_RET_ERR:
+                       case ACT_RET_INV:
                                result = 0;
                                goto end;
+                       default:
+                               ABORT_NOW("not implemented");
                        }
                }
+               else if (rule->action == ACT_ACTION_ALLOW) {
+                       goto end;
+               }
+               else if (rule->action == ACT_ACTION_DENY) {
+                       result = 0;
+                       goto end;
+               }
        }
 
  end:
index 9ffdf07d9f5d3f7adf2a896ac1b0517c5a7434eb..41a2ffcb961b3ee4c5cab7d2cb3f1c63d38208d2 100644 (file)
@@ -1072,45 +1072,38 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an
                struct switching_rule *rule;
 
                list_for_each_entry(rule, &fe->switching_rules, list) {
-                       int ret = 1;
+                       struct proxy *backend = NULL;
 
-                       if (rule->cond) {
-                               ret = acl_exec_cond(rule->cond, fe, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                               ret = acl_pass(ret);
-                               if (rule->cond->pol == ACL_COND_UNLESS)
-                                       ret = !ret;
-                       }
-
-                       if (ret) {
-                               /* If the backend name is dynamic, try to resolve the name.
-                                * If we can't resolve the name, or if any error occurs, break
-                                * the loop and fallback to the default backend.
-                                */
-                               struct proxy *backend = NULL;
+                       if (!acl_match_cond(rule->cond, fe, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                               continue;
 
-                               if (rule->dynamic) {
-                                       struct buffer *tmp;
+                       /* If the backend name is dynamic, try to resolve the name.
+                        * If we can't resolve the name, or if any error occurs, break
+                        * the loop and fallback to the default backend.
+                        */
 
-                                       tmp = alloc_trash_chunk();
-                                       if (!tmp)
-                                               goto sw_failed;
+                       if (rule->dynamic) {
+                               struct buffer *tmp;
 
-                                       if (build_logline(s, tmp->area, tmp->size, &rule->be.expr))
-                                               backend = proxy_be_by_name(tmp->area);
+                               tmp = alloc_trash_chunk();
+                               if (!tmp)
+                                       goto sw_failed;
 
-                                       free_trash_chunk(tmp);
-                                       tmp = NULL;
+                               if (build_logline(s, tmp->area, tmp->size, &rule->be.expr))
+                                       backend = proxy_be_by_name(tmp->area);
 
-                                       if (!backend)
-                                               break;
-                               }
-                               else
-                                       backend = rule->be.backend;
+                               free_trash_chunk(tmp);
+                               tmp = NULL;
 
-                               if (!stream_set_backend(s, backend))
-                                       goto sw_failed;
-                               break;
+                               if (!backend)
+                                       break;
                        }
+                       else
+                               backend = rule->be.backend;
+
+                       if (!stream_set_backend(s, backend))
+                               goto sw_failed;
+                       break;
                }
 
                /* To ensure correct connection accounting on the backend, we
@@ -1147,24 +1140,16 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an
         * persistence rule, and report that in the stream.
         */
        list_for_each_entry(prst_rule, &s->be->persist_rules, list) {
-               int ret = 1;
-
-               if (prst_rule->cond) {
-                       ret = acl_exec_cond(prst_rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (prst_rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
+               if (!acl_match_cond(prst_rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
 
-               if (ret) {
-                       /* no rule, or the rule matches */
-                       if (prst_rule->type == PERSIST_TYPE_FORCE) {
-                               s->flags |= SF_FORCE_PRST;
-                       } else {
-                               s->flags |= SF_IGNORE_PRST;
-                       }
-                       break;
+               /* no rule, or the rule matches */
+               if (prst_rule->type == PERSIST_TYPE_FORCE) {
+                       s->flags |= SF_FORCE_PRST;
+               } else {
+                       s->flags |= SF_IGNORE_PRST;
                }
+               break;
        }
 
        DBG_TRACE_LEAVE(STRM_EV_STRM_ANA, s);
@@ -1201,40 +1186,34 @@ static int process_server_rules(struct stream *s, struct channel *req, int an_bi
 
        if (!(s->flags & SF_ASSIGNED)) {
                list_for_each_entry(rule, &px->server_rules, list) {
-                       int ret;
-
-                       ret = acl_exec_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-
-                       if (ret) {
-                               struct server *srv;
+                       struct server *srv;
 
-                               if (rule->dynamic) {
-                                       struct buffer *tmp = get_trash_chunk();
+                       if (!acl_match_cond(rule->cond, s->be, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                               continue;
 
-                                       if (!build_logline(s, tmp->area, tmp->size, &rule->expr))
-                                               break;
+                       if (rule->dynamic) {
+                               struct buffer *tmp = get_trash_chunk();
 
-                                       srv = findserver(s->be, tmp->area);
-                                       if (!srv)
-                                               break;
-                               }
-                               else
-                                       srv = rule->srv.ptr;
+                               if (!build_logline(s, tmp->area, tmp->size, &rule->expr))
+                                       break;
 
-                               if ((srv->cur_state != SRV_ST_STOPPED) ||
-                                   (px->options & PR_O_PERSIST) ||
-                                   (s->flags & SF_FORCE_PRST)) {
-                                       s->flags |= SF_DIRECT | SF_ASSIGNED;
-                                       s->target = &srv->obj_type;
+                               srv = findserver(s->be, tmp->area);
+                               if (!srv)
                                        break;
-                               }
-                               /* if the server is not UP, let's go on with next rules
-                                * just in case another one is suited.
-                                */
                        }
+                       else
+                               srv = rule->srv.ptr;
+
+                       if ((srv->cur_state != SRV_ST_STOPPED) ||
+                           (px->options & PR_O_PERSIST) ||
+                           (s->flags & SF_FORCE_PRST)) {
+                               s->flags |= SF_DIRECT | SF_ASSIGNED;
+                               s->target = &srv->obj_type;
+                               break;
+                       }
+                       /* if the server is not UP, let's go on with next rules
+                        * just in case another one is suited.
+                        */
                }
        }
 
@@ -1310,7 +1289,7 @@ static int process_sticking_rules(struct stream *s, struct channel *req, int an_
        DBG_TRACE_ENTER(STRM_EV_STRM_ANA, s);
 
        list_for_each_entry(rule, &px->sticking_rules, list) {
-               int ret = 1 ;
+               struct stktable_key *key;
                int i;
 
                /* Only the first stick store-request of each table is applied
@@ -1330,38 +1309,30 @@ static int process_sticking_rules(struct stream *s, struct channel *req, int an_
                                continue;
                }
 
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
+               if (!acl_match_cond(rule->cond, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
 
-               if (ret) {
-                       struct stktable_key *key;
+               key = stktable_fetch_key(rule->table.t, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->expr, NULL);
+               if (!key)
+                       continue;
 
-                       key = stktable_fetch_key(rule->table.t, px, sess, s, SMP_OPT_DIR_REQ|SMP_OPT_FINAL, rule->expr, NULL);
-                       if (!key)
-                               continue;
+               if (rule->flags & STK_IS_MATCH) {
+                       struct stksess *ts;
 
-                       if (rule->flags & STK_IS_MATCH) {
+                       if ((ts = stktable_lookup_key(rule->table.t, key)) != NULL) {
+                               if (!(s->flags & SF_ASSIGNED))
+                                       sticking_rule_find_target(s, rule->table.t, ts);
+                               stktable_touch_local(rule->table.t, ts, 1);
+                       }
+               }
+               if (rule->flags & STK_IS_STORE) {
+                       if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
                                struct stksess *ts;
 
-                               if ((ts = stktable_lookup_key(rule->table.t, key)) != NULL) {
-                                       if (!(s->flags & SF_ASSIGNED))
-                                               sticking_rule_find_target(s, rule->table.t, ts);
-                                       stktable_touch_local(rule->table.t, ts, 1);
-                               }
-                       }
-                       if (rule->flags & STK_IS_STORE) {
-                               if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
-                                       struct stksess *ts;
-
-                                       ts = stksess_new(rule->table.t, key);
-                                       if (ts) {
-                                               s->store[s->store_count].table = rule->table.t;
-                                               s->store[s->store_count++].ts = ts;
-                                       }
+                               ts = stksess_new(rule->table.t, key);
+                               if (ts) {
+                                       s->store[s->store_count].table = rule->table.t;
+                                       s->store[s->store_count++].ts = ts;
                                }
                        }
                }
@@ -1388,7 +1359,7 @@ static int process_store_rules(struct stream *s, struct channel *rep, int an_bit
        DBG_TRACE_ENTER(STRM_EV_STRM_ANA, s);
 
        list_for_each_entry(rule, &px->storersp_rules, list) {
-               int ret = 1 ;
+               struct stktable_key *key;
 
                /* Only the first stick store-response of each table is applied
                 * and other ones are ignored. The purpose is to allow complex
@@ -1411,28 +1382,20 @@ static int process_store_rules(struct stream *s, struct channel *rep, int an_bit
                if (i < s->store_count)
                        continue;
 
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
+               if (!acl_match_cond(rule->cond, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL))
+                       continue;
 
-               if (ret) {
-                       struct stktable_key *key;
+               key = stktable_fetch_key(rule->table.t, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL, rule->expr, NULL);
+               if (!key)
+                       continue;
 
-                       key = stktable_fetch_key(rule->table.t, px, sess, s, SMP_OPT_DIR_RES|SMP_OPT_FINAL, rule->expr, NULL);
-                       if (!key)
-                               continue;
+               if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
+                       struct stksess *ts;
 
-                       if (s->store_count < (sizeof(s->store) / sizeof(s->store[0]))) {
-                               struct stksess *ts;
-
-                               ts = stksess_new(rule->table.t, key);
-                               if (ts) {
-                                       s->store[s->store_count].table = rule->table.t;
-                                       s->store[s->store_count++].ts = ts;
-                               }
+                       ts = stksess_new(rule->table.t, key);
+                       if (ts) {
+                               s->store[s->store_count].table = rule->table.t;
+                               s->store[s->store_count++].ts = ts;
                        }
                }
        }
index fcc47b3d124660b3172822c78da78590b772ef59..9d450cfa9413d9d04128e7da4022e5545ca4c603 100644 (file)
@@ -158,65 +158,66 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit)
                        ret = acl_pass(ret);
                        if (rule->cond->pol == ACL_COND_UNLESS)
                                ret = !ret;
+
+                       if (!ret)
+                               continue;
                }
 
-               if (ret) {
-                       act_opts |= ACT_OPT_FIRST;
+               act_opts |= ACT_OPT_FIRST;
 resume_execution:
-                       /* Always call the action function if defined */
-                       if (rule->action_ptr) {
-                               switch (rule->action_ptr(rule, s->be, s->sess, s, act_opts)) {
-                                       case ACT_RET_CONT:
-                                               break;
-                                       case ACT_RET_STOP:
-                                       case ACT_RET_DONE:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto end;
-                                       case ACT_RET_YIELD:
-                                               s->current_rule = rule;
-                                               if (act_opts & ACT_OPT_FINAL) {
-                                                       send_log(s->be, LOG_WARNING,
-                                                                "Internal error: yield not allowed if the inspect-delay expired "
-                                                                "for the tcp-request content actions.");
-                                                       s->last_entity.type = STRM_ENTITY_RULE;
-                                                       s->last_entity.ptr  = rule;
-                                                       goto internal;
-                                               }
-                                               s->waiting_entity.type = STRM_ENTITY_RULE;
-                                               s->waiting_entity.ptr  = rule;
-                                               goto missing_data;
-                                       case ACT_RET_DENY:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto deny;
-                                       case ACT_RET_ABRT:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto abort;
-                                       case ACT_RET_ERR:
+               /* Always call the action function if defined */
+               if (rule->action_ptr) {
+                       switch (rule->action_ptr(rule, s->be, s->sess, s, act_opts)) {
+                               case ACT_RET_CONT:
+                                       break;
+                               case ACT_RET_STOP:
+                               case ACT_RET_DONE:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto end;
+                               case ACT_RET_YIELD:
+                                       s->current_rule = rule;
+                                       if (act_opts & ACT_OPT_FINAL) {
+                                               send_log(s->be, LOG_WARNING,
+                                                        "Internal error: yield not allowed if the inspect-delay expired "
+                                                        "for the tcp-request content actions.");
                                                s->last_entity.type = STRM_ENTITY_RULE;
                                                s->last_entity.ptr  = rule;
                                                goto internal;
-                                       case ACT_RET_INV:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto invalid;
-                               }
-                               continue; /* eval the next rule */
+                                       }
+                                       s->waiting_entity.type = STRM_ENTITY_RULE;
+                                       s->waiting_entity.ptr  = rule;
+                                       goto missing_data;
+                               case ACT_RET_DENY:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto deny;
+                               case ACT_RET_ABRT:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto abort;
+                               case ACT_RET_ERR:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto internal;
+                               case ACT_RET_INV:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto invalid;
                        }
+                       continue; /* eval the next rule */
+               }
 
-                       /* If not action function defined, check for known actions */
-                       if (rule->action == ACT_ACTION_ALLOW) {
-                               s->last_entity.type = STRM_ENTITY_RULE;
-                               s->last_entity.ptr  = rule;
-                               goto end;
-                       }
-                       else if (rule->action == ACT_ACTION_DENY) {
-                               s->last_entity.type = STRM_ENTITY_RULE;
-                               s->last_entity.ptr  = rule;
-                               goto deny;
-                       }
+               /* If not action function defined, check for known actions */
+               if (rule->action == ACT_ACTION_ALLOW) {
+                       s->last_entity.type = STRM_ENTITY_RULE;
+                       s->last_entity.ptr  = rule;
+                       goto end;
+               }
+               else if (rule->action == ACT_ACTION_DENY) {
+                       s->last_entity.type = STRM_ENTITY_RULE;
+                       s->last_entity.ptr  = rule;
+                       goto deny;
                }
        }
 
@@ -348,76 +349,76 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit)
                        ret = acl_pass(ret);
                        if (rule->cond->pol == ACL_COND_UNLESS)
                                ret = !ret;
+                       if (!ret)
+                               continue;
                }
 
-               if (ret) {
-                       act_opts |= ACT_OPT_FIRST;
+               act_opts |= ACT_OPT_FIRST;
 resume_execution:
 
-                       /* Always call the action function if defined */
-                       if (rule->action_ptr) {
-                               switch (rule->action_ptr(rule, s->be, s->sess, s, act_opts)) {
-                                       case ACT_RET_CONT:
-                                               break;
-                                       case ACT_RET_STOP:
-                                       case ACT_RET_DONE:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto end;
-                                       case ACT_RET_YIELD:
-                                               s->current_rule = rule;
-                                               if (act_opts & ACT_OPT_FINAL) {
-                                                       send_log(s->be, LOG_WARNING,
-                                                                "Internal error: yield not allowed if the inspect-delay expired "
-                                                                "for the tcp-response content actions.");
-                                                       s->last_entity.type = STRM_ENTITY_RULE;
-                                                       s->last_entity.ptr  = rule;
-                                                       goto internal;
-                                               }
-                                               s->waiting_entity.type = STRM_ENTITY_RULE;
-                                               s->waiting_entity.ptr  = rule;
-                                               channel_dont_close(rep);
-                                               goto missing_data;
-                                       case ACT_RET_DENY:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto deny;
-                                       case ACT_RET_ABRT:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto abort;
-                                       case ACT_RET_ERR:
+               /* Always call the action function if defined */
+               if (rule->action_ptr) {
+                       switch (rule->action_ptr(rule, s->be, s->sess, s, act_opts)) {
+                               case ACT_RET_CONT:
+                                       break;
+                               case ACT_RET_STOP:
+                               case ACT_RET_DONE:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto end;
+                               case ACT_RET_YIELD:
+                                       s->current_rule = rule;
+                                       if (act_opts & ACT_OPT_FINAL) {
+                                               send_log(s->be, LOG_WARNING,
+                                                        "Internal error: yield not allowed if the inspect-delay expired "
+                                                        "for the tcp-response content actions.");
                                                s->last_entity.type = STRM_ENTITY_RULE;
                                                s->last_entity.ptr  = rule;
                                                goto internal;
-                                       case ACT_RET_INV:
-                                               s->last_entity.type = STRM_ENTITY_RULE;
-                                               s->last_entity.ptr  = rule;
-                                               goto invalid;
-                               }
-                               continue; /* eval the next rule */
+                                       }
+                                       s->waiting_entity.type = STRM_ENTITY_RULE;
+                                       s->waiting_entity.ptr  = rule;
+                                       channel_dont_close(rep);
+                                       goto missing_data;
+                               case ACT_RET_DENY:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto deny;
+                               case ACT_RET_ABRT:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto abort;
+                               case ACT_RET_ERR:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto internal;
+                               case ACT_RET_INV:
+                                       s->last_entity.type = STRM_ENTITY_RULE;
+                                       s->last_entity.ptr  = rule;
+                                       goto invalid;
                        }
+                       continue; /* eval the next rule */
+               }
 
-                       /* If not action function defined, check for known actions */
-                       if (rule->action == ACT_ACTION_ALLOW) {
-                               s->last_entity.type = STRM_ENTITY_RULE;
-                               s->last_entity.ptr  = rule;
-                               goto end;
-                       }
-                       else if (rule->action == ACT_ACTION_DENY) {
-                               s->last_entity.type = STRM_ENTITY_RULE;
-                               s->last_entity.ptr  = rule;
-                               goto deny;
-                       }
-                       else if (rule->action == ACT_TCP_CLOSE) {
-                               s->scb->flags |= SC_FL_NOLINGER | SC_FL_NOHALF;
-                               sc_must_kill_conn(s->scb);
-                               sc_abort(s->scb);
-                               sc_shutdown(s->scb);
-                               s->last_entity.type = STRM_ENTITY_RULE;
-                               s->last_entity.ptr  = rule;
-                               goto end;
-                       }
+               /* If not action function defined, check for known actions */
+               if (rule->action == ACT_ACTION_ALLOW) {
+                       s->last_entity.type = STRM_ENTITY_RULE;
+                       s->last_entity.ptr  = rule;
+                       goto end;
+               }
+               else if (rule->action == ACT_ACTION_DENY) {
+                       s->last_entity.type = STRM_ENTITY_RULE;
+                       s->last_entity.ptr  = rule;
+                       goto deny;
+               }
+               else if (rule->action == ACT_TCP_CLOSE) {
+                       s->scb->flags |= SC_FL_NOLINGER | SC_FL_NOHALF;
+                       sc_must_kill_conn(s->scb);
+                       sc_abort(s->scb);
+                       sc_shutdown(s->scb);
+                       s->last_entity.type = STRM_ENTITY_RULE;
+                       s->last_entity.ptr  = rule;
+                       goto end;
                }
        }
 
@@ -498,7 +499,6 @@ int tcp_exec_l4_rules(struct session *sess)
        struct act_rule *rule;
        struct connection *conn = objt_conn(sess->origin);
        int result = 1;
-       enum acl_test_res ret;
 
        if (!conn)
                return result;
@@ -508,71 +508,64 @@ int tcp_exec_l4_rules(struct session *sess)
 
   restart:
        list_for_each_entry(rule, &px->tcp_req.l4_rules, list) {
-               ret = ACL_TEST_PASS;
 
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, sess->fe, sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
-
-               if (ret) {
-                       /* Always call the action function if defined */
-                       if (rule->action_ptr) {
-                               switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_OPT_FINAL | ACT_OPT_FIRST)) {
-                                       case ACT_RET_YIELD:
-                                               /* yield is not allowed at this point. If this return code is
-                                                * used it is a bug, so I prefer to abort the process.
-                                                */
-                                               send_log(sess->fe, LOG_WARNING,
-                                                        "Internal error: yield not allowed with tcp-request connection actions.");
-                                               /* fall through */
-                                       case ACT_RET_STOP:
-                                       case ACT_RET_DONE:
-                                               goto end;
-                                       case ACT_RET_CONT:
-                                               break;
-                                       case ACT_RET_DENY:
-                                       case ACT_RET_ABRT:
-                                       case ACT_RET_ERR:
-                                       case ACT_RET_INV:
-                                               result = 0;
-                                               goto end;
-                               }
-                               continue; /* eval the next rule */
+               if (!acl_match_cond(rule->cond, sess->fe, sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
+
+               /* Always call the action function if defined */
+               if (rule->action_ptr) {
+                       switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_OPT_FINAL | ACT_OPT_FIRST)) {
+                               case ACT_RET_YIELD:
+                                       /* yield is not allowed at this point. If this return code is
+                                        * used it is a bug, so I prefer to abort the process.
+                                        */
+                                       send_log(sess->fe, LOG_WARNING,
+                                                "Internal error: yield not allowed with tcp-request connection actions.");
+                                       /* fall through */
+                               case ACT_RET_STOP:
+                               case ACT_RET_DONE:
+                                       goto end;
+                               case ACT_RET_CONT:
+                                       break;
+                               case ACT_RET_DENY:
+                               case ACT_RET_ABRT:
+                               case ACT_RET_ERR:
+                               case ACT_RET_INV:
+                                       result = 0;
+                                       goto end;
                        }
+                       continue; /* eval the next rule */
+               }
 
-                       /* If not action function defined, check for known actions */
-                       if (rule->action == ACT_ACTION_ALLOW) {
-                               goto end;
-                       }
-                       else if (rule->action == ACT_ACTION_DENY) {
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_conn);
-                               if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->denied_conn);
+               /* If not action function defined, check for known actions */
+               if (rule->action == ACT_ACTION_ALLOW) {
+                       goto end;
+               }
+               else if (rule->action == ACT_ACTION_DENY) {
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_conn);
+                       if (sess->listener && sess->listener->counters)
+                               _HA_ATOMIC_INC(&sess->listener->counters->denied_conn);
 
-                               result = 0;
-                               goto end;
-                       }
-                       else if (rule->action == ACT_TCP_EXPECT_PX) {
-                               if (!(conn->flags & CO_FL_HANDSHAKE)) {
-                                       if (xprt_add_hs(conn) < 0) {
-                                               result = 0;
-                                               goto end;
-                                       }
+                       result = 0;
+                       goto end;
+               }
+               else if (rule->action == ACT_TCP_EXPECT_PX) {
+                       if (!(conn->flags & CO_FL_HANDSHAKE)) {
+                               if (xprt_add_hs(conn) < 0) {
+                                       result = 0;
+                                       goto end;
                                }
-                               conn->flags |= CO_FL_ACCEPT_PROXY;
                        }
-                       else if (rule->action == ACT_TCP_EXPECT_CIP) {
-                               if (!(conn->flags & CO_FL_HANDSHAKE)) {
-                                       if (xprt_add_hs(conn) < 0) {
-                                               result = 0;
-                                               goto end;
-                                       }
+                       conn->flags |= CO_FL_ACCEPT_PROXY;
+               }
+               else if (rule->action == ACT_TCP_EXPECT_CIP) {
+                       if (!(conn->flags & CO_FL_HANDSHAKE)) {
+                               if (xprt_add_hs(conn) < 0) {
+                               result = 0;
+                                       goto end;
                                }
-                               conn->flags |= CO_FL_ACCEPT_CIP;
                        }
+                       conn->flags |= CO_FL_ACCEPT_CIP;
                }
        }
 
@@ -596,60 +589,51 @@ int tcp_exec_l5_rules(struct session *sess)
        struct proxy *px = sess->fe;
        struct act_rule *rule;
        int result = 1;
-       enum acl_test_res ret;
 
        if  (sess->fe->defpx && (sess->fe->mode == PR_MODE_TCP || sess->fe->mode == PR_MODE_HTTP))
                px = sess->fe->defpx;
 
   restart:
        list_for_each_entry(rule, &px->tcp_req.l5_rules, list) {
-               ret = ACL_TEST_PASS;
-
-               if (rule->cond) {
-                       ret = acl_exec_cond(rule->cond, sess->fe, sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL);
-                       ret = acl_pass(ret);
-                       if (rule->cond->pol == ACL_COND_UNLESS)
-                               ret = !ret;
-               }
-
-               if (ret) {
-                       /* Always call the action function if defined */
-                       if (rule->action_ptr) {
-                               switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_OPT_FINAL | ACT_OPT_FIRST)) {
-                                       case ACT_RET_YIELD:
-                                               /* yield is not allowed at this point. If this return code is
-                                                * used it is a bug, so I prefer to abort the process.
-                                                */
-                                               send_log(sess->fe, LOG_WARNING,
-                                                        "Internal error: yield not allowed with tcp-request session actions.");
-                                               /* fall through */
-                                       case ACT_RET_STOP:
-                                       case ACT_RET_DONE:
-                                               goto end;
-                                       case ACT_RET_CONT:
-                                               break;
-                                       case ACT_RET_DENY:
-                                       case ACT_RET_ABRT:
-                                       case ACT_RET_ERR:
-                                       case ACT_RET_INV:
-                                               result = 0;
-                                               goto end;
-                               }
-                               continue; /* eval the next rule */
+               if (!acl_match_cond(rule->cond, sess->fe, sess, NULL, SMP_OPT_DIR_REQ|SMP_OPT_FINAL))
+                       continue;
+
+               /* Always call the action function if defined */
+               if (rule->action_ptr) {
+                       switch (rule->action_ptr(rule, sess->fe, sess, NULL, ACT_OPT_FINAL | ACT_OPT_FIRST)) {
+                               case ACT_RET_YIELD:
+                                       /* yield is not allowed at this point. If this return code is
+                                        * used it is a bug, so I prefer to abort the process.
+                                        */
+                                       send_log(sess->fe, LOG_WARNING,
+                                                "Internal error: yield not allowed with tcp-request session actions.");
+                                       /* fall through */
+                               case ACT_RET_STOP:
+                               case ACT_RET_DONE:
+                                       goto end;
+                               case ACT_RET_CONT:
+                                       break;
+                               case ACT_RET_DENY:
+                               case ACT_RET_ABRT:
+                               case ACT_RET_ERR:
+                               case ACT_RET_INV:
+                                       result = 0;
+                                       goto end;
                        }
+                       continue; /* eval the next rule */
+               }
 
-                       /* If not action function defined, check for known actions */
-                       if (rule->action == ACT_ACTION_ALLOW) {
-                               goto end;
-                       }
-                       else if (rule->action == ACT_ACTION_DENY) {
-                               _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_sess);
-                               if (sess->listener && sess->listener->counters)
-                                       _HA_ATOMIC_INC(&sess->listener->counters->denied_sess);
+               /* If not action function defined, check for known actions */
+               if (rule->action == ACT_ACTION_ALLOW) {
+                       goto end;
+               }
+               else if (rule->action == ACT_ACTION_DENY) {
+                       _HA_ATOMIC_INC(&sess->fe->fe_counters.denied_sess);
+                       if (sess->listener && sess->listener->counters)
+                               _HA_ATOMIC_INC(&sess->listener->counters->denied_sess);
 
-                               result = 0;
-                               goto end;
-                       }
+                       result = 0;
+                       goto end;
                }
        }