webrtc: close without an await point; do not report an unknown path as direct

- close_webrtc is no longer async (hbb_common 88f965f), so the ten call
  sites in port_forward and io_loop - all inside select! arms or futures
  the UI can abandon - can no longer be cancelled mid-teardown, which
  left the pc unclosable and its session entry stranded. Client's own
  spawn_close_webrtc went with it: the runtime-teardown guard it existed
  for now lives in close_detached, so both Drop paths share one
  implementation.

- webrtc_relayed() returns None when no candidate pair is selected or
  the pc closed under a concurrent teardown, and both call sites read
  that as "not relayed", i.e. direct. A TURN-relayed session could
  therefore be shown to the user as peer-to-peer. Claiming a direct path
  needs evidence of one, so an unknown answer now counts as relayed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ExUfAkYbq8UC9pQCiLy8TQ
This commit is contained in:
rustdesk
2026-08-08 13:10:22 +08:00
parent 51c496498e
commit 101d9802ff
4 changed files with 20 additions and 44 deletions

View File

@@ -157,7 +157,7 @@ async fn connect_and_login(
*close_port_forward = true;
// Close the WebRTC pc on this decline path too (no-op for TCP/WS), matching every
// other exit in this function; a bare drop leaks it in the global session cache.
stream.close_webrtc().await;
stream.close_webrtc();
return Ok(None);
}
}
@@ -170,7 +170,7 @@ async fn connect_and_login(
tokio::select! {
res = timeout(READ_TIMEOUT, stream.next()) => match res {
Err(_) => {
stream.close_webrtc().await;
stream.close_webrtc();
bail!("Timeout");
}
Ok(Some(Ok(bytes))) => {
@@ -181,7 +181,7 @@ async fn connect_and_login(
let msg_in = match Message::parse_from_bytes(&bytes) {
Ok(msg) => msg,
Err(err) => {
stream.close_webrtc().await;
stream.close_webrtc();
return Err(err.into());
}
};
@@ -194,7 +194,7 @@ async fn connect_and_login(
Some(message::Union::LoginResponse(lr)) => match lr.union {
Some(login_response::Union::Error(err)) => {
if !interface.handle_login_error(&err) {
stream.close_webrtc().await;
stream.close_webrtc();
return Ok(None);
}
}
@@ -211,11 +211,11 @@ async fn connect_and_login(
}
}
Ok(Some(Err(err))) => {
stream.close_webrtc().await;
stream.close_webrtc();
bail!("Connection closed: {}", err);
}
_ => {
stream.close_webrtc().await;
stream.close_webrtc();
bail!("Reset by the peer");
}
},
@@ -234,7 +234,7 @@ async fn connect_and_login(
if let Some(Ok(bytes)) = res {
buffer.extend(bytes);
} else {
stream.close_webrtc().await;
stream.close_webrtc();
return Ok(None);
}
},
@@ -269,6 +269,6 @@ async fn run_forward(forward: Framed<TcpStream, BytesCodec>, stream: Stream) ->
},
}
}
stream.close_webrtc().await;
stream.close_webrtc();
Ok(())
}