]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-pt: Set EOS on error on sending path if read0 was received
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 13 Mar 2023 10:07:37 +0000 (11:07 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 13 Mar 2023 10:22:13 +0000 (11:22 +0100)
It is more a less a revert of the commit b65af26e1 ("MEDIUM: mux-pt: Don't
always set a final error on SE on the sending path"). The PT multiplexer is
so simple that an error on the sending path is terminal. Unlike other muxes,
there is no connection level here. However, instead of reporting an final
error by setting SE_FL_ERROR, we set SE_FL_EOS flag instead if a read0 was
received on the underlying connection. Concretely, it is always true with
the current design of the raw socket layer. But it is cleaner this way.

Without this patch, it is possible to block a TCP socket if a connection
error is triggered when data are sent (for instance a broken pipe) while the
upper stream does not expect to receive more data.

Note the patch above introduced a regression because errors handling at the
connection level is quite simple. All errors are final. But we must keep in
mind it may change. And if so, this will require to move back on a 2-step
errors handling in the mux-pt.

This patch must be backported to 2.7.

src/mux_pt.c

index 86a1f2362e766b43a4b5182ccde2b07180f44114..4895c1780466137886daca0667f740c9db64cad9 100644 (file)
@@ -557,6 +557,8 @@ static size_t mux_pt_snd_buf(struct stconn *sc, struct buffer *buf, size_t count
                b_del(buf, ret);
 
        if (conn->flags & CO_FL_ERROR) {
+               if (conn_xprt_read0_pending(conn))
+                       se_fl_set(ctx->sd, SE_FL_EOS);
                se_fl_set_error(ctx->sd);
                TRACE_DEVEL("error on connection", PT_EV_TX_DATA|PT_EV_CONN_ERR, conn, sc);
        }
@@ -625,6 +627,8 @@ static int mux_pt_snd_pipe(struct stconn *sc, struct pipe *pipe)
        ret = conn->xprt->snd_pipe(conn, conn->xprt_ctx, pipe);
 
        if (conn->flags & CO_FL_ERROR) {
+               if (conn_xprt_read0_pending(conn))
+                       se_fl_set(ctx->sd, SE_FL_EOS);
                se_fl_set_error(ctx->sd);
                TRACE_DEVEL("error on connection", PT_EV_TX_DATA|PT_EV_CONN_ERR, conn, sc);
        }