diff --git a/easytier-gui/src/App.vue b/easytier-gui/src/App.vue index 69e67eaa..4f9a60f8 100644 --- a/easytier-gui/src/App.vue +++ b/easytier-gui/src/App.vue @@ -6,9 +6,11 @@ import StepperPanel from 'primevue/stepperpanel'; import { useToast } from "primevue/usetoast"; -import { i18n, loadLocaleFromLocalStorage, NetworkConfig, parseNetworkConfig, +import { + i18n, loadLocaleFromLocalStorage, NetworkConfig, parseNetworkConfig, useNetworkStore, runNetworkInstance, retainNetworkInstance, collectNetworkInfos, - changeLocale } from './main'; + changeLocale +} from './main'; import Config from './components/Config.vue'; import Status from './components/Status.vue'; @@ -35,7 +37,9 @@ const items = ref([ { label: () => i18n.global.t('del_cur_network'), icon: 'pi pi-times', - command: () => { + command: async () => { + networkStore.removeNetworkInstance(networkStore.curNetwork.instance_id); + await retainNetworkInstance(networkStore.networkInstanceIds); networkStore.delCurNetwork(); }, disabled: () => networkStore.networkList.length <= 1, diff --git a/easytier/src/arch/windows.rs b/easytier/src/arch/windows.rs index 2554cde5..2ee8452c 100644 --- a/easytier/src/arch/windows.rs +++ b/easytier/src/arch/windows.rs @@ -60,6 +60,16 @@ pub fn disable_connection_reset(socket: &S) -> io::Result<()> { Ok(()) } +pub fn interface_count() -> io::Result { + let ifaces = network_interface::NetworkInterface::show().map_err(|e| { + io::Error::new( + ErrorKind::NotFound, + format!("Failed to get interfaces. error: {}", e), + ) + })?; + Ok(ifaces.len()) +} + pub fn find_interface_index(iface_name: &str) -> io::Result { let ifaces = network_interface::NetworkInterface::show().map_err(|e| { io::Error::new( diff --git a/easytier/src/instance/instance.rs b/easytier/src/instance/instance.rs index 29fc243e..64742a65 100644 --- a/easytier/src/instance/instance.rs +++ b/easytier/src/instance/instance.rs @@ -9,6 +9,7 @@ use futures::{SinkExt, StreamExt}; use pnet::packet::ipv4::Ipv4Packet; use tokio::{sync::Mutex, task::JoinSet}; +use tonic::transport::server::TcpIncoming; use tonic::transport::Server; use crate::common::config::ConfigLoader; @@ -285,7 +286,7 @@ impl Instance { self.listener_manager.lock().await.run().await?; self.peer_manager.run().await?; - self.run_rpc_server().unwrap(); + self.run_rpc_server()?; self.ip_proxy = Some(IpProxy::new( self.get_global_ctx(), @@ -390,7 +391,7 @@ impl Instance { } } - fn run_rpc_server(&mut self) -> Result<(), Box> { + fn run_rpc_server(&mut self) -> Result<(), Error> { let Some(addr) = self.global_ctx.config.get_rpc_portal() else { tracing::info!("rpc server not enabled, because rpc_portal is not set."); return Ok(()); @@ -401,6 +402,8 @@ impl Instance { let peer_center = self.peer_center.clone(); let vpn_portal_rpc = self.get_vpn_portal_rpc_service(); + let incoming = TcpIncoming::new(addr, true, None) + .map_err(|e| anyhow::anyhow!("create rpc server failed. addr: {}, err: {}", addr, e))?; self.tasks.spawn(async move { let _g = net_ns.guard(); Server::builder() @@ -422,7 +425,7 @@ impl Instance { .add_service(crate::rpc::vpn_portal_rpc_server::VpnPortalRpcServer::new( vpn_portal_rpc, )) - .serve(addr) + .serve_with_incoming(incoming) .await .with_context(|| format!("rpc server failed. addr: {}", addr)) .unwrap(); diff --git a/easytier/src/instance/virtual_nic.rs b/easytier/src/instance/virtual_nic.rs index 75e7d3f8..e6b7238c 100644 --- a/easytier/src/instance/virtual_nic.rs +++ b/easytier/src/instance/virtual_nic.rs @@ -273,6 +273,15 @@ impl VirtualNic { }); } + #[cfg(target_os = "windows")] + { + use std::net::IpAddr; + let c = crate::arch::windows::interface_count()?; + config.name(format!("et{}_{}", self.dev_name, c)); + // set a temporary address + config.address(format!("172.0.{}.3", c).parse::().unwrap()); + } + if self.queue_num != 1 { todo!("queue_num != 1") }