]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: quic: use a dedicated module for qc_stream_desc
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 19 Apr 2022 15:21:11 +0000 (17:21 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 21 Apr 2022 09:05:27 +0000 (11:05 +0200)
Regroup all type definitions and functions related to qc_stream_desc in
the source file src/quic_stream.c.

qc_stream_desc complexity will be increased with the development of Tx
multi-buffers. Having a dedicated module is useful to mix it with
pure transport/quic-conn code.

Makefile
include/haproxy/mux_quic-t.h
include/haproxy/quic_stream-t.h [new file with mode: 0644]
include/haproxy/quic_stream.h [new file with mode: 0644]
include/haproxy/xprt_quic-t.h
include/haproxy/xprt_quic.h
src/mux_quic.c
src/quic_stream.c [new file with mode: 0644]
src/xprt_quic.c

index fd1caa28758c378a54861c3432b7cfef6204f8ea..7c7d26ad04c131ec4bc66343c9f2751859ab7580 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -636,7 +636,8 @@ ifneq ($(USE_QUIC),)
 OPTIONS_OBJS += src/quic_sock.o src/proto_quic.o src/xprt_quic.o src/quic_tls.o \
                 src/quic_frame.o src/quic_cc.o src/quic_cc_newreno.o src/mux_quic.o \
                 src/cbuf.o src/qpack-dec.o src/qpack-tbl.o src/h3.o src/qpack-enc.o \
-                src/hq_interop.o src/cfgparse-quic.o src/quic_loss.o
+                src/hq_interop.o src/cfgparse-quic.o src/quic_loss.o \
+                src/quic_stream.o
 endif
 
 ifneq ($(USE_LUA),)
index 6fa952244ded1dde41065d23a9a2f2dbc516e14e..f9b8b2fd98f68aa7526e9e3f2950f638a3091089 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <haproxy/buf-t.h>
 #include <haproxy/connection-t.h>
+#include <haproxy/quic_stream-t.h>
 #include <haproxy/xprt_quic-t.h>
 #include <haproxy/conn_stream-t.h>
 
diff --git a/include/haproxy/quic_stream-t.h b/include/haproxy/quic_stream-t.h
new file mode 100644 (file)
index 0000000..6a451ac
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _HAPROXY_QUIC_STREAM_T_H_
+#define _HAPROXY_QUIC_STREAM_T_H_
+
+#ifdef USE_QUIC
+
+#include <import/ebtree-t.h>
+
+#include <haproxy/buf-t.h>
+
+/* QUIC STREAM descriptor.
+ *
+ * This structure is the low-level counterpart of the QUIC STREAM at the MUX
+ * layer. It provides a node for tree-storage and buffering for Tx.
+ *
+ * Once the MUX has finished to transfer data on a STREAM, it must release its
+ * QUIC STREAM descriptor. The descriptor will be kept by the quic_conn until
+ * all acknowledgement has been received.
+ */
+struct qc_stream_desc {
+       struct eb64_node by_id; /* id of the stream used for <streams_by_id> tree */
+
+       struct buffer buf; /* buffer for STREAM data on Tx, emptied on acknowledge */
+       uint64_t ack_offset; /* last acknowledged offset */
+       struct eb_root acked_frms; /* ACK frames tree for non-contiguous ACK ranges */
+
+       int release; /* set to 1 when the MUX has finished to use this stream */
+
+       void *ctx; /* MUX specific context */
+};
+
+#endif /* USE_QUIC */
+#endif /* _HAPROXY_QUIC_STREAM_T_H_ */
diff --git a/include/haproxy/quic_stream.h b/include/haproxy/quic_stream.h
new file mode 100644 (file)
index 0000000..c524d10
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _HAPROXY_QUIC_STREAM_H_
+#define _HAPROXY_QUIC_STREAM_H_
+
+#ifdef USE_QUIC
+
+#include <haproxy/quic_stream-t.h>
+
+struct quic_conn;
+
+struct qc_stream_desc *qc_stream_desc_new(uint64_t id, void *ctx);
+void qc_stream_desc_release(struct qc_stream_desc *stream,
+                            struct quic_conn *qc);
+int qc_stream_desc_free(struct qc_stream_desc *stream);
+
+#endif /* USE_QUIC */
+#endif /* _HAPROXY_QUIC_STREAM_H_ */
index e2999a571e53a093bfbee766047b1f00e8719531..2478332391ae7b6127e506ece91b98ec4318214e 100644 (file)
@@ -767,26 +767,5 @@ struct quic_conn {
        const struct qcc_app_ops *app_ops;
 };
 
-/* QUIC STREAM descriptor.
- *
- * This structure is the low-level counterpart of the QUIC STREAM at the MUX
- * layer. It provides a node for tree-storage and buffering for Tx.
- *
- * Once the MUX has finished to transfer data on a STREAM, it must release its
- * QUIC STREAM descriptor. The descriptor will be kept by the quic_conn until
- * all acknowledgement has been received.
- */
-struct qc_stream_desc {
-       struct eb64_node by_id; /* id of the stream used for <streams_by_id> tree */
-
-       struct buffer buf; /* buffer for STREAM data on Tx, emptied on acknowledge */
-       uint64_t ack_offset; /* last acknowledged offset */
-       struct eb_root acked_frms; /* ACK frames tree for non-contiguous ACK ranges */
-
-       int release; /* set to 1 when the MUX has finished to use this stream */
-
-       void *ctx; /* MUX specific context */
-};
-
 #endif /* USE_QUIC */
 #endif /* _HAPROXY_XPRT_QUIC_T_H */
index 94488b04a74042c917b09da5835fc7f5d56ec478..1a2a3ce4bca6df8688183285a88834d00a13f57d 100644 (file)
@@ -1248,9 +1248,6 @@ int quic_lstnr_dgram_dispatch(unsigned char *buf, size_t len, void *owner,
                               struct quic_dgram *new_dgram, struct list *dgrams);
 int qc_send_app_pkts(struct quic_conn *qc, struct list *frms);
 
-struct qc_stream_desc *qc_stream_desc_new(uint64_t id, void *ctx);
-void qc_stream_desc_release(struct qc_stream_desc *stream, struct quic_conn *qc);
-
 void qc_notify_close(struct quic_conn *qc);
 
 #endif /* USE_QUIC */
index d51bed180ad6a2459213271217bf829994cb1553..642da7206ab2776ed75a868f72cce878e5d36c2a 100644 (file)
@@ -8,6 +8,7 @@
 #include <haproxy/dynbuf.h>
 #include <haproxy/htx.h>
 #include <haproxy/pool.h>
+#include <haproxy/quic_stream.h>
 #include <haproxy/sink.h>
 #include <haproxy/ssl_sock-t.h>
 #include <haproxy/trace.h>
diff --git a/src/quic_stream.c b/src/quic_stream.c
new file mode 100644 (file)
index 0000000..4213e50
--- /dev/null
@@ -0,0 +1,99 @@
+#include <haproxy/quic_stream.h>
+
+#include <import/eb64tree.h>
+
+#include <haproxy/api.h>
+#include <haproxy/buf.h>
+#include <haproxy/list.h>
+#include <haproxy/dynbuf.h>
+#include <haproxy/pool.h>
+#include <haproxy/xprt_quic.h>
+
+DECLARE_STATIC_POOL(pool_head_quic_conn_stream, "qc_stream_desc",
+                    sizeof(struct qc_stream_desc));
+
+/* Allocate a new stream descriptor with id <id>. The caller is responsible to
+ * store the stream in the appropriate tree.
+ *
+ * Returns the newly allocated instance on success or else NULL.
+ */
+struct qc_stream_desc *qc_stream_desc_new(uint64_t id, void *ctx)
+{
+       struct qc_stream_desc *stream;
+
+       stream = pool_alloc(pool_head_quic_conn_stream);
+       if (!stream)
+               return NULL;
+
+       stream->by_id.key = id;
+       stream->by_id.node.leaf_p = NULL;
+
+       stream->buf = BUF_NULL;
+       stream->acked_frms = EB_ROOT;
+       stream->ack_offset = 0;
+       stream->release = 0;
+       stream->ctx = ctx;
+
+       return stream;
+}
+
+/* Mark the stream descriptor <stream> as released by the upper layer. It will
+ * be freed as soon as all its buffered data are acknowledged. In the meantime,
+ * the stream is stored in the <qc> tree : thus it must have been removed from
+ * any other tree before calling this function.
+ */
+void qc_stream_desc_release(struct qc_stream_desc *stream,
+                            struct quic_conn *qc)
+{
+       BUG_ON(stream->by_id.node.leaf_p);
+
+       stream->release = 1;
+       stream->ctx = NULL;
+
+       if (!b_data(&stream->buf))
+               qc_stream_desc_free(stream);
+       else
+               eb64_insert(&qc->streams_by_id, &stream->by_id);
+}
+
+/* Free the stream descriptor <stream> buffer. This function should be used
+ * when all its data have been acknowledged. If the stream was released by the
+ * upper layer, the stream descriptor will be freed.
+ *
+ * Returns 0 if the stream was not freed else non-zero.
+ */
+int qc_stream_desc_free(struct qc_stream_desc *stream)
+{
+       b_free(&stream->buf);
+       offer_buffers(NULL, 1);
+
+       if (stream->release) {
+               /* Free frames still waiting for an ACK. Even if the stream buf
+                * is NULL, some frames could still be not acknowledged. This
+                * is notably the case for retransmission where multiple frames
+                * points to the same buffer content.
+                */
+               struct eb64_node *frm_node = eb64_first(&stream->acked_frms);
+               while (frm_node) {
+                       struct quic_stream *strm;
+                       struct quic_frame *frm;
+
+                       strm = eb64_entry(&frm_node->node, struct quic_stream, offset);
+
+                       frm_node = eb64_next(frm_node);
+                       eb64_delete(&strm->offset);
+
+                       frm = container_of(strm, struct quic_frame, stream);
+                       LIST_DELETE(&frm->list);
+                       quic_tx_packet_refdec(frm->pkt);
+                       pool_free(pool_head_quic_frame, frm);
+               }
+
+               eb64_delete(&stream->by_id);
+               pool_free(pool_head_quic_conn_stream, stream);
+
+               return 1;
+       }
+
+       return 0;
+}
index 36b21e20435b77aad4f8e679a7b141fff1811ef5..fde571d60e5787c6d509baf6134e9e60f762e347 100644 (file)
@@ -45,6 +45,7 @@
 #include <haproxy/quic_frame.h>
 #include <haproxy/quic_loss.h>
 #include <haproxy/quic_sock.h>
+#include <haproxy/quic_stream.h>
 #include <haproxy/cbuf.h>
 #include <haproxy/proto_quic.h>
 #include <haproxy/quic_tls.h>
@@ -169,7 +170,6 @@ DECLARE_POOL(pool_head_quic_rx_strm_frm, "quic_rx_strm_frm", sizeof(struct quic_
 DECLARE_STATIC_POOL(pool_head_quic_crypto_buf, "quic_crypto_buf_pool", sizeof(struct quic_crypto_buf));
 DECLARE_POOL(pool_head_quic_frame, "quic_frame_pool", sizeof(struct quic_frame));
 DECLARE_STATIC_POOL(pool_head_quic_arng, "quic_arng_pool", sizeof(struct quic_arng_node));
-DECLARE_STATIC_POOL(pool_head_quic_conn_stream, "qc_stream_desc", sizeof(struct qc_stream_desc));
 
 static struct quic_tx_packet *qc_build_pkt(unsigned char **pos, const unsigned char *buf_end,
                                            struct quic_enc_level *qel, struct list *frms,
@@ -1429,48 +1429,6 @@ static int qc_pkt_decrypt(struct quic_rx_packet *pkt, struct quic_enc_level *qel
        return 1;
 }
 
-/* Free the stream descriptor <stream> buffer. This function should be used
- * when all its data have been acknowledged. If the stream was released by the
- * upper layer, the stream descriptor will be freed.
- *
- * Returns 0 if the stream was not freed else non-zero.
- */
-static int qc_stream_desc_free(struct qc_stream_desc *stream)
-{
-       b_free(&stream->buf);
-       offer_buffers(NULL, 1);
-
-       if (stream->release) {
-               /* Free frames still waiting for an ACK. Even if the stream buf
-                * is NULL, some frames could still be not acknowledged. This
-                * is notably the case for retransmission where multiple frames
-                * points to the same buffer content.
-                */
-               struct eb64_node *frm_node = eb64_first(&stream->acked_frms);
-               while (frm_node) {
-                       struct quic_stream *strm;
-                       struct quic_frame *frm;
-
-                       strm = eb64_entry(&frm_node->node, struct quic_stream, offset);
-
-                       frm_node = eb64_next(frm_node);
-                       eb64_delete(&strm->offset);
-
-                       frm = container_of(strm, struct quic_frame, stream);
-                       LIST_DELETE(&frm->list);
-                       quic_tx_packet_refdec(frm->pkt);
-                       pool_free(pool_head_quic_frame, frm);
-               }
-
-               eb64_delete(&stream->by_id);
-               pool_free(pool_head_quic_conn_stream, stream);
-
-               return 1;
-       }
-
-       return 0;
-}
-
 /* Remove from <stream> the acknowledged frames.
  *
  * Returns 1 if at least one frame was removed else 0.
@@ -5956,50 +5914,6 @@ int quic_lstnr_dgram_dispatch(unsigned char *buf, size_t len, void *owner,
        return 0;
 }
 
-/* Allocate a new stream descriptor with id <id>. The caller is responsible to
- * store the stream in the appropriate tree.
- *
- * Returns the newly allocated instance on success or else NULL.
- */
-struct qc_stream_desc *qc_stream_desc_new(uint64_t id, void *ctx)
-{
-       struct qc_stream_desc *stream;
-
-       stream = pool_alloc(pool_head_quic_conn_stream);
-       if (!stream)
-               return NULL;
-
-       stream->by_id.key = id;
-       stream->by_id.node.leaf_p = NULL;
-
-       stream->buf = BUF_NULL;
-       stream->acked_frms = EB_ROOT;
-       stream->ack_offset = 0;
-       stream->release = 0;
-       stream->ctx = ctx;
-
-       return stream;
-}
-
-/* Mark the stream descriptor <stream> as released by the upper layer. It will
- * be freed as soon as all its buffered data are acknowledged. In the meantime,
- * the stream is stored in the <qc> tree : thus it must have been removed from
- * any other tree before calling this function.
- */
-void qc_stream_desc_release(struct qc_stream_desc *stream,
-                            struct quic_conn *qc)
-{
-       BUG_ON(stream->by_id.node.leaf_p);
-
-       stream->release = 1;
-       stream->ctx = NULL;
-
-       if (!b_data(&stream->buf))
-               qc_stream_desc_free(stream);
-       else
-               eb64_insert(&qc->streams_by_id, &stream->by_id);
-}
-
 /* Notify the MUX layer if alive about an imminent close of <qc>. */
 void qc_notify_close(struct quic_conn *qc)
 {