Inside Bitcoin
Opening the selected file…
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.
251if (!std::ranges::equal(input_checksum, calculated_checksum)) {252return false;253}255m_net = NET_ONION;256m_addr.assign(input_pubkey.begin(), input_pubkey.end());257return true;258}260return false;261}263bool CNetAddr::SetI2P(std::string_view addr)264{265// I2P addresses that we support consist of 52 base32 characters + ".b32.i2p".266static constexpr size_t b32_len{52};267static const char* suffix{".b32.i2p"};268static constexpr size_t suffix_len{8};270if (addr.size() != b32_len + suffix_len || ToLower(addr.substr(b32_len)) != suffix) {271return false;272}274// Remove the ".b32.i2p" suffix and pad to a multiple of 8 chars, so DecodeBase32()275// can decode it.276const std::string b32_padded{tfm::format("%s====", addr.substr(0, b32_len))};278auto address_bytes = DecodeBase32(b32_padded);280if (!address_bytes || address_bytes->size() != ADDR_I2P_SIZE) {281return false;282}284m_net = NET_I2P;285m_addr.assign(address_bytes->begin(), address_bytes->end());287return true;288}290CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)291{292m_net = NET_IPV4;293const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&ipv4Addr);294m_addr.assign(ptr, ptr + ADDR_IPV4_SIZE);295}297CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)298{299SetLegacyIPv6({reinterpret_cast<const uint8_t*>(&ipv6Addr), sizeof(ipv6Addr)});300m_scope_id = scope;301}303bool CNetAddr::IsBindAny() const304{305if (!IsIPv4() && !IsIPv6()) {306return false;307}308return std::all_of(m_addr.begin(), m_addr.end(), [](uint8_t b) { return b == 0; });309}311bool CNetAddr::IsRFC1918() const312{313return IsIPv4() && (314m_addr[0] == 10 ||315(m_addr[0] == 192 && m_addr[1] == 168) ||316(m_addr[0] == 172 && m_addr[1] >= 16 && m_addr[1] <= 31));317}319bool CNetAddr::IsRFC2544() const320{321return IsIPv4() && m_addr[0] == 198 && (m_addr[1] == 18 || m_addr[1] == 19);322}324bool CNetAddr::IsRFC3927() const325{326return IsIPv4() && HasPrefix(m_addr, std::array<uint8_t, 2>{169, 254});327}329bool CNetAddr::IsRFC6598() const330{331return IsIPv4() && m_addr[0] == 100 && m_addr[1] >= 64 && m_addr[1] <= 127;332}334bool CNetAddr::IsRFC5737() const335{336return IsIPv4() && (HasPrefix(m_addr, std::array<uint8_t, 3>{192, 0, 2}) ||337HasPrefix(m_addr, std::array<uint8_t, 3>{198, 51, 100}) ||338HasPrefix(m_addr, std::array<uint8_t, 3>{203, 0, 113}));339}341bool CNetAddr::IsRFC3849() const342{343return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 4>{0x20, 0x01, 0x0D, 0xB8});344}346bool CNetAddr::IsRFC9637() const347{348return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 2>{0x3F, 0xFF}) &&349(m_addr[2] & 0xF0) == 0x00;350}352bool CNetAddr::IsRFC3964() const353{354return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 2>{0x20, 0x02});355}357bool CNetAddr::IsRFC6052() const358{359return IsIPv6() &&360HasPrefix(m_addr, std::array<uint8_t, 12>{0x00, 0x64, 0xFF, 0x9B, 0x00, 0x00,3610x00, 0x00, 0x00, 0x00, 0x00, 0x00});362}364bool CNetAddr::IsRFC4380() const365{366return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 4>{0x20, 0x01, 0x00, 0x00});367}369bool CNetAddr::IsRFC4862() const370{371return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 8>{0xFE, 0x80, 0x00, 0x00,3720x00, 0x00, 0x00, 0x00});373}375bool CNetAddr::IsRFC4193() const376{377return IsIPv6() && (m_addr[0] & 0xFE) == 0xFC;378}380bool CNetAddr::IsRFC6145() const381{382return IsIPv6() &&383HasPrefix(m_addr, std::array<uint8_t, 12>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,3840x00, 0x00, 0xFF, 0xFF, 0x00, 0x00});385}387bool CNetAddr::IsRFC4843() const388{389return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 3>{0x20, 0x01, 0x00}) &&390(m_addr[3] & 0xF0) == 0x10;391}393bool CNetAddr::IsRFC7343() const394{395return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 3>{0x20, 0x01, 0x00}) &&396(m_addr[3] & 0xF0) == 0x20;397}399bool CNetAddr::IsHeNet() const400{401return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 4>{0x20, 0x01, 0x04, 0x70});402}404bool CNetAddr::IsLocal() const405{406// IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)407if (IsIPv4() && (m_addr[0] == 127 || m_addr[0] == 0)) {408return true;409}411// IPv6 loopback (::1/128)412static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};413if (IsIPv6() && memcmp(m_addr.data(), pchLocal, sizeof(pchLocal)) == 0) {414return true;415}417return false;418}420/**421* @returns Whether or not this network address is a valid address that @a could422* be used to refer to an actual host.423*424* @note A valid address may or may not be publicly routable on the global425* internet. As in, the set of valid addresses is a superset of the set of426* publicly routable addresses.427*428* @see CNetAddr::IsRoutable()429*/430bool CNetAddr::IsValid() const431{432// unspecified IPv6 address (::/128)433unsigned char ipNone6[16] = {};434if (IsIPv6() && memcmp(m_addr.data(), ipNone6, sizeof(ipNone6)) == 0) {435return false;436}438if (IsCJDNS() && !HasCJDNSPrefix()) {439return false;440}442// documentation IPv6 address443if (IsRFC3849() || IsRFC9637())444return false;446if (IsInternal())447return false;449if (IsIPv4()) {450const uint32_t addr = ReadBE32(m_addr.data());451if (addr == INADDR_ANY || addr == INADDR_NONE) {452return false;453}454}456return true;457}459/**460* @returns Whether or not this network address is publicly routable on the461* global internet.462*463* @note A routable address is always valid. As in, the set of routable addresses464* is a subset of the set of valid addresses.465*466* @see CNetAddr::IsValid()467*/468bool CNetAddr::IsRoutable() const469{470return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || IsRFC4193() || IsRFC4843() || IsRFC7343() || IsLocal() || IsInternal());471}473/**474* @returns Whether or not this is a dummy address that represents a name.475*476* @see CNetAddr::SetInternal(const std::string &)477*/478bool CNetAddr::IsInternal() const479{480return m_net == NET_INTERNAL;481}483bool CNetAddr::IsAddrV1Compatible() const484{485switch (m_net) {486case NET_IPV4:487case NET_IPV6:488case NET_INTERNAL:489return true;490case NET_ONION:491case NET_I2P:492case NET_CJDNS:493return false;494case NET_UNROUTABLE: // m_net is never and should not be set to NET_UNROUTABLE495case NET_MAX: // m_net is never and should not be set to NET_MAX496assert(false);497} // no default case, so the compiler can warn about missing cases499assert(false);500}