Просмотр исходного кода

net: downgrade host (don't remove or blacklist) if we can't connect

draoi 2 лет назад
Родитель
Сommit
de78b48549
3 измененных файлов с 22 добавлено и 34 удалено
  1. 17 29
      src/net/hosts/store.rs
  2. 1 2
      src/net/session/mod.rs
  3. 4 3
      src/net/session/outbound_session.rs

+ 17 - 29
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);
         }
     }
 

+ 1 - 2
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());
             }
         }
 

+ 4 - 3
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;