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