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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns
This commit is contained in:
rustdesk
2026-09-18 16:21:02 +08:00
parent 0aacd3e91a
commit abf24d9190

View File

@@ -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();