From: Amaury Denoyelle Date: Mon, 21 Jul 2025 09:29:34 +0000 (+0200) Subject: BUG/MINOR: hq-interop: fix FIN transmission X-Git-Tag: v3.3-dev4~59 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b0fe45307992c657dc52c30eb4150638bab97ecb;p=thirdparty%2Fhaproxy.git BUG/MINOR: hq-interop: fix FIN transmission Since the following patch, app_ops layer is now responsible to report that HTX block was the last transmitted so that FIN STREAM can be set. This is mandatory to properly support HTTP 1xx interim responses. f349df44b4e21d8bf9b575a0aa869056a2ebaa58 MINOR: qmux: change API for snd_buf FIN transmission This change was correctly implemented in HTTP/3 code, however an issue appeared on hq-interop transcoder in case zero-copy DATA transfer is performed when HTX buffer is swapped. If this occured during the transfer of the last HTX block, EOM is not detected and thus STREAM FIN is never set. Most of the times, QMUX shut callback is called immediately after. This results in an emission of a RESET_STREAM to the client, which prevents the data transfer. To fix this, use the same method as HTTP/3 : HTX EOM flag status is checked before any transfer, thus preserving it even after a zero-copy. Criticity of this bug is low as hq-interop is experimental and is mostly used for interop testing. This should fix github issue #3038. This patch must be backported wherever the above one is. --- diff --git a/src/hq_interop.c b/src/hq_interop.c index 4dbd9adf4..3ded46266 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -171,10 +171,13 @@ static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf, uint32_t bsize, fsize; struct buffer *res = NULL; size_t total = 0; + char eom; int err; *fin = 0; htx = htx_from_buf(buf); + /* EOM is saved here, useful if 0-copy is performed with HTX buf. */ + eom = htx->flags & HTX_FL_EOM; while (count && !htx_is_empty(htx) && qcc_stream_can_send(qcs)) { /* Not implemented : QUIC on backend side */ @@ -267,7 +270,7 @@ static size_t hq_interop_snd_buf(struct qcs *qcs, struct buffer *buf, } end: - if (htx->flags & HTX_FL_EOM && htx_is_empty(htx)) + if (eom && htx_is_empty(htx)) *fin = 1; htx_to_buf(htx, buf);