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

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

darkfi 1 год назад
Родитель
Сommit
e7a7e0afe7

+ 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
 'lilith' which is generic, or you can simply just run a normal DarkIRC node
 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},
     hosts::HostColor,
     message,
-    message::{SerializedMessage, VersionMessage, MAGIC_BYTES},
+    message::{SerializedMessage, VersionMessage},
     message_publisher::{MessageSubscription, MessageSubsystem},
     p2p::P2pPtr,
     session::{
@@ -241,7 +241,8 @@ impl Channel {
         });
 
         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()", "Sending command...");
@@ -279,7 +280,8 @@ impl Channel {
         stream.read_exact(&mut magic).await?;
 
         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");
             return Err(Error::MalformedPacket)
         }

+ 0 - 2
src/net/message.rs

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

+ 2 - 1
src/net/p2p.rs

@@ -123,7 +123,8 @@ impl P2p {
 
     /// Starts inbound, outbound, and manual sessions.
     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");
 
         // 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() {
             // Skip protocols that are not registered for this session
             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
             }
 

+ 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
     /// own external addresses
     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
     pub app_version: semver::Version,
     /// Whitelisted network transports for outbound connections
@@ -115,6 +118,7 @@ impl Default for Settings {
             node_id: String::new(),
             inbound_addrs: vec![],
             external_addrs: vec![],
+            magic_bytes: Default::default(),
             peers: vec![],
             seeds: vec![],
             app_version,
@@ -144,6 +148,16 @@ impl Default for Settings {
 // The following is used so we can have P2P settings configurable
 // 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.
 #[derive(Clone, Debug, serde::Deserialize, structopt::StructOpt, structopt_toml::StructOptToml)]
 #[structopt()]
@@ -161,6 +175,12 @@ pub struct SettingsOpt {
     #[structopt(long = "inbound-slots")]
     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
     /// reach us and connect to us, as long as inbound addresses
     /// are also configured
@@ -275,6 +295,7 @@ impl From<SettingsOpt> for Settings {
             node_id: opt.node_id,
             inbound_addrs: opt.inbound,
             external_addrs: opt.external_addrs,
+            magic_bytes: opt.magic_bytes,
             peers: opt.peers,
             seeds: opt.seeds,
             app_version: def.app_version,