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