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 unsigned short GetListenPort()
89 {
90     return (unsigned short)(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 // DNS seeds
973 // Each pair gives a source name and a seed name.
974 // The first name is used as information source for addrman.
975 // The second name should resolve to a list of seed addresses.
976 static const char *strDNSSeed[][2] = {
977     {"novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro"},
978     {"novacoin.ru", "dnsseed.novacoin.ru"},
979     {"novacoin.ru", "testseed.novacoin.ru"},
980     {"novaco.in", "dnsseed.novaco.in"},
981 };
982
983 void ThreadDNSAddressSeed(void* parg)
984 {
985     // Make this thread recognisable as the DNS seeding thread
986     RenameThread("novacoin-dnsseed");
987
988     try
989     {
990         vnThreadsRunning[THREAD_DNSSEED]++;
991         ThreadDNSAddressSeed2(parg);
992         vnThreadsRunning[THREAD_DNSSEED]--;
993     }
994     catch (std::exception& e) {
995         vnThreadsRunning[THREAD_DNSSEED]--;
996         PrintException(&e, "ThreadDNSAddressSeed()");
997     } catch (...) {
998         vnThreadsRunning[THREAD_DNSSEED]--;
999         throw; // support pthread_cancel()
1000     }
1001     printf("ThreadDNSAddressSeed exited\n");
1002 }
1003
1004 void ThreadDNSAddressSeed2(void* parg)
1005 {
1006     printf("ThreadDNSAddressSeed started\n");
1007     int found = 0;
1008
1009     if (!fTestNet)
1010     {
1011         printf("Loading addresses from DNS seeds (could take a while)\n");
1012
1013         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1014             if (HaveNameProxy()) {
1015                 AddOneShot(strDNSSeed[seed_idx][1]);
1016             } else {
1017                 vector<CNetAddr> vaddr;
1018                 vector<CAddress> vAdd;
1019                 if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
1020                 {
1021                     for(CNetAddr& ip :  vaddr)
1022                     {
1023                         auto addr = CAddress(CService(ip, GetDefaultPort()));
1024                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1025                         vAdd.push_back(addr);
1026                         found++;
1027                     }
1028                 }
1029                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1030             }
1031         }
1032     }
1033
1034     printf("%d addresses found from DNS seeds\n", found);
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 uint32_t pnSeed[] =
1049 {
1050     0xa52bf0da, 0x30aa43d8, 0x614488d5, 0x517b6fd5, 0xd4bf62d4, 0xb7d638d4, 0xbc12bcd1, 0xa2501bc6,
1051     0xfde617c6, 0x3337b1c6, 0x1dcd71c3, 0x2c1544c1, 0xe05f6ac1, 0x852f63c0, 0x3e2363c0, 0x15f563c0,
1052     0x430d63c0, 0x50d6a9c0, 0xf0a679c0, 0xefdeedbf, 0x7aaee8bc, 0x3a3dbbbc, 0xef218abc, 0x0bef78bc,
1053     0x8baa3eb2, 0x2bf913b2, 0x24ed9fb2, 0xb42289b2, 0x718a09b0, 0xe9433eb0, 0x559425b0, 0xc97e1fb0,
1054     0x18e1d4b0, 0x8f6cc1b0, 0xac3838ae, 0x86c0ffad, 0x6b0272a7, 0xa463f8a2, 0x6f17f3a2, 0xb3d6f3a2,
1055     0x9cd8f997, 0xd513fb94, 0x39e64880, 0x3859dd6f, 0x0b08fe6d, 0xe601fe6d, 0xeb44a26d, 0xfe53186c,
1056     0x203c2e68, 0x1c542868, 0x0caa8368, 0xb8748368, 0xccca4762, 0xc637555f, 0x638a545f, 0x59b2205f,
1057     0x52568c5f, 0xba568c5f, 0x8a568c5f, 0x31b0f45e, 0x54a0f45e, 0x37d6f15e, 0xc520175e, 0x7620175e,
1058     0xc310175e, 0x8e33b45e, 0x7abb5f5d, 0xd3014c5d, 0xa1e1485d, 0x9947645d, 0xfab8ff5c, 0xa979e65b,
1059     0xa879e65b, 0x9f79e65b, 0x9fa3d25b, 0x112a925b, 0x7b92905b, 0x60647a5b, 0x1e389d5a, 0x851afa59,
1060     0x0185ef59, 0x26549b59, 0x1c9efe57, 0xc54c1256, 0x1ad51955, 0x19d21955, 0x73c41955, 0x3f74ee55,
1061     0x633eea55, 0x6883d655, 0xfb72c655, 0x5360a653, 0x17c1ea52, 0xc661c852, 0x1ecdc852, 0x006a9752,
1062     0xf72d9252, 0x82650551, 0x36f1c851, 0x33f1c851, 0xd5c1864f, 0xb6bf1b4e, 0x96da184e, 0x40d0234d,
1063     0x9a96ab4c, 0x8fc2a84c, 0xb5dbd048, 0xf4644447, 0x2d51af47, 0xa9625445, 0x83f05243, 0x89672941,
1064     0x3a8bad3e, 0xf0a05436, 0x6ab7c936, 0x49971d32, 0xadd4482e, 0xcffd212e, 0x6730bc2e, 0x839aa12e,
1065     0x68d9692e, 0xc7183b25, 0x6c47bb25, 0x2490bb25, 0xad651c1f, 0x048a861f, 0x6937811f, 0x064b2d05,
1066     0x4d226805,
1067 };
1068
1069 void DumpAddresses()
1070 {
1071     auto nStart = GetTimeMillis();
1072
1073     CAddrDB adb;
1074     adb.Write(addrman);
1075
1076     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1077            addrman.size(), GetTimeMillis() - nStart);
1078 }
1079
1080 void ThreadDumpAddress2(void* parg)
1081 {
1082     printf("ThreadDumpAddress started\n");
1083
1084     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1085     while (!fShutdown)
1086     {
1087         DumpAddresses();
1088         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1089         Sleep(600000);
1090         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1091     }
1092     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1093 }
1094
1095 void ThreadDumpAddress(void* parg)
1096 {
1097     // Make this thread recognisable as the address dumping thread
1098     RenameThread("novacoin-adrdump");
1099
1100     try
1101     {
1102         ThreadDumpAddress2(parg);
1103     }
1104     catch (std::exception& e) {
1105         PrintException(&e, "ThreadDumpAddress()");
1106     }
1107     printf("ThreadDumpAddress exited\n");
1108 }
1109
1110 void ThreadOpenConnections(void* parg)
1111 {
1112     // Make this thread recognisable as the connection opening thread
1113     RenameThread("novacoin-opencon");
1114
1115     try
1116     {
1117         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1118         ThreadOpenConnections2(parg);
1119         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1120     }
1121     catch (std::exception& e) {
1122         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1123         PrintException(&e, "ThreadOpenConnections()");
1124     } catch (...) {
1125         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1126         PrintException(NULL, "ThreadOpenConnections()");
1127     }
1128     printf("ThreadOpenConnections exited\n");
1129 }
1130
1131 void static ProcessOneShot()
1132 {
1133     string strDest;
1134     {
1135         LOCK(cs_vOneShots);
1136         if (vOneShots.empty())
1137             return;
1138         strDest = vOneShots.front();
1139         vOneShots.pop_front();
1140     }
1141     CAddress addr;
1142     CSemaphoreGrant grant(*semOutbound, true);
1143     if (grant) {
1144         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1145             AddOneShot(strDest);
1146     }
1147 }
1148
1149 void ThreadOpenConnections2(void* parg)
1150 {
1151     printf("ThreadOpenConnections started\n");
1152
1153     // Connect to specific addresses
1154     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1155     {
1156         for (int64_t nLoop = 0;; nLoop++)
1157         {
1158             ProcessOneShot();
1159             for(string strAddr :  mapMultiArgs["-connect"])
1160             {
1161                 CAddress addr;
1162                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1163                 for (int i = 0; i < 10 && i < nLoop; i++)
1164                 {
1165                     Sleep(500);
1166                     if (fShutdown)
1167                         return;
1168                 }
1169             }
1170             Sleep(500);
1171         }
1172     }
1173
1174     // Initiate network connections
1175     auto nStart = GetTime();
1176     for ( ; ; )
1177     {
1178         ProcessOneShot();
1179
1180         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1181         Sleep(500);
1182         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1183         if (fShutdown)
1184             return;
1185
1186
1187         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1188         CSemaphoreGrant grant(*semOutbound);
1189         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1190         if (fShutdown)
1191             return;
1192
1193         // Add seed nodes if IRC isn't working
1194         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1195         {
1196             std::vector<CAddress> vAdd;
1197             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1198             {
1199                 // It'll only connect to one or two seed nodes because once it connects,
1200                 // it'll get a pile of addresses with newer timestamps.
1201                 // Seed nodes are given a random 'last seen time' of between one and two
1202                 // weeks ago.
1203                 struct in_addr ip;
1204                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1205                 CAddress addr(CService(ip, GetDefaultPort()));
1206                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1207                 vAdd.push_back(addr);
1208             }
1209             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1210         }
1211
1212         // Add Tor nodes if we have connection with onion router
1213         if (mapArgs.count("-tor"))
1214         {
1215             const std::vector<std::string> vstrTorSeed =
1216             {
1217                 "seedp4knqnoei57u.onion",
1218                 "seedr3hhlepyi7fd.onion",
1219                 "seed3uuomkclbiz4.onion",
1220                 "seedeh7qck3ouff5.onion",
1221                 "5rg3vq4jagckeckf.onion",
1222                 "seedt3sraf53ajiy.onion",
1223                 "seedg4qyccsg42oq.onion",
1224                 "novaqrtoywpg7jly.onion",
1225                 "seed3d5wolqbgrcb.onion",
1226                 "seed24u5dwph3qw4.onion",
1227                 "mj26ulzbs2oskgym.onion",
1228                 "eqon4usunavt76m7.onion",
1229                 "seedd3aldwpslzl3.onion"
1230             };
1231             std::vector<CAddress> vAdd;
1232             for (unsigned int i = 0; i < vstrTorSeed.size(); i++)
1233             {
1234                 CAddress addr(CService(vstrTorSeed[i], GetDefaultPort()));
1235                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1236                 vAdd.push_back(addr);
1237             }
1238             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1239         }
1240
1241         //
1242         // Choose an address to connect to based on most recently seen
1243         //
1244         CAddress addrConnect;
1245
1246         // Only connect out to one peer per network group (/16 for IPv4).
1247         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1248         int nOutbound = 0;
1249         set<vector<unsigned char> > setConnected;
1250         {
1251             LOCK(cs_vNodes);
1252             for(CNode* pnode :  vNodes) {
1253                 if (!pnode->fInbound) {
1254                     setConnected.insert(pnode->addr.GetGroup());
1255                     nOutbound++;
1256                 }
1257             }
1258         }
1259
1260         auto nANow = GetAdjustedTime();
1261
1262         int nTries = 0;
1263         for ( ; ; )
1264         {
1265             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1266             auto addr = addrman.Select(10 + min(nOutbound,8)*10);
1267
1268             // if we selected an invalid address, restart
1269             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1270                 break;
1271
1272             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1273             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1274             // already-connected network ranges, ...) before trying new addrman addresses.
1275             nTries++;
1276             if (nTries > 100)
1277                 break;
1278
1279             if (IsLimited(addr))
1280                 continue;
1281
1282             // only consider very recently tried nodes after 30 failed attempts
1283             if (nANow - addr.nLastTry < 600 && nTries < 30)
1284                 continue;
1285
1286             // do not allow non-default ports, unless after 50 invalid addresses selected already
1287             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1288                 continue;
1289
1290             addrConnect = addr;
1291             break;
1292         }
1293
1294         if (addrConnect.IsValid())
1295             OpenNetworkConnection(addrConnect, &grant);
1296     }
1297 }
1298
1299 void ThreadOpenAddedConnections(void* parg)
1300 {
1301     // Make this thread recognisable as the connection opening thread
1302     RenameThread("novacoin-opencon");
1303
1304     try
1305     {
1306         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1307         ThreadOpenAddedConnections2(parg);
1308         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1309     }
1310     catch (std::exception& e) {
1311         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1312         PrintException(&e, "ThreadOpenAddedConnections()");
1313     } catch (...) {
1314         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1315         PrintException(NULL, "ThreadOpenAddedConnections()");
1316     }
1317     printf("ThreadOpenAddedConnections exited\n");
1318 }
1319
1320 void ThreadOpenAddedConnections2(void* parg)
1321 {
1322     printf("ThreadOpenAddedConnections started\n");
1323
1324     {
1325         LOCK(cs_vAddedNodes);
1326         vAddedNodes = mapMultiArgs["-addnode"];
1327     }
1328
1329     if (HaveNameProxy()) {
1330         while(!fShutdown) {
1331             list<string> lAddresses(0);
1332             {
1333                 LOCK(cs_vAddedNodes);
1334                 for(string& strAddNode :  vAddedNodes)
1335                     lAddresses.push_back(strAddNode);
1336             }
1337             for(string& strAddNode :  lAddresses) {
1338                 CAddress addr;
1339                 CSemaphoreGrant grant(*semOutbound);
1340                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1341                 Sleep(500);
1342             }
1343             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1344             Sleep(120000); // Retry every 2 minutes
1345             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1346         }
1347         return;
1348     }
1349
1350     for (uint32_t i = 0; true; i++)
1351     {
1352         list<string> lAddresses(0);
1353         {
1354             LOCK(cs_vAddedNodes);
1355             for(string& strAddNode :  vAddedNodes)
1356                 lAddresses.push_back(strAddNode);
1357         }
1358
1359         list<vector<CService> > lservAddressesToAdd(0);
1360         for(string& strAddNode :  lAddresses)
1361         {
1362             vector<CService> vservNode(0);
1363             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1364             {
1365                 lservAddressesToAdd.push_back(vservNode);
1366                 {
1367                     LOCK(cs_setservAddNodeAddresses);
1368                     for(CService& serv :  vservNode)
1369                         setservAddNodeAddresses.insert(serv);
1370                 }
1371             }
1372         }
1373         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1374         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1375         {
1376             LOCK(cs_vNodes);
1377             for(CNode* pnode :  vNodes)
1378                 for (auto it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1379                 {
1380                     for(CService& addrNode :  *(it))
1381                         if (pnode->addr == addrNode)
1382                         {
1383                             it = lservAddressesToAdd.erase(it);
1384                             if(it != lservAddressesToAdd.begin())
1385                                 it--;
1386                             break;
1387                         }
1388                     if (it == lservAddressesToAdd.end())
1389                         break;
1390                 }
1391         }
1392         for(vector<CService>& vserv :  lservAddressesToAdd)
1393         {
1394             if (vserv.size() == 0)
1395                 continue;
1396             CSemaphoreGrant grant(*semOutbound);
1397             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1398             Sleep(500);
1399             if (fShutdown)
1400                 return;
1401         }
1402         if (fShutdown)
1403             return;
1404         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1405         Sleep(120000); // Retry every 2 minutes
1406         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1407         if (fShutdown)
1408             return;
1409     }
1410 }
1411
1412 // if successful, this moves the passed grant to the constructed node
1413 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1414 {
1415     //
1416     // Initiate outbound network connection
1417     //
1418     if (fShutdown)
1419         return false;
1420     if (!strDest)
1421         if (IsLocal(addrConnect) ||
1422             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1423             FindNode(addrConnect.ToStringIPPort().c_str()))
1424             return false;
1425     if (strDest && FindNode(strDest))
1426         return false;
1427
1428     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1429     CNode* pnode = ConnectNode(addrConnect, strDest);
1430     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1431     if (fShutdown)
1432         return false;
1433     if (!pnode)
1434         return false;
1435     if (grantOutbound)
1436         grantOutbound->MoveTo(pnode->grantOutbound);
1437     pnode->fNetworkNode = true;
1438     if (fOneShot)
1439         pnode->fOneShot = true;
1440
1441     return true;
1442 }
1443
1444 // for now, use a very simple selection metric: the node from which we received
1445 // most recently
1446 static int64_t NodeSyncScore(const CNode *pnode) {
1447     return pnode->nLastRecv;
1448 }
1449
1450 void static StartSync(const vector<CNode*> &vNodes) {
1451     CNode *pnodeNewSync = NULL;
1452     int64_t nBestScore = 0;
1453
1454     // Iterate over all nodes
1455     for(CNode* pnode :  vNodes) {
1456         // check preconditions for allowing a sync
1457         if (!pnode->fClient && !pnode->fOneShot &&
1458             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1459             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1460             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1461             // if ok, compare node's score with the best so far
1462             int64_t nScore = NodeSyncScore(pnode);
1463             if (pnodeNewSync == NULL || nScore > nBestScore) {
1464                 pnodeNewSync = pnode;
1465                 nBestScore = nScore;
1466             }
1467         }
1468     }
1469     // if a new sync candidate was found, start sync!
1470     if (pnodeNewSync) {
1471         pnodeNewSync->fStartSync = true;
1472         pnodeSync = pnodeNewSync;
1473     }
1474 }
1475
1476 void ThreadMessageHandler(void* parg)
1477 {
1478     // Make this thread recognisable as the message handling thread
1479     RenameThread("novacoin-msghand");
1480
1481     try
1482     {
1483         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1484         ThreadMessageHandler2(parg);
1485         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1486     }
1487     catch (std::exception& e) {
1488         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1489         PrintException(&e, "ThreadMessageHandler()");
1490     } catch (...) {
1491         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1492         PrintException(NULL, "ThreadMessageHandler()");
1493     }
1494     printf("ThreadMessageHandler exited\n");
1495 }
1496
1497 void ThreadMessageHandler2(void* parg)
1498 {
1499     printf("ThreadMessageHandler started\n");
1500     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1501     while (!fShutdown)
1502     {
1503         bool fHaveSyncNode = false;
1504         vector<CNode*> vNodesCopy;
1505         {
1506             LOCK(cs_vNodes);
1507             vNodesCopy = vNodes;
1508             for(CNode* pnode :  vNodesCopy) {
1509                 pnode->AddRef();
1510                 if (pnode == pnodeSync)
1511                     fHaveSyncNode = true;
1512             }
1513         }
1514
1515         if (!fHaveSyncNode)
1516             StartSync(vNodesCopy);
1517
1518         // Poll the connected nodes for messages
1519         for(CNode* pnode :  vNodesCopy)
1520         {
1521             // Receive messages
1522             {
1523                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1524                 if (lockRecv)
1525                     ProcessMessages(pnode);
1526             }
1527             if (fShutdown)
1528                 return;
1529
1530             // Send messages
1531             {
1532                 TRY_LOCK(pnode->cs_vSend, lockSend);
1533                 if (lockSend)
1534                     SendMessages(pnode);
1535             }
1536             if (fShutdown)
1537                 return;
1538         }
1539
1540         {
1541             LOCK(cs_vNodes);
1542             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1543         }
1544
1545         // Wait and allow messages to bunch up.
1546         // Reduce vnThreadsRunning so StopNode has permission to exit while
1547         // we're sleeping, but we must always check fShutdown after doing this.
1548         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1549         Sleep(100);
1550         if (fRequestShutdown)
1551             StartShutdown();
1552         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1553         if (fShutdown)
1554             return;
1555     }
1556 }
1557
1558
1559
1560
1561
1562
1563 bool BindListenPort(const CService &addrBind, string& strError)
1564 {
1565     strError.clear();
1566     int nOne = 1;
1567
1568     // Create socket for listening for incoming connections
1569 #ifdef USE_IPV6
1570     struct sockaddr_storage sockaddr;
1571 #else
1572     struct sockaddr sockaddr;
1573 #endif
1574     socklen_t len = sizeof(sockaddr);
1575     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1576     {
1577         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1578         printf("%s\n", strError.c_str());
1579         return false;
1580     }
1581
1582     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1583     if (hListenSocket == INVALID_SOCKET)
1584     {
1585         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1586         printf("%s\n", strError.c_str());
1587         return false;
1588     }
1589
1590 #ifndef WIN32
1591 #ifdef SO_NOSIGPIPE
1592     // Different way of disabling SIGPIPE on BSD
1593     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1594 #endif
1595     // Allow binding if the port is still in TIME_WAIT state after
1596     // the program was closed and restarted. Not an issue on windows!
1597     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1598 #endif
1599
1600 #ifdef WIN32
1601     // Set to non-blocking, incoming connections will also inherit this
1602     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1603 #else
1604     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1605 #endif
1606     {
1607         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1608         printf("%s\n", strError.c_str());
1609         return false;
1610     }
1611
1612 #ifdef USE_IPV6
1613     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1614     // and enable it by default or not. Try to enable it, if possible.
1615     if (addrBind.IsIPv6()) {
1616 #ifdef IPV6_V6ONLY
1617 #ifdef WIN32
1618         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1619 #else
1620         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1621 #endif
1622 #endif
1623 #ifdef WIN32
1624         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1625         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1626 #endif
1627     }
1628 #endif
1629
1630     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1631     {
1632         int nErr = WSAGetLastError();
1633         if (nErr == WSAEADDRINUSE)
1634             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1635         else
1636             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1637         printf("%s\n", strError.c_str());
1638         CloseSocket(hListenSocket);
1639         return false;
1640     }
1641     printf("Bound to %s\n", addrBind.ToString().c_str());
1642
1643     // Listen for incoming connections
1644     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1645     {
1646         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1647         printf("%s\n", strError.c_str());
1648         CloseSocket(hListenSocket);
1649         return false;
1650     }
1651
1652     vhListenSocket.push_back(hListenSocket);
1653
1654     if (addrBind.IsRoutable() && fDiscover)
1655         AddLocal(addrBind, LOCAL_BIND);
1656
1657     return true;
1658 }
1659
1660 void static Discover()
1661 {
1662     if (!fDiscover)
1663         return;
1664
1665 #ifdef WIN32
1666     // Get local host IP
1667     char pszHostName[1000] = "";
1668     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1669     {
1670         vector<CNetAddr> vaddr;
1671         if (LookupHost(pszHostName, vaddr))
1672         {
1673             for(const auto &addr : vaddr)
1674             {
1675                 AddLocal(addr, LOCAL_IF);
1676             }
1677         }
1678     }
1679 #else
1680     // Get local host ip
1681     struct ifaddrs* myaddrs;
1682     if (getifaddrs(&myaddrs) == 0)
1683     {
1684         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1685         {
1686             if (ifa->ifa_addr == NULL) continue;
1687             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1688             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1689             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1690             if (ifa->ifa_addr->sa_family == AF_INET)
1691             {
1692                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1693                 CNetAddr addr(s4->sin_addr);
1694                 if (AddLocal(addr, LOCAL_IF))
1695                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1696             }
1697 #ifdef USE_IPV6
1698             else if (ifa->ifa_addr->sa_family == AF_INET6)
1699             {
1700                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1701                 CNetAddr addr(s6->sin6_addr);
1702                 if (AddLocal(addr, LOCAL_IF))
1703                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1704             }
1705 #endif
1706         }
1707         freeifaddrs(myaddrs);
1708     }
1709 #endif
1710
1711     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1712     if (!IsLimited(NET_IPV4))
1713         NewThread(ThreadGetMyExternalIP, NULL);
1714 }
1715
1716 void StartNode(void* parg)
1717 {
1718     // Make this thread recognisable as the startup thread
1719     RenameThread("novacoin-start");
1720
1721     if (semOutbound == NULL) {
1722         // initialize semaphore
1723         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1724         semOutbound = new CSemaphore(nMaxOutbound);
1725     }
1726
1727     if (pnodeLocalHost == NULL)
1728         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1729
1730     Discover();
1731
1732     //
1733     // Start threads
1734     //
1735
1736     if (!GetBoolArg("-dnsseed", true))
1737         printf("DNS seeding disabled\n");
1738     else
1739         if (!NewThread(ThreadDNSAddressSeed, NULL))
1740             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1741
1742     // Get addresses from IRC and advertise ours
1743     if (!GetBoolArg("-irc", true))
1744         printf("IRC seeding disabled\n");
1745     else
1746         if (!NewThread(ThreadIRCSeed, NULL))
1747             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1748
1749     // Send and receive from sockets, accept connections
1750     if (!NewThread(ThreadSocketHandler, NULL))
1751         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1752
1753     // Initiate outbound connections from -addnode
1754     if (!NewThread(ThreadOpenAddedConnections, NULL))
1755         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1756
1757     // Initiate outbound connections
1758     if (!NewThread(ThreadOpenConnections, NULL))
1759         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1760
1761     // Process messages
1762     if (!NewThread(ThreadMessageHandler, NULL))
1763         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1764
1765     // Dump network addresses
1766     if (!NewThread(ThreadDumpAddress, NULL))
1767         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1768
1769     // Mine proof-of-stake blocks in the background
1770     if (!NewThread(ThreadStakeMiner, pwalletMain))
1771         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1772
1773     // Trusted NTP server, it's localhost by default.
1774     strTrustedUpstream = GetArg("-ntp", "localhost");
1775
1776     // Start periodical NTP sampling thread
1777     NewThread(ThreadNtpSamples, NULL);
1778
1779 }
1780
1781 bool StopNode()
1782 {
1783     printf("StopNode()\n");
1784     fShutdown = true;
1785     nTransactionsUpdated++;
1786     auto nStart = GetTime();
1787     {
1788         LOCK(cs_main);
1789         ThreadScriptCheckQuit();
1790     }
1791     if (semOutbound)
1792         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1793             semOutbound->post();
1794     for ( ; ; )
1795     {
1796         int nThreadsRunning = 0;
1797         for (int n = 0; n < THREAD_MAX; n++)
1798             nThreadsRunning += vnThreadsRunning[n];
1799         if (nThreadsRunning == 0)
1800             break;
1801         if (GetTime() - nStart > 20)
1802             break;
1803         Sleep(20);
1804     };
1805     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1806     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1807     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1808     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1809     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1810     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1811     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1812     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1813     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1814     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1815     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1816         Sleep(20);
1817     Sleep(50);
1818     DumpAddresses();
1819
1820     return true;
1821 }
1822
1823 class CNetCleanup
1824 {
1825 public:
1826     CNetCleanup()
1827     {
1828     }
1829     ~CNetCleanup()
1830     {
1831         // Close sockets
1832         for(CNode* pnode :  vNodes)
1833             if (pnode->hSocket != INVALID_SOCKET)
1834                 CloseSocket(pnode->hSocket);
1835         for(SOCKET hListenSocket :  vhListenSocket)
1836             if (hListenSocket != INVALID_SOCKET)
1837                 if (!CloseSocket(hListenSocket))
1838                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1839
1840         // clean up some globals (to help leak detection)
1841         for(CNode *pnode :  vNodes)
1842             delete pnode;
1843         for(CNode *pnode :  vNodesDisconnected)
1844             delete pnode;
1845         vNodes.clear();
1846         vNodesDisconnected.clear();
1847         delete semOutbound;
1848         semOutbound = NULL;
1849         delete pnodeLocalHost;
1850         pnodeLocalHost = NULL;
1851
1852 #ifdef WIN32
1853         // Shutdown Windows Sockets
1854         WSACleanup();
1855 #endif
1856     }
1857 }
1858 instance_of_cnetcleanup;
1859
1860 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1861 {
1862     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1863     ss.reserve(10000);
1864     ss << tx;
1865     RelayTransaction(tx, hash, ss);
1866 }
1867
1868 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1869 {
1870     CInv inv(MSG_TX, hash);
1871     {
1872         LOCK(cs_mapRelay);
1873         // Expire old relay messages
1874         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1875         {
1876             mapRelay.erase(vRelayExpiration.front().second);
1877             vRelayExpiration.pop_front();
1878         }
1879
1880         // Save original serialized message so newer versions are preserved
1881         mapRelay.insert(std::make_pair(inv, ss));
1882         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1883     }
1884
1885     RelayInventory(inv);
1886 }
1887
1888 void CNode::RecordBytesRecv(uint64_t bytes)
1889 {
1890     LOCK(cs_totalBytesRecv);
1891     nTotalBytesRecv += bytes;
1892 }
1893
1894 void CNode::RecordBytesSent(uint64_t bytes)
1895 {
1896     LOCK(cs_totalBytesSent);
1897     nTotalBytesSent += bytes;
1898 }
1899
1900 uint64_t CNode::GetTotalBytesRecv()
1901 {
1902     LOCK(cs_totalBytesRecv);
1903     return nTotalBytesRecv;
1904 }
1905
1906 uint64_t CNode::GetTotalBytesSent()
1907 {
1908     LOCK(cs_totalBytesSent);
1909     return nTotalBytesSent;
1910 }
1911 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
1912     return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
1913 }