MEDIUM: quic: use a global CID trees list

Previously, quic_connection_id were stored in a per-thread tree list.
Datagram were first dispatched to the correct thread using the encoded
TID before a tree lookup was done.

Remove these trees and replace it with a global trees list of 256
entries. A CID is using the list index corresponding to its first byte.
On datagram dispatch, CID is lookup on its tree and TID is retrieved
using new member quic_connection_id.tid. As such, a read-write lock
protects each list instances. With 256 entries, it is expected that
contention should be reduced.

A new structure quic_cid_tree served as a tree container associated with
its read-write lock. An API is implemented to ensure lock safety for
insert/lookup/delete operation.

This patch is a step forward to be able to break the affinity between a
CID and a TID encoded thread. This is required to be able to migrate a
quic_conn after accept to select thread based on their load.

This should be backported up to 2.7 after a period of observation.
diff --git a/src/proto_quic.c b/src/proto_quic.c
index b1708eb..0961fc2 100644
--- a/src/proto_quic.c
+++ b/src/proto_quic.c
@@ -51,6 +51,11 @@
 
 /* per-thread quic datagram handlers */
 struct quic_dghdlr *quic_dghdlrs;
+struct eb_root *quic_cid_tree;
+
+/* 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)
@@ -734,11 +739,20 @@
 		dghdlr->task->context = dghdlr;
 		dghdlr->task->process = quic_lstnr_dghdlr;
 
-		dghdlr->cids = EB_ROOT_UNIQUE;
-
 		MT_LIST_INIT(&dghdlr->dgrams);
 	}
 
+	quic_cid_trees = calloc(QUIC_CID_TREES_CNT, sizeof(struct quic_cid_tree));
+	if (!quic_cid_trees) {
+		ha_alert("Failed to allocate global 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);
@@ -753,6 +767,8 @@
 		free(quic_dghdlrs);
 	}
 
+	ha_free(&quic_cid_trees);
+
 	return 1;
 }
 REGISTER_POST_DEINIT(quic_deallocate_dghdlrs);