@@ -3185,6 +3185,280 @@ fn voluntary_ack_with_large_datagrams() {
31853185 ) ;
31863186}
31873187
3188+ /// Test the address discovery extension on a normal setup.
3189+ #[ test]
3190+ fn address_discovery ( ) {
3191+ let _guard = subscribe ( ) ;
3192+
3193+ let server = ServerConfig {
3194+ transport : Arc :: new ( TransportConfig {
3195+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3196+ ..TransportConfig :: default ( )
3197+ } ) ,
3198+ ..server_config ( )
3199+ } ;
3200+ let mut pair = Pair :: new ( Default :: default ( ) , server) ;
3201+ let client_config = ClientConfig {
3202+ transport : Arc :: new ( TransportConfig {
3203+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3204+ ..TransportConfig :: default ( )
3205+ } ) ,
3206+ ..client_config ( )
3207+ } ;
3208+ let conn_handle = pair. begin_connect ( client_config) ;
3209+
3210+ // wait for idle connections
3211+ pair. drive ( ) ;
3212+
3213+ // check that the client received the correct address
3214+ let expected_addr = pair. client . addr ;
3215+ let conn = pair. client_conn_mut ( conn_handle) ;
3216+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3217+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3218+ assert_matches ! ( conn. poll( ) , Some ( Event :: ObservedAddr ( addr) ) if addr == expected_addr) ;
3219+ assert_matches ! ( conn. poll( ) , None ) ;
3220+
3221+ // check that the server received the correct address
3222+ let conn_handle = pair. server . assert_accept ( ) ;
3223+ let expected_addr = pair. server . addr ;
3224+ let conn = pair. server_conn_mut ( conn_handle) ;
3225+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3226+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3227+ assert_matches ! ( conn. poll( ) , Some ( Event :: ObservedAddr ( addr) ) if addr == expected_addr) ;
3228+ assert_matches ! ( conn. poll( ) , None ) ;
3229+ }
3230+
3231+ /// Test that a different address discovery configuration on 0rtt used by the client is accepted by
3232+ /// the server.
3233+ /// NOTE: this test is the same as zero_rtt_happypath, changing client transport parameters on
3234+ /// resumption.
3235+ #[ test]
3236+ fn address_discovery_zero_rtt_accepted ( ) {
3237+ let _guard = subscribe ( ) ;
3238+ let server = ServerConfig {
3239+ transport : Arc :: new ( TransportConfig {
3240+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3241+ ..TransportConfig :: default ( )
3242+ } ) ,
3243+ ..server_config ( )
3244+ } ;
3245+ let mut pair = Pair :: new ( Default :: default ( ) , server) ;
3246+
3247+ pair. server . incoming_connection_behavior = IncomingConnectionBehavior :: Validate ;
3248+ let client_cfg = ClientConfig {
3249+ transport : Arc :: new ( TransportConfig {
3250+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3251+ ..TransportConfig :: default ( )
3252+ } ) ,
3253+ ..client_config ( )
3254+ } ;
3255+ let alt_client_cfg = ClientConfig {
3256+ transport : Arc :: new ( TransportConfig {
3257+ address_discovery_role : crate :: address_discovery:: Role :: Disabled ,
3258+ ..TransportConfig :: default ( )
3259+ } ) ,
3260+ ..client_cfg. clone ( )
3261+ } ;
3262+
3263+ // Establish normal connection
3264+ let client_ch = pair. begin_connect ( client_cfg) ;
3265+ pair. drive ( ) ;
3266+ pair. server . assert_accept ( ) ;
3267+ pair. client
3268+ . connections
3269+ . get_mut ( & client_ch)
3270+ . unwrap ( )
3271+ . close ( pair. time , VarInt ( 0 ) , [ ] [ ..] . into ( ) ) ;
3272+ pair. drive ( ) ;
3273+
3274+ pair. client . addr = SocketAddr :: new (
3275+ Ipv6Addr :: LOCALHOST . into ( ) ,
3276+ CLIENT_PORTS . lock ( ) . unwrap ( ) . next ( ) . unwrap ( ) ,
3277+ ) ;
3278+ info ! ( "resuming session" ) ;
3279+ let client_ch = pair. begin_connect ( alt_client_cfg) ;
3280+ assert ! ( pair. client_conn_mut( client_ch) . has_0rtt( ) ) ;
3281+ let s = pair. client_streams ( client_ch) . open ( Dir :: Uni ) . unwrap ( ) ;
3282+ const MSG : & [ u8 ] = b"Hello, 0-RTT!" ;
3283+ pair. client_send ( client_ch, s) . write ( MSG ) . unwrap ( ) ;
3284+ pair. drive ( ) ;
3285+
3286+ let conn = pair. client_conn_mut ( client_ch) ;
3287+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3288+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3289+
3290+ assert ! ( pair. client_conn_mut( client_ch) . accepted_0rtt( ) ) ;
3291+ let server_ch = pair. server . assert_accept ( ) ;
3292+
3293+ let conn = pair. server_conn_mut ( server_ch) ;
3294+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3295+ // We don't currently preserve stream event order wrt. connection events
3296+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3297+ assert_matches ! (
3298+ conn. poll( ) ,
3299+ Some ( Event :: Stream ( StreamEvent :: Opened { dir: Dir :: Uni } ) )
3300+ ) ;
3301+
3302+ let mut recv = pair. server_recv ( server_ch, s) ;
3303+ let mut chunks = recv. read ( false ) . unwrap ( ) ;
3304+ assert_matches ! (
3305+ chunks. next( usize :: MAX ) ,
3306+ Ok ( Some ( chunk) ) if chunk. offset == 0 && chunk. bytes == MSG
3307+ ) ;
3308+ let _ = chunks. finalize ( ) ;
3309+ assert_eq ! ( pair. client_conn_mut( client_ch) . lost_packets( ) , 0 ) ;
3310+ }
3311+
3312+ /// Test that a different address discovery configuration on 0rtt used by the server is rejected by
3313+ /// the client.
3314+ /// NOTE: the server MUST not change configuration on resumption. However, there is no designed
3315+ /// behaviour when this is encountered. Quinn chooses to accept and then close the connection,
3316+ /// which is what this test checks.
3317+ #[ test]
3318+ fn address_discovery_zero_rtt_rejection ( ) {
3319+ let _guard = subscribe ( ) ;
3320+ let server_cfg = ServerConfig {
3321+ transport : Arc :: new ( TransportConfig {
3322+ address_discovery_role : crate :: address_discovery:: Role :: Disabled ,
3323+ ..TransportConfig :: default ( )
3324+ } ) ,
3325+ ..server_config ( )
3326+ } ;
3327+ let alt_server_cfg = ServerConfig {
3328+ transport : Arc :: new ( TransportConfig {
3329+ address_discovery_role : crate :: address_discovery:: Role :: SendOnly ,
3330+ ..TransportConfig :: default ( )
3331+ } ) ,
3332+ ..server_cfg. clone ( )
3333+ } ;
3334+ let mut pair = Pair :: new ( Default :: default ( ) , server_cfg) ;
3335+ let client_cfg = ClientConfig {
3336+ transport : Arc :: new ( TransportConfig {
3337+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3338+ ..TransportConfig :: default ( )
3339+ } ) ,
3340+ ..client_config ( )
3341+ } ;
3342+
3343+ // Establish normal connection
3344+ let client_ch = pair. begin_connect ( client_cfg. clone ( ) ) ;
3345+ pair. drive ( ) ;
3346+ let server_ch = pair. server . assert_accept ( ) ;
3347+ let conn = pair. server_conn_mut ( server_ch) ;
3348+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3349+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3350+ assert_matches ! ( conn. poll( ) , None ) ;
3351+ pair. client
3352+ . connections
3353+ . get_mut ( & client_ch)
3354+ . unwrap ( )
3355+ . close ( pair. time , VarInt ( 0 ) , [ ] [ ..] . into ( ) ) ;
3356+ pair. drive ( ) ;
3357+ assert_matches ! (
3358+ pair. server_conn_mut( server_ch) . poll( ) ,
3359+ Some ( Event :: ConnectionLost { .. } )
3360+ ) ;
3361+ assert_matches ! ( pair. server_conn_mut( server_ch) . poll( ) , None ) ;
3362+ pair. client . connections . clear ( ) ;
3363+ pair. server . connections . clear ( ) ;
3364+
3365+ // Changing address discovery configurations makes the client close the connection
3366+ pair. server
3367+ . set_server_config ( Some ( Arc :: new ( alt_server_cfg) ) ) ;
3368+ info ! ( "resuming session" ) ;
3369+ let client_ch = pair. begin_connect ( client_cfg) ;
3370+ assert ! ( pair. client_conn_mut( client_ch) . has_0rtt( ) ) ;
3371+ let s = pair. client_streams ( client_ch) . open ( Dir :: Uni ) . unwrap ( ) ;
3372+ const MSG : & [ u8 ] = b"Hello, 0-RTT!" ;
3373+ pair. client_send ( client_ch, s) . write ( MSG ) . unwrap ( ) ;
3374+ pair. drive ( ) ;
3375+ let conn = pair. client_conn_mut ( server_ch) ;
3376+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3377+ assert_matches ! (
3378+ conn. poll( ) ,
3379+ Some ( Event :: ConnectionLost { reason } ) if matches!( reason, ConnectionError :: TransportError ( _) )
3380+ ) ;
3381+ }
3382+
3383+ #[ test]
3384+ fn address_discovery_retransmission ( ) {
3385+ let _guard = subscribe ( ) ;
3386+
3387+ let server = ServerConfig {
3388+ transport : Arc :: new ( TransportConfig {
3389+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3390+ ..TransportConfig :: default ( )
3391+ } ) ,
3392+ ..server_config ( )
3393+ } ;
3394+ let mut pair = Pair :: new ( Default :: default ( ) , server) ;
3395+ let client_config = ClientConfig {
3396+ transport : Arc :: new ( TransportConfig {
3397+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3398+ ..TransportConfig :: default ( )
3399+ } ) ,
3400+ ..client_config ( )
3401+ } ;
3402+ let client_ch = pair. begin_connect ( client_config) ;
3403+ pair. step ( ) ;
3404+
3405+ // lose the last packet
3406+ pair. client . inbound . pop_back ( ) . unwrap ( ) ;
3407+ pair. step ( ) ;
3408+ let conn = pair. client_conn_mut ( client_ch) ;
3409+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3410+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3411+ assert_matches ! ( conn. poll( ) , None ) ;
3412+
3413+ pair. drive ( ) ;
3414+ let conn = pair. client_conn_mut ( client_ch) ;
3415+ assert_matches ! ( conn. poll( ) ,
3416+ Some ( Event :: ObservedAddr ( addr) ) if addr == pair. client. addr) ;
3417+ }
3418+
3419+ #[ test]
3420+ fn address_discovery_rebind_retransmission ( ) {
3421+ let _guard = subscribe ( ) ;
3422+
3423+ let server = ServerConfig {
3424+ transport : Arc :: new ( TransportConfig {
3425+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3426+ ..TransportConfig :: default ( )
3427+ } ) ,
3428+ ..server_config ( )
3429+ } ;
3430+ let mut pair = Pair :: new ( Default :: default ( ) , server) ;
3431+ let client_config = ClientConfig {
3432+ transport : Arc :: new ( TransportConfig {
3433+ address_discovery_role : crate :: address_discovery:: Role :: Both ,
3434+ ..TransportConfig :: default ( )
3435+ } ) ,
3436+ ..client_config ( )
3437+ } ;
3438+ let client_ch = pair. begin_connect ( client_config) ;
3439+ pair. step ( ) ;
3440+
3441+ // lose the last packet
3442+ pair. client . inbound . pop_back ( ) . unwrap ( ) ;
3443+ pair. step ( ) ;
3444+ let conn = pair. client_conn_mut ( client_ch) ;
3445+ assert_matches ! ( conn. poll( ) , Some ( Event :: HandshakeDataReady ) ) ;
3446+ assert_matches ! ( conn. poll( ) , Some ( Event :: Connected ) ) ;
3447+ assert_matches ! ( conn. poll( ) , None ) ;
3448+
3449+ // simulate a rebind to ensure we will get an updated address instead of retransmitting
3450+ // outdated info
3451+ pair. client_conn_mut ( client_ch) . local_address_changed ( ) ;
3452+ pair. client
3453+ . addr
3454+ . set_port ( pair. client . addr . port ( ) . overflowing_add ( 1 ) . 0 ) ;
3455+
3456+ pair. drive ( ) ;
3457+ let conn = pair. client_conn_mut ( client_ch) ;
3458+ assert_matches ! ( conn. poll( ) ,
3459+ Some ( Event :: ObservedAddr ( addr) ) if addr == pair. client. addr) ;
3460+ }
3461+
31883462#[ test]
31893463fn reject_short_idcid ( ) {
31903464 let _guard = subscribe ( ) ;
0 commit comments