@@ -556,6 +556,22 @@ mod tests {
556
556
}
557
557
}
558
558
559
+ fn make_tcp_connection ( ) -> ( std:: net:: TcpStream , std:: net:: TcpStream ) {
560
+ if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:9735" ) {
561
+ ( std:: net:: TcpStream :: connect ( "127.0.0.1:9735" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
562
+ } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:19735" ) {
563
+ ( std:: net:: TcpStream :: connect ( "127.0.0.1:19735" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
564
+ } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:9997" ) {
565
+ ( std:: net:: TcpStream :: connect ( "127.0.0.1:9997" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
566
+ } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:9998" ) {
567
+ ( std:: net:: TcpStream :: connect ( "127.0.0.1:9998" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
568
+ } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:9999" ) {
569
+ ( std:: net:: TcpStream :: connect ( "127.0.0.1:9999" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
570
+ } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:46926" ) {
571
+ ( std:: net:: TcpStream :: connect ( "127.0.0.1:46926" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
572
+ } else { panic ! ( "Failed to bind to v4 localhost on common ports" ) ; }
573
+ }
574
+
559
575
async fn do_basic_connection_test ( ) {
560
576
let secp_ctx = Secp256k1 :: new ( ) ;
561
577
let a_key = SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ;
@@ -595,13 +611,7 @@ mod tests {
595
611
// address. This may not always be the case in containers and the like, so if this test is
596
612
// failing for you check that you have a loopback interface and it is configured with
597
613
// 127.0.0.1.
598
- let ( conn_a, conn_b) = if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:9735" ) {
599
- ( std:: net:: TcpStream :: connect ( "127.0.0.1:9735" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
600
- } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:9999" ) {
601
- ( std:: net:: TcpStream :: connect ( "127.0.0.1:9999" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
602
- } else if let Ok ( listener) = std:: net:: TcpListener :: bind ( "127.0.0.1:46926" ) {
603
- ( std:: net:: TcpStream :: connect ( "127.0.0.1:46926" ) . unwrap ( ) , listener. accept ( ) . unwrap ( ) . 0 )
604
- } else { panic ! ( "Failed to bind to v4 localhost on common ports" ) ; } ;
614
+ let ( conn_a, conn_b) = make_tcp_connection ( ) ;
605
615
606
616
let fut_a = super :: setup_outbound ( Arc :: clone ( & a_manager) , b_pub, conn_a) ;
607
617
let fut_b = super :: setup_inbound ( b_manager, conn_b) ;
@@ -629,8 +639,53 @@ mod tests {
629
639
async fn basic_threaded_connection_test ( ) {
630
640
do_basic_connection_test ( ) . await ;
631
641
}
642
+
632
643
#[ tokio:: test]
633
644
async fn basic_unthreaded_connection_test ( ) {
634
645
do_basic_connection_test ( ) . await ;
635
646
}
647
+
648
+ async fn race_disconnect_accept ( ) {
649
+ // Previously, if we handed an already-disconnected socket to `setup_inbound` we'd panic.
650
+ // This attempts to find other similar races by opening connections and shutting them down
651
+ // while connecting. Sadly in testing this did *not* reproduce the previous issue.
652
+ let secp_ctx = Secp256k1 :: new ( ) ;
653
+ let a_key = SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ;
654
+ let b_key = SecretKey :: from_slice ( & [ 2 ; 32 ] ) . unwrap ( ) ;
655
+ let b_pub = PublicKey :: from_secret_key ( & secp_ctx, & b_key) ;
656
+
657
+ let a_manager = Arc :: new ( PeerManager :: new ( MessageHandler {
658
+ chan_handler : Arc :: new ( lightning:: ln:: peer_handler:: ErroringMessageHandler :: new ( ) ) ,
659
+ route_handler : Arc :: new ( lightning:: ln:: peer_handler:: IgnoringMessageHandler { } ) ,
660
+ } , a_key, & [ 1 ; 32 ] , Arc :: new ( TestLogger ( ) ) , Arc :: new ( lightning:: ln:: peer_handler:: IgnoringMessageHandler { } ) ) ) ;
661
+
662
+ // Make two connections, one for an inbound and one for an outbound connection
663
+ let conn_a = {
664
+ let ( conn_a, _) = make_tcp_connection ( ) ;
665
+ conn_a
666
+ } ;
667
+ let conn_b = {
668
+ let ( _, conn_b) = make_tcp_connection ( ) ;
669
+ conn_b
670
+ } ;
671
+
672
+ // Call connection setup inside new tokio tasks.
673
+ let manager_reference = Arc :: clone ( & a_manager) ;
674
+ tokio:: spawn ( async move {
675
+ super :: setup_inbound ( manager_reference, conn_a) . await
676
+ } ) ;
677
+ tokio:: spawn ( async move {
678
+ super :: setup_outbound ( a_manager, b_pub, conn_b) . await
679
+ } ) ;
680
+ }
681
+
682
+ #[ tokio:: test( flavor = "multi_thread" ) ]
683
+ async fn threaded_race_disconnect_accept ( ) {
684
+ race_disconnect_accept ( ) . await ;
685
+ }
686
+
687
+ #[ tokio:: test]
688
+ async fn unthreaded_race_disconnect_accept ( ) {
689
+ race_disconnect_accept ( ) . await ;
690
+ }
636
691
}
0 commit comments