From 36b574a5f8dfd69b0d868567c2d4c66176bc039c Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 7 Nov 2023 17:19:33 +0800 Subject: [PATCH 1/2] close all connections if cm exit unexpected, and allow retry Signed-off-by: 21pages --- src/ipc.rs | 1 + src/server/connection.rs | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/ipc.rs b/src/ipc.rs index aea90a498..7965b00d5 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -236,6 +236,7 @@ pub enum Data { FileTransferLog((String, String)), #[cfg(windows)] ControlledSessionCount(usize), + CmErr(String), } #[tokio::main(flavor = "current_thread")] diff --git a/src/server/connection.rs b/src/server/connection.rs index 174c2db9c..f03bde8aa 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -3,6 +3,8 @@ use super::{input_service::*, *}; use crate::clipboard_file::*; #[cfg(not(any(target_os = "android", target_os = "ios")))] use crate::common::update_clipboard; +#[cfg(target_os = "android")] +use crate::keyboard::client::map_key_to_control_key; #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] use crate::platform::linux_desktop_manager; @@ -32,18 +34,17 @@ use hbb_common::{ get_time, get_version_number, message_proto::{option_message::BoolOption, permission_info::Permission}, password_security::{self as password, ApproveMode}, + protobuf::EnumOrUnknown, sleep, timeout, tokio::{ net::TcpStream, sync::mpsc, time::{self, Duration, Instant, Interval}, }, - tokio_util::codec::{BytesCodec, Framed}, protobuf::EnumOrUnknown, + tokio_util::codec::{BytesCodec, Framed}, }; #[cfg(any(target_os = "android", target_os = "ios"))] -use scrap::android::{call_main_service_pointer_input, call_main_service_key_event}; -#[cfg(target_os = "android")] -use crate::keyboard::client::map_key_to_control_key; +use scrap::android::{call_main_service_key_event, call_main_service_pointer_input}; use serde_derive::Serialize; use serde_json::{json, value::Value}; use sha2::{Digest, Sha256}; @@ -439,6 +440,13 @@ impl Connection { conn.on_close("connection manager", true).await; break; } + ipc::Data::CmErr(e) => { + if e != "expected" { + // cm closed before connection + conn.on_close(&format!("connection manager error: {}", e), false).await; + break; + } + } ipc::Data::ChatMessage{text} => { let mut misc = Misc::new(); misc.set_chat_message(ChatMessage { @@ -816,7 +824,11 @@ impl Connection { Some(data) = rx_from_cm.recv() => { match data { ipc::Data::Close => { - bail!("Close requested from selection manager"); + bail!("Close requested from connection manager"); + } + ipc::Data::CmErr(e) => { + log::error!("Connection manager error: {e}"); + bail!("{e}"); } _ => {} } @@ -1383,15 +1395,15 @@ impl Connection { } fn is_recent_session(&mut self) -> bool { + SESSIONS + .lock() + .unwrap() + .retain(|_, s| s.last_recv_time.lock().unwrap().elapsed() < SESSION_TIMEOUT); let session = SESSIONS .lock() .unwrap() .get(&self.lr.my_id) .map(|s| s.to_owned()); - SESSIONS - .lock() - .unwrap() - .retain(|_, s| s.last_recv_time.lock().unwrap().elapsed() < SESSION_TIMEOUT); // last_recv_time is a mutex variable shared with connection, can be updated lively. if let Some(session) = session { if session.name == self.lr.my_name @@ -1461,6 +1473,7 @@ impl Connection { fn try_start_cm_ipc(&mut self) { if let Some(p) = self.start_cm_ipc_para.take() { tokio::spawn(async move { + let tx_from_cm_clone = p.tx_from_cm.clone(); if let Err(err) = start_ipc( p.rx_to_cm, p.tx_from_cm, @@ -1470,6 +1483,7 @@ impl Connection { .await { log::error!("ipc to connection manager exit: {}", err); + allow_err!(tx_from_cm_clone.send(Data::CmErr(err.to_string()))); } }); #[cfg(all(windows, feature = "flutter"))] From 1902134f0398030e0cb77bcc446cc94348032960 Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 8 Nov 2023 11:28:59 +0800 Subject: [PATCH 2/2] cm get config Signed-off-by: 21pages --- .../lib/desktop/pages/desktop_setting_page.dart | 2 +- flutter/lib/main.dart | 5 +++-- flutter/lib/models/server_model.dart | 4 ++++ src/flutter_ffi.rs | 17 ++++++++++++++++- src/ipc.rs | 8 +++++++- src/server/connection.rs | 6 ++---- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 3c8b5878d..3322291eb 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -1319,7 +1319,7 @@ class _DisplayState extends State<_Display> { otherRow('Zoom cursor', 'zoom-cursor'), otherRow('Show quality monitor', 'show_quality_monitor'), otherRow('Mute', 'disable_audio'), - otherRow('Allow file copy and paste', 'enable_file_transfer'), + otherRow('Enable file copy and paste', 'enable_file_transfer'), otherRow('Disable clipboard', 'disable_clipboard'), otherRow('Lock after session end', 'lock_after_session_end'), otherRow('Privacy mode', 'privacy_mode'), diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index b8a7a8e45..7e793a776 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -91,7 +91,7 @@ Future main(List args) async { debugPrint("--cm started"); desktopType = DesktopType.cm; await windowManager.ensureInitialized(); - runConnectionManagerScreen(args.contains('--hide')); + runConnectionManagerScreen(); } else if (args.contains('--install')) { runInstallPage(); } else { @@ -225,13 +225,14 @@ void runMultiWindow( WindowController.fromWindowId(kWindowId!).show(); } -void runConnectionManagerScreen(bool hide) async { +void runConnectionManagerScreen() async { await initEnv(kAppTypeConnectionManager); _runApp( '', const DesktopServerPage(), MyTheme.currentThemeMode(), ); + final hide = await bind.cmGetConfig(name: "hide_cm") == 'true'; gFFI.serverModel.hideCm = hide; if (hide) { await hideCmWindow(isStartup: true); diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 1422596c2..72013fd0b 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -79,10 +79,12 @@ class ServerModel with ChangeNotifier { setVerificationMethod(String method) async { await bind.mainSetOption(key: "verification-method", value: method); + /* if (method != kUsePermanentPassword) { await bind.mainSetOption( key: 'allow-hide-cm', value: bool2option('allow-hide-cm', false)); } + */ } String get temporaryPasswordLength { @@ -99,10 +101,12 @@ class ServerModel with ChangeNotifier { setApproveMode(String mode) async { await bind.mainSetOption(key: 'approve-mode', value: mode); + /* if (mode != 'password') { await bind.mainSetOption( key: 'allow-hide-cm', value: bool2option('allow-hide-cm', false)); } + */ } TextEditingController get serverId => _serverId; diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 436a95587..f4ef1434e 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -395,7 +395,7 @@ pub fn session_is_keyboard_mode_supported(session_id: SessionID, mode: String) - SyncReturn(is_keyboard_mode_supported( &mode, session.get_peer_version(), - &session.peer_platform() + &session.peer_platform(), )) } else { SyncReturn(false) @@ -1529,6 +1529,21 @@ pub fn cm_switch_back(conn_id: i32) { crate::ui_cm_interface::switch_back(conn_id); } +pub fn cm_get_config(name: String) -> String { + #[cfg(not(target_os = "ios"))] + { + if let Ok(Some(v)) = crate::ipc::get_config(&name) { + v + } else { + "".to_string() + } + } + #[cfg(target_os = "ios")] + { + "".to_string() + } +} + pub fn main_get_build_date() -> String { crate::BUILD_DATE.to_string() } diff --git a/src/ipc.rs b/src/ipc.rs index 7965b00d5..43cf50ecf 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -408,6 +408,12 @@ async fn handle(data: Data, stream: &mut Connection) { } else { None }; + } else if name == "hide_cm" { + value = if crate::hbbs_http::sync::is_pro() { + Some(hbb_common::password_security::hide_cm().to_string()) + } else { + None + }; } else { value = None; } @@ -699,7 +705,7 @@ where } #[tokio::main(flavor = "current_thread")] -async fn get_config(name: &str) -> ResultType> { +pub async fn get_config(name: &str) -> ResultType> { get_config_async(name, 1_000).await } diff --git a/src/server/connection.rs b/src/server/connection.rs index f03bde8aa..b0fd19891 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -26,6 +26,8 @@ use cidr_utils::cidr::IpCidr; #[cfg(all(target_os = "linux", feature = "linux_headless"))] #[cfg(not(any(feature = "flatpak", feature = "appimage")))] use hbb_common::platform::linux::run_cmds; +#[cfg(target_os = "android")] +use hbb_common::protobuf::EnumOrUnknown; use hbb_common::{ config::Config, fs, @@ -34,7 +36,6 @@ use hbb_common::{ get_time, get_version_number, message_proto::{option_message::BoolOption, permission_info::Permission}, password_security::{self as password, ApproveMode}, - protobuf::EnumOrUnknown, sleep, timeout, tokio::{ net::TcpStream, @@ -2791,9 +2792,6 @@ async fn start_ipc( #[allow(unused_mut)] #[allow(unused_assignments)] let mut args = vec!["--cm"]; - if crate::hbbs_http::sync::is_pro() && password::hide_cm() { - args.push("--hide"); - } #[allow(unused_mut)] #[cfg(target_os = "linux")] let mut user = None;