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