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