diff --git a/include/types/stream.h b/include/types/stream.h index be285683d..4203af8db 100644 --- a/include/types/stream.h +++ b/include/types/stream.h @@ -156,7 +156,7 @@ struct stream { /* These two pointers are used to resume the execution of the rule lists. */ struct list *current_rule_list; /* this is used to store the current executed rule list. */ - struct list *current_rule; /* this is used to store the current rule to be resumed. */ + void *current_rule; /* this is used to store the current rule to be resumed. */ struct hlua hlua; /* lua runtime context */ }; diff --git a/src/proto_http.c b/src/proto_http.c index 4db982aee..377160b4b 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -3359,11 +3359,14 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream * and never in the ACL or converters. In this case, we initialise the * current rule, and go to the action execution point. */ - if (s->current_rule_list == rules) { - rule = LIST_ELEM(s->current_rule, typeof(rule), list); - goto resume_execution; + if (s->current_rule) { + rule = s->current_rule; + s->current_rule = NULL; + if (s->current_rule_list == rules) + goto resume_execution; } s->current_rule_list = rules; + list_for_each_entry(rule, rules, list) { if (rule->action >= HTTP_REQ_ACT_MAX) continue; @@ -3383,7 +3386,6 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct stream } resume_execution: - switch (rule->action) { case HTTP_REQ_ACT_ALLOW: return HTTP_RULE_RES_STOP; @@ -3566,7 +3568,7 @@ resume_execution: case HTTP_REQ_ACT_CUSTOM_CONT: if (!rule->action_ptr(rule, px, s)) { - s->current_rule = &rule->list; + s->current_rule = rule; return HTTP_RULE_RES_YIELD; } break; @@ -3637,11 +3639,14 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct stream * and never in the ACL or converters. In this case, we initialise the * current rule, and go to the action execution point. */ - if (s->current_rule_list == rules) { - rule = LIST_ELEM(s->current_rule, typeof(rule), list); - goto resume_execution; + if (s->current_rule) { + rule = s->current_rule; + s->current_rule = NULL; + if (s->current_rule_list == rules) + goto resume_execution; } s->current_rule_list = rules; + list_for_each_entry(rule, rules, list) { if (rule->action >= HTTP_RES_ACT_MAX) continue; @@ -3661,7 +3666,6 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct stream } resume_execution: - switch (rule->action) { case HTTP_RES_ACT_ALLOW: return HTTP_RULE_RES_STOP; /* "allow" rules are OK */ @@ -3814,7 +3818,7 @@ resume_execution: case HTTP_RES_ACT_CUSTOM_CONT: if (!rule->action_ptr(rule, px, s)) { - s->current_rule = &rule->list; + s->current_rule = rule; return HTTP_RULE_RES_YIELD; } break; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 17ec22e1b..efa9158bf 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -1125,11 +1125,14 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit) * and never in the ACL or converters. In this case, we initialise the * current rule, and go to the action execution point. */ - if (s->current_rule_list == &s->be->tcp_req.inspect_rules) { - rule = LIST_ELEM(s->current_rule, typeof(rule), list); - goto resume_execution; + if (s->current_rule) { + rule = s->current_rule; + s->current_rule = NULL; + if (s->current_rule_list == &s->be->tcp_req.inspect_rules) + goto resume_execution; } s->current_rule_list = &s->be->tcp_req.inspect_rules; + list_for_each_entry(rule, &s->be->tcp_req.inspect_rules, list) { enum acl_test_res ret = ACL_TEST_PASS; @@ -1144,9 +1147,7 @@ int tcp_inspect_request(struct stream *s, struct channel *req, int an_bit) } if (ret) { - resume_execution: - /* we have a matching rule. */ if (rule->action == TCP_ACT_REJECT) { channel_abort(req); @@ -1216,7 +1217,7 @@ resume_execution: else { /* Custom keywords. */ if (rule->action_ptr(rule, s->be, s) == 0) { - s->current_rule = &rule->list; + s->current_rule = rule; goto missing_data; } @@ -1283,11 +1284,14 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit) * and never in the ACL or converters. In this case, we initialise the * current rule, and go to the action execution point. */ - if (s->current_rule_list == &s->be->tcp_rep.inspect_rules) { - rule = LIST_ELEM(s->current_rule, typeof(rule), list); - goto resume_execution; + if (s->current_rule) { + rule = s->current_rule; + s->current_rule = NULL; + if (s->current_rule_list == &s->be->tcp_rep.inspect_rules) + goto resume_execution; } s->current_rule_list = &s->be->tcp_rep.inspect_rules; + list_for_each_entry(rule, &s->be->tcp_rep.inspect_rules, list) { enum acl_test_res ret = ACL_TEST_PASS; @@ -1306,9 +1310,7 @@ int tcp_inspect_response(struct stream *s, struct channel *rep, int an_bit) } if (ret) { - resume_execution: - /* we have a matching rule. */ if (rule->action == TCP_ACT_REJECT) { channel_abort(rep); @@ -1336,7 +1338,7 @@ resume_execution: /* Custom keywords. */ if (!rule->action_ptr(rule, s->be, s)) { channel_dont_close(rep); - s->current_rule = &rule->list; + s->current_rule = rule; return 0; }