From: Christopher Faulet Date: Tue, 30 Jul 2024 06:41:03 +0000 (+0200) Subject: BUG/MEDIUM: mux-pt/mux-h1: Release the pipe on connection error on sending path X-Git-Tag: v3.0.5~66 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=7749062aba94938b88165416274734c65989da92;p=haproxy-3.0.git BUG/MEDIUM: mux-pt/mux-h1: Release the pipe on connection error on sending path When data are sent using the kernel splicing, if a connection error occurred, the pipe must be released. Indeed, in that case, no more data can be sent and there is no reason to not release the pipe. But it is in fact an issue for the stream because the channel will appear are not empty. This may prevent the stream to be released. This happens on 2.8 when a filter is also attached on it. On 2.9 and upper, it seems there is not issue. But it is hard to be sure and the current patch remains valid is all cases. On 2.6 and lower, the code is not the same and, AFAIK, there is no issue. This patch must be backported to 2.8. However, on 2.8, there is no zero-copy data forwarding. The patch must be adapted. There is no done_ff/resume_ff callback functions for muxes. The pipe must released in sc_conn_send() when an error flag is set on the SE, after the call to snd_pipe callback function. (cherry picked from commit 760d26a8625f3af2b6939037a40f19b5f8063be1) Signed-off-by: Christopher Faulet --- diff --git a/src/mux_h1.c b/src/mux_h1.c index 45294bc..cdbad2b 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -4830,6 +4830,10 @@ static size_t h1_done_ff(struct stconn *sc) h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event); } se_fl_set_error(h1s->sd); + if (sd->iobuf.pipe) { + put_pipe(sd->iobuf.pipe); + sd->iobuf.pipe = NULL; + } TRACE_DEVEL("connection error", H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s); } @@ -5085,6 +5089,10 @@ static int h1_resume_fastfwd(struct stconn *sc, unsigned int flags) h1c->conn->xprt->subscribe(h1c->conn, h1c->conn->xprt_ctx, SUB_RETRY_RECV, &h1c->wait_event); } se_fl_set_error(h1s->sd); + if (h1s->sd->iobuf.pipe) { + put_pipe(h1s->sd->iobuf.pipe); + h1s->sd->iobuf.pipe = NULL; + } TRACE_DEVEL("connection error", H1_EV_STRM_ERR|H1_EV_H1C_ERR|H1_EV_H1S_ERR, h1c->conn, h1s); } diff --git a/src/mux_pt.c b/src/mux_pt.c index 72526b5..7a7833d 100644 --- a/src/mux_pt.c +++ b/src/mux_pt.c @@ -627,6 +627,10 @@ static size_t mux_pt_done_ff(struct stconn *sc) if (conn_xprt_read0_pending(conn)) se_fl_set(ctx->sd, SE_FL_EOS); se_fl_set_error(ctx->sd); + if (se->iobuf.pipe) { + put_pipe(se->iobuf.pipe); + se->iobuf.pipe = NULL; + } TRACE_DEVEL("error on connection", PT_EV_TX_DATA|PT_EV_CONN_ERR, conn, sc); } @@ -742,6 +746,10 @@ static int mux_pt_resume_fastfwd(struct stconn *sc, unsigned int flags) if (conn_xprt_read0_pending(conn)) se_fl_set(ctx->sd, SE_FL_EOS); se_fl_set_error(ctx->sd); + if (se->iobuf.pipe) { + put_pipe(se->iobuf.pipe); + se->iobuf.pipe = NULL; + } TRACE_DEVEL("error on connection", PT_EV_TX_DATA|PT_EV_CONN_ERR, conn, sc); }