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