/Users/eugenesiegel/btc/bitcoin/src/netaddress.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2009-present 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 |  | #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> | 
| 16 |  |  | 
| 17 |  | #include <array> | 
| 18 |  | #include <cstdint> | 
| 19 |  | #include <ios> | 
| 20 |  | #include <string> | 
| 21 |  | #include <vector> | 
| 22 |  |  | 
| 23 |  | /** | 
| 24 |  |  * A network type. | 
| 25 |  |  * @note An address may belong to more than one network, for example `10.0.0.1` | 
| 26 |  |  * belongs to both `NET_UNROUTABLE` and `NET_IPV4`. | 
| 27 |  |  * Keep these sequential starting from 0 and `NET_MAX` as the last entry. | 
| 28 |  |  * We have loops like `for (int i = 0; i < NET_MAX; ++i)` that expect to iterate | 
| 29 |  |  * over all enum values and also `GetExtNetwork()` "extends" this enum by | 
| 30 |  |  * introducing standalone constants starting from `NET_MAX`. | 
| 31 |  |  */ | 
| 32 |  | enum Network { | 
| 33 |  |     /// Addresses from these networks are not publicly routable on the global Internet. | 
| 34 |  |     NET_UNROUTABLE = 0, | 
| 35 |  |  | 
| 36 |  |     /// IPv4 | 
| 37 |  |     NET_IPV4, | 
| 38 |  |  | 
| 39 |  |     /// IPv6 | 
| 40 |  |     NET_IPV6, | 
| 41 |  |  | 
| 42 |  |     /// TOR (v2 or v3) | 
| 43 |  |     NET_ONION, | 
| 44 |  |  | 
| 45 |  |     /// I2P | 
| 46 |  |     NET_I2P, | 
| 47 |  |  | 
| 48 |  |     /// CJDNS | 
| 49 |  |     NET_CJDNS, | 
| 50 |  |  | 
| 51 |  |     /// A set of addresses that represent the hash of a string or FQDN. We use | 
| 52 |  |     /// them in AddrMan to keep track of which DNS seeds were used. | 
| 53 |  |     NET_INTERNAL, | 
| 54 |  |  | 
| 55 |  |     /// Dummy value to indicate the number of NET_* constants. | 
| 56 |  |     NET_MAX, | 
| 57 |  | }; | 
| 58 |  |  | 
| 59 |  | /// Prefix of an IPv6 address when it contains an embedded IPv4 address. | 
| 60 |  | /// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155). | 
| 61 |  | static const std::array<uint8_t, 12> IPV4_IN_IPV6_PREFIX{ | 
| 62 |  |     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}; | 
| 63 |  |  | 
| 64 |  | /// Prefix of an IPv6 address when it contains an embedded TORv2 address. | 
| 65 |  | /// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155). | 
| 66 |  | /// Such dummy IPv6 addresses are guaranteed to not be publicly routable as they | 
| 67 |  | /// fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses. | 
| 68 |  | static const std::array<uint8_t, 6> TORV2_IN_IPV6_PREFIX{ | 
| 69 |  |     0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43}; | 
| 70 |  |  | 
| 71 |  | /// Prefix of an IPv6 address when it contains an embedded "internal" address. | 
| 72 |  | /// Used when (un)serializing addresses in ADDRv1 format (pre-BIP155). | 
| 73 |  | /// The prefix comes from 0xFD + SHA256("bitcoin")[0:5]. | 
| 74 |  | /// Such dummy IPv6 addresses are guaranteed to not be publicly routable as they | 
| 75 |  | /// fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses. | 
| 76 |  | static const std::array<uint8_t, 6> INTERNAL_IN_IPV6_PREFIX{ | 
| 77 |  |     0xFD, 0x6B, 0x88, 0xC0, 0x87, 0x24 // 0xFD + sha256("bitcoin")[0:5]. | 
| 78 |  | }; | 
| 79 |  |  | 
| 80 |  | /// All CJDNS addresses start with 0xFC. See | 
| 81 |  | /// https://github.com/cjdelisle/cjdns/blob/master/doc/Whitepaper.md#pulling-it-all-together | 
| 82 |  | static constexpr uint8_t CJDNS_PREFIX{0xFC}; | 
| 83 |  |  | 
| 84 |  | /// Size of IPv4 address (in bytes). | 
| 85 |  | static constexpr size_t ADDR_IPV4_SIZE = 4; | 
| 86 |  |  | 
| 87 |  | /// Size of IPv6 address (in bytes). | 
| 88 |  | static constexpr size_t ADDR_IPV6_SIZE = 16; | 
| 89 |  |  | 
| 90 |  | /// Size of TORv3 address (in bytes). This is the length of just the address | 
| 91 |  | /// as used in BIP155, without the checksum and the version byte. | 
| 92 |  | static constexpr size_t ADDR_TORV3_SIZE = 32; | 
| 93 |  |  | 
| 94 |  | /// Size of I2P address (in bytes). | 
| 95 |  | static constexpr size_t ADDR_I2P_SIZE = 32; | 
| 96 |  |  | 
| 97 |  | /// Size of CJDNS address (in bytes). | 
| 98 |  | static constexpr size_t ADDR_CJDNS_SIZE = 16; | 
| 99 |  |  | 
| 100 |  | /// Size of "internal" (NET_INTERNAL) address (in bytes). | 
| 101 |  | static constexpr size_t ADDR_INTERNAL_SIZE = 10; | 
| 102 |  |  | 
| 103 |  | /// SAM 3.1 and earlier do not support specifying ports and force the port to 0. | 
| 104 |  | static constexpr uint16_t I2P_SAM31_PORT{0}; | 
| 105 |  |  | 
| 106 |  | std::string OnionToString(std::span<const uint8_t> addr); | 
| 107 |  |  | 
| 108 |  | /** | 
| 109 |  |  * Network address. | 
| 110 |  |  */ | 
| 111 |  | class CNetAddr | 
| 112 |  | { | 
| 113 |  | protected: | 
| 114 |  |     /** | 
| 115 |  |      * Raw representation of the network address. | 
| 116 |  |      * In network byte order (big endian) for IPv4 and IPv6. | 
| 117 |  |      */ | 
| 118 |  |     prevector<ADDR_IPV6_SIZE, uint8_t> m_addr{ADDR_IPV6_SIZE, 0x0}; | 
| 119 |  |  | 
| 120 |  |     /** | 
| 121 |  |      * Network to which this address belongs. | 
| 122 |  |      */ | 
| 123 |  |     Network m_net{NET_IPV6}; | 
| 124 |  |  | 
| 125 |  |     /** | 
| 126 |  |      * Scope id if scoped/link-local IPV6 address. | 
| 127 |  |      * See https://tools.ietf.org/html/rfc4007 | 
| 128 |  |      */ | 
| 129 |  |     uint32_t m_scope_id{0}; | 
| 130 |  |  | 
| 131 |  | public: | 
| 132 |  |     CNetAddr(); | 
| 133 |  |     explicit CNetAddr(const struct in_addr& ipv4Addr); | 
| 134 |  |     void SetIP(const CNetAddr& ip); | 
| 135 |  |  | 
| 136 |  |     /** | 
| 137 |  |      * Set from a legacy IPv6 address. | 
| 138 |  |      * Legacy IPv6 address may be a normal IPv6 address, or another address | 
| 139 |  |      * (e.g. IPv4) disguised as IPv6. This encoding is used in the legacy | 
| 140 |  |      * `addr` encoding. | 
| 141 |  |      */ | 
| 142 |  |     void SetLegacyIPv6(std::span<const uint8_t> ipv6); | 
| 143 |  |  | 
| 144 |  |     bool SetInternal(const std::string& name); | 
| 145 |  |  | 
| 146 |  |     /** | 
| 147 |  |      * Parse a Tor or I2P address and set this object to it. | 
| 148 |  |      * @param[in] addr Address to parse, for example | 
| 149 |  |      * pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion or | 
| 150 |  |      * ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p. | 
| 151 |  |      * @returns Whether the operation was successful. | 
| 152 |  |      * @see CNetAddr::IsTor(), CNetAddr::IsI2P() | 
| 153 |  |      */ | 
| 154 |  |     bool SetSpecial(const std::string& addr); | 
| 155 |  |  | 
| 156 |  |     bool IsBindAny() const; // INADDR_ANY equivalent | 
| 157 | 4.81M |     [[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) | 
| 158 | 5.88M |     [[nodiscard]] bool IsIPv6() const { return m_net == NET_IPV6; } // IPv6 address (not mapped IPv4, not Tor) | 
| 159 |  |     bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) | 
| 160 |  |     bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15) | 
| 161 |  |     bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10) | 
| 162 |  |     bool IsRFC5737() const; // IPv4 documentation addresses (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) | 
| 163 |  |     bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32) | 
| 164 |  |     bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16) | 
| 165 |  |     bool IsRFC3964() const; // IPv6 6to4 tunnelling (2002::/16) | 
| 166 |  |     bool IsRFC4193() const; // IPv6 unique local (FC00::/7) | 
| 167 |  |     bool IsRFC4380() const; // IPv6 Teredo tunnelling (2001::/32) | 
| 168 |  |     bool IsRFC4843() const; // IPv6 ORCHID (deprecated) (2001:10::/28) | 
| 169 |  |     bool IsRFC7343() const; // IPv6 ORCHIDv2 (2001:20::/28) | 
| 170 |  |     bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64) | 
| 171 |  |     bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96) | 
| 172 |  |     bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765) | 
| 173 |  |     bool IsHeNet() const;   // IPv6 Hurricane Electric - https://he.net (2001:0470::/36) | 
| 174 | 3.20k |     [[nodiscard]] bool IsTor() const { return m_net == NET_ONION; } | 
| 175 | 2.96k |     [[nodiscard]] bool IsI2P() const { return m_net == NET_I2P; } | 
| 176 | 1.23M |     [[nodiscard]] bool IsCJDNS() const { return m_net == NET_CJDNS; } | 
| 177 | 3.59k |     [[nodiscard]] bool HasCJDNSPrefix() const { return m_addr[0] == CJDNS_PREFIX; } | 
| 178 |  |     bool IsLocal() const; | 
| 179 |  |     bool IsRoutable() const; | 
| 180 |  |     bool IsInternal() const; | 
| 181 |  |     bool IsValid() const; | 
| 182 |  |  | 
| 183 |  |     /** | 
| 184 |  |      * Whether this object is a privacy network. | 
| 185 |  |      * TODO: consider adding IsCJDNS() here when more peers adopt CJDNS, see: | 
| 186 |  |      * https://github.com/bitcoin/bitcoin/pull/27411#issuecomment-1497176155 | 
| 187 |  |      */ | 
| 188 | 0 |     [[nodiscard]] bool IsPrivacyNet() const { return IsTor() || IsI2P(); } | 
| 189 |  |  | 
| 190 |  |     /** | 
| 191 |  |      * Check if the current object can be serialized in pre-ADDRv2/BIP155 format. | 
| 192 |  |      */ | 
| 193 |  |     bool IsAddrV1Compatible() const; | 
| 194 |  |  | 
| 195 |  |     enum Network GetNetwork() const; | 
| 196 |  |     std::string ToStringAddr() const; | 
| 197 |  |     bool GetInAddr(struct in_addr* pipv4Addr) const; | 
| 198 |  |     Network GetNetClass() const; | 
| 199 |  |  | 
| 200 |  |     //! For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv4 address as a uint32. | 
| 201 |  |     uint32_t GetLinkedIPv4() const; | 
| 202 |  |     //! Whether this address has a linked IPv4 address (see GetLinkedIPv4()). | 
| 203 |  |     bool HasLinkedIPv4() const; | 
| 204 |  |  | 
| 205 |  |     std::vector<unsigned char> GetAddrBytes() const; | 
| 206 |  |     int GetReachabilityFrom(const CNetAddr& paddrPartner) const; | 
| 207 |  |  | 
| 208 |  |     explicit CNetAddr(const struct in6_addr& pipv6Addr, const uint32_t scope = 0); | 
| 209 |  |     bool GetIn6Addr(struct in6_addr* pipv6Addr) const; | 
| 210 |  |  | 
| 211 |  |     friend bool operator==(const CNetAddr& a, const CNetAddr& b); | 
| 212 | 0 |     friend bool operator!=(const CNetAddr& a, const CNetAddr& b) { return !(a == b); } | 
| 213 |  |     friend bool operator<(const CNetAddr& a, const CNetAddr& b); | 
| 214 |  |  | 
| 215 |  |     /** | 
| 216 |  |      * Whether this address should be relayed to other peers even if we can't reach it ourselves. | 
| 217 |  |      */ | 
| 218 |  |     bool IsRelayable() const | 
| 219 | 0 |     { | 
| 220 | 0 |         return IsIPv4() || IsIPv6() || IsTor() || IsI2P() || IsCJDNS(); | 
| 221 | 0 |     } | 
| 222 |  |  | 
| 223 |  |     enum class Encoding { | 
| 224 |  |         V1, | 
| 225 |  |         V2, //!< BIP155 encoding | 
| 226 |  |     }; | 
| 227 |  |     struct SerParams { | 
| 228 |  |         const Encoding enc; | 
| 229 |  |         SER_PARAMS_OPFUNC | 
| 230 |  |     }; | 
| 231 |  |     static constexpr SerParams V1{Encoding::V1}; | 
| 232 |  |     static constexpr SerParams V2{Encoding::V2}; | 
| 233 |  |  | 
| 234 |  |     /** | 
| 235 |  |      * Serialize to a stream. | 
| 236 |  |      */ | 
| 237 |  |     template <typename Stream> | 
| 238 |  |     void Serialize(Stream& s) const | 
| 239 | 769k |     { | 
| 240 | 769k |         if (s.template GetParams<SerParams>().enc == Encoding::V2) { | 
| 241 | 0 |             SerializeV2Stream(s); | 
| 242 | 769k |         } else { | 
| 243 | 769k |             SerializeV1Stream(s); | 
| 244 | 769k |         } | 
| 245 | 769k |     } Unexecuted instantiation: _ZNK8CNetAddr9SerializeI12ParamsStreamIR10DataStreamNS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr9SerializeI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEENS_9SerParamsEEEEvRT__ZNK8CNetAddr9SerializeI12ParamsStreamIR12VectorWriterNS_9SerParamsEEEEvRT_| Line | Count | Source |  | 239 | 769k |     { |  | 240 | 769k |         if (s.template GetParams<SerParams>().enc == Encoding::V2) { |  | 241 | 0 |             SerializeV2Stream(s); |  | 242 | 769k |         } else { |  | 243 | 769k |             SerializeV1Stream(s); |  | 244 | 769k |         } |  | 245 | 769k |     } | 
Unexecuted instantiation: _ZNK8CNetAddr9SerializeI12ParamsStreamIRS1_IR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr9SerializeI12ParamsStreamIR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr9SerializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr9SerializeI12ParamsStreamIRS1_IR12VectorWriterN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_ | 
| 246 |  |  | 
| 247 |  |     /** | 
| 248 |  |      * Unserialize from a stream. | 
| 249 |  |      */ | 
| 250 |  |     template <typename Stream> | 
| 251 |  |     void Unserialize(Stream& s) | 
| 252 | 574k |     { | 
| 253 | 574k |         if (s.template GetParams<SerParams>().enc == Encoding::V2) { | 
| 254 | 382k |             UnserializeV2Stream(s); | 
| 255 | 382k |         } else { | 
| 256 | 191k |             UnserializeV1Stream(s); | 
| 257 | 191k |         } | 
| 258 | 574k |     } Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEENS_9SerParamsEEEEvRT__ZN8CNetAddr11UnserializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_| Line | Count | Source |  | 252 | 382k |     { |  | 253 | 382k |         if (s.template GetParams<SerParams>().enc == Encoding::V2) { |  | 254 | 382k |             UnserializeV2Stream(s); |  | 255 | 382k |         } else { |  | 256 | 0 |             UnserializeV1Stream(s); |  | 257 | 0 |         } |  | 258 | 382k |     } | 
_ZN8CNetAddr11UnserializeI12ParamsStreamIR10DataStreamNS_9SerParamsEEEEvRT_| Line | Count | Source |  | 252 | 191k |     { |  | 253 | 191k |         if (s.template GetParams<SerParams>().enc == Encoding::V2) { |  | 254 | 0 |             UnserializeV2Stream(s); |  | 255 | 191k |         } else { |  | 256 | 191k |             UnserializeV1Stream(s); |  | 257 | 191k |         } |  | 258 | 191k |     } | 
Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIRS1_IR12HashVerifierI8AutoFileEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIRS1_IR8AutoFileN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIR8AutoFileN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIRS1_IR12HashVerifierI10DataStreamEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamIR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr11UnserializeI12ParamsStreamI10DataStreamN8CAddress9SerParamsEEEEvRT_ | 
| 259 |  |  | 
| 260 |  |     /** | 
| 261 |  |      * BIP155 network ids recognized by this software. | 
| 262 |  |      */ | 
| 263 |  |     enum BIP155Network : uint8_t { | 
| 264 |  |         IPV4 = 1, | 
| 265 |  |         IPV6 = 2, | 
| 266 |  |         TORV2 = 3, | 
| 267 |  |         TORV3 = 4, | 
| 268 |  |         I2P = 5, | 
| 269 |  |         CJDNS = 6, | 
| 270 |  |     }; | 
| 271 |  |  | 
| 272 |  |     friend class CSubNet; | 
| 273 |  |  | 
| 274 |  | private: | 
| 275 |  |     /** | 
| 276 |  |      * Parse a Tor address and set this object to it. | 
| 277 |  |      * @param[in] addr Address to parse, must be a valid C string, for example | 
| 278 |  |      * pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion. | 
| 279 |  |      * @returns Whether the operation was successful. | 
| 280 |  |      * @see CNetAddr::IsTor() | 
| 281 |  |      */ | 
| 282 |  |     bool SetTor(const std::string& addr); | 
| 283 |  |  | 
| 284 |  |     /** | 
| 285 |  |      * Parse an I2P address and set this object to it. | 
| 286 |  |      * @param[in] addr Address to parse, must be a valid C string, for example | 
| 287 |  |      * ukeu3k5oycgaauneqgtnvselmt4yemvoilkln7jpvamvfx7dnkdq.b32.i2p. | 
| 288 |  |      * @returns Whether the operation was successful. | 
| 289 |  |      * @see CNetAddr::IsI2P() | 
| 290 |  |      */ | 
| 291 |  |     bool SetI2P(const std::string& addr); | 
| 292 |  |  | 
| 293 |  |     /** | 
| 294 |  |      * Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes). | 
| 295 |  |      */ | 
| 296 |  |     static constexpr size_t V1_SERIALIZATION_SIZE = ADDR_IPV6_SIZE; | 
| 297 |  |  | 
| 298 |  |     /** | 
| 299 |  |      * Maximum size of an address as defined in BIP155 (in bytes). | 
| 300 |  |      * This is only the size of the address, not the entire CNetAddr object | 
| 301 |  |      * when serialized. | 
| 302 |  |      */ | 
| 303 |  |     static constexpr size_t MAX_ADDRV2_SIZE = 512; | 
| 304 |  |  | 
| 305 |  |     /** | 
| 306 |  |      * Get the BIP155 network id of this address. | 
| 307 |  |      * Must not be called for IsInternal() objects. | 
| 308 |  |      * @returns BIP155 network id, except TORV2 which is no longer supported. | 
| 309 |  |      */ | 
| 310 |  |     BIP155Network GetBIP155Network() const; | 
| 311 |  |  | 
| 312 |  |     /** | 
| 313 |  |      * Set `m_net` from the provided BIP155 network id and size after validation. | 
| 314 |  |      * @retval true the network was recognized, is valid and `m_net` was set | 
| 315 |  |      * @retval false not recognised (from future?) and should be silently ignored | 
| 316 |  |      * @throws std::ios_base::failure if the network is one of the BIP155 founding | 
| 317 |  |      * networks (id 1..6) with wrong address size. | 
| 318 |  |      */ | 
| 319 |  |     bool SetNetFromBIP155Network(uint8_t possible_bip155_net, size_t address_size); | 
| 320 |  |  | 
| 321 |  |     /** | 
| 322 |  |      * Serialize in pre-ADDRv2/BIP155 format to an array. | 
| 323 |  |      */ | 
| 324 |  |     void SerializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE]) const | 
| 325 | 991k |     { | 
| 326 | 991k |         size_t prefix_size; | 
| 327 |  |  | 
| 328 | 991k |         switch (m_net) { | 
| 329 | 698k |         case NET_IPV6: | 
| 330 | 698k |             assert(m_addr.size() == sizeof(arr)); | 
| 331 | 698k |             memcpy(arr, m_addr.data(), m_addr.size()); | 
| 332 | 698k |             return; | 
| 333 | 258k |         case NET_IPV4: | 
| 334 | 258k |             prefix_size = sizeof(IPV4_IN_IPV6_PREFIX); | 
| 335 | 258k |             assert(prefix_size + m_addr.size() == sizeof(arr)); | 
| 336 | 258k |             memcpy(arr, IPV4_IN_IPV6_PREFIX.data(), prefix_size); | 
| 337 | 258k |             memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); | 
| 338 | 258k |             return; | 
| 339 | 33.7k |         case NET_INTERNAL: | 
| 340 | 33.7k |             prefix_size = sizeof(INTERNAL_IN_IPV6_PREFIX); | 
| 341 | 33.7k |             assert(prefix_size + m_addr.size() == sizeof(arr)); | 
| 342 | 33.7k |             memcpy(arr, INTERNAL_IN_IPV6_PREFIX.data(), prefix_size); | 
| 343 | 33.7k |             memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); | 
| 344 | 33.7k |             return; | 
| 345 | 0 |         case NET_ONION: | 
| 346 | 0 |         case NET_I2P: | 
| 347 | 0 |         case NET_CJDNS: | 
| 348 | 0 |             break; | 
| 349 | 0 |         case NET_UNROUTABLE: | 
| 350 | 0 |         case NET_MAX: | 
| 351 | 0 |             assert(false); | 
| 352 | 991k |         } // no default case, so the compiler can warn about missing cases | 
| 353 |  |  | 
| 354 |  |         // Serialize ONION, I2P and CJDNS as all-zeros. | 
| 355 | 0 |         memset(arr, 0x0, V1_SERIALIZATION_SIZE); | 
| 356 | 0 |     } | 
| 357 |  |  | 
| 358 |  |     /** | 
| 359 |  |      * Serialize in pre-ADDRv2/BIP155 format to a stream. | 
| 360 |  |      */ | 
| 361 |  |     template <typename Stream> | 
| 362 |  |     void SerializeV1Stream(Stream& s) const | 
| 363 | 769k |     { | 
| 364 | 769k |         uint8_t serialized[V1_SERIALIZATION_SIZE]; | 
| 365 |  |  | 
| 366 | 769k |         SerializeV1Array(serialized); | 
| 367 |  |  | 
| 368 | 769k |         s << serialized; | 
| 369 | 769k |     } Unexecuted instantiation: _ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIR10DataStreamNS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEENS_9SerParamsEEEEvRT__ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIR12VectorWriterNS_9SerParamsEEEEvRT_| Line | Count | Source |  | 363 | 769k |     { |  | 364 | 769k |         uint8_t serialized[V1_SERIALIZATION_SIZE]; |  | 365 |  |  |  | 366 | 769k |         SerializeV1Array(serialized); |  | 367 |  |  |  | 368 | 769k |         s << serialized; |  | 369 | 769k |     } | 
Unexecuted instantiation: _ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIRS1_IR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV1StreamI12ParamsStreamIRS1_IR12VectorWriterN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_ | 
| 370 |  |  | 
| 371 |  |     /** | 
| 372 |  |      * Serialize as ADDRv2 / BIP155. | 
| 373 |  |      */ | 
| 374 |  |     template <typename Stream> | 
| 375 |  |     void SerializeV2Stream(Stream& s) const | 
| 376 | 0 |     { | 
| 377 | 0 |         if (IsInternal()) { | 
| 378 |  |             // Serialize NET_INTERNAL as embedded in IPv6. We need to | 
| 379 |  |             // serialize such addresses from addrman. | 
| 380 | 0 |             s << static_cast<uint8_t>(BIP155Network::IPV6); | 
| 381 | 0 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |             s << COMPACTSIZE(ADDR_IPV6_SIZE); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 | 
| 382 | 0 |             SerializeV1Stream(s); | 
| 383 | 0 |             return; | 
| 384 | 0 |         } | 
| 385 |  |  | 
| 386 | 0 |         s << static_cast<uint8_t>(GetBIP155Network()); | 
| 387 | 0 |         s << m_addr; | 
| 388 | 0 |     } Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIR10DataStreamNS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIR12VectorWriterNS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIRS1_IR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK8CNetAddr17SerializeV2StreamI12ParamsStreamIRS1_IR12VectorWriterN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_ | 
| 389 |  |  | 
| 390 |  |     /** | 
| 391 |  |      * Unserialize from a pre-ADDRv2/BIP155 format from an array. | 
| 392 |  |      * | 
| 393 |  |      * This function is only called from UnserializeV1Stream() and is a wrapper | 
| 394 |  |      * for SetLegacyIPv6(); however, we keep it for symmetry with | 
| 395 |  |      * SerializeV1Array() to have pairs of ser/unser functions and to make clear | 
| 396 |  |      * that if one is altered, a corresponding reverse modification should be | 
| 397 |  |      * applied to the other. | 
| 398 |  |      */ | 
| 399 |  |     void UnserializeV1Array(uint8_t (&arr)[V1_SERIALIZATION_SIZE]) | 
| 400 | 191k |     { | 
| 401 |  |         // Use SetLegacyIPv6() so that m_net is set correctly. For example | 
| 402 |  |         // ::FFFF:0102:0304 should be set as m_net=NET_IPV4 (1.2.3.4). | 
| 403 | 191k |         SetLegacyIPv6(arr); | 
| 404 | 191k |     } | 
| 405 |  |  | 
| 406 |  |     /** | 
| 407 |  |      * Unserialize from a pre-ADDRv2/BIP155 format from a stream. | 
| 408 |  |      */ | 
| 409 |  |     template <typename Stream> | 
| 410 |  |     void UnserializeV1Stream(Stream& s) | 
| 411 | 191k |     { | 
| 412 | 191k |         uint8_t serialized[V1_SERIALIZATION_SIZE]; | 
| 413 |  |  | 
| 414 | 191k |         s >> serialized; | 
| 415 |  |  | 
| 416 | 191k |         UnserializeV1Array(serialized); | 
| 417 | 191k |     } Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT__ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIR10DataStreamNS_9SerParamsEEEEvRT_| Line | Count | Source |  | 411 | 191k |     { |  | 412 | 191k |         uint8_t serialized[V1_SERIALIZATION_SIZE]; |  | 413 |  |  |  | 414 | 191k |         s >> serialized; |  | 415 |  |  |  | 416 | 191k |         UnserializeV1Array(serialized); |  | 417 | 191k |     } | 
Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIRS1_IR12HashVerifierI8AutoFileEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIRS1_IR8AutoFileN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIR8AutoFileN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIRS1_IR12HashVerifierI10DataStreamEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamIR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV1StreamI12ParamsStreamI10DataStreamN8CAddress9SerParamsEEEEvRT_ | 
| 418 |  |  | 
| 419 |  |     /** | 
| 420 |  |      * Unserialize from a ADDRv2 / BIP155 format. | 
| 421 |  |      */ | 
| 422 |  |     template <typename Stream> | 
| 423 |  |     void UnserializeV2Stream(Stream& s) | 
| 424 | 382k |     { | 
| 425 | 382k |         uint8_t bip155_net; | 
| 426 | 382k |         s >> bip155_net; | 
| 427 |  |  | 
| 428 | 382k |         size_t address_size; | 
| 429 | 382k |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 382k | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 0 | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 | 
| 430 |  |  | 
| 431 | 382k |         if (address_size > MAX_ADDRV2_SIZE) { | 
| 432 | 0 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 | 
| 433 | 0 |                 "Address too long: %u > %u", address_size, MAX_ADDRV2_SIZE)); | 
| 434 | 0 |         } | 
| 435 |  |  | 
| 436 | 382k |         m_scope_id = 0; | 
| 437 |  |  | 
| 438 | 382k |         if (SetNetFromBIP155Network(bip155_net, address_size)) { | 
| 439 | 382k |             m_addr.resize(address_size); | 
| 440 | 382k |             s >> std::span{m_addr}; | 
| 441 |  |  | 
| 442 | 382k |             if (m_net != NET_IPV6) { | 
| 443 | 367k |                 return; | 
| 444 | 367k |             } | 
| 445 |  |  | 
| 446 |  |             // Do some special checks on IPv6 addresses. | 
| 447 |  |  | 
| 448 |  |             // Recognize NET_INTERNAL embedded in IPv6, such addresses are not | 
| 449 |  |             // gossiped but could be coming from addrman, when unserializing from | 
| 450 |  |             // disk. | 
| 451 | 15.3k |             if (util::HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) { | 
| 452 | 22 |                 m_net = NET_INTERNAL; | 
| 453 | 22 |                 memmove(m_addr.data(), m_addr.data() + INTERNAL_IN_IPV6_PREFIX.size(), | 
| 454 | 22 |                         ADDR_INTERNAL_SIZE); | 
| 455 | 22 |                 m_addr.resize(ADDR_INTERNAL_SIZE); | 
| 456 | 22 |                 return; | 
| 457 | 22 |             } | 
| 458 |  |  | 
| 459 | 15.3k |             if (!util::HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) && | 
| 460 | 15.3k |                 !util::HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)15.3k) { | 
| 461 | 15.2k |                 return; | 
| 462 | 15.2k |             } | 
| 463 |  |  | 
| 464 |  |             // IPv4 and TORv2 are not supposed to be embedded in IPv6 (like in V1 | 
| 465 |  |             // encoding). Unserialize as !IsValid(), thus ignoring them. | 
| 466 | 15.3k |         } else { | 
| 467 |  |             // If we receive an unknown BIP155 network id (from the future?) then | 
| 468 |  |             // ignore the address - unserialize as !IsValid(). | 
| 469 | 0 |             s.ignore(address_size); | 
| 470 | 0 |         } | 
| 471 |  |  | 
| 472 |  |         // Mimic a default-constructed CNetAddr object which is !IsValid() and thus | 
| 473 |  |         // will not be gossiped, but continue reading next addresses from the stream. | 
| 474 | 63 |         m_net = NET_IPV6; | 
| 475 | 63 |         m_addr.assign(ADDR_IPV6_SIZE, 0x0); | 
| 476 | 63 |     } Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEENS_9SerParamsEEEEvRT__ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_| Line | Count | Source |  | 424 | 382k |     { |  | 425 | 382k |         uint8_t bip155_net; |  | 426 | 382k |         s >> bip155_net; |  | 427 |  |  |  | 428 | 382k |         size_t address_size; |  | 429 | 382k |         s >> COMPACTSIZE(address_size); | Line | Count | Source |  | 492 | 382k | #define COMPACTSIZE(obj) Using<CompactSizeFormatter<true>>(obj) | 
 |  | 430 |  |  |  | 431 | 382k |         if (address_size > MAX_ADDRV2_SIZE) { |  | 432 | 0 |             throw std::ios_base::failure(strprintf( | Line | Count | Source |  | 1172 | 0 | #define strprintf tfm::format | 
 |  | 433 | 0 |                 "Address too long: %u > %u", address_size, MAX_ADDRV2_SIZE)); |  | 434 | 0 |         } |  | 435 |  |  |  | 436 | 382k |         m_scope_id = 0; |  | 437 |  |  |  | 438 | 382k |         if (SetNetFromBIP155Network(bip155_net, address_size)) { |  | 439 | 382k |             m_addr.resize(address_size); |  | 440 | 382k |             s >> std::span{m_addr}; |  | 441 |  |  |  | 442 | 382k |             if (m_net != NET_IPV6) { |  | 443 | 367k |                 return; |  | 444 | 367k |             } |  | 445 |  |  |  | 446 |  |             // Do some special checks on IPv6 addresses. |  | 447 |  |  |  | 448 |  |             // Recognize NET_INTERNAL embedded in IPv6, such addresses are not |  | 449 |  |             // gossiped but could be coming from addrman, when unserializing from |  | 450 |  |             // disk. |  | 451 | 15.3k |             if (util::HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) { |  | 452 | 22 |                 m_net = NET_INTERNAL; |  | 453 | 22 |                 memmove(m_addr.data(), m_addr.data() + INTERNAL_IN_IPV6_PREFIX.size(), |  | 454 | 22 |                         ADDR_INTERNAL_SIZE); |  | 455 | 22 |                 m_addr.resize(ADDR_INTERNAL_SIZE); |  | 456 | 22 |                 return; |  | 457 | 22 |             } |  | 458 |  |  |  | 459 | 15.3k |             if (!util::HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) && |  | 460 | 15.3k |                 !util::HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)15.3k) { |  | 461 | 15.2k |                 return; |  | 462 | 15.2k |             } |  | 463 |  |  |  | 464 |  |             // IPv4 and TORv2 are not supposed to be embedded in IPv6 (like in V1 |  | 465 |  |             // encoding). Unserialize as !IsValid(), thus ignoring them. |  | 466 | 15.3k |         } else { |  | 467 |  |             // If we receive an unknown BIP155 network id (from the future?) then |  | 468 |  |             // ignore the address - unserialize as !IsValid(). |  | 469 | 0 |             s.ignore(address_size); |  | 470 | 0 |         } |  | 471 |  |  |  | 472 |  |         // Mimic a default-constructed CNetAddr object which is !IsValid() and thus |  | 473 |  |         // will not be gossiped, but continue reading next addresses from the stream. |  | 474 | 63 |         m_net = NET_IPV6; |  | 475 | 63 |         m_addr.assign(ADDR_IPV6_SIZE, 0x0); |  | 476 | 63 |     } | 
Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIR10DataStreamNS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIRS1_IR12HashVerifierI8AutoFileEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIRS1_IR8AutoFileN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIR8AutoFileN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIRS1_IR12HashVerifierI10DataStreamEN8CAddress9SerParamsEENS_9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamIR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN8CNetAddr19UnserializeV2StreamI12ParamsStreamI10DataStreamN8CAddress9SerParamsEEEEvRT_ | 
| 477 |  | }; | 
| 478 |  |  | 
| 479 |  | class CSubNet | 
| 480 |  | { | 
| 481 |  | protected: | 
| 482 |  |     /// Network (base) address | 
| 483 |  |     CNetAddr network; | 
| 484 |  |     /// Netmask, in network byte order | 
| 485 |  |     uint8_t netmask[16]; | 
| 486 |  |     /// Is this value valid? (only used to signal parse errors) | 
| 487 |  |     bool valid; | 
| 488 |  |  | 
| 489 |  | public: | 
| 490 |  |     /** | 
| 491 |  |      * Construct an invalid subnet (empty, `Match()` always returns false). | 
| 492 |  |      */ | 
| 493 |  |     CSubNet(); | 
| 494 |  |  | 
| 495 |  |     /** | 
| 496 |  |      * Construct from a given network start and number of bits (CIDR mask). | 
| 497 |  |      * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is | 
| 498 |  |      * created. | 
| 499 |  |      * @param[in] mask CIDR mask, must be in [0, 32] for IPv4 addresses and in [0, 128] for | 
| 500 |  |      * IPv6 addresses. Otherwise an invalid subnet is created. | 
| 501 |  |      */ | 
| 502 |  |     CSubNet(const CNetAddr& addr, uint8_t mask); | 
| 503 |  |  | 
| 504 |  |     /** | 
| 505 |  |      * Construct from a given network start and mask. | 
| 506 |  |      * @param[in] addr Network start. Must be IPv4 or IPv6, otherwise an invalid subnet is | 
| 507 |  |      * created. | 
| 508 |  |      * @param[in] mask Network mask, must be of the same type as `addr` and not contain 0-bits | 
| 509 |  |      * followed by 1-bits. Otherwise an invalid subnet is created. | 
| 510 |  |      */ | 
| 511 |  |     CSubNet(const CNetAddr& addr, const CNetAddr& mask); | 
| 512 |  |  | 
| 513 |  |     /** | 
| 514 |  |      * Construct a single-host subnet. | 
| 515 |  |      * @param[in] addr The sole address to be contained in the subnet, can also be non-IPv[46]. | 
| 516 |  |      */ | 
| 517 |  |     explicit CSubNet(const CNetAddr& addr); | 
| 518 |  |  | 
| 519 |  |     bool Match(const CNetAddr& addr) const; | 
| 520 |  |  | 
| 521 |  |     std::string ToString() const; | 
| 522 |  |     bool IsValid() const; | 
| 523 |  |  | 
| 524 |  |     friend bool operator==(const CSubNet& a, const CSubNet& b); | 
| 525 | 0 |     friend bool operator!=(const CSubNet& a, const CSubNet& b) { return !(a == b); } | 
| 526 |  |     friend bool operator<(const CSubNet& a, const CSubNet& b); | 
| 527 |  | }; | 
| 528 |  |  | 
| 529 |  | /** A combination of a network address (CNetAddr) and a (TCP) port */ | 
| 530 |  | class CService : public CNetAddr | 
| 531 |  | { | 
| 532 |  | protected: | 
| 533 |  |     uint16_t port; // host order | 
| 534 |  |  | 
| 535 |  | public: | 
| 536 |  |     CService(); | 
| 537 |  |     CService(const CNetAddr& ip, uint16_t port); | 
| 538 |  |     CService(const struct in_addr& ipv4Addr, uint16_t port); | 
| 539 |  |     explicit CService(const struct sockaddr_in& addr); | 
| 540 |  |     uint16_t GetPort() const; | 
| 541 |  |     bool GetSockAddr(struct sockaddr* paddr, socklen_t* addrlen) const; | 
| 542 |  |     /** | 
| 543 |  |      * Set CService from a network sockaddr. | 
| 544 |  |      * @param[in] paddr Pointer to sockaddr structure | 
| 545 |  |      * @param[in] addrlen Length of sockaddr structure in bytes. This will be checked to exactly match the length of | 
| 546 |  |      * a socket address of the provided family, unless std::nullopt is passed | 
| 547 |  |      * @returns true on success | 
| 548 |  |      */ | 
| 549 |  |     bool SetSockAddr(const struct sockaddr* paddr, socklen_t addrlen); | 
| 550 |  |     /** | 
| 551 |  |      * Get the address family | 
| 552 |  |      * @returns AF_UNSPEC if unspecified | 
| 553 |  |      */ | 
| 554 |  |     [[nodiscard]] sa_family_t GetSAFamily() const; | 
| 555 |  |     friend bool operator==(const CService& a, const CService& b); | 
| 556 | 0 |     friend bool operator!=(const CService& a, const CService& b) { return !(a == b); } | 
| 557 |  |     friend bool operator<(const CService& a, const CService& b); | 
| 558 |  |     std::vector<unsigned char> GetKey() const; | 
| 559 |  |     std::string ToStringAddrPort() const; | 
| 560 |  |  | 
| 561 |  |     CService(const struct in6_addr& ipv6Addr, uint16_t port); | 
| 562 |  |     explicit CService(const struct sockaddr_in6& addr); | 
| 563 |  |  | 
| 564 |  |     SERIALIZE_METHODS(CService, obj) | 
| 565 | 961k |     { | 
| 566 | 961k |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 191k | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 769k | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 0 | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 | 
| 567 | 961k |     } Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEEN8CNetAddr9SerParamsEES_17ActionUnserializeEEvRT0_RT_T1__ZN8CService16SerializationOpsI12ParamsStreamIR10DataStreamN8CNetAddr9SerParamsEES_17ActionUnserializeEEvRT0_RT_T1_| Line | Count | Source |  | 565 | 191k |     { |  | 566 | 191k |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 191k | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |  | 567 | 191k |     } | 
Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIR10DataStreamN8CNetAddr9SerParamsEEKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR10DataStreamN8CAddress9SerParamsEEN8CNetAddr9SerParamsEEKS_15ActionSerializeEEvRT0_RT_T1__ZN8CService16SerializationOpsI12ParamsStreamIR12VectorWriterN8CNetAddr9SerParamsEEKS_15ActionSerializeEEvRT0_RT_T1_| Line | Count | Source |  | 565 | 769k |     { |  | 566 | 769k |         READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | Line | Count | Source |  | 145 | 769k | #define READWRITE(...) (ser_action.SerReadWriteMany(s, __VA_ARGS__)) | 
 |  | 567 | 769k |     } | 
Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEN8CNetAddr9SerParamsEEKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEN8CNetAddr9SerParamsEES_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR8AutoFileN8CAddress9SerParamsEEN8CNetAddr9SerParamsEES_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEN8CNetAddr9SerParamsEES_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamI10DataStreamN8CAddress9SerParamsEES_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN8CService16SerializationOpsI12ParamsStreamIRS1_IR12VectorWriterN8CAddress9SerParamsEEN8CNetAddr9SerParamsEEKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 568 |  |  | 
| 569 |  |     friend class CServiceHash; | 
| 570 |  |     friend CService MaybeFlipIPv6toCJDNS(const CService& service); | 
| 571 |  | }; | 
| 572 |  |  | 
| 573 |  | class CServiceHash | 
| 574 |  | { | 
| 575 |  | public: | 
| 576 |  |     CServiceHash() | 
| 577 | 51.2k |         : m_salt_k0{FastRandomContext().rand64()}, | 
| 578 | 51.2k |           m_salt_k1{FastRandomContext().rand64()} | 
| 579 | 51.2k |     { | 
| 580 | 51.2k |     } | 
| 581 |  |  | 
| 582 | 0 |     CServiceHash(uint64_t salt_k0, uint64_t salt_k1) : m_salt_k0{salt_k0}, m_salt_k1{salt_k1} {} | 
| 583 |  |  | 
| 584 |  |     size_t operator()(const CService& a) const noexcept | 
| 585 | 23.9k |     { | 
| 586 | 23.9k |         CSipHasher hasher(m_salt_k0, m_salt_k1); | 
| 587 | 23.9k |         hasher.Write(a.m_net); | 
| 588 | 23.9k |         hasher.Write(a.port); | 
| 589 | 23.9k |         hasher.Write(a.m_addr); | 
| 590 | 23.9k |         return static_cast<size_t>(hasher.Finalize()); | 
| 591 | 23.9k |     } | 
| 592 |  |  | 
| 593 |  | private: | 
| 594 |  |     const uint64_t m_salt_k0; | 
| 595 |  |     const uint64_t m_salt_k1; | 
| 596 |  | }; | 
| 597 |  |  | 
| 598 |  | #endif // BITCOIN_NETADDRESS_H |