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