diff --git a/easytier/src/instance/instance.rs b/easytier/src/instance/instance.rs index d6c2f156..6d927256 100644 --- a/easytier/src/instance/instance.rs +++ b/easytier/src/instance/instance.rs @@ -4,15 +4,17 @@ use std::collections::HashSet; use std::net::{IpAddr, Ipv4Addr}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Weak}; -#[cfg(feature = "tun")] +#[cfg(all(feature = "tun", not(mobile)))] use std::time::Duration; use anyhow::Context; use cidr::{IpCidr, Ipv4Inet}; use futures::FutureExt; +#[cfg(all(feature = "tun", not(mobile)))] +use tokio::sync::oneshot; use tokio::sync::{Mutex, Notify}; #[cfg(feature = "tun")] -use tokio::{sync::oneshot, task::JoinSet}; +use tokio::task::JoinSet; #[cfg(feature = "magic-dns")] use tokio_util::sync::CancellationToken; use tokio_util::task::AbortOnDropHandle; @@ -1588,12 +1590,19 @@ impl Instance { .await .with_context(|| "add ip failed")?; + #[cfg(feature = "magic-dns")] let magic_dns_runner = if let Some(ipv4) = global_ctx.get_ipv4() { Self::create_magic_dns_runner(peer_manager.clone(), None, ipv4) } else { None }; - Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx, magic_dns_runner).await; + Self::use_new_nic_ctx( + nic_ctx.clone(), + new_nic_ctx, + #[cfg(feature = "magic-dns")] + magic_dns_runner, + ) + .await; Ok(()) } diff --git a/easytier/src/instance/shared_virtual_nic.rs b/easytier/src/instance/shared_virtual_nic.rs index aaa0009c..6f5a4213 100644 --- a/easytier/src/instance/shared_virtual_nic.rs +++ b/easytier/src/instance/shared_virtual_nic.rs @@ -404,6 +404,26 @@ impl SharedVirtualNic { )); Ok(()) } + + #[cfg(mobile)] + async fn ensure_dispatcher_for_mobile( + &mut self, + tun_fd: std::os::fd::RawFd, + ) -> Result<(), Error> { + self.ensure_valid()?; + + if self.dispatcher.is_some() { + return Ok(()); + } + + let tunnel = self.nic.lock().await.create_dev_for_mobile(tun_fd).await?; + self.dispatcher = Some(SharedVirtualNicDispatcher::start( + tunnel, + self.member_tunnel_table.clone(), + self.valid.clone(), + )); + Ok(()) + } } struct SharedVirtualNicMemberRegistration { @@ -500,6 +520,21 @@ impl SharedVirtualNicMember { Ok(member_tunnel) } + #[cfg(mobile)] + pub async fn create_dev_for_mobile( + &self, + tun_fd: std::os::fd::RawFd, + ) -> Result, Error> { + let (member_tunnel, shared_tunnel) = create_ring_tunnel_pair(); + { + let mut shared_nic = self.shared_nic.lock().await; + shared_nic.ensure_dispatcher_for_mobile(tun_fd).await?; + } + self.registration + .register_tunnel(shared_tunnel, self.close_notifier.clone())?; + Ok(member_tunnel) + } + #[cfg(not(target_os = "linux"))] pub async fn ifcfg_and_ifname(&self) -> Result<(IfConfiger, String), Error> { self.shared_nic.lock().await.ifcfg_and_ifname().await diff --git a/easytier/src/instance/virtual_nic.rs b/easytier/src/instance/virtual_nic.rs index b0cc00ca..c7c7a2de 100644 --- a/easytier/src/instance/virtual_nic.rs +++ b/easytier/src/instance/virtual_nic.rs @@ -863,7 +863,7 @@ impl NicBackend { ) -> Result, Error> { match self { Self::Dedicated(nic) => nic.lock().await.create_dev_for_mobile(tun_fd).await, - Self::Shared(member) => member.create_dev().await, + Self::Shared(member) => member.create_dev_for_mobile(tun_fd).await, } } diff --git a/easytier/src/launcher.rs b/easytier/src/launcher.rs index 9b7d4f4a..a4056cf1 100644 --- a/easytier/src/launcher.rs +++ b/easytier/src/launcher.rs @@ -128,7 +128,7 @@ impl EasyTierLauncher { let Some(tun_fd) = tun_fd_receiver.recv().await.flatten() else { return; }; - let res = Instance::setup_nic_ctx_for_mobile( + let _ = Instance::setup_nic_ctx_for_mobile( nic_ctx.clone(), global_ctx.clone(), peer_mgr.clone(),