diff --git a/src/mux_quic.c b/src/mux_quic.c index e82569f07..d2a1e6e3a 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -3525,6 +3525,12 @@ static void qcc_release(struct qcc *qcc) } TRACE_PROTO("application layer released", QMUX_EV_QCC_END, conn); + if (conn && !conn_is_quic(conn)) { + b_free(&qcc->rx.qstrm_buf); + b_free(&qcc->tx.qstrm_buf); + offer_buffers(NULL, 2); + } + pool_free(pool_head_qcc, qcc); if (conn) { @@ -3844,22 +3850,16 @@ static int qmux_init(struct connection *conn, struct proxy *prx, struct buffer *xprt_buf; qcc->tx.qstrm_buf = BUF_NULL; - b_alloc(&qcc->tx.qstrm_buf, DB_MUX_TX); - if (!b_size(&qcc->tx.qstrm_buf)) { - TRACE_ERROR("tx qstrm buf alloc failure", QMUX_EV_QCC_NEW); - goto err; - } - qcc->rx.qstrm_buf = BUF_NULL; - b_alloc(&qcc->rx.qstrm_buf, DB_MUX_RX); - if (!b_size(&qcc->rx.qstrm_buf)) { - TRACE_ERROR("rx qstrm buf alloc failure", QMUX_EV_QCC_NEW); - goto err; - } /* Retrieve data if xprt read too much */ xprt_buf = xprt_qstrm_rxbuf(conn->xprt_ctx); if (unlikely(b_data(xprt_buf))) { + b_alloc(&qcc->rx.qstrm_buf, DB_MUX_RX); + if (!b_size(&qcc->rx.qstrm_buf)) { + TRACE_ERROR("rx qstrm buf alloc failure", QMUX_EV_QCC_NEW); + goto err; + } b_xfer(&qcc->rx.qstrm_buf, xprt_buf, b_data(xprt_buf)); qcc->rx.rlen = xprt_qstrm_rxrlen(conn->xprt_ctx); } diff --git a/src/mux_quic_qstrm.c b/src/mux_quic_qstrm.c index cf56c23fa..339a2f15f 100644 --- a/src/mux_quic_qstrm.c +++ b/src/mux_quic_qstrm.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,13 @@ int qcc_qstrm_recv(struct qcc *qcc) TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn); + if (!b_size(buf)) { + if (!b_alloc(buf, DB_MUX_RX)) { + TRACE_ERROR("rx qstrm buf alloc failure", QMUX_EV_QCC_RECV); + goto err; + } + } + do { recv: /* Wrapping is not supported for QMux reception. */ @@ -165,6 +173,11 @@ int qcc_qstrm_recv(struct qcc *qcc) &qcc->wait_event); } + if (!b_data(buf)) { + b_free(buf); + offer_buffers(NULL, 1); + } + TRACE_LEAVE(QMUX_EV_QCC_RECV, qcc->conn); return total; @@ -252,6 +265,11 @@ int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms) TRACE_ENTER(QMUX_EV_QCC_SEND, qcc->conn); + if (!b_alloc(buf, DB_MUX_TX)) { + TRACE_ERROR("tx qstrm buf alloc failure", QMUX_EV_QCC_SEND); + goto out; + } + /* Record size field length */ lensz = quic_int_getsize(quic_int_cap_length(b_size(buf))); @@ -319,6 +337,7 @@ int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms) /* TODO */ BUG_ON(sent != b_data(buf)); + b_del(buf, sent); if (frm->type >= QUIC_FT_STREAM_8 && frm->type <= QUIC_FT_STREAM_F) qstrm_ctrl_send(frm->stream.stream, frm->stream.len); @@ -343,6 +362,11 @@ int qcc_qstrm_send_frames(struct qcc *qcc, struct list *frms) ret = 0; } + if (!b_data(buf)) { + b_free(buf); + offer_buffers(NULL, 1); + } + TRACE_LEAVE(QMUX_EV_QCC_SEND, qcc->conn); return ret; }