diff --git a/src/common.rs b/src/common.rs index 2d5fa5073..a29273397 100644 --- a/src/common.rs +++ b/src/common.rs @@ -3,7 +3,7 @@ use hbb_common::{ allow_err, anyhow::bail, compress::{compress as compress_func, decompress}, - config::{Config, NetworkType, COMPRESS_LEVEL, RENDEZVOUS_TIMEOUT}, + config::{Config, COMPRESS_LEVEL, RENDEZVOUS_TIMEOUT}, log, message_proto::*, protobuf::Message as _, @@ -238,8 +238,9 @@ pub fn test_nat_type() { #[tokio::main(flavor = "current_thread")] async fn test_nat_type_() -> ResultType { log::info!("Testing nat ..."); + let is_direct = crate::ipc::get_socks_async(1_000).await.is_none(); // sync socks BTW let start = std::time::Instant::now(); - let rendezvous_server = get_rendezvous_server(100).await; + let rendezvous_server = get_rendezvous_server(1_000).await; let server1 = rendezvous_server; let tmp: Vec<&str> = server1.split(":").collect(); if tmp.len() != 2 { @@ -272,7 +273,7 @@ async fn test_nat_type_() -> ResultType { RENDEZVOUS_TIMEOUT, ) .await?; - if Config::get_network_type() == NetworkType::Direct { + if is_direct { // to-do: should set NatType::UNKNOWN for proxy addr = socket.local_addr(); } diff --git a/src/ipc.rs b/src/ipc.rs index 1c5a0cc15..841dd37ef 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -89,6 +89,7 @@ pub enum Data { NatType(Option), ConfirmedKey(Option<(Vec, Vec)>), RawMessage(Vec), + Socks(Option), FS(FS), Test, } @@ -192,6 +193,20 @@ async fn handle(data: Data, stream: &mut Connection) { }; allow_err!(stream.send(&Data::ConfirmedKey(out)).await); } + Data::Socks(s) => match s { + None => { + allow_err!(stream.send(&Data::Socks(Config::get_socks())).await); + } + Some(data) => { + if data.proxy.is_empty() { + Config::set_socks(None); + } else { + Config::set_socks(Some(data)); + } + crate::rendezvous_mediator::RendezvousMediator::restart(); + log::info!("socks updated"); + } + }, Data::Config((name, value)) => match value { None => { let value; @@ -467,6 +482,41 @@ pub async fn get_nat_type(ms_timeout: u64) -> i32 { .unwrap_or(Config::get_nat_type()) } +#[inline] +async fn get_socks_(ms_timeout: u64) -> ResultType> { + let mut c = connect(ms_timeout, "").await?; + c.send(&Data::Socks(None)).await?; + if let Some(Data::Socks(value)) = c.next_timeout(ms_timeout).await? { + Config::set_socks(value.clone()); + Ok(value) + } else { + Ok(Config::get_socks()) + } +} + +pub async fn get_socks_async(ms_timeout: u64) -> Option { + get_socks_(ms_timeout).await.unwrap_or(Config::get_socks()) +} + +#[tokio::main(flavor = "current_thread")] +pub async fn get_socks() -> Option { + get_socks_async(1_000).await +} + +#[tokio::main(flavor = "current_thread")] +pub async fn set_socks(value: config::Socks5Server) -> ResultType<()> { + Config::set_socks(if value.proxy.is_empty() { + None + } else { + Some(value.clone()) + }); + connect(1_000, "") + .await? + .send(&Data::Socks(Some(value))) + .await?; + Ok(()) +} + /* static mut SHARED_MEMORY: *mut i64 = std::ptr::null_mut(); diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 184b09d36..33dbb8f3a 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -192,5 +192,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Remove from Favorites", "从收藏中删除"), ("Empty", "空空如也"), ("Invalid folder name", "无效文件夹名称"), + ("Socks5 Proxy", "Socks5 代理") ].iter().cloned().collect(); } diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index ec2822474..b994b4b91 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -28,7 +28,7 @@ use uuid::Uuid; type Message = RendezvousMessage; lazy_static::lazy_static! { - pub static ref SOLVING_PK_MISMATCH: Arc> = Default::default(); + static ref SOLVING_PK_MISMATCH: Arc> = Default::default(); } static SHOULD_EXIT: AtomicBool = AtomicBool::new(false); @@ -42,6 +42,10 @@ pub struct RendezvousMediator { } impl RendezvousMediator { + pub fn restart() { + SHOULD_EXIT.store(true, Ordering::SeqCst); + } + pub async fn start_all() { let mut nat_tested = false; check_zombie(); diff --git a/src/ui.rs b/src/ui.rs index f0e8ecd48..dcf97b298 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -8,7 +8,7 @@ use crate::common::SOFTWARE_UPDATE_URL; use crate::ipc; use hbb_common::{ allow_err, - config::{Config, Fav, PeerConfig, APP_NAME, ICON}, + config::{self, Config, Fav, PeerConfig, APP_NAME, ICON}, log, sleep, tokio::{self, time}, }; @@ -372,6 +372,29 @@ impl UI { return "".to_owned(); } + fn get_socks(&self) -> Value { + let s = ipc::get_socks(); + match s { + None => Value::null(), + Some(s) => { + let mut v = Value::array(0); + v.push(s.proxy); + v.push(s.username); + v.push(s.password); + v + } + } + } + + fn set_socks(&self, proxy: String, username: String, password: String) { + ipc::set_socks(config::Socks5Server { + proxy, + username, + password, + }) + .ok(); + } + fn is_installed(&mut self) -> bool { crate::platform::is_installed() } @@ -628,6 +651,8 @@ impl sciter::EventHandler for UI { fn get_msgbox(); fn install_me(String); fn is_installed(); + fn set_socks(String, String, String); + fn get_socks(); fn is_installed_lower_version(); fn install_path(); fn goto_install(); diff --git a/src/ui/common.tis b/src/ui/common.tis index 2ce6214e2..b4e0bf190 100644 --- a/src/ui/common.tis +++ b/src/ui/common.tis @@ -360,8 +360,9 @@ class PasswordComponent: Reactor.Component { var start = el.xcall(#selectionStart) || 0; var end = el.xcall(#selectionEnd); this.update({ visible: !this.visible }); + var me = this; self.timer(30ms, function() { - var el = this.$(input); + var el = me.$(input); view.focus = el; el.value = value; el.xcall(#setSelection, start, end); diff --git a/src/ui/index.tis b/src/ui/index.tis index 974640831..f8d8f4921 100644 --- a/src/ui/index.tis +++ b/src/ui/index.tis @@ -135,6 +135,7 @@ class MyIdMenu: Reactor.Component {
  • {translate('IP Whitelisting')}
  • {translate('ID/Relay Server')}
  • +
  • {translate('Socks5 Proxy')}
  • {svg_checkmark}{translate("Enable Service")}
  • @@ -211,6 +212,28 @@ class MyIdMenu: Reactor.Component { configOptions["relay-server"] = relay; handler.set_options(configOptions); }, 240); + } else if (me.id == "socks5-server") { + var socks5 = handler.get_socks() || {}; + var old_proxy = socks5[0] || ""; + var old_username = socks5[1] || ""; + var old_password = socks5[2] || ""; + msgbox("custom-server", "Socks5 Proxy",
    +
    {translate("Hostname")}
    +
    {translate("Username")}
    +
    {translate("Password")}
    +
    + , function(res=null) { + if (!res) return; + var proxy = (res.proxy || "").trim(); + var username = (res.username || "").trim(); + var password = (res.password || "").trim(); + if (proxy == old_proxy && username == old_username && password == old_password) return; + if (proxy) { + var err = handler.test_if_valid_server(proxy); + if (err) return translate("Server") + ": " + err; + } + handler.set_socks(proxy, username, password); + }, 240); } else if (me.id == "stop-service") { handler.set_option("stop-service", service_stopped ? "" : "Y"); } else if (me.id == "about") {