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