From 086e51017e7731ee9820b882fe6e8cc5f0dd5352 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Thu, 23 May 2024 10:45:28 +0200 Subject: [PATCH] BUG/MEDIUM: mux-quic: Create sedesc in same time of the QUIC stream 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 | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/mux_quic.c b/src/mux_quic.c index dcbe072b6..a0d586fe5 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -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;