mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-05-10 18:06:01 +02: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:
parent
86bbdf7a5d
commit
9475743b4e
61 changed files with 413 additions and 64 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -5724,7 +5724,7 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"webpki-roots 0.25.4",
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
|
@ -7051,8 +7051,15 @@ checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
|
|||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"native-tls",
|
||||
"rustls 0.23.26",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls 0.26.0",
|
||||
"tungstenite",
|
||||
"webpki-roots 0.26.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -7253,10 +7260,15 @@ dependencies = [
|
|||
"http 1.3.1",
|
||||
"httparse",
|
||||
"log",
|
||||
"native-tls",
|
||||
"rand 0.9.0",
|
||||
"rustls 0.23.26",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"sha1",
|
||||
"thiserror 2.0.11",
|
||||
"utf-8",
|
||||
"webpki-roots 0.26.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -7753,6 +7765,15 @@ version = "0.25.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29aad86cec885cafd03e8305fd727c418e970a521322c91688414d5b8efba16b"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.8"
|
||||
|
|
|
@ -147,9 +147,13 @@ const String kOptionDirectxCapture = "enable-directx-capture";
|
|||
const String kOptionAllowRemoteCmModification = "allow-remote-cm-modification";
|
||||
const String kOptionEnableTrustedDevices = "enable-trusted-devices";
|
||||
|
||||
// network options
|
||||
const String kOptionAllowWebSocket = "allow-websocket";
|
||||
|
||||
// buildin opitons
|
||||
const String kOptionHideServerSetting = "hide-server-settings";
|
||||
const String kOptionHideProxySetting = "hide-proxy-settings";
|
||||
const String kOptionHideWebSocketSetting = "hide-websocket-settings";
|
||||
const String kOptionHideRemotePrinterSetting = "hide-remote-printer-settings";
|
||||
const String kOptionHideSecuritySetting = "hide-security-settings";
|
||||
const String kOptionHideNetworkSetting = "hide-network-settings";
|
||||
|
|
|
@ -1475,11 +1475,70 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
|||
bind.mainGetBuildinOption(key: kOptionHideServerSetting) == 'Y';
|
||||
final hideProxy =
|
||||
isWeb || bind.mainGetBuildinOption(key: kOptionHideProxySetting) == 'Y';
|
||||
// final hideWebSocket = isWeb ||
|
||||
// bind.mainGetBuildinOption(key: kOptionHideWebSocketSetting) == 'Y';
|
||||
final hideWebSocket = true;
|
||||
|
||||
if (hideServer && hideProxy) {
|
||||
if (hideServer && hideProxy && hideWebSocket) {
|
||||
return Offstage();
|
||||
}
|
||||
|
||||
// Helper function to create network setting ListTiles
|
||||
Widget listTile({
|
||||
required IconData icon,
|
||||
required String title,
|
||||
VoidCallback? onTap,
|
||||
Widget? trailing,
|
||||
bool showTooltip = false,
|
||||
String tooltipMessage = '',
|
||||
}) {
|
||||
final titleWidget = showTooltip
|
||||
? Row(
|
||||
children: [
|
||||
Tooltip(
|
||||
waitDuration: Duration(milliseconds: 1000),
|
||||
message: translate(tooltipMessage),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
translate(title),
|
||||
style: TextStyle(fontSize: _kContentFontSize),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Icon(
|
||||
Icons.help_outline,
|
||||
size: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
.titleLarge
|
||||
?.color
|
||||
?.withOpacity(0.7),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
translate(title),
|
||||
style: TextStyle(fontSize: _kContentFontSize),
|
||||
);
|
||||
|
||||
return ListTile(
|
||||
leading: Icon(icon, color: _accentColor),
|
||||
title: titleWidget,
|
||||
enabled: !locked,
|
||||
onTap: onTap,
|
||||
trailing: trailing,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16),
|
||||
minLeadingWidth: 0,
|
||||
horizontalTitleGap: 10,
|
||||
);
|
||||
}
|
||||
|
||||
return _Card(
|
||||
title: 'Network',
|
||||
children: [
|
||||
|
@ -1488,39 +1547,36 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (!hideServer)
|
||||
ListTile(
|
||||
leading: Icon(Icons.dns_outlined, color: _accentColor),
|
||||
title: Text(
|
||||
translate('ID/Relay Server'),
|
||||
style: TextStyle(fontSize: _kContentFontSize),
|
||||
),
|
||||
enabled: !locked,
|
||||
listTile(
|
||||
icon: Icons.dns_outlined,
|
||||
title: 'ID/Relay Server',
|
||||
onTap: () => showServerSettings(gFFI.dialogManager),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16),
|
||||
minLeadingWidth: 0,
|
||||
horizontalTitleGap: 10,
|
||||
),
|
||||
if (!hideServer && !hideProxy)
|
||||
if (!hideServer && (!hideProxy || !hideWebSocket))
|
||||
Divider(height: 1, indent: 16, endIndent: 16),
|
||||
if (!hideProxy)
|
||||
ListTile(
|
||||
leading:
|
||||
Icon(Icons.network_ping_outlined, color: _accentColor),
|
||||
title: Text(
|
||||
translate('Socks5/Http(s) Proxy'),
|
||||
style: TextStyle(fontSize: _kContentFontSize),
|
||||
),
|
||||
enabled: !locked,
|
||||
listTile(
|
||||
icon: Icons.network_ping_outlined,
|
||||
title: 'Socks5/Http(s) Proxy',
|
||||
onTap: changeSocks5Proxy,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16),
|
||||
minLeadingWidth: 0,
|
||||
horizontalTitleGap: 10,
|
||||
if (!hideProxy && !hideWebSocket)
|
||||
Divider(height: 1, indent: 16, endIndent: 16),
|
||||
if (!hideWebSocket)
|
||||
listTile(
|
||||
icon: Icons.web_asset_outlined,
|
||||
title: 'Use WebSocket',
|
||||
showTooltip: true,
|
||||
tooltipMessage: 'websocket_tip',
|
||||
trailing: Switch(
|
||||
value: mainGetBoolOptionSync(kOptionAllowWebSocket),
|
||||
onChanged: locked
|
||||
? null
|
||||
: (value) {
|
||||
mainSetBoolOption(kOptionAllowWebSocket, value);
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -80,6 +80,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||
var _enableDirectIPAccess = false;
|
||||
var _enableRecordSession = false;
|
||||
var _enableHardwareCodec = false;
|
||||
var _allowWebSocket = false;
|
||||
var _autoRecordIncomingSession = false;
|
||||
var _autoRecordOutgoingSession = false;
|
||||
var _allowAutoDisconnect = false;
|
||||
|
@ -91,6 +92,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||
var _hideServer = false;
|
||||
var _hideProxy = false;
|
||||
var _hideNetwork = false;
|
||||
var _hideWebSocket = false;
|
||||
var _enableTrustedDevices = false;
|
||||
|
||||
_SettingsState() {
|
||||
|
@ -105,6 +107,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||
bind.mainGetOptionSync(key: kOptionEnableRecordSession));
|
||||
_enableHardwareCodec = option2bool(kOptionEnableHwcodec,
|
||||
bind.mainGetOptionSync(key: kOptionEnableHwcodec));
|
||||
_allowWebSocket = mainGetBoolOptionSync(kOptionAllowWebSocket);
|
||||
_autoRecordIncomingSession = option2bool(kOptionAllowAutoRecordIncoming,
|
||||
bind.mainGetOptionSync(key: kOptionAllowAutoRecordIncoming));
|
||||
_autoRecordOutgoingSession = option2bool(kOptionAllowAutoRecordOutgoing,
|
||||
|
@ -120,6 +123,8 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||
_hideProxy = bind.mainGetBuildinOption(key: kOptionHideProxySetting) == 'Y';
|
||||
_hideNetwork =
|
||||
bind.mainGetBuildinOption(key: kOptionHideNetworkSetting) == 'Y';
|
||||
_hideWebSocket =
|
||||
true; //bind.mainGetBuildinOption(key: kOptionHideWebSocketSetting) == 'Y';
|
||||
_enableTrustedDevices = mainGetBoolOptionSync(kOptionEnableTrustedDevices);
|
||||
}
|
||||
|
||||
|
@ -667,6 +672,21 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||
onPressed: (context) {
|
||||
changeSocks5Proxy();
|
||||
}),
|
||||
if (!disabledSettings && !_hideNetwork && !_hideWebSocket)
|
||||
SettingsTile.switchTile(
|
||||
title: Text(translate('Use WebSocket')),
|
||||
initialValue: _allowWebSocket,
|
||||
onToggle: isOptionFixed(kOptionAllowWebSocket)
|
||||
? null
|
||||
: (v) async {
|
||||
await mainSetBoolOption(kOptionAllowWebSocket, v);
|
||||
final newValue =
|
||||
await mainGetBoolOption(kOptionAllowWebSocket);
|
||||
setState(() {
|
||||
_allowWebSocket = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
SettingsTile(
|
||||
title: Text(translate('Language')),
|
||||
leading: Icon(Icons.translate),
|
||||
|
|
|
@ -49,14 +49,15 @@ class PlatformFFI {
|
|||
}
|
||||
|
||||
bool registerEventHandler(
|
||||
String eventName, String handlerName, HandleEvent handler) {
|
||||
String eventName, String handlerName, HandleEvent handler,
|
||||
{bool replace = false}) {
|
||||
debugPrint('registerEventHandler $eventName $handlerName');
|
||||
var handlers = _eventHandlers[eventName];
|
||||
if (handlers == null) {
|
||||
_eventHandlers[eventName] = {handlerName: handler};
|
||||
return true;
|
||||
} else {
|
||||
if (handlers.containsKey(handlerName)) {
|
||||
if (!replace && handlers.containsKey(handlerName)) {
|
||||
return false;
|
||||
} else {
|
||||
handlers[handlerName] = handler;
|
||||
|
|
|
@ -1852,5 +1852,49 @@ class RustdeskImpl {
|
|||
throw UnimplementedError("sessionGetConnToken");
|
||||
}
|
||||
|
||||
String mainGetPrinterNames({dynamic hint}) {
|
||||
return '';
|
||||
}
|
||||
|
||||
Future<void> sessionPrinterResponse(
|
||||
{required UuidValue sessionId,
|
||||
required int id,
|
||||
required String path,
|
||||
required String printerName,
|
||||
dynamic hint}) {
|
||||
throw UnimplementedError("sessionPrinterResponse");
|
||||
}
|
||||
|
||||
Future<String> mainGetCommon({required String key, dynamic hint}) {
|
||||
throw UnimplementedError("mainGetCommon");
|
||||
}
|
||||
|
||||
String mainGetCommonSync({required String key, dynamic hint}) {
|
||||
throw UnimplementedError("mainGetCommonSync");
|
||||
}
|
||||
|
||||
Future<void> mainSetCommon(
|
||||
{required String key, required String value, dynamic hint}) {
|
||||
throw UnimplementedError("mainSetCommon");
|
||||
}
|
||||
|
||||
Future<String> sessionHandleScreenshot(
|
||||
{required UuidValue sessionId, required String action, dynamic hint}) {
|
||||
throw UnimplementedError("sessionHandleScreenshot");
|
||||
}
|
||||
|
||||
String? sessionGetCommonSync(
|
||||
{required UuidValue sessionId,
|
||||
required String key,
|
||||
required String param,
|
||||
dynamic hint}) {
|
||||
throw UnimplementedError("sessionGetCommonSync");
|
||||
}
|
||||
|
||||
Future<void> sessionTakeScreenshot(
|
||||
{required UuidValue sessionId, required int display, dynamic hint}) {
|
||||
throw UnimplementedError("sessionTakeScreenshot");
|
||||
}
|
||||
|
||||
void dispose() {}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d64954ae2211e5154fd9036ec4862413f24bbd7b
|
||||
Subproject commit 7839dcf4e4ddc3feab9b52b0ae1903d443bc084d
|
|
@ -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());
|
||||
|
@ -381,6 +387,7 @@ impl RendezvousMediator {
|
|||
//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()
|
||||
|| 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"))]
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue