bump hbb_common: end the ICE forwarder at gathering complete, drop the closes Drop covers

hbb_common now closes the local-candidate channel when gathering
completes, so the controlled side's forwarder in spawn_webrtc_answerer
ends there, and its signaling connection to hbbs with it, instead of
sitting on a socket hbbs closed at 90s idle for the rest of the session.
It also keeps the reassembly buffer across fragmented frames.

Stream closes the WebRTC peer connection on drop (hbb_common b0b624d),
so the close_webrtc() calls in port_forward and io_loop that sat
immediately before a return or the end of scope did nothing Drop was
not about to do, while the comments beside them still said a bare drop
leaked the pc. Remove both.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns
This commit is contained in:
rustdesk
2026-09-03 19:02:45 +08:00
parent e677fd510a
commit a02063ece8
3 changed files with 1 additions and 24 deletions

View File

@@ -204,11 +204,6 @@ impl<T: InvokeUiSession> Remote<T> {
tokio::time::sleep(KCP_CLOSE_REASON_FLUSH_DELAY).await;
}
self.handle_disconnected(round);
// Close the WebRTC pc on this decline path too (no-op for TCP/WS); otherwise its
// pc lingers in the global session cache until ICE decays on its own. The pc
// and its teardown live on hbb_common's WebRTC I/O runtime, so this session
// runtime's death on return affects neither.
peer.close_webrtc();
return;
}
self.handler.update_direct(Some(direct));
@@ -355,14 +350,6 @@ impl<T: InvokeUiSession> Remote<T> {
}
}
log::debug!("Exit io_loop of id={}", self.handler.get_id());
// Close the WebRTC peer connection (if this session used it) so its pc is not left
// lingering in the global session cache after the session ends; dropping `peer`
// alone does not release it. No-op for TCP/WebSocket transports. The pc, its
// sockets and pump tasks, and this close all live on hbb_common's WebRTC I/O
// runtime — nothing may run them on this session runtime, which is dropped the
// moment io_loop returns and would kill the teardown (or, if awaited under a
// timeout, cancel it after `close()` latches `is_closed`, stranding the pc).
peer.close_webrtc();
// Stop client audio server.
if let Some(s) = self.stop_voice_call_sender.take() {
s.send(()).ok();

View File

@@ -156,9 +156,6 @@ async fn connect_and_login(
if !stream.is_secured() && !crate::common::is_direct_ip_access(id) {
if !confirm_insecure_connection(&interface, ui_receiver).await {
*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();
return Ok(None);
}
}
@@ -173,7 +170,6 @@ async fn connect_and_login(
tokio::select! {
res = timeout(READ_TIMEOUT, stream.next()) => match res {
Err(_) => {
stream.close_webrtc();
bail!("Timeout");
}
Ok(Some(Ok(bytes))) => {
@@ -184,7 +180,6 @@ async fn connect_and_login(
let msg_in = match Message::parse_from_bytes(&bytes) {
Ok(msg) => msg,
Err(err) => {
stream.close_webrtc();
return Err(err.into());
}
};
@@ -198,7 +193,6 @@ 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();
return Ok(None);
}
}
@@ -215,11 +209,9 @@ async fn connect_and_login(
}
}
Ok(Some(Err(err))) => {
stream.close_webrtc();
bail!("Connection closed: {}", err);
}
_ => {
stream.close_webrtc();
bail!("Reset by the peer");
}
},
@@ -239,7 +231,6 @@ async fn connect_and_login(
if let Some(Ok(bytes)) = res {
buffer.extend(bytes);
} else {
stream.close_webrtc();
return Ok(None);
}
},
@@ -344,7 +335,6 @@ async fn run_forward(forward: Framed<TcpStream, BytesCodec>, stream: Stream) ->
},
}
}
stream.close_webrtc();
Ok(())
}