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