From abf24d91902519e02876d4c165ddfd7543d97a08 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 18 Sep 2026 16:21:02 +0800 Subject: [PATCH] controller: a second at most for the UDP target's lookup `new_direct_udp_for` resolves the rendezvous server before `_start_inner` opens the connection to it, and that lookup is the first on the path and the one not under CONNECT_TIMEOUT: a resolver that hangs holds the connection here for its whole retry schedule, half a minute on a glibc default, before `connect_tcp` even starts and fails on its own. A second bounds it. What a lookup slower than that loses is the UDP NAT test for this connection; the TCP punch and the relay carry it, as they do wherever the test finds no port. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns --- src/client.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client.rs b/src/client.rs index 3c8837bf2..0c7466cc2 100644 --- a/src/client.rs +++ b/src/client.rs @@ -490,7 +490,12 @@ impl Client { // no need to care about multiple rendezvous servers case, since it is acutally not used any more. // Shared state for UDP NAT test result if crate::get_udp_punch_enabled() && !interface.is_force_relay() { - if let Ok((socket, addr)) = new_direct_udp_for(&rendezvous_server).await { + // The first lookup on the connection path, and the one not under CONNECT_TIMEOUT: a + // resolver that hangs would hold the connection here for its whole retry schedule. + // Without the NAT test the TCP punch and the relay carry it, so a second is enough. + if let Ok(Ok((socket, addr))) = + timeout(1000, new_direct_udp_for(&rendezvous_server)).await + { let udp_port = Arc::new(Mutex::new(0)); let up_cloned = udp_port.clone(); let socket_cloned = socket.clone();