From 4e9a96dad926c57c5e9706d71facaa8188013d4c Mon Sep 17 00:00:00 2001 From: rustdesk Date: Sat, 19 Feb 2022 15:30:09 +0800 Subject: [PATCH] direct access port editable --- src/common.rs | 2 +- src/rendezvous_mediator.rs | 60 +++++++++++++++++++++++++++++--------- src/ui/common.css | 2 +- src/ui/index.tis | 45 ++++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 19 deletions(-) diff --git a/src/common.rs b/src/common.rs index ca62b6d2e..d00d01b55 100644 --- a/src/common.rs +++ b/src/common.rs @@ -461,7 +461,7 @@ pub fn get_full_name() -> String { } pub fn is_ip(id: &str) -> bool { - hbb_common::regex::Regex::new(r"^\d+\.\d+\.\d+\.\d+$") + hbb_common::regex::Regex::new(r"^\d+\.\d+\.\d+\.\d+(:\d+)?$") .unwrap() .is_match(id) } diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 736d73a78..ce91a39b9 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -56,7 +56,7 @@ impl RendezvousMediator { } let server_cloned = server.clone(); tokio::spawn(async move { - allow_err!(direct_server(server_cloned).await); + direct_server(server_cloned).await; }); if crate::platform::is_installed() { std::thread::spawn(move || { @@ -457,26 +457,58 @@ impl RendezvousMediator { } } -async fn direct_server(server: ServerPtr) -> ResultType<()> { - let port = RENDEZVOUS_PORT + 2; - let addr = format!("0.0.0.0:{}", port); +fn get_direct_port() -> i32 { + let mut port = Config::get_option("direct-access-port") + .parse::() + .unwrap_or(0); + if port <= 0 { + port = RENDEZVOUS_PORT + 2; + } + port +} + +async fn direct_server(server: ServerPtr) { let mut listener = None; + let mut port = 0; loop { - if !Config::get_option("direct-server").is_empty() && listener.is_none() { - listener = Some(hbb_common::tcp::new_listener(&addr, false).await?); - log::info!( - "Direct server listening on: {}", - &listener.as_ref().unwrap().local_addr()? - ); + let disabled = Config::get_option("direct-server").is_empty(); + if !disabled && listener.is_none() { + port = get_direct_port(); + let addr = format!("0.0.0.0:{}", port); + match hbb_common::tcp::new_listener(&addr, false).await { + Ok(l) => { + listener = Some(l); + log::info!( + "Direct server listening on: {:?}", + listener.as_ref().unwrap().local_addr() + ); + } + Err(err) => { + // to-do: pass to ui + log::error!( + "Failed to start direct server on : {}, error: {}", + addr, + err + ); + loop { + if port != get_direct_port() { + break; + } + sleep(1.).await; + } + } + } } if let Some(l) = listener.as_mut() { + if disabled || port != get_direct_port() { + log::info!("Exit direct access listen"); + listener = None; + continue; + } if let Ok(Ok((stream, addr))) = hbb_common::timeout(1000, l.accept()).await { - if Config::get_option("direct-server").is_empty() { - continue; - } stream.set_nodelay(true).ok(); log::info!("direct access from {}", addr); - let local_addr = stream.local_addr()?; + let local_addr = stream.local_addr().unwrap_or(Config::get_any_listen_addr()); let server = server.clone(); tokio::spawn(async move { allow_err!( diff --git a/src/ui/common.css b/src/ui/common.css index 318ac0bb3..e22cf0369 100644 --- a/src/ui/common.css +++ b/src/ui/common.css @@ -303,7 +303,7 @@ menu li span { display: none; } -menu li.selected span { +menu li.selected span:nth-child(1) { display: inline-block; position: absolute; left: -10px; diff --git a/src/ui/index.tis b/src/ui/index.tis index 8c2fb061d..04e97e742 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -70,11 +70,16 @@ class DirectServer: Reactor.Component { function render() { var text = translate("Enable Direct IP Access"); - var cls = handler.get_option("direct-server") == "Y" ? "selected" : "line-through"; - return
  • {svg_checkmark}{text}
  • ; + var enabled = handler.get_option("direct-server") == "Y"; + var cls = enabled ? "selected" : "line-through"; + return
  • {svg_checkmark}{text}{enabled && }
  • ; } function onClick() { + if (is_edit_rdp_port) { + is_edit_rdp_port = false; + return; + } handler.set_option("direct-server", handler.get_option("direct-server") == "Y" ? "" : "Y"); this.update(); } @@ -275,6 +280,40 @@ class MyIdMenu: Reactor.Component { } } +var is_edit_direct_access_port; +class EditDirectAccessPort: Reactor.Component { + function render() { + return {svg_edit}; + } + + function onMouse(evt) { + if (evt.type == Event.MOUSE_DOWN) { + is_edit_direct_access_port = true; + editDirectAccessPort(); + } + } +} + +function editDirectAccessPort() { + var p0 = handler.get_option('direct-access-port'); + var port = p0 ? : + ; + msgbox("custom-direct-access-port", translate('Direct IP Access Settings'),
    +
    {translate('Port')}:{port}
    +
    , function(res=null) { + if (!res) return; + var p = (res.port || '').trim(); + if (p) { + p = p.toInteger(); + if (!(p > 0)) { + return translate("Invalid port"); + } + p = p + ''; + } + if (p != p0) handler.set_option('direct-access-port', p); + }); +} + class App: Reactor.Component { function this() { @@ -623,7 +662,7 @@ class Password: Reactor.Component { class ID: Reactor.Component { function render() { - return ; }