MINOR: h2: create the h2c struct and allocate its pool
The h2c struct describes an H2 connection context and is assigned as the
mux's context. It has its own pool, allocated at boot time and released
after deinit().
diff --git a/src/mux_h2.c b/src/mux_h2.c
index ff870a1..7a2c588 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -12,10 +12,72 @@
#include <common/cfgparse.h>
#include <common/config.h>
+#include <common/h2.h>
+#include <common/hpack-tbl.h>
#include <proto/connection.h>
#include <proto/stream.h>
+#include <eb32tree.h>
+/* the h2c connection pool */
+static struct pool_head *pool2_h2c;
+
+/* Connection flags (32 bit), in h2c->flags */
+#define H2_CF_NONE 0x00000000
+
+/* H2 connection state, in h2c->st0 */
+enum h2_cs {
+ H2_CS_PREFACE, // init done, waiting for connection preface
+ H2_CS_SETTINGS1, // preface OK, waiting for first settings frame
+ H2_CS_FRAME_H, // first settings frame ok, waiting for frame header
+ H2_CS_FRAME_P, // frame header OK, waiting for frame payload
+ H2_CS_FRAME_A, // frame payload OK, trying to send ACK/RST frame
+ H2_CS_ERROR, // send GOAWAY(errcode) and close the connection ASAP
+ H2_CS_ERROR2, // GOAWAY(errcode) sent, close the connection ASAP
+ H2_CS_ENTRIES // must be last
+} __attribute__((packed));
+
+/* H2 connection descriptor */
+struct h2c {
+ struct connection *conn;
+
+ enum h2_cs st0; /* mux state */
+ enum h2_err errcode; /* H2 err code (H2_ERR_*) */
+
+ /* 16 bit hole here */
+ uint32_t flags; /* connection flags: H2_CF_* */
+ int32_t max_id; /* highest ID known on this connection, <0 before preface */
+ uint32_t rcvd_c; /* newly received data to ACK for the connection */
+ uint32_t rcvd_s; /* newly received data to ACK for the current stream (dsi) */
+
+ /* states for the demux direction */
+ struct hpack_dht *ddht; /* demux dynamic header table */
+ struct buffer *dbuf; /* demux buffer */
+
+ int32_t dsi; /* demux stream ID (<0 = idle) */
+ int32_t dfl; /* demux frame length (if dsi >= 0) */
+ int8_t dft; /* demux frame type (if dsi >= 0) */
+ int8_t dff; /* demux frame flags (if dsi >= 0) */
+ /* 16 bit hole here */
+ int32_t last_sid; /* last processed stream ID for GOAWAY, <0 before preface */
+
+ /* states for the mux direction */
+ struct buffer *mbuf; /* mux buffer */
+ int32_t msi; /* mux stream ID (<0 = idle) */
+ int32_t mfl; /* mux frame length (if dsi >= 0) */
+ int8_t mft; /* mux frame type (if dsi >= 0) */
+ int8_t mff; /* mux frame flags (if dsi >= 0) */
+ /* 16 bit hole here */
+ int32_t miw; /* mux initial window size for all new streams */
+ int32_t mws; /* mux window size. Can be negative. */
+ int32_t mfs; /* mux's max frame size */
+
+ struct eb_root streams_by_id; /* all active streams by their ID */
+ struct list send_list; /* list of blocked streams requesting to send */
+ struct list fctl_list; /* list of streams blocked by connection's fctl */
+};
+
+
/* a few settings from the global section */
static int h2_settings_header_table_size = 4096; /* initial value */
static int h2_settings_initial_window_size = 65535; /* initial value */
@@ -214,9 +276,16 @@
{ 0, NULL, NULL }
}};
+static void __h2_deinit(void)
+{
+ pool_destroy2(pool2_h2c);
+}
+
__attribute__((constructor))
static void __h2_init(void)
{
alpn_register_mux(&alpn_mux_h2);
cfg_register_keywords(&cfg_kws);
+ hap_register_post_deinit(__h2_deinit);
+ pool2_h2c = create_pool("h2c", sizeof(struct h2c), MEM_F_SHARED);
}