MEDIUM: hpack: use a pool for the hpack table
Instead of using malloc/free to allocate an HPACK table, let's declare
a pool. However the HPACK size is configured by the H2 mux, so it's
also this one which allocates it after post_check.
diff --git a/include/common/hpack-tbl.h b/include/common/hpack-tbl.h
index bb1ac06..44c0cc1 100644
--- a/include/common/hpack-tbl.h
+++ b/include/common/hpack-tbl.h
@@ -32,6 +32,7 @@
#include <common/config.h>
#include <common/http-hdr.h>
#include <common/ist.h>
+#include <common/memory.h>
/* Dynamic Headers Table, usable for tables up to 4GB long and values of 64kB-1.
* The model can be improved by using offsets relative to the table entry's end
@@ -133,6 +134,7 @@
/* static header table as in RFC7541 Appendix A. [0] unused. */
#define HPACK_SHT_SIZE 62
extern const struct http_hdr hpack_sht[HPACK_SHT_SIZE];
+extern struct pool_head *pool_head_hpack_tbl;
extern int __hpack_dht_make_room(struct hpack_dht *dht, unsigned int needed);
extern int hpack_dht_insert(struct hpack_dht *dht, struct ist name, struct ist value);
@@ -233,23 +235,24 @@
dht->used = 0;
}
-/* allocate a dynamic headers table of <size> bytes and return it initialized */
-static inline struct hpack_dht *hpack_dht_alloc(uint32_t size)
+/* allocate a dynamic headers table from the pool and return it initialized */
+static inline struct hpack_dht *hpack_dht_alloc()
{
struct hpack_dht *dht;
- dht = malloc(size);
- if (!dht)
- return dht;
+ if (unlikely(!pool_head_hpack_tbl))
+ return NULL;
- hpack_dht_init(dht, size);
+ dht = pool_alloc(pool_head_hpack_tbl);
+ if (dht)
+ hpack_dht_init(dht, pool_head_hpack_tbl->size);
return dht;
}
/* free a dynamic headers table */
static inline void hpack_dht_free(struct hpack_dht *dht)
{
- free(dht);
+ pool_free(pool_head_hpack_tbl, dht);
}
#endif /* _COMMON_HPACK_TBL_H */
diff --git a/src/hpack-tbl.c b/src/hpack-tbl.c
index 727ff7a..effe5e0 100644
--- a/src/hpack-tbl.c
+++ b/src/hpack-tbl.c
@@ -101,6 +101,8 @@
[61] = { .n = IST("www-authenticate"), .v = IST("") },
};
+struct pool_head *pool_head_hpack_tbl = NULL;
+
/* returns the slot number of the oldest entry (tail). Must not be used on an
* empty table.
*/
@@ -173,7 +175,7 @@
/* Note: for small tables we could use alloca() instead but
* portability especially for large tables can be problematic.
*/
- alt_dht = hpack_dht_alloc(dht->size);
+ alt_dht = hpack_dht_alloc();
if (!alt_dht)
return NULL;
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 6b1c0d1..2972925 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -823,7 +823,7 @@
h2c->wait_event.tasklet->context = h2c;
h2c->wait_event.events = 0;
- h2c->ddht = hpack_dht_alloc(h2_settings_header_table_size);
+ h2c->ddht = hpack_dht_alloc();
if (!h2c->ddht)
goto fail;
@@ -6195,3 +6195,18 @@
}};
INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
+
+/* initialize internal structs after the config is parsed.
+ * Returns zero on success, non-zero on error.
+ */
+static int init_h2()
+{
+ pool_head_hpack_tbl = create_pool("hpack_tbl",
+ h2_settings_header_table_size,
+ MEM_F_SHARED|MEM_F_EXACT);
+ if (!pool_head_hpack_tbl)
+ return -1;
+ return 0;
+}
+
+REGISTER_POST_CHECK(init_h2);