Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2012-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <compat/compat.h>6#include <net_permissions.h>7#include <netaddress.h>8#include <netbase.h>9#include <netgroup.h>10#include <protocol.h>11#include <serialize.h>12#include <streams.h>13#include <test/util/common.h>14#include <test/util/setup_common.h>15#include <util/strencodings.h>16#include <util/translation.h>18#include <string>19#include <numeric>21#include <boost/test/unit_test.hpp>23using namespace std::literals;24using namespace util::hex_literals;26BOOST_FIXTURE_TEST_SUITE(netbase_tests, BasicTestingSetup)28static CNetAddr ResolveIP(const std::string& ip)29{30return LookupHost(ip, false).value_or(CNetAddr{});31}33static CNetAddr CreateInternal(const std::string& host)34{35CNetAddr addr;36addr.SetInternal(host);37return addr;38}40BOOST_AUTO_TEST_CASE(netbase_networks)41{42BOOST_CHECK(ResolveIP("127.0.0.1").GetNetwork() == NET_UNROUTABLE);43BOOST_CHECK(ResolveIP("::1").GetNetwork() == NET_UNROUTABLE);44BOOST_CHECK(ResolveIP("8.8.8.8").GetNetwork() == NET_IPV4);45BOOST_CHECK(ResolveIP("2001::8888").GetNetwork() == NET_IPV6);46BOOST_CHECK(ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion").GetNetwork() == NET_ONION);47BOOST_CHECK(CreateInternal("foo.com").GetNetwork() == NET_INTERNAL);48}50BOOST_AUTO_TEST_CASE(netbase_properties)51{53BOOST_CHECK(ResolveIP("127.0.0.1").IsIPv4());54BOOST_CHECK(ResolveIP("::FFFF:192.168.1.1").IsIPv4());55BOOST_CHECK(ResolveIP("::1").IsIPv6());56BOOST_CHECK(ResolveIP("10.0.0.1").IsRFC1918());57BOOST_CHECK(ResolveIP("192.168.1.1").IsRFC1918());58BOOST_CHECK(ResolveIP("172.31.255.255").IsRFC1918());59BOOST_CHECK(ResolveIP("198.18.0.0").IsRFC2544());60BOOST_CHECK(ResolveIP("198.19.255.255").IsRFC2544());61BOOST_CHECK(ResolveIP("2001:0DB8::").IsRFC3849());62BOOST_CHECK(ResolveIP("3FFF::").IsRFC9637());63BOOST_CHECK(ResolveIP("3FFF:0FFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF").IsRFC9637());64BOOST_CHECK(!ResolveIP("3FFF:1000::").IsRFC9637());65BOOST_CHECK(ResolveIP("169.254.1.1").IsRFC3927());66BOOST_CHECK(ResolveIP("2002::1").IsRFC3964());67BOOST_CHECK(ResolveIP("FC00::").IsRFC4193());68BOOST_CHECK(ResolveIP("2001::2").IsRFC4380());69BOOST_CHECK(ResolveIP("2001:10::").IsRFC4843());70BOOST_CHECK(ResolveIP("2001:20::").IsRFC7343());71BOOST_CHECK(ResolveIP("FE80::").IsRFC4862());72BOOST_CHECK(ResolveIP("64:FF9B::").IsRFC6052());73BOOST_CHECK(ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion").IsTor());74BOOST_CHECK(ResolveIP("127.0.0.1").IsLocal());75BOOST_CHECK(ResolveIP("::1").IsLocal());76BOOST_CHECK(ResolveIP("8.8.8.8").IsRoutable());77BOOST_CHECK(ResolveIP("2001::1").IsRoutable());78BOOST_CHECK(ResolveIP("127.0.0.1").IsValid());79BOOST_CHECK(!ResolveIP("3FFF::").IsValid());80BOOST_CHECK(CreateInternal("FD6B:88C0:8724:edb1:8e4:3588:e546:35ca").IsInternal());81BOOST_CHECK(CreateInternal("bar.com").IsInternal());83}85bool static TestSplitHost(const std::string& test, const std::string& host, uint16_t port, bool validPort=true)86{87std::string hostOut;88uint16_t portOut{0};89bool validPortOut = SplitHostPort(test, portOut, hostOut);90return hostOut == host && portOut == port && validPortOut == validPort;91}93BOOST_AUTO_TEST_CASE(netbase_splithost)94{95BOOST_CHECK(TestSplitHost("www.bitcoincore.org", "www.bitcoincore.org", 0));96BOOST_CHECK(TestSplitHost("[www.bitcoincore.org]", "www.bitcoincore.org", 0));97BOOST_CHECK(TestSplitHost("www.bitcoincore.org:80", "www.bitcoincore.org", 80));98BOOST_CHECK(TestSplitHost("[www.bitcoincore.org]:80", "www.bitcoincore.org", 80));99BOOST_CHECK(TestSplitHost("127.0.0.1", "127.0.0.1", 0));100BOOST_CHECK(TestSplitHost("127.0.0.1:8333", "127.0.0.1", 8333));101BOOST_CHECK(TestSplitHost("[127.0.0.1]", "127.0.0.1", 0));102BOOST_CHECK(TestSplitHost("[127.0.0.1]:8333", "127.0.0.1", 8333));103BOOST_CHECK(TestSplitHost("::ffff:127.0.0.1", "::ffff:127.0.0.1", 0));104BOOST_CHECK(TestSplitHost("[::ffff:127.0.0.1]:8333", "::ffff:127.0.0.1", 8333));105BOOST_CHECK(TestSplitHost("[::]:8333", "::", 8333));106BOOST_CHECK(TestSplitHost("::8333", "::8333", 0));107BOOST_CHECK(TestSplitHost(":8333", "", 8333));108BOOST_CHECK(TestSplitHost("[]:8333", "", 8333));109BOOST_CHECK(TestSplitHost("", "", 0));110BOOST_CHECK(TestSplitHost(":65535", "", 65535));111BOOST_CHECK(TestSplitHost(":65536", ":65536", 0, false));112BOOST_CHECK(TestSplitHost(":-1", ":-1", 0, false));113BOOST_CHECK(TestSplitHost("[]:70001", "[]:70001", 0, false));114BOOST_CHECK(TestSplitHost("[]:-1", "[]:-1", 0, false));115BOOST_CHECK(TestSplitHost("[]:-0", "[]:-0", 0, false));116BOOST_CHECK(TestSplitHost("[]:0", "", 0, false));117BOOST_CHECK(TestSplitHost("[]:1/2", "[]:1/2", 0, false));118BOOST_CHECK(TestSplitHost("[]:1E2", "[]:1E2", 0, false));119BOOST_CHECK(TestSplitHost("127.0.0.1:65536", "127.0.0.1:65536", 0, false));120BOOST_CHECK(TestSplitHost("127.0.0.1:0", "127.0.0.1", 0, false));121BOOST_CHECK(TestSplitHost("127.0.0.1:", "127.0.0.1:", 0, false));122BOOST_CHECK(TestSplitHost("127.0.0.1:1/2", "127.0.0.1:1/2", 0, false));123BOOST_CHECK(TestSplitHost("127.0.0.1:1E2", "127.0.0.1:1E2", 0, false));124BOOST_CHECK(TestSplitHost("www.bitcoincore.org:65536", "www.bitcoincore.org:65536", 0, false));125BOOST_CHECK(TestSplitHost("www.bitcoincore.org:0", "www.bitcoincore.org", 0, false));126BOOST_CHECK(TestSplitHost("www.bitcoincore.org:", "www.bitcoincore.org:", 0, false));127}129bool static TestParse(std::string src, std::string canon)130{131CService addr(LookupNumeric(src, 65535));132return canon == addr.ToStringAddrPort();133}135BOOST_AUTO_TEST_CASE(netbase_lookupnumeric)136{137BOOST_CHECK(TestParse("127.0.0.1", "127.0.0.1:65535"));138BOOST_CHECK(TestParse("127.0.0.1:8333", "127.0.0.1:8333"));139BOOST_CHECK(TestParse("::ffff:127.0.0.1", "127.0.0.1:65535"));140BOOST_CHECK(TestParse("::", "[::]:65535"));141BOOST_CHECK(TestParse("[::]:8333", "[::]:8333"));142BOOST_CHECK(TestParse("[127.0.0.1]", "127.0.0.1:65535"));143BOOST_CHECK(TestParse(":::", "[::]:0"));145// verify that an internal address fails to resolve146BOOST_CHECK(TestParse("[fd6b:88c0:8724:1:2:3:4:5]", "[::]:0"));147// and that a one-off resolves correctly148BOOST_CHECK(TestParse("[fd6c:88c0:8724:1:2:3:4:5]", "[fd6c:88c0:8724:1:2:3:4:5]:65535"));149}151BOOST_AUTO_TEST_CASE(embedded_test)152{153CNetAddr addr1(ResolveIP("1.2.3.4"));154CNetAddr addr2(ResolveIP("::FFFF:0102:0304"));155BOOST_CHECK(addr2.IsIPv4());156BOOST_CHECK_EQUAL(addr1.ToStringAddr(), addr2.ToStringAddr());157}159BOOST_AUTO_TEST_CASE(subnet_test)160{161BOOST_CHECK(LookupSubNet("1.2.3.0/24") == LookupSubNet("1.2.3.0/255.255.255.0"));162BOOST_CHECK(LookupSubNet("1.2.3.0/24") != LookupSubNet("1.2.4.0/255.255.255.0"));163BOOST_CHECK(LookupSubNet("1.2.3.0/24").Match(ResolveIP("1.2.3.4")));164BOOST_CHECK(!LookupSubNet("1.2.2.0/24").Match(ResolveIP("1.2.3.4")));165BOOST_CHECK(LookupSubNet("1.2.3.4").Match(ResolveIP("1.2.3.4")));166BOOST_CHECK(LookupSubNet("1.2.3.4/32").Match(ResolveIP("1.2.3.4")));167BOOST_CHECK(!LookupSubNet("1.2.3.4").Match(ResolveIP("5.6.7.8")));168BOOST_CHECK(!LookupSubNet("1.2.3.4/32").Match(ResolveIP("5.6.7.8")));169BOOST_CHECK(LookupSubNet("::ffff:127.0.0.1").Match(ResolveIP("127.0.0.1")));170BOOST_CHECK(LookupSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:8")));171BOOST_CHECK(!LookupSubNet("1:2:3:4:5:6:7:8").Match(ResolveIP("1:2:3:4:5:6:7:9")));172BOOST_CHECK(LookupSubNet("1:2:3:4:5:6:7:0/112").Match(ResolveIP("1:2:3:4:5:6:7:1234")));173BOOST_CHECK(LookupSubNet("192.168.0.1/24").Match(ResolveIP("192.168.0.2")));174BOOST_CHECK(LookupSubNet("192.168.0.20/29").Match(ResolveIP("192.168.0.18")));175BOOST_CHECK(LookupSubNet("1.2.2.1/24").Match(ResolveIP("1.2.2.4")));176BOOST_CHECK(LookupSubNet("1.2.2.110/31").Match(ResolveIP("1.2.2.111")));177BOOST_CHECK(LookupSubNet("1.2.2.20/26").Match(ResolveIP("1.2.2.63")));178// All-Matching IPv6 Matches arbitrary IPv6179BOOST_CHECK(LookupSubNet("::/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));180// But not `::` or `0.0.0.0` because they are considered invalid addresses181BOOST_CHECK(!LookupSubNet("::/0").Match(ResolveIP("::")));182BOOST_CHECK(!LookupSubNet("::/0").Match(ResolveIP("0.0.0.0")));183// Addresses from one network (IPv4) don't belong to subnets of another network (IPv6)184BOOST_CHECK(!LookupSubNet("::/0").Match(ResolveIP("1.2.3.4")));185// All-Matching IPv4 does not Match IPv6186BOOST_CHECK(!LookupSubNet("0.0.0.0/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));187// Invalid subnets Match nothing (not even invalid addresses)188BOOST_CHECK(!CSubNet().Match(ResolveIP("1.2.3.4")));189BOOST_CHECK(!LookupSubNet("").Match(ResolveIP("4.5.6.7")));190BOOST_CHECK(!LookupSubNet("bloop").Match(ResolveIP("0.0.0.0")));191BOOST_CHECK(!LookupSubNet("bloop").Match(ResolveIP("hab")));192// Check valid/invalid193BOOST_CHECK(LookupSubNet("1.2.3.0/0").IsValid());194BOOST_CHECK(!LookupSubNet("1.2.3.0/-1").IsValid());195BOOST_CHECK(!LookupSubNet("1.2.3.0/+24").IsValid());196BOOST_CHECK(LookupSubNet("1.2.3.0/32").IsValid());197BOOST_CHECK(!LookupSubNet("1.2.3.0/33").IsValid());198BOOST_CHECK(!LookupSubNet("1.2.3.0/300").IsValid());199BOOST_CHECK(LookupSubNet("1:2:3:4:5:6:7:8/0").IsValid());200BOOST_CHECK(LookupSubNet("1:2:3:4:5:6:7:8/33").IsValid());201BOOST_CHECK(!LookupSubNet("1:2:3:4:5:6:7:8/-1").IsValid());202BOOST_CHECK(LookupSubNet("1:2:3:4:5:6:7:8/128").IsValid());203BOOST_CHECK(!LookupSubNet("1:2:3:4:5:6:7:8/129").IsValid());204BOOST_CHECK(!LookupSubNet("fuzzy").IsValid());206//CNetAddr constructor test207BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).IsValid());208BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.1")));209BOOST_CHECK(!CSubNet(ResolveIP("127.0.0.1")).Match(ResolveIP("127.0.0.2")));210BOOST_CHECK(CSubNet(ResolveIP("127.0.0.1")).ToString() == "127.0.0.1/32");212CSubNet subnet = CSubNet(ResolveIP("1.2.3.4"), 32);213BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");214subnet = CSubNet(ResolveIP("1.2.3.4"), 8);215BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");216subnet = CSubNet(ResolveIP("1.2.3.4"), 0);217BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");219subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.255.255.255"));220BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");221subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("255.0.0.0"));222BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");223subnet = CSubNet(ResolveIP("1.2.3.4"), ResolveIP("0.0.0.0"));224BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");226BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).IsValid());227BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).Match(ResolveIP("1:2:3:4:5:6:7:8")));228BOOST_CHECK(!CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).Match(ResolveIP("1:2:3:4:5:6:7:9")));229BOOST_CHECK(CSubNet(ResolveIP("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128");230// IPv4 address with IPv6 netmask or the other way around.231BOOST_CHECK(!CSubNet(ResolveIP("1.1.1.1"), ResolveIP("ffff::")).IsValid());232BOOST_CHECK(!CSubNet(ResolveIP("::1"), ResolveIP("255.0.0.0")).IsValid());234// Create Non-IP subnets.236const CNetAddr tor_addr{237ResolveIP("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion")};239subnet = CSubNet(tor_addr);240BOOST_CHECK(subnet.IsValid());241BOOST_CHECK_EQUAL(subnet.ToString(), tor_addr.ToStringAddr());242BOOST_CHECK(subnet.Match(tor_addr));243BOOST_CHECK(244!subnet.Match(ResolveIP("kpgvmscirrdqpekbqjsvw5teanhatztpp2gl6eee4zkowvwfxwenqaid.onion")));245BOOST_CHECK(!subnet.Match(ResolveIP("1.2.3.4")));247BOOST_CHECK(!CSubNet(tor_addr, 200).IsValid());248BOOST_CHECK(!CSubNet(tor_addr, ResolveIP("255.0.0.0")).IsValid());250subnet = LookupSubNet("1.2.3.4/255.255.255.255");
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.