From: Amaury Denoyelle Date: Wed, 25 Mar 2026 13:17:38 +0000 (+0100) Subject: MEDIUM: ssl: load xprt_qstrm after handshake completion X-Git-Tag: v3.4-dev8~22 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/NGINX-js-1660x332.png%20%22NGINX%20JavaScript%20Banner%22?a=commitdiff_plain;h=3c42a7e9acacb2527cbdadff064eacb13715783b;p=haproxy.git MEDIUM: ssl: load xprt_qstrm after handshake completion On SSL handshake completion, MUX layer can be initialized if not already the case. However, for QMux protocol, it is necessary first to perform transport parameters exchange, via the new xprt_qstrm layer. This patch ensures this is performed if any flag CO_FL_QSTRM_* is set on the connection. Also, SSL layer registers itself via add_xprt. This ensures that it can be used by xprt_qstrm for the emission/reception of the necessary frames. --- diff --git a/src/connection.c b/src/connection.c index 19ee3be57..677f3f474 100644 --- a/src/connection.c +++ b/src/connection.c @@ -182,7 +182,7 @@ int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake) * information to create one, typically from the ALPN. If we're * done with the handshake, attempt to create one. */ - if (unlikely(!conn->mux) && !(conn->flags & CO_FL_WAIT_XPRT)) { + if (unlikely(!conn->mux) && !(conn->flags & (CO_FL_WAIT_XPRT|CO_FL_QSTRM_RECV|CO_FL_QSTRM_SEND))) { ret = conn_create_mux(conn, NULL); if (ret < 0) goto done; diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 23ad58cbe..9544deffc 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -6957,9 +6957,30 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state) if (ctx->conn->xprt_ctx == ctx) { int closed_connection = 0; - if (!ctx->conn->mux) - ret = conn_create_mux(ctx->conn, &closed_connection); - if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake) { + if (!ctx->conn->mux) { + if (ctx->conn->flags & (CO_FL_QSTRM_RECV|CO_FL_QSTRM_SEND)) { + const struct xprt_ops *ops = xprt_get(XPRT_QSTRM); + void *xprt_ctx_hs = NULL; + + ret = ops->init(conn, &xprt_ctx_hs); + BUG_ON(ret); + + ret = ops->add_xprt(conn, xprt_ctx_hs, + conn->xprt_ctx, conn->xprt, NULL, NULL); + BUG_ON(ret); + + conn->xprt = ops; + conn->xprt_ctx = xprt_ctx_hs; + + + ret = conn->xprt->start(conn, xprt_ctx_hs); + BUG_ON(ret); + } + else + ret = conn_create_mux(ctx->conn, &closed_connection); + } + + if (ret >= 0 && ctx->conn->mux && !woke && ctx->conn->mux && ctx->conn->mux->wake) { ret = CALL_MUX_WITH_RET(ctx->conn->mux, wake(ctx->conn)); if (ret < 0) closed_connection = 1;