Skip to content

Commit d649070

Browse files
fix: ensure Multiaddrs are /p2p terminated where possible
Fixes #4573. Pull-Request: #4596.
1 parent cf8a24d commit d649070

File tree

14 files changed

+73
-48
lines changed

14 files changed

+73
-48
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ libp2p-dcutr = { version = "0.11.0", path = "protocols/dcutr" }
8080
libp2p-dns = { version = "0.41.1", path = "transports/dns" }
8181
libp2p-floodsub = { version = "0.44.0", path = "protocols/floodsub" }
8282
libp2p-gossipsub = { version = "0.46.1", path = "protocols/gossipsub" }
83-
libp2p-identify = { version = "0.44.0", path = "protocols/identify" }
83+
libp2p-identify = { version = "0.44.1", path = "protocols/identify" }
8484
libp2p-identity = { version = "0.2.8" }
85-
libp2p-kad = { version = "0.45.1", path = "protocols/kad" }
86-
libp2p-mdns = { version = "0.45.0", path = "protocols/mdns" }
85+
libp2p-kad = { version = "0.45.2", path = "protocols/kad" }
86+
libp2p-mdns = { version = "0.45.1", path = "protocols/mdns" }
8787
libp2p-memory-connection-limits = { version = "0.2.0", path = "misc/memory-connection-limits" }
8888
libp2p-metrics = { version = "0.14.1", path = "misc/metrics" }
8989
libp2p-mplex = { version = "0.41.0", path = "muxers/mplex" }
@@ -122,7 +122,7 @@ rw-stream-sink = { version = "0.4.0", path = "misc/rw-stream-sink" }
122122

123123
[patch.crates-io]
124124

125-
# Patch away `libp2p-idnentity` in our dependency tree with the workspace version.
125+
# Patch away `libp2p-identity` in our dependency tree with the workspace version.
126126
# `libp2p-identity` is a leaf dependency and used within `rust-multiaddr` which is **not** part of the workspace.
127127
# As a result, we cannot just reference the workspace version in our crates because the types would mismatch with what
128128
# we import via `rust-multiaddr`.

protocols/identify/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.44.1 - unreleased
2+
3+
- Ensure `Multiaddr` handled and returned by `Behaviour` are `/p2p` terminated.
4+
See [PR 4596](https://github.com/libp2p/rust-libp2p/pull/4596).
5+
16
## 0.44.0
27

38
- Add `Info` to the `libp2p-identify::Event::Pushed` to report pushed info.

protocols/identify/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "libp2p-identify"
33
edition = "2021"
44
rust-version = { workspace = true }
55
description = "Nodes identifcation protocol for libp2p"
6-
version = "0.44.0"
6+
version = "0.44.1"
77
authors = ["Parity Technologies <[email protected]>"]
88
license = "MIT"
99
repository = "https://github.com/libp2p/rust-libp2p"

protocols/identify/src/behaviour.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ impl PeerCache {
466466
Some(cache) => cache,
467467
};
468468

469+
let addresses = addresses.filter_map(|a| a.with_p2p(peer).ok());
469470
cache.put(peer, HashSet::from_iter(addresses));
470471
}
471472

protocols/kad/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.45.2 - unreleased
2+
3+
- Ensure `Multiaddr` handled and returned by `Behaviour` are `/p2p` terminated.
4+
See [PR 4596](https://github.com/libp2p/rust-libp2p/pull/4596).
5+
16
## 0.45.1
27

38
- Fix a bug where calling `Behaviour::remove_address` with an address not in the peer's bucket would remove the peer from the routing table if the bucket has only one address left.

protocols/kad/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "libp2p-kad"
33
edition = "2021"
44
rust-version = { workspace = true }
55
description = "Kademlia protocol for libp2p"
6-
version = "0.45.1"
6+
version = "0.45.2"
77
authors = ["Parity Technologies <[email protected]>"]
88
license = "MIT"
99
repository = "https://github.com/libp2p/rust-libp2p"

protocols/kad/src/addresses.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use smallvec::SmallVec;
2323
use std::fmt;
2424

2525
/// A non-empty list of (unique) addresses of a peer in the routing table.
26+
/// Every address must be a fully-qualified /p2p address.
2627
#[derive(Clone)]
2728
pub struct Addresses {
2829
addrs: SmallVec<[Multiaddr; 6]>,

protocols/kad/src/behaviour.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,10 @@ where
513513
/// If the routing table has been updated as a result of this operation,
514514
/// a [`Event::RoutingUpdated`] event is emitted.
515515
pub fn add_address(&mut self, peer: &PeerId, address: Multiaddr) -> RoutingUpdate {
516+
// ensuring address is a fully-qualified /p2p multiaddr
517+
let Ok(address) = address.with_p2p(*peer) else {
518+
return RoutingUpdate::Failed;
519+
};
516520
let key = kbucket::Key::from(*peer);
517521
match self.kbuckets.entry(&key) {
518522
kbucket::Entry::Present(mut entry, _) => {
@@ -593,6 +597,7 @@ where
593597
peer: &PeerId,
594598
address: &Multiaddr,
595599
) -> Option<kbucket::EntryView<kbucket::Key<PeerId>, Addresses>> {
600+
let address = &address.to_owned().with_p2p(*peer).ok()?;
596601
let key = kbucket::Key::from(*peer);
597602
match self.kbuckets.entry(&key) {
598603
kbucket::Entry::Present(mut entry, _) => {

protocols/kad/src/protocol.rs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use libp2p_swarm::StreamProtocol;
3939
use std::marker::PhantomData;
4040
use std::{convert::TryFrom, time::Duration};
4141
use std::{io, iter};
42+
use tracing::debug;
4243

4344
/// The protocol name used for negotiating with multistream-select.
4445
pub(crate) const DEFAULT_PROTO_NAME: StreamProtocol = StreamProtocol::new("/ipfs/kad/1.0.0");
@@ -103,11 +104,12 @@ impl TryFrom<proto::Peer> for KadPeer {
103104

104105
let mut addrs = Vec::with_capacity(peer.addrs.len());
105106
for addr in peer.addrs.into_iter() {
106-
match Multiaddr::try_from(addr) {
107-
Ok(a) => addrs.push(a),
108-
Err(e) => {
109-
tracing::debug!("Unable to parse multiaddr: {e}");
107+
match Multiaddr::try_from(addr).map(|addr| addr.with_p2p(node_id)) {
108+
Ok(Ok(a)) => addrs.push(a),
109+
Ok(Err(a)) => {
110+
debug!("Unable to parse multiaddr: {a} is not compatible with {node_id}")
110111
}
112+
Err(e) => debug!("Unable to parse multiaddr: {e}"),
111113
};
112114
}
113115

@@ -596,10 +598,34 @@ where
596598
mod tests {
597599
use super::*;
598600

601+
#[test]
602+
fn append_p2p() {
603+
let peer_id = PeerId::random();
604+
let multiaddr = "/ip6/2001:db8::/tcp/1234".parse::<Multiaddr>().unwrap();
605+
606+
let payload = proto::Peer {
607+
id: peer_id.to_bytes(),
608+
addrs: vec![multiaddr.to_vec()],
609+
connection: proto::ConnectionType::CAN_CONNECT,
610+
};
611+
612+
let peer = KadPeer::try_from(payload).unwrap();
613+
614+
assert_eq!(peer.multiaddrs, vec![multiaddr.with_p2p(peer_id).unwrap()])
615+
}
616+
599617
#[test]
600618
fn skip_invalid_multiaddr() {
601-
let valid_multiaddr: Multiaddr = "/ip6/2001:db8::/tcp/1234".parse().unwrap();
602-
let valid_multiaddr_bytes = valid_multiaddr.to_vec();
619+
let peer_id = PeerId::random();
620+
let multiaddr = "/ip6/2001:db8::/tcp/1234".parse::<Multiaddr>().unwrap();
621+
622+
let valid_multiaddr = multiaddr.clone().with_p2p(peer_id).unwrap();
623+
624+
let multiaddr_with_incorrect_peer_id = {
625+
let other_peer_id = PeerId::random();
626+
assert_ne!(peer_id, other_peer_id);
627+
multiaddr.with_p2p(other_peer_id).unwrap()
628+
};
603629

604630
let invalid_multiaddr = {
605631
let a = vec![255; 8];
@@ -608,12 +634,16 @@ mod tests {
608634
};
609635

610636
let payload = proto::Peer {
611-
id: PeerId::random().to_bytes(),
612-
addrs: vec![valid_multiaddr_bytes, invalid_multiaddr],
637+
id: peer_id.to_bytes(),
638+
addrs: vec![
639+
valid_multiaddr.to_vec(),
640+
multiaddr_with_incorrect_peer_id.to_vec(),
641+
invalid_multiaddr,
642+
],
613643
connection: proto::ConnectionType::CAN_CONNECT,
614644
};
615645

616-
let peer = KadPeer::try_from(payload).expect("not to fail");
646+
let peer = KadPeer::try_from(payload).unwrap();
617647

618648
assert_eq!(peer.multiaddrs, vec![valid_multiaddr])
619649
}

0 commit comments

Comments
 (0)