From 54feb3bc5a35aa49ab15edd512059ad61f14e693 Mon Sep 17 00:00:00 2001 From: Michel de Graaf Date: Fri, 24 Jul 2026 22:21:06 +0200 Subject: [PATCH] fix(peer): log disconnect cause; bind e2e browse listener on all interfaces The brokered third-party browse e2e failed deterministically on CI. The test bound its listener to 127.0.0.1 only, but the server brokers back the address it observed for that client - the host's routable IP (172.17.0.2 under Docker, 10.x on a CI runner). The sharer's dial was refused, it fell back to re-brokering, and the accept never arrived. The sibling third-party browse tests already bind 0.0.0.0. disconnect_with_error logged only "disconnect" and dropped the io::Error on the floor, which is what made this invisible in the logs; it now logs the cause. --- soulseek-rs-lib/src/actor/peer_actor.rs | 5 ++++- soulseek-rs-lib/tests/e2e.rs | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/soulseek-rs-lib/src/actor/peer_actor.rs b/soulseek-rs-lib/src/actor/peer_actor.rs index 8b05a7a..7bf6f83 100644 --- a/soulseek-rs-lib/src/actor/peer_actor.rs +++ b/soulseek-rs-lib/src/actor/peer_actor.rs @@ -609,7 +609,10 @@ impl PeerActor { fn disconnect_with_error(&mut self, error: Error) { let username = self.peer_username(); - debug!("[peer:{}] disconnect", username); + // Include the cause: a failed outbound dial reports nothing else, so + // without it an unreachable peer is indistinguishable from a clean + // disconnect in the logs. + debug!("[peer:{}] disconnect: {}", username, error); self.stream.take(); diff --git a/soulseek-rs-lib/tests/e2e.rs b/soulseek-rs-lib/tests/e2e.rs index ef268b8..1891c56 100644 --- a/soulseek-rs-lib/tests/e2e.rs +++ b/soulseek-rs-lib/tests/e2e.rs @@ -1528,8 +1528,13 @@ fn a_third_party_client_browses_our_shares_via_the_server_broker() { // The third-party client listens and advertises its port, then asks the // server to broker a P connection from the sharer. + // + // Bind every interface, not just loopback: the server brokers back the + // address it observed for this client, which is the host's routable IP + // (172.17.0.2 under Docker, 10.x on a CI runner), not 127.0.0.1. A + // loopback-only listener refuses that dial and the browse never arrives. let listener = - std::net::TcpListener::bind("127.0.0.1:0").expect("browser listener"); + std::net::TcpListener::bind("0.0.0.0:0").expect("browser listener"); let browser_port = listener.local_addr().unwrap().port(); let server_addr = format!("{}:{}", server.host, server.port); let mut srv = login_raw(&server_addr, "e2e_qt_brok_browser", "pw")