Skip to content

Commit

Permalink
fix(identify): Skip invalid multiaddr in listen_addrs (#3246)
Browse files Browse the repository at this point in the history
With this commit `libp2p-identify` no longer discards the whole identify payload in case a listen
addr of the remote node is invalid, but instead logs the failure, skips the invalid multiaddr and
parses the remaining identify payload.

> This is especially relevant when rolling out a new protocol to a live network. Say that most nodes
> of a network run on an implementation version v1. Say that the `multiaddr` implementation is not
> aware of the `webrtc/` protocol. Say that a new version (v2) is rolled out to the network with
> support for the `webrtc/` protocol, listening via `webrtc/` by default. In such case all v1 nodes
> would discard all identify payloads of v2 nodes, given that the v2 identify payloads would contain
> the `webrtc/` protocol in their `listen_addr` addresses.

See #3244 for details.
  • Loading branch information
mxinden authored Dec 17, 2022
1 parent be0b62a commit fd48971
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 5 deletions.
6 changes: 6 additions & 0 deletions protocols/identify/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 0.41.1

- Skip invalid multiaddr in `listen_addrs`. See [PR 3246].

[PR 3246]: https://github.com/libp2p/rust-libp2p/pull/3246

# 0.41.0

- Change default `cache_size` of `Config` to 100. See [PR 2995].
Expand Down
4 changes: 2 additions & 2 deletions protocols/identify/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "libp2p-identify"
edition = "2021"
rust-version = "1.62.0"
description = "Nodes identifcation protocol for libp2p"
version = "0.41.0"
version = "0.41.1"
authors = ["Parity Technologies <[email protected]>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand Down Expand Up @@ -32,7 +32,7 @@ libp2p = { path = "../..", features = ["full"] }
[build-dependencies]
prost-build = "0.11"

# Passing arguments to the docsrs builder in order to properly document cfg's.
# Passing arguments to the docsrs builder in order to properly document cfg's.
# More information: https://docs.rs/about/builds#cross-compiling
[package.metadata.docs.rs]
all-features = true
Expand Down
46 changes: 43 additions & 3 deletions protocols/identify/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use libp2p_core::{
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo},
Multiaddr, PublicKey,
};
use log::trace;
use log::{debug, trace};
use std::convert::TryFrom;
use std::{fmt, io, iter, pin::Pin};
use thiserror::Error;
Expand Down Expand Up @@ -236,14 +236,25 @@ impl TryFrom<structs_proto::Identify> for Info {
let listen_addrs = {
let mut addrs = Vec::new();
for addr in msg.listen_addrs.into_iter() {
addrs.push(parse_multiaddr(addr)?);
match parse_multiaddr(addr) {
Ok(a) => addrs.push(a),
Err(e) => {
debug!("Unable to parse multiaddr: {e:?}");
}
}
}
addrs
};

let public_key = PublicKey::from_protobuf_encoding(&msg.public_key.unwrap_or_default())?;

let observed_addr = parse_multiaddr(msg.observed_addr.unwrap_or_default())?;
let observed_addr = match parse_multiaddr(msg.observed_addr.unwrap_or_default()) {
Ok(a) => a,
Err(e) => {
debug!("Unable to parse multiaddr: {e:?}");
Multiaddr::empty()
}
};
let info = Info {
public_key,
protocol_version: msg.protocol_version.unwrap_or_default(),
Expand Down Expand Up @@ -363,4 +374,33 @@ mod tests {
bg_task.await;
});
}

#[test]
fn skip_invalid_multiaddr() {
let valid_multiaddr: Multiaddr = "/ip6/2001:db8::/tcp/1234".parse().unwrap();
let valid_multiaddr_bytes = valid_multiaddr.to_vec();

let invalid_multiaddr = {
let a = vec![255; 8];
assert!(Multiaddr::try_from(a.clone()).is_err());
a
};

let payload = structs_proto::Identify {
agent_version: None,
listen_addrs: vec![valid_multiaddr_bytes, invalid_multiaddr],
observed_addr: None,
protocol_version: None,
protocols: vec![],
public_key: Some(
identity::Keypair::generate_ed25519()
.public()
.to_protobuf_encoding(),
),
};

let info = Info::try_from(payload).expect("not to fail");

assert_eq!(info.listen_addrs, vec![valid_multiaddr])
}
}

0 comments on commit fd48971

Please sign in to comment.