Move DNS Seed lookup to a new thread.
[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 WIN32
14 #include <string.h>
15 #endif
16
17 #ifdef USE_UPNP
18 #include <miniupnpc/miniwget.h>
19 #include <miniupnpc/miniupnpc.h>
20 #include <miniupnpc/upnpcommands.h>
21 #include <miniupnpc/upnperrors.h>
22 #endif
23
24 using namespace std;
25 using namespace boost;
26
27 static const int MAX_OUTBOUND_CONNECTIONS = 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 WIN32
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 WIN32
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 WIN32
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 WIN32
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 WIN32
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 std::map<unsigned int, int64> CNode::setBanned;
731 CCriticalSection CNode::cs_setBanned;
732
733 void CNode::ClearBanned()
734 {
735     setBanned.clear();
736 }
737
738 bool CNode::IsBanned(unsigned int ip)
739 {
740     bool fResult = false;
741     CRITICAL_BLOCK(cs_setBanned)
742     {
743         std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
744         if (i != setBanned.end())
745         {
746             int64 t = (*i).second;
747             if (GetTime() < t)
748                 fResult = true;
749         }
750     }
751     return fResult;
752 }
753
754 bool CNode::Misbehaving(int howmuch)
755 {
756     if (addr.IsLocal())
757     {
758         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
759         return false;
760     }
761
762     nMisbehavior += howmuch;
763     if (nMisbehavior >= GetArg("-banscore", 100))
764     {
765         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
766         CRITICAL_BLOCK(cs_setBanned)
767             if (setBanned[addr.ip] < banTime)
768                 setBanned[addr.ip] = banTime;
769         CloseSocketDisconnect();
770         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
771         return true;
772     }
773     return false;
774 }
775
776
777
778
779
780
781
782
783
784
785
786
787 void ThreadSocketHandler(void* parg)
788 {
789     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
790     try
791     {
792         vnThreadsRunning[0]++;
793         ThreadSocketHandler2(parg);
794         vnThreadsRunning[0]--;
795     }
796     catch (std::exception& e) {
797         vnThreadsRunning[0]--;
798         PrintException(&e, "ThreadSocketHandler()");
799     } catch (...) {
800         vnThreadsRunning[0]--;
801         throw; // support pthread_cancel()
802     }
803     printf("ThreadSocketHandler exiting\n");
804 }
805
806 void ThreadSocketHandler2(void* parg)
807 {
808     printf("ThreadSocketHandler started\n");
809     list<CNode*> vNodesDisconnected;
810     int nPrevNodeCount = 0;
811
812     loop
813     {
814         //
815         // Disconnect nodes
816         //
817         CRITICAL_BLOCK(cs_vNodes)
818         {
819             // Disconnect unused nodes
820             vector<CNode*> vNodesCopy = vNodes;
821             BOOST_FOREACH(CNode* pnode, vNodesCopy)
822             {
823                 if (pnode->fDisconnect ||
824                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
825                 {
826                     // remove from vNodes
827                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
828
829                     // close socket and cleanup
830                     pnode->CloseSocketDisconnect();
831                     pnode->Cleanup();
832
833                     // hold in disconnected pool until all refs are released
834                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
835                     if (pnode->fNetworkNode || pnode->fInbound)
836                         pnode->Release();
837                     vNodesDisconnected.push_back(pnode);
838                 }
839             }
840
841             // Delete disconnected nodes
842             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
843             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
844             {
845                 // wait until threads are done using it
846                 if (pnode->GetRefCount() <= 0)
847                 {
848                     bool fDelete = false;
849                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
850                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
851                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
852                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
853                         fDelete = true;
854                     if (fDelete)
855                     {
856                         vNodesDisconnected.remove(pnode);
857                         delete pnode;
858                     }
859                 }
860             }
861         }
862         if (vNodes.size() != nPrevNodeCount)
863         {
864             nPrevNodeCount = vNodes.size();
865             MainFrameRepaint();
866         }
867
868
869         //
870         // Find which sockets have data to receive
871         //
872         struct timeval timeout;
873         timeout.tv_sec  = 0;
874         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
875
876         fd_set fdsetRecv;
877         fd_set fdsetSend;
878         fd_set fdsetError;
879         FD_ZERO(&fdsetRecv);
880         FD_ZERO(&fdsetSend);
881         FD_ZERO(&fdsetError);
882         SOCKET hSocketMax = 0;
883
884         if(hListenSocket != INVALID_SOCKET)
885             FD_SET(hListenSocket, &fdsetRecv);
886         hSocketMax = max(hSocketMax, hListenSocket);
887         CRITICAL_BLOCK(cs_vNodes)
888         {
889             BOOST_FOREACH(CNode* pnode, vNodes)
890             {
891                 if (pnode->hSocket == INVALID_SOCKET)
892                     continue;
893                 FD_SET(pnode->hSocket, &fdsetRecv);
894                 FD_SET(pnode->hSocket, &fdsetError);
895                 hSocketMax = max(hSocketMax, pnode->hSocket);
896                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
897                     if (!pnode->vSend.empty())
898                         FD_SET(pnode->hSocket, &fdsetSend);
899             }
900         }
901
902         vnThreadsRunning[0]--;
903         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
904         vnThreadsRunning[0]++;
905         if (fShutdown)
906             return;
907         if (nSelect == SOCKET_ERROR)
908         {
909             int nErr = WSAGetLastError();
910             if (hSocketMax > -1)
911             {
912                 printf("socket select error %d\n", nErr);
913                 for (int i = 0; i <= hSocketMax; i++)
914                     FD_SET(i, &fdsetRecv);
915             }
916             FD_ZERO(&fdsetSend);
917             FD_ZERO(&fdsetError);
918             Sleep(timeout.tv_usec/1000);
919         }
920
921
922         //
923         // Accept new connections
924         //
925         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
926         {
927             struct sockaddr_in sockaddr;
928             socklen_t len = sizeof(sockaddr);
929             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
930             CAddress addr(sockaddr);
931             int nInbound = 0;
932
933             CRITICAL_BLOCK(cs_vNodes)
934                 BOOST_FOREACH(CNode* pnode, vNodes)
935                 if (pnode->fInbound)
936                     nInbound++;
937             if (hSocket == INVALID_SOCKET)
938             {
939                 if (WSAGetLastError() != WSAEWOULDBLOCK)
940                     printf("socket error accept failed: %d\n", WSAGetLastError());
941             }
942             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
943             {
944                 closesocket(hSocket);
945             }
946             else if (CNode::IsBanned(addr.ip))
947             {
948                 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
949                 closesocket(hSocket);
950             }
951             else
952             {
953                 printf("accepted connection %s\n", addr.ToString().c_str());
954                 CNode* pnode = new CNode(hSocket, addr, true);
955                 pnode->AddRef();
956                 CRITICAL_BLOCK(cs_vNodes)
957                     vNodes.push_back(pnode);
958             }
959         }
960
961
962         //
963         // Service each socket
964         //
965         vector<CNode*> vNodesCopy;
966         CRITICAL_BLOCK(cs_vNodes)
967         {
968             vNodesCopy = vNodes;
969             BOOST_FOREACH(CNode* pnode, vNodesCopy)
970                 pnode->AddRef();
971         }
972         BOOST_FOREACH(CNode* pnode, vNodesCopy)
973         {
974             if (fShutdown)
975                 return;
976
977             //
978             // Receive
979             //
980             if (pnode->hSocket == INVALID_SOCKET)
981                 continue;
982             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
983             {
984                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
985                 {
986                     CDataStream& vRecv = pnode->vRecv;
987                     unsigned int nPos = vRecv.size();
988
989                     if (nPos > ReceiveBufferSize()) {
990                         if (!pnode->fDisconnect)
991                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
992                         pnode->CloseSocketDisconnect();
993                     }
994                     else {
995                         // typical socket buffer is 8K-64K
996                         char pchBuf[0x10000];
997                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
998                         if (nBytes > 0)
999                         {
1000                             vRecv.resize(nPos + nBytes);
1001                             memcpy(&vRecv[nPos], pchBuf, nBytes);
1002                             pnode->nLastRecv = GetTime();
1003                         }
1004                         else if (nBytes == 0)
1005                         {
1006                             // socket closed gracefully
1007                             if (!pnode->fDisconnect)
1008                                 printf("socket closed\n");
1009                             pnode->CloseSocketDisconnect();
1010                         }
1011                         else if (nBytes < 0)
1012                         {
1013                             // error
1014                             int nErr = WSAGetLastError();
1015                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1016                             {
1017                                 if (!pnode->fDisconnect)
1018                                     printf("socket recv error %d\n", nErr);
1019                                 pnode->CloseSocketDisconnect();
1020                             }
1021                         }
1022                     }
1023                 }
1024             }
1025
1026             //
1027             // Send
1028             //
1029             if (pnode->hSocket == INVALID_SOCKET)
1030                 continue;
1031             if (FD_ISSET(pnode->hSocket, &fdsetSend))
1032             {
1033                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1034                 {
1035                     CDataStream& vSend = pnode->vSend;
1036                     if (!vSend.empty())
1037                     {
1038                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
1039                         if (nBytes > 0)
1040                         {
1041                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1042                             pnode->nLastSend = GetTime();
1043                         }
1044                         else if (nBytes < 0)
1045                         {
1046                             // error
1047                             int nErr = WSAGetLastError();
1048                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1049                             {
1050                                 printf("socket send error %d\n", nErr);
1051                                 pnode->CloseSocketDisconnect();
1052                             }
1053                         }
1054                         if (vSend.size() > SendBufferSize()) {
1055                             if (!pnode->fDisconnect)
1056                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1057                             pnode->CloseSocketDisconnect();
1058                         }
1059                     }
1060                 }
1061             }
1062
1063             //
1064             // Inactivity checking
1065             //
1066             if (pnode->vSend.empty())
1067                 pnode->nLastSendEmpty = GetTime();
1068             if (GetTime() - pnode->nTimeConnected > 60)
1069             {
1070                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1071                 {
1072                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1073                     pnode->fDisconnect = true;
1074                 }
1075                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1076                 {
1077                     printf("socket not sending\n");
1078                     pnode->fDisconnect = true;
1079                 }
1080                 else if (GetTime() - pnode->nLastRecv > 90*60)
1081                 {
1082                     printf("socket inactivity timeout\n");
1083                     pnode->fDisconnect = true;
1084                 }
1085             }
1086         }
1087         CRITICAL_BLOCK(cs_vNodes)
1088         {
1089             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1090                 pnode->Release();
1091         }
1092
1093         Sleep(10);
1094     }
1095 }
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 #ifdef USE_UPNP
1106 void ThreadMapPort(void* parg)
1107 {
1108     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1109     try
1110     {
1111         vnThreadsRunning[5]++;
1112         ThreadMapPort2(parg);
1113         vnThreadsRunning[5]--;
1114     }
1115     catch (std::exception& e) {
1116         vnThreadsRunning[5]--;
1117         PrintException(&e, "ThreadMapPort()");
1118     } catch (...) {
1119         vnThreadsRunning[5]--;
1120         PrintException(NULL, "ThreadMapPort()");
1121     }
1122     printf("ThreadMapPort exiting\n");
1123 }
1124
1125 void ThreadMapPort2(void* parg)
1126 {
1127     printf("ThreadMapPort started\n");
1128
1129     char port[6];
1130     sprintf(port, "%d", GetListenPort());
1131
1132     const char * rootdescurl = 0;
1133     const char * multicastif = 0;
1134     const char * minissdpdpath = 0;
1135     int error = 0;
1136     struct UPNPDev * devlist = 0;
1137     char lanaddr[64];
1138
1139     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1140
1141     struct UPNPUrls urls;
1142     struct IGDdatas data;
1143     int r;
1144
1145     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1146     if (r == 1)
1147     {
1148         char intClient[16];
1149         char intPort[6];
1150         string strDesc = "Bitcoin " + FormatFullVersion();
1151         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1152                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1153
1154         if(r!=UPNPCOMMAND_SUCCESS)
1155             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1156                 port, port, lanaddr, r, strupnperror(r));
1157         else
1158             printf("UPnP Port Mapping successful.\n");
1159         loop {
1160             if (fShutdown || !fUseUPnP)
1161             {
1162                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1163                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1164                 freeUPNPDevlist(devlist); devlist = 0;
1165                 FreeUPNPUrls(&urls);
1166                 return;
1167             }
1168             Sleep(2000);
1169         }
1170     } else {
1171         printf("No valid UPnP IGDs found\n");
1172         freeUPNPDevlist(devlist); devlist = 0;
1173         if (r != 0)
1174             FreeUPNPUrls(&urls);
1175         loop {
1176             if (fShutdown || !fUseUPnP)
1177                 return;
1178             Sleep(2000);
1179         }
1180     }
1181 }
1182
1183 void MapPort(bool fMapPort)
1184 {
1185     if (fUseUPnP != fMapPort)
1186     {
1187         fUseUPnP = fMapPort;
1188         WriteSetting("fUseUPnP", fUseUPnP);
1189     }
1190     if (fUseUPnP && vnThreadsRunning[5] < 1)
1191     {
1192         if (!CreateThread(ThreadMapPort, NULL))
1193             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1194     }
1195 }
1196 #else
1197 void MapPort(bool /* unused fMapPort */)
1198 {
1199     // Intentionally left blank.
1200 }
1201 #endif
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212 static const char *strDNSSeed[] = {
1213     "bitseed.xf2.org",
1214     "dnsseed.bluematt.me",
1215 };
1216
1217 void ThreadDNSAddressSeed(void* parg)
1218 {
1219     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1220     try
1221     {
1222         vnThreadsRunning[6]++;
1223         ThreadDNSAddressSeed2(parg);
1224         vnThreadsRunning[6]--;
1225     }
1226     catch (std::exception& e) {
1227         vnThreadsRunning[6]--;
1228         PrintException(&e, "ThreadDNSAddressSeed()");
1229     } catch (...) {
1230         vnThreadsRunning[6]--;
1231         throw; // support pthread_cancel()
1232     }
1233     printf("ThreadDNSAddressSeed exiting\n");
1234 }
1235
1236 void ThreadDNSAddressSeed2(void* parg)
1237 {
1238     printf("ThreadDNSAddressSeed started\n");
1239     int found = 0;
1240
1241     if (!fTestNet)
1242     {
1243         printf("Loading addresses from DNS seeds (could take a while)\n");
1244         CAddrDB addrDB;
1245         addrDB.TxnBegin();
1246
1247         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1248             vector<CAddress> vaddr;
1249             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1250             {
1251                 BOOST_FOREACH (CAddress& addr, vaddr)
1252                 {
1253                     if (addr.GetByte(3) != 127)
1254                     {
1255                         addr.nTime = 0;
1256                         AddAddress(addr, 0, &addrDB);
1257                         found++;
1258                     }
1259                 }
1260             }
1261         }
1262
1263         addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1264     }
1265
1266     printf("%d addresses found from DNS seeds\n", found);
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280 unsigned int pnSeed[] =
1281 {
1282     0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1283     0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1284     0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1285     0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1286     0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1287     0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1288     0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1289     0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1290     0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1291     0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1292     0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1293     0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1294     0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1295     0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1296     0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1297     0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1298     0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1299     0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1300     0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1301     0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1302     0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1303     0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1304     0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1305     0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1306     0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1307     0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1308     0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1309     0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1310     0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1311     0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1312     0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1313     0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1314     0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1315     0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1316     0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1317     0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1318     0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1319     0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1320     0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1321     0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1322     0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1323     0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1324     0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1325     0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1326     0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1327     0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1328     0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1329     0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1330     0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1331     0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1332     0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1333     0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1334     0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1335     0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1336     0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1337     0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1338     0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1339     0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1340     0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1341     0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1342     0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1343     0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1344     0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1345     0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1346 };
1347
1348
1349
1350 void ThreadOpenConnections(void* parg)
1351 {
1352     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1353     try
1354     {
1355         vnThreadsRunning[1]++;
1356         ThreadOpenConnections2(parg);
1357         vnThreadsRunning[1]--;
1358     }
1359     catch (std::exception& e) {
1360         vnThreadsRunning[1]--;
1361         PrintException(&e, "ThreadOpenConnections()");
1362     } catch (...) {
1363         vnThreadsRunning[1]--;
1364         PrintException(NULL, "ThreadOpenConnections()");
1365     }
1366     printf("ThreadOpenConnections exiting\n");
1367 }
1368
1369 void ThreadOpenConnections2(void* parg)
1370 {
1371     printf("ThreadOpenConnections started\n");
1372
1373     // Connect to specific addresses
1374     if (mapArgs.count("-connect"))
1375     {
1376         for (int64 nLoop = 0;; nLoop++)
1377         {
1378             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1379             {
1380                 CAddress addr(strAddr, fAllowDNS);
1381                 if (addr.IsValid())
1382                     OpenNetworkConnection(addr);
1383                 for (int i = 0; i < 10 && i < nLoop; i++)
1384                 {
1385                     Sleep(500);
1386                     if (fShutdown)
1387                         return;
1388                 }
1389             }
1390         }
1391     }
1392
1393     // Connect to manually added nodes first
1394     if (mapArgs.count("-addnode"))
1395     {
1396         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1397         {
1398             CAddress addr(strAddr, fAllowDNS);
1399             if (addr.IsValid())
1400             {
1401                 OpenNetworkConnection(addr);
1402                 Sleep(500);
1403                 if (fShutdown)
1404                     return;
1405             }
1406         }
1407     }
1408
1409     // Initiate network connections
1410     int64 nStart = GetTime();
1411     loop
1412     {
1413         // Limit outbound connections
1414         vnThreadsRunning[1]--;
1415         Sleep(500);
1416         loop
1417         {
1418             int nOutbound = 0;
1419             CRITICAL_BLOCK(cs_vNodes)
1420                 BOOST_FOREACH(CNode* pnode, vNodes)
1421                     if (!pnode->fInbound)
1422                         nOutbound++;
1423             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1424             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1425             if (nOutbound < nMaxOutboundConnections)
1426                 break;
1427             Sleep(2000);
1428             if (fShutdown)
1429                 return;
1430         }
1431         vnThreadsRunning[1]++;
1432         if (fShutdown)
1433             return;
1434
1435         CRITICAL_BLOCK(cs_mapAddresses)
1436         {
1437             // Add seed nodes if IRC isn't working
1438             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1439             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1440             {
1441                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1442                 {
1443                     // It'll only connect to one or two seed nodes because once it connects,
1444                     // it'll get a pile of addresses with newer timestamps.
1445                     // Seed nodes are given a random 'last seen time' of between one and two
1446                     // weeks ago.
1447                     const int64 nOneWeek = 7*24*60*60;
1448                     CAddress addr;
1449                     addr.ip = pnSeed[i];
1450                     addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1451                     AddAddress(addr);
1452                 }
1453             }
1454         }
1455
1456
1457         //
1458         // Choose an address to connect to based on most recently seen
1459         //
1460         CAddress addrConnect;
1461         int64 nBest = INT64_MIN;
1462
1463         // Only connect to one address per a.b.?.? range.
1464         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1465         set<unsigned int> setConnected;
1466         CRITICAL_BLOCK(cs_vNodes)
1467             BOOST_FOREACH(CNode* pnode, vNodes)
1468                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1469
1470         int64 nANow = GetAdjustedTime();
1471
1472         CRITICAL_BLOCK(cs_mapAddresses)
1473         {
1474             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1475             {
1476                 const CAddress& addr = item.second;
1477                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1478                     continue;
1479                 int64 nSinceLastSeen = nANow - addr.nTime;
1480                 int64 nSinceLastTry = nANow - addr.nLastTry;
1481
1482                 // Randomize the order in a deterministic way, putting the standard port first
1483                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1484                 if (addr.port != htons(GetDefaultPort()))
1485                     nRandomizer += 2 * 60 * 60;
1486
1487                 // Last seen  Base retry frequency
1488                 //   <1 hour   10 min
1489                 //    1 hour    1 hour
1490                 //    4 hours   2 hours
1491                 //   24 hours   5 hours
1492                 //   48 hours   7 hours
1493                 //    7 days   13 hours
1494                 //   30 days   27 hours
1495                 //   90 days   46 hours
1496                 //  365 days   93 hours
1497                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1498
1499                 // Fast reconnect for one hour after last seen
1500                 if (nSinceLastSeen < 60 * 60)
1501                     nDelay = 10 * 60;
1502
1503                 // Limit retry frequency
1504                 if (nSinceLastTry < nDelay)
1505                     continue;
1506
1507                 // If we have IRC, we'll be notified when they first come online,
1508                 // and again every 24 hours by the refresh broadcast.
1509                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1510                     continue;
1511
1512                 // Only try the old stuff if we don't have enough connections
1513                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1514                     continue;
1515
1516                 // If multiple addresses are ready, prioritize by time since
1517                 // last seen and time since last tried.
1518                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1519                 if (nScore > nBest)
1520                 {
1521                     nBest = nScore;
1522                     addrConnect = addr;
1523                 }
1524             }
1525         }
1526
1527         if (addrConnect.IsValid())
1528             OpenNetworkConnection(addrConnect);
1529     }
1530 }
1531
1532 bool OpenNetworkConnection(const CAddress& addrConnect)
1533 {
1534     //
1535     // Initiate outbound network connection
1536     //
1537     if (fShutdown)
1538         return false;
1539     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1540         FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1541         return false;
1542
1543     vnThreadsRunning[1]--;
1544     CNode* pnode = ConnectNode(addrConnect);
1545     vnThreadsRunning[1]++;
1546     if (fShutdown)
1547         return false;
1548     if (!pnode)
1549         return false;
1550     pnode->fNetworkNode = true;
1551
1552     return true;
1553 }
1554
1555
1556
1557
1558
1559
1560
1561
1562 void ThreadMessageHandler(void* parg)
1563 {
1564     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1565     try
1566     {
1567         vnThreadsRunning[2]++;
1568         ThreadMessageHandler2(parg);
1569         vnThreadsRunning[2]--;
1570     }
1571     catch (std::exception& e) {
1572         vnThreadsRunning[2]--;
1573         PrintException(&e, "ThreadMessageHandler()");
1574     } catch (...) {
1575         vnThreadsRunning[2]--;
1576         PrintException(NULL, "ThreadMessageHandler()");
1577     }
1578     printf("ThreadMessageHandler exiting\n");
1579 }
1580
1581 void ThreadMessageHandler2(void* parg)
1582 {
1583     printf("ThreadMessageHandler started\n");
1584     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1585     while (!fShutdown)
1586     {
1587         vector<CNode*> vNodesCopy;
1588         CRITICAL_BLOCK(cs_vNodes)
1589         {
1590             vNodesCopy = vNodes;
1591             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1592                 pnode->AddRef();
1593         }
1594
1595         // Poll the connected nodes for messages
1596         CNode* pnodeTrickle = NULL;
1597         if (!vNodesCopy.empty())
1598             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1599         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1600         {
1601             // Receive messages
1602             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1603                 ProcessMessages(pnode);
1604             if (fShutdown)
1605                 return;
1606
1607             // Send messages
1608             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1609                 SendMessages(pnode, pnode == pnodeTrickle);
1610             if (fShutdown)
1611                 return;
1612         }
1613
1614         CRITICAL_BLOCK(cs_vNodes)
1615         {
1616             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1617                 pnode->Release();
1618         }
1619
1620         // Wait and allow messages to bunch up.
1621         // Reduce vnThreadsRunning so StopNode has permission to exit while
1622         // we're sleeping, but we must always check fShutdown after doing this.
1623         vnThreadsRunning[2]--;
1624         Sleep(100);
1625         if (fRequestShutdown)
1626             Shutdown(NULL);
1627         vnThreadsRunning[2]++;
1628         if (fShutdown)
1629             return;
1630     }
1631 }
1632
1633
1634
1635
1636
1637
1638 bool BindListenPort(string& strError)
1639 {
1640     strError = "";
1641     int nOne = 1;
1642     addrLocalHost.port = htons(GetListenPort());
1643
1644 #ifdef WIN32
1645     // Initialize Windows Sockets
1646     WSADATA wsadata;
1647     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1648     if (ret != NO_ERROR)
1649     {
1650         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1651         printf("%s\n", strError.c_str());
1652         return false;
1653     }
1654 #endif
1655
1656     // Create socket for listening for incoming connections
1657     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1658     if (hListenSocket == INVALID_SOCKET)
1659     {
1660         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1661         printf("%s\n", strError.c_str());
1662         return false;
1663     }
1664
1665 #ifdef SO_NOSIGPIPE
1666     // Different way of disabling SIGPIPE on BSD
1667     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1668 #endif
1669
1670 #ifndef WIN32
1671     // Allow binding if the port is still in TIME_WAIT state after
1672     // the program was closed and restarted.  Not an issue on windows.
1673     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1674 #endif
1675
1676 #ifdef WIN32
1677     // Set to nonblocking, incoming connections will also inherit this
1678     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1679 #else
1680     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1681 #endif
1682     {
1683         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1684         printf("%s\n", strError.c_str());
1685         return false;
1686     }
1687
1688     // The sockaddr_in structure specifies the address family,
1689     // IP address, and port for the socket that is being bound
1690     struct sockaddr_in sockaddr;
1691     memset(&sockaddr, 0, sizeof(sockaddr));
1692     sockaddr.sin_family = AF_INET;
1693     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1694     sockaddr.sin_port = htons(GetListenPort());
1695     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1696     {
1697         int nErr = WSAGetLastError();
1698         if (nErr == WSAEADDRINUSE)
1699             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1700         else
1701             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1702         printf("%s\n", strError.c_str());
1703         return false;
1704     }
1705     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1706
1707     // Listen for incoming connections
1708     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1709     {
1710         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1711         printf("%s\n", strError.c_str());
1712         return false;
1713     }
1714
1715     return true;
1716 }
1717
1718 void StartNode(void* parg)
1719 {
1720     if (pnodeLocalHost == NULL)
1721         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1722
1723 #ifdef WIN32
1724     // Get local host ip
1725     char pszHostName[1000] = "";
1726     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1727     {
1728         vector<CAddress> vaddr;
1729         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1730             BOOST_FOREACH (const CAddress &addr, vaddr)
1731                 if (addr.GetByte(3) != 127)
1732                 {
1733                     addrLocalHost = addr;
1734                     break;
1735                 }
1736     }
1737 #else
1738     // Get local host ip
1739     struct ifaddrs* myaddrs;
1740     if (getifaddrs(&myaddrs) == 0)
1741     {
1742         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1743         {
1744             if (ifa->ifa_addr == NULL) continue;
1745             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1746             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1747             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1748             char pszIP[100];
1749             if (ifa->ifa_addr->sa_family == AF_INET)
1750             {
1751                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1752                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1753                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1754
1755                 // Take the first IP that isn't loopback 127.x.x.x
1756                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1757                 if (addr.IsValid() && addr.GetByte(3) != 127)
1758                 {
1759                     addrLocalHost = addr;
1760                     break;
1761                 }
1762             }
1763             else if (ifa->ifa_addr->sa_family == AF_INET6)
1764             {
1765                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1766                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1767                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1768             }
1769         }
1770         freeifaddrs(myaddrs);
1771     }
1772 #endif
1773     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1774
1775     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1776     {
1777         // Proxies can't take incoming connections
1778         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1779         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1780     }
1781     else
1782     {
1783         CreateThread(ThreadGetMyExternalIP, NULL);
1784     }
1785
1786     //
1787     // Start threads
1788     //
1789
1790     if (GetBoolArg("-nodnsseed"))
1791         printf("DNS seeding disabled\n");
1792     else
1793         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1794             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1795
1796     // Map ports with UPnP
1797     if (fHaveUPnP)
1798         MapPort(fUseUPnP);
1799
1800     // Get addresses from IRC and advertise ours
1801     if (!CreateThread(ThreadIRCSeed, NULL))
1802         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1803
1804     // Send and receive from sockets, accept connections
1805     if (!CreateThread(ThreadSocketHandler, NULL))
1806         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1807
1808     // Initiate outbound connections
1809     if (!CreateThread(ThreadOpenConnections, NULL))
1810         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1811
1812     // Process messages
1813     if (!CreateThread(ThreadMessageHandler, NULL))
1814         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1815
1816     // Generate coins in the background
1817     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1818 }
1819
1820 bool StopNode()
1821 {
1822     printf("StopNode()\n");
1823     fShutdown = true;
1824     nTransactionsUpdated++;
1825     int64 nStart = GetTime();
1826     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1827 #ifdef USE_UPNP
1828         || vnThreadsRunning[5] > 0
1829 #endif
1830     )
1831     {
1832         if (GetTime() - nStart > 20)
1833             break;
1834         Sleep(20);
1835     }
1836     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1837     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1838     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1839     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1840     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1841     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1842     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1843     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1844         Sleep(20);
1845     Sleep(50);
1846
1847     return true;
1848 }
1849
1850 class CNetCleanup
1851 {
1852 public:
1853     CNetCleanup()
1854     {
1855     }
1856     ~CNetCleanup()
1857     {
1858         // Close sockets
1859         BOOST_FOREACH(CNode* pnode, vNodes)
1860             if (pnode->hSocket != INVALID_SOCKET)
1861                 closesocket(pnode->hSocket);
1862         if (hListenSocket != INVALID_SOCKET)
1863             if (closesocket(hListenSocket) == SOCKET_ERROR)
1864                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1865
1866 #ifdef WIN32
1867         // Shutdown Windows Sockets
1868         WSACleanup();
1869 #endif
1870     }
1871 }
1872 instance_of_cnetcleanup;