From 5ba0a2d5270f2ba52a3022578e52fb5709bff3cb Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 30 Jun 2025 16:23:39 +0200 Subject: [PATCH] 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. --- src/mux_h2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 */