diff --git a/src/h3.c b/src/h3.c index 48bf6d8de..06d954ebc 100644 --- a/src/h3.c +++ b/src/h3.c @@ -938,8 +938,8 @@ static ssize_t h3_headers_to_htx(struct qcs *qcs, const struct buffer *buf, if (htx) htx_to_buf(htx, &htx_buf); - /* buffer is transferred to the stream connector and set to NULL - * except on stream creation error. + /* Buffer is transferred to the stream connector and set to NULL except + * on stream creation error or QCS already fully closed. */ if (b_size(&htx_buf)) { b_free(&htx_buf); diff --git a/src/mux_quic.c b/src/mux_quic.c index 5ff006090..6e5cad01a 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -899,7 +899,12 @@ void qcs_send_metadata(struct qcs *qcs) * the first received request data. must be set if the whole request is * already received. * - * Returns 0 on success else a negative error code. + * Note that if is already fully closed, no streamdesc is instantiated. + * This is useful if a RESET_STREAM was already emitted in response to a + * STOP_SENDING. + * + * Returns 0 on success else a negative error code. If stream is already fully + * closed and nothing is performed, it is considered as a success case. */ int qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin) { @@ -908,6 +913,11 @@ int qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin) TRACE_ENTER(QMUX_EV_STRM_RECV, qcc->conn, qcs); + if (qcs->st == QC_SS_CLO) { + TRACE_STATE("skip attach on already closed stream", QMUX_EV_STRM_RECV, qcc->conn, qcs); + goto out; + } + /* TODO duplicated from mux_h2 */ sess->t_idle = ns_to_ms(now_ns - sess->accept_ts) - sess->t_handshake; @@ -958,6 +968,7 @@ int qcs_attach_sc(struct qcs *qcs, struct buffer *buf, char fin) se_fl_set_error(qcs->sd); } + out: TRACE_LEAVE(QMUX_EV_STRM_RECV, qcc->conn, qcs); return 0; } @@ -1152,7 +1163,7 @@ static int qcc_decode_qcs(struct qcc *qcc, struct qcs *qcs) if (qcs_is_close_remote(qcs)) fin = 1; - if (!(qcs->flags & QC_SF_READ_ABORTED) && !qcs_is_completed(qcs)) { + if (!(qcs->flags & QC_SF_READ_ABORTED)) { ret = qcc->app_ops->rcv_buf(qcs, &b, fin); if (qcc->glitches != prev_glitches)