/workdir/bitcoin/src/netaddress.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2009-2022 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(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(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 | 870 | [[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) |
158 | 3.77k | [[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 | 870 | [[nodiscard]] bool IsTor() const { return m_net == NET_ONION; } |
175 | 870 | [[nodiscard]] bool IsI2P() const { return m_net == NET_I2P; } |
176 | 0 | [[nodiscard]] bool IsCJDNS() const { return m_net == NET_CJDNS; } |
177 | 0 | [[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(); } Branch (188:54): [True: 0, False: 0]
Branch (188:65): [True: 0, False: 0]
|
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(); Branch (220:16): [True: 0, False: 0]
Branch (220:28): [True: 0, False: 0]
Branch (220:40): [True: 0, False: 0]
Branch (220:51): [True: 0, False: 0]
Branch (220:62): [True: 0, False: 0]
|
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 | 3.48k | { |
240 | 3.48k | if (s.template GetParams<SerParams>().enc == Encoding::V2) { Branch (240:13): [True: 0, False: 0]
Branch (240:13): [True: 0, False: 0]
Branch (240:13): [True: 0, False: 3.48k]
Branch (240:13): [True: 0, False: 0]
Branch (240:13): [True: 0, False: 0]
Branch (240:13): [True: 0, False: 0]
Branch (240:13): [True: 0, False: 0]
|
241 | 0 | SerializeV2Stream(s); |
242 | 3.48k | } else { |
243 | 3.48k | SerializeV1Stream(s); |
244 | 3.48k | } |
245 | 3.48k | } 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 void CNetAddr::Serialize<ParamsStream<VectorWriter&, CNetAddr::SerParams> >(ParamsStream<VectorWriter&, CNetAddr::SerParams>&) const Line | Count | Source | 239 | 3.48k | { | 240 | 3.48k | if (s.template GetParams<SerParams>().enc == Encoding::V2) { Branch (240:13): [True: 0, False: 3.48k]
| 241 | 0 | SerializeV2Stream(s); | 242 | 3.48k | } else { | 243 | 3.48k | SerializeV1Stream(s); | 244 | 3.48k | } | 245 | 3.48k | } |
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 |
246 | | |
247 | | /** |
248 | | * Unserialize from a stream. |
249 | | */ |
250 | | template <typename Stream> |
251 | | void Unserialize(Stream& s) |
252 | 870 | { |
253 | 870 | if (s.template GetParams<SerParams>().enc == Encoding::V2) { Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 870]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
Branch (253:13): [True: 0, False: 0]
|
254 | 0 | UnserializeV2Stream(s); |
255 | 870 | } else { |
256 | 870 | UnserializeV1Stream(s); |
257 | 870 | } |
258 | 870 | } 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>&) void CNetAddr::Unserialize<ParamsStream<DataStream&, CNetAddr::SerParams> >(ParamsStream<DataStream&, CNetAddr::SerParams>&) Line | Count | Source | 252 | 870 | { | 253 | 870 | if (s.template GetParams<SerParams>().enc == Encoding::V2) { Branch (253:13): [True: 0, False: 870]
| 254 | 0 | UnserializeV2Stream(s); | 255 | 870 | } else { | 256 | 870 | UnserializeV1Stream(s); | 257 | 870 | } | 258 | 870 | } |
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>&) |
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 | 3.48k | { |
326 | 3.48k | size_t prefix_size; |
327 | | |
328 | 3.48k | switch (m_net) { Branch (328:17): [True: 0, False: 3.48k]
|
329 | 3.48k | case NET_IPV6: Branch (329:9): [True: 3.48k, False: 0]
|
330 | 3.48k | assert(m_addr.size() == sizeof(arr)); |
331 | 3.48k | memcpy(arr, m_addr.data(), m_addr.size()); |
332 | 3.48k | return; |
333 | 0 | case NET_IPV4: Branch (333:9): [True: 0, False: 3.48k]
|
334 | 0 | prefix_size = sizeof(IPV4_IN_IPV6_PREFIX); |
335 | 0 | assert(prefix_size + m_addr.size() == sizeof(arr)); |
336 | 0 | memcpy(arr, IPV4_IN_IPV6_PREFIX.data(), prefix_size); |
337 | 0 | memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); |
338 | 0 | return; |
339 | 0 | case NET_INTERNAL: Branch (339:9): [True: 0, False: 3.48k]
|
340 | 0 | prefix_size = sizeof(INTERNAL_IN_IPV6_PREFIX); |
341 | 0 | assert(prefix_size + m_addr.size() == sizeof(arr)); |
342 | 0 | memcpy(arr, INTERNAL_IN_IPV6_PREFIX.data(), prefix_size); |
343 | 0 | memcpy(arr + prefix_size, m_addr.data(), m_addr.size()); |
344 | 0 | return; |
345 | 0 | case NET_ONION: Branch (345:9): [True: 0, False: 3.48k]
|
346 | 0 | case NET_I2P: Branch (346:9): [True: 0, False: 3.48k]
|
347 | 0 | case NET_CJDNS: Branch (347:9): [True: 0, False: 3.48k]
|
348 | 0 | break; |
349 | 0 | case NET_UNROUTABLE: Branch (349:9): [True: 0, False: 3.48k]
|
350 | 0 | case NET_MAX: Branch (350:9): [True: 0, False: 3.48k]
|
351 | 0 | assert(false); |
352 | 3.48k | } // 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 | 3.48k | { |
364 | 3.48k | uint8_t serialized[V1_SERIALIZATION_SIZE]; |
365 | | |
366 | 3.48k | SerializeV1Array(serialized); |
367 | | |
368 | 3.48k | s << serialized; |
369 | 3.48k | } 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 void CNetAddr::SerializeV1Stream<ParamsStream<VectorWriter&, CNetAddr::SerParams> >(ParamsStream<VectorWriter&, CNetAddr::SerParams>&) const Line | Count | Source | 363 | 3.48k | { | 364 | 3.48k | uint8_t serialized[V1_SERIALIZATION_SIZE]; | 365 | | | 366 | 3.48k | SerializeV1Array(serialized); | 367 | | | 368 | 3.48k | s << serialized; | 369 | 3.48k | } |
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 |
370 | | |
371 | | /** |
372 | | * Serialize as ADDRv2 / BIP155. |
373 | | */ |
374 | | template <typename Stream> |
375 | | void SerializeV2Stream(Stream& s) const |
376 | 0 | { |
377 | 0 | if (IsInternal()) { Branch (377:13): [True: 0, False: 0]
Branch (377:13): [True: 0, False: 0]
Branch (377:13): [True: 0, False: 0]
Branch (377:13): [True: 0, False: 0]
Branch (377:13): [True: 0, False: 0]
Branch (377:13): [True: 0, False: 0]
Branch (377:13): [True: 0, False: 0]
|
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); |
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: 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 |
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 | 870 | { |
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 | 870 | SetLegacyIPv6(arr); |
404 | 870 | } |
405 | | |
406 | | /** |
407 | | * Unserialize from a pre-ADDRv2/BIP155 format from a stream. |
408 | | */ |
409 | | template <typename Stream> |
410 | | void UnserializeV1Stream(Stream& s) |
411 | 870 | { |
412 | 870 | uint8_t serialized[V1_SERIALIZATION_SIZE]; |
413 | | |
414 | 870 | s >> serialized; |
415 | | |
416 | 870 | UnserializeV1Array(serialized); |
417 | 870 | } 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>&) void CNetAddr::UnserializeV1Stream<ParamsStream<DataStream&, CNetAddr::SerParams> >(ParamsStream<DataStream&, CNetAddr::SerParams>&) Line | Count | Source | 411 | 870 | { | 412 | 870 | uint8_t serialized[V1_SERIALIZATION_SIZE]; | 413 | | | 414 | 870 | s >> serialized; | 415 | | | 416 | 870 | UnserializeV1Array(serialized); | 417 | 870 | } |
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>&) |
418 | | |
419 | | /** |
420 | | * Unserialize from a ADDRv2 / BIP155 format. |
421 | | */ |
422 | | template <typename Stream> |
423 | | void UnserializeV2Stream(Stream& s) |
424 | 0 | { |
425 | 0 | uint8_t bip155_net; |
426 | 0 | s >> bip155_net; |
427 | |
|
428 | 0 | size_t address_size; |
429 | 0 | s >> COMPACTSIZE(address_size); |
430 | |
|
431 | 0 | if (address_size > MAX_ADDRV2_SIZE) { Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
Branch (431:13): [True: 0, False: 0]
|
432 | 0 | throw std::ios_base::failure(strprintf( |
433 | 0 | "Address too long: %u > %u", address_size, MAX_ADDRV2_SIZE)); |
434 | 0 | } |
435 | | |
436 | 0 | m_scope_id = 0; |
437 | |
|
438 | 0 | if (SetNetFromBIP155Network(bip155_net, address_size)) { Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
Branch (438:13): [True: 0, False: 0]
|
439 | 0 | m_addr.resize(address_size); |
440 | 0 | s >> Span{m_addr}; |
441 | |
|
442 | 0 | if (m_net != NET_IPV6) { Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
Branch (442:17): [True: 0, False: 0]
|
443 | 0 | return; |
444 | 0 | } |
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 | 0 | if (util::HasPrefix(m_addr, INTERNAL_IN_IPV6_PREFIX)) { Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
Branch (451:17): [True: 0, False: 0]
|
452 | 0 | m_net = NET_INTERNAL; |
453 | 0 | memmove(m_addr.data(), m_addr.data() + INTERNAL_IN_IPV6_PREFIX.size(), |
454 | 0 | ADDR_INTERNAL_SIZE); |
455 | 0 | m_addr.resize(ADDR_INTERNAL_SIZE); |
456 | 0 | return; |
457 | 0 | } |
458 | | |
459 | 0 | if (!util::HasPrefix(m_addr, IPV4_IN_IPV6_PREFIX) && Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
Branch (459:17): [True: 0, False: 0]
|
460 | 0 | !util::HasPrefix(m_addr, TORV2_IN_IPV6_PREFIX)) { Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
Branch (460:17): [True: 0, False: 0]
|
461 | 0 | return; |
462 | 0 | } |
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 | 0 | } 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 | 0 | m_net = NET_IPV6; |
475 | 0 | m_addr.assign(ADDR_IPV6_SIZE, 0x0); |
476 | 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>&) |
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 | | bool SetSockAddr(const struct sockaddr* paddr); |
543 | | /** |
544 | | * Get the address family |
545 | | * @returns AF_UNSPEC if unspecified |
546 | | */ |
547 | | [[nodiscard]] sa_family_t GetSAFamily() const; |
548 | | friend bool operator==(const CService& a, const CService& b); |
549 | 0 | friend bool operator!=(const CService& a, const CService& b) { return !(a == b); } |
550 | | friend bool operator<(const CService& a, const CService& b); |
551 | | std::vector<unsigned char> GetKey() const; |
552 | | std::string ToStringAddrPort() const; |
553 | | |
554 | | CService(const struct in6_addr& ipv6Addr, uint16_t port); |
555 | | explicit CService(const struct sockaddr_in6& addr); |
556 | | |
557 | | SERIALIZE_METHODS(CService, obj) |
558 | 4.35k | { |
559 | 4.35k | READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); |
560 | 4.35k | } Unexecuted instantiation: void CService::SerializationOps<ParamsStream<ParamsStream<DataStream&, CAddress::SerParams>&, CNetAddr::SerParams>, CService, ActionUnserialize>(CService&, ParamsStream<ParamsStream<DataStream&, CAddress::SerParams>&, CNetAddr::SerParams>&, ActionUnserialize) void CService::SerializationOps<ParamsStream<DataStream&, CNetAddr::SerParams>, CService, ActionUnserialize>(CService&, ParamsStream<DataStream&, CNetAddr::SerParams>&, ActionUnserialize) Line | Count | Source | 558 | 870 | { | 559 | 870 | READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | 560 | 870 | } |
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) void CService::SerializationOps<ParamsStream<VectorWriter&, CNetAddr::SerParams>, CService const, ActionSerialize>(CService const&, ParamsStream<VectorWriter&, CNetAddr::SerParams>&, ActionSerialize) Line | Count | Source | 558 | 3.48k | { | 559 | 3.48k | READWRITE(AsBase<CNetAddr>(obj), Using<BigEndianFormatter<2>>(obj.port)); | 560 | 3.48k | } |
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) |
561 | | |
562 | | friend class CServiceHash; |
563 | | friend CService MaybeFlipIPv6toCJDNS(const CService& service); |
564 | | }; |
565 | | |
566 | | class CServiceHash |
567 | | { |
568 | | public: |
569 | | CServiceHash() |
570 | 0 | : m_salt_k0{FastRandomContext().rand64()}, |
571 | 0 | m_salt_k1{FastRandomContext().rand64()} |
572 | 0 | { |
573 | 0 | } |
574 | | |
575 | 0 | CServiceHash(uint64_t salt_k0, uint64_t salt_k1) : m_salt_k0{salt_k0}, m_salt_k1{salt_k1} {} |
576 | | |
577 | | size_t operator()(const CService& a) const noexcept |
578 | 0 | { |
579 | 0 | CSipHasher hasher(m_salt_k0, m_salt_k1); |
580 | 0 | hasher.Write(a.m_net); |
581 | 0 | hasher.Write(a.port); |
582 | 0 | hasher.Write(a.m_addr); |
583 | 0 | return static_cast<size_t>(hasher.Finalize()); |
584 | 0 | } |
585 | | |
586 | | private: |
587 | | const uint64_t m_salt_k0; |
588 | | const uint64_t m_salt_k1; |
589 | | }; |
590 | | |
591 | | #endif // BITCOIN_NETADDRESS_H |