]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Make usage of by datagram handler trees
authorFrédéric Lécaille <flecaille@haproxy.com>
Thu, 27 Jan 2022 14:35:56 +0000 (15:35 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 27 Jan 2022 15:37:55 +0000 (16:37 +0100)
The CID trees are no more attached to the listener receiver but to the
underlying datagram handlers (one by thread) which run always on the same thread.
So, any operation on these trees do not require any locking.

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

index 83ac049536c08b676342e80a0bdfe9f201a49b78..d0dddb98446bb74605a8a6669bbabffe52369add 100644 (file)
@@ -65,9 +65,6 @@ struct receiver {
        struct rx_settings *settings;    /* points to the settings used by this receiver */
        struct list proto_list;          /* list in the protocol header */
 #ifdef USE_QUIC
-       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 **tx_qrings;         /* Array of rings (one by thread) */
        struct mt_list tx_qring_list;    /* The same as ->tx_qrings but arranged in a list */
 
index 99b8afdff311463b4b05ce98388463a63db3c41e..3862e31dd724c03bc1dedc426c7499ce06bf7ca4 100644 (file)
@@ -519,11 +519,7 @@ int quic_connect_server(struct connection *conn, int flags)
 static void quic_add_listener(struct protocol *proto, struct listener *listener)
 {
        listener->flags |= LI_F_QUIC_LISTENER;
-
-       listener->rx.odcids = EB_ROOT_UNIQUE;
-       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);
 }
index 11fd33df693d7de450543ee76933fa66dbd65721..322f11787462652d163fcafd2614d85eafa64481 100644 (file)
@@ -2810,10 +2810,8 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc)
                if (!cid)
                        goto err;
 
-               /* insert the allocated CID in the receiver tree */
-               HA_RWLOCK_WRLOCK(QUIC_LOCK, &l->rx.cids_lock);
-               ebmb_insert(&l->rx.cids, &cid->node, cid->cid.len);
-               HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &l->rx.cids_lock);
+               /* insert the allocated CID in the receiver datagram handler tree */
+               ebmb_insert(&l->rx.dghdlrs[tid]->cids, &cid->node, cid->cid.len);
 
                quic_connection_id_to_frm_cpy(frm, cid);
                LIST_APPEND(&qel->pktns->tx.frms, &frm->list);
@@ -3440,11 +3438,9 @@ static void quic_conn_release(struct quic_conn *qc)
        struct ssl_sock_ctx *conn_ctx;
 
        /* remove the connection from receiver cids trees */
-       HA_RWLOCK_WRLOCK(QUIC_LOCK, &qc->li->rx.cids_lock);
        ebmb_delete(&qc->odcid_node);
        ebmb_delete(&qc->scid_node);
        free_quic_conn_cids(qc);
-       HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qc->li->rx.cids_lock);
 
        /* Kill the tasklet. Do not use tasklet_free as this is not thread safe
         * as other threads may call tasklet_wakeup after this.
@@ -3615,12 +3611,9 @@ static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
                goto err;
        }
 
-       /* insert the allocated CID in the receiver tree */
-       if (server) {
-               HA_RWLOCK_WRLOCK(QUIC_LOCK, &l->rx.cids_lock);
-               ebmb_insert(&l->rx.cids, &icid->node, icid->cid.len);
-               HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &l->rx.cids_lock);
-       }
+       /* insert the allocated CID in the receiver datagram handler tree */
+       if (server)
+               ebmb_insert(&l->rx.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;
@@ -4018,8 +4011,6 @@ static struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
        /* set if the quic_conn is found in the second DCID tree */
        int found_in_dcid = 0;
 
-       HA_RWLOCK_RDLOCK(QUIC_LOCK, &l->rx.cids_lock);
-
        /* Look first into ODCIDs tree for INITIAL/0-RTT packets. */
        if (pkt->type == QUIC_PACKET_TYPE_INITIAL ||
            pkt->type == QUIC_PACKET_TYPE_0RTT) {
@@ -4028,7 +4019,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.odcids, pkt->dcid.data,
+               node = ebmb_lookup(&l->rx.dghdlrs[tid]->odcids, pkt->dcid.data,
                                   pkt->dcid.len + pkt->dcid.addrlen);
                if (node) {
                        qc = ebmb_entry(node, struct quic_conn, odcid_node);
@@ -4040,7 +4031,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.cids, pkt->dcid.data, pkt->dcid.len);
+       node = ebmb_lookup(&l->rx.dghdlrs[tid]->cids, pkt->dcid.data, pkt->dcid.len);
        if (!node)
                goto end;
 
@@ -4051,18 +4042,12 @@ static struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
  end:
        if (qc)
                quic_conn_take(qc);
-       HA_RWLOCK_RDUNLOCK(QUIC_LOCK, &l->rx.cids_lock);
 
        /* If found in DCIDs tree, remove the quic_conn from the ODCIDs tree.
         * If already done, this is a noop.
-        *
-        * node.leaf_p is first checked to avoid unnecessary locking.
         */
-       if (qc && found_in_dcid && qc->odcid_node.node.leaf_p) {
-               HA_RWLOCK_WRLOCK(QUIC_LOCK, &l->rx.cids_lock);
+       if (qc && found_in_dcid)
                ebmb_delete(&qc->odcid_node);
-               HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &l->rx.cids_lock);
-       }
 
        return qc;
 }
@@ -4377,9 +4362,8 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
                                goto err;
                        }
 
-                       HA_RWLOCK_WRLOCK(QUIC_LOCK, &l->rx.cids_lock);
                        /* Insert the DCID the QUIC client has chosen (only for listeners) */
-                       n = ebmb_insert(&l->rx.odcids, &qc->odcid_node,
+                       n = ebmb_insert(&l->rx.dghdlrs[tid]->odcids, &qc->odcid_node,
                                        qc->odcid.len + qc->odcid.addrlen);
 
                        /* If the insertion failed, it means that another
@@ -4394,7 +4378,6 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
                        }
 
                        quic_conn_take(qc);
-                       HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &l->rx.cids_lock);
 
                        if (likely(!qc_to_purge)) {
                                /* Enqueue this packet. */