udp / ipv6 punch option

This commit is contained in:
rustdesk
2025-06-14 21:42:18 +08:00
parent bf77f582d0
commit 645a76d43f
55 changed files with 269 additions and 30 deletions

View File

@@ -274,21 +274,28 @@ impl Client {
}
};
crate::test_ipv6().await;
if crate::get_ipv6_punch_enabled() {
crate::test_ipv6().await;
}
let (stop_udp_tx, stop_udp_rx) = oneshot::channel::<()>();
let mut udp =
// no need to care about multiple rendezvous servers case, since it is acutally not used any more.
// Shared state for UDP NAT test result
if let Ok((socket, addr)) = new_direct_udp_for(&rendezvous_server).await {
let udp_port = Arc::new(Mutex::new(0));
let up_cloned = udp_port.clone();
let socket_cloned = socket.clone();
let func = async move {
allow_err!(test_udp_uat(socket_cloned, addr, up_cloned, stop_udp_rx).await);
};
tokio::spawn(func);
(Some(socket), Some(udp_port))
if crate::get_udp_punch_enabled() {
if let Ok((socket, addr)) = new_direct_udp_for(&rendezvous_server).await {
let udp_port = Arc::new(Mutex::new(0));
let up_cloned = udp_port.clone();
let socket_cloned = socket.clone();
let func = async move {
allow_err!(test_udp_uat(socket_cloned, addr, up_cloned, stop_udp_rx).await);
};
tokio::spawn(func);
(Some(socket), Some(udp_port))
} else {
(None, None)
}
} else {
(None, None)
};
@@ -351,8 +358,12 @@ impl Client {
// Stop UDP NAT test task if still running
let _ = stop_udp_tx.send(());
let mut msg_out = RendezvousMessage::new();
let mut ipv6 = if let Some((socket, addr)) = crate::get_ipv6_socket().await {
(Some(socket), Some(addr))
let mut ipv6 = if crate::get_ipv6_punch_enabled() {
if let Some((socket, addr)) = crate::get_ipv6_socket().await {
(Some(socket), Some(addr))
} else {
(None, None)
}
} else {
(None, None)
};
@@ -3778,7 +3789,7 @@ pub mod peer_online {
}
// Retry for 2 times to get the online response
for _ in 0..2 {
if let Some(msg_in) = crate::common::get_next_nonkeyexchange_msg(
if let Some(msg_in) = crate::get_next_nonkeyexchange_msg(
&mut socket,
Some(timeout.as_millis() as _),
)

View File

@@ -6,7 +6,6 @@ use std::{
task::Poll,
};
use default_net::ip;
use serde_json::{json, Map, Value};
#[cfg(not(any(target_os = "android", target_os = "ios")))]
@@ -16,7 +15,9 @@ use hbb_common::{
anyhow::{anyhow, Context},
bail, base64,
bytes::Bytes,
config::{self, use_ws, Config, CONNECT_TIMEOUT, READ_TIMEOUT, RENDEZVOUS_PORT},
config::{
self, keys, use_ws, Config, LocalConfig, CONNECT_TIMEOUT, READ_TIMEOUT, RENDEZVOUS_PORT,
},
futures::future::join_all,
futures_util::future::poll_fn,
get_version_number, log,
@@ -881,8 +882,8 @@ pub fn check_software_update() {
if is_custom_client() {
return;
}
let opt = config::LocalConfig::get_option(config::keys::OPTION_ENABLE_CHECK_UPDATE);
if config::option2bool(config::keys::OPTION_ENABLE_CHECK_UPDATE, &opt) {
let opt = LocalConfig::get_option(keys::OPTION_ENABLE_CHECK_UPDATE);
if config::option2bool(keys::OPTION_ENABLE_CHECK_UPDATE, &opt) {
std::thread::spawn(move || allow_err!(do_check_software_update()));
}
}
@@ -973,7 +974,7 @@ pub fn get_api_server(api: String, custom: String) -> String {
}
if res.starts_with("https")
&& res.ends_with(":21114")
&& get_builtin_option(config::keys::OPTION_ALLOW_HTTPS_21114) != "Y"
&& get_builtin_option(keys::OPTION_ALLOW_HTTPS_21114) != "Y"
{
return res.replace(":21114", "");
}
@@ -1011,6 +1012,32 @@ pub fn is_public(url: &str) -> bool {
url.contains("rustdesk.com")
}
pub fn get_udp_punch_enabled() -> bool {
config::option2bool(
keys::OPTION_ENABLE_UDP_PUNCH,
&get_local_option(keys::OPTION_ENABLE_UDP_PUNCH),
)
}
pub fn get_ipv6_punch_enabled() -> bool {
config::option2bool(
keys::OPTION_ENABLE_IPV6_PUNCH,
&get_local_option(keys::OPTION_ENABLE_IPV6_PUNCH),
)
}
pub fn get_local_option(key: &str) -> String {
let v = LocalConfig::get_option(key);
if key == keys::OPTION_ENABLE_UDP_PUNCH || key == keys::OPTION_ENABLE_IPV6_PUNCH {
if v.is_empty() {
if !is_public(&Config::get_rendezvous_server()) {
return "N".to_owned();
}
}
}
v
}
pub fn get_audit_server(api: String, custom: String, typ: String) -> String {
let url = get_api_server(api, custom);
if url.is_empty() || is_public(&url) {
@@ -1618,19 +1645,19 @@ pub fn read_custom_client(config: &str) {
}
let mut map_display_settings = HashMap::new();
for s in config::keys::KEYS_DISPLAY_SETTINGS {
for s in keys::KEYS_DISPLAY_SETTINGS {
map_display_settings.insert(s.replace("_", "-"), s);
}
let mut map_local_settings = HashMap::new();
for s in config::keys::KEYS_LOCAL_SETTINGS {
for s in keys::KEYS_LOCAL_SETTINGS {
map_local_settings.insert(s.replace("_", "-"), s);
}
let mut map_settings = HashMap::new();
for s in config::keys::KEYS_SETTINGS {
for s in keys::KEYS_SETTINGS {
map_settings.insert(s.replace("_", "-"), s);
}
let mut buildin_settings = HashMap::new();
for s in config::keys::KEYS_BUILDIN_SETTINGS {
for s in keys::KEYS_BUILDIN_SETTINGS {
buildin_settings.insert(s.replace("_", "-"), s);
}
if let Some(default_settings) = data.remove("default-settings") {
@@ -1725,7 +1752,7 @@ pub fn verify_login(raw: &str, id: &str) -> bool {
#[inline]
pub fn is_udp_disabled() -> bool {
get_builtin_option(config::keys::OPTION_DISABLE_UDP) == "Y"
get_builtin_option(keys::OPTION_DISABLE_UDP) == "Y"
}
// this crate https://github.com/yoshd/stun-client supports nat type

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "سرعة لوحة التتبع"),
("Default trackpad speed", "سرعة لوحة التتبع الافتراضية"),
("Numeric one-time password", "كلمة مرور رقمية لمرة واحدة"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "触控板速度"),
("Default trackpad speed", "默认触控板速度"),
("Numeric one-time password", "一次性密码为数字"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Geschwindigkeit des Trackpads"),
("Default trackpad speed", "Standardgeschwindigkeit des Trackpads"),
("Numeric one-time password", "Numerisches Einmalpasswort"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Velocidad de trackpad"),
("Default trackpad speed", "Velocidad predeterminada de trackpad"),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "سرعت ترک‌پد"),
("Default trackpad speed", "سرعت پیش‌فرض ترک‌پد"),
("Numeric one-time password", "رمز عبور یک‌بار مصرف عددی"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Vitesse du pavé tactile"),
("Default trackpad speed", "Vitesse par défaut du pavé tactile"),
("Numeric one-time password", "Mot de passe à usage unique numérique"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "מהירות משטח מגע"),
("Default trackpad speed", "מהירות ברירת מחדל של משטח מגע"),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Érintőpad sebessége"),
("Default trackpad speed", "Alapértelmezett érintőpad sebessége"),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Velocità trackpad"),
("Default trackpad speed", "Velocità predefinita trackpad"),
("Numeric one-time password", "Password numerica monouso"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -690,7 +690,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable remote printer", "원격 프린터 활성화"),
("Downloading {}", "{} 다운로드 중"),
("{} Update", "{} 업데이트"),
("update_to_{}_tip", "{} 버전으로 업데이트합니다. 프로그램 종료 후 새 버전이 설치됩니다."),
("{}-to-update-tip", ""),
("download-new-version-failed-tip", "다운로드에 실패했습니다. 다시 시도하거나 '다운로드' 버튼을 클릭하여 릴리스 페이지에서 직접 다운로드한 후 수동으로 업그레이드하십시오."),
("Auto update", "자동 업데이트"),
("update-failed-check-msi-tip", "설치 방법을 확인할 수 없습니다. '다운로드' 버튼을 클릭하여 릴리스 페이지에서 직접 다운로드한 후 수동으로 업그레이드하십시오."),
@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "트랙패드 속도"),
("Default trackpad speed", "기본 트랙패드 속도"),
("Numeric one-time password", "일회용 비밀번호"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Skārienpaliktņa ātrums"),
("Default trackpad speed", "Noklusējuma skārienpaliktņa ātrums"),
("Numeric one-time password", "Vienreiz lietojama ciparu parole"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Snelheid Trackpad"),
("Default trackpad speed", "Standaardsnelheid Trackpad"),
("Numeric one-time password", "Eenmalig numeriek wachtwoord"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "Скорость трекпада"),
("Default trackpad speed", "Скорость трекпада по умолчанию"),
("Numeric one-time password", "Цифровой одноразовый пароль"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", "觸控板速度"),
("Default trackpad speed", "預設觸控板速度"),
("Numeric one-time password", "數字一次性密碼"),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -699,5 +699,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Trackpad speed", ""),
("Default trackpad speed", ""),
("Numeric one-time password", ""),
("Enable IPv6 P2P connection", ""),
("Enable UDP hole punching", ""),
].iter().cloned().collect();
}

View File

@@ -4,7 +4,7 @@ use hbb_common::{
allow_err,
bytes::Bytes,
config::{
self, keys::*, option2bool, Config, LocalConfig, PeerConfig, CONNECT_TIMEOUT,
self, keys::*, Config, LocalConfig, PeerConfig, CONNECT_TIMEOUT,
RENDEZVOUS_PORT,
},
directories_next,
@@ -208,7 +208,7 @@ pub fn use_texture_render() -> bool {
#[inline]
pub fn get_local_option(key: String) -> String {
LocalConfig::get_option(&key)
crate::get_local_option(&key)
}
#[inline]
@@ -1185,7 +1185,7 @@ async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver<ipc:
{
let b = OPTIONS.lock().unwrap().get(OPTION_ENABLE_FILE_TRANSFER).map(|x| x.to_string()).unwrap_or_default();
if b != enable_file_transfer {
clipboard::ContextSend::enable(option2bool(OPTION_ENABLE_FILE_TRANSFER, &b));
clipboard::ContextSend::enable(config::option2bool(OPTION_ENABLE_FILE_TRANSFER, &b));
enable_file_transfer = b;
}
}