diff --git a/src/cloud.rs b/src/cloud.rs index eaeb4e0..585d60b 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -73,7 +73,7 @@ impl PeerList { } #[inline] - fn is_connected(&self, addr: Addr) -> Result { + fn is_connected(&self, addr: Addr) -> Result { for addr in try!(resolve(addr)) { if self.contains_addr(&addr) { return Ok(true); @@ -155,6 +155,8 @@ impl PeerList { #[derive(Clone)] pub struct ReconnectEntry { address: String, + resolved: Vec, + next_resolve: Time, tries: u16, timeout: u16, next: Time @@ -300,6 +302,8 @@ impl GenericCloud

{ address: add, tries: 0, timeout: 1, + resolved: vec![], + next_resolve: now(), next: now() }) } @@ -309,7 +313,7 @@ impl GenericCloud

{ /// # Errors /// Returns an `Error::SocketError` if the given address is a name that failed to resolve to /// actual addresses. - fn is_blacklisted(&self, addr: Addr) -> Result { + fn is_blacklisted(&self, addr: Addr) -> Result { for addr in try!(resolve(addr)) { if self.blacklist_peers.contains(&addr) { return Ok(true); @@ -326,11 +330,11 @@ impl GenericCloud

{ /// /// # Errors /// This method returns `Error::NameError` if the address is a name that fails to resolve. - pub fn connect(&mut self, addr: Addr) -> Result<(), Error> { + pub fn connect(&mut self, addr: Addr) -> Result<(), Error> { if try!(self.peers.is_connected(addr.clone())) || try!(self.is_blacklisted(addr.clone())) { return Ok(()) } - debug!("Connecting to {}", addr); + debug!("Connecting to {:?}", addr); let subnets = self.addresses.clone(); let node_id = self.node_id; // Send a message to each resolved address @@ -385,16 +389,23 @@ impl GenericCloud

{ if entry.next > now { continue } - try!(self.connect(&entry.address as &str)); + try!(self.connect(&entry.resolved as &[SocketAddr])); } for entry in &mut self.reconnect_peers { // Schedule for next second if node is connected - if try!(self.peers.is_connected(&entry.address as &str)) { + if try!(self.peers.is_connected(&entry.resolved as &[SocketAddr])) { entry.tries = 0; entry.timeout = 1; entry.next = now + 1; continue } + // Resolve entries anew + if entry.next_resolve <= now { + if let Ok(addrs) = resolve(&entry.address as &str) { + entry.resolved = addrs; + } + entry.next_resolve = now + 60; + } // Ignore if next attempt is already in the future if entry.next > now { continue diff --git a/src/util.rs b/src/util.rs index 10c6a67..2caf5e1 100644 --- a/src/util.rs +++ b/src/util.rs @@ -123,8 +123,8 @@ macro_rules! try_fail { } -pub fn resolve(addr: Addr) -> Result, Error> { - let addrs = try!(addr.to_socket_addrs().map_err(|_| Error::Name(format!("{}", addr)))); +pub fn resolve(addr: Addr) -> Result, Error> { + let addrs = try!(addr.to_socket_addrs().map_err(|_| Error::Name(format!("{:?}", addr)))); // Remove duplicates in addrs (why are there duplicates???) let mut addrs = addrs.collect::>(); // Try IPv4 first as it usually is faster