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