mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-07 13:01:11 +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,
|
pub remember: bool,
|
||||||
config: PeerConfig,
|
config: PeerConfig,
|
||||||
pub port_forward: (String, i32),
|
pub port_forward: (String, i32),
|
||||||
/// Held by a port-forward mapping from filling `port_forward` and `hash`
|
/// Whether the next port-forward login asks for the multiplexed tunnel.
|
||||||
/// until its login is built from them; a window's mappings log in
|
/// `port_forward::listen` sets it per accept.
|
||||||
/// concurrently.
|
pub port_forward_mux: bool,
|
||||||
pub(crate) port_forward_login_turn: Arc<hbb_common::tokio::sync::Mutex<()>>,
|
|
||||||
pub version: i64,
|
pub version: i64,
|
||||||
features: Option<Features>,
|
features: Option<Features>,
|
||||||
pub session_id: u64, // used for local <-> server communication
|
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 {
|
ConnType::PORT_FORWARD | ConnType::RDP => lr.set_port_forward(PortForward {
|
||||||
host: self.port_forward.0.clone(),
|
host: self.port_forward.0.clone(),
|
||||||
port: self.port_forward.1,
|
port: self.port_forward.1,
|
||||||
multiplex: crate::common::get_port_forward_mux_enabled(),
|
multiplex: self.port_forward_mux,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
ConnType::TERMINAL => {
|
ConnType::TERMINAL => {
|
||||||
|
|||||||
@@ -125,11 +125,14 @@ pub async fn listen(
|
|||||||
log::debug!("cannot open channel for {:?}: {}", peer_addr, e);
|
log::debug!("cannot open channel for {:?}: {}", peer_addr, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// A `Legacy` window logs in for every accept, as it always did,
|
// The claiming accept negotiates: it asks for the tunnel, and
|
||||||
// and publishes the outcome the same way the claiming accept
|
// the peer's answer fixes the window's mode until it closes.
|
||||||
// does: a peer upgraded since the window opened becomes a tunnel.
|
Claim::Claimed => {
|
||||||
Claim::Claimed | Claim::Legacy => {
|
{
|
||||||
lc.write().unwrap().port_forward = (remote_host.clone(), remote_port);
|
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 forward = Framed::new(forward, BytesCodec::new());
|
||||||
let mut close_port_forward = false;
|
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 {
|
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(),
|
_ => 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.
|
// Resolved above; a stray `Wait` just drops this accept.
|
||||||
Claim::Wait => continue,
|
Claim::Wait => continue,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user