From: Christopher Faulet Date: Tue, 9 Sep 2025 13:40:01 +0000 (+0200) Subject: BUG/MEDIUM: mux-h2: Restart reading when mbuf ring is no longer full X-Git-Tag: v3.3-dev9~190 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12edcccc8230b271635a764b5bee9346d6828733;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mux-h2: Restart reading when mbuf ring is no longer full When the mbuf ring buffer is full, the flag H2_CF_DEM_MROOM is set on the H2 connection to block any demux. It is important to properly handle ACK frames. However, we must take care to restart reading when some data were removed from the mbuf. Otherwise, we may block the demux for no reason. It is especially an issue if the demux buffer is full. In that case, the H2 connection is blocked, waiting for the timeout. This patch should be backported to 3.2. But is is probably a good idea to not backport it on older versions, except if a bug is reported in this area. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index 96f6d884a..457df083f 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -5037,6 +5037,7 @@ static int h2_process(struct h2c *h2c) { struct connection *conn = h2c->conn; int extra_reads = MIN(MAX(bl_avail(h2c->shared_rx_bufs), 1) - 1, 12); + int was_blocked = 0; TRACE_ENTER(H2_EV_H2C_WAKE, conn); @@ -5071,6 +5072,7 @@ static int h2_process(struct h2c *h2c) if (h2c->st0 >= H2_CS_ERROR || (h2c->flags & H2_CF_ERROR)) b_reset(&h2c->dbuf); } + was_blocked |= !!(h2c->flags & H2_CF_DEM_MROOM); h2_send(h2c); if (unlikely(h2c->proxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) && !(h2c->flags & H2_CF_IS_BACK)) { @@ -5163,7 +5165,13 @@ static int h2_process(struct h2c *h2c) h2_release_mbuf(h2c); h2c_update_timeout(h2c); + + was_blocked |= !!(h2c->flags & H2_CF_DEM_MROOM); h2_send(h2c); + + if (was_blocked && !(h2c->flags & H2_CF_DEM_MROOM)) + h2c_restart_reading(h2c, 1); + TRACE_LEAVE(H2_EV_H2C_WAKE, conn); return 0; }