diff --git a/radicle-node/Cargo.toml b/radicle-node/Cargo.toml index 15add4a8..506b995d 100644 --- a/radicle-node/Cargo.toml +++ b/radicle-node/Cargo.toml @@ -19,7 +19,7 @@ byteorder = { version = "1" } chrono = { version = "0.4.0", default-features = false, features = ["clock"] } colored = { version = "2.1.0" } crossbeam-channel = { version = "0.5.6" } -cyphernet = { version = "0.5.0", features = ["tor", "dns", "ed25519", "p2p-ed25519"] } +cyphernet = { version = "0.5.2", features = ["tor", "dns", "ed25519", "p2p-ed25519"] } fastrand = { version = "2.0.0" } gix-protocol = { version = "0.41.1", features = ["blocking-client"] } io-reactor = { version = "0.5.1", features = ["popol"] } diff --git a/radicle-node/src/wire/protocol.rs b/radicle-node/src/wire/protocol.rs index 5786dfc2..aed6a4a5 100644 --- a/radicle-node/src/wire/protocol.rs +++ b/radicle-node/src/wire/protocol.rs @@ -1126,21 +1126,29 @@ pub fn dial>( signer: G, config: &service::Config, ) -> io::Result> { - let inet_addr: NetAddr = match &remote_addr.host { - HostName::Ip(ip) => NetAddr::new(InetHost::Ip(*ip), remote_addr.port), - HostName::Dns(dns) => NetAddr::new(InetHost::Dns(dns.clone()), remote_addr.port), - HostName::Tor(onion) => match config.onion { - // In Tor proxy mode, simply specify the proxy address. + // Determine what address to establish a TCP connection with, given the remote peer + // address and our node configuration. + let inet_addr: NetAddr = match (&remote_addr.host, config.proxy) { + // For IP and DNS addresses, use the global proxy if set, otherwise use the address as-is. + (HostName::Ip(_), Some(proxy)) => proxy.into(), + (HostName::Ip(ip), None) => NetAddr::new(InetHost::Ip(*ip), remote_addr.port), + (HostName::Dns(_), Some(proxy)) => proxy.into(), + (HostName::Dns(dns), None) => NetAddr::new(InetHost::Dns(dns.clone()), remote_addr.port), + // For onion addresses, handle with care. + (HostName::Tor(onion), proxy) => match config.onion { + // In onion proxy mode, simply use the configured proxy address. + // This takes precedence over any global proxy. Some(AddressConfig::Proxy { address }) => address.into(), // In "forward" mode, if a global proxy is set, we use that, otherwise // we treat `.onion` addresses as regular DNS names. Some(AddressConfig::Forward) => { - if let Some(proxy) = config.proxy { + if let Some(proxy) = proxy { proxy.into() } else { NetAddr::new(InetHost::Dns(onion.to_string()), remote_addr.port) } } + // If onion address support isn't configured, refuse to connect. None => { return Err(io::Error::new( io::ErrorKind::Unsupported, @@ -1152,14 +1160,14 @@ pub fn dial>( return Err(io::Error::new( io::ErrorKind::Unsupported, "unsupported remote address type", - )) + )); } }; - // Whether to tunnel regular connections through the proxy. - let force_proxy = config.proxy.is_some(); // Nb. This timeout is currently not used by the underlying library due to the // `socket2` library not supporting non-blocking connect with timeout. let connection = net::TcpStream::connect_nonblocking(inet_addr, DEFAULT_DIAL_TIMEOUT)?; + // Whether to tunnel regular connections through the proxy. + let force_proxy = config.proxy.is_some(); session::( remote_addr,