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