From 2ce99fe4bf22054fbdac84c3a7bb3c31582a00c0 Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Wed, 19 Jan 2022 15:46:11 +0100 Subject: [PATCH] MINOR: quic: create accept queue for QUIC connections Create a new type quic_accept_queue to handle QUIC connections accept. A queue will be allocated for each thread. It contains a list of listeners which contains at least one quic_conn ready to be accepted and the tasklet to run listener_accept for these listeners. --- include/haproxy/quic_sock-t.h | 12 +++++++ include/haproxy/quic_sock.h | 1 + src/proto_quic.c | 1 + src/quic_sock.c | 64 +++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 include/haproxy/quic_sock-t.h diff --git a/include/haproxy/quic_sock-t.h b/include/haproxy/quic_sock-t.h new file mode 100644 index 000000000..5a591ccd5 --- /dev/null +++ b/include/haproxy/quic_sock-t.h @@ -0,0 +1,12 @@ +#ifndef _HAPROXY_QUIC_SOCK_T_H +#define _HAPROXY_QUIC_SOCK_T_H +#ifdef USE_QUIC + +/* QUIC connection accept queue. One per thread. */ +struct quic_accept_queue { + struct mt_list listeners; /* QUIC listeners with at least one connection ready to be accepted on this queue */ + struct tasklet *tasklet; /* task responsible to call listener_accept */ +}; + +#endif /* USE_QUIC */ +#endif /* _HAPROXY_QUIC_SOCK_T_H */ diff --git a/include/haproxy/quic_sock.h b/include/haproxy/quic_sock.h index 652bc414b..2a2818bc5 100644 --- a/include/haproxy/quic_sock.h +++ b/include/haproxy/quic_sock.h @@ -32,6 +32,7 @@ #include #include #include +#include int quic_session_accept(struct connection *cli_conn); int quic_sock_accepting_conn(const struct receiver *rx); diff --git a/src/proto_quic.c b/src/proto_quic.c index 6fdb3f779..dc3d26219 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -525,6 +525,7 @@ static void quic_add_listener(struct protocol *proto, struct listener *listener) listener->rx.cids = EB_ROOT_UNIQUE; listener->rx.flags |= RX_F_LOCAL_ACCEPT; HA_RWLOCK_INIT(&listener->rx.cids_lock); + default_add_listener(proto, listener); } diff --git a/src/quic_sock.c b/src/quic_sock.c index bb593738e..866eaa287 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -222,3 +222,67 @@ void quic_sock_fd_iocb(int fd) out: MT_LIST_APPEND(&l->rx.rxbuf_list, &rxbuf->mt_list); } + + +/*********************** QUIC accept queue management ***********************/ +/* per-thread accept queues */ +struct quic_accept_queue *quic_accept_queues; + +/* Tasklet handler to accept QUIC connections. Call listener_accept on every + * listener instances registered in the accept queue. + */ +static struct task *quic_accept_run(struct task *t, void *ctx, unsigned int i) +{ + struct li_per_thread *lthr; + struct mt_list *elt1, elt2; + struct quic_accept_queue *queue = &quic_accept_queues[tid]; + + mt_list_for_each_entry_safe(lthr, &queue->listeners, quic_accept.list, elt1, elt2) { + listener_accept(lthr->li); + MT_LIST_DELETE_SAFE(elt1); + } + + return NULL; +} + +static int quic_alloc_accept_queues(void) +{ + int i; + + quic_accept_queues = calloc(global.nbthread, sizeof(struct quic_accept_queue)); + if (!quic_accept_queues) { + ha_alert("Failed to allocate the quic accept queues.\n"); + return 0; + } + + for (i = 0; i < global.nbthread; ++i) { + struct tasklet *task; + if (!(task = tasklet_new())) { + ha_alert("Failed to allocate the quic accept queue on thread %d.\n", i); + return 0; + } + + tasklet_set_tid(task, i); + task->process = quic_accept_run; + quic_accept_queues[i].tasklet = task; + + MT_LIST_INIT(&quic_accept_queues[i].listeners); + } + + return 1; +} +REGISTER_POST_CHECK(quic_alloc_accept_queues); + +static int quic_deallocate_accept_queues(void) +{ + int i; + + if (quic_accept_queues) { + for (i = 0; i < global.nbthread; ++i) + tasklet_free(quic_accept_queues[i].tasklet); + free(quic_accept_queues); + } + + return 1; +} +REGISTER_POST_DEINIT(quic_deallocate_accept_queues);