From 02f87ba9ccf199fb8d39014f2542e0dd4d902190 Mon Sep 17 00:00:00 2001 From: Bran Liang Date: Fri, 27 Jan 2023 23:02:47 +0800 Subject: [PATCH] Enable tun destination configuration --- crates/shadowsocks-service/src/config.rs | 10 ++++++++++ crates/shadowsocks-service/src/local/mod.rs | 3 +++ crates/shadowsocks-service/src/local/tun/mod.rs | 5 +++++ src/service/local.rs | 11 +++++++++++ src/vparser/mod.rs | 6 +----- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/crates/shadowsocks-service/src/config.rs b/crates/shadowsocks-service/src/config.rs index 892cef25..11236b79 100644 --- a/crates/shadowsocks-service/src/config.rs +++ b/crates/shadowsocks-service/src/config.rs @@ -275,6 +275,9 @@ struct SSLocalExtConfig { #[cfg(feature = "local-tun")] #[serde(skip_serializing_if = "Option::is_none")] tun_interface_address: Option, + #[cfg(feature = "local-tun")] + #[serde(skip_serializing_if = "Option::is_none")] + tun_interface_destination: Option, #[cfg(all(feature = "local-tun", unix))] #[serde(skip_serializing_if = "Option::is_none")] tun_device_fd_from_path: Option, @@ -867,6 +870,9 @@ pub struct LocalConfig { /// Tun interface's address and netmask #[cfg(feature = "local-tun")] pub tun_interface_address: Option, + /// Tun interface's destination address and netmask + #[cfg(feature = "local-tun")] + pub tun_interface_destination: Option, /// Tun interface's file descriptor #[cfg(all(feature = "local-tun", unix))] pub tun_device_fd: Option, @@ -910,6 +916,8 @@ impl LocalConfig { tun_interface_name: None, #[cfg(feature = "local-tun")] tun_interface_address: None, + #[cfg(feature = "local-tun")] + tun_interface_destination: None, #[cfg(all(feature = "local-tun", unix))] tun_device_fd: None, #[cfg(all(feature = "local-tun", unix))] @@ -2403,6 +2411,8 @@ impl fmt::Display for Config { tun_interface_name: local.tun_interface_name.clone(), #[cfg(feature = "local-tun")] tun_interface_address: local.tun_interface_address.as_ref().map(ToString::to_string), + #[cfg(feature = "local-tun")] + tun_interface_destination: local.tun_interface_destination.as_ref().map(ToString::to_string), #[cfg(all(feature = "local-tun", unix))] tun_device_fd_from_path: local .tun_device_fd_from_path diff --git a/crates/shadowsocks-service/src/local/mod.rs b/crates/shadowsocks-service/src/local/mod.rs index cb79e1ef..da28bb33 100644 --- a/crates/shadowsocks-service/src/local/mod.rs +++ b/crates/shadowsocks-service/src/local/mod.rs @@ -356,6 +356,9 @@ pub async fn create(config: Config) -> io::Result { if let Some(address) = local_config.tun_interface_address { builder = builder.address(address); } + if let Some(address) = local_config.tun_interface_destination { + builder = builder.destination(address); + } if let Some(name) = local_config.tun_interface_name { builder = builder.name(&name); } diff --git a/crates/shadowsocks-service/src/local/tun/mod.rs b/crates/shadowsocks-service/src/local/tun/mod.rs index 45a8e333..3cbfb7bb 100644 --- a/crates/shadowsocks-service/src/local/tun/mod.rs +++ b/crates/shadowsocks-service/src/local/tun/mod.rs @@ -58,6 +58,11 @@ impl TunBuilder { self } + pub fn destination(mut self, addr: IpNet) -> TunBuilder { + self.tun_config.destination(addr.addr()); + self + } + pub fn name(mut self, name: &str) -> TunBuilder { self.tun_config.name(name); self diff --git a/src/service/local.rs b/src/service/local.rs index 64c493d1..6e122754 100644 --- a/src/service/local.rs +++ b/src/service/local.rs @@ -415,6 +415,14 @@ pub fn define_command_line_options(mut app: Command) -> Command { .action(ArgAction::Set) .value_parser(vparser::parse_ipnet) .help("Tun interface address (network)"), + ) + .arg( + Arg::new("TUN_INTERFACE_DESTINATION") + .long("tun-interface-destination") + .num_args(1) + .action(ArgAction::Set) + .value_parser(vparser::parse_ipnet) + .help("Tun interface destination address (network)"), ); #[cfg(unix)] @@ -702,6 +710,9 @@ pub fn main(matches: &ArgMatches) -> ExitCode { if let Some(tun_address) = matches.get_one::("TUN_INTERFACE_ADDRESS").cloned() { local_config.tun_interface_address = Some(tun_address); } + if let Some(tun_address) = matches.get_one::("TUN_INTERFACE_DESTINATION").cloned() { + local_config.tun_interface_destination = Some(tun_address); + } if let Some(tun_name) = matches.get_one::("TUN_INTERFACE_NAME").cloned() { local_config.tun_interface_name = Some(tun_name); } diff --git a/src/vparser/mod.rs b/src/vparser/mod.rs index efe4c996..cc3b915c 100644 --- a/src/vparser/mod.rs +++ b/src/vparser/mod.rs @@ -61,11 +61,7 @@ pub fn parse_ipnet(v: &str) -> Result { match v.parse::() { Err(..) => Err("should be a CIDR address like 10.1.2.3/24".to_owned()), Ok(n) => { - if n.trunc() == n { - Err("should be a valid CIDR address with a host like 10.1.2.3/24".to_owned()) - } else { - Ok(n) - } + Ok(n) } } }