diff --git a/src/mux_quic.c b/src/mux_quic.c index dcf21a726..a8a552cb6 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -3643,8 +3643,10 @@ static void qcc_release(struct qcc *qcc) } /* register streams IDs so that quic-conn layer can ignore already closed streams. */ - qc->rx.stream_max_uni = qcc->largest_uni_r; - qc->rx.stream_max_bidi = qcc->largest_bidi_r; + if (!conn_is_back(conn)) { + qc->rx.stream_max_uni = qcc->largest_uni_r; + qc->rx.stream_max_bidi = qcc->largest_bidi_r; + } } tasklet_free(qcc->wait_event.tasklet); @@ -3667,7 +3669,7 @@ static void qcc_release(struct qcc *qcc) if (qcc->app_ops) { if (qcc->app_ops->release) qcc->app_ops->release(qcc->ctx); - if (conn && conn_is_quic(conn) && conn->handle.qc) + if (conn && !conn_is_back(conn) && conn_is_quic(conn) && conn->handle.qc) conn->handle.qc->strm_reject = qcc->app_ops->strm_reject; } TRACE_PROTO("application layer released", QMUX_EV_QCC_END, conn); diff --git a/src/quic_rx.c b/src/quic_rx.c index 06b3f3e99..932058f0c 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -975,11 +975,21 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, { struct qf_stream *strm_frm = &frm->stream; const char fin = frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT; - const uint64_t max = quic_stream_is_uni(strm_frm->id) ? - qc->rx.stream_max_uni : qc->rx.stream_max_bidi; + uint64_t max; /* The upper layer may not be allocated. */ if (!qc_is_conn_ready(qc)) { + if (qc_is_back(qc)) { + /* Drain STREAM frames on the backend side. MUX should + * have emitted STOP_SENDING on shut for incomplete streams, + * so the peer should soon stop emission. + */ + TRACE_DATA("Ignore stream on backend", QUIC_EV_CONN_PRSHPKT, qc); + break; + } + + max = quic_stream_is_uni(strm_frm->id) ? + qc->rx.stream_max_uni : qc->rx.stream_max_bidi; if (strm_frm->id < max) { TRACE_DATA("Already closed stream", QUIC_EV_CONN_PRSHPKT, qc); }