From: Willy Tarreau Date: Fri, 5 Feb 2021 10:41:46 +0000 (+0100) Subject: BUG/MEDIUM: mux-h2: handle remaining read0 cases X-Git-Tag: v2.1.12~54 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=e035d9f9937783f21f68e8c27cf4873fea7a0332;p=haproxy-2.1.git BUG/MEDIUM: mux-h2: handle remaining read0 cases Commit 3d4631fec ("BUG/MEDIUM: mux-h2: fix read0 handling on partial frames") tried to address an issue introduced in commit aade4edc1 where read0 wasn't properly handled in the middle of a frame. But the fix was incomplete for two reasons: - first, it would set H2_CF_RCVD_SHUT in h2_recv() after detecting a read0 but the condition was guarded by h2_recv_allowed() which explicitly excludes read0 ; - second, h2_process would only call h2_process_demux() when there were still data in the buffer, but closing after a short pause to leave a buffer empty wouldn't be caught in this case. This patch fixes this by properly taking care of the received shutdown and by also waking up h2_process_demux() on an empty buffer if the demux is not blocked. Given the patches above were tagged for backporting to 2.0, this one should be as well. (cherry picked from commit f09612289f4a6e358524df385473323ea4254883) Signed-off-by: Willy Tarreau (cherry picked from commit 5554e636261a90f672e391e7e90c3089501a386d) Signed-off-by: Willy Tarreau (cherry picked from commit f58701b2f2a4db22f0eaea6fc3e53e22dcbe11b0) Signed-off-by: Christopher Faulet --- diff --git a/src/mux_h2.c b/src/mux_h2.c index 2903129..1b60607 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3411,11 +3411,11 @@ static int h2_recv(struct h2c *h2c) ret = max ? conn->xprt->rcv_buf(conn, conn->xprt_ctx, buf, max, 0) : 0; - if (max && !ret && h2_recv_allowed(h2c)) { + if (max && !ret) { if (conn_xprt_read0_pending(h2c->conn)) { TRACE_DATA("received read0", H2_EV_H2C_RECV, h2c->conn); h2c->flags |= H2_CF_RCVD_SHUT; - } else { + } else if (h2_recv_allowed(h2c)) { TRACE_DATA("failed to receive data, subscribing", H2_EV_H2C_RECV, h2c->conn); conn->xprt->subscribe(conn, conn->xprt_ctx, SUB_RETRY_RECV, &h2c->wait_event); } @@ -3578,7 +3578,8 @@ static int h2_process(struct h2c *h2c) TRACE_ENTER(H2_EV_H2C_WAKE, conn); - if (b_data(&h2c->dbuf) && !(h2c->flags & H2_CF_DEM_BLOCK_ANY)) { + if (!(h2c->flags & H2_CF_DEM_BLOCK_ANY) && + (b_data(&h2c->dbuf) || (h2c->flags & H2_CF_RCVD_SHUT))) { h2_process_demux(h2c); if (h2c->st0 >= H2_CS_ERROR || conn->flags & CO_FL_ERROR)