fix an incorrect if-clause in net.cpp
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING 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 __WXMSW__
14 #include <string.h>
15 #else
16 #include <netinet/in.h>
17 #endif
18
19 #ifdef USE_UPNP
20 #include <miniupnpc/miniwget.h>
21 #include <miniupnpc/miniupnpc.h>
22 #include <miniupnpc/upnpcommands.h>
23 #include <miniupnpc/upnperrors.h>
24 #endif
25
26 using namespace std;
27 using namespace boost;
28
29 static const int MAX_OUTBOUND_CONNECTIONS = 8;
30
31 void ThreadMessageHandler2(void* parg);
32 void ThreadSocketHandler2(void* parg);
33 void ThreadOpenConnections2(void* parg);
34 #ifdef USE_UPNP
35 void ThreadMapPort2(void* parg);
36 #endif
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect);
39
40
41
42
43
44 //
45 // Global state variables
46 //
47 bool fClient = false;
48 bool fAllowDNS = false;
49 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
50 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
51 static CNode* pnodeLocalHost = NULL;
52 uint64 nLocalHostNonce = 0;
53 array<int, 10> vnThreadsRunning;
54 static SOCKET hListenSocket = INVALID_SOCKET;
55
56 vector<CNode*> vNodes;
57 CCriticalSection cs_vNodes;
58 map<vector<unsigned char>, CAddress> mapAddresses;
59 CCriticalSection cs_mapAddresses;
60 map<CInv, CDataStream> mapRelay;
61 deque<pair<int64, CInv> > vRelayExpiration;
62 CCriticalSection cs_mapRelay;
63 map<CInv, int64> mapAlreadyAskedFor;
64
65 // Settings
66 int fUseProxy = false;
67 int nConnectTimeout = 5000;
68 CAddress addrProxy("127.0.0.1",9050);
69
70
71
72
73 unsigned short GetListenPort()
74 {
75     return (unsigned short)(GetArg("-port", GetDefaultPort()));
76 }
77
78 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
79 {
80     // Filter out duplicate requests
81     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
82         return;
83     pindexLastGetBlocksBegin = pindexBegin;
84     hashLastGetBlocksEnd = hashEnd;
85
86     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
87 }
88
89
90
91
92
93 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
94 {
95     hSocketRet = INVALID_SOCKET;
96
97     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
98     if (hSocket == INVALID_SOCKET)
99         return false;
100 #ifdef SO_NOSIGPIPE
101     int set = 1;
102     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
103 #endif
104
105     bool fProxy = (fUseProxy && addrConnect.IsRoutable());
106     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
107
108 #ifdef __WXMSW__
109     u_long fNonblock = 1;
110     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
111 #else
112     int fFlags = fcntl(hSocket, F_GETFL, 0);
113     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
114 #endif
115     {
116         closesocket(hSocket);
117         return false;
118     }
119
120
121     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
122     {
123         // WSAEINVAL is here because some legacy version of winsock uses it
124         if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
125         {
126             struct timeval timeout;
127             timeout.tv_sec  = nTimeout / 1000;
128             timeout.tv_usec = (nTimeout % 1000) * 1000;
129
130             fd_set fdset;
131             FD_ZERO(&fdset);
132             FD_SET(hSocket, &fdset);
133             int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
134             if (nRet == 0)
135             {
136                 printf("connection timeout\n");
137                 closesocket(hSocket);
138                 return false;
139             }
140             if (nRet == SOCKET_ERROR)
141             {
142                 printf("select() for connection failed: %i\n",WSAGetLastError());
143                 closesocket(hSocket);
144                 return false;
145             }
146             socklen_t nRetSize = sizeof(nRet);
147 #ifdef __WXMSW__
148             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
149 #else
150             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
151 #endif
152             {
153                 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
154                 closesocket(hSocket);
155                 return false;
156             }
157             if (nRet != 0)
158             {
159                 printf("connect() failed after select(): %s\n",strerror(nRet));
160                 closesocket(hSocket);
161                 return false;
162             }
163         }
164 #ifdef __WXMSW__
165         else if (WSAGetLastError() != WSAEISCONN)
166 #else
167         else
168 #endif
169         {
170             printf("connect() failed: %i\n",WSAGetLastError());
171             closesocket(hSocket);
172             return false;
173         }
174     }
175
176     /*
177     this isn't even strictly necessary
178     CNode::ConnectNode immediately turns the socket back to non-blocking
179     but we'll turn it back to blocking just in case
180     */
181 #ifdef __WXMSW__
182     fNonblock = 0;
183     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
184 #else
185     fFlags = fcntl(hSocket, F_GETFL, 0);
186     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
187 #endif
188     {
189         closesocket(hSocket);
190         return false;
191     }
192
193     if (fProxy)
194     {
195         printf("proxy connecting %s\n", addrConnect.ToString().c_str());
196         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
197         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
198         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
199         char* pszSocks4 = pszSocks4IP;
200         int nSize = sizeof(pszSocks4IP);
201
202         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
203         if (ret != nSize)
204         {
205             closesocket(hSocket);
206             return error("Error sending to proxy");
207         }
208         char pchRet[8];
209         if (recv(hSocket, pchRet, 8, 0) != 8)
210         {
211             closesocket(hSocket);
212             return error("Error reading proxy response");
213         }
214         if (pchRet[1] != 0x5a)
215         {
216             closesocket(hSocket);
217             if (pchRet[1] != 0x5b)
218                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
219             return false;
220         }
221         printf("proxy connected %s\n", addrConnect.ToString().c_str());
222     }
223
224     hSocketRet = hSocket;
225     return true;
226 }
227
228 // portDefault is in host order
229 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
230 {
231     vaddr.clear();
232     if (pszName[0] == 0)
233         return false;
234     int port = portDefault;
235     char psz[256];
236     char *pszHost = psz;
237     strlcpy(psz, pszName, sizeof(psz));
238     if (fAllowPort)
239     {
240         char* pszColon = strrchr(psz+1,':');
241         char *pszPortEnd = NULL;
242         int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
243         if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
244         {
245             if (psz[0] == '[' && pszColon[-1] == ']')
246             {
247                 // Future: enable IPv6 colon-notation inside []
248                 pszHost = psz+1;
249                 pszColon[-1] = 0;
250             }
251             else
252                 pszColon[0] = 0;
253             port = portParsed;
254             if (port < 0 || port > USHRT_MAX)
255                 port = USHRT_MAX;
256         }
257     }
258
259     unsigned int addrIP = inet_addr(pszHost);
260     if (addrIP != INADDR_NONE)
261     {
262         // valid IP address passed
263         vaddr.push_back(CAddress(addrIP, port, nServices));
264         return true;
265     }
266
267     if (!fAllowLookup)
268         return false;
269
270     struct hostent* phostent = gethostbyname(pszHost);
271     if (!phostent)
272         return false;
273
274     if (phostent->h_addrtype != AF_INET)
275         return false;
276
277     char** ppAddr = phostent->h_addr_list;
278     while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
279     {
280         CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
281         if (addr.IsValid())
282             vaddr.push_back(addr);
283         ppAddr++;
284     }
285
286     return (vaddr.size() > 0);
287 }
288
289 // portDefault is in host order
290 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
291 {
292     vector<CAddress> vaddr;
293     bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
294     if (fRet)
295         addr = vaddr[0];
296     return fRet;
297 }
298
299 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
300 {
301     SOCKET hSocket;
302     if (!ConnectSocket(addrConnect, hSocket))
303         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
304
305     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
306
307     string strLine;
308     while (RecvLine(hSocket, strLine))
309     {
310         if (strLine.empty()) // HTTP response is separated from headers by blank line
311         {
312             loop
313             {
314                 if (!RecvLine(hSocket, strLine))
315                 {
316                     closesocket(hSocket);
317                     return false;
318                 }
319                 if (pszKeyword == NULL)
320                     break;
321                 if (strLine.find(pszKeyword) != string::npos)
322                 {
323                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
324                     break;
325                 }
326             }
327             closesocket(hSocket);
328             if (strLine.find("<") != string::npos)
329                 strLine = strLine.substr(0, strLine.find("<"));
330             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
331             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
332                 strLine.resize(strLine.size()-1);
333             CAddress addr(strLine,0,true);
334             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
335             if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
336                 return false;
337             ipRet = addr.ip;
338             return true;
339         }
340     }
341     closesocket(hSocket);
342     return error("GetMyExternalIP() : connection closed");
343 }
344
345 // We now get our external IP from the IRC server first and only use this as a backup
346 bool GetMyExternalIP(unsigned int& ipRet)
347 {
348     CAddress addrConnect;
349     const char* pszGet;
350     const char* pszKeyword;
351
352     if (fUseProxy)
353         return false;
354
355     for (int nLookup = 0; nLookup <= 1; nLookup++)
356     for (int nHost = 1; nHost <= 2; nHost++)
357     {
358         // We should be phasing out our use of sites like these.  If we need
359         // replacements, we should ask for volunteers to put this simple
360         // php file on their webserver that prints the client IP:
361         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
362         if (nHost == 1)
363         {
364             addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
365
366             if (nLookup == 1)
367             {
368                 CAddress addrIP("checkip.dyndns.org", 80, true);
369                 if (addrIP.IsValid())
370                     addrConnect = addrIP;
371             }
372
373             pszGet = "GET / HTTP/1.1\r\n"
374                      "Host: checkip.dyndns.org\r\n"
375                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
376                      "Connection: close\r\n"
377                      "\r\n";
378
379             pszKeyword = "Address:";
380         }
381         else if (nHost == 2)
382         {
383             addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
384
385             if (nLookup == 1)
386             {
387                 CAddress addrIP("www.showmyip.com", 80, true);
388                 if (addrIP.IsValid())
389                     addrConnect = addrIP;
390             }
391
392             pszGet = "GET /simple/ HTTP/1.1\r\n"
393                      "Host: www.showmyip.com\r\n"
394                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
395                      "Connection: close\r\n"
396                      "\r\n";
397
398             pszKeyword = NULL; // Returns just IP address
399         }
400
401         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
402             return true;
403     }
404
405     return false;
406 }
407
408 void ThreadGetMyExternalIP(void* parg)
409 {
410     // Wait for IRC to get it first
411     if (!GetBoolArg("-noirc"))
412     {
413         for (int i = 0; i < 2 * 60; i++)
414         {
415             Sleep(1000);
416             if (fGotExternalIP || fShutdown)
417                 return;
418         }
419     }
420
421     // Fallback in case IRC fails to get it
422     if (GetMyExternalIP(addrLocalHost.ip))
423     {
424         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
425         if (addrLocalHost.IsRoutable())
426         {
427             // If we already connected to a few before we had our IP, go back and addr them.
428             // setAddrKnown automatically filters any duplicate sends.
429             CAddress addr(addrLocalHost);
430             addr.nTime = GetAdjustedTime();
431             CRITICAL_BLOCK(cs_vNodes)
432                 BOOST_FOREACH(CNode* pnode, vNodes)
433                     pnode->PushAddress(addr);
434         }
435     }
436 }
437
438
439
440
441
442 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
443 {
444     if (!addr.IsRoutable())
445         return false;
446     if (addr.ip == addrLocalHost.ip)
447         return false;
448     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
449     bool fUpdated = false;
450     bool fNew = false;
451     CAddress addrFound = addr;
452
453     CRITICAL_BLOCK(cs_mapAddresses)
454     {
455         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
456         if (it == mapAddresses.end())
457         {
458             // New address
459             printf("AddAddress(%s)\n", addr.ToString().c_str());
460             mapAddresses.insert(make_pair(addr.GetKey(), addr));
461             fUpdated = true;
462             fNew = true;
463         }
464         else
465         {
466             addrFound = (*it).second;
467             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
468             {
469                 // Services have been added
470                 addrFound.nServices |= addr.nServices;
471                 fUpdated = true;
472             }
473             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
474             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
475             if (addrFound.nTime < addr.nTime - nUpdateInterval)
476             {
477                 // Periodically update most recently seen time
478                 addrFound.nTime = addr.nTime;
479                 fUpdated = true;
480             }
481         }
482     }
483     // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
484     // CRITICAL_BLOCK:
485     // Thread 1:  begin db transaction (locks inside-db-mutex)
486     //            then AddAddress (locks cs_mapAddresses)
487     // Thread 2:  AddAddress (locks cs_mapAddresses)
488     //             ... then db operation hangs waiting for inside-db-mutex
489     if (fUpdated)
490     {
491         if (pAddrDB)
492             pAddrDB->WriteAddress(addrFound);
493         else
494             CAddrDB().WriteAddress(addrFound);
495     }
496     return fNew;
497 }
498
499 void AddressCurrentlyConnected(const CAddress& addr)
500 {
501     CAddress *paddrFound = NULL;
502
503     CRITICAL_BLOCK(cs_mapAddresses)
504     {
505         // Only if it's been published already
506         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
507         if (it != mapAddresses.end())
508             paddrFound = &(*it).second;
509     }
510
511     if (paddrFound)
512     {
513         int64 nUpdateInterval = 20 * 60;
514         if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
515         {
516             // Periodically update most recently seen time
517             paddrFound->nTime = GetAdjustedTime();
518             CAddrDB addrdb;
519             addrdb.WriteAddress(*paddrFound);
520         }
521     }
522 }
523
524
525
526
527
528 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
529 {
530     // If the dialog might get closed before the reply comes back,
531     // call this in the destructor so it doesn't get called after it's deleted.
532     CRITICAL_BLOCK(cs_vNodes)
533     {
534         BOOST_FOREACH(CNode* pnode, vNodes)
535         {
536             CRITICAL_BLOCK(pnode->cs_mapRequests)
537             {
538                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
539                 {
540                     CRequestTracker& tracker = (*mi).second;
541                     if (tracker.fn == fn && tracker.param1 == param1)
542                         pnode->mapRequests.erase(mi++);
543                     else
544                         mi++;
545                 }
546             }
547         }
548     }
549 }
550
551
552
553
554
555
556
557 //
558 // Subscription methods for the broadcast and subscription system.
559 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
560 //
561 // The subscription system uses a meet-in-the-middle strategy.
562 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
563 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
564 //
565
566 bool AnySubscribed(unsigned int nChannel)
567 {
568     if (pnodeLocalHost->IsSubscribed(nChannel))
569         return true;
570     CRITICAL_BLOCK(cs_vNodes)
571         BOOST_FOREACH(CNode* pnode, vNodes)
572             if (pnode->IsSubscribed(nChannel))
573                 return true;
574     return false;
575 }
576
577 bool CNode::IsSubscribed(unsigned int nChannel)
578 {
579     if (nChannel >= vfSubscribe.size())
580         return false;
581     return vfSubscribe[nChannel];
582 }
583
584 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
585 {
586     if (nChannel >= vfSubscribe.size())
587         return;
588
589     if (!AnySubscribed(nChannel))
590     {
591         // Relay subscribe
592         CRITICAL_BLOCK(cs_vNodes)
593             BOOST_FOREACH(CNode* pnode, vNodes)
594                 if (pnode != this)
595                     pnode->PushMessage("subscribe", nChannel, nHops);
596     }
597
598     vfSubscribe[nChannel] = true;
599 }
600
601 void CNode::CancelSubscribe(unsigned int nChannel)
602 {
603     if (nChannel >= vfSubscribe.size())
604         return;
605
606     // Prevent from relaying cancel if wasn't subscribed
607     if (!vfSubscribe[nChannel])
608         return;
609     vfSubscribe[nChannel] = false;
610
611     if (!AnySubscribed(nChannel))
612     {
613         // Relay subscription cancel
614         CRITICAL_BLOCK(cs_vNodes)
615             BOOST_FOREACH(CNode* pnode, vNodes)
616                 if (pnode != this)
617                     pnode->PushMessage("sub-cancel", nChannel);
618     }
619 }
620
621
622
623
624
625
626
627
628
629 CNode* FindNode(unsigned int ip)
630 {
631     CRITICAL_BLOCK(cs_vNodes)
632     {
633         BOOST_FOREACH(CNode* pnode, vNodes)
634             if (pnode->addr.ip == ip)
635                 return (pnode);
636     }
637     return NULL;
638 }
639
640 CNode* FindNode(CAddress addr)
641 {
642     CRITICAL_BLOCK(cs_vNodes)
643     {
644         BOOST_FOREACH(CNode* pnode, vNodes)
645             if (pnode->addr == addr)
646                 return (pnode);
647     }
648     return NULL;
649 }
650
651 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
652 {
653     if (addrConnect.ip == addrLocalHost.ip)
654         return NULL;
655
656     // Look for an existing connection
657     CNode* pnode = FindNode(addrConnect.ip);
658     if (pnode)
659     {
660         if (nTimeout != 0)
661             pnode->AddRef(nTimeout);
662         else
663             pnode->AddRef();
664         return pnode;
665     }
666
667     /// debug print
668     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
669         addrConnect.ToString().c_str(),
670         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
671         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
672
673     CRITICAL_BLOCK(cs_mapAddresses)
674         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
675
676     // Connect
677     SOCKET hSocket;
678     if (ConnectSocket(addrConnect, hSocket))
679     {
680         /// debug print
681         printf("connected %s\n", addrConnect.ToString().c_str());
682
683         // Set to nonblocking
684 #ifdef __WXMSW__
685         u_long nOne = 1;
686         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
687             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
688 #else
689         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
690             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
691 #endif
692
693         // Add node
694         CNode* pnode = new CNode(hSocket, addrConnect, false);
695         if (nTimeout != 0)
696             pnode->AddRef(nTimeout);
697         else
698             pnode->AddRef();
699         CRITICAL_BLOCK(cs_vNodes)
700             vNodes.push_back(pnode);
701
702         pnode->nTimeConnected = GetTime();
703         return pnode;
704     }
705     else
706     {
707         return NULL;
708     }
709 }
710
711 void CNode::CloseSocketDisconnect()
712 {
713     fDisconnect = true;
714     if (hSocket != INVALID_SOCKET)
715     {
716         if (fDebug)
717             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
718         printf("disconnecting node %s\n", addr.ToString().c_str());
719         closesocket(hSocket);
720         hSocket = INVALID_SOCKET;
721         vRecv.clear();
722     }
723 }
724
725 void CNode::Cleanup()
726 {
727     // All of a nodes broadcasts and subscriptions are automatically torn down
728     // when it goes down, so a node has to stay up to keep its broadcast going.
729
730     // Cancel subscriptions
731     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
732         if (vfSubscribe[nChannel])
733             CancelSubscribe(nChannel);
734 }
735
736
737
738
739
740
741
742
743
744
745
746
747
748 void ThreadSocketHandler(void* parg)
749 {
750     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
751     try
752     {
753         vnThreadsRunning[0]++;
754         ThreadSocketHandler2(parg);
755         vnThreadsRunning[0]--;
756     }
757     catch (std::exception& e) {
758         vnThreadsRunning[0]--;
759         PrintException(&e, "ThreadSocketHandler()");
760     } catch (...) {
761         vnThreadsRunning[0]--;
762         throw; // support pthread_cancel()
763     }
764     printf("ThreadSocketHandler exiting\n");
765 }
766
767 void ThreadSocketHandler2(void* parg)
768 {
769     printf("ThreadSocketHandler started\n");
770     list<CNode*> vNodesDisconnected;
771     int nPrevNodeCount = 0;
772
773     loop
774     {
775         //
776         // Disconnect nodes
777         //
778         CRITICAL_BLOCK(cs_vNodes)
779         {
780             // Disconnect unused nodes
781             vector<CNode*> vNodesCopy = vNodes;
782             BOOST_FOREACH(CNode* pnode, vNodesCopy)
783             {
784                 if (pnode->fDisconnect ||
785                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
786                 {
787                     // remove from vNodes
788                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
789
790                     // close socket and cleanup
791                     pnode->CloseSocketDisconnect();
792                     pnode->Cleanup();
793
794                     // hold in disconnected pool until all refs are released
795                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
796                     if (pnode->fNetworkNode || pnode->fInbound)
797                         pnode->Release();
798                     vNodesDisconnected.push_back(pnode);
799                 }
800             }
801
802             // Delete disconnected nodes
803             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
804             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
805             {
806                 // wait until threads are done using it
807                 if (pnode->GetRefCount() <= 0)
808                 {
809                     bool fDelete = false;
810                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
811                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
812                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
813                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
814                         fDelete = true;
815                     if (fDelete)
816                     {
817                         vNodesDisconnected.remove(pnode);
818                         delete pnode;
819                     }
820                 }
821             }
822         }
823         if (vNodes.size() != nPrevNodeCount)
824         {
825             nPrevNodeCount = vNodes.size();
826             MainFrameRepaint();
827         }
828
829
830         //
831         // Find which sockets have data to receive
832         //
833         struct timeval timeout;
834         timeout.tv_sec  = 0;
835         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
836
837         fd_set fdsetRecv;
838         fd_set fdsetSend;
839         fd_set fdsetError;
840         FD_ZERO(&fdsetRecv);
841         FD_ZERO(&fdsetSend);
842         FD_ZERO(&fdsetError);
843         SOCKET hSocketMax = 0;
844
845         if(hListenSocket != INVALID_SOCKET)
846             FD_SET(hListenSocket, &fdsetRecv);
847         hSocketMax = max(hSocketMax, hListenSocket);
848         CRITICAL_BLOCK(cs_vNodes)
849         {
850             BOOST_FOREACH(CNode* pnode, vNodes)
851             {
852                 if (pnode->hSocket == INVALID_SOCKET)
853                     continue;
854                 FD_SET(pnode->hSocket, &fdsetRecv);
855                 FD_SET(pnode->hSocket, &fdsetError);
856                 hSocketMax = max(hSocketMax, pnode->hSocket);
857                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
858                     if (!pnode->vSend.empty())
859                         FD_SET(pnode->hSocket, &fdsetSend);
860             }
861         }
862
863         vnThreadsRunning[0]--;
864         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
865         vnThreadsRunning[0]++;
866         if (fShutdown)
867             return;
868         if (nSelect == SOCKET_ERROR)
869         {
870             int nErr = WSAGetLastError();
871             if (hSocketMax != INVALID_SOCKET)
872             {
873                 printf("socket select error %d\n", nErr);
874                 for (unsigned int i = 0; i <= hSocketMax; i++)
875                     FD_SET(i, &fdsetRecv);
876             }
877             FD_ZERO(&fdsetSend);
878             FD_ZERO(&fdsetError);
879             Sleep(timeout.tv_usec/1000);
880         }
881
882
883         //
884         // Accept new connections
885         //
886         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
887         {
888             struct sockaddr_in sockaddr;
889             socklen_t len = sizeof(sockaddr);
890             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
891             CAddress addr;
892             int nInbound = 0;
893
894             if (hSocket != INVALID_SOCKET)
895                 addr = CAddress(sockaddr);
896
897             CRITICAL_BLOCK(cs_vNodes)
898                 BOOST_FOREACH(CNode* pnode, vNodes)
899                 if (pnode->fInbound)
900                     nInbound++;
901
902             if (hSocket == INVALID_SOCKET)
903             {
904                 if (WSAGetLastError() != WSAEWOULDBLOCK)
905                     printf("socket error accept failed: %d\n", WSAGetLastError());
906             }
907             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
908             {
909                 closesocket(hSocket);
910             }
911             else
912             {
913                 printf("accepted connection %s\n", addr.ToString().c_str());
914                 CNode* pnode = new CNode(hSocket, addr, true);
915                 pnode->AddRef();
916                 CRITICAL_BLOCK(cs_vNodes)
917                     vNodes.push_back(pnode);
918             }
919         }
920
921
922         //
923         // Service each socket
924         //
925         vector<CNode*> vNodesCopy;
926         CRITICAL_BLOCK(cs_vNodes)
927         {
928             vNodesCopy = vNodes;
929             BOOST_FOREACH(CNode* pnode, vNodesCopy)
930                 pnode->AddRef();
931         }
932         BOOST_FOREACH(CNode* pnode, vNodesCopy)
933         {
934             if (fShutdown)
935                 return;
936
937             //
938             // Receive
939             //
940             if (pnode->hSocket == INVALID_SOCKET)
941                 continue;
942             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
943             {
944                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
945                 {
946                     CDataStream& vRecv = pnode->vRecv;
947                     unsigned int nPos = vRecv.size();
948
949                     if (nPos > ReceiveBufferSize()) {
950                         if (!pnode->fDisconnect)
951                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
952                         pnode->CloseSocketDisconnect();
953                     }
954                     else {
955                         // typical socket buffer is 8K-64K
956                         char pchBuf[0x10000];
957                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
958                         if (nBytes > 0)
959                         {
960                             vRecv.resize(nPos + nBytes);
961                             memcpy(&vRecv[nPos], pchBuf, nBytes);
962                             pnode->nLastRecv = GetTime();
963                         }
964                         else if (nBytes == 0)
965                         {
966                             // socket closed gracefully
967                             if (!pnode->fDisconnect)
968                                 printf("socket closed\n");
969                             pnode->CloseSocketDisconnect();
970                         }
971                         else if (nBytes < 0)
972                         {
973                             // error
974                             int nErr = WSAGetLastError();
975                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
976                             {
977                                 if (!pnode->fDisconnect)
978                                     printf("socket recv error %d\n", nErr);
979                                 pnode->CloseSocketDisconnect();
980                             }
981                         }
982                     }
983                 }
984             }
985
986             //
987             // Send
988             //
989             if (pnode->hSocket == INVALID_SOCKET)
990                 continue;
991             if (FD_ISSET(pnode->hSocket, &fdsetSend))
992             {
993                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
994                 {
995                     CDataStream& vSend = pnode->vSend;
996                     if (!vSend.empty())
997                     {
998                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
999                         if (nBytes > 0)
1000                         {
1001                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1002                             pnode->nLastSend = GetTime();
1003                         }
1004                         else if (nBytes < 0)
1005                         {
1006                             // error
1007                             int nErr = WSAGetLastError();
1008                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1009                             {
1010                                 printf("socket send error %d\n", nErr);
1011                                 pnode->CloseSocketDisconnect();
1012                             }
1013                         }
1014                         if (vSend.size() > SendBufferSize()) {
1015                             if (!pnode->fDisconnect)
1016                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1017                             pnode->CloseSocketDisconnect();
1018                         }
1019                     }
1020                 }
1021             }
1022
1023             //
1024             // Inactivity checking
1025             //
1026             if (pnode->vSend.empty())
1027                 pnode->nLastSendEmpty = GetTime();
1028             if (GetTime() - pnode->nTimeConnected > 60)
1029             {
1030                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1031                 {
1032                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1033                     pnode->fDisconnect = true;
1034                 }
1035                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1036                 {
1037                     printf("socket not sending\n");
1038                     pnode->fDisconnect = true;
1039                 }
1040                 else if (GetTime() - pnode->nLastRecv > 90*60)
1041                 {
1042                     printf("socket inactivity timeout\n");
1043                     pnode->fDisconnect = true;
1044                 }
1045             }
1046         }
1047         CRITICAL_BLOCK(cs_vNodes)
1048         {
1049             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1050                 pnode->Release();
1051         }
1052
1053         Sleep(10);
1054     }
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065 #ifdef USE_UPNP
1066 void ThreadMapPort(void* parg)
1067 {
1068     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1069     try
1070     {
1071         vnThreadsRunning[5]++;
1072         ThreadMapPort2(parg);
1073         vnThreadsRunning[5]--;
1074     }
1075     catch (std::exception& e) {
1076         vnThreadsRunning[5]--;
1077         PrintException(&e, "ThreadMapPort()");
1078     } catch (...) {
1079         vnThreadsRunning[5]--;
1080         PrintException(NULL, "ThreadMapPort()");
1081     }
1082     printf("ThreadMapPort exiting\n");
1083 }
1084
1085 void ThreadMapPort2(void* parg)
1086 {
1087     printf("ThreadMapPort started\n");
1088
1089     char port[6];
1090     sprintf(port, "%d", GetListenPort());
1091
1092     const char * multicastif = 0;
1093     const char * minissdpdpath = 0;
1094     struct UPNPDev * devlist = 0;
1095     char lanaddr[64];
1096
1097 #ifndef UPNPDISCOVER_SUCCESS
1098     /* miniupnpc 1.5 */
1099     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1100 #else
1101     /* miniupnpc 1.6 */
1102     int error = 0;
1103     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1104 #endif
1105
1106     struct UPNPUrls urls;
1107     struct IGDdatas data;
1108     int r;
1109
1110     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1111     if (r == 1)
1112     {
1113         if (!addrLocalHost.IsRoutable())
1114         {
1115             char externalIPAddress[40];
1116             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1117             if(r != UPNPCOMMAND_SUCCESS)
1118                 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1119             else
1120             {
1121                 if(externalIPAddress[0])
1122                 {
1123                     printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1124                     CAddress addrExternalFromUPnP(externalIPAddress, 0, false, nLocalServices);
1125                     if (addrExternalFromUPnP.IsRoutable())
1126                         addrLocalHost = addrExternalFromUPnP;
1127                 }
1128                 else
1129                     printf("UPnP: GetExternalIPAddress failed.\n");
1130             }
1131         }
1132
1133         string strDesc = "Bitcoin " + FormatFullVersion();
1134 #ifndef UPNPDISCOVER_SUCCESS
1135         /* miniupnpc 1.5 */
1136         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1137                             port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1138 #else
1139         /* miniupnpc 1.6 */
1140         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1141                             port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1142 #endif
1143
1144         if(r!=UPNPCOMMAND_SUCCESS)
1145             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1146                 port, port, lanaddr, r, strupnperror(r));
1147         else
1148             printf("UPnP Port Mapping successful.\n");
1149         int i = 1;
1150         loop {
1151             if (fShutdown || !fUseUPnP)
1152             {
1153                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1154                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1155                 freeUPNPDevlist(devlist); devlist = 0;
1156                 FreeUPNPUrls(&urls);
1157                 return;
1158             }
1159             if (i % 600 == 0) // Refresh every 20 minutes
1160             {
1161 #ifndef UPNPDISCOVER_SUCCESS
1162                 /* miniupnpc 1.5 */
1163                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1164                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1165 #else
1166                 /* miniupnpc 1.6 */
1167                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1168                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1169 #endif
1170
1171                 if(r!=UPNPCOMMAND_SUCCESS)
1172                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1173                         port, port, lanaddr, r, strupnperror(r));
1174                 else
1175                     printf("UPnP Port Mapping successful.\n");;
1176             }
1177             Sleep(2000);
1178             i++;
1179         }
1180     } else {
1181         printf("No valid UPnP IGDs found\n");
1182         freeUPNPDevlist(devlist); devlist = 0;
1183         if (r != 0)
1184             FreeUPNPUrls(&urls);
1185         loop {
1186             if (fShutdown || !fUseUPnP)
1187                 return;
1188             Sleep(2000);
1189         }
1190     }
1191 }
1192
1193 void MapPort(bool fMapPort)
1194 {
1195     if (fUseUPnP != fMapPort)
1196     {
1197         fUseUPnP = fMapPort;
1198         WriteSetting("fUseUPnP", fUseUPnP);
1199     }
1200     if (fUseUPnP && vnThreadsRunning[5] < 1)
1201     {
1202         if (!CreateThread(ThreadMapPort, NULL))
1203             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1204     }
1205 }
1206 #else
1207 void MapPort(bool /* unused fMapPort */)
1208 {
1209     // Intentionally left blank.
1210 }
1211 #endif
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 static const char *strDNSSeed[] = {
1223     "bitseed.xf2.org",
1224     "dnsseed.bluematt.me",
1225     "seed.bitcoin.sipa.be",
1226     "dnsseed.bitcoin.dashjr.org",
1227 };
1228
1229 void ThreadDNSAddressSeed(void* parg)
1230 {
1231     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1232     try
1233     {
1234         vnThreadsRunning[6]++;
1235         ThreadDNSAddressSeed2(parg);
1236         vnThreadsRunning[6]--;
1237     }
1238     catch (std::exception& e) {
1239         vnThreadsRunning[6]--;
1240         PrintException(&e, "ThreadDNSAddressSeed()");
1241     } catch (...) {
1242         vnThreadsRunning[6]--;
1243         throw; // support pthread_cancel()
1244     }
1245     printf("ThreadDNSAddressSeed exiting\n");
1246 }
1247
1248 void ThreadDNSAddressSeed2(void* parg)
1249 {
1250     printf("ThreadDNSAddressSeed started\n");
1251     int found = 0;
1252
1253     if (!fTestNet)
1254     {
1255         printf("Loading addresses from DNS seeds (could take a while)\n");
1256
1257         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1258             vector<CAddress> vaddr;
1259             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1260             {
1261                 CAddrDB addrDB;
1262                 addrDB.TxnBegin();
1263                 BOOST_FOREACH (CAddress& addr, vaddr)
1264                 {
1265                     if (addr.GetByte(3) != 127)
1266                     {
1267                         addr.nTime = 0;
1268                         AddAddress(addr, 0, &addrDB);
1269                         found++;
1270                     }
1271                 }
1272                 addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1273             }
1274         }
1275     }
1276
1277     printf("%d addresses found from DNS seeds\n", found);
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291 unsigned int pnSeed[] =
1292 {
1293     0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1294     0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1295     0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1296     0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1297     0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1298     0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1299     0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1300     0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1301     0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1302     0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1303     0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1304     0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1305     0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1306     0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1307     0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1308     0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1309     0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1310     0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1311     0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1312     0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1313     0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1314     0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1315     0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1316     0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1317     0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1318     0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1319     0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1320     0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1321     0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1322     0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1323     0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1324     0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1325     0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1326     0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1327     0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1328     0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1329     0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1330     0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1331     0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1332     0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1333     0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1334     0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1335     0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1336     0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1337     0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1338     0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1339     0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1340     0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1341     0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1342     0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1343     0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1344     0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1345     0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1346     0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1347     0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1348     0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1349     0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1350     0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1351     0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1352     0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1353     0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1354     0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1355     0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1356     0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1357     0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1358     0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1359     0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1360     0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1361     0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1362     0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1363     0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1364     0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1365     0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1366     0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1367     0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1368     0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1369     0xc461d84a, 0xb2dbe247,
1370 };
1371
1372
1373
1374 void ThreadOpenConnections(void* parg)
1375 {
1376     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1377     try
1378     {
1379         vnThreadsRunning[1]++;
1380         ThreadOpenConnections2(parg);
1381         vnThreadsRunning[1]--;
1382     }
1383     catch (std::exception& e) {
1384         vnThreadsRunning[1]--;
1385         PrintException(&e, "ThreadOpenConnections()");
1386     } catch (...) {
1387         vnThreadsRunning[1]--;
1388         PrintException(NULL, "ThreadOpenConnections()");
1389     }
1390     printf("ThreadOpenConnections exiting\n");
1391 }
1392
1393 void ThreadOpenConnections2(void* parg)
1394 {
1395     printf("ThreadOpenConnections started\n");
1396
1397     // Connect to specific addresses
1398     if (mapArgs.count("-connect"))
1399     {
1400         for (int64 nLoop = 0;; nLoop++)
1401         {
1402             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1403             {
1404                 CAddress addr(strAddr, fAllowDNS);
1405                 if (addr.IsValid())
1406                     OpenNetworkConnection(addr);
1407                 for (int i = 0; i < 10 && i < nLoop; i++)
1408                 {
1409                     Sleep(500);
1410                     if (fShutdown)
1411                         return;
1412                 }
1413             }
1414         }
1415     }
1416
1417     // Connect to manually added nodes first
1418     if (mapArgs.count("-addnode"))
1419     {
1420         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1421         {
1422             CAddress addr(strAddr, fAllowDNS);
1423             if (addr.IsValid())
1424             {
1425                 OpenNetworkConnection(addr);
1426                 Sleep(500);
1427                 if (fShutdown)
1428                     return;
1429             }
1430         }
1431     }
1432
1433     // Initiate network connections
1434     int64 nStart = GetTime();
1435     loop
1436     {
1437         vnThreadsRunning[1]--;
1438         Sleep(500);
1439         vnThreadsRunning[1]++;
1440         if (fShutdown)
1441             return;
1442
1443         // Limit outbound connections
1444         loop
1445         {
1446             int nOutbound = 0;
1447             CRITICAL_BLOCK(cs_vNodes)
1448                 BOOST_FOREACH(CNode* pnode, vNodes)
1449                     if (!pnode->fInbound)
1450                         nOutbound++;
1451             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1452             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1453             if (nOutbound < nMaxOutboundConnections)
1454                 break;
1455             vnThreadsRunning[1]--;
1456             Sleep(2000);
1457             vnThreadsRunning[1]++;
1458             if (fShutdown)
1459                 return;
1460         }
1461
1462         bool fAddSeeds = false;
1463
1464         CRITICAL_BLOCK(cs_mapAddresses)
1465         {
1466             // Add seed nodes if IRC isn't working
1467             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1468             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
1469                 fAddSeeds = true;
1470         }
1471
1472         if (fAddSeeds)
1473         {
1474             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1475             {
1476                 // It'll only connect to one or two seed nodes because once it connects,
1477                 // it'll get a pile of addresses with newer timestamps.
1478                 // Seed nodes are given a random 'last seen time' of between one and two
1479                 // weeks ago.
1480                 const int64 nOneWeek = 7*24*60*60;
1481                 CAddress addr;
1482                 addr.ip = pnSeed[i];
1483                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1484                 AddAddress(addr);
1485             }
1486         }
1487
1488         //
1489         // Choose an address to connect to based on most recently seen
1490         //
1491         CAddress addrConnect;
1492         int64 nBest = INT64_MIN;
1493
1494         // Only connect to one address per a.b.?.? range.
1495         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1496         set<unsigned int> setConnected;
1497         CRITICAL_BLOCK(cs_vNodes)
1498             BOOST_FOREACH(CNode* pnode, vNodes)
1499                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1500
1501         CRITICAL_BLOCK(cs_mapAddresses)
1502         {
1503             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1504             {
1505                 const CAddress& addr = item.second;
1506                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1507                     continue;
1508                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1509                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1510
1511                 // Randomize the order in a deterministic way, putting the standard port first
1512                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1513                 if (addr.port != htons(GetDefaultPort()))
1514                     nRandomizer += 2 * 60 * 60;
1515
1516                 // Last seen  Base retry frequency
1517                 //   <1 hour   10 min
1518                 //    1 hour    1 hour
1519                 //    4 hours   2 hours
1520                 //   24 hours   5 hours
1521                 //   48 hours   7 hours
1522                 //    7 days   13 hours
1523                 //   30 days   27 hours
1524                 //   90 days   46 hours
1525                 //  365 days   93 hours
1526                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1527
1528                 // Fast reconnect for one hour after last seen
1529                 if (nSinceLastSeen < 60 * 60)
1530                     nDelay = 10 * 60;
1531
1532                 // Limit retry frequency
1533                 if (nSinceLastTry < nDelay)
1534                     continue;
1535
1536                 // If we have IRC, we'll be notified when they first come online,
1537                 // and again every 24 hours by the refresh broadcast.
1538                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1539                     continue;
1540
1541                 // Only try the old stuff if we don't have enough connections
1542                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1543                     continue;
1544
1545                 // If multiple addresses are ready, prioritize by time since
1546                 // last seen and time since last tried.
1547                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1548                 if (nScore > nBest)
1549                 {
1550                     nBest = nScore;
1551                     addrConnect = addr;
1552                 }
1553             }
1554         }
1555
1556         if (addrConnect.IsValid())
1557             OpenNetworkConnection(addrConnect);
1558     }
1559 }
1560
1561 bool OpenNetworkConnection(const CAddress& addrConnect)
1562 {
1563     //
1564     // Initiate outbound network connection
1565     //
1566     if (fShutdown)
1567         return false;
1568     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1569         return false;
1570
1571     vnThreadsRunning[1]--;
1572     CNode* pnode = ConnectNode(addrConnect);
1573     vnThreadsRunning[1]++;
1574     if (fShutdown)
1575         return false;
1576     if (!pnode)
1577         return false;
1578     pnode->fNetworkNode = true;
1579
1580     return true;
1581 }
1582
1583
1584
1585
1586
1587
1588
1589
1590 void ThreadMessageHandler(void* parg)
1591 {
1592     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1593     try
1594     {
1595         vnThreadsRunning[2]++;
1596         ThreadMessageHandler2(parg);
1597         vnThreadsRunning[2]--;
1598     }
1599     catch (std::exception& e) {
1600         vnThreadsRunning[2]--;
1601         PrintException(&e, "ThreadMessageHandler()");
1602     } catch (...) {
1603         vnThreadsRunning[2]--;
1604         PrintException(NULL, "ThreadMessageHandler()");
1605     }
1606     printf("ThreadMessageHandler exiting\n");
1607 }
1608
1609 void ThreadMessageHandler2(void* parg)
1610 {
1611     printf("ThreadMessageHandler started\n");
1612     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1613     while (!fShutdown)
1614     {
1615         vector<CNode*> vNodesCopy;
1616         CRITICAL_BLOCK(cs_vNodes)
1617         {
1618             vNodesCopy = vNodes;
1619             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1620                 pnode->AddRef();
1621         }
1622
1623         // Poll the connected nodes for messages
1624         CNode* pnodeTrickle = NULL;
1625         if (!vNodesCopy.empty())
1626             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1627         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1628         {
1629             // Receive messages
1630             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1631                 ProcessMessages(pnode);
1632             if (fShutdown)
1633                 return;
1634
1635             // Send messages
1636             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1637                 SendMessages(pnode, pnode == pnodeTrickle);
1638             if (fShutdown)
1639                 return;
1640         }
1641
1642         CRITICAL_BLOCK(cs_vNodes)
1643         {
1644             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1645                 pnode->Release();
1646         }
1647
1648         // Wait and allow messages to bunch up.
1649         // Reduce vnThreadsRunning so StopNode has permission to exit while
1650         // we're sleeping, but we must always check fShutdown after doing this.
1651         vnThreadsRunning[2]--;
1652         Sleep(100);
1653         if (fRequestShutdown)
1654             Shutdown(NULL);
1655         vnThreadsRunning[2]++;
1656         if (fShutdown)
1657             return;
1658     }
1659 }
1660
1661
1662
1663
1664
1665
1666 bool BindListenPort(string& strError)
1667 {
1668     strError = "";
1669     int nOne = 1;
1670     addrLocalHost.port = htons(GetListenPort());
1671
1672 #ifdef __WXMSW__
1673     // Initialize Windows Sockets
1674     WSADATA wsadata;
1675     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1676     if (ret != NO_ERROR)
1677     {
1678         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1679         printf("%s\n", strError.c_str());
1680         return false;
1681     }
1682 #endif
1683
1684     // Create socket for listening for incoming connections
1685     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1686     if (hListenSocket == INVALID_SOCKET)
1687     {
1688         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1689         printf("%s\n", strError.c_str());
1690         return false;
1691     }
1692
1693 #ifdef SO_NOSIGPIPE
1694     // Different way of disabling SIGPIPE on BSD
1695     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1696 #endif
1697
1698 #ifndef __WXMSW__
1699     // Allow binding if the port is still in TIME_WAIT state after
1700     // the program was closed and restarted.  Not an issue on windows.
1701     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1702 #endif
1703
1704 #ifdef __WXMSW__
1705     // Set to nonblocking, incoming connections will also inherit this
1706     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1707 #else
1708     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1709 #endif
1710     {
1711         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1712         printf("%s\n", strError.c_str());
1713         return false;
1714     }
1715
1716     // The sockaddr_in structure specifies the address family,
1717     // IP address, and port for the socket that is being bound
1718     struct sockaddr_in sockaddr;
1719     memset(&sockaddr, 0, sizeof(sockaddr));
1720     sockaddr.sin_family = AF_INET;
1721     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1722     sockaddr.sin_port = htons(GetListenPort());
1723     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1724     {
1725         int nErr = WSAGetLastError();
1726         if (nErr == WSAEADDRINUSE)
1727             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1728         else
1729             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1730         printf("%s\n", strError.c_str());
1731         return false;
1732     }
1733     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1734
1735     // Listen for incoming connections
1736     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1737     {
1738         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1739         printf("%s\n", strError.c_str());
1740         return false;
1741     }
1742
1743     return true;
1744 }
1745
1746 void StartNode(void* parg)
1747 {
1748     if (pnodeLocalHost == NULL)
1749         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1750
1751 #ifdef __WXMSW__
1752     // Get local host ip
1753     char pszHostName[1000] = "";
1754     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1755     {
1756         vector<CAddress> vaddr;
1757         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1758             BOOST_FOREACH (const CAddress &addr, vaddr)
1759                 if (addr.GetByte(3) != 127)
1760                 {
1761                     addrLocalHost = addr;
1762                     break;
1763                 }
1764     }
1765 #else
1766     // Get local host ip
1767     struct ifaddrs* myaddrs;
1768     if (getifaddrs(&myaddrs) == 0)
1769     {
1770         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1771         {
1772             if (ifa->ifa_addr == NULL) continue;
1773             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1774             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1775             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1776             char pszIP[100];
1777             if (ifa->ifa_addr->sa_family == AF_INET)
1778             {
1779                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1780                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1781                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1782
1783                 // Take the first IP that isn't loopback 127.x.x.x
1784                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1785                 if (addr.IsValid() && addr.GetByte(3) != 127)
1786                 {
1787                     addrLocalHost = addr;
1788                     break;
1789                 }
1790             }
1791             else if (ifa->ifa_addr->sa_family == AF_INET6)
1792             {
1793                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1794                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1795                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1796             }
1797         }
1798         freeifaddrs(myaddrs);
1799     }
1800 #endif
1801     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1802
1803     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1804     {
1805         // Proxies can't take incoming connections
1806         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1807         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1808     }
1809     else
1810     {
1811         CreateThread(ThreadGetMyExternalIP, NULL);
1812     }
1813
1814     //
1815     // Start threads
1816     //
1817
1818     if (GetBoolArg("-nodnsseed"))
1819         printf("DNS seeding disabled\n");
1820     else
1821         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1822             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1823
1824     // Map ports with UPnP
1825     if (fHaveUPnP)
1826         MapPort(fUseUPnP);
1827
1828     // Get addresses from IRC and advertise ours
1829     if (!CreateThread(ThreadIRCSeed, NULL))
1830         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1831
1832     // Send and receive from sockets, accept connections
1833     if (!CreateThread(ThreadSocketHandler, NULL))
1834         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1835
1836     // Initiate outbound connections
1837     if (!CreateThread(ThreadOpenConnections, NULL))
1838         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1839
1840     // Process messages
1841     if (!CreateThread(ThreadMessageHandler, NULL))
1842         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1843
1844     // Generate coins in the background
1845     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1846 }
1847
1848 bool StopNode()
1849 {
1850     printf("StopNode()\n");
1851     fShutdown = true;
1852     nTransactionsUpdated++;
1853     int64 nStart = GetTime();
1854     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1855 #ifdef USE_UPNP
1856         || vnThreadsRunning[5] > 0
1857 #endif
1858     )
1859     {
1860         if (GetTime() - nStart > 20)
1861             break;
1862         Sleep(20);
1863     }
1864     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1865     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1866     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1867     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1868     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1869     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1870     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1871     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1872         Sleep(20);
1873     Sleep(50);
1874
1875     return true;
1876 }
1877
1878 class CNetCleanup
1879 {
1880 public:
1881     CNetCleanup()
1882     {
1883     }
1884     ~CNetCleanup()
1885     {
1886         // Close sockets
1887         BOOST_FOREACH(CNode* pnode, vNodes)
1888             if (pnode->hSocket != INVALID_SOCKET)
1889                 closesocket(pnode->hSocket);
1890         if (hListenSocket != INVALID_SOCKET)
1891             if (closesocket(hListenSocket) == SOCKET_ERROR)
1892                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1893
1894 #ifdef __WXMSW__
1895         // Shutdown Windows Sockets
1896         WSACleanup();
1897 #endif
1898     }
1899 }
1900 instance_of_cnetcleanup;