mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-09 11:14:30 +00:00
Android Support (#166)
1. Add vpnservice tauri plugin for android. 2. add workflow for android. 3. Easytier Core support android, allow set tun fd.
This commit is contained in:
@@ -214,7 +214,7 @@ impl Instance {
|
||||
let peer_manager_c = self.peer_manager.clone();
|
||||
let global_ctx_c = self.get_global_ctx();
|
||||
let nic_ctx = self.nic_ctx.clone();
|
||||
let peer_packet_receiver = self.peer_packet_receiver.clone();
|
||||
let _peer_packet_receiver = self.peer_packet_receiver.clone();
|
||||
tokio::spawn(async move {
|
||||
let default_ipv4_addr = Ipv4Inet::new(Ipv4Addr::new(10, 126, 126, 0), 24).unwrap();
|
||||
let mut current_dhcp_ip: Option<Ipv4Inet> = None;
|
||||
@@ -286,26 +286,31 @@ impl Instance {
|
||||
));
|
||||
continue;
|
||||
}
|
||||
let mut new_nic_ctx = NicCtx::new(
|
||||
global_ctx_c.clone(),
|
||||
&peer_manager_c,
|
||||
peer_packet_receiver.clone(),
|
||||
);
|
||||
if let Err(e) = new_nic_ctx.run(ip.address()).await {
|
||||
tracing::error!(
|
||||
?current_dhcp_ip,
|
||||
?candidate_ipv4_addr,
|
||||
?e,
|
||||
"add ip failed"
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
let mut new_nic_ctx = NicCtx::new(
|
||||
global_ctx_c.clone(),
|
||||
&peer_manager_c,
|
||||
_peer_packet_receiver.clone(),
|
||||
);
|
||||
global_ctx_c.set_ipv4(None);
|
||||
continue;
|
||||
if let Err(e) = new_nic_ctx.run(ip.address()).await {
|
||||
tracing::error!(
|
||||
?current_dhcp_ip,
|
||||
?candidate_ipv4_addr,
|
||||
?e,
|
||||
"add ip failed"
|
||||
);
|
||||
global_ctx_c.set_ipv4(None);
|
||||
continue;
|
||||
}
|
||||
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx).await;
|
||||
}
|
||||
|
||||
current_dhcp_ip = Some(ip);
|
||||
global_ctx_c.set_ipv4(Some(ip.address()));
|
||||
global_ctx_c
|
||||
.issue_event(GlobalCtxEvent::DhcpIpv4Changed(last_ip, Some(ip.address())));
|
||||
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx).await;
|
||||
} else {
|
||||
current_dhcp_ip = None;
|
||||
global_ctx_c.set_ipv4(None);
|
||||
@@ -326,14 +331,17 @@ impl Instance {
|
||||
|
||||
if self.global_ctx.config.get_flags().no_tun {
|
||||
self.peer_packet_receiver.lock().await.close();
|
||||
} else if let Some(ipv4_addr) = self.global_ctx.get_ipv4() {
|
||||
let mut new_nic_ctx = NicCtx::new(
|
||||
self.global_ctx.clone(),
|
||||
&self.peer_manager,
|
||||
self.peer_packet_receiver.clone(),
|
||||
);
|
||||
new_nic_ctx.run(ipv4_addr).await?;
|
||||
Self::use_new_nic_ctx(self.nic_ctx.clone(), new_nic_ctx).await;
|
||||
} else {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
if let Some(ipv4_addr) = self.global_ctx.get_ipv4() {
|
||||
let mut new_nic_ctx = NicCtx::new(
|
||||
self.global_ctx.clone(),
|
||||
&self.peer_manager,
|
||||
self.peer_packet_receiver.clone(),
|
||||
);
|
||||
new_nic_ctx.run(ipv4_addr).await?;
|
||||
Self::use_new_nic_ctx(self.nic_ctx.clone(), new_nic_ctx).await;
|
||||
}
|
||||
}
|
||||
|
||||
if self.global_ctx.config.get_dhcp() {
|
||||
@@ -506,4 +514,38 @@ impl Instance {
|
||||
pub fn get_vpn_portal_inst(&self) -> Arc<Mutex<Box<dyn VpnPortal>>> {
|
||||
self.vpn_portal.clone()
|
||||
}
|
||||
|
||||
pub fn get_nic_ctx(&self) -> ArcNicCtx {
|
||||
self.nic_ctx.clone()
|
||||
}
|
||||
|
||||
pub fn get_peer_packet_receiver(&self) -> Arc<Mutex<PacketRecvChanReceiver>> {
|
||||
self.peer_packet_receiver.clone()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub async fn setup_nic_ctx_for_android(
|
||||
nic_ctx: ArcNicCtx,
|
||||
global_ctx: ArcGlobalCtx,
|
||||
peer_manager: Arc<PeerManager>,
|
||||
peer_packet_receiver: Arc<Mutex<PacketRecvChanReceiver>>,
|
||||
fd: i32,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
println!("setup_nic_ctx_for_android, fd: {}", fd);
|
||||
Self::clear_nic_ctx(nic_ctx.clone()).await;
|
||||
if fd <= 0 {
|
||||
return Ok(());
|
||||
}
|
||||
let mut new_nic_ctx = NicCtx::new(
|
||||
global_ctx.clone(),
|
||||
&peer_manager,
|
||||
peer_packet_receiver.clone(),
|
||||
);
|
||||
new_nic_ctx
|
||||
.run_for_android(fd)
|
||||
.await
|
||||
.with_context(|| "add ip failed")?;
|
||||
Self::use_new_nic_ctx(nic_ctx.clone(), new_nic_ctx).await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +274,9 @@ impl VirtualNic {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let dev_name = self.global_ctx.get_flags().dev_name;
|
||||
config.name(format!("{}{}", dev_name, 0));
|
||||
if !dev_name.is_empty() {
|
||||
config.name(format!("{}", dev_name));
|
||||
}
|
||||
config.platform(|config| {
|
||||
// detect protocol by ourselves for cross platform
|
||||
config.packet_information(false);
|
||||
@@ -318,7 +320,37 @@ impl VirtualNic {
|
||||
Ok(create_as_async(&config)?)
|
||||
}
|
||||
|
||||
async fn create_dev_ret_err(&mut self) -> Result<Box<dyn Tunnel>, Error> {
|
||||
#[cfg(target_os = "android")]
|
||||
pub async fn create_dev_for_android(
|
||||
&mut self,
|
||||
tun_fd: std::os::fd::RawFd,
|
||||
) -> Result<Box<dyn Tunnel>, Error> {
|
||||
println!("tun_fd: {}", tun_fd);
|
||||
let mut config = Configuration::default();
|
||||
config.layer(Layer::L3);
|
||||
config.raw_fd(tun_fd);
|
||||
config.platform(|config| {
|
||||
config.no_close_fd_on_drop(true);
|
||||
});
|
||||
config.up();
|
||||
|
||||
let dev = create_as_async(&config)?;
|
||||
let (a, b) = BiLock::new(dev);
|
||||
let ft = TunnelWrapper::new(
|
||||
TunStream::new(a, false),
|
||||
FramedWriter::new_with_converter(
|
||||
TunAsyncWrite { l: b },
|
||||
TunZCPacketToBytes::new(false),
|
||||
),
|
||||
None,
|
||||
);
|
||||
|
||||
self.ifname = Some(format!("tunfd_{}", tun_fd));
|
||||
|
||||
Ok(Box::new(ft))
|
||||
}
|
||||
|
||||
pub async fn create_dev(&mut self) -> Result<Box<dyn Tunnel>, Error> {
|
||||
let dev = self.create_tun().await?;
|
||||
let ifname = dev.get_ref().name()?;
|
||||
self.ifcfg.wait_interface_show(ifname.as_str()).await?;
|
||||
@@ -351,10 +383,6 @@ impl VirtualNic {
|
||||
Ok(Box::new(ft))
|
||||
}
|
||||
|
||||
pub async fn create_dev(&mut self) -> Result<Box<dyn Tunnel>, Error> {
|
||||
self.create_dev_ret_err().await
|
||||
}
|
||||
|
||||
pub fn ifname(&self) -> &str {
|
||||
self.ifname.as_ref().unwrap().as_str()
|
||||
}
|
||||
@@ -589,6 +617,24 @@ impl NicCtx {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub async fn run_for_android(&mut self, tun_fd: std::os::fd::RawFd) -> Result<(), Error> {
|
||||
let tunnel = {
|
||||
let mut nic = self.nic.lock().await;
|
||||
let ret = nic.create_dev_for_android(tun_fd).await?;
|
||||
self.global_ctx
|
||||
.issue_event(GlobalCtxEvent::TunDeviceReady(nic.ifname().to_string()));
|
||||
ret
|
||||
};
|
||||
|
||||
let (stream, sink) = tunnel.split();
|
||||
|
||||
self.do_forward_nic_to_peers(stream)?;
|
||||
self.do_forward_peers_to_nic(sink);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user