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