From d5de69630cf544fd048c8376e1b51cd0e4e7c7fc Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 1 Nov 2026 13:23:21 +0100 Subject: libp2p: public means global routable --- src/transport/libp2p/book.rs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'src/transport/libp2p/book.rs') diff --git a/src/transport/libp2p/book.rs b/src/transport/libp2p/book.rs index 02a6b49..c2296d3 100644 --- a/src/transport/libp2p/book.rs +++ b/src/transport/libp2p/book.rs @@ -611,24 +611,38 @@ pub(super) fn ip_of(address: &Multiaddr) -> Option { } } -/// Whether `ip` can be reached from the internet, as far as its range tells. +/// Whether `ip` can be reached from the internet, as far as its range tells. For IPv6, +/// only global unicast (`2000::/3`) is: other ranges in use are an overlay's +/// (Mycelium's `400::/7`), a translator's (`64:ff9b::/96`) or local, and, ranked as +/// public, would be preferred over the LAN (`preference`). pub(super) fn is_public(ip: std::net::IpAddr) -> bool { use std::net::IpAddr; match ip { IpAddr::V4(ip) => { + let [a, b, c, _] = ip.octets(); // 100.64.0.0/10: carrier-grade NAT. - let shared = ip.octets()[0] == 100 && (ip.octets()[1] & 0xc0) == 64; + let shared = a == 100 && (b & 0xc0) == 64; + // 198.18.0.0/15: benchmarking; 240.0.0.0/4: reserved (and broadcast). + let benchmarking = a == 198 && (b & 0xfe) == 18; + let reserved = a >= 240; + // 192.0.0.0/24: protocol assignments. + let protocol = a == 192 && b == 0 && c == 0; !(ip.is_private() || ip.is_loopback() || ip.is_link_local() || ip.is_unspecified() - || shared) + || ip.is_documentation() + || ip.is_multicast() + || shared + || benchmarking + || reserved + || protocol) } IpAddr::V6(ip) => { - !(ip.is_loopback() - || ip.is_unspecified() - || ip.is_unique_local() - || ip.is_unicast_link_local()) + let [first, second, ..] = ip.segments(); + // 2001:db8::/32: documentation. + let documentation = first == 0x2001 && second == 0x0db8; + (first & 0xe000) == 0x2000 && !documentation } } } -- cgit v1.3.1