]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: h3: Set FIN when last DATA block is sent via zero-copy
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 23 Sep 2026 18:34:31 +0000 (20:34 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 24 Sep 2026 07:47:01 +0000 (09:47 +0200)
Since commit ab7bb500a ("MEDIUM: h3: Use flags of HTX blocks to detect end
of message during sending"), the end of the message is detected via the
HTX_BLK_FL_EOM flag of consumed HTX blocks. But the zero-copy path in
h3_resp_data_send() jumps to the end without testing this flag. So when the
last DATA block of a message is transferred via zero-copy, "fin" is never
set and no FIN is emitted on the QUIC stream, leaving the peer waiting
indefinitely for the end of the stream.

Fix this by capturing the block's EOM flag before the buffer area swap and
setting "fin" accordingly.

It is a 3.5-specific issue. No backport needed.

src/h3.c

index 6ba1ae9fbae1cd0fba076ebb854a69dce0a866d8..2768c779ab99dd2fd9dd2138104a1ee2103c3890 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -3057,6 +3057,7 @@ static int h3_resp_data_send(struct qcs *qcs, struct htx *htx,
                     !b_data(res) &&
                     htx_nbblks(htx) == 1 && type == HTX_BLK_DATA)) {
                void *old_area = res->area;
+               const int eom = blk->flags & HTX_BLK_FL_EOM;
 
                TRACE_DATA("perform zero-copy DATA transfer",
                           H3_EV_TX_FRAME|H3_EV_TX_DATA, qcs->qcc->conn, qcs);
@@ -3075,6 +3076,11 @@ static int h3_resp_data_send(struct qcs *qcs, struct htx *htx,
                buf->data = buf->head = 0;
                total += fsize;
 
+               if (eom) {
+                       TRACE_USER("transcoding last HTX message", H3_EV_STRM_SEND, qcs->qcc->conn, qcs);
+                       *fin = 1;
+               }
+
                goto end;
        }