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

net: allow customizing the magic_bytes used in the p2p network. adds stronger distintinguishability between different net instances.

darkfi 1 год назад
Родитель
Сommit
e7a7e0afe7
6 измененных файлов с 40 добавлено и 7 удалено
  1. 8 0
      doc/src/misc/darkirc/darkirc.md
  2. 5 3
      src/net/channel.rs
  3. 0 2
      src/net/message.rs
  4. 2 1
      src/net/p2p.rs
  5. 4 1
      src/net/protocol/protocol_registry.rs
  6. 21 0
      src/net/settings.rs

+ 8 - 0
doc/src/misc/darkirc/darkirc.md

@@ -406,3 +406,11 @@ seeds = ["tcp+tls://mynet-seed.peer:5645"]
 For hosting the seed node, you can either use the generic seed node called
 For hosting the seed node, you can either use the generic seed node called
 'lilith' which is generic, or you can simply just run a normal DarkIRC node
 'lilith' which is generic, or you can simply just run a normal DarkIRC node
 which has the inbound correctly set.
 which has the inbound correctly set.
+
+To make your network distinct, an extra measure is to modify the magic bytes
+used in messages. This means any nodes that do drift into your custom instance
+will be unable to connect anyway.
+
+```
+magic_bytes=[127, 64, 12, 201]
+```

+ 5 - 3
src/net/channel.rs

@@ -41,7 +41,7 @@ use super::{
     dnet::{self, dnetev, DnetEvent},
     dnet::{self, dnetev, DnetEvent},
     hosts::HostColor,
     hosts::HostColor,
     message,
     message,
-    message::{SerializedMessage, VersionMessage, MAGIC_BYTES},
+    message::{SerializedMessage, VersionMessage},
     message_publisher::{MessageSubscription, MessageSubsystem},
     message_publisher::{MessageSubscription, MessageSubsystem},
     p2p::P2pPtr,
     p2p::P2pPtr,
     session::{
     session::{
@@ -241,7 +241,8 @@ impl Channel {
         });
         });
 
 
         trace!(target: "net::channel::send_message()", "Sending magic...");
         trace!(target: "net::channel::send_message()", "Sending magic...");
-        written += MAGIC_BYTES.encode_async(stream).await?;
+        let magic_bytes = self.p2p().settings().read().await.magic_bytes.0;
+        written += magic_bytes.encode_async(stream).await?;
         trace!(target: "net::channel::send_message()", "Sent magic");
         trace!(target: "net::channel::send_message()", "Sent magic");
 
 
         trace!(target: "net::channel::send_message()", "Sending command...");
         trace!(target: "net::channel::send_message()", "Sending command...");
@@ -279,7 +280,8 @@ impl Channel {
         stream.read_exact(&mut magic).await?;
         stream.read_exact(&mut magic).await?;
 
 
         trace!(target: "net::channel::read_command()", "Read magic {:?}", magic);
         trace!(target: "net::channel::read_command()", "Read magic {:?}", magic);
-        if magic != MAGIC_BYTES {
+        let magic_bytes = self.p2p().settings().read().await.magic_bytes.0;
+        if magic != magic_bytes {
             error!(target: "net::channel::read_command", "Error: Magic bytes mismatch");
             error!(target: "net::channel::read_command", "Error: Magic bytes mismatch");
             return Err(Error::MalformedPacket)
             return Err(Error::MalformedPacket)
         }
         }

+ 0 - 2
src/net/message.rs

@@ -21,8 +21,6 @@ use darkfi_serial::{
 };
 };
 use url::Url;
 use url::Url;
 
 
-pub(in crate::net) const MAGIC_BYTES: [u8; 4] = [0xd9, 0xef, 0xb6, 0x7d];
-
 /// Generic message template.
 /// Generic message template.
 pub trait Message: 'static + Send + Sync + AsyncDecodable + AsyncEncodable {
 pub trait Message: 'static + Send + Sync + AsyncDecodable + AsyncEncodable {
     const NAME: &'static str;
     const NAME: &'static str;

+ 2 - 1
src/net/p2p.rs

@@ -123,7 +123,8 @@ impl P2p {
 
 
     /// Starts inbound, outbound, and manual sessions.
     /// Starts inbound, outbound, and manual sessions.
     pub async fn start(self: Arc<Self>) -> Result<()> {
     pub async fn start(self: Arc<Self>) -> Result<()> {
-        debug!(target: "net::p2p::start", "P2P::start() [BEGIN]");
+        debug!(target: "net::p2p::start", "P2P::start() [BEGIN] [magic_bytes={:?}]",
+               self.settings.read().await.magic_bytes.0);
         info!(target: "net::p2p::start", "[P2P] Starting P2P subsystem");
         info!(target: "net::p2p::start", "[P2P] Starting P2P subsystem");
 
 
         // Start the inbound session
         // Start the inbound session

+ 4 - 1
src/net/protocol/protocol_registry.rs

@@ -63,7 +63,10 @@ impl ProtocolRegistry {
         for (session_flags, construct) in self.constructors.lock().await.iter() {
         for (session_flags, construct) in self.constructors.lock().await.iter() {
             // Skip protocols that are not registered for this session
             // Skip protocols that are not registered for this session
             if selector_id & session_flags == 0 {
             if selector_id & session_flags == 0 {
-                debug!(target: "net::protocol_registry", "Skipping {selector_id:#b}, {session_flags:#b}");
+                debug!(
+                    target: "net::protocol_registry",
+                    "Skipping protocol attach [selector_id={selector_id:#b}, session_flags={session_flags:#b}]",
+                );
                 continue
                 continue
             }
             }
 
 

+ 21 - 0
src/net/settings.rs

@@ -55,6 +55,9 @@ pub struct Settings {
     /// Seed nodes to connect to for peer discovery and/or adversising our
     /// Seed nodes to connect to for peer discovery and/or adversising our
     /// own external addresses
     /// own external addresses
     pub seeds: Vec<Url>,
     pub seeds: Vec<Url>,
+    /// Magic bytes should be unique per P2P network.
+    /// Avoid bleeding of networks.
+    pub magic_bytes: MagicBytes,
     /// Application version, used for convenient protocol matching
     /// Application version, used for convenient protocol matching
     pub app_version: semver::Version,
     pub app_version: semver::Version,
     /// Whitelisted network transports for outbound connections
     /// Whitelisted network transports for outbound connections
@@ -115,6 +118,7 @@ impl Default for Settings {
             node_id: String::new(),
             node_id: String::new(),
             inbound_addrs: vec![],
             inbound_addrs: vec![],
             external_addrs: vec![],
             external_addrs: vec![],
+            magic_bytes: Default::default(),
             peers: vec![],
             peers: vec![],
             seeds: vec![],
             seeds: vec![],
             app_version,
             app_version,
@@ -144,6 +148,16 @@ impl Default for Settings {
 // The following is used so we can have P2P settings configurable
 // The following is used so we can have P2P settings configurable
 // from TOML files.
 // from TOML files.
 
 
+/// Distinguishes distinct P2P networks
+#[derive(serde::Deserialize, Debug, Clone)]
+pub struct MagicBytes(pub [u8; 4]);
+
+impl Default for MagicBytes {
+    fn default() -> Self {
+        Self([0xd9, 0xef, 0xb6, 0x7d])
+    }
+}
+
 /// Defines the network settings.
 /// Defines the network settings.
 #[derive(Clone, Debug, serde::Deserialize, structopt::StructOpt, structopt_toml::StructOptToml)]
 #[derive(Clone, Debug, serde::Deserialize, structopt::StructOpt, structopt_toml::StructOptToml)]
 #[structopt()]
 #[structopt()]
@@ -161,6 +175,12 @@ pub struct SettingsOpt {
     #[structopt(long = "inbound-slots")]
     #[structopt(long = "inbound-slots")]
     pub inbound_connections: Option<usize>,
     pub inbound_connections: Option<usize>,
 
 
+    #[serde(default)]
+    #[structopt(skip)]
+    /// Magic bytes used to distinguish P2P distinct networks and
+    /// avoid nodes bleeding due to user config error.
+    pub magic_bytes: MagicBytes,
+
     /// P2P external addresses node advertises so other peers can
     /// P2P external addresses node advertises so other peers can
     /// reach us and connect to us, as long as inbound addresses
     /// reach us and connect to us, as long as inbound addresses
     /// are also configured
     /// are also configured
@@ -275,6 +295,7 @@ impl From<SettingsOpt> for Settings {
             node_id: opt.node_id,
             node_id: opt.node_id,
             inbound_addrs: opt.inbound,
             inbound_addrs: opt.inbound,
             external_addrs: opt.external_addrs,
             external_addrs: opt.external_addrs,
+            magic_bytes: opt.magic_bytes,
             peers: opt.peers,
             peers: opt.peers,
             seeds: opt.seeds,
             seeds: opt.seeds,
             app_version: def.app_version,
             app_version: def.app_version,