Changeset View
Changeset View
Standalone View
Standalone View
src/test/net_tests.cpp
// Copyright (c) 2012-2019 The Bitcoin Core developers | // Copyright (c) 2012-2019 The Bitcoin Core developers | ||||
// Copyright (c) 2017-2019 The Bitcoin developers | // Copyright (c) 2017-2019 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <net.h> | #include <net.h> | ||||
#include <addrdb.h> | #include <addrdb.h> | ||||
#include <addrman.h> | #include <addrman.h> | ||||
#include <chainparams.h> | #include <chainparams.h> | ||||
#include <clientversion.h> | #include <clientversion.h> | ||||
#include <config.h> | #include <config.h> | ||||
#include <netbase.h> | #include <netbase.h> | ||||
#include <serialize.h> | #include <serialize.h> | ||||
#include <span.h> | |||||
#include <streams.h> | #include <streams.h> | ||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/string.h> | #include <util/string.h> | ||||
#include <version.h> | #include <version.h> | ||||
#include <test/util/setup_common.h> | #include <test/util/setup_common.h> | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
#include <ios> | |||||
#include <memory> | #include <memory> | ||||
#include <string> | #include <string> | ||||
class CAddrManSerializationMock : public CAddrMan { | class CAddrManSerializationMock : public CAddrMan { | ||||
public: | public: | ||||
virtual void Serialize(CDataStream &s) const = 0; | virtual void Serialize(CDataStream &s) const = 0; | ||||
//! Ensure that bucket placement is always the same for testing purposes. | //! Ensure that bucket placement is always the same for testing purposes. | ||||
▲ Show 20 Lines • Show All 325 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(cnetaddr_basic) { | ||||
// "internal" is considered invalid | // "internal" is considered invalid | ||||
BOOST_REQUIRE(!addr.IsValid()); | BOOST_REQUIRE(!addr.IsValid()); | ||||
BOOST_REQUIRE(addr.IsInternal()); | BOOST_REQUIRE(addr.IsInternal()); | ||||
BOOST_CHECK(!addr.IsBindAny()); | BOOST_CHECK(!addr.IsBindAny()); | ||||
BOOST_CHECK_EQUAL(addr.ToString(), "esffpvrt3wpeaygy.internal"); | BOOST_CHECK_EQUAL(addr.ToString(), "esffpvrt3wpeaygy.internal"); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(cnetaddr_serialize) { | BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v1) { | ||||
CNetAddr addr; | CNetAddr addr; | ||||
CDataStream s(SER_NETWORK, PROTOCOL_VERSION); | CDataStream s(SER_NETWORK, PROTOCOL_VERSION); | ||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000000000000000"); | |||||
s.clear(); | |||||
BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false)); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "00000000000000000000ffff01020304"); | |||||
s.clear(); | |||||
BOOST_REQUIRE( | |||||
LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false)); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "1a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); | |||||
s.clear(); | |||||
BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion")); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "fd87d87eeb43f1f2f3f4f5f6f7f8f9fa"); | |||||
s.clear(); | |||||
addr.SetInternal("a"); | addr.SetInternal("a"); | ||||
s << addr; | s << addr; | ||||
BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2"); | BOOST_CHECK_EQUAL(HexStr(s), "fd6b88c08724ca978112ca1bbdcafac2"); | ||||
s.clear(); | s.clear(); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(cnetaddr_serialize_v2) { | |||||
CNetAddr addr; | |||||
CDataStream s(SER_NETWORK, PROTOCOL_VERSION); | |||||
// Add ADDRV2_FORMAT to the version so that the CNetAddr | |||||
// serialize method produces an address in v2 format. | |||||
s.SetVersion(s.GetVersion() | ADDRV2_FORMAT); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "021000000000000000000000000000000000"); | |||||
s.clear(); | |||||
BOOST_REQUIRE(LookupHost("1.2.3.4", addr, false)); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "010401020304"); | |||||
s.clear(); | |||||
BOOST_REQUIRE( | |||||
LookupHost("1a1b:2a2b:3a3b:4a4b:5a5b:6a6b:7a7b:8a8b", addr, false)); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "02101a1b2a2b3a3b4a4b5a5b6a6b7a7b8a8b"); | |||||
s.clear(); | |||||
BOOST_REQUIRE(addr.SetSpecial("6hzph5hv6337r6p2.onion")); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "030af1f2f3f4f5f6f7f8f9fa"); | |||||
s.clear(); | |||||
BOOST_REQUIRE(addr.SetInternal("a")); | |||||
s << addr; | |||||
BOOST_CHECK_EQUAL(HexStr(s), "0210fd6b88c08724ca978112ca1bbdcafac2"); | |||||
s.clear(); | |||||
} | |||||
BOOST_AUTO_TEST_CASE(cnetaddr_unserialize_v2) { | |||||
CNetAddr addr; | |||||
CDataStream s(SER_NETWORK, PROTOCOL_VERSION); | |||||
// Add ADDRV2_FORMAT to the version so that the CNetAddr | |||||
// unserialize method expects an address in v2 format. | |||||
s.SetVersion(s.GetVersion() | ADDRV2_FORMAT); | |||||
// Valid IPv4. | |||||
s << MakeSpan(ParseHex("01" // network type (IPv4) | |||||
"04" // address length | |||||
"01020304")); // address | |||||
s >> addr; | |||||
BOOST_CHECK(addr.IsValid()); | |||||
BOOST_CHECK(addr.IsIPv4()); | |||||
BOOST_CHECK_EQUAL(addr.ToString(), "1.2.3.4"); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Invalid IPv4, valid length but address itself is shorter. | |||||
s << MakeSpan(ParseHex("01" // network type (IPv4) | |||||
"04" // address length | |||||
"0102")); // address | |||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, | |||||
HasReason("end of data")); | |||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. | |||||
s.clear(); | |||||
// Invalid IPv4, with bogus length. | |||||
s << MakeSpan(ParseHex("01" // network type (IPv4) | |||||
"05" // address length | |||||
"01020304")); // address | |||||
BOOST_CHECK_EXCEPTION( | |||||
s >> addr, std::ios_base::failure, | |||||
HasReason("BIP155 IPv4 address with length 5 (should be 4)")); | |||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. | |||||
s.clear(); | |||||
// Invalid IPv4, with extreme length. | |||||
s << MakeSpan(ParseHex("01" // network type (IPv4) | |||||
"fd0102" // address length (513 as CompactSize) | |||||
"01020304")); // address | |||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, | |||||
HasReason("Address too long: 513 > 512")); | |||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. | |||||
s.clear(); | |||||
// Valid IPv6. | |||||
s << MakeSpan(ParseHex("02" // network type (IPv6) | |||||
"10" // address length | |||||
"0102030405060708090a0b0c0d0e0f10")); // address | |||||
s >> addr; | |||||
BOOST_CHECK(addr.IsValid()); | |||||
BOOST_CHECK(addr.IsIPv6()); | |||||
BOOST_CHECK_EQUAL(addr.ToString(), "102:304:506:708:90a:b0c:d0e:f10"); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Valid IPv6, contains embedded "internal". | |||||
s << MakeSpan( | |||||
ParseHex("02" // network type (IPv6) | |||||
"10" // address length | |||||
"fd6b88c08724ca978112ca1bbdcafac2")); // address: 0xfd + | |||||
// sha256("bitcoin")[0:5] | |||||
// + sha256(name)[0:10] | |||||
s >> addr; | |||||
BOOST_CHECK(addr.IsInternal()); | |||||
BOOST_CHECK_EQUAL(addr.ToString(), "zklycewkdo64v6wc.internal"); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Invalid IPv6, with bogus length. | |||||
s << MakeSpan(ParseHex("02" // network type (IPv6) | |||||
"04" // address length | |||||
"00")); // address | |||||
BOOST_CHECK_EXCEPTION( | |||||
s >> addr, std::ios_base::failure, | |||||
HasReason("BIP155 IPv6 address with length 4 (should be 16)")); | |||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. | |||||
s.clear(); | |||||
// Invalid IPv6, contains embedded IPv4. | |||||
s << MakeSpan(ParseHex("02" // network type (IPv6) | |||||
"10" // address length | |||||
"00000000000000000000ffff01020304")); // address | |||||
s >> addr; | |||||
BOOST_CHECK(!addr.IsValid()); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Invalid IPv6, contains embedded TORv2. | |||||
s << MakeSpan(ParseHex("02" // network type (IPv6) | |||||
"10" // address length | |||||
"fd87d87eeb430102030405060708090a")); // address | |||||
s >> addr; | |||||
BOOST_CHECK(!addr.IsValid()); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Valid TORv2. | |||||
s << MakeSpan(ParseHex("03" // network type (TORv2) | |||||
"0a" // address length | |||||
"f1f2f3f4f5f6f7f8f9fa")); // address | |||||
s >> addr; | |||||
BOOST_CHECK(addr.IsValid()); | |||||
BOOST_CHECK(addr.IsTor()); | |||||
BOOST_CHECK_EQUAL(addr.ToString(), "6hzph5hv6337r6p2.onion"); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Invalid TORv2, with bogus length. | |||||
s << MakeSpan(ParseHex("03" // network type (TORv2) | |||||
"07" // address length | |||||
"00")); // address | |||||
BOOST_CHECK_EXCEPTION( | |||||
s >> addr, std::ios_base::failure, | |||||
HasReason("BIP155 TORv2 address with length 7 (should be 10)")); | |||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. | |||||
s.clear(); | |||||
// Unknown, with extreme length. | |||||
s << MakeSpan( | |||||
ParseHex("aa" // network type (unknown) | |||||
"fe00000002" // address length (CompactSize's MAX_SIZE) | |||||
"01020304050607" // address | |||||
)); | |||||
BOOST_CHECK_EXCEPTION(s >> addr, std::ios_base::failure, | |||||
HasReason("Address too long: 33554432 > 512")); | |||||
BOOST_REQUIRE(!s.empty()); // The stream is not consumed on invalid input. | |||||
s.clear(); | |||||
// Unknown, with reasonable length. | |||||
s << MakeSpan(ParseHex("aa" // network type (unknown) | |||||
"04" // address length | |||||
"01020304" // address | |||||
)); | |||||
s >> addr; | |||||
BOOST_CHECK(!addr.IsValid()); | |||||
BOOST_REQUIRE(s.empty()); | |||||
// Unknown, with zero length. | |||||
s << MakeSpan(ParseHex("aa" // network type (unknown) | |||||
"00" // address length | |||||
"" // address | |||||
)); | |||||
s >> addr; | |||||
BOOST_CHECK(!addr.IsValid()); | |||||
BOOST_REQUIRE(s.empty()); | |||||
} | |||||
// prior to PR #14728, this test triggers an undefined behavior | // prior to PR #14728, this test triggers an undefined behavior | ||||
BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test) { | BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test) { | ||||
// set up local addresses; all that's necessary to reproduce the bug is | // set up local addresses; all that's necessary to reproduce the bug is | ||||
// that a normal IPv4 address is among the entries, but if this address is | // that a normal IPv4 address is among the entries, but if this address is | ||||
// !IsRoutable the undefined behavior is easier to trigger deterministically | // !IsRoutable the undefined behavior is easier to trigger deterministically | ||||
{ | { | ||||
LOCK(cs_mapLocalHost); | LOCK(cs_mapLocalHost); | ||||
in_addr ipv4AddrLocal; | in_addr ipv4AddrLocal; | ||||
▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines |