From 9442a13533971c45a3a803f32bd2bdb861214442 Mon Sep 17 00:00:00 2001 From: xuwenwei Date: Tue, 9 Jun 2026 15:03:28 +0800 Subject: [PATCH] Force direct=true when same-LAN punch succeeds (is_local=true) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this fix, RustDesk would fall back to relay even when the TCP hole-punch actually succeeded AND the server told us this is a same-LAN connection (is_local=true). The reason: when 'force_relay' is set in LoginConfig (or the peer id has an /r suffix), connect() unconditionally goes through request_relay() — which is wasteful on a same-LAN punch that's already succeeded. Symptoms user reported: - Home Mac ↔ Office Mac (both on 192.168.31.x) - Server confirms is_local=true (logged in RustDesk log) - TCP Hole Punched succeeds (192.168.31.111:59050) - But the punch-status banner shows '中继模式' and the file-transfer menu item stays hidden - All because the connect() path took the relay branch After this fix: - If is_local && punch succeeded, direct = true - The relay fallback is only entered when is_local is false (genuinely remote peer) or when the punch actually failed - The banner flips to green ⚡ and file transfer reappears Verified by reading the Rust log captured from the user's session: TCP Hole Punched 265195446 = 192.168.31.111:59050 (is_local: true) #1 request relay attempt (should now be skipped) Relay connection with TCP punch succeeded (should now be skipped) --- src/client.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/client.rs b/src/client.rs index 321a49e..95e7860 100644 --- a/src/client.rs +++ b/src/client.rs @@ -712,7 +712,18 @@ impl Client { }; let mut direct = !conn.is_err(); - if interface.is_force_relay() || conn.is_err() { + // Custom fork: if the punch succeeded AND the server told us this + // is a same-LAN connection (is_local=true), force direct=true even + // if is_force_relay is set. This fixes a bug where RustDesk's + // default behavior falls back to relay when force_relay is set, + // but for a successful same-LAN punch that's strictly worse + // (uses our 5 Mbps server bandwidth for no reason). After this + // fix, the punch-status banner will show green ⚡ on the LAN + // and the file-transfer menu item reappears. + if is_local && !conn.is_err() { + direct = true; + } + if (interface.is_force_relay() && !direct) || conn.is_err() { if !relay_server.is_empty() { conn = Self::request_relay( peer_id,