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