@@ -7955,6 +7955,90 @@ fn connection_id_retire_limit(
79557955 ) ;
79567956}
79577957
7958+ #[ rstest]
7959+ fn connection_id_retire_exotic_sequence (
7960+ #[ values( "cubic" , "bbr2" , "bbr2_gcongestion" ) ] cc_algorithm_name : & str ,
7961+ ) {
7962+ let mut buf = [ 0 ; 65535 ] ;
7963+
7964+ let mut config = Config :: new ( PROTOCOL_VERSION ) . unwrap ( ) ;
7965+ assert_eq ! ( config. set_cc_algorithm_name( cc_algorithm_name) , Ok ( ( ) ) ) ;
7966+ config
7967+ . load_cert_chain_from_pem_file ( "examples/cert.crt" )
7968+ . unwrap ( ) ;
7969+ config
7970+ . load_priv_key_from_pem_file ( "examples/cert.key" )
7971+ . unwrap ( ) ;
7972+ config
7973+ . set_application_protos ( & [ b"proto1" , b"proto2" ] )
7974+ . unwrap ( ) ;
7975+ config. verify_peer ( false ) ;
7976+ config. set_active_connection_id_limit ( 2 ) ;
7977+ config. set_initial_max_data ( 30 ) ;
7978+ config. set_initial_max_stream_data_bidi_local ( 15 ) ;
7979+ config. set_initial_max_stream_data_bidi_remote ( 15 ) ;
7980+ config. set_initial_max_stream_data_uni ( 10 ) ;
7981+ config. set_initial_max_streams_uni ( 3 ) ;
7982+ config. set_initial_max_streams_bidi ( 3 ) ;
7983+
7984+ let mut pipe = test_utils:: Pipe :: with_config ( & mut config) . unwrap ( ) ;
7985+ assert_eq ! ( pipe. handshake( ) , Ok ( ( ) ) ) ;
7986+
7987+ // Inject an exotic sequence of NEW_CONNECTION_ID frames, unbeknowst to
7988+ // quiche client connection object.
7989+ let frames = [
7990+ frame:: Frame :: NewConnectionId {
7991+ seq_num : 8 ,
7992+ retire_prior_to : 1 ,
7993+ conn_id : vec ! [ 0 ] ,
7994+ reset_token : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ] ,
7995+ } ,
7996+ frame:: Frame :: NewConnectionId {
7997+ seq_num : 1 ,
7998+ retire_prior_to : 0 ,
7999+ conn_id : vec ! [ 02 ] ,
8000+ reset_token : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 ] ,
8001+ } ,
8002+ frame:: Frame :: NewConnectionId {
8003+ seq_num : 6 ,
8004+ retire_prior_to : 6 ,
8005+ conn_id : vec ! [ 0x15 ] ,
8006+ reset_token : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 3 ] ,
8007+ } ,
8008+ frame:: Frame :: NewConnectionId {
8009+ seq_num : 8 ,
8010+ retire_prior_to : 1 ,
8011+ conn_id : vec ! [ 0 ] ,
8012+ reset_token : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 ] ,
8013+ } ,
8014+ frame:: Frame :: NewConnectionId {
8015+ seq_num : 48 ,
8016+ retire_prior_to : 8 ,
8017+ conn_id : vec ! [ 1 ] ,
8018+ reset_token : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 5 ] ,
8019+ } ,
8020+ ] ;
8021+
8022+ let pkt_type = Type :: Short ;
8023+ pipe. send_pkt_to_server ( pkt_type, & frames, & mut buf)
8024+ . unwrap ( ) ;
8025+
8026+ // Ensure operations continue to be allowed.
8027+ assert_eq ! ( pipe. client. stream_send( 0 , b"data" , true ) , Ok ( 4 ) ) ;
8028+ assert_eq ! ( pipe. server. stream_send( 1 , b"data" , true ) , Ok ( 4 ) ) ;
8029+ assert_eq ! ( pipe. client. stream_send( 2 , b"data" , true ) , Ok ( 4 ) ) ;
8030+ assert_eq ! ( pipe. server. stream_send( 3 , b"data" , true ) , Ok ( 4 ) ) ;
8031+
8032+ assert_eq ! ( pipe. advance( ) , Ok ( ( ) ) ) ;
8033+
8034+ let mut b = [ 0 ; 15 ] ;
8035+ assert_eq ! ( pipe. server. stream_recv( 0 , & mut b) , Ok ( ( 4 , true ) ) ) ;
8036+ assert_eq ! ( pipe. server. stream_recv( 2 , & mut b) , Ok ( ( 4 , true ) ) ) ;
8037+
8038+ // The exotic sequence insertion messes with the client object's
8039+ // worldview so we can't check its side of things.
8040+ }
8041+
79588042// Utility function.
79598043fn pipe_with_exchanged_cids (
79608044 config : & mut Config , client_scid_len : usize , server_scid_len : usize ,
0 commit comments