Merge bitcoin/bitcoin#27071: Handle CJDNS from LookupSubNet()

0e6f6ebc06 net: remove unused CConnman::FindNode(const CSubNet&) (Vasil Dimov)
9482cb780f netbase: possibly change the result of LookupSubNet() to CJDNS (Vasil Dimov)
53afa68026 net: move MaybeFlipIPv6toCJDNS() from net to netbase (Vasil Dimov)
6e308651c4 net: move IsReachable() code to netbase and encapsulate it (Vasil Dimov)
c42ded3d9b fuzz: ConsumeNetAddr(): avoid IPv6 addresses that look like CJDNS (Vasil Dimov)
64d6f77907 net: put CJDNS prefix byte in a constant (Vasil Dimov)

Pull request description:

  `LookupSubNet()` would treat addresses that start with `fc` as IPv6 even if `-cjdnsreachable` is set. This creates the following problems where it is called:

  * `NetWhitelistPermissions::TryParse()`: otherwise `-whitelist=` fails to white list CJDNS addresses: when a CJDNS peer connects to us, it will be matched against IPv6 `fc...` subnet and the match will never succeed.

  * `BanMapFromJson()`: CJDNS bans are stored as just IPv6 addresses in `banlist.json`. Upon reading from disk they have to be converted back to CJDNS, otherwise, after restart, a ban entry like (`fc00::1`, IPv6) would not match a peer (`fc00::1`, CJDNS).

  * `RPCConsole::unbanSelectedNode()`: in the GUI the ban entries go through `CSubNet::ToString()` and back via `LookupSubNet()`. Then it must match whatever is stored in `BanMan`, otherwise it is impossible to unban via the GUI.

  These were uncovered by https://github.com/bitcoin/bitcoin/pull/26859.

  Thus, flip the result of `LookupSubNet()` to CJDNS if the network base address starts with `fc` and `-cjdnsreachable` is set. Since subnetting/masking does not make sense for CJDNS (the address is "random" bytes, like Tor and I2P, there is no hierarchy) treat `fc.../mask` as an invalid `CSubNet`.

  To achieve that, `MaybeFlipIPv6toCJDNS()` has to be moved from `net` to `netbase` and thus also `IsReachable()`. In the process of moving `IsReachable()`, `SetReachable()` and `vfLimited[]` encapsulate those in a class.

ACKs for top commit:
  jonatack:
    Code review ACK 0e6f6ebc06
  achow101:
    ACK 0e6f6ebc06
  mzumsande:
    re-ACK 0e6f6ebc06

Tree-SHA512: 4767a60dc882916de4c8b110ce8de208ff3f58daaa0b560e6547d72e604d07c4157e72cf98b237228310fc05c0a3922f446674492e2ba02e990a272d288bd566
This commit is contained in:
Andrew Chow
2023-10-19 12:41:44 -04:00
13 changed files with 162 additions and 133 deletions

View File

@@ -718,47 +718,55 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
{
BOOST_CHECK(IsReachable(NET_IPV4));
BOOST_CHECK(IsReachable(NET_IPV6));
BOOST_CHECK(IsReachable(NET_ONION));
BOOST_CHECK(IsReachable(NET_I2P));
BOOST_CHECK(IsReachable(NET_CJDNS));
BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));
BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));
BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));
BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));
BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));
SetReachable(NET_IPV4, false);
SetReachable(NET_IPV6, false);
SetReachable(NET_ONION, false);
SetReachable(NET_I2P, false);
SetReachable(NET_CJDNS, false);
g_reachable_nets.Remove(NET_IPV4);
g_reachable_nets.Remove(NET_IPV6);
g_reachable_nets.Remove(NET_ONION);
g_reachable_nets.Remove(NET_I2P);
g_reachable_nets.Remove(NET_CJDNS);
BOOST_CHECK(!IsReachable(NET_IPV4));
BOOST_CHECK(!IsReachable(NET_IPV6));
BOOST_CHECK(!IsReachable(NET_ONION));
BOOST_CHECK(!IsReachable(NET_I2P));
BOOST_CHECK(!IsReachable(NET_CJDNS));
BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV4));
BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV6));
BOOST_CHECK(!g_reachable_nets.Contains(NET_ONION));
BOOST_CHECK(!g_reachable_nets.Contains(NET_I2P));
BOOST_CHECK(!g_reachable_nets.Contains(NET_CJDNS));
SetReachable(NET_IPV4, true);
SetReachable(NET_IPV6, true);
SetReachable(NET_ONION, true);
SetReachable(NET_I2P, true);
SetReachable(NET_CJDNS, true);
g_reachable_nets.Add(NET_IPV4);
g_reachable_nets.Add(NET_IPV6);
g_reachable_nets.Add(NET_ONION);
g_reachable_nets.Add(NET_I2P);
g_reachable_nets.Add(NET_CJDNS);
BOOST_CHECK(IsReachable(NET_IPV4));
BOOST_CHECK(IsReachable(NET_IPV6));
BOOST_CHECK(IsReachable(NET_ONION));
BOOST_CHECK(IsReachable(NET_I2P));
BOOST_CHECK(IsReachable(NET_CJDNS));
BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));
BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));
BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));
BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));
BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));
}
BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
{
BOOST_CHECK(IsReachable(NET_UNROUTABLE));
BOOST_CHECK(IsReachable(NET_INTERNAL));
// Should be reachable by default.
BOOST_CHECK(g_reachable_nets.Contains(NET_UNROUTABLE));
BOOST_CHECK(g_reachable_nets.Contains(NET_INTERNAL));
SetReachable(NET_UNROUTABLE, false);
SetReachable(NET_INTERNAL, false);
g_reachable_nets.RemoveAll();
BOOST_CHECK(IsReachable(NET_UNROUTABLE)); // Ignored for both networks
BOOST_CHECK(IsReachable(NET_INTERNAL));
BOOST_CHECK(!g_reachable_nets.Contains(NET_UNROUTABLE));
BOOST_CHECK(!g_reachable_nets.Contains(NET_INTERNAL));
g_reachable_nets.Add(NET_IPV4);
g_reachable_nets.Add(NET_IPV6);
g_reachable_nets.Add(NET_ONION);
g_reachable_nets.Add(NET_I2P);
g_reachable_nets.Add(NET_CJDNS);
g_reachable_nets.Add(NET_UNROUTABLE);
g_reachable_nets.Add(NET_INTERNAL);
}
CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
@@ -776,13 +784,13 @@ BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
{
CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
SetReachable(NET_IPV4, true);
BOOST_CHECK(IsReachable(addr));
g_reachable_nets.Add(NET_IPV4);
BOOST_CHECK(g_reachable_nets.Contains(addr));
SetReachable(NET_IPV4, false);
BOOST_CHECK(!IsReachable(addr));
g_reachable_nets.Remove(NET_IPV4);
BOOST_CHECK(!g_reachable_nets.Contains(addr));
SetReachable(NET_IPV4, true); // have to reset this, because this is stateful.
g_reachable_nets.Add(NET_IPV4); // have to reset this, because this is stateful.
}
@@ -790,7 +798,7 @@ BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
{
CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
SetReachable(NET_IPV4, true);
g_reachable_nets.Add(NET_IPV4);
BOOST_CHECK(!IsLocal(addr));
BOOST_CHECK(AddLocal(addr, 1000));
@@ -915,7 +923,7 @@ BOOST_AUTO_TEST_CASE(advertise_local_address)
ConnectionType::OUTBOUND_FULL_RELAY,
/*inbound_onion=*/false);
};
SetReachable(NET_CJDNS, true);
g_reachable_nets.Add(NET_CJDNS);
CAddress addr_ipv4{Lookup("1.2.3.4", 8333, false).value(), NODE_NONE};
BOOST_REQUIRE(addr_ipv4.IsValid());