Remove unreachable or otherwise redundant code
[bitcoinplatinum.git] / src / netaddress.cpp
blob34a7029862e4d16517bc07a9ff62d29e865887ac
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.
6 #ifdef HAVE_CONFIG_H
7 #include "config/bitcoin-config.h"
8 #endif
10 #include "netaddress.h"
11 #include "hash.h"
12 #include "utilstrencodings.h"
13 #include "tinyformat.h"
15 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
16 static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
18 void CNetAddr::Init()
20 memset(ip, 0, sizeof(ip));
21 scopeId = 0;
24 void CNetAddr::SetIP(const CNetAddr& ipIn)
26 memcpy(ip, ipIn.ip, sizeof(ip));
29 void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
31 switch(network)
33 case NET_IPV4:
34 memcpy(ip, pchIPv4, 12);
35 memcpy(ip+12, ip_in, 4);
36 break;
37 case NET_IPV6:
38 memcpy(ip, ip_in, 16);
39 break;
40 default:
41 assert(!"invalid network");
45 bool CNetAddr::SetSpecial(const std::string &strName)
47 if (strName.size()>6 && strName.substr(strName.size() - 6, 6) == ".onion") {
48 std::vector<unsigned char> vchAddr = DecodeBase32(strName.substr(0, strName.size() - 6).c_str());
49 if (vchAddr.size() != 16-sizeof(pchOnionCat))
50 return false;
51 memcpy(ip, pchOnionCat, sizeof(pchOnionCat));
52 for (unsigned int i=0; i<16-sizeof(pchOnionCat); i++)
53 ip[i + sizeof(pchOnionCat)] = vchAddr[i];
54 return true;
56 return false;
59 CNetAddr::CNetAddr()
61 Init();
64 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
66 SetRaw(NET_IPV4, (const uint8_t*)&ipv4Addr);
69 CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr, const uint32_t scope)
71 SetRaw(NET_IPV6, (const uint8_t*)&ipv6Addr);
72 scopeId = scope;
75 unsigned int CNetAddr::GetByte(int n) const
77 return ip[15-n];
80 bool CNetAddr::IsIPv4() const
82 return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
85 bool CNetAddr::IsIPv6() const
87 return (!IsIPv4() && !IsTor());
90 bool CNetAddr::IsRFC1918() const
92 return IsIPv4() && (
93 GetByte(3) == 10 ||
94 (GetByte(3) == 192 && GetByte(2) == 168) ||
95 (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
98 bool CNetAddr::IsRFC2544() const
100 return IsIPv4() && GetByte(3) == 198 && (GetByte(2) == 18 || GetByte(2) == 19);
103 bool CNetAddr::IsRFC3927() const
105 return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
108 bool CNetAddr::IsRFC6598() const
110 return IsIPv4() && GetByte(3) == 100 && GetByte(2) >= 64 && GetByte(2) <= 127;
113 bool CNetAddr::IsRFC5737() const
115 return IsIPv4() && ((GetByte(3) == 192 && GetByte(2) == 0 && GetByte(1) == 2) ||
116 (GetByte(3) == 198 && GetByte(2) == 51 && GetByte(1) == 100) ||
117 (GetByte(3) == 203 && GetByte(2) == 0 && GetByte(1) == 113));
120 bool CNetAddr::IsRFC3849() const
122 return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8;
125 bool CNetAddr::IsRFC3964() const
127 return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
130 bool CNetAddr::IsRFC6052() const
132 static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0};
133 return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
136 bool CNetAddr::IsRFC4380() const
138 return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0);
141 bool CNetAddr::IsRFC4862() const
143 static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0};
144 return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
147 bool CNetAddr::IsRFC4193() const
149 return ((GetByte(15) & 0xFE) == 0xFC);
152 bool CNetAddr::IsRFC6145() const
154 static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0};
155 return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
158 bool CNetAddr::IsRFC4843() const
160 return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
163 bool CNetAddr::IsTor() const
165 return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
168 bool CNetAddr::IsLocal() const
170 // IPv4 loopback
171 if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0))
172 return true;
174 // IPv6 loopback (::1/128)
175 static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
176 if (memcmp(ip, pchLocal, 16) == 0)
177 return true;
179 return false;
182 bool CNetAddr::IsValid() const
184 // Cleanup 3-byte shifted addresses caused by garbage in size field
185 // of addr messages from versions before 0.2.9 checksum.
186 // Two consecutive addr messages look like this:
187 // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
188 // so if the first length field is garbled, it reads the second batch
189 // of addr misaligned by 3 bytes.
190 if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
191 return false;
193 // unspecified IPv6 address (::/128)
194 unsigned char ipNone6[16] = {};
195 if (memcmp(ip, ipNone6, 16) == 0)
196 return false;
198 // documentation IPv6 address
199 if (IsRFC3849())
200 return false;
202 if (IsIPv4())
204 // INADDR_NONE
205 uint32_t ipNone = INADDR_NONE;
206 if (memcmp(ip+12, &ipNone, 4) == 0)
207 return false;
209 // 0
210 ipNone = 0;
211 if (memcmp(ip+12, &ipNone, 4) == 0)
212 return false;
215 return true;
218 bool CNetAddr::IsRoutable() const
220 return IsValid() && !(IsRFC1918() || IsRFC2544() || IsRFC3927() || IsRFC4862() || IsRFC6598() || IsRFC5737() || (IsRFC4193() && !IsTor()) || IsRFC4843() || IsLocal());
223 enum Network CNetAddr::GetNetwork() const
225 if (!IsRoutable())
226 return NET_UNROUTABLE;
228 if (IsIPv4())
229 return NET_IPV4;
231 if (IsTor())
232 return NET_TOR;
234 return NET_IPV6;
237 std::string CNetAddr::ToStringIP() const
239 if (IsTor())
240 return EncodeBase32(&ip[6], 10) + ".onion";
241 CService serv(*this, 0);
242 struct sockaddr_storage sockaddr;
243 socklen_t socklen = sizeof(sockaddr);
244 if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
245 char name[1025] = "";
246 if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST))
247 return std::string(name);
249 if (IsIPv4())
250 return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
251 else
252 return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
253 GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12),
254 GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8),
255 GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4),
256 GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0));
259 std::string CNetAddr::ToString() const
261 return ToStringIP();
264 bool operator==(const CNetAddr& a, const CNetAddr& b)
266 return (memcmp(a.ip, b.ip, 16) == 0);
269 bool operator!=(const CNetAddr& a, const CNetAddr& b)
271 return (memcmp(a.ip, b.ip, 16) != 0);
274 bool operator<(const CNetAddr& a, const CNetAddr& b)
276 return (memcmp(a.ip, b.ip, 16) < 0);
279 bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
281 if (!IsIPv4())
282 return false;
283 memcpy(pipv4Addr, ip+12, 4);
284 return true;
287 bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
289 memcpy(pipv6Addr, ip, 16);
290 return true;
293 // get canonical identifier of an address' group
294 // no two connections will be attempted to addresses with the same group
295 std::vector<unsigned char> CNetAddr::GetGroup() const
297 std::vector<unsigned char> vchRet;
298 int nClass = NET_IPV6;
299 int nStartByte = 0;
300 int nBits = 16;
302 // all local addresses belong to the same group
303 if (IsLocal())
305 nClass = 255;
306 nBits = 0;
309 // all unroutable addresses belong to the same group
310 if (!IsRoutable())
312 nClass = NET_UNROUTABLE;
313 nBits = 0;
315 // for IPv4 addresses, '1' + the 16 higher-order bits of the IP
316 // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
317 else if (IsIPv4() || IsRFC6145() || IsRFC6052())
319 nClass = NET_IPV4;
320 nStartByte = 12;
322 // for 6to4 tunnelled addresses, use the encapsulated IPv4 address
323 else if (IsRFC3964())
325 nClass = NET_IPV4;
326 nStartByte = 2;
328 // for Teredo-tunnelled IPv6 addresses, use the encapsulated IPv4 address
329 else if (IsRFC4380())
331 vchRet.push_back(NET_IPV4);
332 vchRet.push_back(GetByte(3) ^ 0xFF);
333 vchRet.push_back(GetByte(2) ^ 0xFF);
334 return vchRet;
336 else if (IsTor())
338 nClass = NET_TOR;
339 nStartByte = 6;
340 nBits = 4;
342 // for he.net, use /36 groups
343 else if (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
344 nBits = 36;
345 // for the rest of the IPv6 network, use /32 groups
346 else
347 nBits = 32;
349 vchRet.push_back(nClass);
350 while (nBits >= 8)
352 vchRet.push_back(GetByte(15 - nStartByte));
353 nStartByte++;
354 nBits -= 8;
356 if (nBits > 0)
357 vchRet.push_back(GetByte(15 - nStartByte) | ((1 << (8 - nBits)) - 1));
359 return vchRet;
362 uint64_t CNetAddr::GetHash() const
364 uint256 hash = Hash(&ip[0], &ip[16]);
365 uint64_t nRet;
366 memcpy(&nRet, &hash, sizeof(nRet));
367 return nRet;
370 // private extensions to enum Network, only returned by GetExtNetwork,
371 // and only used in GetReachabilityFrom
372 static const int NET_UNKNOWN = NET_MAX + 0;
373 static const int NET_TEREDO = NET_MAX + 1;
374 int static GetExtNetwork(const CNetAddr *addr)
376 if (addr == NULL)
377 return NET_UNKNOWN;
378 if (addr->IsRFC4380())
379 return NET_TEREDO;
380 return addr->GetNetwork();
383 /** Calculates a metric for how reachable (*this) is from a given partner */
384 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
386 enum Reachability {
387 REACH_UNREACHABLE,
388 REACH_DEFAULT,
389 REACH_TEREDO,
390 REACH_IPV6_WEAK,
391 REACH_IPV4,
392 REACH_IPV6_STRONG,
393 REACH_PRIVATE
396 if (!IsRoutable())
397 return REACH_UNREACHABLE;
399 int ourNet = GetExtNetwork(this);
400 int theirNet = GetExtNetwork(paddrPartner);
401 bool fTunnel = IsRFC3964() || IsRFC6052() || IsRFC6145();
403 switch(theirNet) {
404 case NET_IPV4:
405 switch(ourNet) {
406 default: return REACH_DEFAULT;
407 case NET_IPV4: return REACH_IPV4;
409 case NET_IPV6:
410 switch(ourNet) {
411 default: return REACH_DEFAULT;
412 case NET_TEREDO: return REACH_TEREDO;
413 case NET_IPV4: return REACH_IPV4;
414 case NET_IPV6: return fTunnel ? REACH_IPV6_WEAK : REACH_IPV6_STRONG; // only prefer giving our IPv6 address if it's not tunnelled
416 case NET_TOR:
417 switch(ourNet) {
418 default: return REACH_DEFAULT;
419 case NET_IPV4: return REACH_IPV4; // Tor users can connect to IPv4 as well
420 case NET_TOR: return REACH_PRIVATE;
422 case NET_TEREDO:
423 switch(ourNet) {
424 default: return REACH_DEFAULT;
425 case NET_TEREDO: return REACH_TEREDO;
426 case NET_IPV6: return REACH_IPV6_WEAK;
427 case NET_IPV4: return REACH_IPV4;
429 case NET_UNKNOWN:
430 case NET_UNROUTABLE:
431 default:
432 switch(ourNet) {
433 default: return REACH_DEFAULT;
434 case NET_TEREDO: return REACH_TEREDO;
435 case NET_IPV6: return REACH_IPV6_WEAK;
436 case NET_IPV4: return REACH_IPV4;
437 case NET_TOR: return REACH_PRIVATE; // either from Tor, or don't care about our address
442 void CService::Init()
444 port = 0;
447 CService::CService()
449 Init();
452 CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
456 CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn)
460 CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
464 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
466 assert(addr.sin_family == AF_INET);
469 CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr, addr.sin6_scope_id), port(ntohs(addr.sin6_port))
471 assert(addr.sin6_family == AF_INET6);
474 bool CService::SetSockAddr(const struct sockaddr *paddr)
476 switch (paddr->sa_family) {
477 case AF_INET:
478 *this = CService(*(const struct sockaddr_in*)paddr);
479 return true;
480 case AF_INET6:
481 *this = CService(*(const struct sockaddr_in6*)paddr);
482 return true;
483 default:
484 return false;
488 unsigned short CService::GetPort() const
490 return port;
493 bool operator==(const CService& a, const CService& b)
495 return (CNetAddr)a == (CNetAddr)b && a.port == b.port;
498 bool operator!=(const CService& a, const CService& b)
500 return (CNetAddr)a != (CNetAddr)b || a.port != b.port;
503 bool operator<(const CService& a, const CService& b)
505 return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
508 bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
510 if (IsIPv4()) {
511 if (*addrlen < (socklen_t)sizeof(struct sockaddr_in))
512 return false;
513 *addrlen = sizeof(struct sockaddr_in);
514 struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
515 memset(paddrin, 0, *addrlen);
516 if (!GetInAddr(&paddrin->sin_addr))
517 return false;
518 paddrin->sin_family = AF_INET;
519 paddrin->sin_port = htons(port);
520 return true;
522 if (IsIPv6()) {
523 if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
524 return false;
525 *addrlen = sizeof(struct sockaddr_in6);
526 struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
527 memset(paddrin6, 0, *addrlen);
528 if (!GetIn6Addr(&paddrin6->sin6_addr))
529 return false;
530 paddrin6->sin6_scope_id = scopeId;
531 paddrin6->sin6_family = AF_INET6;
532 paddrin6->sin6_port = htons(port);
533 return true;
535 return false;
538 std::vector<unsigned char> CService::GetKey() const
540 std::vector<unsigned char> vKey;
541 vKey.resize(18);
542 memcpy(&vKey[0], ip, 16);
543 vKey[16] = port / 0x100;
544 vKey[17] = port & 0x0FF;
545 return vKey;
548 std::string CService::ToStringPort() const
550 return strprintf("%u", port);
553 std::string CService::ToStringIPPort() const
555 if (IsIPv4() || IsTor()) {
556 return ToStringIP() + ":" + ToStringPort();
557 } else {
558 return "[" + ToStringIP() + "]:" + ToStringPort();
562 std::string CService::ToString() const
564 return ToStringIPPort();
567 void CService::SetPort(unsigned short portIn)
569 port = portIn;
572 CSubNet::CSubNet():
573 valid(false)
575 memset(netmask, 0, sizeof(netmask));
578 CSubNet::CSubNet(const CNetAddr &addr, int32_t mask)
580 valid = true;
581 network = addr;
582 // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
583 memset(netmask, 255, sizeof(netmask));
585 // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
586 const int astartofs = network.IsIPv4() ? 12 : 0;
588 int32_t n = mask;
589 if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
591 n += astartofs*8;
592 // Clear bits [n..127]
593 for (; n < 128; ++n)
594 netmask[n>>3] &= ~(1<<(7-(n&7)));
595 } else
596 valid = false;
598 // Normalize network according to netmask
599 for(int x=0; x<16; ++x)
600 network.ip[x] &= netmask[x];
603 CSubNet::CSubNet(const CNetAddr &addr, const CNetAddr &mask)
605 valid = true;
606 network = addr;
607 // Default to /32 (IPv4) or /128 (IPv6), i.e. match single address
608 memset(netmask, 255, sizeof(netmask));
610 // IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
611 const int astartofs = network.IsIPv4() ? 12 : 0;
613 for(int x=astartofs; x<16; ++x)
614 netmask[x] = mask.ip[x];
616 // Normalize network according to netmask
617 for(int x=0; x<16; ++x)
618 network.ip[x] &= netmask[x];
621 CSubNet::CSubNet(const CNetAddr &addr):
622 valid(addr.IsValid())
624 memset(netmask, 255, sizeof(netmask));
625 network = addr;
628 bool CSubNet::Match(const CNetAddr &addr) const
630 if (!valid || !addr.IsValid())
631 return false;
632 for(int x=0; x<16; ++x)
633 if ((addr.ip[x] & netmask[x]) != network.ip[x])
634 return false;
635 return true;
638 static inline int NetmaskBits(uint8_t x)
640 switch(x) {
641 case 0x00: return 0; break;
642 case 0x80: return 1; break;
643 case 0xc0: return 2; break;
644 case 0xe0: return 3; break;
645 case 0xf0: return 4; break;
646 case 0xf8: return 5; break;
647 case 0xfc: return 6; break;
648 case 0xfe: return 7; break;
649 case 0xff: return 8; break;
650 default: return -1; break;
654 std::string CSubNet::ToString() const
656 /* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
657 int cidr = 0;
658 bool valid_cidr = true;
659 int n = network.IsIPv4() ? 12 : 0;
660 for (; n < 16 && netmask[n] == 0xff; ++n)
661 cidr += 8;
662 if (n < 16) {
663 int bits = NetmaskBits(netmask[n]);
664 if (bits < 0)
665 valid_cidr = false;
666 else
667 cidr += bits;
668 ++n;
670 for (; n < 16 && valid_cidr; ++n)
671 if (netmask[n] != 0x00)
672 valid_cidr = false;
674 /* Format output */
675 std::string strNetmask;
676 if (valid_cidr) {
677 strNetmask = strprintf("%u", cidr);
678 } else {
679 if (network.IsIPv4())
680 strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
681 else
682 strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
683 netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
684 netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
685 netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
686 netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
689 return network.ToString() + "/" + strNetmask;
692 bool CSubNet::IsValid() const
694 return valid;
697 bool operator==(const CSubNet& a, const CSubNet& b)
699 return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16);
702 bool operator!=(const CSubNet& a, const CSubNet& b)
704 return !(a==b);
707 bool operator<(const CSubNet& a, const CSubNet& b)
709 return (a.network < b.network || (a.network == b.network && memcmp(a.netmask, b.netmask, 16) < 0));