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_mapRequests, lockReq);
738                                 if (lockReq)
739                                 {
740                                     TRY_LOCK(pnode->cs_inventory, lockInv);
741                                     if (lockInv)
742                                         fDelete = true;
743                                 }
744                             }
745                         }
746                     }
747                     if (fDelete)
748                     {
749                         vNodesDisconnected.remove(pnode);
750                         delete pnode;
751                     }
752                 }
753             }
754         }
755         if (vNodes.size() != nPrevNodeCount)
756         {
757             nPrevNodeCount = vNodes.size();
758             uiInterface.NotifyNumConnectionsChanged(vNodes.size());
759         }
760
761
762         //
763         // Find which sockets have data to receive
764         //
765         struct timeval timeout;
766         timeout.tv_sec  = 0;
767         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
768
769         fd_set fdsetRecv;
770         fd_set fdsetSend;
771         fd_set fdsetError;
772         FD_ZERO(&fdsetRecv);
773         FD_ZERO(&fdsetSend);
774         FD_ZERO(&fdsetError);
775         SOCKET hSocketMax = 0;
776         bool have_fds = false;
777
778         for (SOCKET hListenSocket : vhListenSocket) {
779             FD_SET(hListenSocket, &fdsetRecv);
780             hSocketMax = max(hSocketMax, hListenSocket);
781             have_fds = true;
782         }
783         {
784             LOCK(cs_vNodes);
785             for (CNode* pnode : vNodes)
786             {
787                 if (pnode->hSocket == INVALID_SOCKET)
788                     continue;
789                 FD_SET(pnode->hSocket, &fdsetRecv);
790                 FD_SET(pnode->hSocket, &fdsetError);
791                 hSocketMax = max(hSocketMax, pnode->hSocket);
792                 have_fds = true;
793                 {
794                     TRY_LOCK(pnode->cs_vSend, lockSend);
795                     if (lockSend && !pnode->vSend.empty())
796                         FD_SET(pnode->hSocket, &fdsetSend);
797                 }
798             }
799         }
800
801         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
802         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
803                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
804         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
805         if (fShutdown)
806             return;
807         if (nSelect == SOCKET_ERROR)
808         {
809             if (have_fds)
810             {
811                 int nErr = WSAGetLastError();
812                 printf("socket select error %d\n", nErr);
813                 for (unsigned int i = 0; i <= hSocketMax; i++)
814                     FD_SET(i, &fdsetRecv);
815             }
816             FD_ZERO(&fdsetSend);
817             FD_ZERO(&fdsetError);
818             Sleep(timeout.tv_usec/1000);
819         }
820
821
822         //
823         // Accept new connections
824         //
825         for (SOCKET hListenSocket : vhListenSocket)
826         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
827         {
828 #ifdef USE_IPV6
829             struct sockaddr_storage sockaddr;
830 #else
831             struct sockaddr sockaddr;
832 #endif
833             socklen_t len = sizeof(sockaddr);
834             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
835             CAddress addr;
836             int nInbound = 0;
837
838             if (hSocket != INVALID_SOCKET)
839                 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
840                     printf("Warning: Unknown socket family\n");
841
842             {
843                 LOCK(cs_vNodes);
844                 for (CNode* pnode : vNodes)
845                     if (pnode->fInbound)
846                         nInbound++;
847             }
848
849             if (hSocket == INVALID_SOCKET)
850             {
851                 int nErr = WSAGetLastError();
852                 if (nErr != WSAEWOULDBLOCK)
853                     printf("socket error accept failed: %d\n", nErr);
854             }
855             else if (nInbound >= GetArgInt("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
856             {
857                 {
858                     LOCK(cs_setservAddNodeAddresses);
859                     if (!setservAddNodeAddresses.count(addr))
860                         CloseSocket(hSocket);
861                 }
862             }
863             else if (CNode::IsBanned(addr))
864             {
865                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
866                 CloseSocket(hSocket);
867             }
868             else
869             {
870                 printf("accepted connection %s\n", addr.ToString().c_str());
871                 CNode* pnode = new CNode(hSocket, addr, "", true);
872                 pnode->AddRef();
873                 {
874                     LOCK(cs_vNodes);
875                     vNodes.push_back(pnode);
876                 }
877             }
878         }
879
880
881         //
882         // Service each socket
883         //
884         vector<CNode*> vNodesCopy;
885         {
886             LOCK(cs_vNodes);
887             vNodesCopy = vNodes;
888             for (CNode* pnode : vNodesCopy)
889                 pnode->AddRef();
890         }
891         for (CNode* pnode : vNodesCopy)
892         {
893             if (fShutdown)
894                 return;
895
896             //
897             // Receive
898             //
899             if (pnode->hSocket == INVALID_SOCKET)
900                 continue;
901             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
902             {
903                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
904                 if (lockRecv)
905                 {
906                     CDataStream& vRecv = pnode->vRecv;
907                     uint64_t nPos = vRecv.size();
908
909                     if (nPos > ReceiveBufferSize()) {
910                         if (!pnode->fDisconnect)
911                             printf("socket recv flood control disconnect (%" PRIszu " bytes)\n", vRecv.size());
912                         pnode->CloseSocketDisconnect();
913                     }
914                     else {
915                         // typical socket buffer is 8K-64K
916                         char pchBuf[0x10000];
917                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
918                         if (nBytes > 0)
919                         {
920                             vRecv.resize(nPos + nBytes);
921                             memcpy(&vRecv[nPos], pchBuf, nBytes);
922                             pnode->nLastRecv = GetTime();
923                             pnode->nRecvBytes += nBytes;
924                             pnode->RecordBytesRecv(nBytes);
925                         }
926                         else if (nBytes == 0)
927                         {
928                             // socket closed gracefully
929                             if (!pnode->fDisconnect)
930                                 printf("socket closed\n");
931                             pnode->CloseSocketDisconnect();
932                         }
933                         else if (nBytes < 0)
934                         {
935                             // error
936                             int nErr = WSAGetLastError();
937                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
938                             {
939                                 if (!pnode->fDisconnect)
940                                     printf("socket recv error %d\n", nErr);
941                                 pnode->CloseSocketDisconnect();
942                             }
943                         }
944                     }
945                 }
946             }
947
948             //
949             // Send
950             //
951             if (pnode->hSocket == INVALID_SOCKET)
952                 continue;
953             if (FD_ISSET(pnode->hSocket, &fdsetSend))
954             {
955                 TRY_LOCK(pnode->cs_vSend, lockSend);
956                 if (lockSend)
957                 {
958                     CDataStream& vSend = pnode->vSend;
959                     if (!vSend.empty())
960                     {
961                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
962                         if (nBytes > 0)
963                         {
964                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
965                             pnode->nLastSend = GetTime();
966                             pnode->nSendBytes += nBytes;
967                             pnode->RecordBytesSent(nBytes);
968                         }
969                         else if (nBytes < 0)
970                         {
971                             // error
972                             int nErr = WSAGetLastError();
973                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
974                             {
975                                 printf("socket send error %d\n", nErr);
976                                 pnode->CloseSocketDisconnect();
977                             }
978                         }
979                     }
980                 }
981             }
982
983             //
984             // Inactivity checking
985             //
986             if (pnode->vSend.empty())
987                 pnode->nLastSendEmpty = GetTime();
988             if (GetTime() - pnode->nTimeConnected > 60)
989             {
990                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
991                 {
992                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
993                     pnode->fDisconnect = true;
994                 }
995                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
996                 {
997                     printf("socket not sending\n");
998                     pnode->fDisconnect = true;
999                 }
1000                 else if (GetTime() - pnode->nLastRecv > 90*60)
1001                 {
1002                     printf("socket inactivity timeout\n");
1003                     pnode->fDisconnect = true;
1004                 }
1005             }
1006         }
1007         {
1008             LOCK(cs_vNodes);
1009             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1010         }
1011
1012         Sleep(10);
1013     }
1014 }
1015
1016 // DNS seeds
1017 // Each pair gives a source name and a seed name.
1018 // The first name is used as information source for addrman.
1019 // The second name should resolve to a list of seed addresses.
1020 static const char *strDNSSeed[][2] = {
1021     {"node.novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro"},
1022     {"novacoin.ru", "dnsseed.novacoin.ru"},
1023     {"novacoin.ru", "testseed.novacoin.ru"},
1024     {"novaco.in", "dnsseed.novaco.in"},
1025 };
1026
1027 void ThreadDNSAddressSeed(void* parg)
1028 {
1029     // Make this thread recognisable as the DNS seeding thread
1030     RenameThread("novacoin-dnsseed");
1031
1032     try
1033     {
1034         vnThreadsRunning[THREAD_DNSSEED]++;
1035         ThreadDNSAddressSeed2(parg);
1036         vnThreadsRunning[THREAD_DNSSEED]--;
1037     }
1038     catch (std::exception& e) {
1039         vnThreadsRunning[THREAD_DNSSEED]--;
1040         PrintException(&e, "ThreadDNSAddressSeed()");
1041     } catch (...) {
1042         vnThreadsRunning[THREAD_DNSSEED]--;
1043         throw; // support pthread_cancel()
1044     }
1045     printf("ThreadDNSAddressSeed exited\n");
1046 }
1047
1048 void ThreadDNSAddressSeed2(void* parg)
1049 {
1050     printf("ThreadDNSAddressSeed started\n");
1051     int found = 0;
1052
1053     if (!fTestNet)
1054     {
1055         printf("Loading addresses from DNS seeds (could take a while)\n");
1056
1057         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1058             if (HaveNameProxy()) {
1059                 AddOneShot(strDNSSeed[seed_idx][1]);
1060             } else {
1061                 vector<CNetAddr> vaddr;
1062                 vector<CAddress> vAdd;
1063                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1064                 {
1065                     for (CNetAddr& ip : vaddr)
1066                     {
1067                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1068                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1069                         vAdd.push_back(addr);
1070                         found++;
1071                     }
1072                 }
1073                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1074             }
1075         }
1076     }
1077
1078     printf("%d addresses found from DNS seeds\n", found);
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092 uint32_t pnSeed[] =
1093 {
1094     0x1c542868, 0x3859dd6f, 0x203c2e68, 0xf145a6bc, 0x638a545f, 0x325da346, 0x385da346, 0xfb2b8d5f,
1095     0x52568c5f, 0xa979e65b, 0x8de6485d, 0x9f79e65b, 0x048a861f, 0x3388b55f, 0x6ff0b45e, 0x17e81f5f,
1096     0x6c47bb25, 0x1ecdc852, 0x28263db9, 0x47824e5d, 0x36f1c851, 0x2bf913b2, 0x95923cb3, 0x84e63eb2,
1097     0xefdeedbf, 0x65200092, 0xf36f6805, 0x42692d05, 0x772c1955, 0xb6bf1b4e, 0x7abb5f5d, 0xdb2fa6bc,
1098     0x90e911bf, 0x82de565f, 0x694416b2, 0x0ab600bc, 0xfcecbe6d, 0x24ed9fb2, 0x1bb618c2, 0xc64765bb,
1099     0x4e3d62c3, 0xdba24baa, 0x4b7109b0, 0x12a12cc2, 0xfc01864f, 0x0b69e85b, 0x33922c1f, 0xac611bc6,
1100     0x2a257155, 0x991d5fc0, 0xbfdabcb1, 0x9b73ee55, 0x5bc2b95d, 0xdef0762e, 0x6ab7c936, 0x9c4416b2,
1101     0xd60d864f, 0x03671f1f, 0x3b5da346, 0xc6f5c851, 0x5411b2d4, 0xe7c25702, 0x63474fb0, 0x7e11c854,
1102     0x52381d5f, 0x72fdfe59, 0x51599a05, 0xfb12b2d4, 0xaee4f15e, 0xd0e3f15e, 0x2aa2805f, 0xa1caf15e,
1103     0x34fe425e, 0x46e1f15e, 0xd7c71955, 0xaeeff15e, 0x47c2af55, 0x563d89b2, 0x67980fd9, 0xc9def15e,
1104     0x9cc51eb9, 0xdaa7aa6b, 0x78e6871f, 0x0d5d2cb2, 0x7aedf15e, 0x9bcaf15e, 0xe5f7f15e, 0x501c1759,
1105     0xdfbc4980, 0xa7397f2e, 0x31ea1a02, 0x3a27655e, 0xaa86f05c, 0xdcddf15e, 0x64689cb2, 0xd4bf62d4,
1106     0xf093eab2, 0x98def15e, 0xb6c5f15e, 0x81e8f15e, 0xe5d2fe59, 0xa312786d, 0x4cf9fe59, 0x8a922c1f,
1107     0x00c7fe59, 0x1ade565f, 0x9e4116b2, 0x2c36983e, 0x68f8f15e, 0x51b7eab2, 0x76c51eb9, 0x9edd4980,
1108     0x90ef565f, 0x0dd80857, 0xd513fb94, 0xf5bdeab2, 0xa95277b0, 0x2cf2f15e, 0x1897eab2, 0x924416b2,
1109     0x985c9b59, 0x30aa43d8, 0xf9c6745f, 0xaf862e5f, 0xe0ceeab2, 0xb9b3eab2, 0x6da4eab2, 0xa4fdeab2,
1110     0x0fa6c125, 0xe38bbd05, 0x5d922c1f, 0x9bd0eab2, 0x73025e02, 0xc4fd794d, 0x8435b35f, 0x2d01bc2e,
1111     0xaa2a14d4, 0xa22b07cb, 0xebda6f4f, 0xddc6514e, 0xf23feab2, 0xea1e5256, 0x6147b45e, 0x47d21e4f,
1112     0x67c41c1f, 0x53ec1a02, 0x352e786d, 0x6bec1a02, 0x78fb4abe, 0xd3014c5d, 0x9fbbeab2, 0x1fc51eb9,
1113     0x720eeab2, 0x2db5eab2, 0xe8baf65c, 0x521b459e, 0x65c4955f, 0x0e7b915f, 0xa8f37e6d, 0x6d0b465f,
1114     0xfab8ff5c, 0xf7c27e6d, 0x7345a846, 0x4fd1a7d5, 0xdfc97e6d, 0x26c27e6d, 0xa9de36b2, 0xc615344d,
1115     0x28ceb95d, 0xa52d895e, 0x18c17e6d, 0x13ec1a02, 0x0ba37125, 0x6c3d344d, 0xb3922c1f, 0x506bbeb0,
1116     0x4d04994e, 0xa1bbe56d, 0xf62c344d, 0x0847d048, 0x4bdc6451, 0xc95b9a05, 0xbcd3a7d5, 0x29b57125,
1117     0x0c4d2cb2, 0xf2b8eab2, 0xc2d5b95d, 0x0185ef59, 0x30adeab2, 0xcaf0e92e, 0x756c344d, 0xfd9e252e,
1118     0xbe5ef3bc, 0x4689344d, 0xb223895e, 0xfcebeaad, 0xb7c0e92e, 0x993c1760, 0xe1e171b0, 0xb857e75b,
1119     0xbf10002e, 0xb55b2cb2, 0xa90e2cb2, 0x13d6f15e, 0xf8be9225, 0x14ddf15e, 0x06e90305, 0x82472cb2,
1120 };
1121
1122 const char* pchTorSeed[] = 
1123 {
1124     "seedp4knqnoei57u.onion",
1125     "seedr3hhlepyi7fd.onion",
1126     "seed3uuomkclbiz4.onion",
1127     "seedeh7qck3ouff5.onion",
1128     "5rg3vq4jagckeckf.onion",
1129     "seedt3sraf53ajiy.onion",
1130     "seedg4qyccsg42oq.onion",
1131     "novaqrtoywpg7jly.onion",
1132     "seed3d5wolqbgrcb.onion",
1133     "seed24u5dwph3qw4.onion",
1134     "mj26ulzbs2oskgym.onion",
1135     "eqon4usunavt76m7.onion",
1136     "seedd3aldwpslzl3.onion"
1137 };
1138
1139 void DumpAddresses()
1140 {
1141     int64_t nStart = GetTimeMillis();
1142
1143     CAddrDB adb;
1144     adb.Write(addrman);
1145
1146     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1147            addrman.size(), GetTimeMillis() - nStart);
1148 }
1149
1150 void ThreadDumpAddress2(void* parg)
1151 {
1152     printf("ThreadDumpAddress started\n");
1153
1154     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1155     while (!fShutdown)
1156     {
1157         DumpAddresses();
1158         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1159         Sleep(600000);
1160         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1161     }
1162     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1163 }
1164
1165 void ThreadDumpAddress(void* parg)
1166 {
1167     // Make this thread recognisable as the address dumping thread
1168     RenameThread("novacoin-adrdump");
1169
1170     try
1171     {
1172         ThreadDumpAddress2(parg);
1173     }
1174     catch (std::exception& e) {
1175         PrintException(&e, "ThreadDumpAddress()");
1176     }
1177     printf("ThreadDumpAddress exited\n");
1178 }
1179
1180 void ThreadOpenConnections(void* parg)
1181 {
1182     // Make this thread recognisable as the connection opening thread
1183     RenameThread("novacoin-opencon");
1184
1185     try
1186     {
1187         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1188         ThreadOpenConnections2(parg);
1189         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1190     }
1191     catch (std::exception& e) {
1192         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1193         PrintException(&e, "ThreadOpenConnections()");
1194     } catch (...) {
1195         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1196         PrintException(NULL, "ThreadOpenConnections()");
1197     }
1198     printf("ThreadOpenConnections exited\n");
1199 }
1200
1201 void static ProcessOneShot()
1202 {
1203     string strDest;
1204     {
1205         LOCK(cs_vOneShots);
1206         if (vOneShots.empty())
1207             return;
1208         strDest = vOneShots.front();
1209         vOneShots.pop_front();
1210     }
1211     CAddress addr;
1212     CSemaphoreGrant grant(*semOutbound, true);
1213     if (grant) {
1214         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1215             AddOneShot(strDest);
1216     }
1217 }
1218
1219 void ThreadOpenConnections2(void* parg)
1220 {
1221     printf("ThreadOpenConnections started\n");
1222
1223     // Connect to specific addresses
1224     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1225     {
1226         for (int64_t nLoop = 0;; nLoop++)
1227         {
1228             ProcessOneShot();
1229             for (string strAddr : mapMultiArgs["-connect"])
1230             {
1231                 CAddress addr;
1232                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1233                 for (int i = 0; i < 10 && i < nLoop; i++)
1234                 {
1235                     Sleep(500);
1236                     if (fShutdown)
1237                         return;
1238                 }
1239             }
1240             Sleep(500);
1241         }
1242     }
1243
1244     // Initiate network connections
1245     int64_t nStart = GetTime();
1246     for ( ; ; )
1247     {
1248         ProcessOneShot();
1249
1250         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1251         Sleep(500);
1252         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1253         if (fShutdown)
1254             return;
1255
1256
1257         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1258         CSemaphoreGrant grant(*semOutbound);
1259         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1260         if (fShutdown)
1261             return;
1262
1263         // Add seed nodes if IRC isn't working
1264         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1265         {
1266             std::vector<CAddress> vAdd;
1267             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1268             {
1269                 // It'll only connect to one or two seed nodes because once it connects,
1270                 // it'll get a pile of addresses with newer timestamps.
1271                 // Seed nodes are given a random 'last seen time' of between one and two
1272                 // weeks ago.
1273                 struct in_addr ip;
1274                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1275                 CAddress addr(CService(ip, GetDefaultPort()));
1276                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1277                 vAdd.push_back(addr);
1278             }
1279             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1280         }
1281
1282         // Add Tor nodes if we have connection with onion router
1283         if (mapArgs.count("-tor"))
1284         {
1285             std::vector<CAddress> vAdd;
1286             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1287             {
1288                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1289                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1290                 vAdd.push_back(addr);
1291             }
1292             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1293         }
1294
1295         //
1296         // Choose an address to connect to based on most recently seen
1297         //
1298         CAddress addrConnect;
1299
1300         // Only connect out to one peer per network group (/16 for IPv4).
1301         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1302         int nOutbound = 0;
1303         set<vector<unsigned char> > setConnected;
1304         {
1305             LOCK(cs_vNodes);
1306             for (CNode* pnode : vNodes) {
1307                 if (!pnode->fInbound) {
1308                     setConnected.insert(pnode->addr.GetGroup());
1309                     nOutbound++;
1310                 }
1311             }
1312         }
1313
1314         int64_t nANow = GetAdjustedTime();
1315
1316         int nTries = 0;
1317         for ( ; ; )
1318         {
1319             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1320             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1321
1322             // if we selected an invalid address, restart
1323             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1324                 break;
1325
1326             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1327             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1328             // already-connected network ranges, ...) before trying new addrman addresses.
1329             nTries++;
1330             if (nTries > 100)
1331                 break;
1332
1333             if (IsLimited(addr))
1334                 continue;
1335
1336             // only consider very recently tried nodes after 30 failed attempts
1337             if (nANow - addr.nLastTry < 600 && nTries < 30)
1338                 continue;
1339
1340             // do not allow non-default ports, unless after 50 invalid addresses selected already
1341             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1342                 continue;
1343
1344             addrConnect = addr;
1345             break;
1346         }
1347
1348         if (addrConnect.IsValid())
1349             OpenNetworkConnection(addrConnect, &grant);
1350     }
1351 }
1352
1353 void ThreadOpenAddedConnections(void* parg)
1354 {
1355     // Make this thread recognisable as the connection opening thread
1356     RenameThread("novacoin-opencon");
1357
1358     try
1359     {
1360         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1361         ThreadOpenAddedConnections2(parg);
1362         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1363     }
1364     catch (std::exception& e) {
1365         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1366         PrintException(&e, "ThreadOpenAddedConnections()");
1367     } catch (...) {
1368         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1369         PrintException(NULL, "ThreadOpenAddedConnections()");
1370     }
1371     printf("ThreadOpenAddedConnections exited\n");
1372 }
1373
1374 void ThreadOpenAddedConnections2(void* parg)
1375 {
1376     printf("ThreadOpenAddedConnections started\n");
1377
1378     {
1379         LOCK(cs_vAddedNodes);
1380         vAddedNodes = mapMultiArgs["-addnode"];
1381     }
1382
1383     if (HaveNameProxy()) {
1384         while(!fShutdown) {
1385             list<string> lAddresses(0);
1386             {
1387                 LOCK(cs_vAddedNodes);
1388                 for (string& strAddNode : vAddedNodes)
1389                     lAddresses.push_back(strAddNode);
1390             }
1391             for (string& strAddNode : lAddresses) {
1392                 CAddress addr;
1393                 CSemaphoreGrant grant(*semOutbound);
1394                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1395                 Sleep(500);
1396             }
1397             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1398             Sleep(120000); // Retry every 2 minutes
1399             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1400         }
1401         return;
1402     }
1403
1404     for (uint32_t i = 0; true; i++)
1405     {
1406         list<string> lAddresses(0);
1407         {
1408             LOCK(cs_vAddedNodes);
1409             for (string& strAddNode : vAddedNodes)
1410                 lAddresses.push_back(strAddNode);
1411         }
1412
1413         list<vector<CService> > lservAddressesToAdd(0);
1414         for (string& strAddNode : lAddresses)
1415         {
1416             vector<CService> vservNode(0);
1417             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1418             {
1419                 lservAddressesToAdd.push_back(vservNode);
1420                 {
1421                     LOCK(cs_setservAddNodeAddresses);
1422                     for (CService& serv : vservNode)
1423                         setservAddNodeAddresses.insert(serv);
1424                 }
1425             }
1426         }
1427         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1428         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1429         {
1430             LOCK(cs_vNodes);
1431             for (CNode* pnode : vNodes)
1432                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1433                 {
1434                     for (CService& addrNode : *(it))
1435                         if (pnode->addr == addrNode)
1436                         {
1437                             it = lservAddressesToAdd.erase(it);
1438                             if(it != lservAddressesToAdd.begin())
1439                                 it--;
1440                             break;
1441                         }
1442                     if (it == lservAddressesToAdd.end())
1443                         break;
1444                 }
1445         }
1446         for (vector<CService>& vserv : lservAddressesToAdd)
1447         {
1448             if (vserv.size() == 0)
1449                 continue;
1450             CSemaphoreGrant grant(*semOutbound);
1451             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1452             Sleep(500);
1453             if (fShutdown)
1454                 return;
1455         }
1456         if (fShutdown)
1457             return;
1458         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1459         Sleep(120000); // Retry every 2 minutes
1460         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1461         if (fShutdown)
1462             return;
1463     }
1464 }
1465
1466 // if successful, this moves the passed grant to the constructed node
1467 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1468 {
1469     //
1470     // Initiate outbound network connection
1471     //
1472     if (fShutdown)
1473         return false;
1474     if (!strDest)
1475         if (IsLocal(addrConnect) ||
1476             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1477             FindNode(addrConnect.ToStringIPPort().c_str()))
1478             return false;
1479     if (strDest && FindNode(strDest))
1480         return false;
1481
1482     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1483     CNode* pnode = ConnectNode(addrConnect, strDest);
1484     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1485     if (fShutdown)
1486         return false;
1487     if (!pnode)
1488         return false;
1489     if (grantOutbound)
1490         grantOutbound->MoveTo(pnode->grantOutbound);
1491     pnode->fNetworkNode = true;
1492     if (fOneShot)
1493         pnode->fOneShot = true;
1494
1495     return true;
1496 }
1497
1498 // for now, use a very simple selection metric: the node from which we received
1499 // most recently
1500 static int64_t NodeSyncScore(const CNode *pnode) {
1501     return pnode->nLastRecv;
1502 }
1503
1504 void static StartSync(const vector<CNode*> &vNodes) {
1505     CNode *pnodeNewSync = NULL;
1506     int64_t nBestScore = 0;
1507
1508     // Iterate over all nodes
1509     for (CNode* pnode : vNodes) {
1510         // check preconditions for allowing a sync
1511         if (!pnode->fClient && !pnode->fOneShot &&
1512             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1513             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1514             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1515             // if ok, compare node's score with the best so far
1516             int64_t nScore = NodeSyncScore(pnode);
1517             if (pnodeNewSync == NULL || nScore > nBestScore) {
1518                 pnodeNewSync = pnode;
1519                 nBestScore = nScore;
1520             }
1521         }
1522     }
1523     // if a new sync candidate was found, start sync!
1524     if (pnodeNewSync) {
1525         pnodeNewSync->fStartSync = true;
1526         pnodeSync = pnodeNewSync;
1527     }
1528 }
1529
1530 void ThreadMessageHandler(void* parg)
1531 {
1532     // Make this thread recognisable as the message handling thread
1533     RenameThread("novacoin-msghand");
1534
1535     try
1536     {
1537         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1538         ThreadMessageHandler2(parg);
1539         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1540     }
1541     catch (std::exception& e) {
1542         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1543         PrintException(&e, "ThreadMessageHandler()");
1544     } catch (...) {
1545         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1546         PrintException(NULL, "ThreadMessageHandler()");
1547     }
1548     printf("ThreadMessageHandler exited\n");
1549 }
1550
1551 void ThreadMessageHandler2(void* parg)
1552 {
1553     printf("ThreadMessageHandler started\n");
1554     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1555     while (!fShutdown)
1556     {
1557         bool fHaveSyncNode = false;
1558         vector<CNode*> vNodesCopy;
1559         {
1560             LOCK(cs_vNodes);
1561             vNodesCopy = vNodes;
1562             for (CNode* pnode : vNodesCopy) {
1563                 pnode->AddRef();
1564                 if (pnode == pnodeSync)
1565                     fHaveSyncNode = true;
1566             }
1567         }
1568
1569         if (!fHaveSyncNode)
1570             StartSync(vNodesCopy);
1571
1572         // Poll the connected nodes for messages
1573         for (CNode* pnode : vNodesCopy)
1574         {
1575             // Receive messages
1576             {
1577                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1578                 if (lockRecv) {
1579                     if (!ProcessMessages(pnode)) {
1580                         pnode->CloseSocketDisconnect();
1581                         if (pnode == pnodeSync)
1582                             fHaveSyncNode = false;
1583                     }
1584                 }
1585             }
1586             if (fShutdown)
1587                 return;
1588
1589             // Send messages
1590             {
1591                 TRY_LOCK(pnode->cs_vSend, lockSend);
1592                 if (lockSend)
1593                     SendMessages(pnode);
1594             }
1595             if (fShutdown)
1596                 return;
1597         }
1598
1599         {
1600             LOCK(cs_vNodes);
1601             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1602         }
1603
1604         // Wait and allow messages to bunch up.
1605         // Reduce vnThreadsRunning so StopNode has permission to exit while
1606         // we're sleeping, but we must always check fShutdown after doing this.
1607         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1608         Sleep(100);
1609         if (fRequestShutdown)
1610             StartShutdown();
1611         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1612         if (fShutdown)
1613             return;
1614     }
1615 }
1616
1617
1618
1619
1620
1621
1622 bool BindListenPort(const CService &addrBind, string& strError)
1623 {
1624     strError.clear();
1625     int nOne = 1;
1626
1627     // Create socket for listening for incoming connections
1628 #ifdef USE_IPV6
1629     struct sockaddr_storage sockaddr;
1630 #else
1631     struct sockaddr sockaddr;
1632 #endif
1633     socklen_t len = sizeof(sockaddr);
1634     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1635     {
1636         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1637         printf("%s\n", strError.c_str());
1638         return false;
1639     }
1640
1641     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1642     if (hListenSocket == INVALID_SOCKET)
1643     {
1644         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1645         printf("%s\n", strError.c_str());
1646         return false;
1647     }
1648
1649 #ifndef WIN32
1650 #ifdef SO_NOSIGPIPE
1651     // Different way of disabling SIGPIPE on BSD
1652     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1653 #endif
1654     // Allow binding if the port is still in TIME_WAIT state after
1655     // the program was closed and restarted. Not an issue on windows!
1656     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1657 #endif
1658
1659 #ifdef WIN32
1660     // Set to non-blocking, incoming connections will also inherit this
1661     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1662 #else
1663     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1664 #endif
1665     {
1666         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1667         printf("%s\n", strError.c_str());
1668         return false;
1669     }
1670
1671 #ifdef USE_IPV6
1672     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1673     // and enable it by default or not. Try to enable it, if possible.
1674     if (addrBind.IsIPv6()) {
1675 #ifdef IPV6_V6ONLY
1676 #ifdef WIN32
1677         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1678 #else
1679         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1680 #endif
1681 #endif
1682 #ifdef WIN32
1683         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1684         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1685 #endif
1686     }
1687 #endif
1688
1689     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1690     {
1691         int nErr = WSAGetLastError();
1692         if (nErr == WSAEADDRINUSE)
1693             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1694         else
1695             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1696         printf("%s\n", strError.c_str());
1697         CloseSocket(hListenSocket);
1698         return false;
1699     }
1700     printf("Bound to %s\n", addrBind.ToString().c_str());
1701
1702     // Listen for incoming connections
1703     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1704     {
1705         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1706         printf("%s\n", strError.c_str());
1707         CloseSocket(hListenSocket);
1708         return false;
1709     }
1710
1711     vhListenSocket.push_back(hListenSocket);
1712
1713     if (addrBind.IsRoutable() && fDiscover)
1714         AddLocal(addrBind, LOCAL_BIND);
1715
1716     return true;
1717 }
1718
1719 void static Discover()
1720 {
1721     if (!fDiscover)
1722         return;
1723
1724 #ifdef WIN32
1725     // Get local host IP
1726     char pszHostName[1000] = "";
1727     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1728     {
1729         vector<CNetAddr> vaddr;
1730         if (LookupHost(pszHostName, vaddr))
1731         {
1732             for (const CNetAddr &addr : vaddr)
1733             {
1734                 AddLocal(addr, LOCAL_IF);
1735             }
1736         }
1737     }
1738 #else
1739     // Get local host ip
1740     struct ifaddrs* myaddrs;
1741     if (getifaddrs(&myaddrs) == 0)
1742     {
1743         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1744         {
1745             if (ifa->ifa_addr == NULL) continue;
1746             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1747             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1748             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1749             if (ifa->ifa_addr->sa_family == AF_INET)
1750             {
1751                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1752                 CNetAddr addr(s4->sin_addr);
1753                 if (AddLocal(addr, LOCAL_IF))
1754                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1755             }
1756 #ifdef USE_IPV6
1757             else if (ifa->ifa_addr->sa_family == AF_INET6)
1758             {
1759                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1760                 CNetAddr addr(s6->sin6_addr);
1761                 if (AddLocal(addr, LOCAL_IF))
1762                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1763             }
1764 #endif
1765         }
1766         freeifaddrs(myaddrs);
1767     }
1768 #endif
1769
1770     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1771     if (!IsLimited(NET_IPV4))
1772         NewThread(ThreadGetMyExternalIP, NULL);
1773 }
1774
1775 void StartNode(void* parg)
1776 {
1777     // Make this thread recognisable as the startup thread
1778     RenameThread("novacoin-start");
1779
1780     if (semOutbound == NULL) {
1781         // initialize semaphore
1782         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1783         semOutbound = new CSemaphore(nMaxOutbound);
1784     }
1785
1786     if (pnodeLocalHost == NULL)
1787         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1788
1789     Discover();
1790
1791     //
1792     // Start threads
1793     //
1794
1795     if (!GetBoolArg("-dnsseed", true))
1796         printf("DNS seeding disabled\n");
1797     else
1798         if (!NewThread(ThreadDNSAddressSeed, NULL))
1799             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1800
1801     // Get addresses from IRC and advertise ours
1802     if (!GetBoolArg("-irc", true))
1803         printf("IRC seeding disabled\n");
1804     else
1805         if (!NewThread(ThreadIRCSeed, NULL))
1806             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1807
1808     // Send and receive from sockets, accept connections
1809     if (!NewThread(ThreadSocketHandler, NULL))
1810         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1811
1812     // Initiate outbound connections from -addnode
1813     if (!NewThread(ThreadOpenAddedConnections, NULL))
1814         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1815
1816     // Initiate outbound connections
1817     if (!NewThread(ThreadOpenConnections, NULL))
1818         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1819
1820     // Process messages
1821     if (!NewThread(ThreadMessageHandler, NULL))
1822         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1823
1824     // Dump network addresses
1825     if (!NewThread(ThreadDumpAddress, NULL))
1826         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1827
1828     // Mine proof-of-stake blocks in the background
1829     if (!NewThread(ThreadStakeMiner, pwalletMain))
1830         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1831
1832     // Trusted NTP server, it's localhost by default.
1833     strTrustedUpstream = GetArg("-ntp", "localhost");
1834
1835     // Start periodical NTP sampling thread
1836     NewThread(ThreadNtpSamples, NULL);
1837
1838 }
1839
1840 bool StopNode()
1841 {
1842     printf("StopNode()\n");
1843     fShutdown = true;
1844     nTransactionsUpdated++;
1845     int64_t nStart = GetTime();
1846     {
1847         LOCK(cs_main);
1848         ThreadScriptCheckQuit();
1849     }
1850     if (semOutbound)
1851         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1852             semOutbound->post();
1853     for ( ; ; )
1854     {
1855         int nThreadsRunning = 0;
1856         for (int n = 0; n < THREAD_MAX; n++)
1857             nThreadsRunning += vnThreadsRunning[n];
1858         if (nThreadsRunning == 0)
1859             break;
1860         if (GetTime() - nStart > 20)
1861             break;
1862         Sleep(20);
1863     };
1864     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1865     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1866     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1867     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1868     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1869     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1870     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1871     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1872     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1873     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1874     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1875         Sleep(20);
1876     Sleep(50);
1877     DumpAddresses();
1878
1879     return true;
1880 }
1881
1882 class CNetCleanup
1883 {
1884 public:
1885     CNetCleanup()
1886     {
1887     }
1888     ~CNetCleanup()
1889     {
1890         // Close sockets
1891         for (CNode* pnode : vNodes)
1892             if (pnode->hSocket != INVALID_SOCKET)
1893                 CloseSocket(pnode->hSocket);
1894         for (SOCKET hListenSocket : vhListenSocket)
1895             if (hListenSocket != INVALID_SOCKET)
1896                 if (!CloseSocket(hListenSocket))
1897                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1898
1899         // clean up some globals (to help leak detection)
1900         for (CNode *pnode : vNodes)
1901             delete pnode;
1902         for (CNode *pnode : vNodesDisconnected)
1903             delete pnode;
1904         vNodes.clear();
1905         vNodesDisconnected.clear();
1906         delete semOutbound;
1907         semOutbound = NULL;
1908         delete pnodeLocalHost;
1909         pnodeLocalHost = NULL;
1910
1911 #ifdef WIN32
1912         // Shutdown Windows Sockets
1913         WSACleanup();
1914 #endif
1915     }
1916 }
1917 instance_of_cnetcleanup;
1918
1919 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1920 {
1921     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1922     ss.reserve(10000);
1923     ss << tx;
1924     RelayTransaction(tx, hash, ss);
1925 }
1926
1927 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1928 {
1929     CInv inv(MSG_TX, hash);
1930     {
1931         LOCK(cs_mapRelay);
1932         // Expire old relay messages
1933         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1934         {
1935             mapRelay.erase(vRelayExpiration.front().second);
1936             vRelayExpiration.pop_front();
1937         }
1938
1939         // Save original serialized message so newer versions are preserved
1940         mapRelay.insert(std::make_pair(inv, ss));
1941         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1942     }
1943
1944     RelayInventory(inv);
1945 }
1946
1947 void CNode::RecordBytesRecv(uint64_t bytes)
1948 {
1949     LOCK(cs_totalBytesRecv);
1950     nTotalBytesRecv += bytes;
1951 }
1952
1953 void CNode::RecordBytesSent(uint64_t bytes)
1954 {
1955     LOCK(cs_totalBytesSent);
1956     nTotalBytesSent += bytes;
1957 }
1958
1959 uint64_t CNode::GetTotalBytesRecv()
1960 {
1961     LOCK(cs_totalBytesRecv);
1962     return nTotalBytesRecv;
1963 }
1964
1965 uint64_t CNode::GetTotalBytesSent()
1966 {
1967     LOCK(cs_totalBytesSent);
1968     return nTotalBytesSent;
1969 }
1970 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
1971     return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
1972 }