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.
1// Copyright (c) 2009-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#ifndef BITCOIN_NETADDRESS_H6#define BITCOIN_NETADDRESS_H8#include <compat/compat.h>9#include <crypto/siphash.h>10#include <prevector.h>11#include <random.h>12#include <serialize.h>13#include <tinyformat.h>14#include <util/strencodings.h>15#include <util/string.h>17#include <array>18#include <cstdint>19#include <ios>20#include <string>21#include <string_view>22#include <vector>24/**25* A network type.26* @note An address may belong to more than one network, for example `10.0.0.1`27* belongs to both `NET_UNROUTABLE` and `NET_IPV4`.28* Keep these sequential starting from 0 and `NET_MAX` as the last entry.29* We have loops like `for (int i = 0; i < NET_MAX; ++i)` that expect to iterate30* over all enum values and also `GetExtNetwork()` "extends" this enum by31* introducing standalone constants starting from `NET_MAX`.32*/33enum Network {34/// Addresses from these networks are not publicly routable on the global Internet.35NET_UNROUTABLE = 0,37/// IPv438NET_IPV4,40/// IPv641NET_IPV6,43/// TOR (v2 or v3)44NET_ONION,46/// I2P47NET_I2P,49/// CJDNS50NET_CJDNS,52/// A set of addresses that represent the hash of a string or FQDN. We use53/// them in AddrMan to keep track of which DNS seeds were used.54NET_INTERNAL,56/// Dummy value to indicate the number of NET_* constants.57NET_MAX,58};60/// Prefix of an IPv6 address when it contains an embedded IPv4 address.61/// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155).62inline constexpr std::array<uint8_t, 12> IPV4_IN_IPV6_PREFIX{630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF};65/// Prefix of an IPv6 address when it contains an embedded TORv2 address.66/// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155).67/// Such dummy IPv6 addresses are guaranteed to not be publicly routable as they68/// fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses.69inline constexpr std::array<uint8_t, 6> TORV2_IN_IPV6_PREFIX{700xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43};72/// Prefix of an IPv6 address when it contains an embedded "internal" address.73/// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155).74/// The prefix comes from 0xFD + SHA256("bitcoin")[0:5].75/// Such dummy IPv6 addresses are guaranteed to not be publicly routable as they76/// fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses.77inline constexpr std::array<uint8_t, 6> INTERNAL_IN_IPV6_PREFIX{780xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 // 0xFD + sha256("bitcoin")[0:5].79};81/// All CJDNS addresses start with 0xFC. See82/// https://github.com/cjdelisle/cjdns/blob/master/doc/Whitepaper.md#pulling-it-all-together83inline constexpr uint8_t CJDNS_PREFIX{0xFC};85/// Size of IPv4 address (in bytes).86inline constexpr size_t ADDR_IPV4_SIZE = 4;88/// Size of IPv6 address (in bytes).89inline constexpr size_t ADDR_IPV6_SIZE = 16;91/// Size of TORv3 address (in bytes). This is the length of just the address92/// as used in BIP155, without the checksum and the version byte.93inline constexpr size_t ADDR_TORV3_SIZE = 32;95/// Size of I2P address (in bytes).96inline constexpr size_t ADDR_I2P_SIZE = 32;98/// Size of CJDNS address (in bytes).99inline constexpr size_t ADDR_CJDNS_SIZE = 16;101/// Size of "internal" (NET_INTERNAL) address (in bytes).102inline constexpr size_t ADDR_INTERNAL_SIZE = 10;104/// SAM 3.1 and earlier do not support specifying ports and force the port to 0.105inline constexpr uint16_t I2P_SAM31_PORT{0};107std::string OnionToString(std::span<const uint8_t> addr);109/**110* Network address.111*/112class CNetAddr113{114protected:115/**116* Raw representation of the network address.117* In network byte order (big endian) for IPv4 and IPv6.118*/119prevector<ADDR_IPV6_SIZE, uint8_t> m_addr{ADDR_IPV6_SIZE, 0x0};121/**122* Network to which this address belongs.123*/124Network m_net{NET_IPV6};126/**127* Scope id if scoped/link-local IPV6 address.128* See https://tools.ietf.org/html/rfc4007129*/130uint32_t m_scope_id{0};132public:133CNetAddr();134explicit CNetAddr(const struct in_addr& ipv4Addr);135void SetIP(const CNetAddr& ip);137/**138* Set from a legacy IPv6 address.139* Legacy IPv6 address may be a normal IPv6 address, or another address140* (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy141* `addr` encoding.142*/143void SetLegacyIPv6(std::span<const uint8_t> ipv6);145bool SetInternal(const std::string& name);147/**148* Parse a Tor or I2P address and set this object to it.149* @param[in] addr Address to parse, for example150* pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion or151* ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p.152* @returns Whether the operation was successful.153* @see CNetAddr::IsTor(), CNetAddr::IsI2P()154*/155bool SetSpecial(std::string_view addr);157bool IsBindAny() const; // INADDR_ANY equivalent158[[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)159[[nodiscard]] bool IsIPv6() const { return m_net == NET_IPV6; } // IPv6 address (not mapped IPv4, not Tor)160bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)161bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)162bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)163bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)164bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)165bool IsRFC9637() const; // IPv6 documentation address (3FFF::/20)166bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)167bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)168bool IsRFC4193() const; // IPv6 unique local (FC00::/7)169bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32)170bool IsRFC4843() const; // IPv6 ORCHID (deprecated) (2001:10::/28)171bool IsRFC7343() const; // IPv6 ORCHIDv2 (2001:20::/28)172bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)173bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96)174bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765)175bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)176[[nodiscard]] bool IsTor() const { return m_net == NET_ONION; }177[[nodiscard]] bool IsI2P() const { return m_net == NET_I2P; }178[[nodiscard]] bool IsCJDNS() const { return m_net == NET_CJDNS; }179[[nodiscard]] bool HasCJDNSPrefix() const { return m_addr[0] == CJDNS_PREFIX; }180bool IsLocal() const;181bool IsRoutable() const;182bool IsInternal() const;183bool IsValid() const;185/**186* Whether this object is a privacy network.187* TODO: consider adding IsCJDNS() here when more peers adopt CJDNS, see:188* https://github.com/bitcoin/bitcoin/pull/27411#issuecomment-1497176155189*/190[[nodiscard]] bool IsPrivacyNet() const { return IsTor() || IsI2P(); }192/**193* Check if the current object can be serialized in pre-ADDRv2/BIP155 format.194*/195bool IsAddrV1Compatible() const;197enum Network GetNetwork() const;198std::string ToStringAddr() const;199bool GetInAddr(struct in_addr* pipv4Addr) const;200Network GetNetClass() const;202//! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32.203uint32_t GetLinkedIPv4() const;204//! Whether this address has a linked IPv4 address (see GetLinkedIPv4()).205bool HasLinkedIPv4() const;207std::vector<unsigned char> GetAddrBytes() const;208int GetReachabilityFrom(const CNetAddr& paddrPartner) const;210explicit CNetAddr(const struct in6_addr& pipv6Addr, uint32_t scope = 0);211bool GetIn6Addr(struct in6_addr* pipv6Addr) const;213friend bool operator==(const CNetAddr& a, const CNetAddr& b);214friend bool operator<(const CNetAddr& a, const CNetAddr& b);216/**217* Whether this address should be relayed to other peers even if we can't reach it ourselves.218*/219bool IsRelayable() const220{221return IsIPv4() || IsIPv6() || IsTor() || IsI2P() || IsCJDNS();222}224enum class Encoding {225V1,226V2, //!< BIP155 encoding227};228struct SerParams {229const Encoding enc;230SER_PARAMS_OPFUNC231};232static constexpr SerParams V1{Encoding::V1};233static constexpr SerParams V2{Encoding::V2};235/**236* Serialize to a stream.237*/238template <typename Stream>239void Serialize(Stream& s) const240{241if (s.template GetParams<SerParams>().enc == Encoding::V2) {242SerializeV2Stream(s);243} else {244SerializeV1Stream(s);245}246}248/**249* Unserialize from a stream.250*/
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.