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