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