From f9a62e7d8de906bfdd557c28fbc0ae00d879267f Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Sat, 29 Nov 2025 12:34:06 +0100 Subject: [PATCH] radicle/node: `Address::is_local` for DNS names `Address:is_local` would return `false` for all DNS names. This is incorrect, with one counterexample being the name "localhost", which generally resolves to a local (usually loopback) address. The function is changed to catch "localhost", but also the top level domain ".localhost", which is reserved in RFC 2606, Section 2. `Address::is_routable` would return `true` for all DNS names. While it is much harder to decide global routeability based on a domain name, as these usually have to be resolved to an address before being able to judge routability, there is one particular class of names, namely local ones (see above), which are not globally routable. --- crates/radicle/src/node.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/radicle/src/node.rs b/crates/radicle/src/node.rs index e02fb2c1..63b66c6c 100644 --- a/crates/radicle/src/node.rs +++ b/crates/radicle/src/node.rs @@ -465,8 +465,15 @@ pub struct Address( impl Address { /// Check whether this address is from the local network. pub fn is_local(&self) -> bool { - match self.0.host { - HostName::Ip(ip) => address::is_local(&ip), + match &self.0.host { + HostName::Ip(ip) => address::is_local(ip), + HostName::Dns(name) => { + let name = name.strip_suffix(".").unwrap_or(name); + + // RFC 2606, Section 2 + // + name.ends_with(".localhost") || name == "localhost" + } _ => false, } } @@ -475,6 +482,7 @@ impl Address { pub fn is_routable(&self) -> bool { match self.0.host { HostName::Ip(ip) => address::is_routable(&ip), + HostName::Dns(_) => !self.is_local(), _ => true, } }