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