mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-05 07:31:03 +03:00
port forward: a legacy window stays legacy until it is reopened
Review: the merged `Claimed | Legacy` arm gave a legacy window a hot transition to a tunnel — every accept re-negotiated, and a peer upgraded while the window stayed open was promoted underneath live connections. The product does not need a mode switch inside a window's lifetime, and the transition was extra state-machine surface for nothing: reopening the window picks up an upgraded peer. The two arms are separate again. `Claimed` negotiates once and the peer's answer fixes the window's mode. `Legacy` logs in for every accept as before, asks for no tunnel — `LoginConfigHandler::port_forward_mux` carries the request per login, so the raw pipe never has to talk to a peer that thinks it agreed to multiplex — and ignores what the peer reports. Both arms keep skipping a local socket that hung up during login. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
This commit is contained in:
@@ -1753,10 +1753,9 @@ pub struct LoginConfigHandler {
|
||||
pub remember: bool,
|
||||
config: PeerConfig,
|
||||
pub port_forward: (String, i32),
|
||||
/// Held by a port-forward mapping from filling `port_forward` and `hash`
|
||||
/// until its login is built from them; a window's mappings log in
|
||||
/// concurrently.
|
||||
pub(crate) port_forward_login_turn: Arc<hbb_common::tokio::sync::Mutex<()>>,
|
||||
/// Whether the next port-forward login asks for the multiplexed tunnel.
|
||||
/// `port_forward::listen` sets it per accept.
|
||||
pub port_forward_mux: bool,
|
||||
pub version: i64,
|
||||
features: Option<Features>,
|
||||
pub session_id: u64, // used for local <-> server communication
|
||||
@@ -2769,7 +2768,7 @@ impl LoginConfigHandler {
|
||||
ConnType::PORT_FORWARD | ConnType::RDP => lr.set_port_forward(PortForward {
|
||||
host: self.port_forward.0.clone(),
|
||||
port: self.port_forward.1,
|
||||
multiplex: crate::common::get_port_forward_mux_enabled(),
|
||||
multiplex: self.port_forward_mux,
|
||||
..Default::default()
|
||||
}),
|
||||
ConnType::TERMINAL => {
|
||||
|
||||
@@ -125,11 +125,14 @@ pub async fn listen(
|
||||
log::debug!("cannot open channel for {:?}: {}", peer_addr, e);
|
||||
}
|
||||
}
|
||||
// A `Legacy` window logs in for every accept, as it always did,
|
||||
// and publishes the outcome the same way the claiming accept
|
||||
// does: a peer upgraded since the window opened becomes a tunnel.
|
||||
Claim::Claimed | Claim::Legacy => {
|
||||
lc.write().unwrap().port_forward = (remote_host.clone(), remote_port);
|
||||
// The claiming accept negotiates: it asks for the tunnel, and
|
||||
// the peer's answer fixes the window's mode until it closes.
|
||||
Claim::Claimed => {
|
||||
{
|
||||
let mut lc = lc.write().unwrap();
|
||||
lc.port_forward = (remote_host.clone(), remote_port);
|
||||
lc.port_forward_mux = crate::common::get_port_forward_mux_enabled();
|
||||
}
|
||||
let mut forward = Framed::new(forward, BytesCodec::new());
|
||||
let mut close_port_forward = false;
|
||||
match connect_and_login(&id, &password, &mut ui_receiver, interface.clone(), &mut forward, key, token, is_rdp, &mut close_port_forward).await {
|
||||
@@ -161,6 +164,29 @@ pub async fn listen(
|
||||
_ => tunnel.set_failed(),
|
||||
}
|
||||
}
|
||||
// A `Legacy` window stays legacy until it closes: every accept
|
||||
// logs in on its own, asks for no tunnel, and takes the raw pipe
|
||||
// whatever the peer reports. Reopening the window is how a user
|
||||
// picks up an upgraded peer; nothing switches modes underneath
|
||||
// live connections.
|
||||
Claim::Legacy => {
|
||||
{
|
||||
let mut lc = lc.write().unwrap();
|
||||
lc.port_forward = (remote_host.clone(), remote_port);
|
||||
lc.port_forward_mux = false;
|
||||
}
|
||||
let mut forward = Framed::new(forward, BytesCodec::new());
|
||||
let mut close_port_forward = false;
|
||||
match connect_and_login(&id, &password, &mut ui_receiver, interface.clone(), &mut forward, key, token, is_rdp, &mut close_port_forward).await {
|
||||
Ok(Some(outcome)) if outcome.local_eof => {
|
||||
log::debug!("legacy peer and local {:?} already gone", peer_addr);
|
||||
}
|
||||
Ok(Some(outcome)) => run_legacy(outcome, forward, peer_addr, interface.clone()),
|
||||
_ if close_port_forward => break,
|
||||
Err(err) => interface.on_establish_connection_error(err.to_string()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// Resolved above; a stray `Wait` just drops this accept.
|
||||
Claim::Wait => continue,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user