]> Git Repo - VerusCoin.git/blob - src/netbase.cpp
Merge branch 'master' into async-ipv6-rpc
[VerusCoin.git] / src / netbase.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "netbase.h"
7 #include "util.h"
8
9 #ifndef WIN32
10 #include <sys/fcntl.h>
11 #endif
12
13 #include "strlcpy.h"
14 #include <boost/algorithm/string/case_conv.hpp> // for to_lower()
15
16 using namespace std;
17
18 // Settings
19 typedef std::pair<CService, int> proxyType;
20 static proxyType proxyInfo[NET_MAX];
21 static proxyType nameproxyInfo;
22 int nConnectTimeout = 5000;
23 bool fNameLookup = false;
24
25 static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
26
27 enum Network ParseNetwork(std::string net) {
28     boost::to_lower(net);
29     if (net == "ipv4") return NET_IPV4;
30     if (net == "ipv6") return NET_IPV6;
31     if (net == "tor")  return NET_TOR;
32     if (net == "i2p")  return NET_I2P;
33     return NET_UNROUTABLE;
34 }
35
36 bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
37 {
38     vIP.clear();
39     struct addrinfo aiHint;
40     memset(&aiHint, 0, sizeof(struct addrinfo));
41
42     aiHint.ai_socktype = SOCK_STREAM;
43     aiHint.ai_protocol = IPPROTO_TCP;
44 #ifdef WIN32
45 #  ifdef USE_IPV6
46     aiHint.ai_family = AF_UNSPEC;
47     aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
48 #  else
49     aiHint.ai_family = AF_INET;
50     aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
51 #  endif
52 #else
53 #  ifdef USE_IPV6
54     aiHint.ai_family = AF_UNSPEC;
55     aiHint.ai_flags = AI_ADDRCONFIG | (fAllowLookup ? 0 : AI_NUMERICHOST);
56 #  else
57     aiHint.ai_family = AF_INET;
58     aiHint.ai_flags = AI_ADDRCONFIG | (fAllowLookup ? 0 : AI_NUMERICHOST);
59 #  endif
60 #endif
61     struct addrinfo *aiRes = NULL;
62     int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes);
63     if (nErr)
64         return false;
65
66     struct addrinfo *aiTrav = aiRes;
67     while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions))
68     {
69         if (aiTrav->ai_family == AF_INET)
70         {
71             assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in));
72             vIP.push_back(CNetAddr(((struct sockaddr_in*)(aiTrav->ai_addr))->sin_addr));
73         }
74
75 #ifdef USE_IPV6
76         if (aiTrav->ai_family == AF_INET6)
77         {
78             assert(aiTrav->ai_addrlen >= sizeof(sockaddr_in6));
79             vIP.push_back(CNetAddr(((struct sockaddr_in6*)(aiTrav->ai_addr))->sin6_addr));
80         }
81 #endif
82
83         aiTrav = aiTrav->ai_next;
84     }
85
86     freeaddrinfo(aiRes);
87
88     return (vIP.size() > 0);
89 }
90
91 bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
92 {
93     if (pszName[0] == 0)
94         return false;
95     char psz[256];
96     char *pszHost = psz;
97     strlcpy(psz, pszName, sizeof(psz));
98     if (psz[0] == '[' && psz[strlen(psz)-1] == ']')
99     {
100         pszHost = psz+1;
101         psz[strlen(psz)-1] = 0;
102     }
103
104     return LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
105 }
106
107 bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions)
108 {
109     return LookupHost(pszName, vIP, nMaxSolutions, false);
110 }
111
112 bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
113 {
114     if (pszName[0] == 0)
115         return false;
116     int port = portDefault;
117     char psz[256];
118     char *pszHost = psz;
119     strlcpy(psz, pszName, sizeof(psz));
120     char* pszColon = strrchr(psz+1,':');
121     char *pszPortEnd = NULL;
122     int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
123     if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
124     {
125         if (psz[0] == '[' && pszColon[-1] == ']')
126         {
127             pszHost = psz+1;
128             pszColon[-1] = 0;
129         }
130         else
131             pszColon[0] = 0;
132         if (port >= 0 && port <= USHRT_MAX)
133             port = portParsed;
134     }
135     else
136     {
137         if (psz[0] == '[' && psz[strlen(psz)-1] == ']')
138         {
139             pszHost = psz+1;
140             psz[strlen(psz)-1] = 0;
141         }
142
143     }
144
145     std::vector<CNetAddr> vIP;
146     bool fRet = LookupIntern(pszHost, vIP, nMaxSolutions, fAllowLookup);
147     if (!fRet)
148         return false;
149     vAddr.resize(vIP.size());
150     for (unsigned int i = 0; i < vIP.size(); i++)
151         vAddr[i] = CService(vIP[i], port);
152     return true;
153 }
154
155 bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup)
156 {
157     std::vector<CService> vService;
158     bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1);
159     if (!fRet)
160         return false;
161     addr = vService[0];
162     return true;
163 }
164
165 bool LookupNumeric(const char *pszName, CService& addr, int portDefault)
166 {
167     return Lookup(pszName, addr, portDefault, false);
168 }
169
170 bool static Socks4(const CService &addrDest, SOCKET& hSocket)
171 {
172     printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str());
173     if (!addrDest.IsIPv4())
174     {
175         closesocket(hSocket);
176         return error("Proxy destination is not IPv4");
177     }
178     char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
179     struct sockaddr_in addr;
180     socklen_t len = sizeof(addr);
181     if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET)
182     {
183         closesocket(hSocket);
184         return error("Cannot get proxy destination address");
185     }
186     memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
187     memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
188     char* pszSocks4 = pszSocks4IP;
189     int nSize = sizeof(pszSocks4IP);
190
191     int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
192     if (ret != nSize)
193     {
194         closesocket(hSocket);
195         return error("Error sending to proxy");
196     }
197     char pchRet[8];
198     if (recv(hSocket, pchRet, 8, 0) != 8)
199     {
200         closesocket(hSocket);
201         return error("Error reading proxy response");
202     }
203     if (pchRet[1] != 0x5a)
204     {
205         closesocket(hSocket);
206         if (pchRet[1] != 0x5b)
207             printf("ERROR: Proxy returned error %d\n", pchRet[1]);
208         return false;
209     }
210     printf("SOCKS4 connected %s\n", addrDest.ToString().c_str());
211     return true;
212 }
213
214 bool static Socks5(string strDest, int port, SOCKET& hSocket)
215 {
216     printf("SOCKS5 connecting %s\n", strDest.c_str());
217     if (strDest.size() > 255)
218     {
219         closesocket(hSocket);
220         return error("Hostname too long");
221     }
222     char pszSocks5Init[] = "\5\1\0";
223     char *pszSocks5 = pszSocks5Init;
224     ssize_t nSize = sizeof(pszSocks5Init);
225
226     ssize_t ret = send(hSocket, pszSocks5, nSize, MSG_NOSIGNAL);
227     if (ret != nSize)
228     {
229         closesocket(hSocket);
230         return error("Error sending to proxy");
231     }
232     char pchRet1[2];
233     if (recv(hSocket, pchRet1, 2, 0) != 2)
234     {
235         closesocket(hSocket);
236         return error("Error reading proxy response");
237     }
238     if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00)
239     {
240         closesocket(hSocket);
241         return error("Proxy failed to initialize");
242     }
243     string strSocks5("\5\1");
244     strSocks5 += '\000'; strSocks5 += '\003';
245     strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255));
246     strSocks5 += strDest; 
247     strSocks5 += static_cast<char>((port >> 8) & 0xFF);
248     strSocks5 += static_cast<char>((port >> 0) & 0xFF);
249     ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL);
250     if (ret != (ssize_t)strSocks5.size())
251     {
252         closesocket(hSocket);
253         return error("Error sending to proxy");
254     }
255     char pchRet2[4];
256     if (recv(hSocket, pchRet2, 4, 0) != 4)
257     {
258         closesocket(hSocket);
259         return error("Error reading proxy response");
260     }
261     if (pchRet2[0] != 0x05)
262     {
263         closesocket(hSocket);
264         return error("Proxy failed to accept request");
265     }
266     if (pchRet2[1] != 0x00)
267     {
268         closesocket(hSocket);
269         switch (pchRet2[1])
270         {
271             case 0x01: return error("Proxy error: general failure");
272             case 0x02: return error("Proxy error: connection not allowed");
273             case 0x03: return error("Proxy error: network unreachable");
274             case 0x04: return error("Proxy error: host unreachable");
275             case 0x05: return error("Proxy error: connection refused");
276             case 0x06: return error("Proxy error: TTL expired");
277             case 0x07: return error("Proxy error: protocol error");
278             case 0x08: return error("Proxy error: address type not supported");
279             default:   return error("Proxy error: unknown");
280         }
281     }
282     if (pchRet2[2] != 0x00)
283     {
284         closesocket(hSocket);
285         return error("Error: malformed proxy response");
286     }
287     char pchRet3[256];
288     switch (pchRet2[3])
289     {
290         case 0x01: ret = recv(hSocket, pchRet3, 4, 0) != 4; break;
291         case 0x04: ret = recv(hSocket, pchRet3, 16, 0) != 16; break;
292         case 0x03:
293         {
294             ret = recv(hSocket, pchRet3, 1, 0) != 1;
295             if (ret)
296                 return error("Error reading from proxy");
297             int nRecv = pchRet3[0];
298             ret = recv(hSocket, pchRet3, nRecv, 0) != nRecv;
299             break;
300         }
301         default: closesocket(hSocket); return error("Error: malformed proxy response");
302     }
303     if (ret)
304     {
305         closesocket(hSocket);
306         return error("Error reading from proxy");
307     }
308     if (recv(hSocket, pchRet3, 2, 0) != 2)
309     {
310         closesocket(hSocket);
311         return error("Error reading from proxy");
312     }
313     printf("SOCKS5 connected %s\n", strDest.c_str());
314     return true;
315 }
316
317 bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
318 {
319     hSocketRet = INVALID_SOCKET;
320
321 #ifdef USE_IPV6
322     struct sockaddr_storage sockaddr;
323 #else
324     struct sockaddr sockaddr;
325 #endif
326     socklen_t len = sizeof(sockaddr);
327     if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
328         printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
329         return false;
330     }
331
332     SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
333     if (hSocket == INVALID_SOCKET)
334         return false;
335 #ifdef SO_NOSIGPIPE
336     int set = 1;
337     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
338 #endif
339
340 #ifdef WIN32
341     u_long fNonblock = 1;
342     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
343 #else
344     int fFlags = fcntl(hSocket, F_GETFL, 0);
345     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
346 #endif
347     {
348         closesocket(hSocket);
349         return false;
350     }
351
352     if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
353     {
354         // WSAEINVAL is here because some legacy version of winsock uses it
355         if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
356         {
357             struct timeval timeout;
358             timeout.tv_sec  = nTimeout / 1000;
359             timeout.tv_usec = (nTimeout % 1000) * 1000;
360
361             fd_set fdset;
362             FD_ZERO(&fdset);
363             FD_SET(hSocket, &fdset);
364             int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
365             if (nRet == 0)
366             {
367                 printf("connection timeout\n");
368                 closesocket(hSocket);
369                 return false;
370             }
371             if (nRet == SOCKET_ERROR)
372             {
373                 printf("select() for connection failed: %i\n",WSAGetLastError());
374                 closesocket(hSocket);
375                 return false;
376             }
377             socklen_t nRetSize = sizeof(nRet);
378 #ifdef WIN32
379             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
380 #else
381             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
382 #endif
383             {
384                 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
385                 closesocket(hSocket);
386                 return false;
387             }
388             if (nRet != 0)
389             {
390                 printf("connect() failed after select(): %s\n",strerror(nRet));
391                 closesocket(hSocket);
392                 return false;
393             }
394         }
395 #ifdef WIN32
396         else if (WSAGetLastError() != WSAEISCONN)
397 #else
398         else
399 #endif
400         {
401             printf("connect() failed: %i\n",WSAGetLastError());
402             closesocket(hSocket);
403             return false;
404         }
405     }
406
407     // this isn't even strictly necessary
408     // CNode::ConnectNode immediately turns the socket back to non-blocking
409     // but we'll turn it back to blocking just in case
410 #ifdef WIN32
411     fNonblock = 0;
412     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
413 #else
414     fFlags = fcntl(hSocket, F_GETFL, 0);
415     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
416 #endif
417     {
418         closesocket(hSocket);
419         return false;
420     }
421
422     hSocketRet = hSocket;
423     return true;
424 }
425
426 bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
427     assert(net >= 0 && net < NET_MAX);
428     if (nSocksVersion != 0 && nSocksVersion != 4 && nSocksVersion != 5)
429         return false;
430     if (nSocksVersion != 0 && !addrProxy.IsValid())
431         return false;
432     proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
433     return true;
434 }
435
436 bool GetProxy(enum Network net, CService &addrProxy) {
437     assert(net >= 0 && net < NET_MAX);
438     if (!proxyInfo[net].second)
439         return false;
440     addrProxy = proxyInfo[net].first;
441     return true;
442 }
443
444 bool SetNameProxy(CService addrProxy, int nSocksVersion) {
445     if (nSocksVersion != 0 && nSocksVersion != 5)
446         return false;
447     if (nSocksVersion != 0 && !addrProxy.IsValid())
448         return false;
449     nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
450     return true;
451 }
452
453 bool GetNameProxy() {
454     return nameproxyInfo.second != 0;
455 }
456
457 bool IsProxy(const CNetAddr &addr) {
458     for (int i=0; i<NET_MAX; i++) {
459         if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first))
460             return true;
461     }
462     return false;
463 }
464
465 bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
466 {
467     const proxyType &proxy = proxyInfo[addrDest.GetNetwork()];
468
469     // no proxy needed
470     if (!proxy.second)
471         return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout);
472
473     SOCKET hSocket = INVALID_SOCKET;
474
475     // first connect to proxy server
476     if (!ConnectSocketDirectly(proxy.first, hSocket, nTimeout))
477         return false;
478  
479     // do socks negotiation
480     switch (proxy.second) {
481     case 4:
482         if (!Socks4(addrDest, hSocket))
483             return false;
484         break;
485     case 5:
486         if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
487             return false;
488         break;
489     default:
490         return false;
491     }
492
493     hSocketRet = hSocket;
494     return true;
495 }
496
497 bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout)
498 {
499     string strDest(pszDest);
500     int port = portDefault;
501
502     // split hostname and port
503     size_t colon = strDest.find_last_of(':');
504     if (colon != strDest.npos) {
505         char *endp = NULL;
506         int n = strtol(pszDest + colon + 1, &endp, 10);
507         if (endp && *endp == 0 && n >= 0) {
508             strDest = strDest.substr(0, colon);
509             if (n > 0 && n < 0x10000)
510                 port = n;
511         }
512     }
513     if (strDest[0] == '[' && strDest[strDest.size()-1] == ']')
514         strDest = strDest.substr(1, strDest.size()-2);
515
516     SOCKET hSocket = INVALID_SOCKET;
517     CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxyInfo.second), port);
518     if (addrResolved.IsValid()) {
519         addr = addrResolved;
520         return ConnectSocket(addr, hSocketRet, nTimeout);
521     }
522     addr = CService("0.0.0.0:0");
523     if (!nameproxyInfo.second)
524         return false;
525     if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout))
526         return false;
527
528     switch(nameproxyInfo.second)
529     {
530         default:
531         case 4: return false;
532         case 5:
533             if (!Socks5(strDest, port, hSocket))
534                 return false;
535             break;
536     }
537
538     hSocketRet = hSocket;
539     return true;
540 }
541
542 void CNetAddr::Init()
543 {
544     memset(ip, 0, 16);
545 }
546
547 void CNetAddr::SetIP(const CNetAddr& ipIn)
548 {
549     memcpy(ip, ipIn.ip, sizeof(ip));
550 }
551
552 CNetAddr::CNetAddr()
553 {
554     Init();
555 }
556
557 CNetAddr::CNetAddr(const struct in_addr& ipv4Addr)
558 {
559     memcpy(ip,    pchIPv4, 12);
560     memcpy(ip+12, &ipv4Addr, 4);
561 }
562
563 #ifdef USE_IPV6
564 CNetAddr::CNetAddr(const struct in6_addr& ipv6Addr)
565 {
566     memcpy(ip, &ipv6Addr, 16);
567 }
568 #endif
569
570 CNetAddr::CNetAddr(const char *pszIp, bool fAllowLookup)
571 {
572     Init();
573     std::vector<CNetAddr> vIP;
574     if (LookupHost(pszIp, vIP, 1, fAllowLookup))
575         *this = vIP[0];
576 }
577
578 CNetAddr::CNetAddr(const std::string &strIp, bool fAllowLookup)
579 {
580     Init();
581     std::vector<CNetAddr> vIP;
582     if (LookupHost(strIp.c_str(), vIP, 1, fAllowLookup))
583         *this = vIP[0];
584 }
585
586 int CNetAddr::GetByte(int n) const
587 {
588     return ip[15-n];
589 }
590
591 bool CNetAddr::IsIPv4() const
592 {
593     return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
594 }
595
596 bool CNetAddr::IsIPv6() const
597 {
598     return (!IsIPv4());
599 }
600
601 bool CNetAddr::IsRFC1918() const
602 {
603     return IsIPv4() && (
604         GetByte(3) == 10 || 
605         (GetByte(3) == 192 && GetByte(2) == 168) || 
606         (GetByte(3) == 172 && (GetByte(2) >= 16 && GetByte(2) <= 31)));
607 }
608
609 bool CNetAddr::IsRFC3927() const
610 {
611     return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254);
612 }
613
614 bool CNetAddr::IsRFC3849() const
615 {
616     return GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x0D && GetByte(12) == 0xB8;
617 }
618
619 bool CNetAddr::IsRFC3964() const
620 {
621     return (GetByte(15) == 0x20 && GetByte(14) == 0x02);
622 }
623
624 bool CNetAddr::IsRFC6052() const
625 {
626     static const unsigned char pchRFC6052[] = {0,0x64,0xFF,0x9B,0,0,0,0,0,0,0,0};
627     return (memcmp(ip, pchRFC6052, sizeof(pchRFC6052)) == 0);
628 }
629
630 bool CNetAddr::IsRFC4380() const
631 {
632     return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0 && GetByte(12) == 0);
633 }
634
635 bool CNetAddr::IsRFC4862() const
636 {
637     static const unsigned char pchRFC4862[] = {0xFE,0x80,0,0,0,0,0,0};
638     return (memcmp(ip, pchRFC4862, sizeof(pchRFC4862)) == 0);
639 }
640
641 bool CNetAddr::IsRFC4193() const
642 {
643     return ((GetByte(15) & 0xFE) == 0xFC);
644 }
645
646 bool CNetAddr::IsRFC6145() const
647 {
648     static const unsigned char pchRFC6145[] = {0,0,0,0,0,0,0,0,0xFF,0xFF,0,0};
649     return (memcmp(ip, pchRFC6145, sizeof(pchRFC6145)) == 0);
650 }
651
652 bool CNetAddr::IsRFC4843() const
653 {
654     return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
655 }
656
657 bool CNetAddr::IsOnionCat() const
658 {
659     static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
660     return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
661 }
662
663 bool CNetAddr::IsGarliCat() const
664 {
665     static const unsigned char pchGarliCat[] = {0xFD,0x60,0xDB,0x4D,0xDD,0xB5};
666     return (memcmp(ip, pchGarliCat, sizeof(pchGarliCat)) == 0);
667 }
668
669 bool CNetAddr::IsLocal() const
670 {
671     // IPv4 loopback
672    if (IsIPv4() && (GetByte(3) == 127 || GetByte(3) == 0))
673        return true;
674
675    // IPv6 loopback (::1/128)
676    static const unsigned char pchLocal[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
677    if (memcmp(ip, pchLocal, 16) == 0)
678        return true;
679
680    return false;
681 }
682
683 bool CNetAddr::IsMulticast() const
684 {
685     return    (IsIPv4() && (GetByte(3) & 0xF0) == 0xE0)
686            || (GetByte(15) == 0xFF);
687 }
688
689 bool CNetAddr::IsValid() const
690 {
691     // Clean up 3-byte shifted addresses caused by garbage in size field
692     // of addr messages from versions before 0.2.9 checksum.
693     // Two consecutive addr messages look like this:
694     // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...
695     // so if the first length field is garbled, it reads the second batch
696     // of addr misaligned by 3 bytes.
697     if (memcmp(ip, pchIPv4+3, sizeof(pchIPv4)-3) == 0)
698         return false;
699
700     // unspecified IPv6 address (::/128)
701     unsigned char ipNone[16] = {};
702     if (memcmp(ip, ipNone, 16) == 0)
703         return false;
704
705     // documentation IPv6 address
706     if (IsRFC3849())
707         return false;
708
709     if (IsIPv4())
710     {
711         // INADDR_NONE
712         uint32_t ipNone = INADDR_NONE;
713         if (memcmp(ip+12, &ipNone, 4) == 0)
714             return false;
715
716         // 0
717         ipNone = 0;
718         if (memcmp(ip+12, &ipNone, 4) == 0)
719             return false;
720     }
721
722     return true;
723 }
724
725 bool CNetAddr::IsRoutable() const
726 {
727     return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsOnionCat() && !IsGarliCat()) || IsRFC4843() || IsLocal());
728 }
729
730 enum Network CNetAddr::GetNetwork() const
731 {
732     if (!IsRoutable())
733         return NET_UNROUTABLE;
734
735     if (IsIPv4())
736         return NET_IPV4;
737
738     if (IsOnionCat())
739         return NET_TOR;
740
741     if (IsGarliCat())
742         return NET_I2P;
743
744     return NET_IPV6;
745 }
746
747 std::string CNetAddr::ToStringIP() const
748 {
749     CService serv(*this, 0);
750 #ifdef USE_IPV6
751     struct sockaddr_storage sockaddr;
752 #else
753     struct sockaddr sockaddr;
754 #endif
755     socklen_t socklen = sizeof(sockaddr);
756     if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
757         char name[1025] = "";
758         if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST))
759             return std::string(name);
760     }
761     if (IsIPv4()) 
762         return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
763     else
764         return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
765                          GetByte(15) << 8 | GetByte(14), GetByte(13) << 8 | GetByte(12),
766                          GetByte(11) << 8 | GetByte(10), GetByte(9) << 8 | GetByte(8),
767                          GetByte(7) << 8 | GetByte(6), GetByte(5) << 8 | GetByte(4),
768                          GetByte(3) << 8 | GetByte(2), GetByte(1) << 8 | GetByte(0));
769 }
770
771 std::string CNetAddr::ToString() const
772 {
773     return ToStringIP();
774 }
775
776 bool operator==(const CNetAddr& a, const CNetAddr& b)
777 {
778     return (memcmp(a.ip, b.ip, 16) == 0);
779 }
780
781 bool operator!=(const CNetAddr& a, const CNetAddr& b)
782 {
783     return (memcmp(a.ip, b.ip, 16) != 0);
784 }
785
786 bool operator<(const CNetAddr& a, const CNetAddr& b)
787 {
788     return (memcmp(a.ip, b.ip, 16) < 0);
789 }
790
791 bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
792 {
793     if (!IsIPv4())
794         return false;
795     memcpy(pipv4Addr, ip+12, 4);
796     return true;
797 }
798
799 #ifdef USE_IPV6
800 bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
801 {
802     memcpy(pipv6Addr, ip, 16);
803     return true;
804 }
805 #endif
806
807 // get canonical identifier of an address' group
808 // no two connections will be attempted to addresses with the same group
809 std::vector<unsigned char> CNetAddr::GetGroup() const
810 {
811     std::vector<unsigned char> vchRet;
812     int nClass = NET_IPV6;
813     int nStartByte = 0;
814     int nBits = 16;
815
816     // all local addresses belong to the same group
817     if (IsLocal())
818     {
819         nClass = 255;
820         nBits = 0;
821     }
822
823     // all unroutable addresses belong to the same group
824     if (!IsRoutable())
825     {
826         nClass = NET_UNROUTABLE;
827         nBits = 0;
828     }
829     // for IPv4 addresses, '1' + the 16 higher-order bits of the IP
830     // includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
831     else if (IsIPv4() || IsRFC6145() || IsRFC6052())
832     {
833         nClass = NET_IPV4;
834         nStartByte = 12;
835     }
836     // for 6to4 tunneled addresses, use the encapsulated IPv4 address
837     else if (IsRFC3964())
838     {
839         nClass = NET_IPV4;
840         nStartByte = 2;
841     }
842     // for Teredo-tunneled IPv6 addresses, use the encapsulated IPv4 address
843     else if (IsRFC4380())
844     {
845         vchRet.push_back(NET_IPV4);
846         vchRet.push_back(GetByte(3) ^ 0xFF);
847         vchRet.push_back(GetByte(2) ^ 0xFF);
848         return vchRet;
849     }
850     // for he.net, use /36 groups
851     else if (GetByte(15) == 0x20 && GetByte(14) == 0x11 && GetByte(13) == 0x04 && GetByte(12) == 0x70)
852         nBits = 36;
853     // for the rest of the IPv6 network, use /32 groups
854     else
855         nBits = 32;
856
857     vchRet.push_back(nClass);
858     while (nBits >= 8)
859     {
860         vchRet.push_back(GetByte(15 - nStartByte));
861         nStartByte++;
862         nBits -= 8;
863     }
864     if (nBits > 0)
865         vchRet.push_back(GetByte(15 - nStartByte) | ((1 << nBits) - 1));
866
867     return vchRet;
868 }
869
870 int64 CNetAddr::GetHash() const
871 {
872     uint256 hash = Hash(&ip[0], &ip[16]);
873     int64 nRet;
874     memcpy(&nRet, &hash, sizeof(nRet));
875     return nRet;
876 }
877
878 void CNetAddr::print() const
879 {
880     printf("CNetAddr(%s)\n", ToString().c_str());
881 }
882
883 // for IPv6 partners:        for unknown/Teredo partners:      for IPv4 partners:
884 // 0 - unroutable            // 0 - unroutable                 // 0 - unroutable
885 // 1 - teredo                // 1 - teredo                     // 1 - ipv4
886 // 2 - tunneled ipv6         // 2 - tunneled ipv6
887 // 3 - ipv4                  // 3 - ipv6
888 // 4 - ipv6                  // 4 - ipv4
889 int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
890 {
891     if (!IsValid() || !IsRoutable())
892         return 0;
893     if (paddrPartner && paddrPartner->IsIPv4())
894         return IsIPv4() ? 1 : 0;
895     if (IsRFC4380())
896         return 1;
897     if (IsRFC3964() || IsRFC6052())
898         return 2;
899     bool fRealIPv6 = paddrPartner && !paddrPartner->IsRFC4380() && paddrPartner->IsValid() && paddrPartner->IsRoutable();
900     if (fRealIPv6)
901         return IsIPv4() ? 3 : 4;
902     else
903         return IsIPv4() ? 4 : 3;
904 }
905
906 void CService::Init()
907 {
908     port = 0;
909 }
910
911 CService::CService()
912 {
913     Init();
914 }
915
916 CService::CService(const CNetAddr& cip, unsigned short portIn) : CNetAddr(cip), port(portIn)
917 {
918 }
919
920 CService::CService(const struct in_addr& ipv4Addr, unsigned short portIn) : CNetAddr(ipv4Addr), port(portIn)
921 {
922 }
923
924 #ifdef USE_IPV6
925 CService::CService(const struct in6_addr& ipv6Addr, unsigned short portIn) : CNetAddr(ipv6Addr), port(portIn)
926 {
927 }
928 #endif
929
930 CService::CService(const struct sockaddr_in& addr) : CNetAddr(addr.sin_addr), port(ntohs(addr.sin_port))
931 {
932     assert(addr.sin_family == AF_INET);
933 }
934
935 #ifdef USE_IPV6
936 CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr), port(ntohs(addr.sin6_port))
937 {
938    assert(addr.sin6_family == AF_INET6);
939 }
940 #endif
941
942 bool CService::SetSockAddr(const struct sockaddr *paddr)
943 {
944     switch (paddr->sa_family) {
945     case AF_INET:
946         *this = CService(*(const struct sockaddr_in*)paddr);
947         return true;
948 #ifdef USE_IPV6
949     case AF_INET6:
950         *this = CService(*(const struct sockaddr_in6*)paddr);
951         return true;
952 #endif
953     default:
954         return false;
955     }
956 }
957
958 CService::CService(const char *pszIpPort, bool fAllowLookup)
959 {
960     Init();
961     CService ip;
962     if (Lookup(pszIpPort, ip, 0, fAllowLookup))
963         *this = ip;
964 }
965
966 CService::CService(const char *pszIpPort, int portDefault, bool fAllowLookup)
967 {
968     Init();
969     CService ip;
970     if (Lookup(pszIpPort, ip, portDefault, fAllowLookup))
971         *this = ip;
972 }
973
974 CService::CService(const std::string &strIpPort, bool fAllowLookup)
975 {
976     Init();
977     CService ip;
978     if (Lookup(strIpPort.c_str(), ip, 0, fAllowLookup))
979         *this = ip;
980 }
981
982 CService::CService(const std::string &strIpPort, int portDefault, bool fAllowLookup)
983 {
984     Init();
985     CService ip;
986     if (Lookup(strIpPort.c_str(), ip, portDefault, fAllowLookup))
987         *this = ip;
988 }
989
990 unsigned short CService::GetPort() const
991 {
992     return port;
993 }
994
995 bool operator==(const CService& a, const CService& b)
996 {
997     return (CNetAddr)a == (CNetAddr)b && a.port == b.port;
998 }
999
1000 bool operator!=(const CService& a, const CService& b)
1001 {
1002     return (CNetAddr)a != (CNetAddr)b || a.port != b.port;
1003 }
1004
1005 bool operator<(const CService& a, const CService& b)
1006 {
1007     return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
1008 }
1009
1010 bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
1011 {
1012     if (IsIPv4()) {
1013         if (*addrlen < (socklen_t)sizeof(struct sockaddr_in))
1014             return false;
1015         *addrlen = sizeof(struct sockaddr_in);
1016         struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
1017         memset(paddrin, 0, *addrlen);
1018         if (!GetInAddr(&paddrin->sin_addr))
1019             return false;
1020         paddrin->sin_family = AF_INET;
1021         paddrin->sin_port = htons(port);
1022         return true;
1023     }
1024 #ifdef USE_IPV6
1025     if (IsIPv6()) {
1026         if (*addrlen < (socklen_t)sizeof(struct sockaddr_in6))
1027             return false;
1028         *addrlen = sizeof(struct sockaddr_in6);
1029         struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
1030         memset(paddrin6, 0, *addrlen);
1031         if (!GetIn6Addr(&paddrin6->sin6_addr))
1032             return false;
1033         paddrin6->sin6_family = AF_INET6;
1034         paddrin6->sin6_port = htons(port);
1035         return true;
1036     }
1037 #endif
1038     return false;
1039 }
1040
1041 std::vector<unsigned char> CService::GetKey() const
1042 {
1043      std::vector<unsigned char> vKey;
1044      vKey.resize(18);
1045      memcpy(&vKey[0], ip, 16);
1046      vKey[16] = port / 0x100;
1047      vKey[17] = port & 0x0FF;
1048      return vKey;
1049 }
1050
1051 std::string CService::ToStringPort() const
1052 {
1053     return strprintf("%i", port);
1054 }
1055
1056 std::string CService::ToStringIPPort() const
1057 {
1058     if (IsIPv4()) {
1059         return ToStringIP() + ":" + ToStringPort();
1060     } else {
1061         return "[" + ToStringIP() + "]:" + ToStringPort();
1062     }
1063 }
1064
1065 std::string CService::ToString() const
1066 {
1067     return ToStringIPPort();
1068 }
1069
1070 void CService::print() const
1071 {
1072     printf("CService(%s)\n", ToString().c_str());
1073 }
1074
1075 void CService::SetPort(unsigned short portIn)
1076 {
1077     port = portIn;
1078 }
This page took 0.081146 seconds and 4 git commands to generate.