MINOR: quic: remove ODCID dedicated tree
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.
diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h
index 1ec368c..f6a9629 100644
--- a/include/haproxy/quic_conn-t.h
+++ b/include/haproxy/quic_conn-t.h
@@ -55,7 +55,9 @@
/* 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_dghdlr {
struct mt_list dgrams;
struct tasklet *task;
- struct eb_root odcids;
struct eb_root cids;
};
@@ -654,7 +655,6 @@
* 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 */
diff --git a/src/proto_quic.c b/src/proto_quic.c
index 9d27553..b1708eb 100644
--- a/src/proto_quic.c
+++ b/src/proto_quic.c
@@ -734,7 +734,6 @@
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);
diff --git a/src/quic_conn.c b/src/quic_conn.c
index 6fa187a..268368f 100644
--- a/src/quic_conn.c
+++ b/src/quic_conn.c
@@ -5638,7 +5638,6 @@
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 @@
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 @@
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 @@
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) {