]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: remove ODCID dedicated tree
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 3 Apr 2023 16:50:58 +0000 (18:50 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 5 Apr 2023 09:07:01 +0000 (11:07 +0200)
First connection CID generation has been altered. It is now directly
derived from client ODCID since previous commit :
  commit 162baaff7ab761c411800f4ca6bef45315d7afcb
  MINOR: quic: derive first DCID from client ODCID

This patch removes the ODCID tree which is now unneeded. On connection
lookup via CID, if a DCID is not found the hash derivation is performed
for an INITIAL/0-RTT packet only. In case a client has used multiple
times an ODCID, this will allow to retrieve our generated DCID in the
CID tree without storing the ODCID node.

The impact of this two combined patch is that it may improve slightly
haproxy memory footprint by removing a tree node from quic_conn
structure. The cpu calculation induced by hash derivation should only be
performed only a few times per connection as the client will start to
use our generated CID as soon as it received it.

This should be backported up to 2.7.

include/haproxy/quic_conn-t.h
src/proto_quic.c
src/quic_conn.c

index 1ec368cc2b89964c3eb712bcc3da42cacfa22ab0..f6a962984291d22b258f3cf43082684319813ac4 100644 (file)
@@ -55,7 +55,9 @@ typedef unsigned long long ull;
 /* The minimum length of Initial packets. */
 #define QUIC_INITIAL_PACKET_MINLEN 1200
 
-/* Lengths of the QUIC CIDs generated by the haproxy implementation. */
+/* Lengths of the QUIC CIDs generated by the haproxy implementation. Current
+ * value is used to match 64 bits hash produced when deriving ODCID.
+ */
 #define QUIC_HAP_CID_LEN               8
 
 /* Common definitions for short and long QUIC packet headers. */
@@ -440,7 +442,6 @@ struct quic_rx_packet {
 struct quic_dghdlr {
        struct mt_list dgrams;
        struct tasklet *task;
-       struct eb_root odcids;
        struct eb_root cids;
 };
 
@@ -654,7 +655,6 @@ struct quic_conn {
         * Original DCID used by clients on first Initial packets.
         * <odcid> is concatenated with the socket src address.
         */
-       struct ebmb_node odcid_node;
        struct quic_cid odcid;
 
        struct quic_cid dcid; /* DCID of our endpoint - not updated when a new DCID is used */
index 9d2755310390e6593613d8293c2f710289797273..b1708eb9f2a4b31c4dc2e89ff15fcc42b451b233 100644 (file)
@@ -734,7 +734,6 @@ static int quic_alloc_dghdlrs(void)
                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);
index 6fa187ace7cc8dd600894dd04c51f412f5cff7c6..268368f5b98e2525bec12b430b4d1cddf38fdb6e 100644 (file)
@@ -5638,7 +5638,6 @@ void quic_conn_release(struct quic_conn *qc)
                tasklet_free(qc->wait_event.tasklet);
 
        /* remove the connection from receiver cids trees */
-       ebmb_delete(&qc->odcid_node);
        ebmb_delete(&qc->scid_node);
        free_quic_conn_cids(qc);
 
@@ -6463,9 +6462,9 @@ static int send_retry(int fd, struct sockaddr_storage *addr,
        return !ret;
 }
 
-/* Retrieve a quic_conn instance from the <pkt> DCID field. If the packet is of
- * type INITIAL, the ODCID tree is first used. In this case, <saddr> is
- * concatenated to the <pkt> DCID field.
+/* Retrieve a quic_conn instance from the <pkt> DCID field. If the packet is an
+ * INITIAL or 0RTT type, we may have to use client address <saddr> if an ODCID
+ * is used.
  *
  * Returns the instance or NULL if not found.
  */
@@ -6480,39 +6479,25 @@ static struct quic_conn *retrieve_qc_conn_from_cid(struct quic_rx_packet *pkt,
 
        TRACE_ENTER(QUIC_EV_CONN_RXPKT);
 
-       /* Look first into ODCIDs tree for INITIAL/0-RTT packets. */
-       if (pkt->type == QUIC_PACKET_TYPE_INITIAL ||
-           pkt->type == QUIC_PACKET_TYPE_0RTT) {
-               /* DCIDs of first packets coming from multiple clients may have
-                * the same values. Let's distinguish them by concatenating the
-                * socket addresses.
-                */
-               quic_cid_saddr_cat(&pkt->dcid, saddr);
-               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);
-                       goto end;
-               }
-       }
+       /* First look into DCID tree. */
+       node = ebmb_lookup(&quic_dghdlrs[tid].cids, pkt->dcid.data, pkt->dcid.len);
 
-       /* Look into DCIDs tree for non-INITIAL/0-RTT packets. This may be used
-        * also for INITIAL/0-RTT non-first packets with the final DCID in
-        * used.
+       /* If not found on an Initial/0-RTT packet, it could be because an
+        * ODCID is reused by the client. Calculate the derived CID value to
+        * retrieve it from the DCID tree.
         */
-       node = ebmb_lookup(&quic_dghdlrs[tid].cids, pkt->dcid.data, pkt->dcid.len);
+       if (!node && (pkt->type == QUIC_PACKET_TYPE_INITIAL ||
+            pkt->type == QUIC_PACKET_TYPE_0RTT)) {
+               uint64_t hash = quic_derive_cid(&pkt->dcid, saddr);
+               node = ebmb_lookup(&quic_dghdlrs[tid].cids, &hash, sizeof(hash));
+       }
+
        if (!node)
                goto end;
 
        id = ebmb_entry(node, struct quic_connection_id, node);
        qc = id->qc;
 
-       /* If found in DCIDs tree, remove the quic_conn from the ODCIDs tree.
-        * If already done, this is a noop.
-        */
-       if (qc)
-               ebmb_delete(&qc->odcid_node);
-
  end:
        TRACE_LEAVE(QUIC_EV_CONN_RXPKT, qc);
        return qc;
@@ -6701,9 +6686,6 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt,
                                goto err;
 
                        HA_ATOMIC_INC(&prx_counters->half_open_conn);
-                       /* Insert the DCID the QUIC client has chosen (only for listeners) */
-                       ebmb_insert(&quic_dghdlrs[tid].odcids, &qc->odcid_node,
-                                   qc->odcid.len + qc->odcid.addrlen);
                }
        }
        else if (!qc) {