Compare commits

...

3 Commits

Author SHA1 Message Date
rustdesk
ba65c30df1 connection: keep the non-video send timeout at its long-standing 120 s
Lowering `SEND_TIMEOUT_OTHER` to 30 s was a policy change on top of the
bug fix, argued from the 30 s read timeout, which measures something
else and cannot even run while a send is blocked. The constant goes
back to `SEND_TIMEOUT_VIDEO * 10`, where it has been since 2021, and
the raw port-forward loop's local write shares it again. What remains
is the fix alone: the type-specific timeout is chosen once the login
request has said what the connection is.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
2026-09-04 17:07:19 +08:00
rustdesk
ac0b226568 connection: keep the raw port-forward local write at 120 s
`SEND_TIMEOUT_OTHER` also bounded `forward.send` in
`try_port_forward_loop`, the write to the local target, whose own idle
timeout is an hour. Lowering it to 30 s made a target that stops
draining for half a minute drop the whole tunnel. That write gets its
own constant at the value it always had.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
2026-09-04 16:54:57 +08:00
rustdesk
0d8a52bc5a connection: apply the non-video send timeout once the type is known
`Connection::start` set the send timeout before the login request had
arrived, when `file_transfer`, `port_forward_socket` and `terminal` were
all still unset, so every connection got `SEND_TIMEOUT_VIDEO` (12 s) and
the `SEND_TIMEOUT_OTHER` branch never ran. A file transfer, terminal or
port forward whose peer stopped draining for 12 s — a Wi-Fi roam, a VPN
reconnect — was dropped.

The type-specific timeout is now set in `on_message` right after the
login request's union has been matched; `start` keeps the video figure
for the login phase.

`SEND_TIMEOUT_OTHER` also drops from 120 s to 30 s, the same horizon as
the 30 s read timeout: the timeout wraps a single `send`, so it only
fires when the peer makes no progress at all for that long, and beyond
30 s the read check would declare the same peer dead anyway. The raw
port-forward pipe's write to its local target shares the constant and
moves with it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
2026-09-04 09:56:47 +08:00

View File

@@ -585,13 +585,9 @@ impl Connection {
crate::rustdesk_interval(time::interval_at(Instant::now(), TEST_DELAY_TIMEOUT)); crate::rustdesk_interval(time::interval_at(Instant::now(), TEST_DELAY_TIMEOUT));
let mut last_recv_time = Instant::now(); let mut last_recv_time = Instant::now();
conn.stream.set_send_timeout( // The connection type is not known until the login request arrives;
if conn.file_transfer.is_some() || conn.port_forward_socket.is_some() || conn.terminal { // `on_message` picks the type-specific timeout then.
SEND_TIMEOUT_OTHER conn.stream.set_send_timeout(SEND_TIMEOUT_VIDEO);
} else {
SEND_TIMEOUT_VIDEO
},
);
#[cfg(not(any(target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "android", target_os = "ios")))]
std::thread::spawn(move || Self::handle_input(_rx_input, tx_cloned)); std::thread::spawn(move || Self::handle_input(_rx_input, tx_cloned));
@@ -2766,6 +2762,17 @@ impl Connection {
} }
} }
self.stream.set_send_timeout(
if self.file_transfer.is_some()
|| self.terminal
|| matches!(self.lr.union, Some(login_request::Union::PortForward(_)))
{
SEND_TIMEOUT_OTHER
} else {
SEND_TIMEOUT_VIDEO
},
);
if !crate::common::is_direct_ip_access(&lr.username) && lr.username != Config::get_id() if !crate::common::is_direct_ip_access(&lr.username) && lr.username != Config::get_id()
{ {
self.send_login_error(crate::client::LOGIN_MSG_OFFLINE) self.send_login_error(crate::client::LOGIN_MSG_OFFLINE)