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