]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: quic: detect the stream FIN
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 3 Dec 2021 14:03:36 +0000 (15:03 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 7 Dec 2021 14:44:45 +0000 (15:44 +0100)
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.

include/haproxy/mux_quic-t.h
src/h3.c
src/hq_interop.c
src/mux_quic.c

index 2e869c62c507c8de2d5c6256cd718d798ada2b60..3bded6753388cf54751cf66062017d25f864a87a 100644 (file)
@@ -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;
index af206565ebf770f941302b19e1e37a98d07efa77..ecaa02d499e3e158cc2d569a601d5b777621915b 100644 (file)
--- 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))
index af59410b7be9875d58bd6ef09f93dbecd6cdead1..3d530f4bfb56a940d87dda4f996717bd7e45e868 100644 (file)
@@ -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) {
index bdf57e5690aecdc3afcd49a41577d0c097478320..df586863730d86e46cfec76256871806c6ce984e 100644 (file)
@@ -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();