bitcoind changes to stop storing settings in wallet.dat.
[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 static bool fUseUPnP = false;
47 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
48 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
49 static CNode* pnodeLocalHost = NULL;
50 uint64 nLocalHostNonce = 0;
51 array<int, THREAD_MAX> vnThreadsRunning;
52 static SOCKET hListenSocket = INVALID_SOCKET;
53
54 vector<CNode*> vNodes;
55 CCriticalSection cs_vNodes;
56 map<vector<unsigned char>, CAddress> mapAddresses;
57 CCriticalSection cs_mapAddresses;
58 map<CInv, CDataStream> mapRelay;
59 deque<pair<int64, CInv> > vRelayExpiration;
60 CCriticalSection cs_mapRelay;
61 map<CInv, int64> mapAlreadyAskedFor;
62
63
64 set<CNetAddr> setservAddNodeAddresses;
65 CCriticalSection cs_setservAddNodeAddresses;
66
67
68
69 unsigned short GetListenPort()
70 {
71     return (unsigned short)(GetArg("-port", GetDefaultPort()));
72 }
73
74 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
75 {
76     // Filter out duplicate requests
77     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
78         return;
79     pindexLastGetBlocksBegin = pindexBegin;
80     hashLastGetBlocksEnd = hashEnd;
81
82     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
83 }
84
85
86
87 bool RecvLine(SOCKET hSocket, string& strLine)
88 {
89     strLine = "";
90     loop
91     {
92         char c;
93         int nBytes = recv(hSocket, &c, 1, 0);
94         if (nBytes > 0)
95         {
96             if (c == '\n')
97                 continue;
98             if (c == '\r')
99                 return true;
100             strLine += c;
101             if (strLine.size() >= 9000)
102                 return true;
103         }
104         else if (nBytes <= 0)
105         {
106             if (fShutdown)
107                 return false;
108             if (nBytes < 0)
109             {
110                 int nErr = WSAGetLastError();
111                 if (nErr == WSAEMSGSIZE)
112                     continue;
113                 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
114                 {
115                     Sleep(10);
116                     continue;
117                 }
118             }
119             if (!strLine.empty())
120                 return true;
121             if (nBytes == 0)
122             {
123                 // socket closed
124                 printf("socket closed\n");
125                 return false;
126             }
127             else
128             {
129                 // socket error
130                 int nErr = WSAGetLastError();
131                 printf("recv failed: %d\n", nErr);
132                 return false;
133             }
134         }
135     }
136 }
137
138
139
140 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
141 {
142     SOCKET hSocket;
143     if (!ConnectSocket(addrConnect, hSocket))
144         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
145
146     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
147
148     string strLine;
149     while (RecvLine(hSocket, strLine))
150     {
151         if (strLine.empty()) // HTTP response is separated from headers by blank line
152         {
153             loop
154             {
155                 if (!RecvLine(hSocket, strLine))
156                 {
157                     closesocket(hSocket);
158                     return false;
159                 }
160                 if (pszKeyword == NULL)
161                     break;
162                 if (strLine.find(pszKeyword) != -1)
163                 {
164                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
165                     break;
166                 }
167             }
168             closesocket(hSocket);
169             if (strLine.find("<") != -1)
170                 strLine = strLine.substr(0, strLine.find("<"));
171             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
172             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
173                 strLine.resize(strLine.size()-1);
174             CService addr(strLine,0,true);
175             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
176             if (!addr.IsValid() || !addr.IsRoutable())
177                 return false;
178             ipRet.SetIP(addr);
179             return true;
180         }
181     }
182     closesocket(hSocket);
183     return error("GetMyExternalIP() : connection closed");
184 }
185
186 // We now get our external IP from the IRC server first and only use this as a backup
187 bool GetMyExternalIP(CNetAddr& ipRet)
188 {
189     CService addrConnect;
190     const char* pszGet;
191     const char* pszKeyword;
192
193     if (fNoListen||fUseProxy)
194         return false;
195
196     for (int nLookup = 0; nLookup <= 1; nLookup++)
197     for (int nHost = 1; nHost <= 2; nHost++)
198     {
199         // We should be phasing out our use of sites like these.  If we need
200         // replacements, we should ask for volunteers to put this simple
201         // php file on their webserver that prints the client IP:
202         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
203         if (nHost == 1)
204         {
205             addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
206
207             if (nLookup == 1)
208             {
209                 CService addrIP("checkip.dyndns.org", 80, true);
210                 if (addrIP.IsValid())
211                     addrConnect = addrIP;
212             }
213
214             pszGet = "GET / HTTP/1.1\r\n"
215                      "Host: checkip.dyndns.org\r\n"
216                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
217                      "Connection: close\r\n"
218                      "\r\n";
219
220             pszKeyword = "Address:";
221         }
222         else if (nHost == 2)
223         {
224             addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
225
226             if (nLookup == 1)
227             {
228                 CService addrIP("www.showmyip.com", 80, true);
229                 if (addrIP.IsValid())
230                     addrConnect = addrIP;
231             }
232
233             pszGet = "GET /simple/ HTTP/1.1\r\n"
234                      "Host: www.showmyip.com\r\n"
235                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
236                      "Connection: close\r\n"
237                      "\r\n";
238
239             pszKeyword = NULL; // Returns just IP address
240         }
241
242         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
243             return true;
244     }
245
246     return false;
247 }
248
249 void ThreadGetMyExternalIP(void* parg)
250 {
251     // Wait for IRC to get it first
252     if (GetBoolArg("-irc", false))
253     {
254         for (int i = 0; i < 2 * 60; i++)
255         {
256             Sleep(1000);
257             if (fGotExternalIP || fShutdown)
258                 return;
259         }
260     }
261
262     // Fallback in case IRC fails to get it
263     if (GetMyExternalIP(addrLocalHost))
264     {
265         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
266         if (addrLocalHost.IsRoutable())
267         {
268             // If we already connected to a few before we had our IP, go back and addr them.
269             // setAddrKnown automatically filters any duplicate sends.
270             CAddress addr(addrLocalHost);
271             addr.nTime = GetAdjustedTime();
272             CRITICAL_BLOCK(cs_vNodes)
273                 BOOST_FOREACH(CNode* pnode, vNodes)
274                     pnode->PushAddress(addr);
275         }
276     }
277 }
278
279
280
281
282
283 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
284 {
285     if (!addr.IsRoutable())
286         return false;
287     if ((CService)addr == (CService)addrLocalHost)
288         return false;
289     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
290     bool fUpdated = false;
291     bool fNew = false;
292     CAddress addrFound = addr;
293
294     CRITICAL_BLOCK(cs_mapAddresses)
295     {
296         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
297         if (it == mapAddresses.end())
298         {
299             // New address
300             printf("AddAddress(%s)\n", addr.ToString().c_str());
301             mapAddresses.insert(make_pair(addr.GetKey(), addr));
302             fUpdated = true;
303             fNew = true;
304         }
305         else
306         {
307             addrFound = (*it).second;
308             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
309             {
310                 // Services have been added
311                 addrFound.nServices |= addr.nServices;
312                 fUpdated = true;
313             }
314             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
315             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
316             if (addrFound.nTime < addr.nTime - nUpdateInterval)
317             {
318                 // Periodically update most recently seen time
319                 addrFound.nTime = addr.nTime;
320                 fUpdated = true;
321             }
322         }
323     }
324     // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
325     // CRITICAL_BLOCK:
326     // Thread 1:  begin db transaction (locks inside-db-mutex)
327     //            then AddAddress (locks cs_mapAddresses)
328     // Thread 2:  AddAddress (locks cs_mapAddresses)
329     //             ... then db operation hangs waiting for inside-db-mutex
330     if (fUpdated)
331     {
332         if (pAddrDB)
333             pAddrDB->WriteAddress(addrFound);
334         else
335             CAddrDB().WriteAddress(addrFound);
336     }
337     return fNew;
338 }
339
340 void AddressCurrentlyConnected(const CService& addr)
341 {
342     CAddress *paddrFound = NULL;
343
344     CRITICAL_BLOCK(cs_mapAddresses)
345     {
346         // Only if it's been published already
347         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
348         if (it != mapAddresses.end())
349             paddrFound = &(*it).second;
350     }
351
352     if (paddrFound)
353     {
354         int64 nUpdateInterval = 20 * 60;
355         if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
356         {
357             // Periodically update most recently seen time
358             paddrFound->nTime = GetAdjustedTime();
359             CAddrDB addrdb;
360             addrdb.WriteAddress(*paddrFound);
361         }
362     }
363 }
364
365
366
367
368
369 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
370 {
371     // If the dialog might get closed before the reply comes back,
372     // call this in the destructor so it doesn't get called after it's deleted.
373     CRITICAL_BLOCK(cs_vNodes)
374     {
375         BOOST_FOREACH(CNode* pnode, vNodes)
376         {
377             CRITICAL_BLOCK(pnode->cs_mapRequests)
378             {
379                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
380                 {
381                     CRequestTracker& tracker = (*mi).second;
382                     if (tracker.fn == fn && tracker.param1 == param1)
383                         pnode->mapRequests.erase(mi++);
384                     else
385                         mi++;
386                 }
387             }
388         }
389     }
390 }
391
392
393
394
395
396
397
398 //
399 // Subscription methods for the broadcast and subscription system.
400 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
401 //
402 // The subscription system uses a meet-in-the-middle strategy.
403 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
404 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
405 //
406
407 bool AnySubscribed(unsigned int nChannel)
408 {
409     if (pnodeLocalHost->IsSubscribed(nChannel))
410         return true;
411     CRITICAL_BLOCK(cs_vNodes)
412         BOOST_FOREACH(CNode* pnode, vNodes)
413             if (pnode->IsSubscribed(nChannel))
414                 return true;
415     return false;
416 }
417
418 bool CNode::IsSubscribed(unsigned int nChannel)
419 {
420     if (nChannel >= vfSubscribe.size())
421         return false;
422     return vfSubscribe[nChannel];
423 }
424
425 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
426 {
427     if (nChannel >= vfSubscribe.size())
428         return;
429
430     if (!AnySubscribed(nChannel))
431     {
432         // Relay subscribe
433         CRITICAL_BLOCK(cs_vNodes)
434             BOOST_FOREACH(CNode* pnode, vNodes)
435                 if (pnode != this)
436                     pnode->PushMessage("subscribe", nChannel, nHops);
437     }
438
439     vfSubscribe[nChannel] = true;
440 }
441
442 void CNode::CancelSubscribe(unsigned int nChannel)
443 {
444     if (nChannel >= vfSubscribe.size())
445         return;
446
447     // Prevent from relaying cancel if wasn't subscribed
448     if (!vfSubscribe[nChannel])
449         return;
450     vfSubscribe[nChannel] = false;
451
452     if (!AnySubscribed(nChannel))
453     {
454         // Relay subscription cancel
455         CRITICAL_BLOCK(cs_vNodes)
456             BOOST_FOREACH(CNode* pnode, vNodes)
457                 if (pnode != this)
458                     pnode->PushMessage("sub-cancel", nChannel);
459     }
460 }
461
462
463
464
465
466
467
468
469
470 CNode* FindNode(const CNetAddr& ip)
471 {
472     CRITICAL_BLOCK(cs_vNodes)
473     {
474         BOOST_FOREACH(CNode* pnode, vNodes)
475             if ((CNetAddr)pnode->addr == ip)
476                 return (pnode);
477     }
478     return NULL;
479 }
480
481 CNode* FindNode(const CService& addr)
482 {
483     CRITICAL_BLOCK(cs_vNodes)
484     {
485         BOOST_FOREACH(CNode* pnode, vNodes)
486             if ((CService)pnode->addr == addr)
487                 return (pnode);
488     }
489     return NULL;
490 }
491
492 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
493 {
494     if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
495         return NULL;
496
497     // Look for an existing connection
498     CNode* pnode = FindNode((CService)addrConnect);
499     if (pnode)
500     {
501         if (nTimeout != 0)
502             pnode->AddRef(nTimeout);
503         else
504             pnode->AddRef();
505         return pnode;
506     }
507
508     /// debug print
509     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
510         addrConnect.ToString().c_str(),
511         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
512         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
513
514     CRITICAL_BLOCK(cs_mapAddresses)
515         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
516
517     // Connect
518     SOCKET hSocket;
519     if (ConnectSocket(addrConnect, hSocket))
520     {
521         /// debug print
522         printf("connected %s\n", addrConnect.ToString().c_str());
523
524         // Set to nonblocking
525 #ifdef WIN32
526         u_long nOne = 1;
527         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
528             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
529 #else
530         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
531             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
532 #endif
533
534         // Add node
535         CNode* pnode = new CNode(hSocket, addrConnect, false);
536         if (nTimeout != 0)
537             pnode->AddRef(nTimeout);
538         else
539             pnode->AddRef();
540         CRITICAL_BLOCK(cs_vNodes)
541             vNodes.push_back(pnode);
542
543         pnode->nTimeConnected = GetTime();
544         return pnode;
545     }
546     else
547     {
548         return NULL;
549     }
550 }
551
552 void CNode::CloseSocketDisconnect()
553 {
554     fDisconnect = true;
555     if (hSocket != INVALID_SOCKET)
556     {
557         if (fDebug)
558             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
559         printf("disconnecting node %s\n", addr.ToString().c_str());
560         closesocket(hSocket);
561         hSocket = INVALID_SOCKET;
562     }
563 }
564
565 void CNode::Cleanup()
566 {
567     // All of a nodes broadcasts and subscriptions are automatically torn down
568     // when it goes down, so a node has to stay up to keep its broadcast going.
569
570     // Cancel subscriptions
571     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
572         if (vfSubscribe[nChannel])
573             CancelSubscribe(nChannel);
574 }
575
576
577 void CNode::PushVersion()
578 {
579     /// when NTP implemented, change to just nTime = GetAdjustedTime()
580     int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
581     CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
582     CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
583     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
584     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
585                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
586 }
587
588
589
590
591
592 std::map<CNetAddr, int64> CNode::setBanned;
593 CCriticalSection CNode::cs_setBanned;
594
595 void CNode::ClearBanned()
596 {
597     setBanned.clear();
598 }
599
600 bool CNode::IsBanned(CNetAddr ip)
601 {
602     bool fResult = false;
603     CRITICAL_BLOCK(cs_setBanned)
604     {
605         std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
606         if (i != setBanned.end())
607         {
608             int64 t = (*i).second;
609             if (GetTime() < t)
610                 fResult = true;
611         }
612     }
613     return fResult;
614 }
615
616 bool CNode::Misbehaving(int howmuch)
617 {
618     if (addr.IsLocal())
619     {
620         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
621         return false;
622     }
623
624     nMisbehavior += howmuch;
625     if (nMisbehavior >= GetArg("-banscore", 100))
626     {
627         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
628         CRITICAL_BLOCK(cs_setBanned)
629             if (setBanned[addr] < banTime)
630                 setBanned[addr] = banTime;
631         CloseSocketDisconnect();
632         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
633         return true;
634     }
635     return false;
636 }
637
638
639
640
641
642
643
644
645
646
647
648
649 void ThreadSocketHandler(void* parg)
650 {
651     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
652     try
653     {
654         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
655         ThreadSocketHandler2(parg);
656         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
657     }
658     catch (std::exception& e) {
659         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
660         PrintException(&e, "ThreadSocketHandler()");
661     } catch (...) {
662         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
663         throw; // support pthread_cancel()
664     }
665     printf("ThreadSocketHandler exiting\n");
666 }
667
668 void ThreadSocketHandler2(void* parg)
669 {
670     printf("ThreadSocketHandler started\n");
671     list<CNode*> vNodesDisconnected;
672     int nPrevNodeCount = 0;
673
674     loop
675     {
676         //
677         // Disconnect nodes
678         //
679         CRITICAL_BLOCK(cs_vNodes)
680         {
681             // Disconnect unused nodes
682             vector<CNode*> vNodesCopy = vNodes;
683             BOOST_FOREACH(CNode* pnode, vNodesCopy)
684             {
685                 if (pnode->fDisconnect ||
686                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
687                 {
688                     // remove from vNodes
689                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
690
691                     // close socket and cleanup
692                     pnode->CloseSocketDisconnect();
693                     pnode->Cleanup();
694
695                     // hold in disconnected pool until all refs are released
696                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
697                     if (pnode->fNetworkNode || pnode->fInbound)
698                         pnode->Release();
699                     vNodesDisconnected.push_back(pnode);
700                 }
701             }
702
703             // Delete disconnected nodes
704             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
705             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
706             {
707                 // wait until threads are done using it
708                 if (pnode->GetRefCount() <= 0)
709                 {
710                     bool fDelete = false;
711                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
712                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
713                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
714                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
715                         fDelete = true;
716                     if (fDelete)
717                     {
718                         vNodesDisconnected.remove(pnode);
719                         delete pnode;
720                     }
721                 }
722             }
723         }
724         if (vNodes.size() != nPrevNodeCount)
725         {
726             nPrevNodeCount = vNodes.size();
727             MainFrameRepaint();
728         }
729
730
731         //
732         // Find which sockets have data to receive
733         //
734         struct timeval timeout;
735         timeout.tv_sec  = 0;
736         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
737
738         fd_set fdsetRecv;
739         fd_set fdsetSend;
740         fd_set fdsetError;
741         FD_ZERO(&fdsetRecv);
742         FD_ZERO(&fdsetSend);
743         FD_ZERO(&fdsetError);
744         SOCKET hSocketMax = 0;
745
746         if(hListenSocket != INVALID_SOCKET)
747             FD_SET(hListenSocket, &fdsetRecv);
748         hSocketMax = max(hSocketMax, hListenSocket);
749         CRITICAL_BLOCK(cs_vNodes)
750         {
751             BOOST_FOREACH(CNode* pnode, vNodes)
752             {
753                 if (pnode->hSocket == INVALID_SOCKET)
754                     continue;
755                 FD_SET(pnode->hSocket, &fdsetRecv);
756                 FD_SET(pnode->hSocket, &fdsetError);
757                 hSocketMax = max(hSocketMax, pnode->hSocket);
758                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
759                     if (!pnode->vSend.empty())
760                         FD_SET(pnode->hSocket, &fdsetSend);
761             }
762         }
763
764         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
765         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
766         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
767         if (fShutdown)
768             return;
769         if (nSelect == SOCKET_ERROR)
770         {
771             int nErr = WSAGetLastError();
772             if (hSocketMax > -1)
773             {
774                 printf("socket select error %d\n", nErr);
775                 for (int i = 0; i <= hSocketMax; i++)
776                     FD_SET(i, &fdsetRecv);
777             }
778             FD_ZERO(&fdsetSend);
779             FD_ZERO(&fdsetError);
780             Sleep(timeout.tv_usec/1000);
781         }
782
783
784         //
785         // Accept new connections
786         //
787         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
788         {
789             struct sockaddr_in sockaddr;
790             socklen_t len = sizeof(sockaddr);
791             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
792             CAddress addr;
793             int nInbound = 0;
794
795             if (hSocket != INVALID_SOCKET)
796                 addr = CAddress(sockaddr);
797
798             CRITICAL_BLOCK(cs_vNodes)
799                 BOOST_FOREACH(CNode* pnode, vNodes)
800                 if (pnode->fInbound)
801                     nInbound++;
802
803             if (hSocket == INVALID_SOCKET)
804             {
805                 if (WSAGetLastError() != WSAEWOULDBLOCK)
806                     printf("socket error accept failed: %d\n", WSAGetLastError());
807             }
808             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
809             {
810                 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
811                     if (!setservAddNodeAddresses.count(addr))
812                         closesocket(hSocket);
813             }
814             else if (CNode::IsBanned(addr))
815             {
816                 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
817                 closesocket(hSocket);
818             }
819             else
820             {
821                 printf("accepted connection %s\n", addr.ToString().c_str());
822                 CNode* pnode = new CNode(hSocket, addr, true);
823                 pnode->AddRef();
824                 CRITICAL_BLOCK(cs_vNodes)
825                     vNodes.push_back(pnode);
826             }
827         }
828
829
830         //
831         // Service each socket
832         //
833         vector<CNode*> vNodesCopy;
834         CRITICAL_BLOCK(cs_vNodes)
835         {
836             vNodesCopy = vNodes;
837             BOOST_FOREACH(CNode* pnode, vNodesCopy)
838                 pnode->AddRef();
839         }
840         BOOST_FOREACH(CNode* pnode, vNodesCopy)
841         {
842             if (fShutdown)
843                 return;
844
845             //
846             // Receive
847             //
848             if (pnode->hSocket == INVALID_SOCKET)
849                 continue;
850             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
851             {
852                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
853                 {
854                     CDataStream& vRecv = pnode->vRecv;
855                     unsigned int nPos = vRecv.size();
856
857                     if (nPos > ReceiveBufferSize()) {
858                         if (!pnode->fDisconnect)
859                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
860                         pnode->CloseSocketDisconnect();
861                     }
862                     else {
863                         // typical socket buffer is 8K-64K
864                         char pchBuf[0x10000];
865                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
866                         if (nBytes > 0)
867                         {
868                             vRecv.resize(nPos + nBytes);
869                             memcpy(&vRecv[nPos], pchBuf, nBytes);
870                             pnode->nLastRecv = GetTime();
871                         }
872                         else if (nBytes == 0)
873                         {
874                             // socket closed gracefully
875                             if (!pnode->fDisconnect)
876                                 printf("socket closed\n");
877                             pnode->CloseSocketDisconnect();
878                         }
879                         else if (nBytes < 0)
880                         {
881                             // error
882                             int nErr = WSAGetLastError();
883                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
884                             {
885                                 if (!pnode->fDisconnect)
886                                     printf("socket recv error %d\n", nErr);
887                                 pnode->CloseSocketDisconnect();
888                             }
889                         }
890                     }
891                 }
892             }
893
894             //
895             // Send
896             //
897             if (pnode->hSocket == INVALID_SOCKET)
898                 continue;
899             if (FD_ISSET(pnode->hSocket, &fdsetSend))
900             {
901                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
902                 {
903                     CDataStream& vSend = pnode->vSend;
904                     if (!vSend.empty())
905                     {
906                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
907                         if (nBytes > 0)
908                         {
909                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
910                             pnode->nLastSend = GetTime();
911                         }
912                         else if (nBytes < 0)
913                         {
914                             // error
915                             int nErr = WSAGetLastError();
916                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
917                             {
918                                 printf("socket send error %d\n", nErr);
919                                 pnode->CloseSocketDisconnect();
920                             }
921                         }
922                         if (vSend.size() > SendBufferSize()) {
923                             if (!pnode->fDisconnect)
924                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
925                             pnode->CloseSocketDisconnect();
926                         }
927                     }
928                 }
929             }
930
931             //
932             // Inactivity checking
933             //
934             if (pnode->vSend.empty())
935                 pnode->nLastSendEmpty = GetTime();
936             if (GetTime() - pnode->nTimeConnected > 60)
937             {
938                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
939                 {
940                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
941                     pnode->fDisconnect = true;
942                 }
943                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
944                 {
945                     printf("socket not sending\n");
946                     pnode->fDisconnect = true;
947                 }
948                 else if (GetTime() - pnode->nLastRecv > 90*60)
949                 {
950                     printf("socket inactivity timeout\n");
951                     pnode->fDisconnect = true;
952                 }
953             }
954         }
955         CRITICAL_BLOCK(cs_vNodes)
956         {
957             BOOST_FOREACH(CNode* pnode, vNodesCopy)
958                 pnode->Release();
959         }
960
961         Sleep(10);
962     }
963 }
964
965
966
967
968
969
970
971
972
973 #ifdef USE_UPNP
974 void ThreadMapPort(void* parg)
975 {
976     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
977     try
978     {
979         vnThreadsRunning[THREAD_UPNP]++;
980         ThreadMapPort2(parg);
981         vnThreadsRunning[THREAD_UPNP]--;
982     }
983     catch (std::exception& e) {
984         vnThreadsRunning[THREAD_UPNP]--;
985         PrintException(&e, "ThreadMapPort()");
986     } catch (...) {
987         vnThreadsRunning[THREAD_UPNP]--;
988         PrintException(NULL, "ThreadMapPort()");
989     }
990     printf("ThreadMapPort exiting\n");
991 }
992
993 void ThreadMapPort2(void* parg)
994 {
995     printf("ThreadMapPort started\n");
996
997     char port[6];
998     sprintf(port, "%d", GetListenPort());
999
1000     const char * multicastif = 0;
1001     const char * minissdpdpath = 0;
1002     struct UPNPDev * devlist = 0;
1003     char lanaddr[64];
1004
1005 #ifndef UPNPDISCOVER_SUCCESS
1006     /* miniupnpc 1.5 */
1007     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1008 #else
1009     /* miniupnpc 1.6 */
1010     int error = 0;
1011     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1012 #endif
1013
1014     struct UPNPUrls urls;
1015     struct IGDdatas data;
1016     int r;
1017
1018     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1019     if (r == 1)
1020     {
1021         if (!addrLocalHost.IsRoutable())
1022         {
1023             char externalIPAddress[40];
1024             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1025             if(r != UPNPCOMMAND_SUCCESS)
1026                 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
1027             else
1028             {
1029                 if(externalIPAddress[0])
1030                 {
1031                     printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1032                     CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
1033                     if (addrExternalFromUPnP.IsRoutable())
1034                         addrLocalHost = addrExternalFromUPnP;
1035                 }
1036                 else
1037                     printf("UPnP: GetExternalIPAddress failed.\n");
1038             }
1039         }
1040
1041         string strDesc = "Bitcoin " + FormatFullVersion();
1042 #ifndef UPNPDISCOVER_SUCCESS
1043         /* miniupnpc 1.5 */
1044         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1045                             port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1046 #else
1047         /* miniupnpc 1.6 */
1048         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1049                             port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1050 #endif
1051
1052         if(r!=UPNPCOMMAND_SUCCESS)
1053             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1054                 port, port, lanaddr, r, strupnperror(r));
1055         else
1056             printf("UPnP Port Mapping successful.\n");
1057         int i = 1;
1058         loop {
1059             if (fShutdown || !fUseUPnP)
1060             {
1061                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1062                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1063                 freeUPNPDevlist(devlist); devlist = 0;
1064                 FreeUPNPUrls(&urls);
1065                 return;
1066             }
1067             if (i % 600 == 0) // Refresh every 20 minutes
1068             {
1069 #ifndef UPNPDISCOVER_SUCCESS
1070                 /* miniupnpc 1.5 */
1071                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1072                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1073 #else
1074                 /* miniupnpc 1.6 */
1075                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1076                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1077 #endif
1078
1079                 if(r!=UPNPCOMMAND_SUCCESS)
1080                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1081                         port, port, lanaddr, r, strupnperror(r));
1082                 else
1083                     printf("UPnP Port Mapping successful.\n");;
1084             }
1085             Sleep(2000);
1086             i++;
1087         }
1088     } else {
1089         printf("No valid UPnP IGDs found\n");
1090         freeUPNPDevlist(devlist); devlist = 0;
1091         if (r != 0)
1092             FreeUPNPUrls(&urls);
1093         loop {
1094             if (fShutdown || !fUseUPnP)
1095                 return;
1096             Sleep(2000);
1097         }
1098     }
1099 }
1100
1101 void MapPort(bool fMapPort)
1102 {
1103     if (fUseUPnP != fMapPort)
1104     {
1105         fUseUPnP = fMapPort;
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 #ifdef USE_UPNP
1715 #if USE_UPNP
1716     fUseUPnP = GetBoolArg("-upnp", true);
1717 #else
1718     fUseUPnP = GetBoolArg("-upnp", false);
1719 #endif
1720 #endif
1721
1722     if (pnodeLocalHost == NULL)
1723         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1724
1725 #ifdef WIN32
1726     // Get local host ip
1727     char pszHostName[1000] = "";
1728     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1729     {
1730         vector<CNetAddr> vaddr;
1731         if (LookupHost(pszHostName, vaddr))
1732             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1733                 if (!addr.IsLocal())
1734                 {
1735                     addrLocalHost.SetIP(addr);
1736                     break;
1737                 }
1738     }
1739 #else
1740     // Get local host ip
1741     struct ifaddrs* myaddrs;
1742     if (getifaddrs(&myaddrs) == 0)
1743     {
1744         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1745         {
1746             if (ifa->ifa_addr == NULL) continue;
1747             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1748             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1749             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1750             char pszIP[100];
1751             if (ifa->ifa_addr->sa_family == AF_INET)
1752             {
1753                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1754                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1755                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1756
1757                 // Take the first IP that isn't loopback 127.x.x.x
1758                 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1759                 if (addr.IsValid() && !addr.IsLocal())
1760                 {
1761                     addrLocalHost = addr;
1762                     break;
1763                 }
1764             }
1765             else if (ifa->ifa_addr->sa_family == AF_INET6)
1766             {
1767                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1768                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1769                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1770             }
1771         }
1772         freeifaddrs(myaddrs);
1773     }
1774 #endif
1775     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1776
1777     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1778     {
1779         // Proxies can't take incoming connections
1780         addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1781         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1782     }
1783     else
1784     {
1785         CreateThread(ThreadGetMyExternalIP, NULL);
1786     }
1787
1788     //
1789     // Start threads
1790     //
1791
1792     if (!GetBoolArg("-dnsseed", true))
1793         printf("DNS seeding disabled\n");
1794     else
1795         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1796             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1797
1798     // Map ports with UPnP
1799     if (fHaveUPnP)
1800         MapPort(fUseUPnP);
1801
1802     // Get addresses from IRC and advertise ours
1803     if (!CreateThread(ThreadIRCSeed, NULL))
1804         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1805
1806     // Send and receive from sockets, accept connections
1807     if (!CreateThread(ThreadSocketHandler, NULL))
1808         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1809
1810     // Initiate outbound connections from -addnode
1811     if (!CreateThread(ThreadOpenAddedConnections, NULL))
1812         printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1813
1814     // Initiate outbound connections
1815     if (!CreateThread(ThreadOpenConnections, NULL))
1816         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1817
1818     // Process messages
1819     if (!CreateThread(ThreadMessageHandler, NULL))
1820         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1821
1822     // Generate coins in the background
1823     GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1824 }
1825
1826 bool StopNode()
1827 {
1828     printf("StopNode()\n");
1829     fShutdown = true;
1830     nTransactionsUpdated++;
1831     int64 nStart = GetTime();
1832     do
1833     {
1834         int nThreadsRunning = 0;
1835         for (int n = 0; n < THREAD_MAX; n++)
1836             nThreadsRunning += vnThreadsRunning[n];
1837         if (nThreadsRunning == 0)
1838             break;
1839         if (GetTime() - nStart > 20)
1840             break;
1841         Sleep(20);
1842     } while(true);
1843     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1844     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1845     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1846     if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1847     if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1848     if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1849     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1850     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1851     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1852         Sleep(20);
1853     Sleep(50);
1854
1855     return true;
1856 }
1857
1858 class CNetCleanup
1859 {
1860 public:
1861     CNetCleanup()
1862     {
1863     }
1864     ~CNetCleanup()
1865     {
1866         // Close sockets
1867         BOOST_FOREACH(CNode* pnode, vNodes)
1868             if (pnode->hSocket != INVALID_SOCKET)
1869                 closesocket(pnode->hSocket);
1870         if (hListenSocket != INVALID_SOCKET)
1871             if (closesocket(hListenSocket) == SOCKET_ERROR)
1872                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1873
1874 #ifdef WIN32
1875         // Shutdown Windows Sockets
1876         WSACleanup();
1877 #endif
1878     }
1879 }
1880 instance_of_cnetcleanup;