PIVX Core  5.6.99
P2P Digital Currency
net_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2016 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 "addrman.h"
6 #include "chainparams.h"
7 #include "hash.h"
8 #include "net.h"
9 #include "netbase.h"
10 #include "serialize.h"
11 #include "span.h"
12 #include "streams.h"
13 #include "version.h"
14 
15 #include <cstdint>
16 
17 #include "test/test_pivx.h"
18 
19 #include <ios>
20 #include <string>
21 
22 #include <boost/test/unit_test.hpp>
23 
25 {
26 public:
27  virtual void Serialize(CDataStream::CBaseDataStream& s) const = 0;
28 
31  {
32  nKey.SetNull();
33  SeedInsecureRand(SeedRand::ZEROS);
34  }
35 };
36 
38 {
39 public:
41  {
43  }
44 };
45 
47 {
48 public:
50  {
51  // Produces corrupt output that claims addrman has 20 addrs when it only has one addr.
52  unsigned char nVersion = 1;
53  s << nVersion;
54  s << ((unsigned char)32);
55  s << nKey;
56  s << 10; // nNew
57  s << 10; // nTried
58 
59  int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
60  s << nUBuckets;
61 
62  CService serv;
63  Lookup("252.1.1.1", serv, 7777, false);
64  CAddress addr = CAddress(serv, NODE_NONE);
65  CNetAddr resolved;
66  LookupHost("252.2.2.2", resolved, false);
67  CAddrInfo info = CAddrInfo(addr, resolved);
68  s << info;
69  }
70 };
71 
73 {
74  CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
75  ssPeersIn << Params().MessageStart();
76  ssPeersIn << addrman;
77  std::string str = ssPeersIn.str();
78  std::vector<unsigned char> vchData(str.begin(), str.end());
79  return CDataStream(vchData, SER_DISK, CLIENT_VERSION);
80 }
81 
83 
84 BOOST_AUTO_TEST_CASE(cnode_listen_port)
85 {
86  // test default
87  uint16_t port = GetListenPort();
88  BOOST_CHECK(port == Params().GetDefaultPort());
89  // test set port
90  uint16_t altPort = 12345;
91  BOOST_CHECK(gArgs.SoftSetArg("-port", std::to_string(altPort)));
92  port = GetListenPort();
93  BOOST_CHECK(port == altPort);
94 }
95 
96 BOOST_AUTO_TEST_CASE(caddrdb_read)
97 {
98  CAddrManUncorrupted addrmanUncorrupted;
99  addrmanUncorrupted.MakeDeterministic();
100 
101  CService addr1, addr2, addr3;
102  BOOST_CHECK(Lookup("250.7.1.1", addr1, 8333, false));
103  BOOST_CHECK(Lookup("250.7.2.2", addr2, 9999, false));
104  BOOST_CHECK(Lookup("250.7.3.3", addr3, 9999, false));
105  BOOST_CHECK(Lookup(std::string("250.7.3.3", 9), addr3, 9999, false));
106  BOOST_CHECK(!Lookup(std::string("250.7.3.3\0example.com", 21), addr3, 9999, false));
107 
108  // Add three addresses to new table.
110  Lookup("252.5.1.1", source, 8333, false);
111  addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), source);
112  addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), source);
113  addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), source);
114 
115  // Test that the de-serialization does not throw an exception.
116  CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
117  bool exceptionThrown = false;
118  CAddrMan addrman1;
119 
120  BOOST_CHECK(addrman1.size() == 0);
121  try {
122  unsigned char pchMsgTmp[4];
123  ssPeers1 >> pchMsgTmp;
124  ssPeers1 >> addrman1;
125  } catch (const std::exception& e) {
126  exceptionThrown = true;
127  }
128 
129  BOOST_CHECK(addrman1.size() == 3);
130  BOOST_CHECK(exceptionThrown == false);
131 
132  // Test that CAddrDB::Read creates an addrman with the correct number of addrs.
133  CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
134 
135  CAddrMan addrman2;
136  BOOST_CHECK(addrman2.size() == 0);
137  BOOST_CHECK(CAddrDB::Read(addrman2, ssPeers2));
138  BOOST_CHECK(addrman2.size() == 3);
139 }
140 
141 
142 BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
143 {
144  CAddrManCorrupted addrmanCorrupted;
145  addrmanCorrupted.MakeDeterministic();
146 
147  // Test that the de-serialization of corrupted addrman throws an exception.
148  CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted);
149  bool exceptionThrown = false;
150  CAddrMan addrman1;
151  BOOST_CHECK(addrman1.size() == 0);
152  try {
153  unsigned char pchMsgTmp[4];
154  ssPeers1 >> pchMsgTmp;
155  ssPeers1 >> addrman1;
156  } catch (const std::exception& e) {
157  exceptionThrown = true;
158  }
159  // Even through de-serialization failed addrman is not left in a clean state.
160  BOOST_CHECK(addrman1.size() == 1);
161  BOOST_CHECK(exceptionThrown);
162 
163  // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails.
164  CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted);
165 
166  CAddrMan addrman2;
167  BOOST_CHECK(addrman2.size() == 0);
168  BOOST_CHECK(!CAddrDB::Read(addrman2, ssPeers2));
169  BOOST_CHECK(addrman2.size() == 0);
170 }
171 
172 BOOST_AUTO_TEST_CASE(cnode_simple_test)
173 {
174  SOCKET hSocket = INVALID_SOCKET;
175  NodeId id = 0;
176  int height = 0;
177 
178  in_addr ipv4Addr;
179  ipv4Addr.s_addr = 0xa0b0c001;
180 
181  CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
182  std::string pszDest = "";
183  bool fInboundIn = false;
184 
185  // Test that fFeeler is false by default.
186  std::unique_ptr<CNode> pnode1(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 0, 0, pszDest, fInboundIn));
187  BOOST_CHECK(pnode1->fInbound == false);
188  BOOST_CHECK(pnode1->fFeeler == false);
189 
190  fInboundIn = true;
191  std::unique_ptr<CNode> pnode2(new CNode(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, pszDest, fInboundIn));
192  BOOST_CHECK(pnode2->fInbound == true);
193  BOOST_CHECK(pnode2->fFeeler == false);
194 }
195 
196 BOOST_AUTO_TEST_CASE(cnetaddr_basic)
197 {
198  CNetAddr addr;
199 
200  // IPv4, INADDR_ANY
201  BOOST_REQUIRE(LookupHost("0.0.0.0", addr, false));
202  BOOST_REQUIRE(!addr.IsValid());
203  BOOST_REQUIRE(addr.IsIPv4());
204 
205  BOOST_CHECK(addr.IsBindAny());
207  BOOST_CHECK_EQUAL(addr.ToString(), "0.0.0.0");
208 
209  // IPv4, INADDR_NONE
210  BOOST_REQUIRE(LookupHost("255.255.255.255", addr, false));
211  BOOST_REQUIRE(!addr.IsValid());
212  BOOST_REQUIRE(addr.IsIPv4());
213 
214  BOOST_CHECK(!addr.IsBindAny());
216  BOOST_CHECK_EQUAL(addr.ToString(), "255.255.255.255");
217 
218  // IPv4, casual
219  BOOST_REQUIRE(LookupHost("12.34.56.78", addr, false));
220  BOOST_REQUIRE(addr.IsValid());
221  BOOST_REQUIRE(addr.IsIPv4());
222 
223  BOOST_CHECK(!addr.IsBindAny());
225  BOOST_CHECK_EQUAL(addr.ToString(), "12.34.56.78");
226 
227  // IPv6, in6addr_any
228  BOOST_REQUIRE(LookupHost("::", addr, false));
229  BOOST_REQUIRE(!addr.IsValid());
230  BOOST_REQUIRE(addr.IsIPv6());
231 
232  BOOST_CHECK(addr.IsBindAny());
234  BOOST_CHECK_EQUAL(addr.ToString(), "::");
235 
236  // IPv6, casual
237  BOOST_REQUIRE(LookupHost("1122:3344:5566:7788:9900:aabb:ccdd:eeff", addr, false));
238  BOOST_REQUIRE(addr.IsValid());
239  BOOST_REQUIRE(addr.IsIPv6());
240 
241  BOOST_CHECK(!addr.IsBindAny());
243  BOOST_CHECK_EQUAL(addr.ToString(), "1122:3344:5566:7788:9900:aabb:ccdd:eeff");
244 
245  // TORv2
246  BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion"));
247  BOOST_REQUIRE(addr.IsValid());
248  BOOST_REQUIRE(addr.IsTor());
249 
250  BOOST_CHECK(!addr.IsBindAny());
252  BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion");
253 
254  // TORv3
255  const char* torv3_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";
256  BOOST_REQUIRE(addr.SetSpecial(torv3_addr));
257  BOOST_REQUIRE(addr.IsValid());
258  BOOST_REQUIRE(addr.IsTor());
259 
260  BOOST_CHECK(!addr.IsBindAny());
262  BOOST_CHECK_EQUAL(addr.ToString(), torv3_addr);
263 
264  // TORv3, broken, with wrong checksum
265  BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.onion"));
266 
267  // TORv3, broken, with wrong version
268  BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrye.onion"));
269 
270  // TORv3, malicious
271  BOOST_CHECK(!addr.SetSpecial(std::string{
272  "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd\0wtf.onion", 66}));
273 
274  // TOR, bogus length
275  BOOST_CHECK(!addr.SetSpecial(std::string{"mfrggzak.onion"}));
276 
277  // TOR, invalid base32
278  BOOST_CHECK(!addr.SetSpecial(std::string{"mf*g zak.onion"}));
279 
280  // Internal
281  addr.SetInternal("esffpp");
282  BOOST_REQUIRE(!addr.IsValid()); // "internal" is considered invalid
283  BOOST_REQUIRE(addr.IsInternal());
284 
285  BOOST_CHECK(!addr.IsBindAny());
287  BOOST_CHECK_EQUAL(addr.ToString(), "esffpvrt3wpeaygy.internal");
288 
289  // Totally bogus
290  BOOST_CHECK(!addr.SetSpecial("totally bogus"));
291 }
292 
293 BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
294 {
295  CNetAddr addr;
296  CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
297 
298  s << addr;
299  BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
300  s.clear();
301 
302  BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false));
303  s << addr;
304  BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
305  s.clear();
306 
307  BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false));
308  s << addr;
309  BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
310  s.clear();
311 
312  BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion"));
313  s << addr;
314  BOOST_CHECK_EQUAL(HexStr(s), "fd87d87eeb43f1f2f3f4f5f6f7f8f9fa");
315  s.clear();
316 
317  BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
318  s << addr;
319  BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
320  s.clear();
321 
322  addr.SetInternal("a");
323  s << addr;
324  BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
325  s.clear();
326 }
327 
328 BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
329 {
330  CNetAddr addr;
331  CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
332  // Add ADDRV2_FORMAT to the version so that the CNetAddr
333  // serialize method produces an address in v2 format.
334  s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
335 
336  s << addr;
337  BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
338  s.clear();
339 
340  BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false));
341  s << addr;
342  BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
343  s.clear();
344 
345  BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false));
346  s << addr;
347  BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
348  s.clear();
349 
350  BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion"));
351  s << addr;
352  BOOST_CHECK_EQUAL(HexStr(s), "030af1f2f3f4f5f6f7f8f9fa");
353  s.clear();
354 
355  BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
356  s << addr;
357  BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
358  s.clear();
359 
360  BOOST_REQUIRE(addr.SetInternal("a"));
361  s << addr;
362  BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
363  s.clear();
364 }
365 
366 BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
367 {
368  CNetAddr addr;
369  CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
370  // Add ADDRV2_FORMAT to the version so that the CNetAddr
371  // unserialize method expects an address in v2 format.
372  s.SetVersion(s.GetVersion() | ADDRV2_FORMAT);
373 
374  // Valid IPv4.
375  s << MakeSpan(ParseHex("01" // network type (IPv4)
376  "04" // address length
377  "01020304")); // address
378  s >> addr;
379  BOOST_CHECK(addr.IsValid());
380  BOOST_CHECK(addr.IsIPv4());
382  BOOST_CHECK_EQUAL(addr.ToString(), "1.2.3.4");
383  BOOST_REQUIRE(s.empty());
384 
385  // Invalid IPv4, valid length but address itself is shorter.
386  s << MakeSpan(ParseHex("01" // network type (IPv4)
387  "04" // address length
388  "0102")); // address
389  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, HasReason("end of data"));
390  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
391  s.clear();
392 
393  // Invalid IPv4, with bogus length.
394  s << MakeSpan(ParseHex("01" // network type (IPv4)
395  "05" // address length
396  "01020304")); // address
397  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
398  HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
399  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
400  s.clear();
401 
402  // Invalid IPv4, with extreme length.
403  s << MakeSpan(ParseHex("01" // network type (IPv4)
404  "fd0102" // address length (513 as CompactSize)
405  "01020304")); // address
406  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
407  HasReason("Address too long: 513 > 512"));
408  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
409  s.clear();
410 
411  // Valid IPv6.
412  s << MakeSpan(ParseHex("02" // network type (IPv6)
413  "10" // address length
414  "0102030405060708090a0b0c0d0e0f10")); // address
415  s >> addr;
416  BOOST_CHECK(addr.IsValid());
417  BOOST_CHECK(addr.IsIPv6());
419  BOOST_CHECK_EQUAL(addr.ToString(), "102:304:506:708:90a:b0c:d0e:f10");
420  BOOST_REQUIRE(s.empty());
421 
422  // Valid IPv6, contains embedded "internal".
423  s << MakeSpan(ParseHex(
424  "02" // network type (IPv6)
425  "10" // address length
426  "fd6b88c08724ca978112ca1bbdcafac2")); // address: 0xfd + sha256("bitcoin")[0:5] +
427  // sha256(name)[0:10]
428  s >> addr;
429  BOOST_CHECK(addr.IsInternal());
431  BOOST_CHECK_EQUAL(addr.ToString(), "zklycewkdo64v6wc.internal");
432  BOOST_REQUIRE(s.empty());
433 
434  // Invalid IPv6, with bogus length.
435  s << MakeSpan(ParseHex("02" // network type (IPv6)
436  "04" // address length
437  "00")); // address
438  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
439  HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
440  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
441  s.clear();
442 
443  // Invalid IPv6, contains embedded IPv4.
444  s << MakeSpan(ParseHex("02" // network type (IPv6)
445  "10" // address length
446  "00000000000000000000ffff01020304")); // address
447  s >> addr;
448  BOOST_CHECK(!addr.IsValid());
449  BOOST_REQUIRE(s.empty());
450 
451  // Invalid IPv6, contains embedded TORv2.
452  s << MakeSpan(ParseHex("02" // network type (IPv6)
453  "10" // address length
454  "fd87d87eeb430102030405060708090a")); // address
455  s >> addr;
456  BOOST_CHECK(!addr.IsValid());
457  BOOST_REQUIRE(s.empty());
458 
459  // Valid TORv2.
460  s << MakeSpan(ParseHex("03" // network type (TORv2)
461  "0a" // address length
462  "f1f2f3f4f5f6f7f8f9fa")); // address
463  s >> addr;
464  BOOST_CHECK(addr.IsValid());
465  BOOST_CHECK(addr.IsTor());
467  BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion");
468  BOOST_REQUIRE(s.empty());
469 
470  // Invalid TORv2, with bogus length.
471  s << MakeSpan(ParseHex("03" // network type (TORv2)
472  "07" // address length
473  "00")); // address
474  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
475  HasReason("BIP155 TORv2 address with length 7 (should be 10)"));
476  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
477  s.clear();
478 
479  // Valid TORv3.
480  s << MakeSpan(ParseHex("04" // network type (TORv3)
481  "20" // address length
482  "79bcc625184b05194975c28b66b66b04" // address
483  "69f7f6556fb1ac3189a79b40dda32f1f"
484  ));
485  s >> addr;
486  BOOST_CHECK(addr.IsValid());
487  BOOST_CHECK(addr.IsTor());
490  "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion");
491  BOOST_REQUIRE(s.empty());
492 
493  // Invalid TORv3, with bogus length.
494  s << MakeSpan(ParseHex("04" // network type (TORv3)
495  "00" // address length
496  "00" // address
497  ));
498  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
499  HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
500  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
501  s.clear();
502 
503  // Valid I2P.
504  s << MakeSpan(ParseHex("05" // network type (I2P)
505  "20" // address length
506  "a2894dabaec08c0051a481a6dac88b64" // address
507  "f98232ae42d4b6fd2fa81952dfe36a87"));
508  s >> addr;
509  BOOST_CHECK(addr.IsValid());
510  BOOST_CHECK(addr.IsI2P());
513  "ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p");
514  BOOST_REQUIRE(s.empty());
515 
516  // Invalid I2P, with bogus length.
517  s << MakeSpan(ParseHex("05" // network type (I2P)
518  "03" // address length
519  "00" // address
520  ));
521  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
522  HasReason("BIP155 I2P address with length 3 (should be 32)"));
523  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
524  s.clear();
525 
526  // Valid CJDNS.
527  s << MakeSpan(ParseHex("06" // network type (CJDNS)
528  "10" // address length
529  "fc000001000200030004000500060007" // address
530  ));
531  s >> addr;
532  BOOST_CHECK(addr.IsValid());
533  BOOST_CHECK(addr.IsCJDNS());
535  BOOST_CHECK_EQUAL(addr.ToString(), "fc00:1:2:3:4:5:6:7");
536  BOOST_REQUIRE(s.empty());
537 
538  // Invalid CJDNS, with bogus length.
539  s << MakeSpan(ParseHex("06" // network type (CJDNS)
540  "01" // address length
541  "00" // address
542  ));
543  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
544  HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
545  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
546  s.clear();
547 
548  // Unknown, with extreme length.
549  s << MakeSpan(ParseHex("aa" // network type (unknown)
550  "fe00000002" // address length (CompactSize's MAX_SIZE)
551  "01020304050607" // address
552  ));
553  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
554  HasReason("Address too long: 33554432 > 512"));
555  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
556  s.clear();
557 
558  // Unknown, with reasonable length.
559  s << MakeSpan(ParseHex("aa" // network type (unknown)
560  "04" // address length
561  "01020304" // address
562  ));
563  s >> addr;
564  BOOST_CHECK(!addr.IsValid());
565  BOOST_REQUIRE(s.empty());
566 
567  // Unknown, with zero length.
568  s << MakeSpan(ParseHex("aa" // network type (unknown)
569  "00" // address length
570  "" // address
571  ));
572  s >> addr;
573  BOOST_CHECK(!addr.IsValid());
574  BOOST_REQUIRE(s.empty());
575 }
576 
577 // prior to PR #14728, this test triggers an undefined behavior
578 BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
579 {
580  // set up local addresses; all that's necessary to reproduce the bug is
581  // that a normal IPv4 address is among the entries, but if this address is
582  // !IsRoutable the undefined behavior is easier to trigger deterministically
583  {
585  in_addr ipv4AddrLocal;
586  ipv4AddrLocal.s_addr = 0x0100007f;
587  CNetAddr addr = CNetAddr(ipv4AddrLocal);
588  LocalServiceInfo lsi;
589  lsi.nScore = 23;
590  lsi.nPort = 42;
591  mapLocalHost[addr] = lsi;
592  }
593 
594  // create a peer with an IPv4 address
595  in_addr ipv4AddrPeer;
596  ipv4AddrPeer.s_addr = 0xa0b0c001;
597  CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
598  std::unique_ptr<CNode> pnode = std::make_unique<CNode>(0, NODE_NETWORK, 0, INVALID_SOCKET, addr, 0, 0, std::string{}, false);
599  pnode->fSuccessfullyConnected.store(true);
600 
601  // the peer claims to be reaching us via IPv6
602  in6_addr ipv6AddrLocal;
603  memset(ipv6AddrLocal.s6_addr, 0, 16);
604  ipv6AddrLocal.s6_addr[0] = 0xcc;
605  CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK);
606  pnode->SetAddrLocal(addrLocal);
607 
608  // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
609  AdvertiseLocal(&*pnode);
610 
611  // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
612  BOOST_CHECK(1);
613 }
614 
615 
616 BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
617 {
621 
622  SetReachable(NET_IPV4, false);
623  SetReachable(NET_IPV6, false);
624  SetReachable(NET_ONION, false);
625 
629 
630  SetReachable(NET_IPV4, true);
631  SetReachable(NET_IPV6, true);
632  SetReachable(NET_ONION, true);
633 
637 }
638 
639 BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
640 {
643 
645  SetReachable(NET_INTERNAL, false);
646 
647  BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true); // Ignored for both networks
649 }
650 
651 CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
652 {
653  unsigned char ip[] = {p1, p2, p3, p4};
654 
655  struct sockaddr_in sa;
656  memset(&sa, 0, sizeof(sockaddr_in)); // initialize the memory block
657  memcpy(&(sa.sin_addr), &ip, sizeof(ip));
658  return CNetAddr(sa.sin_addr);
659 }
660 
661 
662 BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
663 {
664  CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
665 
666  SetReachable(NET_IPV4, true);
667  BOOST_CHECK_EQUAL(IsReachable(addr), true);
668 
669  SetReachable(NET_IPV4, false);
670  BOOST_CHECK_EQUAL(IsReachable(addr), false);
671 
672  SetReachable(NET_IPV4, true); // have to reset this, because this is stateful.
673 }
674 
675 
676 BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
677 {
678  CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
679 
680  SetReachable(NET_IPV4, true);
681 
682  BOOST_CHECK_EQUAL(IsLocal(addr), false);
683  BOOST_CHECK_EQUAL(AddLocal(addr, 1000), true);
684  BOOST_CHECK_EQUAL(IsLocal(addr), true);
685 
686  RemoveLocal(addr);
687  BOOST_CHECK_EQUAL(IsLocal(addr), false);
688 }
689 
691 {
693 
694  int64_t now = 5000;
695  int average_interval_seconds = 600;
696 
697  auto poisson = ::PoissonNextSend(now, average_interval_seconds);
698  std::chrono::microseconds poisson_chrono = ::PoissonNextSend(std::chrono::microseconds{now}, std::chrono::seconds{average_interval_seconds});
699 
700  BOOST_CHECK_EQUAL(poisson, poisson_chrono.count());
701 
703 }
704 
CService ip(uint32_t i)
Definition: DoS_tests.cpp:39
#define ADDRMAN_NEW_BUCKET_COUNT
Definition: addrman.h:165
const CChainParams & Params()
Return the currently selected parameters.
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:473
bool Read(CAddrMan &addr)
Definition: addrdb.cpp:148
Extended statistics about a CAddress.
Definition: addrman.h:37
void Serialize(CDataStream::CBaseDataStream &s) const
Definition: net_tests.cpp:49
Stochastical (IP) address manager.
Definition: addrman.h:178
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:623
void Serialize(Stream &s_) const
Serialized format.
Definition: addrman.h:363
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.h:603
uint256 nKey
secret key to randomize bucket select with
Definition: addrman.h:239
virtual void Serialize(CDataStream::CBaseDataStream &s) const =0
void MakeDeterministic()
Ensure that bucket placement is always the same for testing purposes.
Definition: net_tests.cpp:30
void Serialize(CDataStream::CBaseDataStream &s) const
Definition: net_tests.cpp:40
A CService with information about it as peer.
Definition: protocol.h:338
CBaseDataStream(int nTypeIn, int nVersionIn)
Definition: streams.h:95
void SetVersion(int n)
Definition: streams.h:259
bool empty() const
Definition: streams.h:166
std::string str() const
Definition: streams.h:152
void clear()
Definition: streams.h:171
int GetVersion() const
Definition: streams.h:260
const CMessageHeader::MessageStartChars & MessageStart() const
Definition: chainparams.h:73
Network address.
Definition: netaddress.h:120
bool IsBindAny() const
Definition: netaddress.cpp:287
std::string ToString() const
Definition: netaddress.cpp:568
bool IsCJDNS() const
Check whether this object represents a CJDNS address.
Definition: netaddress.cpp:400
bool IsTor() const
Check whether this object represents a TOR address.
Definition: netaddress.cpp:390
bool IsValid() const
Definition: netaddress.cpp:418
bool IsIPv4() const
Definition: netaddress.cpp:295
bool SetSpecial(const std::string &strName)
Parse a TOR address and set this object to it.
Definition: netaddress.cpp:231
bool IsIPv6() const
Definition: netaddress.cpp:297
bool IsInternal() const
Definition: netaddress.cpp:464
bool SetInternal(const std::string &name)
Transform an arbitrary string into a non-routable ipv6 address.
Definition: netaddress.cpp:185
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
Definition: netaddress.cpp:469
bool IsI2P() const
Check whether this object represents an I2P address.
Definition: netaddress.cpp:395
Information about a peer.
Definition: net.h:669
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:484
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
Definition: test_pivx.h:169
void SetNull()
Definition: uint256.h:44
#define INVALID_SOCKET
Definition: compat.h:64
u_int SOCKET
Definition: compat.h:53
BOOST_AUTO_TEST_SUITE_END()
void * memcpy(void *a, const void *b, size_t c)
@ LOCK
Definition: lockunlock.h:16
bool RemoveLocal(const CService &addr)
Definition: net.cpp:237
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
Definition: net.cpp:92
uint16_t GetListenPort()
Definition: net.cpp:104
void AdvertiseLocal(CNode *pnode)
Definition: net.cpp:186
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:278
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:91
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
Definition: net.cpp:2846
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:245
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:206
bool IsReachable(enum Network net)
Definition: net.cpp:253
int NodeId
Definition: net.h:109
BOOST_AUTO_TEST_CASE(cnode_listen_port)
Definition: net_tests.cpp:84
CDataStream AddrmanToStream(CAddrManSerializationMock &addrman)
Definition: net_tests.cpp:72
CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
Definition: net_tests.cpp:651
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:55
@ NET_IPV6
IPv6.
Definition: netaddress.h:52
@ NET_IPV4
IPv4.
Definition: netaddress.h:49
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:46
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:65
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:177
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Definition: netbase.cpp:149
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
@ NODE_NONE
Definition: protocol.h:314
@ NODE_NETWORK
Definition: protocol.h:318
bool g_mock_deterministic_tests
Flag to make GetRand in random.h return the same number.
Definition: random.cpp:584
const char * source
Definition: rpcconsole.cpp:52
@ SER_DISK
Definition: serialize.h:175
@ SER_NETWORK
Definition: serialize.h:174
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
Definition: span.h:221
Basic testing setup.
Definition: test_pivx.h:51
int nScore
Definition: net.h:577
ArgsManager gArgs
Definition: system.cpp:89
@ ZEROS
Seed with a compile time constant of zeros.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::vector< unsigned char > ParseHex(const char *psz)