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