From de9d605aa56d257e3720f080a8c7f30b54fa6543 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Fri, 23 Apr 2021 12:25:18 +0200 Subject: [PATCH] BUG/MEDIUM: mux-h2: Properly handle shutdowns when received with data The H2_CF_RCVD_SHUT flag is used to report a read0 was encountered. It is used by the H2 mux to properly handle shutdowns. However, this flag is only set when no data are received. If it is detected at the socket level when some data are received, it is not handled. And because the event was reported on the connection, any other read attempts are blocked. In this case, we are unable to close the connection and release the mux immediately. We must wait the mux timeout expires. This patch should fix the issue #1231. It must be backported as far as 2.0. --- src/mux_h2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index 35767b185..950dc9e73 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3631,17 +3631,17 @@ static int h2_recv(struct h2c *h2c) ret = max ? conn->xprt->rcv_buf(conn, conn->xprt_ctx, buf, max, 0) : 0; - 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 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); - } + if (max && !ret && 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); } else if (ret) TRACE_DATA("received data", H2_EV_H2C_RECV, h2c->conn, 0, 0, (void*)(long)ret); + if (conn_xprt_read0_pending(h2c->conn)) { + TRACE_DATA("received read0", H2_EV_H2C_RECV, h2c->conn); + h2c->flags |= H2_CF_RCVD_SHUT; + } + if (!b_data(buf)) { h2_release_buf(h2c, &h2c->dbuf); TRACE_LEAVE(H2_EV_H2C_RECV, h2c->conn);