]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-quic: define Rx connection buffer for QMux
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 27 Mar 2026 09:14:39 +0000 (10:14 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 2 Apr 2026 12:02:04 +0000 (14:02 +0200)
When QMux is used, mux-quic must actively performed reception of new
content. This has been implemented by the previous patch.

The current patch extends this by defining a buffer on QCC dedicated to
this operation. This replaces the usage of the trash buffer. This is
necessary to deal with incomplete reads.

include/haproxy/mux_quic-t.h
src/mux_quic.c
src/mux_quic_qstrm.c

index 94d4b007ff894ee0b8f65fbed4a266be41698de2..8275e00160652529d1ec36bdd1073b385a0bc196 100644 (file)
@@ -84,6 +84,9 @@ struct qcc {
                struct quic_pacer pacer; /* engine used to pace emission */
                int paced_sent_ctr; /* counter for when emission is interrupted due to pacing */
        } tx;
+       struct {
+               struct buffer qstrm_buf;
+       } rx;
 
        uint64_t largest_bidi_r; /* largest remote bidi stream ID opened. */
        uint64_t largest_uni_r;  /* largest remote uni stream ID opened. */
index f696941ff6e940e302b0cdcc7e190ea6c2b25564..1335dfe58a511f3572461e0c0c7b8e68a7c81467 100644 (file)
@@ -3745,6 +3745,15 @@ static int qmux_init(struct connection *conn, struct proxy *prx,
                qcc->pacing_task->state |= TASK_F_WANTS_TIME;
        }
 
+       if (!conn_is_quic(conn)) {
+               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;
+               }
+       }
+
        if (conn_is_back(conn)) {
                qcc->next_bidi_l    = 0x00;
                qcc->largest_bidi_r = 0x01;
index 2c885b4530c0e19d7ab0f5f8ccd220801ed6c5a9..67632b1f316a77255fbe88d7bbbb4f86327e9ddd 100644 (file)
@@ -42,7 +42,8 @@ static int qstrm_parse_frm(struct qcc *qcc, struct buffer *buf)
        old = pos = (unsigned char *)b_head(buf);
        end = (unsigned char *)b_head(buf) + b_data(buf);
        ret = qc_parse_frm_type(&frm, &pos, end, NULL);
-       BUG_ON(!ret);
+       if (!ret)
+               return 0;
 
        if (!qstrm_is_frm_valid(&frm)) {
                /* TODO close connection with FRAME_ENCODING_ERROR */
@@ -51,7 +52,8 @@ static int qstrm_parse_frm(struct qcc *qcc, struct buffer *buf)
        }
 
        ret = qc_parse_frm_payload(&frm, &pos, end, NULL);
-       BUG_ON(!ret);
+       if (!ret)
+               return 0;
 
        if (frm.type >= QUIC_FT_STREAM_8 &&
            frm.type <= QUIC_FT_STREAM_F) {
@@ -86,24 +88,26 @@ static int qstrm_parse_frm(struct qcc *qcc, struct buffer *buf)
  */
 int qcc_qstrm_recv(struct qcc *qcc)
 {
-       /* TODO add a buffer on the connection for incomplete data read */
        struct connection *conn = qcc->conn;
+       struct buffer *buf = &qcc->rx.qstrm_buf;
        int total = 0, frm_ret;
        size_t ret;
 
        TRACE_ENTER(QMUX_EV_QCC_RECV, qcc->conn);
 
        do {
-               b_reset(&trash);
-               ret = conn->xprt->rcv_buf(conn, conn->xprt_ctx, &trash, trash.size, NULL, 0, 0);
+               b_realign_if_empty(buf);
+               ret = conn->xprt->rcv_buf(conn, conn->xprt_ctx, buf, b_contig_space(buf), NULL, 0, 0);
                BUG_ON(conn->flags & CO_FL_ERROR);
 
                total += ret;
-               while (b_data(&trash)) {
-                       frm_ret = qstrm_parse_frm(qcc, &trash);
-                       BUG_ON(!frm_ret);
+               while (b_data(buf)) {
+                       frm_ret = qstrm_parse_frm(qcc, buf);
+                       BUG_ON(frm_ret < 0); /* TODO handle fatal errors */
+                       if (!frm_ret)
+                               break;
 
-                       b_del(&trash, frm_ret);
+                       b_del(buf, frm_ret);
                }
        } while (ret > 0);