mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-27 16:51:34 +00:00
protocols/identify: Check multiaddr has valid peer id component prior to caching (#2338)
Check multiaddr has valid peer id component or none at all. We don't want to cache a multiaddr with a purposely wrong multiaddr. e.g. something that ends with .../p2p/some-other-peer. While this should fail to dial because we [check this before dialing](https://github.com/libp2p/rust-libp2p/blob/master/core/src/connection/pool/concurrent_dial.rs#L144), it's better to not cache this in the first place.
This commit is contained in:
@ -23,6 +23,7 @@ use crate::protocol::{IdentifyInfo, ReplySubstream};
|
||||
use futures::prelude::*;
|
||||
use libp2p_core::{
|
||||
connection::{ConnectionId, ListenerId},
|
||||
multiaddr::Protocol,
|
||||
upgrade::UpgradeError,
|
||||
ConnectedPoint, Multiaddr, PeerId, PublicKey,
|
||||
};
|
||||
@ -304,7 +305,11 @@ impl NetworkBehaviour for Identify {
|
||||
event: <Self::ProtocolsHandler as ProtocolsHandler>::OutEvent,
|
||||
) {
|
||||
match event {
|
||||
IdentifyHandlerEvent::Identified(info) => {
|
||||
IdentifyHandlerEvent::Identified(mut info) => {
|
||||
// Remove invalid multiaddrs.
|
||||
info.listen_addrs
|
||||
.retain(|addr| multiaddr_matches_peer_id(addr, &peer_id));
|
||||
|
||||
// Replace existing addresses to prevent other peer from filling up our memory.
|
||||
self.discovered_peers
|
||||
.put(peer_id, HashSet::from_iter(info.listen_addrs.clone()));
|
||||
@ -499,6 +504,16 @@ fn listen_addrs(params: &impl PollParameters) -> Vec<Multiaddr> {
|
||||
listen_addrs
|
||||
}
|
||||
|
||||
/// If there is a given peer_id in the multiaddr, make sure it is the same as
|
||||
/// the given peer_id. If there is no peer_id for the peer in the mutiaddr, this returns true.
|
||||
fn multiaddr_matches_peer_id(addr: &Multiaddr, peer_id: &PeerId) -> bool {
|
||||
let last_component = addr.iter().last();
|
||||
if let Some(Protocol::P2p(multi_addr_peer_id)) = last_component {
|
||||
return multi_addr_peer_id == *peer_id.as_ref();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -771,4 +786,26 @@ mod tests {
|
||||
|
||||
assert_eq!(connected_peer, swarm1_peer_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_multiaddr_matches_peer_id() {
|
||||
let peer_id = PeerId::random();
|
||||
let other_peer_id = PeerId::random();
|
||||
let mut addr: Multiaddr = "/ip4/147.75.69.143/tcp/4001"
|
||||
.parse()
|
||||
.expect("failed to parse multiaddr");
|
||||
|
||||
let addr_without_peer_id: Multiaddr = addr.clone();
|
||||
let mut addr_with_other_peer_id = addr.clone();
|
||||
|
||||
addr.push(Protocol::P2p(peer_id.clone().into()));
|
||||
addr_with_other_peer_id.push(Protocol::P2p(other_peer_id.into()));
|
||||
|
||||
assert!(multiaddr_matches_peer_id(&addr, &peer_id));
|
||||
assert!(!multiaddr_matches_peer_id(
|
||||
&addr_with_other_peer_id,
|
||||
&peer_id
|
||||
));
|
||||
assert!(multiaddr_matches_peer_id(&addr_without_peer_id, &peer_id));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user