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