]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection/mux_quic: add MUX <init_xprt> field for QMux handshake
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 18 May 2026 14:58:04 +0000 (16:58 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 19 May 2026 16:40:50 +0000 (18:40 +0200)
The first part of this patch defines a new mux_proto_list field named
<xprt_init>. This allows to define an extra XPRT layer which should be
activated first prior to the MUX creation both on frontend and backend
sides.

This is immediately used for QMux mux_proto_list to require XPRT_QMUX
handshake. With this change, activation of QMux connection flags in
session_accept_fd() and connect_server() are adjusted to take into
account <init_xprt> field. This approach is much more evolutive than
relying on the previous MUX name.

Change in connect_server() will also be necessary to support QMux
activation on a TCP server with h3 ALPN without explicit "proto qmux".
This guarantees that MUX initialization is delayed after QMux handshake.

include/haproxy/connection-t.h
src/backend.c
src/mux_quic.c
src/session.c

index 41f02425f50478a225b27f03e2f98327d63a2ae2..1cff9f3ee00a54bf1a8954153f8133d9cb093442 100644 (file)
@@ -678,6 +678,7 @@ struct mux_proto_list {
        enum proto_proxy_side side;
        const struct mux_ops *mux;
        const char *alpn;          /* Default alpn to set by default when the mux protocol is forced (optional, in binary form) */
+       int init_xprt;
        struct list list;
 };
 
index db914fd613665c57c23126f447f405036903d5a7..f460b261c2c6f4beedd203ec78f9e37bd6ef994d 100644 (file)
@@ -1811,6 +1811,7 @@ int connect_server(struct stream *s)
 {
        struct connection *cli_conn = objt_conn(strm_orig(s));
        struct connection *srv_conn = NULL;
+       const struct mux_proto_list *mux_proto;
        struct server *srv;
        int reuse_mode;
        int reuse __maybe_unused = 0;
@@ -2130,9 +2131,13 @@ int connect_server(struct stream *s)
                        srv_conn->flags |= CO_FL_SOCKS4;
                }
 
-               if (srv && srv->mux_proto && isteq(srv->mux_proto->mux_proto, ist("qmux"))) {
-                       srv_conn->flags |= (CO_FL_QMUX_RECV|CO_FL_QMUX_SEND);
-                       may_start_mux_now = 0;
+               if (may_start_mux_now) {
+                       /* Delay QMux MUX init to let xprt_qmux handshake runs first. */
+                       mux_proto = conn_select_mux_be(srv_conn);
+                       if (mux_proto && mux_proto->init_xprt == XPRT_QMUX) {
+                               srv_conn->flags |= (CO_FL_QMUX_RECV|CO_FL_QMUX_SEND);
+                               may_start_mux_now = 0;
+                       }
                }
 
 #if defined(USE_OPENSSL) && defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
index 5e18178a955278e0a53aff20f3ca73361b70d4fa..94f7b5c5b9293cc73a79bcdef0a31c36783505e3 100644 (file)
@@ -4813,6 +4813,7 @@ static const struct mux_ops qmux_ops = {
 };
 
 static struct mux_proto_list mux_proto_qmux =
-  { .mux_proto = IST("qmux"), .mode = PROTO_MODE_HTTP, .side = PROTO_SIDE_BOTH, .mux = &qmux_ops };
+  { .mux_proto = IST("qmux"), .mode = PROTO_MODE_HTTP, .side = PROTO_SIDE_BOTH, .mux = &qmux_ops,
+    .init_xprt = XPRT_QMUX };
 
 INITCALL1(STG_REGISTER, register_mux_proto, &mux_proto_qmux);
index 2815c215f248009767b08604977d17ed4deaa95b..a9c8c6d8505c6c4bf88a96b7c413f941a6c97cf2 100644 (file)
@@ -241,7 +241,7 @@ int session_accept_fd(struct connection *cli_conn)
                if (l->bind_conf->options & BC_O_ACC_CIP)
                        cli_conn->flags |= CO_FL_ACCEPT_CIP;
 
-               if (l->bind_conf->mux_proto && isteq(l->bind_conf->mux_proto->mux_proto, ist("qmux")))
+               if (l->bind_conf->mux_proto && l->bind_conf->mux_proto->init_xprt == XPRT_QMUX)
                        cli_conn->flags |= (CO_FL_QMUX_RECV|CO_FL_QMUX_SEND);
 
                /* Add the handshake pseudo-XPRT */