From 5451b52daaff1851d3f5f7fc48c02126c8bd0248 Mon Sep 17 00:00:00 2001 From: "Sijie.Sun" Date: Wed, 24 Jul 2024 22:45:55 +0800 Subject: [PATCH] allow set routes manually and disable propagated routes (#191) --- easytier/src/common/config.rs | 14 ++++++++++ easytier/src/common/global_ctx.rs | 1 + easytier/src/easytier-core.rs | 27 +++++++++++++++++++ easytier/src/instance/virtual_nic.rs | 39 ++++++++++++++++++++++------ 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs index 20ba1856..758ad34f 100644 --- a/easytier/src/common/config.rs +++ b/easytier/src/common/config.rs @@ -61,6 +61,9 @@ pub trait ConfigLoader: Send + Sync { fn get_exit_nodes(&self) -> Vec; fn set_exit_nodes(&self, nodes: Vec); + fn get_routes(&self) -> Option>; + fn set_routes(&self, routes: Option>); + fn dump(&self) -> String; } @@ -190,6 +193,8 @@ struct Config { vpn_portal_config: Option, + routes: Option>, + flags: Option, } @@ -487,6 +492,14 @@ impl ConfigLoader for TomlConfigLoader { fn dump(&self) -> String { toml::to_string_pretty(&*self.config.lock().unwrap()).unwrap() } + + fn get_routes(&self) -> Option> { + self.config.lock().unwrap().routes.clone() + } + + fn set_routes(&self, routes: Option>) { + self.config.lock().unwrap().routes = routes; + } } #[cfg(test)] @@ -500,6 +513,7 @@ instance_name = "default" instance_id = "87ede5a2-9c3d-492d-9bbe-989b9d07e742" ipv4 = "10.144.144.10" listeners = [ "tcp://0.0.0.0:11010", "udp://0.0.0.0:11010" ] +routes = [ "192.168.0.0/16" ] [network_identity] network_name = "default" diff --git a/easytier/src/common/global_ctx.rs b/easytier/src/common/global_ctx.rs index 040caf60..6e7f8c3d 100644 --- a/easytier/src/common/global_ctx.rs +++ b/easytier/src/common/global_ctx.rs @@ -20,6 +20,7 @@ pub type NetworkIdentity = crate::common::config::NetworkIdentity; #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub enum GlobalCtxEvent { TunDeviceReady(String), + TunDeviceError(String), PeerAdded(PeerId), PeerRemoved(PeerId), diff --git a/easytier/src/easytier-core.rs b/easytier/src/easytier-core.rs index eb3323bc..deb9c326 100644 --- a/easytier/src/easytier-core.rs +++ b/easytier/src/easytier-core.rs @@ -215,6 +215,14 @@ and the vpn client is in network of 10.14.14.0/24" default_value = "false" )] use_smoltcp: bool, + + #[arg( + long, + help = "assign routes cidr manually, will disable subnet proxy and + wireguard routes propogated from peers. e.g.: 192.168.0.0/16", + num_args = 0.. + )] + manual_routes: Option>, } impl Cli { @@ -420,6 +428,21 @@ impl From for TomlConfigLoader { }); } + if cli.manual_routes.is_some() { + cfg.set_routes(Some( + cli.manual_routes + .clone() + .unwrap() + .iter() + .map(|s| { + s.parse() + .with_context(|| format!("failed to parse route: {}", s)) + .unwrap() + }) + .collect(), + )); + } + let mut f = cfg.get_flags(); if cli.default_protocol.is_some() { f.default_protocol = cli.default_protocol.as_ref().unwrap().clone(); @@ -532,6 +555,10 @@ pub async fn async_main(cli: Cli) { print_event(format!("tun device ready. dev: {}", dev)); } + GlobalCtxEvent::TunDeviceError(err) => { + print_event(format!("tun device error. err: {}", err)); + } + GlobalCtxEvent::Connecting(dst) => { print_event(format!("connecting to peer. dst: {}", dst)); } diff --git a/easytier/src/instance/virtual_nic.rs b/easytier/src/instance/virtual_nic.rs index 38e358c6..4f16807a 100644 --- a/easytier/src/instance/virtual_nic.rs +++ b/easytier/src/instance/virtual_nic.rs @@ -544,6 +544,13 @@ impl NicCtx { proxy_cidrs.push(vpn_cfg.client_cidr); } + if let Some(routes) = global_ctx.config.get_routes() { + // if has manual routes, just override entire proxy_cidrs + proxy_cidrs = routes; + } + + println!("proxy_cidrs: {:?}", proxy_cidrs); + // if route is in cur_proxy_cidrs but not in proxy_cidrs, delete it. for cidr in cur_proxy_cidrs.iter() { if proxy_cidrs.contains(cidr) { @@ -601,10 +608,18 @@ impl NicCtx { pub async fn run(&mut self, ipv4_addr: Ipv4Addr) -> Result<(), Error> { let tunnel = { let mut nic = self.nic.lock().await; - let ret = nic.create_dev().await?; - self.global_ctx - .issue_event(GlobalCtxEvent::TunDeviceReady(nic.ifname().to_string())); - ret + match nic.create_dev().await { + Ok(ret) => { + self.global_ctx + .issue_event(GlobalCtxEvent::TunDeviceReady(nic.ifname().to_string())); + ret + } + Err(err) => { + self.global_ctx + .issue_event(GlobalCtxEvent::TunDeviceError(err.to_string())); + return Err(err); + } + } }; let (stream, sink) = tunnel.split(); @@ -622,10 +637,18 @@ impl NicCtx { 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 + match nic.create_dev_for_android(tun_fd).await { + Ok(ret) => { + self.global_ctx + .issue_event(GlobalCtxEvent::TunDeviceReady(nic.ifname().to_string())); + ret + } + Err(err) => { + self.global_ctx + .issue_event(GlobalCtxEvent::TunDeviceError(err.to_string())); + return Err(err); + } + } }; let (stream, sink) = tunnel.split();