75280b3d3116f6f81ad1446f79aea39575d6fb82
[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 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 (map<CNetAddr, LocalServiceInfo>::iterator 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             CAddress 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         CAddress 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     uint64_t 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     int64_t 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         std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
555         if (i != setBanned.end())
556         {
557             int64_t 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         int64_t 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     {"node.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                         CAddress 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     0x1c542868, 0x3859dd6f, 0x203c2e68, 0xf145a6bc, 0x638a545f, 0x325da346, 0x385da346, 0xfb2b8d5f,
1051     0x52568c5f, 0xa979e65b, 0x8de6485d, 0x9f79e65b, 0x048a861f, 0x3388b55f, 0x6ff0b45e, 0x17e81f5f,
1052     0x6c47bb25, 0x1ecdc852, 0x28263db9, 0x47824e5d, 0x36f1c851, 0x2bf913b2, 0x95923cb3, 0x84e63eb2,
1053     0xefdeedbf, 0x65200092, 0xf36f6805, 0x42692d05, 0x772c1955, 0xb6bf1b4e, 0x7abb5f5d, 0xdb2fa6bc,
1054     0x90e911bf, 0x82de565f, 0x694416b2, 0x0ab600bc, 0xfcecbe6d, 0x24ed9fb2, 0x1bb618c2, 0xc64765bb,
1055     0x4e3d62c3, 0xdba24baa, 0x4b7109b0, 0x12a12cc2, 0xfc01864f, 0x0b69e85b, 0x33922c1f, 0xac611bc6,
1056     0x2a257155, 0x991d5fc0, 0xbfdabcb1, 0x9b73ee55, 0x5bc2b95d, 0xdef0762e, 0x6ab7c936, 0x9c4416b2,
1057     0xd60d864f, 0x03671f1f, 0x3b5da346, 0xc6f5c851, 0x5411b2d4, 0xe7c25702, 0x63474fb0, 0x7e11c854,
1058     0x52381d5f, 0x72fdfe59, 0x51599a05, 0xfb12b2d4, 0xaee4f15e, 0xd0e3f15e, 0x2aa2805f, 0xa1caf15e,
1059     0x34fe425e, 0x46e1f15e, 0xd7c71955, 0xaeeff15e, 0x47c2af55, 0x563d89b2, 0x67980fd9, 0xc9def15e,
1060     0x9cc51eb9, 0xdaa7aa6b, 0x78e6871f, 0x0d5d2cb2, 0x7aedf15e, 0x9bcaf15e, 0xe5f7f15e, 0x501c1759,
1061     0xdfbc4980, 0xa7397f2e, 0x31ea1a02, 0x3a27655e, 0xaa86f05c, 0xdcddf15e, 0x64689cb2, 0xd4bf62d4,
1062     0xf093eab2, 0x98def15e, 0xb6c5f15e, 0x81e8f15e, 0xe5d2fe59, 0xa312786d, 0x4cf9fe59, 0x8a922c1f,
1063     0x00c7fe59, 0x1ade565f, 0x9e4116b2, 0x2c36983e, 0x68f8f15e, 0x51b7eab2, 0x76c51eb9, 0x9edd4980,
1064     0x90ef565f, 0x0dd80857, 0xd513fb94, 0xf5bdeab2, 0xa95277b0, 0x2cf2f15e, 0x1897eab2, 0x924416b2,
1065     0x985c9b59, 0x30aa43d8, 0xf9c6745f, 0xaf862e5f, 0xe0ceeab2, 0xb9b3eab2, 0x6da4eab2, 0xa4fdeab2,
1066     0x0fa6c125, 0xe38bbd05, 0x5d922c1f, 0x9bd0eab2, 0x73025e02, 0xc4fd794d, 0x8435b35f, 0x2d01bc2e,
1067     0xaa2a14d4, 0xa22b07cb, 0xebda6f4f, 0xddc6514e, 0xf23feab2, 0xea1e5256, 0x6147b45e, 0x47d21e4f,
1068     0x67c41c1f, 0x53ec1a02, 0x352e786d, 0x6bec1a02, 0x78fb4abe, 0xd3014c5d, 0x9fbbeab2, 0x1fc51eb9,
1069     0x720eeab2, 0x2db5eab2, 0xe8baf65c, 0x521b459e, 0x65c4955f, 0x0e7b915f, 0xa8f37e6d, 0x6d0b465f,
1070     0xfab8ff5c, 0xf7c27e6d, 0x7345a846, 0x4fd1a7d5, 0xdfc97e6d, 0x26c27e6d, 0xa9de36b2, 0xc615344d,
1071     0x28ceb95d, 0xa52d895e, 0x18c17e6d, 0x13ec1a02, 0x0ba37125, 0x6c3d344d, 0xb3922c1f, 0x506bbeb0,
1072     0x4d04994e, 0xa1bbe56d, 0xf62c344d, 0x0847d048, 0x4bdc6451, 0xc95b9a05, 0xbcd3a7d5, 0x29b57125,
1073     0x0c4d2cb2, 0xf2b8eab2, 0xc2d5b95d, 0x0185ef59, 0x30adeab2, 0xcaf0e92e, 0x756c344d, 0xfd9e252e,
1074     0xbe5ef3bc, 0x4689344d, 0xb223895e, 0xfcebeaad, 0xb7c0e92e, 0x993c1760, 0xe1e171b0, 0xb857e75b,
1075     0xbf10002e, 0xb55b2cb2, 0xa90e2cb2, 0x13d6f15e, 0xf8be9225, 0x14ddf15e, 0x06e90305, 0x82472cb2,
1076 };
1077
1078 const char* pchTorSeed[] = 
1079 {
1080     "seedp4knqnoei57u.onion",
1081     "seedr3hhlepyi7fd.onion",
1082     "seed3uuomkclbiz4.onion",
1083     "seedeh7qck3ouff5.onion",
1084     "5rg3vq4jagckeckf.onion",
1085     "seedt3sraf53ajiy.onion",
1086     "seedg4qyccsg42oq.onion",
1087     "novaqrtoywpg7jly.onion",
1088     "seed3d5wolqbgrcb.onion",
1089     "seed24u5dwph3qw4.onion",
1090     "mj26ulzbs2oskgym.onion",
1091     "eqon4usunavt76m7.onion",
1092     "seedd3aldwpslzl3.onion"
1093 };
1094
1095 void DumpAddresses()
1096 {
1097     int64_t nStart = GetTimeMillis();
1098
1099     CAddrDB adb;
1100     adb.Write(addrman);
1101
1102     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1103            addrman.size(), GetTimeMillis() - nStart);
1104 }
1105
1106 void ThreadDumpAddress2(void* parg)
1107 {
1108     printf("ThreadDumpAddress started\n");
1109
1110     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1111     while (!fShutdown)
1112     {
1113         DumpAddresses();
1114         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1115         Sleep(600000);
1116         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1117     }
1118     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1119 }
1120
1121 void ThreadDumpAddress(void* parg)
1122 {
1123     // Make this thread recognisable as the address dumping thread
1124     RenameThread("novacoin-adrdump");
1125
1126     try
1127     {
1128         ThreadDumpAddress2(parg);
1129     }
1130     catch (std::exception& e) {
1131         PrintException(&e, "ThreadDumpAddress()");
1132     }
1133     printf("ThreadDumpAddress exited\n");
1134 }
1135
1136 void ThreadOpenConnections(void* parg)
1137 {
1138     // Make this thread recognisable as the connection opening thread
1139     RenameThread("novacoin-opencon");
1140
1141     try
1142     {
1143         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1144         ThreadOpenConnections2(parg);
1145         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1146     }
1147     catch (std::exception& e) {
1148         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1149         PrintException(&e, "ThreadOpenConnections()");
1150     } catch (...) {
1151         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1152         PrintException(NULL, "ThreadOpenConnections()");
1153     }
1154     printf("ThreadOpenConnections exited\n");
1155 }
1156
1157 void static ProcessOneShot()
1158 {
1159     string strDest;
1160     {
1161         LOCK(cs_vOneShots);
1162         if (vOneShots.empty())
1163             return;
1164         strDest = vOneShots.front();
1165         vOneShots.pop_front();
1166     }
1167     CAddress addr;
1168     CSemaphoreGrant grant(*semOutbound, true);
1169     if (grant) {
1170         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1171             AddOneShot(strDest);
1172     }
1173 }
1174
1175 void ThreadOpenConnections2(void* parg)
1176 {
1177     printf("ThreadOpenConnections started\n");
1178
1179     // Connect to specific addresses
1180     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1181     {
1182         for (int64_t nLoop = 0;; nLoop++)
1183         {
1184             ProcessOneShot();
1185             for (string strAddr : mapMultiArgs["-connect"])
1186             {
1187                 CAddress addr;
1188                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1189                 for (int i = 0; i < 10 && i < nLoop; i++)
1190                 {
1191                     Sleep(500);
1192                     if (fShutdown)
1193                         return;
1194                 }
1195             }
1196             Sleep(500);
1197         }
1198     }
1199
1200     // Initiate network connections
1201     int64_t nStart = GetTime();
1202     for ( ; ; )
1203     {
1204         ProcessOneShot();
1205
1206         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1207         Sleep(500);
1208         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1209         if (fShutdown)
1210             return;
1211
1212
1213         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1214         CSemaphoreGrant grant(*semOutbound);
1215         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1216         if (fShutdown)
1217             return;
1218
1219         // Add seed nodes if IRC isn't working
1220         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1221         {
1222             std::vector<CAddress> vAdd;
1223             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1224             {
1225                 // It'll only connect to one or two seed nodes because once it connects,
1226                 // it'll get a pile of addresses with newer timestamps.
1227                 // Seed nodes are given a random 'last seen time' of between one and two
1228                 // weeks ago.
1229                 struct in_addr ip;
1230                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1231                 CAddress addr(CService(ip, GetDefaultPort()));
1232                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1233                 vAdd.push_back(addr);
1234             }
1235             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1236         }
1237
1238         // Add Tor nodes if we have connection with onion router
1239         if (mapArgs.count("-tor"))
1240         {
1241             std::vector<CAddress> vAdd;
1242             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1243             {
1244                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1245                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1246                 vAdd.push_back(addr);
1247             }
1248             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1249         }
1250
1251         //
1252         // Choose an address to connect to based on most recently seen
1253         //
1254         CAddress addrConnect;
1255
1256         // Only connect out to one peer per network group (/16 for IPv4).
1257         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1258         int nOutbound = 0;
1259         set<vector<unsigned char> > setConnected;
1260         {
1261             LOCK(cs_vNodes);
1262             for (CNode* pnode : vNodes) {
1263                 if (!pnode->fInbound) {
1264                     setConnected.insert(pnode->addr.GetGroup());
1265                     nOutbound++;
1266                 }
1267             }
1268         }
1269
1270         int64_t nANow = GetAdjustedTime();
1271
1272         int nTries = 0;
1273         for ( ; ; )
1274         {
1275             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1276             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1277
1278             // if we selected an invalid address, restart
1279             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1280                 break;
1281
1282             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1283             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1284             // already-connected network ranges, ...) before trying new addrman addresses.
1285             nTries++;
1286             if (nTries > 100)
1287                 break;
1288
1289             if (IsLimited(addr))
1290                 continue;
1291
1292             // only consider very recently tried nodes after 30 failed attempts
1293             if (nANow - addr.nLastTry < 600 && nTries < 30)
1294                 continue;
1295
1296             // do not allow non-default ports, unless after 50 invalid addresses selected already
1297             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1298                 continue;
1299
1300             addrConnect = addr;
1301             break;
1302         }
1303
1304         if (addrConnect.IsValid())
1305             OpenNetworkConnection(addrConnect, &grant);
1306     }
1307 }
1308
1309 void ThreadOpenAddedConnections(void* parg)
1310 {
1311     // Make this thread recognisable as the connection opening thread
1312     RenameThread("novacoin-opencon");
1313
1314     try
1315     {
1316         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1317         ThreadOpenAddedConnections2(parg);
1318         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1319     }
1320     catch (std::exception& e) {
1321         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1322         PrintException(&e, "ThreadOpenAddedConnections()");
1323     } catch (...) {
1324         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1325         PrintException(NULL, "ThreadOpenAddedConnections()");
1326     }
1327     printf("ThreadOpenAddedConnections exited\n");
1328 }
1329
1330 void ThreadOpenAddedConnections2(void* parg)
1331 {
1332     printf("ThreadOpenAddedConnections started\n");
1333
1334     {
1335         LOCK(cs_vAddedNodes);
1336         vAddedNodes = mapMultiArgs["-addnode"];
1337     }
1338
1339     if (HaveNameProxy()) {
1340         while(!fShutdown) {
1341             list<string> lAddresses(0);
1342             {
1343                 LOCK(cs_vAddedNodes);
1344                 for (string& strAddNode : vAddedNodes)
1345                     lAddresses.push_back(strAddNode);
1346             }
1347             for (string& strAddNode : lAddresses) {
1348                 CAddress addr;
1349                 CSemaphoreGrant grant(*semOutbound);
1350                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1351                 Sleep(500);
1352             }
1353             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1354             Sleep(120000); // Retry every 2 minutes
1355             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1356         }
1357         return;
1358     }
1359
1360     for (uint32_t i = 0; true; i++)
1361     {
1362         list<string> lAddresses(0);
1363         {
1364             LOCK(cs_vAddedNodes);
1365             for (string& strAddNode : vAddedNodes)
1366                 lAddresses.push_back(strAddNode);
1367         }
1368
1369         list<vector<CService> > lservAddressesToAdd(0);
1370         for (string& strAddNode : lAddresses)
1371         {
1372             vector<CService> vservNode(0);
1373             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1374             {
1375                 lservAddressesToAdd.push_back(vservNode);
1376                 {
1377                     LOCK(cs_setservAddNodeAddresses);
1378                     for (CService& serv : vservNode)
1379                         setservAddNodeAddresses.insert(serv);
1380                 }
1381             }
1382         }
1383         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1384         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1385         {
1386             LOCK(cs_vNodes);
1387             for (CNode* pnode : vNodes)
1388                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1389                 {
1390                     for (CService& addrNode : *(it))
1391                         if (pnode->addr == addrNode)
1392                         {
1393                             it = lservAddressesToAdd.erase(it);
1394                             if(it != lservAddressesToAdd.begin())
1395                                 it--;
1396                             break;
1397                         }
1398                     if (it == lservAddressesToAdd.end())
1399                         break;
1400                 }
1401         }
1402         for (vector<CService>& vserv : lservAddressesToAdd)
1403         {
1404             if (vserv.size() == 0)
1405                 continue;
1406             CSemaphoreGrant grant(*semOutbound);
1407             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1408             Sleep(500);
1409             if (fShutdown)
1410                 return;
1411         }
1412         if (fShutdown)
1413             return;
1414         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1415         Sleep(120000); // Retry every 2 minutes
1416         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1417         if (fShutdown)
1418             return;
1419     }
1420 }
1421
1422 // if successful, this moves the passed grant to the constructed node
1423 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1424 {
1425     //
1426     // Initiate outbound network connection
1427     //
1428     if (fShutdown)
1429         return false;
1430     if (!strDest)
1431         if (IsLocal(addrConnect) ||
1432             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1433             FindNode(addrConnect.ToStringIPPort().c_str()))
1434             return false;
1435     if (strDest && FindNode(strDest))
1436         return false;
1437
1438     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1439     CNode* pnode = ConnectNode(addrConnect, strDest);
1440     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1441     if (fShutdown)
1442         return false;
1443     if (!pnode)
1444         return false;
1445     if (grantOutbound)
1446         grantOutbound->MoveTo(pnode->grantOutbound);
1447     pnode->fNetworkNode = true;
1448     if (fOneShot)
1449         pnode->fOneShot = true;
1450
1451     return true;
1452 }
1453
1454 // for now, use a very simple selection metric: the node from which we received
1455 // most recently
1456 static int64_t NodeSyncScore(const CNode *pnode) {
1457     return pnode->nLastRecv;
1458 }
1459
1460 void static StartSync(const vector<CNode*> &vNodes) {
1461     CNode *pnodeNewSync = NULL;
1462     int64_t nBestScore = 0;
1463
1464     // Iterate over all nodes
1465     for (CNode* pnode : vNodes) {
1466         // check preconditions for allowing a sync
1467         if (!pnode->fClient && !pnode->fOneShot &&
1468             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1469             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1470             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1471             // if ok, compare node's score with the best so far
1472             int64_t nScore = NodeSyncScore(pnode);
1473             if (pnodeNewSync == NULL || nScore > nBestScore) {
1474                 pnodeNewSync = pnode;
1475                 nBestScore = nScore;
1476             }
1477         }
1478     }
1479     // if a new sync candidate was found, start sync!
1480     if (pnodeNewSync) {
1481         pnodeNewSync->fStartSync = true;
1482         pnodeSync = pnodeNewSync;
1483     }
1484 }
1485
1486 void ThreadMessageHandler(void* parg)
1487 {
1488     // Make this thread recognisable as the message handling thread
1489     RenameThread("novacoin-msghand");
1490
1491     try
1492     {
1493         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1494         ThreadMessageHandler2(parg);
1495         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1496     }
1497     catch (std::exception& e) {
1498         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1499         PrintException(&e, "ThreadMessageHandler()");
1500     } catch (...) {
1501         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1502         PrintException(NULL, "ThreadMessageHandler()");
1503     }
1504     printf("ThreadMessageHandler exited\n");
1505 }
1506
1507 void ThreadMessageHandler2(void* parg)
1508 {
1509     printf("ThreadMessageHandler started\n");
1510     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1511     while (!fShutdown)
1512     {
1513         bool fHaveSyncNode = false;
1514         vector<CNode*> vNodesCopy;
1515         {
1516             LOCK(cs_vNodes);
1517             vNodesCopy = vNodes;
1518             for (CNode* pnode : vNodesCopy) {
1519                 pnode->AddRef();
1520                 if (pnode == pnodeSync)
1521                     fHaveSyncNode = true;
1522             }
1523         }
1524
1525         if (!fHaveSyncNode)
1526             StartSync(vNodesCopy);
1527
1528         // Poll the connected nodes for messages
1529         for (CNode* pnode : vNodesCopy)
1530         {
1531             // Receive messages
1532             {
1533                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1534                 if (lockRecv) {
1535                     if (!ProcessMessages(pnode)) {
1536                         pnode->CloseSocketDisconnect();
1537                         if (pnode == pnodeSync)
1538                             fHaveSyncNode = false;
1539                     }
1540                 }
1541             }
1542             if (fShutdown)
1543                 return;
1544
1545             // Send messages
1546             {
1547                 TRY_LOCK(pnode->cs_vSend, lockSend);
1548                 if (lockSend)
1549                     SendMessages(pnode);
1550             }
1551             if (fShutdown)
1552                 return;
1553         }
1554
1555         {
1556             LOCK(cs_vNodes);
1557             for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
1558         }
1559
1560         // Wait and allow messages to bunch up.
1561         // Reduce vnThreadsRunning so StopNode has permission to exit while
1562         // we're sleeping, but we must always check fShutdown after doing this.
1563         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1564         Sleep(100);
1565         if (fRequestShutdown)
1566             StartShutdown();
1567         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1568         if (fShutdown)
1569             return;
1570     }
1571 }
1572
1573
1574
1575
1576
1577
1578 bool BindListenPort(const CService &addrBind, string& strError)
1579 {
1580     strError.clear();
1581     int nOne = 1;
1582
1583     // Create socket for listening for incoming connections
1584 #ifdef USE_IPV6
1585     struct sockaddr_storage sockaddr;
1586 #else
1587     struct sockaddr sockaddr;
1588 #endif
1589     socklen_t len = sizeof(sockaddr);
1590     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1591     {
1592         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1593         printf("%s\n", strError.c_str());
1594         return false;
1595     }
1596
1597     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1598     if (hListenSocket == INVALID_SOCKET)
1599     {
1600         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1601         printf("%s\n", strError.c_str());
1602         return false;
1603     }
1604
1605 #ifndef WIN32
1606 #ifdef SO_NOSIGPIPE
1607     // Different way of disabling SIGPIPE on BSD
1608     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1609 #endif
1610     // Allow binding if the port is still in TIME_WAIT state after
1611     // the program was closed and restarted. Not an issue on windows!
1612     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1613 #endif
1614
1615 #ifdef WIN32
1616     // Set to non-blocking, incoming connections will also inherit this
1617     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1618 #else
1619     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1620 #endif
1621     {
1622         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1623         printf("%s\n", strError.c_str());
1624         return false;
1625     }
1626
1627 #ifdef USE_IPV6
1628     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1629     // and enable it by default or not. Try to enable it, if possible.
1630     if (addrBind.IsIPv6()) {
1631 #ifdef IPV6_V6ONLY
1632 #ifdef WIN32
1633         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1634 #else
1635         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1636 #endif
1637 #endif
1638 #ifdef WIN32
1639         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1640         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1641 #endif
1642     }
1643 #endif
1644
1645     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1646     {
1647         int nErr = WSAGetLastError();
1648         if (nErr == WSAEADDRINUSE)
1649             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1650         else
1651             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1652         printf("%s\n", strError.c_str());
1653         CloseSocket(hListenSocket);
1654         return false;
1655     }
1656     printf("Bound to %s\n", addrBind.ToString().c_str());
1657
1658     // Listen for incoming connections
1659     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1660     {
1661         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1662         printf("%s\n", strError.c_str());
1663         CloseSocket(hListenSocket);
1664         return false;
1665     }
1666
1667     vhListenSocket.push_back(hListenSocket);
1668
1669     if (addrBind.IsRoutable() && fDiscover)
1670         AddLocal(addrBind, LOCAL_BIND);
1671
1672     return true;
1673 }
1674
1675 void static Discover()
1676 {
1677     if (!fDiscover)
1678         return;
1679
1680 #ifdef WIN32
1681     // Get local host IP
1682     char pszHostName[1000] = "";
1683     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1684     {
1685         vector<CNetAddr> vaddr;
1686         if (LookupHost(pszHostName, vaddr))
1687         {
1688             for (const CNetAddr &addr : vaddr)
1689             {
1690                 AddLocal(addr, LOCAL_IF);
1691             }
1692         }
1693     }
1694 #else
1695     // Get local host ip
1696     struct ifaddrs* myaddrs;
1697     if (getifaddrs(&myaddrs) == 0)
1698     {
1699         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1700         {
1701             if (ifa->ifa_addr == NULL) continue;
1702             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1703             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1704             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1705             if (ifa->ifa_addr->sa_family == AF_INET)
1706             {
1707                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1708                 CNetAddr addr(s4->sin_addr);
1709                 if (AddLocal(addr, LOCAL_IF))
1710                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1711             }
1712 #ifdef USE_IPV6
1713             else if (ifa->ifa_addr->sa_family == AF_INET6)
1714             {
1715                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1716                 CNetAddr addr(s6->sin6_addr);
1717                 if (AddLocal(addr, LOCAL_IF))
1718                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1719             }
1720 #endif
1721         }
1722         freeifaddrs(myaddrs);
1723     }
1724 #endif
1725
1726     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1727     if (!IsLimited(NET_IPV4))
1728         NewThread(ThreadGetMyExternalIP, NULL);
1729 }
1730
1731 void StartNode(void* parg)
1732 {
1733     // Make this thread recognisable as the startup thread
1734     RenameThread("novacoin-start");
1735
1736     if (semOutbound == NULL) {
1737         // initialize semaphore
1738         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1739         semOutbound = new CSemaphore(nMaxOutbound);
1740     }
1741
1742     if (pnodeLocalHost == NULL)
1743         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1744
1745     Discover();
1746
1747     //
1748     // Start threads
1749     //
1750
1751     if (!GetBoolArg("-dnsseed", true))
1752         printf("DNS seeding disabled\n");
1753     else
1754         if (!NewThread(ThreadDNSAddressSeed, NULL))
1755             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1756
1757     // Get addresses from IRC and advertise ours
1758     if (!GetBoolArg("-irc", true))
1759         printf("IRC seeding disabled\n");
1760     else
1761         if (!NewThread(ThreadIRCSeed, NULL))
1762             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1763
1764     // Send and receive from sockets, accept connections
1765     if (!NewThread(ThreadSocketHandler, NULL))
1766         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1767
1768     // Initiate outbound connections from -addnode
1769     if (!NewThread(ThreadOpenAddedConnections, NULL))
1770         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1771
1772     // Initiate outbound connections
1773     if (!NewThread(ThreadOpenConnections, NULL))
1774         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1775
1776     // Process messages
1777     if (!NewThread(ThreadMessageHandler, NULL))
1778         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1779
1780     // Dump network addresses
1781     if (!NewThread(ThreadDumpAddress, NULL))
1782         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1783
1784     // Mine proof-of-stake blocks in the background
1785     if (!NewThread(ThreadStakeMiner, pwalletMain))
1786         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1787
1788     // Trusted NTP server, it's localhost by default.
1789     strTrustedUpstream = GetArg("-ntp", "localhost");
1790
1791     // Start periodical NTP sampling thread
1792     NewThread(ThreadNtpSamples, NULL);
1793
1794 }
1795
1796 bool StopNode()
1797 {
1798     printf("StopNode()\n");
1799     fShutdown = true;
1800     nTransactionsUpdated++;
1801     int64_t nStart = GetTime();
1802     {
1803         LOCK(cs_main);
1804         ThreadScriptCheckQuit();
1805     }
1806     if (semOutbound)
1807         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1808             semOutbound->post();
1809     for ( ; ; )
1810     {
1811         int nThreadsRunning = 0;
1812         for (int n = 0; n < THREAD_MAX; n++)
1813             nThreadsRunning += vnThreadsRunning[n];
1814         if (nThreadsRunning == 0)
1815             break;
1816         if (GetTime() - nStart > 20)
1817             break;
1818         Sleep(20);
1819     };
1820     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1821     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1822     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1823     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1824     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1825     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1826     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1827     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1828     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1829     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1830     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1831         Sleep(20);
1832     Sleep(50);
1833     DumpAddresses();
1834
1835     return true;
1836 }
1837
1838 class CNetCleanup
1839 {
1840 public:
1841     CNetCleanup()
1842     {
1843     }
1844     ~CNetCleanup()
1845     {
1846         // Close sockets
1847         for (CNode* pnode : vNodes)
1848             if (pnode->hSocket != INVALID_SOCKET)
1849                 CloseSocket(pnode->hSocket);
1850         for (SOCKET hListenSocket : vhListenSocket)
1851             if (hListenSocket != INVALID_SOCKET)
1852                 if (!CloseSocket(hListenSocket))
1853                     printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1854
1855         // clean up some globals (to help leak detection)
1856         for (CNode *pnode : vNodes)
1857             delete pnode;
1858         for (CNode *pnode : vNodesDisconnected)
1859             delete pnode;
1860         vNodes.clear();
1861         vNodesDisconnected.clear();
1862         delete semOutbound;
1863         semOutbound = NULL;
1864         delete pnodeLocalHost;
1865         pnodeLocalHost = NULL;
1866
1867 #ifdef WIN32
1868         // Shutdown Windows Sockets
1869         WSACleanup();
1870 #endif
1871     }
1872 }
1873 instance_of_cnetcleanup;
1874
1875 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1876 {
1877     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1878     ss.reserve(10000);
1879     ss << tx;
1880     RelayTransaction(tx, hash, ss);
1881 }
1882
1883 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1884 {
1885     CInv inv(MSG_TX, hash);
1886     {
1887         LOCK(cs_mapRelay);
1888         // Expire old relay messages
1889         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1890         {
1891             mapRelay.erase(vRelayExpiration.front().second);
1892             vRelayExpiration.pop_front();
1893         }
1894
1895         // Save original serialized message so newer versions are preserved
1896         mapRelay.insert(std::make_pair(inv, ss));
1897         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1898     }
1899
1900     RelayInventory(inv);
1901 }
1902
1903 void CNode::RecordBytesRecv(uint64_t bytes)
1904 {
1905     LOCK(cs_totalBytesRecv);
1906     nTotalBytesRecv += bytes;
1907 }
1908
1909 void CNode::RecordBytesSent(uint64_t bytes)
1910 {
1911     LOCK(cs_totalBytesSent);
1912     nTotalBytesSent += bytes;
1913 }
1914
1915 uint64_t CNode::GetTotalBytesRecv()
1916 {
1917     LOCK(cs_totalBytesRecv);
1918     return nTotalBytesRecv;
1919 }
1920
1921 uint64_t CNode::GetTotalBytesSent()
1922 {
1923     LOCK(cs_totalBytesSent);
1924     return nTotalBytesSent;
1925 }
1926 int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
1927     return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
1928 }