From 5d401ffb8bcad57f5387280b3950b28354ead590 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 19 Mar 2020 17:11:29 +0100 Subject: [PATCH 1/2] Allow customizing the Kademlia maximum packet size --- protocols/kad/src/behaviour.rs | 17 ++++++++++++++++- protocols/kad/src/protocol.rs | 15 ++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 2da11ee13bd..5061e217f65 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -80,6 +80,9 @@ pub struct Kademlia { /// How long to keep connections alive when they're idle. connection_idle_timeout: Duration, + /// Maximum allowed size of a packet on the wire. + max_protocol_packet_size: usize, + /// Queued events to return when the behaviour is being polled. queued_events: VecDeque, KademliaEvent>>, @@ -101,6 +104,7 @@ pub struct KademliaConfig { provider_record_ttl: Option, provider_publication_interval: Option, connection_idle_timeout: Duration, + max_protocol_packet_size: usize, } impl Default for KademliaConfig { @@ -115,6 +119,7 @@ impl Default for KademliaConfig { provider_publication_interval: Some(Duration::from_secs(12 * 60 * 60)), provider_record_ttl: Some(Duration::from_secs(24 * 60 * 60)), connection_idle_timeout: Duration::from_secs(10), + max_protocol_packet_size: 4096, } } } @@ -228,6 +233,14 @@ impl KademliaConfig { self.connection_idle_timeout = duration; self } + + /// Modifies the maximum allowed size of individual Kademlia packets. + /// + /// It might be necessary to increase this value if trying to put large records. + pub fn set_max_packet_size(&mut self, size: usize) -> &mut Self { + self.max_protocol_packet_size = size; + self + } } impl Kademlia @@ -276,6 +289,7 @@ where record_ttl: config.record_ttl, provider_record_ttl: config.provider_record_ttl, connection_idle_timeout: config.connection_idle_timeout, + max_protocol_packet_size: config.max_protocol_packet_size, } } @@ -1064,7 +1078,8 @@ where type OutEvent = KademliaEvent; fn new_handler(&mut self) -> Self::ProtocolsHandler { - let mut protocol_config = KademliaProtocolConfig::default(); + let mut protocol_config = KademliaProtocolConfig::default() + .with_max_packet_size(self.max_protocol_packet_size); if let Some(name) = self.protocol_name_override.as_ref() { protocol_config = protocol_config.with_protocol_name(name.clone()); } diff --git a/protocols/kad/src/protocol.rs b/protocols/kad/src/protocol.rs index d2d891cca61..f0f6ac2d877 100644 --- a/protocols/kad/src/protocol.rs +++ b/protocols/kad/src/protocol.rs @@ -141,6 +141,8 @@ impl Into for KadPeer { #[derive(Debug, Clone)] pub struct KademliaProtocolConfig { protocol_name: Cow<'static, [u8]>, + /// Maximum allowed size of a packet. + max_packet_size: usize, } impl KademliaProtocolConfig { @@ -150,12 +152,19 @@ impl KademliaProtocolConfig { self.protocol_name = name.into(); self } + + /// Modifies the maximum allowed size of a single Kademlia packet. + pub fn with_max_packet_size(mut self, size: usize) -> Self { + self.max_packet_size = size; + self + } } impl Default for KademliaProtocolConfig { fn default() -> Self { KademliaProtocolConfig { - protocol_name: Cow::Borrowed(DEFAULT_PROTO_NAME) + protocol_name: Cow::Borrowed(DEFAULT_PROTO_NAME), + max_packet_size: 4096, } } } @@ -179,7 +188,7 @@ where fn upgrade_inbound(self, incoming: C, _: Self::Info) -> Self::Future { let mut codec = UviBytes::default(); - codec.set_max_len(4096); + codec.set_max_len(self.max_packet_size); future::ok( Framed::new(incoming, codec) @@ -211,7 +220,7 @@ where fn upgrade_outbound(self, incoming: C, _: Self::Info) -> Self::Future { let mut codec = UviBytes::default(); - codec.set_max_len(4096); + codec.set_max_len(self.max_packet_size); future::ok( Framed::new(incoming, codec) From 426318128ad5d5bb27226a0caef8bb71cdeb9677 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 19 Mar 2020 18:36:20 +0100 Subject: [PATCH 2/2] Address concern --- protocols/kad/src/behaviour.rs | 32 +++++++++----------------------- protocols/kad/src/protocol.rs | 11 +++++++---- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 5061e217f65..466a4ee0a15 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -52,8 +52,8 @@ pub struct Kademlia { /// The Kademlia routing table. kbuckets: KBucketsTable, Addresses>, - /// An optional protocol name override to segregate DHTs in the network. - protocol_name_override: Option>, + /// Configuration of the wire protocol. + protocol_config: KademliaProtocolConfig, /// The currently active (i.e. in-progress) queries. queries: QueryPool, @@ -80,9 +80,6 @@ pub struct Kademlia { /// How long to keep connections alive when they're idle. connection_idle_timeout: Duration, - /// Maximum allowed size of a packet on the wire. - max_protocol_packet_size: usize, - /// Queued events to return when the behaviour is being polled. queued_events: VecDeque, KademliaEvent>>, @@ -97,14 +94,13 @@ pub struct Kademlia { pub struct KademliaConfig { kbucket_pending_timeout: Duration, query_config: QueryConfig, - protocol_name_override: Option>, + protocol_config: KademliaProtocolConfig, record_ttl: Option, record_replication_interval: Option, record_publication_interval: Option, provider_record_ttl: Option, provider_publication_interval: Option, connection_idle_timeout: Duration, - max_protocol_packet_size: usize, } impl Default for KademliaConfig { @@ -112,14 +108,13 @@ impl Default for KademliaConfig { KademliaConfig { kbucket_pending_timeout: Duration::from_secs(60), query_config: QueryConfig::default(), - protocol_name_override: None, + protocol_config: Default::default(), record_ttl: Some(Duration::from_secs(36 * 60 * 60)), record_replication_interval: Some(Duration::from_secs(60 * 60)), record_publication_interval: Some(Duration::from_secs(24 * 60 * 60)), provider_publication_interval: Some(Duration::from_secs(12 * 60 * 60)), provider_record_ttl: Some(Duration::from_secs(24 * 60 * 60)), connection_idle_timeout: Duration::from_secs(10), - max_protocol_packet_size: 4096, } } } @@ -130,7 +125,7 @@ impl KademliaConfig { /// Kademlia nodes only communicate with other nodes using the same protocol name. Using a /// custom name therefore allows to segregate the DHT from others, if that is desired. pub fn set_protocol_name(&mut self, name: impl Into>) -> &mut Self { - self.protocol_name_override = Some(name.into()); + self.protocol_config.set_protocol_name(name); self } @@ -238,7 +233,7 @@ impl KademliaConfig { /// /// It might be necessary to increase this value if trying to put large records. pub fn set_max_packet_size(&mut self, size: usize) -> &mut Self { - self.max_protocol_packet_size = size; + self.protocol_config.set_max_packet_size(size); self } } @@ -254,9 +249,7 @@ where /// Get the protocol name of this kademlia instance. pub fn protocol_name(&self) -> &[u8] { - self.protocol_name_override - .as_ref() - .map_or(crate::protocol::DEFAULT_PROTO_NAME.as_ref(), AsRef::as_ref) + self.protocol_config.protocol_name() } /// Creates a new `Kademlia` network behaviour with the given configuration. @@ -280,7 +273,7 @@ where Kademlia { store, kbuckets: KBucketsTable::new(local_key, config.kbucket_pending_timeout), - protocol_name_override: config.protocol_name_override, + protocol_config: config.protocol_config, queued_events: VecDeque::with_capacity(config.query_config.replication_factor.get()), queries: QueryPool::new(config.query_config), connected_peers: Default::default(), @@ -289,7 +282,6 @@ where record_ttl: config.record_ttl, provider_record_ttl: config.provider_record_ttl, connection_idle_timeout: config.connection_idle_timeout, - max_protocol_packet_size: config.max_protocol_packet_size, } } @@ -1078,14 +1070,8 @@ where type OutEvent = KademliaEvent; fn new_handler(&mut self) -> Self::ProtocolsHandler { - let mut protocol_config = KademliaProtocolConfig::default() - .with_max_packet_size(self.max_protocol_packet_size); - if let Some(name) = self.protocol_name_override.as_ref() { - protocol_config = protocol_config.with_protocol_name(name.clone()); - } - KademliaHandler::new(KademliaHandlerConfig { - protocol_config, + protocol_config: self.protocol_config.clone(), allow_listening: true, idle_timeout: self.connection_idle_timeout, }) diff --git a/protocols/kad/src/protocol.rs b/protocols/kad/src/protocol.rs index f0f6ac2d877..13b1320a172 100644 --- a/protocols/kad/src/protocol.rs +++ b/protocols/kad/src/protocol.rs @@ -146,17 +146,20 @@ pub struct KademliaProtocolConfig { } impl KademliaProtocolConfig { + /// Returns the configured protocol name. + pub fn protocol_name(&self) -> &[u8] { + &self.protocol_name + } + /// Modifies the protocol name used on the wire. Can be used to create incompatibilities /// between networks on purpose. - pub fn with_protocol_name(mut self, name: impl Into>) -> Self { + pub fn set_protocol_name(&mut self, name: impl Into>) { self.protocol_name = name.into(); - self } /// Modifies the maximum allowed size of a single Kademlia packet. - pub fn with_max_packet_size(mut self, size: usize) -> Self { + pub fn set_max_packet_size(&mut self, size: usize) { self.max_packet_size = size; - self } }