From: Amaury Denoyelle Date: Fri, 3 Dec 2021 14:03:36 +0000 (+0100) Subject: MEDIUM: quic: detect the stream FIN X-Git-Tag: v2.6-dev1~317 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c2025c1ec62707c37310c9a39341f1d94aa2def3;p=thirdparty%2Fhaproxy.git MEDIUM: quic: detect the stream FIN Set the QC_SF_FIN_STREAM on the app layers (h3 / hq-interop) when reaching the HTX EOM. This is used to warn the mux layer to set the FIN on the QUIC stream. --- diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 2e869c62c5..3bded67533 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -54,6 +54,7 @@ struct qcc { }; #define QC_SF_NONE 0x00000000 +#define QC_SF_FIN_STREAM 0x00000001 // FIN bit must be set for last frame of the stream struct qcs { struct qcc *qcc; diff --git a/src/h3.c b/src/h3.c index af206565eb..ecaa02d499 100644 --- a/src/h3.c +++ b/src/h3.c @@ -620,6 +620,9 @@ size_t h3_snd_buf(struct conn_stream *cs, struct buffer *buf, size_t count, int } } + if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx)) + qcs->flags |= QC_SF_FIN_STREAM; + out: if (total) { if (!(qcs->qcc->wait_event.events & SUB_RETRY_SEND)) diff --git a/src/hq_interop.c b/src/hq_interop.c index af59410b7b..3d530f4bfb 100644 --- a/src/hq_interop.c +++ b/src/hq_interop.c @@ -116,6 +116,9 @@ static size_t hq_interop_snd_buf(struct conn_stream *cs, struct buffer *buf, } } + if ((htx->flags & HTX_FL_EOM) && htx_is_empty(htx)) + qcs->flags |= QC_SF_FIN_STREAM; + b_add(res, b_data(&outbuf)); if (total) { diff --git a/src/mux_quic.c b/src/mux_quic.c index bdf57e5690..df58686373 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -143,8 +143,17 @@ static int qc_send(struct qcc *qcc) struct qcs *qcs = container_of(node, struct qcs, by_id); struct buffer *buf = &qcs->tx.buf; if (b_data(buf)) { - /* TODO handle the FIN parameter */ - ret = qcs_push_frame(qcs, buf, 0, qcs->tx.offset); + char fin = 0; + + /* if FIN is activated, ensure the buffer to + * send is the last + */ + if (qcs->flags & QC_SF_FIN_STREAM) { + BUG_ON(b_data(&qcs->tx.buf) < b_data(buf)); + fin = (b_data(&qcs->tx.buf) - b_data(buf) == 0); + } + + ret = qcs_push_frame(qcs, buf, fin, qcs->tx.offset); if (ret < 0) ABORT_NOW();