diff --git a/easytier/src/connector/udp_hole_punch/cone.rs b/easytier/src/connector/udp_hole_punch/cone.rs index a88eb5c7..71be9519 100644 --- a/easytier/src/connector/udp_hole_punch/cone.rs +++ b/easytier/src/connector/udp_hole_punch/cone.rs @@ -120,7 +120,7 @@ impl PunchConeHoleClient { let local_addr = local_socket .local_addr() - .with_context(|| anyhow::anyhow!("failed to get local port from udp array"))?; + .with_context(|| "failed to get local port from udp array")?; let local_port = local_addr.port(); drop(local_socket); diff --git a/easytier/src/core.rs b/easytier/src/core.rs index 44f667d1..218d87af 100644 --- a/easytier/src/core.rs +++ b/easytier/src/core.rs @@ -740,43 +740,50 @@ impl Cli { return Ok(vec![]); } - let origin_listeners = listeners; - let mut listeners: Vec = Vec::new(); - if origin_listeners.len() == 1 - && let Ok(port) = origin_listeners[0].parse::() + if listeners.len() == 1 + && let Ok(port) = listeners[0].parse::() { - for proto in IpScheme::VARIANTS { - listeners.push(format!( - "{}://0.0.0.0:{}", - proto, - port + proto.port_offset() - )); - } + let listeners = IpScheme::VARIANTS + .iter() + .map(|proto| { + format!( + "{}://0.0.0.0:{}", + proto, + if port == 0 { + 0 + } else { + port + proto.port_offset() + } + ) + }) + .collect(); return Ok(listeners); } - for l in &origin_listeners { - let proto_port: Vec<&str> = l.split(':').collect(); - if proto_port.len() > 2 { - if let Ok(url) = l.parse::() { - listeners.push(url.to_string()); - } else { - panic!("failed to parse listener: {}", l); + listeners + .into_iter() + .map(|l| { + let l = l + .parse::() + .or_else(|_| url::Url::parse(&format!("{}:", l)))?; + + if l.has_authority() { + return Ok(l.to_string()); } - } else { - let scheme: IpScheme = proto_port[0].parse()?; - let port = if proto_port.len() == 2 { - proto_port[1].parse::().unwrap() - } else { - 11010 + scheme.port_offset() + let scheme: IpScheme = l.scheme().parse()?; + let port = { + let port = l.path(); + if port.is_empty() { + 11010 + scheme.port_offset() + } else { + port.parse::() + .with_context(|| format!("invalid port: {}", port))? + } }; - - listeners.push(format!("{}://0.0.0.0:{}", scheme, port)); - } - } - - Ok(listeners) + Ok(format!("{}://0.0.0.0:{}", scheme, port)) + }) + .collect() } } @@ -848,7 +855,8 @@ impl NetworkOptions { if self.no_listener || !self.listeners.is_empty() { cfg.set_listeners( - Cli::parse_listeners(self.no_listener, self.listeners.clone())? + Cli::parse_listeners(self.no_listener, self.listeners.clone()) + .with_context(|| format!("failed to parse listeners: {:?}", self.listeners))? .into_iter() .map(|s| s.parse().unwrap()) .collect(),