mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-20 03:11:02 +03:00
port forward: apply the whole-branch review
Correctness:
- listen(): the Legacy arm is merged with the Claimed arm. On its own it
ignored outcome.local_eof, so a client that hung up during login still
got a target connect, an audit record and a CM row on the controlled
side, and ignored outcome.mux, so a peer upgraded while a legacy window
stayed open answered as a tunnel while the controller went raw.
- Refusal dialogs are deduplicated per quiet spell (10 s) rather than per
tunnel lifetime; the lifetime set went silent for the rest of a
long-lived window after the first burst.
- Android's CM listener handles UpdatePortForward; it fell into `_ => {}`.
- relay_socket_to_tunnel reads into one scratch buffer per channel and
sends an exact-size copy. A frame owning its 64 KiB read allocation
pinned it until sent, once per byte on interactive traffic.
Consistency and cleanups:
- The controlled side's refusal text is the raw pipe's wording, RDP
substitution included.
- connection.rs: the PortForwardChannel arm is a one-line hook, the CM
label is pushed from the 1 s tick alone, and the unreachable inner.tx
fall-through is gone.
- The Ready enum is removed; wait_ready() returns Option<Claim>.
- SendCredit::add wakes with notify_one alone.
- on_ui_command() replaces the two ui_receiver handlers in listen().
- TunnelHandle is no longer re-exported (unused-import warning).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
This commit is contained in:
@@ -97,24 +97,15 @@ pub async fn listen(
|
||||
// never shadow it.
|
||||
Ok((forward, peer_addr)) = listener.accept() => {
|
||||
log::debug!("new connection from {:?}", peer_addr);
|
||||
let claim = tunnel.try_claim();
|
||||
let claim = match claim {
|
||||
let claim = match tunnel.try_claim() {
|
||||
Claim::Wait => {
|
||||
// Keep servicing the UI while the establishing accept holds the
|
||||
// prompt. `None` means establishment failed: this accept is dropped.
|
||||
let resolved: Option<Claim> = loop {
|
||||
let resolved = loop {
|
||||
tokio::select! {
|
||||
// `tokio::select!` brings its own `Poll::{Ready, Pending}` into
|
||||
// scope, so `Ready` must be qualified here or it resolves to that.
|
||||
r = tunnel.wait_ready() => break match r {
|
||||
crate::port_forward_mux::Ready::Muxed(h) => Some(Claim::Muxed(h)),
|
||||
crate::port_forward_mux::Ready::Legacy => Some(Claim::Legacy),
|
||||
crate::port_forward_mux::Ready::Failed => None,
|
||||
},
|
||||
d = ui_receiver.recv() => match d {
|
||||
Some(Data::Close) => return Ok(()),
|
||||
Some(Data::NewRDP) => run_rdp(addr.port(), &rdp_display_name(&lc, &id)),
|
||||
_ => {}
|
||||
r = tunnel.wait_ready() => break r,
|
||||
d = ui_receiver.recv() => if on_ui_command(d, addr.port(), &lc, &id) {
|
||||
return Ok(());
|
||||
},
|
||||
}
|
||||
};
|
||||
@@ -134,18 +125,10 @@ pub async fn listen(
|
||||
log::debug!("cannot open channel for {:?}: {}", peer_addr, e);
|
||||
}
|
||||
}
|
||||
Claim::Legacy => {
|
||||
lc.write().unwrap().port_forward = (remote_host.clone(), remote_port);
|
||||
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)) => run_legacy(outcome, forward, peer_addr, interface.clone()),
|
||||
_ if close_port_forward => break,
|
||||
Err(err) => interface.on_establish_connection_error(err.to_string()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Claim::Claimed => {
|
||||
// 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);
|
||||
let mut forward = Framed::new(forward, BytesCodec::new());
|
||||
let mut close_port_forward = false;
|
||||
@@ -182,23 +165,27 @@ pub async fn listen(
|
||||
Claim::Wait => continue,
|
||||
}
|
||||
}
|
||||
d = ui_receiver.recv() => {
|
||||
match d {
|
||||
Some(Data::Close) => {
|
||||
break;
|
||||
}
|
||||
Some(Data::NewRDP) => {
|
||||
println!("receive run_rdp from ui_receiver");
|
||||
run_rdp(addr.port(), &rdp_display_name(&lc, &id));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
d = ui_receiver.recv() => if on_ui_command(d, addr.port(), &lc, &id) {
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Commands the window sends its listener. `true` means stop listening: the
|
||||
/// window is closing, or its sender is gone.
|
||||
fn on_ui_command(d: Option<Data>, port: u16, lc: &Arc<RwLock<LoginConfigHandler>>, id: &str) -> bool {
|
||||
match d {
|
||||
Some(Data::Close) | None => true,
|
||||
Some(Data::NewRDP) => {
|
||||
run_rdp(port, &rdp_display_name(lc, id));
|
||||
false
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Today's raw pipe, for peers without multiplexing.
|
||||
fn run_legacy(
|
||||
outcome: LoginOutcome,
|
||||
|
||||
Reference in New Issue
Block a user