Add sipa's new dnsseed.
[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     struct UPNPDev * devlist = 0;
1136     char lanaddr[64];
1137
1138 #ifndef UPNPDISCOVER_SUCCESS
1139     /* miniupnpc 1.5 */
1140     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1141 #else
1142     /* miniupnpc 1.6 */
1143     int error = 0;
1144     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1145 #endif
1146
1147     struct UPNPUrls urls;
1148     struct IGDdatas data;
1149     int r;
1150
1151     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1152     if (r == 1)
1153     {
1154         char intClient[16];
1155         char intPort[6];
1156         string strDesc = "Bitcoin " + FormatFullVersion();
1157 #ifndef UPNPDISCOVER_SUCCESS
1158     /* miniupnpc 1.5 */
1159         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1160                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1161 #else
1162     /* miniupnpc 1.6 */
1163         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1164                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1165 #endif
1166
1167         if(r!=UPNPCOMMAND_SUCCESS)
1168             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1169                 port, port, lanaddr, r, strupnperror(r));
1170         else
1171             printf("UPnP Port Mapping successful.\n");
1172         loop {
1173             if (fShutdown || !fUseUPnP)
1174             {
1175                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1176                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1177                 freeUPNPDevlist(devlist); devlist = 0;
1178                 FreeUPNPUrls(&urls);
1179                 return;
1180             }
1181             Sleep(2000);
1182         }
1183     } else {
1184         printf("No valid UPnP IGDs found\n");
1185         freeUPNPDevlist(devlist); devlist = 0;
1186         if (r != 0)
1187             FreeUPNPUrls(&urls);
1188         loop {
1189             if (fShutdown || !fUseUPnP)
1190                 return;
1191             Sleep(2000);
1192         }
1193     }
1194 }
1195
1196 void MapPort(bool fMapPort)
1197 {
1198     if (fUseUPnP != fMapPort)
1199     {
1200         fUseUPnP = fMapPort;
1201         WriteSetting("fUseUPnP", fUseUPnP);
1202     }
1203     if (fUseUPnP && vnThreadsRunning[5] < 1)
1204     {
1205         if (!CreateThread(ThreadMapPort, NULL))
1206             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1207     }
1208 }
1209 #else
1210 void MapPort(bool /* unused fMapPort */)
1211 {
1212     // Intentionally left blank.
1213 }
1214 #endif
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 static const char *strDNSSeed[] = {
1226     "bitseed.xf2.org",
1227     "dnsseed.bluematt.me",
1228     "seed.bitcoin.sipa.be",
1229 };
1230
1231 void ThreadDNSAddressSeed(void* parg)
1232 {
1233     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1234     try
1235     {
1236         vnThreadsRunning[6]++;
1237         ThreadDNSAddressSeed2(parg);
1238         vnThreadsRunning[6]--;
1239     }
1240     catch (std::exception& e) {
1241         vnThreadsRunning[6]--;
1242         PrintException(&e, "ThreadDNSAddressSeed()");
1243     } catch (...) {
1244         vnThreadsRunning[6]--;
1245         throw; // support pthread_cancel()
1246     }
1247     printf("ThreadDNSAddressSeed exiting\n");
1248 }
1249
1250 void ThreadDNSAddressSeed2(void* parg)
1251 {
1252     printf("ThreadDNSAddressSeed started\n");
1253     int found = 0;
1254
1255     if (!fTestNet)
1256     {
1257         printf("Loading addresses from DNS seeds (could take a while)\n");
1258         CAddrDB addrDB;
1259         addrDB.TxnBegin();
1260
1261         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1262             vector<CAddress> vaddr;
1263             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1264             {
1265                 BOOST_FOREACH (CAddress& addr, vaddr)
1266                 {
1267                     if (addr.GetByte(3) != 127)
1268                     {
1269                         addr.nTime = 0;
1270                         AddAddress(addr, 0, &addrDB);
1271                         found++;
1272                     }
1273                 }
1274             }
1275         }
1276
1277         addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1278     }
1279
1280     printf("%d addresses found from DNS seeds\n", found);
1281 }
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 unsigned int pnSeed[] =
1295 {
1296     0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1297     0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1298     0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1299     0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1300     0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1301     0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1302     0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1303     0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1304     0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1305     0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1306     0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1307     0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1308     0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1309     0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1310     0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1311     0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1312     0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1313     0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1314     0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1315     0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1316     0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1317     0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1318     0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1319     0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1320     0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1321     0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1322     0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1323     0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1324     0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1325     0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1326     0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1327     0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1328     0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1329     0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1330     0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1331     0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1332     0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1333     0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1334     0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1335     0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1336     0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1337     0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1338     0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1339     0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1340     0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1341     0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1342     0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1343     0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1344     0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1345     0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1346     0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1347     0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1348     0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1349     0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1350     0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1351     0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1352     0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1353     0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1354     0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1355     0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1356     0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1357     0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1358     0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1359     0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1360 };
1361
1362
1363
1364 void ThreadOpenConnections(void* parg)
1365 {
1366     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1367     try
1368     {
1369         vnThreadsRunning[1]++;
1370         ThreadOpenConnections2(parg);
1371         vnThreadsRunning[1]--;
1372     }
1373     catch (std::exception& e) {
1374         vnThreadsRunning[1]--;
1375         PrintException(&e, "ThreadOpenConnections()");
1376     } catch (...) {
1377         vnThreadsRunning[1]--;
1378         PrintException(NULL, "ThreadOpenConnections()");
1379     }
1380     printf("ThreadOpenConnections exiting\n");
1381 }
1382
1383 void ThreadOpenConnections2(void* parg)
1384 {
1385     printf("ThreadOpenConnections started\n");
1386
1387     // Connect to specific addresses
1388     if (mapArgs.count("-connect"))
1389     {
1390         for (int64 nLoop = 0;; nLoop++)
1391         {
1392             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1393             {
1394                 CAddress addr(strAddr, fAllowDNS);
1395                 if (addr.IsValid())
1396                     OpenNetworkConnection(addr);
1397                 for (int i = 0; i < 10 && i < nLoop; i++)
1398                 {
1399                     Sleep(500);
1400                     if (fShutdown)
1401                         return;
1402                 }
1403             }
1404         }
1405     }
1406
1407     // Connect to manually added nodes first
1408     if (mapArgs.count("-addnode"))
1409     {
1410         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1411         {
1412             CAddress addr(strAddr, fAllowDNS);
1413             if (addr.IsValid())
1414             {
1415                 OpenNetworkConnection(addr);
1416                 Sleep(500);
1417                 if (fShutdown)
1418                     return;
1419             }
1420         }
1421     }
1422
1423     // Initiate network connections
1424     int64 nStart = GetTime();
1425     loop
1426     {
1427         // Limit outbound connections
1428         vnThreadsRunning[1]--;
1429         Sleep(500);
1430         loop
1431         {
1432             int nOutbound = 0;
1433             CRITICAL_BLOCK(cs_vNodes)
1434                 BOOST_FOREACH(CNode* pnode, vNodes)
1435                     if (!pnode->fInbound)
1436                         nOutbound++;
1437             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1438             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1439             if (nOutbound < nMaxOutboundConnections)
1440                 break;
1441             Sleep(2000);
1442             if (fShutdown)
1443                 return;
1444         }
1445         vnThreadsRunning[1]++;
1446         if (fShutdown)
1447             return;
1448
1449         CRITICAL_BLOCK(cs_mapAddresses)
1450         {
1451             // Add seed nodes if IRC isn't working
1452             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1453             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1454             {
1455                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1456                 {
1457                     // It'll only connect to one or two seed nodes because once it connects,
1458                     // it'll get a pile of addresses with newer timestamps.
1459                     // Seed nodes are given a random 'last seen time' of between one and two
1460                     // weeks ago.
1461                     const int64 nOneWeek = 7*24*60*60;
1462                     CAddress addr;
1463                     addr.ip = pnSeed[i];
1464                     addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1465                     AddAddress(addr);
1466                 }
1467             }
1468         }
1469
1470
1471         //
1472         // Choose an address to connect to based on most recently seen
1473         //
1474         CAddress addrConnect;
1475         int64 nBest = INT64_MIN;
1476
1477         // Only connect to one address per a.b.?.? range.
1478         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1479         set<unsigned int> setConnected;
1480         CRITICAL_BLOCK(cs_vNodes)
1481             BOOST_FOREACH(CNode* pnode, vNodes)
1482                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1483
1484         int64 nANow = GetAdjustedTime();
1485
1486         CRITICAL_BLOCK(cs_mapAddresses)
1487         {
1488             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1489             {
1490                 const CAddress& addr = item.second;
1491                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1492                     continue;
1493                 int64 nSinceLastSeen = nANow - addr.nTime;
1494                 int64 nSinceLastTry = nANow - addr.nLastTry;
1495
1496                 // Randomize the order in a deterministic way, putting the standard port first
1497                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1498                 if (addr.port != htons(GetDefaultPort()))
1499                     nRandomizer += 2 * 60 * 60;
1500
1501                 // Last seen  Base retry frequency
1502                 //   <1 hour   10 min
1503                 //    1 hour    1 hour
1504                 //    4 hours   2 hours
1505                 //   24 hours   5 hours
1506                 //   48 hours   7 hours
1507                 //    7 days   13 hours
1508                 //   30 days   27 hours
1509                 //   90 days   46 hours
1510                 //  365 days   93 hours
1511                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1512
1513                 // Fast reconnect for one hour after last seen
1514                 if (nSinceLastSeen < 60 * 60)
1515                     nDelay = 10 * 60;
1516
1517                 // Limit retry frequency
1518                 if (nSinceLastTry < nDelay)
1519                     continue;
1520
1521                 // If we have IRC, we'll be notified when they first come online,
1522                 // and again every 24 hours by the refresh broadcast.
1523                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1524                     continue;
1525
1526                 // Only try the old stuff if we don't have enough connections
1527                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1528                     continue;
1529
1530                 // If multiple addresses are ready, prioritize by time since
1531                 // last seen and time since last tried.
1532                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1533                 if (nScore > nBest)
1534                 {
1535                     nBest = nScore;
1536                     addrConnect = addr;
1537                 }
1538             }
1539         }
1540
1541         if (addrConnect.IsValid())
1542             OpenNetworkConnection(addrConnect);
1543     }
1544 }
1545
1546 bool OpenNetworkConnection(const CAddress& addrConnect)
1547 {
1548     //
1549     // Initiate outbound network connection
1550     //
1551     if (fShutdown)
1552         return false;
1553     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1554         FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1555         return false;
1556
1557     vnThreadsRunning[1]--;
1558     CNode* pnode = ConnectNode(addrConnect);
1559     vnThreadsRunning[1]++;
1560     if (fShutdown)
1561         return false;
1562     if (!pnode)
1563         return false;
1564     pnode->fNetworkNode = true;
1565
1566     return true;
1567 }
1568
1569
1570
1571
1572
1573
1574
1575
1576 void ThreadMessageHandler(void* parg)
1577 {
1578     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1579     try
1580     {
1581         vnThreadsRunning[2]++;
1582         ThreadMessageHandler2(parg);
1583         vnThreadsRunning[2]--;
1584     }
1585     catch (std::exception& e) {
1586         vnThreadsRunning[2]--;
1587         PrintException(&e, "ThreadMessageHandler()");
1588     } catch (...) {
1589         vnThreadsRunning[2]--;
1590         PrintException(NULL, "ThreadMessageHandler()");
1591     }
1592     printf("ThreadMessageHandler exiting\n");
1593 }
1594
1595 void ThreadMessageHandler2(void* parg)
1596 {
1597     printf("ThreadMessageHandler started\n");
1598     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1599     while (!fShutdown)
1600     {
1601         vector<CNode*> vNodesCopy;
1602         CRITICAL_BLOCK(cs_vNodes)
1603         {
1604             vNodesCopy = vNodes;
1605             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1606                 pnode->AddRef();
1607         }
1608
1609         // Poll the connected nodes for messages
1610         CNode* pnodeTrickle = NULL;
1611         if (!vNodesCopy.empty())
1612             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1613         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1614         {
1615             // Receive messages
1616             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1617                 ProcessMessages(pnode);
1618             if (fShutdown)
1619                 return;
1620
1621             // Send messages
1622             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1623                 SendMessages(pnode, pnode == pnodeTrickle);
1624             if (fShutdown)
1625                 return;
1626         }
1627
1628         CRITICAL_BLOCK(cs_vNodes)
1629         {
1630             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1631                 pnode->Release();
1632         }
1633
1634         // Wait and allow messages to bunch up.
1635         // Reduce vnThreadsRunning so StopNode has permission to exit while
1636         // we're sleeping, but we must always check fShutdown after doing this.
1637         vnThreadsRunning[2]--;
1638         Sleep(100);
1639         if (fRequestShutdown)
1640             Shutdown(NULL);
1641         vnThreadsRunning[2]++;
1642         if (fShutdown)
1643             return;
1644     }
1645 }
1646
1647
1648
1649
1650
1651
1652 bool BindListenPort(string& strError)
1653 {
1654     strError = "";
1655     int nOne = 1;
1656     addrLocalHost.port = htons(GetListenPort());
1657
1658 #ifdef WIN32
1659     // Initialize Windows Sockets
1660     WSADATA wsadata;
1661     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1662     if (ret != NO_ERROR)
1663     {
1664         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1665         printf("%s\n", strError.c_str());
1666         return false;
1667     }
1668 #endif
1669
1670     // Create socket for listening for incoming connections
1671     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1672     if (hListenSocket == INVALID_SOCKET)
1673     {
1674         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1675         printf("%s\n", strError.c_str());
1676         return false;
1677     }
1678
1679 #ifdef SO_NOSIGPIPE
1680     // Different way of disabling SIGPIPE on BSD
1681     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1682 #endif
1683
1684 #ifndef WIN32
1685     // Allow binding if the port is still in TIME_WAIT state after
1686     // the program was closed and restarted.  Not an issue on windows.
1687     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1688 #endif
1689
1690 #ifdef WIN32
1691     // Set to nonblocking, incoming connections will also inherit this
1692     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1693 #else
1694     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1695 #endif
1696     {
1697         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1698         printf("%s\n", strError.c_str());
1699         return false;
1700     }
1701
1702     // The sockaddr_in structure specifies the address family,
1703     // IP address, and port for the socket that is being bound
1704     struct sockaddr_in sockaddr;
1705     memset(&sockaddr, 0, sizeof(sockaddr));
1706     sockaddr.sin_family = AF_INET;
1707     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1708     sockaddr.sin_port = htons(GetListenPort());
1709     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1710     {
1711         int nErr = WSAGetLastError();
1712         if (nErr == WSAEADDRINUSE)
1713             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1714         else
1715             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1716         printf("%s\n", strError.c_str());
1717         return false;
1718     }
1719     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1720
1721     // Listen for incoming connections
1722     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1723     {
1724         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1725         printf("%s\n", strError.c_str());
1726         return false;
1727     }
1728
1729     return true;
1730 }
1731
1732 void StartNode(void* parg)
1733 {
1734     if (pnodeLocalHost == NULL)
1735         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1736
1737 #ifdef WIN32
1738     // Get local host ip
1739     char pszHostName[1000] = "";
1740     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1741     {
1742         vector<CAddress> vaddr;
1743         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1744             BOOST_FOREACH (const CAddress &addr, vaddr)
1745                 if (addr.GetByte(3) != 127)
1746                 {
1747                     addrLocalHost = addr;
1748                     break;
1749                 }
1750     }
1751 #else
1752     // Get local host ip
1753     struct ifaddrs* myaddrs;
1754     if (getifaddrs(&myaddrs) == 0)
1755     {
1756         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1757         {
1758             if (ifa->ifa_addr == NULL) continue;
1759             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1760             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1761             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1762             char pszIP[100];
1763             if (ifa->ifa_addr->sa_family == AF_INET)
1764             {
1765                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1766                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1767                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1768
1769                 // Take the first IP that isn't loopback 127.x.x.x
1770                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1771                 if (addr.IsValid() && addr.GetByte(3) != 127)
1772                 {
1773                     addrLocalHost = addr;
1774                     break;
1775                 }
1776             }
1777             else if (ifa->ifa_addr->sa_family == AF_INET6)
1778             {
1779                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1780                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1781                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1782             }
1783         }
1784         freeifaddrs(myaddrs);
1785     }
1786 #endif
1787     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1788
1789     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1790     {
1791         // Proxies can't take incoming connections
1792         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1793         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1794     }
1795     else
1796     {
1797         CreateThread(ThreadGetMyExternalIP, NULL);
1798     }
1799
1800     //
1801     // Start threads
1802     //
1803
1804     if (GetBoolArg("-nodnsseed"))
1805         printf("DNS seeding disabled\n");
1806     else
1807         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1808             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1809
1810     // Map ports with UPnP
1811     if (fHaveUPnP)
1812         MapPort(fUseUPnP);
1813
1814     // Get addresses from IRC and advertise ours
1815     if (!CreateThread(ThreadIRCSeed, NULL))
1816         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1817
1818     // Send and receive from sockets, accept connections
1819     if (!CreateThread(ThreadSocketHandler, NULL))
1820         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1821
1822     // Initiate outbound connections
1823     if (!CreateThread(ThreadOpenConnections, NULL))
1824         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1825
1826     // Process messages
1827     if (!CreateThread(ThreadMessageHandler, NULL))
1828         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1829
1830     // Generate coins in the background
1831     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1832 }
1833
1834 bool StopNode()
1835 {
1836     printf("StopNode()\n");
1837     fShutdown = true;
1838     nTransactionsUpdated++;
1839     int64 nStart = GetTime();
1840     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1841 #ifdef USE_UPNP
1842         || vnThreadsRunning[5] > 0
1843 #endif
1844     )
1845     {
1846         if (GetTime() - nStart > 20)
1847             break;
1848         Sleep(20);
1849     }
1850     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1851     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1852     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1853     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1854     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1855     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1856     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1857     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1858         Sleep(20);
1859     Sleep(50);
1860
1861     return true;
1862 }
1863
1864 class CNetCleanup
1865 {
1866 public:
1867     CNetCleanup()
1868     {
1869     }
1870     ~CNetCleanup()
1871     {
1872         // Close sockets
1873         BOOST_FOREACH(CNode* pnode, vNodes)
1874             if (pnode->hSocket != INVALID_SOCKET)
1875                 closesocket(pnode->hSocket);
1876         if (hListenSocket != INVALID_SOCKET)
1877             if (closesocket(hListenSocket) == SOCKET_ERROR)
1878                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1879
1880 #ifdef WIN32
1881         // Shutdown Windows Sockets
1882         WSACleanup();
1883 #endif
1884     }
1885 }
1886 instance_of_cnetcleanup;