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