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.
!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);
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;
}