diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index 81829e938..a0281c94d 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -478,7 +478,7 @@ struct quic_conn { struct quic_cid odcid; /* First DCID used by client on its Initial packet. */ struct quic_cid dcid; /* DCID of our endpoint - not updated when a new DCID is used */ struct quic_cid scid; /* first SCID of our endpoint - not updated when a new SCID is used */ - struct eb_root cids; /* tree of quic_connection_id - used to match a received packet DCID with a connection */ + struct eb_root *cids; /* tree of quic_connection_id - used to match a received packet DCID with a connection */ uint64_t next_cid_seq_num; /* Initial encryption level */ diff --git a/include/haproxy/quic_conn.h b/include/haproxy/quic_conn.h index 2f7b36982..c9ee29209 100644 --- a/include/haproxy/quic_conn.h +++ b/include/haproxy/quic_conn.h @@ -209,7 +209,7 @@ static inline void free_quic_conn_cids(struct quic_conn *conn) { struct eb64_node *node; - node = eb64_first(&conn->cids); + node = eb64_first(conn->cids); while (node) { struct quic_connection_id *conn_id; diff --git a/src/quic_conn.c b/src/quic_conn.c index 8cc582903..97cb1eb55 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -129,6 +129,7 @@ const struct quic_version quic_version_VN_reserved = { .num = 0, }; static BIO_METHOD *ha_quic_meth; DECLARE_STATIC_POOL(pool_head_quic_conn, "quic_conn", sizeof(struct quic_conn)); +DECLARE_STATIC_POOL(pool_head_quic_cids, "quic_cids", sizeof(struct eb_root)); DECLARE_POOL(pool_head_quic_connection_id, "quic_connection_id", sizeof(struct quic_connection_id)); DECLARE_POOL(pool_head_quic_crypto_buf, "quic_crypto_buf", sizeof(struct quic_crypto_buf)); @@ -1033,7 +1034,7 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4, qc->streams_by_id = EB_ROOT_UNIQUE; /* Required to call free_quic_conn_cids() from quic_conn_release() */ - qc->cids = EB_ROOT; + qc->cids = NULL; qc_init_fd(qc); LIST_INIT(&qc->back_refs); @@ -1075,6 +1076,13 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4, goto err; } + qc->cids = pool_alloc(pool_head_quic_cids); + if (!qc->cids) { + TRACE_ERROR("Could not allocate a new CID tree", QUIC_EV_CONN_INIT, qc); + goto err; + } + + *qc->cids = EB_ROOT; /* QUIC Server (or listener). */ if (server) { struct proxy *prx; @@ -1294,6 +1302,7 @@ void quic_conn_release(struct quic_conn *qc) /* remove the connection from receiver cids trees */ free_quic_conn_cids(qc); + pool_free(pool_head_quic_cids, qc->cids); /* free the SSL sock context */ qc_free_ssl_sock_ctx(&qc->xprt_ctx); @@ -1695,7 +1704,7 @@ int qc_set_tid_affinity(struct quic_conn *qc, uint new_tid, struct listener *new */ qc_detach_th_ctx_list(qc, 0); - node = eb64_first(&qc->cids); + node = eb64_first(qc->cids); BUG_ON(!node || eb64_next(node)); /* One and only one CID must be present before affinity rebind. */ conn_id = eb64_entry(node, struct quic_connection_id, seq_num); diff --git a/src/quic_rx.c b/src/quic_rx.c index d28faa5a8..152bbe3ce 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -874,7 +874,7 @@ static int qc_handle_retire_connection_id_frm(struct quic_conn *qc, * the Destination Connection ID field of the packet in which the frame is contained. * The peer MAY treat this as a connection error of type PROTOCOL_VIOLATION. */ - node = eb64_lookup(&qc->cids, rcid_frm->seq_num); + node = eb64_lookup(qc->cids, rcid_frm->seq_num); if (!node) { TRACE_PROTO("CID already retired", QUIC_EV_CONN_PSTRM, qc, frm); goto out; @@ -1056,7 +1056,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, pool_free(pool_head_quic_connection_id, conn_id); TRACE_PROTO("CID retired", QUIC_EV_CONN_PSTRM, qc); - conn_id = new_quic_cid(&qc->cids, qc, NULL, NULL); + conn_id = new_quic_cid(qc->cids, qc, NULL, NULL); if (!conn_id) { TRACE_ERROR("CID allocation error", QUIC_EV_CONN_IO_CB, qc); } @@ -1954,7 +1954,7 @@ static struct quic_conn *quic_rx_pkt_retrieve_conn(struct quic_rx_packet *pkt, * packet. must be inserted in the CIDs tree for this * connection. */ - eb64_insert(&qc->cids, &conn_id->seq_num); + eb64_insert(qc->cids, &conn_id->seq_num); /* Initialize the next CID sequence number to be used for this connection. */ qc->next_cid_seq_num = 1; } diff --git a/src/quic_tx.c b/src/quic_tx.c index 814934fb3..c414e2c43 100644 --- a/src/quic_tx.c +++ b/src/quic_tx.c @@ -771,7 +771,7 @@ int quic_build_post_handshake_frames(struct quic_conn *qc) goto err; } - conn_id = new_quic_cid(&qc->cids, qc, NULL, NULL); + conn_id = new_quic_cid(qc->cids, qc, NULL, NULL); if (!conn_id) { qc_frm_free(qc, &frm); TRACE_ERROR("CID allocation error", QUIC_EV_CONN_IO_CB, qc); @@ -803,7 +803,7 @@ int quic_build_post_handshake_frames(struct quic_conn *qc) /* The first CID sequence number value used to allocated CIDs by this function is 1, * 0 being the sequence number of the CID for this connection. */ - node = eb64_lookup_ge(&qc->cids, 1); + node = eb64_lookup_ge(qc->cids, 1); while (node) { struct quic_connection_id *conn_id;