#include <haproxy/buf-t.h>
#include <haproxy/chunk.h>
#include <haproxy/quic_conn-t.h>
+#include <haproxy/quic_cid-t.h>
#include <haproxy/quic_rx-t.h>
#include <haproxy/proto_quic.h>
+extern struct quic_cid_tree *quic_cid_trees;
+
struct quic_connection_id *new_quic_cid(struct eb_root *root,
struct quic_conn *qc,
const struct quic_cid *orig,
/* per-thread quic datagram handlers */
struct quic_dghdlr *quic_dghdlrs;
-/* global CID trees */
-#define QUIC_CID_TREES_CNT 256
-struct quic_cid_tree *quic_cid_trees;
-
/* Size of the internal buffer of QUIC RX buffer at the fd level */
#define QUIC_RX_BUFSZ (1UL << 18)
MT_LIST_INIT(&dghdlr->dgrams);
}
- quic_cid_trees = calloc(QUIC_CID_TREES_CNT, sizeof(*quic_cid_trees));
- if (!quic_cid_trees) {
- ha_alert("Failed to allocate global quic CIDs trees.\n");
- return 0;
- }
-
- for (i = 0; i < QUIC_CID_TREES_CNT; ++i) {
- HA_RWLOCK_INIT(&quic_cid_trees[i].lock);
- quic_cid_trees[i].root = EB_ROOT_UNIQUE;
- }
-
return 1;
}
REGISTER_POST_CHECK(quic_alloc_dghdlrs);
free(quic_dghdlrs);
}
- ha_free(&quic_cid_trees);
-
return 1;
}
REGISTER_POST_DEINIT(quic_deallocate_dghdlrs);
+#include <stdlib.h>
+
#include <import/eb64tree.h>
#include <import/ebmbtree.h>
+#include <haproxy/bug.h>
+#include <haproxy/errors.h>
#include <haproxy/pool.h>
#include <haproxy/quic_cid.h>
#include <haproxy/quic_conn.h>
#include <haproxy/trace.h>
#include <haproxy/xxhash.h>
+/* *** QUIC CID handling general principles
+ *
+ * . CID global storage
+ * CIDs generated by haproxy and reuse by the peer as DCID are stored in a
+ * global tree. Tree access must only be done under lock protection.
+ *
+ * . CID global tree splitting
+ * To reduce thread contention, global CID tree is in reality splitted into 256
+ * distinct tree instances. Each CID is assigned to a single tree instance
+ * based on its content. Use quic_cid_tree_idx() to retrieve the expected tree
+ * location for a CID.
+ *
+ * . ODCID handling
+ * ODCID are never stored in global CID tree. This allows to reduce tree size
+ * as clients are expected to switch quickly to a new haproxy assigned CID.
+ * This new CID value is derived by haproxy from the ODCID plus a bunch of
+ * other parameters. If ODCID is reused by the client, first lookup in global
+ * CID tree won't be successful. In this case, derive operation is performed
+ * again before a new tree lookup.
+ */
+
+#define QUIC_CID_TREES_CNT 256
+struct quic_cid_tree *quic_cid_trees;
+
/* Initialize the stateless reset token attached to <conn_id> connection ID.
* Returns 1 if succeeded, 0 if not.
*/
TRACE_LEAVE(QUIC_EV_CONN_PRSHPKT, qc);
return ret;
}
+
+static int quic_alloc_global_cid_tree(void)
+{
+ int i;
+
+ quic_cid_trees = calloc(QUIC_CID_TREES_CNT, sizeof(*quic_cid_trees));
+ if (!quic_cid_trees) {
+ ha_alert("Failed to allocate global quic CIDs trees.\n");
+ return 0;
+ }
+
+ for (i = 0; i < QUIC_CID_TREES_CNT; ++i) {
+ HA_RWLOCK_INIT(&quic_cid_trees[i].lock);
+ quic_cid_trees[i].root = EB_ROOT_UNIQUE;
+ }
+
+ return 1;
+}
+REGISTER_POST_CHECK(quic_alloc_global_cid_tree);
+
+static int quic_deallocate_global_cid_tree(void)
+{
+ ha_free(&quic_cid_trees);
+ return 1;
+}
+REGISTER_POST_DEINIT(quic_deallocate_global_cid_tree);