From: Frédéric Lécaille Date: Mon, 6 Mar 2023 13:07:59 +0000 (+0100) Subject: MINOR: quic: Store the next connection IDs sequence number in the connection X-Git-Tag: v2.8-dev5~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4c5471425134900948b1e0a642e9eaac40b6ef4;p=thirdparty%2Fhaproxy.git MINOR: quic: Store the next connection IDs sequence number in the connection Add ->next_cid_seq_num new member to quic_conn struct to store the next connection ID to be used to alloacated a connection ID. It is initialized to 0 from qc_new_conn() which initializes a connection. Modify new_quic_cid() to use this variable each time it is called without giving the possibility to the caller to pass the sequence number for the connection to be allocated. Modify quic_build_post_handshake_frames() to use ->next_cid_seq_num when building NEW_CONNECTION_ID frames after the hanshake has been completed. Limit the number of connection IDs provided to the peer to the minimum between 4 and the value it sent with active_connection_id_limit transport parameter. This includes the connection ID used by the connection to send this new connection IDs. Must be backported to 2.7. --- diff --git a/include/haproxy/quic_conn-t.h b/include/haproxy/quic_conn-t.h index 9c3d4f4ba7..e302fb59f5 100644 --- a/include/haproxy/quic_conn-t.h +++ b/include/haproxy/quic_conn-t.h @@ -656,6 +656,7 @@ struct quic_conn { struct ebmb_node scid_node; /* used only for client side (backend) */ 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 */ + uint64_t next_cid_seq_num; struct quic_enc_level els[QUIC_TLS_ENC_LEVEL_MAX]; struct quic_pktns pktns[QUIC_TLS_PKTNS_MAX]; diff --git a/src/quic_conn.c b/src/quic_conn.c index d8ae0385c6..80d80f2862 100644 --- a/src/quic_conn.c +++ b/src/quic_conn.c @@ -3725,8 +3725,7 @@ static int quic_stateless_reset_token_init(struct quic_conn *qc, return ret; } -/* Allocate a new CID with as sequence number and attach it to - * ebtree. +/* Allocate a new CID and attach it to ebtree. * * The CID is randomly generated in part with the result altered to be * associated with the current thread ID. This means this function must only @@ -3735,8 +3734,7 @@ static int quic_stateless_reset_token_init(struct quic_conn *qc, * Returns the new CID if succeeded, NULL if not. */ static struct quic_connection_id *new_quic_cid(struct eb_root *root, - struct quic_conn *qc, - int seq_num) + struct quic_conn *qc) { struct quic_connection_id *cid; @@ -3763,7 +3761,7 @@ static struct quic_connection_id *new_quic_cid(struct eb_root *root, cid->qc = qc; - cid->seq_num.key = seq_num; + cid->seq_num.key = qc->next_cid_seq_num++; cid->retire_prior_to = 0; /* insert the allocated CID in the quic_conn tree */ eb64_insert(root, &cid->seq_num); @@ -3784,7 +3782,7 @@ static struct quic_connection_id *new_quic_cid(struct eb_root *root, */ static int quic_build_post_handshake_frames(struct quic_conn *qc) { - int ret = 0, i, first, max; + int ret = 0, max; struct quic_enc_level *qel; struct quic_frame *frm, *frmbak; struct list frm_list = LIST_HEAD_INIT(frm_list); @@ -3805,13 +3803,14 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc) } /* Initialize connection IDs minus one: there is - * already one connection ID used for the current connection. + * already one connection ID used for the current connection. Also limit + * the number of connection IDs sent to the peer to 4 (3 from this function + * plus 1 for the current connection. + * Note that active_connection_id_limit >= 2: this has been already checked + * when receiving this parameter. */ - first = 1; - max = qc->tx.params.active_connection_id_limit; - - /* TODO: check limit */ - for (i = first; i < max; i++) { + max = QUIC_MIN(qc->tx.params.active_connection_id_limit - 1, (uint64_t)3); + while (max--) { struct quic_connection_id *cid; frm = qc_frm_alloc(QUIC_FT_NEW_CONNECTION_ID); @@ -3820,7 +3819,7 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc) goto err; } - cid = new_quic_cid(&qc->cids, qc, i); + cid = new_quic_cid(&qc->cids, qc); if (!cid) { qc_frm_free(&frm); TRACE_ERROR("CID allocation error", QUIC_EV_CONN_IO_CB, qc); @@ -3847,7 +3846,10 @@ static int quic_build_post_handshake_frames(struct quic_conn *qc) list_for_each_entry_safe(frm, frmbak, &frm_list, list) qc_frm_free(&frm); - node = eb64_lookup_ge(&qc->cids, first); + /* 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); while (node) { struct quic_connection_id *cid; @@ -5179,7 +5181,10 @@ static struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4, qc->mux_state = QC_MUX_NULL; qc->err = quic_err_transport(QC_ERR_NO_ERROR); - icid = new_quic_cid(&qc->cids, qc, 0); + /* Initialize the next CID sequence number to be used for this connection. */ + qc->next_cid_seq_num = 0; + /* Insert the CID for this connection with 0 as sequence number. */ + icid = new_quic_cid(&qc->cids, qc); if (!icid) { TRACE_ERROR("Could not allocate a new connection ID", QUIC_EV_CONN_INIT, qc); goto err;