/* 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. */
struct quic_dghdlr {
struct mt_list dgrams;
struct tasklet *task;
- struct eb_root odcids;
struct eb_root cids;
};
* 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 */
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);
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.
*/
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;
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) {