mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-06 17:59:11 +00:00
feat: support macOS Network Extension (#1902)
* feat: support macOS Network Extension * fix: disable macOS NE feature in cargo hack check
This commit is contained in:
@@ -394,3 +394,5 @@ tracing = ["tokio/tracing", "dep:console-subscriber"]
|
||||
magic-dns = ["dep:hickory-client", "dep:hickory-server"]
|
||||
faketcp = ["dep:flume"]
|
||||
zstd = ["dep:zstd"]
|
||||
# For Network Extension on macOS
|
||||
macos-ne = []
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
mod darwin;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod netlink;
|
||||
@@ -144,14 +147,17 @@ impl IfConfiguerTrait for DummyIfConfiger {}
|
||||
#[cfg(target_os = "linux")]
|
||||
pub type IfConfiger = netlink::NetlinkIfConfiger;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
pub type IfConfiger = darwin::MacIfConfiger;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub type IfConfiger = windows::WindowsIfConfiger;
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "macos",
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "linux",
|
||||
target_os = "windows",
|
||||
target_os = "freebsd",
|
||||
|
||||
@@ -120,7 +120,7 @@ pub fn get_machine_id() -> uuid::Uuid {
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "windows",
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
@@ -137,7 +137,7 @@ pub fn get_machine_id() -> uuid::Uuid {
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "windows",
|
||||
target_os = "freebsd"
|
||||
)))]
|
||||
|
||||
@@ -16,7 +16,11 @@ struct InterfaceFilter {
|
||||
iface: NetworkInterface,
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))]
|
||||
impl InterfaceFilter {
|
||||
async fn filter_iface(&self) -> bool {
|
||||
true
|
||||
@@ -60,13 +64,16 @@ impl InterfaceFilter {
|
||||
}
|
||||
|
||||
// Cache for networksetup command output
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
static NETWORKSETUP_CACHE: std::sync::OnceLock<Mutex<(String, std::time::Instant)>> =
|
||||
std::sync::OnceLock::new();
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
impl InterfaceFilter {
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
async fn get_networksetup_output() -> String {
|
||||
use anyhow::Context;
|
||||
use std::time::{Duration, Instant};
|
||||
@@ -101,7 +108,7 @@ impl InterfaceFilter {
|
||||
stdout
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
async fn is_interface_physical(&self) -> bool {
|
||||
let interface_name = &self.iface.name;
|
||||
let stdout = Self::get_networksetup_output().await;
|
||||
|
||||
@@ -36,7 +36,7 @@ async fn set_bind_addr_for_peer_connector(
|
||||
) {
|
||||
if cfg!(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
)) {
|
||||
return;
|
||||
|
||||
@@ -539,7 +539,7 @@ impl<C: NatDstConnector> TcpProxy<C> {
|
||||
|| self.global_ctx.no_tun()
|
||||
|| cfg!(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))
|
||||
{
|
||||
|
||||
@@ -464,7 +464,7 @@ fn get_system_config(
|
||||
return Ok(Some(Box::new(WindowsDNSManager::new(tun_name)?)));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
{
|
||||
use super::system_config::darwin::DarwinConfigurator;
|
||||
return Ok(Some(Box::new(DarwinConfigurator::new())));
|
||||
|
||||
@@ -4,7 +4,7 @@ pub mod linux;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub mod windows;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
pub mod darwin;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
|
||||
@@ -114,7 +114,7 @@ impl IpProxy {
|
||||
tracing::error!("start icmp proxy failed: {:?}", e);
|
||||
if cfg!(not(any(
|
||||
target_os = "android",
|
||||
target_os = "ios",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))) {
|
||||
// android, ios and ohos not support icmp proxy
|
||||
@@ -802,7 +802,11 @@ impl Instance {
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
not(any(target_os = "android", target_os = "ios", target_env = "ohos")),
|
||||
not(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
)),
|
||||
feature = "tun"
|
||||
))]
|
||||
{
|
||||
@@ -846,7 +850,11 @@ impl Instance {
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
not(any(target_os = "android", target_os = "ios", target_env = "ohos")),
|
||||
not(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
)),
|
||||
feature = "tun"
|
||||
))]
|
||||
fn check_for_static_ip(&self, first_round_output: oneshot::Sender<Result<(), Error>>) {
|
||||
@@ -936,7 +944,11 @@ impl Instance {
|
||||
{
|
||||
Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await;
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))]
|
||||
#[cfg(not(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
)))]
|
||||
if !self.global_ctx.config.get_flags().no_tun {
|
||||
let (output_tx, output_rx) = oneshot::channel();
|
||||
self.check_for_static_ip(output_tx);
|
||||
@@ -1440,7 +1452,11 @@ impl Instance {
|
||||
self.peer_packet_receiver.clone()
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))]
|
||||
pub async fn setup_nic_ctx_for_mobile(
|
||||
nic_ctx: ArcNicCtx,
|
||||
global_ctx: ArcGlobalCtx,
|
||||
|
||||
@@ -523,7 +523,7 @@ impl VirtualNic {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
config.platform_config(|config| {
|
||||
// disable packet information so we can process the header by ourselves, see tun2 impl for more details
|
||||
config.packet_information(false);
|
||||
@@ -583,7 +583,11 @@ impl VirtualNic {
|
||||
Ok(tun::create(&config)?)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))]
|
||||
pub async fn create_dev_for_mobile(
|
||||
&mut self,
|
||||
tun_fd: std::os::fd::RawFd,
|
||||
@@ -592,7 +596,7 @@ impl VirtualNic {
|
||||
let mut config = Configuration::default();
|
||||
config.layer(Layer::L3);
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(any(target_os = "ios", feature = "macos-ne"))]
|
||||
config.platform_config(|config| {
|
||||
// disable packet information so we can process the header by ourselves, see tun2 impl for more details
|
||||
config.packet_information(false);
|
||||
@@ -602,7 +606,7 @@ impl VirtualNic {
|
||||
config.close_fd_on_drop(false);
|
||||
config.up();
|
||||
|
||||
let has_packet_info = cfg!(target_os = "ios");
|
||||
let has_packet_info = cfg!(any(target_os = "ios", feature = "macos-ne"));
|
||||
let dev = tun::create(&config)?;
|
||||
let dev = AsyncDevice::new(dev)?;
|
||||
let (a, b) = BiLock::new(dev);
|
||||
@@ -680,7 +684,7 @@ impl VirtualNic {
|
||||
self.ifcfg.set_mtu(ifname.as_str(), mtu_in_config).await?;
|
||||
}
|
||||
|
||||
let has_packet_info = cfg!(target_os = "macos");
|
||||
let has_packet_info = cfg!(all(target_os = "macos", not(feature = "macos-ne")));
|
||||
let (a, b) = BiLock::new(dev);
|
||||
let ft = TunnelWrapper::new(
|
||||
TunStream::new(a, has_packet_info),
|
||||
@@ -827,7 +831,10 @@ impl NicCtx {
|
||||
nic.remove_ip(None).await?;
|
||||
nic.add_ip(ipv4_addr.address(), ipv4_addr.network_length() as i32)
|
||||
.await?;
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
{
|
||||
nic.add_route(ipv4_addr.first_address(), ipv4_addr.network_length())
|
||||
.await?;
|
||||
@@ -841,7 +848,10 @@ impl NicCtx {
|
||||
nic.remove_ipv6(None).await?;
|
||||
nic.add_ipv6(ipv6_addr.address(), ipv6_addr.network_length() as i32)
|
||||
.await?;
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
{
|
||||
nic.add_ipv6_route(ipv6_addr.first_address(), ipv6_addr.network_length())
|
||||
.await?;
|
||||
@@ -1134,7 +1144,10 @@ impl NicCtx {
|
||||
let _ = RegistryManager::reg_change_catrgory_in_profile(&dev_name);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
|
||||
#[cfg(any(
|
||||
all(target_os = "macos", not(feature = "macos-ne")),
|
||||
target_os = "freebsd"
|
||||
))]
|
||||
{
|
||||
// remove the 10.0.0.0/24 route (which is added by rust-tun by default)
|
||||
let _ = nic
|
||||
@@ -1175,7 +1188,11 @@ impl NicCtx {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))]
|
||||
pub async fn run_for_mobile(&mut self, tun_fd: std::os::fd::RawFd) -> Result<(), Error> {
|
||||
let tunnel = {
|
||||
let mut nic = self.nic.lock().await;
|
||||
|
||||
@@ -93,7 +93,11 @@ impl EasyTierLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))]
|
||||
async fn run_routine_for_mobile(
|
||||
instance: &Instance,
|
||||
data: &EasyTierData,
|
||||
@@ -152,7 +156,11 @@ impl EasyTierLauncher {
|
||||
}
|
||||
});
|
||||
|
||||
#[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
|
||||
#[cfg(any(
|
||||
target_os = "android",
|
||||
any(target_os = "ios", feature = "macos-ne"),
|
||||
target_env = "ohos"
|
||||
))]
|
||||
Self::run_routine_for_mobile(&instance, &data, &mut tasks).await;
|
||||
|
||||
instance.run().await?;
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Service {
|
||||
pub fn new(name: String) -> Result<Self, anyhow::Error> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let service_manager = Box::new(self::win_service_manager::WinServiceManager::new()?);
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(all(target_os = "macos", not(feature = "macos-ne")))]
|
||||
let service_manager: Box<dyn ServiceManager> =
|
||||
Box::new(service_manager::TypedServiceManager::Launchd(
|
||||
service_manager::LaunchdServiceManager::system().with_config(
|
||||
@@ -63,7 +63,10 @@ impl Service {
|
||||
),
|
||||
));
|
||||
|
||||
#[cfg(not(any(target_os = "windows", target_os = "macos")))]
|
||||
#[cfg(not(any(
|
||||
target_os = "windows",
|
||||
all(target_os = "macos", not(feature = "macos-ne"))
|
||||
)))]
|
||||
let service_manager: Box<dyn ServiceManager> =
|
||||
Box::new(service_manager::TypedServiceManager::native()?);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if #[cfg(target_os = "macos")] {
|
||||
} else if #[cfg(all(target_os = "macos", not(feature = "macos-ne")))] {
|
||||
pub mod macos_bpf;
|
||||
|
||||
pub fn create_tun(
|
||||
|
||||
Reference in New Issue
Block a user