Bitcoin Core  22.99.0
P2P Digital Currency
net_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2021 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 <cstdint>
8 #include <net.h>
9 #include <netaddress.h>
10 #include <netbase.h>
11 #include <serialize.h>
12 #include <span.h>
13 #include <streams.h>
14 #include <test/util/setup_common.h>
15 #include <util/strencodings.h>
16 #include <util/string.h>
17 #include <util/system.h>
18 #include <version.h>
19 
20 #include <boost/test/unit_test.hpp>
21 
22 #include <algorithm>
23 #include <ios>
24 #include <memory>
25 #include <optional>
26 #include <string>
27 
28 using namespace std::literals;
29 
31 
32 BOOST_AUTO_TEST_CASE(cnode_listen_port)
33 {
34  // test default
35  uint16_t port{GetListenPort()};
36  BOOST_CHECK(port == Params().GetDefaultPort());
37  // test set port
38  uint16_t altPort = 12345;
39  BOOST_CHECK(gArgs.SoftSetArg("-port", ToString(altPort)));
40  port = GetListenPort();
41  BOOST_CHECK(port == altPort);
42 }
43 
44 BOOST_AUTO_TEST_CASE(cnode_simple_test)
45 {
46  NodeId id = 0;
47 
48  in_addr ipv4Addr;
49  ipv4Addr.s_addr = 0xa0b0c001;
50 
51  CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK);
52  std::string pszDest;
53 
54  std::unique_ptr<CNode> pnode1 = std::make_unique<CNode>(id++,
56  /*sock=*/nullptr,
57  addr,
58  /*nKeyedNetGroupIn=*/0,
59  /*nLocalHostNonceIn=*/0,
60  CAddress(),
61  pszDest,
63  /*inbound_onion=*/false);
64  BOOST_CHECK(pnode1->IsFullOutboundConn() == true);
65  BOOST_CHECK(pnode1->IsManualConn() == false);
66  BOOST_CHECK(pnode1->IsBlockOnlyConn() == false);
67  BOOST_CHECK(pnode1->IsFeelerConn() == false);
68  BOOST_CHECK(pnode1->IsAddrFetchConn() == false);
69  BOOST_CHECK(pnode1->IsInboundConn() == false);
70  BOOST_CHECK(pnode1->m_inbound_onion == false);
71  BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4);
72 
73  std::unique_ptr<CNode> pnode2 = std::make_unique<CNode>(id++,
75  /*sock=*/nullptr,
76  addr,
77  /*nKeyedNetGroupIn=*/1,
78  /*nLocalHostNonceIn=*/1,
79  CAddress(),
80  pszDest,
82  /*inbound_onion=*/false);
83  BOOST_CHECK(pnode2->IsFullOutboundConn() == false);
84  BOOST_CHECK(pnode2->IsManualConn() == false);
85  BOOST_CHECK(pnode2->IsBlockOnlyConn() == false);
86  BOOST_CHECK(pnode2->IsFeelerConn() == false);
87  BOOST_CHECK(pnode2->IsAddrFetchConn() == false);
88  BOOST_CHECK(pnode2->IsInboundConn() == true);
89  BOOST_CHECK(pnode2->m_inbound_onion == false);
90  BOOST_CHECK_EQUAL(pnode2->ConnectedThroughNetwork(), Network::NET_IPV4);
91 
92  std::unique_ptr<CNode> pnode3 = std::make_unique<CNode>(id++,
94  /*sock=*/nullptr,
95  addr,
96  /*nKeyedNetGroupIn=*/0,
97  /*nLocalHostNonceIn=*/0,
98  CAddress(),
99  pszDest,
101  /*inbound_onion=*/false);
102  BOOST_CHECK(pnode3->IsFullOutboundConn() == true);
103  BOOST_CHECK(pnode3->IsManualConn() == false);
104  BOOST_CHECK(pnode3->IsBlockOnlyConn() == false);
105  BOOST_CHECK(pnode3->IsFeelerConn() == false);
106  BOOST_CHECK(pnode3->IsAddrFetchConn() == false);
107  BOOST_CHECK(pnode3->IsInboundConn() == false);
108  BOOST_CHECK(pnode3->m_inbound_onion == false);
109  BOOST_CHECK_EQUAL(pnode3->ConnectedThroughNetwork(), Network::NET_IPV4);
110 
111  std::unique_ptr<CNode> pnode4 = std::make_unique<CNode>(id++,
112  NODE_NETWORK,
113  /*sock=*/nullptr,
114  addr,
115  /*nKeyedNetGroupIn=*/1,
116  /*nLocalHostNonceIn=*/1,
117  CAddress(),
118  pszDest,
120  /*inbound_onion=*/true);
121  BOOST_CHECK(pnode4->IsFullOutboundConn() == false);
122  BOOST_CHECK(pnode4->IsManualConn() == false);
123  BOOST_CHECK(pnode4->IsBlockOnlyConn() == false);
124  BOOST_CHECK(pnode4->IsFeelerConn() == false);
125  BOOST_CHECK(pnode4->IsAddrFetchConn() == false);
126  BOOST_CHECK(pnode4->IsInboundConn() == true);
127  BOOST_CHECK(pnode4->m_inbound_onion == true);
128  BOOST_CHECK_EQUAL(pnode4->ConnectedThroughNetwork(), Network::NET_ONION);
129 }
130 
131 BOOST_AUTO_TEST_CASE(cnetaddr_basic)
132 {
133  CNetAddr addr;
134 
135  // IPv4, INADDR_ANY
136  BOOST_REQUIRE(LookupHost("0.0.0.0", addr, false));
137  BOOST_REQUIRE(!addr.IsValid());
138  BOOST_REQUIRE(addr.IsIPv4());
139 
140  BOOST_CHECK(addr.IsBindAny());
142  BOOST_CHECK_EQUAL(addr.ToString(), "0.0.0.0");
143 
144  // IPv4, INADDR_NONE
145  BOOST_REQUIRE(LookupHost("255.255.255.255", addr, false));
146  BOOST_REQUIRE(!addr.IsValid());
147  BOOST_REQUIRE(addr.IsIPv4());
148 
149  BOOST_CHECK(!addr.IsBindAny());
151  BOOST_CHECK_EQUAL(addr.ToString(), "255.255.255.255");
152 
153  // IPv4, casual
154  BOOST_REQUIRE(LookupHost("12.34.56.78", addr, false));
155  BOOST_REQUIRE(addr.IsValid());
156  BOOST_REQUIRE(addr.IsIPv4());
157 
158  BOOST_CHECK(!addr.IsBindAny());
160  BOOST_CHECK_EQUAL(addr.ToString(), "12.34.56.78");
161 
162  // IPv6, in6addr_any
163  BOOST_REQUIRE(LookupHost("::", addr, false));
164  BOOST_REQUIRE(!addr.IsValid());
165  BOOST_REQUIRE(addr.IsIPv6());
166 
167  BOOST_CHECK(addr.IsBindAny());
169  BOOST_CHECK_EQUAL(addr.ToString(), "::");
170 
171  // IPv6, casual
172  BOOST_REQUIRE(LookupHost("1122:3344:5566:7788:9900:aabb:ccdd:eeff", addr, false));
173  BOOST_REQUIRE(addr.IsValid());
174  BOOST_REQUIRE(addr.IsIPv6());
175 
176  BOOST_CHECK(!addr.IsBindAny());
178  BOOST_CHECK_EQUAL(addr.ToString(), "1122:3344:5566:7788:9900:aabb:ccdd:eeff");
179 
180  // IPv6, scoped/link-local. See https://tools.ietf.org/html/rfc4007
181  // We support non-negative decimal integers (uint32_t) as zone id indices.
182  // Normal link-local scoped address functionality is to append "%" plus the
183  // zone id, for example, given a link-local address of "fe80::1" and a zone
184  // id of "32", return the address as "fe80::1%32".
185  const std::string link_local{"fe80::1"};
186  const std::string scoped_addr{link_local + "%32"};
187  BOOST_REQUIRE(LookupHost(scoped_addr, addr, false));
188  BOOST_REQUIRE(addr.IsValid());
189  BOOST_REQUIRE(addr.IsIPv6());
190  BOOST_CHECK(!addr.IsBindAny());
191  BOOST_CHECK_EQUAL(addr.ToString(), scoped_addr);
192 
193  // Test that the delimiter "%" and default zone id of 0 can be omitted for the default scope.
194  BOOST_REQUIRE(LookupHost(link_local + "%0", addr, false));
195  BOOST_REQUIRE(addr.IsValid());
196  BOOST_REQUIRE(addr.IsIPv6());
197  BOOST_CHECK(!addr.IsBindAny());
198  BOOST_CHECK_EQUAL(addr.ToString(), link_local);
199 
200  // TORv2, no longer supported
201  BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
202 
203  // TORv3
204  const char* torv3_addr = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";
205  BOOST_REQUIRE(addr.SetSpecial(torv3_addr));
206  BOOST_REQUIRE(addr.IsValid());
207  BOOST_REQUIRE(addr.IsTor());
208 
209  BOOST_CHECK(!addr.IsI2P());
210  BOOST_CHECK(!addr.IsBindAny());
212  BOOST_CHECK_EQUAL(addr.ToString(), torv3_addr);
213 
214  // TORv3, broken, with wrong checksum
215  BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.onion"));
216 
217  // TORv3, broken, with wrong version
218  BOOST_CHECK(!addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscrye.onion"));
219 
220  // TORv3, malicious
221  BOOST_CHECK(!addr.SetSpecial(std::string{
222  "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd\0wtf.onion", 66}));
223 
224  // TOR, bogus length
225  BOOST_CHECK(!addr.SetSpecial(std::string{"mfrggzak.onion"}));
226 
227  // TOR, invalid base32
228  BOOST_CHECK(!addr.SetSpecial(std::string{"mf*g zak.onion"}));
229 
230  // I2P
231  const char* i2p_addr = "UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P";
232  BOOST_REQUIRE(addr.SetSpecial(i2p_addr));
233  BOOST_REQUIRE(addr.IsValid());
234  BOOST_REQUIRE(addr.IsI2P());
235 
236  BOOST_CHECK(!addr.IsTor());
237  BOOST_CHECK(!addr.IsBindAny());
239  BOOST_CHECK_EQUAL(addr.ToString(), ToLower(i2p_addr));
240 
241  // I2P, correct length, but decodes to less than the expected number of bytes.
242  BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jn=.b32.i2p"));
243 
244  // I2P, extra unnecessary padding
245  BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna=.b32.i2p"));
246 
247  // I2P, malicious
248  BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v\0wtf.b32.i2p"s));
249 
250  // I2P, valid but unsupported (56 Base32 characters)
251  // See "Encrypted LS with Base 32 Addresses" in
252  // https://geti2p.net/spec/encryptedleaseset.txt
253  BOOST_CHECK(
254  !addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.b32.i2p"));
255 
256  // I2P, invalid base32
257  BOOST_CHECK(!addr.SetSpecial(std::string{"tp*szydbh4dp.b32.i2p"}));
258 
259  // Internal
260  addr.SetInternal("esffpp");
261  BOOST_REQUIRE(!addr.IsValid()); // "internal" is considered invalid
262  BOOST_REQUIRE(addr.IsInternal());
263 
264  BOOST_CHECK(!addr.IsBindAny());
266  BOOST_CHECK_EQUAL(addr.ToString(), "esffpvrt3wpeaygy.internal");
267 
268  // Totally bogus
269  BOOST_CHECK(!addr.SetSpecial("totally bogus"));
270 }
271 
272 BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6)
273 {
274  // Test that CNetAddr::ToString formats IPv6 addresses with zero compression as described in
275  // RFC 5952 ("A Recommendation for IPv6 Address Text Representation").
276  const std::map<std::string, std::string> canonical_representations_ipv6{
277  {"0000:0000:0000:0000:0000:0000:0000:0000", "::"},
278  {"000:0000:000:00:0:00:000:0000", "::"},
279  {"000:000:000:000:000:000:000:000", "::"},
280  {"00:00:00:00:00:00:00:00", "::"},
281  {"0:0:0:0:0:0:0:0", "::"},
282  {"0:0:0:0:0:0:0:1", "::1"},
283  {"2001:0:0:1:0:0:0:1", "2001:0:0:1::1"},
284  {"2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"},
285  {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:db8:85a3::8a2e:370:7334"},
286  {"2001:0db8::0001", "2001:db8::1"},
287  {"2001:0db8::0001:0000", "2001:db8::1:0"},
288  {"2001:0db8::1:0:0:1", "2001:db8::1:0:0:1"},
289  {"2001:db8:0000:0:1::1", "2001:db8::1:0:0:1"},
290  {"2001:db8:0000:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
291  {"2001:db8:0:0:0:0:2:1", "2001:db8::2:1"},
292  {"2001:db8:0:0:0::1", "2001:db8::1"},
293  {"2001:db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"},
294  {"2001:db8:0:0:1::1", "2001:db8::1:0:0:1"},
295  {"2001:DB8:0:0:1::1", "2001:db8::1:0:0:1"},
296  {"2001:db8:0:0::1", "2001:db8::1"},
297  {"2001:db8:0:0:aaaa::1", "2001:db8::aaaa:0:0:1"},
298  {"2001:db8:0:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
299  {"2001:db8:0::1", "2001:db8::1"},
300  {"2001:db8:85a3:0:0:8a2e:370:7334", "2001:db8:85a3::8a2e:370:7334"},
301  {"2001:db8::0:1", "2001:db8::1"},
302  {"2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1"},
303  {"2001:DB8::1", "2001:db8::1"},
304  {"2001:db8::1", "2001:db8::1"},
305  {"2001:db8::1:0:0:1", "2001:db8::1:0:0:1"},
306  {"2001:db8::1:1:1:1:1", "2001:db8:0:1:1:1:1:1"},
307  {"2001:db8::aaaa:0:0:1", "2001:db8::aaaa:0:0:1"},
308  {"2001:db8:aaaa:bbbb:cccc:dddd:0:1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"},
309  {"2001:db8:aaaa:bbbb:cccc:dddd::1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"},
310  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
311  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
312  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:01", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
313  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"},
314  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
315  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
316  {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"},
317  };
318  for (const auto& [input_address, expected_canonical_representation_output] : canonical_representations_ipv6) {
319  CNetAddr net_addr;
320  BOOST_REQUIRE(LookupHost(input_address, net_addr, false));
321  BOOST_REQUIRE(net_addr.IsIPv6());
322  BOOST_CHECK_EQUAL(net_addr.ToString(), expected_canonical_representation_output);
323  }
324 }
325 
326 BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1)
327 {
328  CNetAddr addr;
330 
331  s << addr;
332  BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
333  s.clear();
334 
335  BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false));
336  s << addr;
337  BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304");
338  s.clear();
339 
340  BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false));
341  s << addr;
342  BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
343  s.clear();
344 
345  // TORv2, no longer supported
346  BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
347 
348  BOOST_REQUIRE(addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"));
349  s << addr;
350  BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000");
351  s.clear();
352 
353  addr.SetInternal("a");
354  s << addr;
355  BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2");
356  s.clear();
357 }
358 
359 BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2)
360 {
361  CNetAddr addr;
363  // Add ADDRV2_FORMAT to the version so that the CNetAddr
364  // serialize method produces an address in v2 format.
366 
367  s << addr;
368  BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000");
369  s.clear();
370 
371  BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false));
372  s << addr;
373  BOOST_CHECK_EQUAL(HexStr(s), "010401020304");
374  s.clear();
375 
376  BOOST_REQUIRE(LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false));
377  s << addr;
378  BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b");
379  s.clear();
380 
381  // TORv2, no longer supported
382  BOOST_CHECK(!addr.SetSpecial("6hzph5hv6337r6p2.onion"));
383 
384  BOOST_REQUIRE(addr.SetSpecial("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion"));
385  s << addr;
386  BOOST_CHECK_EQUAL(HexStr(s), "042053cd5648488c4707914182655b7664034e09e66f7e8cbf1084e654eb56c5bd88");
387  s.clear();
388 
389  BOOST_REQUIRE(addr.SetInternal("a"));
390  s << addr;
391  BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2");
392  s.clear();
393 }
394 
395 BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2)
396 {
397  CNetAddr addr;
399  // Add ADDRV2_FORMAT to the version so that the CNetAddr
400  // unserialize method expects an address in v2 format.
402 
403  // Valid IPv4.
404  s << Span{ParseHex("01" // network type (IPv4)
405  "04" // address length
406  "01020304")}; // address
407  s >> addr;
408  BOOST_CHECK(addr.IsValid());
409  BOOST_CHECK(addr.IsIPv4());
410  BOOST_CHECK(addr.IsAddrV1Compatible());
411  BOOST_CHECK_EQUAL(addr.ToString(), "1.2.3.4");
412  BOOST_REQUIRE(s.empty());
413 
414  // Invalid IPv4, valid length but address itself is shorter.
415  s << Span{ParseHex("01" // network type (IPv4)
416  "04" // address length
417  "0102")}; // address
418  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, HasReason("end of data"));
419  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
420  s.clear();
421 
422  // Invalid IPv4, with bogus length.
423  s << Span{ParseHex("01" // network type (IPv4)
424  "05" // address length
425  "01020304")}; // address
426  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
427  HasReason("BIP155 IPv4 address with length 5 (should be 4)"));
428  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
429  s.clear();
430 
431  // Invalid IPv4, with extreme length.
432  s << Span{ParseHex("01" // network type (IPv4)
433  "fd0102" // address length (513 as CompactSize)
434  "01020304")}; // address
435  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
436  HasReason("Address too long: 513 > 512"));
437  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
438  s.clear();
439 
440  // Valid IPv6.
441  s << Span{ParseHex("02" // network type (IPv6)
442  "10" // address length
443  "0102030405060708090a0b0c0d0e0f10")}; // address
444  s >> addr;
445  BOOST_CHECK(addr.IsValid());
446  BOOST_CHECK(addr.IsIPv6());
447  BOOST_CHECK(addr.IsAddrV1Compatible());
448  BOOST_CHECK_EQUAL(addr.ToString(), "102:304:506:708:90a:b0c:d0e:f10");
449  BOOST_REQUIRE(s.empty());
450 
451  // Valid IPv6, contains embedded "internal".
452  s << Span{ParseHex(
453  "02" // network type (IPv6)
454  "10" // address length
455  "fd6b88c08724ca978112ca1bbdcafac2")}; // address: 0xfd + sha256("bitcoin")[0:5] +
456  // sha256(name)[0:10]
457  s >> addr;
458  BOOST_CHECK(addr.IsInternal());
459  BOOST_CHECK(addr.IsAddrV1Compatible());
460  BOOST_CHECK_EQUAL(addr.ToString(), "zklycewkdo64v6wc.internal");
461  BOOST_REQUIRE(s.empty());
462 
463  // Invalid IPv6, with bogus length.
464  s << Span{ParseHex("02" // network type (IPv6)
465  "04" // address length
466  "00")}; // address
467  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
468  HasReason("BIP155 IPv6 address with length 4 (should be 16)"));
469  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
470  s.clear();
471 
472  // Invalid IPv6, contains embedded IPv4.
473  s << Span{ParseHex("02" // network type (IPv6)
474  "10" // address length
475  "00000000000000000000ffff01020304")}; // address
476  s >> addr;
477  BOOST_CHECK(!addr.IsValid());
478  BOOST_REQUIRE(s.empty());
479 
480  // Invalid IPv6, contains embedded TORv2.
481  s << Span{ParseHex("02" // network type (IPv6)
482  "10" // address length
483  "fd87d87eeb430102030405060708090a")}; // address
484  s >> addr;
485  BOOST_CHECK(!addr.IsValid());
486  BOOST_REQUIRE(s.empty());
487 
488  // TORv2, no longer supported.
489  s << Span{ParseHex("03" // network type (TORv2)
490  "0a" // address length
491  "f1f2f3f4f5f6f7f8f9fa")}; // address
492  s >> addr;
493  BOOST_CHECK(!addr.IsValid());
494  BOOST_REQUIRE(s.empty());
495 
496  // Valid TORv3.
497  s << Span{ParseHex("04" // network type (TORv3)
498  "20" // address length
499  "79bcc625184b05194975c28b66b66b04" // address
500  "69f7f6556fb1ac3189a79b40dda32f1f"
501  )};
502  s >> addr;
503  BOOST_CHECK(addr.IsValid());
504  BOOST_CHECK(addr.IsTor());
505  BOOST_CHECK(!addr.IsAddrV1Compatible());
506  BOOST_CHECK_EQUAL(addr.ToString(),
507  "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion");
508  BOOST_REQUIRE(s.empty());
509 
510  // Invalid TORv3, with bogus length.
511  s << Span{ParseHex("04" // network type (TORv3)
512  "00" // address length
513  "00" // address
514  )};
515  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
516  HasReason("BIP155 TORv3 address with length 0 (should be 32)"));
517  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
518  s.clear();
519 
520  // Valid I2P.
521  s << Span{ParseHex("05" // network type (I2P)
522  "20" // address length
523  "a2894dabaec08c0051a481a6dac88b64" // address
524  "f98232ae42d4b6fd2fa81952dfe36a87")};
525  s >> addr;
526  BOOST_CHECK(addr.IsValid());
527  BOOST_CHECK(addr.IsI2P());
528  BOOST_CHECK(!addr.IsAddrV1Compatible());
529  BOOST_CHECK_EQUAL(addr.ToString(),
530  "ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p");
531  BOOST_REQUIRE(s.empty());
532 
533  // Invalid I2P, with bogus length.
534  s << Span{ParseHex("05" // network type (I2P)
535  "03" // address length
536  "00" // address
537  )};
538  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
539  HasReason("BIP155 I2P address with length 3 (should be 32)"));
540  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
541  s.clear();
542 
543  // Valid CJDNS.
544  s << Span{ParseHex("06" // network type (CJDNS)
545  "10" // address length
546  "fc000001000200030004000500060007" // address
547  )};
548  s >> addr;
549  BOOST_CHECK(addr.IsValid());
550  BOOST_CHECK(addr.IsCJDNS());
551  BOOST_CHECK(!addr.IsAddrV1Compatible());
552  BOOST_CHECK_EQUAL(addr.ToString(), "fc00:1:2:3:4:5:6:7");
553  BOOST_REQUIRE(s.empty());
554 
555  // Invalid CJDNS, wrong prefix.
556  s << Span{ParseHex("06" // network type (CJDNS)
557  "10" // address length
558  "aa000001000200030004000500060007" // address
559  )};
560  s >> addr;
561  BOOST_CHECK(addr.IsCJDNS());
562  BOOST_CHECK(!addr.IsValid());
563  BOOST_REQUIRE(s.empty());
564 
565  // Invalid CJDNS, with bogus length.
566  s << Span{ParseHex("06" // network type (CJDNS)
567  "01" // address length
568  "00" // address
569  )};
570  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
571  HasReason("BIP155 CJDNS address with length 1 (should be 16)"));
572  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
573  s.clear();
574 
575  // Unknown, with extreme length.
576  s << Span{ParseHex("aa" // network type (unknown)
577  "fe00000002" // address length (CompactSize's MAX_SIZE)
578  "01020304050607" // address
579  )};
580  BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure,
581  HasReason("Address too long: 33554432 > 512"));
582  BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input.
583  s.clear();
584 
585  // Unknown, with reasonable length.
586  s << Span{ParseHex("aa" // network type (unknown)
587  "04" // address length
588  "01020304" // address
589  )};
590  s >> addr;
591  BOOST_CHECK(!addr.IsValid());
592  BOOST_REQUIRE(s.empty());
593 
594  // Unknown, with zero length.
595  s << Span{ParseHex("aa" // network type (unknown)
596  "00" // address length
597  "" // address
598  )};
599  s >> addr;
600  BOOST_CHECK(!addr.IsValid());
601  BOOST_REQUIRE(s.empty());
602 }
603 
604 // prior to PR #14728, this test triggers an undefined behavior
605 BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
606 {
607  // set up local addresses; all that's necessary to reproduce the bug is
608  // that a normal IPv4 address is among the entries, but if this address is
609  // !IsRoutable the undefined behavior is easier to trigger deterministically
610  {
612  in_addr ipv4AddrLocal;
613  ipv4AddrLocal.s_addr = 0x0100007f;
614  CNetAddr addr = CNetAddr(ipv4AddrLocal);
615  LocalServiceInfo lsi;
616  lsi.nScore = 23;
617  lsi.nPort = 42;
618  mapLocalHost[addr] = lsi;
619  }
620 
621  // create a peer with an IPv4 address
622  in_addr ipv4AddrPeer;
623  ipv4AddrPeer.s_addr = 0xa0b0c001;
624  CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK);
625  std::unique_ptr<CNode> pnode = std::make_unique<CNode>(/*id=*/0,
626  NODE_NETWORK,
627  /*sock=*/nullptr,
628  addr,
629  /*nKeyedNetGroupIn=*/0,
630  /*nLocalHostNonceIn=*/0,
631  CAddress{},
632  /*pszDest=*/std::string{},
634  /*inbound_onion=*/false);
635  pnode->fSuccessfullyConnected.store(true);
636 
637  // the peer claims to be reaching us via IPv6
638  in6_addr ipv6AddrLocal;
639  memset(ipv6AddrLocal.s6_addr, 0, 16);
640  ipv6AddrLocal.s6_addr[0] = 0xcc;
641  CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK);
642  pnode->SetAddrLocal(addrLocal);
643 
644  // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
645  GetLocalAddrForPeer(&*pnode);
646 
647  // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
648  BOOST_CHECK(1);
649 }
650 
651 
652 BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
653 {
658 
659  SetReachable(NET_IPV4, false);
660  SetReachable(NET_IPV6, false);
661  SetReachable(NET_ONION, false);
662  SetReachable(NET_I2P, false);
663 
668 
669  SetReachable(NET_IPV4, true);
670  SetReachable(NET_IPV6, true);
671  SetReachable(NET_ONION, true);
672  SetReachable(NET_I2P, true);
673 
678 }
679 
680 BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
681 {
684 
686  SetReachable(NET_INTERNAL, false);
687 
688  BOOST_CHECK(IsReachable(NET_UNROUTABLE)); // Ignored for both networks
690 }
691 
692 CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
693 {
694  unsigned char ip[] = {p1, p2, p3, p4};
695 
696  struct sockaddr_in sa;
697  memset(&sa, 0, sizeof(sockaddr_in)); // initialize the memory block
698  memcpy(&(sa.sin_addr), &ip, sizeof(ip));
699  return CNetAddr(sa.sin_addr);
700 }
701 
702 
703 BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
704 {
705  CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
706 
707  SetReachable(NET_IPV4, true);
708  BOOST_CHECK(IsReachable(addr));
709 
710  SetReachable(NET_IPV4, false);
711  BOOST_CHECK(!IsReachable(addr));
712 
713  SetReachable(NET_IPV4, true); // have to reset this, because this is stateful.
714 }
715 
716 
717 BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
718 {
719  CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
720 
721  SetReachable(NET_IPV4, true);
722 
723  BOOST_CHECK(!IsLocal(addr));
724  BOOST_CHECK(AddLocal(addr, 1000));
725  BOOST_CHECK(IsLocal(addr));
726 
727  RemoveLocal(addr);
728  BOOST_CHECK(!IsLocal(addr));
729 }
730 
CNetAddr::IsIPv6
bool IsIPv6() const
Definition: netaddress.cpp:320
ADDRV2_FORMAT
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
Definition: netaddress.h:34
NodeId
int64_t NodeId
Definition: net.h:88
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:528
HasReason
BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
Definition: setup_common.h:225
LookupHost
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
Definition: netbase.cpp:170
ParseHex
std::vector< unsigned char > ParseHex(const char *psz)
Definition: strencodings.cpp:84
ToString
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:87
NET_UNROUTABLE
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:47
RemoveLocal
void RemoveLocal(const CService &addr)
Definition: net.cpp:285
NET_IPV4
@ NET_IPV4
IPv4.
Definition: netaddress.h:50
streams.h
g_maplocalhost_mutex
Mutex g_maplocalhost_mutex
Definition: net.cpp:116
setup_common.h
NET_INTERNAL
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:66
string.h
CNetAddr
Network address.
Definition: netaddress.h:118
ConnectionType::OUTBOUND_FULL_RELAY
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
CNetAddr::ToString
std::string ToString() const
Definition: netaddress.cpp:631
clientversion.h
NODE_NETWORK
@ NODE_NETWORK
Definition: protocol.h:277
chainparams.h
BOOST_FIXTURE_TEST_SUITE
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
version.h
BOOST_AUTO_TEST_SUITE_END
BOOST_AUTO_TEST_SUITE_END()
CNetAddr::IsInternal
bool IsInternal() const
Definition: netaddress.cpp:500
CNetAddr::IsBindAny
bool IsBindAny() const
Definition: netaddress.cpp:310
UtilBuildAddress
CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
Definition: net_tests.cpp:692
CNetAddr::IsIPv4
bool IsIPv4() const
Definition: netaddress.cpp:318
Span
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:96
ConnectionType::INBOUND
@ INBOUND
Inbound connections are those initiated by a peer.
strencodings.h
CNetAddr::IsI2P
bool IsI2P() const
Check whether this object represents an I2P address.
Definition: netaddress.cpp:418
NET_I2P
@ NET_I2P
I2P.
Definition: netaddress.h:59
CNetAddr::SetSpecial
bool SetSpecial(const std::string &addr)
Parse a Tor or I2P address and set this object to it.
Definition: netaddress.cpp:212
ip
static CService ip(uint32_t i)
Definition: denialofservice_tests.cpp:30
IsReachable
bool IsReachable(enum Network net)
Definition: net.cpp:300
ArgsManager::SoftSetArg
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:606
span.h
netaddress.h
SetReachable
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:292
CNetAddr::IsValid
bool IsValid() const
Definition: netaddress.cpp:451
BasicTestingSetup
Basic testing setup.
Definition: setup_common.h:83
AddLocal
bool AddLocal(const CService &addr_, int nScore)
Definition: net.cpp:252
gArgs
ArgsManager gArgs
Definition: system.cpp:87
CDataStream::SetVersion
void SetVersion(int n)
Definition: streams.h:276
system.h
CDataStream::GetVersion
int GetVersion() const
Definition: streams.h:277
LocalServiceInfo::nScore
int nScore
Definition: net.h:229
CAddress
A CService with information about it as peer.
Definition: protocol.h:358
LocalServiceInfo
Definition: net.h:228
CDataStream::clear
void clear()
Definition: streams.h:242
GetLocalAddrForPeer
std::optional< CAddress > GetLocalAddrForPeer(CNode *pnode)
Returns a local address that we should advertise to this peer.
Definition: net.cpp:210
LOCK
#define LOCK(cs)
Definition: sync.h:226
NET_ONION
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
CNetAddr::IsTor
bool IsTor() const
Check whether this object represents a TOR address.
Definition: netaddress.cpp:413
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:561
LocalServiceInfo::nPort
uint16_t nPort
Definition: net.h:230
serialize.h
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:184
NET_IPV6
@ NET_IPV6
IPv6.
Definition: netaddress.h:53
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:131
CNetAddr::SetInternal
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:173
netbase.h
CDataStream::empty
bool empty() const
Definition: streams.h:237
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(cnode_listen_port)
Definition: net_tests.cpp:32
CNetAddr::IsAddrV1Compatible
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
Definition: netaddress.cpp:505
GetListenPort
uint16_t GetListenPort()
Definition: net.cpp:127
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:511
IsLocal
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:323
BOOST_CHECK
#define BOOST_CHECK(expr)
Definition: object.cpp:17
BOOST_CHECK_EQUAL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
ToLower
std::string ToLower(const std::string &str)
Returns the lowercase equivalent of the given string.
Definition: strencodings.cpp:490