mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-02-17 14:07:28 +08:00
update kcp-sys (#12419)
1. Update kcp-sys to send KCP in frames to avoid potential crashes. 2. Fix the issue when the controling side is closed, the kcp connection close is not immediately recognized by the controlled end. * Unless the controling side receives the close reason, force the sending of the close reason to the controlled end when using KCP, and delay for 30ms to ensure the message is sent successfully. * Move the CloseReason receiving forward, as this message needs to be received when unauthorized, especially for kcp. Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -3651,7 +3651,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kcp-sys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/rustdesk-org/kcp-sys#1e5e30ab8b8c2f7787ab0f88822de36476531562"
|
||||
source = "git+https://github.com/rustdesk-org/kcp-sys#32a6c09fc6223f54aea83981a6aa8995931d29be"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"auto_impl",
|
||||
@@ -3660,6 +3660,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"cc",
|
||||
"dashmap 6.1.0",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"rand 0.8.5",
|
||||
"thiserror 2.0.11",
|
||||
|
||||
@@ -77,6 +77,7 @@ pub struct Remote<T: InvokeUiSession> {
|
||||
video_threads: HashMap<usize, VideoThread>,
|
||||
chroma: Arc<RwLock<Option<Chroma>>>,
|
||||
last_record_state: bool,
|
||||
sent_close_reason: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -125,6 +126,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
video_threads: Default::default(),
|
||||
chroma: Default::default(),
|
||||
last_record_state: false,
|
||||
sent_close_reason: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +174,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(((mut peer, direct, pk, _kcp), (feedback, rendezvous_server))) => {
|
||||
Ok(((mut peer, direct, pk, kcp), (feedback, rendezvous_server))) => {
|
||||
self.handler
|
||||
.connection_round_state
|
||||
.lock()
|
||||
@@ -320,6 +322,13 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
if let Some(s) = self.stop_voice_call_sender.take() {
|
||||
s.send(()).ok();
|
||||
}
|
||||
if kcp.is_some() {
|
||||
// Send the close reason if it hasn't been sent yet, as KCP cannot detect the socket close event.
|
||||
self.send_close_reason(&mut peer, "kcp").await;
|
||||
// KCP does not send messages immediately, so wait to ensure the last message is sent.
|
||||
// 1ms works in my test, but 30ms is more reliable.
|
||||
tokio::time::sleep(Duration::from_millis(30)).await;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
self.handler.on_establish_connection_error(err.to_string());
|
||||
@@ -511,14 +520,22 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_close_reason(&mut self, peer: &mut Stream, reason: &str) {
|
||||
if self.sent_close_reason {
|
||||
return;
|
||||
}
|
||||
let mut misc = Misc::new();
|
||||
misc.set_close_reason(reason.to_owned());
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
self.sent_close_reason = true;
|
||||
}
|
||||
|
||||
async fn handle_msg_from_ui(&mut self, data: Data, peer: &mut Stream) -> bool {
|
||||
match data {
|
||||
Data::Close => {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_close_reason("".to_owned());
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
allow_err!(peer.send(&msg).await);
|
||||
self.send_close_reason(peer, "").await;
|
||||
return false;
|
||||
}
|
||||
Data::Login((os_username, os_password, password, remember)) => {
|
||||
@@ -1712,6 +1729,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
}
|
||||
}
|
||||
Some(misc::Union::CloseReason(c)) => {
|
||||
self.sent_close_reason = true; // The controlled end will close, no need to send close reason
|
||||
self.handler.msgbox("error", "Connection Error", &c, "");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1937,6 +1937,16 @@ impl Connection {
|
||||
}
|
||||
|
||||
async fn on_message(&mut self, msg: Message) -> bool {
|
||||
if let Some(message::Union::Misc(misc)) = &msg.union {
|
||||
// Move the CloseReason forward, as this message needs to be received when unauthorized, especially for kcp.
|
||||
if let Some(misc::Union::CloseReason(s)) = &misc.union {
|
||||
log::info!("receive close reason: {}", s);
|
||||
self.on_close("Peer close", true).await;
|
||||
raii::AuthedConnID::check_remove_session(self.inner.id(), self.session_key());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// After handling CloseReason messages, proceed to process other message types
|
||||
if let Some(message::Union::LoginRequest(lr)) = msg.union {
|
||||
self.handle_login_request_without_validation(&lr).await;
|
||||
if self.authorized {
|
||||
@@ -2790,15 +2800,6 @@ impl Connection {
|
||||
Some(Instant::now().into()),
|
||||
);
|
||||
}
|
||||
Some(misc::Union::CloseReason(_)) => {
|
||||
self.on_close("Peer close", true).await;
|
||||
raii::AuthedConnID::check_remove_session(
|
||||
self.inner.id(),
|
||||
self.session_key(),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
Some(misc::Union::RestartRemoteDevice(_)) => {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
if self.restart {
|
||||
|
||||
Reference in New Issue
Block a user