Bitcoin ABC 0.34.3
P2P Digital Currency
Loading...
Searching...
No Matches
netaddress.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <netaddress.h>
7
8#include <crypto/common.h>
9#include <crypto/sha3.h>
10#include <hash.h>
11#include <prevector.h>
12#include <util/asmap.h>
13#include <util/strencodings.h>
14#include <util/string.h>
15
16#include <tinyformat.h>
17
18#include <algorithm>
19#include <array>
20#include <cstdint>
21#include <ios>
22#include <iterator>
23#include <tuple>
24
26using util::HasPrefix;
27
29 switch (m_net) {
30 case NET_IPV4:
32 case NET_IPV6:
34 case NET_ONION:
35 switch (m_addr.size()) {
36 case ADDR_TORV2_SIZE:
38 case ADDR_TORV3_SIZE:
40 default:
41 assert(false);
42 }
43 case NET_I2P:
44 return BIP155Network::I2P;
45 case NET_CJDNS:
47 case NET_INTERNAL:
48 // should have been handled before calling this function
49 case NET_UNROUTABLE:
50 // m_net is never and should not be set to NET_UNROUTABLE
51 case NET_MAX:
52 // m_net is never and should not be set to NET_MAX
53 assert(false);
54 } // no default case, so the compiler can warn about missing cases
55
56 assert(false);
57}
58
59bool CNetAddr::SetNetFromBIP155Network(uint8_t possible_bip155_net,
60 size_t address_size) {
61 switch (possible_bip155_net) {
63 if (address_size == ADDR_IPV4_SIZE) {
65 return true;
66 }
67 throw std::ios_base::failure(
68 strprintf("BIP155 IPv4 address with length %u (should be %u)",
69 address_size, ADDR_IPV4_SIZE));
71 if (address_size == ADDR_IPV6_SIZE) {
73 return true;
74 }
75 throw std::ios_base::failure(
76 strprintf("BIP155 IPv6 address with length %u (should be %u)",
77 address_size, ADDR_IPV6_SIZE));
79 if (address_size == ADDR_TORV2_SIZE) {
81 return true;
82 }
83 throw std::ios_base::failure(
84 strprintf("BIP155 TORv2 address with length %u (should be %u)",
85 address_size, ADDR_TORV2_SIZE));
87 if (address_size == ADDR_TORV3_SIZE) {
89 return true;
90 }
91 throw std::ios_base::failure(
92 strprintf("BIP155 TORv3 address with length %u (should be %u)",
93 address_size, ADDR_TORV3_SIZE));
95 if (address_size == ADDR_I2P_SIZE) {
96 m_net = NET_I2P;
97 return true;
98 }
99 throw std::ios_base::failure(
100 strprintf("BIP155 I2P address with length %u (should be %u)",
101 address_size, ADDR_I2P_SIZE));
103 if (address_size == ADDR_CJDNS_SIZE) {
105 return true;
106 }
107 throw std::ios_base::failure(
108 strprintf("BIP155 CJDNS address with length %u (should be %u)",
109 address_size, ADDR_CJDNS_SIZE));
110 }
111
112 // Don't throw on addresses with unknown network ids (maybe from the
113 // future). Instead silently drop them and have the unserialization code
114 // consume subsequent ones which may be known to us.
115 return false;
116}
117
123CNetAddr::CNetAddr() = default;
124
125void CNetAddr::SetIP(const CNetAddr &ipIn) {
126 // Size check.
127 switch (ipIn.m_net) {
128 case NET_IPV4:
129 assert(ipIn.m_addr.size() == ADDR_IPV4_SIZE);
130 break;
131 case NET_IPV6:
132 assert(ipIn.m_addr.size() == ADDR_IPV6_SIZE);
133 break;
134 case NET_ONION:
135 assert(ipIn.m_addr.size() == ADDR_TORV2_SIZE ||
136 ipIn.m_addr.size() == ADDR_TORV3_SIZE);
137 break;
138 case NET_I2P:
139 assert(ipIn.m_addr.size() == ADDR_I2P_SIZE);
140 break;
141 case NET_CJDNS:
143 break;
144 case NET_INTERNAL:
146 break;
147 case NET_UNROUTABLE:
148 case NET_MAX:
149 assert(false);
150 } // no default case, so the compiler can warn about missing cases
151
152 m_net = ipIn.m_net;
153 m_addr = ipIn.m_addr;
154}
155
157 assert(ipv6.size() == ADDR_IPV6_SIZE);
158
159 size_t skip{0};
160
161 if (HasPrefix(ipv6, IPV4_IN_IPV6_PREFIX)) {
162 // IPv4-in-IPv6
163 m_net = NET_IPV4;
164 skip = sizeof(IPV4_IN_IPV6_PREFIX);
165 } else if (HasPrefix(ipv6, TORV2_IN_IPV6_PREFIX)) {
166 // TORv2-in-IPv6
168 skip = sizeof(TORV2_IN_IPV6_PREFIX);
169 } else if (HasPrefix(ipv6, INTERNAL_IN_IPV6_PREFIX)) {
170 // Internal-in-IPv6
172 skip = sizeof(INTERNAL_IN_IPV6_PREFIX);
173 } else {
174 // IPv6
175 m_net = NET_IPV6;
176 }
177
178 m_addr.assign(ipv6.begin() + skip, ipv6.end());
179}
180
188bool CNetAddr::SetInternal(const std::string &name) {
189 if (name.empty()) {
190 return false;
191 }
193 uint8_t hash[32] = {};
194 CSHA256().Write((const uint8_t *)name.data(), name.size()).Finalize(hash);
195 m_addr.assign(hash, hash + ADDR_INTERNAL_SIZE);
196 return true;
197}
198
199namespace torv3 {
200// https://gitweb.torproject.org/torspec.git/tree/rend-spec-v3.txt#n2135
201static constexpr size_t CHECKSUM_LEN = 2;
202static const uint8_t VERSION[] = {3};
203static constexpr size_t TOTAL_LEN =
205
206static void Checksum(Span<const uint8_t> addr_pubkey,
207 uint8_t (&checksum)[CHECKSUM_LEN]) {
208 // TORv3 CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]
209 static const uint8_t prefix[] = ".onion checksum";
210 static constexpr size_t prefix_len = 15;
211
212 SHA3_256 hasher;
213
214 hasher.Write(Span{prefix}.first(prefix_len));
215 hasher.Write(addr_pubkey);
216 hasher.Write(VERSION);
217
218 uint8_t checksum_full[SHA3_256::OUTPUT_SIZE];
219
220 hasher.Finalize(checksum_full);
221
222 memcpy(checksum, checksum_full, sizeof(checksum));
223}
224
225}; // namespace torv3
226
227bool CNetAddr::SetSpecial(const std::string &addr) {
228 if (!ContainsNoNUL(addr)) {
229 return false;
230 }
231
232 if (SetTor(addr)) {
233 return true;
234 }
235
236 if (SetI2P(addr)) {
237 return true;
238 }
239
240 return false;
241}
242
243bool CNetAddr::SetTor(const std::string &addr) {
244 static const char *suffix{".onion"};
245 static constexpr size_t suffix_len{6};
246
247 if (addr.size() <= suffix_len ||
248 addr.substr(addr.size() - suffix_len) != suffix) {
249 return false;
250 }
251
252 auto input = DecodeBase32(
253 std::string_view{addr}.substr(0, addr.size() - suffix_len));
254
255 if (!input) {
256 return false;
257 }
258
259 switch (input->size()) {
260 case ADDR_TORV2_SIZE:
262 m_addr.assign(input->begin(), input->end());
263 return true;
264 case torv3::TOTAL_LEN: {
265 Span<const uint8_t> input_pubkey{input->data(), ADDR_TORV3_SIZE};
266 Span<const uint8_t> input_checksum{input->data() + ADDR_TORV3_SIZE,
268 Span<const uint8_t> input_version{input->data() + ADDR_TORV3_SIZE +
270 sizeof(torv3::VERSION)};
271
272 if (input_version != torv3::VERSION) {
273 return false;
274 }
275
276 uint8_t calculated_checksum[torv3::CHECKSUM_LEN];
277 torv3::Checksum(input_pubkey, calculated_checksum);
278
279 if (input_checksum != calculated_checksum) {
280 return false;
281 }
282
284 m_addr.assign(input_pubkey.begin(), input_pubkey.end());
285 return true;
286 }
287 }
288
289 return false;
290}
291
292bool CNetAddr::SetI2P(const std::string &addr) {
293 // I2P addresses that we support consist of 52 base32 characters +
294 // ".b32.i2p".
295 static constexpr size_t b32_len{52};
296 static const char *suffix{".b32.i2p"};
297 static constexpr size_t suffix_len{8};
298
299 if (addr.size() != b32_len + suffix_len ||
300 ToLower(addr.substr(b32_len)) != suffix) {
301 return false;
302 }
303
304 // Remove the ".b32.i2p" suffix and pad to a multiple of 8 chars, so
305 // DecodeBase32() can decode it.
306 const std::string b32_padded = addr.substr(0, b32_len) + "====";
307
308 auto address_bytes = DecodeBase32(b32_padded);
309
310 if (!address_bytes || address_bytes->size() != ADDR_I2P_SIZE) {
311 return false;
312 }
313
314 m_net = NET_I2P;
315 m_addr.assign(address_bytes->begin(), address_bytes->end());
316
317 return true;
318}
319
320CNetAddr::CNetAddr(const struct in_addr &ipv4Addr) {
321 m_net = NET_IPV4;
322 const uint8_t *ptr = reinterpret_cast<const uint8_t *>(&ipv4Addr);
323 m_addr.assign(ptr, ptr + ADDR_IPV4_SIZE);
324}
325
326CNetAddr::CNetAddr(const struct in6_addr &ipv6Addr, const uint32_t scope) {
328 {reinterpret_cast<const uint8_t *>(&ipv6Addr), sizeof(ipv6Addr)});
329 m_scope_id = scope;
330}
331
333 if (!IsIPv4() && !IsIPv6()) {
334 return false;
335 }
336 return std::all_of(m_addr.begin(), m_addr.end(),
337 [](uint8_t b) { return b == 0; });
338}
339
340bool CNetAddr::IsIPv4() const {
341 return m_net == NET_IPV4;
342}
343
344bool CNetAddr::IsIPv6() const {
345 return m_net == NET_IPV6;
346}
347
349 return IsIPv4() &&
350 (m_addr[0] == 10 || (m_addr[0] == 192 && m_addr[1] == 168) ||
351 (m_addr[0] == 172 && m_addr[1] >= 16 && m_addr[1] <= 31));
352}
353
355 return IsIPv4() && m_addr[0] == 198 && (m_addr[1] == 18 || m_addr[1] == 19);
356}
357
359 return IsIPv4() && HasPrefix(m_addr, std::array<uint8_t, 2>{{169, 254}});
360}
361
363 return IsIPv4() && m_addr[0] == 100 && m_addr[1] >= 64 && m_addr[1] <= 127;
364}
365
367 return IsIPv4() &&
368 (HasPrefix(m_addr, std::array<uint8_t, 3>{{192, 0, 2}}) ||
369 HasPrefix(m_addr, std::array<uint8_t, 3>{{198, 51, 100}}) ||
370 HasPrefix(m_addr, std::array<uint8_t, 3>{{203, 0, 113}}));
371}
372
374 return IsIPv6() &&
375 HasPrefix(m_addr, std::array<uint8_t, 4>{{0x20, 0x01, 0x0D, 0xB8}});
376}
377
379 return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 2>{{0x20, 0x02}});
380}
381
383 return IsIPv6() &&
384 HasPrefix(m_addr, std::array<uint8_t, 12>{{0x00, 0x64, 0xFF, 0x9B,
385 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00}});
387}
388
390 return IsIPv6() &&
391 HasPrefix(m_addr, std::array<uint8_t, 4>{{0x20, 0x01, 0x00, 0x00}});
392}
393
395 return IsIPv6() &&
396 HasPrefix(m_addr, std::array<uint8_t, 8>{{0xFE, 0x80, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00}});
398}
399
401 return IsIPv6() && (m_addr[0] & 0xFE) == 0xFC;
402}
403
405 return IsIPv6() &&
406 HasPrefix(m_addr, std::array<uint8_t, 12>{{0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00,
408 0xFF, 0xFF, 0x00, 0x00}});
409}
410
412 return IsIPv6() &&
413 HasPrefix(m_addr, std::array<uint8_t, 3>{{0x20, 0x01, 0x00}}) &&
414 (m_addr[3] & 0xF0) == 0x10;
415}
416
418 return IsIPv6() &&
419 HasPrefix(m_addr, std::array<uint8_t, 3>{{0x20, 0x01, 0x00}}) &&
420 (m_addr[3] & 0xF0) == 0x20;
421}
422
423bool CNetAddr::IsHeNet() const {
424 return IsIPv6() &&
425 HasPrefix(m_addr, std::array<uint8_t, 4>{{0x20, 0x01, 0x04, 0x70}});
426}
427
433bool CNetAddr::IsTor() const {
434 return m_net == NET_ONION;
435}
436
440bool CNetAddr::IsI2P() const {
441 return m_net == NET_I2P;
442}
443
447bool CNetAddr::IsCJDNS() const {
448 return m_net == NET_CJDNS;
449}
450
451bool CNetAddr::IsLocal() const {
452 // IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)
453 if (IsIPv4() && (m_addr[0] == 127 || m_addr[0] == 0)) {
454 return true;
455 }
456
457 // IPv6 loopback (::1/128)
458 static const uint8_t pchLocal[16] = {0, 0, 0, 0, 0, 0, 0, 0,
459 0, 0, 0, 0, 0, 0, 0, 1};
460 if (IsIPv6() && memcmp(m_addr.data(), pchLocal, sizeof(pchLocal)) == 0) {
461 return true;
462 }
463
464 return false;
465}
466
477bool CNetAddr::IsValid() const {
478 // unspecified IPv6 address (::/128)
479 uint8_t ipNone6[16] = {};
480 if (IsIPv6() && memcmp(m_addr.data(), ipNone6, sizeof(ipNone6)) == 0) {
481 return false;
482 }
483
484 if (IsCJDNS() && !HasCJDNSPrefix()) {
485 return false;
486 }
487
488 // documentation IPv6 address
489 if (IsRFC3849()) {
490 return false;
491 }
492
493 if (IsInternal()) {
494 return false;
495 }
496
497 if (IsIPv4()) {
498 const uint32_t addr = ReadBE32(m_addr.data());
499 if (addr == INADDR_ANY || addr == INADDR_NONE) {
500 return false;
501 }
502 }
503
504 return true;
505}
506
517 return IsValid() &&
518 !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() ||
519 IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) ||
520 IsRFC4843() || IsRFC7343() || IsLocal() || IsInternal());
521}
522
529 return m_net == NET_INTERNAL;
530}
531
533 switch (m_net) {
534 case NET_IPV4:
535 case NET_IPV6:
536 case NET_INTERNAL:
537 return true;
538 case NET_ONION:
539 return m_addr.size() == ADDR_TORV2_SIZE;
540 case NET_I2P:
541 case NET_CJDNS:
542 return false;
543 case NET_UNROUTABLE:
544 // m_net is never and should not be set to NET_UNROUTABLE
545 case NET_MAX:
546 // m_net is never and should not be set to NET_MAX
547 assert(false);
548 } // no default case, so the compiler can warn about missing cases
549
550 assert(false);
551}
552
554 if (IsInternal()) {
555 return NET_INTERNAL;
556 }
557
558 if (!IsRoutable()) {
559 return NET_UNROUTABLE;
560 }
561
562 return m_net;
563}
564
565static std::string IPv4ToString(Span<const uint8_t> a) {
566 return strprintf("%u.%u.%u.%u", a[0], a[1], a[2], a[3]);
567}
568
572static std::string IPv6ToString(Span<const uint8_t> a, uint32_t scope_id) {
573 assert(a.size() == ADDR_IPV6_SIZE);
574 const std::array<uint16_t, 8> groups{{
575 ReadBE16(&a[0]),
576 ReadBE16(&a[2]),
577 ReadBE16(&a[4]),
578 ReadBE16(&a[6]),
579 ReadBE16(&a[8]),
580 ReadBE16(&a[10]),
581 ReadBE16(&a[12]),
582 ReadBE16(&a[14]),
583 }};
584
585 // The zero compression implementation is inspired by Rust's
586 // std::net::Ipv6Addr, see
587 // https://github.com/rust-lang/rust/blob/cc4103089f40a163f6d143f06359cba7043da29b/library/std/src/net/ip.rs#L1635-L1683
588 struct ZeroSpan {
589 size_t start_index{0};
590 size_t len{0};
591 };
592
593 // Find longest sequence of consecutive all-zero fields. Use first zero
594 // sequence if two or more zero sequences of equal length are found.
595 ZeroSpan longest, current;
596 for (size_t i{0}; i < groups.size(); ++i) {
597 if (groups[i] != 0) {
598 current = {i + 1, 0};
599 continue;
600 }
601 current.len += 1;
602 if (current.len > longest.len) {
603 longest = current;
604 }
605 }
606
607 std::string r;
608 r.reserve(39);
609 for (size_t i{0}; i < groups.size(); ++i) {
610 // Replace the longest sequence of consecutive all-zero fields with
611 // two colons ("::").
612 if (longest.len >= 2 && i >= longest.start_index &&
613 i < longest.start_index + longest.len) {
614 if (i == longest.start_index) {
615 r += "::";
616 }
617 continue;
618 }
619 r += strprintf("%s%x", ((!r.empty() && r.back() != ':') ? ":" : ""),
620 groups[i]);
621 }
622
623 if (scope_id != 0) {
624 r += strprintf("%%%u", scope_id);
625 }
626
627 return r;
628}
629
630std::string CNetAddr::ToStringAddr() const {
631 switch (m_net) {
632 case NET_IPV4:
633 return IPv4ToString(m_addr);
634 case NET_IPV6:
636 case NET_ONION:
637 switch (m_addr.size()) {
638 case ADDR_TORV2_SIZE:
639 return EncodeBase32(m_addr) + ".onion";
640 case ADDR_TORV3_SIZE: {
641 uint8_t checksum[torv3::CHECKSUM_LEN];
642 torv3::Checksum(m_addr, checksum);
643
644 // TORv3 onion_address = base32(PUBKEY | CHECKSUM | VERSION)
645 // + ".onion"
647 m_addr.end()};
648 address.insert(address.end(), checksum,
649 checksum + torv3::CHECKSUM_LEN);
650 address.insert(address.end(), torv3::VERSION,
652
653 return EncodeBase32(address) + ".onion";
654 }
655 default:
656 assert(false);
657 }
658 case NET_I2P:
659 return EncodeBase32(m_addr, false /* don't pad with = */) +
660 ".b32.i2p";
661 case NET_CJDNS:
662 return IPv6ToString(m_addr, 0);
663 case NET_INTERNAL:
664 return EncodeBase32(m_addr) + ".internal";
665 case NET_UNROUTABLE:
666 // m_net is never and should not be set to NET_UNROUTABLE
667 case NET_MAX:
668 // m_net is never and should not be set to NET_MAX
669 assert(false);
670 } // no default case, so the compiler can warn about missing cases
671
672 assert(false);
673}
674
675bool operator==(const CNetAddr &a, const CNetAddr &b) {
676 return a.m_net == b.m_net && a.m_addr == b.m_addr;
677}
678
679bool operator<(const CNetAddr &a, const CNetAddr &b) {
680 return std::tie(a.m_net, a.m_addr) < std::tie(b.m_net, b.m_addr);
681}
682
693bool CNetAddr::GetInAddr(struct in_addr *pipv4Addr) const {
694 if (!IsIPv4()) {
695 return false;
696 }
697 assert(sizeof(*pipv4Addr) == m_addr.size());
698 memcpy(pipv4Addr, m_addr.data(), m_addr.size());
699 return true;
700}
701
712bool CNetAddr::GetIn6Addr(struct in6_addr *pipv6Addr) const {
713 if (!IsIPv6()) {
714 return false;
715 }
716 assert(sizeof(*pipv6Addr) == m_addr.size());
717 memcpy(pipv6Addr, m_addr.data(), m_addr.size());
718 return true;
719}
720
722 return IsRoutable() && (IsIPv4() || IsRFC6145() || IsRFC6052() ||
723 IsRFC3964() || IsRFC4380());
724}
725
726uint32_t CNetAddr::GetLinkedIPv4() const {
727 if (IsIPv4()) {
728 return ReadBE32(m_addr.data());
729 } else if (IsRFC6052() || IsRFC6145()) {
730 // mapped IPv4, SIIT translated IPv4: the IPv4 address is the last 4
731 // bytes of the address
732 return ReadBE32(Span{m_addr}.last(ADDR_IPV4_SIZE).data());
733 } else if (IsRFC3964()) {
734 // 6to4 tunneled IPv4: the IPv4 address is in bytes 2-6
735 return ReadBE32(Span{m_addr}.subspan(2, ADDR_IPV4_SIZE).data());
736 } else if (IsRFC4380()) {
737 // Teredo tunneled IPv4: the IPv4 address is in the last 4 bytes of the
738 // address, but bitflipped
739 return ~ReadBE32(Span{m_addr}.last(ADDR_IPV4_SIZE).data());
740 }
741 assert(false);
742}
743
745 // Make sure that if we return NET_IPV6, then IsIPv6() is true. The callers
746 // expect that.
747
748 // Check for "internal" first because such addresses are also !IsRoutable()
749 // and we don't want to return NET_UNROUTABLE in that case.
750 if (IsInternal()) {
751 return NET_INTERNAL;
752 }
753 if (!IsRoutable()) {
754 return NET_UNROUTABLE;
755 }
756 if (HasLinkedIPv4()) {
757 return NET_IPV4;
758 }
759 return m_net;
760}
761
762uint32_t CNetAddr::GetMappedAS(const std::vector<bool> &asmap) const {
763 uint32_t net_class = GetNetClass();
764 if (asmap.size() == 0 || (net_class != NET_IPV4 && net_class != NET_IPV6)) {
765 return 0; // Indicates not found, safe because AS0 is reserved per
766 // RFC7607.
767 }
768 std::vector<bool> ip_bits(128);
769 if (HasLinkedIPv4()) {
770 // For lookup, treat as if it was just an IPv4 address
771 // (IPV4_IN_IPV6_PREFIX + IPv4 bits)
772 for (int8_t byte_i = 0; byte_i < 12; ++byte_i) {
773 for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
774 ip_bits[byte_i * 8 + bit_i] =
775 (IPV4_IN_IPV6_PREFIX[byte_i] >> (7 - bit_i)) & 1;
776 }
777 }
778 uint32_t ipv4 = GetLinkedIPv4();
779 for (int i = 0; i < 32; ++i) {
780 ip_bits[96 + i] = (ipv4 >> (31 - i)) & 1;
781 }
782 } else {
783 // Use all 128 bits of the IPv6 address otherwise
784 assert(IsIPv6());
785 for (int8_t byte_i = 0; byte_i < 16; ++byte_i) {
786 uint8_t cur_byte = m_addr[byte_i];
787 for (uint8_t bit_i = 0; bit_i < 8; ++bit_i) {
788 ip_bits[byte_i * 8 + bit_i] = (cur_byte >> (7 - bit_i)) & 1;
789 }
790 }
791 }
792 uint32_t mapped_as = Interpret(asmap, ip_bits);
793 return mapped_as;
794}
795
806std::vector<uint8_t> CNetAddr::GetGroup(const std::vector<bool> &asmap) const {
807 std::vector<uint8_t> vchRet;
808 uint32_t net_class = GetNetClass();
809 // If non-empty asmap is supplied and the address is IPv4/IPv6,
810 // return ASN to be used for bucketing.
811 uint32_t asn = GetMappedAS(asmap);
812 if (asn != 0) { // Either asmap was empty, or address has non-asmappable net
813 // class (e.g. TOR).
814 vchRet.push_back(NET_IPV6); // IPv4 and IPv6 with same ASN should be in
815 // the same bucket
816 for (int i = 0; i < 4; i++) {
817 vchRet.push_back((asn >> (8 * i)) & 0xFF);
818 }
819 return vchRet;
820 }
821
822 vchRet.push_back(net_class);
823 int nBits{0};
824
825 if (IsLocal()) {
826 // all local addresses belong to the same group
827 } else if (IsInternal()) {
828 // all internal-usage addresses get their own group
829 nBits = ADDR_INTERNAL_SIZE * 8;
830 } else if (!IsRoutable()) {
831 // all other unroutable addresses belong to the same group
832 } else if (HasLinkedIPv4()) {
833 // IPv4 addresses (and mapped IPv4 addresses) use /16 groups
834 uint32_t ipv4 = GetLinkedIPv4();
835 vchRet.push_back((ipv4 >> 24) & 0xFF);
836 vchRet.push_back((ipv4 >> 16) & 0xFF);
837 return vchRet;
838 } else if (IsTor() || IsI2P() || IsCJDNS()) {
839 nBits = 4;
840 } else if (IsHeNet()) {
841 // for he.net, use /36 groups
842 nBits = 36;
843 } else {
844 // for the rest of the IPv6 network, use /32 groups
845 nBits = 32;
846 }
847
848 // Push our address onto vchRet.
849 const size_t num_bytes = nBits / 8;
850 vchRet.insert(vchRet.end(), m_addr.begin(), m_addr.begin() + num_bytes);
851 nBits %= 8;
852 // ...for the last byte, push nBits and for the rest of the byte push 1's
853 if (nBits > 0) {
854 assert(num_bytes < m_addr.size());
855 vchRet.push_back(m_addr[num_bytes] | ((1 << (8 - nBits)) - 1));
856 }
857
858 return vchRet;
859}
860
861std::vector<uint8_t> CNetAddr::GetAddrBytes() const {
862 if (IsAddrV1Compatible()) {
863 uint8_t serialized[V1_SERIALIZATION_SIZE];
864 SerializeV1Array(serialized);
865 return {std::begin(serialized), std::end(serialized)};
866 }
867 return std::vector<uint8_t>(m_addr.begin(), m_addr.end());
868}
869
870// private extensions to enum Network, only returned by GetExtNetwork, and only
871// used in GetReachabilityFrom
872static const int NET_UNKNOWN = NET_MAX + 0;
873static const int NET_TEREDO = NET_MAX + 1;
874static int GetExtNetwork(const CNetAddr *addr) {
875 if (addr == nullptr) {
876 return NET_UNKNOWN;
877 }
878 if (addr->IsRFC4380()) {
879 return NET_TEREDO;
880 }
881 return addr->GetNetwork();
882}
883
885int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const {
886 enum Reachability {
887 REACH_UNREACHABLE,
888 REACH_DEFAULT,
889 REACH_TEREDO,
890 REACH_IPV6_WEAK,
891 REACH_IPV4,
892 REACH_IPV6_STRONG,
893 REACH_PRIVATE
894 };
895
896 if (!IsRoutable() || IsInternal()) {
897 return REACH_UNREACHABLE;
898 }
899
900 int ourNet = GetExtNetwork(this);
901 int theirNet = GetExtNetwork(paddrPartner);
902 bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
903
904 switch (theirNet) {
905 case NET_IPV4:
906 switch (ourNet) {
907 default:
908 return REACH_DEFAULT;
909 case NET_IPV4:
910 return REACH_IPV4;
911 }
912 case NET_IPV6:
913 switch (ourNet) {
914 default:
915 return REACH_DEFAULT;
916 case NET_TEREDO:
917 return REACH_TEREDO;
918 case NET_IPV4:
919 return REACH_IPV4;
920 // only prefer giving our IPv6 address if it's not tunnelled
921 case NET_IPV6:
922 return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG;
923 }
924 case NET_ONION:
925 switch (ourNet) {
926 default:
927 return REACH_DEFAULT;
928 // Tor users can connect to IPv4 as well
929 case NET_IPV4:
930 return REACH_IPV4;
931 case NET_ONION:
932 return REACH_PRIVATE;
933 }
934 case NET_I2P:
935 switch (ourNet) {
936 case NET_I2P:
937 return REACH_PRIVATE;
938 default:
939 return REACH_DEFAULT;
940 }
941 case NET_TEREDO:
942 switch (ourNet) {
943 default:
944 return REACH_DEFAULT;
945 case NET_TEREDO:
946 return REACH_TEREDO;
947 case NET_IPV6:
948 return REACH_IPV6_WEAK;
949 case NET_IPV4:
950 return REACH_IPV4;
951 }
952 case NET_UNKNOWN:
953 case NET_UNROUTABLE:
954 default:
955 switch (ourNet) {
956 default:
957 return REACH_DEFAULT;
958 case NET_TEREDO:
959 return REACH_TEREDO;
960 case NET_IPV6:
961 return REACH_IPV6_WEAK;
962 case NET_IPV4:
963 return REACH_IPV4;
964 // either from Tor, or don't care about our address
965 case NET_ONION:
966 return REACH_PRIVATE;
967 }
968 }
969}
970
971CService::CService() : port(0) {}
972
973CService::CService(const CNetAddr &cip, uint16_t portIn)
974 : CNetAddr(cip), port(portIn) {}
975
976CService::CService(const struct in_addr &ipv4Addr, uint16_t portIn)
977 : CNetAddr(ipv4Addr), port(portIn) {}
978
979CService::CService(const struct in6_addr &ipv6Addr, uint16_t portIn)
980 : CNetAddr(ipv6Addr), port(portIn) {}
981
982CService::CService(const struct sockaddr_in &addr)
983 : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port)) {
984 assert(addr.sin_family == AF_INET);
985}
986
987CService::CService(const struct sockaddr_in6 &addr)
988 : CNetAddr(addr.sin6_addr, addr.sin6_scope_id),
989 port(ntohs(addr.sin6_port)) {
990 assert(addr.sin6_family == AF_INET6);
991}
992
993bool CService::SetSockAddr(const struct sockaddr *paddr, socklen_t addrlen) {
994 switch (paddr->sa_family) {
995 case AF_INET:
996 if (addrlen != sizeof(struct sockaddr_in)) {
997 return false;
998 }
999 *this =
1000 CService(*reinterpret_cast<const struct sockaddr_in *>(paddr));
1001 return true;
1002 case AF_INET6:
1003 if (addrlen != sizeof(struct sockaddr_in6)) {
1004 return false;
1005 }
1006 *this =
1007 CService(*reinterpret_cast<const struct sockaddr_in6 *>(paddr));
1008 return true;
1009 default:
1010 return false;
1011 }
1012}
1013
1014sa_family_t CService::GetSAFamily() const {
1015 switch (m_net) {
1016 case NET_IPV4:
1017 return AF_INET;
1018 case NET_IPV6:
1019 case NET_CJDNS:
1020 return AF_INET6;
1021 default:
1022 return AF_UNSPEC;
1023 }
1024}
1025
1026uint16_t CService::GetPort() const {
1027 return port;
1028}
1029
1030bool operator==(const CService &a, const CService &b) {
1031 return static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) &&
1032 a.port == b.port;
1033}
1034
1035bool operator<(const CService &a, const CService &b) {
1036 return static_cast<CNetAddr>(a) < static_cast<CNetAddr>(b) ||
1037 (static_cast<CNetAddr>(a) == static_cast<CNetAddr>(b) &&
1038 a.port < b.port);
1039}
1040
1053bool CService::GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const {
1054 if (IsIPv4()) {
1055 if (*addrlen < (socklen_t)sizeof(struct sockaddr_in)) {
1056 return false;
1057 }
1058 *addrlen = sizeof(struct sockaddr_in);
1059 struct sockaddr_in *paddrin =
1060 reinterpret_cast<struct sockaddr_in *>(paddr);
1061 memset(paddrin, 0, *addrlen);
1062 if (!GetInAddr(&paddrin->sin_addr)) {
1063 return false;
1064 }
1065 paddrin->sin_family = AF_INET;
1066 paddrin->sin_port = htons(port);
1067 return true;
1068 }
1069 if (IsIPv6()) {
1070 if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6)) {
1071 return false;
1072 }
1073 *addrlen = sizeof(struct sockaddr_in6);
1074 struct sockaddr_in6 *paddrin6 =
1075 reinterpret_cast<struct sockaddr_in6 *>(paddr);
1076 memset(paddrin6, 0, *addrlen);
1077 if (!GetIn6Addr(&paddrin6->sin6_addr)) {
1078 return false;
1079 }
1080 paddrin6->sin6_scope_id = m_scope_id;
1081 paddrin6->sin6_family = AF_INET6;
1082 paddrin6->sin6_port = htons(port);
1083 return true;
1084 }
1085 return false;
1086}
1087
1091std::vector<uint8_t> CService::GetKey() const {
1092 auto key = GetAddrBytes();
1093 // most significant byte of our port
1094 key.push_back(port / 0x100);
1095 // least significant byte of our port
1096 key.push_back(port & 0x0FF);
1097 return key;
1098}
1099
1100std::string CService::ToStringAddrPort() const {
1101 const auto port_str = strprintf("%u", port);
1102
1103 if (IsIPv4() || IsTor() || IsI2P() || IsInternal()) {
1104 return ToStringAddr() + ":" + port_str;
1105 } else {
1106 return "[" + ToStringAddr() + "]:" + port_str;
1107 }
1108}
1109
1110CSubNet::CSubNet() : valid(false) {
1111 memset(netmask, 0, sizeof(netmask));
1112}
1113
1114CSubNet::CSubNet(const CNetAddr &addr, uint8_t mask) : CSubNet() {
1115 valid = (addr.IsIPv4() && mask <= ADDR_IPV4_SIZE * 8) ||
1116 (addr.IsIPv6() && mask <= ADDR_IPV6_SIZE * 8);
1117 if (!valid) {
1118 return;
1119 }
1120
1121 assert(mask <= sizeof(netmask) * 8);
1122
1123 network = addr;
1124
1125 uint8_t n = mask;
1126 for (size_t i = 0; i < network.m_addr.size(); ++i) {
1127 const uint8_t bits = n < 8 ? n : 8;
1128 // Set first bits.
1129 netmask[i] = (uint8_t)((uint8_t)0xFF << (8 - bits));
1130 // Normalize network according to netmask.
1131 network.m_addr[i] &= netmask[i];
1132 n -= bits;
1133 }
1134}
1135
1140static inline int NetmaskBits(uint8_t x) {
1141 switch (x) {
1142 case 0x00:
1143 return 0;
1144 case 0x80:
1145 return 1;
1146 case 0xc0:
1147 return 2;
1148 case 0xe0:
1149 return 3;
1150 case 0xf0:
1151 return 4;
1152 case 0xf8:
1153 return 5;
1154 case 0xfc:
1155 return 6;
1156 case 0xfe:
1157 return 7;
1158 case 0xff:
1159 return 8;
1160 default:
1161 return -1;
1162 }
1163}
1164
1165CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask) : CSubNet() {
1166 valid = (addr.IsIPv4() || addr.IsIPv6()) && addr.m_net == mask.m_net;
1167 if (!valid) {
1168 return;
1169 }
1170 // Check if `mask` contains 1-bits after 0-bits (which is an invalid
1171 // netmask).
1172 bool zeros_found = false;
1173 for (auto b : mask.m_addr) {
1174 const int num_bits = NetmaskBits(b);
1175 if (num_bits == -1 || (zeros_found && num_bits != 0)) {
1176 valid = false;
1177 return;
1178 }
1179 if (num_bits < 8) {
1180 zeros_found = true;
1181 }
1182 }
1183
1184 assert(mask.m_addr.size() <= sizeof(netmask));
1185
1186 memcpy(netmask, mask.m_addr.data(), mask.m_addr.size());
1187
1188 network = addr;
1189
1190 // Normalize network according to netmask
1191 for (size_t x = 0; x < network.m_addr.size(); ++x) {
1192 network.m_addr[x] &= netmask[x];
1193 }
1194}
1195
1197 switch (addr.m_net) {
1198 case NET_IPV4:
1199 case NET_IPV6:
1200 valid = true;
1201 assert(addr.m_addr.size() <= sizeof(netmask));
1202 memset(netmask, 0xFF, addr.m_addr.size());
1203 break;
1204 case NET_ONION:
1205 case NET_I2P:
1206 case NET_CJDNS:
1207 valid = true;
1208 break;
1209 case NET_INTERNAL:
1210 case NET_UNROUTABLE:
1211 case NET_MAX:
1212 return;
1213 }
1214
1215 network = addr;
1216}
1217
1222bool CSubNet::Match(const CNetAddr &addr) const {
1223 if (!valid || !addr.IsValid() || network.m_net != addr.m_net) {
1224 return false;
1225 }
1226
1227 switch (network.m_net) {
1228 case NET_IPV4:
1229 case NET_IPV6:
1230 break;
1231 case NET_ONION:
1232 case NET_I2P:
1233 case NET_CJDNS:
1234 case NET_INTERNAL:
1235 return addr == network;
1236 case NET_UNROUTABLE:
1237 case NET_MAX:
1238 return false;
1239 }
1240
1241 assert(network.m_addr.size() == addr.m_addr.size());
1242 for (size_t x = 0; x < addr.m_addr.size(); ++x) {
1243 if ((addr.m_addr[x] & netmask[x]) != network.m_addr[x]) {
1244 return false;
1245 }
1246 }
1247 return true;
1248}
1249
1250std::string CSubNet::ToString() const {
1251 std::string suffix;
1252
1253 switch (network.m_net) {
1254 case NET_IPV4:
1255 case NET_IPV6: {
1256 assert(network.m_addr.size() <= sizeof(netmask));
1257
1258 uint8_t cidr = 0;
1259
1260 for (size_t i = 0; i < network.m_addr.size(); ++i) {
1261 if (netmask[i] == 0x00) {
1262 break;
1263 }
1264 cidr += NetmaskBits(netmask[i]);
1265 }
1266
1267 suffix = strprintf("/%u", cidr);
1268 break;
1269 }
1270 case NET_ONION:
1271 case NET_I2P:
1272 case NET_CJDNS:
1273 case NET_INTERNAL:
1274 case NET_UNROUTABLE:
1275 case NET_MAX:
1276 break;
1277 }
1278
1279 return network.ToStringAddr() + suffix;
1280}
1281
1282bool CSubNet::IsValid() const {
1283 return valid;
1284}
1285
1287 switch (network.m_net) {
1288 case NET_IPV4:
1289 case NET_IPV6:
1290 break;
1291 case NET_ONION:
1292 case NET_I2P:
1293 case NET_CJDNS:
1294 return true;
1295 case NET_INTERNAL:
1296 case NET_UNROUTABLE:
1297 case NET_MAX:
1298 return false;
1299 }
1300
1301 for (size_t x = 0; x < network.m_addr.size(); ++x) {
1302 if (network.m_addr[x] & ~netmask[x]) {
1303 return false;
1304 }
1305 }
1306
1307 return true;
1308}
1309
1310bool operator==(const CSubNet &a, const CSubNet &b) {
1311 return a.valid == b.valid && a.network == b.network &&
1312 !memcmp(a.netmask, b.netmask, 16);
1313}
1314
1315bool operator<(const CSubNet &a, const CSubNet &b) {
1316 return (a.network < b.network ||
1317 (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));
1318}
uint32_t Interpret(const std::vector< bool > &asmap, const std::vector< bool > &ip)
Definition asmap.cpp:93
Network address.
Definition netaddress.h:114
Network GetNetClass() const
void SerializeV1Array(uint8_t(&arr)[V1_SERIALIZATION_SIZE]) const
Serialize in pre-ADDRv2/BIP155 format to an array.
Definition netaddress.h:349
std::string ToStringAddr() const
prevector< ADDR_IPV6_SIZE, uint8_t > m_addr
Raw representation of the network address.
Definition netaddress.h:120
bool IsBindAny() const
bool IsRFC6052() const
void SetIP(const CNetAddr &ip)
bool SetSpecial(const std::string &addr)
Parse a Tor or I2P address and set this object to it.
bool IsRFC7343() const
bool GetIn6Addr(struct in6_addr *pipv6Addr) const
Try to get our IPv6 address.
bool IsCJDNS() const
Check whether this object represents a CJDNS address.
bool IsTor() const
Check whether this object represents a TOR address.
bool IsRoutable() const
bool GetInAddr(struct in_addr *pipv4Addr) const
Try to get our IPv4 address.
bool HasLinkedIPv4() const
Whether this address has a linked IPv4 address (see GetLinkedIPv4()).
bool HasCJDNSPrefix() const
Definition netaddress.h:199
Network m_net
Network to which this address belongs.
Definition netaddress.h:125
bool IsRFC5737() const
void SetLegacyIPv6(Span< const uint8_t > ipv6)
Set from a legacy IPv6 address.
bool SetI2P(const std::string &addr)
Parse an I2P address and set this object to it.
bool IsRFC6598() const
bool IsRFC1918() const
bool IsValid() const
bool IsIPv4() const
BIP155Network GetBIP155Network() const
Get the BIP155 network id of this address.
uint32_t GetLinkedIPv4() const
For IPv4, mapped IPv4, SIIT translated IPv4, Teredo, 6to4 tunneled addresses, return the relevant IPv...
bool SetTor(const std::string &addr)
Parse a Tor address and set this object to it.
uint32_t m_scope_id
Scope id if scoped/link-local IPV6 address.
Definition netaddress.h:131
bool IsRFC3849() const
bool IsHeNet() const
bool IsLocal() const
static constexpr size_t V1_SERIALIZATION_SIZE
Size of CNetAddr when serialized as ADDRv1 (pre-BIP155) (in bytes).
Definition netaddress.h:317
bool IsIPv6() const
bool IsInternal() const
std::vector< uint8_t > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
std::vector< uint8_t > GetAddrBytes() const
bool SetNetFromBIP155Network(uint8_t possible_bip155_net, size_t address_size)
Set m_net from the provided BIP155 network id and size after validation.
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
bool IsRFC4193() const
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
int GetReachabilityFrom(const CNetAddr *paddrPartner=nullptr) const
Calculates a metric for how reachable (*this) is from a given partner.
bool IsRFC2544() const
enum Network GetNetwork() const
bool IsRFC6145() const
CNetAddr()
Construct an unspecified IPv6 network address (::/128).
bool IsRFC3964() const
bool IsRFC4380() const
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
BIP155Network
BIP155 network ids recognized by this software.
Definition netaddress.h:305
bool IsRFC3927() const
bool IsRFC4862() const
bool IsRFC4843() const
bool IsI2P() const
Check whether this object represents an I2P address.
A hasher class for SHA-256.
Definition sha256.h:13
CSHA256 & Write(const uint8_t *data, size_t len)
Definition sha256.cpp:819
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition sha256.cpp:844
A combination of a network address (CNetAddr) and a (TCP) port.
Definition netaddress.h:573
std::vector< uint8_t > GetKey() const
bool SetSockAddr(const struct sockaddr *paddr, socklen_t addrlen)
Set CService from a network sockaddr.
uint16_t GetPort() const
sa_family_t GetSAFamily() const
Get the address family.
uint16_t port
Definition netaddress.h:576
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
std::string ToStringAddrPort() const
bool valid
Is this value valid? (only used to signal parse errors)
Definition netaddress.h:506
CNetAddr network
Network (base) address.
Definition netaddress.h:502
bool SanityCheck() const
uint8_t netmask[16]
Netmask, in network byte order.
Definition netaddress.h:504
std::string ToString() const
bool IsValid() const
CSubNet()
Construct an invalid subnet (empty, Match() always returns false).
bool Match(const CNetAddr &addr) const
SHA3_256 & Finalize(Span< uint8_t > output)
Definition sha3.cpp:232
SHA3_256 & Write(Span< const uint8_t > data)
Definition sha3.cpp:202
static constexpr size_t OUTPUT_SIZE
Definition sha3.h:33
A Span is an object that can refer to a contiguous sequence of objects.
Definition span.h:94
constexpr std::size_t size() const noexcept
Definition span.h:210
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition span.h:228
constexpr C * data() const noexcept
Definition span.h:199
constexpr C * begin() const noexcept
Definition span.h:200
constexpr C * end() const noexcept
Definition span.h:201
Implements a drop-in replacement for std::vector<T> which stores up to N elements directly (without h...
Definition prevector.h:38
size_type size() const
Definition prevector.h:398
value_type * data()
Definition prevector.h:611
iterator begin()
Definition prevector.h:402
iterator end()
Definition prevector.h:404
void assign(size_type n, const T &val)
Definition prevector.h:330
static uint16_t ReadBE16(const uint8_t *ptr)
Definition common.h:46
static uint32_t ReadBE32(const uint8_t *ptr)
Definition common.h:52
static const uint8_t VERSION[]
static constexpr size_t CHECKSUM_LEN
static void Checksum(Span< const uint8_t > addr_pubkey, uint8_t(&checksum)[CHECKSUM_LEN])
static constexpr size_t TOTAL_LEN
bool HasPrefix(const T1 &obj, const std::array< uint8_t, PREFIX_LEN > &prefix)
Check whether a container begins with the given prefix.
Definition string.h:168
bool ContainsNoNUL(std::string_view str) noexcept
Check if a string does not contain any embedded NUL (\0) characters.
Definition string.h:144
static const int NET_UNKNOWN
static int GetExtNetwork(const CNetAddr *addr)
static const int NET_TEREDO
static int NetmaskBits(uint8_t x)
bool operator==(const CNetAddr &a, const CNetAddr &b)
static std::string IPv6ToString(Span< const uint8_t > a, uint32_t scope_id)
Return an IPv6 address text representation with zero compression as described in RFC 5952 ("A Recomme...
static std::string IPv4ToString(Span< const uint8_t > a)
bool operator<(const CNetAddr &a, const CNetAddr &b)
static constexpr size_t ADDR_CJDNS_SIZE
Size of CJDNS address (in bytes).
Definition netaddress.h:103
static constexpr size_t ADDR_TORV3_SIZE
Size of TORv3 address (in bytes).
Definition netaddress.h:97
static constexpr size_t ADDR_I2P_SIZE
Size of I2P address (in bytes).
Definition netaddress.h:100
static constexpr size_t ADDR_INTERNAL_SIZE
Size of "internal" (NET_INTERNAL) address (in bytes).
Definition netaddress.h:106
static constexpr size_t ADDR_TORV2_SIZE
Size of TORv2 address (in bytes).
Definition netaddress.h:93
static const std::array< uint8_t, 6 > INTERNAL_IN_IPV6_PREFIX
Prefix of an IPv6 address when it contains an embedded "internal" address.
Definition netaddress.h:82
static constexpr size_t ADDR_IPV4_SIZE
Size of IPv4 address (in bytes).
Definition netaddress.h:87
static const std::array< uint8_t, 6 > TORV2_IN_IPV6_PREFIX
Prefix of an IPv6 address when it contains an embedded TORv2 address.
Definition netaddress.h:74
Network
A network type.
Definition netaddress.h:37
@ NET_I2P
I2P.
Definition netaddress.h:52
@ NET_CJDNS
CJDNS.
Definition netaddress.h:55
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition netaddress.h:62
@ NET_ONION
TOR (v2 or v3)
Definition netaddress.h:49
@ NET_IPV6
IPv6.
Definition netaddress.h:46
@ NET_IPV4
IPv4.
Definition netaddress.h:43
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition netaddress.h:40
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition netaddress.h:59
static const std::array< uint8_t, 12 > IPV4_IN_IPV6_PREFIX
Prefix of an IPv6 address when it contains an embedded IPv4 address.
Definition netaddress.h:67
static constexpr size_t ADDR_IPV6_SIZE
Size of IPv6 address (in bytes).
Definition netaddress.h:90
const char * prefix
Definition rest.cpp:1078
const char * name
Definition rest.cpp:46
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
std::string EncodeBase32(Span< const uint8_t > input, bool pad)
Base32 encode.
std::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.
std::optional< std::vector< uint8_t > > DecodeBase32(std::string_view str)
assert(!tx.IsCoinBase())