From: Amaury Denoyelle Date: Tue, 22 Jul 2025 14:45:39 +0000 (+0200) Subject: MEDIUM: mux-quic: support backend private connection X-Git-Tag: v3.3-dev4~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08d664b17c13cd7c2000de8dfec38ba0fb7711c0;p=thirdparty%2Fhaproxy.git MEDIUM: mux-quic: support backend private connection If a backend connection is private, it should not be reused outside of its original attached session. As such, on stream detach operation, such connection is never inserted into server idle/avail list. Instead, it is stored directly on the session. The purpose of this commit is to implement proper handling of private backend connections via QUIC multiplexer. --- diff --git a/src/mux_quic.c b/src/mux_quic.c index 87d981154..1a0db225c 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -3751,6 +3751,7 @@ static void qmux_strm_detach(struct sedesc *sd) struct qcs *qcs = sd->se; struct qcc *qcc = qcs->qcc; struct connection *conn = qcc->conn; + struct session *sess = qcs->sess; TRACE_ENTER(QMUX_EV_STRM_END, conn, qcs); @@ -3780,7 +3781,32 @@ static void qmux_strm_detach(struct sedesc *sd) /* Backend connection can be reused unless it is already on error/closed. */ if ((qcc->flags & QC_CF_IS_BACK) && !qcc_is_dead(qcc) && qcc->app_st == QCC_APP_ST_INIT) { - if (!(conn->flags & CO_FL_PRIVATE)) { + if (conn->flags & CO_FL_PRIVATE) { + TRACE_DEVEL("handle private connection reuse", QMUX_EV_STRM_END, conn); + + /* Add connection into session. If an error occured, + * conn will be closed if idle, or insert will be + * retried on next detach. + */ + if (!session_add_conn(sess, conn, conn->target)) { + TRACE_ERROR("error during connection insert into session list", QMUX_EV_STRM_END, conn); + conn->owner = NULL; + if (!qcc->nb_sc) { + qcc_shutdown(qcc); + goto end; + } + } + + /* If conn is idle, check if session can keep it. Conn is freed if this is not the case. + * TODO graceful shutdown should be preferable instead of plain mux->destroy(). + */ + if (!qcc->nb_sc && session_check_idle_conn(sess, conn)) { + TRACE_DEVEL("idle conn rejected by session", QMUX_EV_STRM_END); + conn = NULL; + goto end; + } + } + else { if (!qcc->nb_sc) { TRACE_DEVEL("prepare for idle connection reuse", QMUX_EV_STRM_END, conn); if (!srv_add_to_idle_list(objt_server(conn->target), conn, 1)) {