From 061a098c5c2b559a2b208d9c67145d98400ada2d Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 29 Nov 2022 17:16:30 +0100 Subject: [PATCH] BUG/MEDIUM: mux-h1: Close client H1C on EOS when there is no output data If the client closes the connection while there is no pending outgoing data, the H1 connection must be released. However, it was switched to CLOSING state instead. Thus the client connection was closed on client timeout. It is side effect of the commif d1b573059a ("MINOR: mux-h1: Avoid useless call to h1_send() if no error is sent"). Before, the extra call to h1_send() was able to fix the H1C state. To fix the bug and make switch to close state (CLOSING or CLOSED) less errorprone, h1_close() helper function is systematically used. It is a 2.7-specific bug. No backport needed. --- src/mux_h1.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mux_h1.c b/src/mux_h1.c index c1fcc256a4..9a2306ae64 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -2635,7 +2635,7 @@ static int h1_send_error(struct h1c *h1c) } h1c->flags = (h1c->flags & ~(H1C_F_WAIT_NEXT_REQ|H1C_F_ABRT_PENDING)) | H1C_F_ABRTED; - h1c->state = H1_CS_CLOSING; + h1_close(h1c); out: TRACE_LEAVE(H1_EV_H1C_ERR, h1c->conn); return ret; @@ -2673,8 +2673,8 @@ static int h1_handle_parsing_error(struct h1c *h1c) int ret = 0; if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) { - h1c->state = H1_CS_CLOSING; h1c->flags = (h1c->flags & ~H1C_F_WAIT_NEXT_REQ) | H1C_F_ABRTED; + h1_close(h1c); goto end; } @@ -2706,8 +2706,8 @@ static int h1_handle_not_impl_err(struct h1c *h1c) int ret = 0; if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) { - h1c->state = H1_CS_CLOSING; h1c->flags = (h1c->flags & ~H1C_F_WAIT_NEXT_REQ) | H1C_F_ABRTED; + h1_close(h1c); goto end; } @@ -2736,8 +2736,8 @@ static int h1_handle_req_tout(struct h1c *h1c) int ret = 0; if (!b_data(&h1c->ibuf) && ((h1c->flags & H1C_F_WAIT_NEXT_REQ) || (sess->fe->options & PR_O_IGNORE_PRB))) { - h1c->state = H1_CS_CLOSING; h1c->flags = (h1c->flags & ~H1C_F_WAIT_NEXT_REQ) | H1C_F_ABRTED; + h1_close(h1c); goto end; } @@ -3404,7 +3404,7 @@ static void h1_detach(struct sedesc *sd) */ if (b_data(&h1c->ibuf)) { h1_release_buf(h1c, &h1c->ibuf); - h1c->state = H1_CS_CLOSING; + h1_close(h1c); TRACE_DEVEL("remaining data on detach, kill connection", H1_EV_STRM_END|H1_EV_H1C_END); goto release; } @@ -3521,7 +3521,7 @@ static void h1_shutw(struct stconn *sc, enum co_shw_mode mode) } do_shutw: - h1c->state = H1_CS_CLOSING; + h1_close(h1c); if (mode != CO_SHW_NORMAL) h1c->flags |= H1C_F_SILENT_SHUT; -- 2.47.3