diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs index b49938f2..d146d700 100644 --- a/easytier/src/common/config.rs +++ b/easytier/src/common/config.rs @@ -70,7 +70,11 @@ pub trait ConfigLoader: Send + Sync { fn get_dhcp(&self) -> bool; fn set_dhcp(&self, dhcp: bool); - fn add_proxy_cidr(&self, cidr: cidr::Ipv4Cidr, mapped_cidr: Option); + fn add_proxy_cidr( + &self, + cidr: cidr::Ipv4Cidr, + mapped_cidr: Option, + ) -> Result<(), anyhow::Error>; fn remove_proxy_cidr(&self, cidr: cidr::Ipv4Cidr); fn get_proxy_cidrs(&self) -> Vec; @@ -445,17 +449,23 @@ impl ConfigLoader for TomlConfigLoader { self.config.lock().unwrap().dhcp = Some(dhcp); } - fn add_proxy_cidr(&self, cidr: cidr::Ipv4Cidr, mapped_cidr: Option) { + fn add_proxy_cidr( + &self, + cidr: cidr::Ipv4Cidr, + mapped_cidr: Option, + ) -> Result<(), anyhow::Error> { let mut locked_config = self.config.lock().unwrap(); if locked_config.proxy_network.is_none() { locked_config.proxy_network = Some(vec![]); } if let Some(mapped_cidr) = mapped_cidr.as_ref() { - assert_eq!( - cidr.network_length(), - mapped_cidr.network_length(), - "Mapped CIDR must have the same network length as the original CIDR", - ); + if cidr.network_length() != mapped_cidr.network_length() { + return Err(anyhow::anyhow!( + "Mapped CIDR must have the same network length as the original CIDR: {} != {}", + cidr.network_length(), + mapped_cidr.network_length() + )); + } } // insert if no duplicate if !locked_config @@ -475,6 +485,7 @@ impl ConfigLoader for TomlConfigLoader { allow: None, }); } + Ok(()) } fn remove_proxy_cidr(&self, cidr: cidr::Ipv4Cidr) { diff --git a/easytier/src/connector/dns_connector.rs b/easytier/src/connector/dns_connector.rs index 97bc64d9..bcc0d539 100644 --- a/easytier/src/connector/dns_connector.rs +++ b/easytier/src/connector/dns_connector.rs @@ -168,13 +168,23 @@ impl DNSTunnelConnector { impl super::TunnelConnector for DNSTunnelConnector { async fn connect(&mut self) -> Result, TunnelError> { let mut conn = if self.addr.scheme() == "txt" { - self.handle_txt_record(self.addr.host_str().as_ref().unwrap()) - .await - .with_context(|| "get txt record url failed")? + self.handle_txt_record( + self.addr + .host_str() + .as_ref() + .ok_or(anyhow::anyhow!("host should not be empty in txt url"))?, + ) + .await + .with_context(|| "get txt record url failed")? } else if self.addr.scheme() == "srv" { - self.handle_srv_record(self.addr.host_str().as_ref().unwrap()) - .await - .with_context(|| "get srv record url failed")? + self.handle_srv_record( + self.addr + .host_str() + .as_ref() + .ok_or(anyhow::anyhow!("host should not be empty in srv url"))?, + ) + .await + .with_context(|| "get srv record url failed")? } else { return Err(anyhow::anyhow!( "unsupported dns scheme: {}, expecting txt or srv", diff --git a/easytier/src/connector/mod.rs b/easytier/src/connector/mod.rs index ba202cd4..bd3a10d5 100644 --- a/easytier/src/connector/mod.rs +++ b/easytier/src/connector/mod.rs @@ -147,6 +147,12 @@ pub async fn create_connector_by_url( Box::new(connector) } "txt" | "srv" => { + if url.host_str().is_none() { + return Err(Error::InvalidUrl(format!( + "host should not be empty in txt or srv url: {}", + url + ))); + } let connector = dns_connector::DNSTunnelConnector::new(url, global_ctx.clone()); Box::new(connector) } diff --git a/easytier/src/easytier-core.rs b/easytier/src/easytier-core.rs index 7f23c6bf..a7ef78bc 100644 --- a/easytier/src/easytier-core.rs +++ b/easytier/src/easytier-core.rs @@ -658,6 +658,7 @@ impl NetworkOptions { } if !self.mapped_listeners.is_empty() { + let mut errs = Vec::new(); cfg.set_mapped_listeners(Some( self.mapped_listeners .iter() @@ -668,12 +669,21 @@ impl NetworkOptions { }) .map(|s: url::Url| { if s.port().is_none() { - panic!("mapped listener port is missing: {}", s); + errs.push(anyhow::anyhow!("mapped listener port is missing: {}", s)); } s }) - .collect(), + .collect::>(), )); + if !errs.is_empty() { + return Err(anyhow::anyhow!( + "{}", + errs.iter() + .map(|x| format!("{}", x)) + .collect::>() + .join("\n") + )); + } } for n in self.proxy_networks.iter() { diff --git a/easytier/src/launcher.rs b/easytier/src/launcher.rs index eb21cc74..1c8c5a52 100644 --- a/easytier/src/launcher.rs +++ b/easytier/src/launcher.rs @@ -483,7 +483,7 @@ pub fn add_proxy_network_to_config( } else { None }; - cfg.add_proxy_cidr(real_cidr, mapped_cidr); + cfg.add_proxy_cidr(real_cidr, mapped_cidr)?; Ok(()) } @@ -1003,7 +1003,7 @@ mod tests { } else { None }; - config.add_proxy_cidr(network, mapped_network); + config.add_proxy_cidr(network, mapped_network).unwrap(); } } diff --git a/easytier/src/tests/three_node.rs b/easytier/src/tests/three_node.rs index 1d5d6f82..d0e775cd 100644 --- a/easytier/src/tests/three_node.rs +++ b/easytier/src/tests/three_node.rs @@ -448,7 +448,8 @@ pub async fn quic_proxy() { "udp", |cfg| { if cfg.get_inst_name() == "inst3" { - cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap(), None); + cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap(), None) + .unwrap(); } cfg }, @@ -498,11 +499,13 @@ pub async fn subnet_proxy_three_node_test( flags.disable_quic_input = disable_quic_input; flags.enable_quic_proxy = dst_enable_quic_proxy; cfg.set_flags(flags); - cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap(), None); + cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap(), None) + .unwrap(); cfg.add_proxy_cidr( "10.1.2.0/24".parse().unwrap(), Some("10.1.3.0/24".parse().unwrap()), - ); + ) + .unwrap(); } if cfg.get_inst_name() == "inst2" && relay_by_public_server { @@ -1181,7 +1184,8 @@ pub async fn port_forward_test( }, ]); } else if cfg.get_inst_name() == "inst3" { - cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap(), None); + cfg.add_proxy_cidr("10.1.2.0/24".parse().unwrap(), None) + .unwrap(); } let mut flags = cfg.get_flags(); flags.no_tun = no_tun;