]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-quic: Create sedesc in same time of the QUIC stream
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 May 2024 08:45:28 +0000 (10:45 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 May 2024 09:18:06 +0000 (11:18 +0200)
Recent changes to save abort reason revealed an issue during the QUIC stream
creation. Indeed, by design, when a mux stream is created, it must always
have a valid stream-endpoint descriptor and it must remain valid till the
mux stream destruction. On frontend side, it is the multiplexer
responsibility to create it and set it as orphan. On the backend side, the
sedesc is provided by the upper layer. It is the sedesc of the back
stream-connector.

For the QUIC multiplexer, the stream-endpoint descriptor was only created
when the stream-connector was created and attached on it. It is unexpected
and some bugs may be introduced because there is no valid sedesc on a QUIC
stream. And a recent bug was introduced for this reason.

This patch must be backported as far as 2.6.

src/mux_quic.c

index dcbe072b6d6267f18ff3b05ba0851def5e8588b3..a0d586fe5ef578af5fe79ffc284e702b607988de 100644 (file)
@@ -100,11 +100,21 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type)
 
        qcs->stream = NULL;
        qcs->qcc = qcc;
-       qcs->sd = NULL;
        qcs->flags = QC_SF_NONE;
        qcs->st = QC_SS_IDLE;
        qcs->ctx = NULL;
 
+       qcs->sd = sedesc_new();
+       if (!qcs->sd)
+               goto err;
+       qcs->sd->se   = qcs;
+       qcs->sd->conn = qcc->conn;
+       se_fl_set(qcs->sd, SE_FL_T_MUX | SE_FL_ORPHAN | SE_FL_NOT_FIRST);
+       se_expect_no_data(qcs->sd);
+
+       if (!(global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_QUIC_SND))
+               se_fl_set(qcs->sd, SE_FL_MAY_FASTFWD_CONS);
+
        /* App callback attach may register the stream for http-request wait.
         * These fields must be initialed before.
         */
@@ -692,17 +702,6 @@ struct stconn *qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin)
        struct qcc *qcc = qcs->qcc;
        struct session *sess = qcc->conn->owner;
 
-       qcs->sd = sedesc_new();
-       if (!qcs->sd)
-               return NULL;
-
-       qcs->sd->se   = qcs;
-       qcs->sd->conn = qcc->conn;
-       se_fl_set(qcs->sd, SE_FL_T_MUX | SE_FL_ORPHAN | SE_FL_NOT_FIRST);
-       se_expect_no_data(qcs->sd);
-
-       if (!(global.tune.no_zero_copy_fwd & NO_ZERO_COPY_FWD_QUIC_SND))
-               se_fl_set(qcs->sd, SE_FL_MAY_FASTFWD_CONS);
 
        /* TODO duplicated from mux_h2 */
        sess->t_idle = ns_to_ms(now_ns - sess->accept_ts) - sess->t_handshake;