Skip to content

Commit 9490393

Browse files
committed
Add a test for socket connection races
Sadly this does not reproduce the issue fixed in the previous commit.
1 parent fca67bc commit 9490393

File tree

1 file changed

+62
-7
lines changed

1 file changed

+62
-7
lines changed

lightning-net-tokio/src/lib.rs

+62-7
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,22 @@ mod tests {
556556
}
557557
}
558558

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+
559575
async fn do_basic_connection_test() {
560576
let secp_ctx = Secp256k1::new();
561577
let a_key = SecretKey::from_slice(&[1; 32]).unwrap();
@@ -595,13 +611,7 @@ mod tests {
595611
// address. This may not always be the case in containers and the like, so if this test is
596612
// failing for you check that you have a loopback interface and it is configured with
597613
// 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();
605615

606616
let fut_a = super::setup_outbound(Arc::clone(&a_manager), b_pub, conn_a);
607617
let fut_b = super::setup_inbound(b_manager, conn_b);
@@ -629,8 +639,53 @@ mod tests {
629639
async fn basic_threaded_connection_test() {
630640
do_basic_connection_test().await;
631641
}
642+
632643
#[tokio::test]
633644
async fn basic_unthreaded_connection_test() {
634645
do_basic_connection_test().await;
635646
}
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 in by opening connections and shutting them
651+
// down 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();
685+
}
686+
687+
#[tokio::test]
688+
async fn unthreaded_race_disconnect_accept() {
689+
race_disconnect_accept();
690+
}
636691
}

0 commit comments

Comments
 (0)