Skip to content

Commit 3837e33

Browse files
b-zeedariusc93
andauthored
feat(identify): add hide_listen_addrs config option (#5507)
## Description Implements #4010, which was closed. It was closed because it appeared that the Identify specification doesn't dictate this feature. But, in the discussion on the specs repo (libp2p/specs#597) it is mentioned that this might very well be an implementation detail. This PR introduces a `hide_listen_addrs` flag that will prevent our listen addresses to be included, effectively only sharing our external addresses. <!-- Please write a summary of your changes and why you made them. This section will appear as the commit message after merging. Please craft it accordingly. For a quick primer on good commit messages, check out this blog post: https://cbea.ms/git-commit/ Please include any relevant issues in here, for example: Related https://github.com/libp2p/rust-libp2p/issues/ABCD. Fixes https://github.com/libp2p/rust-libp2p/issues/XYZ. --> ## Notes & open questions An alternative implementation would be to allow us to filter the addresses we are sending out, by providing a closure I imagine. <!-- Any notes, remarks or open questions you have to make about the PR which don't need to go into the final commit message. --> ## Change checklist <!-- Please add a Changelog entry in the appropriate crates and bump the crate versions if needed. See <https://github.com/libp2p/rust-libp2p/blob/master/docs/release.md#development-between-releases>--> - [x] I have performed a self-review of my own code - [x] I have made corresponding changes to the documentation - [x] I have added tests that prove my fix is effective or that my feature works - [x] A changelog entry has been made in the appropriate crates --------- Co-authored-by: Darius Clark <[email protected]>
1 parent 5137e4e commit 3837e33

File tree

6 files changed

+97
-8
lines changed

6 files changed

+97
-8
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ libp2p-dcutr = { version = "0.12.0", path = "protocols/dcutr" }
8484
libp2p-dns = { version = "0.42.0", path = "transports/dns" }
8585
libp2p-floodsub = { version = "0.45.0", path = "protocols/floodsub" }
8686
libp2p-gossipsub = { version = "0.47.1", path = "protocols/gossipsub" }
87-
libp2p-identify = { version = "0.45.0", path = "protocols/identify" }
87+
libp2p-identify = { version = "0.45.1", path = "protocols/identify" }
8888
libp2p-identity = { version = "0.2.9" }
8989
libp2p-kad = { version = "0.47.0", path = "protocols/kad" }
9090
libp2p-mdns = { version = "0.46.0", path = "protocols/mdns" }

protocols/identify/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 0.45.1
2+
3+
- Add `hide_listen_addrs` option to prevent leaking (local) listen addresses.
4+
See [PR 5507](https://github.com/libp2p/rust-libp2p/pull/5507).
5+
16
## 0.45.0
27

38
- Address translation is moved here from `libp2p-core`.

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 identification protocol for libp2p"
6-
version = "0.45.0"
6+
version = "0.45.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: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ pub struct Config {
147147
///
148148
/// Disabled by default.
149149
pub cache_size: usize,
150+
151+
/// Whether to include our listen addresses in our responses. If enabled,
152+
/// we will effectively only share our external addresses.
153+
///
154+
/// Disabled by default.
155+
pub hide_listen_addrs: bool,
150156
}
151157

152158
impl Config {
@@ -160,6 +166,7 @@ impl Config {
160166
interval: Duration::from_secs(5 * 60),
161167
push_listen_addr_updates: false,
162168
cache_size: 100,
169+
hide_listen_addrs: false,
163170
}
164171
}
165172

@@ -189,6 +196,12 @@ impl Config {
189196
self.cache_size = cache_size;
190197
self
191198
}
199+
200+
/// Configures whether we prevent sending out our listen addresses.
201+
pub fn with_hide_listen_addrs(mut self, b: bool) -> Self {
202+
self.hide_listen_addrs = b;
203+
self
204+
}
192205
}
193206

194207
impl Behaviour {
@@ -258,11 +271,11 @@ impl Behaviour {
258271
}
259272

260273
fn all_addresses(&self) -> HashSet<Multiaddr> {
261-
self.listen_addresses
262-
.iter()
263-
.chain(self.external_addresses.iter())
264-
.cloned()
265-
.collect()
274+
let mut addrs = HashSet::from_iter(self.external_addresses.iter().cloned());
275+
if !self.config.hide_listen_addrs {
276+
addrs.extend(self.listen_addresses.iter().cloned());
277+
};
278+
addrs
266279
}
267280

268281
fn emit_new_external_addr_candidate_event(

protocols/identify/tests/smoke.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,77 @@ async fn emits_unique_listen_addresses() {
222222
assert!(reported_addrs.contains(&(swarm2_peer_id, swarm2_tcp_listen_addr)));
223223
}
224224

225+
#[async_std::test]
226+
async fn hides_listen_addresses() {
227+
let _ = tracing_subscriber::fmt()
228+
.with_env_filter(EnvFilter::from_default_env())
229+
.try_init();
230+
231+
let mut swarm1 = Swarm::new_ephemeral(|identity| {
232+
identify::Behaviour::new(
233+
identify::Config::new("a".to_string(), identity.public())
234+
.with_agent_version("b".to_string())
235+
.with_interval(Duration::from_secs(1))
236+
.with_cache_size(10),
237+
)
238+
});
239+
let mut swarm2 = Swarm::new_ephemeral(|identity| {
240+
identify::Behaviour::new(
241+
identify::Config::new("c".to_string(), identity.public())
242+
.with_agent_version("d".to_string())
243+
.with_hide_listen_addrs(true),
244+
)
245+
});
246+
247+
let (_swarm2_mem_listen_addr, swarm2_tcp_listen_addr) =
248+
swarm2.listen().with_tcp_addr_external().await;
249+
let swarm2_peer_id = *swarm2.local_peer_id();
250+
swarm1.connect(&mut swarm2).await;
251+
252+
async_std::task::spawn(swarm2.loop_on_next());
253+
254+
let swarm_events = futures::stream::poll_fn(|cx| swarm1.poll_next_unpin(cx))
255+
.take(8)
256+
.collect::<Vec<_>>()
257+
.await;
258+
259+
let infos = swarm_events
260+
.iter()
261+
.filter_map(|e| match e {
262+
SwarmEvent::Behaviour(identify::Event::Received { info, .. }) => Some(info.clone()),
263+
_ => None,
264+
})
265+
.collect::<Vec<_>>();
266+
267+
assert!(
268+
infos.len() > 1,
269+
"should exchange identify payload more than once"
270+
);
271+
272+
let listen_addrs = infos
273+
.iter()
274+
.map(|i| i.listen_addrs.clone())
275+
.collect::<Vec<_>>();
276+
277+
for addrs in listen_addrs {
278+
assert_eq!(addrs.len(), 1);
279+
assert!(addrs.contains(&swarm2_tcp_listen_addr));
280+
}
281+
282+
let reported_addrs = swarm_events
283+
.iter()
284+
.filter_map(|e| match e {
285+
SwarmEvent::NewExternalAddrOfPeer { peer_id, address } => {
286+
Some((*peer_id, address.clone()))
287+
}
288+
_ => None,
289+
})
290+
.collect::<Vec<_>>();
291+
292+
assert_eq!(reported_addrs.len(), 1, "To have one TCP address of remote");
293+
assert!(reported_addrs.contains(&(swarm2_peer_id, swarm2_tcp_listen_addr)));
294+
}
295+
225296
#[async_std::test]
226297
async fn identify_push() {
227298
let _ = tracing_subscriber::fmt()

0 commit comments

Comments
 (0)