diff --git a/easytier/locales/app.yml b/easytier/locales/app.yml index cb4256ee..fe903b35 100644 --- a/easytier/locales/app.yml +++ b/easytier/locales/app.yml @@ -262,6 +262,9 @@ core_clap: stun_servers_v6: en: "Override default STUN servers, IPv6; If configured but empty, IPv6 STUN servers are not used" zh-CN: "覆盖内置的默认 IPv6 STUN server 列表;如果设置了但是为空,则不使用 IPv6 STUN servers;如果没设置,则使用默认 IPv6 STUN server 列表" + tcp_stun_servers: + en: "Override default TCP STUN servers; If configured but empty, TCP STUN servers are not used" + zh-CN: "覆盖内置的默认 TCP STUN server 列表;如果设置了但是为空,则不使用 TCP STUN servers;如果没设置,则使用默认 TCP STUN server 列表" secure_mode: en: "if true, enable secure mode. default is false" zh-CN: "如果为true,则启用安全模式。默认值为false" diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs index 57cb8f0c..51e535b4 100644 --- a/easytier/src/common/config.rs +++ b/easytier/src/common/config.rs @@ -238,6 +238,9 @@ pub trait ConfigLoader: Send + Sync { fn get_stun_servers(&self) -> Option>; fn set_stun_servers(&self, servers: Option>); + fn get_tcp_stun_servers(&self) -> Option>; + fn set_tcp_stun_servers(&self, servers: Option>); + fn get_stun_servers_v6(&self) -> Option>; fn set_stun_servers_v6(&self, servers: Option>); @@ -563,6 +566,7 @@ struct Config { tcp_whitelist: Option>, udp_whitelist: Option>, stun_servers: Option>, + tcp_stun_servers: Option>, stun_servers_v6: Option>, credential_file: Option, @@ -1000,6 +1004,14 @@ impl ConfigLoader for TomlConfigLoader { self.config.lock().unwrap().stun_servers = servers; } + fn get_tcp_stun_servers(&self) -> Option> { + self.config.lock().unwrap().tcp_stun_servers.clone() + } + + fn set_tcp_stun_servers(&self, servers: Option>) { + self.config.lock().unwrap().tcp_stun_servers = servers; + } + fn get_stun_servers_v6(&self) -> Option> { self.config.lock().unwrap().stun_servers_v6.clone() } @@ -1067,6 +1079,9 @@ impl ConfigLoader for TomlConfigLoader { if config.stun_servers == Some(StunInfoCollector::get_default_servers()) { config.stun_servers = None; } + if config.tcp_stun_servers == Some(StunInfoCollector::get_default_tcp_servers()) { + config.tcp_stun_servers = None; + } if config.stun_servers_v6 == Some(StunInfoCollector::get_default_servers_v6()) { config.stun_servers_v6 = None; } @@ -1341,15 +1356,20 @@ stun_servers = [ "stun.l.google.com:19302", "stun1.l.google.com:19302", "txt:stun.easytier.cn" +] +tcp_stun_servers = [ + "tcp-stun.example.com:3478" ]"#; let config = TomlConfigLoader::new_from_str(config_str).unwrap(); let stun_servers = config.get_stun_servers().unwrap(); + let tcp_stun_servers = config.get_tcp_stun_servers().unwrap(); assert_eq!(stun_servers.len(), 3); assert_eq!(stun_servers[0], "stun.l.google.com:19302"); assert_eq!(stun_servers[1], "stun1.l.google.com:19302"); assert_eq!(stun_servers[2], "txt:stun.easytier.cn"); + assert_eq!(tcp_stun_servers, vec!["tcp-stun.example.com:3478"]); } #[test] diff --git a/easytier/src/common/global_ctx.rs b/easytier/src/common/global_ctx.rs index 91a4c457..56123704 100644 --- a/easytier/src/common/global_ctx.rs +++ b/easytier/src/common/global_ctx.rs @@ -295,6 +295,12 @@ impl GlobalCtx { stun_info_collector.set_stun_servers(StunInfoCollector::get_default_servers()); } + stun_info_collector.set_tcp_stun_servers( + config_fs + .get_tcp_stun_servers() + .unwrap_or_else(StunInfoCollector::get_default_tcp_servers), + ); + if let Some(stun_servers) = config_fs.get_stun_servers_v6() { stun_info_collector.set_stun_servers_v6(stun_servers); } else { diff --git a/easytier/src/core.rs b/easytier/src/core.rs index ed014faa..3ff6dc89 100644 --- a/easytier/src/core.rs +++ b/easytier/src/core.rs @@ -693,6 +693,15 @@ struct NetworkOptions { )] stun_servers_v6: Option>, + #[arg( + long, + env = "ET_TCP_STUN_SERVERS", + value_delimiter = ',', + help = t!("core_clap.tcp_stun_servers").to_string(), + num_args = 0.. + )] + tcp_stun_servers: Option>, + #[arg( long, env = "ET_SECURE_MODE", @@ -1201,6 +1210,12 @@ impl NetworkOptions { old_stun_servers_v6.extend(stun_servers_v6.iter().cloned()); cfg.set_stun_servers_v6(Some(old_stun_servers_v6)); } + + if let Some(tcp_stun_servers) = &self.tcp_stun_servers { + let mut old_tcp_stun_servers = cfg.get_tcp_stun_servers().unwrap_or_default(); + old_tcp_stun_servers.extend(tcp_stun_servers.iter().cloned()); + cfg.set_tcp_stun_servers(Some(old_tcp_stun_servers)); + } Ok(()) } } @@ -1307,6 +1322,9 @@ fn parse_cli() -> Cli { if let Some(stun_servers_v6) = &mut cli.network_options.stun_servers_v6 { stun_servers_v6.retain(|s| !s.trim().is_empty()); } + if let Some(tcp_stun_servers) = &mut cli.network_options.tcp_stun_servers { + tcp_stun_servers.retain(|s| !s.trim().is_empty()); + } cli }