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