From f410230240b270ec01cfbf0002cbe9d3849eb03b Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 4 Apr 2023 19:06:33 +0200 Subject: [PATCH] parse private_ip earlier --- src/config/options_test.rs | 4 ++-- src/config/runtime.rs | 13 +++++++++---- src/diplonat.rs | 2 +- src/fw.rs | 2 +- src/igd_actor.rs | 28 ++++++++++++---------------- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/config/options_test.rs b/src/config/options_test.rs index 655fb01..8e05c90 100644 --- a/src/config/options_test.rs +++ b/src/config/options_test.rs @@ -26,7 +26,7 @@ fn all_valid_options() -> HashMap { ); opts.insert( "DIPLONAT_PRIVATE_IP".to_string(), - "172.123.43.555".to_string(), + "172.123.43.55".to_string(), ); opts.insert("DIPLONAT_REFRESH_TIME".to_string(), "10".to_string()); opts.insert( @@ -118,7 +118,7 @@ fn ok_from_iter_all_valid_options() { ); assert_eq!(rt_config.firewall.refresh_time, refresh_time); assert_eq!( - &rt_config.igd.private_ip.unwrap(), + &rt_config.igd.private_ip.unwrap().to_string(), opts.get(&"DIPLONAT_PRIVATE_IP".to_string()).unwrap() ); assert_eq!(rt_config.igd.expiration_time, expiration_time); diff --git a/src/config/runtime.rs b/src/config/runtime.rs index bffea52..45a29c3 100644 --- a/src/config/runtime.rs +++ b/src/config/runtime.rs @@ -1,9 +1,9 @@ use std::fs::File; use std::io::Read; -use std::net::{SocketAddr, ToSocketAddrs}; +use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs}; use std::time::Duration; -use anyhow::{anyhow, bail, Result}; +use anyhow::{anyhow, bail, Context, Result}; use crate::config::{ConfigOpts, ConfigOptsAcme, ConfigOptsBase, ConfigOptsConsul}; @@ -31,7 +31,7 @@ pub struct RuntimeConfigFirewall { #[derive(Debug)] pub struct RuntimeConfigIgd { - pub private_ip: Option, + pub private_ip: Option, pub expiration_time: Duration, pub refresh_time: Duration, } @@ -137,7 +137,12 @@ impl RuntimeConfigFirewall { impl RuntimeConfigIgd { pub(super) fn new(opts: &ConfigOptsBase) -> Result { - let private_ip = opts.private_ip.clone(); + let private_ip = opts + .private_ip + .as_ref() + .map(|x| x.parse()) + .transpose() + .context("parse private_ip")?; let expiration_time = Duration::from_secs( opts.expiration_time .unwrap_or(super::EXPIRATION_TIME) diff --git a/src/diplonat.rs b/src/diplonat.rs index 604227c..a66836a 100644 --- a/src/diplonat.rs +++ b/src/diplonat.rs @@ -23,7 +23,7 @@ impl Diplonat { let fw = FirewallActor::new(rt_cfg.firewall.refresh_time, &ca.rx_open_ports).await?; let ia = IgdActor::new( - rt_cfg.igd.private_ip.as_ref().map(String::as_str), + rt_cfg.igd.private_ip, rt_cfg.igd.refresh_time, rt_cfg.igd.expiration_time, &ca.rx_open_ports, diff --git a/src/fw.rs b/src/fw.rs index 6745b3f..88aaa86 100644 --- a/src/fw.rs +++ b/src/fw.rs @@ -11,7 +11,7 @@ pub fn setup(ipt: &iptables::IPTables) -> Result<()> { // ensure we start from a clean state without any rule already set cleanup(ipt)?; - info!("{}: creating DIPLONAT chain using", ipt.cmd); + info!("{}: creating DIPLONAT chain", ipt.cmd); ipt.new_chain("filter", "DIPLONAT") .context("Failed to create new chain")?; ipt.insert_unique("filter", "INPUT", "-j DIPLONAT", 1) diff --git a/src/igd_actor.rs b/src/igd_actor.rs index a75395d..f0dd391 100644 --- a/src/igd_actor.rs +++ b/src/igd_actor.rs @@ -1,4 +1,4 @@ -use std::net::SocketAddrV4; +use std::net::{Ipv4Addr, SocketAddrV4}; use anyhow::{Context, Result}; use igd::{aio::*, PortMappingProtocol}; @@ -17,12 +17,12 @@ pub struct IgdActor { gateway: Gateway, refresh: Duration, expire: Duration, - private_ip: String, + private_ip: Ipv4Addr, } impl IgdActor { pub async fn new( - priv_ip: Option<&str>, + priv_ip: Option, refresh: Duration, expire: Duration, rxp: &watch::Receiver, @@ -34,7 +34,7 @@ impl IgdActor { let private_ip = if let Some(ip) = priv_ip { info!("Using private IP from config: {}", ip); - ip.to_string() + ip } else { info!("Trying to automatically detect private IP"); let gwa = gw.addr.ip().octets(); @@ -47,18 +47,17 @@ impl IgdActor { ), }; #[allow(unused_parens)] - let public_ip = get_if_addrs::get_if_addrs()? + let private_ip = get_if_addrs::get_if_addrs()? .into_iter() .map(|i| i.addr.ip()) - .filter(|a| match a { - std::net::IpAddr::V4(a4) => (a4.octets()[..cmplen] == gwa[..cmplen]), - _ => false, + .filter_map(|a| match a { + std::net::IpAddr::V4(a4) if a4.octets()[..cmplen] == gwa[..cmplen] => Some(a4), + _ => None, }) .next() - .expect("No interface has an IP on same subnet as gateway") - .to_string(); - info!("Found private IP: {}", public_ip); - public_ip + .expect("No interface has an IP on same subnet as gateway"); + info!("Autodetected private IP: {}", private_ip); + private_ip }; let ctx = Self { @@ -104,10 +103,7 @@ impl IgdActor { for (proto, list) in actions.iter() { for port in *list { - let service_str = format!("{}:{}", self.private_ip, port); - let service = service_str - .parse::() - .context("Invalid socket address")?; + let service = SocketAddrV4::new(self.private_ip, *port); self.gateway .add_port( *proto,