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