Преглед изворни кода

refinery: acquire exclusive lock on greylist before refining

Modifications to the greylist (appending or deleting from) are dangerous while the refinery is ongoing, since it can lead to panics in the case the refinery fails (because we delete from the greylist by index when that happens).

We mitigate this issue by acquiring an exclusive lock on the greylist before proceeding with the refinery, and dropping the lock once the refinery process has finished and greylist modifications are no longer dangerous.
draoi пре 2 година
родитељ
комит
c47630366c
1 измењених фајлова са 9 додато и 1 уклоњено
  1. 9 1
      src/net/session/refine_session.rs

+ 9 - 1
src/net/session/refine_session.rs

@@ -249,8 +249,12 @@ impl GreylistRefinery {
                         continue
                         continue
                     }
                     }
 
 
+                    // Freeze the greylist in this state. Necessary since the greylist
+                    // can be modified by `hosts::move_host()`.
+                    let mut greylist = hosts.container.hostlists[HostColor::Grey as usize].write().await;
+
                     if !self.session().handshake_node(url.clone(), self.p2p().clone()).await {
                     if !self.session().handshake_node(url.clone(), self.p2p().clone()).await {
-                        hosts.container.remove(HostColor::Grey, url, position).await;
+                        greylist.remove(position);
 
 
                         debug!(
                         debug!(
                             target: "net::refinery",
                             target: "net::refinery",
@@ -262,9 +266,13 @@ impl GreylistRefinery {
                         // modification is now complete.
                         // modification is now complete.
                         hosts.unregister(url).await;
                         hosts.unregister(url).await;
 
 
+                        drop(greylist);
+
                         continue
                         continue
                     }
                     }
 
 
+                    drop(greylist);
+
                     debug!(
                     debug!(
                         target: "net::refinery",
                         target: "net::refinery",
                         "Peer {} is responsive. Adding to whitelist", url,
                         "Peer {} is responsive. Adding to whitelist", url,