From 281e1ebe6aaab873a9a02afb26f3fe8da55d18ac Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 21 Nov 2024 12:54:53 +0200 Subject: [PATCH] network/types: Move verification of external addr Signed-off-by: Alexandru Vasile --- .../client/network/types/src/multiaddr.rs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/substrate/client/network/types/src/multiaddr.rs b/substrate/client/network/types/src/multiaddr.rs index c394f81a2505..6121db908d42 100644 --- a/substrate/client/network/types/src/multiaddr.rs +++ b/substrate/client/network/types/src/multiaddr.rs @@ -32,6 +32,7 @@ pub use protocol::Protocol; // Re-export the macro under shorter name under `multiaddr`. pub use crate::build_multiaddr as multiaddr; +use crate::PeerId; /// [`Multiaddr`] type used in Substrate. Converted to libp2p's `Multiaddr` /// or litep2p's `Multiaddr` when passed to the corresponding network backend. @@ -76,6 +77,41 @@ impl Multiaddr { pub fn to_vec(&self) -> Vec { self.multiaddr.to_vec() } + + /// Verify the external address is valid. + /// + /// An external address address discovered by the network is valid when: + /// - the address is not empty + /// - the address contains a valid IP address + /// - the address is for the local peer ID + pub fn verify_external_address(&self, local_peer_id: PeerId) -> Result<(), ParseError> { + if self.is_empty() { + return Err(ParseError::InvalidMultiaddr); + } + + // Expect the address to contain a valid IP address. + if !std::matches!( + self.iter().next(), + Some( + Protocol::Dns(_) | + Protocol::Dns4(_) | + Protocol::Dns6(_) | + Protocol::Ip6(_) | + Protocol::Ip4(_), + ) + ) { + return Err(ParseError::InvalidMultiaddr); + } + + if let Some(Protocol::P2p(peer_id)) = self.iter().last() { + // Invalid address if the reported peer ID is not the local peer ID. + if peer_id != *local_peer_id.as_ref() { + return Err(ParseError::InvalidMultiaddr); + } + } + + Ok(()) + } } impl Display for Multiaddr {