]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: Reinforce conditions to report an error to app-layer stream
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 9 Sep 2025 13:59:11 +0000 (15:59 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 9 Sep 2025 14:30:54 +0000 (16:30 +0200)
This patch relies on the previous one ("BUG/MEDIUM: mux-h2: Report RST/error to
app-layer stream during 0-copy fwding").

When the end of the connection is detected, so when the H2_CF_END_REACHED
flag is set after the shutdown was received and all incoming data were
processed, if a stream is blocked by the flow control (the stream one or the
connection one), an error must be reported to the app-layer stream.

Otherwise, outgoing data won't be sent and the opposite side will handle
this as a lack of room. So the stream will be blocked until the write
timeout is triggerd. By reporting the error early, the stream can be
immediately closed.

This patch should be backported to 3.2. For older versions, it is probably a
good idea to wait for bug report.

src/mux_h2.c

index cfb3d36bd599f0a906644bdc31ed032954727158..a64e432dc7d563b1c643c103b4a34d1edbf723c8 100644 (file)
@@ -7949,7 +7949,8 @@ static size_t h2_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, in
        }
 
        /* RST are sent similarly to frame acks */
-       if (h2s->st == H2_SS_ERROR || h2s->flags & H2_SF_RST_RCVD) {
+       if (h2s->st == H2_SS_ERROR || h2s->flags & H2_SF_RST_RCVD ||
+           ((h2s->h2c->flags & H2_CF_END_REACHED) && (h2s->flags & (H2_SF_BLK_SFCTL|H2_SF_BLK_MFCTL)))) {
                TRACE_DEVEL("reporting RST/error to the app-layer stream", H2_EV_H2S_SEND|H2_EV_H2S_ERR|H2_EV_STRM_ERR, h2s->h2c->conn, h2s);
                se_fl_set_error(h2s->sd);
                se_report_term_evt(h2s->sd, se_tevt_type_snd_err);
@@ -8124,7 +8125,8 @@ static size_t h2_nego_ff(struct stconn *sc, struct buffer *input, size_t count,
                h2s->flags &= ~H2_SF_NOTIFIED;
 
        /* RST are sent similarly to frame acks */
-       if (h2s->st == H2_SS_ERROR || h2s->flags & H2_SF_RST_RCVD) {
+       if (h2s->st == H2_SS_ERROR || h2s->flags & H2_SF_RST_RCVD ||
+           ((h2c->flags & H2_CF_END_REACHED) && (h2s->flags & (H2_SF_BLK_SFCTL|H2_SF_BLK_MFCTL)))) {
                TRACE_DEVEL("reporting RST/error to the app-layer stream", H2_EV_H2S_SEND|H2_EV_H2S_ERR|H2_EV_STRM_ERR, h2s->h2c->conn, h2s);
                se_fl_set_error(h2s->sd);
                se_report_term_evt(h2s->sd, se_tevt_type_snd_err);