Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow customizing the Kademlia maximum packet size #1502

Merged
merged 2 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion protocols/kad/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ pub struct Kademlia<TStore> {
/// 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<NetworkBehaviourAction<KademliaHandlerIn<QueryId>, KademliaEvent>>,

Expand All @@ -101,6 +104,7 @@ pub struct KademliaConfig {
provider_record_ttl: Option<Duration>,
provider_publication_interval: Option<Duration>,
connection_idle_timeout: Duration,
max_protocol_packet_size: usize,
}

impl Default for KademliaConfig {
Expand All @@ -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,
Copy link
Contributor

@romanb romanb Mar 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be an idea to replace protocol_name_override and max_protocol_packet_size with directly embedding a KademliaProtocolConfig in the KademliaConfig (e.g. like it is done with QueryConfig)? It may simplify things a bit, now and for the future if more options are added. For example, the default packet size would not be duplicated but only exist in the Default impl for KademliaProtocolConfig. One step further would be to even embed the KademliaHandlerConfig in the KademliaConfig. These embeddings are implementation details, of course, the KademliaConfig has the public API, but it keeps the number of potentially duplicated fields to a minimum, e.g. the embedded configs can be moved into fields of the behaviour on construction as a whole.

}
}
}
Expand Down Expand Up @@ -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<TStore> Kademlia<TStore>
Expand Down Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -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());
}
Expand Down
15 changes: 12 additions & 3 deletions protocols/kad/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ impl Into<proto::message::Peer> 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 {
Expand All @@ -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,
}
}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down