From: Christopher Faulet Date: Mon, 30 Jun 2025 14:23:39 +0000 (+0200) Subject: BUG/MEDIUM: mux-h2: Properly handle connection error during preface sending X-Git-Tag: v3.3-dev3~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5ba0a2d5270f2ba52a3022578e52fb5709bff3cb;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-h2: Properly handle connection error during preface sending On backend side, an error at connection level during the preface sending was not properly handled and could lead to a spinning loop on process_stream() when the h2 stream on client side was blocked, for instance because of h2 flow control. It appeared that no transition was perfromed from the PREFACE state to an ERROR state on the H2 connection when an error occurred on the underlying connection. In that case, the H2 connection was woken up in loop to try to receive data, waking up the upper stream at the same time. To fix the issue, an H2C error must be reported. Most state transitions are handled by the demux function. So it is the right place to do so. First, in PREFACE state and on server side, if an error occurred on the TCP connection, an error is now reported on the H2 connection. REFUSED_STREAM error code is used in that case. In addition, in that case, we also take care to properly handle the connection shutdown. This patch should fix the issue #3020. It must be backported to all stable versions. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index c5f12fca3..46c2d756c 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -4139,8 +4139,11 @@ static void h2_process_demux(struct h2c *h2c) if (unlikely(h2c->st0 < H2_CS_FRAME_H)) { if (h2c->st0 == H2_CS_PREFACE) { TRACE_STATE("expecting preface", H2_EV_RX_PREFACE, h2c->conn); - if (h2c->flags & H2_CF_IS_BACK) - goto out; + if (h2c->flags & H2_CF_IS_BACK) { + if (h2c->conn->flags & CO_FL_ERROR) + h2c_error(h2c, H2_ERR_REFUSED_STREAM); + goto done; + } if (unlikely(h2c_frt_recv_preface(h2c) <= 0)) { /* RFC7540#3.5: a GOAWAY frame MAY be omitted */