From 56b3b8fe5a1e5d0b14ba7987a74ff3bc29f6b4e2 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 27 Dec 2022 12:59:52 +0100 Subject: [PATCH] fix(kad): Skip invalid multiaddr (#3284) With this commit `libp2p-kad` no longer discards the whole peer payload in case an addr is invalid, but instead logs the failure, skips the invalid multiaddr and parses the remaining payload. See https://github.com/libp2p/rust-libp2p/issues/3244 for details. Co-authored-by: Thomas Eizinger --- protocols/kad/CHANGELOG.md | 6 ++++++ protocols/kad/src/protocol.rs | 32 +++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/protocols/kad/CHANGELOG.md b/protocols/kad/CHANGELOG.md index f1fdcccefed..ce49b612c9b 100644 --- a/protocols/kad/CHANGELOG.md +++ b/protocols/kad/CHANGELOG.md @@ -10,6 +10,12 @@ [PR 3239]: https://github.com/libp2p/rust-libp2p/pull/3239 +# 0.42.1 + +- Skip unparsable multiaddr in `Peer::addrs`. See [PR 3280]. + +[PR 3280]: https://github.com/libp2p/rust-libp2p/pull/3280 + # 0.42.0 - Update to `libp2p-core` `v0.38.0`. diff --git a/protocols/kad/src/protocol.rs b/protocols/kad/src/protocol.rs index 707edd8fe02..3988d08f24d 100644 --- a/protocols/kad/src/protocol.rs +++ b/protocols/kad/src/protocol.rs @@ -105,10 +105,13 @@ impl TryFrom for KadPeer { let mut addrs = Vec::with_capacity(peer.addrs.len()); for addr in peer.addrs.into_iter() { - let as_ma = Multiaddr::try_from(addr).map_err(invalid_data)?; - addrs.push(as_ma); + match Multiaddr::try_from(addr) { + Ok(a) => addrs.push(a), + Err(e) => { + log::debug!("Unable to parse multiaddr: {e}"); + } + }; } - debug_assert_eq!(addrs.len(), addrs.capacity()); let connection_ty = proto::message::ConnectionType::from_i32(peer.connection) .ok_or_else(|| invalid_data("unknown connection type"))? @@ -601,6 +604,29 @@ where #[cfg(test)] mod tests { + use super::*; + + #[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 = proto::message::Peer { + id: PeerId::random().to_bytes(), + addrs: vec![valid_multiaddr_bytes, invalid_multiaddr], + connection: proto::message::ConnectionType::CanConnect.into(), + }; + + let peer = KadPeer::try_from(payload).expect("not to fail"); + + assert_eq!(peer.multiaddrs, vec![valid_multiaddr]) + } /*// TODO: restore use self::libp2p_tcp::TcpTransport;