/ src / test / net_tests.cpp
net_tests.cpp
   1  // Copyright (c) 2012-present 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 <chainparams.h>
   6  #include <clientversion.h>
   7  #include <common/args.h>
   8  #include <compat/compat.h>
   9  #include <cstdint>
  10  #include <net.h>
  11  #include <net_processing.h>
  12  #include <netaddress.h>
  13  #include <netbase.h>
  14  #include <netmessagemaker.h>
  15  #include <node/protocol_version.h>
  16  #include <serialize.h>
  17  #include <span.h>
  18  #include <streams.h>
  19  #include <test/util/random.h>
  20  #include <test/util/setup_common.h>
  21  #include <test/util/validation.h>
  22  #include <util/strencodings.h>
  23  #include <util/string.h>
  24  #include <validation.h>
  25  
  26  #include <boost/test/unit_test.hpp>
  27  
  28  #include <algorithm>
  29  #include <ios>
  30  #include <memory>
  31  #include <optional>
  32  #include <string>
  33  
  34  using namespace std::literals;
  35  using namespace util::hex_literals;
  36  using util::ToString;
  37  
  38  BOOST_FIXTURE_TEST_SUITE(net_tests, RegTestingSetup)
  39  
  40  BOOST_AUTO_TEST_CASE(cnode_listen_port)
  41  {
  42      // test default
  43      uint16_t port{GetListenPort()};
  44      BOOST_CHECK(port == Params().GetDefaultPort());
  45      // test set port
  46      uint16_t altPort = 12345;
  47      BOOST_CHECK(gArgs.SoftSetArg("-port", ToString(altPort)));
  48      port = GetListenPort();
  49      BOOST_CHECK(port == altPort);
  50  }
  51  
  52  BOOST_AUTO_TEST_CASE(cnode_simple_test)
  53  {
  54      NodeId id = 0;
  55  
  56      in_addr ipv4Addr;
  57      ipv4Addr.s_addr = 0xa0b0c001;
  58  
  59      CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
  60      std::string pszDest;
  61  
  62      std::unique_ptr<CNode> pnode1 = std::make_unique<CNode>(id++,
  63                                                              /*sock=*/nullptr,
  64                                                              addr,
  65                                                              /*nKeyedNetGroupIn=*/0,
  66                                                              /*nLocalHostNonceIn=*/0,
  67                                                              CAddress(),
  68                                                              pszDest,
  69                                                              ConnectionType::OUTBOUND_FULL_RELAY,
  70                                                              /*inbound_onion=*/false);
  71      BOOST_CHECK(pnode1->IsFullOutboundConn() == true);
  72      BOOST_CHECK(pnode1->IsManualConn() == false);
  73      BOOST_CHECK(pnode1->IsBlockOnlyConn() == false);
  74      BOOST_CHECK(pnode1->IsFeelerConn() == false);
  75      BOOST_CHECK(pnode1->IsAddrFetchConn() == false);
  76      BOOST_CHECK(pnode1->IsInboundConn() == false);
  77      BOOST_CHECK(pnode1->m_inbound_onion == false);
  78      BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4);
  79  
  80      std::unique_ptr<CNode> pnode2 = std::make_unique<CNode>(id++,
  81                                                              /*sock=*/nullptr,
  82                                                              addr,
  83                                                              /*nKeyedNetGroupIn=*/1,
  84                                                              /*nLocalHostNonceIn=*/1,
  85                                                              CAddress(),
  86                                                              pszDest,
  87                                                              ConnectionType::INBOUND,
  88                                                              /*inbound_onion=*/false);
  89      BOOST_CHECK(pnode2->IsFullOutboundConn() == false);
  90      BOOST_CHECK(pnode2->IsManualConn() == false);
  91      BOOST_CHECK(pnode2->IsBlockOnlyConn() == false);
  92      BOOST_CHECK(pnode2->IsFeelerConn() == false);
  93      BOOST_CHECK(pnode2->IsAddrFetchConn() == false);
  94      BOOST_CHECK(pnode2->IsInboundConn() == true);
  95      BOOST_CHECK(pnode2->m_inbound_onion == false);
  96      BOOST_CHECK_EQUAL(pnode2->ConnectedThroughNetwork(), Network::NET_IPV4);
  97  
  98      std::unique_ptr<CNode> pnode3 = std::make_unique<CNode>(id++,
  99                                                              /*sock=*/nullptr,
 100                                                              addr,
 101                                                              /*nKeyedNetGroupIn=*/0,
 102                                                              /*nLocalHostNonceIn=*/0,
 103                                                              CAddress(),
 104                                                              pszDest,
 105                                                              ConnectionType::OUTBOUND_FULL_RELAY,
 106                                                              /*inbound_onion=*/false);
 107      BOOST_CHECK(pnode3->IsFullOutboundConn() == true);
 108      BOOST_CHECK(pnode3->IsManualConn() == false);
 109      BOOST_CHECK(pnode3->IsBlockOnlyConn() == false);
 110      BOOST_CHECK(pnode3->IsFeelerConn() == false);
 111      BOOST_CHECK(pnode3->IsAddrFetchConn() == false);
 112      BOOST_CHECK(pnode3->IsInboundConn() == false);
 113      BOOST_CHECK(pnode3->m_inbound_onion == false);
 114      BOOST_CHECK_EQUAL(pnode3->ConnectedThroughNetwork(), Network::NET_IPV4);
 115  
 116      std::unique_ptr<CNode> pnode4 = std::make_unique<CNode>(id++,
 117                                                              /*sock=*/nullptr,
 118                                                              addr,
 119                                                              /*nKeyedNetGroupIn=*/1,
 120                                                              /*nLocalHostNonceIn=*/1,
 121                                                              CAddress(),
 122                                                              pszDest,
 123                                                              ConnectionType::INBOUND,
 124                                                              /*inbound_onion=*/true);
 125      BOOST_CHECK(pnode4->IsFullOutboundConn() == false);
 126      BOOST_CHECK(pnode4->IsManualConn() == false);
 127      BOOST_CHECK(pnode4->IsBlockOnlyConn() == false);
 128      BOOST_CHECK(pnode4->IsFeelerConn() == false);
 129      BOOST_CHECK(pnode4->IsAddrFetchConn() == false);
 130      BOOST_CHECK(pnode4->IsInboundConn() == true);
 131      BOOST_CHECK(pnode4->m_inbound_onion == true);
 132      BOOST_CHECK_EQUAL(pnode4->ConnectedThroughNetwork(), Network::NET_ONION);
 133  }
 134  
 135  BOOST_AUTO_TEST_CASE(cnetaddr_basic)
 136  {
 137      CNetAddr addr;
 138  
 139      // IPv4, INADDR_ANY
 140      addr = LookupHost("0.0.0.0", false).value();
 141      BOOST_REQUIRE(!addr.IsValid());
 142      BOOST_REQUIRE(addr.IsIPv4());
 143  
 144      BOOST_CHECK(addr.IsBindAny());
 145      BOOST_CHECK(addr.IsAddrV1Compatible());
 146      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "0.0.0.0");
 147  
 148      // IPv4, INADDR_NONE
 149      addr = LookupHost("255.255.255.255", false).value();
 150      BOOST_REQUIRE(!addr.IsValid());
 151      BOOST_REQUIRE(addr.IsIPv4());
 152  
 153      BOOST_CHECK(!addr.IsBindAny());
 154      BOOST_CHECK(addr.IsAddrV1Compatible());
 155      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "255.255.255.255");
 156  
 157      // IPv4, casual
 158      addr = LookupHost("12.34.56.78", false).value();
 159      BOOST_REQUIRE(addr.IsValid());
 160      BOOST_REQUIRE(addr.IsIPv4());
 161  
 162      BOOST_CHECK(!addr.IsBindAny());
 163      BOOST_CHECK(addr.IsAddrV1Compatible());
 164      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "12.34.56.78");
 165  
 166      // IPv6, in6addr_any
 167      addr = LookupHost("::", false).value();
 168      BOOST_REQUIRE(!addr.IsValid());
 169      BOOST_REQUIRE(addr.IsIPv6());
 170  
 171      BOOST_CHECK(addr.IsBindAny());
 172      BOOST_CHECK(addr.IsAddrV1Compatible());
 173      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "::");
 174  
 175      // IPv6, casual
 176      addr = LookupHost("1122:3344:5566:7788:9900:aabb:ccdd:eeff", false).value();
 177      BOOST_REQUIRE(addr.IsValid());
 178      BOOST_REQUIRE(addr.IsIPv6());
 179  
 180      BOOST_CHECK(!addr.IsBindAny());
 181      BOOST_CHECK(addr.IsAddrV1Compatible());
 182      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "1122:3344:5566:7788:9900:aabb:ccdd:eeff");
 183  
 184      // IPv6, scoped/link-local. See https://tools.ietf.org/html/rfc4007
 185      // We support non-negative decimal integers (uint32_t) as zone id indices.
 186      // Normal link-local scoped address functionality is to append "%" plus the
 187      // zone id, for example, given a link-local address of "fe80::1" and a zone
 188      // id of "32", return the address as "fe80::1%32".
 189      const std::string link_local{"fe80::1"};
 190      const std::string scoped_addr{link_local + "%32"};
 191      addr = LookupHost(scoped_addr, false).value();
 192      BOOST_REQUIRE(addr.IsValid());
 193      BOOST_REQUIRE(addr.IsIPv6());
 194      BOOST_CHECK(!addr.IsBindAny());
 195      BOOST_CHECK_EQUAL(addr.ToStringAddr(), scoped_addr);
 196  
 197      // TORv2, no longer supported
 198      BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
 199  
 200      // TORv3
 201      const char* torv3_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";
 202      BOOST_REQUIRE(addr.SetSpecial(torv3_addr));
 203      BOOST_REQUIRE(addr.IsValid());
 204      BOOST_REQUIRE(addr.IsTor());
 205  
 206      BOOST_CHECK(!addr.IsI2P());
 207      BOOST_CHECK(!addr.IsBindAny());
 208      BOOST_CHECK(!addr.IsAddrV1Compatible());
 209      BOOST_CHECK_EQUAL(addr.ToStringAddr(), torv3_addr);
 210  
 211      // TORv3, broken, with wrong checksum
 212      BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.onion"));
 213  
 214      // TORv3, broken, with wrong version
 215      BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrye.onion"));
 216  
 217      // TORv3, malicious
 218      BOOST_CHECK(!addr.SetSpecial(std::string{
 219          "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd\0wtf.onion", 66}));
 220  
 221      // TOR, bogus length
 222      BOOST_CHECK(!addr.SetSpecial(std::string{"mfrggzak.onion"}));
 223  
 224      // TOR, invalid base32
 225      BOOST_CHECK(!addr.SetSpecial(std::string{"mf*g zak.onion"}));
 226  
 227      // I2P
 228      const char* i2p_addr = "UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P";
 229      BOOST_REQUIRE(addr.SetSpecial(i2p_addr));
 230      BOOST_REQUIRE(addr.IsValid());
 231      BOOST_REQUIRE(addr.IsI2P());
 232  
 233      BOOST_CHECK(!addr.IsTor());
 234      BOOST_CHECK(!addr.IsBindAny());
 235      BOOST_CHECK(!addr.IsAddrV1Compatible());
 236      BOOST_CHECK_EQUAL(addr.ToStringAddr(), ToLower(i2p_addr));
 237  
 238      // I2P, correct length, but decodes to less than the expected number of bytes.
 239      BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jn=.b32.i2p"));
 240  
 241      // I2P, extra unnecessary padding
 242      BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna=.b32.i2p"));
 243  
 244      // I2P, malicious
 245      BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v\0wtf.b32.i2p"s));
 246  
 247      // I2P, valid but unsupported (56 Base32 characters)
 248      // See "Encrypted LS with Base 32 Addresses" in
 249      // https://geti2p.net/spec/encryptedleaseset.txt
 250      BOOST_CHECK(
 251          !addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.b32.i2p"));
 252  
 253      // I2P, invalid base32
 254      BOOST_CHECK(!addr.SetSpecial(std::string{"tp*szydbh4dp.b32.i2p"}));
 255  
 256      // Internal
 257      addr.SetInternal("esffpp");
 258      BOOST_REQUIRE(!addr.IsValid()); // "internal" is considered invalid
 259      BOOST_REQUIRE(addr.IsInternal());
 260  
 261      BOOST_CHECK(!addr.IsBindAny());
 262      BOOST_CHECK(addr.IsAddrV1Compatible());
 263      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "esffpvrt3wpeaygy.internal");
 264  
 265      // Totally bogus
 266      BOOST_CHECK(!addr.SetSpecial("totally bogus"));
 267  }
 268  
 269  BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6)
 270  {
 271      // Test that CNetAddr::ToString formats IPv6 addresses with zero compression as described in
 272      // RFC 5952 ("A Recommendation for IPv6 Address Text Representation").
 273      const std::map<std::string, std::string> canonical_representations_ipv6{
 274          {"0000:0000:0000:0000:0000:0000:0000:0000", "::"},
 275          {"000:0000:000:00:0:00:000:0000", "::"},
 276          {"000:000:000:000:000:000:000:000", "::"},
 277          {"00:00:00:00:00:00:00:00", "::"},
 278          {"0:0:0:0:0:0:0:0", "::"},
 279          {"0:0:0:0:0:0:0:1", "::1"},
 280          {"2001:0:0:1:0:0:0:1", "2001:0:0:1::1"},
 281          {"2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"},
 282          {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:db8:85a3::8a2e:370:7334"},
 283          {"2001:0db8::0001", "2001:db8::1"},
 284          {"2001:0db8::0001:0000", "2001:db8::1:0"},
 285          {"2001:0db8::1:0:0:1", "2001:db8::1:0:0:1"},
 286          {"2001:db8:0000:0:1::1", "2001:db8::1:0:0:1"},
 287          {"2001:db8:0000:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
 288          {"2001:db8:0:0:0:0:2:1", "2001:db8::2:1"},
 289          {"2001:db8:0:0:0::1", "2001:db8::1"},
 290          {"2001:db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"},
 291          {"2001:db8:0:0:1::1", "2001:db8::1:0:0:1"},
 292          {"2001:DB8:0:0:1::1", "2001:db8::1:0:0:1"},
 293          {"2001:db8:0:0::1", "2001:db8::1"},
 294          {"2001:db8:0:0:aaaa::1", "2001:db8::aaaa:0:0:1"},
 295          {"2001:db8:0:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
 296          {"2001:db8:0::1", "2001:db8::1"},
 297          {"2001:db8:85a3:0:0:8a2e:370:7334", "2001:db8:85a3::8a2e:370:7334"},
 298          {"2001:db8::0:1", "2001:db8::1"},
 299          {"2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1"},
 300          {"2001:DB8::1", "2001:db8::1"},
 301          {"2001:db8::1", "2001:db8::1"},
 302          {"2001:db8::1:0:0:1", "2001:db8::1:0:0:1"},
 303          {"2001:db8::1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
 304          {"2001:db8::aaaa:0:0:1", "2001:db8::aaaa:0:0:1"},
 305          {"2001:db8:aaaa:bbbb:cccc:dddd:0:1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"},
 306          {"2001:db8:aaaa:bbbb:cccc:dddd::1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"},
 307          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
 308          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
 309          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:01", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
 310          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
 311          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
 312          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
 313          {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
 314      };
 315      for (const auto& [input_address, expected_canonical_representation_output] : canonical_representations_ipv6) {
 316          const std::optional<CNetAddr> net_addr{LookupHost(input_address, false)};
 317          BOOST_REQUIRE(net_addr.value().IsIPv6());
 318          BOOST_CHECK_EQUAL(net_addr.value().ToStringAddr(), expected_canonical_representation_output);
 319      }
 320  }
 321  
 322  BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
 323  {
 324      CNetAddr addr;
 325      DataStream s{};
 326      const auto ser_params{CAddress::V1_NETWORK};
 327  
 328      s << ser_params(addr);
 329      BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
 330      s.clear();
 331  
 332      addr = LookupHost("1.2.3.4", false).value();
 333      s << ser_params(addr);
 334      BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
 335      s.clear();
 336  
 337      addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value();
 338      s << ser_params(addr);
 339      BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
 340      s.clear();
 341  
 342      // TORv2, no longer supported
 343      BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
 344  
 345      BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
 346      s << ser_params(addr);
 347      BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
 348      s.clear();
 349  
 350      addr.SetInternal("a");
 351      s << ser_params(addr);
 352      BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
 353      s.clear();
 354  }
 355  
 356  BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
 357  {
 358      CNetAddr addr;
 359      DataStream s{};
 360      const auto ser_params{CAddress::V2_NETWORK};
 361  
 362      s << ser_params(addr);
 363      BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
 364      s.clear();
 365  
 366      addr = LookupHost("1.2.3.4", false).value();
 367      s << ser_params(addr);
 368      BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
 369      s.clear();
 370  
 371      addr = LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", false).value();
 372      s << ser_params(addr);
 373      BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
 374      s.clear();
 375  
 376      // TORv2, no longer supported
 377      BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
 378  
 379      BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
 380      s << ser_params(addr);
 381      BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
 382      s.clear();
 383  
 384      BOOST_REQUIRE(addr.SetInternal("a"));
 385      s << ser_params(addr);
 386      BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
 387      s.clear();
 388  }
 389  
 390  BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
 391  {
 392      CNetAddr addr;
 393      DataStream s{};
 394      const auto ser_params{CAddress::V2_NETWORK};
 395  
 396      // Valid IPv4.
 397      s << "01"            // network type (IPv4)
 398           "04"            // address length
 399           "01020304"_hex; // address
 400      s >> ser_params(addr);
 401      BOOST_CHECK(addr.IsValid());
 402      BOOST_CHECK(addr.IsIPv4());
 403      BOOST_CHECK(addr.IsAddrV1Compatible());
 404      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "1.2.3.4");
 405      BOOST_REQUIRE(s.empty());
 406  
 407      // Invalid IPv4, valid length but address itself is shorter.
 408      s << "01"        // network type (IPv4)
 409           "04"        // address length
 410           "0102"_hex; // address
 411      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure, HasReason("end of data"));
 412      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 413      s.clear();
 414  
 415      // Invalid IPv4, with bogus length.
 416      s << "01"            // network type (IPv4)
 417           "05"            // address length
 418           "01020304"_hex; // address
 419      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 420                            HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
 421      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 422      s.clear();
 423  
 424      // Invalid IPv4, with extreme length.
 425      s << "01"            // network type (IPv4)
 426           "fd0102"        // address length (513 as CompactSize)
 427           "01020304"_hex; // address
 428      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 429                            HasReason("Address too long: 513 > 512"));
 430      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 431      s.clear();
 432  
 433      // Valid IPv6.
 434      s << "02"                                    // network type (IPv6)
 435           "10"                                    // address length
 436           "0102030405060708090a0b0c0d0e0f10"_hex; // address
 437      s >> ser_params(addr);
 438      BOOST_CHECK(addr.IsValid());
 439      BOOST_CHECK(addr.IsIPv6());
 440      BOOST_CHECK(addr.IsAddrV1Compatible());
 441      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "102:304:506:708:90a:b0c:d0e:f10");
 442      BOOST_REQUIRE(s.empty());
 443  
 444      // Valid IPv6, contains embedded "internal".
 445      s << "02"                                    // network type (IPv6)
 446           "10"                                    // address length
 447           "fd6b88c08724ca978112ca1bbdcafac2"_hex; // address: 0xfd + sha256("bitcoin")[0:5] +
 448                                                   // sha256(name)[0:10]
 449      s >> ser_params(addr);
 450      BOOST_CHECK(addr.IsInternal());
 451      BOOST_CHECK(addr.IsAddrV1Compatible());
 452      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "zklycewkdo64v6wc.internal");
 453      BOOST_REQUIRE(s.empty());
 454  
 455      // Invalid IPv6, with bogus length.
 456      s << "02"      // network type (IPv6)
 457           "04"      // address length
 458           "00"_hex; // address
 459      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 460                            HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
 461      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 462      s.clear();
 463  
 464      // Invalid IPv6, contains embedded IPv4.
 465      s << "02"                                    // network type (IPv6)
 466           "10"                                    // address length
 467           "00000000000000000000ffff01020304"_hex; // address
 468      s >> ser_params(addr);
 469      BOOST_CHECK(!addr.IsValid());
 470      BOOST_REQUIRE(s.empty());
 471  
 472      // Invalid IPv6, contains embedded TORv2.
 473      s << "02"                                    // network type (IPv6)
 474           "10"                                    // address length
 475           "fd87d87eeb430102030405060708090a"_hex; // address
 476      s >> ser_params(addr);
 477      BOOST_CHECK(!addr.IsValid());
 478      BOOST_REQUIRE(s.empty());
 479  
 480      // TORv2, no longer supported.
 481      s << "03"                        // network type (TORv2)
 482           "0a"                        // address length
 483           "f1f2f3f4f5f6f7f8f9fa"_hex; // address
 484      s >> ser_params(addr);
 485      BOOST_CHECK(!addr.IsValid());
 486      BOOST_REQUIRE(s.empty());
 487  
 488      // Valid TORv3.
 489      s << "04"                               // network type (TORv3)
 490           "20"                               // address length
 491           "79bcc625184b05194975c28b66b66b04" // address
 492           "69f7f6556fb1ac3189a79b40dda32f1f"_hex;
 493      s >> ser_params(addr);
 494      BOOST_CHECK(addr.IsValid());
 495      BOOST_CHECK(addr.IsTor());
 496      BOOST_CHECK(!addr.IsAddrV1Compatible());
 497      BOOST_CHECK_EQUAL(addr.ToStringAddr(),
 498                        "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion");
 499      BOOST_REQUIRE(s.empty());
 500  
 501      // Invalid TORv3, with bogus length.
 502      s << "04"      // network type (TORv3)
 503           "00"      // address length
 504           "00"_hex; // address
 505      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 506                            HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
 507      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 508      s.clear();
 509  
 510      // Valid I2P.
 511      s << "05"                               // network type (I2P)
 512           "20"                               // address length
 513           "a2894dabaec08c0051a481a6dac88b64" // address
 514           "f98232ae42d4b6fd2fa81952dfe36a87"_hex;
 515      s >> ser_params(addr);
 516      BOOST_CHECK(addr.IsValid());
 517      BOOST_CHECK(addr.IsI2P());
 518      BOOST_CHECK(!addr.IsAddrV1Compatible());
 519      BOOST_CHECK_EQUAL(addr.ToStringAddr(),
 520                        "ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p");
 521      BOOST_REQUIRE(s.empty());
 522  
 523      // Invalid I2P, with bogus length.
 524      s << "05"      // network type (I2P)
 525           "03"      // address length
 526           "00"_hex; // address
 527      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 528                            HasReason("BIP155 I2P address with length 3 (should be 32)"));
 529      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 530      s.clear();
 531  
 532      // Valid CJDNS.
 533      s << "06"                                    // network type (CJDNS)
 534           "10"                                    // address length
 535           "fc000001000200030004000500060007"_hex; // address
 536      s >> ser_params(addr);
 537      BOOST_CHECK(addr.IsValid());
 538      BOOST_CHECK(addr.IsCJDNS());
 539      BOOST_CHECK(!addr.IsAddrV1Compatible());
 540      BOOST_CHECK_EQUAL(addr.ToStringAddr(), "fc00:1:2:3:4:5:6:7");
 541      BOOST_REQUIRE(s.empty());
 542  
 543      // Invalid CJDNS, wrong prefix.
 544      s << "06"                                    // network type (CJDNS)
 545           "10"                                    // address length
 546           "aa000001000200030004000500060007"_hex; // address
 547      s >> ser_params(addr);
 548      BOOST_CHECK(addr.IsCJDNS());
 549      BOOST_CHECK(!addr.IsValid());
 550      BOOST_REQUIRE(s.empty());
 551  
 552      // Invalid CJDNS, with bogus length.
 553      s << "06"      // network type (CJDNS)
 554           "01"      // address length
 555           "00"_hex; // address
 556      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 557                            HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
 558      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 559      s.clear();
 560  
 561      // Unknown, with extreme length.
 562      s << "aa"                  // network type (unknown)
 563           "fe00000002"          // address length (CompactSize's MAX_SIZE)
 564           "01020304050607"_hex; // address
 565      BOOST_CHECK_EXCEPTION(s >> ser_params(addr), std::ios_base::failure,
 566                            HasReason("Address too long: 33554432 > 512"));
 567      BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
 568      s.clear();
 569  
 570      // Unknown, with reasonable length.
 571      s << "aa"            // network type (unknown)
 572           "04"            // address length
 573           "01020304"_hex; // address
 574      s >> ser_params(addr);
 575      BOOST_CHECK(!addr.IsValid());
 576      BOOST_REQUIRE(s.empty());
 577  
 578      // Unknown, with zero length.
 579      s << "aa"    // network type (unknown)
 580           "00"    // address length
 581           ""_hex; // address
 582      s >> ser_params(addr);
 583      BOOST_CHECK(!addr.IsValid());
 584      BOOST_REQUIRE(s.empty());
 585  }
 586  
 587  // prior to PR #14728, this test triggers an undefined behavior
 588  BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
 589  {
 590      // set up local addresses; all that's necessary to reproduce the bug is
 591      // that a normal IPv4 address is among the entries, but if this address is
 592      // !IsRoutable the undefined behavior is easier to trigger deterministically
 593      in_addr raw_addr;
 594      raw_addr.s_addr = htonl(0x7f000001);
 595      const CNetAddr mapLocalHost_entry = CNetAddr(raw_addr);
 596      {
 597          LOCK(g_maplocalhost_mutex);
 598          LocalServiceInfo lsi;
 599          lsi.nScore = 23;
 600          lsi.nPort = 42;
 601          mapLocalHost[mapLocalHost_entry] = lsi;
 602      }
 603  
 604      // create a peer with an IPv4 address
 605      in_addr ipv4AddrPeer;
 606      ipv4AddrPeer.s_addr = 0xa0b0c001;
 607      CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
 608      std::unique_ptr<CNode> pnode = std::make_unique<CNode>(/*id=*/0,
 609                                                             /*sock=*/nullptr,
 610                                                             addr,
 611                                                             /*nKeyedNetGroupIn=*/0,
 612                                                             /*nLocalHostNonceIn=*/0,
 613                                                             CAddress{},
 614                                                             /*pszDest=*/std::string{},
 615                                                             ConnectionType::OUTBOUND_FULL_RELAY,
 616                                                             /*inbound_onion=*/false);
 617      pnode->fSuccessfullyConnected.store(true);
 618  
 619      // the peer claims to be reaching us via IPv6
 620      in6_addr ipv6AddrLocal;
 621      memset(ipv6AddrLocal.s6_addr, 0, 16);
 622      ipv6AddrLocal.s6_addr[0] = 0xcc;
 623      CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK);
 624      pnode->SetAddrLocal(addrLocal);
 625  
 626      // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
 627      GetLocalAddrForPeer(*pnode);
 628  
 629      // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
 630      BOOST_CHECK(1);
 631  
 632      // Cleanup, so that we don't confuse other tests.
 633      {
 634          LOCK(g_maplocalhost_mutex);
 635          mapLocalHost.erase(mapLocalHost_entry);
 636      }
 637  }
 638  
 639  BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
 640  {
 641      // Test that GetLocalAddrForPeer() properly selects the address to self-advertise:
 642      //
 643      // 1. GetLocalAddrForPeer() calls GetLocalAddress() which returns an address that is
 644      //    not routable.
 645      // 2. GetLocalAddrForPeer() overrides the address with whatever the peer has told us
 646      //    he sees us as.
 647      // 2.1. For inbound connections we must override both the address and the port.
 648      // 2.2. For outbound connections we must override only the address.
 649  
 650      // Pretend that we bound to this port.
 651      const uint16_t bind_port = 20001;
 652      m_node.args->ForceSetArg("-bind", strprintf("3.4.5.6:%u", bind_port));
 653  
 654      // Our address:port as seen from the peer, completely different from the above.
 655      in_addr peer_us_addr;
 656      peer_us_addr.s_addr = htonl(0x02030405);
 657      const CService peer_us{peer_us_addr, 20002};
 658  
 659      // Create a peer with a routable IPv4 address (outbound).
 660      in_addr peer_out_in_addr;
 661      peer_out_in_addr.s_addr = htonl(0x01020304);
 662      CNode peer_out{/*id=*/0,
 663                     /*sock=*/nullptr,
 664                     /*addrIn=*/CAddress{CService{peer_out_in_addr, 8333}, NODE_NETWORK},
 665                     /*nKeyedNetGroupIn=*/0,
 666                     /*nLocalHostNonceIn=*/0,
 667                     /*addrBindIn=*/CService{},
 668                     /*addrNameIn=*/std::string{},
 669                     /*conn_type_in=*/ConnectionType::OUTBOUND_FULL_RELAY,
 670                     /*inbound_onion=*/false};
 671      peer_out.fSuccessfullyConnected = true;
 672      peer_out.SetAddrLocal(peer_us);
 673  
 674      // Without the fix peer_us:8333 is chosen instead of the proper peer_us:bind_port.
 675      auto chosen_local_addr = GetLocalAddrForPeer(peer_out);
 676      BOOST_REQUIRE(chosen_local_addr);
 677      const CService expected{peer_us_addr, bind_port};
 678      BOOST_CHECK(*chosen_local_addr == expected);
 679  
 680      // Create a peer with a routable IPv4 address (inbound).
 681      in_addr peer_in_in_addr;
 682      peer_in_in_addr.s_addr = htonl(0x05060708);
 683      CNode peer_in{/*id=*/0,
 684                    /*sock=*/nullptr,
 685                    /*addrIn=*/CAddress{CService{peer_in_in_addr, 8333}, NODE_NETWORK},
 686                    /*nKeyedNetGroupIn=*/0,
 687                    /*nLocalHostNonceIn=*/0,
 688                    /*addrBindIn=*/CService{},
 689                    /*addrNameIn=*/std::string{},
 690                    /*conn_type_in=*/ConnectionType::INBOUND,
 691                    /*inbound_onion=*/false};
 692      peer_in.fSuccessfullyConnected = true;
 693      peer_in.SetAddrLocal(peer_us);
 694  
 695      // Without the fix peer_us:8333 is chosen instead of the proper peer_us:peer_us.GetPort().
 696      chosen_local_addr = GetLocalAddrForPeer(peer_in);
 697      BOOST_REQUIRE(chosen_local_addr);
 698      BOOST_CHECK(*chosen_local_addr == peer_us);
 699  
 700      m_node.args->ForceSetArg("-bind", "");
 701  }
 702  
 703  BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
 704  {
 705      BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));
 706      BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));
 707      BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));
 708      BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));
 709      BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));
 710  
 711      g_reachable_nets.Remove(NET_IPV4);
 712      g_reachable_nets.Remove(NET_IPV6);
 713      g_reachable_nets.Remove(NET_ONION);
 714      g_reachable_nets.Remove(NET_I2P);
 715      g_reachable_nets.Remove(NET_CJDNS);
 716  
 717      BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV4));
 718      BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV6));
 719      BOOST_CHECK(!g_reachable_nets.Contains(NET_ONION));
 720      BOOST_CHECK(!g_reachable_nets.Contains(NET_I2P));
 721      BOOST_CHECK(!g_reachable_nets.Contains(NET_CJDNS));
 722  
 723      g_reachable_nets.Add(NET_IPV4);
 724      g_reachable_nets.Add(NET_IPV6);
 725      g_reachable_nets.Add(NET_ONION);
 726      g_reachable_nets.Add(NET_I2P);
 727      g_reachable_nets.Add(NET_CJDNS);
 728  
 729      BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));
 730      BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));
 731      BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));
 732      BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));
 733      BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));
 734  }
 735  
 736  BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
 737  {
 738      // Should be reachable by default.
 739      BOOST_CHECK(g_reachable_nets.Contains(NET_UNROUTABLE));
 740      BOOST_CHECK(g_reachable_nets.Contains(NET_INTERNAL));
 741  
 742      g_reachable_nets.RemoveAll();
 743  
 744      BOOST_CHECK(!g_reachable_nets.Contains(NET_UNROUTABLE));
 745      BOOST_CHECK(!g_reachable_nets.Contains(NET_INTERNAL));
 746  
 747      g_reachable_nets.Add(NET_IPV4);
 748      g_reachable_nets.Add(NET_IPV6);
 749      g_reachable_nets.Add(NET_ONION);
 750      g_reachable_nets.Add(NET_I2P);
 751      g_reachable_nets.Add(NET_CJDNS);
 752      g_reachable_nets.Add(NET_UNROUTABLE);
 753      g_reachable_nets.Add(NET_INTERNAL);
 754  }
 755  
 756  CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
 757  {
 758      unsigned char ip[] = {p1, p2, p3, p4};
 759  
 760      struct sockaddr_in sa;
 761      memset(&sa, 0, sizeof(sockaddr_in)); // initialize the memory block
 762      memcpy(&(sa.sin_addr), &ip, sizeof(ip));
 763      return CNetAddr(sa.sin_addr);
 764  }
 765  
 766  
 767  BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
 768  {
 769      CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
 770  
 771      g_reachable_nets.Add(NET_IPV4);
 772      BOOST_CHECK(g_reachable_nets.Contains(addr));
 773  
 774      g_reachable_nets.Remove(NET_IPV4);
 775      BOOST_CHECK(!g_reachable_nets.Contains(addr));
 776  
 777      g_reachable_nets.Add(NET_IPV4); // have to reset this, because this is stateful.
 778  }
 779  
 780  
 781  BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
 782  {
 783      CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
 784  
 785      g_reachable_nets.Add(NET_IPV4);
 786  
 787      BOOST_CHECK(!IsLocal(addr));
 788      BOOST_CHECK(AddLocal(addr, 1000));
 789      BOOST_CHECK(IsLocal(addr));
 790  
 791      RemoveLocal(addr);
 792      BOOST_CHECK(!IsLocal(addr));
 793  }
 794  
 795  BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
 796  {
 797      LOCK(NetEventsInterface::g_msgproc_mutex);
 798  
 799      // Tests the following scenario:
 800      // * -bind=3.4.5.6:20001 is specified
 801      // * we make an outbound connection to a peer
 802      // * the peer reports he sees us as 2.3.4.5:20002 in the version message
 803      //   (20002 is a random port assigned by our OS for the outgoing TCP connection,
 804      //   we cannot accept connections to it)
 805      // * we should self-advertise to that peer as 2.3.4.5:20001
 806  
 807      // Pretend that we bound to this port.
 808      const uint16_t bind_port = 20001;
 809      m_node.args->ForceSetArg("-bind", strprintf("3.4.5.6:%u", bind_port));
 810      m_node.args->ForceSetArg("-capturemessages", "1");
 811  
 812      // Our address:port as seen from the peer - 2.3.4.5:20002 (different from the above).
 813      in_addr peer_us_addr;
 814      peer_us_addr.s_addr = htonl(0x02030405);
 815      const CService peer_us{peer_us_addr, 20002};
 816  
 817      // Create a peer with a routable IPv4 address.
 818      in_addr peer_in_addr;
 819      peer_in_addr.s_addr = htonl(0x01020304);
 820      CNode peer{/*id=*/0,
 821                 /*sock=*/nullptr,
 822                 /*addrIn=*/CAddress{CService{peer_in_addr, 8333}, NODE_NETWORK},
 823                 /*nKeyedNetGroupIn=*/0,
 824                 /*nLocalHostNonceIn=*/0,
 825                 /*addrBindIn=*/CService{},
 826                 /*addrNameIn=*/std::string{},
 827                 /*conn_type_in=*/ConnectionType::OUTBOUND_FULL_RELAY,
 828                 /*inbound_onion=*/false};
 829  
 830      const uint64_t services{NODE_NETWORK | NODE_WITNESS};
 831      const int64_t time{0};
 832  
 833      // Force ChainstateManager::IsInitialBlockDownload() to return false.
 834      // Otherwise PushAddress() isn't called by PeerManager::ProcessMessage().
 835      auto& chainman = static_cast<TestChainstateManager&>(*m_node.chainman);
 836      chainman.JumpOutOfIbd();
 837  
 838      m_node.peerman->InitializeNode(peer, NODE_NETWORK);
 839  
 840      std::atomic<bool> interrupt_dummy{false};
 841      std::chrono::microseconds time_received_dummy{0};
 842  
 843      const auto msg_version =
 844          NetMsg::Make(NetMsgType::VERSION, PROTOCOL_VERSION, services, time, services, CAddress::V1_NETWORK(peer_us));
 845      DataStream msg_version_stream{msg_version.data};
 846  
 847      m_node.peerman->ProcessMessage(
 848          peer, NetMsgType::VERSION, msg_version_stream, time_received_dummy, interrupt_dummy);
 849  
 850      const auto msg_verack = NetMsg::Make(NetMsgType::VERACK);
 851      DataStream msg_verack_stream{msg_verack.data};
 852  
 853      // Will set peer.fSuccessfullyConnected to true (necessary in SendMessages()).
 854      m_node.peerman->ProcessMessage(
 855          peer, NetMsgType::VERACK, msg_verack_stream, time_received_dummy, interrupt_dummy);
 856  
 857      // Ensure that peer_us_addr:bind_port is sent to the peer.
 858      const CService expected{peer_us_addr, bind_port};
 859      bool sent{false};
 860  
 861      const auto CaptureMessageOrig = CaptureMessage;
 862      CaptureMessage = [&sent, &expected](const CAddress& addr,
 863                                          const std::string& msg_type,
 864                                          std::span<const unsigned char> data,
 865                                          bool is_incoming) -> void {
 866          if (!is_incoming && msg_type == "addr") {
 867              DataStream s{data};
 868              std::vector<CAddress> addresses;
 869  
 870              s >> CAddress::V1_NETWORK(addresses);
 871  
 872              for (const auto& addr : addresses) {
 873                  if (addr == expected) {
 874                      sent = true;
 875                      return;
 876                  }
 877              }
 878          }
 879      };
 880  
 881      m_node.peerman->SendMessages(&peer);
 882  
 883      BOOST_CHECK(sent);
 884  
 885      CaptureMessage = CaptureMessageOrig;
 886      chainman.ResetIbd();
 887      m_node.args->ForceSetArg("-capturemessages", "0");
 888      m_node.args->ForceSetArg("-bind", "");
 889  }
 890  
 891  
 892  BOOST_AUTO_TEST_CASE(advertise_local_address)
 893  {
 894      auto CreatePeer = [](const CAddress& addr) {
 895          return std::make_unique<CNode>(/*id=*/0,
 896                                         /*sock=*/nullptr,
 897                                         addr,
 898                                         /*nKeyedNetGroupIn=*/0,
 899                                         /*nLocalHostNonceIn=*/0,
 900                                         CAddress{},
 901                                         /*pszDest=*/std::string{},
 902                                         ConnectionType::OUTBOUND_FULL_RELAY,
 903                                         /*inbound_onion=*/false);
 904      };
 905      g_reachable_nets.Add(NET_CJDNS);
 906  
 907      CAddress addr_ipv4{Lookup("1.2.3.4", 8333, false).value(), NODE_NONE};
 908      BOOST_REQUIRE(addr_ipv4.IsValid());
 909      BOOST_REQUIRE(addr_ipv4.IsIPv4());
 910  
 911      CAddress addr_ipv6{Lookup("1122:3344:5566:7788:9900:aabb:ccdd:eeff", 8333, false).value(), NODE_NONE};
 912      BOOST_REQUIRE(addr_ipv6.IsValid());
 913      BOOST_REQUIRE(addr_ipv6.IsIPv6());
 914  
 915      CAddress addr_ipv6_tunnel{Lookup("2002:3344:5566:7788:9900:aabb:ccdd:eeff", 8333, false).value(), NODE_NONE};
 916      BOOST_REQUIRE(addr_ipv6_tunnel.IsValid());
 917      BOOST_REQUIRE(addr_ipv6_tunnel.IsIPv6());
 918      BOOST_REQUIRE(addr_ipv6_tunnel.IsRFC3964());
 919  
 920      CAddress addr_teredo{Lookup("2001:0000:5566:7788:9900:aabb:ccdd:eeff", 8333, false).value(), NODE_NONE};
 921      BOOST_REQUIRE(addr_teredo.IsValid());
 922      BOOST_REQUIRE(addr_teredo.IsIPv6());
 923      BOOST_REQUIRE(addr_teredo.IsRFC4380());
 924  
 925      CAddress addr_onion;
 926      BOOST_REQUIRE(addr_onion.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
 927      BOOST_REQUIRE(addr_onion.IsValid());
 928      BOOST_REQUIRE(addr_onion.IsTor());
 929  
 930      CAddress addr_i2p;
 931      BOOST_REQUIRE(addr_i2p.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p"));
 932      BOOST_REQUIRE(addr_i2p.IsValid());
 933      BOOST_REQUIRE(addr_i2p.IsI2P());
 934  
 935      CService service_cjdns{Lookup("fc00:3344:5566:7788:9900:aabb:ccdd:eeff", 8333, false).value(), NODE_NONE};
 936      CAddress addr_cjdns{MaybeFlipIPv6toCJDNS(service_cjdns), NODE_NONE};
 937      BOOST_REQUIRE(addr_cjdns.IsValid());
 938      BOOST_REQUIRE(addr_cjdns.IsCJDNS());
 939  
 940      const auto peer_ipv4{CreatePeer(addr_ipv4)};
 941      const auto peer_ipv6{CreatePeer(addr_ipv6)};
 942      const auto peer_ipv6_tunnel{CreatePeer(addr_ipv6_tunnel)};
 943      const auto peer_teredo{CreatePeer(addr_teredo)};
 944      const auto peer_onion{CreatePeer(addr_onion)};
 945      const auto peer_i2p{CreatePeer(addr_i2p)};
 946      const auto peer_cjdns{CreatePeer(addr_cjdns)};
 947  
 948      // one local clearnet address - advertise to all but privacy peers
 949      AddLocal(addr_ipv4);
 950      BOOST_CHECK(GetLocalAddress(*peer_ipv4) == addr_ipv4);
 951      BOOST_CHECK(GetLocalAddress(*peer_ipv6) == addr_ipv4);
 952      BOOST_CHECK(GetLocalAddress(*peer_ipv6_tunnel) == addr_ipv4);
 953      BOOST_CHECK(GetLocalAddress(*peer_teredo) == addr_ipv4);
 954      BOOST_CHECK(GetLocalAddress(*peer_cjdns) == addr_ipv4);
 955      BOOST_CHECK(!GetLocalAddress(*peer_onion).IsValid());
 956      BOOST_CHECK(!GetLocalAddress(*peer_i2p).IsValid());
 957      RemoveLocal(addr_ipv4);
 958  
 959      // local privacy addresses - don't advertise to clearnet peers
 960      AddLocal(addr_onion);
 961      AddLocal(addr_i2p);
 962      BOOST_CHECK(!GetLocalAddress(*peer_ipv4).IsValid());
 963      BOOST_CHECK(!GetLocalAddress(*peer_ipv6).IsValid());
 964      BOOST_CHECK(!GetLocalAddress(*peer_ipv6_tunnel).IsValid());
 965      BOOST_CHECK(!GetLocalAddress(*peer_teredo).IsValid());
 966      BOOST_CHECK(!GetLocalAddress(*peer_cjdns).IsValid());
 967      BOOST_CHECK(GetLocalAddress(*peer_onion) == addr_onion);
 968      BOOST_CHECK(GetLocalAddress(*peer_i2p) == addr_i2p);
 969      RemoveLocal(addr_onion);
 970      RemoveLocal(addr_i2p);
 971  
 972      // local addresses from all networks
 973      AddLocal(addr_ipv4);
 974      AddLocal(addr_ipv6);
 975      AddLocal(addr_ipv6_tunnel);
 976      AddLocal(addr_teredo);
 977      AddLocal(addr_onion);
 978      AddLocal(addr_i2p);
 979      AddLocal(addr_cjdns);
 980      BOOST_CHECK(GetLocalAddress(*peer_ipv4) == addr_ipv4);
 981      BOOST_CHECK(GetLocalAddress(*peer_ipv6) == addr_ipv6);
 982      BOOST_CHECK(GetLocalAddress(*peer_ipv6_tunnel) == addr_ipv6);
 983      BOOST_CHECK(GetLocalAddress(*peer_teredo) == addr_ipv4);
 984      BOOST_CHECK(GetLocalAddress(*peer_onion) == addr_onion);
 985      BOOST_CHECK(GetLocalAddress(*peer_i2p) == addr_i2p);
 986      BOOST_CHECK(GetLocalAddress(*peer_cjdns) == addr_cjdns);
 987      RemoveLocal(addr_ipv4);
 988      RemoveLocal(addr_ipv6);
 989      RemoveLocal(addr_ipv6_tunnel);
 990      RemoveLocal(addr_teredo);
 991      RemoveLocal(addr_onion);
 992      RemoveLocal(addr_i2p);
 993      RemoveLocal(addr_cjdns);
 994  }
 995  
 996  namespace {
 997  
 998  CKey GenerateRandomTestKey(FastRandomContext& rng) noexcept
 999  {
1000      CKey key;
1001      uint256 key_data = rng.rand256();
1002      key.Set(key_data.begin(), key_data.end(), true);
1003      return key;
1004  }
1005  
1006  /** A class for scenario-based tests of V2Transport
1007   *
1008   * Each V2TransportTester encapsulates a V2Transport (the one being tested), and can be told to
1009   * interact with it. To do so, it also encapsulates a BIP324Cipher to act as the other side. A
1010   * second V2Transport is not used, as doing so would not permit scenarios that involve sending
1011   * invalid data, or ones using BIP324 features that are not implemented on the sending
1012   * side (like decoy packets).
1013   */
1014  class V2TransportTester
1015  {
1016      FastRandomContext& m_rng;
1017      V2Transport m_transport; //!< V2Transport being tested
1018      BIP324Cipher m_cipher; //!< Cipher to help with the other side
1019      bool m_test_initiator; //!< Whether m_transport is the initiator (true) or responder (false)
1020  
1021      std::vector<uint8_t> m_sent_garbage; //!< The garbage we've sent to m_transport.
1022      std::vector<uint8_t> m_recv_garbage; //!< The garbage we've received from m_transport.
1023      std::vector<uint8_t> m_to_send; //!< Bytes we have queued up to send to m_transport.
1024      std::vector<uint8_t> m_received; //!< Bytes we have received from m_transport.
1025      std::deque<CSerializedNetMsg> m_msg_to_send; //!< Messages to be sent *by* m_transport to us.
1026      bool m_sent_aad{false};
1027  
1028  public:
1029      /** Construct a tester object. test_initiator: whether the tested transport is initiator. */
1030      explicit V2TransportTester(FastRandomContext& rng, bool test_initiator)
1031          : m_rng{rng},
1032            m_transport{0, test_initiator},
1033            m_cipher{GenerateRandomTestKey(m_rng), MakeByteSpan(m_rng.rand256())},
1034            m_test_initiator(test_initiator) {}
1035  
1036      /** Data type returned by Interact:
1037       *
1038       * - std::nullopt: transport error occurred
1039       * - otherwise: a vector of
1040       *   - std::nullopt: invalid message received
1041       *   - otherwise: a CNetMessage retrieved
1042       */
1043      using InteractResult = std::optional<std::vector<std::optional<CNetMessage>>>;
1044  
1045      /** Send/receive scheduled/available bytes and messages.
1046       *
1047       * This is the only function that interacts with the transport being tested; everything else is
1048       * scheduling things done by Interact(), or processing things learned by it.
1049       */
1050      InteractResult Interact()
1051      {
1052          std::vector<std::optional<CNetMessage>> ret;
1053          while (true) {
1054              bool progress{false};
1055              // Send bytes from m_to_send to the transport.
1056              if (!m_to_send.empty()) {
1057                  std::span<const uint8_t> to_send = std::span{m_to_send}.first(1 + m_rng.randrange(m_to_send.size()));
1058                  size_t old_len = to_send.size();
1059                  if (!m_transport.ReceivedBytes(to_send)) {
1060                      return std::nullopt; // transport error occurred
1061                  }
1062                  if (old_len != to_send.size()) {
1063                      progress = true;
1064                      m_to_send.erase(m_to_send.begin(), m_to_send.begin() + (old_len - to_send.size()));
1065                  }
1066              }
1067              // Retrieve messages received by the transport.
1068              if (m_transport.ReceivedMessageComplete() && (!progress || m_rng.randbool())) {
1069                  bool reject{false};
1070                  auto msg = m_transport.GetReceivedMessage({}, reject);
1071                  if (reject) {
1072                      ret.emplace_back(std::nullopt);
1073                  } else {
1074                      ret.emplace_back(std::move(msg));
1075                  }
1076                  progress = true;
1077              }
1078              // Enqueue a message to be sent by the transport to us.
1079              if (!m_msg_to_send.empty() && (!progress || m_rng.randbool())) {
1080                  if (m_transport.SetMessageToSend(m_msg_to_send.front())) {
1081                      m_msg_to_send.pop_front();
1082                      progress = true;
1083                  }
1084              }
1085              // Receive bytes from the transport.
1086              const auto& [recv_bytes, _more, _msg_type] = m_transport.GetBytesToSend(!m_msg_to_send.empty());
1087              if (!recv_bytes.empty() && (!progress || m_rng.randbool())) {
1088                  size_t to_receive = 1 + m_rng.randrange(recv_bytes.size());
1089                  m_received.insert(m_received.end(), recv_bytes.begin(), recv_bytes.begin() + to_receive);
1090                  progress = true;
1091                  m_transport.MarkBytesSent(to_receive);
1092              }
1093              if (!progress) break;
1094          }
1095          return ret;
1096      }
1097  
1098      /** Expose the cipher. */
1099      BIP324Cipher& GetCipher() { return m_cipher; }
1100  
1101      /** Schedule bytes to be sent to the transport. */
1102      void Send(std::span<const uint8_t> data)
1103      {
1104          m_to_send.insert(m_to_send.end(), data.begin(), data.end());
1105      }
1106  
1107      /** Send V1 version message header to the transport. */
1108      void SendV1Version(const MessageStartChars& magic)
1109      {
1110          CMessageHeader hdr(magic, "version", 126 + m_rng.randrange(11));
1111          DataStream ser{};
1112          ser << hdr;
1113          m_to_send.insert(m_to_send.end(), UCharCast(ser.data()), UCharCast(ser.data() + ser.size()));
1114      }
1115  
1116      /** Schedule bytes to be sent to the transport. */
1117      void Send(std::span<const std::byte> data) { Send(MakeUCharSpan(data)); }
1118  
1119      /** Schedule our ellswift key to be sent to the transport. */
1120      void SendKey() { Send(m_cipher.GetOurPubKey()); }
1121  
1122      /** Schedule specified garbage to be sent to the transport. */
1123      void SendGarbage(std::span<const uint8_t> garbage)
1124      {
1125          // Remember the specified garbage (so we can use it as AAD).
1126          m_sent_garbage.assign(garbage.begin(), garbage.end());
1127          // Schedule it for sending.
1128          Send(m_sent_garbage);
1129      }
1130  
1131      /** Schedule garbage (of specified length) to be sent to the transport. */
1132      void SendGarbage(size_t garbage_len)
1133      {
1134          // Generate random garbage and send it.
1135          SendGarbage(m_rng.randbytes<uint8_t>(garbage_len));
1136      }
1137  
1138      /** Schedule garbage (with valid random length) to be sent to the transport. */
1139      void SendGarbage()
1140      {
1141           SendGarbage(m_rng.randrange(V2Transport::MAX_GARBAGE_LEN + 1));
1142      }
1143  
1144      /** Schedule a message to be sent to us by the transport. */
1145      void AddMessage(std::string m_type, std::vector<uint8_t> payload)
1146      {
1147          CSerializedNetMsg msg;
1148          msg.m_type = std::move(m_type);
1149          msg.data = std::move(payload);
1150          m_msg_to_send.push_back(std::move(msg));
1151      }
1152  
1153      /** Expect ellswift key to have been received from transport and process it.
1154       *
1155       * Many other V2TransportTester functions cannot be called until after ReceiveKey() has been
1156       * called, as no encryption keys are set up before that point.
1157       */
1158      void ReceiveKey()
1159      {
1160          // When processing a key, enough bytes need to have been received already.
1161          BOOST_REQUIRE(m_received.size() >= EllSwiftPubKey::size());
1162          // Initialize the cipher using it (acting as the opposite side of the tested transport).
1163          m_cipher.Initialize(MakeByteSpan(m_received).first(EllSwiftPubKey::size()), !m_test_initiator);
1164          // Strip the processed bytes off the front of the receive buffer.
1165          m_received.erase(m_received.begin(), m_received.begin() + EllSwiftPubKey::size());
1166      }
1167  
1168      /** Schedule an encrypted packet with specified content/aad/ignore to be sent to transport
1169       *  (only after ReceiveKey). */
1170      void SendPacket(std::span<const uint8_t> content, std::span<const uint8_t> aad = {}, bool ignore = false)
1171      {
1172          // Use cipher to construct ciphertext.
1173          std::vector<std::byte> ciphertext;
1174          ciphertext.resize(content.size() + BIP324Cipher::EXPANSION);
1175          m_cipher.Encrypt(
1176              /*contents=*/MakeByteSpan(content),
1177              /*aad=*/MakeByteSpan(aad),
1178              /*ignore=*/ignore,
1179              /*output=*/ciphertext);
1180          // Schedule it for sending.
1181          Send(ciphertext);
1182      }
1183  
1184      /** Schedule garbage terminator to be sent to the transport (only after ReceiveKey). */
1185      void SendGarbageTerm()
1186      {
1187          // Schedule the garbage terminator to be sent.
1188          Send(m_cipher.GetSendGarbageTerminator());
1189      }
1190  
1191      /** Schedule version packet to be sent to the transport (only after ReceiveKey). */
1192      void SendVersion(std::span<const uint8_t> version_data = {}, bool vers_ignore = false)
1193      {
1194          std::span<const std::uint8_t> aad;
1195          // Set AAD to garbage only for first packet.
1196          if (!m_sent_aad) aad = m_sent_garbage;
1197          SendPacket(/*content=*/version_data, /*aad=*/aad, /*ignore=*/vers_ignore);
1198          m_sent_aad = true;
1199      }
1200  
1201      /** Expect a packet to have been received from transport, process it, and return its contents
1202       *  (only after ReceiveKey). Decoys are skipped. Optional associated authenticated data (AAD) is
1203       *  expected in the first received packet, no matter if that is a decoy or not. */
1204      std::vector<uint8_t> ReceivePacket(std::span<const std::byte> aad = {})
1205      {
1206          std::vector<uint8_t> contents;
1207          // Loop as long as there are ignored packets that are to be skipped.
1208          while (true) {
1209              // When processing a packet, at least enough bytes for its length descriptor must be received.
1210              BOOST_REQUIRE(m_received.size() >= BIP324Cipher::LENGTH_LEN);
1211              // Decrypt the content length.
1212              size_t size = m_cipher.DecryptLength(MakeByteSpan(std::span{m_received}.first(BIP324Cipher::LENGTH_LEN)));
1213              // Check that the full packet is in the receive buffer.
1214              BOOST_REQUIRE(m_received.size() >= size + BIP324Cipher::EXPANSION);
1215              // Decrypt the packet contents.
1216              contents.resize(size);
1217              bool ignore{false};
1218              bool ret = m_cipher.Decrypt(
1219                  /*input=*/MakeByteSpan(
1220                      std::span{m_received}.first(size + BIP324Cipher::EXPANSION).subspan(BIP324Cipher::LENGTH_LEN)),
1221                  /*aad=*/aad,
1222                  /*ignore=*/ignore,
1223                  /*contents=*/MakeWritableByteSpan(contents));
1224              BOOST_CHECK(ret);
1225              // Don't expect AAD in further packets.
1226              aad = {};
1227              // Strip the processed packet's bytes off the front of the receive buffer.
1228              m_received.erase(m_received.begin(), m_received.begin() + size + BIP324Cipher::EXPANSION);
1229              // Stop if the ignore bit is not set on this packet.
1230              if (!ignore) break;
1231          }
1232          return contents;
1233      }
1234  
1235      /** Expect garbage and garbage terminator to have been received, and process them (only after
1236       *  ReceiveKey). */
1237      void ReceiveGarbage()
1238      {
1239          // Figure out the garbage length.
1240          size_t garblen;
1241          for (garblen = 0; garblen <= V2Transport::MAX_GARBAGE_LEN; ++garblen) {
1242              BOOST_REQUIRE(m_received.size() >= garblen + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1243              auto term_span = MakeByteSpan(std::span{m_received}.subspan(garblen, BIP324Cipher::GARBAGE_TERMINATOR_LEN));
1244              if (std::ranges::equal(term_span, m_cipher.GetReceiveGarbageTerminator())) break;
1245          }
1246          // Copy the garbage to a buffer.
1247          m_recv_garbage.assign(m_received.begin(), m_received.begin() + garblen);
1248          // Strip garbage + garbage terminator off the front of the receive buffer.
1249          m_received.erase(m_received.begin(), m_received.begin() + garblen + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1250      }
1251  
1252      /** Expect version packet to have been received, and process it (only after ReceiveKey). */
1253      void ReceiveVersion()
1254      {
1255          auto contents = ReceivePacket(/*aad=*/MakeByteSpan(m_recv_garbage));
1256          // Version packets from real BIP324 peers are expected to be empty, despite the fact that
1257          // this class supports *sending* non-empty version packets (to test that BIP324 peers
1258          // correctly ignore version packet contents).
1259          BOOST_CHECK(contents.empty());
1260      }
1261  
1262      /** Expect application packet to have been received, with specified short id and payload.
1263       *  (only after ReceiveKey). */
1264      void ReceiveMessage(uint8_t short_id, std::span<const uint8_t> payload)
1265      {
1266          auto ret = ReceivePacket();
1267          BOOST_CHECK(ret.size() == payload.size() + 1);
1268          BOOST_CHECK(ret[0] == short_id);
1269          BOOST_CHECK(std::ranges::equal(std::span{ret}.subspan(1), payload));
1270      }
1271  
1272      /** Expect application packet to have been received, with specified 12-char message type and
1273       *  payload (only after ReceiveKey). */
1274      void ReceiveMessage(const std::string& m_type, std::span<const uint8_t> payload)
1275      {
1276          auto ret = ReceivePacket();
1277          BOOST_REQUIRE(ret.size() == payload.size() + 1 + CMessageHeader::MESSAGE_TYPE_SIZE);
1278          BOOST_CHECK(ret[0] == 0);
1279          for (unsigned i = 0; i < 12; ++i) {
1280              if (i < m_type.size()) {
1281                  BOOST_CHECK(ret[1 + i] == m_type[i]);
1282              } else {
1283                  BOOST_CHECK(ret[1 + i] == 0);
1284              }
1285          }
1286          BOOST_CHECK(std::ranges::equal(std::span{ret}.subspan(1 + CMessageHeader::MESSAGE_TYPE_SIZE), payload));
1287      }
1288  
1289      /** Schedule an encrypted packet with specified message type and payload to be sent to
1290       *  transport (only after ReceiveKey). */
1291      void SendMessage(std::string mtype, std::span<const uint8_t> payload)
1292      {
1293          // Construct contents consisting of 0x00 + 12-byte message type + payload.
1294          std::vector<uint8_t> contents(1 + CMessageHeader::MESSAGE_TYPE_SIZE + payload.size());
1295          std::copy(mtype.begin(), mtype.end(), reinterpret_cast<char*>(contents.data() + 1));
1296          std::copy(payload.begin(), payload.end(), contents.begin() + 1 + CMessageHeader::MESSAGE_TYPE_SIZE);
1297          // Send a packet with that as contents.
1298          SendPacket(contents);
1299      }
1300  
1301      /** Schedule an encrypted packet with specified short message id and payload to be sent to
1302       *  transport (only after ReceiveKey). */
1303      void SendMessage(uint8_t short_id, std::span<const uint8_t> payload)
1304      {
1305          // Construct contents consisting of short_id + payload.
1306          std::vector<uint8_t> contents(1 + payload.size());
1307          contents[0] = short_id;
1308          std::copy(payload.begin(), payload.end(), contents.begin() + 1);
1309          // Send a packet with that as contents.
1310          SendPacket(contents);
1311      }
1312  
1313      /** Test whether the transport's session ID matches the session ID we expect. */
1314      void CompareSessionIDs() const
1315      {
1316          auto info = m_transport.GetInfo();
1317          BOOST_CHECK(info.session_id);
1318          BOOST_CHECK(uint256(MakeUCharSpan(m_cipher.GetSessionID())) == *info.session_id);
1319      }
1320  
1321      /** Introduce a bit error in the data scheduled to be sent. */
1322      void Damage()
1323      {
1324          m_to_send[m_rng.randrange(m_to_send.size())] ^= (uint8_t{1} << m_rng.randrange(8));
1325      }
1326  };
1327  
1328  } // namespace
1329  
1330  BOOST_AUTO_TEST_CASE(v2transport_test)
1331  {
1332      // A mostly normal scenario, testing a transport in initiator mode.
1333      for (int i = 0; i < 10; ++i) {
1334          V2TransportTester tester(m_rng, true);
1335          auto ret = tester.Interact();
1336          BOOST_REQUIRE(ret && ret->empty());
1337          tester.SendKey();
1338          tester.SendGarbage();
1339          tester.ReceiveKey();
1340          tester.SendGarbageTerm();
1341          tester.SendVersion();
1342          ret = tester.Interact();
1343          BOOST_REQUIRE(ret && ret->empty());
1344          tester.ReceiveGarbage();
1345          tester.ReceiveVersion();
1346          tester.CompareSessionIDs();
1347          auto msg_data_1 = m_rng.randbytes<uint8_t>(m_rng.randrange(100000));
1348          auto msg_data_2 = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));
1349          tester.SendMessage(uint8_t(4), msg_data_1); // cmpctblock short id
1350          tester.SendMessage(0, {}); // Invalidly encoded message
1351          tester.SendMessage("tx", msg_data_2); // 12-character encoded message type
1352          ret = tester.Interact();
1353          BOOST_REQUIRE(ret && ret->size() == 3);
1354          BOOST_CHECK((*ret)[0] && (*ret)[0]->m_type == "cmpctblock" && std::ranges::equal((*ret)[0]->m_recv, MakeByteSpan(msg_data_1)));
1355          BOOST_CHECK(!(*ret)[1]);
1356          BOOST_CHECK((*ret)[2] && (*ret)[2]->m_type == "tx" && std::ranges::equal((*ret)[2]->m_recv, MakeByteSpan(msg_data_2)));
1357  
1358          // Then send a message with a bit error, expecting failure. It's possible this failure does
1359          // not occur immediately (when the length descriptor was modified), but it should come
1360          // eventually, and no messages can be delivered anymore.
1361          tester.SendMessage("bad", msg_data_1);
1362          tester.Damage();
1363          while (true) {
1364              ret = tester.Interact();
1365              if (!ret) break; // failure
1366              BOOST_CHECK(ret->size() == 0); // no message can be delivered
1367              // Send another message.
1368              auto msg_data_3 = m_rng.randbytes<uint8_t>(m_rng.randrange(10000));
1369              tester.SendMessage(uint8_t(12), msg_data_3); // getheaders short id
1370          }
1371      }
1372  
1373      // Normal scenario, with a transport in responder node.
1374      for (int i = 0; i < 10; ++i) {
1375          V2TransportTester tester(m_rng, false);
1376          tester.SendKey();
1377          tester.SendGarbage();
1378          auto ret = tester.Interact();
1379          BOOST_REQUIRE(ret && ret->empty());
1380          tester.ReceiveKey();
1381          tester.SendGarbageTerm();
1382          tester.SendVersion();
1383          ret = tester.Interact();
1384          BOOST_REQUIRE(ret && ret->empty());
1385          tester.ReceiveGarbage();
1386          tester.ReceiveVersion();
1387          tester.CompareSessionIDs();
1388          auto msg_data_1 = m_rng.randbytes<uint8_t>(m_rng.randrange(100000));
1389          auto msg_data_2 = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));
1390          tester.SendMessage(uint8_t(14), msg_data_1); // inv short id
1391          tester.SendMessage(uint8_t(19), msg_data_2); // pong short id
1392          ret = tester.Interact();
1393          BOOST_REQUIRE(ret && ret->size() == 2);
1394          BOOST_CHECK((*ret)[0] && (*ret)[0]->m_type == "inv" && std::ranges::equal((*ret)[0]->m_recv, MakeByteSpan(msg_data_1)));
1395          BOOST_CHECK((*ret)[1] && (*ret)[1]->m_type == "pong" && std::ranges::equal((*ret)[1]->m_recv, MakeByteSpan(msg_data_2)));
1396  
1397          // Then send a too-large message.
1398          auto msg_data_3 = m_rng.randbytes<uint8_t>(4005000);
1399          tester.SendMessage(uint8_t(11), msg_data_3); // getdata short id
1400          ret = tester.Interact();
1401          BOOST_CHECK(!ret);
1402      }
1403  
1404      // Various valid but unusual scenarios.
1405      for (int i = 0; i < 50; ++i) {
1406          /** Whether an initiator or responder is being tested. */
1407          bool initiator = m_rng.randbool();
1408          /** Use either 0 bytes or the maximum possible (4095 bytes) garbage length. */
1409          size_t garb_len = m_rng.randbool() ? 0 : V2Transport::MAX_GARBAGE_LEN;
1410          /** How many decoy packets to send before the version packet. */
1411          unsigned num_ignore_version = m_rng.randrange(10);
1412          /** What data to send in the version packet (ignored by BIP324 peers, but reserved for future extensions). */
1413          auto ver_data = m_rng.randbytes<uint8_t>(m_rng.randbool() ? 0 : m_rng.randrange(1000));
1414          /** Whether to immediately send key and garbage out (required for responders, optional otherwise). */
1415          bool send_immediately = !initiator || m_rng.randbool();
1416          /** How many decoy packets to send before the first and second real message. */
1417          unsigned num_decoys_1 = m_rng.randrange(1000), num_decoys_2 = m_rng.randrange(1000);
1418          V2TransportTester tester(m_rng, initiator);
1419          if (send_immediately) {
1420              tester.SendKey();
1421              tester.SendGarbage(garb_len);
1422          }
1423          auto ret = tester.Interact();
1424          BOOST_REQUIRE(ret && ret->empty());
1425          if (!send_immediately) {
1426              tester.SendKey();
1427              tester.SendGarbage(garb_len);
1428          }
1429          tester.ReceiveKey();
1430          tester.SendGarbageTerm();
1431          for (unsigned v = 0; v < num_ignore_version; ++v) {
1432              size_t ver_ign_data_len = m_rng.randbool() ? 0 : m_rng.randrange(1000);
1433              auto ver_ign_data = m_rng.randbytes<uint8_t>(ver_ign_data_len);
1434              tester.SendVersion(ver_ign_data, true);
1435          }
1436          tester.SendVersion(ver_data, false);
1437          ret = tester.Interact();
1438          BOOST_REQUIRE(ret && ret->empty());
1439          tester.ReceiveGarbage();
1440          tester.ReceiveVersion();
1441          tester.CompareSessionIDs();
1442          for (unsigned d = 0; d < num_decoys_1; ++d) {
1443              auto decoy_data = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));
1444              tester.SendPacket(/*content=*/decoy_data, /*aad=*/{}, /*ignore=*/true);
1445          }
1446          auto msg_data_1 = m_rng.randbytes<uint8_t>(m_rng.randrange(4000000));
1447          tester.SendMessage(uint8_t(28), msg_data_1);
1448          for (unsigned d = 0; d < num_decoys_2; ++d) {
1449              auto decoy_data = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));
1450              tester.SendPacket(/*content=*/decoy_data, /*aad=*/{}, /*ignore=*/true);
1451          }
1452          auto msg_data_2 = m_rng.randbytes<uint8_t>(m_rng.randrange(1000));
1453          tester.SendMessage(uint8_t(13), msg_data_2); // headers short id
1454          // Send invalidly-encoded message
1455          tester.SendMessage(std::string("blocktxn\x00\x00\x00a", CMessageHeader::MESSAGE_TYPE_SIZE), {});
1456          tester.SendMessage("foobar", {}); // test receiving unknown message type
1457          tester.AddMessage("barfoo", {}); // test sending unknown message type
1458          ret = tester.Interact();
1459          BOOST_REQUIRE(ret && ret->size() == 4);
1460          BOOST_CHECK((*ret)[0] && (*ret)[0]->m_type == "addrv2" && std::ranges::equal((*ret)[0]->m_recv, MakeByteSpan(msg_data_1)));
1461          BOOST_CHECK((*ret)[1] && (*ret)[1]->m_type == "headers" && std::ranges::equal((*ret)[1]->m_recv, MakeByteSpan(msg_data_2)));
1462          BOOST_CHECK(!(*ret)[2]);
1463          BOOST_CHECK((*ret)[3] && (*ret)[3]->m_type == "foobar" && (*ret)[3]->m_recv.empty());
1464          tester.ReceiveMessage("barfoo", {});
1465      }
1466  
1467      // Too long garbage (initiator).
1468      {
1469          V2TransportTester tester(m_rng, true);
1470          auto ret = tester.Interact();
1471          BOOST_REQUIRE(ret && ret->empty());
1472          tester.SendKey();
1473          tester.SendGarbage(V2Transport::MAX_GARBAGE_LEN + 1);
1474          tester.ReceiveKey();
1475          tester.SendGarbageTerm();
1476          ret = tester.Interact();
1477          BOOST_CHECK(!ret);
1478      }
1479  
1480      // Too long garbage (responder).
1481      {
1482          V2TransportTester tester(m_rng, false);
1483          tester.SendKey();
1484          tester.SendGarbage(V2Transport::MAX_GARBAGE_LEN + 1);
1485          auto ret = tester.Interact();
1486          BOOST_REQUIRE(ret && ret->empty());
1487          tester.ReceiveKey();
1488          tester.SendGarbageTerm();
1489          ret = tester.Interact();
1490          BOOST_CHECK(!ret);
1491      }
1492  
1493      // Send garbage that includes the first 15 garbage terminator bytes somewhere.
1494      {
1495          V2TransportTester tester(m_rng, true);
1496          auto ret = tester.Interact();
1497          BOOST_REQUIRE(ret && ret->empty());
1498          tester.SendKey();
1499          tester.ReceiveKey();
1500          /** The number of random garbage bytes before the included first 15 bytes of terminator. */
1501          size_t len_before = m_rng.randrange(V2Transport::MAX_GARBAGE_LEN - 16 + 1);
1502          /** The number of random garbage bytes after it. */
1503          size_t len_after = m_rng.randrange(V2Transport::MAX_GARBAGE_LEN - 16 - len_before + 1);
1504          // Construct len_before + 16 + len_after random bytes.
1505          auto garbage = m_rng.randbytes<uint8_t>(len_before + 16 + len_after);
1506          // Replace the designed 16 bytes in the middle with the to-be-sent garbage terminator.
1507          auto garb_term = MakeUCharSpan(tester.GetCipher().GetSendGarbageTerminator());
1508          std::copy(garb_term.begin(), garb_term.begin() + 16, garbage.begin() + len_before);
1509          // Introduce a bit error in the last byte of that copied garbage terminator, making only
1510          // the first 15 of them match.
1511          garbage[len_before + 15] ^= (uint8_t(1) << m_rng.randrange(8));
1512          tester.SendGarbage(garbage);
1513          tester.SendGarbageTerm();
1514          tester.SendVersion();
1515          ret = tester.Interact();
1516          BOOST_REQUIRE(ret && ret->empty());
1517          tester.ReceiveGarbage();
1518          tester.ReceiveVersion();
1519          tester.CompareSessionIDs();
1520          auto msg_data_1 = m_rng.randbytes<uint8_t>(4000000); // test that receiving 4M payload works
1521          auto msg_data_2 = m_rng.randbytes<uint8_t>(4000000); // test that sending 4M payload works
1522          tester.SendMessage(uint8_t(m_rng.randrange(223) + 33), {}); // unknown short id
1523          tester.SendMessage(uint8_t(2), msg_data_1); // "block" short id
1524          tester.AddMessage("blocktxn", msg_data_2); // schedule blocktxn to be sent to us
1525          ret = tester.Interact();
1526          BOOST_REQUIRE(ret && ret->size() == 2);
1527          BOOST_CHECK(!(*ret)[0]);
1528          BOOST_CHECK((*ret)[1] && (*ret)[1]->m_type == "block" && std::ranges::equal((*ret)[1]->m_recv, MakeByteSpan(msg_data_1)));
1529          tester.ReceiveMessage(uint8_t(3), msg_data_2); // "blocktxn" short id
1530      }
1531  
1532      // Send correct network's V1 header
1533      {
1534          V2TransportTester tester(m_rng, false);
1535          tester.SendV1Version(Params().MessageStart());
1536          auto ret = tester.Interact();
1537          BOOST_CHECK(ret);
1538      }
1539  
1540      // Send wrong network's V1 header
1541      {
1542          V2TransportTester tester(m_rng, false);
1543          tester.SendV1Version(CChainParams::Main()->MessageStart());
1544          auto ret = tester.Interact();
1545          BOOST_CHECK(!ret);
1546      }
1547  }
1548  
1549  BOOST_AUTO_TEST_SUITE_END()