feat: support compile for iOS (#1777)

This commit is contained in:
Chenx Dust
2026-01-11 16:36:58 +08:00
committed by GitHub
parent f4f591d14c
commit 48c5c23f9b
7 changed files with 50 additions and 25 deletions
+1 -1
View File
@@ -194,7 +194,7 @@ service-manager = { git = "https://github.com/EasyTier/service-manager-rs.git",
zstd = { version = "0.13" } zstd = { version = "0.13" }
kcp-sys = { git = "https://github.com/EasyTier/kcp-sys", rev = "71eff18c573a4a71bf99c7fabc6a8b9f211c84c1" } kcp-sys = { git = "https://github.com/EasyTier/kcp-sys", rev = "94964794caaed5d388463137da59b97499619e5f" }
prost-reflect = { version = "0.14.5", default-features = false, features = [ prost-reflect = { version = "0.14.5", default-features = false, features = [
"derive", "derive",
+1 -1
View File
@@ -16,7 +16,7 @@ struct InterfaceFilter {
iface: NetworkInterface, iface: NetworkInterface,
} }
#[cfg(any(target_os = "android", target_env = "ohos"))] #[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
impl InterfaceFilter { impl InterfaceFilter {
async fn filter_iface(&self) -> bool { async fn filter_iface(&self) -> bool {
true true
+5 -1
View File
@@ -31,7 +31,11 @@ async fn set_bind_addr_for_peer_connector(
is_ipv4: bool, is_ipv4: bool,
ip_collector: &Arc<IPCollector>, ip_collector: &Arc<IPCollector>,
) { ) {
if cfg!(any(target_os = "android", target_env = "ohos")) { if cfg!(any(
target_os = "android",
target_os = "ios",
target_env = "ohos"
)) {
return; return;
} }
+5 -1
View File
@@ -526,7 +526,11 @@ impl<C: NatDstConnector> TcpProxy<C> {
#[cfg(feature = "smoltcp")] #[cfg(feature = "smoltcp")]
if self.global_ctx.get_flags().use_smoltcp if self.global_ctx.get_flags().use_smoltcp
|| self.global_ctx.no_tun() || self.global_ctx.no_tun()
|| cfg!(any(target_os = "android", target_env = "ohos")) || cfg!(any(
target_os = "android",
target_os = "ios",
target_env = "ohos"
))
{ {
// use smoltcp network stack // use smoltcp network stack
+16 -8
View File
@@ -104,8 +104,12 @@ impl IpProxy {
self.tcp_proxy.start(true).await?; self.tcp_proxy.start(true).await?;
if let Err(e) = self.icmp_proxy.start().await { if let Err(e) = self.icmp_proxy.start().await {
tracing::error!("start icmp proxy failed: {:?}", e); tracing::error!("start icmp proxy failed: {:?}", e);
if cfg!(not(any(target_os = "android", target_env = "ohos"))) { if cfg!(not(any(
// android and ohos not support icmp proxy target_os = "android",
target_os = "ios",
target_env = "ohos"
))) {
// android, ios and ohos not support icmp proxy
return Err(e); return Err(e);
} }
} }
@@ -772,7 +776,11 @@ impl Instance {
continue; continue;
} }
#[cfg(not(any(target_os = "android", target_env = "ohos")))] #[cfg(not(any(
target_os = "android",
target_os = "ios",
target_env = "ohos"
)))]
{ {
let mut new_nic_ctx = NicCtx::new( let mut new_nic_ctx = NicCtx::new(
global_ctx_c.clone(), global_ctx_c.clone(),
@@ -906,7 +914,7 @@ impl Instance {
Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await; Self::clear_nic_ctx(self.nic_ctx.clone(), self.peer_packet_receiver.clone()).await;
if !self.global_ctx.config.get_flags().no_tun { if !self.global_ctx.config.get_flags().no_tun {
#[cfg(not(any(target_os = "android", target_env = "ohos")))] #[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))]
{ {
let (output_tx, output_rx) = oneshot::channel(); let (output_tx, output_rx) = oneshot::channel();
self.check_for_static_ip(output_tx); self.check_for_static_ip(output_tx);
@@ -1402,15 +1410,15 @@ impl Instance {
self.peer_packet_receiver.clone() self.peer_packet_receiver.clone()
} }
#[cfg(any(target_os = "android", target_env = "ohos"))] #[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
pub async fn setup_nic_ctx_for_android( pub async fn setup_nic_ctx_for_mobile(
nic_ctx: ArcNicCtx, nic_ctx: ArcNicCtx,
global_ctx: ArcGlobalCtx, global_ctx: ArcGlobalCtx,
peer_manager: Arc<PeerManager>, peer_manager: Arc<PeerManager>,
peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>, peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>,
fd: i32, fd: i32,
) -> Result<(), anyhow::Error> { ) -> Result<(), anyhow::Error> {
println!("setup_nic_ctx_for_android, fd: {}", fd); tracing::info!("setup_nic_ctx_for_mobile, fd: {}", fd);
Self::clear_nic_ctx(nic_ctx.clone(), peer_packet_receiver.clone()).await; Self::clear_nic_ctx(nic_ctx.clone(), peer_packet_receiver.clone()).await;
if fd <= 0 { if fd <= 0 {
return Ok(()); return Ok(());
@@ -1423,7 +1431,7 @@ impl Instance {
close_notifier.clone(), close_notifier.clone(),
); );
new_nic_ctx new_nic_ctx
.run_for_android(fd) .run_for_mobile(fd)
.await .await
.with_context(|| "add ip failed")?; .with_context(|| "add ip failed")?;
+15 -7
View File
@@ -442,26 +442,34 @@ impl VirtualNic {
Ok(tun::create(&config)?) Ok(tun::create(&config)?)
} }
#[cfg(any(target_os = "android", target_env = "ohos"))] #[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
pub async fn create_dev_for_android( pub async fn create_dev_for_mobile(
&mut self, &mut self,
tun_fd: std::os::fd::RawFd, tun_fd: std::os::fd::RawFd,
) -> Result<Box<dyn Tunnel>, Error> { ) -> Result<Box<dyn Tunnel>, Error> {
println!("tun_fd: {}", tun_fd); println!("tun_fd: {}", tun_fd);
let mut config = Configuration::default(); let mut config = Configuration::default();
config.layer(Layer::L3); config.layer(Layer::L3);
#[cfg(target_os = "ios")]
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);
});
config.raw_fd(tun_fd); config.raw_fd(tun_fd);
config.close_fd_on_drop(false); config.close_fd_on_drop(false);
config.up(); config.up();
let has_packet_info = cfg!(target_os = "ios");
let dev = tun::create(&config)?; let dev = tun::create(&config)?;
let dev = AsyncDevice::new(dev)?; let dev = AsyncDevice::new(dev)?;
let (a, b) = BiLock::new(dev); let (a, b) = BiLock::new(dev);
let ft = TunnelWrapper::new( let ft = TunnelWrapper::new(
TunStream::new(a, false), TunStream::new(a, has_packet_info),
FramedWriter::new_with_converter( FramedWriter::new_with_converter(
TunAsyncWrite { l: b }, TunAsyncWrite { l: b },
TunZCPacketToBytes::new(false), TunZCPacketToBytes::new(has_packet_info),
), ),
None, None,
); );
@@ -1008,11 +1016,11 @@ impl NicCtx {
Ok(()) Ok(())
} }
#[cfg(any(target_os = "android", target_env = "ohos"))] #[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
pub async fn run_for_android(&mut self, tun_fd: std::os::fd::RawFd) -> Result<(), Error> { pub async fn run_for_mobile(&mut self, tun_fd: std::os::fd::RawFd) -> Result<(), Error> {
let tunnel = { let tunnel = {
let mut nic = self.nic.lock().await; let mut nic = self.nic.lock().await;
match nic.create_dev_for_android(tun_fd).await { match nic.create_dev_for_mobile(tun_fd).await {
Ok(ret) => { Ok(ret) => {
self.global_ctx self.global_ctx
.issue_event(GlobalCtxEvent::TunDeviceReady(nic.ifname().to_string())); .issue_event(GlobalCtxEvent::TunDeviceReady(nic.ifname().to_string()));
+7 -6
View File
@@ -93,8 +93,8 @@ impl EasyTierLauncher {
} }
} }
#[cfg(any(target_os = "android", target_env = "ohos"))] #[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
async fn run_routine_for_android( async fn run_routine_for_mobile(
instance: &Instance, instance: &Instance,
data: &EasyTierData, data: &EasyTierData,
tasks: &mut JoinSet<()>, tasks: &mut JoinSet<()>,
@@ -111,8 +111,9 @@ impl EasyTierLauncher {
let Some(tun_fd) = tun_fd_receiver.recv().await.flatten() else { let Some(tun_fd) = tun_fd_receiver.recv().await.flatten() else {
return; return;
}; };
if Some(tun_fd) != old_tun_fd { // iOS needs to re-setup nic ctx even if the tun fd is the same
let res = Instance::setup_nic_ctx_for_android( if Some(tun_fd) != old_tun_fd || cfg!(target_os = "ios") {
let res = Instance::setup_nic_ctx_for_mobile(
nic_ctx.clone(), nic_ctx.clone(),
global_ctx.clone(), global_ctx.clone(),
peer_mgr.clone(), peer_mgr.clone(),
@@ -158,8 +159,8 @@ impl EasyTierLauncher {
} }
}); });
#[cfg(any(target_os = "android", target_env = "ohos"))] #[cfg(any(target_os = "android", target_os = "ios", target_env = "ohos"))]
Self::run_routine_for_android(&instance, &data, &mut tasks).await; Self::run_routine_for_mobile(&instance, &data, &mut tasks).await;
instance.run().await?; instance.run().await?;