From: Amaury Denoyelle Date: Mon, 18 May 2026 14:58:04 +0000 (+0200) Subject: MINOR: connection/mux_quic: add MUX field for QMux handshake X-Git-Tag: v3.4-dev13~32 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/postgres_fdw.c?a=commitdiff_plain;h=879c78c9094886c73301a8847995e9ef48d560e8;p=haproxy.git MINOR: connection/mux_quic: add MUX field for QMux handshake The first part of this patch defines a new mux_proto_list field named . 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 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. --- diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 41f02425f..1cff9f3ee 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -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; }; diff --git a/src/backend.c b/src/backend.c index db914fd61..f460b261c 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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) diff --git a/src/mux_quic.c b/src/mux_quic.c index 5e18178a9..94f7b5c5b 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -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); diff --git a/src/session.c b/src/session.c index 2815c215f..a9c8c6d85 100644 --- a/src/session.c +++ b/src/session.c @@ -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 */