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