From 1e00d09f840e25c552b80a63a078c51c26fdf8f1 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 24 Aug 2026 17:30:25 +0800 Subject: [PATCH] feat: make the TCP punch a user option, with TCP as the backstop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TCP punching was the one direct transport without a switch, while UDP, IPv6 and WebRTC each had one. Add "Enable TCP hole punching" above the UDP toggle on both desktop and mobile, default on — including on self-hosted servers, since unlike the other three (whose default-off there guards against an hbbs that cannot forward their fields) TCP punching has always been supported by every server. Turning all four off would leave no way to punch at all, so TCP runs regardless in that case. That backstop keys off the switches alone: a transport that is enabled but fails to materialize — no public v6 address, no NAT port, a failed offerer — is already covered by the relay fallback for a round that ends up with no usable direct transport. With the TCP punch off, the fallback request is skipped too: it exists only to carry that punch, and would otherwise reach connect() with nothing to try and merely open a second relay. Known cost, unchanged behavior for the peer: the request carries no field for this choice, so a peer that receives one with no udp_port and no offer still punches a TCP hole and listens for a connection the controller will not make. Representing the transport choice on the wire needs a proto field and the server forwarding it. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_016HV43uh1ztv6Wm5qi3Y1ne --- flutter/lib/consts.dart | 1 + .../desktop/pages/desktop_setting_page.dart | 6 ++ flutter/lib/mobile/pages/settings_page.dart | 70 +++++++++++++------ libs/hbb_common | 2 +- src/client.rs | 22 +++++- src/common.rs | 7 ++ src/lang/ar.rs | 1 + src/lang/be.rs | 1 + src/lang/bg.rs | 1 + src/lang/ca.rs | 1 + src/lang/cn.rs | 1 + src/lang/cs.rs | 1 + src/lang/da.rs | 1 + src/lang/de.rs | 1 + src/lang/el.rs | 1 + src/lang/eo.rs | 1 + src/lang/es.rs | 1 + src/lang/et.rs | 1 + src/lang/eu.rs | 1 + src/lang/fa.rs | 1 + src/lang/fi.rs | 1 + src/lang/fr.rs | 1 + src/lang/ge.rs | 1 + src/lang/gu.rs | 1 + src/lang/he.rs | 1 + src/lang/hi.rs | 1 + src/lang/hr.rs | 1 + src/lang/hu.rs | 1 + src/lang/id.rs | 1 + src/lang/it.rs | 1 + src/lang/ja.rs | 1 + src/lang/ko.rs | 1 + src/lang/kz.rs | 1 + src/lang/lt.rs | 1 + src/lang/lv.rs | 1 + src/lang/ml.rs | 1 + src/lang/nb.rs | 1 + src/lang/nl.rs | 1 + src/lang/pl.rs | 1 + src/lang/pt_PT.rs | 1 + src/lang/ptbr.rs | 1 + src/lang/ro.rs | 1 + src/lang/ru.rs | 1 + src/lang/sc.rs | 1 + src/lang/sk.rs | 1 + src/lang/sl.rs | 1 + src/lang/sq.rs | 1 + src/lang/sr.rs | 1 + src/lang/sv.rs | 1 + src/lang/ta.rs | 1 + src/lang/template.rs | 1 + src/lang/th.rs | 1 + src/lang/tr.rs | 1 + src/lang/tw.rs | 1 + src/lang/uk.rs | 1 + src/lang/vi.rs | 1 + 56 files changed, 132 insertions(+), 26 deletions(-) diff --git a/flutter/lib/consts.dart b/flutter/lib/consts.dart index eb07852f6..aff0d3c92 100644 --- a/flutter/lib/consts.dart +++ b/flutter/lib/consts.dart @@ -166,6 +166,7 @@ const String kOptionAllowRemoveWallpaper = "allow-remove-wallpaper"; const String kOptionStopService = "stop-service"; const String kOptionDirectxCapture = "enable-directx-capture"; const String kOptionAllowRemoteCmModification = "allow-remote-cm-modification"; +const String kOptionEnableTcpPunch = "enable-tcp-punch"; const String kOptionEnableUdpPunch = "enable-udp-punch"; const String kOptionEnableIpv6Punch = "enable-ipv6-punch"; const String kOptionAllowSyncClipboardBetweenSessions = diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index b1efa463a..63a1e5a73 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -563,6 +563,12 @@ class _GeneralState extends State<_General> { kOptionDirectxCapture, ), if (!isWeb && !incomingOnly) ...[ + _OptionCheckBox( + context, + 'Enable TCP hole punching', + kOptionEnableTcpPunch, + isServer: false, + ), _OptionCheckBox( context, 'Enable UDP hole punching', diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index d42818637..e630d161e 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -97,6 +97,7 @@ class _SettingsState extends State with WidgetsBindingObserver { var _hideNetwork = false; var _hideWebSocket = false; var _enableTrustedDevices = false; + var _enableTcpPunch = false; var _enableUdpPunch = false; var _allowInsecureTlsFallback = false; var _disableUdp = false; @@ -142,6 +143,7 @@ class _SettingsState extends State with WidgetsBindingObserver { bind.mainGetBuildinOption(key: kOptionHideWebSocketSetting) == 'Y' || isWeb; _enableTrustedDevices = mainGetBoolOptionSync(kOptionEnableTrustedDevices); + _enableTcpPunch = mainGetLocalBoolOptionSync(kOptionEnableTcpPunch); _enableUdpPunch = mainGetLocalBoolOptionSync(kOptionEnableUdpPunch); _enableIpv6Punch = mainGetLocalBoolOptionSync(kOptionEnableIpv6Punch); _enableWebrtc = mainGetLocalBoolOptionSync(kOptionEnableWebrtc); @@ -817,43 +819,65 @@ class _SettingsState extends State with WidgetsBindingObserver { }); }, ), + if (!incomingOnly) + SettingsTile.switchTile( + title: Text(translate('Enable TCP hole punching')), + initialValue: _enableTcpPunch, + onToggle: isOptionFixed(kOptionEnableTcpPunch) + ? null + : (v) async { + await mainSetLocalBoolOption(kOptionEnableTcpPunch, v); + final newValue = + mainGetLocalBoolOptionSync(kOptionEnableTcpPunch); + setState(() { + _enableTcpPunch = newValue; + }); + }, + ), if (!incomingOnly) SettingsTile.switchTile( title: Text(translate('Enable UDP hole punching')), initialValue: _enableUdpPunch, - onToggle: (v) async { - await mainSetLocalBoolOption(kOptionEnableUdpPunch, v); - final newValue = - mainGetLocalBoolOptionSync(kOptionEnableUdpPunch); - setState(() { - _enableUdpPunch = newValue; - }); - }, + onToggle: isOptionFixed(kOptionEnableUdpPunch) + ? null + : (v) async { + await mainSetLocalBoolOption(kOptionEnableUdpPunch, v); + final newValue = + mainGetLocalBoolOptionSync(kOptionEnableUdpPunch); + setState(() { + _enableUdpPunch = newValue; + }); + }, ), if (!incomingOnly) SettingsTile.switchTile( title: Text(translate('Enable IPv6 P2P connection')), initialValue: _enableIpv6Punch, - onToggle: (v) async { - await mainSetLocalBoolOption(kOptionEnableIpv6Punch, v); - final newValue = - mainGetLocalBoolOptionSync(kOptionEnableIpv6Punch); - setState(() { - _enableIpv6Punch = newValue; - }); - }, + onToggle: isOptionFixed(kOptionEnableIpv6Punch) + ? null + : (v) async { + await mainSetLocalBoolOption(kOptionEnableIpv6Punch, v); + final newValue = + mainGetLocalBoolOptionSync(kOptionEnableIpv6Punch); + setState(() { + _enableIpv6Punch = newValue; + }); + }, ), if (!incomingOnly) SettingsTile.switchTile( title: Text(translate('Enable WebRTC P2P connection')), initialValue: _enableWebrtc, - onToggle: (v) async { - await mainSetLocalBoolOption(kOptionEnableWebrtc, v); - final newValue = mainGetLocalBoolOptionSync(kOptionEnableWebrtc); - setState(() { - _enableWebrtc = newValue; - }); - }, + onToggle: isOptionFixed(kOptionEnableWebrtc) + ? null + : (v) async { + await mainSetLocalBoolOption(kOptionEnableWebrtc, v); + final newValue = + mainGetLocalBoolOptionSync(kOptionEnableWebrtc); + setState(() { + _enableWebrtc = newValue; + }); + }, ), SettingsTile( title: Text(translate('Language')), diff --git a/libs/hbb_common b/libs/hbb_common index 01ee2f46e..db7723efa 160000 --- a/libs/hbb_common +++ b/libs/hbb_common @@ -1 +1 @@ -Subproject commit 01ee2f46ece493110510b8d8b5ca019488f33f7a +Subproject commit db7723efa1021fcba6fb78e23799242d5dd1f804 diff --git a/src/client.rs b/src/client.rs index 219117ff0..44e2295b1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -334,6 +334,18 @@ fn request_allows_tcp_punch(webrtc_sdp_offer: &str) -> bool { webrtc_sdp_offer.is_empty() } +/// TCP punch is a user option like the other direct transports, but it is also the backstop: +/// with every direct transport switched off there would be nothing left to punch with, so it +/// runs regardless. Only the switches decide that — a transport that is enabled but fails to +/// materialize (no public v6 address, offerer setup error) leaves this alone, because the +/// relay fallback already covers a round that ends up with no usable direct transport. +fn tcp_punch_allowed() -> bool { + crate::get_tcp_punch_enabled() + || !(crate::get_udp_punch_enabled() + || crate::get_ipv6_punch_enabled() + || crate::get_webrtc_enabled()) +} + impl Client { const CLIENT_CLIPBOARD_NAME: &'static str = "client-clipboard"; @@ -521,7 +533,13 @@ impl Client { servers.clone(), contained, ); - if interface.is_force_relay() || (udp.0.is_none() && !has_webrtc_offerer) { + // The fallback request exists only to carry a TCP punch, so it is pointless once TCP + // punch is off — it would reach `connect()` with nothing to try and just open a second + // relay. + if interface.is_force_relay() + || (udp.0.is_none() && !has_webrtc_offerer) + || !tcp_punch_allowed() + { return fut.await; } let preferred_fut = fut.boxed(); @@ -849,7 +867,7 @@ impl Client { } else { String::new() }; - let allow_tcp_punch = request_allows_tcp_punch(&webrtc_sdp_offer); + let allow_tcp_punch = tcp_punch_allowed() && request_allows_tcp_punch(&webrtc_sdp_offer); let punch_type = if udp_nat_port > 0 { "UDP" } else if allow_tcp_punch { diff --git a/src/common.rs b/src/common.rs index 3b8e9c8da..9eaaacb2c 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1153,6 +1153,13 @@ pub fn is_public(url: &str) -> bool { host == "rustdesk.com" || host.ends_with(".rustdesk.com") } +pub fn get_tcp_punch_enabled() -> bool { + config::option2bool( + keys::OPTION_ENABLE_TCP_PUNCH, + &get_local_option(keys::OPTION_ENABLE_TCP_PUNCH), + ) +} + pub fn get_udp_punch_enabled() -> bool { config::option2bool( keys::OPTION_ENABLE_UDP_PUNCH, diff --git a/src/lang/ar.rs b/src/lang/ar.rs index 9b8a1c9e7..246be45bd 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "مزامنة الحافظة بين الجلسات"), ("sync-clipboard-between-sessions-tip", "النص أو الصور المنسوخة في جلسة بعيدة واحدة تُرسَل أيضًا إلى حافظة جلساتك المتصلة الأخرى."), ("Enable WebRTC P2P connection", "تمكين اتصال نظير إلى نظير عبر WebRTC"), + ("Enable TCP hole punching", "تمكين تقنية حفر الثغرات عبر TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/be.rs b/src/lang/be.rs index de45fed67..3dd8cb6d8 100644 --- a/src/lang/be.rs +++ b/src/lang/be.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Сінхранізаваць буфер абмену паміж сеансамі"), ("sync-clipboard-between-sessions-tip", "Тэкст або відарысы, скапіяваныя ў адным аддаленым сеансе, таксама адпраўляюцца ў буфер абмену іншых вашых падключаных сеансаў."), ("Enable WebRTC P2P connection", "Выкарыстоўваць падключэнне WebRTC P2P"), + ("Enable TCP hole punching", "Выкарыстоўваць TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/bg.rs b/src/lang/bg.rs index 8f9369f7d..0d4b3dc28 100644 --- a/src/lang/bg.rs +++ b/src/lang/bg.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Синхронизиране на клипборда между сесиите"), ("sync-clipboard-between-sessions-tip", "Текст или изображения, копирани в една отдалечена сесия, се изпращат и към клипборда на другите ви свързани сесии."), ("Enable WebRTC P2P connection", "Позволяване на WebRTC P2P връзка"), + ("Enable TCP hole punching", "Позволяване на TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index ae6d5a44d..a2c4d9f93 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincronitza el porta-retalls entre sessions"), ("sync-clipboard-between-sessions-tip", "El text o les imatges copiats en una sessió remota també s'envien al porta-retalls de les altres sessions connectades."), ("Enable WebRTC P2P connection", "Habilita la connexió WebRTC P2P"), + ("Enable TCP hole punching", "Activa la perforació TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 5551babcb..ee024d795 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "在会话间同步剪贴板"), ("sync-clipboard-between-sessions-tip", "在一个远程会话中复制的文本或图片也会发送到其他已连接会话的剪贴板。"), ("Enable WebRTC P2P connection", "启用 WebRTC P2P 连接"), + ("Enable TCP hole punching", "启用 TCP 打洞"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 9c907cbe2..887a33a0a 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synchronizovat schránku mezi relacemi"), ("sync-clipboard-between-sessions-tip", "Text nebo obrázky zkopírované v jedné vzdálené relaci se odešlou i do schránky ostatních připojených relací."), ("Enable WebRTC P2P connection", "Povolit připojení WebRTC P2P"), + ("Enable TCP hole punching", "Povolit TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 7357f4a43..a469d4cde 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synkroniser udklipsholder mellem sessioner"), ("sync-clipboard-between-sessions-tip", "Tekst eller billeder, der kopieres i én fjernsession, sendes også til udklipsholderen i dine andre forbundne sessioner."), ("Enable WebRTC P2P connection", "Aktivér WebRTC P2P-forbindelse"), + ("Enable TCP hole punching", "Aktivér TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 2852a093f..2ed2539a2 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Zwischenablage zwischen Sitzungen synchronisieren"), ("sync-clipboard-between-sessions-tip", "In einer Remote-Sitzung kopierter Text oder kopierte Bilder werden auch an die Zwischenablage Ihrer anderen verbundenen Sitzungen gesendet."), ("Enable WebRTC P2P connection", "WebRTC-P2P-Verbindung aktivieren"), + ("Enable TCP hole punching", "TCP-Hole-Punching aktivieren"), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index e21a7b7ae..f2b4ea9b0 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Συγχρονισμός προχείρου μεταξύ συνεδριών"), ("sync-clipboard-between-sessions-tip", "Κείμενο ή εικόνες που αντιγράφονται σε μία απομακρυσμένη συνεδρία αποστέλλονται και στο πρόχειρο των άλλων συνδεδεμένων συνεδριών σας."), ("Enable WebRTC P2P connection", "Ενεργοποίηση σύνδεσης WebRTC P2P"), + ("Enable TCP hole punching", "Ενεργοποίηση διάτρησης οπών TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 2ba817e78..96611de92 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinkronigi poŝon inter seancoj"), ("sync-clipboard-between-sessions-tip", "Teksto aŭ bildoj kopiitaj en unu fora seanco ankaŭ sendiĝas al la poŝo de viaj aliaj konektitaj seancoj."), ("Enable WebRTC P2P connection", "Ebligi WebRTC P2P-konekton"), + ("Enable TCP hole punching", "Ebligi TCP-trapikadon"), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 6259d5117..d51c077fb 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincronizar portapapeles entre sesiones"), ("sync-clipboard-between-sessions-tip", "El texto o las imágenes copiados en una sesión remota también se envían al portapapeles de tus otras sesiones conectadas."), ("Enable WebRTC P2P connection", "Habilitar conexión WebRTC P2P"), + ("Enable TCP hole punching", "Habilitar perforación de agujero TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/et.rs b/src/lang/et.rs index 86477f1f1..4c7fc56bc 100644 --- a/src/lang/et.rs +++ b/src/lang/et.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sünkrooni lõikelaud seansside vahel"), ("sync-clipboard-between-sessions-tip", "Ühes kaugseansis kopeeritud tekst või pildid saadetakse ka teiste ühendatud seansside lõikelauale."), ("Enable WebRTC P2P connection", "Luba WebRTC P2P-ühendus"), + ("Enable TCP hole punching", "Luba TCP-augustamine"), ].iter().cloned().collect(); } diff --git a/src/lang/eu.rs b/src/lang/eu.rs index 186e65a18..9392be918 100644 --- a/src/lang/eu.rs +++ b/src/lang/eu.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinkronizatu arbela saioen artean"), ("sync-clipboard-between-sessions-tip", "Urruneko saio batean kopiatutako testua edo irudiak konektatutako beste saioen arbelera ere bidaltzen dira."), ("Enable WebRTC P2P connection", "Gaitu WebRTC P2P konexioa"), + ("Enable TCP hole punching", "Gaitu TCP zulo-egitea"), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 63ffb88d8..58b45e8ed 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "همگام‌سازی کلیپ‌بورد بین نشست‌ها"), ("sync-clipboard-between-sessions-tip", "متن یا تصاویری که در یک نشست راه دور کپی می‌شوند به کلیپ‌بورد سایر نشست‌های متصل شما نیز ارسال می‌شوند."), ("Enable WebRTC P2P connection", "فعال‌سازی اتصال همتا‌به‌همتای WebRTC"), + ("Enable TCP hole punching", "فعال‌سازی تکنیک TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/fi.rs b/src/lang/fi.rs index 21feb76bb..589cd9d94 100644 --- a/src/lang/fi.rs +++ b/src/lang/fi.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synkronoi leikepöytä istuntojen välillä"), ("sync-clipboard-between-sessions-tip", "Yhdessä etäistunnossa kopioitu teksti tai kuvat lähetetään myös muiden yhdistettyjen istuntojen leikepöydälle."), ("Enable WebRTC P2P connection", "Ota WebRTC P2P yhteys käyttöön"), + ("Enable TCP hole punching", "Ota käyttöön TCP hole punching tekniikka"), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 1eae1e22b..2d26526d0 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synchroniser le presse-papiers entre les sessions"), ("sync-clipboard-between-sessions-tip", "Le texte ou les images copiés dans une session distante sont également envoyés au presse-papiers de vos autres sessions connectées."), ("Enable WebRTC P2P connection", "Activer la connexion P2P WebRTC"), + ("Enable TCP hole punching", "Activer le « hole punching » TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/ge.rs b/src/lang/ge.rs index dd45d5b20..942cb0656 100644 --- a/src/lang/ge.rs +++ b/src/lang/ge.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "გაცვლის ბუფერის სინქრონიზაცია სესიებს შორის"), ("sync-clipboard-between-sessions-tip", "ერთ დაშორებულ სესიაში დაკოპირებული ტექსტი ან სურათები ასევე იგზავნება თქვენი სხვა დაკავშირებული სესიების გაცვლის ბუფერში."), ("Enable WebRTC P2P connection", "WebRTC P2P კავშირის ჩართვა"), + ("Enable TCP hole punching", "TCP hole punching-ის ჩართვა"), ].iter().cloned().collect(); } diff --git a/src/lang/gu.rs b/src/lang/gu.rs index 879fe5ec9..15526029b 100644 --- a/src/lang/gu.rs +++ b/src/lang/gu.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "સત્રો વચ્ચે ક્લિપબોર્ડ સિંક કરો"), ("sync-clipboard-between-sessions-tip", "એક રિમોટ સત્રમાં કૉપિ કરેલ ટેક્સ્ટ કે છબીઓ તમારા અન્ય જોડાયેલા સત્રોના ક્લિપબોર્ડ પર પણ મોકલવામાં આવે છે."), ("Enable WebRTC P2P connection", "WebRTC P2P કનેક્શન સક્ષમ કરો"), + ("Enable TCP hole punching", "TCP હોલ પંચિંગ સક્ષમ કરો"), ].iter().cloned().collect(); } diff --git a/src/lang/he.rs b/src/lang/he.rs index bd7ea8153..9bf16e7f2 100644 --- a/src/lang/he.rs +++ b/src/lang/he.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "סנכרן לוח בין סשנים"), ("sync-clipboard-between-sessions-tip", "טקסט או תמונות שהועתקו בסשן מרוחק אחד נשלחים גם ללוח של שאר הסשנים המחוברים שלך."), ("Enable WebRTC P2P connection", "אפשר חיבור WebRTC P2P"), + ("Enable TCP hole punching", "אפשר TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/hi.rs b/src/lang/hi.rs index f80a678b2..53c76571b 100644 --- a/src/lang/hi.rs +++ b/src/lang/hi.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "सत्रों के बीच क्लिपबोर्ड सिंक करें"), ("sync-clipboard-between-sessions-tip", "एक रिमोट सत्र में कॉपी किए गए टेक्स्ट या चित्र आपके अन्य जुड़े सत्रों के क्लिपबोर्ड पर भी भेजे जाते हैं।"), ("Enable WebRTC P2P connection", "WebRTC P2P कनेक्शन सक्षम करें"), + ("Enable TCP hole punching", "TCP होल पंचिंग सक्षम करें"), ].iter().cloned().collect(); } diff --git a/src/lang/hr.rs b/src/lang/hr.rs index 5f762f59f..b4ce88845 100644 --- a/src/lang/hr.rs +++ b/src/lang/hr.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinkroniziraj međuspremnik između sesija"), ("sync-clipboard-between-sessions-tip", "Tekst ili slike kopirani u jednoj udaljenoj sesiji šalju se i u međuspremnik vaših ostalih povezanih sesija."), ("Enable WebRTC P2P connection", "Omogući WebRTC P2P vezu"), + ("Enable TCP hole punching", "Omogući TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 3d3d73398..354830bbc 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Vágólap szinkronizálása a munkamenetek között"), ("sync-clipboard-between-sessions-tip", "Az egyik távoli munkamenetben másolt szöveg vagy kép a többi csatlakoztatott munkamenet vágólapjára is elküldésre kerül."), ("Enable WebRTC P2P connection", "WebRTC P2P kapcsolat engedélyezése"), + ("Enable TCP hole punching", "TCP résszűrés engedélyezése"), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 0212d1aa7..38962d0d7 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinkronkan papan klip antar sesi"), ("sync-clipboard-between-sessions-tip", "Teks atau gambar yang disalin di satu sesi jarak jauh juga dikirim ke papan klip sesi terhubung Anda yang lain."), ("Enable WebRTC P2P connection", "Aktifkan koneksi P2P WebRTC"), + ("Enable TCP hole punching", "Aktifkan TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index ec74d5725..dd3c92095 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincronizza gli appunti tra le sessioni"), ("sync-clipboard-between-sessions-tip", "Il testo o le immagini copiati in una sessione remota vengono inviati anche agli appunti delle altre sessioni connesse."), ("Enable WebRTC P2P connection", "Abilita connessione P2P WebRTC"), + ("Enable TCP hole punching", "Abilita hole punching TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index b13166aff..69a027503 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "セッション間でクリップボードを同期"), ("sync-clipboard-between-sessions-tip", "1つのリモートセッションでコピーしたテキストや画像は、接続中の他のセッションのクリップボードにも送信されます。"), ("Enable WebRTC P2P connection", "WebRTC P2P 接続を有効化する"), + ("Enable TCP hole punching", "TCP ホールパンチを有効化する"), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 4fdfd392e..642276a24 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "세션 간 클립보드 동기화"), ("sync-clipboard-between-sessions-tip", "하나의 원격 세션에서 복사한 텍스트나 이미지는 연결된 다른 세션의 클립보드에도 전송됩니다."), ("Enable WebRTC P2P connection", "WebRTC P2P 연결 사용"), + ("Enable TCP hole punching", "TCP 홀 펀칭 사용"), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 9c54585ee..4a2dc39e4 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Сеанстар арасында көшіру-тақтасын синхрондау"), ("sync-clipboard-between-sessions-tip", "Бір қашықтағы сеанста көшірілген мәтін немесе суреттер басқа қосылған сеанстардың көшіру-тақтасына да жіберіледі."), ("Enable WebRTC P2P connection", "WebRTC P2P қосылымын іске қосу"), + ("Enable TCP hole punching", "TCP hole punching'ті іске қосу"), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index ccc1bf1a3..bd9138116 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinchronizuoti iškarpinę tarp seansų"), ("sync-clipboard-between-sessions-tip", "Viename nuotoliniame seanse nukopijuotas tekstas ar vaizdai taip pat siunčiami į kitų prijungtų seansų iškarpinę."), ("Enable WebRTC P2P connection", "Įgalinti WebRTC P2P ryšį"), + ("Enable TCP hole punching", "Įgalinti TCP gręžimą (hole punching)"), ].iter().cloned().collect(); } diff --git a/src/lang/lv.rs b/src/lang/lv.rs index e9055e637..762334378 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinhronizēt starpliktuvi starp sesijām"), ("sync-clipboard-between-sessions-tip", "Vienā attālajā sesijā nokopētais teksts vai attēli tiek nosūtīti arī uz pārējo pievienoto sesiju starpliktuvi."), ("Enable WebRTC P2P connection", "Iespējot WebRTC P2P savienojumu"), + ("Enable TCP hole punching", "Iespējot TCP caurumu veidošanu"), ].iter().cloned().collect(); } diff --git a/src/lang/ml.rs b/src/lang/ml.rs index e7737fd13..fce884abe 100644 --- a/src/lang/ml.rs +++ b/src/lang/ml.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "സെഷനുകൾക്കിടയിൽ ക്ലിപ്പ്ബോർഡ് സമന്വയിപ്പിക്കുക"), ("sync-clipboard-between-sessions-tip", "ഒരു റിമോട്ട് സെഷനിൽ പകർത്തിയ ടെക്സ്റ്റോ ചിത്രങ്ങളോ നിങ്ങളുടെ മറ്റ് കണക്റ്റുചെയ്ത സെഷനുകളുടെ ക്ലിപ്പ്ബോർഡിലേക്കും അയയ്ക്കപ്പെടും."), ("Enable WebRTC P2P connection", "WebRTC P2P കണക്ഷൻ അനുവദിക്കുക"), + ("Enable TCP hole punching", "TCP ഹോൾ പഞ്ചിംഗ് അനുവദിക്കുക"), ].iter().cloned().collect(); } diff --git a/src/lang/nb.rs b/src/lang/nb.rs index 198c329a1..e5bf3544b 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synkroniser utklippstavlen mellom økter"), ("sync-clipboard-between-sessions-tip", "Tekst eller bilder som kopieres i én ekstern økt, sendes også til utklippstavlen i de andre tilkoblede øktene dine."), ("Enable WebRTC P2P connection", "Aktiver WebRTC P2P-tilkobling"), + ("Enable TCP hole punching", "Aktiver TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 2cf3a4b63..09ab5c1a1 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Klembord synchroniseren tussen sessies"), ("sync-clipboard-between-sessions-tip", "Tekst of afbeeldingen die in één externe sessie worden gekopieerd, worden ook naar het klembord van uw andere verbonden sessies gestuurd."), ("Enable WebRTC P2P connection", "WebRTC P2P-verbinding inschakelen"), + ("Enable TCP hole punching", "TCP-hole punching inschakelen"), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 548163a6f..c3b7b2023 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synchronizuj schowek między sesjami"), ("sync-clipboard-between-sessions-tip", "Tekst lub obrazy skopiowane w jednej sesji zdalnej są wysyłane także do schowka pozostałych połączonych sesji."), ("Enable WebRTC P2P connection", "Włącz połączenie P2P WebRTC"), + ("Enable TCP hole punching", "Włącz tworzenie tunelu TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 192e9ab50..805bea14d 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincronizar área de transferência entre sessões"), ("sync-clipboard-between-sessions-tip", "O texto ou as imagens copiados numa sessão remota também são enviados para a área de transferência das suas outras sessões ligadas."), ("Enable WebRTC P2P connection", "Ativar ligação P2P por WebRTC"), + ("Enable TCP hole punching", "Ativar TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index f74f1bb67..115feb2b2 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincronizar área de transferência entre sessões"), ("sync-clipboard-between-sessions-tip", "Texto ou imagens copiados em uma sessão remota também são enviados para a área de transferência das suas outras sessões conectadas."), ("Enable WebRTC P2P connection", "Habilitar conexão WebRTC P2P"), + ("Enable TCP hole punching", "Habilitar TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index a41280ead..4abf4af3a 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincronizează clipboardul între sesiuni"), ("sync-clipboard-between-sessions-tip", "Textul sau imaginile copiate într-o sesiune la distanță sunt trimise și în clipboardul celorlalte sesiuni conectate."), ("Enable WebRTC P2P connection", "Activează conexiunea P2P prin WebRTC"), + ("Enable TCP hole punching", "Activează traversarea TCP (hole punching)"), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 20f0dd9e9..3b2f3a220 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Синхронизировать буфер обмена между сеансами"), ("sync-clipboard-between-sessions-tip", "Текст или изображения, скопированные в одном удалённом сеансе, также отправляются в буфер обмена других подключённых сеансов."), ("Enable WebRTC P2P connection", "Использовать подключение WebRTC P2P"), + ("Enable TCP hole punching", "Использовать TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/sc.rs b/src/lang/sc.rs index 8174e7b7d..729e08b87 100644 --- a/src/lang/sc.rs +++ b/src/lang/sc.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sincroniza sa punta de billete intre is sessiones"), ("sync-clipboard-between-sessions-tip", "Su testu o is immàgines copiadas in una sessione remota sunt imbiadas fintzas a sa punta de billete de is àteras sessiones connètidas."), ("Enable WebRTC P2P connection", "Abìlita connessione P2P WebRTC"), + ("Enable TCP hole punching", "Abìlita s'istampadura TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 361f62d6a..803bd0144 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synchronizovať schránku medzi reláciami"), ("sync-clipboard-between-sessions-tip", "Text alebo obrázky skopírované v jednej vzdialenej relácii sa odošlú aj do schránky ostatných pripojených relácií."), ("Enable WebRTC P2P connection", "Povoliť pripojenie WebRTC P2P"), + ("Enable TCP hole punching", "Povoliť TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index c7e183c78..a40150ded 100644 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinhroniziraj odložišče med sejami"), ("sync-clipboard-between-sessions-tip", "Besedilo ali slike, kopirane v eni oddaljeni seji, se pošljejo tudi v odložišče vaših drugih povezanih sej."), ("Enable WebRTC P2P connection", "Omogoči povezavo WebRTC P2P"), + ("Enable TCP hole punching", "Omogoči preboj lukenj TCP"), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index ae51db01b..d8428c108 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinkronizo clipboard-in midis sesioneve"), ("sync-clipboard-between-sessions-tip", "Teksti ose imazhet e kopjuara në një sesion të largët dërgohen edhe në clipboard-in e sesioneve të tjera të lidhura."), ("Enable WebRTC P2P connection", "Aktivizo lidhjen WebRTC P2P"), + ("Enable TCP hole punching", "Aktivizo TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 6cbe711ef..793df0b56 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Sinhronizuj klipbord između sesija"), ("sync-clipboard-between-sessions-tip", "Tekst ili slike kopirane u jednoj udaljenoj sesiji šalju se i u klipbord vaših ostalih povezanih sesija."), ("Enable WebRTC P2P connection", "Omogući WebRTC P2P konekciju"), + ("Enable TCP hole punching", "Omogući TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 42a7bc218..637a4d903 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Synkronisera urklipp mellan sessioner"), ("sync-clipboard-between-sessions-tip", "Text eller bilder som kopieras i en fjärrsession skickas även till urklipp i dina andra anslutna sessioner."), ("Enable WebRTC P2P connection", "Aktivera WebRTC P2P anslutning"), + ("Enable TCP hole punching", "Aktivera TCP hålslagning"), ].iter().cloned().collect(); } diff --git a/src/lang/ta.rs b/src/lang/ta.rs index 8f4b97e60..96788bb9f 100644 --- a/src/lang/ta.rs +++ b/src/lang/ta.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "அமர்வுகளுக்கு இடையே கிளிப்போர்டை ஒத்திசைக்கவும்"), ("sync-clipboard-between-sessions-tip", "ஒரு தொலை அமர்வில் நகலெடுக்கப்பட்ட உரை அல்லது படங்கள் உங்கள் பிற இணைக்கப்பட்ட அமர்வுகளின் கிளிப்போர்டுக்கும் அனுப்பப்படும்."), ("Enable WebRTC P2P connection", "WebRTC P2P இணைப்பு இயக்கு"), + ("Enable TCP hole punching", "TCP hole punching இயக்கு"), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 9a4fb737e..145e10c08 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", ""), ("sync-clipboard-between-sessions-tip", ""), ("Enable WebRTC P2P connection", ""), + ("Enable TCP hole punching", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 4f16acf86..99981a449 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "ซิงค์คลิปบอร์ดระหว่างเซสชัน"), ("sync-clipboard-between-sessions-tip", "ข้อความหรือรูปภาพที่คัดลอกในเซสชันระยะไกลหนึ่งจะถูกส่งไปยังคลิปบอร์ดของเซสชันอื่นที่เชื่อมต่ออยู่ด้วย"), ("Enable WebRTC P2P connection", "เปิดใช้งานการเชื่อมต่อ P2P แบบ WebRTC"), + ("Enable TCP hole punching", "เปิดใช้งาน TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index cbbbb0aa6..1df1bacb2 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Oturumlar arasında panoyu senkronize et"), ("sync-clipboard-between-sessions-tip", "Bir uzak oturumda kopyalanan metin veya görseller, bağlı diğer oturumlarınızın panosuna da gönderilir."), ("Enable WebRTC P2P connection", "WebRTC P2P bağlantısını etkinleştir"), + ("Enable TCP hole punching", "TCP delik açmayı etkinleştir"), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 5f9d05565..64673d9a8 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "在工作階段間同步剪貼簿"), ("sync-clipboard-between-sessions-tip", "在一個遠端工作階段中複製的文字或圖片也會傳送到其他已連線工作階段的剪貼簿。"), ("Enable WebRTC P2P connection", "啟用 WebRTC P2P 連線"), + ("Enable TCP hole punching", "啟用 TCP 打洞"), ].iter().cloned().collect(); } diff --git a/src/lang/uk.rs b/src/lang/uk.rs index 1edb037d4..1f1394a47 100644 --- a/src/lang/uk.rs +++ b/src/lang/uk.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Синхронізувати буфер обміну між сеансами"), ("sync-clipboard-between-sessions-tip", "Текст або зображення, скопійовані в одному віддаленому сеансі, також надсилаються до буфера обміну інших підключених сеансів."), ("Enable WebRTC P2P connection", "Увімкнути P2P-підключення через WebRTC"), + ("Enable TCP hole punching", "Увімкнути TCP hole punching"), ].iter().cloned().collect(); } diff --git a/src/lang/vi.rs b/src/lang/vi.rs index d82558757..3455bd745 100644 --- a/src/lang/vi.rs +++ b/src/lang/vi.rs @@ -764,5 +764,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Sync clipboard between sessions", "Đồng bộ clipboard giữa các phiên"), ("sync-clipboard-between-sessions-tip", "Văn bản hoặc hình ảnh được sao chép trong một phiên từ xa cũng được gửi đến clipboard của các phiên đã kết nối khác."), ("Enable WebRTC P2P connection", "Cho phép kết nối WebRTC P2P"), + ("Enable TCP hole punching", "Bật TCP Hole Punching"), ].iter().cloned().collect(); }