diff --git a/src/net/hosts/store.rs b/src/net/hosts/store.rs index d7cf681b2..9bdf06cdb 100644 --- a/src/net/hosts/store.rs +++ b/src/net/hosts/store.rs @@ -293,16 +293,15 @@ impl Hosts { self.anchorlist_store_or_update(&[(addr.clone(), last_seen)]).await; } - /// Remove an entry from the hostlist. Called when a handshake fails in - /// session::register_channel(), or after we have failed to connect to them + /// Downgrade a host to greylist. Called after we have failed to connect to a host /// outbound_connect_limit times in quarantine() - pub async fn remove_host(&self, addr: &Url) { - debug!(target: "store::remove_host", "Removing host {}", addr); + pub async fn downgrade_host(&self, addr: &Url, last_seen: u64) { + debug!(target: "store::downgrade_host", "Downgrading host {}", addr); self.mark_migrating(addr).await; // Remove channel from anchorlist if self.anchorlist_contains(addr).await { - debug!(target: "store::remove_host", "Removing from anchorlist {}", addr); + debug!(target: "store::downgrade_host", "Removing from anchorlist {}", addr); let index = self .get_anchorlist_index_at_addr(addr.clone()) @@ -314,7 +313,7 @@ impl Hosts { // Remove channel from whitelist if self.whitelist_contains(addr).await { - debug!(target: "store::remove_host", "Removing from whitelist {}", addr); + debug!(target: "store::downgrade_host", "Removing from whitelist {}", addr); let index = self .get_whitelist_index_at_addr(addr.clone()) @@ -324,17 +323,7 @@ impl Hosts { self.whitelist_remove(addr, index).await; } - // Remove channel the greylist - if self.greylist_contains(addr).await { - debug!(target: "store::remove_host", "Removing from greylist {}", addr); - - let index = self - .get_greylist_index_at_addr(addr.clone()) - .await - .expect("Expected greylist index to exist"); - - self.greylist_remove(addr, index).await; - } + self.greylist_store_or_update(&[(addr.clone(), last_seen)]).await; self.unmark_migrating(addr).await; } @@ -365,6 +354,8 @@ impl Hosts { .get_greylist_index_at_addr(addr.clone()) .await .expect("Expected greylist entry to exist"); + debug!(target: "store::greylist_store_or_update()", + "Selected index, updating last seen..."); self.greylist_update_last_seen(&addr, last_seen, index).await; self.store_subscriber.notify(filtered_addrs_len).await; } @@ -663,25 +654,22 @@ impl Hosts { } /// Quarantine a peer. - /// If they've been quarantined for more than a configured limit, forget them. - pub async fn quarantine(&self, url: &Url) { - debug!(target: "store::remove()", "Quarantining peer {}", url); + /// If they've been quarantined for more than a configured limit, downgrade to greylist. + pub async fn quarantine(&self, addr: &Url, last_seen: u64) { + debug!(target: "store::remove()", "Quarantining peer {}", addr); let timer = Instant::now(); let mut q = self.quarantine.write().await; - if let Some(retries) = q.get_mut(url) { + if let Some(retries) = q.get_mut(addr) { *retries += 1; - debug!(target: "net::hosts::quarantine()", "Peer {} quarantined {} times", url, retries); + debug!(target: "net::hosts::quarantine()", "Peer {} quarantined {} times", addr, retries); if *retries == self.settings.hosts_quarantine_limit { debug!(target: "net::hosts::quarantine()", "Reached quarantine limited after {:?}", timer.elapsed()); - debug!(target: "net::hosts::quarantine()", "Removing from hostlist {}", url); - self.remove_host(url).await; - debug!(target: "net::hosts::quarantine()", "Banning peer {}", url); - q.remove(url); - self.mark_rejected(url).await; + debug!(target: "net::hosts::quarantine()", "Removing from hostlist {}", addr); + self.downgrade_host(addr, last_seen).await; } } else { - debug!(target: "net::hosts::quarantine()", "Added peer {} to quarantine", url); - q.insert(url.clone(), 0); + debug!(target: "net::hosts::quarantine()", "Added peer {} to quarantine", addr); + q.insert(addr.clone(), 0); } } diff --git a/src/net/session/mod.rs b/src/net/session/mod.rs index 06da88b24..7243ff9c6 100644 --- a/src/net/session/mod.rs +++ b/src/net/session/mod.rs @@ -113,8 +113,7 @@ pub trait Session: Sync { } Err(e) => { debug!(target: "net::session::register_channel()", - "Handshake error {}. Removing {} from hostlists", e, channel.clone().address()); - p2p.hosts().remove_host(channel.address()).await; + "Handshake error {} {}", e, channel.clone().address()); } } diff --git a/src/net/session/outbound_session.rs b/src/net/session/outbound_session.rs index dfcb264d5..26ccf12be 100644 --- a/src/net/session/outbound_session.rs +++ b/src/net/session/outbound_session.rs @@ -296,6 +296,7 @@ impl Slot { }; let host = addr.0; + let last_seen = addr.1; let slot = self.slot; info!( @@ -309,7 +310,7 @@ impl Slot { addr: host.clone(), }); - let (addr, channel) = match self.try_connect(host.clone()).await { + let (addr, channel) = match self.try_connect(host.clone(), last_seen).await { Ok(connect_info) => connect_info, Err(err) => { debug!( @@ -378,7 +379,7 @@ impl Slot { /// the list of pending channels, and starts sending messages across the /// channel. In case of any failures, a network error is returned and the /// main connect loop (parent of this function) will iterate again. - async fn try_connect(&self, addr: Url) -> Result<(Url, ChannelPtr)> { + async fn try_connect(&self, addr: Url, last_seen: u64) -> Result<(Url, ChannelPtr)> { let parent = Arc::downgrade(&self.session()); let connector = Connector::new(self.p2p().settings(), parent); @@ -393,7 +394,7 @@ impl Slot { ); // At this point we failed to connect. We'll quarantine this peer now. - self.p2p().hosts().quarantine(&addr).await; + self.p2p().hosts().quarantine(&addr, last_seen).await; // Remove connection from pending self.p2p().remove_pending(&addr).await;