fix: a displaced port forward must not remove the session

Bailing hands the caller an error, and its error branch calls
`check_remove_session`. For a port forward that resolves to a removal: the
check keeps a session only when another *remote* connection shares its key, so
a session made of tunnels alone - the ordinary port forward case - loses its
`SESSIONS` entry while the connection that displaced this one is still live.
The next connection in that session then re-prompts, having lost the recent
session it should have been able to authenticate against.

Close and return instead, which is what every other kind's displacement
already does: the final `on_close("End", true)` sees `closed` and returns, so
nothing else changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns
This commit is contained in:
rustdesk
2026-09-09 09:55:02 +08:00
parent 0312eb9cb5
commit 2c5697129e

View File

@@ -1251,7 +1251,11 @@ impl Connection {
// place a displacement can still reach it.
Some(data) = rx_from_authed.recv() => {
if let ipc::Data::Displaced = data {
bail!("displaced by a newer connection");
// Closed here rather than bailed: the caller answers an error by
// removing the session, and this session is precisely what carries
// on - on the connection that took this one's place.
self.on_close("displaced by a newer connection", false).await;
return Ok(());
}
}
res = forward.next() => {