From 385ff54b3e8a81198e7c93dffcc23e97afd0acf2 Mon Sep 17 00:00:00 2001 From: Luna Yao <40349250+ZnqbuZ@users.noreply.github.com> Date: Sat, 4 Apr 2026 05:51:49 +0200 Subject: [PATCH] fix magic-dns feature gate --- easytier/src/common/config.rs | 86 +++++++++++--------- easytier/src/common/global_ctx.rs | 65 ++++++++++++--- easytier/src/dns/config/dns.rs | 41 +++------- easytier/src/dns/config/mod.rs | 2 +- easytier/src/dns/node.rs | 7 +- easytier/src/dns/peer_mgr.rs | 1 - easytier/src/dns/server.rs | 1 - easytier/src/dns/tests.rs | 1 - easytier/src/dns/zone.rs | 2 +- easytier/src/instance/instance.rs | 3 +- easytier/src/instance/proxy_cidrs_monitor.rs | 15 ++-- easytier/src/peers/peer_manager.rs | 30 ++++--- easytier/src/peers/peer_ospf_route.rs | 19 +++-- 13 files changed, 156 insertions(+), 117 deletions(-) diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs index 651728be..9a63fc03 100644 --- a/easytier/src/common/config.rs +++ b/easytier/src/common/config.rs @@ -1,3 +1,12 @@ +use super::env_parser; +use crate::{ + common::stun::StunInfoCollector, + proto::{ + acl::Acl, + common::{CompressionAlgoPb, PortForwardConfigPb, SecureModeConfig, SocketType}, + }, + tunnel::generate_digest_from_str, +}; use anyhow::Context; use base64::{prelude::BASE64_STANDARD, Engine as _}; use cfg_if::cfg_if; @@ -13,23 +22,15 @@ use std::{ use strum::{Display, EnumString, VariantArray}; use tokio::io::AsyncReadExt as _; -use crate::{ - common::stun::StunInfoCollector, - dns::config::DnsConfig, - proto::{ - acl::Acl, - common::{CompressionAlgoPb, PortForwardConfigPb, SecureModeConfig, SocketType}, - }, - tunnel::generate_digest_from_str, -}; - -use super::env_parser; - pub type Flags = crate::proto::common::FlagsInConfig; pub fn gen_default_flags() -> Flags { - #[allow(deprecated)] Flags { + #[allow(deprecated)] + quic_listen_port: u32::MAX, + #[allow(deprecated)] + tld_dns_zone: "".to_string(), + default_protocol: "tcp".to_string(), dev_name: "".to_string(), enable_encryption: true, @@ -64,9 +65,6 @@ pub fn gen_default_flags() -> Flags { multi_thread_count: 2, encryption_algorithm: EncryptionAlgorithm::default().to_string(), disable_sym_hole_punching: false, - tld_dns_zone: "".to_string(), - - quic_listen_port: u32::MAX, need_p2p: false, instance_recv_bps_limit: u64::MAX, } @@ -119,8 +117,17 @@ impl Default for EncryptionAlgorithm { } } +cfg_if! { + if #[cfg(feature = "magic-dns")] { + use crate::dns::config::{DnsConfig, DnsConfigLoaderExt}; + } else { + #[auto_impl::auto_impl(Box, &)] + pub trait DnsConfigLoaderExt {} + } +} + #[auto_impl::auto_impl(Box, &)] -pub trait ConfigLoader: Send + Sync { +pub trait ConfigLoader: Send + Sync + DnsConfigLoaderExt { fn get_id(&self) -> uuid::Uuid; fn set_id(&self, id: uuid::Uuid); @@ -203,15 +210,9 @@ pub trait ConfigLoader: Send + Sync { } fn set_credential_file(&self, _path: Option) {} - fn get_dns(&self) -> DnsConfig; - fn set_dns(&self, dns: DnsConfig); - fn get_hostname(&self) -> String; fn set_hostname(&self, hostname: &str); - fn get_fqdn(&self) -> String; - fn set_fqdn(&self, fqdn: &str); - fn dump(&self) -> String; } @@ -450,6 +451,7 @@ struct Config { peer: Option>, proxy_network: Option>, + #[cfg(feature = "magic-dns")] dns: DnsConfig, vpn_portal_config: Option, @@ -535,6 +537,28 @@ impl TomlConfigLoader { } } +impl DnsConfigLoaderExt for TomlConfigLoader { + cfg_if! { + if #[cfg(feature = "magic-dns")] { + fn get_dns(&self) -> DnsConfig { + self.config.lock().unwrap().dns.clone() + } + + fn set_dns(&self, dns: DnsConfig) { + self.config.lock().unwrap().dns = dns; + } + + fn get_fqdn(&self) -> String { + self.config.lock().unwrap().dns.get_fqdn().to_string() + } + + fn set_fqdn(&self, fqdn: &str) { + self.config.lock().unwrap().dns.set_fqdn(fqdn); + } + } + } +} + impl ConfigLoader for TomlConfigLoader { fn get_id(&self) -> uuid::Uuid { let mut locked_config = self.config.lock().unwrap(); @@ -849,14 +873,6 @@ impl ConfigLoader for TomlConfigLoader { self.config.lock().unwrap().credential_file = path; } - fn get_dns(&self) -> DnsConfig { - self.config.lock().unwrap().dns.clone() - } - - fn set_dns(&self, dns: DnsConfig) { - self.config.lock().unwrap().dns = dns; - } - fn get_hostname(&self) -> String { self.config.lock().unwrap().dns.get_name().to_string() } @@ -865,14 +881,6 @@ impl ConfigLoader for TomlConfigLoader { self.config.lock().unwrap().dns.set_name(hostname); } - fn get_fqdn(&self) -> String { - self.config.lock().unwrap().dns.get_fqdn().to_string() - } - - fn set_fqdn(&self, fqdn: &str) { - self.config.lock().unwrap().dns.set_fqdn(fqdn); - } - fn dump(&self) -> String { let default_flags_json = serde_json::to_string(&gen_default_flags()).unwrap(); let default_flags_hashmap = diff --git a/easytier/src/common/global_ctx.rs b/easytier/src/common/global_ctx.rs index 25e127bd..cc751639 100644 --- a/easytier/src/common/global_ctx.rs +++ b/easytier/src/common/global_ctx.rs @@ -1,6 +1,7 @@ use std::{ collections::{hash_map::DefaultHasher, HashMap}, hash::Hasher, + iter, net::{IpAddr, SocketAddr}, sync::{Arc, Mutex}, time::{SystemTime, UNIX_EPOCH}, @@ -30,11 +31,16 @@ use crate::{ }, tunnel::matches_protocol, }; +#[cfg(feature = "magic-dns")] +use crate::dns::{ + config::{DnsExportConfig, DnsGlobalCtxExt}, + server::DnsServer, +}; use crossbeam::atomic::AtomicCell; use hmac::{Hmac, Mac}; +use itertools::Itertools; use parking_lot::RwLock; use sha2::Sha256; -use crate::dns::server::DnsServer; use socket2::Protocol; pub type NetworkIdentity = crate::common::config::NetworkIdentity; @@ -204,7 +210,8 @@ pub struct GlobalCtx { hostname: Mutex, - dns: RwLock>>, + #[cfg(feature = "magic-dns")] + dns_server: RwLock>>, stun_info_collection: Mutex>, @@ -239,7 +246,7 @@ impl std::fmt::Debug for GlobalCtx { } } -pub type ArcGlobalCtx = std::sync::Arc; +pub type ArcGlobalCtx = Arc; impl GlobalCtx { fn derive_feature_flags(flags: &Flags, current: Option) -> PeerFeatureFlag { @@ -302,7 +309,8 @@ impl GlobalCtx { stun_info_collector.clone(), )))), - dns: RwLock::new(None), + #[cfg(feature = "magic-dns")] + dns_server: RwLock::new(None), hostname: Mutex::new(hostname), @@ -422,14 +430,6 @@ impl GlobalCtx { self.ip_collector.lock().unwrap().as_ref().unwrap().clone() } - pub fn get_dns(&self) -> Option> { - self.dns.read().clone() - } - - pub fn set_dns(&self, dns: Option>) { - *self.dns.write() = dns; - } - pub fn get_hostname(&self) -> String { return self.hostname.lock().unwrap().clone(); } @@ -680,6 +680,47 @@ impl GlobalCtx { } } +#[cfg(feature = "magic-dns")] +impl DnsGlobalCtxExt for GlobalCtx { + fn dns_server(&self) -> Option> { + self.dns_server.read().clone() + } + + fn set_dns_server(&self, dns: Option>) { + *self.dns_server.write() = dns; + } + + fn dns_self_zone(&self) -> crate::dns::config::zone::ZoneConfig { + let fqdn = self.config.get_dns().get_fqdn(); + let ipv4 = self.get_ipv4().map(|ip| ip.address()); + let ipv6 = self.get_ipv6().map(|ip| ip.address()); + let ipv6 = ipv6.map(|a| vec![a]).unwrap_or_default(); + + crate::dns::config::zone::ZoneConfig::dedicated( + Some(self.get_id()), + fqdn.clone(), + ipv4, + ipv6, + ) + .unwrap() + } + + fn dns_export_config(&self) -> DnsExportConfig { + DnsExportConfig { + zones: self + .dns_iter_zones() + .filter(|z| z.policy.export.is_some()) // TODO: check policies of parent zones + .map_into() + .collect(), + fqdn: self.config.get_dns().get_fqdn().to_string(), + } + } + + fn dns_iter_zones(&self) -> impl Iterator { + iter::once(self.dns_self_zone()).chain(self.config.get_dns().zones) + } +} + #[cfg(test)] pub mod tests { use crate::{ diff --git a/easytier/src/dns/config/dns.rs b/easytier/src/dns/config/dns.rs index f3a2b54c..a0dedafa 100644 --- a/easytier/src/dns/config/dns.rs +++ b/easytier/src/dns/config/dns.rs @@ -1,7 +1,7 @@ -use crate::common::global_ctx::GlobalCtx; use crate::dns::config::policy::DnsPolicyConfig; use crate::dns::config::zone::ZoneConfig; use crate::dns::config::{DNS_DEFAULT_ADDRESS, DNS_DEFAULT_TLD}; +use crate::dns::server::DnsServer; use crate::dns::utils::addr::NameServerAddrGroup; use crate::dns::utils::parse; use crate::proto::dns::GetExportConfigResponse; @@ -9,10 +9,10 @@ use derivative::Derivative; use gethostname::gethostname; use hickory_proto::rr::{LowerName, Name}; use hickory_proto::xfer::Protocol; -use itertools::Itertools; use serde::{Deserialize, Deserializer, Serialize}; use std::collections::HashMap; use std::iter; +use std::sync::Arc; #[derive(Derivative, Debug, Clone, Deserialize, Serialize, PartialEq)] #[derivative(Default)] @@ -79,36 +79,21 @@ impl DnsConfig { } } +#[auto_impl::auto_impl(Box, &)] +pub trait DnsConfigLoaderExt { + fn get_dns(&self) -> DnsConfig; + fn set_dns(&self, dns: DnsConfig); + + fn get_fqdn(&self) -> String; + fn set_fqdn(&self, fqdn: &str); +} + pub type DnsExportConfig = GetExportConfigResponse; pub trait DnsGlobalCtxExt { + fn dns_server(&self) -> Option>; // TODO: remove this + fn set_dns_server(&self, dns: Option>); // TODO: remove this fn dns_self_zone(&self) -> ZoneConfig; fn dns_export_config(&self) -> DnsExportConfig; fn dns_iter_zones(&self) -> impl Iterator; } - -impl DnsGlobalCtxExt for GlobalCtx { - fn dns_self_zone(&self) -> ZoneConfig { - let fqdn = self.config.get_dns().get_fqdn(); - let ipv4 = self.get_ipv4().map(|ip| ip.address()); - let ipv6 = self.get_ipv6().map(|ip| ip.address()); - let ipv6 = ipv6.map(|a| vec![a]).unwrap_or_default(); - - ZoneConfig::dedicated(Some(self.get_id()), fqdn.clone(), ipv4, ipv6).unwrap() - } - - fn dns_export_config(&self) -> DnsExportConfig { - DnsExportConfig { - zones: self - .dns_iter_zones() - .filter(|z| z.policy.export.is_some()) // TODO: check policies of parent zones - .map_into() - .collect(), - fqdn: self.config.get_dns().get_fqdn().to_string(), - } - } - - fn dns_iter_zones(&self) -> impl Iterator { - iter::once(self.dns_self_zone()).chain(self.config.get_dns().zones) - } -} diff --git a/easytier/src/dns/config/mod.rs b/easytier/src/dns/config/mod.rs index 4f5b30f9..bcf85e28 100644 --- a/easytier/src/dns/config/mod.rs +++ b/easytier/src/dns/config/mod.rs @@ -10,7 +10,7 @@ use url::Url; mod dns; pub use dns::*; mod policy; -mod zone; +pub mod zone; pub static DNS_DEFAULT_TLD: LazyLock = LazyLock::new(|| LowerName::from_str("et.net.").unwrap()); diff --git a/easytier/src/dns/node.rs b/easytier/src/dns/node.rs index 39687b91..d7de8fa1 100644 --- a/easytier/src/dns/node.rs +++ b/easytier/src/dns/node.rs @@ -1,6 +1,5 @@ use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtxEvent}; -use crate::common::scoped_task::ScopedTask; -use crate::dns::config::{DNS_SERVER_ELECTION_INTERVAL, DNS_SERVER_RPC_ADDR}; +use crate::dns::config::{DnsGlobalCtxExt, DNS_SERVER_ELECTION_INTERVAL, DNS_SERVER_RPC_ADDR}; use crate::dns::peer_mgr::DnsPeerMgr; use crate::dns::server::DnsServer; use crate::instance::instance::ArcNicCtx; @@ -114,14 +113,14 @@ impl DnsNode { server.register(&rpc); - self.global_ctx.set_dns(Some(server.clone())); + self.global_ctx.set_dns_server(Some(server.clone())); tokio::join!( self.peer_mgr .add_nic_packet_process_pipeline(Box::new(server.clone())), server.run(token.child_token()) ); - self.global_ctx.set_dns(None); + self.global_ctx.set_dns_server(None); let _ = self .peer_mgr .remove_nic_packet_process_pipeline(server.id()) diff --git a/easytier/src/dns/peer_mgr.rs b/easytier/src/dns/peer_mgr.rs index 0baf8d7a..b3fd9ef3 100644 --- a/easytier/src/dns/peer_mgr.rs +++ b/easytier/src/dns/peer_mgr.rs @@ -1,4 +1,3 @@ -use crate::common::config::ConfigLoader; use crate::common::PeerId; use crate::dns::config::{DnsExportConfig, DnsGlobalCtxExt}; use crate::dns::utils::dirty::DirtyFlag; diff --git a/easytier/src/dns/server.rs b/easytier/src/dns/server.rs index 5b8ec42f..10e9aa00 100644 --- a/easytier/src/dns/server.rs +++ b/easytier/src/dns/server.rs @@ -1,4 +1,3 @@ -use crate::common::config::ConfigLoader; use crate::common::global_ctx::ArcGlobalCtx; use crate::dns::node_mgr::DnsNodeMgr; use crate::dns::system; diff --git a/easytier/src/dns/tests.rs b/easytier/src/dns/tests.rs index 1eabf038..43c089fb 100644 --- a/easytier/src/dns/tests.rs +++ b/easytier/src/dns/tests.rs @@ -12,7 +12,6 @@ use hickory_proto::runtime::TokioRuntimeProvider; use hickory_proto::udp::UdpClientStream; use tokio::sync::Notify; -use crate::common::config::ConfigLoader; use crate::common::global_ctx::tests::get_mock_global_ctx; use crate::connector::udp_hole_punch::tests::replace_stun_info_collector; use crate::dns::node::DnsNode; diff --git a/easytier/src/dns/zone.rs b/easytier/src/dns/zone.rs index e2ea54d2..9304ebd5 100644 --- a/easytier/src/dns/zone.rs +++ b/easytier/src/dns/zone.rs @@ -369,7 +369,7 @@ mod tests { let addr = socket.local_addr()?; println!("listening on {}", addr); - let mut server = ServerFuture::new(catalog.clone()); + let mut server = ServerFuture::new(catalog); server.register_socket(socket); spawn(async move { if let Err(e) = server.block_until_done().await { diff --git a/easytier/src/instance/instance.rs b/easytier/src/instance/instance.rs index bd6731a7..f5d89140 100644 --- a/easytier/src/instance/instance.rs +++ b/easytier/src/instance/instance.rs @@ -25,6 +25,7 @@ use crate::connector::direct::DirectConnectorManager; use crate::connector::manual::{ConnectorManagerRpcService, ManualConnectorManager}; use crate::connector::tcp_hole_punch::TcpHolePunchConnector; use crate::connector::udp_hole_punch::UdpHolePunchConnector; +#[cfg(feature = "magic-dns")] use crate::dns::node::DnsNode; use crate::gateway::icmp_proxy::IcmpProxy; #[cfg(feature = "kcp")] @@ -1383,8 +1384,6 @@ impl Instance { .await .with_context(|| "add ip failed")?; - self.dns.start(); - Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx).await; Ok(()) } diff --git a/easytier/src/instance/proxy_cidrs_monitor.rs b/easytier/src/instance/proxy_cidrs_monitor.rs index 55701b91..fc443e10 100644 --- a/easytier/src/instance/proxy_cidrs_monitor.rs +++ b/easytier/src/instance/proxy_cidrs_monitor.rs @@ -1,7 +1,6 @@ use std::collections::BTreeSet; use std::net::IpAddr; use std::sync::{Arc, Weak}; -use std::time::Instant; use crate::common::global_ctx::{ArcGlobalCtx, GlobalCtxEvent}; use crate::common::scoped_task::ScopedTask; @@ -55,11 +54,15 @@ impl ProxyCidrsMonitor { proxy_cidrs = routes.into_iter().collect(); } - if let Some(dns) = global_ctx.get_dns() { - proxy_cidrs.extend(dns.addresses().into_iter().filter_map(|a| match a.ip() { - IpAddr::V4(ip) => Some(cidr::Ipv4Cidr::new_host(ip)), - _ => None, - })) + #[cfg(feature = "magic-dns")] + { + use crate::dns::config::DnsGlobalCtxExt; + if let Some(dns) = global_ctx.dns_server() { + proxy_cidrs.extend(dns.addresses().into_iter().filter_map(|a| match a.ip() { + IpAddr::V4(ip) => Some(cidr::Ipv4Cidr::new_host(ip)), + _ => None, + })) + } } // Calculate diff diff --git a/easytier/src/peers/peer_manager.rs b/easytier/src/peers/peer_manager.rs index 57b9ede8..fc042e2c 100644 --- a/easytier/src/peers/peer_manager.rs +++ b/easytier/src/peers/peer_manager.rs @@ -18,6 +18,20 @@ use tokio::{ task::JoinSet, }; +use super::{ + create_packet_recv_chan, + encrypt::{Encryptor, NullCipher}, + foreign_network_client::ForeignNetworkClient, + foreign_network_manager::{ForeignNetworkManager, GlobalForeignNetworkAccessor}, + peer_conn::PeerConnId, + peer_map::PeerMap, + peer_ospf_route::PeerRoute, + peer_rpc::PeerRpcManager, + peer_task::ExternalTaskSignal, + relay_peer_map::RelayPeerMap, + route_trait::{ArcRoute, Route}, + BoxNicPacketFilter, BoxPeerPacketFilter, PacketRecvChan, PacketRecvChanReceiver, +}; use crate::{ common::{ compressor::{Compressor as _, DefaultCompressor}, @@ -58,21 +72,6 @@ use crate::{ }, }; -use super::{ - create_packet_recv_chan, - encrypt::{Encryptor, NullCipher}, - foreign_network_client::ForeignNetworkClient, - foreign_network_manager::{ForeignNetworkManager, GlobalForeignNetworkAccessor}, - peer_conn::PeerConnId, - peer_map::PeerMap, - peer_ospf_route::PeerRoute, - peer_rpc::PeerRpcManager, - peer_task::ExternalTaskSignal, - relay_peer_map::RelayPeerMap, - route_trait::{ArcRoute, Route}, - BoxNicPacketFilter, BoxPeerPacketFilter, PacketRecvChan, PacketRecvChanReceiver, -}; - struct RpcTransport { my_peer_id: PeerId, peers: Weak, @@ -1986,7 +1985,6 @@ impl PeerManager { #[cfg(test)] mod tests { - use std::{ fmt::Debug, sync::Arc, diff --git a/easytier/src/peers/peer_ospf_route.rs b/easytier/src/peers/peer_ospf_route.rs index fe8c02e6..6b2659dd 100644 --- a/easytier/src/peers/peer_ospf_route.rs +++ b/easytier/src/peers/peer_ospf_route.rs @@ -40,7 +40,6 @@ use super::{ PeerPacketFilter, }; use crate::common::config::ConfigLoader; -use crate::dns::config::DnsGlobalCtxExt; use crate::utils::DeterministicDigest; use crate::{ common::{ @@ -73,6 +72,7 @@ use crate::{ }; use atomic_shim::AtomicU64; +use cfg_if::cfg_if; use itertools::Itertools; static SERVICE_ID: u32 = 7; @@ -170,9 +170,11 @@ fn is_foreign_network_info_newer( } impl RoutePeerInfo { - #[allow(deprecated)] pub fn new() -> Self { Self { + #[allow(deprecated)] + quic_port: None, + peer_id: 0, inst_id: Some(uuid::Uuid::nil().into()), cost: 0, @@ -193,7 +195,6 @@ impl RoutePeerInfo { groups: Vec::new(), dns: Default::default(), - quic_port: None, noise_static_pubkey: Vec::new(), trusted_credential_pubkeys: Vec::new(), } @@ -220,6 +221,14 @@ impl RoutePeerInfo { .and_then(|cfg| cfg.public_key().ok()) .map(|pk| pk.as_bytes().to_vec()) .unwrap_or_default(); + cfg_if! { + if #[cfg(feature = "magic-dns")] { + use crate::dns::config::DnsGlobalCtxExt; + let dns = global_ctx.dns_export_config().digest(); + } else { + let dns = Default::default(); + } + } Self { peer_id: my_peer_id, inst_id: Some(global_ctx.get_id().into()), @@ -252,7 +261,7 @@ impl RoutePeerInfo { ipv6_addr: global_ctx.get_ipv6().map(|x| x.into()), groups: global_ctx.get_acl_groups(my_peer_id), - dns: global_ctx.dns_export_config().digest(), + dns, noise_static_pubkey, @@ -320,7 +329,7 @@ impl From for crate::proto::api::instance::Route { next_hop_peer_id: 0, // next_hop_peer_id is calculated in RouteTable. cost: 0, // cost is calculated in RouteTable. path_latency: 0, // path_latency is calculated in RouteTable. - proxy_cidrs: val.proxy_cidrs.clone(), + proxy_cidrs: val.proxy_cidrs, hostname: val.hostname.unwrap_or_default(), stun_info: { let mut stun_info = StunInfo::default();