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