Headers cleanup
[novacoin.git] / src / net.cpp
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 "irc.h"
7 #include "db.h"
8 #include "net.h"
9 #include "init.h"
10 #include "addrman.h"
11 #include "interface.h"
12 #include "main.h"
13 #include "miner.h"
14 #include "ntp.h"
15 #include "random.h"
16
17 #ifdef WIN32
18 #include <string.h>
19 #endif
20
21 using namespace std;
22
23 static const int MAX_OUTBOUND_CONNECTIONS = 16;
24
25 void ThreadMessageHandler2(void* parg);
26 void ThreadSocketHandler2(void* parg);
27 void ThreadOpenConnections2(void* parg);
28 void ThreadOpenAddedConnections2(void* parg);
29 void ThreadDNSAddressSeed2(void* parg);
30
31 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
32 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
33 #ifdef WIN32
34 #ifndef PROTECTION_LEVEL_UNRESTRICTED
35 #define PROTECTION_LEVEL_UNRESTRICTED 10
36 #endif
37 #ifndef IPV6_PROTECTION_LEVEL
38 #define IPV6_PROTECTION_LEVEL 23
39 #endif
40 #endif
41
42 struct LocalServiceInfo {
43     int nScore;
44     uint16_t nPort;
45 };
46
47 //
48 // Global state variables
49 //
50 bool fClient = false;
51 bool fDiscover = true;
52 uint64_t nLocalServices = (fClient ? 0 : NODE_NETWORK);
53 static CCriticalSection cs_mapLocalHost;
54 static map<CNetAddr, LocalServiceInfo> mapLocalHost;
55 static bool vfReachable[NET_MAX] = {};
56 static bool vfLimited[NET_MAX] = {};
57 static CNode* pnodeLocalHost = NULL;
58 static CNode* pnodeSync = NULL;
59 CAddress addrSeenByPeer(CService("0.0.0.0", nPortZero), nLocalServices);
60 uint64_t nLocalHostNonce = 0;
61 std::array<int, THREAD_MAX> vnThreadsRunning;
62 static std::vector<SOCKET> vhListenSocket;
63 CAddrMan addrman;
64
65 vector<CNode*> vNodes;
66 CCriticalSection cs_vNodes;
67 map<CInv, CDataStream> mapRelay;
68 deque<pair<int64_t, CInv> > vRelayExpiration;
69 CCriticalSection cs_mapRelay;
70 map<CInv, int64_t> mapAlreadyAskedFor;
71
72 static deque<string> vOneShots;
73 CCriticalSection cs_vOneShots;
74
75 set<CNetAddr> setservAddNodeAddresses;
76 CCriticalSection cs_setservAddNodeAddresses;
77
78 vector<std::string> vAddedNodes;
79 CCriticalSection cs_vAddedNodes;
80
81 static CSemaphore *semOutbound = NULL;
82
83 inline void RelayInventory(const CInv& inv)
84 {
85     // Put on lists to offer to the other nodes
86     {
87         LOCK(cs_vNodes);
88         for (CNode* pnode : vNodes)
89             pnode->PushInventory(inv);
90     }
91 }
92
93 void AddOneShot(string strDest)
94 {
95     LOCK(cs_vOneShots);
96     vOneShots.push_back(strDest);
97 }
98
99 unsigned short GetListenPort()
100 {
101     return (unsigned short)(GetArg("-port", GetDefaultPort()));
102 }
103
104 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
105 {
106     // Filter out duplicate requests
107     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
108         return;
109     pindexLastGetBlocksBegin = pindexBegin;
110     hashLastGetBlocksEnd = hashEnd;
111
112     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
113 }
114
115 // find 'best' local address for a particular peer
116 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
117 {
118     if (fNoListen)
119         return false;
120
121     int nBestScore = -1;
122     int nBestReachability = -1;
123     {
124         LOCK(cs_mapLocalHost);
125         for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
126         {
127             int nScore = (*it).second.nScore;
128             int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
129             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
130             {
131                 addr = CService((*it).first, (*it).second.nPort);
132                 nBestReachability = nReachability;
133                 nBestScore = nScore;
134             }
135         }
136     }
137     return nBestScore >= 0;
138 }
139
140 // get best local address for a particular peer as a CAddress
141 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
142 {
143     CAddress ret(CService("0.0.0.0", nPortZero), 0);
144     CService addr;
145     if (GetLocal(addr, paddrPeer))
146     {
147         ret = CAddress(addr);
148         ret.nServices = nLocalServices;
149         ret.nTime = GetAdjustedTime();
150     }
151     return ret;
152 }
153
154 bool RecvLine(SOCKET hSocket, string& strLine)
155 {
156     strLine.clear();
157     for ( ; ; )
158     {
159         char c;
160         int nBytes = recv(hSocket, &c, 1, 0);
161         if (nBytes > 0)
162         {
163             if (c == '\n')
164                 continue;
165             if (c == '\r')
166                 return true;
167             strLine += c;
168             if (strLine.size() >= 9000)
169                 return true;
170         }
171         else if (nBytes <= 0)
172         {
173             if (fShutdown)
174                 return false;
175             if (nBytes < 0)
176             {
177                 int nErr = WSAGetLastError();
178                 if (nErr == WSAEMSGSIZE)
179                     continue;
180                 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
181                 {
182                     Sleep(10);
183                     continue;
184                 }
185             }
186             if (!strLine.empty())
187                 return true;
188             if (nBytes == 0)
189             {
190                 // socket closed
191                 printf("socket closed\n");
192                 return false;
193             }
194             else
195             {
196                 // socket error
197                 int nErr = WSAGetLastError();
198                 printf("recv failed: %d\n", nErr);
199                 return false;
200             }
201         }
202     }
203 }
204
205 // used when scores of local addresses may have changed
206 // pushes better local address to peers
207 void static AdvertizeLocal()
208 {
209     LOCK(cs_vNodes);
210     for (CNode* pnode : vNodes)
211     {
212         if (pnode->fSuccessfullyConnected)
213         {
214             CAddress addrLocal = GetLocalAddress(&pnode->addr);
215             if (addrLocal.IsRoutable() && (CService)addrLocal != pnode->addrLocal)
216             {
217                 pnode->PushAddress(addrLocal);
218                 pnode->addrLocal = addrLocal;
219             }
220         }
221     }
222 }
223
224 void SetReachable(enum Network net, bool fFlag)
225 {
226     LOCK(cs_mapLocalHost);
227     vfReachable[net] = fFlag;
228     if (net == NET_IPV6 && fFlag)
229         vfReachable[NET_IPV4] = true;
230 }
231
232 int GetnScore(const CService& addr)
233 {
234     LOCK(cs_mapLocalHost);
235     if (mapLocalHost.count(addr) == LOCAL_NONE)
236         return 0;
237     return mapLocalHost[addr].nScore;
238 }
239
240
241 // Is our peer's addrLocal potentially useful as an external IP source?
242 bool IsPeerAddrLocalGood(CNode *pnode)
243 {
244     return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
245            !IsLimited(pnode->addrLocal.GetNetwork());
246 }
247
248 // pushes our own address to a peer
249 void AdvertiseLocal(CNode *pnode)
250 {
251     if (!fNoListen && pnode->fSuccessfullyConnected)
252     {
253         CAddress addrLocal = GetLocalAddress(&pnode->addr);
254         // If discovery is enabled, sometimes give our peer the address it
255         // tells us that it sees us as in case it has a better idea of our
256         // address than we do.
257         if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
258              GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
259         {
260             addrLocal.SetIP(pnode->addrLocal);
261         }
262         if (addrLocal.IsRoutable())
263         {
264             printf("AdvertiseLocal: advertising address %s\n", addrLocal.ToString().c_str());
265             pnode->PushAddress(addrLocal);
266         }
267     }
268 }
269
270 // learn a new local address
271 bool AddLocal(const CService& addr, int nScore)
272 {
273     if (!addr.IsRoutable())
274         return false;
275
276     if (!fDiscover && nScore < LOCAL_MANUAL)
277         return false;
278
279     if (IsLimited(addr))
280         return false;
281
282     printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
283
284     {
285         LOCK(cs_mapLocalHost);
286         bool fAlready = mapLocalHost.count(addr) > 0;
287         LocalServiceInfo &info = mapLocalHost[addr];
288         if (!fAlready || nScore >= info.nScore) {
289             info.nScore = nScore + (fAlready ? 1 : 0);
290             info.nPort = addr.GetPort();
291         }
292         SetReachable(addr.GetNetwork());
293     }
294
295     AdvertizeLocal();
296
297     return true;
298 }
299
300 bool AddLocal(const CNetAddr &addr, int nScore)
301 {
302     return AddLocal(CService(addr, GetListenPort()), nScore);
303 }
304
305 /** Make a particular network entirely off-limits (no automatic connects to it) */
306 void SetLimited(enum Network net, bool fLimited)
307 {
308     if (net == NET_UNROUTABLE)
309         return;
310     LOCK(cs_mapLocalHost);
311     vfLimited[net] = fLimited;
312 }
313
314 bool IsLimited(enum Network net)
315 {
316     LOCK(cs_mapLocalHost);
317     return vfLimited[net];
318 }
319
320 bool IsLimited(const CNetAddr &addr)
321 {
322     return IsLimited(addr.GetNetwork());
323 }
324
325 /** vote for a local address */
326 bool SeenLocal(const CService& addr)
327 {
328     {
329         LOCK(cs_mapLocalHost);
330         if (mapLocalHost.count(addr) == 0)
331             return false;
332         mapLocalHost[addr].nScore++;
333     }
334
335     AdvertizeLocal();
336
337     return true;
338 }
339
340 /** check whether a given address is potentially local */
341 bool IsLocal(const CService& addr)
342 {
343     LOCK(cs_mapLocalHost);
344     return mapLocalHost.count(addr) > 0;
345 }
346
347 /** check whether a given address is in a network we can probably connect to */
348 bool IsReachable(const CNetAddr& addr)
349 {
350     LOCK(cs_mapLocalHost);
351     enum Network net = addr.GetNetwork();
352     return vfReachable[net] && !vfLimited[net];
353 }
354
355 extern int GetExternalIPbySTUN(uint64_t rnd, struct sockaddr_in *mapped, const char **srv);
356
357 // We now get our external IP from the IRC server first and only use this as a backup
358 bool GetMyExternalIP(CNetAddr& ipRet)
359 {
360     struct sockaddr_in mapped;
361     uint64_t rnd = std::numeric_limits<uint64_t>::max();
362     const char *srv;
363     int rc = GetExternalIPbySTUN(rnd, &mapped, &srv);
364     if(rc >= 0) {
365         ipRet = CNetAddr(mapped.sin_addr);
366         printf("GetExternalIPbySTUN(%" PRIu64 ") returned %s in attempt %d; Server=%s\n", rnd, ipRet.ToStringIP().c_str(), rc, srv);
367         return true;
368     }
369     return false;
370 }
371
372 void ThreadGetMyExternalIP(void* parg)
373 {
374     // Make this thread recognisable as the external IP detection thread
375     RenameThread("novacoin-ext-ip");
376
377     CNetAddr addrLocalHost;
378     if (GetMyExternalIP(addrLocalHost))
379     {
380         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
381         AddLocal(addrLocalHost, LOCAL_HTTP);
382     }
383 }
384
385
386
387
388
389 void AddressCurrentlyConnected(const CService& addr)
390 {
391     addrman.Connected(addr);
392 }
393
394
395
396
397 uint64_t CNode::nTotalBytesRecv = 0;
398 uint64_t CNode::nTotalBytesSent = 0;
399 CCriticalSection CNode::cs_totalBytesRecv;
400 CCriticalSection CNode::cs_totalBytesSent;
401
402 CNode* FindNode(const CNetAddr& ip)
403 {
404     LOCK(cs_vNodes);
405     for (CNode* pnode : vNodes)
406         if ((CNetAddr)pnode->addr == ip)
407             return (pnode);
408     return NULL;
409 }
410
411 CNode* FindNode(std::string addrName)
412 {
413     LOCK(cs_vNodes);
414     for (CNode* pnode : vNodes)
415         if (pnode->addrName == addrName)
416             return (pnode);
417     return NULL;
418 }
419
420 CNode* FindNode(const CService& addr)
421 {
422     LOCK(cs_vNodes);
423     for (CNode* pnode : vNodes)
424         if ((CService)pnode->addr == addr)
425             return (pnode);
426     return NULL;
427 }
428
429 CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64_t nTimeout)
430 {
431     if (pszDest == NULL) {
432         if (IsLocal(addrConnect))
433             return NULL;
434
435         // Look for an existing connection
436         CNode* pnode = FindNode((CService)addrConnect);
437         if (pnode)
438         {
439             if (nTimeout != 0)
440                 pnode->AddRef(nTimeout);
441             else
442                 pnode->AddRef();
443             return pnode;
444         }
445     }
446
447
448     /// debug print
449     printf("trying connection %s lastseen=%.1fhrs\n",
450         pszDest ? pszDest : addrConnect.ToString().c_str(),
451         pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
452
453     // Connect
454     SOCKET hSocket;
455     if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
456     {
457         addrman.Attempt(addrConnect);
458
459         /// debug print
460         printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
461
462         // Set to non-blocking
463 #ifdef WIN32
464         u_long nOne = 1;
465         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
466             printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
467 #else
468         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
469             printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
470 #endif
471
472         // Add node
473         CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
474         if (nTimeout != 0)
475             pnode->AddRef(nTimeout);
476         else
477             pnode->AddRef();
478
479         {
480             LOCK(cs_vNodes);
481             vNodes.push_back(pnode);
482         }
483
484         pnode->nTimeConnected = GetTime();
485         return pnode;
486     }
487     else
488     {
489         return NULL;
490     }
491 }
492
493 void CNode::CloseSocketDisconnect()
494 {
495     fDisconnect = true;
496     if (hSocket != INVALID_SOCKET)
497     {
498         printf("disconnecting node %s\n", addrName.c_str());
499         CloseSocket(hSocket);
500         vRecv.clear();
501     }
502
503     // in case this fails, we'll empty the recv buffer when the CNode is deleted
504     TRY_LOCK(cs_vRecv, lockRecv);
505     if (lockRecv)
506         vRecv.clear();
507
508     // if this was the sync node, we'll need a new one
509     if (this == pnodeSync)
510         pnodeSync = NULL;
511 }
512
513 void CNode::Cleanup()
514 {
515 }
516
517 void CNode::EndMessage()
518 {
519     if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
520     {
521         printf("dropmessages DROPPING SEND MESSAGE\n");
522         AbortMessage();
523         return;
524     }
525
526     if (nHeaderStart < 0) {
527         LEAVE_CRITICAL_SECTION(cs_vSend);
528         return;
529     }
530
531     // Set the size
532     uint32_t nSize = (uint32_t) vSend.size() - nMessageStart;
533     memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
534
535     // Set the checksum
536     uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
537     uint32_t nChecksum = 0;
538     memcpy(&nChecksum, &hash, sizeof(nChecksum));
539     assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
540     memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum));
541
542     if (fDebug) {
543         printf("(%d bytes)\n", nSize);
544     }
545
546     nHeaderStart = -1;
547     nMessageStart = std::numeric_limits<uint32_t>::max();
548     LEAVE_CRITICAL_SECTION(cs_vSend);
549 }
550
551 void CNode::PushVersion()
552 {
553     int64_t nTime = GetAdjustedTime();
554     CAddress addrYou, addrMe;
555
556     bool fHidden = false;
557     if (addr.IsTor()) {
558         if (mapArgs.count("-torname")) {
559             // Our hidden service address
560             CService addrTorName(mapArgs["-torname"], GetListenPort());
561
562             if (addrTorName.IsValid()) {
563                 addrYou = addr;
564                 addrMe = CAddress(addrTorName);
565                 fHidden = true;
566             }
567         }
568     }
569
570     if (!fHidden) {
571         addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", nPortZero)));
572         addrMe = GetLocalAddress(&addr);
573     }
574
575     GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
576     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());
577     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
578                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
579 }
580
581
582
583
584
585 std::map<CNetAddr, int64_t> CNode::setBanned;
586 CCriticalSection CNode::cs_setBanned;
587
588 void CNode::ClearBanned()
589 {
590     setBanned.clear();
591 }
592
593 bool CNode::IsBanned(CNetAddr ip)
594 {
595     bool fResult = false;
596     {
597         LOCK(cs_setBanned);
598         std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
599         if (i != setBanned.end())
600         {
601             int64_t t = (*i).second;
602             if (GetTime() < t)
603                 fResult = true;
604         }
605     }
606     return fResult;
607 }
608
609 bool CNode::Misbehaving(int howmuch)
610 {
611     if (addr.IsLocal())
612     {
613         printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
614         return false;
615     }
616
617     nMisbehavior += howmuch;
618     if (nMisbehavior >= GetArgInt("-banscore", 100))
619     {
620         int64_t banTime = GetTime()+GetArg("-bantime", nOneDay);  // Default 24-hour ban
621         printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
622         {
623             LOCK(cs_setBanned);
624             if (setBanned[addr] < banTime)
625                 setBanned[addr] = banTime;
626         }
627         CloseSocketDisconnect();
628         return true;
629     } else
630         printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
631     return false;
632 }
633
634 #undef X
635 #define X(name) stats.name = name
636 void CNode::copyStats(CNodeStats &stats)
637 {
638     X(nServices);
639     X(nLastSend);
640     X(nLastRecv);
641     X(nTimeConnected);
642     X(addrName);
643     X(nVersion);
644     X(strSubVer);
645     X(fInbound);
646     X(nReleaseTime);
647     X(nStartingHeight);
648     X(nMisbehavior);
649     X(nSendBytes);
650     X(nRecvBytes);
651     stats.fSyncNode = (this == pnodeSync);
652 }
653 #undef X
654
655 void Release(CNode* node) {
656     node->Release();
657 }
658
659
660
661
662
663 void ThreadSocketHandler(void* parg)
664 {
665     // Make this thread recognisable as the networking thread
666     RenameThread("novacoin-net");
667
668     try
669     {
670         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
671         ThreadSocketHandler2(parg);
672         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
673     }
674     catch (std::exception& e) {
675         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
676         PrintException(&e, "ThreadSocketHandler()");
677     } catch (...) {
678         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
679         throw; // support pthread_cancel()
680     }
681     printf("ThreadSocketHandler exited\n");
682 }
683
684 static list<CNode*> vNodesDisconnected;
685
686 void ThreadSocketHandler2(void* parg)
687 {
688     printf("ThreadSocketHandler started\n");
689     size_t nPrevNodeCount = 0;
690     for ( ; ; )
691     {
692         //
693         // Disconnect nodes
694         //
695         {
696             LOCK(cs_vNodes);
697             // Disconnect unused nodes
698             vector<CNode*> vNodesCopy = vNodes;
699             for (CNode* pnode : vNodesCopy)
700             {
701                 if (pnode->fDisconnect ||
702                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
703                 {
704                     // remove from vNodes
705                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
706
707                     // release outbound grant (if any)
708                     pnode->grantOutbound.Release();
709
710                     // close socket and cleanup
711                     pnode->CloseSocketDisconnect();
712                     pnode->Cleanup();
713
714                     // hold in disconnected pool until all refs are released
715                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
716                     if (pnode->fNetworkNode || pnode->fInbound)
717                         pnode->Release();
718                     vNodesDisconnected.push_back(pnode);
719                 }
720             }
721
722             // Delete disconnected nodes
723             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
724             for (CNode* pnode : vNodesDisconnectedCopy)
725             {
726                 // wait until threads are done using it
727                 if (pnode->GetRefCount() <= 0)
728                 {
729                     bool fDelete = false;
730                     {
731                         TRY_LOCK(pnode->cs_vSend, lockSend);
732                         if (lockSend)
733                         {
734                             TRY_LOCK(pnode->cs_vRecv, lockRecv);
735                             if (lockRecv)
736                             {
737                                 TRY_LOCK(pnode->cs_inventory, lockInv);
738                                 if (lockInv)
739                                     fDelete = true;
740                             }
741                         }
742                     }
743                     if (fDelete)
744                     {
745                         vNodesDisconnected.remove(pnode);
746                         delete pnode;
747                     }
748                 }
749             }
750         }
751         if (vNodes.size() != nPrevNodeCount)
752         {
753             nPrevNodeCount = vNodes.size();
754             uiInterface.NotifyNumConnectionsChanged(vNodes.size());
755         }
756
757
758         //
759         // Find which sockets have data to receive
760         //
761         struct timeval timeout;
762         timeout.tv_sec  = 0;
763         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
764
765         fd_set fdsetRecv;
766         fd_set fdsetSend;
767         fd_set fdsetError;
768         FD_ZERO(&fdsetRecv);
769         FD_ZERO(&fdsetSend);
770         FD_ZERO(&fdsetError);
771         SOCKET hSocketMax = 0;
772         bool have_fds = false;
773
774         for (SOCKET hListenSocket : vhListenSocket) {
775             FD_SET(hListenSocket, &fdsetRecv);
776             hSocketMax = max(hSocketMax, hListenSocket);
777             have_fds = true;
778         }
779         {
780             LOCK(cs_vNodes);
781             for (CNode* pnode : vNodes)
782             {
783                 if (pnode->hSocket == INVALID_SOCKET)
784                     continue;
785                 FD_SET(pnode->hSocket, &fdsetRecv);
786                 FD_SET(pnode->hSocket, &fdsetError);
787                 hSocketMax = max(hSocketMax, pnode->hSocket);
788                 have_fds = true;
789                 {
790                     TRY_LOCK(pnode->cs_vSend, lockSend);
791                     if (lockSend && !pnode->vSend.empty())
792                         FD_SET(pnode->hSocket, &fdsetSend);
793                 }
794             }
795         }
796
797         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
798         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
799                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
800         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
801         if (fShutdown)
802             return;
803         if (nSelect == SOCKET_ERROR)
804         {
805             if (have_fds)
806             {
807                 int nErr = WSAGetLastError();
808                 printf("socket select error %d\n", nErr);
809                 for (unsigned int i = 0; i <= hSocketMax; i++)
810                     FD_SET(i, &fdsetRecv);
811             }
812             FD_ZERO(&fdsetSend);
813             FD_ZERO(&fdsetError);
814             Sleep(timeout.tv_usec/1000);
815         }
816
817
818         //
819         // Accept new connections
820         //
821         for (SOCKET hListenSocket : vhListenSocket)
822         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
823         {
824 #ifdef USE_IPV6
825             struct sockaddr_storage sockaddr;
826 #else
827             struct sockaddr sockaddr;
828 #endif
829             socklen_t len = sizeof(sockaddr);
830             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
831             CAddress addr;
832             int nInbound = 0;
833
834             if (hSocket != INVALID_SOCKET)
835                 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
836                     printf("Warning: Unknown socket family\n");
837
838             {
839                 LOCK(cs_vNodes);
840                 for (CNode* pnode : vNodes)
841                     if (pnode->fInbound)
842                         nInbound++;
843             }
844
845             if (hSocket == INVALID_SOCKET)
846             {
847                 int nErr = WSAGetLastError();
848                 if (nErr != WSAEWOULDBLOCK)
849                     printf("socket error accept failed: %d\n", nErr);
850             }
851             else if (nInbound >= GetArgInt("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
852             {
853                 {
854                     LOCK(cs_setservAddNodeAddresses);
855                     if (!setservAddNodeAddresses.count(addr))
856                         CloseSocket(hSocket);
857                 }
858             }
859             else if (CNode::IsBanned(addr))
860             {
861                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
862                 CloseSocket(hSocket);
863             }
864             else
865             {
866                 printf("accepted connection %s\n", addr.ToString().c_str());
867                 CNode* pnode = new CNode(hSocket, addr, "", true);
868                 pnode->AddRef();
869                 {
870                     LOCK(cs_vNodes);
871                     vNodes.push_back(pnode);
872                 }
873             }
874         }
875
876
877         //
878         // Service each socket
879         //
880         vector<CNode*> vNodesCopy;
881         {
882             LOCK(cs_vNodes);
883             vNodesCopy = vNodes;
884             for (CNode* pnode : vNodesCopy)
885                 pnode->AddRef();
886         }
887         for (CNode* pnode : vNodesCopy)
888         {
889             if (fShutdown)
890                 return;
891
892             //
893             // Receive
894             //
895             if (pnode->hSocket == INVALID_SOCKET)
896                 continue;
897             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
898             {
899                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
900                 if (lockRecv)
901                 {
902                     CDataStream& vRecv = pnode->vRecv;
903                     uint64_t nPos = vRecv.size();
904
905                     if (nPos > ReceiveBufferSize()) {
906                         if (!pnode->fDisconnect)
907                             printf("socket recv flood control disconnect (%" PRIszu " bytes)\n", vRecv.size());
908                         pnode->CloseSocketDisconnect();
909                     }
910                     else {
911                         // typical socket buffer is 8K-64K
912                         char pchBuf[0x10000];
913                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
914                         if (nBytes > 0)
915                         {
916                             vRecv.resize(nPos + nBytes);
917                             memcpy(&vRecv[nPos], pchBuf, nBytes);
918                             pnode->nLastRecv = GetTime();
919                             pnode->nRecvBytes += nBytes;
920                             pnode->RecordBytesRecv(nBytes);
921                         }
922                         else if (nBytes == 0)
923                         {
924                             // socket closed gracefully
925                             if (!pnode->fDisconnect)
926                                 printf("socket closed\n");
927                             pnode->CloseSocketDisconnect();
928                         }
929                         else if (nBytes < 0)
930                         {
931                             // error
932                             int nErr = WSAGetLastError();
933                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
934                             {
935                                 if (!pnode->fDisconnect)
936                                     printf("socket recv error %d\n", nErr);
937                                 pnode->CloseSocketDisconnect();
938                             }
939                         }
940                     }
941                 }
942             }
943
944             //
945             // Send
946             //
947             if (pnode->hSocket == INVALID_SOCKET)
948                 continue;
949             if (FD_ISSET(pnode->hSocket, &fdsetSend))
950             {
951                 TRY_LOCK(pnode->cs_vSend, lockSend);
952                 if (lockSend)
953                 {
954                     CDataStream& vSend = pnode->vSend;
955                     if (!vSend.empty())
956                     {
957                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
958                         if (nBytes > 0)
959                         {
960                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
961                             pnode->nLastSend = GetTime();
962                             pnode->nSendBytes += nBytes;
963                             pnode->RecordBytesSent(nBytes);
964                         }
965                         else if (nBytes < 0)
966                         {
967                             // error
968                             int nErr = WSAGetLastError();
969                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
970                             {
971                                 printf("socket send error %d\n", nErr);
972                                 pnode->CloseSocketDisconnect();
973                             }
974                         }
975                     }
976                 }
977             }
978
979             //
980             // Inactivity checking
981             //
982             if (pnode->vSend.empty())
983                 pnode->nLastSendEmpty = GetTime();
984             if (GetTime() - pnode->nTimeConnected > 60)
985             {
986                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
987                 {
988                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
989                     pnode->fDisconnect = true;
990                 }
991                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
992                 {
993                     printf("socket not sending\n");
994                     pnode->fDisconnect = true;
995                 }
996                 else if (GetTime() - pnode->nLastRecv > 90*60)
997                 {
998                     printf("socket inactivity timeout\n");
999                     pnode->fDisconnect = true;
1000                 }
1001             }
1002         }
1003         {
1004             LOCK(cs_vNodes);
1005             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1006         }
1007
1008         Sleep(10);
1009     }
1010 }
1011
1012 // DNS seeds
1013 // Each pair gives a source name and a seed name.
1014 // The first name is used as information source for addrman.
1015 // The second name should resolve to a list of seed addresses.
1016 static const char *strDNSSeed[][2] = {
1017     {"node.novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro"},
1018     {"novacoin.ru", "dnsseed.novacoin.ru"},
1019     {"novacoin.ru", "testseed.novacoin.ru"},
1020     {"novaco.in", "dnsseed.novaco.in"},
1021 };
1022
1023 void ThreadDNSAddressSeed(void* parg)
1024 {
1025     // Make this thread recognisable as the DNS seeding thread
1026     RenameThread("novacoin-dnsseed");
1027
1028     try
1029     {
1030         vnThreadsRunning[THREAD_DNSSEED]++;
1031         ThreadDNSAddressSeed2(parg);
1032         vnThreadsRunning[THREAD_DNSSEED]--;
1033     }
1034     catch (std::exception& e) {
1035         vnThreadsRunning[THREAD_DNSSEED]--;
1036         PrintException(&e, "ThreadDNSAddressSeed()");
1037     } catch (...) {
1038         vnThreadsRunning[THREAD_DNSSEED]--;
1039         throw; // support pthread_cancel()
1040     }
1041     printf("ThreadDNSAddressSeed exited\n");
1042 }
1043
1044 void ThreadDNSAddressSeed2(void* parg)
1045 {
1046     printf("ThreadDNSAddressSeed started\n");
1047     int found = 0;
1048
1049     if (!fTestNet)
1050     {
1051         printf("Loading addresses from DNS seeds (could take a while)\n");
1052
1053         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1054             if (HaveNameProxy()) {
1055                 AddOneShot(strDNSSeed[seed_idx][1]);
1056             } else {
1057                 vector<CNetAddr> vaddr;
1058                 vector<CAddress> vAdd;
1059                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1060                 {
1061                     for (CNetAddr& ip : vaddr)
1062                     {
1063                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1064                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1065                         vAdd.push_back(addr);
1066                         found++;
1067                     }
1068                 }
1069                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1070             }
1071         }
1072     }
1073
1074     printf("%d addresses found from DNS seeds\n", found);
1075 }
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088 uint32_t pnSeed[] =
1089 {
1090     0x1c542868, 0x3859dd6f, 0x203c2e68, 0xf145a6bc, 0x638a545f, 0x325da346, 0x385da346, 0xfb2b8d5f,
1091     0x52568c5f, 0xa979e65b, 0x8de6485d, 0x9f79e65b, 0x048a861f, 0x3388b55f, 0x6ff0b45e, 0x17e81f5f,
1092     0x6c47bb25, 0x1ecdc852, 0x28263db9, 0x47824e5d, 0x36f1c851, 0x2bf913b2, 0x95923cb3, 0x84e63eb2,
1093     0xefdeedbf, 0x65200092, 0xf36f6805, 0x42692d05, 0x772c1955, 0xb6bf1b4e, 0x7abb5f5d, 0xdb2fa6bc,
1094     0x90e911bf, 0x82de565f, 0x694416b2, 0x0ab600bc, 0xfcecbe6d, 0x24ed9fb2, 0x1bb618c2, 0xc64765bb,
1095     0x4e3d62c3, 0xdba24baa, 0x4b7109b0, 0x12a12cc2, 0xfc01864f, 0x0b69e85b, 0x33922c1f, 0xac611bc6,
1096     0x2a257155, 0x991d5fc0, 0xbfdabcb1, 0x9b73ee55, 0x5bc2b95d, 0xdef0762e, 0x6ab7c936, 0x9c4416b2,
1097     0xd60d864f, 0x03671f1f, 0x3b5da346, 0xc6f5c851, 0x5411b2d4, 0xe7c25702, 0x63474fb0, 0x7e11c854,
1098     0x52381d5f, 0x72fdfe59, 0x51599a05, 0xfb12b2d4, 0xaee4f15e, 0xd0e3f15e, 0x2aa2805f, 0xa1caf15e,
1099     0x34fe425e, 0x46e1f15e, 0xd7c71955, 0xaeeff15e, 0x47c2af55, 0x563d89b2, 0x67980fd9, 0xc9def15e,
1100     0x9cc51eb9, 0xdaa7aa6b, 0x78e6871f, 0x0d5d2cb2, 0x7aedf15e, 0x9bcaf15e, 0xe5f7f15e, 0x501c1759,
1101     0xdfbc4980, 0xa7397f2e, 0x31ea1a02, 0x3a27655e, 0xaa86f05c, 0xdcddf15e, 0x64689cb2, 0xd4bf62d4,
1102     0xf093eab2, 0x98def15e, 0xb6c5f15e, 0x81e8f15e, 0xe5d2fe59, 0xa312786d, 0x4cf9fe59, 0x8a922c1f,
1103     0x00c7fe59, 0x1ade565f, 0x9e4116b2, 0x2c36983e, 0x68f8f15e, 0x51b7eab2, 0x76c51eb9, 0x9edd4980,
1104     0x90ef565f, 0x0dd80857, 0xd513fb94, 0xf5bdeab2, 0xa95277b0, 0x2cf2f15e, 0x1897eab2, 0x924416b2,
1105     0x985c9b59, 0x30aa43d8, 0xf9c6745f, 0xaf862e5f, 0xe0ceeab2, 0xb9b3eab2, 0x6da4eab2, 0xa4fdeab2,
1106     0x0fa6c125, 0xe38bbd05, 0x5d922c1f, 0x9bd0eab2, 0x73025e02, 0xc4fd794d, 0x8435b35f, 0x2d01bc2e,
1107     0xaa2a14d4, 0xa22b07cb, 0xebda6f4f, 0xddc6514e, 0xf23feab2, 0xea1e5256, 0x6147b45e, 0x47d21e4f,
1108     0x67c41c1f, 0x53ec1a02, 0x352e786d, 0x6bec1a02, 0x78fb4abe, 0xd3014c5d, 0x9fbbeab2, 0x1fc51eb9,
1109     0x720eeab2, 0x2db5eab2, 0xe8baf65c, 0x521b459e, 0x65c4955f, 0x0e7b915f, 0xa8f37e6d, 0x6d0b465f,
1110     0xfab8ff5c, 0xf7c27e6d, 0x7345a846, 0x4fd1a7d5, 0xdfc97e6d, 0x26c27e6d, 0xa9de36b2, 0xc615344d,
1111     0x28ceb95d, 0xa52d895e, 0x18c17e6d, 0x13ec1a02, 0x0ba37125, 0x6c3d344d, 0xb3922c1f, 0x506bbeb0,
1112     0x4d04994e, 0xa1bbe56d, 0xf62c344d, 0x0847d048, 0x4bdc6451, 0xc95b9a05, 0xbcd3a7d5, 0x29b57125,
1113     0x0c4d2cb2, 0xf2b8eab2, 0xc2d5b95d, 0x0185ef59, 0x30adeab2, 0xcaf0e92e, 0x756c344d, 0xfd9e252e,
1114     0xbe5ef3bc, 0x4689344d, 0xb223895e, 0xfcebeaad, 0xb7c0e92e, 0x993c1760, 0xe1e171b0, 0xb857e75b,
1115     0xbf10002e, 0xb55b2cb2, 0xa90e2cb2, 0x13d6f15e, 0xf8be9225, 0x14ddf15e, 0x06e90305, 0x82472cb2,
1116 };
1117
1118 const char* pchTorSeed[] = 
1119 {
1120     "seedp4knqnoei57u.onion",
1121     "seedr3hhlepyi7fd.onion",
1122     "seed3uuomkclbiz4.onion",
1123     "seedeh7qck3ouff5.onion",
1124     "5rg3vq4jagckeckf.onion",
1125     "seedt3sraf53ajiy.onion",
1126     "seedg4qyccsg42oq.onion",
1127     "novaqrtoywpg7jly.onion",
1128     "seed3d5wolqbgrcb.onion",
1129     "seed24u5dwph3qw4.onion",
1130     "mj26ulzbs2oskgym.onion",
1131     "eqon4usunavt76m7.onion",
1132     "seedd3aldwpslzl3.onion"
1133 };
1134
1135 void DumpAddresses()
1136 {
1137     int64_t nStart = GetTimeMillis();
1138
1139     CAddrDB adb;
1140     adb.Write(addrman);
1141
1142     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1143            addrman.size(), GetTimeMillis() - nStart);
1144 }
1145
1146 void ThreadDumpAddress2(void* parg)
1147 {
1148     printf("ThreadDumpAddress started\n");
1149
1150     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1151     while (!fShutdown)
1152     {
1153         DumpAddresses();
1154         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1155         Sleep(600000);
1156         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1157     }
1158     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1159 }
1160
1161 void ThreadDumpAddress(void* parg)
1162 {
1163     // Make this thread recognisable as the address dumping thread
1164     RenameThread("novacoin-adrdump");
1165
1166     try
1167     {
1168         ThreadDumpAddress2(parg);
1169     }
1170     catch (std::exception& e) {
1171         PrintException(&e, "ThreadDumpAddress()");
1172     }
1173     printf("ThreadDumpAddress exited\n");
1174 }
1175
1176 void ThreadOpenConnections(void* parg)
1177 {
1178     // Make this thread recognisable as the connection opening thread
1179     RenameThread("novacoin-opencon");
1180
1181     try
1182     {
1183         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1184         ThreadOpenConnections2(parg);
1185         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1186     }
1187     catch (std::exception& e) {
1188         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1189         PrintException(&e, "ThreadOpenConnections()");
1190     } catch (...) {
1191         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1192         PrintException(NULL, "ThreadOpenConnections()");
1193     }
1194     printf("ThreadOpenConnections exited\n");
1195 }
1196
1197 void static ProcessOneShot()
1198 {
1199     string strDest;
1200     {
1201         LOCK(cs_vOneShots);
1202         if (vOneShots.empty())
1203             return;
1204         strDest = vOneShots.front();
1205         vOneShots.pop_front();
1206     }
1207     CAddress addr;
1208     CSemaphoreGrant grant(*semOutbound, true);
1209     if (grant) {
1210         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1211             AddOneShot(strDest);
1212     }
1213 }
1214
1215 void ThreadOpenConnections2(void* parg)
1216 {
1217     printf("ThreadOpenConnections started\n");
1218
1219     // Connect to specific addresses
1220     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1221     {
1222         for (int64_t nLoop = 0;; nLoop++)
1223         {
1224             ProcessOneShot();
1225             for (string strAddr : mapMultiArgs["-connect"])
1226             {
1227                 CAddress addr;
1228                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1229                 for (int i = 0; i < 10 && i < nLoop; i++)
1230                 {
1231                     Sleep(500);
1232                     if (fShutdown)
1233                         return;
1234                 }
1235             }
1236             Sleep(500);
1237         }
1238     }
1239
1240     // Initiate network connections
1241     int64_t nStart = GetTime();
1242     for ( ; ; )
1243     {
1244         ProcessOneShot();
1245
1246         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1247         Sleep(500);
1248         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1249         if (fShutdown)
1250             return;
1251
1252
1253         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1254         CSemaphoreGrant grant(*semOutbound);
1255         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1256         if (fShutdown)
1257             return;
1258
1259         // Add seed nodes if IRC isn't working
1260         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1261         {
1262             std::vector<CAddress> vAdd;
1263             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1264             {
1265                 // It'll only connect to one or two seed nodes because once it connects,
1266                 // it'll get a pile of addresses with newer timestamps.
1267                 // Seed nodes are given a random 'last seen time' of between one and two
1268                 // weeks ago.
1269                 struct in_addr ip;
1270                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1271                 CAddress addr(CService(ip, GetDefaultPort()));
1272                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1273                 vAdd.push_back(addr);
1274             }
1275             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1276         }
1277
1278         // Add Tor nodes if we have connection with onion router
1279         if (mapArgs.count("-tor"))
1280         {
1281             std::vector<CAddress> vAdd;
1282             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1283             {
1284                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1285                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1286                 vAdd.push_back(addr);
1287             }
1288             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1289         }
1290
1291         //
1292         // Choose an address to connect to based on most recently seen
1293         //
1294         CAddress addrConnect;
1295
1296         // Only connect out to one peer per network group (/16 for IPv4).
1297         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1298         int nOutbound = 0;
1299         set<vector<unsigned char> > setConnected;
1300         {
1301             LOCK(cs_vNodes);
1302             for (CNode* pnode : vNodes) {
1303                 if (!pnode->fInbound) {
1304                     setConnected.insert(pnode->addr.GetGroup());
1305                     nOutbound++;
1306                 }
1307             }
1308         }
1309
1310         int64_t nANow = GetAdjustedTime();
1311
1312         int nTries = 0;
1313         for ( ; ; )
1314         {
1315             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1316             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1317
1318             // if we selected an invalid address, restart
1319             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1320                 break;
1321
1322             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1323             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1324             // already-connected network ranges, ...) before trying new addrman addresses.
1325             nTries++;
1326             if (nTries > 100)
1327                 break;
1328
1329             if (IsLimited(addr))
1330                 continue;
1331
1332             // only consider very recently tried nodes after 30 failed attempts
1333             if (nANow - addr.nLastTry < 600 && nTries < 30)
1334                 continue;
1335
1336             // do not allow non-default ports, unless after 50 invalid addresses selected already
1337             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1338                 continue;
1339
1340             addrConnect = addr;
1341             break;
1342         }
1343
1344         if (addrConnect.IsValid())
1345             OpenNetworkConnection(addrConnect, &grant);
1346     }
1347 }
1348
1349 void ThreadOpenAddedConnections(void* parg)
1350 {
1351     // Make this thread recognisable as the connection opening thread
1352     RenameThread("novacoin-opencon");
1353
1354     try
1355     {
1356         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1357         ThreadOpenAddedConnections2(parg);
1358         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1359     }
1360     catch (std::exception& e) {
1361         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1362         PrintException(&e, "ThreadOpenAddedConnections()");
1363     } catch (...) {
1364         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1365         PrintException(NULL, "ThreadOpenAddedConnections()");
1366     }
1367     printf("ThreadOpenAddedConnections exited\n");
1368 }
1369
1370 void ThreadOpenAddedConnections2(void* parg)
1371 {
1372     printf("ThreadOpenAddedConnections started\n");
1373
1374     {
1375         LOCK(cs_vAddedNodes);
1376         vAddedNodes = mapMultiArgs["-addnode"];
1377     }
1378
1379     if (HaveNameProxy()) {
1380         while(!fShutdown) {
1381             list<string> lAddresses(0);
1382             {
1383                 LOCK(cs_vAddedNodes);
1384                 for (string& strAddNode : vAddedNodes)
1385                     lAddresses.push_back(strAddNode);
1386             }
1387             for (string& strAddNode : lAddresses) {
1388                 CAddress addr;
1389                 CSemaphoreGrant grant(*semOutbound);
1390                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1391                 Sleep(500);
1392             }
1393             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1394             Sleep(120000); // Retry every 2 minutes
1395             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1396         }
1397         return;
1398     }
1399
1400     for (uint32_t i = 0; true; i++)
1401     {
1402         list<string> lAddresses(0);
1403         {
1404             LOCK(cs_vAddedNodes);
1405             for (string& strAddNode : vAddedNodes)
1406                 lAddresses.push_back(strAddNode);
1407         }
1408
1409         list<vector<CService> > lservAddressesToAdd(0);
1410         for (string& strAddNode : lAddresses)
1411         {
1412             vector<CService> vservNode(0);
1413             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1414             {
1415                 lservAddressesToAdd.push_back(vservNode);
1416                 {
1417                     LOCK(cs_setservAddNodeAddresses);
1418                     for (CService& serv : vservNode)
1419                         setservAddNodeAddresses.insert(serv);
1420                 }
1421             }
1422         }
1423         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1424         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1425         {
1426             LOCK(cs_vNodes);
1427             for (CNode* pnode : vNodes)
1428                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1429                 {
1430                     for (CService& addrNode : *(it))
1431                         if (pnode->addr == addrNode)
1432                         {
1433                             it = lservAddressesToAdd.erase(it);
1434                             if(it != lservAddressesToAdd.begin())
1435                                 it--;
1436                             break;
1437                         }
1438                     if (it == lservAddressesToAdd.end())
1439                         break;
1440                 }
1441         }
1442         for (vector<CService>& vserv : lservAddressesToAdd)
1443         {
1444             if (vserv.size() == 0)
1445                 continue;
1446             CSemaphoreGrant grant(*semOutbound);
1447             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1448             Sleep(500);
1449             if (fShutdown)
1450                 return;
1451         }
1452         if (fShutdown)
1453             return;
1454         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1455         Sleep(120000); // Retry every 2 minutes
1456         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1457         if (fShutdown)
1458             return;
1459     }
1460 }
1461
1462 // if successful, this moves the passed grant to the constructed node
1463 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1464 {
1465     //
1466     // Initiate outbound network connection
1467     //
1468     if (fShutdown)
1469         return false;
1470     if (!strDest)
1471         if (IsLocal(addrConnect) ||
1472             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1473             FindNode(addrConnect.ToStringIPPort().c_str()))
1474             return false;
1475     if (strDest && FindNode(strDest))
1476         return false;
1477
1478     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1479     CNode* pnode = ConnectNode(addrConnect, strDest);
1480     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1481     if (fShutdown)
1482         return false;
1483     if (!pnode)
1484         return false;
1485     if (grantOutbound)
1486         grantOutbound->MoveTo(pnode->grantOutbound);
1487     pnode->fNetworkNode = true;
1488     if (fOneShot)
1489         pnode->fOneShot = true;
1490
1491     return true;
1492 }
1493
1494 // for now, use a very simple selection metric: the node from which we received
1495 // most recently
1496 static int64_t NodeSyncScore(const CNode *pnode) {
1497     return pnode->nLastRecv;
1498 }
1499
1500 void static StartSync(const vector<CNode*> &vNodes) {
1501     CNode *pnodeNewSync = NULL;
1502     int64_t nBestScore = 0;
1503
1504     // Iterate over all nodes
1505     for (CNode* pnode : vNodes) {
1506         // check preconditions for allowing a sync
1507         if (!pnode->fClient && !pnode->fOneShot &&
1508             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1509             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1510             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1511             // if ok, compare node's score with the best so far
1512             int64_t nScore = NodeSyncScore(pnode);
1513             if (pnodeNewSync == NULL || nScore > nBestScore) {
1514                 pnodeNewSync = pnode;
1515                 nBestScore = nScore;
1516             }
1517         }
1518     }
1519     // if a new sync candidate was found, start sync!
1520     if (pnodeNewSync) {
1521         pnodeNewSync->fStartSync = true;
1522         pnodeSync = pnodeNewSync;
1523     }
1524 }
1525
1526 void ThreadMessageHandler(void* parg)
1527 {
1528     // Make this thread recognisable as the message handling thread
1529     RenameThread("novacoin-msghand");
1530
1531     try
1532     {
1533         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1534         ThreadMessageHandler2(parg);
1535         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1536     }
1537     catch (std::exception& e) {
1538         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1539         PrintException(&e, "ThreadMessageHandler()");
1540     } catch (...) {
1541         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1542         PrintException(NULL, "ThreadMessageHandler()");
1543     }
1544     printf("ThreadMessageHandler exited\n");
1545 }
1546
1547 void ThreadMessageHandler2(void* parg)
1548 {
1549     printf("ThreadMessageHandler started\n");
1550     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1551     while (!fShutdown)
1552     {
1553         bool fHaveSyncNode = false;
1554         vector<CNode*> vNodesCopy;
1555         {
1556             LOCK(cs_vNodes);
1557             vNodesCopy = vNodes;
1558             for (CNode* pnode : vNodesCopy) {
1559                 pnode->AddRef();
1560                 if (pnode == pnodeSync)
1561                     fHaveSyncNode = true;
1562             }
1563         }
1564
1565         if (!fHaveSyncNode)
1566             StartSync(vNodesCopy);
1567
1568         // Poll the connected nodes for messages
1569         for (CNode* pnode : vNodesCopy)
1570         {
1571             // Receive messages
1572             {
1573                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1574                 if (lockRecv) {
1575                     if (!ProcessMessages(pnode)) {
1576                         pnode->CloseSocketDisconnect();
1577                         if (pnode == pnodeSync)
1578                             fHaveSyncNode = false;
1579                     }
1580                 }
1581             }
1582             if (fShutdown)
1583                 return;
1584
1585             // Send messages
1586             {
1587                 TRY_LOCK(pnode->cs_vSend, lockSend);
1588                 if (lockSend)
1589                     SendMessages(pnode);
1590             }
1591             if (fShutdown)
1592                 return;
1593         }
1594
1595         {
1596             LOCK(cs_vNodes);
1597             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1598         }
1599
1600         // Wait and allow messages to bunch up.
1601         // Reduce vnThreadsRunning so StopNode has permission to exit while
1602         // we're sleeping, but we must always check fShutdown after doing this.
1603         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1604         Sleep(100);
1605         if (fRequestShutdown)
1606             StartShutdown();
1607         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1608         if (fShutdown)
1609             return;
1610     }
1611 }
1612
1613
1614
1615
1616
1617
1618 bool BindListenPort(const CService &addrBind, string& strError)
1619 {
1620     strError.clear();
1621     int nOne = 1;
1622
1623     // Create socket for listening for incoming connections
1624 #ifdef USE_IPV6
1625     struct sockaddr_storage sockaddr;
1626 #else
1627     struct sockaddr sockaddr;
1628 #endif
1629     socklen_t len = sizeof(sockaddr);
1630     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1631     {
1632         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1633         printf("%s\n", strError.c_str());
1634         return false;
1635     }
1636
1637     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1638     if (hListenSocket == INVALID_SOCKET)
1639     {
1640         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1641         printf("%s\n", strError.c_str());
1642         return false;
1643     }
1644
1645 #ifndef WIN32
1646 #ifdef SO_NOSIGPIPE
1647     // Different way of disabling SIGPIPE on BSD
1648     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1649 #endif
1650     // Allow binding if the port is still in TIME_WAIT state after
1651     // the program was closed and restarted. Not an issue on windows!
1652     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1653 #endif
1654
1655 #ifdef WIN32
1656     // Set to non-blocking, incoming connections will also inherit this
1657     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1658 #else
1659     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1660 #endif
1661     {
1662         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1663         printf("%s\n", strError.c_str());
1664         return false;
1665     }
1666
1667 #ifdef USE_IPV6
1668     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1669     // and enable it by default or not. Try to enable it, if possible.
1670     if (addrBind.IsIPv6()) {
1671 #ifdef IPV6_V6ONLY
1672 #ifdef WIN32
1673         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1674 #else
1675         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1676 #endif
1677 #endif
1678 #ifdef WIN32
1679         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1680         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1681 #endif
1682     }
1683 #endif
1684
1685     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1686     {
1687         int nErr = WSAGetLastError();
1688         if (nErr == WSAEADDRINUSE)
1689             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1690         else
1691             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1692         printf("%s\n", strError.c_str());
1693         CloseSocket(hListenSocket);
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         CloseSocket(hListenSocket);
1704         return false;
1705     }
1706
1707     vhListenSocket.push_back(hListenSocket);
1708
1709     if (addrBind.IsRoutable() && fDiscover)
1710         AddLocal(addrBind, LOCAL_BIND);
1711
1712     return true;
1713 }
1714
1715 void static Discover()
1716 {
1717     if (!fDiscover)
1718         return;
1719
1720 #ifdef WIN32
1721     // Get local host IP
1722     char pszHostName[1000] = "";
1723     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1724     {
1725         vector<CNetAddr> vaddr;
1726         if (LookupHost(pszHostName, vaddr))
1727         {
1728             for (const CNetAddr &addr : vaddr)
1729             {
1730                 AddLocal(addr, LOCAL_IF);
1731             }
1732         }
1733     }
1734 #else
1735     // Get local host ip
1736     struct ifaddrs* myaddrs;
1737     if (getifaddrs(&myaddrs) == 0)
1738     {
1739         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1740         {
1741             if (ifa->ifa_addr == NULL) continue;
1742             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1743             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1744             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1745             if (ifa->ifa_addr->sa_family == AF_INET)
1746             {
1747                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1748                 CNetAddr addr(s4->sin_addr);
1749                 if (AddLocal(addr, LOCAL_IF))
1750                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1751             }
1752 #ifdef USE_IPV6
1753             else if (ifa->ifa_addr->sa_family == AF_INET6)
1754             {
1755                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1756                 CNetAddr addr(s6->sin6_addr);
1757                 if (AddLocal(addr, LOCAL_IF))
1758                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1759             }
1760 #endif
1761         }
1762         freeifaddrs(myaddrs);
1763     }
1764 #endif
1765
1766     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1767     if (!IsLimited(NET_IPV4))
1768         NewThread(ThreadGetMyExternalIP, NULL);
1769 }
1770
1771 void StartNode(void* parg)
1772 {
1773     // Make this thread recognisable as the startup thread
1774     RenameThread("novacoin-start");
1775
1776     if (semOutbound == NULL) {
1777         // initialize semaphore
1778         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1779         semOutbound = new CSemaphore(nMaxOutbound);
1780     }
1781
1782     if (pnodeLocalHost == NULL)
1783         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1784
1785     Discover();
1786
1787     //
1788     // Start threads
1789     //
1790
1791     if (!GetBoolArg("-dnsseed", true))
1792         printf("DNS seeding disabled\n");
1793     else
1794         if (!NewThread(ThreadDNSAddressSeed, NULL))
1795             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1796
1797     // Get addresses from IRC and advertise ours
1798     if (!GetBoolArg("-irc", true))
1799         printf("IRC seeding disabled\n");
1800     else
1801         if (!NewThread(ThreadIRCSeed, NULL))
1802             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1803
1804     // Send and receive from sockets, accept connections
1805     if (!NewThread(ThreadSocketHandler, NULL))
1806         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1807
1808     // Initiate outbound connections from -addnode
1809     if (!NewThread(ThreadOpenAddedConnections, NULL))
1810         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1811
1812     // Initiate outbound connections
1813     if (!NewThread(ThreadOpenConnections, NULL))
1814         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1815
1816     // Process messages
1817     if (!NewThread(ThreadMessageHandler, NULL))
1818         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1819
1820     // Dump network addresses
1821     if (!NewThread(ThreadDumpAddress, NULL))
1822         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1823
1824     // Mine proof-of-stake blocks in the background
1825     if (!NewThread(ThreadStakeMiner, pwalletMain))
1826         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1827
1828     // Trusted NTP server, it's localhost by default.
1829     strTrustedUpstream = GetArg("-ntp", "localhost");
1830
1831     // Start periodical NTP sampling thread
1832     NewThread(ThreadNtpSamples, NULL);
1833
1834 }
1835
1836 bool StopNode()
1837 {
1838     printf("StopNode()\n");
1839     fShutdown = true;
1840     nTransactionsUpdated++;
1841     int64_t nStart = GetTime();
1842     {
1843         LOCK(cs_main);
1844         ThreadScriptCheckQuit();
1845     }
1846     if (semOutbound)
1847         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1848             semOutbound->post();
1849     for ( ; ; )
1850     {
1851         int nThreadsRunning = 0;
1852         for (int n = 0; n < THREAD_MAX; n++)
1853             nThreadsRunning += vnThreadsRunning[n];
1854         if (nThreadsRunning == 0)
1855             break;
1856         if (GetTime() - nStart > 20)
1857             break;
1858         Sleep(20);
1859     };
1860     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1861     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1862     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1863     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1864     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1865     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1866     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1867     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1868     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1869     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1870     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1871         Sleep(20);
1872     Sleep(50);
1873     DumpAddresses();
1874
1875     return true;
1876 }
1877
1878 class CNetCleanup
1879 {
1880 public:
1881     CNetCleanup()
1882     {
1883     }
1884     ~CNetCleanup()
1885     {
1886         // Close sockets
1887         for (CNode* pnode : vNodes)
1888             if (pnode->hSocket != INVALID_SOCKET)
1889                 CloseSocket(pnode->hSocket);
1890         for (SOCKET hListenSocket : vhListenSocket)
1891             if (hListenSocket != INVALID_SOCKET)
1892                 if (!CloseSocket(hListenSocket))
1893                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1894
1895         // clean up some globals (to help leak detection)
1896         for (CNode *pnode : vNodes)
1897             delete pnode;
1898         for (CNode *pnode : vNodesDisconnected)
1899             delete pnode;
1900         vNodes.clear();
1901         vNodesDisconnected.clear();
1902         delete semOutbound;
1903         semOutbound = NULL;
1904         delete pnodeLocalHost;
1905         pnodeLocalHost = NULL;
1906
1907 #ifdef WIN32
1908         // Shutdown Windows Sockets
1909         WSACleanup();
1910 #endif
1911     }
1912 }
1913 instance_of_cnetcleanup;
1914
1915 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1916 {
1917     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1918     ss.reserve(10000);
1919     ss << tx;
1920     RelayTransaction(tx, hash, ss);
1921 }
1922
1923 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1924 {
1925     CInv inv(MSG_TX, hash);
1926     {
1927         LOCK(cs_mapRelay);
1928         // Expire old relay messages
1929         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1930         {
1931             mapRelay.erase(vRelayExpiration.front().second);
1932             vRelayExpiration.pop_front();
1933         }
1934
1935         // Save original serialized message so newer versions are preserved
1936         mapRelay.insert(std::make_pair(inv, ss));
1937         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1938     }
1939
1940     RelayInventory(inv);
1941 }
1942
1943 void CNode::RecordBytesRecv(uint64_t bytes)
1944 {
1945     LOCK(cs_totalBytesRecv);
1946     nTotalBytesRecv += bytes;
1947 }
1948
1949 void CNode::RecordBytesSent(uint64_t bytes)
1950 {
1951     LOCK(cs_totalBytesSent);
1952     nTotalBytesSent += bytes;
1953 }
1954
1955 uint64_t CNode::GetTotalBytesRecv()
1956 {
1957     LOCK(cs_totalBytesRecv);
1958     return nTotalBytesRecv;
1959 }
1960
1961 uint64_t CNode::GetTotalBytesSent()
1962 {
1963     LOCK(cs_totalBytesSent);
1964     return nTotalBytesSent;
1965 }
1966 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
1967     return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
1968 }