__decl_thread(HA_RWLOCK_T cids_lock); /* RW lock for connection IDs tree accesses */
struct qring *tx_qrings; /* Array of rings (one by thread) */
struct mt_list tx_qring_list; /* The same as ->qrings but arranged in a list */
+
+ struct quic_dghdlr **dghdlrs; /* Datagram handlers (one by thread) */
struct rxbuf *rxbufs; /* Array of buffers for RX (one by thread) */
struct mt_list rxbuf_list; /* The same as ->rxbufs but arranged in a list */
#endif
return 0;
}
+/* Allocate QUIC listener datagram handlers, one by thread.
+ * Returns 1 if succeeded, 0 if not.
+ */
+static int quic_alloc_dghdlrs_listener(struct listener *l)
+{
+ int i;
+
+ l->rx.dghdlrs = calloc(global.nbthread, sizeof *l->rx.dghdlrs);
+ if (!l->rx.dghdlrs)
+ return 0;
+
+ for (i = 0; i < global.nbthread; i++) {
+ struct quic_dghdlr *dghdlr;
+
+ dghdlr = calloc(1, sizeof *dghdlr);
+ if (!dghdlr)
+ goto err;
+
+ dghdlr->task = tasklet_new();
+ if (!dghdlr->task) {
+ free(dghdlr);
+ goto err;
+ }
+
+ dghdlr->task->tid = i;
+ dghdlr->task->context = dghdlr;
+ dghdlr->odcids = EB_ROOT_UNIQUE;
+ dghdlr->cids = EB_ROOT_UNIQUE;
+ MT_LIST_INIT(&dghdlr->dgrams);
+ l->rx.dghdlrs[i] = dghdlr;
+ }
+
+ return 1;
+
+ err:
+ for (i = 0; i < global.nbthread; i++) {
+ struct quic_dghdlr *dghdlr = l->rx.dghdlrs[i];
+
+ if (!dghdlr)
+ break;
+
+ tasklet_free(dghdlr->task);
+ free(dghdlr);
+ }
+ free(l->rx.dghdlrs);
+
+ return 0;
+}
+
/* This function tries to bind a QUIC4/6 listener. It may return a warning or
* an error message in <errmsg> if the message is at most <errlen> bytes long
* (including '\0'). Note that <errmsg> may be NULL if <errlen> is also zero.
}
if (!quic_alloc_tx_rings_listener(listener) ||
- !quic_alloc_rxbufs_listener(listener)) {
- msg = "could not initialize tx/rx rings";
+ !quic_alloc_rxbufs_listener(listener) ||
+ !quic_alloc_dghdlrs_listener(listener)) {
+ msg = "could not initialize tx/rx rings or dgram handlers";
err |= ERR_WARN;
goto udp_return;
}