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