mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
MINOR: quic: use a global dghlrs for each thread
Move the QUIC datagram handlers oustide of the receivers. Use a global handler per-thread which is allocated on post-config. Implement a free function on process deinit to avoid a memory leak.
This commit is contained in:
parent
6c8babf6c4
commit
8524f0f779
@ -24,4 +24,6 @@
|
||||
extern struct protocol proto_quic4;
|
||||
extern struct protocol proto_quic6;
|
||||
|
||||
extern struct quic_dghdlr *quic_dghdlrs;
|
||||
|
||||
#endif /* _HAPROXY_PROTO_QUIC_H */
|
||||
|
@ -68,7 +68,6 @@ struct receiver {
|
||||
struct qring **tx_qrings; /* Array of rings (one by thread) */
|
||||
struct mt_list tx_qring_list; /* The same as ->tx_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
|
||||
|
104
src/proto_quic.c
104
src/proto_quic.c
@ -47,6 +47,8 @@
|
||||
#include <haproxy/tools.h>
|
||||
#include <haproxy/xprt_quic.h>
|
||||
|
||||
/* per-thread quic datagram handlers */
|
||||
struct quic_dghdlr *quic_dghdlrs;
|
||||
|
||||
static void quic_add_listener(struct protocol *proto, struct listener *listener);
|
||||
static int quic_bind_listener(struct listener *listener, char *errmsg, int errlen);
|
||||
@ -619,56 +621,6 @@ static int quic_alloc_rxbufs_listener(struct listener *l)
|
||||
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->task->process = quic_lstnr_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.
|
||||
@ -700,9 +652,8 @@ static int quic_bind_listener(struct listener *listener, char *errmsg, int errle
|
||||
}
|
||||
|
||||
if (!quic_alloc_tx_rings_listener(listener) ||
|
||||
!quic_alloc_rxbufs_listener(listener) ||
|
||||
!quic_alloc_dghdlrs_listener(listener)) {
|
||||
msg = "could not initialize tx/rx rings or dgram handlers";
|
||||
!quic_alloc_rxbufs_listener(listener)) {
|
||||
msg = "could not initialize tx/rx rings";
|
||||
err |= ERR_WARN;
|
||||
goto udp_return;
|
||||
}
|
||||
@ -745,6 +696,53 @@ static void quic_disable_listener(struct listener *l)
|
||||
fd_stop_recv(l->rx.fd);
|
||||
}
|
||||
|
||||
static int quic_alloc_dghdlrs(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
quic_dghdlrs = calloc(global.nbthread, sizeof(struct quic_dghdlr));
|
||||
if (!quic_dghdlrs) {
|
||||
ha_alert("Failed to allocate the quic datagram handlers.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < global.nbthread; i++) {
|
||||
struct quic_dghdlr *dghdlr = &quic_dghdlrs[i];
|
||||
|
||||
dghdlr->task = tasklet_new();
|
||||
if (!dghdlr->task) {
|
||||
ha_alert("Failed to allocate the quic datagram handler on thread %d.\n", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tasklet_set_tid(dghdlr->task, i);
|
||||
dghdlr->task->context = dghdlr;
|
||||
dghdlr->task->process = quic_lstnr_dghdlr;
|
||||
|
||||
dghdlr->odcids = EB_ROOT_UNIQUE;
|
||||
dghdlr->cids = EB_ROOT_UNIQUE;
|
||||
|
||||
MT_LIST_INIT(&dghdlr->dgrams);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
REGISTER_POST_CHECK(quic_alloc_dghdlrs);
|
||||
|
||||
static int quic_deallocate_dghdlrs(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (quic_dghdlrs) {
|
||||
for (i = 0; i < global.nbthread; ++i)
|
||||
tasklet_free(quic_dghdlrs[i].task);
|
||||
free(quic_dghdlrs);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
REGISTER_POST_DEINIT(quic_deallocate_dghdlrs);
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-indent-level: 8
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <haproxy/quic_loss.h>
|
||||
#include <haproxy/quic_sock.h>
|
||||
#include <haproxy/cbuf.h>
|
||||
#include <haproxy/proto_quic.h>
|
||||
#include <haproxy/quic_tls.h>
|
||||
#include <haproxy/sink.h>
|
||||
#include <haproxy/ssl_sock.h>
|
||||
@ -2803,7 +2804,6 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc)
|
||||
|
||||
for (i = 1; i < qc->tx.params.active_connection_id_limit; i++) {
|
||||
struct quic_connection_id *cid;
|
||||
struct listener *l = qc->li;
|
||||
|
||||
frm = pool_alloc(pool_head_quic_frame);
|
||||
if (!frm)
|
||||
@ -2814,7 +2814,7 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc)
|
||||
goto err;
|
||||
|
||||
/* insert the allocated CID in the receiver datagram handler tree */
|
||||
ebmb_insert(&l->rx.dghdlrs[tid]->cids, &cid->node, cid->cid.len);
|
||||
ebmb_insert(&quic_dghdlrs[tid].cids, &cid->node, cid->cid.len);
|
||||
|
||||
quic_connection_id_to_frm_cpy(frm, cid);
|
||||
LIST_APPEND(&qel->pktns->tx.frms, &frm->list);
|
||||
@ -3617,7 +3617,7 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
|
||||
|
||||
/* insert the allocated CID in the receiver datagram handler tree */
|
||||
if (server)
|
||||
ebmb_insert(&l->rx.dghdlrs[tid]->cids, &icid->node, icid->cid.len);
|
||||
ebmb_insert(&quic_dghdlrs[tid].cids, &icid->node, icid->cid.len);
|
||||
|
||||
/* Select our SCID which is the first CID with 0 as sequence number. */
|
||||
qc->scid = icid->cid;
|
||||
@ -4025,7 +4025,7 @@ static struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
|
||||
* socket addresses.
|
||||
*/
|
||||
quic_cid_saddr_cat(&pkt->dcid, saddr);
|
||||
node = ebmb_lookup(&l->rx.dghdlrs[tid]->odcids, pkt->dcid.data,
|
||||
node = ebmb_lookup(&quic_dghdlrs[tid].odcids, pkt->dcid.data,
|
||||
pkt->dcid.len + pkt->dcid.addrlen);
|
||||
if (node) {
|
||||
qc = ebmb_entry(node, struct quic_conn, odcid_node);
|
||||
@ -4037,7 +4037,7 @@ static struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
|
||||
* also for INITIAL/0-RTT non-first packets with the final DCID in
|
||||
* used.
|
||||
*/
|
||||
node = ebmb_lookup(&l->rx.dghdlrs[tid]->cids, pkt->dcid.data, pkt->dcid.len);
|
||||
node = ebmb_lookup(&quic_dghdlrs[tid].cids, pkt->dcid.data, pkt->dcid.len);
|
||||
if (!node)
|
||||
goto end;
|
||||
|
||||
@ -4377,7 +4377,7 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
|
||||
}
|
||||
|
||||
/* Insert the DCID the QUIC client has chosen (only for listeners) */
|
||||
n = ebmb_insert(&l->rx.dghdlrs[tid]->odcids, &qc->odcid_node,
|
||||
n = ebmb_insert(&quic_dghdlrs[tid].odcids, &qc->odcid_node,
|
||||
qc->odcid.len + qc->odcid.addrlen);
|
||||
|
||||
/* If the insertion failed, it means that another
|
||||
@ -5336,7 +5336,6 @@ int quic_lstnr_dgram_dispatch(unsigned char *buf, size_t len, void *owner,
|
||||
unsigned char *dcid;
|
||||
size_t dcid_len;
|
||||
int cid_tid;
|
||||
struct listener *l = owner;
|
||||
|
||||
if (!len || !quic_get_dgram_dcid(buf, buf + len, &dcid, &dcid_len))
|
||||
goto err;
|
||||
@ -5356,9 +5355,9 @@ int quic_lstnr_dgram_dispatch(unsigned char *buf, size_t len, void *owner,
|
||||
dgram->saddr = *saddr;
|
||||
dgram->qc = NULL;
|
||||
LIST_APPEND(dgrams, &dgram->list);
|
||||
MT_LIST_APPEND(&l->rx.dghdlrs[cid_tid]->dgrams, &dgram->mt_list);
|
||||
MT_LIST_APPEND(&quic_dghdlrs[cid_tid].dgrams, &dgram->mt_list);
|
||||
|
||||
tasklet_wakeup(l->rx.dghdlrs[cid_tid]->task);
|
||||
tasklet_wakeup(quic_dghdlrs[cid_tid].task);
|
||||
|
||||
return 1;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user