]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: use a global dghlrs for each thread
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 8 Feb 2022 14:03:40 +0000 (15:03 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 15 Feb 2022 09:13:20 +0000 (10:13 +0100)
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.

include/haproxy/proto_quic.h
include/haproxy/receiver-t.h
src/proto_quic.c
src/xprt_quic.c

index e703f431466ffefe2f417222db425fcdc018f8f4..d015886ef36926a303f0e03fae17ca59d018313d 100644 (file)
@@ -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  */
index d0dddb98446bb74605a8a6669bbabffe52369add..274339d401f369b1ab7c0af9800742956ca5601d 100644 (file)
@@ -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
index 3862e31dd724c03bc1dedc426c7499ce06bf7ca4..5296721c159d1b386dead6e1e8346ccf350027ae 100644 (file)
@@ -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
index 5aa1893d1b0f87bea2d5d7ef54e22d13cf93af30..bff17805c5d20f4f594f9e969fb033cc1d61fa06 100644 (file)
@@ -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;