@@ -3216,4 +3216,75 @@ mod tests {
3216
3216
3217
3217
Ok ( ( ) )
3218
3218
}
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 ( 1 ) ;
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
+ }
3219
3290
}
0 commit comments