Anoncoin  0.9.4
P2P Digital Currency
net.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2013-2015 The Anoncoin Core developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "net.h"
8 
9 #include "addrman.h"
10 #include "clientversion.h"
11 #include "chainparams.h"
12 #include "core.h"
13 #include "ui_interface.h"
14 
15 #ifdef ENABLE_I2PSAM
16 #include "i2pwrapper.h"
17 #endif
18 
19 #ifdef WIN32
20 #include <string.h>
21 #else
22 #include <fcntl.h>
23 #endif
24 
25 #ifdef USE_UPNP
26 #include <miniupnpc/miniupnpc.h>
27 #include <miniupnpc/miniwget.h>
28 #include <miniupnpc/upnpcommands.h>
29 #include <miniupnpc/upnperrors.h>
30 #endif
31 
32 #include <boost/filesystem.hpp>
33 
34 // Dump addresses to peers.dat every 15 minutes (900s)
35 #define DUMP_ADDRESSES_INTERVAL 900
36 
37 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
38 #define MSG_NOSIGNAL 0
39 #endif
40 
41 using namespace std;
42 using namespace boost;
43 
44 static const int MAX_OUTBOUND_CONNECTIONS = 24;
45 
46 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
47 
48 
49 //
50 // Global state variables
51 //
52 bool fDiscover = true;
54 map<CNetAddr, LocalServiceInfo> mapLocalHost;
55 static bool vfReachable[NET_MAX] = {};
56 static bool vfLimited[NET_MAX] = {};
57 static CNode* pnodeLocalHost = NULL;
58 static CNode* pnodeSync = NULL;
59 uint64_t nLocalHostNonce = 0;
60 static std::vector<SOCKET> vhListenSocket;
62 int nMaxConnections = 125;
63 bool fAddressesInitialized = false;
64 
65 
66 #ifdef ENABLE_I2PSAM
67 uint64_t nLocalServices = NODE_NETWORK | NODE_BLOOM | NODE_I2P; // Add the I2P protocol(.h) bit to our local services list
68 static std::vector<SOCKET> vhI2PListenSocket; // We maintain a seperate vector for I2P network SOCKET's
69 int nI2PNodeCount = 0; // And a count of the active nodes we're connected with
70 #else
71 uint64_t nLocalServices = NODE_NETWORK | NODE_BLOOM; // Standard services declaration
72 #endif
73 
74 vector<CNode*> vNodes;
76 map<CInv, CDataStream> mapRelay;
77 deque<pair<int64_t, CInv> > vRelayExpiration;
80 
81 static deque<string> vOneShots;
83 
86 
87 vector<std::string> vAddedNodes;
89 
92 
93 static CSemaphore *semOutbound = NULL;
94 
95 // Signals for message handling
96 static CNodeSignals g_signals;
97 CNodeSignals& GetNodeSignals() { return g_signals; }
98 
99 void AddOneShot(string strDest)
100 {
101  LOCK(cs_vOneShots);
102  vOneShots.push_back(strDest);
103 }
104 
105 unsigned short GetListenPort()
106 {
107  return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
108 }
109 
110 // find 'best' local address for a particular peer
111 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
112 {
113  if (fNoListen)
114  return false;
115 
116  int nBestScore = -1;
117  int nBestReachability = -1;
118  {
119  LOCK(cs_mapLocalHost);
120  for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
121  {
122  int nScore = (*it).second.nScore;
123  int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
124  if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
125  {
126  addr = CService((*it).first, (*it).second.nPort);
127  nBestReachability = nReachability;
128  nBestScore = nScore;
129  }
130  }
131  }
132  return nBestScore >= 0;
133 }
134 
135 // get best local address for a particular peer as a CAddress
137 {
138  CAddress ret(CService("0.0.0.0",0),0);
139  CService addr;
140  if (GetLocal(addr, paddrPeer))
141  {
142  ret = CAddress(addr);
144  ret.nTime = GetAdjustedTime();
145  }
146  return ret;
147 }
148 
149 bool RecvLine(SOCKET hSocket, string& strLine)
150 {
151  strLine = "";
152  while (true)
153  {
154  char c;
155  int nBytes = recv(hSocket, &c, 1, 0);
156  if (nBytes > 0)
157  {
158  if (c == '\n')
159  continue;
160  if (c == '\r')
161  return true;
162  strLine += c;
163  if (strLine.size() >= 9000)
164  return true;
165  }
166  else if (nBytes <= 0)
167  {
168  boost::this_thread::interruption_point();
169  if (nBytes < 0)
170  {
171  int nErr = WSAGetLastError();
172  if (nErr == WSAEMSGSIZE)
173  continue;
174  if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
175  {
176  MilliSleep(10);
177  continue;
178  }
179  }
180  if (!strLine.empty())
181  return true;
182  if (nBytes == 0)
183  {
184  // socket closed
185  LogPrint("net", "socket closed\n");
186  return false;
187  }
188  else
189  {
190  // socket error
191  int nErr = WSAGetLastError();
192  LogPrint("net", "recv failed: %s\n", NetworkErrorString(nErr));
193  return false;
194  }
195  }
196  }
197 }
198 
199 // used when scores of local addresses may have changed
200 // pushes better local address to peers
201 void static AdvertizeLocal()
202 {
203  LOCK(cs_vNodes);
204  BOOST_FOREACH(CNode* pnode, vNodes)
205  {
206  if (pnode->fSuccessfullyConnected)
207  {
208  CAddress addrLocal = GetLocalAddress(&pnode->addr);
209  if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
210  {
211  pnode->PushAddress(addrLocal);
212  pnode->addrLocal = addrLocal;
213  }
214  }
215  }
216 }
217 
218 void SetReachable(enum Network net, bool fFlag)
219 {
220  LOCK(cs_mapLocalHost);
221  vfReachable[net] = fFlag;
222  if (net == NET_IPV6 && fFlag)
223  vfReachable[NET_IPV4] = true;
224 }
225 
226 // learn a new local address
227 bool AddLocal(const CService& addr, int nScore)
228 {
229  if (!addr.IsRoutable())
230  return false;
231 
232  if (!fDiscover && nScore < LOCAL_MANUAL)
233  return false;
234 
235  if (IsLimited(addr))
236  return false;
237 
238  LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
239 
240  {
241  LOCK(cs_mapLocalHost);
242  bool fAlready = mapLocalHost.count(addr) > 0;
243  LocalServiceInfo &info = mapLocalHost[addr];
244  if (!fAlready || nScore >= info.nScore) {
245  info.nScore = nScore + (fAlready ? 1 : 0);
246  info.nPort = addr.GetPort();
247  }
248  SetReachable(addr.GetNetwork());
249  }
250 
251  AdvertizeLocal();
252 
253  return true;
254 }
255 
256 bool AddLocal(const CNetAddr &addr, int nScore)
257 {
258  return AddLocal(CService(addr, GetListenPort()), nScore);
259 }
260 
262 void SetLimited(enum Network net, bool fLimited)
263 {
264  if (net == NET_UNROUTABLE)
265  return;
266  LOCK(cs_mapLocalHost);
267  vfLimited[net] = fLimited;
268 }
269 
270 bool IsLimited(enum Network net)
271 {
272  LOCK(cs_mapLocalHost);
273  return vfLimited[net];
274 }
275 
276 bool IsLimited(const CNetAddr &addr)
277 {
278  return IsLimited(addr.GetNetwork());
279 }
280 
282 bool SeenLocal(const CService& addr)
283 {
284  {
285  LOCK(cs_mapLocalHost);
286  if (mapLocalHost.count(addr) == 0)
287  return false;
288  mapLocalHost[addr].nScore++;
289  }
290 
291  AdvertizeLocal();
292 
293  return true;
294 }
295 
297 bool IsLocal(const CService& addr)
298 {
299  LOCK(cs_mapLocalHost);
300  return mapLocalHost.count(addr) > 0;
301 }
302 
304 bool IsReachable(enum Network net)
305 {
306  LOCK(cs_mapLocalHost);
307  return vfReachable[net] && !vfLimited[net];
308 }
309 
311 bool IsReachable(const CNetAddr& addr)
312 {
313  enum Network net = addr.GetNetwork();
314  return IsReachable(net);
315 }
316 
317 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
318 {
319  SOCKET hSocket;
320  if (!ConnectSocket(addrConnect, hSocket))
321  return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString());
322 
323  send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
324 
325  string strLine;
326  while (RecvLine(hSocket, strLine))
327  {
328  if (strLine.empty()) // HTTP response is separated from headers by blank line
329  {
330  while (true)
331  {
332  if (!RecvLine(hSocket, strLine))
333  {
334  closesocket(hSocket);
335  return false;
336  }
337  if (pszKeyword == NULL)
338  break;
339  if (strLine.find(pszKeyword) != string::npos)
340  {
341  strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
342  break;
343  }
344  }
345  closesocket(hSocket);
346  if (strLine.find("<") != string::npos)
347  strLine = strLine.substr(0, strLine.find("<"));
348  strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
349  while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
350  strLine.resize(strLine.size()-1);
351  CService addr(strLine,0,true);
352  LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine, addr.ToString());
353  if (!addr.IsValid() || !addr.IsRoutable())
354  return false;
355  ipRet.SetIP(addr);
356  return true;
357  }
358  }
359  closesocket(hSocket);
360  return error("GetMyExternalIP() : connection closed");
361 }
362 
364 {
365  CService addrConnect;
366  const char* pszGet;
367  const char* pszKeyword;
368 
369  for (int nLookup = 0; nLookup <= 1; nLookup++)
370  for (int nHost = 1; nHost <= 1; nHost++)
371  {
372  // We should be phasing out our use of sites like these. If we need
373  // replacements, we should ask for volunteers to put this simple
374  // php file on their web server that prints the client IP:
375  // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
376  if (nHost == 1)
377  {
378  addrConnect = CService("91.198.22.70", 80); // checkip.dyndns.org
379 
380  if (nLookup == 1)
381  {
382  CService addrIP("checkip.dyndns.org", 80, true);
383  if (addrIP.IsValid())
384  addrConnect = addrIP;
385  }
386 
387  pszGet = "GET / HTTP/1.1\r\n"
388  "Host: checkip.dyndns.org\r\n"
389  "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
390  "Connection: close\r\n"
391  "\r\n";
392 
393  pszKeyword = "Address:";
394  }
395 
396  if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
397  return true;
398  }
399 
400  return false;
401 }
402 
404 {
405  CNetAddr addrLocalHost;
406  if (GetMyExternalIP(addrLocalHost))
407  {
408  LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP());
409  AddLocal(addrLocalHost, LOCAL_HTTP);
410  }
411 }
412 
413 
414 
415 
416 
418 {
419  addrman.Connected(addr);
420 }
421 
422 
423 
424 
425 uint64_t CNode::nTotalBytesRecv = 0;
426 uint64_t CNode::nTotalBytesSent = 0;
429 
431 {
432  LOCK(cs_vNodes);
433  BOOST_FOREACH(CNode* pnode, vNodes)
434  if ((CNetAddr)pnode->addr == ip)
435  return (pnode);
436  return NULL;
437 }
438 
439 CNode* FindNode(std::string addrName)
440 {
441  LOCK(cs_vNodes);
442  BOOST_FOREACH(CNode* pnode, vNodes)
443  if (pnode->addrName == addrName)
444  return (pnode);
445  return NULL;
446 }
447 
448 CNode* FindNode(const CService& addr)
449 {
450  LOCK(cs_vNodes);
451  BOOST_FOREACH(CNode* pnode, vNodes)
452  if ((CService)pnode->addr == addr)
453  return (pnode);
454  return NULL;
455 }
456 
457 CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
458 {
459  if (pszDest == NULL) {
460  if (IsLocal(addrConnect))
461  return NULL;
462 
463  // Look for an existing connection
464  CNode* pnode = FindNode((CService)addrConnect);
465  if (pnode)
466  {
467  pnode->AddRef();
468  return pnode;
469  }
470  }
471 
472 
474  LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
475  pszDest ? pszDest : addrConnect.ToString(),
476  pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
477 
478  // Connect
479  SOCKET hSocket;
480  if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
481  {
482  addrman.Attempt(addrConnect);
483 
484  LogPrint("net", "connected %s\n", pszDest ? pszDest : addrConnect.ToString());
485 
486  // Set to non-blocking
487 #ifdef WIN32
488  u_long nOne = 1;
489  if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
490  LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %s\n", NetworkErrorString(WSAGetLastError()));
491 #else
492  if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
493  LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %s\n", NetworkErrorString(errno));
494 #endif
495 
496  // Add node
497  CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
498  pnode->AddRef();
499 
500  {
501  LOCK(cs_vNodes);
502  vNodes.push_back(pnode);
503 #ifdef ENABLE_I2PSAM
504  if (addrConnect.IsNativeI2P()) ++nI2PNodeCount;
505 #endif
506  }
507 
508  pnode->nTimeConnected = GetTime();
509  return pnode;
510  }
511  else
512  {
513  return NULL;
514  }
515 }
516 
518 {
519  fDisconnect = true;
520  if (hSocket != INVALID_SOCKET)
521  {
522  LogPrint("net", "disconnecting node %s\n", addrName);
523  closesocket(hSocket);
524  hSocket = INVALID_SOCKET;
525  }
526 
527  // in case this fails, we'll empty the recv buffer when the CNode is deleted
528  TRY_LOCK(cs_vRecvMsg, lockRecv);
529  if (lockRecv)
530  vRecvMsg.clear();
531 
532  // if this was the sync node, we'll need a new one
533  if (this == pnodeSync)
534  pnodeSync = NULL;
535 }
536 
538 {
539 }
540 
541 
543 {
544  int nBestHeight = g_signals.GetHeight().get_value_or(0);
545 
547  int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
548  CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
549  CAddress addrMe = GetLocalAddress(&addr);
550  RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
551  LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), addr.ToString());
552  PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
553  nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
554 }
555 
556 
557 
558 
559 
560 std::map<CNetAddr, int64_t> CNode::setBanned;
562 
564 {
565  setBanned.clear();
566 }
567 
569 {
570  bool fResult = false;
571  {
572  LOCK(cs_setBanned);
573  std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
574  if (i != setBanned.end())
575  {
576  int64_t t = (*i).second;
577  if (GetTime() < t)
578  fResult = true;
579  }
580  }
581  return fResult;
582 }
583 
584 bool CNode::Ban(const CNetAddr &addr) {
585  int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
586  {
587  LOCK(cs_setBanned);
588  if (setBanned[addr] < banTime)
589  setBanned[addr] = banTime;
590  }
591  return true;
592 }
593 
594 #undef X
595 #define X(name) stats.name = name
597 {
598  stats.nodeid = this->GetId();
599  X(nServices);
600  X(nLastSend);
601  X(nLastRecv);
602  X(nTimeConnected);
603  X(addrName);
604  X(nVersion);
605  X(cleanSubVer);
606  X(fInbound);
607  X(nStartingHeight);
608  X(nSendBytes);
609  X(nRecvBytes);
610  stats.fSyncNode = (this == pnodeSync);
611 
612  // It is common for nodes with good ping times to suddenly become lagged,
613  // due to a new block arriving or other large transfer.
614  // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
615  // since pingtime does not update until the ping is complete, which might take a while.
616  // So, if a ping is taking an unusually long time in flight,
617  // the caller can immediately detect that this is happening.
618  int64_t nPingUsecWait = 0;
619  if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
620  nPingUsecWait = GetTimeMicros() - nPingUsecStart;
621  }
622 
623  // Raw ping time is in microseconds, but show it to user as whole seconds (Anoncoin users should be well used to small numbers with many decimal places by now :)
624  stats.dPingTime = (((double)nPingUsecTime) / 1e6);
625  stats.dPingWait = (((double)nPingUsecWait) / 1e6);
626 
627  // Leave string empty if addrLocal invalid (not filled in yet)
628  stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
629 }
630 #undef X
631 
632 // requires LOCK(cs_vRecvMsg)
633 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
634 {
635  while (nBytes > 0) {
636 
637  // get current incomplete message, or create a new one
638  if (vRecvMsg.empty() ||
639  vRecvMsg.back().complete())
640  vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
641 
642  CNetMessage& msg = vRecvMsg.back();
643 
644  // absorb network data
645  int handled;
646  if (!msg.in_data)
647  handled = msg.readHeader(pch, nBytes);
648  else
649  handled = msg.readData(pch, nBytes);
650 
651  if (handled < 0)
652  return false;
653 
654  pch += handled;
655  nBytes -= handled;
656  }
657 
658  return true;
659 }
660 
661 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
662 {
663  // copy data to temporary parsing buffer
664  unsigned int nRemaining = 24 - nHdrPos;
665  unsigned int nCopy = std::min(nRemaining, nBytes);
666 
667  memcpy(&hdrbuf[nHdrPos], pch, nCopy);
668  nHdrPos += nCopy;
669 
670  // if header incomplete, exit
671  if (nHdrPos < 24)
672  return nCopy;
673 
674  // deserialize to CMessageHeader
675  try {
676  hdrbuf >> hdr;
677  }
678  catch (std::exception &e) {
679  return -1;
680  }
681 
682  // reject messages larger than MAX_SIZE
683  if (hdr.nMessageSize > MAX_SIZE)
684  return -1;
685 
686  // switch state to reading message data
687  in_data = true;
688  vRecv.resize(hdr.nMessageSize);
689 
690  return nCopy;
691 }
692 
693 int CNetMessage::readData(const char *pch, unsigned int nBytes)
694 {
695  unsigned int nRemaining = hdr.nMessageSize - nDataPos;
696  unsigned int nCopy = std::min(nRemaining, nBytes);
697 
698  memcpy(&vRecv[nDataPos], pch, nCopy);
699  nDataPos += nCopy;
700 
701  return nCopy;
702 }
703 
704 
705 
706 
707 
708 
709 
710 
711 
712 // requires LOCK(cs_vSend)
713 void SocketSendData(CNode *pnode)
714 {
715  std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
716 
717  while (it != pnode->vSendMsg.end()) {
718  const CSerializeData &data = *it;
719  assert(data.size() > pnode->nSendOffset);
720  int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
721  if (nBytes > 0) {
722  pnode->nLastSend = GetTime();
723  pnode->nSendBytes += nBytes;
724  pnode->nSendOffset += nBytes;
725  pnode->RecordBytesSent(nBytes);
726  if (pnode->nSendOffset == data.size()) {
727  pnode->nSendOffset = 0;
728  pnode->nSendSize -= data.size();
729  it++;
730  } else {
731  // could not send full message; stop sending more
732  break;
733  }
734  } else {
735  if (nBytes < 0) {
736  // error
737  int nErr = WSAGetLastError();
738  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
739  {
740  LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
741  pnode->CloseSocketDisconnect();
742  }
743  }
744  // couldn't send anything at all
745  break;
746  }
747  }
748 
749  if (it == pnode->vSendMsg.end()) {
750  assert(pnode->nSendOffset == 0);
751  assert(pnode->nSendSize == 0);
752  }
753  pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
754 }
755 
756 static list<CNode*> vNodesDisconnected;
757 
758 #ifdef ENABLE_I2PSAM
759 
762 static void AddIncomingI2pConnection(SOCKET hSocket, const CAddress& addr)
763 {
764  int nInbound = 0;
765 
766  {
767  LOCK(cs_vNodes);
768  BOOST_FOREACH(CNode* pnode, vNodes)
769  if (pnode->fInbound)
770  nInbound++;
771  }
772 
773  if (hSocket == INVALID_SOCKET)
774  {
775  int nErr = WSAGetLastError();
776  if (nErr != WSAEWOULDBLOCK)
777  LogPrintf("socket error accept failed: %d\n", nErr);
778  }
779  else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
780  {
781  {
782  LOCK(cs_setservAddNodeAddresses);
783  if (!setservAddNodeAddresses.count(addr))
784  closesocket(hSocket);
785  }
786  }
787  else if (CNode::IsBanned(addr))
788  {
789  LogPrintf("connection from %s dropped (banned)\n", addr.ToString().c_str());
790  closesocket(hSocket);
791  }
792  else
793  {
794  LogPrintf("accepted connection %s\n", addr.ToString().c_str());
795  CNode* pnode = new CNode(hSocket, addr, "", true);
796  pnode->AddRef();
797  {
798  LOCK(cs_vNodes);
799  vNodes.push_back(pnode);
800  ++nI2PNodeCount;
801  }
802  }
803 }
804 #endif // ENABLE_I2PSAM
805 
811 {
812  unsigned int nPrevNodeCount = 0;
813 #ifdef ENABLE_I2PSAM
814  int nPrevI2PNodeCount = 0;
815 #endif
816 
817  while (true)
818  {
819  //
820  // Disconnect nodes
821  //
822  {
823  LOCK(cs_vNodes);
824  // Disconnect unused nodes
825  vector<CNode*> vNodesCopy = vNodes;
826  BOOST_FOREACH(CNode* pnode, vNodesCopy)
827  {
828  if (pnode->fDisconnect ||
829  (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
830  {
831  // remove from vNodes
832  vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
833 
834  // release outbound grant (if any)
835  pnode->grantOutbound.Release();
836 
837  // close socket and cleanup
838  pnode->CloseSocketDisconnect();
839  pnode->Cleanup();
840 
841  // hold in disconnected pool until all refs are released
842  if (pnode->fNetworkNode || pnode->fInbound)
843  pnode->Release();
844  vNodesDisconnected.push_back(pnode);
845 #ifdef ENABLE_I2PSAM
846  if (pnode->addr.IsNativeI2P()) --nI2PNodeCount;
847 #endif
848 
849  }
850  }
851  }
852  {
853  // Delete disconnected nodes
854  list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
855  BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
856  {
857  // wait until threads are done using it
858  if (pnode->GetRefCount() <= 0)
859  {
860  bool fDelete = false;
861  {
862  TRY_LOCK(pnode->cs_vSend, lockSend);
863  if (lockSend)
864  {
865  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
866  if (lockRecv)
867  {
868  TRY_LOCK(pnode->cs_inventory, lockInv);
869  if (lockInv)
870  fDelete = true;
871  }
872  }
873  }
874  if (fDelete)
875  {
876  vNodesDisconnected.remove(pnode);
877  delete pnode;
878  }
879  }
880  }
881  }
882 
883  // We notify the ui of I2P node count changes BEFORE, we notify the normal node count, this way QT's status
884  // icons display the correct number of nodes MINUS the i2p ones connected. See: anoncoingui.cpp setNumConnections()
885  // This I think caused a bug in the display of non-i2p node connection counts right after startup, had to add a
886  // fix in the status line display output, so that if the value was negative, then it was set to 0, as it should be
887 #ifdef ENABLE_I2PSAM
888  if (nPrevI2PNodeCount != nI2PNodeCount)
889  {
890  nPrevI2PNodeCount = nI2PNodeCount;
891  uiInterface.NotifyNumI2PConnectionsChanged(nI2PNodeCount);
892  }
893 #endif // ENABLE_I2PSAM
894 
895  if(vNodes.size() != nPrevNodeCount) {
896  nPrevNodeCount = vNodes.size();
898  }
899 
900  //
901  // Find which sockets have data to receive
902  //
903  struct timeval timeout;
904  timeout.tv_sec = 0;
905  timeout.tv_usec = 50000; // frequency to poll pnode->vSend
906 
907  fd_set fdsetRecv;
908  fd_set fdsetSend;
909  fd_set fdsetError;
910  FD_ZERO(&fdsetRecv);
911  FD_ZERO(&fdsetSend);
912  FD_ZERO(&fdsetError);
913  SOCKET hSocketMax = 0;
914  bool have_fds = false;
915 
916 #ifdef ENABLE_I2PSAM
917  BOOST_FOREACH(SOCKET hI2PListenSocket, vhI2PListenSocket) {
918  if (hI2PListenSocket != INVALID_SOCKET) {
919  FD_SET(hI2PListenSocket, &fdsetRecv);
920  hSocketMax = max(hSocketMax, hI2PListenSocket);
921  have_fds = true;
922  }
923  }
924 #endif // ENABLE_I2PSAM
925 
926  BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
927  FD_SET(hListenSocket, &fdsetRecv);
928  hSocketMax = max(hSocketMax, hListenSocket);
929  have_fds = true;
930  }
931  {
932  LOCK(cs_vNodes);
933  BOOST_FOREACH(CNode* pnode, vNodes)
934  {
935  if (pnode->hSocket == INVALID_SOCKET)
936  continue;
937  FD_SET(pnode->hSocket, &fdsetError);
938  hSocketMax = max(hSocketMax, pnode->hSocket);
939  have_fds = true;
940 
941  // Implement the following logic:
942  // * If there is data to send, select() for sending data. As this only
943  // happens when optimistic write failed, we choose to first drain the
944  // write buffer in this case before receiving more. This avoids
945  // needlessly queueing received data, if the remote peer is not themselves
946  // receiving data. This means properly utilizing TCP flow control signalling.
947  // * Otherwise, if there is no (complete) message in the receive buffer,
948  // or there is space left in the buffer, select() for receiving data.
949  // * (if neither of the above applies, there is certainly one message
950  // in the receiver buffer ready to be processed).
951  // Together, that means that at least one of the following is always possible,
952  // so we don't deadlock:
953  // * We send some data.
954  // * We wait for data to be received (and disconnect after timeout).
955  // * We process a message in the buffer (message handler thread).
956  {
957  TRY_LOCK(pnode->cs_vSend, lockSend);
958  if (lockSend && !pnode->vSendMsg.empty()) {
959  FD_SET(pnode->hSocket, &fdsetSend);
960  continue;
961  }
962  }
963  {
964  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
965  if (lockRecv && (
966  pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
967  pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
968  FD_SET(pnode->hSocket, &fdsetRecv);
969  }
970  }
971  }
972 
973  int nSelect = select(have_fds ? hSocketMax + 1 : 0,
974  &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
975  boost::this_thread::interruption_point();
976 
977  if (nSelect == SOCKET_ERROR)
978  {
979  if (have_fds)
980  {
981  int nErr = WSAGetLastError();
982  LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
983  for (unsigned int i = 0; i <= hSocketMax; i++)
984  FD_SET(i, &fdsetRecv);
985  }
986  FD_ZERO(&fdsetSend);
987  FD_ZERO(&fdsetError);
988  MilliSleep(timeout.tv_usec/1000);
989  }
990 
991 
992  //
993  // Accept new connections
994  //
995  // ToDo: Double check me, all of this net.cpp code for I2PSAM should be looked over again.
996 #ifdef ENABLE_I2PSAM
997  if (!IsI2POnly()) {
998 #endif // Without I2P onlynet, execute the original code
999  BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1000  if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
1001  {
1002  struct sockaddr_storage sockaddr;
1003  socklen_t len = sizeof(sockaddr);
1004  SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
1005  CAddress addr;
1006  int nInbound = 0;
1007 
1008  if (hSocket != INVALID_SOCKET)
1009  if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
1010  LogPrintf("Warning: Unknown socket family\n");
1011 
1012  {
1013  LOCK(cs_vNodes);
1014  BOOST_FOREACH(CNode* pnode, vNodes)
1015  if (pnode->fInbound)
1016  nInbound++;
1017  }
1018 
1019  if (hSocket == INVALID_SOCKET)
1020  {
1021  int nErr = WSAGetLastError();
1022  if (nErr != WSAEWOULDBLOCK)
1023  LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
1024  }
1025  else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
1026  {
1027  closesocket(hSocket);
1028  }
1029  else if (CNode::IsBanned(addr))
1030  {
1031  LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
1032  closesocket(hSocket);
1033  }
1034  else
1035  {
1036  LogPrint("net", "accepted connection %s\n", addr.ToString());
1037  CNode* pnode = new CNode(hSocket, addr, "", true);
1038  pnode->AddRef();
1039  {
1040  LOCK(cs_vNodes);
1041  vNodes.push_back(pnode);
1042  }
1043  }
1044  }
1045 #ifdef ENABLE_I2PSAM
1046  }
1047  //
1048  // Accept new I2P connections
1049  //
1050  {
1051  bool haveInvalids = false;
1052  for (std::vector<SOCKET>::iterator it = vhI2PListenSocket.begin(); it != vhI2PListenSocket.end(); ++it)
1053  {
1054  SOCKET& hI2PListenSocket = *it;
1055  if (hI2PListenSocket == INVALID_SOCKET)
1056  {
1057  if (haveInvalids)
1058  it = vhI2PListenSocket.erase(it) - 1;
1059  else
1060  BindListenNativeI2P(hI2PListenSocket);
1061  haveInvalids = true;
1062  }
1063  else if (FD_ISSET(hI2PListenSocket, &fdsetRecv))
1064  {
1065  const size_t bufSize = NATIVE_I2P_DESTINATION_SIZE + 1;
1066  char pchBuf[bufSize];
1067  memset(pchBuf, 0, bufSize);
1068  int nBytes = recv(hI2PListenSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1069  if (nBytes > 0)
1070  {
1071  // ToDo: This is not correct,
1072  // <orignal> this line must be fixed ASAP
1073  // https://geti2p.net/en/docs/spec/common-structures#struct_Destination
1074  if (nBytes == NATIVE_I2P_DESTINATION_SIZE + 1) // we're waiting for dest-hash + '\n' symbol
1075  {
1076  std::string incomingAddr(pchBuf, pchBuf + NATIVE_I2P_DESTINATION_SIZE);
1077  CAddress addr;
1078  if (addr.SetSpecial(incomingAddr) && addr.IsNativeI2P())
1079  {
1080  AddIncomingI2pConnection(hI2PListenSocket, addr);
1081  }
1082  else
1083  {
1084  LogPrintf("Invalid incoming destination hash received (%s)\n", incomingAddr.c_str());
1085  closesocket(hI2PListenSocket);
1086  }
1087  }
1088  else
1089  {
1090  LogPrintf("Invalid incoming destination hash size received (%d)\n", nBytes);
1091  closesocket(hI2PListenSocket);
1092  }
1093  }
1094  else if (nBytes == 0)
1095  {
1096  // socket closed gracefully
1097  LogPrintf("I2P listen socket closed\n");
1098  closesocket(hI2PListenSocket);
1099  }
1100  else if (nBytes < 0)
1101  {
1102  // error
1103  const int nErr = WSAGetLastError();
1104  if (nErr == WSAEWOULDBLOCK || nErr == WSAEMSGSIZE || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
1105  continue;
1106 
1107  LogPrintf("I2P listen socket recv error %d\n", nErr);
1108  closesocket(hI2PListenSocket);
1109  }
1110  hI2PListenSocket = INVALID_SOCKET; // we've saved this socket in a CNode or closed it, so we can safety reset it anyway
1111  BindListenNativeI2P(hI2PListenSocket);
1112  }
1113  }
1114  }
1115 #endif // ENABLE_I2PSAM
1116 
1117  //
1118  // Service each socket
1119  //
1120  vector<CNode*> vNodesCopy;
1121  {
1122  LOCK(cs_vNodes);
1123  vNodesCopy = vNodes;
1124  BOOST_FOREACH(CNode* pnode, vNodesCopy)
1125  pnode->AddRef();
1126  }
1127  BOOST_FOREACH(CNode* pnode, vNodesCopy)
1128  {
1129  boost::this_thread::interruption_point();
1130 
1131  //
1132  // Receive
1133  //
1134  if (pnode->hSocket == INVALID_SOCKET)
1135  continue;
1136  if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
1137  {
1138  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1139  if (lockRecv)
1140  {
1141  {
1142  // typical socket buffer is 8K-64K
1143  char pchBuf[0x10000];
1144  int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1145  if (nBytes > 0)
1146  {
1147  if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
1148  pnode->CloseSocketDisconnect();
1149  pnode->nLastRecv = GetTime();
1150  pnode->nRecvBytes += nBytes;
1151  pnode->RecordBytesRecv(nBytes);
1152  }
1153  else if (nBytes == 0)
1154  {
1155  // socket closed gracefully
1156  if (!pnode->fDisconnect)
1157  LogPrint("net", "socket closed\n");
1158  pnode->CloseSocketDisconnect();
1159  }
1160  else if (nBytes < 0)
1161  {
1162  // error
1163  int nErr = WSAGetLastError();
1164  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1165  {
1166  if (!pnode->fDisconnect)
1167  LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1168  pnode->CloseSocketDisconnect();
1169  }
1170  }
1171  }
1172  }
1173  }
1174 
1175  //
1176  // Send
1177  //
1178  if (pnode->hSocket == INVALID_SOCKET)
1179  continue;
1180  if (FD_ISSET(pnode->hSocket, &fdsetSend))
1181  {
1182  TRY_LOCK(pnode->cs_vSend, lockSend);
1183  if (lockSend)
1184  SocketSendData(pnode);
1185  }
1186 
1187  //
1188  // Inactivity checking
1189  //
1190  int64_t nTime = GetTime();
1191  if (nTime - pnode->nTimeConnected > 60)
1192  {
1193  if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1194  {
1195  LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1196  pnode->fDisconnect = true;
1197  }
1198  else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1199  {
1200  LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1201  pnode->fDisconnect = true;
1202  }
1203  else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1204  {
1205  LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1206  pnode->fDisconnect = true;
1207  }
1208  else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
1209  {
1210  LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1211  pnode->fDisconnect = true;
1212  }
1213  }
1214  }
1215  {
1216  LOCK(cs_vNodes);
1217  BOOST_FOREACH(CNode* pnode, vNodesCopy)
1218  pnode->Release();
1219  }
1220  }
1221 }
1222 
1223 
1224 #ifdef USE_UPNP
1225 void ThreadMapPort()
1226 {
1227  std::string port = strprintf("%u", GetListenPort());
1228  const char * multicastif = 0;
1229  const char * minissdpdpath = 0;
1230  struct UPNPDev * devlist = 0;
1231  char lanaddr[64];
1232 
1233 #ifndef UPNPDISCOVER_SUCCESS
1234  /* miniupnpc 1.5 */
1235  devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1236 #else
1237  /* miniupnpc 1.6 */
1238  int error = 0;
1239  devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1240 #endif
1241 
1242  struct UPNPUrls urls;
1243  struct IGDdatas data;
1244  int r;
1245 
1246  r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1247  if (r == 1)
1248  {
1249  if (fDiscover) {
1250  char externalIPAddress[40];
1251  r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1252  if(r != UPNPCOMMAND_SUCCESS)
1253  LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1254  else
1255  {
1256  if(externalIPAddress[0])
1257  {
1258  LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1259  AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1260  }
1261  else
1262  LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1263  }
1264  }
1265 
1266  string strDesc = "Anoncoin " + FormatFullVersion();
1267 
1268  try {
1269  while (true) {
1270 #ifndef UPNPDISCOVER_SUCCESS
1271  /* miniupnpc 1.5 */
1272  r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1273  port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1274 #else
1275  /* miniupnpc 1.6 */
1276  r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1277  port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1278 #endif
1279 
1280  if(r!=UPNPCOMMAND_SUCCESS)
1281  LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1282  port, port, lanaddr, r, strupnperror(r));
1283  else
1284  LogPrintf("UPnP Port Mapping successful.\n");;
1285 
1286  MilliSleep(20*60*1000); // Refresh every 20 minutes
1287  }
1288  }
1289  catch (boost::thread_interrupted)
1290  {
1291  r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1292  LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
1293  freeUPNPDevlist(devlist); devlist = 0;
1294  FreeUPNPUrls(&urls);
1295  throw;
1296  }
1297  } else {
1298  LogPrintf("No valid UPnP IGDs found\n");
1299  freeUPNPDevlist(devlist); devlist = 0;
1300  if (r != 0)
1301  FreeUPNPUrls(&urls);
1302  }
1303 }
1304 
1305 void MapPort(bool fUseUPnP)
1306 {
1307  static boost::thread* upnp_thread = NULL;
1308 
1309  if (fUseUPnP)
1310  {
1311  if (upnp_thread) {
1312  upnp_thread->interrupt();
1313  upnp_thread->join();
1314  delete upnp_thread;
1315  }
1316  upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1317  }
1318  else if (upnp_thread) {
1319  upnp_thread->interrupt();
1320  upnp_thread->join();
1321  delete upnp_thread;
1322  upnp_thread = NULL;
1323  }
1324 }
1325 
1326 #else
1327 void MapPort(bool)
1328 {
1329  // Intentionally left blank.
1330 }
1331 #endif
1332 
1333 
1338 {
1339  // goal: only query DNS seeds if address need is acute
1340  if ((addrman.size() > 0) &&
1341  (!GetBoolArg("-forcednsseed", false))) {
1342  MilliSleep(11 * 1000);
1343 
1344  LOCK(cs_vNodes);
1345  if (vNodes.size() >= 2) {
1346  LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1347  return;
1348  }
1349  }
1350 
1351  int found = 0;
1352  LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1353 // LogPrintf("DNS seeds temporary disabled\n");
1354 // return;
1355 
1356 #ifdef ENABLE_I2PSAM
1357  // If I2P is enabled, we need to process those too...
1358  if( IsI2PEnabled() ) {
1359  LogPrintf("I2P DNS seed addresses...preferred\n");
1360  const vector<CDNSSeedData> &i2pvSeeds = Params().i2pDNSSeeds();
1361  BOOST_FOREACH(const CDNSSeedData &seed, i2pvSeeds) {
1362 // if (HaveNameProxy()) {
1363 // AddOneShot(seed.host);
1364 // } else {
1365  vector<CNetAddr> vaddr;
1366  vector<CAddress> vAdd;
1367  if (LookupHost(seed.host.c_str(), vaddr)) {
1368  assert( vaddr.size() == 1 ); // All this could ever be from what I could tell looking down into the lookup process
1369  CNetAddr& ip = vaddr[0]; // Need to clean up the variable use here, if this is finalized code
1370 // BOOST_FOREACH(CNetAddr& ip, vaddr) {
1371  int nOneDay = 24*3600;
1372  CAddress addr = CAddress(CService(ip, 0));
1373  addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1374  vAdd.push_back(addr);
1375  found++;
1376 // }
1377  // Lookup is very time expensive over I2P, (and satellite).
1378  // Handle it differently here, with that in mind.
1379  // Only add it if Lookup works, we don't need to again.
1380  // Also set the flag AllowLookup false, otherwise I2PSAM goes through the same process all over again in a few millisecs, because it was true.
1381  addrman.Add(vAdd, CNetAddr(seed.name, false));
1382  }
1383 // addrman.Add(vAdd, CNetAddr(seed.name, true));
1384 // }
1385  }
1386  }
1387  // If we are I2P only, clearnet seeds will do us no good, so no point in loading them.
1388  if( IsI2POnly() ) // Do what we normally would do on clearnet
1389  LogPrintf("Skipping Clearnet DNS seeds, Running I2P net only.\n");
1390  else
1391 #endif
1392  {
1393  const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1394  LogPrintf("Loading clearnet DNS seed addresses...\n");
1395  BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1396  if (HaveNameProxy()) {
1397  AddOneShot(seed.host);
1398  } else {
1399  vector<CNetAddr> vIPs;
1400  vector<CAddress> vAdd;
1401  if (LookupHost(seed.host.c_str(), vIPs))
1402  {
1403  BOOST_FOREACH(CNetAddr& ip, vIPs)
1404  {
1405  int nOneDay = 24*3600;
1406  CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1407  addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1408  vAdd.push_back(addr);
1409  found++;
1410  }
1411  }
1412  addrman.Add(vAdd, CNetAddr(seed.name, true));
1413  }
1414  }
1415  }
1416 
1417  LogPrintf("%d addresses found from DNS seeds\n", found);
1418 }
1419 
1420 
1422 {
1423  int64_t nStart = GetTimeMillis();
1424 
1425  CAddrDB adb;
1426  adb.Write(addrman);
1427 
1428  LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1429  addrman.size(), GetTimeMillis() - nStart);
1430 }
1431 
1432 void static ProcessOneShot()
1433 {
1434  string strDest;
1435  {
1436  LOCK(cs_vOneShots);
1437  if (vOneShots.empty())
1438  return;
1439  strDest = vOneShots.front();
1440  vOneShots.pop_front();
1441  }
1442  CAddress addr;
1443  CSemaphoreGrant grant(*semOutbound, true);
1444  if (grant) {
1445  if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1446  AddOneShot(strDest);
1447  }
1448 }
1449 
1451 {
1452  // Connect to specific addresses
1453  if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1454  {
1455  for (int64_t nLoop = 0;; nLoop++)
1456  {
1457  ProcessOneShot();
1458  BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1459  {
1460  CAddress addr;
1461  OpenNetworkConnection(addr, NULL, strAddr.c_str());
1462  for (int i = 0; i < 10 && i < nLoop; i++)
1463  {
1464  MilliSleep(500);
1465  }
1466  }
1467  MilliSleep(500);
1468  }
1469  }
1470 
1471  // Initiate network connections
1472  int64_t nStart = GetTime();
1473  while (true)
1474  {
1475  ProcessOneShot();
1476 
1477  MilliSleep(500);
1478 
1479  CSemaphoreGrant grant(*semOutbound);
1480  boost::this_thread::interruption_point();
1481 
1482  // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1483  if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1484  static bool done = false;
1485  if (!done) {
1486  LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1487  addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
1488  done = true;
1489  }
1490  }
1491  // Note on I2P seed nodes: They are stored now in Chainparams, and loaded based on what Network we are running.
1492  // No special code needs to be introduced here, as was the case in 0.8.5.6 builds.
1493 
1494  //
1495  // Choose an address to connect to based on most recently seen
1496  //
1497  CAddress addrConnect;
1498 
1499  // Only connect out to one peer per network group (/16 for IPv4).
1500  // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1501  int nOutbound = 0;
1502  set<vector<unsigned char> > setConnected;
1503  {
1504  LOCK(cs_vNodes);
1505  BOOST_FOREACH(CNode* pnode, vNodes) {
1506  if (!pnode->fInbound) {
1507  setConnected.insert(pnode->addr.GetGroup());
1508  nOutbound++;
1509  }
1510  }
1511  }
1512 
1513  int64_t nANow = GetAdjustedTime();
1514 
1515  int nTries = 0;
1516  while (true)
1517  {
1518  // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1519  CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1520 
1521  // if we selected an invalid address, restart
1522  if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1523  break;
1524 
1525  // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1526  // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1527  // already-connected network ranges, ...) before trying new addrman addresses.
1528  nTries++;
1529  if (nTries > 100)
1530  break;
1531 
1532  if (IsLimited(addr))
1533  continue;
1534 
1535  // only consider very recently tried nodes after 30 failed attempts
1536  if (nANow - addr.nLastTry < 600 && nTries < 30)
1537  continue;
1538 
1539  if(
1540 #ifdef ENABLE_I2PSAM
1541  !addr.IsNativeI2P() &&
1542 #endif
1543  // do not allow non-default ports, unless after 50 invalid addresses selected already
1544  addr.GetPort() != Params().GetDefaultPort() &&
1545  nTries < 50
1546  )
1547  continue;
1548 
1549  addrConnect = addr;
1550  break;
1551  }
1552 
1553  if (addrConnect.IsValid())
1554  OpenNetworkConnection(addrConnect, &grant);
1555  }
1556 }
1557 
1559 {
1560  {
1561  LOCK(cs_vAddedNodes);
1562  vAddedNodes = mapMultiArgs["-addnode"];
1563  }
1564 
1565  if (HaveNameProxy()) {
1566  while(true) {
1567  list<string> lAddresses(0);
1568  {
1569  LOCK(cs_vAddedNodes);
1570  BOOST_FOREACH(string& strAddNode, vAddedNodes)
1571  lAddresses.push_back(strAddNode);
1572  }
1573  BOOST_FOREACH(string& strAddNode, lAddresses) {
1574  CAddress addr;
1575  CSemaphoreGrant grant(*semOutbound);
1576  OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1577  MilliSleep(500);
1578  }
1579  MilliSleep(120000); // Retry every 2 minutes
1580  }
1581  }
1582 
1583  for (unsigned int i = 0; true; i++)
1584  {
1585  list<string> lAddresses(0);
1586  {
1587  LOCK(cs_vAddedNodes);
1588  BOOST_FOREACH(string& strAddNode, vAddedNodes)
1589  lAddresses.push_back(strAddNode);
1590  }
1591 
1592  list<vector<CService> > lservAddressesToAdd(0);
1593  BOOST_FOREACH(string& strAddNode, lAddresses)
1594  {
1595  vector<CService> vservNode(0);
1596  if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1597  {
1598  lservAddressesToAdd.push_back(vservNode);
1599  {
1600  LOCK(cs_setservAddNodeAddresses);
1601  BOOST_FOREACH(CService& serv, vservNode)
1602  setservAddNodeAddresses.insert(serv);
1603  }
1604  }
1605  }
1606  // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1607  // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1608  {
1609  LOCK(cs_vNodes);
1610  BOOST_FOREACH(CNode* pnode, vNodes)
1611  for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1612  BOOST_FOREACH(CService& addrNode, *(it))
1613  if (pnode->addr == addrNode)
1614  {
1615  it = lservAddressesToAdd.erase(it);
1616  it--;
1617  break;
1618  }
1619  }
1620  BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1621  {
1622  CSemaphoreGrant grant(*semOutbound);
1623  OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1624  MilliSleep(500);
1625  }
1626  MilliSleep(120000); // Retry every 2 minutes
1627  }
1628 }
1629 
1630 // if successful, this moves the passed grant to the constructed node
1631 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1632 {
1633  //
1634  // Initiate outbound network connection
1635  //
1636  boost::this_thread::interruption_point();
1637  if (!strDest)
1638  if (IsLocal(addrConnect) ||
1639  FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1640  FindNode(addrConnect.ToStringIPPort().c_str()))
1641  return false;
1642  if (strDest && FindNode(strDest))
1643  return false;
1644 
1645  CNode* pnode = ConnectNode(addrConnect, strDest);
1646  boost::this_thread::interruption_point();
1647 
1648  if (!pnode)
1649  return false;
1650  if (grantOutbound)
1651  grantOutbound->MoveTo(pnode->grantOutbound);
1652  pnode->fNetworkNode = true;
1653  if (fOneShot)
1654  pnode->fOneShot = true;
1655 
1656  return true;
1657 }
1658 
1659 
1660 // for now, use a very simple selection metric: the node from which we received
1661 // most recently
1662 static int64_t NodeSyncScore(const CNode *pnode) {
1663  return pnode->nLastRecv;
1664 }
1665 
1666 void static StartSync(const vector<CNode*> &vNodes) {
1667  CNode *pnodeNewSync = NULL;
1668  int64_t nBestScore = 0;
1669 
1670  int nBestHeight = g_signals.GetHeight().get_value_or(0);
1671 
1672  // Iterate over all nodes
1673  BOOST_FOREACH(CNode* pnode, vNodes) {
1674  // check preconditions for allowing a sync
1675  if (!pnode->fClient && !pnode->fOneShot &&
1676  !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1677  (pnode->nStartingHeight > (nBestHeight - 144)) &&
1678  (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1679  // if ok, compare node's score with the best so far
1680  int64_t nScore = NodeSyncScore(pnode);
1681  if (pnodeNewSync == NULL || nScore > nBestScore) {
1682  pnodeNewSync = pnode;
1683  nBestScore = nScore;
1684  }
1685  }
1686  }
1687  // if a new sync candidate was found, start sync!
1688  if (pnodeNewSync) {
1689  pnodeNewSync->fStartSync = true;
1690  pnodeSync = pnodeNewSync;
1691  }
1692 }
1693 
1695 {
1697  while (true)
1698  {
1699  bool fHaveSyncNode = false;
1700 
1701  vector<CNode*> vNodesCopy;
1702  {
1703  LOCK(cs_vNodes);
1704  vNodesCopy = vNodes;
1705  BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1706  pnode->AddRef();
1707  if (pnode == pnodeSync)
1708  fHaveSyncNode = true;
1709  }
1710  }
1711 
1712  if (!fHaveSyncNode)
1713  StartSync(vNodesCopy);
1714 
1715  // Poll the connected nodes for messages
1716  CNode* pnodeTrickle = NULL;
1717  if (!vNodesCopy.empty())
1718  pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1719 
1720  bool fSleep = true;
1721 
1722  BOOST_FOREACH(CNode* pnode, vNodesCopy)
1723  {
1724  if (pnode->fDisconnect)
1725  continue;
1726 
1727  // Receive messages
1728  {
1729  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1730  if (lockRecv)
1731  {
1732  if (!g_signals.ProcessMessages(pnode))
1733  pnode->CloseSocketDisconnect();
1734 
1735  if (pnode->nSendSize < SendBufferSize())
1736  {
1737  if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1738  {
1739  fSleep = false;
1740  }
1741  }
1742  }
1743  }
1744  boost::this_thread::interruption_point();
1745 
1746  // Send messages
1747  {
1748  TRY_LOCK(pnode->cs_vSend, lockSend);
1749  if (lockSend)
1750  g_signals.SendMessages(pnode, pnode == pnodeTrickle);
1751  }
1752  boost::this_thread::interruption_point();
1753  }
1754 
1755  {
1756  LOCK(cs_vNodes);
1757  BOOST_FOREACH(CNode* pnode, vNodesCopy)
1758  pnode->Release();
1759  }
1760 
1761  if (fSleep)
1762  MilliSleep(100);
1763  }
1764 }
1765 
1766 
1767 bool BindListenPort(const CService &addrBind, string& strError)
1768 {
1769  strError = "";
1770  int nOne = 1;
1771 
1772  // Create socket for listening for incoming connections
1773  struct sockaddr_storage sockaddr;
1774  socklen_t len = sizeof(sockaddr);
1775  if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1776  {
1777  strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString());
1778  LogPrintf("%s\n", strError);
1779  return false;
1780  }
1781 
1782  SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1783  if (hListenSocket == INVALID_SOCKET)
1784  {
1785  strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1786  LogPrintf("%s\n", strError);
1787  return false;
1788  }
1789 
1790 #ifdef SO_NOSIGPIPE
1791  // Different way of disabling SIGPIPE on BSD
1792  setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1793 #endif
1794 
1795 #ifndef WIN32
1796  // Allow binding if the port is still in TIME_WAIT state after
1797  // the program was closed and restarted. Not an issue on windows.
1798  setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1799 #endif
1800 
1801 
1802 #ifdef WIN32
1803  // Set to non-blocking, incoming connections will also inherit this
1804  if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1805 #else
1806  if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1807 #endif
1808  {
1809  strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %s)", NetworkErrorString(WSAGetLastError()));
1810  LogPrintf("%s\n", strError);
1811  return false;
1812  }
1813 
1814  // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1815  // and enable it by default or not. Try to enable it, if possible.
1816  if (addrBind.IsIPv6()) {
1817 #ifdef IPV6_V6ONLY
1818 #ifdef WIN32
1819  setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1820 #else
1821  setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1822 #endif
1823 #endif
1824 #ifdef WIN32
1825  int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1826  int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1827  // this call is allowed to fail
1828  setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1829 #endif
1830  }
1831 
1832  if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1833  {
1834  int nErr = WSAGetLastError();
1835  if (nErr == WSAEADDRINUSE)
1836  strError = strprintf(_("Unable to bind to %s on this computer. Anoncoin Core is probably already running."), addrBind.ToString());
1837  else
1838  strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
1839  LogPrintf("%s\n", strError);
1840  return false;
1841  }
1842  LogPrintf("Bound to %s\n", addrBind.ToString());
1843 
1844  // Listen for incoming connections
1845  if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1846  {
1847  strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1848  LogPrintf("%s\n", strError);
1849  return false;
1850  }
1851 
1852  vhListenSocket.push_back(hListenSocket);
1853 
1854  if (addrBind.IsRoutable() && fDiscover)
1855  AddLocal(addrBind, LOCAL_BIND);
1856 
1857  return true;
1858 }
1859 
1860 
1861 #ifdef ENABLE_I2PSAM
1862 
1865 std::string FormatI2PNativeFullVersion() {
1866  // We need to NOT talk to the SAM module if I2P is unavailable
1867  return IsI2PEnabled() ? I2PSession::Instance().getSAMVersion() : "?.??";
1868 }
1869 
1870 // GR note...doodled for abit on code cleanup, trying to figure out where these best fit into the scheme of I2P implementation upon the 0.9.3 codebase,
1871 // in the end, put them back here in net.cpp for now...the only reason was because of NATIVE_I2P_NET_STRING being defined in netbase.h, which is included
1872 // within our net.h header, where netbase.h is included as a dependency....clear as mud?
1873 bool IsTorOnly() {
1874  bool i2pOnly = false;
1875  const std::vector<std::string>& onlyNets = mapMultiArgs["-onlynet"];
1876  i2pOnly = (onlyNets.size() == 1 && onlyNets[0] == "tor");
1877  return i2pOnly;
1878 }
1879 
1880 bool IsI2POnly()
1881 {
1882  bool i2pOnly = false;
1883  if (mapArgs.count("-onlynet")) {
1884  const std::vector<std::string>& onlyNets = mapMultiArgs["-onlynet"];
1885  i2pOnly = (onlyNets.size() == 1 && onlyNets[0] == NATIVE_I2P_NET_STRING);
1886  }
1887  return i2pOnly;
1888 }
1889 
1890 // If either/or dark net or if we're running a proxy or onion and in either of those cases if i2p is also enabled
1891 bool IsDarknetOnly() {
1892  return IsI2POnly() || IsTorOnly() ||
1893  (((mapArgs.count("-proxy") && mapArgs["-proxy"] != "0") || (mapArgs.count("-onion") && mapArgs["-onion"] != "0")) &&
1894  (mapArgs.count("-i2p.options.enabled") && mapArgs["-i2p.options.enabled"] != "0")
1895  );
1896 }
1897 
1898 // Basically we override the -i2p.options.enabled flag here, if we are running -onlynet=i2p....
1899 bool IsI2PEnabled() {
1900  return GetBoolArg("-i2p.options.enabled", false) || IsI2POnly();
1901 }
1902 
1903 bool IsBehindDarknet() {
1904  return IsDarknetOnly() || (mapArgs.count("-onion") && mapArgs["-onion"] != "0");
1905 }
1906 
1910 bool BindListenNativeI2P()
1911 {
1912  SOCKET hNewI2PListenSocket = INVALID_SOCKET;
1913  if (!BindListenNativeI2P(hNewI2PListenSocket))
1914  return false;
1915  vhI2PListenSocket.push_back(hNewI2PListenSocket);
1916  return true;
1917 }
1918 
1919 bool BindListenNativeI2P(SOCKET& hSocket)
1920 {
1921  hSocket = I2PSession::Instance().accept(false);
1922 
1923  if ( hSocket == INVALID_SOCKET ) return false;
1924  CService addrBind(I2PSession::Instance().getMyDestination().pub, 0);
1925 // ToDo: Check this code carefully. Changed it some so it would work. I2P onlynet means fDiscover(maybe) false. AddLocal needs LOCAL_MANUAL or it will return false and not set
1926 // if (addrBind.IsRoutable() && fDiscover)
1927  // AddLocal(addrBind, LOCAL_BIND);
1928  // return true;
1929  return AddLocal(addrBind, LOCAL_MANUAL);
1930 }
1931 #endif // ENABLE_I2PSAM
1932 
1933 void static Discover(boost::thread_group& threadGroup)
1934 {
1935  if (!fDiscover)
1936  return;
1937 
1938 #ifdef WIN32
1939  // Get local host IP
1940  char pszHostName[1000] = "";
1941  if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1942  {
1943  vector<CNetAddr> vaddr;
1944  if (LookupHost(pszHostName, vaddr))
1945  {
1946  BOOST_FOREACH (const CNetAddr &addr, vaddr)
1947  {
1948  AddLocal(addr, LOCAL_IF);
1949  }
1950  }
1951  }
1952 #else
1953  // Get local host ip
1954  struct ifaddrs* myaddrs;
1955  if (getifaddrs(&myaddrs) == 0)
1956  {
1957  for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1958  {
1959  if (ifa->ifa_addr == NULL) continue;
1960  if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1961  if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1962  if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1963  if (ifa->ifa_addr->sa_family == AF_INET)
1964  {
1965  struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1966  CNetAddr addr(s4->sin_addr);
1967  if (AddLocal(addr, LOCAL_IF))
1968  LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString());
1969  }
1970  else if (ifa->ifa_addr->sa_family == AF_INET6)
1971  {
1972  struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1973  CNetAddr addr(s6->sin6_addr);
1974  if (AddLocal(addr, LOCAL_IF))
1975  LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString());
1976  }
1977  }
1978  freeifaddrs(myaddrs);
1979  }
1980 #endif
1981 
1982  // Don't use external IPv4 discovery, when -onlynet="IPv6"
1983  // This should work fine as well for -onlynet="i2p" or other combinations, if NET_IPV4 is
1984  // not limited at this point, we proceed normally to detect our external IP
1985  if (!IsLimited(NET_IPV4))
1986  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP));
1987 }
1988 
1989 void StartNode(boost::thread_group& threadGroup)
1990 {
1991  uiInterface.InitMessage(_("Loading addresses..."));
1992  // Load addresses for peers.dat
1993  int64_t nStart = GetTimeMillis();
1994  {
1995  CAddrDB adb;
1996  if (!adb.Read(addrman))
1997  LogPrintf("Invalid or missing peers.dat; recreating\n");
1998  }
1999  LogPrintf("Loaded %i addresses from peers.dat %dms\n",
2000  addrman.size(), GetTimeMillis() - nStart);
2001  fAddressesInitialized = true;
2002 
2003  if (semOutbound == NULL) {
2004  // initialize semaphore
2005  int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
2006  semOutbound = new CSemaphore(nMaxOutbound);
2007  }
2008 
2009  if (pnodeLocalHost == NULL)
2010  pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
2011 
2012  Discover(threadGroup);
2013 
2014  //
2015  // Start threads
2016  //
2017 
2018  if (!GetBoolArg("-dnsseed", true))
2019  LogPrintf("DNS seeding disabled\n");
2020  else
2021  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
2022 
2023 #ifdef USE_UPNP
2024  // Map ports with UPnP
2025  MapPort(GetBoolArg("-upnp", USE_UPNP));
2026 #endif
2027 
2028  // Send and receive from sockets, accept connections
2029  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
2030 
2031  // Initiate outbound connections from -addnode
2032  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
2033 
2034  // Initiate outbound connections
2035  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
2036 
2037  // Process messages
2038  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
2039 
2040  // Dump network addresses
2041  threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, DUMP_ADDRESSES_INTERVAL * 1000));
2042 }
2043 
2044 bool StopNode()
2045 {
2046  LogPrintf("StopNode()\n");
2047  MapPort(false);
2048  if (semOutbound)
2049  for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
2050  semOutbound->post();
2051 
2053  {
2054  DumpAddresses();
2055  fAddressesInitialized = false;
2056  }
2057 
2058  return true;
2059 }
2060 
2062 {
2063 public:
2065  {
2066  }
2068  {
2069  // Close sockets
2070  BOOST_FOREACH(CNode* pnode, vNodes)
2071  if (pnode->hSocket != INVALID_SOCKET)
2072  closesocket(pnode->hSocket);
2073  BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
2074  if (hListenSocket != INVALID_SOCKET)
2075  if (closesocket(hListenSocket) == SOCKET_ERROR)
2076  LogPrintf("closesocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2077 #ifdef ENABLE_I2PSAM
2078  BOOST_FOREACH(SOCKET& hI2PListenSocket, vhI2PListenSocket)
2079  if (hI2PListenSocket != INVALID_SOCKET)
2080  if (closesocket(hI2PListenSocket) == SOCKET_ERROR)
2081  LogPrintf("I2P closesocket(hI2PListenSocket) failed with error %d\n", WSAGetLastError());
2082 #endif // ENABLE_I2PSAM
2083 
2084  // clean up some globals (to help leak detection)
2085  BOOST_FOREACH(CNode *pnode, vNodes)
2086  delete pnode;
2087  BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
2088  delete pnode;
2089  vNodes.clear();
2090  vNodesDisconnected.clear();
2091  delete semOutbound;
2092  semOutbound = NULL;
2093  delete pnodeLocalHost;
2094  pnodeLocalHost = NULL;
2095 
2096 #ifdef WIN32
2097  // Shutdown Windows Sockets
2098  WSACleanup();
2099 #endif
2100  }
2101 }
2103 
2104 
2105 
2106 void RelayTransaction(const CTransaction& tx, const uint256& hash)
2107 {
2108  CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
2109  ss.reserve(10000);
2110  ss << tx;
2111  RelayTransaction(tx, hash, ss);
2112 }
2113 
2114 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
2115 {
2116  CInv inv(MSG_TX, hash);
2117  {
2118  LOCK(cs_mapRelay);
2119  // Expire old relay messages
2120  while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
2121  {
2122  mapRelay.erase(vRelayExpiration.front().second);
2123  vRelayExpiration.pop_front();
2124  }
2125 
2126  // Save original serialized message so newer versions are preserved
2127  mapRelay.insert(std::make_pair(inv, ss));
2128  vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
2129  }
2130  LOCK(cs_vNodes);
2131  BOOST_FOREACH(CNode* pnode, vNodes)
2132  {
2133  if(!pnode->fRelayTxes)
2134  continue;
2135  LOCK(pnode->cs_filter);
2136  if (pnode->pfilter)
2137  {
2138  if (pnode->pfilter->IsRelevantAndUpdate(tx, hash))
2139  pnode->PushInventory(inv);
2140  } else
2141  pnode->PushInventory(inv);
2142  }
2143 }
2144 
2145 void CNode::RecordBytesRecv(uint64_t bytes)
2146 {
2147  LOCK(cs_totalBytesRecv);
2148  nTotalBytesRecv += bytes;
2149 }
2150 
2151 void CNode::RecordBytesSent(uint64_t bytes)
2152 {
2153  LOCK(cs_totalBytesSent);
2154  nTotalBytesSent += bytes;
2155 }
2156 
2158 {
2159  LOCK(cs_totalBytesRecv);
2160  return nTotalBytesRecv;
2161 }
2162 
2164 {
2165  LOCK(cs_totalBytesSent);
2166  return nTotalBytesSent;
2167 }
2168 
2169 void CNode::Fuzz(int nChance)
2170 {
2171  if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
2172  if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
2173 
2174  switch (GetRand(3))
2175  {
2176  case 0:
2177  // xor a random byte with a random value:
2178  if (!ssSend.empty()) {
2179  CDataStream::size_type pos = GetRand(ssSend.size());
2180  ssSend[pos] ^= (unsigned char)(GetRand(256));
2181  }
2182  break;
2183  case 1:
2184  // delete a random byte:
2185  if (!ssSend.empty()) {
2186  CDataStream::size_type pos = GetRand(ssSend.size());
2187  ssSend.erase(ssSend.begin()+pos);
2188  }
2189  break;
2190  case 2:
2191  // insert a random byte at a random position
2192  {
2193  CDataStream::size_type pos = GetRand(ssSend.size());
2194  char ch = (char)GetRand(256);
2195  ssSend.insert(ssSend.begin()+pos, ch);
2196  }
2197  break;
2198  }
2199  // Chance of more than one change half the time:
2200  // (more changes exponentially less likely):
2201  Fuzz(2);
2202 }
2203 
2204 //
2205 // CAddrDB
2206 //
2207 
2209 {
2210  pathAddr = GetDataDir() / "peers.dat";
2211 }
2212 
2213 bool CAddrDB::Write(const CAddrMan& addr)
2214 {
2215  // Generate random temporary filename
2216  unsigned short randv = 0;
2217  RAND_bytes((unsigned char *)&randv, sizeof(randv));
2218  std::string tmpfn = strprintf("peers.dat.%04x", randv);
2219 
2220  // serialize addresses, checksum data up to that point, then append csum
2221  CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
2222  ssPeers << FLATDATA(Params().MessageStart());
2223  ssPeers << addr;
2224  uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
2225  ssPeers << hash;
2226 
2227  // open temp output file, and associate with CAutoFile
2228  boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
2229  FILE *file = fopen(pathTmp.string().c_str(), "wb");
2230  CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
2231  if (!fileout)
2232  return error("%s : Failed to open file %s", __func__, pathTmp.string());
2233 
2234  // Write and commit header, data
2235  try {
2236  fileout << ssPeers;
2237  }
2238  catch (std::exception &e) {
2239  return error("%s : Serialize or I/O error - %s", __func__, e.what());
2240  }
2241  FileCommit(fileout);
2242  fileout.fclose();
2243 
2244  // replace existing peers.dat, if any, with new peers.dat.XXXX
2245  if (!RenameOver(pathTmp, pathAddr))
2246  return error("%s : Rename-into-place failed", __func__);
2247 
2248  return true;
2249 }
2250 
2252 {
2253  // open input file, and associate with CAutoFile
2254  FILE *file = fopen(pathAddr.string().c_str(), "rb");
2255  CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
2256  if (!filein)
2257  return error("%s : Failed to open file %s", __func__, pathAddr.string());
2258 
2259  // use file size to size memory buffer
2260  int fileSize = boost::filesystem::file_size(pathAddr);
2261  int dataSize = fileSize - sizeof(uint256);
2262  // Don't try to resize to a negative number if file is small
2263  if (dataSize < 0)
2264  dataSize = 0;
2265  vector<unsigned char> vchData;
2266  vchData.resize(dataSize);
2267  uint256 hashIn;
2268 
2269  // read data and checksum from file
2270  try {
2271  filein.read((char *)&vchData[0], dataSize);
2272  filein >> hashIn;
2273  }
2274  catch (std::exception &e) {
2275  return error("%s : Deserialize or I/O error - %s", __func__, e.what());
2276  }
2277  filein.fclose();
2278 
2279  CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
2280 
2281  // verify stored checksum matches input data
2282  uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
2283  if (hashIn != hashTmp)
2284  return error("%s : Checksum mismatch, data corrupted", __func__);
2285 
2286  unsigned char pchMsgTmp[4];
2287  try {
2288  // de-serialize file header (network specific magic number) and ..
2289  ssPeers >> FLATDATA(pchMsgTmp);
2290 
2291  // ... verify the network matches ours
2292  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2293  return error("%s : Invalid network magic number", __func__);
2294 
2295  // de-serialize address data into one CAddrMan object
2296  ssPeers >> addr;
2297  }
2298  catch (std::exception &e) {
2299  return error("%s : Deserialize or I/O error - %s", __func__, e.what());
2300  }
2301 
2302  return true;
2303 }
2304 
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:968
const vector< CDNSSeedData > & DNSSeeds() const
Definition: chainparams.h:86
CClientUIInterface uiInterface
Definition: util.cpp:100
void SetReachable(enum Network net, bool fFlag)
Definition: net.cpp:218
#define WSAEINPROGRESS
Definition: compat.h:56
uint64_t GetRand(uint64_t nMax)
Definition: util.cpp:186
void Attempt(const CService &addr, int64_t nTime=GetAdjustedTime())
Definition: addrman.h:456
CNodeSignals & GetNodeSignals()
Definition: net.cpp:97
static uint64_t GetTotalBytesRecv()
Definition: net.cpp:2157
void MoveTo(CSemaphoreGrant &grant)
Definition: sync.h:236
Access to the (IP) address database (peers.dat)
Definition: net.h:778
#define WSAEINTR
Definition: compat.h:55
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
Definition: net.cpp:111
void AddOneShot(string strDest)
Definition: net.cpp:99
uint64_t nServices
Definition: protocol.h:118
unsigned short GetPort() const
Definition: netbase.cpp:1216
bool fDisconnect
Definition: net.h:259
CCriticalSection cs_filter
Definition: net.h:266
#define NATIVE_I2P_NET_STRING
Definition: i2pwrapper.h:15
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:227
std::string addrName
Definition: net.h:246
const_iterator begin() const
Definition: serialize.h:933
CNode * FindNode(const CNetAddr &ip)
Definition: net.cpp:430
bool fAddressesInitialized
Definition: net.cpp:63
#define TRY_LOCK(cs, name)
Definition: sync.h:159
STL-like map container that only keeps the N elements with the highest value.
Definition: limitedmap.h:13
Definition: init.h:14
void SetIP(const CNetAddr &ip)
Definition: netbase.cpp:613
void FileCommit(FILE *fileout)
Definition: util.cpp:1097
CAddress addr
Definition: net.h:245
void MilliSleep(int64_t n)
Definition: util.h:80
#define strprintf
Definition: tinyformat.h:1011
std::string ToStringIP() const
Definition: netbase.cpp:882
static void ClearBanned()
Definition: net.cpp:563
bool GetMyExternalIP(CNetAddr &ipRet)
Definition: net.cpp:363
Definition: net.h:95
#define WSAEADDRINUSE
Definition: compat.h:57
CAddrDB()
Definition: net.cpp:2208
inv message data
Definition: protocol.h:128
vector_type::size_type size_type
Definition: serialize.h:861
static SAM::StreamSessionAdapter & Instance()
Definition: i2pwrapper.h:68
#define closesocket(s)
Definition: compat.h:75
#define USE_UPNP
void ThreadOpenConnections()
Definition: net.cpp:1450
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
Definition: net.cpp:262
RAII-style semaphore lock.
Definition: sync.h:209
int nMaxConnections
Definition: net.cpp:62
u_int SOCKET
Definition: compat.h:48
bool fDiscover
Specific functions we need to implement I2P functionality.
Definition: net.cpp:52
limitedmap< CInv, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
bool ConnectSocketByName(CService &addr, SOCKET &hSocketRet, const char *pszDest, int portDefault, int nTimeout)
Definition: netbase.cpp:573
Definition: net.h:97
Double ended buffer combining vector and stream-like interfaces.
Definition: serialize.h:848
void ThreadDNSAddressSeed()
Process DNS seed data from chainparams.
Definition: net.cpp:1337
unsigned short GetListenPort()
Definition: net.cpp:105
CCriticalSection cs_inventory
Definition: net.h:296
bool SeenLocal(const CService &addr)
vote for a local address
Definition: net.cpp:282
SAM::SOCKET accept(bool silent)
Definition: i2pwrapper.cpp:94
#define INVALID_SOCKET
Definition: compat.h:59
void Cleanup()
Definition: net.cpp:537
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
Definition: util.cpp:1069
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Definition: addrman.h:414
bool IsIPv6() const
Definition: netbase.cpp:706
CAddrMan addrman
Definition: net.cpp:61
int64_t nPingUsecStart
Definition: net.h:303
vector< std::string > vAddedNodes
Definition: net.cpp:87
bool in_data
Definition: net.h:185
#define WSAGetLastError()
Definition: compat.h:50
static void RecordBytesRecv(uint64_t bytes)
Definition: net.cpp:2145
#define FLATDATA(obj)
Definition: serialize.h:318
void PushInventory(const CInv &inv)
Definition: net.h:473
bool fSyncNode
Definition: net.h:174
bool RecvLine(SOCKET hSocket, string &strLine)
Definition: net.cpp:149
std::deque< CInv > vRecvGetData
Definition: net.h:236
void MapPort(bool)
Definition: net.cpp:1327
vector< CNode * > vNodes
Definition: net.cpp:74
void ThreadSocketHandler()
Main Thread that handling socket's & their housekeeping...
Definition: net.cpp:810
Stochastical (IP) address manager.
Definition: addrman.h:167
CCriticalSection cs_nLastNodeId
Definition: net.cpp:91
const std::string & getSAMVersion() const
Definition: i2pwrapper.cpp:170
int64_t nLastRecv
Definition: net.h:243
bool HaveNameProxy()
Definition: netbase.cpp:501
CCriticalSection cs_vOneShots
Definition: net.cpp:82
std::deque< CNetMessage > vRecvMsg
Definition: net.h:237
uint64_t nLocalHostNonce
Definition: net.cpp:59
#define SOCKET_ERROR
Definition: compat.h:60
unsigned int GetTotalRecvSize()
Definition: net.h:418
int nStartingHeight
Definition: net.h:284
bool fClient
Definition: net.h:255
void CloseSocketDisconnect()
Definition: net.cpp:517
bool fNoListen
Definition: util.cpp:97
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:520
#define LogPrintf(...)
Definition: util.h:118
int64_t GetAdjustedTime()
Definition: util.cpp:1241
bool Write(const CAddrMan &addr)
Definition: net.cpp:2213
void Release()
Definition: net.h:443
NodeId nLastNodeId
Definition: net.cpp:90
string host
Definition: chainparams.h:36
bool fInbound
Definition: net.h:256
int GetDefaultPort() const
Definition: chainparams.h:79
bool IsValid() const
Definition: netbase.cpp:816
bool fOneShot
Definition: net.h:254
static uint64_t nTotalBytesRecv
Definition: net.h:382
void AddressCurrentlyConnected(const CService &addr)
Definition: net.cpp:417
void Fuzz(int nChance)
Definition: net.cpp:2169
unsigned int ReceiveFloodSize()
Definition: net.h:54
#define LOCK(cs)
Definition: sync.h:157
void ThreadMessageHandler()
Definition: net.cpp:1694
CCriticalSection cs_mapLocalHost
Definition: net.cpp:53
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netbase.h:109
std::vector< char, zero_after_free_allocator< char > > CSerializeData
Definition: serialize.h:841
void TraceThread(const char *name, Callable func)
Definition: util.h:543
bool IsProxy(const CNetAddr &addr)
Definition: netbase.cpp:506
#define THREAD_PRIORITY_BELOW_NORMAL
Definition: util.h:484
#define NATIVE_I2P_DESTINATION_SIZE
Definition: i2pwrapper.h:13
static CCriticalSection cs_totalBytesRecv
Definition: net.h:380
int64_t nLastTry
Definition: protocol.h:124
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes)
Definition: net.cpp:633
uint64_t nSendBytes
Definition: net.h:232
CCriticalSection cs_setservAddNodeAddresses
Definition: net.cpp:85
A CService with information about it as peer.
Definition: protocol.h:91
unsigned int SendBufferSize()
Definition: net.h:55
void DumpAddresses()
Definition: net.cpp:1421
int64_t nLastSend
Definition: net.h:242
void Release()
Definition: sync.h:223
bool ConnectSocket(const CService &addrDest, SOCKET &hSocketRet, int nTimeout)
Definition: netbase.cpp:541
void RelayTransaction(const CTransaction &tx, const uint256 &hash)
Definition: net.cpp:2106
double dPingTime
Definition: net.h:175
bool fSuccessfullyConnected
Definition: net.h:258
std::string ToString() const
Definition: netbase.cpp:1325
CNetCleanup()
Definition: net.cpp:2064
bool OpenNetworkConnection(const CAddress &addrConnect, CSemaphoreGrant *grantOutbound=NULL, const char *strDest=NULL, bool fOneShot=false)
Definition: net.cpp:1631
uint256 Hash(const T1 pbegin, const T1 pend)
Definition: hash.h:20
#define MSG_NOSIGNAL
Definition: util.h:77
int64_t GetTimeMillis()
Definition: util.h:304
int64_t GetTimeMicros()
Definition: util.h:310
uint64_t nRecvBytes
Definition: net.h:239
size_t nSendOffset
Definition: net.h:231
const std::string CLIENT_NAME
static uint64_t GetTotalBytesSent()
Definition: net.cpp:2163
boost::signals2::signal< bool(CNode *, bool)> SendMessages
Definition: net.h:82
static CCriticalSection cs_totalBytesSent
Definition: net.h:381
int64_t GetTime()
Definition: util.cpp:1220
bool IsRoutable() const
Definition: netbase.cpp:855
size_t nSendSize
Definition: net.h:230
map< CNetAddr, LocalServiceInfo > mapLocalHost
Definition: net.cpp:54
CNode * ConnectNode(CAddress addrConnect, const char *pszDest)
Definition: net.cpp:457
#define DUMP_ADDRESSES_INTERVAL
Definition: net.cpp:35
void PushVersion()
Definition: net.cpp:542
#define WSAEWOULDBLOCK
Definition: compat.h:53
std::string FormatFullVersion()
boost::signals2::signal< bool(CNode *)> ProcessMessages
Definition: net.h:81
int readData(const char *pch, unsigned int nBytes)
Definition: net.cpp:693
CCriticalSection cs_vAddedNodes
Definition: net.cpp:88
void ThreadGetMyExternalIP()
Definition: net.cpp:403
bool fStartSync
Definition: net.h:285
void SetThreadPriority(int nPriority)
Definition: util.h:488
Network
Definition: netbase.h:29
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: ui_interface.h:93
std::vector< unsigned char > GetGroup() const
Definition: netbase.cpp:959
uint64_t nLocalServices
Definition: net.cpp:71
boost::signals2::signal< int()> GetHeight
Definition: net.h:80
void SocketSendData(CNode *pnode)
Definition: net.cpp:713
#define X(name)
Definition: net.cpp:595
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netbase.h:45
static void RecordBytesSent(uint64_t bytes)
Definition: net.cpp:2151
int size()
Definition: addrman.h:395
CService addrLocal
Definition: net.h:247
256-bit unsigned integer
Definition: uint256.h:532
~CNetCleanup()
Definition: net.cpp:2067
unsigned int nTime
Definition: protocol.h:121
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
Definition: net.cpp:304
int nScore
Definition: net.h:152
bool BindListenPort(const CService &addrBind, string &strError)
Definition: net.cpp:1767
CCriticalSection cs_mapRelay
Definition: net.cpp:78
bool IsRelevantAndUpdate(const CTransaction &tx, const uint256 &hash)
Definition: bloom.cpp:103
CCriticalSection cs_vRecvMsg
Definition: net.h:238
void reserve(size_type n)
Definition: serialize.h:940
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
Definition: net.h:265
void * memcpy(void *a, const void *b, size_t c)
string name
Definition: chainparams.h:36
#define ENABLE_I2PSAM
static bool IsBanned(CNetAddr ip)
Definition: net.cpp:568
std::string addrLocal
Definition: net.h:177
int NodeId
Definition: net.h:75
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: ui_interface.h:125
bool StopNode()
Definition: net.cpp:2044
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:225
std::string FormatSubVersion(const std::string &name, int nClientVersion, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip...
static CCriticalSection cs_setBanned
Definition: net.h:275
CAddress Select(int nUnkBias=50)
Definition: addrman.h:468
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
Definition: net.cpp:136
static bool Ban(const CNetAddr &ip)
Definition: net.cpp:584
Definition: net.h:96
SOCKET hSocket
Definition: net.h:228
bool fRelayTxes
Definition: net.h:264
bool SetSpecial(const std::string &strName)
Returns TRUE if the address name can be looked up and resolved.
Definition: netbase.cpp:626
class CNetCleanup instance_of_cnetcleanup
int readHeader(const char *pch, unsigned int nBytes)
Definition: net.cpp:661
int nVersion
Definition: net.h:248
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:506
bool GetMyExternalIP2(const CService &addrConnect, const char *pszGet, const char *pszKeyword, CNetAddr &ipRet)
Definition: net.cpp:317
uint64_t nPingNonceSent
Definition: net.h:301
int64_t nTimeConnected
Definition: net.h:244
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: netbase.cpp:1357
#define WSAEMSGSIZE
Definition: compat.h:54
deque< pair< int64_t, CInv > > vRelayExpiration
Definition: net.cpp:77
CBloomFilter * pfilter
Definition: net.h:267
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: core.h:179
Definition: net.h:94
bool fNetworkNode
Definition: net.h:257
Information about a peer.
Definition: net.h:223
bool LookupHost(const char *pszName, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Definition: netbase.cpp:207
set< CNetAddr > setservAddNodeAddresses
Definition: net.cpp:84
void post()
Definition: sync.h:199
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netbase.cpp:1170
CCriticalSection cs_vSend
Definition: net.h:234
static uint64_t nTotalBytesSent
Definition: net.h:383
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Definition: addrman.h:494
void copyStats(CNodeStats &stats)
Definition: net.cpp:596
map< string, vector< string > > mapMultiArgs
Definition: util.cpp:90
CNode * AddRef()
Definition: net.h:437
double dPingWait
Definition: net.h:176
void LoopForever(const char *name, Callable func, int64_t msecs)
Definition: util.h:515
void ThreadOpenAddedConnections()
Definition: net.cpp:1558
CCriticalSection cs_vNodes
Definition: net.cpp:75
bool Read(CAddrMan &addr)
Definition: net.cpp:2251
bool fNameLookup
Definition: netbase.cpp:48
static std::map< CNetAddr, int64_t > setBanned
Definition: net.h:274
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Definition: netbase.cpp:1248
int GetRefCount()
Definition: net.h:411
RAII wrapper for FILE*.
Definition: serialize.h:1154
bool IsLimited(enum Network net)
Definition: net.cpp:270
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: ui_interface.h:84
void StartNode(boost::thread_group &threadGroup)
Definition: net.cpp:1989
map< string, string > mapArgs
Definition: util.cpp:89
NodeId nodeid
Definition: net.h:162
map< CInv, CDataStream > mapRelay
Definition: net.cpp:76
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:297
bool empty() const
Definition: serialize.h:938
std::deque< CSerializeData > vSendMsg
Definition: net.h:233
const_iterator end() const
Definition: serialize.h:935
void PushAddress(const CAddress &addr)
Definition: net.h:455
CDataStream ssSend
Definition: net.h:229
enum Network GetNetwork() const
Definition: netbase.cpp:864