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