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