@@ -3216,4 +3216,75 @@ mod tests {
32163216
32173217 Ok ( ( ) )
32183218 }
3219+
3220+ /// Test that we can immediately reconnect after respawning an endpoint with the same node id.
3221+ #[ tokio:: test]
3222+ #[ traced_test]
3223+ async fn can_abort_and_reconnect ( ) -> Result {
3224+ const TEST_ALPN : & [ u8 ] = b"/iroh/test/1" ;
3225+ const TIMEOUT : Duration = Duration :: from_secs ( 5 ) ;
3226+
3227+ let mut rng = & mut rand_chacha:: ChaCha12Rng :: seed_from_u64 ( 1 ) ;
3228+
3229+ // Spawn a server endpoint.
3230+ let server = Endpoint :: builder ( )
3231+ . secret_key ( SecretKey :: generate ( & mut rng) )
3232+ . relay_mode ( RelayMode :: Disabled )
3233+ . alpns ( vec ! [ TEST_ALPN . to_vec( ) ] )
3234+ . bind ( )
3235+ . await ?;
3236+ let server_addr = server. node_addr ( ) . initialized ( ) . await . e ( ) ?;
3237+
3238+ // The server accepts all connections, waits for them being closed, and sends the
3239+ // close code over a channel.
3240+ let ( tx, mut rx) = tokio:: sync:: mpsc:: channel ( 1 ) ;
3241+ let server_loop = tokio:: task:: spawn ( async move {
3242+ while let Some ( conn) = server. accept ( ) . await {
3243+ let conn = conn. accept ( ) . e ( ) ?. await . e ( ) ?;
3244+ let res = match conn. closed ( ) . await {
3245+ ConnectionError :: ApplicationClosed ( frame) => Ok ( u64:: from ( frame. error_code ) ) ,
3246+ reason @ _ => Err ( reason) ,
3247+ } ;
3248+ tx. send ( res) . await . e ( ) ?;
3249+ }
3250+ Result :: < _ , n0_snafu:: Error > :: Ok ( ( ) )
3251+ } ) ;
3252+
3253+ // Clients connect to the server, and immediately close the connection with a code
3254+ // and then close the endpoint.
3255+ async fn connect ( secret_key : SecretKey , addr : NodeAddr , code : u32 ) -> Result < ( ) > {
3256+ let ep = Endpoint :: builder ( )
3257+ . secret_key ( secret_key)
3258+ . relay_mode ( RelayMode :: Disabled )
3259+ . bind ( )
3260+ . await ?;
3261+ let conn = ep. connect ( addr, TEST_ALPN ) . await ?;
3262+ conn. close ( code. into ( ) , b"bye" ) ;
3263+ ep. close ( ) . await ;
3264+ Ok ( ( ) )
3265+ }
3266+
3267+ let client_secret_key = SecretKey :: generate ( & mut rng) ;
3268+
3269+ // First connection
3270+ n0_future:: time:: timeout (
3271+ TIMEOUT ,
3272+ connect ( client_secret_key. clone ( ) , server_addr. clone ( ) , 23 ) ,
3273+ )
3274+ . await
3275+ . e ( ) ??;
3276+ assert_eq ! ( rx. recv( ) . await . unwrap( ) . unwrap( ) , 23 ) ;
3277+
3278+ // Second connection
3279+ n0_future:: time:: timeout (
3280+ TIMEOUT ,
3281+ connect ( client_secret_key. clone ( ) , server_addr. clone ( ) , 24 ) ,
3282+ )
3283+ . await
3284+ . e ( ) ??;
3285+ assert_eq ! ( rx. recv( ) . await . unwrap( ) . unwrap( ) , 24 ) ;
3286+ server_loop. abort ( ) ;
3287+
3288+ Ok ( ( ) )
3289+ }
32193290}
0 commit comments