LCOV - code coverage report
Current view: top level - src - netaddress.h (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 106 120 88.3 %
Date: 2020-06-05 16:23:38 Functions: 25 36 69.4 %
Legend: Lines: hit, modifiedhit, not modified not hit, modifiednot hit, not modified

          Line data    Source code
#       1             : // Copyright (c) 2009-2020 The Bitcoin Core developers
#       2             : // Distributed under the MIT software license, see the accompanying
#       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4             : 
#       5             : #ifndef BITCOIN_NETADDRESS_H
#       6             : #define BITCOIN_NETADDRESS_H
#       7             : 
#       8             : #if defined(HAVE_CONFIG_H)
#       9             : #include <config/bitcoin-config.h>
#      10             : #endif
#      11             : 
#      12             : #include <attributes.h>
#      13             : #include <compat.h>
#      14             : #include <serialize.h>
#      15             : #include <tinyformat.h>
#      16             : 
#      17             : #include <ios>
#      18             : #include <stdint.h>
#      19             : #include <string>
#      20             : #include <vector>
#      21             : 
#      22             : /**
#      23             :  * A flag that is ORed into the protocol version to designate that addresses
#      24             :  * should be serialized in (unserialized from) v2 format (BIP155).
#      25             :  * Make sure that this does not collide with any of the values in `version.h`
#      26             :  * or with `SERIALIZE_TRANSACTION_NO_WITNESS`.
#      27             :  */
#      28             : static const int ADDRv2_FORMAT = 0x20000000;
#      29             : 
#      30             : /**
#      31             :  * A network type.
#      32             :  * @note An address may belong to more than one network, for example `10.0.0.1`
#      33             :  * belongs to both `NET_UNROUTABLE` and `NET_IPV4`.
#      34             :  * Keep these sequential starting from 0 and `NET_MAX` as last.
#      35             :  */
#      36             : enum Network
#      37             : {
#      38             :     /// Addresses from these networks are not publicly routable on the global Internet.
#      39             :     NET_UNROUTABLE = 0,
#      40             : 
#      41             :     /// IPv4
#      42             :     NET_IPV4,
#      43             : 
#      44             :     /// IPv6
#      45             :     NET_IPV6,
#      46             : 
#      47             :     /// TORv2
#      48             :     NET_ONION,
#      49             : 
#      50             :     /// A set of dummy addresses that map a name to an IPv6 address.
#      51             :     NET_INTERNAL,
#      52             : 
#      53             :     /// Dummy value to indicate the number of NET_* constants.
#      54             :     NET_MAX,
#      55             : };
#      56             : 
#      57             : /// If an IPv6 address begins with this, then we treat the rest of it as IPv4 address.
#      58             : static constexpr uint8_t IPv4_IN_IPv6_PREFIX[12] = {
#      59             :     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0XFF
#      60             : };
#      61             : 
#      62             : /// If an IPv6 address begins with this, then we treat the rest of it as TORv2 address.
#      63             : static constexpr uint8_t TORv2_IN_IPv6_PREFIX[6] = {
#      64             :     0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43
#      65             : };
#      66             : 
#      67             : /// If an IPv6 address begins with this, then we treat the rest of it as an internal address.
#      68             : static constexpr uint8_t INTERNAL_IN_IPv6_PREFIX[6] = {
#      69             :     0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 // 0xFD + sha256("bitcoin")[0:5].
#      70             : };
#      71             : 
#      72             : /// Size of IPv4 address (in bytes).
#      73             : static constexpr size_t ADDR_IPv4_SIZE = 4;
#      74             : 
#      75             : /// Size of IPv6 address (in bytes).
#      76             : static constexpr size_t ADDR_IPv6_SIZE = 16;
#      77             : 
#      78             : /// Size of TORv2 address (in bytes).
#      79             : static constexpr size_t ADDR_TORv2_SIZE = 10;
#      80             : 
#      81             : /// Size of "internal" (NET_INTERNAL) address (in bytes).
#      82             : static constexpr size_t ADDR_INTERNAL_SIZE = 10;
#      83             : 
#      84             : /**
#      85             :  * Network address.
#      86             :  */
#      87             : class CNetAddr
#      88             : {
#      89             :     protected:
#      90             :         /**
#      91             :          * Network to which this address belongs.
#      92             :          */
#      93             :         Network m_net;
#      94             : 
#      95             :         /**
#      96             :          * Raw representation of the network address.
#      97             :          * In network byte order (big endian) for IPv4 and IPv6.
#      98             :          */
#      99             :         std::vector<uint8_t> m_addr;
#     100             : 
#     101             :         uint32_t scopeId{0}; // for scoped/link-local ipv6 addresses
#     102             : 
#     103             :     public:
#     104             :         CNetAddr();
#     105             :         explicit CNetAddr(const struct in_addr& ipv4Addr);
#     106             :         void SetIP(const CNetAddr& ip);
#     107             : 
#     108             :         /**
#     109             :          * Set raw IPv4 or IPv6 address (in network byte order)
#     110             :          * @note Only NET_IPV4 and NET_IPV6 are allowed for network.
#     111             :          */
#     112             :         void SetRaw(Network network, const uint8_t *data);
#     113             : 
#     114             :         bool SetInternal(const std::string& name);
#     115             : 
#     116             :         bool SetSpecial(const std::string &strName); // for Tor addresses
#     117             :         bool IsBindAny() const; // INADDR_ANY equivalent
#     118             :         bool IsIPv4() const;    // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
#     119             :         bool IsIPv6() const;    // IPv6 address (not mapped IPv4, not Tor)
#     120             :         bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
#     121             :         bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)
#     122             :         bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
#     123             :         bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24)
#     124             :         bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
#     125             :         bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
#     126             :         bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16)
#     127             :         bool IsRFC4193() const; // IPv6 unique local (FC00::/7)
#     128             :         bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32)
#     129             :         bool IsRFC4843() const; // IPv6 ORCHID (deprecated) (2001:10::/28)
#     130             :         bool IsRFC7343() const; // IPv6 ORCHIDv2 (2001:20::/28)
#     131             :         bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
#     132             :         bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96)
#     133             :         bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765)
#     134             :         bool IsHeNet() const;   // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)
#     135             :         bool IsTor() const;
#     136             :         bool IsLocal() const;
#     137             :         bool IsRoutable() const;
#     138             :         bool IsInternal() const;
#     139             :         bool IsValid() const;
#     140             : 
#     141             :         /**
#     142             :          * Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
#     143             :          */
#     144             :         bool IsAddrV1Compatible() const;
#     145             : 
#     146             :         enum Network GetNetwork() const;
#     147             :         std::string ToString() const;
#     148             :         std::string ToStringIP() const;
#     149             :         uint64_t GetHash() const;
#     150             : 
#     151             :         /**
#     152             :          * Get an identifier unique to this address.
#     153             :          */
#     154             :         std::vector<unsigned char> GetAddrKey() const;
#     155             : 
#     156             :         bool GetInAddr(struct in_addr* pipv4Addr) const;
#     157             :         uint32_t GetNetClass() const;
#     158             : 
#     159             :         //! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32.
#     160             :         uint32_t GetLinkedIPv4() const;
#     161             :         //! Whether this address has a linked IPv4 address (see GetLinkedIPv4()).
#     162             :         bool HasLinkedIPv4() const;
#     163             : 
#     164             :         // The AS on the BGP path to the node we use to diversify
#     165             :         // peers in AddrMan bucketing based on the AS infrastructure.
#     166             :         // The ip->AS mapping depends on how asmap is constructed.
#     167             :         uint32_t GetMappedAS(const std::vector<bool> &asmap) const;
#     168             : 
#     169             :         std::vector<unsigned char> GetGroup(const std::vector<bool> &asmap) const;
#     170             :         int GetReachabilityFrom(const CNetAddr *paddrPartner = nullptr) const;
#     171             : 
#     172             :         explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0);
#     173             :         bool GetIn6Addr(struct in6_addr* pipv6Addr) const;
#     174             : 
#     175             :         friend bool operator==(const CNetAddr& a, const CNetAddr& b);
#     176           0 :         friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); }
#     177             :         friend bool operator<(const CNetAddr& a, const CNetAddr& b);
#     178             : 
#     179             :         /**
#     180             :          * Serialize to a stream.
#     181             :          */
#     182             :         template <typename Stream>
#     183             :         void Serialize(Stream& s) const
#     184         156 :         {
#     185         156 :             if (s.GetVersion() & ADDRv2_FORMAT) {
#     186          50 :                 SerializeV2Stream(s);
#     187         106 :             } else {
#     188         106 :                 SerializeV1Stream(s);
#     189         106 :             }
#     190         156 :         }
#     191             : 
#     192             :         /**
#     193             :          * Unserialize from a stream.
#     194             :          * @throws std::ios_base::failure if the data is invalid and cannot be unserialized
#     195             :          */
#     196             :         template <typename Stream>
#     197             :         void Unserialize(Stream& s)
#     198          64 :         {
#     199          64 :             if (s.GetVersion() & ADDRv2_FORMAT) {
#     200          44 :                 UnserializeV2Stream(s);
#     201          44 :             } else {
#     202          20 :                 UnserializeV1Stream(s);
#     203          20 :             }
#     204          64 :         }
#     205             : 
#     206             :         friend class CSubNet;
#     207             : 
#     208             :     private:
#     209             :         /**
#     210             :          * BIP155 network id.
#     211             :          */
#     212             :         enum class Bip155NetworkId : uint8_t {
#     213             :             IPv4 = 0x01,
#     214             :             IPv6 = 0x02,
#     215             :             TORv2 = 0x03,
#     216             :             TORv3 = 0x04,
#     217             :             I2P = 0x05,
#     218             :             CJDNS = 0x06,
#     219             :         };
#     220             : 
#     221             :         /**
#     222             :          * Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes).
#     223             :          */
#     224             :         static constexpr size_t V1_SERIALIZATION_SIZE = 16;
#     225             : 
#     226             :         /**
#     227             :          * Maximum size of an address as defined in BIP155 (in bytes).
#     228             :          */
#     229             :         static constexpr size_t MAX_ADDRv2_SIZE = 512;
#     230             : 
#     231             :         /**
#     232             :          * Deduce the BIP155 network id of this address.
#     233             :          */
#     234             :         Bip155NetworkId ToBIP155NetworkId() const;
#     235             : 
#     236             :         /**
#     237             :          * Deduce the network type from BIP155 network id and size.
#     238             :          * @return true if the network is known and `net` was set
#     239             :          */
#     240             :         bool FromBIP155NetworkId(Bip155NetworkId bip155_network_id,
#     241             :             unsigned int address_size,
#     242             :             Network& net) const;
#     243             : 
#     244             :         /**
#     245             :          * Serialize in pre-ADDRv2/BIP155 format to an array.
#     246             :          * Some addresses (e.g. TORv3) cannot be serialized in pre-BIP155 format.
#     247             :          */
#     248             :         void SerializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE]) const
#     249     1255234 :         {
#     250     1255234 :             size_t prefix_size;
#     251     1255234 : 
#     252     1255234 :             switch (m_net) {
#     253     1255196 :             case NET_IPV4:
#     254     1255196 :                 prefix_size = sizeof(IPv4_IN_IPv6_PREFIX);
#     255     1255196 :                 assert(prefix_size + m_addr.size() == sizeof(arr));
#     256     1255196 :                 memcpy(arr, IPv4_IN_IPv6_PREFIX, prefix_size);
#     257     1255196 :                 memcpy(arr + prefix_size, m_addr.data(), m_addr.size());
#     258     1255196 :                 break;
#     259          36 :             case NET_IPV6:
#     260          36 :                 assert(m_addr.size() == sizeof(arr));
#     261          36 :                 memcpy(arr, m_addr.data(), m_addr.size());
#     262          36 :                 break;
#     263           2 :             case NET_ONION:
#     264           2 :                 prefix_size = sizeof(TORv2_IN_IPv6_PREFIX);
#     265           2 :                 assert(m_addr.size() + prefix_size == sizeof(arr));
#     266           2 :                 memcpy(arr, TORv2_IN_IPv6_PREFIX, prefix_size);
#     267           2 :                 memcpy(arr + prefix_size, m_addr.data(), m_addr.size());
#     268           2 :                 break;
#     269           0 :             case NET_INTERNAL:
#     270           0 :                 prefix_size = sizeof(INTERNAL_IN_IPv6_PREFIX);
#     271           0 :                 assert(m_addr.size() + prefix_size == sizeof(arr));
#     272           0 :                 memcpy(arr, INTERNAL_IN_IPv6_PREFIX, prefix_size);
#     273           0 :                 memcpy(arr + prefix_size, m_addr.data(), m_addr.size());
#     274           0 :                 break;
#     275           0 :             case NET_UNROUTABLE:
#     276           0 :             case NET_MAX:
#     277           0 :                 memset(arr, 0x0, sizeof(arr));
#     278           0 :                 break;
#     279     1255234 :             }
#     280     1255234 :         }
#     281             : 
#     282             :         /**
#     283             :          * Serialize in pre-ADDRv2/BIP155 format to a stream.
#     284             :          * Some addresses (e.g. TORv3) cannot be serialized in pre-BIP155 format.
#     285             :          */
#     286             :         template <typename Stream>
#     287             :         void SerializeV1Stream(Stream& s) const
#     288         106 :         {
#     289         106 :             uint8_t serialized[V1_SERIALIZATION_SIZE];
#     290         106 : 
#     291         106 :             SerializeV1Array(serialized);
#     292         106 : 
#     293         106 :             s << serialized;
#     294         106 :         }
#     295             : 
#     296             :         /**
#     297             :          * Serialize as ADDRv2 / BIP155.
#     298             :          */
#     299             :         template <typename Stream>
#     300             :         void SerializeV2Stream(Stream& s) const
#     301          50 :         {
#     302          50 :             if (IsValid()) {
#     303          40 :                 s << (uint8_t)ToBIP155NetworkId();
#     304          40 :                 s << m_addr;
#     305          40 :             } else {
#     306          10 :                 // At least lots of tests try to serialize a default-constructed
#     307          10 :                 // `CNetAddr`.
#     308          10 :                 s << (uint8_t)0x00;
#     309          10 :                 s << std::vector<uint8_t>();
#     310          10 :             }
#     311          50 :         }
#     312             : 
#     313             :         /**
#     314             :          * Unserialize from a pre-ADDRv2/BIP155 format from an array.
#     315             :          */
#     316             :         void UnserializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE])
#     317         156 :         {
#     318         156 :             if (memcmp(arr, IPv4_IN_IPv6_PREFIX, sizeof(IPv4_IN_IPv6_PREFIX)) == 0) {
#     319          28 :                 // IPv4-in-IPv6
#     320          28 :                 SetRaw(NET_IPV4, arr + sizeof(IPv4_IN_IPv6_PREFIX));
#     321         128 :             } else if (memcmp(arr, TORv2_IN_IPv6_PREFIX, sizeof(TORv2_IN_IPv6_PREFIX)) == 0) {
#     322           8 :                 // TORv2-in-IPv6
#     323           8 :                 m_net = NET_ONION;
#     324           8 :                 m_addr.assign(arr + sizeof(TORv2_IN_IPv6_PREFIX), arr + sizeof(arr));
#     325         120 :             } else if (memcmp(arr, INTERNAL_IN_IPv6_PREFIX, sizeof(INTERNAL_IN_IPv6_PREFIX)) == 0) {
#     326           2 :                 // Internal-in-IPv6
#     327           2 :                 m_net = NET_INTERNAL;
#     328           2 :                 m_addr.assign(arr + sizeof(INTERNAL_IN_IPv6_PREFIX), arr + sizeof(arr));
#     329         118 :             } else {
#     330         118 :                 // IPv6
#     331         118 :                 SetRaw(NET_IPV6, arr);
#     332         118 :             }
#     333         156 :         }
#     334             : 
#     335             :         /**
#     336             :          * Unserialize from a pre-ADDRv2/BIP155 format from a stream.
#     337             :          */
#     338             :         template <typename Stream>
#     339             :         void UnserializeV1Stream(Stream& s)
#     340          20 :         {
#     341          20 :             uint8_t serialized[V1_SERIALIZATION_SIZE];
#     342          20 : 
#     343          20 :             s >> serialized;
#     344          20 : 
#     345          20 :             UnserializeV1Array(serialized);
#     346          20 :         }
#     347             : 
#     348             :         /**
#     349             :          * Unserialize from a ADDRv2 / BIP155 format.
#     350             :          * @throws std::ios_base::failure if the data is invalid and cannot be unserialized
#     351             :          */
#     352             :         template <typename Stream>
#     353             :         void UnserializeV2Stream(Stream& s)
#     354          44 :         {
#     355          44 :             uint8_t bip155_network_id;
#     356          44 :             s >> bip155_network_id;
#     357          44 : 
#     358          44 :             unsigned int address_size;
#     359          44 :             s >> VARINT(address_size);
#     360          44 : 
#     361          44 :             if (address_size > MAX_ADDRv2_SIZE) {
#     362           0 :                 throw std::ios_base::failure(strprintf(
#     363           0 :                     "Address too long: %u > %zu", address_size, MAX_ADDRv2_SIZE));
#     364           0 :             }
#     365          44 : 
#     366          44 :             if (FromBIP155NetworkId((Bip155NetworkId)bip155_network_id, address_size, m_net)) {
#     367          34 :                 m_addr.resize(address_size);
#     368          34 :                 s >> MakeSpan(m_addr);
#     369          34 :             } else {
#     370          10 :                 // If we receive an unknown BIP155 network id (from the future?) then
#     371          10 :                 // mimic a default-constructed object which is !IsValid().
#     372          10 :                 m_net = NET_IPV6;
#     373          10 :                 m_addr.assign(ADDR_IPv6_SIZE, 0x0);
#     374          10 :             }
#     375          44 : 
#     376          44 :             scopeId = 0;
#     377          44 :         }
#     378             : };
#     379             : 
#     380             : class CSubNet
#     381             : {
#     382             :     protected:
#     383             :         /// Network (base) address
#     384             :         CNetAddr network;
#     385             :         /// Netmask, in network byte order
#     386             :         uint8_t netmask[16];
#     387             :         /// Is this value valid? (only used to signal parse errors)
#     388             :         bool valid;
#     389             : 
#     390             :     public:
#     391             :         CSubNet();
#     392             :         CSubNet(const CNetAddr &addr, uint8_t mask);
#     393             :         CSubNet(const CNetAddr &addr, const CNetAddr &mask);
#     394             : 
#     395             :         //constructor for single ip subnet (<ipv4>/32 or <ipv6>/128)
#     396             :         explicit CSubNet(const CNetAddr &addr);
#     397             : 
#     398             :         bool Match(const CNetAddr &addr) const;
#     399             : 
#     400             :         std::string ToString() const;
#     401             :         bool IsValid() const;
#     402             : 
#     403             :         friend bool operator==(const CSubNet& a, const CSubNet& b);
#     404           2 :         friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); }
#     405             :         friend bool operator<(const CSubNet& a, const CSubNet& b);
#     406             : 
#     407          40 :         SERIALIZE_METHODS(CSubNet, obj) { READWRITE(obj.network, obj.netmask, obj.valid); }
#     408             : };
#     409             : 
#     410             : /** A combination of a network address (CNetAddr) and a (TCP) port */
#     411             : class CService : public CNetAddr
#     412             : {
#     413             :     protected:
#     414             :         uint16_t port; // host order
#     415             : 
#     416             :     public:
#     417             :         CService();
#     418             :         CService(const CNetAddr& ip, unsigned short port);
#     419             :         CService(const struct in_addr& ipv4Addr, unsigned short port);
#     420             :         explicit CService(const struct sockaddr_in& addr);
#     421             :         unsigned short GetPort() const;
#     422             :         bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
#     423             :         bool SetSockAddr(const struct sockaddr* paddr);
#     424             :         friend bool operator==(const CService& a, const CService& b);
#     425         874 :         friend bool operator!=(const CService& a, const CService& b) { return !(a == b); }
#     426             :         friend bool operator<(const CService& a, const CService& b);
#     427             :         std::vector<unsigned char> GetKey() const;
#     428             :         std::string ToString() const;
#     429             :         std::string ToStringPort() const;
#     430             :         std::string ToStringIPPort() const;
#     431             : 
#     432             :         CService(const struct in6_addr& ipv6Addr, unsigned short port);
#     433             :         explicit CService(const struct sockaddr_in6& addr);
#     434             : 
#     435             :         SERIALIZE_METHODS(CService, obj)
#     436         116 :         {
#     437         116 :             READWRITEAS(CNetAddr, obj);
#     438         116 :             READWRITE(Using<BigEndianFormatter<2>>(obj.port));
#     439         116 :         }
#     440             : };
#     441             : 
#     442             : bool SanityCheckASMap(const std::vector<bool>& asmap);
#     443             : 
#     444             : #endif // BITCOIN_NETADDRESS_H

Generated by: LCOV version 1.14