diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 91408d746..d8f2422d9 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -66,6 +66,8 @@ struct receiver { struct eb_root odcids; /* QUIC original destination connection IDs. */ struct eb_root cids; /* QUIC connection IDs. */ __decl_thread(HA_RWLOCK_T cids_lock); /* RW lock for connection IDs tree accesses */ + struct qring *qrings; /* Array of rings (one by thread) */ + struct mt_list tx_qrings; /* The same as ->qrings but arranged in a list */ #endif /* warning: this struct is huge, keep it at the bottom */ struct sockaddr_storage addr; /* the address the socket is bound to */ diff --git a/src/proto_quic.c b/src/proto_quic.c index 2b6bb6a6a..1e2ca5786 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include static void quic_add_listener(struct protocol *proto, struct listener *listener); @@ -521,6 +523,38 @@ static void quic_add_listener(struct protocol *proto, struct listener *listener) default_add_listener(proto, listener); } +/* Allocate the TX ring buffers for listener. + * Return 1 if succeeded, 0 if not. + */ +static int quic_alloc_rings_listener(struct listener *l) +{ + struct qring *qr; + int i; + + l->rx.qrings = calloc(global.nbthread, sizeof *l->rx.qrings); + if (!l->rx.qrings) + return 0; + + MT_LIST_INIT(&l->rx.tx_qrings); + for (i = 0; i < global.nbthread; i++) { + struct qring *qr = &l->rx.qrings[i]; + + qr->cbuf = cbuf_new(); + if (!qr->cbuf) + goto err; + + MT_LIST_APPEND(&l->rx.tx_qrings, &qr->mt_list); + } + + return 1; + + err: + while ((qr = MT_LIST_POP(&l->rx.tx_qrings, typeof(qr), mt_list))) + cbuf_free(qr->cbuf); + free(l->rx.qrings); + return 0; +} + /* This function tries to bind a QUIC4/6 listener. It may return a warning or * an error message in if the message is at most bytes long * (including '\0'). Note that may be NULL if is also zero. @@ -551,6 +585,12 @@ static int quic_bind_listener(struct listener *listener, char *errmsg, int errle goto udp_return; } + if (!quic_alloc_rings_listener(listener)) { + msg = "could not initialize tx rings"; + err |= ERR_WARN; + goto udp_return; + } + listener_set_state(listener, LI_LISTEN); udp_return: