From: Amaury Denoyelle Date: Mon, 3 Apr 2023 16:50:58 +0000 (+0200) Subject: MINOR: quic: remove ODCID dedicated tree X-Git-Tag: v2.8-dev7~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2c98209c1c807d378c303cc65299a74730b3809a;p=thirdparty%2Fhaproxy.git 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 1ec368cc2b..f6a9629842 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -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. * 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 9d27553103..b1708eb9f2 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -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); diff --git a/src/quic_conn.c b/src/quic_conn.c index 6fa187ace7..268368f5b9 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -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 DCID field. If the packet is of - * type INITIAL, the ODCID tree is first used. In this case, is - * concatenated to the DCID field. +/* Retrieve a quic_conn instance from the DCID field. If the packet is an + * INITIAL or 0RTT type, we may have to use client address 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) {