Bugfix: do not create CAddress for invalid accepts
[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         // Limit outbound connections
1435         vnThreadsRunning[1]--;
1436         Sleep(500);
1437         loop
1438         {
1439             int nOutbound = 0;
1440             CRITICAL_BLOCK(cs_vNodes)
1441                 BOOST_FOREACH(CNode* pnode, vNodes)
1442                     if (!pnode->fInbound)
1443                         nOutbound++;
1444             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1445             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1446             if (nOutbound < nMaxOutboundConnections)
1447                 break;
1448             Sleep(2000);
1449             if (fShutdown)
1450                 return;
1451         }
1452         vnThreadsRunning[1]++;
1453         if (fShutdown)
1454             return;
1455
1456         bool fAddSeeds = false;
1457
1458         CRITICAL_BLOCK(cs_mapAddresses)
1459         {
1460             // Add seed nodes if IRC isn't working
1461             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1462             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fUseProxy) && !fTestNet)
1463                 fAddSeeds = true;
1464         }
1465
1466         if (fAddSeeds)
1467         {
1468             for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1469             {
1470                 // It'll only connect to one or two seed nodes because once it connects,
1471                 // it'll get a pile of addresses with newer timestamps.
1472                 // Seed nodes are given a random 'last seen time' of between one and two
1473                 // weeks ago.
1474                 const int64 nOneWeek = 7*24*60*60;
1475                 CAddress addr;
1476                 addr.ip = pnSeed[i];
1477                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1478                 AddAddress(addr);
1479             }
1480         }
1481
1482         //
1483         // Choose an address to connect to based on most recently seen
1484         //
1485         CAddress addrConnect;
1486         int64 nBest = INT64_MIN;
1487
1488         // Only connect to one address per a.b.?.? range.
1489         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1490         set<unsigned int> setConnected;
1491         CRITICAL_BLOCK(cs_vNodes)
1492             BOOST_FOREACH(CNode* pnode, vNodes)
1493                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1494
1495         CRITICAL_BLOCK(cs_mapAddresses)
1496         {
1497             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1498             {
1499                 const CAddress& addr = item.second;
1500                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1501                     continue;
1502                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1503                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1504
1505                 // Randomize the order in a deterministic way, putting the standard port first
1506                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1507                 if (addr.port != htons(GetDefaultPort()))
1508                     nRandomizer += 2 * 60 * 60;
1509
1510                 // Last seen  Base retry frequency
1511                 //   <1 hour   10 min
1512                 //    1 hour    1 hour
1513                 //    4 hours   2 hours
1514                 //   24 hours   5 hours
1515                 //   48 hours   7 hours
1516                 //    7 days   13 hours
1517                 //   30 days   27 hours
1518                 //   90 days   46 hours
1519                 //  365 days   93 hours
1520                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1521
1522                 // Fast reconnect for one hour after last seen
1523                 if (nSinceLastSeen < 60 * 60)
1524                     nDelay = 10 * 60;
1525
1526                 // Limit retry frequency
1527                 if (nSinceLastTry < nDelay)
1528                     continue;
1529
1530                 // If we have IRC, we'll be notified when they first come online,
1531                 // and again every 24 hours by the refresh broadcast.
1532                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1533                     continue;
1534
1535                 // Only try the old stuff if we don't have enough connections
1536                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1537                     continue;
1538
1539                 // If multiple addresses are ready, prioritize by time since
1540                 // last seen and time since last tried.
1541                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1542                 if (nScore > nBest)
1543                 {
1544                     nBest = nScore;
1545                     addrConnect = addr;
1546                 }
1547             }
1548         }
1549
1550         if (addrConnect.IsValid())
1551             OpenNetworkConnection(addrConnect);
1552     }
1553 }
1554
1555 bool OpenNetworkConnection(const CAddress& addrConnect)
1556 {
1557     //
1558     // Initiate outbound network connection
1559     //
1560     if (fShutdown)
1561         return false;
1562     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1563         return false;
1564
1565     vnThreadsRunning[1]--;
1566     CNode* pnode = ConnectNode(addrConnect);
1567     vnThreadsRunning[1]++;
1568     if (fShutdown)
1569         return false;
1570     if (!pnode)
1571         return false;
1572     pnode->fNetworkNode = true;
1573
1574     return true;
1575 }
1576
1577
1578
1579
1580
1581
1582
1583
1584 void ThreadMessageHandler(void* parg)
1585 {
1586     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1587     try
1588     {
1589         vnThreadsRunning[2]++;
1590         ThreadMessageHandler2(parg);
1591         vnThreadsRunning[2]--;
1592     }
1593     catch (std::exception& e) {
1594         vnThreadsRunning[2]--;
1595         PrintException(&e, "ThreadMessageHandler()");
1596     } catch (...) {
1597         vnThreadsRunning[2]--;
1598         PrintException(NULL, "ThreadMessageHandler()");
1599     }
1600     printf("ThreadMessageHandler exiting\n");
1601 }
1602
1603 void ThreadMessageHandler2(void* parg)
1604 {
1605     printf("ThreadMessageHandler started\n");
1606     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1607     while (!fShutdown)
1608     {
1609         vector<CNode*> vNodesCopy;
1610         CRITICAL_BLOCK(cs_vNodes)
1611         {
1612             vNodesCopy = vNodes;
1613             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1614                 pnode->AddRef();
1615         }
1616
1617         // Poll the connected nodes for messages
1618         CNode* pnodeTrickle = NULL;
1619         if (!vNodesCopy.empty())
1620             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1621         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1622         {
1623             // Receive messages
1624             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1625                 ProcessMessages(pnode);
1626             if (fShutdown)
1627                 return;
1628
1629             // Send messages
1630             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1631                 SendMessages(pnode, pnode == pnodeTrickle);
1632             if (fShutdown)
1633                 return;
1634         }
1635
1636         CRITICAL_BLOCK(cs_vNodes)
1637         {
1638             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1639                 pnode->Release();
1640         }
1641
1642         // Wait and allow messages to bunch up.
1643         // Reduce vnThreadsRunning so StopNode has permission to exit while
1644         // we're sleeping, but we must always check fShutdown after doing this.
1645         vnThreadsRunning[2]--;
1646         Sleep(100);
1647         if (fRequestShutdown)
1648             Shutdown(NULL);
1649         vnThreadsRunning[2]++;
1650         if (fShutdown)
1651             return;
1652     }
1653 }
1654
1655
1656
1657
1658
1659
1660 bool BindListenPort(string& strError)
1661 {
1662     strError = "";
1663     int nOne = 1;
1664     addrLocalHost.port = htons(GetListenPort());
1665
1666 #ifdef __WXMSW__
1667     // Initialize Windows Sockets
1668     WSADATA wsadata;
1669     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1670     if (ret != NO_ERROR)
1671     {
1672         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1673         printf("%s\n", strError.c_str());
1674         return false;
1675     }
1676 #endif
1677
1678     // Create socket for listening for incoming connections
1679     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1680     if (hListenSocket == INVALID_SOCKET)
1681     {
1682         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1683         printf("%s\n", strError.c_str());
1684         return false;
1685     }
1686
1687 #ifdef SO_NOSIGPIPE
1688     // Different way of disabling SIGPIPE on BSD
1689     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1690 #endif
1691
1692 #ifndef __WXMSW__
1693     // Allow binding if the port is still in TIME_WAIT state after
1694     // the program was closed and restarted.  Not an issue on windows.
1695     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1696 #endif
1697
1698 #ifdef __WXMSW__
1699     // Set to nonblocking, incoming connections will also inherit this
1700     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1701 #else
1702     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1703 #endif
1704     {
1705         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1706         printf("%s\n", strError.c_str());
1707         return false;
1708     }
1709
1710     // The sockaddr_in structure specifies the address family,
1711     // IP address, and port for the socket that is being bound
1712     struct sockaddr_in sockaddr;
1713     memset(&sockaddr, 0, sizeof(sockaddr));
1714     sockaddr.sin_family = AF_INET;
1715     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1716     sockaddr.sin_port = htons(GetListenPort());
1717     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1718     {
1719         int nErr = WSAGetLastError();
1720         if (nErr == WSAEADDRINUSE)
1721             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1722         else
1723             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1724         printf("%s\n", strError.c_str());
1725         return false;
1726     }
1727     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1728
1729     // Listen for incoming connections
1730     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1731     {
1732         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1733         printf("%s\n", strError.c_str());
1734         return false;
1735     }
1736
1737     return true;
1738 }
1739
1740 void StartNode(void* parg)
1741 {
1742     if (pnodeLocalHost == NULL)
1743         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1744
1745 #ifdef __WXMSW__
1746     // Get local host ip
1747     char pszHostName[1000] = "";
1748     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1749     {
1750         vector<CAddress> vaddr;
1751         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1752             BOOST_FOREACH (const CAddress &addr, vaddr)
1753                 if (addr.GetByte(3) != 127)
1754                 {
1755                     addrLocalHost = addr;
1756                     break;
1757                 }
1758     }
1759 #else
1760     // Get local host ip
1761     struct ifaddrs* myaddrs;
1762     if (getifaddrs(&myaddrs) == 0)
1763     {
1764         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1765         {
1766             if (ifa->ifa_addr == NULL) continue;
1767             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1768             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1769             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1770             char pszIP[100];
1771             if (ifa->ifa_addr->sa_family == AF_INET)
1772             {
1773                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1774                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1775                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1776
1777                 // Take the first IP that isn't loopback 127.x.x.x
1778                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1779                 if (addr.IsValid() && addr.GetByte(3) != 127)
1780                 {
1781                     addrLocalHost = addr;
1782                     break;
1783                 }
1784             }
1785             else if (ifa->ifa_addr->sa_family == AF_INET6)
1786             {
1787                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1788                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1789                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1790             }
1791         }
1792         freeifaddrs(myaddrs);
1793     }
1794 #endif
1795     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1796
1797     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1798     {
1799         // Proxies can't take incoming connections
1800         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1801         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1802     }
1803     else
1804     {
1805         CreateThread(ThreadGetMyExternalIP, NULL);
1806     }
1807
1808     //
1809     // Start threads
1810     //
1811
1812     if (GetBoolArg("-nodnsseed"))
1813         printf("DNS seeding disabled\n");
1814     else
1815         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1816             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1817
1818     // Map ports with UPnP
1819     if (fHaveUPnP)
1820         MapPort(fUseUPnP);
1821
1822     // Get addresses from IRC and advertise ours
1823     if (!CreateThread(ThreadIRCSeed, NULL))
1824         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1825
1826     // Send and receive from sockets, accept connections
1827     if (!CreateThread(ThreadSocketHandler, NULL))
1828         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1829
1830     // Initiate outbound connections
1831     if (!CreateThread(ThreadOpenConnections, NULL))
1832         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1833
1834     // Process messages
1835     if (!CreateThread(ThreadMessageHandler, NULL))
1836         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1837
1838     // Generate coins in the background
1839     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1840 }
1841
1842 bool StopNode()
1843 {
1844     printf("StopNode()\n");
1845     fShutdown = true;
1846     nTransactionsUpdated++;
1847     int64 nStart = GetTime();
1848     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1849 #ifdef USE_UPNP
1850         || vnThreadsRunning[5] > 0
1851 #endif
1852     )
1853     {
1854         if (GetTime() - nStart > 20)
1855             break;
1856         Sleep(20);
1857     }
1858     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1859     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1860     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1861     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1862     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1863     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1864     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1865     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1866         Sleep(20);
1867     Sleep(50);
1868
1869     return true;
1870 }
1871
1872 class CNetCleanup
1873 {
1874 public:
1875     CNetCleanup()
1876     {
1877     }
1878     ~CNetCleanup()
1879     {
1880         // Close sockets
1881         BOOST_FOREACH(CNode* pnode, vNodes)
1882             if (pnode->hSocket != INVALID_SOCKET)
1883                 closesocket(pnode->hSocket);
1884         if (hListenSocket != INVALID_SOCKET)
1885             if (closesocket(hListenSocket) == SOCKET_ERROR)
1886                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1887
1888 #ifdef __WXMSW__
1889         // Shutdown Windows Sockets
1890         WSACleanup();
1891 #endif
1892     }
1893 }
1894 instance_of_cnetcleanup;