Fix loop index var types, fixing many minor sign comparison warnings
[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 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 __WXMSW__
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 __WXMSW__
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 __WXMSW__
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 __WXMSW__
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 __WXMSW__
180     fNonblock = 0;
181     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
182 #else
183     fFlags = fcntl(hSocket, F_GETFL, 0);
184     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
185 #endif
186     {
187         closesocket(hSocket);
188         return false;
189     }
190
191     if (fProxy)
192     {
193         printf("proxy connecting %s\n", addrConnect.ToString().c_str());
194         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
195         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
196         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
197         char* pszSocks4 = pszSocks4IP;
198         int nSize = sizeof(pszSocks4IP);
199
200         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
201         if (ret != nSize)
202         {
203             closesocket(hSocket);
204             return error("Error sending to proxy");
205         }
206         char pchRet[8];
207         if (recv(hSocket, pchRet, 8, 0) != 8)
208         {
209             closesocket(hSocket);
210             return error("Error reading proxy response");
211         }
212         if (pchRet[1] != 0x5a)
213         {
214             closesocket(hSocket);
215             if (pchRet[1] != 0x5b)
216                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
217             return false;
218         }
219         printf("proxy connected %s\n", addrConnect.ToString().c_str());
220     }
221
222     hSocketRet = hSocket;
223     return true;
224 }
225
226 // portDefault is in host order
227 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
228 {
229     vaddr.clear();
230     if (pszName[0] == 0)
231         return false;
232     int port = portDefault;
233     char psz[256];
234     char *pszHost = psz;
235     strlcpy(psz, pszName, sizeof(psz));
236     if (fAllowPort)
237     {
238         char* pszColon = strrchr(psz+1,':');
239         char *pszPortEnd = NULL;
240         int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
241         if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
242         {
243             if (psz[0] == '[' && pszColon[-1] == ']')
244             {
245                 // Future: enable IPv6 colon-notation inside []
246                 pszHost = psz+1;
247                 pszColon[-1] = 0;
248             }
249             else
250                 pszColon[0] = 0;
251             port = portParsed;
252             if (port < 0 || port > USHRT_MAX)
253                 port = USHRT_MAX;
254         }
255     }
256
257     unsigned int addrIP = inet_addr(pszHost);
258     if (addrIP != INADDR_NONE)
259     {
260         // valid IP address passed
261         vaddr.push_back(CAddress(addrIP, port, nServices));
262         return true;
263     }
264
265     if (!fAllowLookup)
266         return false;
267
268     struct hostent* phostent = gethostbyname(pszHost);
269     if (!phostent)
270         return false;
271
272     if (phostent->h_addrtype != AF_INET)
273         return false;
274
275     char** ppAddr = phostent->h_addr_list;
276     while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
277     {
278         CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
279         if (addr.IsValid())
280             vaddr.push_back(addr);
281         ppAddr++;
282     }
283
284     return (vaddr.size() > 0);
285 }
286
287 // portDefault is in host order
288 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
289 {
290     vector<CAddress> vaddr;
291     bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
292     if (fRet)
293         addr = vaddr[0];
294     return fRet;
295 }
296
297 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
298 {
299     SOCKET hSocket;
300     if (!ConnectSocket(addrConnect, hSocket))
301         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
302
303     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
304
305     string strLine;
306     while (RecvLine(hSocket, strLine))
307     {
308         if (strLine.empty()) // HTTP response is separated from headers by blank line
309         {
310             loop
311             {
312                 if (!RecvLine(hSocket, strLine))
313                 {
314                     closesocket(hSocket);
315                     return false;
316                 }
317                 if (pszKeyword == NULL)
318                     break;
319                 if (strLine.find(pszKeyword) != string::npos)
320                 {
321                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
322                     break;
323                 }
324             }
325             closesocket(hSocket);
326             if (strLine.find("<") != string::npos)
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 __WXMSW__
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         vRecv.clear();
720     }
721 }
722
723 void CNode::Cleanup()
724 {
725     // All of a nodes broadcasts and subscriptions are automatically torn down
726     // when it goes down, so a node has to stay up to keep its broadcast going.
727
728     // Cancel subscriptions
729     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
730         if (vfSubscribe[nChannel])
731             CancelSubscribe(nChannel);
732 }
733
734
735
736
737
738
739
740
741
742
743
744
745
746 void ThreadSocketHandler(void* parg)
747 {
748     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
749     try
750     {
751         vnThreadsRunning[0]++;
752         ThreadSocketHandler2(parg);
753         vnThreadsRunning[0]--;
754     }
755     catch (std::exception& e) {
756         vnThreadsRunning[0]--;
757         PrintException(&e, "ThreadSocketHandler()");
758     } catch (...) {
759         vnThreadsRunning[0]--;
760         throw; // support pthread_cancel()
761     }
762     printf("ThreadSocketHandler exiting\n");
763 }
764
765 void ThreadSocketHandler2(void* parg)
766 {
767     printf("ThreadSocketHandler started\n");
768     list<CNode*> vNodesDisconnected;
769     int nPrevNodeCount = 0;
770
771     loop
772     {
773         //
774         // Disconnect nodes
775         //
776         CRITICAL_BLOCK(cs_vNodes)
777         {
778             // Disconnect unused nodes
779             vector<CNode*> vNodesCopy = vNodes;
780             BOOST_FOREACH(CNode* pnode, vNodesCopy)
781             {
782                 if (pnode->fDisconnect ||
783                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
784                 {
785                     // remove from vNodes
786                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
787
788                     // close socket and cleanup
789                     pnode->CloseSocketDisconnect();
790                     pnode->Cleanup();
791
792                     // hold in disconnected pool until all refs are released
793                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
794                     if (pnode->fNetworkNode || pnode->fInbound)
795                         pnode->Release();
796                     vNodesDisconnected.push_back(pnode);
797                 }
798             }
799
800             // Delete disconnected nodes
801             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
802             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
803             {
804                 // wait until threads are done using it
805                 if (pnode->GetRefCount() <= 0)
806                 {
807                     bool fDelete = false;
808                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
809                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
810                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
811                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
812                         fDelete = true;
813                     if (fDelete)
814                     {
815                         vNodesDisconnected.remove(pnode);
816                         delete pnode;
817                     }
818                 }
819             }
820         }
821         if (vNodes.size() != nPrevNodeCount)
822         {
823             nPrevNodeCount = vNodes.size();
824             MainFrameRepaint();
825         }
826
827
828         //
829         // Find which sockets have data to receive
830         //
831         struct timeval timeout;
832         timeout.tv_sec  = 0;
833         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
834
835         fd_set fdsetRecv;
836         fd_set fdsetSend;
837         fd_set fdsetError;
838         FD_ZERO(&fdsetRecv);
839         FD_ZERO(&fdsetSend);
840         FD_ZERO(&fdsetError);
841         SOCKET hSocketMax = 0;
842
843         if(hListenSocket != INVALID_SOCKET)
844             FD_SET(hListenSocket, &fdsetRecv);
845         hSocketMax = max(hSocketMax, hListenSocket);
846         CRITICAL_BLOCK(cs_vNodes)
847         {
848             BOOST_FOREACH(CNode* pnode, vNodes)
849             {
850                 if (pnode->hSocket == INVALID_SOCKET)
851                     continue;
852                 FD_SET(pnode->hSocket, &fdsetRecv);
853                 FD_SET(pnode->hSocket, &fdsetError);
854                 hSocketMax = max(hSocketMax, pnode->hSocket);
855                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
856                     if (!pnode->vSend.empty())
857                         FD_SET(pnode->hSocket, &fdsetSend);
858             }
859         }
860
861         vnThreadsRunning[0]--;
862         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
863         vnThreadsRunning[0]++;
864         if (fShutdown)
865             return;
866         if (nSelect == SOCKET_ERROR)
867         {
868             int nErr = WSAGetLastError();
869             if (hSocketMax > -1)
870             {
871                 printf("socket select error %d\n", nErr);
872                 for (unsigned int i = 0; i <= hSocketMax; i++)
873                     FD_SET(i, &fdsetRecv);
874             }
875             FD_ZERO(&fdsetSend);
876             FD_ZERO(&fdsetError);
877             Sleep(timeout.tv_usec/1000);
878         }
879
880
881         //
882         // Accept new connections
883         //
884         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
885         {
886             struct sockaddr_in sockaddr;
887             socklen_t len = sizeof(sockaddr);
888             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
889             CAddress addr;
890             int nInbound = 0;
891
892             if (hSocket != INVALID_SOCKET)
893                 addr = CAddress(sockaddr);
894
895             CRITICAL_BLOCK(cs_vNodes)
896                 BOOST_FOREACH(CNode* pnode, vNodes)
897                 if (pnode->fInbound)
898                     nInbound++;
899
900             if (hSocket == INVALID_SOCKET)
901             {
902                 if (WSAGetLastError() != WSAEWOULDBLOCK)
903                     printf("socket error accept failed: %d\n", WSAGetLastError());
904             }
905             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
906             {
907                 closesocket(hSocket);
908             }
909             else
910             {
911                 printf("accepted connection %s\n", addr.ToString().c_str());
912                 CNode* pnode = new CNode(hSocket, addr, true);
913                 pnode->AddRef();
914                 CRITICAL_BLOCK(cs_vNodes)
915                     vNodes.push_back(pnode);
916             }
917         }
918
919
920         //
921         // Service each socket
922         //
923         vector<CNode*> vNodesCopy;
924         CRITICAL_BLOCK(cs_vNodes)
925         {
926             vNodesCopy = vNodes;
927             BOOST_FOREACH(CNode* pnode, vNodesCopy)
928                 pnode->AddRef();
929         }
930         BOOST_FOREACH(CNode* pnode, vNodesCopy)
931         {
932             if (fShutdown)
933                 return;
934
935             //
936             // Receive
937             //
938             if (pnode->hSocket == INVALID_SOCKET)
939                 continue;
940             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
941             {
942                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
943                 {
944                     CDataStream& vRecv = pnode->vRecv;
945                     unsigned int nPos = vRecv.size();
946
947                     if (nPos > ReceiveBufferSize()) {
948                         if (!pnode->fDisconnect)
949                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
950                         pnode->CloseSocketDisconnect();
951                     }
952                     else {
953                         // typical socket buffer is 8K-64K
954                         char pchBuf[0x10000];
955                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
956                         if (nBytes > 0)
957                         {
958                             vRecv.resize(nPos + nBytes);
959                             memcpy(&vRecv[nPos], pchBuf, nBytes);
960                             pnode->nLastRecv = GetTime();
961                         }
962                         else if (nBytes == 0)
963                         {
964                             // socket closed gracefully
965                             if (!pnode->fDisconnect)
966                                 printf("socket closed\n");
967                             pnode->CloseSocketDisconnect();
968                         }
969                         else if (nBytes < 0)
970                         {
971                             // error
972                             int nErr = WSAGetLastError();
973                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
974                             {
975                                 if (!pnode->fDisconnect)
976                                     printf("socket recv error %d\n", nErr);
977                                 pnode->CloseSocketDisconnect();
978                             }
979                         }
980                     }
981                 }
982             }
983
984             //
985             // Send
986             //
987             if (pnode->hSocket == INVALID_SOCKET)
988                 continue;
989             if (FD_ISSET(pnode->hSocket, &fdsetSend))
990             {
991                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
992                 {
993                     CDataStream& vSend = pnode->vSend;
994                     if (!vSend.empty())
995                     {
996                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
997                         if (nBytes > 0)
998                         {
999                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1000                             pnode->nLastSend = GetTime();
1001                         }
1002                         else if (nBytes < 0)
1003                         {
1004                             // error
1005                             int nErr = WSAGetLastError();
1006                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1007                             {
1008                                 printf("socket send error %d\n", nErr);
1009                                 pnode->CloseSocketDisconnect();
1010                             }
1011                         }
1012                         if (vSend.size() > SendBufferSize()) {
1013                             if (!pnode->fDisconnect)
1014                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1015                             pnode->CloseSocketDisconnect();
1016                         }
1017                     }
1018                 }
1019             }
1020
1021             //
1022             // Inactivity checking
1023             //
1024             if (pnode->vSend.empty())
1025                 pnode->nLastSendEmpty = GetTime();
1026             if (GetTime() - pnode->nTimeConnected > 60)
1027             {
1028                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1029                 {
1030                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1031                     pnode->fDisconnect = true;
1032                 }
1033                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1034                 {
1035                     printf("socket not sending\n");
1036                     pnode->fDisconnect = true;
1037                 }
1038                 else if (GetTime() - pnode->nLastRecv > 90*60)
1039                 {
1040                     printf("socket inactivity timeout\n");
1041                     pnode->fDisconnect = true;
1042                 }
1043             }
1044         }
1045         CRITICAL_BLOCK(cs_vNodes)
1046         {
1047             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1048                 pnode->Release();
1049         }
1050
1051         Sleep(10);
1052     }
1053 }
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 #ifdef USE_UPNP
1064 void ThreadMapPort(void* parg)
1065 {
1066     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1067     try
1068     {
1069         vnThreadsRunning[5]++;
1070         ThreadMapPort2(parg);
1071         vnThreadsRunning[5]--;
1072     }
1073     catch (std::exception& e) {
1074         vnThreadsRunning[5]--;
1075         PrintException(&e, "ThreadMapPort()");
1076     } catch (...) {
1077         vnThreadsRunning[5]--;
1078         PrintException(NULL, "ThreadMapPort()");
1079     }
1080     printf("ThreadMapPort exiting\n");
1081 }
1082
1083 void ThreadMapPort2(void* parg)
1084 {
1085     printf("ThreadMapPort started\n");
1086
1087     char port[6];
1088     sprintf(port, "%d", GetListenPort());
1089
1090     const char * multicastif = 0;
1091     const char * minissdpdpath = 0;
1092     struct UPNPDev * devlist = 0;
1093     char lanaddr[64];
1094
1095 #ifndef UPNPDISCOVER_SUCCESS
1096     /* miniupnpc 1.5 */
1097     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1098 #else
1099     /* miniupnpc 1.6 */
1100     int error = 0;
1101     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1102 #endif
1103
1104     struct UPNPUrls urls;
1105     struct IGDdatas data;
1106     int r;
1107
1108     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1109     if (r == 1)
1110     {
1111         if (!addrLocalHost.IsRoutable())
1112         {
1113             char externalIPAddress[40];
1114             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1115             if(r != UPNPCOMMAND_SUCCESS)
1116                 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1117             else
1118             {
1119                 if(externalIPAddress[0])
1120                 {
1121                     printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1122                     CAddress addrExternalFromUPnP(externalIPAddress, 0, false, nLocalServices);
1123                     if (addrExternalFromUPnP.IsRoutable())
1124                         addrLocalHost = addrExternalFromUPnP;
1125                 }
1126                 else
1127                     printf("UPnP: GetExternalIPAddress failed.\n");
1128             }
1129         }
1130
1131         string strDesc = "Bitcoin " + FormatFullVersion();
1132 #ifndef UPNPDISCOVER_SUCCESS
1133         /* miniupnpc 1.5 */
1134         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1135                             port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1136 #else
1137         /* miniupnpc 1.6 */
1138         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1139                             port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1140 #endif
1141
1142         if(r!=UPNPCOMMAND_SUCCESS)
1143             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1144                 port, port, lanaddr, r, strupnperror(r));
1145         else
1146             printf("UPnP Port Mapping successful.\n");
1147         int i = 1;
1148         loop {
1149             if (fShutdown || !fUseUPnP)
1150             {
1151                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1152                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1153                 freeUPNPDevlist(devlist); devlist = 0;
1154                 FreeUPNPUrls(&urls);
1155                 return;
1156             }
1157             if (i % 600 == 0) // Refresh every 20 minutes
1158             {
1159 #ifndef UPNPDISCOVER_SUCCESS
1160                 /* miniupnpc 1.5 */
1161                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1162                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1163 #else
1164                 /* miniupnpc 1.6 */
1165                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1166                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1167 #endif
1168
1169                 if(r!=UPNPCOMMAND_SUCCESS)
1170                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1171                         port, port, lanaddr, r, strupnperror(r));
1172                 else
1173                     printf("UPnP Port Mapping successful.\n");;
1174             }
1175             Sleep(2000);
1176             i++;
1177         }
1178     } else {
1179         printf("No valid UPnP IGDs found\n");
1180         freeUPNPDevlist(devlist); devlist = 0;
1181         if (r != 0)
1182             FreeUPNPUrls(&urls);
1183         loop {
1184             if (fShutdown || !fUseUPnP)
1185                 return;
1186             Sleep(2000);
1187         }
1188     }
1189 }
1190
1191 void MapPort(bool fMapPort)
1192 {
1193     if (fUseUPnP != fMapPort)
1194     {
1195         fUseUPnP = fMapPort;
1196         WriteSetting("fUseUPnP", fUseUPnP);
1197     }
1198     if (fUseUPnP && vnThreadsRunning[5] < 1)
1199     {
1200         if (!CreateThread(ThreadMapPort, NULL))
1201             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1202     }
1203 }
1204 #else
1205 void MapPort(bool /* unused fMapPort */)
1206 {
1207     // Intentionally left blank.
1208 }
1209 #endif
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 static const char *strDNSSeed[] = {
1221     "bitseed.xf2.org",
1222     "dnsseed.bluematt.me",
1223     "seed.bitcoin.sipa.be",
1224     "dnsseed.bitcoin.dashjr.org",
1225 };
1226
1227 void ThreadDNSAddressSeed(void* parg)
1228 {
1229     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1230     try
1231     {
1232         vnThreadsRunning[6]++;
1233         ThreadDNSAddressSeed2(parg);
1234         vnThreadsRunning[6]--;
1235     }
1236     catch (std::exception& e) {
1237         vnThreadsRunning[6]--;
1238         PrintException(&e, "ThreadDNSAddressSeed()");
1239     } catch (...) {
1240         vnThreadsRunning[6]--;
1241         throw; // support pthread_cancel()
1242     }
1243     printf("ThreadDNSAddressSeed exiting\n");
1244 }
1245
1246 void ThreadDNSAddressSeed2(void* parg)
1247 {
1248     printf("ThreadDNSAddressSeed started\n");
1249     int found = 0;
1250
1251     if (!fTestNet)
1252     {
1253         printf("Loading addresses from DNS seeds (could take a while)\n");
1254
1255         for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1256             vector<CAddress> vaddr;
1257             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1258             {
1259                 CAddrDB addrDB;
1260                 addrDB.TxnBegin();
1261                 BOOST_FOREACH (CAddress& addr, vaddr)
1262                 {
1263                     if (addr.GetByte(3) != 127)
1264                     {
1265                         addr.nTime = 0;
1266                         AddAddress(addr, 0, &addrDB);
1267                         found++;
1268                     }
1269                 }
1270                 addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1271             }
1272         }
1273     }
1274
1275     printf("%d addresses found from DNS seeds\n", found);
1276 }
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289 unsigned int pnSeed[] =
1290 {
1291     0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1292     0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1293     0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1294     0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1295     0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1296     0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1297     0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1298     0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1299     0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1300     0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1301     0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1302     0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1303     0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1304     0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1305     0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1306     0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1307     0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1308     0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1309     0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1310     0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1311     0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1312     0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1313     0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1314     0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1315     0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1316     0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1317     0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1318     0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1319     0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1320     0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1321     0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1322     0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1323     0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1324     0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1325     0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1326     0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1327     0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1328     0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1329     0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1330     0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1331     0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1332     0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1333     0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1334     0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1335     0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1336     0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1337     0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1338     0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1339     0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1340     0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1341     0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1342     0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1343     0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1344     0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1345     0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1346     0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1347     0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1348     0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1349     0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1350     0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1351     0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1352     0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1353     0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1354     0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1355     0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1356     0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1357     0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1358     0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1359     0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1360     0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1361     0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1362     0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1363     0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1364     0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1365     0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1366     0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1367     0xc461d84a, 0xb2dbe247,
1368 };
1369
1370
1371
1372 void ThreadOpenConnections(void* parg)
1373 {
1374     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1375     try
1376     {
1377         vnThreadsRunning[1]++;
1378         ThreadOpenConnections2(parg);
1379         vnThreadsRunning[1]--;
1380     }
1381     catch (std::exception& e) {
1382         vnThreadsRunning[1]--;
1383         PrintException(&e, "ThreadOpenConnections()");
1384     } catch (...) {
1385         vnThreadsRunning[1]--;
1386         PrintException(NULL, "ThreadOpenConnections()");
1387     }
1388     printf("ThreadOpenConnections exiting\n");
1389 }
1390
1391 void ThreadOpenConnections2(void* parg)
1392 {
1393     printf("ThreadOpenConnections started\n");
1394
1395     // Connect to specific addresses
1396     if (mapArgs.count("-connect"))
1397     {
1398         for (int64 nLoop = 0;; nLoop++)
1399         {
1400             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1401             {
1402                 CAddress addr(strAddr, fAllowDNS);
1403                 if (addr.IsValid())
1404                     OpenNetworkConnection(addr);
1405                 for (int i = 0; i < 10 && i < nLoop; i++)
1406                 {
1407                     Sleep(500);
1408                     if (fShutdown)
1409                         return;
1410                 }
1411             }
1412         }
1413     }
1414
1415     // Connect to manually added nodes first
1416     if (mapArgs.count("-addnode"))
1417     {
1418         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1419         {
1420             CAddress addr(strAddr, fAllowDNS);
1421             if (addr.IsValid())
1422             {
1423                 OpenNetworkConnection(addr);
1424                 Sleep(500);
1425                 if (fShutdown)
1426                     return;
1427             }
1428         }
1429     }
1430
1431     // Initiate network connections
1432     int64 nStart = GetTime();
1433     loop
1434     {
1435         vnThreadsRunning[1]--;
1436         Sleep(500);
1437         vnThreadsRunning[1]++;
1438         if (fShutdown)
1439             return;
1440
1441         // Limit outbound connections
1442         loop
1443         {
1444             int nOutbound = 0;
1445             CRITICAL_BLOCK(cs_vNodes)
1446                 BOOST_FOREACH(CNode* pnode, vNodes)
1447                     if (!pnode->fInbound)
1448                         nOutbound++;
1449             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1450             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1451             if (nOutbound < nMaxOutboundConnections)
1452                 break;
1453             vnThreadsRunning[1]--;
1454             Sleep(2000);
1455             vnThreadsRunning[1]++;
1456             if (fShutdown)
1457                 return;
1458         }
1459
1460         bool fAddSeeds = false;
1461
1462         CRITICAL_BLOCK(cs_mapAddresses)
1463         {
1464             // Add seed nodes if IRC isn't working
1465             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1466             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
1467                 fAddSeeds = true;
1468         }
1469
1470         if (fAddSeeds)
1471         {
1472             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1473             {
1474                 // It'll only connect to one or two seed nodes because once it connects,
1475                 // it'll get a pile of addresses with newer timestamps.
1476                 // Seed nodes are given a random 'last seen time' of between one and two
1477                 // weeks ago.
1478                 const int64 nOneWeek = 7*24*60*60;
1479                 CAddress addr;
1480                 addr.ip = pnSeed[i];
1481                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1482                 AddAddress(addr);
1483             }
1484         }
1485
1486         //
1487         // Choose an address to connect to based on most recently seen
1488         //
1489         CAddress addrConnect;
1490         int64 nBest = INT64_MIN;
1491
1492         // Only connect to one address per a.b.?.? range.
1493         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1494         set<unsigned int> setConnected;
1495         CRITICAL_BLOCK(cs_vNodes)
1496             BOOST_FOREACH(CNode* pnode, vNodes)
1497                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1498
1499         CRITICAL_BLOCK(cs_mapAddresses)
1500         {
1501             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1502             {
1503                 const CAddress& addr = item.second;
1504                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1505                     continue;
1506                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1507                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1508
1509                 // Randomize the order in a deterministic way, putting the standard port first
1510                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1511                 if (addr.port != htons(GetDefaultPort()))
1512                     nRandomizer += 2 * 60 * 60;
1513
1514                 // Last seen  Base retry frequency
1515                 //   <1 hour   10 min
1516                 //    1 hour    1 hour
1517                 //    4 hours   2 hours
1518                 //   24 hours   5 hours
1519                 //   48 hours   7 hours
1520                 //    7 days   13 hours
1521                 //   30 days   27 hours
1522                 //   90 days   46 hours
1523                 //  365 days   93 hours
1524                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1525
1526                 // Fast reconnect for one hour after last seen
1527                 if (nSinceLastSeen < 60 * 60)
1528                     nDelay = 10 * 60;
1529
1530                 // Limit retry frequency
1531                 if (nSinceLastTry < nDelay)
1532                     continue;
1533
1534                 // If we have IRC, we'll be notified when they first come online,
1535                 // and again every 24 hours by the refresh broadcast.
1536                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1537                     continue;
1538
1539                 // Only try the old stuff if we don't have enough connections
1540                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1541                     continue;
1542
1543                 // If multiple addresses are ready, prioritize by time since
1544                 // last seen and time since last tried.
1545                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1546                 if (nScore > nBest)
1547                 {
1548                     nBest = nScore;
1549                     addrConnect = addr;
1550                 }
1551             }
1552         }
1553
1554         if (addrConnect.IsValid())
1555             OpenNetworkConnection(addrConnect);
1556     }
1557 }
1558
1559 bool OpenNetworkConnection(const CAddress& addrConnect)
1560 {
1561     //
1562     // Initiate outbound network connection
1563     //
1564     if (fShutdown)
1565         return false;
1566     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1567         return false;
1568
1569     vnThreadsRunning[1]--;
1570     CNode* pnode = ConnectNode(addrConnect);
1571     vnThreadsRunning[1]++;
1572     if (fShutdown)
1573         return false;
1574     if (!pnode)
1575         return false;
1576     pnode->fNetworkNode = true;
1577
1578     return true;
1579 }
1580
1581
1582
1583
1584
1585
1586
1587
1588 void ThreadMessageHandler(void* parg)
1589 {
1590     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1591     try
1592     {
1593         vnThreadsRunning[2]++;
1594         ThreadMessageHandler2(parg);
1595         vnThreadsRunning[2]--;
1596     }
1597     catch (std::exception& e) {
1598         vnThreadsRunning[2]--;
1599         PrintException(&e, "ThreadMessageHandler()");
1600     } catch (...) {
1601         vnThreadsRunning[2]--;
1602         PrintException(NULL, "ThreadMessageHandler()");
1603     }
1604     printf("ThreadMessageHandler exiting\n");
1605 }
1606
1607 void ThreadMessageHandler2(void* parg)
1608 {
1609     printf("ThreadMessageHandler started\n");
1610     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1611     while (!fShutdown)
1612     {
1613         vector<CNode*> vNodesCopy;
1614         CRITICAL_BLOCK(cs_vNodes)
1615         {
1616             vNodesCopy = vNodes;
1617             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1618                 pnode->AddRef();
1619         }
1620
1621         // Poll the connected nodes for messages
1622         CNode* pnodeTrickle = NULL;
1623         if (!vNodesCopy.empty())
1624             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1625         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1626         {
1627             // Receive messages
1628             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1629                 ProcessMessages(pnode);
1630             if (fShutdown)
1631                 return;
1632
1633             // Send messages
1634             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1635                 SendMessages(pnode, pnode == pnodeTrickle);
1636             if (fShutdown)
1637                 return;
1638         }
1639
1640         CRITICAL_BLOCK(cs_vNodes)
1641         {
1642             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1643                 pnode->Release();
1644         }
1645
1646         // Wait and allow messages to bunch up.
1647         // Reduce vnThreadsRunning so StopNode has permission to exit while
1648         // we're sleeping, but we must always check fShutdown after doing this.
1649         vnThreadsRunning[2]--;
1650         Sleep(100);
1651         if (fRequestShutdown)
1652             Shutdown(NULL);
1653         vnThreadsRunning[2]++;
1654         if (fShutdown)
1655             return;
1656     }
1657 }
1658
1659
1660
1661
1662
1663
1664 bool BindListenPort(string& strError)
1665 {
1666     strError = "";
1667     int nOne = 1;
1668     addrLocalHost.port = htons(GetListenPort());
1669
1670 #ifdef __WXMSW__
1671     // Initialize Windows Sockets
1672     WSADATA wsadata;
1673     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1674     if (ret != NO_ERROR)
1675     {
1676         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1677         printf("%s\n", strError.c_str());
1678         return false;
1679     }
1680 #endif
1681
1682     // Create socket for listening for incoming connections
1683     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1684     if (hListenSocket == INVALID_SOCKET)
1685     {
1686         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1687         printf("%s\n", strError.c_str());
1688         return false;
1689     }
1690
1691 #ifdef SO_NOSIGPIPE
1692     // Different way of disabling SIGPIPE on BSD
1693     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1694 #endif
1695
1696 #ifndef __WXMSW__
1697     // Allow binding if the port is still in TIME_WAIT state after
1698     // the program was closed and restarted.  Not an issue on windows.
1699     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1700 #endif
1701
1702 #ifdef __WXMSW__
1703     // Set to nonblocking, incoming connections will also inherit this
1704     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1705 #else
1706     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1707 #endif
1708     {
1709         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1710         printf("%s\n", strError.c_str());
1711         return false;
1712     }
1713
1714     // The sockaddr_in structure specifies the address family,
1715     // IP address, and port for the socket that is being bound
1716     struct sockaddr_in sockaddr;
1717     memset(&sockaddr, 0, sizeof(sockaddr));
1718     sockaddr.sin_family = AF_INET;
1719     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1720     sockaddr.sin_port = htons(GetListenPort());
1721     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1722     {
1723         int nErr = WSAGetLastError();
1724         if (nErr == WSAEADDRINUSE)
1725             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1726         else
1727             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1728         printf("%s\n", strError.c_str());
1729         return false;
1730     }
1731     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1732
1733     // Listen for incoming connections
1734     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1735     {
1736         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1737         printf("%s\n", strError.c_str());
1738         return false;
1739     }
1740
1741     return true;
1742 }
1743
1744 void StartNode(void* parg)
1745 {
1746     if (pnodeLocalHost == NULL)
1747         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1748
1749 #ifdef __WXMSW__
1750     // Get local host ip
1751     char pszHostName[1000] = "";
1752     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1753     {
1754         vector<CAddress> vaddr;
1755         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1756             BOOST_FOREACH (const CAddress &addr, vaddr)
1757                 if (addr.GetByte(3) != 127)
1758                 {
1759                     addrLocalHost = addr;
1760                     break;
1761                 }
1762     }
1763 #else
1764     // Get local host ip
1765     struct ifaddrs* myaddrs;
1766     if (getifaddrs(&myaddrs) == 0)
1767     {
1768         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1769         {
1770             if (ifa->ifa_addr == NULL) continue;
1771             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1772             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1773             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1774             char pszIP[100];
1775             if (ifa->ifa_addr->sa_family == AF_INET)
1776             {
1777                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1778                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1779                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1780
1781                 // Take the first IP that isn't loopback 127.x.x.x
1782                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1783                 if (addr.IsValid() && addr.GetByte(3) != 127)
1784                 {
1785                     addrLocalHost = addr;
1786                     break;
1787                 }
1788             }
1789             else if (ifa->ifa_addr->sa_family == AF_INET6)
1790             {
1791                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1792                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1793                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1794             }
1795         }
1796         freeifaddrs(myaddrs);
1797     }
1798 #endif
1799     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1800
1801     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1802     {
1803         // Proxies can't take incoming connections
1804         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1805         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1806     }
1807     else
1808     {
1809         CreateThread(ThreadGetMyExternalIP, NULL);
1810     }
1811
1812     //
1813     // Start threads
1814     //
1815
1816     if (GetBoolArg("-nodnsseed"))
1817         printf("DNS seeding disabled\n");
1818     else
1819         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1820             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1821
1822     // Map ports with UPnP
1823     if (fHaveUPnP)
1824         MapPort(fUseUPnP);
1825
1826     // Get addresses from IRC and advertise ours
1827     if (!CreateThread(ThreadIRCSeed, NULL))
1828         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1829
1830     // Send and receive from sockets, accept connections
1831     if (!CreateThread(ThreadSocketHandler, NULL))
1832         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1833
1834     // Initiate outbound connections
1835     if (!CreateThread(ThreadOpenConnections, NULL))
1836         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1837
1838     // Process messages
1839     if (!CreateThread(ThreadMessageHandler, NULL))
1840         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1841
1842     // Generate coins in the background
1843     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1844 }
1845
1846 bool StopNode()
1847 {
1848     printf("StopNode()\n");
1849     fShutdown = true;
1850     nTransactionsUpdated++;
1851     int64 nStart = GetTime();
1852     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1853 #ifdef USE_UPNP
1854         || vnThreadsRunning[5] > 0
1855 #endif
1856     )
1857     {
1858         if (GetTime() - nStart > 20)
1859             break;
1860         Sleep(20);
1861     }
1862     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1863     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1864     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1865     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1866     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1867     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1868     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1869     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1870         Sleep(20);
1871     Sleep(50);
1872
1873     return true;
1874 }
1875
1876 class CNetCleanup
1877 {
1878 public:
1879     CNetCleanup()
1880     {
1881     }
1882     ~CNetCleanup()
1883     {
1884         // Close sockets
1885         BOOST_FOREACH(CNode* pnode, vNodes)
1886             if (pnode->hSocket != INVALID_SOCKET)
1887                 closesocket(pnode->hSocket);
1888         if (hListenSocket != INVALID_SOCKET)
1889             if (closesocket(hListenSocket) == SOCKET_ERROR)
1890                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1891
1892 #ifdef __WXMSW__
1893         // Shutdown Windows Sockets
1894         WSACleanup();
1895 #endif
1896     }
1897 }
1898 instance_of_cnetcleanup;