]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: abort conn if cannot create stream due to fctl
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 18 Jun 2025 14:24:41 +0000 (16:24 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 18 Jun 2025 15:25:27 +0000 (17:25 +0200)
Prior to initiate first stream on the backend side, ensure that peer
flow-control allows at least that a single bidirectional stream can be
created. If this is not the case, abort MUX init operation.

Before this patch, flow-control limit was not checked. Hence, if peer
does not allow any bidirectional stream, haproxy would violate it, which
whould then cause the peer to close the connection.

Note that with the current situation, haproxy won't be able to talk to
servers which uses a 0 for initial max bidi streams. A proper solution
could be to pause the request until a MAX_STREAMS is received, under
timeout supervision to ensure the connection is closed if no frame is
received.

src/mux_quic.c

index a1de84000ca2276608c0ed80b707d57ccbe73b3e..3a19fddfdf20b7847b1c78892f9728a583741d23 100644 (file)
@@ -815,6 +815,8 @@ struct qcs *qcc_init_stream_local(struct qcc *qcc, int bidi)
        TRACE_ENTER(QMUX_EV_QCS_NEW, qcc->conn);
 
        if (bidi) {
+               /* Caller must ensure that max-streams peer flow-control won't be violated. */
+               BUG_ON(qcc->rfctl.ms_bidi * 4 < qcc->next_bidi_l);
                next = &qcc->next_bidi_l;
                type = conn_is_back(qcc->conn) ? QCS_CLT_BIDI : QCS_SRV_BIDI;
        }
@@ -3629,6 +3631,13 @@ static int qmux_init(struct connection *conn, struct proxy *prx,
                struct qcs *qcs;
                struct stconn *sc = conn_ctx;
 
+               /* TODO how to properly handle initial value of max-bidi-stream set to 0 ? */
+               if (!qcc_fctl_avail_streams(qcc, 1)) {
+                       TRACE_ERROR("peer does not allow any bidi stream, not yet supported",
+                                   QMUX_EV_QCC_NEW|QMUX_EV_QCC_ERR, qcc->conn);
+                       goto err;
+               }
+
                qcs = qcc_init_stream_local(qcc, 1);
                if (!qcs) {
                        TRACE_PROTO("Cannot allocate a new locally initiated streeam",