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