PRCYCoin  2.0.0.7rc1
P2P Digital Currency
net.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin developers
3 // Copyright (c) 2014-2015 The Dash developers
4 // Copyright (c) 2015-2018 The PIVX developers
5 // Copyright (c) 2018-2020 The DAPS Project developers
6 // Distributed under the MIT/X11 software license, see the accompanying
7 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
8 
9 #if defined(HAVE_CONFIG_H)
10 #include "config/prcycoin-config.h"
11 #endif
12 
13 #include "net.h"
14 
15 #include "addrman.h"
16 #include "chainparams.h"
17 #include "clientversion.h"
18 #include "crypto/common.h"
19 #include "guiinterface.h"
20 #include "main.h"
21 #include "primitives/transaction.h"
22 #include "netbase.h"
23 #include "scheduler.h"
24 
25 #ifdef WIN32
26 #include <string.h>
27 #else
28 
29 #include <fcntl.h>
30 
31 #endif
32 
33 #ifdef USE_UPNP
34 #include <miniupnpc/miniupnpc.h>
35 #include <miniupnpc/upnpcommands.h>
36 #include <miniupnpc/upnperrors.h>
37 #endif
38 
39 #include <boost/thread.hpp>
40 
41 #include <math.h>
42 
43 // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
44 #define DUMP_ADDRESSES_INTERVAL 900
45 
46 // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
47 #define FEELER_SLEEP_WINDOW 1
48 
49 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
50 #define MSG_NOSIGNAL 0
51 #endif
52 
53 namespace {
54  const int MAX_OUTBOUND_CONNECTIONS = 16;
55  const int MAX_FEELER_CONNECTIONS = 1;
56 
57  struct ListenSocket {
58  SOCKET socket;
59  bool whitelisted;
60 
61  ListenSocket(SOCKET socket, bool whitelisted) : socket(socket), whitelisted(whitelisted) {}
62  };
63 }
64 
66 static const ServiceFlags nRelevantServices = NODE_NETWORK;
67 
68 //
69 // Global state variables
70 //
71 bool fDiscover = true;
72 bool fListen = true;
75 std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
76 static bool vfLimited[NET_MAX] = {};
77 static CNode *pnodeLocalHost = NULL;
78 uint64_t nLocalHostNonce = 0;
79 static std::vector <ListenSocket> vhListenSocket;
81 int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
82 bool fAddressesInitialized = false;
83 std::string strSubVersion;
84 
85 std::vector<CNode*> vNodes;
87 std::map<CInv, CDataStream> mapRelay;
88 std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
91 
92 static std::deque<std::string> vOneShots;
94 
95 std::vector<std::string> vAddedNodes;
97 
100 
101 static CSemaphore *semOutbound = NULL;
102 boost::condition_variable messageHandlerCondition;
103 
104 // Signals for message handling
105 static CNodeSignals g_signals;
106 
107 CNodeSignals &GetNodeSignals() { return g_signals; }
108 
109 void AddOneShot(std::string strDest) {
111  vOneShots.push_back(strDest);
112 }
113 
114 unsigned short GetListenPort() {
115  return (unsigned short) (GetArg("-port", Params().GetDefaultPort()));
116 }
117 
118 // find 'best' local address for a particular peer
119 bool GetLocal(CService &addr, const CNetAddr *paddrPeer) {
120  if (!fListen)
121  return false;
122 
123  int nBestScore = -1;
124  int nBestReachability = -1;
125  {
127  for (std::map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++) {
128  int nScore = (*it).second.nScore;
129  int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
130  if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
131  addr = CService((*it).first, (*it).second.nPort);
132  nBestReachability = nReachability;
133  nBestScore = nScore;
134  }
135  }
136  }
137  return nBestScore >= 0;
138 }
139 
141 static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6>& vSeedsIn)
142 {
143  // It'll only connect to one or two seed nodes because once it connects,
144  // it'll get a pile of addresses with newer timestamps.
145  // Seed nodes are given a random 'last seen time' of between one and two
146  // weeks ago.
147  const int64_t nOneWeek = 7 * 24 * 60 * 60;
148  std::vector<CAddress> vSeedsOut;
149  vSeedsOut.reserve(vSeedsIn.size());
150  for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i) {
151  struct in6_addr ip;
152  memcpy(&ip, i->addr, sizeof(ip));
153  CAddress addr(CService(ip, i->port), NODE_NETWORK);
154  addr.nTime = GetTime() - GetRand(nOneWeek) - nOneWeek;
155  vSeedsOut.push_back(addr);
156  }
157  return vSeedsOut;
158 }
159 
160 // get best local address for a particular peer as a CAddress
161 // Otherwise, return the unroutable 0.0.0.0 but filled in with
162 // the normal parameters, since the IP may be changed to a useful
163 // one by discovery.
164 CAddress GetLocalAddress(const CNetAddr *paddrPeer) {
166  CService addr;
167  if (GetLocal(addr, paddrPeer)) {
168  ret = CAddress(addr, nLocalServices);
169  }
170  ret.nTime = GetAdjustedTime();
171  return ret;
172 }
173 
174 int GetnScore(const CService &addr) {
176  if (mapLocalHost.count(addr) == LOCAL_NONE)
177  return 0;
178  return mapLocalHost[addr].nScore;
179 }
180 
181 // Is our peer's addrLocal potentially useful as an external IP source?
183  return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
184  !IsLimited(pnode->addrLocal.GetNetwork());
185 }
186 
187 // pushes our own address to a peer
188 void AdvertiseLocal(CNode* pnode)
189 {
190  if (fListen && pnode->fSuccessfullyConnected) {
191  CAddress addrLocal = GetLocalAddress(&pnode->addr);
192  // If discovery is enabled, sometimes give our peer the address it
193  // tells us that it sees us as in case it has a better idea of our
194  // address than we do.
195  if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
196  GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8 : 2) == 0)) {
197  addrLocal.SetIP(pnode->addrLocal);
198  }
199  if (addrLocal.IsRoutable()) {
200  LogPrintf("%s: advertising address %s\n", __func__, addrLocal.ToString());
201  FastRandomContext insecure_rand;
202  pnode->PushAddress(addrLocal, insecure_rand);
203  }
204  }
205 }
206 
207 // learn a new local address
208 bool AddLocal(const CService &addr, int nScore) {
209  if (!addr.IsRoutable())
210  return false;
211 
212  if (!fDiscover && nScore < LOCAL_MANUAL)
213  return false;
214 
215  if (IsLimited(addr))
216  return false;
217 
218  LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
219 
220  {
222  bool fAlready = mapLocalHost.count(addr) > 0;
223  LocalServiceInfo &info = mapLocalHost[addr];
224  if (!fAlready || nScore >= info.nScore) {
225  info.nScore = nScore + (fAlready ? 1 : 0);
226  info.nPort = addr.GetPort();
227  }
228  }
229 
230  return true;
231 }
232 
233 bool AddLocal(const CNetAddr &addr, int nScore) {
234  return AddLocal(CService(addr, GetListenPort()), nScore);
235 }
236 
237 bool RemoveLocal(const CService &addr) {
239  LogPrintf("RemoveLocal(%s)\n", addr.ToString());
240  mapLocalHost.erase(addr);
241  return true;
242 }
243 
245 void SetLimited(enum Network net, bool fLimited) {
246  if (net == NET_UNROUTABLE)
247  return;
249  vfLimited[net] = fLimited;
250 }
251 
252 bool IsLimited(enum Network net) {
254  return vfLimited[net];
255 }
256 
257 bool IsLimited(const CNetAddr &addr) {
258  return IsLimited(addr.GetNetwork());
259 }
260 
262 bool SeenLocal(const CService &addr) {
263  {
265  if (mapLocalHost.count(addr) == 0)
266  return false;
267  mapLocalHost[addr].nScore++;
268  }
269  return true;
270 }
271 
272 
274 bool IsLocal(const CService &addr) {
276  return mapLocalHost.count(addr) > 0;
277 }
278 
280 bool IsReachable(enum Network net) {
282  return !vfLimited[net];
283 }
284 
286 bool IsReachable(const CNetAddr &addr) {
287  enum Network net = addr.GetNetwork();
288  return IsReachable(net);
289 }
290 
292  addrman.Connected(addr);
293 }
294 
295 
296 uint64_t CNode::nTotalBytesRecv = 0;
297 uint64_t CNode::nTotalBytesSent = 0;
300 
301 CNode *FindNode(const CNetAddr &ip) {
302  LOCK(cs_vNodes);
303  for (CNode * pnode : vNodes)
304  if ((CNetAddr) pnode->addr == ip)
305  return (pnode);
306  return NULL;
307 }
308 
309 CNode *FindNode(const CSubNet &subNet) {
310  LOCK(cs_vNodes);
311  for (CNode * pnode : vNodes)
312  if (subNet.Match((CNetAddr) pnode->addr))
313  return (pnode);
314  return NULL;
315 }
316 
317 CNode *FindNode(const std::string &addrName) {
318  LOCK(cs_vNodes);
319  for (CNode * pnode : vNodes)
320  if (pnode->addrName == addrName)
321  return (pnode);
322  return NULL;
323 }
324 
325 CNode *FindNode(const CService &addr) {
326  LOCK(cs_vNodes);
327  const bool isRegTestNet = Params().IsRegTestNet();
328  for (CNode * pnode : vNodes)
329  {
330  if (isRegTestNet) {
331  //if using regtest, just check the IP
332  if ((CNetAddr) pnode->addr == (CNetAddr) addr)
333  return (pnode);
334  } else {
335  if (pnode->addr == addr)
336  return (pnode);
337  }
338  }
339  return NULL;
340 }
341 
342 CNode* ConnectNode(CAddress addrConnect, const char* pszDest, bool fCountFailure)
343 {
344  if (pszDest == NULL) {
345  if (IsLocal(addrConnect))
346  return NULL;
347 
348  // Look for an existing connection
349  CNode *pnode = FindNode((CService) addrConnect);
350  if (pnode) {
351  pnode->AddRef();
352  return pnode;
353  }
354  }
355 
357  LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
358  pszDest ? pszDest : addrConnect.ToString(),
359  pszDest ? 0.0 : (double) (GetAdjustedTime() - addrConnect.nTime) / 3600.0);
360 
361  // Connect
362  SOCKET hSocket = INVALID_SOCKET;
363  bool proxyConnectionFailed = false;
364  if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout,
365  &proxyConnectionFailed) :
366  ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) {
367  if (!IsSelectableSocket(hSocket)) {
368  LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
369  CloseSocket(hSocket);
370  return NULL;
371  }
372 
373  addrman.Attempt(addrConnect, fCountFailure);
374 
375  // Add node
376  CNode *pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
377  pnode->AddRef();
378 
379  {
380  LOCK(cs_vNodes);
381  vNodes.push_back(pnode);
382  }
383 
384  pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
385  pnode->nTimeConnected = GetTime();
386 
387  return pnode;
388  } else if (!proxyConnectionFailed) {
389  // If connecting to the node failed, and failure is not caused by a problem connecting to
390  // the proxy, mark this as an attempt.
391  addrman.Attempt(addrConnect, fCountFailure);
392  }
393 
394  return NULL;
395 }
396 
397 static void DumpBanlist()
398 {
399  CNode::SweepBanned(); // clean unused entries (if bantime has expired)
400 
402  return;
403 
404  int64_t nStart = GetTimeMillis();
405 
406  CBanDB bandb;
407  banmap_t banmap;
409  CNode::GetBanned(banmap);
410  if (!bandb.Write(banmap))
412 
413  LogPrint(BCLog::NET, "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
414  banmap.size(), GetTimeMillis() - nStart);
415 }
416 
418  fDisconnect = true;
419  if (hSocket != INVALID_SOCKET) {
420  LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
422  }
423 
424  // in case this fails, we'll empty the recv buffer when the CNode is deleted
425  TRY_LOCK(cs_vRecvMsg, lockRecv);
426  if (lockRecv)
427  vRecvMsg.clear();
428 }
429 
430 bool CNode::DisconnectOldProtocol(int nVersionRequired, std::string strLastCommand) {
431  fDisconnect = false;
432  if (nVersion < nVersionRequired) {
433  LogPrintf("%s : peer=%d using obsolete version %i; disconnecting\n", __func__, id, nVersion);
434  PushMessage(NetMsgType::REJECT, strLastCommand, REJECT_OBSOLETE,
435  strprintf("Version must be %d or greater", ActiveProtocol()));
436  fDisconnect = true;
437  }
438 
439  return fDisconnect;
440 }
441 
442 bool CNode::DisconnectOldVersion(std::string strSubVer, int nHeight, std::string strLastCommand) {
443  fDisconnect = false;
444  //if (nHeight >= Params().FixChecks()) {
445  if (strSubVer == "/PRCY:1.0.0.2/" || strSubVer == "/PRCY:1.0.0.3/" ||
446  strSubVer == "/PRCY:1.0.0.4/" || strSubVer == "/PRCY:1.0.0.5/" ||
447  strSubVer == "/PRCY:1.0.0.6/" || strSubVer == "/PRCY:1.0.0.7/" ||
448  strSubVer == "/PRCY:1.0.0.8/" || strSubVer == "/PRCY:1.0.0.9/" ||
449  strSubVer == "/PRCY:2.0.0/" || strSubVer == "/PRCY:2.0.0.1/" ||
450  strSubVer == "/PRCY:2.0.0.2/" || strSubVer == "/PRCY:2.0.0.3/" ||
451  strSubVer == "/PRCY:2.0.0.4/") {
452  LogPrintf("%s : peer=%d using unsupported version %i; disconnecting\n", __func__, id, strSubVer);
453  PushMessage(NetMsgType::REJECT, strLastCommand, REJECT_OBSOLETE,
454  strprintf("Using unsupported version %i; disconnecting\n", strSubVer));
455  fDisconnect = true;
456  }
457  //}
458  return fDisconnect;
459 }
460 
462  int nBestHeight = GetNodeSignals().GetHeight().get_value_or(0);
463 
465  int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
466  CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
467  CAddress addrMe = GetLocalAddress(&addr);
468  GetRandBytes((unsigned char *) &nLocalHostNonce, sizeof(nLocalHostNonce));
469  if (fLogIPs)
470  LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION,
471  nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
472  else
473  LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight,
474  addrMe.ToString(), id);
475  PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalServices, nTime, addrYou, addrMe,
476  nLocalHostNonce, strSubVersion, nBestHeight, true);
477 }
478 
479 
483 
485  {
487  setBanned.clear();
488  setBannedIsDirty = true;
489  }
490  DumpBanlist(); // store banlist to Disk
492 }
493 
495  bool fResult = false;
496  {
498  for (banmap_t::iterator it = setBanned.begin(); it != setBanned.end(); it++) {
499  CSubNet subNet = (*it).first;
500  CBanEntry banEntry = (*it).second;
501  if (subNet.Match(ip) && GetTime() < banEntry.nBanUntil)
502  fResult = true;
503  }
504  }
505  return fResult;
506 }
507 
508 bool CNode::IsBanned(CSubNet subnet) {
509  bool fResult = false;
510  {
512  banmap_t::iterator i = setBanned.find(subnet);
513  if (i != setBanned.end()) {
514  CBanEntry banEntry = (*i).second;
515  if (GetTime() < banEntry.nBanUntil)
516  fResult = true;
517  }
518  }
519  return fResult;
520 }
521 
522 void CNode::Ban(const CNetAddr &addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) {
523  CSubNet subNet(addr);
524  Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
525 }
526 
527 void CNode::Ban(const CSubNet &subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) {
528  CBanEntry banEntry(GetTime());
529  banEntry.banReason = banReason;
530  if (bantimeoffset <= 0) {
531  bantimeoffset = GetArg("-bantime", 60 * 60 * 24); // Default 24-hour ban
532  sinceUnixEpoch = false;
533  }
534  banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime()) + bantimeoffset;
535  {
537  if (setBanned[subNet].nBanUntil < banEntry.nBanUntil) {
538  setBanned[subNet] = banEntry;
539  setBannedIsDirty = true;
540  }
541  else return;
542  }
544  {
545  LOCK(cs_vNodes);
546  for (CNode* pnode : vNodes) {
547  if (subNet.Match((CNetAddr)pnode->addr))
548  pnode->fDisconnect = true;
549  }
550  }
551  if(banReason == BanReasonManuallyAdded)
552  DumpBanlist(); //store banlist to disk immediately if user requested ban
553 
554 }
555 
556 bool CNode::Unban(const CNetAddr &addr) {
557  CSubNet subNet(addr);
558  return Unban(subNet);
559 }
560 
561 bool CNode::Unban(const CSubNet &subNet) {
562  {
564  if (!setBanned.erase(subNet))
565  return false;
566  setBannedIsDirty = true;
567  }
569  DumpBanlist(); //store banlist to disk immediately
570  return true;
571 }
572 
573 void CNode::GetBanned(banmap_t &banMap) {
575  banMap = setBanned; //create a thread safe copy
576 }
577 
578 void CNode::SetBanned(const banmap_t &banMap) {
580  setBanned = banMap;
581  setBannedIsDirty = true;
582 }
583 
585  int64_t now = GetTime();
586  bool notifyUI = false;
587  {
589  banmap_t::iterator it = setBanned.begin();
590  while(it != setBanned.end())
591  {
592  CSubNet subNet = (*it).first;
593  CBanEntry banEntry = (*it).second;
594  if(now > banEntry.nBanUntil)
595  {
596  setBanned.erase(it++);
597  setBannedIsDirty = true;
598  notifyUI = true;
599  LogPrint(BCLog::NET, "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.ToString());
600  }
601  else
602  ++it;
603  }
604  }
605  // update UI
606  if(notifyUI) {
608  }
609 }
610 
613  return setBannedIsDirty;
614 }
615 
616 void CNode::SetBannedSetDirty(bool dirty) {
617  LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag
618  setBannedIsDirty = dirty;
619 }
620 
621 std::vector <CSubNet> CNode::vWhitelistedRange;
623 
626  for (const CSubNet &subnet : vWhitelistedRange) {
627  if (subnet.Match(addr))
628  return true;
629  }
630  return false;
631 }
632 
633 void CNode::AddWhitelistedRange(const CSubNet &subnet) {
635  vWhitelistedRange.push_back(subnet);
636 }
637 
638 #undef X
639 #define X(name) stats.name = name
640 
642  stats.nodeid = this->GetId();
643  X(nServices);
644  X(addr);
645  X(nLastSend);
646  X(nLastRecv);
647  X(nTimeConnected);
648  X(nTimeOffset);
649  X(addrName);
650  X(nVersion);
651  X(cleanSubVer);
652  X(fInbound);
654  X(nSendBytes);
655  X(nRecvBytes);
656  X(fWhitelisted);
657 
658  // It is common for nodes with good ping times to suddenly become lagged,
659  // due to a new block arriving or other large transfer.
660  // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
661  // since pingtime does not update until the ping is complete, which might take a while.
662  // So, if a ping is taking an unusually long time in flight,
663  // the caller can immediately detect that this is happening.
664  int64_t nPingUsecWait = 0;
665  if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
666  nPingUsecWait = GetTimeMicros() - nPingUsecStart;
667  }
668 
669  // Raw ping time is in microseconds, but show it to user as whole seconds (PRCY users should be well used to small numbers with many decimal places by now :)
670  stats.dPingTime = (((double) nPingUsecTime) / 1e6);
671  stats.dPingWait = (((double) nPingUsecWait) / 1e6);
672 
673  // Leave string empty if addrLocal invalid (not filled in yet)
674  stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
675 }
676 
677 #undef X
678 
679 // requires LOCK(cs_vRecvMsg)
680 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes) {
681  while (nBytes > 0) {
682  // get current incomplete message, or create a new one
683  if (vRecvMsg.empty() ||
684  vRecvMsg.back().complete())
686 
687  CNetMessage &msg = vRecvMsg.back();
688 
689  // absorb network data
690  int handled;
691  if (!msg.in_data)
692  handled = msg.readHeader(pch, nBytes);
693  else
694  handled = msg.readData(pch, nBytes);
695 
696  if (handled < 0)
697  return false;
698 
699  if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
700  LogPrint(BCLog::NET, "Oversized message from peer=%i, disconnecting", GetId());
701  return false;
702  }
703 
704  pch += handled;
705  nBytes -= handled;
706 
707  if (msg.complete()) {
708  msg.nTime = GetTimeMicros();
709  messageHandlerCondition.notify_one();
710  }
711  }
712 
713  return true;
714 }
715 
716 int CNetMessage::readHeader(const char *pch, unsigned int nBytes) {
717  // copy data to temporary parsing buffer
718  unsigned int nRemaining = 24 - nHdrPos;
719  unsigned int nCopy = std::min(nRemaining, nBytes);
720 
721  memcpy(&hdrbuf[nHdrPos], pch, nCopy);
722  nHdrPos += nCopy;
723 
724  // if header incomplete, exit
725  if (nHdrPos < 24)
726  return nCopy;
727 
728  // deserialize to CMessageHeader
729  try {
730  hdrbuf >> hdr;
731  } catch (const std::exception &) {
732  return -1;
733  }
734 
735  // reject messages larger than MAX_SIZE
736  if (hdr.nMessageSize > MAX_SIZE)
737  return -1;
738 
739  // switch state to reading message data
740  in_data = true;
741 
742  return nCopy;
743 }
744 
745 int CNetMessage::readData(const char *pch, unsigned int nBytes) {
746  unsigned int nRemaining = hdr.nMessageSize - nDataPos;
747  unsigned int nCopy = std::min(nRemaining, nBytes);
748 
749  if (vRecv.size() < nDataPos + nCopy) {
750  // Allocate up to 256 KiB ahead, but never more than the total message size.
751  vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
752  }
753 
754  memcpy(&vRecv[nDataPos], pch, nCopy);
755  nDataPos += nCopy;
756 
757  return nCopy;
758 }
759 
760 
761 // requires LOCK(cs_vSend)
762 void SocketSendData(CNode *pnode) {
763  std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
764 
765  while (it != pnode->vSendMsg.end()) {
766  const CSerializeData &data = *it;
767  assert(data.size() > pnode->nSendOffset);
768  int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset,
769  MSG_NOSIGNAL | MSG_DONTWAIT);
770  if (nBytes > 0) {
771  pnode->nLastSend = GetTime();
772  pnode->nSendBytes += nBytes;
773  pnode->nSendOffset += nBytes;
774  pnode->RecordBytesSent(nBytes);
775  if (pnode->nSendOffset == data.size()) {
776  pnode->nSendOffset = 0;
777  pnode->nSendSize -= data.size();
778  it++;
779  } else {
780  // could not send full message; stop sending more
781  break;
782  }
783  } else {
784  if (nBytes < 0) {
785  // error
786  int nErr = WSAGetLastError();
787  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
788  LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
789  pnode->CloseSocketDisconnect();
790  }
791  }
792  // couldn't send anything at all
793  break;
794  }
795  }
796 
797  if (it == pnode->vSendMsg.end()) {
798  assert(pnode->nSendOffset == 0);
799  assert(pnode->nSendSize == 0);
800  }
801  pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
802 }
803 
804 static std::list<CNode*> vNodesDisconnected;
805 
807 {
809  int64_t nTimeConnected;
812 };
813 
814 static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
815 {
816  return a.nMinPingUsecTime > b.nMinPingUsecTime;
817 }
818 
819 static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
820 {
821  return a.nTimeConnected > b.nTimeConnected;
822 }
823 
825 {
826  std::vector<unsigned char> vchSecretKey;
827 public:
829  {
830  vchSecretKey.resize(32, 0);
831  GetRandBytes(vchSecretKey.data(), vchSecretKey.size());
832  }
833 
835  {
836  std::vector<unsigned char> vchGroupA, vchGroupB;
837  CSHA256 hashA, hashB;
838  std::vector<unsigned char> vchA(32), vchB(32);
839 
840  vchGroupA = a.addr.GetGroup();
841  vchGroupB = b.addr.GetGroup();
842 
843  hashA.Write(begin_ptr(vchGroupA), vchGroupA.size());
844  hashB.Write(begin_ptr(vchGroupB), vchGroupB.size());
845 
846  hashA.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
847  hashB.Write(begin_ptr(vchSecretKey), vchSecretKey.size());
848 
849  hashA.Finalize(begin_ptr(vchA));
850  hashB.Finalize(begin_ptr(vchB));
851 
852  return vchA < vchB;
853  }
854 };
855 
864 static bool AttemptToEvictConnection(bool fPreferNewConnection) {
865  std::vector<NodeEvictionCandidate> vEvictionCandidates;
866  {
867  LOCK(cs_vNodes);
868 
869  for (CNode *node : vNodes) {
870  if (node->fWhitelisted)
871  continue;
872  if (!node->fInbound)
873  continue;
874  if (node->fDisconnect)
875  continue;
876  NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, node->addr};
877  vEvictionCandidates.push_back(candidate);
878  }
879  }
880 
881  if (vEvictionCandidates.empty()) return false;
882 
883  // Protect connections with certain characteristics
884 
885  // Deterministically select 4 peers to protect by netgroup.
886  // An attacker cannot predict which netgroups will be protected.
887  static CompareNetGroupKeyed comparerNetGroupKeyed;
888  std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), comparerNetGroupKeyed);
889  vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
890 
891  if (vEvictionCandidates.empty()) return false;
892 
893  // Protect the 8 nodes with the lowest minimum ping time.
894  // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
895  std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
896  vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
897 
898  if (vEvictionCandidates.empty()) return false;
899 
900  // Protect the half of the remaining nodes which have been connected the longest.
901  // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
902  std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
903  vEvictionCandidates.erase(vEvictionCandidates.end() - static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
904 
905  if (vEvictionCandidates.empty()) return false;
906 
907  // Identify the network group with the most connections and youngest member.
908  // (vEvictionCandidates is already sorted by reverse connect time)
909  std::vector<unsigned char> naMostConnections;
910  unsigned int nMostConnections = 0;
911  int64_t nMostConnectionsTime = 0;
912  std::map<std::vector<unsigned char>, std::vector<NodeEvictionCandidate> > mapAddrCounts;
913  for (const NodeEvictionCandidate &node : vEvictionCandidates) {
914  mapAddrCounts[node.addr.GetGroup()].push_back(node);
915  int64_t grouptime = mapAddrCounts[node.addr.GetGroup()][0].nTimeConnected;
916  size_t groupsize = mapAddrCounts[node.addr.GetGroup()].size();
917 
918  if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
919  nMostConnections = groupsize;
920  nMostConnectionsTime = grouptime;
921  naMostConnections = node.addr.GetGroup();
922  }
923  }
924 
925  // Reduce to the network group with the most connections
926  vEvictionCandidates = mapAddrCounts[naMostConnections];
927 
928  // Do not disconnect peers if there is only 1 connection from their network group
929  if (vEvictionCandidates.size() <= 1)
930  // unless we prefer the new connection (for whitelisted peers)
931  if (!fPreferNewConnection)
932  return false;
933 
934  // Disconnect from the network group with the most connections
935  NodeId evicted = vEvictionCandidates.front().id;
936  LOCK(cs_vNodes);
937  for(std::vector<CNode*>::const_iterator it(vNodes.begin()); it != vNodes.end(); ++it) {
938  if ((*it)->GetId() == evicted) {
939  (*it)->fDisconnect = true;
940  return true;
941  }
942  }
943  return false;
944 }
945 
946 static void AcceptConnection(const ListenSocket& hListenSocket) {
947  struct sockaddr_storage sockaddr;
948  socklen_t len = sizeof(sockaddr);
949  SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
950  CAddress addr;
951  int nInbound = 0;
952  int nMaxInbound = nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS);
953 
954  if (hSocket != INVALID_SOCKET)
955  if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
956  LogPrintf("Warning: Unknown socket family\n");
957 
958  bool whitelisted = hListenSocket.whitelisted || CNode::IsWhitelistedRange(addr);
959  {
960  LOCK(cs_vNodes);
961  for (CNode* pnode : vNodes)
962  if (pnode->fInbound)
963  nInbound++;
964  }
965 
966  if (hSocket == INVALID_SOCKET) {
967  int nErr = WSAGetLastError();
968  if (nErr != WSAEWOULDBLOCK)
969  LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
970  return;
971  }
972 
973  if (!IsSelectableSocket(hSocket)) {
974  LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
975  CloseSocket(hSocket);
976  return;
977  }
978 
979  if (CNode::IsBanned(addr) && !whitelisted) {
980  LogPrintf("connection from %s dropped (banned)\n", addr.ToString());
981  CloseSocket(hSocket);
982  return;
983  }
984 
985  if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) {
986  if (!AttemptToEvictConnection(whitelisted)) {
987  // No connection to evict, disconnect the new connection
988  LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
989  CloseSocket(hSocket);
990  return;
991  }
992  }
993 
994  CNode* pnode = new CNode(hSocket, addr, "", true);
995  pnode->AddRef();
996  pnode->fWhitelisted = whitelisted;
997 
998  LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
999 
1000  {
1001  LOCK(cs_vNodes);
1002  vNodes.push_back(pnode);
1003  }
1004 }
1005 
1007  unsigned int nPrevNodeCount = 0;
1008  while (true) {
1009  //
1010  // Disconnect nodes
1011  //
1012  {
1013  LOCK(cs_vNodes);
1014  // Disconnect unused nodes
1015  std::vector<CNode*> vNodesCopy = vNodes;
1016  for (CNode * pnode : vNodesCopy)
1017  {
1018  if (pnode->fDisconnect ||
1019  (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 &&
1020  pnode->ssSend.empty())) {
1021  // remove from vNodes
1022  vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1023 
1024  // release outbound grant (if any)
1025  pnode->grantOutbound.Release();
1026 
1027  // close socket and cleanup
1028  pnode->CloseSocketDisconnect();
1029 
1030  // hold in disconnected pool until all refs are released
1031  if (pnode->fNetworkNode || pnode->fInbound)
1032  pnode->Release();
1033  vNodesDisconnected.push_back(pnode);
1034  }
1035  }
1036  }
1037  {
1038  // Delete disconnected nodes
1039  std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1040  for (CNode * pnode : vNodesDisconnectedCopy)
1041  {
1042  // wait until threads are done using it
1043  if (pnode->GetRefCount() <= 0) {
1044  bool fDelete = false;
1045  {
1046  TRY_LOCK(pnode->cs_vSend, lockSend);
1047  if (lockSend) {
1048  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1049  if (lockRecv) {
1050  TRY_LOCK(pnode->cs_inventory, lockInv);
1051  if (lockInv)
1052  fDelete = true;
1053  }
1054  }
1055  }
1056  if (fDelete) {
1057  vNodesDisconnected.remove(pnode);
1058  delete pnode;
1059  }
1060  }
1061  }
1062  }
1063  size_t vNodesSize;
1064  {
1065  LOCK(cs_vNodes);
1066  vNodesSize = vNodes.size();
1067  }
1068  if (vNodesSize != nPrevNodeCount) {
1069  nPrevNodeCount = vNodesSize;
1070  uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
1071  }
1072 
1073  //
1074  // Find which sockets have data to receive
1075  //
1076  struct timeval timeout;
1077  timeout.tv_sec = 0;
1078  timeout.tv_usec = 50000; // frequency to poll pnode->vSend
1079 
1080  fd_set fdsetRecv;
1081  fd_set fdsetSend;
1082  fd_set fdsetError;
1083  FD_ZERO(&fdsetRecv);
1084  FD_ZERO(&fdsetSend);
1085  FD_ZERO(&fdsetError);
1086  SOCKET hSocketMax = 0;
1087  bool have_fds = false;
1088 
1089  for (const ListenSocket &hListenSocket : vhListenSocket) {
1090  FD_SET(hListenSocket.socket, &fdsetRecv);
1091  hSocketMax = std::max(hSocketMax, hListenSocket.socket);
1092  have_fds = true;
1093  }
1094 
1095  {
1096  LOCK(cs_vNodes);
1097  for (CNode * pnode : vNodes)
1098  {
1099  if (pnode->hSocket == INVALID_SOCKET)
1100  continue;
1101  FD_SET(pnode->hSocket, &fdsetError);
1102  hSocketMax = std::max(hSocketMax, pnode->hSocket);
1103  have_fds = true;
1104 
1105  // Implement the following logic:
1106  // * If there is data to send, select() for sending data. As this only
1107  // happens when optimistic write failed, we choose to first drain the
1108  // write buffer in this case before receiving more. This avoids
1109  // needlessly queueing received data, if the remote peer is not themselves
1110  // receiving data. This means properly utilizing TCP flow control signalling.
1111  // * Otherwise, if there is no (complete) message in the receive buffer,
1112  // or there is space left in the buffer, select() for receiving data.
1113  // * (if neither of the above applies, there is certainly one message
1114  // in the receiver buffer ready to be processed).
1115  // Together, that means that at least one of the following is always possible,
1116  // so we don't deadlock:
1117  // * We send some data.
1118  // * We wait for data to be received (and disconnect after timeout).
1119  // * We process a message in the buffer (message handler thread).
1120  {
1121  LOCK(pnode->cs_vSend);
1122  if (!pnode->vSendMsg.empty()) {
1123  FD_SET(pnode->hSocket, &fdsetSend);
1124  continue;
1125  }
1126  }
1127  {
1128  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1129  if (lockRecv && (pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
1130  pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
1131  FD_SET(pnode->hSocket, &fdsetRecv);
1132  }
1133  }
1134  }
1135 
1136  int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1137  &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1138  boost::this_thread::interruption_point();
1139 
1140  if (nSelect == SOCKET_ERROR) {
1141  if (have_fds) {
1142  int nErr = WSAGetLastError();
1143  LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1144  for (unsigned int i = 0; i <= hSocketMax; i++)
1145  FD_SET(i, &fdsetRecv);
1146  }
1147  FD_ZERO(&fdsetSend);
1148  FD_ZERO(&fdsetError);
1149  MilliSleep(timeout.tv_usec / 1000);
1150  }
1151 
1152  //
1153  // Accept new connections
1154  //
1155  for (const ListenSocket &hListenSocket : vhListenSocket) {
1156  if (hListenSocket.socket != INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv)) {
1157  AcceptConnection(hListenSocket);
1158  }
1159  }
1160 
1161  //
1162  // Service each socket
1163  //
1164  std::vector<CNode*> vNodesCopy;
1165  {
1166  LOCK(cs_vNodes);
1167  vNodesCopy = vNodes;
1168  for (CNode * pnode : vNodesCopy)
1169  pnode->AddRef();
1170  }
1171  for (CNode * pnode : vNodesCopy)
1172  {
1173  boost::this_thread::interruption_point();
1174 
1175  //
1176  // Receive
1177  //
1178  if (pnode->hSocket == INVALID_SOCKET)
1179  continue;
1180  if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) {
1181  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1182  if (lockRecv) {
1183  {
1184  // typical socket buffer is 8K-64K
1185  char pchBuf[0x10000];
1186  int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1187  if (nBytes > 0) {
1188  if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
1189  pnode->CloseSocketDisconnect();
1190  pnode->nLastRecv = GetTime();
1191  pnode->nRecvBytes += nBytes;
1192  pnode->RecordBytesRecv(nBytes);
1193  } else if (nBytes == 0) {
1194  // socket closed gracefully
1195  if (!pnode->fDisconnect)
1196  LogPrint(BCLog::NET, "socket closed\n");
1197  pnode->CloseSocketDisconnect();
1198  } else if (nBytes < 0) {
1199  // error
1200  int nErr = WSAGetLastError();
1201  if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR &&
1202  nErr != WSAEINPROGRESS) {
1203  if (!pnode->fDisconnect)
1204  LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1205  pnode->CloseSocketDisconnect();
1206  }
1207  }
1208  }
1209  }
1210  }
1211 
1212  //
1213  // Send
1214  //
1215  if (pnode->hSocket == INVALID_SOCKET)
1216  continue;
1217  if (FD_ISSET(pnode->hSocket, &fdsetSend)) {
1218  LOCK(pnode->cs_vSend);
1219  SocketSendData(pnode);
1220  }
1221 
1222  //
1223  // Inactivity checking
1224  //
1225  int64_t nTime = GetTime();
1226  if (nTime - pnode->nTimeConnected > 60) {
1227  if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) {
1228  LogPrint(BCLog::NET, "socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0,
1229  pnode->nLastSend != 0, pnode->id);
1230  pnode->fDisconnect = true;
1231  } else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL) {
1232  LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1233  pnode->fDisconnect = true;
1234  } else if (nTime - pnode->nLastRecv >
1235  (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90 * 60)) {
1236  LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1237  pnode->fDisconnect = true;
1238  } else if (pnode->nPingNonceSent &&
1239  pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros()) {
1240  LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1241  pnode->fDisconnect = true;
1242  }
1243  }
1244  }
1245  {
1246  LOCK(cs_vNodes);
1247  for (CNode * pnode : vNodesCopy)
1248  pnode->Release();
1249  }
1250  }
1251 }
1252 
1253 
1254 #ifdef USE_UPNP
1255 void ThreadMapPort()
1256 {
1257  std::string port = strprintf("%u", GetListenPort());
1258  const char* multicastif = 0;
1259  const char* minissdpdpath = 0;
1260  struct UPNPDev* devlist = 0;
1261  char lanaddr[64];
1262 
1263 #ifndef UPNPDISCOVER_SUCCESS
1264  /* miniupnpc 1.5 */
1265  devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1266 #elif MINIUPNPC_API_VERSION < 14
1267  /* miniupnpc 1.6 */
1268  int error = 0;
1269  devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1270 #else
1271  /* miniupnpc 1.9.20150730 */
1272  int error = 0;
1273  devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1274 #endif
1275 
1276  struct UPNPUrls urls;
1277  struct IGDdatas data;
1278  int r;
1279 
1280  r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1281  if (r == 1) {
1282  if (fDiscover) {
1283  char externalIPAddress[40];
1284  r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1285  if (r != UPNPCOMMAND_SUCCESS)
1286  LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1287  else {
1288  if (externalIPAddress[0]) {
1289  CNetAddr resolved;
1290  if (LookupHost(externalIPAddress, resolved, false)) {
1291  LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str());
1292  AddLocal(resolved, LOCAL_UPNP);
1293  }
1294  } else
1295  LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1296  }
1297  }
1298 
1299  std::string strDesc = "PRCY " + FormatFullVersion();
1300 
1301  try {
1302  while (true) {
1303 #ifndef UPNPDISCOVER_SUCCESS
1304  /* miniupnpc 1.5 */
1305  r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1306  port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1307 #else
1308  /* miniupnpc 1.6 */
1309  r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1310  port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1311 #endif
1312 
1313  if (r != UPNPCOMMAND_SUCCESS)
1314  LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1315  port, port, lanaddr, r, strupnperror(r));
1316  else
1317  LogPrintf("UPnP Port Mapping successful.\n");
1318  ;
1319 
1320  MilliSleep(20 * 60 * 1000); // Refresh every 20 minutes
1321  }
1322  } catch (const boost::thread_interrupted&) {
1323  r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1324  LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
1325  freeUPNPDevlist(devlist);
1326  devlist = 0;
1327  FreeUPNPUrls(&urls);
1328  throw;
1329  }
1330  } else {
1331  LogPrintf("No valid UPnP IGDs found\n");
1332  freeUPNPDevlist(devlist);
1333  devlist = 0;
1334  if (r != 0)
1335  FreeUPNPUrls(&urls);
1336  }
1337 }
1338 
1339 void MapPort(bool fUseUPnP)
1340 {
1341  static boost::thread* upnp_thread = NULL;
1342 
1343  if (fUseUPnP) {
1344  if (upnp_thread) {
1345  upnp_thread->interrupt();
1346  upnp_thread->join();
1347  delete upnp_thread;
1348  }
1349  upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1350  } else if (upnp_thread) {
1351  upnp_thread->interrupt();
1352  upnp_thread->join();
1353  delete upnp_thread;
1354  upnp_thread = NULL;
1355  }
1356 }
1357 
1358 #else
1359 
1360 void MapPort(bool) {
1361  // Intentionally left blank.
1362 }
1363 
1364 #endif
1365 
1366 static std::string GetDNSHost(const CDNSSeedData& data, ServiceFlags* requiredServiceBits)
1367 {
1368  //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK)
1369  if (!data.supportsServiceBitsFiltering || *requiredServiceBits == NODE_NETWORK) {
1370  *requiredServiceBits = NODE_NETWORK;
1371  return data.host;
1372  }
1373 
1374  return strprintf("x%x.%s", *requiredServiceBits, data.host);
1375 }
1376 
1378  // goal: only query DNS seeds if address need is acute
1379  if ((addrman.size() > 0) &&
1380  (!GetBoolArg("-forcednsseed", false))) {
1381  MilliSleep(11 * 1000);
1382 
1383  LOCK(cs_vNodes);
1384  if (vNodes.size() >= 3) {
1385  LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1386  return;
1387  }
1388  }
1389 
1390  const std::vector<CDNSSeedData>& vSeeds = Params().DNSSeeds();
1391  int found = 0;
1392 
1393  LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1394 
1395  for (const CDNSSeedData &seed : vSeeds) {
1396  if (HaveNameProxy()) {
1397  AddOneShot(seed.host);
1398  } else {
1399  std::vector<CNetAddr> vIPs;
1400  std::vector<CAddress> vAdd;
1401  ServiceFlags requiredServiceBits = nRelevantServices;
1402  if (LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0, true)) {
1403  for (CNetAddr & ip : vIPs)
1404  {
1405  int nOneDay = 24 * 3600;
1406  CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1407  addr.nTime =
1408  GetTime() - 3 * nOneDay - GetRand(4 * nOneDay); // use a random age between 3 and 7 days old
1409  vAdd.push_back(addr);
1410  found++;
1411  }
1412  }
1413  // TODO: The seed name resolve may fail, yielding an IP of [::], which results in
1414  // addrman assigning the same source to results from different seeds.
1415  // This should switch to a hard-coded stable dummy IP for each seed name, so that the
1416  // resolve is not required at all.
1417  if (!vIPs.empty()) {
1418  CService seedSource;
1419  Lookup(seed.name.c_str(), seedSource, 0, true);
1420  addrman.Add(vAdd, seedSource);
1421  }
1422  }
1423  }
1424 
1425  LogPrintf("%d addresses found from DNS seeds\n", found);
1426 }
1427 
1428 
1430  int64_t nStart = GetTimeMillis();
1431 
1432  CAddrDB adb;
1433  adb.Write(addrman);
1434 
1435  LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1436  addrman.size(), GetTimeMillis() - nStart);
1437 }
1438 
1439 void DumpData() {
1440  DumpAddresses();
1441  DumpBanlist();
1442 }
1443 
1444 void static ProcessOneShot() {
1445  std::string strDest;
1446  {
1447  LOCK(cs_vOneShots);
1448  if (vOneShots.empty())
1449  return;
1450  strDest = vOneShots.front();
1451  vOneShots.pop_front();
1452  }
1453  CAddress addr;
1454  CSemaphoreGrant grant(*semOutbound, true);
1455  if (grant) {
1456  if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true))
1457  AddOneShot(strDest);
1458  }
1459 }
1460 
1462  // Connect to specific addresses
1463  if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) {
1464  for (int64_t nLoop = 0;; nLoop++) {
1465  ProcessOneShot();
1466  for (std::string strAddr : mapMultiArgs["-connect"]) {
1467  CAddress addr(CService(), NODE_NONE);
1468  OpenNetworkConnection(addr, false, NULL, strAddr.c_str());
1469  for (int i = 0; i < 10 && i < nLoop; i++) {
1470  MilliSleep(500);
1471  }
1472  }
1473  MilliSleep(500);
1474  }
1475  }
1476 
1477  // Initiate network connections
1478  int64_t nStart = GetTime();
1479 
1480  // Minimum time before next feeler connection (in microseconds).
1481  int64_t nNextFeeler = PoissonNextSend(nStart * 1000 * 1000, FEELER_INTERVAL);
1482  while (true) {
1483  ProcessOneShot();
1484 
1485  MilliSleep(500);
1486 
1487  CSemaphoreGrant grant(*semOutbound);
1488  boost::this_thread::interruption_point();
1489 
1490  // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1491  if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1492  static bool done = false;
1493  if (!done) {
1494  LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1495  CNetAddr local;
1496  LookupHost("127.0.0.1", local, false);
1497  addrman.Add(convertSeed6(Params().FixedSeeds()), local);
1498  done = true;
1499  }
1500  }
1501 
1502  //
1503  // Choose an address to connect to based on most recently seen
1504  //
1505  CAddress addrConnect;
1506 
1507  // Only connect out to one peer per network group (/16 for IPv4).
1508  // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1509  int nOutbound = 0;
1510  std::set<std::vector<unsigned char> > setConnected;
1511  {
1512  LOCK(cs_vNodes);
1513  for (CNode * pnode : vNodes)
1514  {
1515  if (!pnode->fInbound) {
1516  setConnected.insert(pnode->addr.GetGroup());
1517  nOutbound++;
1518  }
1519  }
1520  }
1521 
1522  // Feeler Connections
1523  //
1524  // Design goals:
1525  // * Increase the number of connectable addresses in the tried table.
1526  //
1527  // Method:
1528  // * Choose a random address from new and attempt to connect to it if we can connect
1529  // successfully it is added to tried.
1530  // * Start attempting feeler connections only after node finishes making outbound
1531  // connections.
1532  // * Only make a feeler connection once every few minutes.
1533  //
1534  bool fFeeler = false;
1535  if (nOutbound >= MAX_OUTBOUND_CONNECTIONS) {
1536  int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
1537  if (nTime > nNextFeeler) {
1538  nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
1539  fFeeler = true;
1540  } else {
1541  continue;
1542  }
1543  }
1544 
1545  int64_t nANow = GetAdjustedTime();
1546  int nTries = 0;
1547  while (true) {
1548  CAddrInfo addr = addrman.Select(fFeeler);
1549 
1550  // if we selected an invalid address, restart
1551  if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1552  break;
1553 
1554  // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1555  // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1556  // already-connected network ranges, ...) before trying new addrman addresses.
1557  nTries++;
1558  if (nTries > 100)
1559  break;
1560 
1561  if (IsLimited(addr))
1562  continue;
1563 
1564  // only connect to full nodes
1565  if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1566  continue;
1567 
1568  // only consider very recently tried nodes after 30 failed attempts
1569  if (nANow - addr.nLastTry < 600 && nTries < 30)
1570  continue;
1571 
1572  // do not allow non-default ports, unless after 50 invalid addresses selected already
1573  if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1574  continue;
1575 
1576  addrConnect = addr;
1577  break;
1578  }
1579 
1580  if (addrConnect.IsValid()) {
1581  if (fFeeler) {
1582  // Add small amount of random noise before connection to avoid synchronization.
1583  int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
1584  MilliSleep(randsleep);
1585  LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
1586  }
1587 
1588  OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler);
1589  }
1590  }
1591 }
1592 
1593 std::vector<AddedNodeInfo> GetAddedNodeInfo()
1594 {
1595  std::vector<AddedNodeInfo> ret;
1596 
1597  std::list<std::string> lAddresses(0);
1598  {
1600  ret.reserve(vAddedNodes.size());
1601  for (std::string& strAddNode : vAddedNodes)
1602  lAddresses.push_back(strAddNode);
1603  }
1604 
1605 
1606  // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
1607  std::map<CService, bool> mapConnected;
1608  std::map<std::string, std::pair<bool, CService> > mapConnectedByName;
1609  {
1610  LOCK(cs_vNodes);
1611  for (const CNode* pnode : vNodes) {
1612  if (pnode->addr.IsValid()) {
1613  mapConnected[pnode->addr] = pnode->fInbound;
1614  }
1615  if (!pnode->addrName.empty()) {
1616  mapConnectedByName[pnode->addrName] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1617  }
1618  }
1619  }
1620 
1621  for (std::string& strAddNode : lAddresses) {
1622  CService service(LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort()));
1623  if (service.IsValid()) {
1624  // strAddNode is an IP:port
1625  auto it = mapConnected.find(service);
1626  if (it != mapConnected.end()) {
1627  ret.push_back(AddedNodeInfo{strAddNode, service, true, it->second});
1628  } else {
1629  ret.push_back(AddedNodeInfo{strAddNode, CService(), false, false});
1630  }
1631  } else {
1632  // strAddNode is a name
1633  auto it = mapConnectedByName.find(strAddNode);
1634  if (it != mapConnectedByName.end()) {
1635  ret.push_back(AddedNodeInfo{strAddNode, it->second.second, true, it->second.first});
1636  } else {
1637  ret.push_back(AddedNodeInfo{strAddNode, CService(), false, false});
1638  }
1639  }
1640  }
1641 
1642  return ret;
1643 }
1644 
1646 {
1647  {
1649  vAddedNodes = mapMultiArgs["-addnode"];
1650  }
1651 
1652  for (unsigned int i = 0; true; i++) {
1653  std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
1654  for (const AddedNodeInfo& info : vInfo) {
1655  if (!info.fConnected) {
1656  CSemaphoreGrant grant(*semOutbound);
1657  // If strAddedNode is an IP/port, decode it immediately, so
1658  // OpenNetworkConnection can detect existing connections to that IP/port.
1659  CService service(LookupNumeric(info.strAddedNode.c_str(), Params().GetDefaultPort()));
1660  OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false);
1661  MilliSleep(500);
1662  }
1663  }
1664 
1665  MilliSleep(120000); // Retry every 2 minutes
1666  }
1667 }
1668 
1669 // if successful, this moves the passed grant to the constructed node
1670 bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound, const char* pszDest, bool fOneShot, bool fFeeler)
1671 {
1672  //
1673  // Initiate outbound network connection
1674  //
1675  boost::this_thread::interruption_point();
1676  if (!pszDest) {
1677  if (IsLocal(addrConnect) ||
1678  FindNode((CNetAddr) addrConnect) || CNode::IsBanned(addrConnect) ||
1679  FindNode(addrConnect.ToStringIPPort()))
1680  return false;
1681  } else if (FindNode(pszDest))
1682  return false;
1683 
1684  CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
1685  boost::this_thread::interruption_point();
1686 
1687  if (!pnode)
1688  return false;
1689  if (grantOutbound)
1690  grantOutbound->MoveTo(pnode->grantOutbound);
1691  pnode->fNetworkNode = true;
1692  if (fOneShot)
1693  pnode->fOneShot = true;
1694  if (fFeeler)
1695  pnode->fFeeler = true;
1696 
1697  return true;
1698 }
1699 
1701  boost::mutex condition_mutex;
1702  boost::unique_lock<boost::mutex> lock(condition_mutex);
1703 
1705  while (true) {
1706  std::vector<CNode*> vNodesCopy;
1707  {
1708  LOCK(cs_vNodes);
1709  vNodesCopy = vNodes;
1710  for (CNode * pnode : vNodesCopy)
1711  {
1712  pnode->AddRef();
1713  }
1714  }
1715 
1716  bool fSleep = true;
1717  for (CNode * pnode : vNodesCopy)
1718  {
1719  if (pnode->fDisconnect)
1720  continue;
1721  // Receive messages
1722  {
1723  TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1724  if (lockRecv) {
1725  if (!GetNodeSignals().ProcessMessages(pnode)) {
1726  pnode->CloseSocketDisconnect();
1727  }
1728  if (pnode->nSendSize < SendBufferSize()) {
1729  if (!pnode->vRecvGetData.empty() ||
1730  (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete())) {
1731  fSleep = false;
1732  }
1733  }
1734  }
1735  }
1736  boost::this_thread::interruption_point();
1737  // Send messages
1738  {
1739  LOCK(pnode->cs_sendProcessing);
1740  GetNodeSignals().SendMessages(pnode);
1741  }
1742  boost::this_thread::interruption_point();
1743  }
1744 
1745  {
1746  LOCK(cs_vNodes);
1747  for (CNode * pnode : vNodesCopy)
1748  pnode->Release();
1749  }
1750 
1751  if (fSleep)
1752  messageHandlerCondition.timed_wait(lock, boost::posix_time::microsec_clock::universal_time() +
1753  boost::posix_time::milliseconds(100));
1754  }
1755 }
1756 
1757 bool BindListenPort(const CService& addrBind, std::string& strError, bool fWhitelisted) {
1758  strError = "";
1759  int nOne = 1;
1760 
1761  // Create socket for listening for incoming connections
1762  struct sockaddr_storage sockaddr;
1763  socklen_t len = sizeof(sockaddr);
1764  if (!addrBind.GetSockAddr((struct sockaddr *) &sockaddr, &len)) {
1765  strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
1766  LogPrintf("%s\n", strError);
1767  return false;
1768  }
1769 
1770  SOCKET hListenSocket = socket(((struct sockaddr *) &sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1771  if (hListenSocket == INVALID_SOCKET) {
1772  strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)",
1774  LogPrintf("%s\n", strError);
1775  return false;
1776  }
1777  if (!IsSelectableSocket(hListenSocket)) {
1778  strError = "Error: Couldn't create a listenable socket for incoming connections";
1779  LogPrintf("%s\n", strError);
1780  return false;
1781  }
1782 
1783 
1784 #ifndef WIN32
1785 #ifdef SO_NOSIGPIPE
1786  // Different way of disabling SIGPIPE on BSD
1787  setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1788 #endif
1789  // Allow binding if the port is still in TIME_WAIT state after
1790  // the program was closed and restarted. Not an issue on windows!
1791  setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void *) &nOne, sizeof(int));
1792 #endif
1793 
1794  // Set to non-blocking, incoming connections will also inherit this
1795  if (!SetSocketNonBlocking(hListenSocket, true)) {
1796  strError = strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n",
1798  LogPrintf("%s\n", strError);
1799  return false;
1800  }
1801 
1802  // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1803  // and enable it by default or not. Try to enable it, if possible.
1804  if (addrBind.IsIPv6()) {
1805 #ifdef IPV6_V6ONLY
1806 #ifdef WIN32
1807  setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1808 #else
1809  setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1810 #endif
1811 #endif
1812 #ifdef WIN32
1813  int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1814  setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1815 #endif
1816  }
1817 
1818  if (::bind(hListenSocket, (struct sockaddr *) &sockaddr, len) == SOCKET_ERROR) {
1819  int nErr = WSAGetLastError();
1820  if (nErr == WSAEADDRINUSE)
1821  strError = strprintf(_("Unable to bind to %s on this computer. PRCY is probably already running."),
1822  addrBind.ToString());
1823  else
1824  strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"),
1825  addrBind.ToString(), NetworkErrorString(nErr));
1826  LogPrintf("%s\n", strError);
1827  CloseSocket(hListenSocket);
1828  return false;
1829  }
1830  LogPrintf("Bound to %s\n", addrBind.ToString());
1831 
1832  // Listen for incoming connections
1833  if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) {
1834  strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"),
1836  LogPrintf("%s\n", strError);
1837  CloseSocket(hListenSocket);
1838  return false;
1839  }
1840 
1841  vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
1842 
1843  if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
1844  AddLocal(addrBind, LOCAL_BIND);
1845 
1846  return true;
1847 }
1848 
1849 void static Discover(boost::thread_group &threadGroup) {
1850  if (!fDiscover)
1851  return;
1852 
1853 #ifdef WIN32
1854  // Get local host IP
1855  char pszHostName[256] = "";
1856  if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) {
1857  std::vector<CNetAddr> vaddr;
1858  if (LookupHost(pszHostName, vaddr, 0, true)) {
1859  for (const CNetAddr& addr : vaddr) {
1860  if (AddLocal(addr, LOCAL_IF))
1861  LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
1862  }
1863  }
1864  }
1865 #else
1866  // Get local host ip
1867  struct ifaddrs *myaddrs;
1868  if (getifaddrs(&myaddrs) == 0) {
1869  for (struct ifaddrs *ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) {
1870  if (ifa->ifa_addr == NULL) continue;
1871  if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1872  if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1873  if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1874  if (ifa->ifa_addr->sa_family == AF_INET) {
1875  struct sockaddr_in *s4 = (struct sockaddr_in *) (ifa->ifa_addr);
1876  CNetAddr addr(s4->sin_addr);
1877  if (AddLocal(addr, LOCAL_IF))
1878  LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1879  } else if (ifa->ifa_addr->sa_family == AF_INET6) {
1880  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) (ifa->ifa_addr);
1881  CNetAddr addr(s6->sin6_addr);
1882  if (AddLocal(addr, LOCAL_IF))
1883  LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
1884  }
1885  }
1886  freeifaddrs(myaddrs);
1887  }
1888 #endif
1889 }
1890 
1891 void StartNode(boost::thread_group &threadGroup, CScheduler &scheduler) {
1892  uiInterface.InitMessage(_("Loading addresses..."));
1893  // Load addresses from peers.dat
1894  int64_t nStart = GetTimeMillis();
1895  {
1896  CAddrDB adb;
1897  if (adb.Read(addrman))
1898  LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart);
1899  else {
1900  addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
1901  LogPrintf("Invalid or missing peers.dat; recreating\n");
1902  DumpAddresses();
1903  }
1904  }
1905 
1906  uiInterface.InitMessage(_("Loading banlist..."));
1907  // Load addresses from banlist.dat
1908  nStart = GetTimeMillis();
1909  CBanDB bandb;
1910  banmap_t banmap;
1911  if (bandb.Read(banmap)) {
1912  CNode::SetBanned(banmap); // thread save setter
1913  CNode::SetBannedSetDirty(false); // no need to write down, just read data
1914  CNode::SweepBanned(); // sweep out unused entries
1915 
1916  LogPrint(BCLog::NET, "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
1917  banmap.size(), GetTimeMillis() - nStart);
1918  } else {
1919  LogPrintf("Invalid or missing banlist.dat; recreating\n");
1920  CNode::SetBannedSetDirty(true); // force write
1921  DumpBanlist();
1922  }
1923  // Initialize random numbers. Even when rand() is only usable for trivial use-cases most nodes should have a different
1924  // seed after all the file-IO done at this point. Should be good enough even when nodes are started via scripts.
1925  srand(time(NULL));
1926 
1927  fAddressesInitialized = true;
1928 
1929  if (semOutbound == NULL) {
1930  // initialize semaphore
1931  int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections);
1932  semOutbound = new CSemaphore(nMaxOutbound);
1933  }
1934 
1935  if (pnodeLocalHost == NULL) {
1936  CNetAddr local;
1937  LookupHost("127.0.0.1", local, false);
1938  pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
1939  }
1940 
1941  Discover(threadGroup);
1942 
1943  //
1944  // Start threads
1945  //
1946 
1947  if (!GetBoolArg("-dnsseed", true))
1948  LogPrintf("DNS seeding disabled\n");
1949  else
1950  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1951 
1952  // Map ports with UPnP
1953  MapPort(GetBoolArg("-upnp", DEFAULT_UPNP));
1954 
1955  // Send and receive from sockets, accept connections
1956  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1957 
1958  // Initiate outbound connections from -addnode
1959  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1960 
1961  // Initiate outbound connections unless connect=0
1962  if (!mapArgs.count("-connect") || mapMultiArgs["-connect"].size() != 1 || mapMultiArgs["-connect"][0] != "0")
1963  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1964 
1965  // Process messages
1966  threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1967 
1968  // Dump network addresses
1970 }
1971 
1972 bool StopNode() {
1973  LogPrintf("StopNode()\n");
1974  MapPort(false);
1975  if (semOutbound)
1976  for (int i = 0; i < (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); i++)
1977  semOutbound->post();
1978 
1979  if (fAddressesInitialized) {
1980  DumpData();
1981  fAddressesInitialized = false;
1982  }
1983 
1984  return true;
1985 }
1986 
1988 public:
1990 
1992  // Close sockets
1993  for (CNode * pnode : vNodes)
1994  if (pnode->hSocket != INVALID_SOCKET)
1995  CloseSocket(pnode->hSocket);
1996  for (ListenSocket & hListenSocket : vhListenSocket)
1997  if (hListenSocket.socket != INVALID_SOCKET)
1998  if (!CloseSocket(hListenSocket.socket))
1999  LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2000 
2001  // clean up some globals (to help leak detection)
2002  for (CNode * pnode : vNodes)
2003  delete pnode;
2004  for (CNode * pnode : vNodesDisconnected)
2005  delete pnode;
2006  vNodes.clear();
2007  vNodesDisconnected.clear();
2008  vhListenSocket.clear();
2009  delete semOutbound;
2010  semOutbound = NULL;
2011  delete pnodeLocalHost;
2012  pnodeLocalHost = NULL;
2013 
2014 #ifdef WIN32
2015  // Shutdown Windows Sockets
2016  WSACleanup();
2017 #endif
2018  }
2020 
2022  // Explicit call to destructor of CNetCleanup because it's not implicitly called
2023  // when the wallet is restarted from within the wallet itself.
2024  CNetCleanup *tmp = new CNetCleanup();
2025  delete tmp; // Stroustrup's gonna kill me for that
2026 }
2027 
2029  CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
2030  ss.reserve(50000);
2031  ss << tx;
2032  RelayTransaction(tx, ss);
2033 }
2034 
2035 void RelayTransaction(const CTransaction &tx, const CDataStream &ss) {
2036  CInv inv(MSG_TX, tx.GetHash());
2037  {
2038  LOCK(cs_mapRelay);
2039  // Expire old relay messages
2040  while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) {
2041  mapRelay.erase(vRelayExpiration.front().second);
2042  vRelayExpiration.pop_front();
2043  }
2044 
2045  // Save original serialized message so newer versions are preserved
2046  mapRelay.insert(std::make_pair(inv, ss));
2047  vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
2048  }
2049  LOCK(cs_vNodes);
2050  for (CNode * pnode : vNodes)
2051  {
2052  if (!pnode->fRelayTxes)
2053  continue;
2054  LOCK(pnode->cs_filter);
2055  if (pnode->pfilter) {
2056  if (pnode->pfilter->IsRelevantAndUpdate(tx))
2057  pnode->PushInventory(inv);
2058  } else
2059  pnode->PushInventory(inv);
2060  }
2061 }
2062 
2063 void RelayTransactionLockReq(const CTransaction &tx, bool relayToAll) {
2064  CInv inv(MSG_TXLOCK_REQUEST, tx.GetHash());
2065 
2066  //broadcast the new lock
2067  LOCK(cs_vNodes);
2068  for (CNode * pnode : vNodes)
2069  {
2070  if (!relayToAll && !pnode->fRelayTxes)
2071  continue;
2072 
2073  pnode->PushMessage(NetMsgType::IX, tx);
2074  }
2075 }
2076 
2077 void RelayInv(CInv &inv) {
2078  LOCK(cs_vNodes);
2079  for (CNode * pnode : vNodes)
2080  {
2081  if ((pnode->nServices == NODE_BLOOM_WITHOUT_MN) && inv.IsMasterNodeType())continue;
2082  if (pnode->nVersion >= ActiveProtocol())
2083  pnode->PushInventory(inv);
2084  }
2085 }
2086 
2087 void CNode::RecordBytesRecv(uint64_t bytes) {
2089  nTotalBytesRecv += bytes;
2090 }
2091 
2092 void CNode::RecordBytesSent(uint64_t bytes) {
2094  nTotalBytesSent += bytes;
2095 }
2096 
2099  return nTotalBytesRecv;
2100 }
2101 
2104  return nTotalBytesSent;
2105 }
2106 
2107 void CNode::Fuzz(int nChance) {
2108  if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
2109  if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
2110 
2111  switch (GetRand(3)) {
2112  case 0:
2113  // xor a random byte with a random value:
2114  if (!ssSend.empty()) {
2116  ssSend[pos] ^= (unsigned char) (GetRand(256));
2117  }
2118  break;
2119  case 1:
2120  // delete a random byte:
2121  if (!ssSend.empty()) {
2123  ssSend.erase(ssSend.begin() + pos);
2124  }
2125  break;
2126  case 2:
2127  // insert a random byte at a random position
2128  {
2130  char ch = (char) GetRand(256);
2131  ssSend.insert(ssSend.begin() + pos, ch);
2132  }
2133  break;
2134  }
2135  // Chance of more than one change half the time:
2136  // (more changes exponentially less likely):
2137  Fuzz(2);
2138 }
2139 
2140 //
2141 // CAddrDB
2142 //
2143 
2145  pathAddr = GetDataDir() / "peers.dat";
2146 }
2147 
2148 bool CAddrDB::Write(const CAddrMan &addr) {
2149  // Generate random temporary filename
2150  unsigned short randv = 0;
2151  GetRandBytes((unsigned char *) &randv, sizeof(randv));
2152  std::string tmpfn = strprintf("peers.dat.%04x", randv);
2153 
2154  // serialize addresses, checksum data up to that point, then append csum
2155  CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
2156  ssPeers << FLATDATA(Params().MessageStart());
2157  ssPeers << addr;
2158  uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
2159  ssPeers << hash;
2160 
2161  // open output file, and associate with CAutoFile
2162  fs::path pathAddr = GetDataDir() / "peers.dat";
2163  FILE* file = fsbridge::fopen(pathAddr, "wb");
2164  CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
2165  if (fileout.IsNull())
2166  return error("%s : Failed to open file %s", __func__, pathAddr.string());
2167 
2168  // Write and commit header, data
2169  try {
2170  fileout << ssPeers;
2171  } catch (const std::exception& e) {
2172  return error("%s : Serialize or I/O error - %s", __func__, e.what());
2173  }
2174  FileCommit(fileout.Get());
2175  fileout.fclose();
2176 
2177  return true;
2178 }
2179 
2181  // open input file, and associate with CAutoFile
2182  FILE* file = fsbridge::fopen(pathAddr, "rb");
2183  CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
2184  if (filein.IsNull())
2185  return error("%s : Failed to open file %s", __func__, pathAddr.string());
2186 
2187  // use file size to size memory buffer
2188  uint64_t fileSize = fs::file_size(pathAddr);
2189  uint64_t dataSize = fileSize - sizeof(uint256);
2190  // Don't try to resize to a negative number if file is small
2191  if (fileSize >= sizeof(uint256))
2192  dataSize = fileSize - sizeof(uint256);
2193  else
2194  return error("%s : Failed to open file %s", __func__, pathAddr.string());
2195 
2196  std::vector<unsigned char> vchData;
2197  vchData.resize(dataSize);
2198  uint256 hashIn;
2199 
2200  // read data and checksum from file
2201  try {
2202  filein.read((char *) &vchData[0], dataSize);
2203  filein >> hashIn;
2204  } catch (const std::exception& e) {
2205  return error("%s : Deserialize or I/O error - %s", __func__, e.what());
2206  }
2207  filein.fclose();
2208 
2209  CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
2210 
2211  // verify stored checksum matches input data
2212  uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
2213  if (hashIn != hashTmp)
2214  return error("%s : Checksum mismatch, data corrupted", __func__);
2215 
2216  return Read(addr, ssPeers);
2217 }
2218 
2219 bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
2220 {
2221  unsigned char pchMsgTmp[4];
2222  try {
2223  // de-serialize file header (network specific magic number) and ..
2224  ssPeers >> FLATDATA(pchMsgTmp);
2225 
2226  // ... verify the network matches ours
2227  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2228  return error("%s : Invalid network magic number", __func__);
2229 
2230  // de-serialize address data into one CAddrMan object
2231  ssPeers >> addr;
2232  } catch (const std::exception& e) {
2233  // de-serialization has failed, ensure addrman is left in a clean state
2234  addr.Clear();
2235  return error("%s : Deserialize or I/O error - %s", __func__, e.what());
2236  }
2237 
2238  return true;
2239 }
2240 
2241 unsigned int ReceiveFloodSize() { return 1000 * GetArg("-maxreceivebuffer", 5 * 1000); }
2242 
2243 unsigned int SendBufferSize() { return 1000 * GetArg("-maxsendbuffer", 1 * 1000); }
2244 
2245 CNode::CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn, bool fInboundIn) :
2246  ssSend(SER_NETWORK, INIT_PROTO_VERSION),
2247  addrKnown(5000, 0.001),
2248  filterInventoryKnown(50000, 0.000001)
2249 {
2250  nServices = NODE_NONE;
2252  hSocket = hSocketIn;
2253  nRecvVersion = INIT_PROTO_VERSION;
2254  nLastSend = 0;
2255  nLastRecv = 0;
2256  nSendBytes = 0;
2257  nRecvBytes = 0;
2258  nTimeConnected = GetTime();
2259  nTimeOffset = 0;
2260  addr = addrIn;
2261  addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2262  nVersion = 0;
2263  strSubVer = "";
2264  fWhitelisted = false;
2265  fOneShot = false;
2266  fClient = false; // set by version message
2267  fFeeler = false;
2268  fInbound = fInboundIn;
2269  fNetworkNode = false;
2270  fSuccessfullyConnected = false;
2271  fDisconnect = false;
2272  nRefCount = 0;
2273  nSendSize = 0;
2274  nSendOffset = 0;
2276  nStartingHeight = -1;
2278  fGetAddr = false;
2279  nNextLocalAddrSend = 0;
2280  nNextAddrSend = 0;
2281  nNextInvSend = 0;
2282  fRelayTxes = false;
2283  pfilter = new CBloomFilter();
2284  nPingNonceSent = 0;
2285  nPingUsecStart = 0;
2286  nPingUsecTime = 0;
2287  fPingQueued = false;
2288  nMinPingUsecTime = std::numeric_limits<int64_t>::max();
2289 
2290  {
2292  id = nLastNodeId++;
2293  }
2294 
2295  if (fLogIPs)
2296  LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
2297  else
2298  LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
2299 
2300  // Be shy and don't send version until we hear
2301  if (hSocket != INVALID_SOCKET && !fInbound)
2302  PushVersion();
2303 
2304  GetNodeSignals().InitializeNode(GetId(), this);
2305 }
2306 
2309 
2310  if (pfilter)
2311  delete pfilter;
2312 
2314 }
2315 
2316 void CNode::AskFor(const CInv &inv, bool fImmediateRetry) {
2317  if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
2318  return;
2319  // We're using mapAskFor as a priority queue,
2320  // the key is the earliest time the request can be sent
2321  int64_t nRequestTime;
2323  if (it != mapAlreadyAskedFor.end())
2324  nRequestTime = it->second;
2325  else
2326  nRequestTime = 0;
2327  LogPrint(BCLog::NET, "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime,
2328  DateTimeStrFormat("%H:%M:%S", nRequestTime / 1000000), id);
2329  //LogPrintf("askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime,
2330  //DateTimeStrFormat("%H:%M:%S", nRequestTime / 1000000), id);
2331  // Make sure not to reuse time indexes to keep things in the same order
2332  int64_t nNow = GetTimeMicros() - 1000000;
2333  static int64_t nLastTime;
2334  ++nLastTime;
2335  nNow = std::max(nNow, nLastTime);
2336  nLastTime = nNow;
2337 
2338  // Each retry is 2 minutes after the last
2339  nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2340  if (fImmediateRetry)
2341  nRequestTime = nNow;
2342  else
2343  nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2344  if (it != mapAlreadyAskedFor.end())
2345  mapAlreadyAskedFor.update(it, nRequestTime);
2346  else
2347  mapAlreadyAskedFor.insert(std::make_pair(inv, nRequestTime));
2348  mapAskFor.insert(std::make_pair(nRequestTime, inv));
2349 }
2350 
2351 void CNode::BeginMessage(const char *pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend) {
2352  ENTER_CRITICAL_SECTION(cs_vSend);
2353  assert(ssSend.size() == 0);
2354  ssSend << CMessageHeader(pszCommand, 0);
2355  LogPrint(BCLog::NET, "sending: %s ", SanitizeString(pszCommand));
2356 }
2357 
2359  ssSend.clear();
2360 
2362 
2363  LogPrint(BCLog::NET, "(aborted)\n");
2364 }
2365 
2367  // The -*messagestest options are intentionally not documented in the help message,
2368  // since they are only used during development to debug the networking code and are
2369  // not intended for end-users.
2370  if (mapArgs.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0) {
2371  LogPrint(BCLog::NET, "dropmessages DROPPING SEND MESSAGE\n");
2372  AbortMessage();
2373  return;
2374  }
2375  if (mapArgs.count("-fuzzmessagestest"))
2376  Fuzz(GetArg("-fuzzmessagestest", 10));
2377 
2378  if (ssSend.size() == 0) {
2380  return;
2381  }
2382 
2383  // Set the size
2384  unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
2385  WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
2386 
2387  // Set the checksum
2389  unsigned int nChecksum = 0;
2390  memcpy(&nChecksum, &hash, sizeof(nChecksum));
2391  assert(ssSend.size() >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
2392  memcpy((char *) &ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum, sizeof(nChecksum));
2393 
2394  LogPrint(BCLog::NET, "(%d bytes) peer=%d\n", nSize, id);
2395 
2396  std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(), CSerializeData());
2397  ssSend.GetAndClear(*it);
2398  nSendSize += (*it).size();
2399 
2400  // If write queue empty, attempt "optimistic write"
2401  if (it == vSendMsg.begin())
2402  SocketSendData(this);
2403 
2405 }
2406 
2407 //
2408 // CBanDB
2409 //
2410 
2412  pathBanlist = GetDataDir() / "banlist.dat";
2413 }
2414 
2415 bool CBanDB::Write(const banmap_t &banSet) {
2416  // Generate random temporary filename
2417  unsigned short randv = 0;
2418  GetRandBytes((unsigned char *) &randv, sizeof(randv));
2419  std::string tmpfn = strprintf("banlist.dat.%04x", randv);
2420  // serialize banlist, checksum data up to that point, then append csum
2421  CDataStream ssBanlist(SER_DISK, CLIENT_VERSION);
2422  ssBanlist << FLATDATA(Params().MessageStart());
2423  ssBanlist << banSet;
2424  uint256 hash = Hash(ssBanlist.begin(), ssBanlist.end());
2425  ssBanlist << hash;
2426  // open temp output file, and associate with CAutoFile
2427  fs::path pathTmp = GetDataDir() / tmpfn;
2428  FILE *file = fsbridge::fopen(pathTmp, "wb");
2429  CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
2430  if (fileout.IsNull())
2431  return error("%s: Failed to open file %s", __func__, pathTmp.string());
2432  // Write and commit header, data
2433  try {
2434  fileout << ssBanlist;
2435  }
2436  catch (const std::exception& e) {
2437  return error("%s: Serialize or I/O error - %s", __func__, e.what());
2438  }
2439  FileCommit(fileout.Get());
2440  fileout.fclose();
2441  // replace existing banlist.dat, if any, with new banlist.dat.XXXX
2442  if (!RenameOver(pathTmp, pathBanlist))
2443  return error("%s: Rename-into-place failed", __func__);
2444  return true;
2445 }
2446 
2447 bool CBanDB::Read(banmap_t &banSet) {
2448  // open input file, and associate with CAutoFile
2449  FILE *file = fsbridge::fopen(pathBanlist, "rb");
2450  CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
2451  if (filein.IsNull())
2452  return error("%s: Failed to open file %s", __func__, pathBanlist.string());
2453  // use file size to size memory buffer
2454  uint64_t fileSize = fs::file_size(pathBanlist);
2455  uint64_t dataSize = 0;
2456  // Don't try to resize to a negative number if file is small
2457  if (fileSize >= sizeof(uint256))
2458  dataSize = fileSize - sizeof(uint256);
2459  std::vector<unsigned char> vchData;
2460  vchData.resize(dataSize);
2461  uint256 hashIn;
2462  // read data and checksum from file
2463  try {
2464  filein.read((char *) &vchData[0], dataSize);
2465  filein >> hashIn;
2466  }
2467  catch (const std::exception& e) {
2468  return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2469  }
2470  filein.fclose();
2471  CDataStream ssBanlist(vchData, SER_DISK, CLIENT_VERSION);
2472  // verify stored checksum matches input data
2473  uint256 hashTmp = Hash(ssBanlist.begin(), ssBanlist.end());
2474  if (hashIn != hashTmp)
2475  return error("%s: Checksum mismatch, data corrupted", __func__);
2476  unsigned char pchMsgTmp[4];
2477  try {
2478  // de-serialize file header (network specific magic number) and ..
2479  ssBanlist >> FLATDATA(pchMsgTmp);
2480  // ... verify the network matches ours
2481  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2482  return error("%s: Invalid network magic number", __func__);
2483  // de-serialize address data into one CAddrMan object
2484  ssBanlist >> banSet;
2485  }
2486  catch (const std::exception& e) {
2487  return error("%s: Deserialize or I/O error - %s", __func__, e.what());
2488  }
2489  return true;
2490 }
2491 
2492 // valid, reachable and routable address (except for RegTest)
2493 bool validateMasternodeIP(const std::string& addrStr)
2494 {
2495  CNetAddr resolved;
2496  if (LookupHost(addrStr.c_str(), resolved, false)) {
2497  return ((IsReachable(resolved) && resolved.IsRoutable()) ||
2498  (Params().IsRegTestNet() && resolved.IsValid()));
2499  }
2500  return false;
2501 }
2502 
2503 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
2504  return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
2505 }
CNetAddr::IsIPv6
bool IsIPv6() const
Definition: netaddress.cpp:85
CNetMessage::readData
int readData(const char *pch, unsigned int nBytes)
Definition: net.cpp:745
CNode::addrLocal
CService addrLocal
Definition: net.h:334
NodeId
int64_t NodeId
Definition: net.h:92
WSAEADDRINUSE
#define WSAEADDRINUSE
Definition: compat.h:53
mapRelay
std::map< CInv, CDataStream > mapRelay
Definition: net.cpp:87
CService
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:133
CNode::filterInventoryKnown
CRollingBloomFilter filterInventoryKnown
Definition: net.h:390
BanReason
BanReason
Definition: net.h:244
CService::GetSockAddr
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Definition: netaddress.cpp:514
CBanDB::Read
bool Read(banmap_t &banSet)
Definition: net.cpp:2447
CNetMessage::nDataPos
unsigned int nDataPos
Definition: net.h:214
UINT256_ZERO
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:129
ConnectNode
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
Definition: net.cpp:342
CNode::cs_filter
RecursiveMutex cs_filter
Definition: net.h:355
CScheduler
Definition: scheduler.h:37
vNodes
std::vector< CNode * > vNodes
Definition: net.cpp:85
fLogIPs
bool fLogIPs
Definition: logging.cpp:30
SendBufferSize
unsigned int SendBufferSize()
Definition: net.cpp:2243
CDataStream::size_type
vector_type::size_type size_type
Definition: streams.h:46
GetRandInt
int GetRandInt(int nMax)
Definition: random.cpp:366
CNode::cs_inventory
RecursiveMutex cs_inventory
Definition: net.h:392
BanReasonManuallyAdded
@ BanReasonManuallyAdded
Definition: net.h:248
CNode::fWhitelisted
bool fWhitelisted
Definition: net.h:341
NET_UNROUTABLE
@ NET_UNROUTABLE
Definition: netaddress.h:21
CNode::nRecvVersion
int nRecvVersion
Definition: net.h:326
CDNSSeedData::host
std::string host
Definition: chainparams.h:24
CSHA256::Write
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:141
CNode::nSendOffset
size_t nSendOffset
Definition: net.h:315
CompareNetGroupKeyed
Definition: net.cpp:824
LOCAL_IF
@ LOCAL_IF
Definition: net.h:124
CAutoFile::read
CAutoFile & read(char *pch, size_t nSize)
Definition: streams.h:367
GetTime
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:19
CNode::GetRefCount
int GetRefCount()
Definition: net.h:428
CBanDB::pathBanlist
fs::path pathBanlist
Definition: net.h:789
CSemaphore::post
void post()
Definition: sync.h:237
CNodeStats::addrLocal
std::string addrLocal
Definition: net.h:199
nLastNodeId
NodeId nLastNodeId
Definition: net.cpp:98
CNode::nServices
ServiceFlags nServices
Definition: net.h:310
CNode::GetId
NodeId GetId() const
Definition: net.h:423
transaction.h
RelayTransactionLockReq
void RelayTransactionLockReq(const CTransaction &tx, bool relayToAll)
Definition: net.cpp:2063
FLATDATA
#define FLATDATA(obj)
Definition: serialize.h:365
CNode::vSendMsg
std::deque< CSerializeData > vSendMsg
Definition: net.h:317
CNodeStats::nodeid
NodeId nodeid
Definition: net.h:183
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
AddressCurrentlyConnected
void AddressCurrentlyConnected(const CService &addr)
Definition: net.cpp:291
CAddrDB::CAddrDB
CAddrDB()
Definition: net.cpp:2144
CNode::SweepBanned
static void SweepBanned()
clean unused entires (if bantime has expired)
Definition: net.cpp:584
fsbridge::fopen
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:13
CNode::SetBannedSetDirty
static void SetBannedSetDirty(bool dirty=true)
set the "dirty" flag for the banlist
Definition: net.cpp:616
CNode::DisconnectOldProtocol
bool DisconnectOldProtocol(int nVersionRequired, std::string strLastCommand="")
Definition: net.cpp:430
NODE_BLOOM_WITHOUT_MN
@ NODE_BLOOM_WITHOUT_MN
Definition: protocol.h:311
cs_vAddedNodes
RecursiveMutex cs_vAddedNodes
Definition: net.cpp:96
CBloomFilter
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
Definition: bloom.h:43
WSAEMSGSIZE
#define WSAEMSGSIZE
Definition: compat.h:50
CDataStream::begin
const_iterator begin() const
Definition: streams.h:116
CNode::Release
void Release()
Definition: net.h:460
CNodeSignals::FinalizeNode
boost::signals2::signal< void(NodeId)> FinalizeNode
Definition: net.h:115
limitedmap::const_iterator
std::map< K, V >::const_iterator const_iterator
Definition: limitedmap.h:19
CAddrMan::Add
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
Definition: addrman.h:505
EXCLUSIVE_LOCK_FUNCTION
#define EXCLUSIVE_LOCK_FUNCTION(...)
Definition: threadsafety.h:43
CNode::nTotalBytesRecv
static uint64_t nTotalBytesRecv
Definition: net.h:416
WSAEINPROGRESS
#define WSAEINPROGRESS
Definition: compat.h:52
CNode::nPingUsecTime
int64_t nPingUsecTime
Definition: net.h:403
UNLOCK_FUNCTION
#define UNLOCK_FUNCTION(...)
Definition: threadsafety.h:47
uiInterface
CClientUIInterface uiInterface
Definition: init.cpp:101
CNetMessage::nTime
int64_t nTime
Definition: net.h:216
CNode::GetTotalBytesRecv
static uint64_t GetTotalBytesRecv()
Definition: net.cpp:2097
CNode::cs_vWhitelistedRange
static RecursiveMutex cs_vWhitelistedRange
Definition: net.h:372
CAutoFile::Get
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:351
CNetAddr
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:30
NET_MAX
@ NET_MAX
Definition: netaddress.h:26
LocalServiceInfo::nPort
int nPort
Definition: net.h:174
mapArgs
std::map< std::string, std::string > mapArgs
Definition: util.cpp:111
CNode::setBannedIsDirty
static bool setBannedIsDirty
Definition: net.h:365
ThreadDNSAddressSeed
void ThreadDNSAddressSeed()
Definition: net.cpp:1377
CBanDB::Write
bool Write(const banmap_t &banSet)
Definition: net.cpp:2415
limitedmap
STL-like map container that only keeps the N elements with the highest value.
Definition: limitedmap.h:13
instance_of_cnetcleanup
class CNetCleanup instance_of_cnetcleanup
CNode::Fuzz
void Fuzz(int nChance)
Definition: net.cpp:2107
CNode
Information about a peer.
Definition: net.h:306
FileCommit
void FileCommit(FILE *fileout)
Definition: util.cpp:477
GetnScore
int GetnScore(const CService &addr)
Definition: net.cpp:174
nConnectTimeout
int nConnectTimeout
Definition: netbase.cpp:45
CNode::addr
CAddress addr
Definition: net.h:332
CSemaphoreGrant::MoveTo
void MoveTo(CSemaphoreGrant &grant)
Definition: sync.h:278
NetMsgType::IX
const char * IX
The ix message transmits a single SwiftX transaction.
Definition: protocol.cpp:48
CClientUIInterface::BannedListChanged
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
Definition: guiinterface.h:110
GetAddedNodeInfo
std::vector< AddedNodeInfo > GetAddedNodeInfo()
Definition: net.cpp:1593
SeenLocal
bool SeenLocal(const CService &addr)
vote for a local address
Definition: net.cpp:262
CNode::PushInventory
void PushInventory(const CInv &inv)
Definition: net.h:494
CompareNetGroupKeyed::vchSecretKey
std::vector< unsigned char > vchSecretKey
Definition: net.cpp:826
CNetAddr::GetGroup
std::vector< unsigned char > GetGroup() const
Definition: netaddress.cpp:301
CNetAddr::ToString
std::string ToString() const
Definition: netaddress.cpp:265
FEELER_SLEEP_WINDOW
#define FEELER_SLEEP_WINDOW
Definition: net.cpp:47
CNode::fSuccessfullyConnected
bool fSuccessfullyConnected
Definition: net.h:347
CNode::BeginMessage
void BeginMessage(const char *pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
Definition: net.cpp:2351
CNode::nRefCount
int nRefCount
Definition: net.h:357
CAddrMan::Select
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
Definition: addrman.h:553
CNode::AbortMessage
void AbortMessage() UNLOCK_FUNCTION(cs_vSend)
Definition: net.cpp:2358
CNode::nNextLocalAddrSend
int64_t nNextLocalAddrSend
Definition: net.h:387
AnnotatedMixin< std::recursive_mutex >
CNode::copyStats
void copyStats(CNodeStats &stats)
Definition: net.cpp:641
CNetCleanup::~CNetCleanup
~CNetCleanup()
Definition: net.cpp:1991
StopNode
bool StopNode()
Definition: net.cpp:1972
CNode::nSendBytes
uint64_t nSendBytes
Definition: net.h:316
clientversion.h
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
CAddress::nTime
unsigned int nTime
Definition: protocol.h:354
ServiceFlags
ServiceFlags
nServices flags
Definition: protocol.h:296
CNode::hashContinue
uint256 hashContinue
Definition: net.h:378
CAddress::nServices
ServiceFlags nServices
Definition: protocol.h:351
SetThreadPriority
void SetThreadPriority(int nPriority)
Definition: util.cpp:648
CNode::cs_vSend
RecursiveMutex cs_vSend
Definition: net.h:318
cs_vNodes
RecursiveMutex cs_vNodes
Definition: net.cpp:86
CNode::nTimeOffset
int64_t nTimeOffset
Definition: net.h:331
TRY_LOCK
#define TRY_LOCK(cs, name)
Definition: sync.h:186
fDiscover
bool fDiscover
Definition: net.cpp:71
CNode::Ban
static void Ban(const CNetAddr &ip, const BanReason &banReason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
Definition: net.cpp:522
ConnectSocket
bool ConnectSocket(const CService &addrDest, SOCKET &hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
Definition: netbase.cpp:627
SOCKET
u_int SOCKET
Definition: compat.h:44
LOCAL_BIND
@ LOCAL_BIND
Definition: net.h:125
DateTimeStrFormat
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
Definition: utiltime.cpp:50
NODE_NETWORK
@ NODE_NETWORK
Definition: protocol.h:302
CMessageHeader::HEADER_SIZE
@ HEADER_SIZE
Definition: protocol.h:58
SanitizeString
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
Definition: utilstrencodings.cpp:32
CInv
inv message data
Definition: protocol.h:358
chainparams.h
WSAGetLastError
#define WSAGetLastError()
Definition: compat.h:46
guiinterface.h
messageHandlerCondition
boost::condition_variable messageHandlerCondition
Definition: net.cpp:102
CAddrDB::Write
bool Write(const CAddrMan &addr)
Definition: net.cpp:2148
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:159
NetworkErrorString
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: netbase.cpp:718
Network
Network
Definition: netaddress.h:19
CChainParams::IsRegTestNet
bool IsRegTestNet() const
Definition: chainparams.h:104
cs_vOneShots
RecursiveMutex cs_vOneShots
Definition: net.cpp:93
MSG_TX
@ MSG_TX
Definition: protocol.h:388
CNode::fDisconnect
std::atomic_bool fDisconnect
Definition: net.h:348
CNode::GetTotalRecvSize
unsigned int GetTotalRecvSize()
Definition: net.h:435
FindNode
CNode * FindNode(const CNetAddr &ip)
Definition: net.cpp:301
CNode::ssSend
CDataStream ssSend
Definition: net.h:313
CDataStream::insert
iterator insert(iterator it, const char &x=char())
Definition: streams.h:131
CService::ToStringIPPort
std::string ToStringIPPort() const
Definition: netaddress.cpp:559
CSubNet::Match
bool Match(const CNetAddr &addr) const
Definition: netaddress.cpp:634
scheduler.h
CNode::cs_totalBytesRecv
static RecursiveMutex cs_totalBytesRecv
Definition: net.h:414
CNode::PushVersion
void PushVersion()
Definition: net.cpp:461
CNode::PushMessage
void PushMessage(const char *pszCommand)
Definition: net.h:518
cs_mapRelay
RecursiveMutex cs_mapRelay
Definition: net.cpp:89
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:269
CNetMessage::readHeader
int readHeader(const char *pch, unsigned int nBytes)
Definition: net.cpp:716
CNode::nVersion
int nVersion
Definition: net.h:335
CNode::fRelayTxes
bool fRelayTxes
Definition: net.h:353
CAddrDB
Access to the (IP) address database (peers.dat)
Definition: net.h:773
r
void const uint64_t uint64_t * r
Definition: field_5x52_asm_impl.h:10
CNode::nTimeConnected
int64_t nTimeConnected
Definition: net.h:330
CMessageHeader::MESSAGE_SIZE_OFFSET
@ MESSAGE_SIZE_OFFSET
Definition: protocol.h:56
CAutoFile
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:303
HaveNameProxy
bool HaveNameProxy()
Definition: netbase.cpp:586
CAddrInfo
Extended statistics about a CAddress.
Definition: addrman.h:25
GetLocalAddress
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
Definition: net.cpp:164
CSemaphore
Definition: sync.h:211
GetRand
uint64_t GetRand(uint64_t nMax)
Definition: random.cpp:351
AddOneShot
void AddOneShot(std::string strDest)
Definition: net.cpp:109
CClientUIInterface::InitMessage
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: guiinterface.h:83
IsProxy
bool IsProxy(const CNetAddr &addr)
Definition: netbase.cpp:592
CInv::IsMasterNodeType
bool IsMasterNodeType() const
Definition: protocol.cpp:240
CNode::SetBanned
static void SetBanned(const banmap_t &banmap)
Definition: net.cpp:578
ActiveProtocol
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
Definition: main.cpp:6844
CSemaphoreGrant
RAII-style semaphore lock.
Definition: sync.h:248
CNode::nPingUsecStart
int64_t nPingUsecStart
Definition: net.h:401
ENTER_CRITICAL_SECTION
#define ENTER_CRITICAL_SECTION(cs)
Definition: sync.h:189
CNetAddr::GetNetwork
enum Network GetNetwork() const
Definition: netaddress.cpp:229
CNode::fNetworkNode
bool fNetworkNode
Definition: net.h:346
CNode::pfilter
CBloomFilter * pfilter
Definition: net.h:356
CService::ToString
std::string ToString() const
Definition: netaddress.cpp:568
CDNSSeedData::supportsServiceBitsFiltering
bool supportsServiceBitsFiltering
Definition: chainparams.h:25
CNode::GetBanned
static void GetBanned(banmap_t &banmap)
Definition: net.cpp:573
CNode::fInbound
bool fInbound
Definition: net.h:345
DUMP_ADDRESSES_INTERVAL
#define DUMP_ADDRESSES_INTERVAL
Definition: net.cpp:44
IsPeerAddrLocalGood
bool IsPeerAddrLocalGood(CNode *pnode)
Definition: net.cpp:182
CNode::cs_totalBytesSent
static RecursiveMutex cs_totalBytesSent
Definition: net.h:415
CMessageHeader::CHECKSUM_OFFSET
@ CHECKSUM_OFFSET
Definition: protocol.h:57
ThreadOpenConnections
void ThreadOpenConnections()
Definition: net.cpp:1461
NodeEvictionCandidate
Definition: net.cpp:806
CNode::fFeeler
bool fFeeler
Definition: net.h:342
BindListenPort
bool BindListenPort(const CService &addrBind, std::string &strError, bool fWhitelisted)
Definition: net.cpp:1757
CNode::Unban
static bool Unban(const CNetAddr &ip)
Definition: net.cpp:556
GetLocal
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
Definition: net.cpp:119
CNode::vRecvGetData
std::deque< CInv > vRecvGetData
Definition: net.h:322
prcycoin-config.h
INVALID_SOCKET
#define INVALID_SOCKET
Definition: compat.h:55
_
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
Definition: guiinterface.h:119
GetRandBytes
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
Definition: random.cpp:273
IsReachable
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
Definition: net.cpp:280
NodeEvictionCandidate::id
NodeId id
Definition: net.cpp:808
CService::SetSockAddr
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:480
CNode::AddRef
CNode * AddRef()
Definition: net.h:454
CNetMessage::complete
bool complete() const
Definition: net.h:227
CNode::RecordBytesRecv
static void RecordBytesRecv(uint64_t bytes)
Definition: net.cpp:2087
CNodeStats::dPingTime
double dPingTime
Definition: net.h:197
cs_mapLocalHost
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:74
DumpAddresses
void DumpAddresses()
Definition: net.cpp:1429
LookupHost
bool LookupHost(const char *pszName, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Definition: netbase.cpp:184
CNetAddr::IsRoutable
bool IsRoutable() const
Definition: netaddress.cpp:224
CNode::fGetAddr
bool fGetAddr
Definition: net.h:384
CompareNetGroupKeyed::operator()
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:834
CRollingBloomFilter::reset
void reset()
Definition: bloom.cpp:254
CDataStream::end
const_iterator end() const
Definition: streams.h:118
GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:255
RelayInv
void RelayInv(CInv &inv)
Definition: net.cpp:2077
AddedNodeInfo
Definition: net.h:796
LOCAL_UPNP
@ LOCAL_UPNP
Definition: net.h:126
LogPrintf
#define LogPrintf(...)
Definition: logging.h:147
CBanEntry::banReason
uint8_t banReason
Definition: net.h:258
MSG_TXLOCK_REQUEST
@ MSG_TXLOCK_REQUEST
Definition: protocol.h:393
CDataStream::erase
iterator erase(iterator it)
Definition: streams.h:158
CDataStream::GetAndClear
void GetAndClear(CSerializeData &data)
Definition: streams.h:289
CNode::DisconnectOldVersion
bool DisconnectOldVersion(std::string strSubVer, int nHeight, std::string strLastCommand="")
Definition: net.cpp:442
GetNodeSignals
CNodeSignals & GetNodeSignals()
Definition: net.cpp:107
CNode::setBanned
static banmap_t setBanned
Definition: net.h:363
CNetAddr::IsValid
bool IsValid() const
Definition: netaddress.cpp:188
CSubNet
Definition: netaddress.h:95
CNetCleanup
Definition: net.cpp:1987
SER_DISK
@ SER_DISK
Definition: serialize.h:160
CAddrInfo::nLastTry
int64_t nLastTry
last try whatsoever by us (memory only)
Definition: addrman.h:31
CNode::vRecvMsg
std::deque< CNetMessage > vRecvMsg
Definition: net.h:323
cs_nLastNodeId
RecursiveMutex cs_nLastNodeId
Definition: net.cpp:99
CAutoFile::IsNull
bool IsNull() const
Return true if the wrapped FILE* is NULL, false otherwise.
Definition: streams.h:355
CNode::AddWhitelistedRange
static void AddWhitelistedRange(const CSubNet &subnet)
Definition: net.cpp:633
SOCKET_ERROR
#define SOCKET_ERROR
Definition: compat.h:56
CSerializeData
std::vector< char, zero_after_free_allocator< char > > CSerializeData
Definition: allocators.h:265
CNode::RecordBytesSent
static void RecordBytesSent(uint64_t bytes)
Definition: net.cpp:2092
RemoveLocal
bool RemoveLocal(const CService &addr)
Definition: net.cpp:237
GetListenPort
unsigned short GetListenPort()
Definition: net.cpp:114
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
CSHA256::Finalize
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:167
banmap_t
std::map< CSubNet, CBanEntry > banmap_t
Definition: net.h:302
CNode::EndMessage
void EndMessage() UNLOCK_FUNCTION(cs_vSend)
Definition: net.cpp:2366
CService::GetPort
unsigned short GetPort() const
Definition: netaddress.cpp:494
CNode::AskFor
void AskFor(const CInv &inv, bool fImmediateRetry=false)
Definition: net.cpp:2316
LogPrint
#define LogPrint(category,...)
Definition: logging.h:162
NetMsgType::REJECT
const char * REJECT
The reject message informs the receiving node that one of its previous messages has been rejected.
Definition: protocol.cpp:46
AdvertiseLocal
void AdvertiseLocal(CNode *pnode)
Definition: net.cpp:188
addrman
CAddrMan addrman
Definition: net.cpp:80
WSAEWOULDBLOCK
#define WSAEWOULDBLOCK
Definition: compat.h:49
CBanDB
Access to the banlist database (banlist.dat)
Definition: net.h:786
CAutoFile::fclose
void fclose()
Definition: streams.h:328
CNode::PushAddress
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
Definition: net.h:471
CNode::grantOutbound
CSemaphoreGrant grantOutbound
Definition: net.h:354
CDataStream::reserve
void reserve(size_type n)
Definition: streams.h:123
CNodeSignals::SendMessages
boost::signals2::signal< bool(CNode *), CombinerAll > SendMessages
Definition: net.h:113
CDataStream::size
size_type size() const
Definition: streams.h:120
mapLocalHost
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
Definition: net.cpp:75
NodeEvictionCandidate::addr
CAddress addr
Definition: net.cpp:811
NODE_NONE
@ NODE_NONE
Definition: protocol.h:298
CNode::ClearBanned
static void ClearBanned()
Definition: net.cpp:484
NodeEvictionCandidate::nTimeConnected
int64_t nTimeConnected
Definition: net.cpp:809
RelayTransaction
void RelayTransaction(const CTransaction &tx)
Definition: net.cpp:2028
CNode::ReceiveMsgBytes
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes)
Definition: net.cpp:680
CNode::nRecvBytes
uint64_t nRecvBytes
Definition: net.h:325
GetTimeMillis
int64_t GetTimeMillis()
Definition: utiltime.cpp:31
CNode::IsWhitelistedRange
static bool IsWhitelistedRange(const CNetAddr &ip)
Definition: net.cpp:624
CNode::nServicesExpected
ServiceFlags nServicesExpected
Definition: net.h:311
CNodeStats::dPingWait
double dPingWait
Definition: net.h:198
strprintf
#define strprintf
Definition: tinyformat.h:1056
CAddrMan
Stochastical (IP) address manager.
Definition: addrman.h:182
CScheduler::scheduleEvery
void scheduleEvery(Function f, int64_t deltaSeconds)
Definition: scheduler.cpp:95
CNetMessage::in_data
bool in_data
Definition: net.h:207
strSubVersion
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:83
CBanDB::CBanDB
CBanDB()
Definition: net.cpp:2411
GetAdjustedTime
int64_t GetAdjustedTime()
Definition: timedata.cpp:30
GetTimeMicros
int64_t GetTimeMicros()
Definition: utiltime.cpp:38
CNode::cs_sendProcessing
RecursiveMutex cs_sendProcessing
Definition: net.h:320
LOCAL_MANUAL
@ LOCAL_MANUAL
Definition: net.h:127
LocalServiceInfo::nScore
int nScore
Definition: net.h:173
CompareNetGroupKeyed::CompareNetGroupKeyed
CompareNetGroupKeyed()
Definition: net.cpp:828
CAddress
A CService with information about it as peer.
Definition: protocol.h:323
CMessageHeader
Message header.
Definition: protocol.h:29
common.h
LocalServiceInfo
Definition: net.h:172
CNode::GetTotalBytesSent
static uint64_t GetTotalBytesSent()
Definition: net.cpp:2102
ConnectSocketByName
bool ConnectSocketByName(CService &addr, SOCKET &hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
Definition: netbase.cpp:639
CDataStream::clear
void clear()
Definition: streams.h:126
CNetCleanup::CNetCleanup
CNetCleanup()
Definition: net.cpp:1989
main.h
CSubNet::ToString
std::string ToString() const
Definition: netaddress.cpp:660
CNode::fPingQueued
bool fPingQueued
Definition: net.h:407
X
#define X(name)
Definition: net.cpp:639
LOCK
#define LOCK(cs)
Definition: sync.h:182
nLocalServices
ServiceFlags nLocalServices
Definition: net.cpp:73
SetLimited
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
Definition: net.cpp:245
CNode::hSocket
SOCKET hSocket
Definition: net.h:312
LOCAL_NONE
@ LOCAL_NONE
Definition: net.h:123
SocketSendData
void SocketSendData(CNode *pnode)
Definition: net.cpp:762
MSG_NOSIGNAL
#define MSG_NOSIGNAL
Definition: compat.h:70
CNode::CNode
CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn="", bool fInboundIn=false)
Definition: net.cpp:2245
CSemaphoreGrant::Release
void Release()
Definition: sync.h:263
CNode::CloseSocketDisconnect
void CloseSocketDisconnect()
Definition: net.cpp:417
nLocalHostNonce
uint64_t nLocalHostNonce
Definition: net.cpp:78
CAddrMan::Connected
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
Definition: addrman.h:579
CNode::nNextInvSend
int64_t nNextInvSend
Definition: net.h:395
IsLimited
bool IsLimited(enum Network net)
Definition: net.cpp:252
RenameOver
bool RenameOver(fs::path src, fs::path dest)
Definition: util.cpp:448
CNode::cs_setBanned
static RecursiveMutex cs_setBanned
Definition: net.h:364
CNetMessage
Definition: net.h:204
fAddressesInitialized
bool fAddressesInitialized
Definition: net.cpp:82
OpenNetworkConnection
bool OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler)
Definition: net.cpp:1670
CBanEntry
Definition: net.h:251
CDataStream::resize
void resize(size_type n, value_type c=0)
Definition: streams.h:122
CAddrMan::Clear
void Clear()
Definition: addrman.h:453
LookupNumeric
CService LookupNumeric(const char *pszName, int portDefault)
Definition: netbase.cpp:234
CNetMessage::vRecv
CDataStream vRecv
Definition: net.h:213
ProcessMessages
bool ProcessMessages(CNode *pfrom)
Process protocol messages received from a given node.
Definition: main.cpp:6849
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:349
CNode::nPingNonceSent
uint64_t nPingNonceSent
Definition: net.h:399
CBanEntry::nBanUntil
int64_t nBanUntil
Definition: net.h:257
PoissonNextSend
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
Definition: net.cpp:2503
CSHA256
A hasher class for SHA-256.
Definition: sha256.h:12
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
CNetMessage::hdrbuf
CDataStream hdrbuf
Definition: net.h:209
CNode::nTotalBytesSent
static uint64_t nTotalBytesSent
Definition: net.h:417
SetSocketNonBlocking
bool SetSocketNonBlocking(SOCKET &hSocket, bool fNonBlocking)
Disable or enable blocking-mode for a socket.
Definition: netbase.cpp:751
CNode::addrName
std::string addrName
Definition: net.h:333
CAddrDB::Read
bool Read(CAddrMan &addr)
Definition: net.cpp:2180
WSAEINTR
#define WSAEINTR
Definition: compat.h:51
MilliSleep
void MilliSleep(int64_t n)
Definition: utiltime.cpp:45
vRelayExpiration
std::deque< std::pair< int64_t, CInv > > vRelayExpiration
Definition: net.cpp:88
CNode::fOneShot
bool fOneShot
Definition: net.h:343
TraceThread
void TraceThread(const char *name, Callable func)
Definition: util.h:169
StartNode
void StartNode(boost::thread_group &threadGroup, CScheduler &scheduler)
Definition: net.cpp:1891
DumpData
void DumpData()
Definition: net.cpp:1439
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:34
addrman.h
CNode::nMinPingUsecTime
int64_t nMinPingUsecTime
Definition: net.h:405
CMessageHeader::nMessageSize
unsigned int nMessageSize
Definition: protocol.h:62
CAddrMan::size
int size()
Return the number of (unique) addresses in all tables.
Definition: addrman.h:485
THREAD_PRIORITY_BELOW_NORMAL
#define THREAD_PRIORITY_BELOW_NORMAL
Definition: compat.h:79
CNode::nNextAddrSend
int64_t nNextAddrSend
Definition: net.h:386
vAddedNodes
std::vector< std::string > vAddedNodes
Definition: net.cpp:95
CNode::nLastSend
int64_t nLastSend
Definition: net.h:328
CNode::id
NodeId id
Definition: net.h:358
CTransaction::GetHash
const uint256 & GetHash() const
Definition: transaction.h:342
NodeEvictionCandidate::nMinPingUsecTime
int64_t nMinPingUsecTime
Definition: net.cpp:810
CNetMessage::nHdrPos
unsigned int nHdrPos
Definition: net.h:211
CNode::cs_vRecvMsg
RecursiveMutex cs_vRecvMsg
Definition: net.h:324
netbase.h
LEAVE_CRITICAL_SECTION
#define LEAVE_CRITICAL_SECTION(cs)
Definition: sync.h:195
CDataStream::empty
bool empty() const
Definition: streams.h:121
begin_ptr
V::value_type * begin_ptr(V &v)
Important: Do not use the following functions in new code, but use v.data() and v....
Definition: serialize.h:57
CNode::nLastRecv
int64_t nLastRecv
Definition: net.h:329
CNodeSignals
Definition: net.h:109
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:80
CBloomFilter::IsRelevantAndUpdate
bool IsRelevantAndUpdate(const CTransaction &tx)
Also adds any outputs which match the filter to the filter (to match their spending txes)
Definition: bloom.cpp:131
CNode::mapAskFor
std::multimap< int64_t, CInv > mapAskFor
Definition: net.h:393
ReceiveFloodSize
unsigned int ReceiveFloodSize()
Definition: net.cpp:2241
ThreadOpenAddedConnections
void ThreadOpenAddedConnections()
Definition: net.cpp:1645
BCLog::NET
@ NET
Definition: logging.h:40
CNode::IsBanned
static bool IsBanned(CNetAddr ip)
Definition: net.cpp:494
Hash
std::string Hash(std::string input)
Compute the 256-bit hash of a std::string.
Definition: hash.h:122
CNodeSignals::InitializeNode
boost::signals2::signal< void(NodeId, const CNode *)> InitializeNode
Definition: net.h:114
NetMsgType::VERSION
const char * VERSION
The version message provides information about the transmitting node to the receiving node at the beg...
Definition: protocol.cpp:17
fListen
bool fListen
Definition: net.cpp:72
mapMultiArgs
std::map< std::string, std::vector< std::string > > mapMultiArgs
Definition: util.cpp:112
net.h
ThreadSocketHandler
void ThreadSocketHandler()
Definition: net.cpp:1006
CNode::fClient
bool fClient
Definition: net.h:344
validateMasternodeIP
bool validateMasternodeIP(const std::string &addrStr)
Definition: net.cpp:2493
GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:241
CNode::nSendSize
size_t nSendSize
Definition: net.h:314
IsLocal
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:274
CNode::nStartingHeight
int nStartingHeight
Definition: net.h:379
CChainParams::DNSSeeds
const std::vector< CDNSSeedData > & DNSSeeds() const
Definition: chainparams.h:96
CNode::strSubVer
std::string strSubVer
Definition: net.h:340
CDNSSeedData
Definition: chainparams.h:23
CAddrDB::pathAddr
fs::path pathAddr
Definition: net.h:776
CNodeSignals::GetHeight
boost::signals2::signal< int()> GetHeight
Definition: net.h:111
nMaxConnections
int nMaxConnections
Definition: net.cpp:81
CNodeStats
Definition: net.h:180
CExplicitNetCleanup::callCleanup
static void callCleanup()
Definition: net.cpp:2021
CNetMessage::hdr
CMessageHeader hdr
Definition: net.h:210
CAddrMan::Attempt
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.h:541
CNetAddr::SetIP
void SetIP(const CNetAddr &ip)
Definition: netaddress.cpp:24
CInv::ToString
std::string ToString() const
Definition: protocol.cpp:254
FastRandomContext
Fast randomness source.
Definition: random.h:44
CNode::~CNode
~CNode()
Definition: net.cpp:2307
CNode::vWhitelistedRange
static std::vector< CSubNet > vWhitelistedRange
Definition: net.h:371
CNode::cleanSubVer
std::string cleanSubVer
Definition: net.h:340
error
bool error(const char *fmt, const Args &... args)
Definition: util.h:61
ThreadMessageHandler
void ThreadMessageHandler()
Definition: net.cpp:1700
mapAlreadyAskedFor
limitedmap< CInv, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
CClientUIInterface::NotifyNumConnectionsChanged
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
Definition: guiinterface.h:92
Lookup
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:206
MapPort
void MapPort(bool)
Definition: net.cpp:1360
CNode::BannedSetIsDirty
static bool BannedSetIsDirty()
check is the banlist has unwritten changes
Definition: net.cpp:611
AddLocal
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:208
CloseSocket
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
Definition: netbase.cpp:735