BUG/MEDIUM: mux-h2: Reinforce conditions to report an error to app-layer stream

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.
This commit is contained in:
Christopher Faulet 2025-09-09 15:59:11 +02:00
parent 22e14f7b54
commit b901e56acd

View 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);