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