mirror of
https://github.com/EasyTier/EasyTier.git
synced 2025-09-26 20:51:17 +08:00
refactor: update custom STUN server settings (#1310)
* refactor: update global context STUN server initialization Modified global context initialization to use a single StunInfoCollector instance with properly configured IPv4 and IPv6 servers instead of creating separate instances. feat: add IPv6 STUN server configuration support Added interface methods and config struct fields to support both IPv4 and IPv6 STUN server configuration. Modified getter and setter methods to handle Option<Vec<String>> type for both server types. feat: enhance StunInfoCollector with IPv6 support Updated StunInfoCollector to support both IPv4 and IPv6 STUN servers. Added new constructor that accepts both server types and methods to set them independently. feat: add CLI argument for IPv6 STUN servers Added command line argument support for configuring IPv6 STUN servers. Updated configuration setup to handle both IPv4 and IPv6 STUN server settings. docs: add localization for STUN server configuration Added English and Chinese localization strings for the new STUN server configuration options, including both IPv4 and IPv6 variants.
This commit is contained in:
@@ -208,6 +208,12 @@ core_clap:
|
|||||||
enable_relay_foreign_network_kcp:
|
enable_relay_foreign_network_kcp:
|
||||||
en: "if true, allow relay kcp packets from foreign network. default is false (not forward foreign network kcp packets)"
|
en: "if true, allow relay kcp packets from foreign network. default is false (not forward foreign network kcp packets)"
|
||||||
zh-CN: "如果为true,则作为共享节点时也可以转发其他网络的 KCP 数据包。默认值为false(不转发)"
|
zh-CN: "如果为true,则作为共享节点时也可以转发其他网络的 KCP 数据包。默认值为false(不转发)"
|
||||||
|
stun_servers:
|
||||||
|
en: "Override default STUN servers; If configured but empty, STUN servers are not used"
|
||||||
|
zh-CN: "覆盖内置的默认 STUN server 列表;如果设置了但是为空,则不使用 STUN servers;如果没设置,则使用默认 STUN server 列表"
|
||||||
|
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 列表"
|
||||||
|
|
||||||
core_app:
|
core_app:
|
||||||
panic_backtrace_save:
|
panic_backtrace_save:
|
||||||
|
@@ -200,8 +200,11 @@ pub trait ConfigLoader: Send + Sync {
|
|||||||
fn get_udp_whitelist(&self) -> Vec<String>;
|
fn get_udp_whitelist(&self) -> Vec<String>;
|
||||||
fn set_udp_whitelist(&self, whitelist: Vec<String>);
|
fn set_udp_whitelist(&self, whitelist: Vec<String>);
|
||||||
|
|
||||||
fn get_stun_servers(&self) -> Vec<String>;
|
fn get_stun_servers(&self) -> Option<Vec<String>>;
|
||||||
fn set_stun_servers(&self, servers: Vec<String>);
|
fn set_stun_servers(&self, servers: Option<Vec<String>>);
|
||||||
|
|
||||||
|
fn get_stun_servers_v6(&self) -> Option<Vec<String>>;
|
||||||
|
fn set_stun_servers_v6(&self, servers: Option<Vec<String>>);
|
||||||
|
|
||||||
fn dump(&self) -> String;
|
fn dump(&self) -> String;
|
||||||
}
|
}
|
||||||
@@ -374,7 +377,7 @@ impl From<PortForwardConfig> for PortForwardConfigPb {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
netns: Option<String>,
|
netns: Option<String>,
|
||||||
hostname: Option<String>,
|
hostname: Option<String>,
|
||||||
@@ -412,6 +415,7 @@ struct Config {
|
|||||||
tcp_whitelist: Option<Vec<String>>,
|
tcp_whitelist: Option<Vec<String>>,
|
||||||
udp_whitelist: Option<Vec<String>>,
|
udp_whitelist: Option<Vec<String>>,
|
||||||
stun_servers: Option<Vec<String>>,
|
stun_servers: Option<Vec<String>>,
|
||||||
|
stun_servers_v6: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -791,17 +795,20 @@ impl ConfigLoader for TomlConfigLoader {
|
|||||||
self.config.lock().unwrap().udp_whitelist = Some(whitelist);
|
self.config.lock().unwrap().udp_whitelist = Some(whitelist);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_stun_servers(&self) -> Vec<String> {
|
fn get_stun_servers(&self) -> Option<Vec<String>> {
|
||||||
self.config
|
self.config.lock().unwrap().stun_servers.clone()
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.stun_servers
|
|
||||||
.clone()
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_stun_servers(&self, servers: Vec<String>) {
|
fn set_stun_servers(&self, servers: Option<Vec<String>>) {
|
||||||
self.config.lock().unwrap().stun_servers = Some(servers);
|
self.config.lock().unwrap().stun_servers = servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_stun_servers_v6(&self) -> Option<Vec<String>> {
|
||||||
|
self.config.lock().unwrap().stun_servers_v6.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_stun_servers_v6(&self, servers: Option<Vec<String>>) {
|
||||||
|
self.config.lock().unwrap().stun_servers_v6 = servers;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump(&self) -> String {
|
fn dump(&self) -> String {
|
||||||
@@ -838,14 +845,14 @@ pub mod tests {
|
|||||||
fn test_stun_servers_config() {
|
fn test_stun_servers_config() {
|
||||||
let config = TomlConfigLoader::default();
|
let config = TomlConfigLoader::default();
|
||||||
let stun_servers = config.get_stun_servers();
|
let stun_servers = config.get_stun_servers();
|
||||||
assert!(stun_servers.is_empty());
|
assert!(stun_servers.is_none());
|
||||||
|
|
||||||
// Test setting custom stun servers
|
// Test setting custom stun servers
|
||||||
let custom_servers = vec!["txt:stun.easytier.cn".to_string()];
|
let custom_servers = vec!["txt:stun.easytier.cn".to_string()];
|
||||||
config.set_stun_servers(custom_servers.clone());
|
config.set_stun_servers(Some(custom_servers.clone()));
|
||||||
|
|
||||||
let retrieved_servers = config.get_stun_servers();
|
let retrieved_servers = config.get_stun_servers();
|
||||||
assert_eq!(retrieved_servers, custom_servers);
|
assert_eq!(retrieved_servers.unwrap(), custom_servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -859,7 +866,7 @@ stun_servers = [
|
|||||||
]"#;
|
]"#;
|
||||||
|
|
||||||
let config = TomlConfigLoader::new_from_str(config_str).unwrap();
|
let config = TomlConfigLoader::new_from_str(config_str).unwrap();
|
||||||
let stun_servers = config.get_stun_servers();
|
let stun_servers = config.get_stun_servers().unwrap();
|
||||||
|
|
||||||
assert_eq!(stun_servers.len(), 3);
|
assert_eq!(stun_servers.len(), 3);
|
||||||
assert_eq!(stun_servers[0], "stun.l.google.com:19302");
|
assert_eq!(stun_servers[0], "stun.l.google.com:19302");
|
||||||
|
@@ -114,12 +114,21 @@ impl GlobalCtx {
|
|||||||
|
|
||||||
let (event_bus, _) = tokio::sync::broadcast::channel(8);
|
let (event_bus, _) = tokio::sync::broadcast::channel(8);
|
||||||
|
|
||||||
let stun_servers = config_fs.get_stun_servers();
|
let stun_info_collector = StunInfoCollector::new_with_default_servers();
|
||||||
let stun_info_collection = Arc::new(if stun_servers.is_empty() {
|
|
||||||
StunInfoCollector::new_with_default_servers()
|
if let Some(stun_servers) = config_fs.get_stun_servers() {
|
||||||
|
stun_info_collector.set_stun_servers(stun_servers);
|
||||||
} else {
|
} else {
|
||||||
StunInfoCollector::new(stun_servers)
|
stun_info_collector.set_stun_servers(Vec::new());
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if let Some(stun_servers) = config_fs.get_stun_servers_v6() {
|
||||||
|
stun_info_collector.set_stun_servers_v6(stun_servers);
|
||||||
|
} else {
|
||||||
|
stun_info_collector.set_stun_servers_v6(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
let stun_info_collector = Arc::new(stun_info_collector);
|
||||||
|
|
||||||
let enable_exit_node = config_fs.get_flags().enable_exit_node || cfg!(target_env = "ohos");
|
let enable_exit_node = config_fs.get_flags().enable_exit_node || cfg!(target_env = "ohos");
|
||||||
let proxy_forward_by_system = config_fs.get_flags().proxy_forward_by_system;
|
let proxy_forward_by_system = config_fs.get_flags().proxy_forward_by_system;
|
||||||
@@ -145,12 +154,12 @@ impl GlobalCtx {
|
|||||||
|
|
||||||
ip_collector: Mutex::new(Some(Arc::new(IPCollector::new(
|
ip_collector: Mutex::new(Some(Arc::new(IPCollector::new(
|
||||||
net_ns,
|
net_ns,
|
||||||
stun_info_collection.clone(),
|
stun_info_collector.clone(),
|
||||||
)))),
|
)))),
|
||||||
|
|
||||||
hostname: Mutex::new(hostname),
|
hostname: Mutex::new(hostname),
|
||||||
|
|
||||||
stun_info_collection: Mutex::new(stun_info_collection),
|
stun_info_collection: Mutex::new(stun_info_collector),
|
||||||
|
|
||||||
running_listeners: Mutex::new(Vec::new()),
|
running_listeners: Mutex::new(Vec::new()),
|
||||||
|
|
||||||
|
@@ -71,12 +71,7 @@ impl IfConfiguerTrait for MacIfConfiger {
|
|||||||
run_shell_cmd(format!("ifconfig {} inet delete", name).as_str()).await
|
run_shell_cmd(format!("ifconfig {} inet delete", name).as_str()).await
|
||||||
} else {
|
} else {
|
||||||
run_shell_cmd(
|
run_shell_cmd(
|
||||||
format!(
|
format!("ifconfig {} inet {} delete", name, ip.unwrap().address()).as_str(),
|
||||||
"ifconfig {} inet {} delete",
|
|
||||||
name,
|
|
||||||
ip.unwrap().address().to_string()
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ impl InterfaceFilter {
|
|||||||
async fn is_interface_physical(&self) -> bool {
|
async fn is_interface_physical(&self) -> bool {
|
||||||
let interface_name = &self.iface.name;
|
let interface_name = &self.iface.name;
|
||||||
let output = tokio::process::Command::new("networksetup")
|
let output = tokio::process::Command::new("networksetup")
|
||||||
.args(&["-listallhardwareports"])
|
.args(["-listallhardwareports"])
|
||||||
.output()
|
.output()
|
||||||
.await
|
.await
|
||||||
.expect("Failed to execute command");
|
.expect("Failed to execute command");
|
||||||
@@ -79,11 +79,7 @@ impl InterfaceFilter {
|
|||||||
|
|
||||||
if line.contains("Device:") && line.contains(interface_name) {
|
if line.contains("Device:") && line.contains(interface_name) {
|
||||||
let next_line = lines[i + 1];
|
let next_line = lines[i + 1];
|
||||||
if next_line.contains("Virtual Interface") {
|
return !next_line.contains("Virtual Interface");
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -718,10 +718,10 @@ impl StunInfoCollectorTrait for StunInfoCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StunInfoCollector {
|
impl StunInfoCollector {
|
||||||
pub fn new(stun_servers: Vec<String>) -> Self {
|
pub fn new(stun_servers: Vec<String>, stun_servers_v6: Vec<String>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
stun_servers: Arc::new(RwLock::new(stun_servers)),
|
stun_servers: Arc::new(RwLock::new(stun_servers)),
|
||||||
stun_servers_v6: Arc::new(RwLock::new(Self::get_default_servers_v6())),
|
stun_servers_v6: Arc::new(RwLock::new(stun_servers_v6)),
|
||||||
udp_nat_test_result: Arc::new(RwLock::new(None)),
|
udp_nat_test_result: Arc::new(RwLock::new(None)),
|
||||||
public_ipv6: Arc::new(AtomicCell::new(None)),
|
public_ipv6: Arc::new(AtomicCell::new(None)),
|
||||||
nat_test_result_time: Arc::new(AtomicCell::new(Local::now())),
|
nat_test_result_time: Arc::new(AtomicCell::new(Local::now())),
|
||||||
@@ -732,7 +732,17 @@ impl StunInfoCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_default_servers() -> Self {
|
pub fn new_with_default_servers() -> Self {
|
||||||
Self::new(Self::get_default_servers())
|
Self::new(Self::get_default_servers(), Self::get_default_servers_v6())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_stun_servers(&self, stun_servers: Vec<String>) {
|
||||||
|
let mut g = self.stun_servers.write().unwrap();
|
||||||
|
*g = stun_servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_stun_servers_v6(&self, stun_servers_v6: Vec<String>) {
|
||||||
|
let mut g = self.stun_servers_v6.write().unwrap();
|
||||||
|
*g = stun_servers_v6;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_default_servers() -> Vec<String> {
|
pub fn get_default_servers() -> Vec<String> {
|
||||||
|
@@ -25,7 +25,7 @@ use easytier::{
|
|||||||
constants::EASYTIER_VERSION,
|
constants::EASYTIER_VERSION,
|
||||||
global_ctx::GlobalCtx,
|
global_ctx::GlobalCtx,
|
||||||
set_default_machine_id,
|
set_default_machine_id,
|
||||||
stun::MockStunInfoCollector,
|
stun::{MockStunInfoCollector, StunInfoCollector},
|
||||||
},
|
},
|
||||||
connector::create_connector_by_url,
|
connector::create_connector_by_url,
|
||||||
instance_manager::NetworkInstanceManager,
|
instance_manager::NetworkInstanceManager,
|
||||||
@@ -572,6 +572,15 @@ struct NetworkOptions {
|
|||||||
num_args = 0..
|
num_args = 0..
|
||||||
)]
|
)]
|
||||||
stun_servers: Option<Vec<String>>,
|
stun_servers: Option<Vec<String>>,
|
||||||
|
|
||||||
|
#[arg(
|
||||||
|
long,
|
||||||
|
env = "ET_STUN_SERVERS_V6",
|
||||||
|
value_delimiter = ',',
|
||||||
|
help = t!("core_clap.stun_servers_v6").to_string(),
|
||||||
|
num_args = 0..
|
||||||
|
)]
|
||||||
|
stun_servers_v6: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@@ -943,7 +952,23 @@ impl NetworkOptions {
|
|||||||
cfg.set_udp_whitelist(old_udp_whitelist);
|
cfg.set_udp_whitelist(old_udp_whitelist);
|
||||||
|
|
||||||
if let Some(stun_servers) = &self.stun_servers {
|
if let Some(stun_servers) = &self.stun_servers {
|
||||||
cfg.set_stun_servers(stun_servers.clone());
|
if stun_servers.is_empty() {
|
||||||
|
cfg.set_stun_servers(None);
|
||||||
|
} else {
|
||||||
|
cfg.set_stun_servers(Some(stun_servers.clone()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cfg.set_stun_servers(Some(StunInfoCollector::get_default_servers()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(stun_servers) = &self.stun_servers_v6 {
|
||||||
|
if stun_servers.is_empty() {
|
||||||
|
cfg.set_stun_servers_v6(None);
|
||||||
|
} else {
|
||||||
|
cfg.set_stun_servers_v6(Some(stun_servers.clone()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cfg.set_stun_servers_v6(Some(StunInfoCollector::get_default_servers_v6()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@@ -457,7 +457,7 @@ impl KcpProxyDst {
|
|||||||
global_ctx: ArcGlobalCtx,
|
global_ctx: ArcGlobalCtx,
|
||||||
proxy_entries: Arc<DashMap<ConnId, TcpProxyEntry>>,
|
proxy_entries: Arc<DashMap<ConnId, TcpProxyEntry>>,
|
||||||
cidr_set: Arc<CidrSet>,
|
cidr_set: Arc<CidrSet>,
|
||||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut conn_data = kcp_stream.conn_data().clone();
|
let mut conn_data = kcp_stream.conn_data().clone();
|
||||||
let parsed_conn_data = KcpConnData::decode(&mut conn_data)
|
let parsed_conn_data = KcpConnData::decode(&mut conn_data)
|
||||||
|
@@ -252,13 +252,13 @@ pub struct QUICProxyDst {
|
|||||||
endpoint: Arc<quinn::Endpoint>,
|
endpoint: Arc<quinn::Endpoint>,
|
||||||
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
||||||
tasks: Arc<Mutex<JoinSet<()>>>,
|
tasks: Arc<Mutex<JoinSet<()>>>,
|
||||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl QUICProxyDst {
|
impl QUICProxyDst {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global_ctx: ArcGlobalCtx,
|
global_ctx: ArcGlobalCtx,
|
||||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let _g = global_ctx.net_ns.guard();
|
let _g = global_ctx.net_ns.guard();
|
||||||
let (endpoint, _) = make_server_endpoint("0.0.0.0:0".parse().unwrap())
|
let (endpoint, _) = make_server_endpoint("0.0.0.0:0".parse().unwrap())
|
||||||
@@ -324,7 +324,7 @@ impl QUICProxyDst {
|
|||||||
ctx: Arc<GlobalCtx>,
|
ctx: Arc<GlobalCtx>,
|
||||||
cidr_set: Arc<CidrSet>,
|
cidr_set: Arc<CidrSet>,
|
||||||
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
||||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>,
|
||||||
) {
|
) {
|
||||||
let remote_addr = conn.remote_address();
|
let remote_addr = conn.remote_address();
|
||||||
defer!(
|
defer!(
|
||||||
@@ -368,7 +368,7 @@ impl QUICProxyDst {
|
|||||||
cidr_set: Arc<CidrSet>,
|
cidr_set: Arc<CidrSet>,
|
||||||
proxy_entry_key: SocketAddr,
|
proxy_entry_key: SocketAddr,
|
||||||
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
||||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
route: Arc<dyn crate::peers::route_trait::Route + Send + Sync + 'static>,
|
||||||
) -> Result<(QUICStream, TcpStream, ProxyAclHandler)> {
|
) -> Result<(QUICStream, TcpStream, ProxyAclHandler)> {
|
||||||
let conn = incoming.await.with_context(|| "accept failed")?;
|
let conn = incoming.await.with_context(|| "accept failed")?;
|
||||||
let addr = conn.remote_address();
|
let addr = conn.remote_address();
|
||||||
|
@@ -127,10 +127,7 @@ impl PacketProtocol {
|
|||||||
match self {
|
match self {
|
||||||
PacketProtocol::IPv4 => Ok(libc::PF_INET as u16),
|
PacketProtocol::IPv4 => Ok(libc::PF_INET as u16),
|
||||||
PacketProtocol::IPv6 => Ok(libc::PF_INET6 as u16),
|
PacketProtocol::IPv6 => Ok(libc::PF_INET6 as u16),
|
||||||
PacketProtocol::Other(_) => Err(io::Error::new(
|
PacketProtocol::Other(_) => Err(io::Error::other("neither an IPv4 nor IPv6 packet")),
|
||||||
io::ErrorKind::Other,
|
|
||||||
"neither an IPv4 nor IPv6 packet",
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -904,7 +901,7 @@ impl NicCtx {
|
|||||||
// remove the 10.0.0.0/24 route (which is added by rust-tun by default)
|
// remove the 10.0.0.0/24 route (which is added by rust-tun by default)
|
||||||
let _ = nic
|
let _ = nic
|
||||||
.ifcfg
|
.ifcfg
|
||||||
.remove_ipv4_route(&nic.ifname(), "10.0.0.0".parse().unwrap(), 24)
|
.remove_ipv4_route(nic.ifname(), "10.0.0.0".parse().unwrap(), 24)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user