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