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