protocols/kad: Support multiple protocol names (#2846)

Add support for multiple Kademlia protocol names to allow
protocol name upgrades.
This commit is contained in:
Dmitry Markin
2022-09-03 03:46:50 +03:00
committed by GitHub
parent 89f898c69f
commit cee199afca
3 changed files with 39 additions and 12 deletions

View File

@ -1,7 +1,13 @@
# 0.40.0 [unreleased]
- Add support for multiple protocol names. Update `Kademlia`, `KademliaConfig`,
and `KademliaProtocolConfig` accordingly. See [Issue 2837]. See [PR 2846].
- Update to `libp2p-swarm` `v0.39.0`.
[Issue 2837]: https://github.com/libp2p/rust-libp2p/issues/2837
[PR 2846]: https://github.com/libp2p/rust-libp2p/pull/2846
# 0.39.0
- Update prost requirement from 0.10 to 0.11 which no longer installs the protoc Protobuf compiler.

View File

@ -214,14 +214,28 @@ impl Default for KademliaConfig {
}
impl KademliaConfig {
/// Sets custom protocol names.
///
/// Kademlia nodes only communicate with other nodes using the same protocol
/// name. Using custom name(s) therefore allows to segregate the DHT from
/// others, if that is desired.
///
/// More than one protocol name can be supplied. In this case the node will
/// be able to talk to other nodes supporting any of the provided names.
/// Multiple names must be used with caution to avoid network partitioning.
pub fn set_protocol_names(&mut self, names: Vec<Cow<'static, [u8]>>) -> &mut Self {
self.protocol_config.set_protocol_names(names);
self
}
/// Sets a custom protocol name.
///
/// 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.
#[deprecated(since = "0.40.0", note = "use `set_protocol_names()` instead")]
pub fn set_protocol_name(&mut self, name: impl Into<Cow<'static, [u8]>>) -> &mut Self {
self.protocol_config.set_protocol_name(name);
self
self.set_protocol_names(std::iter::once(name.into()).collect())
}
/// Sets the timeout for a single query.
@ -403,8 +417,8 @@ where
}
/// Get the protocol name of this kademlia instance.
pub fn protocol_name(&self) -> &[u8] {
self.protocol_config.protocol_name()
pub fn protocol_names(&self) -> &[Cow<'static, [u8]>] {
self.protocol_config.protocol_names()
}
/// Creates a new `Kademlia` network behaviour with the given configuration.

View File

@ -142,21 +142,28 @@ impl From<KadPeer> for proto::message::Peer {
// `OutboundUpgrade` to be just a single message
#[derive(Debug, Clone)]
pub struct KademliaProtocolConfig {
protocol_name: Cow<'static, [u8]>,
protocol_names: Vec<Cow<'static, [u8]>>,
/// Maximum allowed size of a packet.
max_packet_size: usize,
}
impl KademliaProtocolConfig {
/// Returns the configured protocol name.
pub fn protocol_name(&self) -> &[u8] {
&self.protocol_name
pub fn protocol_names(&self) -> &[Cow<'static, [u8]>] {
&self.protocol_names
}
/// Modifies the protocol name used on the wire. Can be used to create incompatibilities
/// Modifies the protocol names used on the wire. Can be used to create incompatibilities
/// between networks on purpose.
pub fn set_protocol_names(&mut self, names: Vec<Cow<'static, [u8]>>) {
self.protocol_names = names;
}
/// Sets single protocol name used on the wire. Can be used to create incompatibilities
/// between networks on purpose.
#[deprecated(since = "0.40.0", note = "use `set_protocol_names()` instead")]
pub fn set_protocol_name(&mut self, name: impl Into<Cow<'static, [u8]>>) {
self.protocol_name = name.into();
self.set_protocol_names(std::iter::once(name.into()).collect());
}
/// Modifies the maximum allowed size of a single Kademlia packet.
@ -168,7 +175,7 @@ impl KademliaProtocolConfig {
impl Default for KademliaProtocolConfig {
fn default() -> Self {
KademliaProtocolConfig {
protocol_name: Cow::Borrowed(DEFAULT_PROTO_NAME),
protocol_names: iter::once(Cow::Borrowed(DEFAULT_PROTO_NAME)).collect(),
max_packet_size: DEFAULT_MAX_PACKET_SIZE,
}
}
@ -176,10 +183,10 @@ impl Default for KademliaProtocolConfig {
impl UpgradeInfo for KademliaProtocolConfig {
type Info = Cow<'static, [u8]>;
type InfoIter = iter::Once<Self::Info>;
type InfoIter = std::vec::IntoIter<Self::Info>;
fn protocol_info(&self) -> Self::InfoIter {
iter::once(self.protocol_name.clone())
self.protocol_names.clone().into_iter()
}
}