Framework for banning mis-behaving peers
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "irc.h"
8 #include "db.h"
9 #include "net.h"
10 #include "init.h"
11 #include "strlcpy.h"
12
13 #ifdef __WXMSW__
14 #include <string.h>
15 #endif
16
17 #ifdef USE_UPNP
18 #include <miniupnpc/miniwget.h>
19 #include <miniupnpc/miniupnpc.h>
20 #include <miniupnpc/upnpcommands.h>
21 #include <miniupnpc/upnperrors.h>
22 #endif
23
24 using namespace std;
25 using namespace boost;
26
27 static const int MAX_OUTBOUND_CONNECTIONS = 8;
28
29 void ThreadMessageHandler2(void* parg);
30 void ThreadSocketHandler2(void* parg);
31 void ThreadOpenConnections2(void* parg);
32 #ifdef USE_UPNP
33 void ThreadMapPort2(void* parg);
34 #endif
35 bool OpenNetworkConnection(const CAddress& addrConnect);
36
37
38
39
40
41 //
42 // Global state variables
43 //
44 bool fClient = false;
45 bool fAllowDNS = false;
46 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
47 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
48 static CNode* pnodeLocalHost = NULL;
49 uint64 nLocalHostNonce = 0;
50 array<int, 10> vnThreadsRunning;
51 static SOCKET hListenSocket = INVALID_SOCKET;
52
53 vector<CNode*> vNodes;
54 CCriticalSection cs_vNodes;
55 map<vector<unsigned char>, CAddress> mapAddresses;
56 CCriticalSection cs_mapAddresses;
57 map<CInv, CDataStream> mapRelay;
58 deque<pair<int64, CInv> > vRelayExpiration;
59 CCriticalSection cs_mapRelay;
60 map<CInv, int64> mapAlreadyAskedFor;
61
62 // Settings
63 int fUseProxy = false;
64 int nConnectTimeout = 5000;
65 CAddress addrProxy("127.0.0.1",9050);
66
67
68
69
70 unsigned short GetListenPort()
71 {
72     return (unsigned short)(GetArg("-port", GetDefaultPort()));
73 }
74
75 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
76 {
77     // Filter out duplicate requests
78     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
79         return;
80     pindexLastGetBlocksBegin = pindexBegin;
81     hashLastGetBlocksEnd = hashEnd;
82
83     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
84 }
85
86
87
88
89
90 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
91 {
92     hSocketRet = INVALID_SOCKET;
93
94     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
95     if (hSocket == INVALID_SOCKET)
96         return false;
97 #ifdef SO_NOSIGPIPE
98     int set = 1;
99     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
100 #endif
101
102     bool fProxy = (fUseProxy && addrConnect.IsRoutable());
103     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
104
105 #ifdef __WXMSW__
106     u_long fNonblock = 1;
107     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
108 #else
109     int fFlags = fcntl(hSocket, F_GETFL, 0);
110     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
111 #endif
112     {
113         closesocket(hSocket);
114         return false;
115     }
116
117
118     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
119     {
120         // WSAEINVAL is here because some legacy version of winsock uses it
121         if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
122         {
123             struct timeval timeout;
124             timeout.tv_sec  = nTimeout / 1000;
125             timeout.tv_usec = (nTimeout % 1000) * 1000;
126
127             fd_set fdset;
128             FD_ZERO(&fdset);
129             FD_SET(hSocket, &fdset);
130             int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
131             if (nRet == 0)
132             {
133                 printf("connection timeout\n");
134                 closesocket(hSocket);
135                 return false;
136             }
137             if (nRet == SOCKET_ERROR)
138             {
139                 printf("select() for connection failed: %i\n",WSAGetLastError());
140                 closesocket(hSocket);
141                 return false;
142             }
143             socklen_t nRetSize = sizeof(nRet);
144 #ifdef __WXMSW__
145             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
146 #else
147             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
148 #endif
149             {
150                 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
151                 closesocket(hSocket);
152                 return false;
153             }
154             if (nRet != 0)
155             {
156                 printf("connect() failed after select(): %s\n",strerror(nRet));
157                 closesocket(hSocket);
158                 return false;
159             }
160         }
161 #ifdef __WXMSW__
162         else if (WSAGetLastError() != WSAEISCONN)
163 #else
164         else
165 #endif
166         {
167             printf("connect() failed: %i\n",WSAGetLastError());
168             closesocket(hSocket);
169             return false;
170         }
171     }
172
173     /*
174     this isn't even strictly necessary
175     CNode::ConnectNode immediately turns the socket back to non-blocking
176     but we'll turn it back to blocking just in case
177     */
178 #ifdef __WXMSW__
179     fNonblock = 0;
180     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
181 #else
182     fFlags = fcntl(hSocket, F_GETFL, 0);
183     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
184 #endif
185     {
186         closesocket(hSocket);
187         return false;
188     }
189
190     if (fProxy)
191     {
192         printf("proxy connecting %s\n", addrConnect.ToString().c_str());
193         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
194         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
195         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
196         char* pszSocks4 = pszSocks4IP;
197         int nSize = sizeof(pszSocks4IP);
198
199         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
200         if (ret != nSize)
201         {
202             closesocket(hSocket);
203             return error("Error sending to proxy");
204         }
205         char pchRet[8];
206         if (recv(hSocket, pchRet, 8, 0) != 8)
207         {
208             closesocket(hSocket);
209             return error("Error reading proxy response");
210         }
211         if (pchRet[1] != 0x5a)
212         {
213             closesocket(hSocket);
214             if (pchRet[1] != 0x5b)
215                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
216             return false;
217         }
218         printf("proxy connected %s\n", addrConnect.ToString().c_str());
219     }
220
221     hSocketRet = hSocket;
222     return true;
223 }
224
225 // portDefault is in host order
226 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
227 {
228     vaddr.clear();
229     if (pszName[0] == 0)
230         return false;
231     int port = portDefault;
232     char psz[256];
233     char *pszHost = psz;
234     strlcpy(psz, pszName, sizeof(psz));
235     if (fAllowPort)
236     {
237         char* pszColon = strrchr(psz+1,':');
238         char *pszPortEnd = NULL;
239         int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
240         if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
241         {
242             if (psz[0] == '[' && pszColon[-1] == ']')
243             {
244                 // Future: enable IPv6 colon-notation inside []
245                 pszHost = psz+1;
246                 pszColon[-1] = 0;
247             }
248             else
249                 pszColon[0] = 0;
250             port = portParsed;
251             if (port < 0 || port > USHRT_MAX)
252                 port = USHRT_MAX;
253         }
254     }
255
256     unsigned int addrIP = inet_addr(pszHost);
257     if (addrIP != INADDR_NONE)
258     {
259         // valid IP address passed
260         vaddr.push_back(CAddress(addrIP, port, nServices));
261         return true;
262     }
263
264     if (!fAllowLookup)
265         return false;
266
267     struct hostent* phostent = gethostbyname(pszHost);
268     if (!phostent)
269         return false;
270
271     if (phostent->h_addrtype != AF_INET)
272         return false;
273
274     char** ppAddr = phostent->h_addr_list;
275     while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
276     {
277         CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
278         if (addr.IsValid())
279             vaddr.push_back(addr);
280         ppAddr++;
281     }
282
283     return (vaddr.size() > 0);
284 }
285
286 // portDefault is in host order
287 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
288 {
289     vector<CAddress> vaddr;
290     bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
291     if (fRet)
292         addr = vaddr[0];
293     return fRet;
294 }
295
296 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
297 {
298     SOCKET hSocket;
299     if (!ConnectSocket(addrConnect, hSocket))
300         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
301
302     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
303
304     string strLine;
305     while (RecvLine(hSocket, strLine))
306     {
307         if (strLine.empty()) // HTTP response is separated from headers by blank line
308         {
309             loop
310             {
311                 if (!RecvLine(hSocket, strLine))
312                 {
313                     closesocket(hSocket);
314                     return false;
315                 }
316                 if (pszKeyword == NULL)
317                     break;
318                 if (strLine.find(pszKeyword) != -1)
319                 {
320                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
321                     break;
322                 }
323             }
324             closesocket(hSocket);
325             if (strLine.find("<") != -1)
326                 strLine = strLine.substr(0, strLine.find("<"));
327             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
328             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
329                 strLine.resize(strLine.size()-1);
330             CAddress addr(strLine,0,true);
331             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
332             if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
333                 return false;
334             ipRet = addr.ip;
335             return true;
336         }
337     }
338     closesocket(hSocket);
339     return error("GetMyExternalIP() : connection closed");
340 }
341
342 // We now get our external IP from the IRC server first and only use this as a backup
343 bool GetMyExternalIP(unsigned int& ipRet)
344 {
345     CAddress addrConnect;
346     const char* pszGet;
347     const char* pszKeyword;
348
349     if (fUseProxy)
350         return false;
351
352     for (int nLookup = 0; nLookup <= 1; nLookup++)
353     for (int nHost = 1; nHost <= 2; nHost++)
354     {
355         // We should be phasing out our use of sites like these.  If we need
356         // replacements, we should ask for volunteers to put this simple
357         // php file on their webserver that prints the client IP:
358         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
359         if (nHost == 1)
360         {
361             addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
362
363             if (nLookup == 1)
364             {
365                 CAddress addrIP("checkip.dyndns.org", 80, true);
366                 if (addrIP.IsValid())
367                     addrConnect = addrIP;
368             }
369
370             pszGet = "GET / HTTP/1.1\r\n"
371                      "Host: checkip.dyndns.org\r\n"
372                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
373                      "Connection: close\r\n"
374                      "\r\n";
375
376             pszKeyword = "Address:";
377         }
378         else if (nHost == 2)
379         {
380             addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
381
382             if (nLookup == 1)
383             {
384                 CAddress addrIP("www.showmyip.com", 80, true);
385                 if (addrIP.IsValid())
386                     addrConnect = addrIP;
387             }
388
389             pszGet = "GET /simple/ HTTP/1.1\r\n"
390                      "Host: www.showmyip.com\r\n"
391                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
392                      "Connection: close\r\n"
393                      "\r\n";
394
395             pszKeyword = NULL; // Returns just IP address
396         }
397
398         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
399             return true;
400     }
401
402     return false;
403 }
404
405 void ThreadGetMyExternalIP(void* parg)
406 {
407     // Wait for IRC to get it first
408     if (!GetBoolArg("-noirc"))
409     {
410         for (int i = 0; i < 2 * 60; i++)
411         {
412             Sleep(1000);
413             if (fGotExternalIP || fShutdown)
414                 return;
415         }
416     }
417
418     // Fallback in case IRC fails to get it
419     if (GetMyExternalIP(addrLocalHost.ip))
420     {
421         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
422         if (addrLocalHost.IsRoutable())
423         {
424             // If we already connected to a few before we had our IP, go back and addr them.
425             // setAddrKnown automatically filters any duplicate sends.
426             CAddress addr(addrLocalHost);
427             addr.nTime = GetAdjustedTime();
428             CRITICAL_BLOCK(cs_vNodes)
429                 BOOST_FOREACH(CNode* pnode, vNodes)
430                     pnode->PushAddress(addr);
431         }
432     }
433 }
434
435
436
437
438
439 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
440 {
441     if (!addr.IsRoutable())
442         return false;
443     if (addr.ip == addrLocalHost.ip)
444         return false;
445     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
446     bool fUpdated = false;
447     bool fNew = false;
448     CAddress addrFound = addr;
449
450     CRITICAL_BLOCK(cs_mapAddresses)
451     {
452         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
453         if (it == mapAddresses.end())
454         {
455             // New address
456             printf("AddAddress(%s)\n", addr.ToString().c_str());
457             mapAddresses.insert(make_pair(addr.GetKey(), addr));
458             fUpdated = true;
459             fNew = true;
460         }
461         else
462         {
463             addrFound = (*it).second;
464             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
465             {
466                 // Services have been added
467                 addrFound.nServices |= addr.nServices;
468                 fUpdated = true;
469             }
470             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
471             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
472             if (addrFound.nTime < addr.nTime - nUpdateInterval)
473             {
474                 // Periodically update most recently seen time
475                 addrFound.nTime = addr.nTime;
476                 fUpdated = true;
477             }
478         }
479     }
480     // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
481     // CRITICAL_BLOCK:
482     // Thread 1:  begin db transaction (locks inside-db-mutex)
483     //            then AddAddress (locks cs_mapAddresses)
484     // Thread 2:  AddAddress (locks cs_mapAddresses)
485     //             ... then db operation hangs waiting for inside-db-mutex
486     if (fUpdated)
487     {
488         if (pAddrDB)
489             pAddrDB->WriteAddress(addrFound);
490         else
491             CAddrDB().WriteAddress(addrFound);
492     }
493     return fNew;
494 }
495
496 void AddressCurrentlyConnected(const CAddress& addr)
497 {
498     CRITICAL_BLOCK(cs_mapAddresses)
499     {
500         // Only if it's been published already
501         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
502         if (it != mapAddresses.end())
503         {
504             CAddress& addrFound = (*it).second;
505             int64 nUpdateInterval = 20 * 60;
506             if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
507             {
508                 // Periodically update most recently seen time
509                 addrFound.nTime = GetAdjustedTime();
510                 CAddrDB addrdb;
511                 addrdb.WriteAddress(addrFound);
512             }
513         }
514     }
515 }
516
517
518
519
520
521 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
522 {
523     // If the dialog might get closed before the reply comes back,
524     // call this in the destructor so it doesn't get called after it's deleted.
525     CRITICAL_BLOCK(cs_vNodes)
526     {
527         BOOST_FOREACH(CNode* pnode, vNodes)
528         {
529             CRITICAL_BLOCK(pnode->cs_mapRequests)
530             {
531                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
532                 {
533                     CRequestTracker& tracker = (*mi).second;
534                     if (tracker.fn == fn && tracker.param1 == param1)
535                         pnode->mapRequests.erase(mi++);
536                     else
537                         mi++;
538                 }
539             }
540         }
541     }
542 }
543
544
545
546
547
548
549
550 //
551 // Subscription methods for the broadcast and subscription system.
552 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
553 //
554 // The subscription system uses a meet-in-the-middle strategy.
555 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
556 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
557 //
558
559 bool AnySubscribed(unsigned int nChannel)
560 {
561     if (pnodeLocalHost->IsSubscribed(nChannel))
562         return true;
563     CRITICAL_BLOCK(cs_vNodes)
564         BOOST_FOREACH(CNode* pnode, vNodes)
565             if (pnode->IsSubscribed(nChannel))
566                 return true;
567     return false;
568 }
569
570 bool CNode::IsSubscribed(unsigned int nChannel)
571 {
572     if (nChannel >= vfSubscribe.size())
573         return false;
574     return vfSubscribe[nChannel];
575 }
576
577 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
578 {
579     if (nChannel >= vfSubscribe.size())
580         return;
581
582     if (!AnySubscribed(nChannel))
583     {
584         // Relay subscribe
585         CRITICAL_BLOCK(cs_vNodes)
586             BOOST_FOREACH(CNode* pnode, vNodes)
587                 if (pnode != this)
588                     pnode->PushMessage("subscribe", nChannel, nHops);
589     }
590
591     vfSubscribe[nChannel] = true;
592 }
593
594 void CNode::CancelSubscribe(unsigned int nChannel)
595 {
596     if (nChannel >= vfSubscribe.size())
597         return;
598
599     // Prevent from relaying cancel if wasn't subscribed
600     if (!vfSubscribe[nChannel])
601         return;
602     vfSubscribe[nChannel] = false;
603
604     if (!AnySubscribed(nChannel))
605     {
606         // Relay subscription cancel
607         CRITICAL_BLOCK(cs_vNodes)
608             BOOST_FOREACH(CNode* pnode, vNodes)
609                 if (pnode != this)
610                     pnode->PushMessage("sub-cancel", nChannel);
611     }
612 }
613
614
615
616
617
618
619
620
621
622 CNode* FindNode(unsigned int ip)
623 {
624     CRITICAL_BLOCK(cs_vNodes)
625     {
626         BOOST_FOREACH(CNode* pnode, vNodes)
627             if (pnode->addr.ip == ip)
628                 return (pnode);
629     }
630     return NULL;
631 }
632
633 CNode* FindNode(CAddress addr)
634 {
635     CRITICAL_BLOCK(cs_vNodes)
636     {
637         BOOST_FOREACH(CNode* pnode, vNodes)
638             if (pnode->addr == addr)
639                 return (pnode);
640     }
641     return NULL;
642 }
643
644 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
645 {
646     if (addrConnect.ip == addrLocalHost.ip)
647         return NULL;
648
649     // Look for an existing connection
650     CNode* pnode = FindNode(addrConnect.ip);
651     if (pnode)
652     {
653         if (nTimeout != 0)
654             pnode->AddRef(nTimeout);
655         else
656             pnode->AddRef();
657         return pnode;
658     }
659
660     /// debug print
661     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
662         addrConnect.ToString().c_str(),
663         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
664         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
665
666     CRITICAL_BLOCK(cs_mapAddresses)
667         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
668
669     // Connect
670     SOCKET hSocket;
671     if (ConnectSocket(addrConnect, hSocket))
672     {
673         /// debug print
674         printf("connected %s\n", addrConnect.ToString().c_str());
675
676         // Set to nonblocking
677 #ifdef __WXMSW__
678         u_long nOne = 1;
679         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
680             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
681 #else
682         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
683             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
684 #endif
685
686         // Add node
687         CNode* pnode = new CNode(hSocket, addrConnect, false);
688         if (nTimeout != 0)
689             pnode->AddRef(nTimeout);
690         else
691             pnode->AddRef();
692         CRITICAL_BLOCK(cs_vNodes)
693             vNodes.push_back(pnode);
694
695         pnode->nTimeConnected = GetTime();
696         return pnode;
697     }
698     else
699     {
700         return NULL;
701     }
702 }
703
704 void CNode::CloseSocketDisconnect()
705 {
706     fDisconnect = true;
707     if (hSocket != INVALID_SOCKET)
708     {
709         if (fDebug)
710             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
711         printf("disconnecting node %s\n", addr.ToString().c_str());
712         closesocket(hSocket);
713         hSocket = INVALID_SOCKET;
714     }
715 }
716
717 void CNode::Cleanup()
718 {
719     // All of a nodes broadcasts and subscriptions are automatically torn down
720     // when it goes down, so a node has to stay up to keep its broadcast going.
721
722     // Cancel subscriptions
723     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
724         if (vfSubscribe[nChannel])
725             CancelSubscribe(nChannel);
726 }
727
728
729 std::map<unsigned int, int64> CNode::setBanned;
730 CCriticalSection CNode::cs_setBanned;
731
732 void CNode::ClearBanned()
733 {
734     setBanned.clear();
735 }
736
737 bool CNode::IsBanned(unsigned int ip)
738 {
739     bool fResult = false;
740     CRITICAL_BLOCK(cs_setBanned)
741     {
742         std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
743         if (i != setBanned.end())
744         {
745             int64 t = (*i).second;
746             if (GetTime() < t)
747                 fResult = true;
748         }
749     }
750     return fResult;
751 }
752
753 bool CNode::Misbehaving(int howmuch)
754 {
755     if (addr.IsLocal())
756     {
757         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
758         return false;
759     }
760
761     nMisbehavior += howmuch;
762     if (nMisbehavior >= GetArg("-banscore", 100))
763     {
764         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
765         CRITICAL_BLOCK(cs_setBanned)
766             if (setBanned[addr.ip] < banTime)
767                 setBanned[addr.ip] = banTime;
768         CloseSocketDisconnect();
769         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
770         return true;
771     }
772     return false;
773 }
774
775
776
777
778
779
780
781
782
783
784
785
786 void ThreadSocketHandler(void* parg)
787 {
788     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
789     try
790     {
791         vnThreadsRunning[0]++;
792         ThreadSocketHandler2(parg);
793         vnThreadsRunning[0]--;
794     }
795     catch (std::exception& e) {
796         vnThreadsRunning[0]--;
797         PrintException(&e, "ThreadSocketHandler()");
798     } catch (...) {
799         vnThreadsRunning[0]--;
800         throw; // support pthread_cancel()
801     }
802     printf("ThreadSocketHandler exiting\n");
803 }
804
805 void ThreadSocketHandler2(void* parg)
806 {
807     printf("ThreadSocketHandler started\n");
808     list<CNode*> vNodesDisconnected;
809     int nPrevNodeCount = 0;
810
811     loop
812     {
813         //
814         // Disconnect nodes
815         //
816         CRITICAL_BLOCK(cs_vNodes)
817         {
818             // Disconnect unused nodes
819             vector<CNode*> vNodesCopy = vNodes;
820             BOOST_FOREACH(CNode* pnode, vNodesCopy)
821             {
822                 if (pnode->fDisconnect ||
823                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
824                 {
825                     // remove from vNodes
826                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
827
828                     // close socket and cleanup
829                     pnode->CloseSocketDisconnect();
830                     pnode->Cleanup();
831
832                     // hold in disconnected pool until all refs are released
833                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
834                     if (pnode->fNetworkNode || pnode->fInbound)
835                         pnode->Release();
836                     vNodesDisconnected.push_back(pnode);
837                 }
838             }
839
840             // Delete disconnected nodes
841             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
842             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
843             {
844                 // wait until threads are done using it
845                 if (pnode->GetRefCount() <= 0)
846                 {
847                     bool fDelete = false;
848                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
849                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
850                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
851                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
852                         fDelete = true;
853                     if (fDelete)
854                     {
855                         vNodesDisconnected.remove(pnode);
856                         delete pnode;
857                     }
858                 }
859             }
860         }
861         if (vNodes.size() != nPrevNodeCount)
862         {
863             nPrevNodeCount = vNodes.size();
864             MainFrameRepaint();
865         }
866
867
868         //
869         // Find which sockets have data to receive
870         //
871         struct timeval timeout;
872         timeout.tv_sec  = 0;
873         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
874
875         fd_set fdsetRecv;
876         fd_set fdsetSend;
877         fd_set fdsetError;
878         FD_ZERO(&fdsetRecv);
879         FD_ZERO(&fdsetSend);
880         FD_ZERO(&fdsetError);
881         SOCKET hSocketMax = 0;
882
883         if(hListenSocket != INVALID_SOCKET)
884             FD_SET(hListenSocket, &fdsetRecv);
885         hSocketMax = max(hSocketMax, hListenSocket);
886         CRITICAL_BLOCK(cs_vNodes)
887         {
888             BOOST_FOREACH(CNode* pnode, vNodes)
889             {
890                 if (pnode->hSocket == INVALID_SOCKET)
891                     continue;
892                 FD_SET(pnode->hSocket, &fdsetRecv);
893                 FD_SET(pnode->hSocket, &fdsetError);
894                 hSocketMax = max(hSocketMax, pnode->hSocket);
895                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
896                     if (!pnode->vSend.empty())
897                         FD_SET(pnode->hSocket, &fdsetSend);
898             }
899         }
900
901         vnThreadsRunning[0]--;
902         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
903         vnThreadsRunning[0]++;
904         if (fShutdown)
905             return;
906         if (nSelect == SOCKET_ERROR)
907         {
908             int nErr = WSAGetLastError();
909             if (hSocketMax > -1)
910             {
911                 printf("socket select error %d\n", nErr);
912                 for (int i = 0; i <= hSocketMax; i++)
913                     FD_SET(i, &fdsetRecv);
914             }
915             FD_ZERO(&fdsetSend);
916             FD_ZERO(&fdsetError);
917             Sleep(timeout.tv_usec/1000);
918         }
919
920
921         //
922         // Accept new connections
923         //
924         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
925         {
926             struct sockaddr_in sockaddr;
927             socklen_t len = sizeof(sockaddr);
928             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
929             CAddress addr(sockaddr);
930             int nInbound = 0;
931
932             CRITICAL_BLOCK(cs_vNodes)
933                 BOOST_FOREACH(CNode* pnode, vNodes)
934                 if (pnode->fInbound)
935                     nInbound++;
936             if (hSocket == INVALID_SOCKET)
937             {
938                 if (WSAGetLastError() != WSAEWOULDBLOCK)
939                     printf("socket error accept failed: %d\n", WSAGetLastError());
940             }
941             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
942             {
943                 closesocket(hSocket);
944             }
945             else if (CNode::IsBanned(addr.ip))
946             {
947                 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
948                 closesocket(hSocket);
949             }
950             else
951             {
952                 printf("accepted connection %s\n", addr.ToString().c_str());
953                 CNode* pnode = new CNode(hSocket, addr, true);
954                 pnode->AddRef();
955                 CRITICAL_BLOCK(cs_vNodes)
956                     vNodes.push_back(pnode);
957             }
958         }
959
960
961         //
962         // Service each socket
963         //
964         vector<CNode*> vNodesCopy;
965         CRITICAL_BLOCK(cs_vNodes)
966         {
967             vNodesCopy = vNodes;
968             BOOST_FOREACH(CNode* pnode, vNodesCopy)
969                 pnode->AddRef();
970         }
971         BOOST_FOREACH(CNode* pnode, vNodesCopy)
972         {
973             if (fShutdown)
974                 return;
975
976             //
977             // Receive
978             //
979             if (pnode->hSocket == INVALID_SOCKET)
980                 continue;
981             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
982             {
983                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
984                 {
985                     CDataStream& vRecv = pnode->vRecv;
986                     unsigned int nPos = vRecv.size();
987
988                     if (nPos > ReceiveBufferSize()) {
989                         if (!pnode->fDisconnect)
990                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
991                         pnode->CloseSocketDisconnect();
992                     }
993                     else {
994                         // typical socket buffer is 8K-64K
995                         char pchBuf[0x10000];
996                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
997                         if (nBytes > 0)
998                         {
999                             vRecv.resize(nPos + nBytes);
1000                             memcpy(&vRecv[nPos], pchBuf, nBytes);
1001                             pnode->nLastRecv = GetTime();
1002                         }
1003                         else if (nBytes == 0)
1004                         {
1005                             // socket closed gracefully
1006                             if (!pnode->fDisconnect)
1007                                 printf("socket closed\n");
1008                             pnode->CloseSocketDisconnect();
1009                         }
1010                         else if (nBytes < 0)
1011                         {
1012                             // error
1013                             int nErr = WSAGetLastError();
1014                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1015                             {
1016                                 if (!pnode->fDisconnect)
1017                                     printf("socket recv error %d\n", nErr);
1018                                 pnode->CloseSocketDisconnect();
1019                             }
1020                         }
1021                     }
1022                 }
1023             }
1024
1025             //
1026             // Send
1027             //
1028             if (pnode->hSocket == INVALID_SOCKET)
1029                 continue;
1030             if (FD_ISSET(pnode->hSocket, &fdsetSend))
1031             {
1032                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1033                 {
1034                     CDataStream& vSend = pnode->vSend;
1035                     if (!vSend.empty())
1036                     {
1037                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
1038                         if (nBytes > 0)
1039                         {
1040                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1041                             pnode->nLastSend = GetTime();
1042                         }
1043                         else if (nBytes < 0)
1044                         {
1045                             // error
1046                             int nErr = WSAGetLastError();
1047                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1048                             {
1049                                 printf("socket send error %d\n", nErr);
1050                                 pnode->CloseSocketDisconnect();
1051                             }
1052                         }
1053                         if (vSend.size() > SendBufferSize()) {
1054                             if (!pnode->fDisconnect)
1055                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1056                             pnode->CloseSocketDisconnect();
1057                         }
1058                     }
1059                 }
1060             }
1061
1062             //
1063             // Inactivity checking
1064             //
1065             if (pnode->vSend.empty())
1066                 pnode->nLastSendEmpty = GetTime();
1067             if (GetTime() - pnode->nTimeConnected > 60)
1068             {
1069                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1070                 {
1071                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1072                     pnode->fDisconnect = true;
1073                 }
1074                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1075                 {
1076                     printf("socket not sending\n");
1077                     pnode->fDisconnect = true;
1078                 }
1079                 else if (GetTime() - pnode->nLastRecv > 90*60)
1080                 {
1081                     printf("socket inactivity timeout\n");
1082                     pnode->fDisconnect = true;
1083                 }
1084             }
1085         }
1086         CRITICAL_BLOCK(cs_vNodes)
1087         {
1088             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1089                 pnode->Release();
1090         }
1091
1092         Sleep(10);
1093     }
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 #ifdef USE_UPNP
1105 void ThreadMapPort(void* parg)
1106 {
1107     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1108     try
1109     {
1110         vnThreadsRunning[5]++;
1111         ThreadMapPort2(parg);
1112         vnThreadsRunning[5]--;
1113     }
1114     catch (std::exception& e) {
1115         vnThreadsRunning[5]--;
1116         PrintException(&e, "ThreadMapPort()");
1117     } catch (...) {
1118         vnThreadsRunning[5]--;
1119         PrintException(NULL, "ThreadMapPort()");
1120     }
1121     printf("ThreadMapPort exiting\n");
1122 }
1123
1124 void ThreadMapPort2(void* parg)
1125 {
1126     printf("ThreadMapPort started\n");
1127
1128     char port[6];
1129     sprintf(port, "%d", GetListenPort());
1130
1131     const char * rootdescurl = 0;
1132     const char * multicastif = 0;
1133     const char * minissdpdpath = 0;
1134     int error = 0;
1135     struct UPNPDev * devlist = 0;
1136     char lanaddr[64];
1137
1138     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1139
1140     struct UPNPUrls urls;
1141     struct IGDdatas data;
1142     int r;
1143
1144     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1145     if (r == 1)
1146     {
1147         char intClient[16];
1148         char intPort[6];
1149         string strDesc = "Bitcoin " + FormatFullVersion();
1150         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1151                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1152
1153         if(r!=UPNPCOMMAND_SUCCESS)
1154             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1155                 port, port, lanaddr, r, strupnperror(r));
1156         else
1157             printf("UPnP Port Mapping successful.\n");
1158         loop {
1159             if (fShutdown || !fUseUPnP)
1160             {
1161                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1162                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1163                 freeUPNPDevlist(devlist); devlist = 0;
1164                 FreeUPNPUrls(&urls);
1165                 return;
1166             }
1167             Sleep(2000);
1168         }
1169     } else {
1170         printf("No valid UPnP IGDs found\n");
1171         freeUPNPDevlist(devlist); devlist = 0;
1172         if (r != 0)
1173             FreeUPNPUrls(&urls);
1174         loop {
1175             if (fShutdown || !fUseUPnP)
1176                 return;
1177             Sleep(2000);
1178         }
1179     }
1180 }
1181
1182 void MapPort(bool fMapPort)
1183 {
1184     if (fUseUPnP != fMapPort)
1185     {
1186         fUseUPnP = fMapPort;
1187         WriteSetting("fUseUPnP", fUseUPnP);
1188     }
1189     if (fUseUPnP && vnThreadsRunning[5] < 1)
1190     {
1191         if (!CreateThread(ThreadMapPort, NULL))
1192             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1193     }
1194 }
1195 #else
1196 void MapPort(bool /* unused fMapPort */)
1197 {
1198     // Intentionally left blank.
1199 }
1200 #endif
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 static const char *strDNSSeed[] = {
1212     "bitseed.xf2.org",
1213     "bitseed.bitcoin.org.uk",
1214     "dnsseed.bluematt.me",
1215 };
1216
1217 void DNSAddressSeed()
1218 {
1219     int found = 0;
1220
1221     if (!fTestNet)
1222     {
1223         printf("Loading addresses from DNS seeds (could take a while)\n");
1224         CAddrDB addrDB;
1225         addrDB.TxnBegin();
1226
1227         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1228             vector<CAddress> vaddr;
1229             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1230             {
1231                 BOOST_FOREACH (CAddress& addr, vaddr)
1232                 {
1233                     if (addr.GetByte(3) != 127)
1234                     {
1235                         addr.nTime = 0;
1236                         AddAddress(addr, 0, &addrDB);
1237                         found++;
1238                     }
1239                 }
1240             }
1241         }
1242
1243         addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1244     }
1245
1246     printf("%d addresses found from DNS seeds\n", found);
1247 }
1248
1249
1250
1251 unsigned int pnSeed[] =
1252 {
1253     0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1254     0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1255     0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1256     0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1257     0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1258     0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1259     0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1260     0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1261     0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1262     0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1263     0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1264     0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1265     0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1266     0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1267     0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1268     0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1269     0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1270     0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1271     0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1272     0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1273     0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1274     0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1275     0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1276     0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1277     0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1278     0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1279     0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1280     0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1281     0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1282     0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1283     0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1284     0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1285     0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1286     0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1287     0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1288     0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1289     0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1290     0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1291     0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1292     0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1293     0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1294     0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1295     0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1296     0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1297     0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1298     0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1299     0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1300     0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1301     0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1302     0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1303     0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1304     0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1305     0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1306     0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1307     0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1308     0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1309     0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1310     0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1311     0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1312     0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1313     0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1314     0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1315     0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1316     0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1317 };
1318
1319
1320
1321 void ThreadOpenConnections(void* parg)
1322 {
1323     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1324     try
1325     {
1326         vnThreadsRunning[1]++;
1327         ThreadOpenConnections2(parg);
1328         vnThreadsRunning[1]--;
1329     }
1330     catch (std::exception& e) {
1331         vnThreadsRunning[1]--;
1332         PrintException(&e, "ThreadOpenConnections()");
1333     } catch (...) {
1334         vnThreadsRunning[1]--;
1335         PrintException(NULL, "ThreadOpenConnections()");
1336     }
1337     printf("ThreadOpenConnections exiting\n");
1338 }
1339
1340 void ThreadOpenConnections2(void* parg)
1341 {
1342     printf("ThreadOpenConnections started\n");
1343
1344     // Connect to specific addresses
1345     if (mapArgs.count("-connect"))
1346     {
1347         for (int64 nLoop = 0;; nLoop++)
1348         {
1349             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1350             {
1351                 CAddress addr(strAddr, fAllowDNS);
1352                 if (addr.IsValid())
1353                     OpenNetworkConnection(addr);
1354                 for (int i = 0; i < 10 && i < nLoop; i++)
1355                 {
1356                     Sleep(500);
1357                     if (fShutdown)
1358                         return;
1359                 }
1360             }
1361         }
1362     }
1363
1364     // Connect to manually added nodes first
1365     if (mapArgs.count("-addnode"))
1366     {
1367         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1368         {
1369             CAddress addr(strAddr, fAllowDNS);
1370             if (addr.IsValid())
1371             {
1372                 OpenNetworkConnection(addr);
1373                 Sleep(500);
1374                 if (fShutdown)
1375                     return;
1376             }
1377         }
1378     }
1379
1380     // Initiate network connections
1381     int64 nStart = GetTime();
1382     loop
1383     {
1384         // Limit outbound connections
1385         vnThreadsRunning[1]--;
1386         Sleep(500);
1387         loop
1388         {
1389             int nOutbound = 0;
1390             CRITICAL_BLOCK(cs_vNodes)
1391                 BOOST_FOREACH(CNode* pnode, vNodes)
1392                     if (!pnode->fInbound)
1393                         nOutbound++;
1394             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1395             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1396             if (nOutbound < nMaxOutboundConnections)
1397                 break;
1398             Sleep(2000);
1399             if (fShutdown)
1400                 return;
1401         }
1402         vnThreadsRunning[1]++;
1403         if (fShutdown)
1404             return;
1405
1406         CRITICAL_BLOCK(cs_mapAddresses)
1407         {
1408             // Add seed nodes if IRC isn't working
1409             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1410             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1411             {
1412                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1413                 {
1414                     // It'll only connect to one or two seed nodes because once it connects,
1415                     // it'll get a pile of addresses with newer timestamps.
1416                     // Seed nodes are given a random 'last seen time' of between one and two
1417                     // weeks ago.
1418                     const int64 nOneWeek = 7*24*60*60;
1419                     CAddress addr;
1420                     addr.ip = pnSeed[i];
1421                     addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1422                     AddAddress(addr);
1423                 }
1424             }
1425         }
1426
1427
1428         //
1429         // Choose an address to connect to based on most recently seen
1430         //
1431         CAddress addrConnect;
1432         int64 nBest = INT64_MIN;
1433
1434         // Only connect to one address per a.b.?.? range.
1435         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1436         set<unsigned int> setConnected;
1437         CRITICAL_BLOCK(cs_vNodes)
1438             BOOST_FOREACH(CNode* pnode, vNodes)
1439                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1440
1441         CRITICAL_BLOCK(cs_mapAddresses)
1442         {
1443             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1444             {
1445                 const CAddress& addr = item.second;
1446                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1447                     continue;
1448                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1449                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1450
1451                 // Randomize the order in a deterministic way, putting the standard port first
1452                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1453                 if (addr.port != htons(GetDefaultPort()))
1454                     nRandomizer += 2 * 60 * 60;
1455
1456                 // Last seen  Base retry frequency
1457                 //   <1 hour   10 min
1458                 //    1 hour    1 hour
1459                 //    4 hours   2 hours
1460                 //   24 hours   5 hours
1461                 //   48 hours   7 hours
1462                 //    7 days   13 hours
1463                 //   30 days   27 hours
1464                 //   90 days   46 hours
1465                 //  365 days   93 hours
1466                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1467
1468                 // Fast reconnect for one hour after last seen
1469                 if (nSinceLastSeen < 60 * 60)
1470                     nDelay = 10 * 60;
1471
1472                 // Limit retry frequency
1473                 if (nSinceLastTry < nDelay)
1474                     continue;
1475
1476                 // If we have IRC, we'll be notified when they first come online,
1477                 // and again every 24 hours by the refresh broadcast.
1478                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1479                     continue;
1480
1481                 // Only try the old stuff if we don't have enough connections
1482                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1483                     continue;
1484
1485                 // If multiple addresses are ready, prioritize by time since
1486                 // last seen and time since last tried.
1487                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1488                 if (nScore > nBest)
1489                 {
1490                     nBest = nScore;
1491                     addrConnect = addr;
1492                 }
1493             }
1494         }
1495
1496         if (addrConnect.IsValid())
1497             OpenNetworkConnection(addrConnect);
1498     }
1499 }
1500
1501 bool OpenNetworkConnection(const CAddress& addrConnect)
1502 {
1503     //
1504     // Initiate outbound network connection
1505     //
1506     if (fShutdown)
1507         return false;
1508     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1509         FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1510         return false;
1511
1512     vnThreadsRunning[1]--;
1513     CNode* pnode = ConnectNode(addrConnect);
1514     vnThreadsRunning[1]++;
1515     if (fShutdown)
1516         return false;
1517     if (!pnode)
1518         return false;
1519     pnode->fNetworkNode = true;
1520
1521     return true;
1522 }
1523
1524
1525
1526
1527
1528
1529
1530
1531 void ThreadMessageHandler(void* parg)
1532 {
1533     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1534     try
1535     {
1536         vnThreadsRunning[2]++;
1537         ThreadMessageHandler2(parg);
1538         vnThreadsRunning[2]--;
1539     }
1540     catch (std::exception& e) {
1541         vnThreadsRunning[2]--;
1542         PrintException(&e, "ThreadMessageHandler()");
1543     } catch (...) {
1544         vnThreadsRunning[2]--;
1545         PrintException(NULL, "ThreadMessageHandler()");
1546     }
1547     printf("ThreadMessageHandler exiting\n");
1548 }
1549
1550 void ThreadMessageHandler2(void* parg)
1551 {
1552     printf("ThreadMessageHandler started\n");
1553     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1554     while (!fShutdown)
1555     {
1556         vector<CNode*> vNodesCopy;
1557         CRITICAL_BLOCK(cs_vNodes)
1558         {
1559             vNodesCopy = vNodes;
1560             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1561                 pnode->AddRef();
1562         }
1563
1564         // Poll the connected nodes for messages
1565         CNode* pnodeTrickle = NULL;
1566         if (!vNodesCopy.empty())
1567             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1568         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1569         {
1570             // Receive messages
1571             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1572                 ProcessMessages(pnode);
1573             if (fShutdown)
1574                 return;
1575
1576             // Send messages
1577             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1578                 SendMessages(pnode, pnode == pnodeTrickle);
1579             if (fShutdown)
1580                 return;
1581         }
1582
1583         CRITICAL_BLOCK(cs_vNodes)
1584         {
1585             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1586                 pnode->Release();
1587         }
1588
1589         // Wait and allow messages to bunch up.
1590         // Reduce vnThreadsRunning so StopNode has permission to exit while
1591         // we're sleeping, but we must always check fShutdown after doing this.
1592         vnThreadsRunning[2]--;
1593         Sleep(100);
1594         if (fRequestShutdown)
1595             Shutdown(NULL);
1596         vnThreadsRunning[2]++;
1597         if (fShutdown)
1598             return;
1599     }
1600 }
1601
1602
1603
1604
1605
1606
1607 bool BindListenPort(string& strError)
1608 {
1609     strError = "";
1610     int nOne = 1;
1611     addrLocalHost.port = htons(GetListenPort());
1612
1613 #ifdef __WXMSW__
1614     // Initialize Windows Sockets
1615     WSADATA wsadata;
1616     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1617     if (ret != NO_ERROR)
1618     {
1619         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1620         printf("%s\n", strError.c_str());
1621         return false;
1622     }
1623 #endif
1624
1625     // Create socket for listening for incoming connections
1626     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1627     if (hListenSocket == INVALID_SOCKET)
1628     {
1629         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1630         printf("%s\n", strError.c_str());
1631         return false;
1632     }
1633
1634 #ifdef SO_NOSIGPIPE
1635     // Different way of disabling SIGPIPE on BSD
1636     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1637 #endif
1638
1639 #ifndef __WXMSW__
1640     // Allow binding if the port is still in TIME_WAIT state after
1641     // the program was closed and restarted.  Not an issue on windows.
1642     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1643 #endif
1644
1645 #ifdef __WXMSW__
1646     // Set to nonblocking, incoming connections will also inherit this
1647     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1648 #else
1649     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1650 #endif
1651     {
1652         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1653         printf("%s\n", strError.c_str());
1654         return false;
1655     }
1656
1657     // The sockaddr_in structure specifies the address family,
1658     // IP address, and port for the socket that is being bound
1659     struct sockaddr_in sockaddr;
1660     memset(&sockaddr, 0, sizeof(sockaddr));
1661     sockaddr.sin_family = AF_INET;
1662     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1663     sockaddr.sin_port = htons(GetListenPort());
1664     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1665     {
1666         int nErr = WSAGetLastError();
1667         if (nErr == WSAEADDRINUSE)
1668             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1669         else
1670             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1671         printf("%s\n", strError.c_str());
1672         return false;
1673     }
1674     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1675
1676     // Listen for incoming connections
1677     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1678     {
1679         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1680         printf("%s\n", strError.c_str());
1681         return false;
1682     }
1683
1684     return true;
1685 }
1686
1687 void StartNode(void* parg)
1688 {
1689     if (pnodeLocalHost == NULL)
1690         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1691
1692 #ifdef __WXMSW__
1693     // Get local host ip
1694     char pszHostName[1000] = "";
1695     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1696     {
1697         vector<CAddress> vaddr;
1698         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1699             BOOST_FOREACH (const CAddress &addr, vaddr)
1700                 if (addr.GetByte(3) != 127)
1701                 {
1702                     addrLocalHost = addr;
1703                     break;
1704                 }
1705     }
1706 #else
1707     // Get local host ip
1708     struct ifaddrs* myaddrs;
1709     if (getifaddrs(&myaddrs) == 0)
1710     {
1711         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1712         {
1713             if (ifa->ifa_addr == NULL) continue;
1714             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1715             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1716             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1717             char pszIP[100];
1718             if (ifa->ifa_addr->sa_family == AF_INET)
1719             {
1720                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1721                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1722                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1723
1724                 // Take the first IP that isn't loopback 127.x.x.x
1725                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1726                 if (addr.IsValid() && addr.GetByte(3) != 127)
1727                 {
1728                     addrLocalHost = addr;
1729                     break;
1730                 }
1731             }
1732             else if (ifa->ifa_addr->sa_family == AF_INET6)
1733             {
1734                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1735                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1736                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1737             }
1738         }
1739         freeifaddrs(myaddrs);
1740     }
1741 #endif
1742     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1743
1744     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1745     {
1746         // Proxies can't take incoming connections
1747         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1748         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1749     }
1750     else
1751     {
1752         CreateThread(ThreadGetMyExternalIP, NULL);
1753     }
1754
1755     //
1756     // Start threads
1757     //
1758
1759     // Map ports with UPnP
1760     if (fHaveUPnP)
1761         MapPort(fUseUPnP);
1762
1763     // Get addresses from IRC and advertise ours
1764     if (!CreateThread(ThreadIRCSeed, NULL))
1765         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1766
1767     // Send and receive from sockets, accept connections
1768     CreateThread(ThreadSocketHandler, NULL);
1769
1770     // Initiate outbound connections
1771     if (!CreateThread(ThreadOpenConnections, NULL))
1772         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1773
1774     // Process messages
1775     if (!CreateThread(ThreadMessageHandler, NULL))
1776         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1777
1778     // Generate coins in the background
1779     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1780 }
1781
1782 bool StopNode()
1783 {
1784     printf("StopNode()\n");
1785     fShutdown = true;
1786     nTransactionsUpdated++;
1787     int64 nStart = GetTime();
1788     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1789 #ifdef USE_UPNP
1790         || vnThreadsRunning[5] > 0
1791 #endif
1792     )
1793     {
1794         if (GetTime() - nStart > 20)
1795             break;
1796         Sleep(20);
1797     }
1798     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1799     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1800     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1801     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1802     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1803     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1804     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1805         Sleep(20);
1806     Sleep(50);
1807
1808     return true;
1809 }
1810
1811 class CNetCleanup
1812 {
1813 public:
1814     CNetCleanup()
1815     {
1816     }
1817     ~CNetCleanup()
1818     {
1819         // Close sockets
1820         BOOST_FOREACH(CNode* pnode, vNodes)
1821             if (pnode->hSocket != INVALID_SOCKET)
1822                 closesocket(pnode->hSocket);
1823         if (hListenSocket != INVALID_SOCKET)
1824             if (closesocket(hListenSocket) == SOCKET_ERROR)
1825                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1826
1827 #ifdef __WXMSW__
1828         // Shutdown Windows Sockets
1829         WSACleanup();
1830 #endif
1831     }
1832 }
1833 instance_of_cnetcleanup;