@@ -738,12 +738,15 @@ xqc_process_ping_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in)
738
738
xqc_int_t
739
739
xqc_process_new_conn_id_frame (xqc_connection_t * conn , xqc_packet_in_t * packet_in )
740
740
{
741
- xqc_int_t ret = XQC_ERROR ;
742
- xqc_cid_t new_conn_cid ;
743
- uint64_t retire_prior_to ;
741
+ xqc_int_t ret = XQC_ERROR ;
742
+ xqc_cid_t new_conn_cid ;
743
+ uint64_t retire_prior_to ;
744
+ uint64_t largest_retire_prior_to ;
745
+ uint64_t cid_limit ;
746
+
744
747
745
- xqc_cid_inner_t * inner_cid ;
746
- xqc_list_head_t * pos , * next ;
748
+ /* the initial cid limit */
749
+ cid_limit = conn -> local_settings . active_connection_id_limit ;
747
750
748
751
ret = xqc_parse_new_conn_id_frame (packet_in , & new_conn_cid , & retire_prior_to , conn );
749
752
if (ret != XQC_OK ) {
@@ -769,6 +772,7 @@ xqc_process_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in
769
772
770
773
/* TODO: write_retire_conn_id_frame 可能涉及到 替换 path.dcid (当前无 retire_prior_to 因此不涉及) */
771
774
775
+ /* the current cid was retired and is needed no more */
772
776
if (new_conn_cid .cid_seq_num < conn -> dcid_set .largest_retire_prior_to ) {
773
777
/*
774
778
* An endpoint that receives a NEW_CONNECTION_ID frame with a sequence number smaller
@@ -788,37 +792,26 @@ xqc_process_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in
788
792
return XQC_OK ;
789
793
}
790
794
791
- if (retire_prior_to > conn -> dcid_set .largest_retire_prior_to ) {
792
- /*
793
- * Upon receipt of an increased Retire Prior To field, the peer MUST stop using the
794
- * corresponding connection IDs and retire them with RETIRE_CONNECTION_ID frames before
795
- * adding the newly provided connection ID to the set of active connection IDs.
796
- */
797
-
798
- xqc_list_for_each_safe (pos , next , & conn -> dcid_set .cid_set .list_head ) {
799
- inner_cid = xqc_list_entry (pos , xqc_cid_inner_t , list );
800
- uint64_t seq_num = inner_cid -> cid .cid_seq_num ;
801
- if ((inner_cid -> state == XQC_CID_UNUSED || inner_cid -> state == XQC_CID_USED )
802
- && (seq_num >= conn -> dcid_set .largest_retire_prior_to && seq_num < retire_prior_to ))
803
- {
804
- ret = xqc_write_retire_conn_id_frame_to_packet (conn , seq_num );
805
- if (ret != XQC_OK ) {
806
- xqc_log (conn -> log , XQC_LOG_ERROR , "|xqc_write_retire_conn_id_frame_to_packet error|" );
807
- return ret ;
808
- }
809
- }
810
- }
811
-
812
- conn -> dcid_set .largest_retire_prior_to = retire_prior_to ;
813
- xqc_log (conn -> log , XQC_LOG_DEBUG , "|retire_prior_to|%ui|increase to|%ui|" ,
814
- conn -> dcid_set .largest_retire_prior_to , retire_prior_to );
815
- }
816
-
817
795
/* store dcid & add unused_dcid_count */
818
796
if (xqc_cid_in_cid_set (& conn -> dcid_set .cid_set , & new_conn_cid ) != NULL ) {
819
797
return XQC_OK ;
820
798
}
821
799
800
+ /* check if insertion of the new conneciton id will violate the cid limit */
801
+ largest_retire_prior_to = xqc_max (retire_prior_to ,
802
+ conn -> dcid_set .largest_retire_prior_to );
803
+ if (!xqc_cid_set_validate_new_cid_limit (& conn -> dcid_set .cid_set ,
804
+ largest_retire_prior_to , & cid_limit ))
805
+ {
806
+ xqc_log (conn -> log , XQC_LOG_ERROR , "|retire_prior_to:%ui greater than seq_num:%ui|" ,
807
+ retire_prior_to , new_conn_cid .cid_seq_num );
808
+ XQC_CONN_ERR (conn , TRA_PROTOCOL_VIOLATION );
809
+ return - XQC_EPROTO ;
810
+ }
811
+
812
+ xqc_log (conn -> log , XQC_LOG_DEBUG , "|nci allow to be inserted|seq:%ui|dcid_cnt:%ui|cid_limit:%ui" ,
813
+ new_conn_cid .cid_seq_num , xqc_cid_set_cnt (& conn -> dcid_set .cid_set ), cid_limit );
814
+
822
815
/* insert into dcid-connection hash, for processing the deprecated stateless
823
816
reset packet */
824
817
ret = xqc_insert_conns_hash (conn -> engine -> conns_hash_dcid , conn ,
@@ -840,13 +833,31 @@ xqc_process_new_conn_id_frame(xqc_connection_t *conn, xqc_packet_in_t *packet_in
840
833
return ret ;
841
834
}
842
835
843
- ret = xqc_cid_set_insert_cid (& conn -> dcid_set .cid_set , & new_conn_cid , XQC_CID_UNUSED , conn -> local_settings .active_connection_id_limit );
836
+ /* An endpoint MAY send connection IDs that temporarily exceed a peer's
837
+ * limit if the NEW_CONNECTION_ID frame also requires the retirement of any
838
+ * excess, by including a sufficiently large value in the Retire Prior To
839
+ * field. Hence it is not reasonable to consider it as an error */
840
+ ret = xqc_cid_set_insert_cid (& conn -> dcid_set .cid_set , & new_conn_cid ,
841
+ XQC_CID_UNUSED , cid_limit );
844
842
if (ret != XQC_OK ) {
845
- xqc_log (conn -> log , XQC_LOG_ERROR , "|xqc_cid_set_insert_cid error|limit:%ui|unused:%ui|used:%ui|" ,
846
- conn -> local_settings .active_connection_id_limit , conn -> dcid_set .cid_set .unused_cnt , conn -> dcid_set .cid_set .used_cnt );
843
+ xqc_log (conn -> log , XQC_LOG_ERROR , "|xqc_cid_set_insert_cid error"
844
+ "|local_limit:%ui|largest_limit:%ui|retire_prior_to:%ui|"
845
+ "unused:%ui|used:%ui|" ,
846
+ conn -> local_settings .active_connection_id_limit ,
847
+ cid_limit , retire_prior_to , conn -> dcid_set .cid_set .unused_cnt ,
848
+ conn -> dcid_set .cid_set .used_cnt );
847
849
return ret ;
848
850
}
849
851
852
+ /*
853
+ * Upon receipt of an increased Retire Prior To field, the peer MUST stop
854
+ * using the corresponding connection IDs and retire them with
855
+ * RETIRE_CONNECTION_ID frames before adding the newly provided connection
856
+ * ID to the set of active connection IDs.
857
+ */
858
+ if (retire_prior_to > conn -> dcid_set .largest_retire_prior_to ) {
859
+ xqc_conn_retire_dcid_prior_to (conn , retire_prior_to );
860
+ }
850
861
851
862
return XQC_OK ;
852
863
}
0 commit comments