Răsfoiți Sursa

net+lilith: introduce BanPolicy

We create a new net Setting called BanPolicy that can be Strict or
Relaxed. If it's set to Strict, we ban peers that send messages without
us having a corresponding Dispatcher. If it's set to Relaxed we simply
close the connection.

Lilith is set to Relaxed by default while other peers are set to Strict.
This helps us avoid Lilith blacklisting peers that send messages for
protocols it is not subscribed to.
draoi 2 ani în urmă
părinte
comite
9dd240f13e
4 a modificat fișierele cu 42 adăugiri și 5 ștergeri
  1. 2 1
      bin/lilith/src/main.rs
  2. 4 3
      src/net/channel.rs
  3. 1 1
      src/net/mod.rs
  4. 35 0
      src/net/settings.rs

+ 2 - 1
bin/lilith/src/main.rs

@@ -39,7 +39,7 @@ use url::Url;
 
 use darkfi::{
     async_daemonize, cli_desc,
-    net::{self, hosts::HostColor, P2p, P2pPtr},
+    net::{self, hosts::HostColor, settings::BanPolicy, P2p, P2pPtr},
     rpc::{
         jsonrpc::*,
         server::{listen_and_serve, RequestHandler},
@@ -363,6 +363,7 @@ async fn spawn_net(name: String, info: &NetInfo, ex: Arc<Executor<'static>>) ->
             "nym".to_string(),
             "nym+tls".to_string(),
         ],
+        ban_policy: BanPolicy::Relaxed,
         ..Default::default()
     };
 

+ 4 - 3
src/net/channel.rs

@@ -50,6 +50,7 @@ use super::{
     transport::PtStream,
 };
 use crate::{
+    net::BanPolicy,
     system::{Publisher, PublisherPtr, StoppableTask, StoppableTaskPtr, Subscription},
     util::time::NanoTimestamp,
     Error, Result,
@@ -378,9 +379,9 @@ impl Channel {
                 // If we're getting messages without dispatchers, it's spam.
                 Err(Error::MissingDispatcher) => {
                     debug!(target: "net::channel::main_receive_loop()", "Stopping channel {:?}", self);
-
-                    // We will reject further connections from this peer
-                    self.ban(self.address()).await;
+                    if let BanPolicy::Strict = self.p2p().settings().read().await.ban_policy {
+                        self.ban(self.address()).await;
+                    }
 
                     return Err(Error::ChannelStopped)
                 }

+ 1 - 1
src/net/mod.rs

@@ -117,7 +117,7 @@ pub mod connector;
 /// Network configuration settings. This holds the configured P2P instance
 /// behaviour and is controlled by clients of this API.
 pub mod settings;
-pub use settings::Settings;
+pub use settings::{BanPolicy, Settings};
 
 /// Optional events based debug-notify subsystem. Off by default. Enabled in P2P instance,
 /// and then call `p2p.dnet_sub()` to start receiving events.

+ 35 - 0
src/net/settings.rs

@@ -21,6 +21,32 @@ use url::Url;
 
 type BlacklistEntry = (String, Vec<String>, Vec<u16>);
 
+/// Ban policy which if set to `Relaxed` will not ban peers if the case
+/// they send a message without a corresponding MessageDispatcher.
+/// This is useful for nodes that may not be subscribed to protocols,
+/// such as Lilith. For most uses this should be set to `Strict`.
+///
+/// TODO: this will be deprecated when we introduce the p2p resource
+/// mananger.
+#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
+#[serde(rename_all = "lowercase")]
+pub enum BanPolicy {
+    Strict,
+    Relaxed,
+}
+
+impl std::str::FromStr for BanPolicy {
+    type Err = String;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s.to_lowercase().as_str() {
+            "strict" => Ok(BanPolicy::Strict),
+            "relaxed" => Ok(BanPolicy::Relaxed),
+            _ => Err(format!("Invalid ban policy: {}", s)),
+        }
+    }
+}
+
 /// P2P network settings. The scope of this is a P2P network instance
 /// configured by the library user.
 #[derive(Debug, Clone)]
@@ -83,6 +109,9 @@ pub struct Settings {
     /// If scheme is left empty it will default to "tcp+tls".
     /// If ports are left empty all ports from this peer will be blocked.
     pub blacklist: Vec<BlacklistEntry>,
+    /// Do not ban nodes that send messages without dispatchers if set
+    /// to `Relaxed`. For most uses, should be set to `Strict`.
+    pub ban_policy: BanPolicy,
 }
 
 impl Default for Settings {
@@ -115,6 +144,7 @@ impl Default for Settings {
             slot_preference_strict: false,
             time_with_no_connections: 30,
             blacklist: vec![],
+            ban_policy: BanPolicy::Strict,
         }
     }
 }
@@ -237,6 +267,10 @@ pub struct SettingsOpt {
     #[serde(default)]
     #[structopt(skip)]
     pub blacklist: Vec<BlacklistEntry>,
+
+    /// Do not ban nodes that send messages without dispatchers if set
+    /// to `Relaxed`. For most uses, should be set to `Strict`.
+    pub ban_policy: BanPolicy,
 }
 
 impl From<SettingsOpt> for Settings {
@@ -282,6 +316,7 @@ impl From<SettingsOpt> for Settings {
                 .time_with_no_connections
                 .unwrap_or(def.time_with_no_connections),
             blacklist: opt.blacklist,
+            ban_policy: opt.ban_policy,
         }
     }
 }