LCOV - code coverage report
Current view: top level - src/test - net_tests.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 596 598 99.7 %
Date: 2021-06-29 14:35:33 Functions: 19 19 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 2 2 100.0 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2012-2020 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : #include <addrdb.h>
#       6                 :            : #include <addrman.h>
#       7                 :            : #include <chainparams.h>
#       8                 :            : #include <clientversion.h>
#       9                 :            : #include <cstdint>
#      10                 :            : #include <net.h>
#      11                 :            : #include <netaddress.h>
#      12                 :            : #include <netbase.h>
#      13                 :            : #include <serialize.h>
#      14                 :            : #include <span.h>
#      15                 :            : #include <streams.h>
#      16                 :            : #include <test/util/setup_common.h>
#      17                 :            : #include <util/strencodings.h>
#      18                 :            : #include <util/string.h>
#      19                 :            : #include <util/system.h>
#      20                 :            : #include <version.h>
#      21                 :            : 
#      22                 :            : #include <boost/test/unit_test.hpp>
#      23                 :            : 
#      24                 :            : #include <algorithm>
#      25                 :            : #include <ios>
#      26                 :            : #include <memory>
#      27                 :            : #include <optional>
#      28                 :            : #include <string>
#      29                 :            : 
#      30                 :            : using namespace std::literals;
#      31                 :            : 
#      32                 :            : class CAddrManSerializationMock : public CAddrMan
#      33                 :            : {
#      34                 :            : public:
#      35                 :            :     virtual void Serialize(CDataStream& s) const = 0;
#      36                 :            : 
#      37                 :            :     //! Ensure that bucket placement is always the same for testing purposes.
#      38                 :            :     void MakeDeterministic()
#      39                 :          4 :     {
#      40                 :          4 :         nKey.SetNull();
#      41                 :          4 :         insecure_rand = FastRandomContext(true);
#      42                 :          4 :     }
#      43                 :            : };
#      44                 :            : 
#      45                 :            : class CAddrManUncorrupted : public CAddrManSerializationMock
#      46                 :            : {
#      47                 :            : public:
#      48                 :            :     void Serialize(CDataStream& s) const override
#      49                 :          4 :     {
#      50                 :          4 :         CAddrMan::Serialize(s);
#      51                 :          4 :     }
#      52                 :            : };
#      53                 :            : 
#      54                 :            : class CAddrManCorrupted : public CAddrManSerializationMock
#      55                 :            : {
#      56                 :            : public:
#      57                 :            :     void Serialize(CDataStream& s) const override
#      58                 :          4 :     {
#      59                 :            :         // Produces corrupt output that claims addrman has 20 addrs when it only has one addr.
#      60                 :          4 :         unsigned char nVersion = 1;
#      61                 :          4 :         s << nVersion;
#      62                 :          4 :         s << ((unsigned char)32);
#      63                 :          4 :         s << nKey;
#      64                 :          4 :         s << 10; // nNew
#      65                 :          4 :         s << 10; // nTried
#      66                 :            : 
#      67                 :          4 :         int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
#      68                 :          4 :         s << nUBuckets;
#      69                 :            : 
#      70                 :          4 :         CService serv;
#      71                 :          4 :         BOOST_CHECK(Lookup("252.1.1.1", serv, 7777, false));
#      72                 :          4 :         CAddress addr = CAddress(serv, NODE_NONE);
#      73                 :          4 :         CNetAddr resolved;
#      74                 :          4 :         BOOST_CHECK(LookupHost("252.2.2.2", resolved, false));
#      75                 :          4 :         CAddrInfo info = CAddrInfo(addr, resolved);
#      76                 :          4 :         s << info;
#      77                 :          4 :     }
#      78                 :            : };
#      79                 :            : 
#      80                 :            : static CDataStream AddrmanToStream(const CAddrManSerializationMock& _addrman)
#      81                 :          8 : {
#      82                 :          8 :     CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
#      83                 :          8 :     ssPeersIn << Params().MessageStart();
#      84                 :          8 :     ssPeersIn << _addrman;
#      85                 :          8 :     std::string str = ssPeersIn.str();
#      86                 :          8 :     std::vector<unsigned char> vchData(str.begin(), str.end());
#      87                 :          8 :     return CDataStream(vchData, SER_DISK, CLIENT_VERSION);
#      88                 :          8 : }
#      89                 :            : 
#      90                 :            : BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup)
#      91                 :            : 
#      92                 :            : BOOST_AUTO_TEST_CASE(cnode_listen_port)
#      93                 :          2 : {
#      94                 :            :     // test default
#      95                 :          2 :     uint16_t port{GetListenPort()};
#      96                 :          2 :     BOOST_CHECK(port == Params().GetDefaultPort());
#      97                 :            :     // test set port
#      98                 :          2 :     uint16_t altPort = 12345;
#      99                 :          2 :     BOOST_CHECK(gArgs.SoftSetArg("-port", ToString(altPort)));
#     100                 :          2 :     port = GetListenPort();
#     101                 :          2 :     BOOST_CHECK(port == altPort);
#     102                 :          2 : }
#     103                 :            : 
#     104                 :            : BOOST_AUTO_TEST_CASE(caddrdb_read)
#     105                 :          2 : {
#     106                 :          2 :     CAddrManUncorrupted addrmanUncorrupted;
#     107                 :          2 :     addrmanUncorrupted.MakeDeterministic();
#     108                 :            : 
#     109                 :          2 :     CService addr1, addr2, addr3;
#     110                 :          2 :     BOOST_CHECK(Lookup("250.7.1.1", addr1, 8333, false));
#     111                 :          2 :     BOOST_CHECK(Lookup("250.7.2.2", addr2, 9999, false));
#     112                 :          2 :     BOOST_CHECK(Lookup("250.7.3.3", addr3, 9999, false));
#     113                 :          2 :     BOOST_CHECK(Lookup("250.7.3.3"s, addr3, 9999, false));
#     114                 :          2 :     BOOST_CHECK(!Lookup("250.7.3.3\0example.com"s, addr3, 9999, false));
#     115                 :            : 
#     116                 :            :     // Add three addresses to new table.
#     117                 :          2 :     CService source;
#     118                 :          2 :     BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false));
#     119                 :          2 :     BOOST_CHECK(addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), source));
#     120                 :          2 :     BOOST_CHECK(addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), source));
#     121                 :          2 :     BOOST_CHECK(addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), source));
#     122                 :            : 
#     123                 :            :     // Test that the de-serialization does not throw an exception.
#     124                 :          2 :     CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
#     125                 :          2 :     bool exceptionThrown = false;
#     126                 :          2 :     CAddrMan addrman1;
#     127                 :            : 
#     128                 :          2 :     BOOST_CHECK(addrman1.size() == 0);
#     129                 :          2 :     try {
#     130                 :          2 :         unsigned char pchMsgTmp[4];
#     131                 :          2 :         ssPeers1 >> pchMsgTmp;
#     132                 :          2 :         ssPeers1 >> addrman1;
#     133                 :          2 :     } catch (const std::exception&) {
#     134                 :          0 :         exceptionThrown = true;
#     135                 :          0 :     }
#     136                 :            : 
#     137                 :          2 :     BOOST_CHECK(addrman1.size() == 3);
#     138                 :          2 :     BOOST_CHECK(exceptionThrown == false);
#     139                 :            : 
#     140                 :            :     // Test that CAddrDB::Read creates an addrman with the correct number of addrs.
#     141                 :          2 :     CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
#     142                 :            : 
#     143                 :          2 :     CAddrMan addrman2;
#     144                 :          2 :     BOOST_CHECK(addrman2.size() == 0);
#     145                 :          2 :     BOOST_CHECK(CAddrDB::Read(addrman2, ssPeers2));
#     146                 :          2 :     BOOST_CHECK(addrman2.size() == 3);
#     147                 :          2 : }
#     148                 :            : 
#     149                 :            : 
#     150                 :            : BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
#     151                 :          2 : {
#     152                 :          2 :     CAddrManCorrupted addrmanCorrupted;
#     153                 :          2 :     addrmanCorrupted.MakeDeterministic();
#     154                 :            : 
#     155                 :            :     // Test that the de-serialization of corrupted addrman throws an exception.
#     156                 :          2 :     CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted);
#     157                 :          2 :     bool exceptionThrown = false;
#     158                 :          2 :     CAddrMan addrman1;
#     159                 :          2 :     BOOST_CHECK(addrman1.size() == 0);
#     160                 :          2 :     try {
#     161                 :          2 :         unsigned char pchMsgTmp[4];
#     162                 :          2 :         ssPeers1 >> pchMsgTmp;
#     163                 :          2 :         ssPeers1 >> addrman1;
#     164                 :          2 :     } catch (const std::exception&) {
#     165                 :          2 :         exceptionThrown = true;
#     166                 :          2 :     }
#     167                 :            :     // Even through de-serialization failed addrman is not left in a clean state.
#     168                 :          2 :     BOOST_CHECK(addrman1.size() == 1);
#     169                 :          2 :     BOOST_CHECK(exceptionThrown);
#     170                 :            : 
#     171                 :            :     // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails.
#     172                 :          2 :     CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted);
#     173                 :            : 
#     174                 :          2 :     CAddrMan addrman2;
#     175                 :          2 :     BOOST_CHECK(addrman2.size() == 0);
#     176                 :          2 :     BOOST_CHECK(!CAddrDB::Read(addrman2, ssPeers2));
#     177                 :          2 :     BOOST_CHECK(addrman2.size() == 0);
#     178                 :          2 : }
#     179                 :            : 
#     180                 :            : BOOST_AUTO_TEST_CASE(cnode_simple_test)
#     181                 :          2 : {
#     182                 :          2 :     SOCKET hSocket = INVALID_SOCKET;
#     183                 :          2 :     NodeId id = 0;
#     184                 :            : 
#     185                 :          2 :     in_addr ipv4Addr;
#     186                 :          2 :     ipv4Addr.s_addr = 0xa0b0c001;
#     187                 :            : 
#     188                 :          2 :     CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
#     189                 :          2 :     std::string pszDest;
#     190                 :            : 
#     191                 :          2 :     std::unique_ptr<CNode> pnode1 = std::make_unique<CNode>(
#     192                 :          2 :         id++, NODE_NETWORK, hSocket, addr,
#     193                 :          2 :         /* nKeyedNetGroupIn = */ 0,
#     194                 :          2 :         /* nLocalHostNonceIn = */ 0,
#     195                 :          2 :         CAddress(), pszDest, ConnectionType::OUTBOUND_FULL_RELAY,
#     196                 :          2 :         /* inbound_onion = */ false);
#     197                 :          2 :     BOOST_CHECK(pnode1->IsFullOutboundConn() == true);
#     198                 :          2 :     BOOST_CHECK(pnode1->IsManualConn() == false);
#     199                 :          2 :     BOOST_CHECK(pnode1->IsBlockOnlyConn() == false);
#     200                 :          2 :     BOOST_CHECK(pnode1->IsFeelerConn() == false);
#     201                 :          2 :     BOOST_CHECK(pnode1->IsAddrFetchConn() == false);
#     202                 :          2 :     BOOST_CHECK(pnode1->IsInboundConn() == false);
#     203                 :          2 :     BOOST_CHECK(pnode1->m_inbound_onion == false);
#     204                 :          2 :     BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4);
#     205                 :            : 
#     206                 :          2 :     std::unique_ptr<CNode> pnode2 = std::make_unique<CNode>(
#     207                 :          2 :         id++, NODE_NETWORK, hSocket, addr,
#     208                 :          2 :         /* nKeyedNetGroupIn = */ 1,
#     209                 :          2 :         /* nLocalHostNonceIn = */ 1,
#     210                 :          2 :         CAddress(), pszDest, ConnectionType::INBOUND,
#     211                 :          2 :         /* inbound_onion = */ false);
#     212                 :          2 :     BOOST_CHECK(pnode2->IsFullOutboundConn() == false);
#     213                 :          2 :     BOOST_CHECK(pnode2->IsManualConn() == false);
#     214                 :          2 :     BOOST_CHECK(pnode2->IsBlockOnlyConn() == false);
#     215                 :          2 :     BOOST_CHECK(pnode2->IsFeelerConn() == false);
#     216                 :          2 :     BOOST_CHECK(pnode2->IsAddrFetchConn() == false);
#     217                 :          2 :     BOOST_CHECK(pnode2->IsInboundConn() == true);
#     218                 :          2 :     BOOST_CHECK(pnode2->m_inbound_onion == false);
#     219                 :          2 :     BOOST_CHECK_EQUAL(pnode2->ConnectedThroughNetwork(), Network::NET_IPV4);
#     220                 :            : 
#     221                 :          2 :     std::unique_ptr<CNode> pnode3 = std::make_unique<CNode>(
#     222                 :          2 :         id++, NODE_NETWORK, hSocket, addr,
#     223                 :          2 :         /* nKeyedNetGroupIn = */ 0,
#     224                 :          2 :         /* nLocalHostNonceIn = */ 0,
#     225                 :          2 :         CAddress(), pszDest, ConnectionType::OUTBOUND_FULL_RELAY,
#     226                 :          2 :         /* inbound_onion = */ false);
#     227                 :          2 :     BOOST_CHECK(pnode3->IsFullOutboundConn() == true);
#     228                 :          2 :     BOOST_CHECK(pnode3->IsManualConn() == false);
#     229                 :          2 :     BOOST_CHECK(pnode3->IsBlockOnlyConn() == false);
#     230                 :          2 :     BOOST_CHECK(pnode3->IsFeelerConn() == false);
#     231                 :          2 :     BOOST_CHECK(pnode3->IsAddrFetchConn() == false);
#     232                 :          2 :     BOOST_CHECK(pnode3->IsInboundConn() == false);
#     233                 :          2 :     BOOST_CHECK(pnode3->m_inbound_onion == false);
#     234                 :          2 :     BOOST_CHECK_EQUAL(pnode3->ConnectedThroughNetwork(), Network::NET_IPV4);
#     235                 :            : 
#     236                 :          2 :     std::unique_ptr<CNode> pnode4 = std::make_unique<CNode>(
#     237                 :          2 :         id++, NODE_NETWORK, hSocket, addr,
#     238                 :          2 :         /* nKeyedNetGroupIn = */ 1,
#     239                 :          2 :         /* nLocalHostNonceIn = */ 1,
#     240                 :          2 :         CAddress(), pszDest, ConnectionType::INBOUND,
#     241                 :          2 :         /* inbound_onion = */ true);
#     242                 :          2 :     BOOST_CHECK(pnode4->IsFullOutboundConn() == false);
#     243                 :          2 :     BOOST_CHECK(pnode4->IsManualConn() == false);
#     244                 :          2 :     BOOST_CHECK(pnode4->IsBlockOnlyConn() == false);
#     245                 :          2 :     BOOST_CHECK(pnode4->IsFeelerConn() == false);
#     246                 :          2 :     BOOST_CHECK(pnode4->IsAddrFetchConn() == false);
#     247                 :          2 :     BOOST_CHECK(pnode4->IsInboundConn() == true);
#     248                 :          2 :     BOOST_CHECK(pnode4->m_inbound_onion == true);
#     249                 :          2 :     BOOST_CHECK_EQUAL(pnode4->ConnectedThroughNetwork(), Network::NET_ONION);
#     250                 :          2 : }
#     251                 :            : 
#     252                 :            : BOOST_AUTO_TEST_CASE(cnetaddr_basic)
#     253                 :          2 : {
#     254                 :          2 :     CNetAddr addr;
#     255                 :            : 
#     256                 :            :     // IPv4, INADDR_ANY
#     257                 :          2 :     BOOST_REQUIRE(LookupHost("0.0.0.0", addr, false));
#     258                 :          2 :     BOOST_REQUIRE(!addr.IsValid());
#     259                 :          2 :     BOOST_REQUIRE(addr.IsIPv4());
#     260                 :            : 
#     261                 :          2 :     BOOST_CHECK(addr.IsBindAny());
#     262                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     263                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "0.0.0.0");
#     264                 :            : 
#     265                 :            :     // IPv4, INADDR_NONE
#     266                 :          2 :     BOOST_REQUIRE(LookupHost("255.255.255.255", addr, false));
#     267                 :          2 :     BOOST_REQUIRE(!addr.IsValid());
#     268                 :          2 :     BOOST_REQUIRE(addr.IsIPv4());
#     269                 :            : 
#     270                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     271                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     272                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "255.255.255.255");
#     273                 :            : 
#     274                 :            :     // IPv4, casual
#     275                 :          2 :     BOOST_REQUIRE(LookupHost("12.34.56.78", addr, false));
#     276                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     277                 :          2 :     BOOST_REQUIRE(addr.IsIPv4());
#     278                 :            : 
#     279                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     280                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     281                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "12.34.56.78");
#     282                 :            : 
#     283                 :            :     // IPv6, in6addr_any
#     284                 :          2 :     BOOST_REQUIRE(LookupHost("::", addr, false));
#     285                 :          2 :     BOOST_REQUIRE(!addr.IsValid());
#     286                 :          2 :     BOOST_REQUIRE(addr.IsIPv6());
#     287                 :            : 
#     288                 :          2 :     BOOST_CHECK(addr.IsBindAny());
#     289                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     290                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "::");
#     291                 :            : 
#     292                 :            :     // IPv6, casual
#     293                 :          2 :     BOOST_REQUIRE(LookupHost("1122:3344:5566:7788:9900:aabb:ccdd:eeff", addr, false));
#     294                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     295                 :          2 :     BOOST_REQUIRE(addr.IsIPv6());
#     296                 :            : 
#     297                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     298                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     299                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "1122:3344:5566:7788:9900:aabb:ccdd:eeff");
#     300                 :            : 
#     301                 :            :     // IPv6, scoped/link-local. See https://tools.ietf.org/html/rfc4007
#     302                 :            :     // We support non-negative decimal integers (uint32_t) as zone id indices.
#     303                 :            :     // Normal link-local scoped address functionality is to append "%" plus the
#     304                 :            :     // zone id, for example, given a link-local address of "fe80::1" and a zone
#     305                 :            :     // id of "32", return the address as "fe80::1%32".
#     306                 :          2 :     const std::string link_local{"fe80::1"};
#     307                 :          2 :     const std::string scoped_addr{link_local + "%32"};
#     308                 :          2 :     BOOST_REQUIRE(LookupHost(scoped_addr, addr, false));
#     309                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     310                 :          2 :     BOOST_REQUIRE(addr.IsIPv6());
#     311                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     312                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), scoped_addr);
#     313                 :            : 
#     314                 :            :     // Test that the delimiter "%" and default zone id of 0 can be omitted for the default scope.
#     315                 :          2 :     BOOST_REQUIRE(LookupHost(link_local + "%0", addr, false));
#     316                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     317                 :          2 :     BOOST_REQUIRE(addr.IsIPv6());
#     318                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     319                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), link_local);
#     320                 :            : 
#     321                 :            :     // TORv2
#     322                 :          2 :     BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion"));
#     323                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     324                 :          2 :     BOOST_REQUIRE(addr.IsTor());
#     325                 :            : 
#     326                 :          2 :     BOOST_CHECK(!addr.IsI2P());
#     327                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     328                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     329                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion");
#     330                 :            : 
#     331                 :            :     // TORv3
#     332                 :          2 :     const char* torv3_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";
#     333                 :          2 :     BOOST_REQUIRE(addr.SetSpecial(torv3_addr));
#     334                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     335                 :          2 :     BOOST_REQUIRE(addr.IsTor());
#     336                 :            : 
#     337                 :          2 :     BOOST_CHECK(!addr.IsI2P());
#     338                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     339                 :          2 :     BOOST_CHECK(!addr.IsAddrV1Compatible());
#     340                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), torv3_addr);
#     341                 :            : 
#     342                 :            :     // TORv3, broken, with wrong checksum
#     343                 :          2 :     BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.onion"));
#     344                 :            : 
#     345                 :            :     // TORv3, broken, with wrong version
#     346                 :          2 :     BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrye.onion"));
#     347                 :            : 
#     348                 :            :     // TORv3, malicious
#     349                 :          2 :     BOOST_CHECK(!addr.SetSpecial(std::string{
#     350                 :          2 :         "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd\0wtf.onion", 66}));
#     351                 :            : 
#     352                 :            :     // TOR, bogus length
#     353                 :          2 :     BOOST_CHECK(!addr.SetSpecial(std::string{"mfrggzak.onion"}));
#     354                 :            : 
#     355                 :            :     // TOR, invalid base32
#     356                 :          2 :     BOOST_CHECK(!addr.SetSpecial(std::string{"mf*g zak.onion"}));
#     357                 :            : 
#     358                 :            :     // I2P
#     359                 :          2 :     const char* i2p_addr = "UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P";
#     360                 :          2 :     BOOST_REQUIRE(addr.SetSpecial(i2p_addr));
#     361                 :          2 :     BOOST_REQUIRE(addr.IsValid());
#     362                 :          2 :     BOOST_REQUIRE(addr.IsI2P());
#     363                 :            : 
#     364                 :          2 :     BOOST_CHECK(!addr.IsTor());
#     365                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     366                 :          2 :     BOOST_CHECK(!addr.IsAddrV1Compatible());
#     367                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), ToLower(i2p_addr));
#     368                 :            : 
#     369                 :            :     // I2P, correct length, but decodes to less than the expected number of bytes.
#     370                 :          2 :     BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jn=.b32.i2p"));
#     371                 :            : 
#     372                 :            :     // I2P, extra unnecessary padding
#     373                 :          2 :     BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna=.b32.i2p"));
#     374                 :            : 
#     375                 :            :     // I2P, malicious
#     376                 :          2 :     BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v\0wtf.b32.i2p"s));
#     377                 :            : 
#     378                 :            :     // I2P, valid but unsupported (56 Base32 characters)
#     379                 :            :     // See "Encrypted LS with Base 32 Addresses" in
#     380                 :            :     // https://geti2p.net/spec/encryptedleaseset.txt
#     381                 :          2 :     BOOST_CHECK(
#     382                 :          2 :         !addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.b32.i2p"));
#     383                 :            : 
#     384                 :            :     // I2P, invalid base32
#     385                 :          2 :     BOOST_CHECK(!addr.SetSpecial(std::string{"tp*szydbh4dp.b32.i2p"}));
#     386                 :            : 
#     387                 :            :     // Internal
#     388                 :          2 :     addr.SetInternal("esffpp");
#     389                 :          2 :     BOOST_REQUIRE(!addr.IsValid()); // "internal" is considered invalid
#     390                 :          2 :     BOOST_REQUIRE(addr.IsInternal());
#     391                 :            : 
#     392                 :          2 :     BOOST_CHECK(!addr.IsBindAny());
#     393                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     394                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "esffpvrt3wpeaygy.internal");
#     395                 :            : 
#     396                 :            :     // Totally bogus
#     397                 :          2 :     BOOST_CHECK(!addr.SetSpecial("totally bogus"));
#     398                 :          2 : }
#     399                 :            : 
#     400                 :            : BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6)
#     401                 :          2 : {
#     402                 :            :     // Test that CNetAddr::ToString formats IPv6 addresses with zero compression as described in
#     403                 :            :     // RFC 5952 ("A Recommendation for IPv6 Address Text Representation").
#     404                 :          2 :     const std::map<std::string, std::string> canonical_representations_ipv6{
#     405                 :          2 :         {"0000:0000:0000:0000:0000:0000:0000:0000", "::"},
#     406                 :          2 :         {"000:0000:000:00:0:00:000:0000", "::"},
#     407                 :          2 :         {"000:000:000:000:000:000:000:000", "::"},
#     408                 :          2 :         {"00:00:00:00:00:00:00:00", "::"},
#     409                 :          2 :         {"0:0:0:0:0:0:0:0", "::"},
#     410                 :          2 :         {"0:0:0:0:0:0:0:1", "::1"},
#     411                 :          2 :         {"2001:0:0:1:0:0:0:1", "2001:0:0:1::1"},
#     412                 :          2 :         {"2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"},
#     413                 :          2 :         {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:db8:85a3::8a2e:370:7334"},
#     414                 :          2 :         {"2001:0db8::0001", "2001:db8::1"},
#     415                 :          2 :         {"2001:0db8::0001:0000", "2001:db8::1:0"},
#     416                 :          2 :         {"2001:0db8::1:0:0:1", "2001:db8::1:0:0:1"},
#     417                 :          2 :         {"2001:db8:0000:0:1::1", "2001:db8::1:0:0:1"},
#     418                 :          2 :         {"2001:db8:0000:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
#     419                 :          2 :         {"2001:db8:0:0:0:0:2:1", "2001:db8::2:1"},
#     420                 :          2 :         {"2001:db8:0:0:0::1", "2001:db8::1"},
#     421                 :          2 :         {"2001:db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"},
#     422                 :          2 :         {"2001:db8:0:0:1::1", "2001:db8::1:0:0:1"},
#     423                 :          2 :         {"2001:DB8:0:0:1::1", "2001:db8::1:0:0:1"},
#     424                 :          2 :         {"2001:db8:0:0::1", "2001:db8::1"},
#     425                 :          2 :         {"2001:db8:0:0:aaaa::1", "2001:db8::aaaa:0:0:1"},
#     426                 :          2 :         {"2001:db8:0:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
#     427                 :          2 :         {"2001:db8:0::1", "2001:db8::1"},
#     428                 :          2 :         {"2001:db8:85a3:0:0:8a2e:370:7334", "2001:db8:85a3::8a2e:370:7334"},
#     429                 :          2 :         {"2001:db8::0:1", "2001:db8::1"},
#     430                 :          2 :         {"2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1"},
#     431                 :          2 :         {"2001:DB8::1", "2001:db8::1"},
#     432                 :          2 :         {"2001:db8::1", "2001:db8::1"},
#     433                 :          2 :         {"2001:db8::1:0:0:1", "2001:db8::1:0:0:1"},
#     434                 :          2 :         {"2001:db8::1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
#     435                 :          2 :         {"2001:db8::aaaa:0:0:1", "2001:db8::aaaa:0:0:1"},
#     436                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:0:1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"},
#     437                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd::1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"},
#     438                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
#     439                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
#     440                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:01", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
#     441                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
#     442                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
#     443                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
#     444                 :          2 :         {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
#     445                 :          2 :     };
#     446         [ +  + ]:         80 :     for (const auto& [input_address, expected_canonical_representation_output] : canonical_representations_ipv6) {
#     447                 :         80 :         CNetAddr net_addr;
#     448                 :         80 :         BOOST_REQUIRE(LookupHost(input_address, net_addr, false));
#     449                 :         80 :         BOOST_REQUIRE(net_addr.IsIPv6());
#     450                 :         80 :         BOOST_CHECK_EQUAL(net_addr.ToString(), expected_canonical_representation_output);
#     451                 :         80 :     }
#     452                 :          2 : }
#     453                 :            : 
#     454                 :            : BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
#     455                 :          2 : {
#     456                 :          2 :     CNetAddr addr;
#     457                 :          2 :     CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
#     458                 :            : 
#     459                 :          2 :     s << addr;
#     460                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
#     461                 :          2 :     s.clear();
#     462                 :            : 
#     463                 :          2 :     BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false));
#     464                 :          2 :     s << addr;
#     465                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
#     466                 :          2 :     s.clear();
#     467                 :            : 
#     468                 :          2 :     BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false));
#     469                 :          2 :     s << addr;
#     470                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
#     471                 :          2 :     s.clear();
#     472                 :            : 
#     473                 :          2 :     BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion"));
#     474                 :          2 :     s << addr;
#     475                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "fd87d87eeb43f1f2f3f4f5f6f7f8f9fa");
#     476                 :          2 :     s.clear();
#     477                 :            : 
#     478                 :          2 :     BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
#     479                 :          2 :     s << addr;
#     480                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
#     481                 :          2 :     s.clear();
#     482                 :            : 
#     483                 :          2 :     addr.SetInternal("a");
#     484                 :          2 :     s << addr;
#     485                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
#     486                 :          2 :     s.clear();
#     487                 :          2 : }
#     488                 :            : 
#     489                 :            : BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
#     490                 :          2 : {
#     491                 :          2 :     CNetAddr addr;
#     492                 :          2 :     CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
#     493                 :            :     // Add ADDRV2_FORMAT to the version so that the CNetAddr
#     494                 :            :     // serialize method produces an address in v2 format.
#     495                 :          2 :     s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
#     496                 :            : 
#     497                 :          2 :     s << addr;
#     498                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
#     499                 :          2 :     s.clear();
#     500                 :            : 
#     501                 :          2 :     BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false));
#     502                 :          2 :     s << addr;
#     503                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
#     504                 :          2 :     s.clear();
#     505                 :            : 
#     506                 :          2 :     BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false));
#     507                 :          2 :     s << addr;
#     508                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
#     509                 :          2 :     s.clear();
#     510                 :            : 
#     511                 :          2 :     BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion"));
#     512                 :          2 :     s << addr;
#     513                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "030af1f2f3f4f5f6f7f8f9fa");
#     514                 :          2 :     s.clear();
#     515                 :            : 
#     516                 :          2 :     BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
#     517                 :          2 :     s << addr;
#     518                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
#     519                 :          2 :     s.clear();
#     520                 :            : 
#     521                 :          2 :     BOOST_REQUIRE(addr.SetInternal("a"));
#     522                 :          2 :     s << addr;
#     523                 :          2 :     BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
#     524                 :          2 :     s.clear();
#     525                 :          2 : }
#     526                 :            : 
#     527                 :            : BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
#     528                 :          2 : {
#     529                 :          2 :     CNetAddr addr;
#     530                 :          2 :     CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
#     531                 :            :     // Add ADDRV2_FORMAT to the version so that the CNetAddr
#     532                 :            :     // unserialize method expects an address in v2 format.
#     533                 :          2 :     s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
#     534                 :            : 
#     535                 :            :     // Valid IPv4.
#     536                 :          2 :     s << MakeSpan(ParseHex("01"          // network type (IPv4)
#     537                 :          2 :                            "04"          // address length
#     538                 :          2 :                            "01020304")); // address
#     539                 :          2 :     s >> addr;
#     540                 :          2 :     BOOST_CHECK(addr.IsValid());
#     541                 :          2 :     BOOST_CHECK(addr.IsIPv4());
#     542                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     543                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "1.2.3.4");
#     544                 :          2 :     BOOST_REQUIRE(s.empty());
#     545                 :            : 
#     546                 :            :     // Invalid IPv4, valid length but address itself is shorter.
#     547                 :          2 :     s << MakeSpan(ParseHex("01"      // network type (IPv4)
#     548                 :          2 :                            "04"      // address length
#     549                 :          2 :                            "0102")); // address
#     550                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, HasReason("end of data"));
#     551                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     552                 :          2 :     s.clear();
#     553                 :            : 
#     554                 :            :     // Invalid IPv4, with bogus length.
#     555                 :          2 :     s << MakeSpan(ParseHex("01"          // network type (IPv4)
#     556                 :          2 :                            "05"          // address length
#     557                 :          2 :                            "01020304")); // address
#     558                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     559                 :          2 :                           HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
#     560                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     561                 :          2 :     s.clear();
#     562                 :            : 
#     563                 :            :     // Invalid IPv4, with extreme length.
#     564                 :          2 :     s << MakeSpan(ParseHex("01"          // network type (IPv4)
#     565                 :          2 :                            "fd0102"      // address length (513 as CompactSize)
#     566                 :          2 :                            "01020304")); // address
#     567                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     568                 :          2 :                           HasReason("Address too long: 513 > 512"));
#     569                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     570                 :          2 :     s.clear();
#     571                 :            : 
#     572                 :            :     // Valid IPv6.
#     573                 :          2 :     s << MakeSpan(ParseHex("02"                                  // network type (IPv6)
#     574                 :          2 :                            "10"                                  // address length
#     575                 :          2 :                            "0102030405060708090a0b0c0d0e0f10")); // address
#     576                 :          2 :     s >> addr;
#     577                 :          2 :     BOOST_CHECK(addr.IsValid());
#     578                 :          2 :     BOOST_CHECK(addr.IsIPv6());
#     579                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     580                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "102:304:506:708:90a:b0c:d0e:f10");
#     581                 :          2 :     BOOST_REQUIRE(s.empty());
#     582                 :            : 
#     583                 :            :     // Valid IPv6, contains embedded "internal".
#     584                 :          2 :     s << MakeSpan(ParseHex(
#     585                 :          2 :         "02"                                  // network type (IPv6)
#     586                 :          2 :         "10"                                  // address length
#     587                 :          2 :         "fd6b88c08724ca978112ca1bbdcafac2")); // address: 0xfd + sha256("bitcoin")[0:5] +
#     588                 :            :                                               // sha256(name)[0:10]
#     589                 :          2 :     s >> addr;
#     590                 :          2 :     BOOST_CHECK(addr.IsInternal());
#     591                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     592                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "zklycewkdo64v6wc.internal");
#     593                 :          2 :     BOOST_REQUIRE(s.empty());
#     594                 :            : 
#     595                 :            :     // Invalid IPv6, with bogus length.
#     596                 :          2 :     s << MakeSpan(ParseHex("02"    // network type (IPv6)
#     597                 :          2 :                            "04"    // address length
#     598                 :          2 :                            "00")); // address
#     599                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     600                 :          2 :                           HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
#     601                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     602                 :          2 :     s.clear();
#     603                 :            : 
#     604                 :            :     // Invalid IPv6, contains embedded IPv4.
#     605                 :          2 :     s << MakeSpan(ParseHex("02"                                  // network type (IPv6)
#     606                 :          2 :                            "10"                                  // address length
#     607                 :          2 :                            "00000000000000000000ffff01020304")); // address
#     608                 :          2 :     s >> addr;
#     609                 :          2 :     BOOST_CHECK(!addr.IsValid());
#     610                 :          2 :     BOOST_REQUIRE(s.empty());
#     611                 :            : 
#     612                 :            :     // Invalid IPv6, contains embedded TORv2.
#     613                 :          2 :     s << MakeSpan(ParseHex("02"                                  // network type (IPv6)
#     614                 :          2 :                            "10"                                  // address length
#     615                 :          2 :                            "fd87d87eeb430102030405060708090a")); // address
#     616                 :          2 :     s >> addr;
#     617                 :          2 :     BOOST_CHECK(!addr.IsValid());
#     618                 :          2 :     BOOST_REQUIRE(s.empty());
#     619                 :            : 
#     620                 :            :     // Valid TORv2.
#     621                 :          2 :     s << MakeSpan(ParseHex("03"                      // network type (TORv2)
#     622                 :          2 :                            "0a"                      // address length
#     623                 :          2 :                            "f1f2f3f4f5f6f7f8f9fa")); // address
#     624                 :          2 :     s >> addr;
#     625                 :          2 :     BOOST_CHECK(addr.IsValid());
#     626                 :          2 :     BOOST_CHECK(addr.IsTor());
#     627                 :          2 :     BOOST_CHECK(addr.IsAddrV1Compatible());
#     628                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion");
#     629                 :          2 :     BOOST_REQUIRE(s.empty());
#     630                 :            : 
#     631                 :            :     // Invalid TORv2, with bogus length.
#     632                 :          2 :     s << MakeSpan(ParseHex("03"    // network type (TORv2)
#     633                 :          2 :                            "07"    // address length
#     634                 :          2 :                            "00")); // address
#     635                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     636                 :          2 :                           HasReason("BIP155 TORv2 address with length 7 (should be 10)"));
#     637                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     638                 :          2 :     s.clear();
#     639                 :            : 
#     640                 :            :     // Valid TORv3.
#     641                 :          2 :     s << MakeSpan(ParseHex("04"                               // network type (TORv3)
#     642                 :          2 :                            "20"                               // address length
#     643                 :          2 :                            "79bcc625184b05194975c28b66b66b04" // address
#     644                 :          2 :                            "69f7f6556fb1ac3189a79b40dda32f1f"
#     645                 :          2 :                            ));
#     646                 :          2 :     s >> addr;
#     647                 :          2 :     BOOST_CHECK(addr.IsValid());
#     648                 :          2 :     BOOST_CHECK(addr.IsTor());
#     649                 :          2 :     BOOST_CHECK(!addr.IsAddrV1Compatible());
#     650                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(),
#     651                 :          2 :                       "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion");
#     652                 :          2 :     BOOST_REQUIRE(s.empty());
#     653                 :            : 
#     654                 :            :     // Invalid TORv3, with bogus length.
#     655                 :          2 :     s << MakeSpan(ParseHex("04" // network type (TORv3)
#     656                 :          2 :                            "00" // address length
#     657                 :          2 :                            "00" // address
#     658                 :          2 :                            ));
#     659                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     660                 :          2 :                           HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
#     661                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     662                 :          2 :     s.clear();
#     663                 :            : 
#     664                 :            :     // Valid I2P.
#     665                 :          2 :     s << MakeSpan(ParseHex("05"                               // network type (I2P)
#     666                 :          2 :                            "20"                               // address length
#     667                 :          2 :                            "a2894dabaec08c0051a481a6dac88b64" // address
#     668                 :          2 :                            "f98232ae42d4b6fd2fa81952dfe36a87"));
#     669                 :          2 :     s >> addr;
#     670                 :          2 :     BOOST_CHECK(addr.IsValid());
#     671                 :          2 :     BOOST_CHECK(addr.IsI2P());
#     672                 :          2 :     BOOST_CHECK(!addr.IsAddrV1Compatible());
#     673                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(),
#     674                 :          2 :                       "ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p");
#     675                 :          2 :     BOOST_REQUIRE(s.empty());
#     676                 :            : 
#     677                 :            :     // Invalid I2P, with bogus length.
#     678                 :          2 :     s << MakeSpan(ParseHex("05" // network type (I2P)
#     679                 :          2 :                            "03" // address length
#     680                 :          2 :                            "00" // address
#     681                 :          2 :                            ));
#     682                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     683                 :          2 :                           HasReason("BIP155 I2P address with length 3 (should be 32)"));
#     684                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     685                 :          2 :     s.clear();
#     686                 :            : 
#     687                 :            :     // Valid CJDNS.
#     688                 :          2 :     s << MakeSpan(ParseHex("06"                               // network type (CJDNS)
#     689                 :          2 :                            "10"                               // address length
#     690                 :          2 :                            "fc000001000200030004000500060007" // address
#     691                 :          2 :                            ));
#     692                 :          2 :     s >> addr;
#     693                 :          2 :     BOOST_CHECK(addr.IsValid());
#     694                 :          2 :     BOOST_CHECK(addr.IsCJDNS());
#     695                 :          2 :     BOOST_CHECK(!addr.IsAddrV1Compatible());
#     696                 :          2 :     BOOST_CHECK_EQUAL(addr.ToString(), "fc00:1:2:3:4:5:6:7");
#     697                 :          2 :     BOOST_REQUIRE(s.empty());
#     698                 :            : 
#     699                 :            :     // Invalid CJDNS, wrong prefix.
#     700                 :          2 :     s << MakeSpan(ParseHex("06"                               // network type (CJDNS)
#     701                 :          2 :                            "10"                               // address length
#     702                 :          2 :                            "aa000001000200030004000500060007" // address
#     703                 :          2 :                            ));
#     704                 :          2 :     s >> addr;
#     705                 :          2 :     BOOST_CHECK(addr.IsCJDNS());
#     706                 :          2 :     BOOST_CHECK(!addr.IsValid());
#     707                 :          2 :     BOOST_REQUIRE(s.empty());
#     708                 :            : 
#     709                 :            :     // Invalid CJDNS, with bogus length.
#     710                 :          2 :     s << MakeSpan(ParseHex("06" // network type (CJDNS)
#     711                 :          2 :                            "01" // address length
#     712                 :          2 :                            "00" // address
#     713                 :          2 :                            ));
#     714                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     715                 :          2 :                           HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
#     716                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     717                 :          2 :     s.clear();
#     718                 :            : 
#     719                 :            :     // Unknown, with extreme length.
#     720                 :          2 :     s << MakeSpan(ParseHex("aa"             // network type (unknown)
#     721                 :          2 :                            "fe00000002"     // address length (CompactSize's MAX_SIZE)
#     722                 :          2 :                            "01020304050607" // address
#     723                 :          2 :                            ));
#     724                 :          2 :     BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
#     725                 :          2 :                           HasReason("Address too long: 33554432 > 512"));
#     726                 :          2 :     BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
#     727                 :          2 :     s.clear();
#     728                 :            : 
#     729                 :            :     // Unknown, with reasonable length.
#     730                 :          2 :     s << MakeSpan(ParseHex("aa"       // network type (unknown)
#     731                 :          2 :                            "04"       // address length
#     732                 :          2 :                            "01020304" // address
#     733                 :          2 :                            ));
#     734                 :          2 :     s >> addr;
#     735                 :          2 :     BOOST_CHECK(!addr.IsValid());
#     736                 :          2 :     BOOST_REQUIRE(s.empty());
#     737                 :            : 
#     738                 :            :     // Unknown, with zero length.
#     739                 :          2 :     s << MakeSpan(ParseHex("aa" // network type (unknown)
#     740                 :          2 :                            "00" // address length
#     741                 :          2 :                            ""   // address
#     742                 :          2 :                            ));
#     743                 :          2 :     s >> addr;
#     744                 :          2 :     BOOST_CHECK(!addr.IsValid());
#     745                 :          2 :     BOOST_REQUIRE(s.empty());
#     746                 :          2 : }
#     747                 :            : 
#     748                 :            : // prior to PR #14728, this test triggers an undefined behavior
#     749                 :            : BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
#     750                 :          2 : {
#     751                 :            :     // set up local addresses; all that's necessary to reproduce the bug is
#     752                 :            :     // that a normal IPv4 address is among the entries, but if this address is
#     753                 :            :     // !IsRoutable the undefined behavior is easier to trigger deterministically
#     754                 :          2 :     {
#     755                 :          2 :         LOCK(cs_mapLocalHost);
#     756                 :          2 :         in_addr ipv4AddrLocal;
#     757                 :          2 :         ipv4AddrLocal.s_addr = 0x0100007f;
#     758                 :          2 :         CNetAddr addr = CNetAddr(ipv4AddrLocal);
#     759                 :          2 :         LocalServiceInfo lsi;
#     760                 :          2 :         lsi.nScore = 23;
#     761                 :          2 :         lsi.nPort = 42;
#     762                 :          2 :         mapLocalHost[addr] = lsi;
#     763                 :          2 :     }
#     764                 :            : 
#     765                 :            :     // create a peer with an IPv4 address
#     766                 :          2 :     in_addr ipv4AddrPeer;
#     767                 :          2 :     ipv4AddrPeer.s_addr = 0xa0b0c001;
#     768                 :          2 :     CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
#     769                 :          2 :     std::unique_ptr<CNode> pnode = std::make_unique<CNode>(0, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress{}, /* pszDest */ std::string{}, ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false);
#     770                 :          2 :     pnode->fSuccessfullyConnected.store(true);
#     771                 :            : 
#     772                 :            :     // the peer claims to be reaching us via IPv6
#     773                 :          2 :     in6_addr ipv6AddrLocal;
#     774                 :          2 :     memset(ipv6AddrLocal.s6_addr, 0, 16);
#     775                 :          2 :     ipv6AddrLocal.s6_addr[0] = 0xcc;
#     776                 :          2 :     CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK);
#     777                 :          2 :     pnode->SetAddrLocal(addrLocal);
#     778                 :            : 
#     779                 :            :     // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
#     780                 :          2 :     GetLocalAddrForPeer(&*pnode);
#     781                 :            : 
#     782                 :            :     // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
#     783                 :          2 :     BOOST_CHECK(1);
#     784                 :          2 : }
#     785                 :            : 
#     786                 :            : 
#     787                 :            : BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
#     788                 :          2 : {
#     789                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), true);
#     790                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), true);
#     791                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_ONION), true);
#     792                 :            : 
#     793                 :          2 :     SetReachable(NET_IPV4, false);
#     794                 :          2 :     SetReachable(NET_IPV6, false);
#     795                 :          2 :     SetReachable(NET_ONION, false);
#     796                 :            : 
#     797                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), false);
#     798                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), false);
#     799                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_ONION), false);
#     800                 :            : 
#     801                 :          2 :     SetReachable(NET_IPV4, true);
#     802                 :          2 :     SetReachable(NET_IPV6, true);
#     803                 :          2 :     SetReachable(NET_ONION, true);
#     804                 :            : 
#     805                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), true);
#     806                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), true);
#     807                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_ONION), true);
#     808                 :          2 : }
#     809                 :            : 
#     810                 :            : BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
#     811                 :          2 : {
#     812                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true);
#     813                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_INTERNAL), true);
#     814                 :            : 
#     815                 :          2 :     SetReachable(NET_UNROUTABLE, false);
#     816                 :          2 :     SetReachable(NET_INTERNAL, false);
#     817                 :            : 
#     818                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true); // Ignored for both networks
#     819                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(NET_INTERNAL), true);
#     820                 :          2 : }
#     821                 :            : 
#     822                 :            : CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
#     823                 :          4 : {
#     824                 :          4 :     unsigned char ip[] = {p1, p2, p3, p4};
#     825                 :            : 
#     826                 :          4 :     struct sockaddr_in sa;
#     827                 :          4 :     memset(&sa, 0, sizeof(sockaddr_in)); // initialize the memory block
#     828                 :          4 :     memcpy(&(sa.sin_addr), &ip, sizeof(ip));
#     829                 :          4 :     return CNetAddr(sa.sin_addr);
#     830                 :          4 : }
#     831                 :            : 
#     832                 :            : 
#     833                 :            : BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
#     834                 :          2 : {
#     835                 :          2 :     CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
#     836                 :            : 
#     837                 :          2 :     SetReachable(NET_IPV4, true);
#     838                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(addr), true);
#     839                 :            : 
#     840                 :          2 :     SetReachable(NET_IPV4, false);
#     841                 :          2 :     BOOST_CHECK_EQUAL(IsReachable(addr), false);
#     842                 :            : 
#     843                 :          2 :     SetReachable(NET_IPV4, true); // have to reset this, because this is stateful.
#     844                 :          2 : }
#     845                 :            : 
#     846                 :            : 
#     847                 :            : BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
#     848                 :          2 : {
#     849                 :          2 :     CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
#     850                 :            : 
#     851                 :          2 :     SetReachable(NET_IPV4, true);
#     852                 :            : 
#     853                 :          2 :     BOOST_CHECK_EQUAL(IsLocal(addr), false);
#     854                 :          2 :     BOOST_CHECK_EQUAL(AddLocal(addr, 1000), true);
#     855                 :          2 :     BOOST_CHECK_EQUAL(IsLocal(addr), true);
#     856                 :            : 
#     857                 :          2 :     RemoveLocal(addr);
#     858                 :          2 :     BOOST_CHECK_EQUAL(IsLocal(addr), false);
#     859                 :          2 : }
#     860                 :            : 
#     861                 :            : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.14