diff --git a/src/cloud.rs b/src/cloud.rs index b12a0f7..4600310 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -222,26 +222,18 @@ impl GenericCloud io::Result<()> { self.own_addresses.clear(); - if self.config.advertise_addresses.len() > 0 && - !self.config.listen.starts_with("ws://") { - // Force advertised addresses based on configuration instead - // of discovery. Note: Disables port forwarding - // Because the listen config may contain a color (aka - // both address and port are specified) we parse it and - // then extract just the port. - let sockaddr = parse_listen(&self.config.listen); - let port = sockaddr.port(); - for address in &self.config.advertise_addresses { - let sockaddr = try_fail!(SocketAddr::from_str(&format!("{}:{}", address, port)), "Invalid IP Address or port {}"); - self.own_addresses.push(sockaddr); - } - } else { - self.own_addresses.push(self.socket.address().map(mapped_addr)?); - if let Some(ref pfw) = self.port_forwarding { - self.own_addresses.push(pfw.get_internal_ip().into()); - self.own_addresses.push(pfw.get_external_ip().into()); - } - } + let socket_addr = self.socket.address().map(mapped_addr)?; + // 1) Specified advertise addresses + for addr in &self.config.advertise_addresses { + self.own_addresses.push(parse_listen(addr, socket_addr.port())); + } + // 2) Address of UDP socket + self.own_addresses.push(socket_addr); + // 3) Addresses from port forwarding + if let Some(ref pfw) = self.port_forwarding { + self.own_addresses.push(pfw.get_internal_ip().into()); + self.own_addresses.push(pfw.get_external_ip().into()); + } debug!("Own addresses: {:?}", self.own_addresses); // TODO: detect address changes and call event Ok(()) @@ -450,11 +442,6 @@ impl GenericCloud GenericCloud GenericCloud GenericCloud) -> Result<(), Error> { if let Some(peer) = self.peers.get_mut(&addr) { peer.last_seen = TS::now(); - peer.timeout = TS::now() + self.config.peer_timeout as Time + peer.timeout = TS::now() + self.config.peer_timeout as Time; + if let Some(info) = &info { + // Update peer addresses, always add seen address + peer.addrs.clear(); + peer.addrs.push(addr); + for addr in &info.addrs { + if !peer.addrs.contains(addr) { + peer.addrs.push(*addr); + } + } + } } else { error!("Received peer update from non peer {}", addr_nice(addr)); return Ok(()); diff --git a/src/net.rs b/src/net.rs index c687c0a..aab0f32 100644 --- a/src/net.rs +++ b/src/net.rs @@ -11,7 +11,7 @@ use std::{ }; use super::util::{MockTimeSource, MsgBuffer, Time, TimeSource}; -use crate::port_forwarding::PortForwarding; +use crate::{config::DEFAULT_PORT, port_forwarding::PortForwarding}; pub fn mapped_addr(addr: SocketAddr) -> SocketAddr { // HOT PATH @@ -35,21 +35,23 @@ pub trait Socket: AsRawFd + Sized { fn create_port_forwarding(&self) -> Option; } -pub fn parse_listen(addr: &str) -> SocketAddr { +pub fn parse_listen(addr: &str, default_port: u16) -> SocketAddr { if let Some(addr) = addr.strip_prefix("*:") { let port = try_fail!(addr.parse::(), "Invalid port: {}"); SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port) } else if addr.contains(':') { try_fail!(addr.parse::(), "Invalid address: {}: {}", addr) - } else { - let port = try_fail!(addr.parse::(), "Invalid port: {}"); + } else if let Ok(port) = addr.parse::() { SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), port) + } else { + let ip = try_fail!(addr.parse::(), "Invalid addr: {}"); + SocketAddr::new(ip, default_port) } } impl Socket for UdpSocket { fn listen(addr: &str) -> Result { - let addr = parse_listen(addr); + let addr = parse_listen(addr, DEFAULT_PORT); UdpSocket::bind(addr) } @@ -134,7 +136,7 @@ impl AsRawFd for MockSocket { impl Socket for MockSocket { fn listen(addr: &str) -> Result { - Ok(Self::new(parse_listen(addr))) + Ok(Self::new(parse_listen(addr, DEFAULT_PORT))) } fn receive(&mut self, buffer: &mut MsgBuffer) -> Result { diff --git a/src/wizard.rs b/src/wizard.rs index 418549a..75e7d95 100644 --- a/src/wizard.rs +++ b/src/wizard.rs @@ -41,6 +41,12 @@ fn configure_connectivity(config: &mut Config, mode: usize, theme: &ColorfulThem .interact()?; } if mode == MODE_EXPERT { + config.advertise_addresses = str_list( + Input::with_theme(theme) + .with_prompt("Advertise addresses (comma separated)") + .default(config.advertise_addresses.join(",")) + .interact_text()?, + ); config.peer_timeout = Input::with_theme(theme) .with_prompt("Peer timeout (in seconds)") .default(config.peer_timeout) diff --git a/src/wsproxy.rs b/src/wsproxy.rs index c1f6b5d..4413fda 100644 --- a/src/wsproxy.rs +++ b/src/wsproxy.rs @@ -92,7 +92,7 @@ fn serve_proxy_connection(stream: TcpStream) -> Result<(), io::Error> { } pub fn run_proxy(listen: &str) -> Result<(), io::Error> { - let addr = parse_listen(listen); + let addr = parse_listen(listen, 8080); let server = TcpListener::bind(addr)?; info!("Listening on ws://{}", server.local_addr()?); for stream in server.incoming() {