From: Amaury Denoyelle Date: Thu, 23 Apr 2026 12:41:34 +0000 (+0200) Subject: MINOR: mux_quic: use dynamic conn buffers for QMux X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=b8e65423f3c9521158821cd13b269842a39ba0aa;p=thirdparty%2Fhaproxy.git MINOR: mux_quic: use dynamic conn buffers for QMux Allocate and release as needed the QCC buffers used for QMux protocol. This should reduce the memory consumption of QMux. This is performed both for send and receive buffers. Along with this, always free these buffers in qcc_release() to prevent a memory leak. --- 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; }