diff --git a/Cargo.lock b/Cargo.lock index ed9f5816..4871b3a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1356,6 +1356,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + [[package]] name = "ipconfig" version = "0.3.2" @@ -1835,6 +1841,7 @@ dependencies = [ "hex-literal", "hickory-resolver", "indexmap", + "ip_network", "libc", "libp2p", "mockall", diff --git a/Cargo.toml b/Cargo.toml index 893e9455..cd4c77a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ x509-parser = "0.17.0" yasna = "0.5.0" zeroize = "1.8.1" yamux = "0.13.7" +ip_network = "0.4.1" # Websocket related dependencies. tokio-tungstenite = { version = "0.27.0", features = ["rustls-tls-native-roots", "url"], optional = true } diff --git a/src/config.rs b/src/config.rs index 13a370c9..3dd368bc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -29,7 +29,8 @@ use crate::{ notification, request_response, UserProtocol, }, transport::{ - manager::limits::ConnectionLimitsConfig, tcp::config::Config as TcpConfig, + manager::{limits::ConnectionLimitsConfig, IpDialingMode}, + tcp::config::Config as TcpConfig, KEEP_ALIVE_TIMEOUT, MAX_PARALLEL_DIALS, }, types::protocol::ProtocolName, @@ -125,6 +126,9 @@ pub struct ConfigBuilder { /// Close the connection if no substreams are open within this time frame. keep_alive_timeout: Duration, + /// IP dialing mode. + ip_dialing_mode: IpDialingMode, + /// Use system's DNS config. use_system_dns_config: bool, } @@ -160,6 +164,7 @@ impl ConfigBuilder { known_addresses: Vec::new(), connection_limits: ConnectionLimitsConfig::default(), keep_alive_timeout: KEEP_ALIVE_TIMEOUT, + ip_dialing_mode: IpDialingMode::All, use_system_dns_config: false, } } @@ -282,6 +287,23 @@ impl ConfigBuilder { self } + /// Set the ip dialing mode. + /// + /// When the private IP is enabled, litep2p will attempt to dial local addresses. + /// This is useful for testing or when you want to preserve local connections. + /// + /// However, for production use, it is recommended to disable the private IP dialing + /// to avoid unnecessary local traffic. Furthermore, it is not recommended + /// to enable private IP dialing when running a validator in a cloud provider, as this behavior + /// might be misinterpreted by the cloud provider's network policies as port scanning. + /// + /// Address allocation for private networks is specified by + /// [RFC1918](https://tools.ietf.org/html/rfc1918)). + pub fn with_ip_dialing_mode(mut self, mode: IpDialingMode) -> Self { + self.ip_dialing_mode = mode; + self + } + /// Set DNS resolver according to system configuration instead of default (Google). pub fn with_system_resolver(mut self) -> Self { self.use_system_dns_config = true; @@ -317,6 +339,7 @@ impl ConfigBuilder { known_addresses: self.known_addresses, connection_limits: self.connection_limits, keep_alive_timeout: self.keep_alive_timeout, + ip_dialing_mode: self.ip_dialing_mode, use_system_dns_config: self.use_system_dns_config, } } @@ -381,6 +404,9 @@ pub struct Litep2pConfig { /// Close the connection if no substreams are open within this time frame. pub(crate) keep_alive_timeout: Duration, + /// IP dialing mode. + pub(crate) ip_dialing_mode: IpDialingMode, + /// Use system's DNS config. pub(crate) use_system_dns_config: bool, } diff --git a/src/error.rs b/src/error.rs index 7128fad7..7ddf94c7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -78,8 +78,6 @@ pub enum Error { Timeout, #[error("Invalid state transition")] InvalidState, - #[error("DNS address resolution failed")] - DnsAddressResolutionFailed, #[error("Transport error: `{0}`")] TransportError(String), #[cfg(feature = "quic")] diff --git a/src/lib.rs b/src/lib.rs index fc36c776..6034c4ff 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -176,6 +176,7 @@ impl Litep2p { bandwidth_sink.clone(), litep2p_config.max_parallel_dials, litep2p_config.connection_limits, + litep2p_config.ip_dialing_mode, ); // add known addresses to `TransportManager`, if any exist @@ -642,6 +643,7 @@ mod tests { .with_notification_protocol(config1) .with_notification_protocol(config2) .with_libp2p_ping(ping_config) + .with_ip_dialing_mode(crate::transport::manager::IpDialingMode::All) .build(); let peer = PeerId::random(); diff --git a/src/protocol/libp2p/identify.rs b/src/protocol/libp2p/identify.rs index 0a969fda..db9c2451 100644 --- a/src/protocol/libp2p/identify.rs +++ b/src/protocol/libp2p/identify.rs @@ -474,6 +474,7 @@ mod tests { ..Default::default() }) .with_libp2p_identify(identify_config) + .with_ip_dialing_mode(crate::transport::manager::IpDialingMode::All) .build(); (Litep2p::new(config).unwrap(), identify, peer) diff --git a/src/protocol/libp2p/kademlia/mod.rs b/src/protocol/libp2p/kademlia/mod.rs index fcfb6a88..bc22c895 100644 --- a/src/protocol/libp2p/kademlia/mod.rs +++ b/src/protocol/libp2p/kademlia/mod.rs @@ -1257,7 +1257,7 @@ mod tests { codec::ProtocolCodec, crypto::ed25519::Keypair, transport::{ - manager::{limits::ConnectionLimitsConfig, TransportManager}, + manager::{limits::ConnectionLimitsConfig, IpDialingMode, TransportManager}, KEEP_ALIVE_TIMEOUT, }, types::protocol::ProtocolName, @@ -1281,6 +1281,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); diff --git a/src/protocol/mdns.rs b/src/protocol/mdns.rs index 44f7048c..1992fc57 100644 --- a/src/protocol/mdns.rs +++ b/src/protocol/mdns.rs @@ -365,7 +365,7 @@ mod tests { use super::*; use crate::{ crypto::ed25519::Keypair, - transport::manager::{limits::ConnectionLimitsConfig, TransportManager}, + transport::manager::{limits::ConnectionLimitsConfig, IpDialingMode, TransportManager}, BandwidthSink, }; use futures::StreamExt; @@ -384,6 +384,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let mdns1 = Mdns::new( @@ -406,6 +407,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let mdns2 = Mdns::new( diff --git a/src/protocol/notification/tests/mod.rs b/src/protocol/notification/tests/mod.rs index 4aa48aa4..2c02312f 100644 --- a/src/protocol/notification/tests/mod.rs +++ b/src/protocol/notification/tests/mod.rs @@ -30,7 +30,7 @@ use crate::{ InnerTransportEvent, ProtocolCommand, TransportService, }, transport::{ - manager::{limits::ConnectionLimitsConfig, TransportManager}, + manager::{limits::ConnectionLimitsConfig, IpDialingMode, TransportManager}, KEEP_ALIVE_TIMEOUT, }, types::protocol::ProtocolName, @@ -57,6 +57,7 @@ fn make_notification_protocol() -> ( BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); diff --git a/src/protocol/request_response/tests.rs b/src/protocol/request_response/tests.rs index 32cc65e7..00956ebb 100644 --- a/src/protocol/request_response/tests.rs +++ b/src/protocol/request_response/tests.rs @@ -30,7 +30,7 @@ use crate::{ }, substream::Substream, transport::{ - manager::{limits::ConnectionLimitsConfig, TransportManager}, + manager::{limits::ConnectionLimitsConfig, IpDialingMode, TransportManager}, KEEP_ALIVE_TIMEOUT, }, types::{RequestId, SubstreamId}, @@ -55,6 +55,7 @@ fn protocol() -> ( BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); diff --git a/src/transport/common/listener.rs b/src/transport/common/listener.rs index 856b4c19..ada323ad 100644 --- a/src/transport/common/listener.rs +++ b/src/transport/common/listener.rs @@ -22,6 +22,7 @@ use crate::{ error::{AddressError, DnsError}, + transport::manager::IpDialingMode, PeerId, }; @@ -54,6 +55,7 @@ pub enum AddressType { address: String, port: u16, dns_type: DnsType, + ip_dialing_mode: IpDialingMode, }, } @@ -71,14 +73,15 @@ pub enum DnsType { impl AddressType { /// Resolve the address to a concrete IP. pub async fn lookup_ip(self, resolver: Arc) -> Result { - let (url, port, dns_type) = match self { + let (url, port, dns_type, ip_dialing_mode) = match self { // We already have the IP address. AddressType::Socket(address) => return Ok(address), AddressType::Dns { address, port, dns_type, - } => (address, port, dns_type), + ip_dialing_mode, + } => (address, port, dns_type, ip_dialing_mode), }; let lookup = match resolver.lookup_ip(url.clone()).await { @@ -95,10 +98,22 @@ impl AddressType { } }; - let Some(ip) = lookup.iter().find(|ip| match dns_type { - DnsType::Dns => true, - DnsType::Dns4 => ip.is_ipv4(), - DnsType::Dns6 => ip.is_ipv6(), + let Some(ip) = lookup.iter().find(|ip| { + if !ip_dialing_mode.allows_ip(*ip) { + tracing::debug!( + target: LOG_TARGET, + ?ip, + ?ip_dialing_mode, + "IP address not allowed by IP dialing mode during DNS lookup", + ); + return false; + } + + match dns_type { + DnsType::Dns => true, + DnsType::Dns4 => ip.is_ipv4(), + DnsType::Dns6 => ip.is_ipv6(), + } }) else { tracing::debug!( target: LOG_TARGET, @@ -178,6 +193,7 @@ pub trait GetSocketAddr { /// The `PeerId` is optional and may not be present. fn multiaddr_to_socket_address( address: &Multiaddr, + ip_dialing_mode: IpDialingMode, ) -> Result<(AddressType, Option), AddressError>; /// Convert concrete `SocketAddr` to `Multiaddr`. @@ -190,8 +206,9 @@ pub struct TcpAddress; impl GetSocketAddr for TcpAddress { fn multiaddr_to_socket_address( address: &Multiaddr, + ip_dialing_mode: IpDialingMode, ) -> Result<(AddressType, Option), AddressError> { - multiaddr_to_socket_address(address, SocketListenerType::Tcp) + multiaddr_to_socket_address(address, ip_dialing_mode, SocketListenerType::Tcp) } fn socket_address_to_multiaddr(address: &SocketAddr) -> Multiaddr { @@ -209,8 +226,9 @@ pub struct WebSocketAddress; impl GetSocketAddr for WebSocketAddress { fn multiaddr_to_socket_address( address: &Multiaddr, + ip_dialing_mode: IpDialingMode, ) -> Result<(AddressType, Option), AddressError> { - multiaddr_to_socket_address(address, SocketListenerType::WebSocket) + multiaddr_to_socket_address(address, ip_dialing_mode, SocketListenerType::WebSocket) } fn socket_address_to_multiaddr(address: &SocketAddr) -> Multiaddr { @@ -231,19 +249,21 @@ impl SocketListener { let (listeners, listen_addresses): (_, Vec>) = addresses .into_iter() .filter_map(|address| { - let address = match T::multiaddr_to_socket_address(&address).ok()?.0 { - AddressType::Dns { address, port, .. } => { - tracing::debug!( - target: LOG_TARGET, - ?address, - ?port, - "dns not supported as bind address" - ); - - return None; - } - AddressType::Socket(address) => address, - }; + // Allows listening on the specified address. + let address = + match T::multiaddr_to_socket_address(&address, IpDialingMode::All).ok()?.0 { + AddressType::Dns { address, port, .. } => { + tracing::debug!( + target: LOG_TARGET, + ?address, + ?port, + "dns not supported as bind address" + ); + + return None; + } + AddressType::Socket(address) => address, + }; let socket = if address.is_ipv4() { Socket::new(Domain::IPV4, Type::STREAM, Some(socket2::Protocol::TCP)).ok()? @@ -348,10 +368,21 @@ enum SocketListenerType { /// Extract socket address and `PeerId`, if found, from `address`. fn multiaddr_to_socket_address( address: &Multiaddr, + ip_dialing_mode: IpDialingMode, ty: SocketListenerType, ) -> Result<(AddressType, Option), AddressError> { tracing::trace!(target: LOG_TARGET, ?address, "parse multi address"); + if !ip_dialing_mode.allows_address(address) { + tracing::error!( + target: LOG_TARGET, + ?address, + ?ip_dialing_mode, + "address not allowed by IP dialing mode", + ); + return Err(AddressError::AddressNotAvailable); + } + let mut iter = address.iter(); // Small helper to handle DNS types. let handle_dns_type = @@ -360,6 +391,7 @@ fn multiaddr_to_socket_address( address, port, dns_type, + ip_dialing_mode, }), protocol => { tracing::error!( @@ -484,11 +516,13 @@ mod tests { fn parse_multiaddresses_tcp() { assert!(multiaddr_to_socket_address( &"/ip6/::1/tcp/8888".parse().expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::Tcp, ) .is_ok()); assert!(multiaddr_to_socket_address( &"/ip4/127.0.0.1/tcp/8888".parse().expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::Tcp, ) .is_ok()); @@ -496,6 +530,7 @@ mod tests { &"/ip6/::1/tcp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::Tcp, ) .is_ok()); @@ -503,6 +538,7 @@ mod tests { &"/ip4/127.0.0.1/tcp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::Tcp, ) .is_ok()); @@ -510,6 +546,7 @@ mod tests { &"/ip6/::1/udp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::Tcp, ) .is_err()); @@ -517,6 +554,7 @@ mod tests { &"/ip4/127.0.0.1/udp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::Tcp, ) .is_err()); @@ -527,11 +565,13 @@ mod tests { fn parse_multiaddresses_websocket() { assert!(multiaddr_to_socket_address( &"/ip6/::1/tcp/8888/ws".parse().expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_ok()); assert!(multiaddr_to_socket_address( &"/ip4/127.0.0.1/tcp/8888/ws".parse().expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_ok()); @@ -539,6 +579,7 @@ mod tests { &"/ip6/::1/tcp/8888/ws/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_ok()); @@ -546,6 +587,7 @@ mod tests { &"/ip4/127.0.0.1/tcp/8888/ws/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_ok()); @@ -553,6 +595,7 @@ mod tests { &"/ip6/::1/udp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_err()); @@ -560,11 +603,13 @@ mod tests { &"/ip4/127.0.0.1/udp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_err()); assert!(multiaddr_to_socket_address( &"/ip4/127.0.0.1/tcp/8888/ws/utp".parse().expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_err()); @@ -572,6 +617,7 @@ mod tests { &"/ip6/::1/tcp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_err()); @@ -579,6 +625,7 @@ mod tests { &"/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_err()); @@ -586,28 +633,32 @@ mod tests { &"/dns/hello.world/tcp/8888/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), + IpDialingMode::All, SocketListenerType::WebSocket, ) .is_err()); assert!(multiaddr_to_socket_address( &"/dns6/hello.world/tcp/8888/ws/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() - .expect("valid multiaddress") - ,SocketListenerType::WebSocket, + .expect("valid multiaddress"), + IpDialingMode::All, + SocketListenerType::WebSocket, ) .is_ok()); assert!(multiaddr_to_socket_address( &"/dns4/hello.world/tcp/8888/ws/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), - SocketListenerType::WebSocket, + IpDialingMode::All, + SocketListenerType::WebSocket, ) .is_ok()); assert!(multiaddr_to_socket_address( &"/dns6/hello.world/tcp/8888/ws/p2p/12D3KooWT2ouvz5uMmCvHJGzAGRHiqDts5hzXR7NdoQ27pGdzp9Q" .parse() .expect("valid multiaddress"), - SocketListenerType::WebSocket, + IpDialingMode::All, + SocketListenerType::WebSocket, ) .is_ok()); } diff --git a/src/transport/manager/handle.rs b/src/transport/manager/handle.rs index 87598609..3872b660 100644 --- a/src/transport/manager/handle.rs +++ b/src/transport/manager/handle.rs @@ -28,7 +28,7 @@ use crate::{ address::AddressRecord, peer_state::StateDialResult, types::{PeerContext, SupportedTransport}, - ProtocolContext, TransportManagerEvent, LOG_TARGET, + IpDialingMode, ProtocolContext, TransportManagerEvent, LOG_TARGET, }, types::{protocol::ProtocolName, ConnectionId}, BandwidthSink, PeerId, @@ -99,6 +99,11 @@ impl TransportManagerHandle { listen_addresses: Arc>>, public_addresses: PublicAddresses, ) -> Self { + tracing::debug!( + target: LOG_TARGET, + "Transport manager handle created", + ); + Self { peers, cmd_tx, @@ -248,7 +253,11 @@ impl TransportManagerHandle { { let peers = self.peers.read(); - let Some(PeerContext { state, addresses }) = peers.get(peer) else { + let Some(PeerContext { + state, + addresses: address_store, + }) = peers.get(peer) + else { return Err(ImmediateDialError::NoAddressAvailable); }; @@ -260,7 +269,7 @@ impl TransportManagerHandle { }; // Check if we have enough addresses to dial. - if addresses.is_empty() { + if address_store.is_empty() { return Err(ImmediateDialError::NoAddressAvailable); } } @@ -321,6 +330,7 @@ pub struct TransportHandle { pub next_substream_id: Arc, pub bandwidth_sink: BandwidthSink, pub executor: Arc, + pub ip_dialing_mode: IpDialingMode, } impl TransportHandle { diff --git a/src/transport/manager/mod.rs b/src/transport/manager/mod.rs index 013d4a7b..30718866 100644 --- a/src/transport/manager/mod.rs +++ b/src/transport/manager/mod.rs @@ -48,7 +48,9 @@ use tokio::sync::mpsc::{channel, Receiver, Sender}; use std::{ collections::{HashMap, HashSet}, + net::IpAddr, pin::Pin, + str::FromStr, sync::{ atomic::{AtomicUsize, Ordering}, Arc, @@ -194,6 +196,60 @@ impl Stream for TransportContext { } } +/// The IP dialing mode determines how the transport manager handles dialing +/// IP addresses. +/// +/// It can either dial only global addresses or all addresses, including private IPs. +#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)] +pub enum IpDialingMode { + /// Dial only global addresses. + GlobalOnly, + + /// Dial all addresses, including private IPs. + /// + /// This setup is not recommended for production use-cases. + #[default] + All, +} + +impl IpDialingMode { + /// Check if the IP address in the given `Multiaddr` is global. + pub fn is_address_global(address: &Multiaddr) -> bool { + let ip = match address.iter().next() { + Some(Protocol::Ip4(ip)) => ip_network::IpNetwork::from(ip), + Some(Protocol::Ip6(ip)) => ip_network::IpNetwork::from(ip), + Some(Protocol::Dns(host)) | Some(Protocol::Dns4(host)) | Some(Protocol::Dns6(host)) => + if let Ok(ip) = IpAddr::from_str(&host) { + ip_network::IpNetwork::from(ip) + } else { + // Allow DNS resolutions for DNS names. + return true; + }, + _ => return false, + }; + + ip.is_global() + } + + /// Check if the IP dialing mode allows dialing the given address. + pub fn allows_address(&self, address: &Multiaddr) -> bool { + match self { + Self::GlobalOnly => Self::is_address_global(address), + // All IP addresses are allowed. + Self::All => true, + } + } + + /// Check if the IP dialing mode allows dialing the given IP address. + pub fn allows_ip(&self, ip: IpAddr) -> bool { + match self { + Self::GlobalOnly => ip_network::IpNetwork::from(ip).is_global(), + // All IP addresses are allowed. + Self::All => true, + } + } +} + /// Litep2p connection manager. pub struct TransportManager { /// Local peer ID. @@ -252,6 +308,9 @@ pub struct TransportManager { /// Opening connections errors. opening_errors: HashMap>, + + /// IP dialing mode. + ip_dialing_mode: IpDialingMode, } impl TransportManager { @@ -263,6 +322,7 @@ impl TransportManager { bandwidth_sink: BandwidthSink, max_parallel_dials: usize, connection_limits_config: limits::ConnectionLimitsConfig, + ip_dialing_mode: IpDialingMode, ) -> (Self, TransportManagerHandle) { let local_peer_id = PeerId::from_public_key(&keypair.public().into()); let peers = Arc::new(RwLock::new(HashMap::new())); @@ -279,6 +339,12 @@ impl TransportManager { public_addresses.clone(), ); + tracing::debug!( + target: LOG_TARGET, + ?ip_dialing_mode, + "Transport manager created", + ); + ( Self { peers, @@ -300,6 +366,7 @@ impl TransportManager { next_connection_id: Arc::new(AtomicUsize::new(0usize)), connection_limits: limits::ConnectionLimits::new(connection_limits_config), opening_errors: HashMap::new(), + ip_dialing_mode, }, handle, ) @@ -390,6 +457,7 @@ impl TransportManager { bandwidth_sink: self.bandwidth_sink.clone(), next_substream_id: self.next_substream_id.clone(), next_connection_id: self.next_connection_id.clone(), + ip_dialing_mode: self.ip_dialing_mode, } } @@ -482,7 +550,14 @@ impl TransportManager { // The addresses are sorted by score and contain the remote peer ID. // We double checked above that the remote peer is not the local peer. - let dial_addresses = context.addresses.addresses(limit); + let dial_addresses = context + .addresses + .addresses(usize::MAX) + .into_iter() + .filter(|addr| self.ip_dialing_mode.allows_address(addr)) + .take(limit) + .collect::>(); + if dial_addresses.is_empty() { return Err(Error::NoAddressAvailable(peer)); } @@ -543,6 +618,11 @@ impl TransportManager { return Err(Error::TriedToDialSelf); } + if !self.ip_dialing_mode.allows_address(address_record.address()) { + tracing::debug!(target: LOG_TARGET, address = ?address_record.address(), "dial address is not global, skipping"); + return Err(Error::AddressError(AddressError::AddressNotAvailable)); + } + tracing::debug!(target: LOG_TARGET, address = ?address_record.address(), "dial address"); let mut protocol_stack = address_record.as_ref().iter(); @@ -1347,6 +1427,7 @@ impl TransportManager { mod tests { use crate::transport::manager::{address::AddressStore, peer_state::SecondaryOrDialing}; use limits::ConnectionLimitsConfig; + use IpDialingMode; use multihash::Multihash; @@ -1539,6 +1620,7 @@ mod tests { sink, 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_protocol( @@ -1566,6 +1648,7 @@ mod tests { sink, 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_protocol( @@ -1596,6 +1679,7 @@ mod tests { sink, 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_protocol( @@ -1629,6 +1713,7 @@ mod tests { sink, 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -1646,6 +1731,7 @@ mod tests { sink, 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); assert!(manager.dial(local_peer_id).await.is_err()); @@ -1659,6 +1745,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -1689,6 +1776,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); let dial_address = Multiaddr::empty() @@ -1751,6 +1839,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -1782,6 +1871,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -1827,6 +1917,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -1846,6 +1937,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -1879,6 +1971,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); // ipv6 @@ -1941,6 +2034,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2008,6 +2102,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2095,6 +2190,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let _handle = manager.transport_handle(Arc::new(DefaultExecutor {})); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2180,6 +2276,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2289,6 +2386,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2385,6 +2483,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2494,6 +2593,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2598,6 +2698,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -2742,6 +2843,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.on_dial_failure(ConnectionId::random()).unwrap(); @@ -2761,6 +2863,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.on_connection_closed(PeerId::random(), ConnectionId::random()).unwrap(); } @@ -2779,6 +2882,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager .on_connection_opened( @@ -2803,6 +2907,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let connection_id = ConnectionId::random(); let peer = PeerId::random(); @@ -2827,6 +2932,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let connection_id = ConnectionId::random(); let peer = PeerId::random(); @@ -2854,6 +2960,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager @@ -2875,6 +2982,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let connection_id = ConnectionId::random(); let peer = PeerId::random(); @@ -2895,6 +3003,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); assert!(manager.next().await.is_none()); @@ -2908,6 +3017,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = { @@ -2956,6 +3066,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = { @@ -3019,6 +3130,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = { @@ -3062,6 +3174,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); // transport doesn't start with ip/dns @@ -3128,6 +3241,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); async fn call_manager(manager: &mut TransportManager, address: Multiaddr) { @@ -3182,6 +3296,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); let dial_address = Multiaddr::empty() @@ -3268,6 +3383,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); let dial_address = Multiaddr::empty() @@ -3358,6 +3474,7 @@ mod tests { ConnectionLimitsConfig::default() .max_incoming_connections(Some(3)) .max_outgoing_connections(Some(2)), + IpDialingMode::All, ); // The connection limit is agnostic of the underlying transports. manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -3434,6 +3551,7 @@ mod tests { ConnectionLimitsConfig::default() .max_incoming_connections(Some(3)) .max_outgoing_connections(Some(2)), + IpDialingMode::All, ); // The connection limit is agnostic of the underlying transports. manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -3521,6 +3639,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -3574,6 +3693,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); manager.register_transport(SupportedTransport::Tcp, Box::new(DummyTransport::new())); @@ -3726,6 +3846,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); let dial_address = Multiaddr::empty() @@ -3812,6 +3933,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let peer = PeerId::random(); let connection_id = ConnectionId::from(0); diff --git a/src/transport/tcp/connection.rs b/src/transport/tcp/connection.rs index c724dff6..200873b7 100644 --- a/src/transport/tcp/connection.rs +++ b/src/transport/tcp/connection.rs @@ -469,6 +469,7 @@ impl TcpConnection { address, port, dns_type, + .. } => match dns_type { DnsType::Dns => Multiaddr::empty() .with(Protocol::Dns(Cow::Owned(address))) @@ -749,7 +750,7 @@ impl TcpConnection { #[cfg(test)] mod tests { - use crate::transport::tcp::TcpTransport; + use crate::transport::{manager::IpDialingMode, tcp::TcpTransport}; use super::*; use hickory_resolver::{name_server::TokioConnectionProvider, TokioResolver}; @@ -783,6 +784,7 @@ mod tests { ) .build(), ), + IpDialingMode::All, ) .await .unwrap(); @@ -885,6 +887,7 @@ mod tests { ) .build(), ), + IpDialingMode::All, ) .await .unwrap(); @@ -1034,6 +1037,7 @@ mod tests { ) .build(), ), + IpDialingMode::All, ) .await .unwrap(); @@ -1087,6 +1091,7 @@ mod tests { ) .build(), ), + IpDialingMode::All, ) .await .unwrap(); @@ -1267,6 +1272,7 @@ mod tests { ) .build(), ), + IpDialingMode::All, ) .await .unwrap(); @@ -1402,6 +1408,7 @@ mod tests { ) .build(), ), + IpDialingMode::All, ) .await .unwrap(); diff --git a/src/transport/tcp/mod.rs b/src/transport/tcp/mod.rs index a97fa417..bca1ac27 100644 --- a/src/transport/tcp/mod.rs +++ b/src/transport/tcp/mod.rs @@ -26,7 +26,7 @@ use crate::{ error::{DialError, Error}, transport::{ common::listener::{DialAddresses, GetSocketAddr, SocketListener, TcpAddress}, - manager::TransportHandle, + manager::{IpDialingMode, TransportHandle}, tcp::{ config::Config, connection::{NegotiatedConnection, TcpConnection}, @@ -134,6 +134,9 @@ pub(crate) struct TcpTransport { /// DNS resolver. resolver: Arc, + + /// IP dialing mode. + ip_dialing_mode: IpDialingMode, } impl TcpTransport { @@ -182,8 +185,10 @@ impl TcpTransport { connection_open_timeout: Duration, nodelay: bool, resolver: Arc, + ip_dialing_mode: IpDialingMode, ) -> Result<(Multiaddr, TcpStream), DialError> { - let (socket_address, _) = TcpAddress::multiaddr_to_socket_address(&address)?; + let (socket_address, _) = + TcpAddress::multiaddr_to_socket_address(&address, ip_dialing_mode)?; let remote_address = match tokio::time::timeout(connection_open_timeout, socket_address.lookup_ip(resolver)) @@ -281,9 +286,12 @@ impl TransportBuilder for TcpTransport { mut config: Self::Config, resolver: Arc, ) -> crate::Result<(Self, Vec)> { + let ip_dialing_mode = context.ip_dialing_mode; + tracing::debug!( target: LOG_TARGET, listen_addresses = ?config.listen_addresses, + ?ip_dialing_mode, "start tcp transport", ); @@ -308,6 +316,7 @@ impl TransportBuilder for TcpTransport { pending_raw_connections: FuturesStream::new(), cancel_futures: HashMap::new(), resolver, + ip_dialing_mode, }, listen_addresses, )) @@ -318,7 +327,8 @@ impl Transport for TcpTransport { fn dial(&mut self, connection_id: ConnectionId, address: Multiaddr) -> crate::Result<()> { tracing::debug!(target: LOG_TARGET, ?connection_id, ?address, "open connection"); - let (socket_address, peer) = TcpAddress::multiaddr_to_socket_address(&address)?; + let (socket_address, peer) = + TcpAddress::multiaddr_to_socket_address(&address, self.ip_dialing_mode)?; let yamux_config = self.config.yamux_config.clone(); let max_read_ahead_factor = self.config.noise_read_ahead_frame_count; let max_write_buffer_size = self.config.noise_write_buffer_size; @@ -328,6 +338,7 @@ impl Transport for TcpTransport { let keypair = self.context.keypair.clone(); let nodelay = self.config.nodelay; let resolver = self.resolver.clone(); + let ip_dialing_mode = self.ip_dialing_mode; self.pending_dials.insert(connection_id, address.clone()); self.pending_connections.push(Box::pin(async move { @@ -337,6 +348,7 @@ impl Transport for TcpTransport { connection_open_timeout, nodelay, resolver, + ip_dialing_mode, ) .await .map_err(|error| (connection_id, error))?; @@ -443,6 +455,7 @@ impl Transport for TcpTransport { let connection_open_timeout = self.config.connection_open_timeout; let nodelay = self.config.nodelay; let resolver = self.resolver.clone(); + let ip_dialing_mode = self.ip_dialing_mode; async move { TcpTransport::dial_peer( @@ -451,6 +464,7 @@ impl Transport for TcpTransport { connection_open_timeout, nodelay, resolver, + ip_dialing_mode, ) .await .map_err(|error| (address, error)) @@ -501,7 +515,9 @@ impl Transport for TcpTransport { .remove(&connection_id) .ok_or(Error::ConnectionDoesntExist(connection_id))?; - let (socket_address, peer) = TcpAddress::multiaddr_to_socket_address(&address)?; + // Address already validated during the dial process. + let (socket_address, peer) = + TcpAddress::multiaddr_to_socket_address(&address, IpDialingMode::All)?; let yamux_config = self.config.yamux_config.clone(); let max_read_ahead_factor = self.config.noise_read_ahead_frame_count; let max_write_buffer_size = self.config.noise_write_buffer_size; @@ -703,7 +719,8 @@ mod tests { crypto::ed25519::Keypair, executor::DefaultExecutor, transport::manager::{ - limits::ConnectionLimitsConfig, ProtocolContext, SupportedTransport, TransportManager, + limits::ConnectionLimitsConfig, IpDialingMode, ProtocolContext, SupportedTransport, + TransportManager, }, types::protocol::ProtocolName, BandwidthSink, PeerId, @@ -731,7 +748,6 @@ mod tests { keypair: keypair1.clone(), tx: event_tx1, bandwidth_sink: bandwidth_sink.clone(), - protocols: HashMap::from_iter([( ProtocolName::from("/notif/1"), ProtocolContext { @@ -740,6 +756,7 @@ mod tests { fallback_names: Vec::new(), }, )]), + ip_dialing_mode: IpDialingMode::All, }; let transport_config1 = Config { listen_addresses: vec!["/ip6/::1/tcp/0".parse().unwrap()], @@ -762,7 +779,6 @@ mod tests { keypair: keypair2.clone(), tx: event_tx2, bandwidth_sink: bandwidth_sink.clone(), - protocols: HashMap::from_iter([( ProtocolName::from("/notif/1"), ProtocolContext { @@ -771,6 +787,7 @@ mod tests { fallback_names: Vec::new(), }, )]), + ip_dialing_mode: IpDialingMode::All, }; let transport_config2 = Config { listen_addresses: vec!["/ip6/::1/tcp/0".parse().unwrap()], @@ -825,7 +842,6 @@ mod tests { keypair: keypair1.clone(), tx: event_tx1, bandwidth_sink: bandwidth_sink.clone(), - protocols: HashMap::from_iter([( ProtocolName::from("/notif/1"), ProtocolContext { @@ -834,6 +850,7 @@ mod tests { fallback_names: Vec::new(), }, )]), + ip_dialing_mode: IpDialingMode::All, }; let transport_config1 = Config { listen_addresses: vec!["/ip6/::1/tcp/0".parse().unwrap()], @@ -856,7 +873,6 @@ mod tests { keypair: keypair2.clone(), tx: event_tx2, bandwidth_sink: bandwidth_sink.clone(), - protocols: HashMap::from_iter([( ProtocolName::from("/notif/1"), ProtocolContext { @@ -865,6 +881,7 @@ mod tests { fallback_names: Vec::new(), }, )]), + ip_dialing_mode: IpDialingMode::All, }; let transport_config2 = Config { listen_addresses: vec!["/ip6/::1/tcp/0".parse().unwrap()], @@ -914,7 +931,6 @@ mod tests { keypair: keypair1.clone(), tx: event_tx1, bandwidth_sink: bandwidth_sink.clone(), - protocols: HashMap::from_iter([( ProtocolName::from("/notif/1"), ProtocolContext { @@ -923,6 +939,7 @@ mod tests { fallback_names: Vec::new(), }, )]), + ip_dialing_mode: IpDialingMode::All, }; let resolver = Arc::new(TokioResolver::builder_tokio().unwrap().build()); let (mut transport1, _) = @@ -952,7 +969,6 @@ mod tests { keypair: keypair2.clone(), tx: event_tx2, bandwidth_sink: bandwidth_sink.clone(), - protocols: HashMap::from_iter([( ProtocolName::from("/notif/1"), ProtocolContext { @@ -961,6 +977,7 @@ mod tests { fallback_names: Vec::new(), }, )]), + ip_dialing_mode: IpDialingMode::All, }; let (mut transport2, _) = TcpTransport::new(handle2, Default::default(), resolver).unwrap(); @@ -1002,6 +1019,7 @@ mod tests { BandwidthSink::new(), 8usize, ConnectionLimitsConfig::default(), + IpDialingMode::All, ); let handle = manager.transport_handle(Arc::new(DefaultExecutor {})); let resolver = Arc::new(TokioResolver::builder_tokio().unwrap().build()); diff --git a/src/transport/websocket/connection.rs b/src/transport/websocket/connection.rs index dcfe60e0..3b0b6066 100644 --- a/src/transport/websocket/connection.rs +++ b/src/transport/websocket/connection.rs @@ -602,7 +602,7 @@ impl WebSocketConnection { #[cfg(test)] mod tests { - use crate::transport::websocket::WebSocketTransport; + use crate::transport::{manager::IpDialingMode, websocket::WebSocketTransport}; use super::*; use futures::AsyncWriteExt; @@ -642,6 +642,7 @@ mod tests { Duration::from_secs(10), false, Arc::new(TokioResolver::builder_tokio().unwrap().build()), + IpDialingMode::All, ) .await .unwrap(); @@ -758,6 +759,7 @@ mod tests { Duration::from_secs(10), false, Arc::new(TokioResolver::builder_tokio().unwrap().build()), + IpDialingMode::All, ) .await .unwrap(); @@ -1030,6 +1032,7 @@ mod tests { Duration::from_secs(10), false, Arc::new(TokioResolver::builder_tokio().unwrap().build()), + IpDialingMode::All, ) .await .unwrap(); @@ -1198,6 +1201,7 @@ mod tests { Duration::from_secs(10), false, Arc::new(TokioResolver::builder_tokio().unwrap().build()), + IpDialingMode::All, ) .await .unwrap(); @@ -1352,6 +1356,7 @@ mod tests { Duration::from_secs(10), false, Arc::new(TokioResolver::builder_tokio().unwrap().build()), + IpDialingMode::All, ) .await .unwrap(); diff --git a/src/transport/websocket/mod.rs b/src/transport/websocket/mod.rs index 11013e6c..f74de6b2 100644 --- a/src/transport/websocket/mod.rs +++ b/src/transport/websocket/mod.rs @@ -25,7 +25,7 @@ use crate::{ error::{AddressError, Error, NegotiationError}, transport::{ common::listener::{DialAddresses, GetSocketAddr, SocketListener, WebSocketAddress}, - manager::TransportHandle, + manager::{IpDialingMode, TransportHandle}, websocket::{ config::Config, connection::{NegotiatedConnection, WebSocketConnection}, @@ -136,6 +136,9 @@ pub(crate) struct WebSocketTransport { /// DNS resolver. resolver: Arc, + + /// IP dialing mode. + ip_dialing_mode: IpDialingMode, } impl WebSocketTransport { @@ -229,10 +232,12 @@ impl WebSocketTransport { connection_open_timeout: Duration, nodelay: bool, resolver: Arc, + ip_dialing_mode: IpDialingMode, ) -> Result<(Multiaddr, WebSocketStream>), DialError> { let (url, _) = Self::multiaddr_into_url(address.clone())?; - let (socket_address, _) = WebSocketAddress::multiaddr_to_socket_address(&address)?; + let (socket_address, _) = + WebSocketAddress::multiaddr_to_socket_address(&address, ip_dialing_mode)?; let remote_address = match tokio::time::timeout(connection_open_timeout, socket_address.lookup_ip(resolver)) .await @@ -314,9 +319,12 @@ impl TransportBuilder for WebSocketTransport { where Self: Sized, { + let ip_dialing_mode = context.ip_dialing_mode; + tracing::debug!( target: LOG_TARGET, listen_addresses = ?config.listen_addresses, + ?ip_dialing_mode, "start websocket transport", ); let (listener, listen_addresses, dial_addresses) = SocketListener::new::( @@ -339,6 +347,7 @@ impl TransportBuilder for WebSocketTransport { pending_raw_connections: FuturesStream::new(), cancel_futures: HashMap::new(), resolver, + ip_dialing_mode, }, listen_addresses, )) @@ -357,6 +366,7 @@ impl Transport for WebSocketTransport { let dial_addresses = self.dial_addresses.clone(); let nodelay = self.config.nodelay; let resolver = self.resolver.clone(); + let ip_dialing_mode = self.ip_dialing_mode; self.pending_dials.insert(connection_id, address.clone()); @@ -369,6 +379,7 @@ impl Transport for WebSocketTransport { connection_open_timeout, nodelay, resolver, + ip_dialing_mode, ) .await .map_err(|error| (connection_id, error))?; @@ -487,6 +498,7 @@ impl Transport for WebSocketTransport { let dial_addresses = self.dial_addresses.clone(); let nodelay = self.config.nodelay; let resolver = self.resolver.clone(); + let ip_dialing_mode = self.ip_dialing_mode; async move { WebSocketTransport::dial_peer( @@ -495,6 +507,7 @@ impl Transport for WebSocketTransport { connection_open_timeout, nodelay, resolver, + ip_dialing_mode, ) .await .map_err(|error| (address, error))