]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: tcp-rules: Don't forward close during tcp-response content rules eval
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 3 Feb 2025 14:31:57 +0000 (15:31 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 3 Feb 2025 14:31:59 +0000 (15:31 +0100)
When the tcp-response content ruleset evaluation is delayed because of an
ACL condition, the close forwarding on the client side is not explicitly
blocked. So it is possible to close the client side before the end of the
response evaluation.

To fix the issue, this is now done in all cases where some data are
missing. Concretely, channel_dont_close() is called in "missing_data" goto
label.

Note it is only a theorical bug (or pending bug). It is not possible to
trigger it for now because an ACL cannot wait for more data when a close was
received. But the code remains a bit weak. It is safer this way. It is
especially mandatory for the "force yield" option that should be added soon.

This patch could be backported to all stable versions.

src/tcp_rules.c

index d65be42043b2a62267a8ed43d67a446aa26ed83c..d4c40258bfe2f45027ef65b559f5b2546fe388c7 100644 (file)
@@ -383,7 +383,6 @@ resume_execution:
                                        }
                                        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;
@@ -445,6 +444,7 @@ resume_execution:
 
  missing_data:
        /* just set the analyser timeout once at the beginning of the response */
+       channel_dont_close(rep);
        if (!tick_isset(s->rules_exp) && s->be->tcp_rep.inspect_delay)
                s->rules_exp = tick_add(now_ms, s->be->tcp_rep.inspect_delay);
        rep->analyse_exp = tick_first((tick_is_expired(rep->analyse_exp, now_ms) ? 0 : rep->analyse_exp), s->rules_exp);