diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 7cf9afdb3..09e0585f6 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -77,6 +77,8 @@ /* other flags */ #define QC_CF_IS_BACK 0x00008000 // this is an outgoing connection +#define QC_CF_CC_RECV 0x00010000 // CONNECTION_CLOSE received + extern struct pool_head *pool_head_qcs; /* Stream types */ diff --git a/src/mux_quic.c b/src/mux_quic.c index 4794a5066..d60df2b6c 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -1498,14 +1498,18 @@ static void qc_detach(struct conn_stream *cs) struct qcc *qcc = qcs->qcc; TRACE_ENTER(QC_EV_STRM_END, qcs ? qcs->qcc->conn : NULL, qcs); - if (b_data(&qcs->tx.buf) || b_data(&qcs->tx.xprt_buf)) { + if (b_data(&qcs->tx.buf) || + (b_data(&qcs->tx.xprt_buf) && !(qcc->flags & QC_CF_CC_RECV))) { qcs->flags |= QC_SF_DETACH; goto out; } qcs_destroy(qcs); - if (qcc_is_dead(qcc)) + if (qcc_is_dead(qcc)) { qc_release(qcc); + TRACE_LEAVE(QC_EV_STRM_END, NULL); + return; + } out: TRACE_LEAVE(QC_EV_STRM_END, qcs ? qcs->qcc->conn : NULL); diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 70bcea8d9..eed8b2fe6 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -2040,6 +2040,7 @@ static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ct break; case QUIC_FT_CONNECTION_CLOSE: case QUIC_FT_CONNECTION_CLOSE_APP: + conn->qcc->flags |= QC_CF_CC_RECV; break; case QUIC_FT_HANDSHAKE_DONE: if (objt_listener(ctx->conn->target))