From f688d4116cf3e0b919fcea132afbfa84f8a983b7 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Fri, 18 Sep 2026 15:40:50 +0800 Subject: [PATCH] socket_client: resolve the UDP target, do not shake hands with it `test_target` opened a TCP connection to the rendezvous server to learn which address the kernel would use, then dropped it: a full handshake, one round trip, on every connection the controller starts, before the one `_start_inner` opens to the same host a moment later - and a second's wait first wherever an IPv6 route led to nothing, before it fell back to the resolver anyway. The handshake stood in for a choice that had been made by hand: before 2022's NAT64 fix the code preferred an A record outright, which a v6-only host cannot reach, and asking the server itself was the way to let the OS decide. The resolver decides the same way. getaddrinfo orders what it returns as RFC 6724 says, looking up a route and a source address for each candidate as it goes, so the synthesized IPv6 comes first on a v6-only host and IPv6 on a dual-stack one, the order the handshake would have tried them in. Its first answer is the address, and the fallback branch is all that is left. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns --- src/socket_client.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/socket_client.rs b/src/socket_client.rs index 9178b74b5..2cb92cc52 100644 --- a/src/socket_client.rs +++ b/src/socket_client.rs @@ -203,12 +203,10 @@ pub fn ipv4_to_ipv6(addr: String, ipv4: bool) -> String { addr } +/// The address of `target` this machine sends to: the resolver's first, ordered as RFC 6724 has +/// it with a route looked up for each, so NAT64's synthesized IPv6 comes first on a v6-only host. +/// A handshake used to ask the server the same, a round trip a connection and 1 s past a dead v6. async fn test_target(target: &str) -> ResultType { - if let Ok(Ok(s)) = super::timeout(1000, tokio::net::TcpStream::connect(target)).await { - if let Ok(addr) = s.peer_addr() { - return Ok(addr); - } - } tokio::net::lookup_host(target) .await? .next()