We have constants (commit e1fc548)
[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 >= GetArgInt("-banscore", 100))
549     {
550         int64_t banTime = GetTime()+GetArg("-bantime", nOneDay);  // 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     size_t 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 >= GetArgInt("-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                         CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1158                         addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1159                         vAdd.push_back(addr);
1160                         found++;
1161                     }
1162                 }
1163                 addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1164             }
1165         }
1166     }
1167
1168     printf("%d addresses found from DNS seeds\n", found);
1169 }
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 uint32_t pnSeed[] =
1183 {
1184     0xa52bf0da, 0x30aa43d8, 0x614488d5, 0x517b6fd5, 0xd4bf62d4, 0xb7d638d4, 0xbc12bcd1, 0xa2501bc6,
1185     0xfde617c6, 0x3337b1c6, 0x1dcd71c3, 0x2c1544c1, 0xe05f6ac1, 0x852f63c0, 0x3e2363c0, 0x15f563c0,
1186     0x430d63c0, 0x50d6a9c0, 0xf0a679c0, 0xefdeedbf, 0x7aaee8bc, 0x3a3dbbbc, 0xef218abc, 0x0bef78bc,
1187     0x8baa3eb2, 0x2bf913b2, 0x24ed9fb2, 0xb42289b2, 0x718a09b0, 0xe9433eb0, 0x559425b0, 0xc97e1fb0,
1188     0x18e1d4b0, 0x8f6cc1b0, 0xac3838ae, 0x86c0ffad, 0x6b0272a7, 0xa463f8a2, 0x6f17f3a2, 0xb3d6f3a2,
1189     0x9cd8f997, 0xd513fb94, 0x39e64880, 0x3859dd6f, 0x0b08fe6d, 0xe601fe6d, 0xeb44a26d, 0xfe53186c,
1190     0x203c2e68, 0x1c542868, 0x0caa8368, 0xb8748368, 0xccca4762, 0xc637555f, 0x638a545f, 0x59b2205f,
1191     0x52568c5f, 0xba568c5f, 0x8a568c5f, 0x31b0f45e, 0x54a0f45e, 0x37d6f15e, 0xc520175e, 0x7620175e,
1192     0xc310175e, 0x8e33b45e, 0x7abb5f5d, 0xd3014c5d, 0xa1e1485d, 0x9947645d, 0xfab8ff5c, 0xa979e65b,
1193     0xa879e65b, 0x9f79e65b, 0x9fa3d25b, 0x112a925b, 0x7b92905b, 0x60647a5b, 0x1e389d5a, 0x851afa59,
1194     0x0185ef59, 0x26549b59, 0x1c9efe57, 0xc54c1256, 0x1ad51955, 0x19d21955, 0x73c41955, 0x3f74ee55,
1195     0x633eea55, 0x6883d655, 0xfb72c655, 0x5360a653, 0x17c1ea52, 0xc661c852, 0x1ecdc852, 0x006a9752,
1196     0xf72d9252, 0x82650551, 0x36f1c851, 0x33f1c851, 0xd5c1864f, 0xb6bf1b4e, 0x96da184e, 0x40d0234d,
1197     0x9a96ab4c, 0x8fc2a84c, 0xb5dbd048, 0xf4644447, 0x2d51af47, 0xa9625445, 0x83f05243, 0x89672941,
1198     0x3a8bad3e, 0xf0a05436, 0x6ab7c936, 0x49971d32, 0xadd4482e, 0xcffd212e, 0x6730bc2e, 0x839aa12e,
1199     0x68d9692e, 0xc7183b25, 0x6c47bb25, 0x2490bb25, 0xad651c1f, 0x048a861f, 0x6937811f, 0x064b2d05,
1200     0x4d226805,
1201 };
1202
1203 const char* pchTorSeed[] = 
1204 {
1205     "seedp4knqnoei57u.onion",
1206     "seedr3hhlepyi7fd.onion",
1207     "seed3uuomkclbiz4.onion",
1208     "seedeh7qck3ouff5.onion",
1209     "5rg3vq4jagckeckf.onion",
1210     "seedt3sraf53ajiy.onion",
1211     "seedg4qyccsg42oq.onion",
1212     "novaqrtoywpg7jly.onion",
1213     "seed3d5wolqbgrcb.onion",
1214     "seed24u5dwph3qw4.onion",
1215     "mj26ulzbs2oskgym.onion",
1216     "eqon4usunavt76m7.onion",
1217     "seedd3aldwpslzl3.onion"
1218 };
1219
1220 void DumpAddresses()
1221 {
1222     int64_t nStart = GetTimeMillis();
1223
1224     CAddrDB adb;
1225     adb.Write(addrman);
1226
1227     printf("Flushed %d addresses to peers.dat  %" PRId64 "ms\n",
1228            addrman.size(), GetTimeMillis() - nStart);
1229 }
1230
1231 void ThreadDumpAddress2(void* parg)
1232 {
1233     printf("ThreadDumpAddress started\n");
1234
1235     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1236     while (!fShutdown)
1237     {
1238         DumpAddresses();
1239         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1240         Sleep(600000);
1241         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1242     }
1243     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1244 }
1245
1246 void ThreadDumpAddress(void* parg)
1247 {
1248     // Make this thread recognisable as the address dumping thread
1249     RenameThread("novacoin-adrdump");
1250
1251     try
1252     {
1253         ThreadDumpAddress2(parg);
1254     }
1255     catch (std::exception& e) {
1256         PrintException(&e, "ThreadDumpAddress()");
1257     }
1258     printf("ThreadDumpAddress exited\n");
1259 }
1260
1261 void ThreadOpenConnections(void* parg)
1262 {
1263     // Make this thread recognisable as the connection opening thread
1264     RenameThread("novacoin-opencon");
1265
1266     try
1267     {
1268         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1269         ThreadOpenConnections2(parg);
1270         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1271     }
1272     catch (std::exception& e) {
1273         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1274         PrintException(&e, "ThreadOpenConnections()");
1275     } catch (...) {
1276         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1277         PrintException(NULL, "ThreadOpenConnections()");
1278     }
1279     printf("ThreadOpenConnections exited\n");
1280 }
1281
1282 void static ProcessOneShot()
1283 {
1284     string strDest;
1285     {
1286         LOCK(cs_vOneShots);
1287         if (vOneShots.empty())
1288             return;
1289         strDest = vOneShots.front();
1290         vOneShots.pop_front();
1291     }
1292     CAddress addr;
1293     CSemaphoreGrant grant(*semOutbound, true);
1294     if (grant) {
1295         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1296             AddOneShot(strDest);
1297     }
1298 }
1299
1300 void ThreadOpenConnections2(void* parg)
1301 {
1302     printf("ThreadOpenConnections started\n");
1303
1304     // Connect to specific addresses
1305     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1306     {
1307         for (int64_t nLoop = 0;; nLoop++)
1308         {
1309             ProcessOneShot();
1310             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1311             {
1312                 CAddress addr;
1313                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1314                 for (int i = 0; i < 10 && i < nLoop; i++)
1315                 {
1316                     Sleep(500);
1317                     if (fShutdown)
1318                         return;
1319                 }
1320             }
1321             Sleep(500);
1322         }
1323     }
1324
1325     // Initiate network connections
1326     int64_t nStart = GetTime();
1327     while (true)
1328     {
1329         ProcessOneShot();
1330
1331         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1332         Sleep(500);
1333         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1334         if (fShutdown)
1335             return;
1336
1337
1338         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1339         CSemaphoreGrant grant(*semOutbound);
1340         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1341         if (fShutdown)
1342             return;
1343
1344         // Add seed nodes if IRC isn't working
1345         if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
1346         {
1347             std::vector<CAddress> vAdd;
1348             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1349             {
1350                 // It'll only connect to one or two seed nodes because once it connects,
1351                 // it'll get a pile of addresses with newer timestamps.
1352                 // Seed nodes are given a random 'last seen time' of between one and two
1353                 // weeks ago.
1354                 const int64_t nOneWeek = 7*24*60*60;
1355                 struct in_addr ip;
1356                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1357                 CAddress addr(CService(ip, GetDefaultPort()));
1358                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1359                 vAdd.push_back(addr);
1360             }
1361             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1362         }
1363
1364         // Add Tor nodes if we have connection with onion router
1365         if (mapArgs.count("-tor"))
1366         {
1367             std::vector<CAddress> vAdd;
1368             for (unsigned int i = 0; i < ARRAYLEN(pchTorSeed); i++)
1369             {
1370                 const int64_t nOneWeek = 7*24*60*60;
1371                 CAddress addr(CService(pchTorSeed[i], GetDefaultPort()));
1372                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1373                 vAdd.push_back(addr);
1374             }
1375             addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
1376         }
1377
1378         //
1379         // Choose an address to connect to based on most recently seen
1380         //
1381         CAddress addrConnect;
1382
1383         // Only connect out to one peer per network group (/16 for IPv4).
1384         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1385         int nOutbound = 0;
1386         set<vector<unsigned char> > setConnected;
1387         {
1388             LOCK(cs_vNodes);
1389             BOOST_FOREACH(CNode* pnode, vNodes) {
1390                 if (!pnode->fInbound) {
1391                     setConnected.insert(pnode->addr.GetGroup());
1392                     nOutbound++;
1393                 }
1394             }
1395         }
1396
1397         int64_t nANow = GetAdjustedTime();
1398
1399         int nTries = 0;
1400         while (true)
1401         {
1402             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1403             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1404
1405             // if we selected an invalid address, restart
1406             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1407                 break;
1408
1409             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1410             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1411             // already-connected network ranges, ...) before trying new addrman addresses.
1412             nTries++;
1413             if (nTries > 100)
1414                 break;
1415
1416             if (IsLimited(addr))
1417                 continue;
1418
1419             // only consider very recently tried nodes after 30 failed attempts
1420             if (nANow - addr.nLastTry < 600 && nTries < 30)
1421                 continue;
1422
1423             // do not allow non-default ports, unless after 50 invalid addresses selected already
1424             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1425                 continue;
1426
1427             addrConnect = addr;
1428             break;
1429         }
1430
1431         if (addrConnect.IsValid())
1432             OpenNetworkConnection(addrConnect, &grant);
1433     }
1434 }
1435
1436 void ThreadOpenAddedConnections(void* parg)
1437 {
1438     // Make this thread recognisable as the connection opening thread
1439     RenameThread("novacoin-opencon");
1440
1441     try
1442     {
1443         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1444         ThreadOpenAddedConnections2(parg);
1445         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1446     }
1447     catch (std::exception& e) {
1448         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1449         PrintException(&e, "ThreadOpenAddedConnections()");
1450     } catch (...) {
1451         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1452         PrintException(NULL, "ThreadOpenAddedConnections()");
1453     }
1454     printf("ThreadOpenAddedConnections exited\n");
1455 }
1456
1457 void ThreadOpenAddedConnections2(void* parg)
1458 {
1459     printf("ThreadOpenAddedConnections started\n");
1460
1461     {
1462         LOCK(cs_vAddedNodes);
1463         vAddedNodes = mapMultiArgs["-addnode"];
1464     }
1465
1466     if (HaveNameProxy()) {
1467         while(!fShutdown) {
1468             list<string> lAddresses(0);
1469             {
1470                 LOCK(cs_vAddedNodes);
1471                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1472                     lAddresses.push_back(strAddNode);
1473             }
1474             BOOST_FOREACH(string& strAddNode, lAddresses) {
1475                 CAddress addr;
1476                 CSemaphoreGrant grant(*semOutbound);
1477                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1478                 Sleep(500);
1479             }
1480             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1481             Sleep(120000); // Retry every 2 minutes
1482             vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1483         }
1484         return;
1485     }
1486
1487     for (uint32_t i = 0; true; i++)
1488     {
1489         list<string> lAddresses(0);
1490         {
1491             LOCK(cs_vAddedNodes);
1492             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1493                 lAddresses.push_back(strAddNode);
1494         }
1495
1496         list<vector<CService> > lservAddressesToAdd(0);
1497         BOOST_FOREACH(string& strAddNode, lAddresses)
1498         {
1499             vector<CService> vservNode(0);
1500             if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
1501             {
1502                 lservAddressesToAdd.push_back(vservNode);
1503                 {
1504                     LOCK(cs_setservAddNodeAddresses);
1505                     BOOST_FOREACH(CService& serv, vservNode)
1506                         setservAddNodeAddresses.insert(serv);
1507                 }
1508             }
1509         }
1510         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1511         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1512         {
1513             LOCK(cs_vNodes);
1514             BOOST_FOREACH(CNode* pnode, vNodes)
1515                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1516                 {
1517                     BOOST_FOREACH(CService& addrNode, *(it))
1518                         if (pnode->addr == addrNode)
1519                         {
1520                             it = lservAddressesToAdd.erase(it);
1521                             if(it != lservAddressesToAdd.begin())
1522                                 it--;
1523                             break;
1524                         }
1525                     if (it == lservAddressesToAdd.end())
1526                         break;
1527                 }
1528         }
1529         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1530         {
1531             if (vserv.size() == 0)
1532                 continue;
1533             CSemaphoreGrant grant(*semOutbound);
1534             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1535             Sleep(500);
1536             if (fShutdown)
1537                 return;
1538         }
1539         if (fShutdown)
1540             return;
1541         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1542         Sleep(120000); // Retry every 2 minutes
1543         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1544         if (fShutdown)
1545             return;
1546     }
1547 }
1548
1549 // if successful, this moves the passed grant to the constructed node
1550 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1551 {
1552     //
1553     // Initiate outbound network connection
1554     //
1555     if (fShutdown)
1556         return false;
1557     if (!strDest)
1558         if (IsLocal(addrConnect) ||
1559             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1560             FindNode(addrConnect.ToStringIPPort().c_str()))
1561             return false;
1562     if (strDest && FindNode(strDest))
1563         return false;
1564
1565     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1566     CNode* pnode = ConnectNode(addrConnect, strDest);
1567     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1568     if (fShutdown)
1569         return false;
1570     if (!pnode)
1571         return false;
1572     if (grantOutbound)
1573         grantOutbound->MoveTo(pnode->grantOutbound);
1574     pnode->fNetworkNode = true;
1575     if (fOneShot)
1576         pnode->fOneShot = true;
1577
1578     return true;
1579 }
1580
1581 // for now, use a very simple selection metric: the node from which we received
1582 // most recently
1583 static int64_t NodeSyncScore(const CNode *pnode) {
1584     return pnode->nLastRecv;
1585 }
1586
1587 void static StartSync(const vector<CNode*> &vNodes) {
1588     CNode *pnodeNewSync = NULL;
1589     int64_t nBestScore = 0;
1590
1591     // Iterate over all nodes
1592     BOOST_FOREACH(CNode* pnode, vNodes) {
1593         // check preconditions for allowing a sync
1594         if (!pnode->fClient && !pnode->fOneShot &&
1595             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1596             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1597             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1598             // if ok, compare node's score with the best so far
1599             int64_t nScore = NodeSyncScore(pnode);
1600             if (pnodeNewSync == NULL || nScore > nBestScore) {
1601                 pnodeNewSync = pnode;
1602                 nBestScore = nScore;
1603             }
1604         }
1605     }
1606     // if a new sync candidate was found, start sync!
1607     if (pnodeNewSync) {
1608         pnodeNewSync->fStartSync = true;
1609         pnodeSync = pnodeNewSync;
1610     }
1611 }
1612
1613 void ThreadMessageHandler(void* parg)
1614 {
1615     // Make this thread recognisable as the message handling thread
1616     RenameThread("novacoin-msghand");
1617
1618     try
1619     {
1620         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1621         ThreadMessageHandler2(parg);
1622         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1623     }
1624     catch (std::exception& e) {
1625         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1626         PrintException(&e, "ThreadMessageHandler()");
1627     } catch (...) {
1628         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1629         PrintException(NULL, "ThreadMessageHandler()");
1630     }
1631     printf("ThreadMessageHandler exited\n");
1632 }
1633
1634 void ThreadMessageHandler2(void* parg)
1635 {
1636     printf("ThreadMessageHandler started\n");
1637     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1638     while (!fShutdown)
1639     {
1640         bool fHaveSyncNode = false;
1641         vector<CNode*> vNodesCopy;
1642         {
1643             LOCK(cs_vNodes);
1644             vNodesCopy = vNodes;
1645             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1646                 pnode->AddRef();
1647                 if (pnode == pnodeSync)
1648                     fHaveSyncNode = true;
1649             }
1650         }
1651
1652         if (!fHaveSyncNode)
1653             StartSync(vNodesCopy);
1654
1655         // Poll the connected nodes for messages
1656         CNode* pnodeTrickle = NULL;
1657         if (!vNodesCopy.empty())
1658             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1659         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1660         {
1661             // Receive messages
1662             {
1663                 TRY_LOCK(pnode->cs_vRecv, lockRecv);
1664                 if (lockRecv)
1665                     ProcessMessages(pnode);
1666             }
1667             if (fShutdown)
1668                 return;
1669
1670             // Send messages
1671             {
1672                 TRY_LOCK(pnode->cs_vSend, lockSend);
1673                 if (lockSend)
1674                     SendMessages(pnode, pnode == pnodeTrickle);
1675             }
1676             if (fShutdown)
1677                 return;
1678         }
1679
1680         {
1681             LOCK(cs_vNodes);
1682             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1683                 pnode->Release();
1684         }
1685
1686         // Wait and allow messages to bunch up.
1687         // Reduce vnThreadsRunning so StopNode has permission to exit while
1688         // we're sleeping, but we must always check fShutdown after doing this.
1689         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1690         Sleep(100);
1691         if (fRequestShutdown)
1692             StartShutdown();
1693         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1694         if (fShutdown)
1695             return;
1696     }
1697 }
1698
1699
1700
1701
1702
1703
1704 bool BindListenPort(const CService &addrBind, string& strError)
1705 {
1706     strError = "";
1707     int nOne = 1;
1708
1709 #ifdef WIN32
1710     // Initialize Windows Sockets
1711     WSADATA wsadata;
1712     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1713     if (ret != NO_ERROR)
1714     {
1715         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1716         printf("%s\n", strError.c_str());
1717         return false;
1718     }
1719 #endif
1720
1721     // Create socket for listening for incoming connections
1722 #ifdef USE_IPV6
1723     struct sockaddr_storage sockaddr;
1724 #else
1725     struct sockaddr sockaddr;
1726 #endif
1727     socklen_t len = sizeof(sockaddr);
1728     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1729     {
1730         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1731         printf("%s\n", strError.c_str());
1732         return false;
1733     }
1734
1735     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1736     if (hListenSocket == INVALID_SOCKET)
1737     {
1738         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1739         printf("%s\n", strError.c_str());
1740         return false;
1741     }
1742
1743 #ifndef WIN32
1744 #ifdef SO_NOSIGPIPE
1745     // Different way of disabling SIGPIPE on BSD
1746     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1747 #endif
1748     // Allow binding if the port is still in TIME_WAIT state after
1749     // the program was closed and restarted. Not an issue on windows!
1750     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1751 #endif
1752
1753 #ifdef WIN32
1754     // Set to non-blocking, incoming connections will also inherit this
1755     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1756 #else
1757     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1758 #endif
1759     {
1760         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1761         printf("%s\n", strError.c_str());
1762         return false;
1763     }
1764
1765 #ifdef USE_IPV6
1766     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1767     // and enable it by default or not. Try to enable it, if possible.
1768     if (addrBind.IsIPv6()) {
1769 #ifdef IPV6_V6ONLY
1770 #ifdef WIN32
1771         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1772 #else
1773         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1774 #endif
1775 #endif
1776 #ifdef WIN32
1777         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
1778         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
1779 #endif
1780     }
1781 #endif
1782
1783     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1784     {
1785         int nErr = WSAGetLastError();
1786         if (nErr == WSAEADDRINUSE)
1787             strError = strprintf(_("Unable to bind to %s on this computer. NovaCoin is probably already running."), addrBind.ToString().c_str());
1788         else
1789             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1790         printf("%s\n", strError.c_str());
1791         closesocket(hListenSocket);
1792         return false;
1793     }
1794     printf("Bound to %s\n", addrBind.ToString().c_str());
1795
1796     // Listen for incoming connections
1797     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1798     {
1799         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1800         printf("%s\n", strError.c_str());
1801         closesocket(hListenSocket);
1802         return false;
1803     }
1804
1805     vhListenSocket.push_back(hListenSocket);
1806
1807     if (addrBind.IsRoutable() && fDiscover)
1808         AddLocal(addrBind, LOCAL_BIND);
1809
1810     return true;
1811 }
1812
1813 void static Discover()
1814 {
1815     if (!fDiscover)
1816         return;
1817
1818 #ifdef WIN32
1819     // Get local host IP
1820     char pszHostName[1000] = "";
1821     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1822     {
1823         vector<CNetAddr> vaddr;
1824         if (LookupHost(pszHostName, vaddr))
1825         {
1826             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1827             {
1828                 AddLocal(addr, LOCAL_IF);
1829             }
1830         }
1831     }
1832 #else
1833     // Get local host ip
1834     struct ifaddrs* myaddrs;
1835     if (getifaddrs(&myaddrs) == 0)
1836     {
1837         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1838         {
1839             if (ifa->ifa_addr == NULL) continue;
1840             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1841             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1842             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1843             if (ifa->ifa_addr->sa_family == AF_INET)
1844             {
1845                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1846                 CNetAddr addr(s4->sin_addr);
1847                 if (AddLocal(addr, LOCAL_IF))
1848                     printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1849             }
1850 #ifdef USE_IPV6
1851             else if (ifa->ifa_addr->sa_family == AF_INET6)
1852             {
1853                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1854                 CNetAddr addr(s6->sin6_addr);
1855                 if (AddLocal(addr, LOCAL_IF))
1856                     printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1857             }
1858 #endif
1859         }
1860         freeifaddrs(myaddrs);
1861     }
1862 #endif
1863
1864     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1865     if (!IsLimited(NET_IPV4))
1866         NewThread(ThreadGetMyExternalIP, NULL);
1867 }
1868
1869 void StartNode(void* parg)
1870 {
1871     // Make this thread recognisable as the startup thread
1872     RenameThread("novacoin-start");
1873
1874     if (semOutbound == NULL) {
1875         // initialize semaphore
1876         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
1877         semOutbound = new CSemaphore(nMaxOutbound);
1878     }
1879
1880     if (pnodeLocalHost == NULL)
1881         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
1882
1883     Discover();
1884
1885     //
1886     // Start threads
1887     //
1888
1889     if (!GetBoolArg("-dnsseed", true))
1890         printf("DNS seeding disabled\n");
1891     else
1892         if (!NewThread(ThreadDNSAddressSeed, NULL))
1893             printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
1894
1895     // Map ports with UPnP
1896     if (!fUseUPnP)
1897         printf("UPNP port mapping is disabled\n");
1898     else
1899         MapPort();
1900
1901     // Get addresses from IRC and advertise ours
1902     if (!GetBoolArg("-irc", true))
1903         printf("IRC seeding disabled\n");
1904     else
1905         if (!NewThread(ThreadIRCSeed, NULL))
1906             printf("Error: NewThread(ThreadIRCSeed) failed\n");
1907
1908     // Send and receive from sockets, accept connections
1909     if (!NewThread(ThreadSocketHandler, NULL))
1910         printf("Error: NewThread(ThreadSocketHandler) failed\n");
1911
1912     // Initiate outbound connections from -addnode
1913     if (!NewThread(ThreadOpenAddedConnections, NULL))
1914         printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
1915
1916     // Initiate outbound connections
1917     if (!NewThread(ThreadOpenConnections, NULL))
1918         printf("Error: NewThread(ThreadOpenConnections) failed\n");
1919
1920     // Process messages
1921     if (!NewThread(ThreadMessageHandler, NULL))
1922         printf("Error: NewThread(ThreadMessageHandler) failed\n");
1923
1924     // Dump network addresses
1925     if (!NewThread(ThreadDumpAddress, NULL))
1926         printf("Error; NewThread(ThreadDumpAddress) failed\n");
1927
1928     // Mine proof-of-stake blocks in the background
1929     if (!NewThread(ThreadStakeMiner, pwalletMain))
1930         printf("Error: NewThread(ThreadStakeMiner) failed\n");
1931
1932     // Trusted NTP server, it's localhost by default.
1933     strTrustedUpstream = GetArg("-ntp", "localhost");
1934
1935     // Start periodical NTP sampling thread
1936     NewThread(ThreadNtpSamples, NULL);
1937
1938 }
1939
1940 bool StopNode()
1941 {
1942     printf("StopNode()\n");
1943     fShutdown = true;
1944     nTransactionsUpdated++;
1945     int64_t nStart = GetTime();
1946     {
1947         LOCK(cs_main);
1948         ThreadScriptCheckQuit();
1949     }
1950     if (semOutbound)
1951         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1952             semOutbound->post();
1953     do
1954     {
1955         int nThreadsRunning = 0;
1956         for (int n = 0; n < THREAD_MAX; n++)
1957             nThreadsRunning += vnThreadsRunning[n];
1958         if (nThreadsRunning == 0)
1959             break;
1960         if (GetTime() - nStart > 20)
1961             break;
1962         Sleep(20);
1963     } while(true);
1964     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1965     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1966     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1967     if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
1968     if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
1969 #ifdef USE_UPNP
1970     if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1971 #endif
1972     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1973     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1974     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1975     if (vnThreadsRunning[THREAD_MINTER] > 0) printf("ThreadStakeMinter still running\n");
1976     if (vnThreadsRunning[THREAD_SCRIPTCHECK] > 0) printf("ThreadScriptCheck still running\n");
1977     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0 || vnThreadsRunning[THREAD_SCRIPTCHECK] > 0)
1978         Sleep(20);
1979     Sleep(50);
1980     DumpAddresses();
1981
1982     return true;
1983 }
1984
1985 class CNetCleanup
1986 {
1987 public:
1988     CNetCleanup()
1989     {
1990     }
1991     ~CNetCleanup()
1992     {
1993         // Close sockets
1994         BOOST_FOREACH(CNode* pnode, vNodes)
1995             if (pnode->hSocket != INVALID_SOCKET)
1996                 closesocket(pnode->hSocket);
1997         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1998             if (hListenSocket != INVALID_SOCKET)
1999                 if (closesocket(hListenSocket) == SOCKET_ERROR)
2000                     printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
2001
2002         // clean up some globals (to help leak detection)
2003         BOOST_FOREACH(CNode *pnode, vNodes)
2004             delete pnode;
2005         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
2006             delete pnode;
2007         vNodes.clear();
2008         vNodesDisconnected.clear();
2009         delete semOutbound;
2010         semOutbound = NULL;
2011         delete pnodeLocalHost;
2012         pnodeLocalHost = NULL;
2013
2014 #ifdef WIN32
2015         // Shutdown Windows Sockets
2016         WSACleanup();
2017 #endif
2018     }
2019 }
2020 instance_of_cnetcleanup;
2021
2022 void RelayTransaction(const CTransaction& tx, const uint256& hash)
2023 {
2024     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
2025     ss.reserve(10000);
2026     ss << tx;
2027     RelayTransaction(tx, hash, ss);
2028 }
2029
2030 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
2031 {
2032     CInv inv(MSG_TX, hash);
2033     {
2034         LOCK(cs_mapRelay);
2035         // Expire old relay messages
2036         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
2037         {
2038             mapRelay.erase(vRelayExpiration.front().second);
2039             vRelayExpiration.pop_front();
2040         }
2041
2042         // Save original serialized message so newer versions are preserved
2043         mapRelay.insert(std::make_pair(inv, ss));
2044         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
2045     }
2046
2047     RelayInventory(inv);
2048 }
2049
2050 void CNode::RecordBytesRecv(uint64_t bytes)
2051 {
2052     LOCK(cs_totalBytesRecv);
2053     nTotalBytesRecv += bytes;
2054 }
2055
2056 void CNode::RecordBytesSent(uint64_t bytes)
2057 {
2058     LOCK(cs_totalBytesSent);
2059     nTotalBytesSent += bytes;
2060 }
2061
2062 uint64_t CNode::GetTotalBytesRecv()
2063 {
2064     LOCK(cs_totalBytesRecv);
2065     return nTotalBytesRecv;
2066 }
2067
2068 uint64_t CNode::GetTotalBytesSent()
2069 {
2070     LOCK(cs_totalBytesSent);
2071     return nTotalBytesSent;
2072 }