]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: load xprt_qstrm after handshake completion
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 25 Mar 2026 13:17:38 +0000 (14:17 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 2 Apr 2026 12:02:04 +0000 (14:02 +0200)
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.

src/connection.c
src/ssl_sock.c

index 19ee3be57c1a898f65a9fa9994a328ea4534a4d3..677f3f4744387eb0534d5bf2af9ff3a30f1cdaaf 100644 (file)
@@ -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;
index 23ad58cbe24fa9571f56bf1abd4eaa0d223ea7f3..9544deffc8b47cefb4e6e66fb39a4c3d443ecdbb 100644 (file)
@@ -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;