From c7133173dfafda65eb6f9e849f6f3d5d7febf216 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Fri, 31 Jul 2026 13:25:33 +0800 Subject: [PATCH 1/2] addrmgr: Fix incorrect fail msg on TestIPTypes. --- addrmgr/network_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 970f3c9945..79a3f978c9 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2025 The Decred developers +// Copyright (c) 2015-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -125,7 +125,7 @@ func TestIPTypes(t *testing.T) { } if rv := isRFC6145(test.ip); rv != test.rfc6145 { - t.Errorf("isRFC1918 %s\n got: %v want: %v", test.ip, rv, test.rfc6145) + t.Errorf("isRFC6145 %s\n got: %v want: %v", test.ip, rv, test.rfc6145) } if rv := isLocal(test.ip); rv != test.local { From 69fb1bdcf56365c240d82550f7f4a7e80c52b665 Mon Sep 17 00:00:00 2001 From: jholdstock Date: Fri, 31 Jul 2026 13:38:26 +0800 Subject: [PATCH 2/2] addrmgr: Treat ORCHIDv2 addresses as unroutable. Add detection and filtering of IPv6 ORCHIDv2 addresses as defined by RFC7343 (2001:20::/28). These addresses are overlay routable cryptographic hash identifiers and should not be treated as routable peer addresses. --- addrmgr/network.go | 12 +++++++++- addrmgr/network_test.go | 53 ++++++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/addrmgr/network.go b/addrmgr/network.go index 98a99788b8..01b970c0f7 100644 --- a/addrmgr/network.go +++ b/addrmgr/network.go @@ -76,6 +76,10 @@ var ( // rfc6598Net specifies the IPv4 block as defined by RFC6598 (100.64.0.0/10). rfc6598Net = ipNet("100.64.0.0", 10, 32) + // rfc7343Net specifies the IPv6 ORCHIDv2 address block as defined by + // RFC7343 (2001:20::/28). + rfc7343Net = ipNet("2001:20::", 28, 128) + // zero4Net defines the IPv4 address block for address staring with 0 // (0.0.0.0/8). zero4Net = ipNet("0.0.0.0", 8, 32) @@ -213,6 +217,12 @@ func isRFC6598(netIP net.IP) bool { return rfc6598Net.Contains(netIP) } +// isRFC7343 returns whether or not the passed address is part of the IPv6 +// ORCHIDv2 range as defined by RFC7343 (2001:20::/28). +func isRFC7343(netIP net.IP) bool { + return rfc7343Net.Contains(netIP) +} + // calcTorV3Checksum returns the checksum bytes given a 32-byte TorV3 public // key. func calcTorV3Checksum(publicKey [32]byte) [2]byte { @@ -276,7 +286,7 @@ func IsRoutable(netIP net.IP) bool { return isValid(netIP) && !(isRFC1918(netIP) || isRFC2544(netIP) || isRFC3927(netIP) || isRFC4862(netIP) || isRFC3849(netIP) || isRFC4843(netIP) || isRFC5737(netIP) || isRFC6598(netIP) || - isLocal(netIP) || isRFC4193(netIP)) + isRFC7343(netIP) || isLocal(netIP) || isRFC4193(netIP)) } // GroupKey returns a string representing the network group an address is part diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index 79a3f978c9..04dc1b781e 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -31,6 +31,7 @@ func TestIPTypes(t *testing.T) { rfc6052 bool rfc6145 bool rfc6598 bool + rfc7343 bool local bool valid bool routable bool @@ -38,52 +39,55 @@ func TestIPTypes(t *testing.T) { newIPTest := func(ip string, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, - local, valid, routable bool) ipTest { + rfc7343, local, valid, routable bool) ipTest { nip := net.ParseIP(ip) - test := ipTest{nip, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, rfc4193, rfc4380, - rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable} + test := ipTest{nip, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, + rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, + rfc6598, rfc7343, local, valid, routable} return test } tests := []ipTest{ newIPTest("10.255.255.255", true, false, false, false, false, false, - false, false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, false, true, false), newIPTest("192.168.0.1", true, false, false, false, false, false, - false, false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, false, true, false), newIPTest("172.31.255.1", true, false, false, false, false, false, - false, false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, false, true, false), newIPTest("172.32.1.1", false, false, false, false, false, false, false, false, - false, false, false, false, false, false, true, true), + false, false, false, false, false, false, false, true, true), newIPTest("169.254.250.120", false, false, false, true, false, false, - false, false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, false, true, false), newIPTest("0.0.0.0", false, false, false, false, false, false, false, - false, false, false, false, false, false, true, false, false), + false, false, false, false, false, false, false, true, false, false), newIPTest("255.255.255.255", false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false), + false, false, false, false, false, false, false, false, false, false, false), newIPTest("127.0.0.1", false, false, false, false, false, false, - false, false, false, false, false, false, false, true, true, false), + false, false, false, false, false, false, false, false, true, true, false), newIPTest("fd00:dead::1", false, false, false, false, false, true, - false, false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, false, true, false), newIPTest("2001::1", false, false, false, false, false, false, - true, false, false, false, false, false, false, false, true, true), + true, false, false, false, false, false, false, false, false, true, true), newIPTest("2001:10:abcd::1:1", false, false, false, false, false, false, - false, true, false, false, false, false, false, false, true, false), + false, true, false, false, false, false, false, false, false, true, false), + newIPTest("2001:20:abcd::1:1", false, false, false, false, false, false, + false, false, false, false, false, false, false, true, false, true, false), newIPTest("fe80::1", false, false, false, false, false, false, - false, false, true, false, false, false, false, false, true, false), + false, false, true, false, false, false, false, false, false, true, false), newIPTest("fe80:1::1", false, false, false, false, false, false, - false, false, false, false, false, false, false, false, true, true), + false, false, false, false, false, false, false, false, false, true, true), newIPTest("64:ff9b::1", false, false, false, false, false, false, - false, false, false, false, true, false, false, false, true, true), + false, false, false, false, true, false, false, false, false, true, true), newIPTest("::ffff:abcd:ef12:1", false, false, false, false, false, false, - false, false, false, false, false, false, false, false, true, true), + false, false, false, false, false, false, false, false, false, true, true), newIPTest("::1", false, false, false, false, false, false, false, false, - false, false, false, false, false, true, true, false), + false, false, false, false, false, false, true, true, false), newIPTest("198.18.0.1", false, true, false, false, false, false, false, - false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, true, false), newIPTest("100.127.255.1", false, false, false, false, false, false, false, - false, false, false, false, false, true, false, true, false), + false, false, false, false, false, true, false, false, true, false), newIPTest("203.0.113.1", false, false, false, false, false, false, false, - false, false, false, false, false, false, false, true, false), + false, false, false, false, false, false, false, false, true, false), } t.Logf("Running %d tests", len(tests)) @@ -128,6 +132,10 @@ func TestIPTypes(t *testing.T) { t.Errorf("isRFC6145 %s\n got: %v want: %v", test.ip, rv, test.rfc6145) } + if rv := isRFC7343(test.ip); rv != test.rfc7343 { + t.Errorf("isRFC7343 %s\n got: %v want: %v", test.ip, rv, test.rfc7343) + } + if rv := isLocal(test.ip); rv != test.local { t.Errorf("isLocal %s\n got: %v want: %v", test.ip, rv, test.local) } @@ -162,6 +170,7 @@ func TestGroupKey(t *testing.T) { {name: "ipv4 rfc1918 172.16/12", host: "172.16.1.2", expected: "unroutable"}, {name: "ipv4 rfc1918 192.168/16", host: "192.168.1.2", expected: "unroutable"}, {name: "ipv6 rfc3849 2001:db8::/32", host: "2001:db8::1234", expected: "unroutable"}, + {name: "ipv6 rfc7343 2001:20::/28", host: "2001:20::1234", expected: "unroutable"}, {name: "ipv4 rfc3927 169.254/16", host: "169.254.1.2", expected: "unroutable"}, {name: "ipv6 rfc4193 fc00::/7", host: "fc00::1234", expected: "unroutable"}, {name: "ipv6 rfc4843 2001:10::/28", host: "2001:10::1234", expected: "unroutable"},