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