diff options
Diffstat (limited to 'src/test/net_tests.cpp')
-rw-r--r-- | src/test/net_tests.cpp | 130 |
1 files changed, 100 insertions, 30 deletions
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 1c7c35528e..858b90b8b2 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -8,13 +8,12 @@ #include <clientversion.h> #include <cstdint> #include <net.h> +#include <netaddress.h> #include <netbase.h> -#include <optional.h> #include <serialize.h> #include <span.h> #include <streams.h> #include <test/util/setup_common.h> -#include <util/memory.h> #include <util/strencodings.h> #include <util/string.h> #include <util/system.h> @@ -25,6 +24,7 @@ #include <algorithm> #include <ios> #include <memory> +#include <optional> #include <string> using namespace std::literals; @@ -92,7 +92,7 @@ BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(cnode_listen_port) { // test default - uint16_t port = GetListenPort(); + uint16_t port{GetListenPort()}; BOOST_CHECK(port == Params().GetDefaultPort()); // test set port uint16_t altPort = 12345; @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) CAddress addr = CAddress(CService(ipv4Addr, 7777), NODE_NETWORK); std::string pszDest; - std::unique_ptr<CNode> pnode1 = MakeUnique<CNode>( + std::unique_ptr<CNode> pnode1 = std::make_unique<CNode>( id++, NODE_NETWORK, hSocket, addr, /* nKeyedNetGroupIn = */ 0, /* nLocalHostNonceIn = */ 0, @@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) BOOST_CHECK(pnode1->m_inbound_onion == false); BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4); - std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>( + std::unique_ptr<CNode> pnode2 = std::make_unique<CNode>( id++, NODE_NETWORK, hSocket, addr, /* nKeyedNetGroupIn = */ 1, /* nLocalHostNonceIn = */ 1, @@ -218,7 +218,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) BOOST_CHECK(pnode2->m_inbound_onion == false); BOOST_CHECK_EQUAL(pnode2->ConnectedThroughNetwork(), Network::NET_IPV4); - std::unique_ptr<CNode> pnode3 = MakeUnique<CNode>( + std::unique_ptr<CNode> pnode3 = std::make_unique<CNode>( id++, NODE_NETWORK, hSocket, addr, /* nKeyedNetGroupIn = */ 0, /* nLocalHostNonceIn = */ 0, @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) BOOST_CHECK(pnode3->m_inbound_onion == false); BOOST_CHECK_EQUAL(pnode3->ConnectedThroughNetwork(), Network::NET_IPV4); - std::unique_ptr<CNode> pnode4 = MakeUnique<CNode>( + std::unique_ptr<CNode> pnode4 = std::make_unique<CNode>( id++, NODE_NETWORK, hSocket, addr, /* nKeyedNetGroupIn = */ 1, /* nLocalHostNonceIn = */ 1, @@ -322,6 +322,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsTor()); + BOOST_CHECK(!addr.IsI2P()); BOOST_CHECK(!addr.IsBindAny()); BOOST_CHECK(addr.IsAddrV1Compatible()); BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion"); @@ -332,6 +333,7 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsTor()); + BOOST_CHECK(!addr.IsI2P()); BOOST_CHECK(!addr.IsBindAny()); BOOST_CHECK(!addr.IsAddrV1Compatible()); BOOST_CHECK_EQUAL(addr.ToString(), torv3_addr); @@ -352,6 +354,35 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) // TOR, invalid base32 BOOST_CHECK(!addr.SetSpecial(std::string{"mf*g zak.onion"})); + // I2P + const char* i2p_addr = "UDHDrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.I2P"; + BOOST_REQUIRE(addr.SetSpecial(i2p_addr)); + BOOST_REQUIRE(addr.IsValid()); + BOOST_REQUIRE(addr.IsI2P()); + + BOOST_CHECK(!addr.IsTor()); + BOOST_CHECK(!addr.IsBindAny()); + BOOST_CHECK(!addr.IsAddrV1Compatible()); + BOOST_CHECK_EQUAL(addr.ToString(), ToLower(i2p_addr)); + + // I2P, correct length, but decodes to less than the expected number of bytes. + BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jn=.b32.i2p")); + + // I2P, extra unnecessary padding + BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna=.b32.i2p")); + + // I2P, malicious + BOOST_CHECK(!addr.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v\0wtf.b32.i2p"s)); + + // I2P, valid but unsupported (56 Base32 characters) + // See "Encrypted LS with Base 32 Addresses" in + // https://geti2p.net/spec/encryptedleaseset.txt + BOOST_CHECK( + !addr.SetSpecial("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscsad.b32.i2p")); + + // I2P, invalid base32 + BOOST_CHECK(!addr.SetSpecial(std::string{"tp*szydbh4dp.b32.i2p"})); + // Internal addr.SetInternal("esffpp"); BOOST_REQUIRE(!addr.IsValid()); // "internal" is considered invalid @@ -365,6 +396,60 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) BOOST_CHECK(!addr.SetSpecial("totally bogus")); } +BOOST_AUTO_TEST_CASE(cnetaddr_tostring_canonical_ipv6) +{ + // Test that CNetAddr::ToString formats IPv6 addresses with zero compression as described in + // RFC 5952 ("A Recommendation for IPv6 Address Text Representation"). + const std::map<std::string, std::string> canonical_representations_ipv6{ + {"0000:0000:0000:0000:0000:0000:0000:0000", "::"}, + {"000:0000:000:00:0:00:000:0000", "::"}, + {"000:000:000:000:000:000:000:000", "::"}, + {"00:00:00:00:00:00:00:00", "::"}, + {"0:0:0:0:0:0:0:0", "::"}, + {"0:0:0:0:0:0:0:1", "::1"}, + {"2001:0:0:1:0:0:0:1", "2001:0:0:1::1"}, + {"2001:0db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:db8:85a3::8a2e:370:7334"}, + {"2001:0db8::0001", "2001:db8::1"}, + {"2001:0db8::0001:0000", "2001:db8::1:0"}, + {"2001:0db8::1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:db8:0000:0:1::1", "2001:db8::1:0:0:1"}, + {"2001:db8:0000:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"}, + {"2001:db8:0:0:0:0:2:1", "2001:db8::2:1"}, + {"2001:db8:0:0:0::1", "2001:db8::1"}, + {"2001:db8:0:0:1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:db8:0:0:1::1", "2001:db8::1:0:0:1"}, + {"2001:DB8:0:0:1::1", "2001:db8::1:0:0:1"}, + {"2001:db8:0:0::1", "2001:db8::1"}, + {"2001:db8:0:0:aaaa::1", "2001:db8::aaaa:0:0:1"}, + {"2001:db8:0:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"}, + {"2001:db8:0::1", "2001:db8::1"}, + {"2001:db8:85a3:0:0:8a2e:370:7334", "2001:db8:85a3::8a2e:370:7334"}, + {"2001:db8::0:1", "2001:db8::1"}, + {"2001:db8::0:1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:DB8::1", "2001:db8::1"}, + {"2001:db8::1", "2001:db8::1"}, + {"2001:db8::1:0:0:1", "2001:db8::1:0:0:1"}, + {"2001:db8::1:1:1:1:1", "2001:db8:0:1:1:1:1:1"}, + {"2001:db8::aaaa:0:0:1", "2001:db8::aaaa:0:0:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:0:1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd::1", "2001:db8:aaaa:bbbb:cccc:dddd:0:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:001", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:01", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"}, + {"2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa", "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"}, + }; + for (const auto& [input_address, expected_canonical_representation_output] : canonical_representations_ipv6) { + CNetAddr net_addr; + BOOST_REQUIRE(LookupHost(input_address, net_addr, false)); + BOOST_REQUIRE(net_addr.IsIPv6()); + BOOST_CHECK_EQUAL(net_addr.ToString(), expected_canonical_representation_output); + } +} + BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) { CNetAddr addr; @@ -680,7 +765,7 @@ BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test) in_addr ipv4AddrPeer; ipv4AddrPeer.s_addr = 0xa0b0c001; CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK); - std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress{}, /* pszDest */ std::string{}, ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false); + std::unique_ptr<CNode> pnode = std::make_unique<CNode>(0, NODE_NETWORK, INVALID_SOCKET, addr, /* nKeyedNetGroupIn */ 0, /* nLocalHostNonceIn */ 0, CAddress{}, /* pszDest */ std::string{}, ConnectionType::OUTBOUND_FULL_RELAY, /* inbound_onion */ false); pnode->fSuccessfullyConnected.store(true); // the peer claims to be reaching us via IPv6 @@ -772,21 +857,6 @@ BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle) BOOST_CHECK_EQUAL(IsLocal(addr), false); } -BOOST_AUTO_TEST_CASE(PoissonNextSend) -{ - g_mock_deterministic_tests = true; - - int64_t now = 5000; - int average_interval_seconds = 600; - - auto poisson = ::PoissonNextSend(now, average_interval_seconds); - std::chrono::microseconds poisson_chrono = ::PoissonNextSend(std::chrono::microseconds{now}, std::chrono::seconds{average_interval_seconds}); - - BOOST_CHECK_EQUAL(poisson, poisson_chrono.count()); - - g_mock_deterministic_tests = false; -} - std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(const int n_candidates, FastRandomContext& random_context) { std::vector<NodeEvictionCandidate> candidates; @@ -794,7 +864,7 @@ std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(const int n_c candidates.push_back({ /* id */ id, /* nTimeConnected */ static_cast<int64_t>(random_context.randrange(100)), - /* m_min_ping_time */ static_cast<int64_t>(random_context.randrange(100)), + /* m_min_ping_time */ std::chrono::microseconds{random_context.randrange(100)}, /* nLastBlockTime */ static_cast<int64_t>(random_context.randrange(100)), /* nLastTXTime */ static_cast<int64_t>(random_context.randrange(100)), /* fRelevantServices */ random_context.randbool(), @@ -812,7 +882,7 @@ std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(const int n_c bool IsEvicted(std::vector<NodeEvictionCandidate> candidates, const std::vector<NodeId>& node_ids, FastRandomContext& random_context) { Shuffle(candidates.begin(), candidates.end(), random_context); - const Optional<NodeId> evicted_node_id = SelectNodeToEvict(std::move(candidates)); + const std::optional<NodeId> evicted_node_id = SelectNodeToEvict(std::move(candidates)); if (!evicted_node_id) { return false; } @@ -854,7 +924,7 @@ BOOST_AUTO_TEST_CASE(node_eviction_test) // from eviction. BOOST_CHECK(!IsEvicted( number_of_nodes, [](NodeEvictionCandidate& candidate) { - candidate.m_min_ping_time = candidate.id; + candidate.m_min_ping_time = std::chrono::microseconds{candidate.id}; }, {0, 1, 2, 3, 4, 5, 6, 7}, random_context)); @@ -900,10 +970,10 @@ BOOST_AUTO_TEST_CASE(node_eviction_test) // Combination of all tests above. BOOST_CHECK(!IsEvicted( number_of_nodes, [number_of_nodes](NodeEvictionCandidate& candidate) { - candidate.nKeyedNetGroup = number_of_nodes - candidate.id; // 4 protected - candidate.m_min_ping_time = candidate.id; // 8 protected - candidate.nLastTXTime = number_of_nodes - candidate.id; // 4 protected - candidate.nLastBlockTime = number_of_nodes - candidate.id; // 4 protected + candidate.nKeyedNetGroup = number_of_nodes - candidate.id; // 4 protected + candidate.m_min_ping_time = std::chrono::microseconds{candidate.id}; // 8 protected + candidate.nLastTXTime = number_of_nodes - candidate.id; // 4 protected + candidate.nLastBlockTime = number_of_nodes - candidate.id; // 4 protected }, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, random_context)); |