From 0ed18211d5f29148889b8ab24a4489b47cd4efe4 Mon Sep 17 00:00:00 2001 From: Andrewmatilde Date: Fri, 26 Nov 2021 15:33:33 +0800 Subject: [PATCH] fix bug on network (#23) * fix bug on network Signed-off-by: andrewmatilde * minor fix Signed-off-by: andrewmatilde * block none port Signed-off-by: andrewmatilde * block none port Signed-off-by: andrewmatilde * main > all Signed-off-by: andrewmatilde --- README.md | 2 +- rs-tproxy-controller/src/proxy/exec.rs | 3 ++ rs-tproxy-controller/src/proxy/net/bridge.rs | 42 ++++++++++++++++++-- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a6d9b39..5d6dcbf 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ Support json and yaml config. Example of config could be found in `./config-examples` ## Yaml config file example ```yaml -proxy_ports: [80] # option u16 vec ; proxy all tcp packet if not provided +proxy_ports: [80] # option u16 vec ; Do nothing if not provided interface: eth33 # option string rules: # option rule vec - target: Request # Request or Response. diff --git a/rs-tproxy-controller/src/proxy/exec.rs b/rs-tproxy-controller/src/proxy/exec.rs index 01bbe51..3f67224 100644 --- a/rs-tproxy-controller/src/proxy/exec.rs +++ b/rs-tproxy-controller/src/proxy/exec.rs @@ -143,6 +143,9 @@ impl Proxy { pub async fn reload(&mut self, config: ProxyRawConfig) -> anyhow::Result<()> { self.stop().await?; + if config.proxy_ports.is_none() { + return Ok(()); + } if self.task.is_none() { let mut new = Self::new(self.opt.verbose); self.opt = new.opt; diff --git a/rs-tproxy-controller/src/proxy/net/bridge.rs b/rs-tproxy-controller/src/proxy/net/bridge.rs index 1e062b2..b8d90ab 100644 --- a/rs-tproxy-controller/src/proxy/net/bridge.rs +++ b/rs-tproxy-controller/src/proxy/net/bridge.rs @@ -1,4 +1,5 @@ use std::process::Command; +use std::net::Ipv4Addr; use anyhow::{anyhow, Result}; use default_net; @@ -38,7 +39,7 @@ impl NetEnv { break key; } }; - let ip_route_store = Uuid::new_v4().to_string(); + let ip_route_store = "ip_route_store".to_string() + &Uuid::new_v4().to_string(); let device = get_default_interface().unwrap(); let netns = prefix.clone() + "ns"; let bridge1 = prefix.clone() + "b1"; @@ -177,19 +178,33 @@ impl NetEnv { } pub fn clear_bridge(&self) -> Result<()> { - let restore = format!("ip route restore < {}", &self.ip_route_store); let restore_dns = "cp /etc/resolv.conf.bak /etc/resolv.conf"; let remove_store = format!("rm -f {}", &self.ip_route_store); + + let net: Ipv4Network = self.ip.parse().unwrap(); + let net_domain = Ipv4Addr::from(u32::from(net.ip()) & u32::from(net.mask())).to_string() + + "/" + + &net.prefix().to_string(); + let del_default_route = format!("ip route del {} dev {} proto kernel scope link src {}", &net_domain, &self.device, &net.ip().to_string()); + let cmdvv = vec![ ip_netns_del(&self.netns), ip_link_del_bridge(&self.bridge1), ip_address("add", &self.ip, &self.device), bash_c(restore_dns), - bash_c(&restore), - bash_c(&remove_store), + bash_c(&del_default_route), clear_ebtables(), ]; execute_all_with_log_error(cmdvv)?; + + let ip_routes= restore_all_ip_routes(&self.ip_route_store)?; + let iproute_cmds: Vec> = ip_routes.iter().map(|s| bash_c(&**s)).collect(); + execute_all_with_log_error(iproute_cmds)?; + + let cmdvv = vec![ + bash_c(&remove_store), + ]; + execute_all_with_log_error(cmdvv)?; Ok(()) } } @@ -353,3 +368,22 @@ pub fn get_default_interface() -> Result { } Err(anyhow!("no valid interface")) } + +pub fn restore_all_ip_routes(path : &str) -> Result> { + let cmd_string = format!("ip route showdump < {}", path); + let mut cmd = Command::new("sh"); + cmd.arg("-c") + .arg(cmd_string); + let stdo = cmd.output()?.stdout; + let out = String::from_utf8_lossy(stdo.as_slice()); + + let mut ip_routes: Vec<_> = out.split('\n').collect(); + ip_routes.reverse(); + let mut route_cmds: Vec = Vec::new(); + for ip_route in ip_routes { + if !ip_route.is_empty() { + route_cmds.push(format!("{} {}", "ip route add", ip_route)); + } + } + Ok(route_cmds) +}