From: Christopher Faulet Date: Wed, 23 Sep 2026 18:34:31 +0000 (+0200) Subject: BUG/MEDIUM: h3: Set FIN when last DATA block is sent via zero-copy X-Git-Tag: v3.5-dev8~118 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=65591cd879fffc313aa35cb124ad4d3eee7281d6;p=haproxy.git BUG/MEDIUM: h3: Set FIN when last DATA block is sent via zero-copy 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. --- diff --git a/src/h3.c b/src/h3.c index 6ba1ae9fb..2768c779a 100644 --- 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; }