mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-03-15 17:21:02 +03:00
allow use websocket (#11677)
1. Enable the RustDesk client to use WebSocket for either controlling or being controlled. 2. Fix TCP sending `register_pk` frequently Note: 1. Because hbb_common directly uses `use_ws` to read config directly, rustdesk also directly reads config Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
@@ -46,7 +46,7 @@ use hbb_common::{
|
||||
anyhow::{anyhow, Context},
|
||||
bail,
|
||||
config::{
|
||||
self, Config, LocalConfig, PeerConfig, PeerInfoSerde, Resolution, CONNECT_TIMEOUT,
|
||||
self, use_ws, Config, LocalConfig, PeerConfig, PeerInfoSerde, Resolution, CONNECT_TIMEOUT,
|
||||
READ_TIMEOUT, RELAY_PORT, RENDEZVOUS_PORT, RENDEZVOUS_SERVERS,
|
||||
},
|
||||
fs::JobType,
|
||||
@@ -216,7 +216,8 @@ impl Client {
|
||||
if hbb_common::is_ip_str(peer) {
|
||||
return Ok((
|
||||
(
|
||||
connect_tcp(check_port(peer, RELAY_PORT + 1), CONNECT_TIMEOUT).await?,
|
||||
connect_tcp_local(check_port(peer, RELAY_PORT + 1), None, CONNECT_TIMEOUT)
|
||||
.await?,
|
||||
true,
|
||||
None,
|
||||
),
|
||||
@@ -226,7 +227,11 @@ impl Client {
|
||||
// Allow connect to {domain}:{port}
|
||||
if hbb_common::is_domain_port_str(peer) {
|
||||
return Ok((
|
||||
(connect_tcp(peer, CONNECT_TIMEOUT).await?, true, None),
|
||||
(
|
||||
connect_tcp_local(peer, None, CONNECT_TIMEOUT).await?,
|
||||
true,
|
||||
None,
|
||||
),
|
||||
(0, "".to_owned()),
|
||||
));
|
||||
}
|
||||
@@ -291,7 +296,7 @@ impl Client {
|
||||
log::info!("#{} punch attempt with {}, id: {}", i, my_addr, peer);
|
||||
let mut msg_out = RendezvousMessage::new();
|
||||
use hbb_common::protobuf::Enum;
|
||||
let nat_type = if interface.is_force_relay() {
|
||||
let nat_type = if interface.is_force_relay() || use_ws() || Config::is_proxy() {
|
||||
NatType::SYMMETRIC
|
||||
} else {
|
||||
NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT)
|
||||
|
||||
@@ -14,7 +14,7 @@ use hbb_common::{
|
||||
anyhow::{anyhow, Context},
|
||||
bail, base64,
|
||||
bytes::Bytes,
|
||||
config::{self, Config, CONNECT_TIMEOUT, READ_TIMEOUT, RENDEZVOUS_PORT},
|
||||
config::{self, use_ws, Config, CONNECT_TIMEOUT, READ_TIMEOUT, RENDEZVOUS_PORT},
|
||||
futures::future::join_all,
|
||||
futures_util::future::poll_fn,
|
||||
get_version_number, log,
|
||||
@@ -504,6 +504,27 @@ audio_rechannel!(audio_rechannel_8_5, 8, 5);
|
||||
audio_rechannel!(audio_rechannel_8_6, 8, 6);
|
||||
audio_rechannel!(audio_rechannel_8_7, 8, 7);
|
||||
|
||||
pub struct CheckTestNatType {
|
||||
is_direct: bool,
|
||||
}
|
||||
|
||||
impl CheckTestNatType {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
is_direct: Config::get_socks().is_none() && !config::use_ws(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for CheckTestNatType {
|
||||
fn drop(&mut self) {
|
||||
let is_direct = Config::get_socks().is_none() && !config::use_ws();
|
||||
if self.is_direct != is_direct {
|
||||
test_nat_type();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_nat_type() {
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
std::thread::spawn(move || {
|
||||
@@ -514,9 +535,8 @@ pub fn test_nat_type() {
|
||||
IS_RUNNING.store(true, Ordering::SeqCst);
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let is_direct = crate::ipc::get_socks().is_none(); // sync socks BTW
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let is_direct = Config::get_socks().is_none(); // sync socks BTW
|
||||
crate::ipc::get_socks_ws();
|
||||
let is_direct = Config::get_socks().is_none() && !config::use_ws();
|
||||
if !is_direct {
|
||||
Config::set_nat_type(NatType::SYMMETRIC as _);
|
||||
IS_RUNNING.store(false, Ordering::SeqCst);
|
||||
@@ -1319,6 +1339,13 @@ pub fn check_process(arg: &str, mut same_uid: bool) -> bool {
|
||||
}
|
||||
|
||||
pub async fn secure_tcp(conn: &mut Stream, key: &str) -> ResultType<()> {
|
||||
// Skip additional encryption when using WebSocket connections (wss://)
|
||||
// as WebSocket Secure (wss://) already provides transport layer encryption.
|
||||
// This doesn't affect the end-to-end encryption between clients,
|
||||
// it only avoids redundant encryption between client and server.
|
||||
if use_ws() {
|
||||
return Ok(());
|
||||
}
|
||||
let rs_pk = get_rs_pk(key);
|
||||
let Some(rs_pk) = rs_pk else {
|
||||
bail!("Handshake failed: invalid public key from rendezvous server");
|
||||
|
||||
@@ -891,7 +891,10 @@ pub fn main_set_option(key: String, value: String) {
|
||||
);
|
||||
}
|
||||
|
||||
if key.eq("custom-rendezvous-server") {
|
||||
if key.eq("custom-rendezvous-server")
|
||||
|| key.eq(config::keys::OPTION_ALLOW_WEBSOCKET)
|
||||
|| key.eq("api-server")
|
||||
{
|
||||
set_option(key, value.clone());
|
||||
#[cfg(target_os = "android")]
|
||||
crate::rendezvous_mediator::RendezvousMediator::restart();
|
||||
@@ -2533,7 +2536,10 @@ pub fn main_set_common(_key: String, _value: String) {
|
||||
);
|
||||
} else if _key == "update-me" {
|
||||
if let Some(new_version_file) = get_download_file_from_url(&_value) {
|
||||
log::debug!("New version file is downloaed, update begin, {:?}", new_version_file.to_str());
|
||||
log::debug!(
|
||||
"New version file is downloaed, update begin, {:?}",
|
||||
new_version_file.to_str()
|
||||
);
|
||||
if let Some(f) = new_version_file.to_str() {
|
||||
// 1.4.0 does not support "--update"
|
||||
// But we can assume that the new version supports it.
|
||||
|
||||
81
src/ipc.rs
81
src/ipc.rs
@@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
common::CheckTestNatType,
|
||||
privacy_mode::PrivacyModeState,
|
||||
ui_interface::{get_local_option, set_local_option},
|
||||
};
|
||||
@@ -22,7 +23,7 @@ pub use clipboard::ClipboardFile;
|
||||
use hbb_common::{
|
||||
allow_err, bail, bytes,
|
||||
bytes_codec::BytesCodec,
|
||||
config::{self, Config, Config2},
|
||||
config::{self, keys::OPTION_ALLOW_WEBSOCKET, Config, Config2},
|
||||
futures::StreamExt as _,
|
||||
futures_util::sink::SinkExt,
|
||||
log, password_security as password, timeout,
|
||||
@@ -282,6 +283,7 @@ pub enum Data {
|
||||
ControllingSessionCount(usize),
|
||||
#[cfg(target_os = "windows")]
|
||||
PortForwardSessionCount(Option<usize>),
|
||||
SocksWs(Option<Box<(Option<config::Socks5Server>, String)>>),
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
@@ -348,29 +350,40 @@ pub async fn new_listener(postfix: &str) -> ResultType<Incoming> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CheckIfRestart(String, Vec<String>, String, String);
|
||||
pub struct CheckIfRestart {
|
||||
stop_service: String,
|
||||
rendezvous_servers: Vec<String>,
|
||||
audio_input: String,
|
||||
voice_call_input: String,
|
||||
ws: String,
|
||||
api_server: String,
|
||||
}
|
||||
|
||||
impl CheckIfRestart {
|
||||
pub fn new() -> CheckIfRestart {
|
||||
CheckIfRestart(
|
||||
Config::get_option("stop-service"),
|
||||
Config::get_rendezvous_servers(),
|
||||
Config::get_option("audio-input"),
|
||||
Config::get_option("voice-call-input"),
|
||||
)
|
||||
CheckIfRestart {
|
||||
stop_service: Config::get_option("stop-service"),
|
||||
rendezvous_servers: Config::get_rendezvous_servers(),
|
||||
audio_input: Config::get_option("audio-input"),
|
||||
voice_call_input: Config::get_option("voice-call-input"),
|
||||
ws: Config::get_option(OPTION_ALLOW_WEBSOCKET),
|
||||
api_server: Config::get_option("api-server"),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Drop for CheckIfRestart {
|
||||
fn drop(&mut self) {
|
||||
if self.0 != Config::get_option("stop-service")
|
||||
|| self.1 != Config::get_rendezvous_servers()
|
||||
if self.stop_service != Config::get_option("stop-service")
|
||||
|| self.rendezvous_servers != Config::get_rendezvous_servers()
|
||||
|| self.ws != Config::get_option(OPTION_ALLOW_WEBSOCKET)
|
||||
|| self.api_server != Config::get_option("api-server")
|
||||
{
|
||||
RendezvousMediator::restart();
|
||||
}
|
||||
if self.2 != Config::get_option("audio-input") {
|
||||
if self.audio_input != Config::get_option("audio-input") {
|
||||
crate::audio_service::restart();
|
||||
}
|
||||
if self.3 != Config::get_option("voice-call-input") {
|
||||
if self.voice_call_input != Config::get_option("voice-call-input") {
|
||||
crate::audio_service::set_voice_call_input_device(
|
||||
Some(Config::get_option("voice-call-input")),
|
||||
true,
|
||||
@@ -455,16 +468,29 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
allow_err!(stream.send(&Data::Socks(Config::get_socks())).await);
|
||||
}
|
||||
Some(data) => {
|
||||
let _nat = CheckTestNatType::new();
|
||||
if data.proxy.is_empty() {
|
||||
Config::set_socks(None);
|
||||
} else {
|
||||
Config::set_socks(Some(data));
|
||||
}
|
||||
crate::common::test_nat_type();
|
||||
RendezvousMediator::restart();
|
||||
log::info!("socks updated");
|
||||
}
|
||||
},
|
||||
Data::SocksWs(s) => match s {
|
||||
None => {
|
||||
allow_err!(
|
||||
stream
|
||||
.send(&Data::SocksWs(Some(Box::new((
|
||||
Config::get_socks(),
|
||||
Config::get_option(OPTION_ALLOW_WEBSOCKET)
|
||||
)))))
|
||||
.await
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
#[cfg(feature = "flutter")]
|
||||
Data::VideoConnCount(None) => {
|
||||
let n = crate::server::AUTHED_CONNS
|
||||
@@ -501,7 +527,8 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
None
|
||||
};
|
||||
} else if name == "hide_cm" {
|
||||
value = if crate::hbbs_http::sync::is_pro() || crate::common::is_custom_client() {
|
||||
value = if crate::hbbs_http::sync::is_pro() || crate::common::is_custom_client()
|
||||
{
|
||||
Some(hbb_common::password_security::hide_cm().to_string())
|
||||
} else {
|
||||
None
|
||||
@@ -544,6 +571,7 @@ async fn handle(data: Data, stream: &mut Connection) {
|
||||
}
|
||||
Some(value) => {
|
||||
let _chk = CheckIfRestart::new();
|
||||
let _nat = CheckTestNatType::new();
|
||||
if let Some(v) = value.get("privacy-mode-impl-key") {
|
||||
crate::privacy_mode::switch(v);
|
||||
}
|
||||
@@ -1113,6 +1141,7 @@ pub fn set_option(key: &str, value: &str) {
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn set_options(value: HashMap<String, String>) -> ResultType<()> {
|
||||
let _nat = CheckTestNatType::new();
|
||||
if let Ok(mut c) = connect(1000, "").await {
|
||||
c.send(&Data::Options(Some(value.clone()))).await?;
|
||||
// do not put below before connect, because we need to check should_exit
|
||||
@@ -1170,6 +1199,7 @@ pub async fn get_socks() -> Option<config::Socks5Server> {
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn set_socks(value: config::Socks5Server) -> ResultType<()> {
|
||||
let _nat = CheckTestNatType::new();
|
||||
Config::set_socks(if value.proxy.is_empty() {
|
||||
None
|
||||
} else {
|
||||
@@ -1182,6 +1212,29 @@ pub async fn set_socks(value: config::Socks5Server) -> ResultType<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_socks_ws_(ms_timeout: u64) -> ResultType<(Option<config::Socks5Server>, String)> {
|
||||
let mut c = connect(ms_timeout, "").await?;
|
||||
c.send(&Data::SocksWs(None)).await?;
|
||||
if let Some(Data::SocksWs(Some(value))) = c.next_timeout(ms_timeout).await? {
|
||||
Config::set_socks(value.0.clone());
|
||||
Config::set_option(OPTION_ALLOW_WEBSOCKET.to_string(), value.1.clone());
|
||||
Ok(*value)
|
||||
} else {
|
||||
Ok((
|
||||
Config::get_socks(),
|
||||
Config::get_option(OPTION_ALLOW_WEBSOCKET),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn get_socks_ws() -> (Option<config::Socks5Server>, String) {
|
||||
get_socks_ws_(1_000).await.unwrap_or((
|
||||
Config::get_socks(),
|
||||
Config::get_option(OPTION_ALLOW_WEBSOCKET),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn get_proxy_status() -> bool {
|
||||
Config::get_socks().is_some()
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "下载失败,您可以重试或者点击\"下载\"按钮,从发布网址下载,并手动升级。"),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", "安装方式检测失败。请点击\"下载\"按钮,从发布网址下载,并手动升级。"),
|
||||
("websocket_tip", "使用 WebSocket 时,仅支持中继连接。"),
|
||||
("Use WebSocket", "使用 WebSocket"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "Download fehlgeschlagen. Sie können es erneut versuchen oder auf die Schaltfläche \"Herunterladen\" klicken, um von der Versionsseite herunterzuladen und manuell zu aktualisieren."),
|
||||
("Auto update", "Automatisch aktualisieren"),
|
||||
("update-failed-check-msi-tip", "Prüfung der Installationsmethode fehlgeschlagen. Bitte klicken Sie auf die Schaltfläche \"Herunterladen\", um von der Versionsseite herunterzuladen und manuell zu aktualisieren."),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("screenshot-action-tip", "Please select how to continue with the screenshot."),
|
||||
("{}-to-update-tip", "{} will close now and install the new version."),
|
||||
("download-new-version-failed-tip", "Download failed. You can try again or click the \"Download\" button to download from the release page and upgrade manually."),
|
||||
("update-failed-check-msi-tip", "Installation method check failed. Please click the \"Download\" button to download from the release page and upgrade manually.")
|
||||
("update-failed-check-msi-tip", "Installation method check failed. Please click the \"Download\" button to download from the release page and upgrade manually."),
|
||||
("websocket_tip", "When using WebSocket, only relay connections are supported."),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "Download non riuscito.\nÈ possibile riprovare o selezionare 'Download' per scaricare e aggiornarlo manualmente."),
|
||||
("Auto update", "Aggiornamento automatico"),
|
||||
("update-failed-check-msi-tip", "Controllo metodo installazione non riuscito.\nSeleziona 'Download' per scaricare il programma e aggiornarlo manualmente."),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "새 버전 다운로드에 실패했습니다"),
|
||||
("Auto update", "자동 업데이트"),
|
||||
("update-failed-check-msi-tip", "업데이트에 실패했습니다. .msi 설치 파일을 확인하세요."),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "Fout bij het downloaden. Je kunt het opnieuw proberen of op de knop Downloaden klikken om de applicatie van de officiële website te downloaden en handmatig bij te werken."),
|
||||
("Auto update", "Automatisch updaten"),
|
||||
("update-failed-check-msi-tip", "Kan de installatiemethode niet bepalen. Klik op “Downloaden” om de applicatie van de officiële website te downloaden en handmatig bij te werken."),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "Pobieranie nie powiodło się. Możesz spróbować ponownie lub kliknąć przycisk \"Pobierz\", aby pobrać ze strony programu i uaktualnić ręcznie."),
|
||||
("Auto update", "Automatyczna aktualizacja"),
|
||||
("update-failed-check-msi-tip", "Sprawdzenie metody instalacji nie powiodło się. Kliknij przycisk \"Pobierz\", aby pobrać ze strony wydania i uaktualnić ręcznie."),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", "Ошибка загрузки. Можно повторить попытку или нажать кнопку \"Скачать\", чтобы скачать приложение с официального сайта и обновить вручную."),
|
||||
("Auto update", "Автоматическое обновление"),
|
||||
("update-failed-check-msi-tip", "Невозможно определить метод установки. Нажмите кнопку \"Скачать\", чтобы скачать приложение с официального сайта и обновить его вручную."),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -694,5 +694,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("download-new-version-failed-tip", ""),
|
||||
("Auto update", ""),
|
||||
("update-failed-check-msi-tip", ""),
|
||||
("websocket_tip", ""),
|
||||
("Use WebSocket", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ use uuid::Uuid;
|
||||
use hbb_common::{
|
||||
allow_err,
|
||||
anyhow::{self, bail},
|
||||
config::{self, keys::*, option2bool, Config, CONNECT_TIMEOUT, REG_INTERVAL, RENDEZVOUS_PORT},
|
||||
config::{
|
||||
self, keys::*, option2bool, use_ws, Config, CONNECT_TIMEOUT, REG_INTERVAL, RENDEZVOUS_PORT,
|
||||
},
|
||||
futures::future::join_all,
|
||||
log,
|
||||
protobuf::Message as _,
|
||||
@@ -139,6 +141,7 @@ impl RendezvousMediator {
|
||||
|
||||
pub async fn start_udp(server: ServerPtr, host: String) -> ResultType<()> {
|
||||
let host = check_port(&host, RENDEZVOUS_PORT);
|
||||
log::info!("start udp: {host}");
|
||||
let (mut socket, mut addr) = socket_client::new_udp_for(&host, CONNECT_TIMEOUT).await?;
|
||||
let mut rz = Self {
|
||||
addr: addr.clone(),
|
||||
@@ -323,6 +326,7 @@ impl RendezvousMediator {
|
||||
|
||||
pub async fn start_tcp(server: ServerPtr, host: String) -> ResultType<()> {
|
||||
let host = check_port(&host, RENDEZVOUS_PORT);
|
||||
log::info!("start tcp: {}", hbb_common::websocket::check_ws(&host));
|
||||
let mut conn = connect_tcp(host.clone(), CONNECT_TIMEOUT).await?;
|
||||
let key = crate::get_key(true).await;
|
||||
crate::secure_tcp(&mut conn, &key).await?;
|
||||
@@ -336,7 +340,7 @@ impl RendezvousMediator {
|
||||
let mut last_register_sent: Option<Instant> = None;
|
||||
let mut last_recv_msg = Instant::now();
|
||||
// we won't support connecting to multiple rendzvous servers any more, so we can use a global variable here.
|
||||
Config::set_host_key_confirmed(&host, false);
|
||||
Config::set_host_key_confirmed(&rz.host_prefix, false);
|
||||
loop {
|
||||
let mut update_latency = || {
|
||||
let latency = last_register_sent
|
||||
@@ -350,6 +354,8 @@ impl RendezvousMediator {
|
||||
last_recv_msg = Instant::now();
|
||||
let bytes = res.ok_or_else(|| anyhow::anyhow!("Rendezvous connection is reset by the peer"))??;
|
||||
if bytes.is_empty() {
|
||||
// After fixing frequent register_pk, for websocket, nginx need to set proxy_read_timeout to more than 60 seconds, eg: 120s
|
||||
// https://serverfault.com/questions/1060525/why-is-my-websocket-connection-gets-closed-in-60-seconds
|
||||
conn.send_bytes(bytes::Bytes::new()).await?;
|
||||
continue; // heartbeat
|
||||
}
|
||||
@@ -365,7 +371,7 @@ impl RendezvousMediator {
|
||||
bail!("Rendezvous connection is timeout");
|
||||
}
|
||||
if (!Config::get_key_confirmed() ||
|
||||
!Config::get_host_key_confirmed(&host)) &&
|
||||
!Config::get_host_key_confirmed(&rz.host_prefix)) &&
|
||||
last_register_sent.map(|x| x.elapsed().as_millis() as i64).unwrap_or(REG_INTERVAL) >= REG_INTERVAL {
|
||||
rz.register_pk(Sink::Stream(&mut conn)).await?;
|
||||
last_register_sent = Some(Instant::now());
|
||||
@@ -380,7 +386,8 @@ impl RendezvousMediator {
|
||||
log::info!("start rendezvous mediator of {}", host);
|
||||
//If the investment agent type is http or https, then tcp forwarding is enabled.
|
||||
if (cfg!(debug_assertions) && option_env!("TEST_TCP").is_some())
|
||||
|| Config::is_proxy()
|
||||
|| Config::is_proxy()
|
||||
|| use_ws()
|
||||
|| get_builtin_option(config::keys::OPTION_DISABLE_UDP) == "Y"
|
||||
{
|
||||
Self::start_tcp(server, host).await
|
||||
@@ -449,7 +456,12 @@ impl RendezvousMediator {
|
||||
async fn handle_intranet(&self, fla: FetchLocalAddr, server: ServerPtr) -> ResultType<()> {
|
||||
let relay_server = self.get_relay_server(fla.relay_server.clone());
|
||||
// nat64, go relay directly, because current hbbs will crash if demangle ipv6 address
|
||||
if is_ipv4(&self.addr) && !config::is_disable_tcp_listen() && !Config::is_proxy() {
|
||||
// websocket, go relay directly
|
||||
if is_ipv4(&self.addr)
|
||||
&& !config::is_disable_tcp_listen()
|
||||
&& !Config::is_proxy()
|
||||
&& !use_ws()
|
||||
{
|
||||
if let Err(err) = self
|
||||
.handle_intranet_(fla.clone(), server.clone(), relay_server.clone())
|
||||
.await
|
||||
@@ -501,9 +513,12 @@ impl RendezvousMediator {
|
||||
|
||||
async fn handle_punch_hole(&self, ph: PunchHole, server: ServerPtr) -> ResultType<()> {
|
||||
let relay_server = self.get_relay_server(ph.relay_server);
|
||||
// for ensure, websocket go relay directly
|
||||
if ph.nat_type.enum_value() == Ok(NatType::SYMMETRIC)
|
||||
|| Config::get_nat_type() == NatType::SYMMETRIC as i32
|
||||
|| config::is_disable_tcp_listen()
|
||||
|| use_ws()
|
||||
|| Config::is_proxy()
|
||||
{
|
||||
let uuid = Uuid::new_v4().to_string();
|
||||
return self
|
||||
|
||||
@@ -325,6 +325,7 @@ class MyIdMenu: Reactor.Component {
|
||||
<li #custom-server>{translate('ID/Relay Server')}</li>
|
||||
<li #whitelist title={translate('whitelist_tip')}>{translate('IP Whitelisting')}</li>
|
||||
<li #socks5-server>{translate('Socks5 Proxy')}</li>
|
||||
{ false && <li #allow-websocket><span>{svg_checkmark}</span>{translate('Use WebSocket')}</li> }
|
||||
<div .separator />
|
||||
<li #stop-service class={service_stopped ? "line-through" : "selected"}><span>{svg_checkmark}</span>{translate("Enable service")}</li>
|
||||
{is_win && handler.is_installed() ? <ShareRdp /> : ""}
|
||||
|
||||
@@ -429,7 +429,10 @@ pub fn set_option(key: String, value: String) {
|
||||
ipc::set_options(options.clone()).ok();
|
||||
}
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
Config::set_option(key, value);
|
||||
{
|
||||
let _nat = crate::CheckTestNatType::new();
|
||||
Config::set_option(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -479,12 +482,12 @@ pub fn set_socks(proxy: String, username: String, password: String) {
|
||||
ipc::set_socks(socks).ok();
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
let _nat = crate::CheckTestNatType::new();
|
||||
if socks.proxy.is_empty() {
|
||||
Config::set_socks(None);
|
||||
} else {
|
||||
Config::set_socks(Some(socks));
|
||||
}
|
||||
crate::common::test_nat_type();
|
||||
crate::RendezvousMediator::restart();
|
||||
log::info!("socks updated");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user