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