Skip to content

Commit a972b9c

Browse files
Implement kademlia client-mode
1 parent 450fc1e commit a972b9c

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

protocols/kad/src/behaviour.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,14 @@ where
20742074
self.connection_updated(source, address, NodeStatus::Connected);
20752075
}
20762076

2077+
KademliaHandlerEvent::ProtocolNotSupported { endpoint } => {
2078+
let address = match endpoint {
2079+
ConnectedPoint::Dialer { address, .. } => Some(address),
2080+
ConnectedPoint::Listener { .. } => None,
2081+
};
2082+
self.connection_updated(source, address, NodeStatus::Disconnected);
2083+
}
2084+
20772085
KademliaHandlerEvent::FindNodeReq { key, request_id } => {
20782086
let closer_peers = self.find_closest(&kbucket::Key::new(key), &source);
20792087

protocols/kad/src/handler.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use libp2p_core::{upgrade, ConnectedPoint};
3131
use libp2p_identity::PeerId;
3232
use libp2p_swarm::handler::{
3333
ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound,
34+
ProtocolsChange,
3435
};
3536
use libp2p_swarm::{
3637
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive,
@@ -92,10 +93,12 @@ pub struct KademliaHandler<TUserData> {
9293
enum ProtocolStatus {
9394
/// It is as yet unknown whether the remote supports the
9495
/// configured protocol name.
95-
Unconfirmed,
96+
Unknown,
9697
/// The configured protocol name has been confirmed by the remote
9798
/// but has not yet been reported to the `Kademlia` behaviour.
9899
Confirmed,
100+
/// The configured protocol name(s) are not or no longer supported by the remote.
101+
NotSupported,
99102
/// The configured protocol has been confirmed by the remote
100103
/// and the confirmation reported to the `Kademlia` behaviour.
101104
Reported,
@@ -226,13 +229,11 @@ impl<TUserData> InboundSubstreamState<TUserData> {
226229
#[derive(Debug)]
227230
pub enum KademliaHandlerEvent<TUserData> {
228231
/// The configured protocol name has been confirmed by the peer through
229-
/// a successfully negotiated substream.
230-
///
231-
/// This event is only emitted once by a handler upon the first
232-
/// successfully negotiated inbound or outbound substream and
233-
/// indicates that the connected peer participates in the Kademlia
234-
/// overlay network identified by the configured protocol name.
232+
/// a successfully negotiated substream or by learning the supported protocols of the remote.
235233
ProtocolConfirmed { endpoint: ConnectedPoint },
234+
/// The configured protocol name(s) are not or no longer supported by the peer on the provided
235+
/// connection and it should be removed from the routing table.
236+
ProtocolNotSupported { endpoint: ConnectedPoint },
236237

237238
/// Request for the list of nodes whose IDs are the closest to `key`. The number of nodes
238239
/// returned is not specified, but should be around 20.
@@ -501,7 +502,7 @@ where
501502
num_requested_outbound_streams: 0,
502503
requested_streams: Default::default(),
503504
keep_alive,
504-
protocol_status: ProtocolStatus::Unconfirmed,
505+
protocol_status: ProtocolStatus::Unknown,
505506
}
506507
}
507508

@@ -520,7 +521,7 @@ where
520521
protocol, msg, user_data,
521522
));
522523
self.num_requested_outbound_streams -= 1;
523-
if let ProtocolStatus::Unconfirmed = self.protocol_status {
524+
if let ProtocolStatus::Unknown = self.protocol_status {
524525
// Upon the first successfully negotiated substream, we know that the
525526
// remote is configured with the same protocol name and we want
526527
// the behaviour to add this peer to the routing table, if possible.
@@ -542,7 +543,7 @@ where
542543
future::Either::Right(p) => void::unreachable(p),
543544
};
544545

545-
if let ProtocolStatus::Unconfirmed = self.protocol_status {
546+
if let ProtocolStatus::Unknown = self.protocol_status {
546547
// Upon the first successfully negotiated substream, we know that the
547548
// remote is configured with the same protocol name and we want
548549
// the behaviour to add this peer to the routing table, if possible.
@@ -789,7 +790,25 @@ where
789790
ConnectionEvent::AddressChange(_)
790791
| ConnectionEvent::ListenUpgradeError(_)
791792
| ConnectionEvent::LocalProtocolsChange(_) => {}
792-
ConnectionEvent::RemoteProtocolsChange(_) => {}
793+
ConnectionEvent::RemoteProtocolsChange(ProtocolsChange { protocols }) => {
794+
// TODO: We should cache this / it will get simpler with #2831.
795+
let kademlia_protocols = self
796+
.config
797+
.protocol_config
798+
.protocol_names()
799+
.iter()
800+
.filter_map(|b| String::from_utf8(b.to_vec()).ok())
801+
.collect::<Vec<_>>();
802+
803+
let remote_supports_our_kademlia_protocols =
804+
kademlia_protocols.iter().all(|p| protocols.contains(p));
805+
806+
if remote_supports_our_kademlia_protocols {
807+
self.protocol_status = ProtocolStatus::Confirmed;
808+
} else {
809+
self.protocol_status = ProtocolStatus::NotSupported;
810+
}
811+
}
793812
}
794813
}
795814
}

0 commit comments

Comments
 (0)