mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-11 15:01:02 +03:00
fix: deliver the displacement to an authorized port forward
An authorized port forward leaves the main select loop as soon as its tunnel is up (`port_forward_socket.is_some()` right after the logon response) and spends the rest of its life in `try_port_forward_loop`, which only received `rx_from_cm`. So the `Displaced` its replacement sent over `tx_from_authed` was queued and never read, and the stale tunnel kept running - while the test below asserts a port forward displaces its own kind. Registration happens inside the logon response, before that break, so the connection is in `AUTHED_CONNS` and does get selected; only the delivery was missing. Every other kind stays in the main loop and was unaffected, the mux port forward included: the break tests `port_forward_socket`, which a mux tunnel does not set. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns
This commit is contained in:
@@ -1109,7 +1109,10 @@ impl Connection {
|
||||
if conn.authorized {
|
||||
password::update_temporary_password();
|
||||
}
|
||||
if let Err(err) = conn.try_port_forward_loop(&mut rx_from_cm).await {
|
||||
if let Err(err) = conn
|
||||
.try_port_forward_loop(&mut rx_from_cm, &mut rx_from_authed)
|
||||
.await
|
||||
{
|
||||
conn.on_close(&err.to_string(), false).await;
|
||||
raii::AuthedConnID::check_remove_session(conn.inner.id(), conn.session_key());
|
||||
}
|
||||
@@ -1215,6 +1218,7 @@ impl Connection {
|
||||
async fn try_port_forward_loop(
|
||||
&mut self,
|
||||
rx_from_cm: &mut mpsc::UnboundedReceiver<Data>,
|
||||
rx_from_authed: &mut mpsc::UnboundedReceiver<Data>,
|
||||
) -> ResultType<()> {
|
||||
let mut last_recv_time = Instant::now();
|
||||
if let Some(mut forward) = self.port_forward_socket.take() {
|
||||
@@ -1242,6 +1246,14 @@ impl Connection {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// An authorized port forward leaves the main select loop the moment its
|
||||
// tunnel is up, so this is where it spends the rest of its life and the only
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
res = forward.next() => {
|
||||
if let Some(res) = res {
|
||||
last_recv_time = Instant::now();
|
||||
|
||||
Reference in New Issue
Block a user