Merge branch '0.5.x' into 0.6.0.x
[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) != string::npos)
163                 {
164                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
165                     break;
166                 }
167             }
168             closesocket(hSocket);
169             if (strLine.find("<") != string::npos)
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 (unsigned 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 (unsigned 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                     int nOneDay = 24*3600;
1097                     CAddress addr = CAddress(CService(ip, GetDefaultPort()));
1098                     addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1099                     vAdd.push_back(addr);
1100                     found++;
1101                 }
1102             }
1103             addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
1104         }
1105     }
1106
1107     printf("%d addresses found from DNS seeds\n", found);
1108 }
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 unsigned int pnSeed[] =
1122 {
1123     0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1124     0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1125     0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1126     0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1127     0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1128     0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1129     0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1130     0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1131     0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1132     0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1133     0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1134     0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1135     0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1136     0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1137     0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1138     0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1139     0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1140     0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1141     0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1142     0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1143     0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1144     0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1145     0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1146     0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1147     0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1148     0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1149     0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1150     0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1151     0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1152     0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1153     0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1154     0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1155     0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1156     0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1157     0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1158     0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1159     0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1160     0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1161     0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1162     0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1163     0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1164     0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1165     0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1166     0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1167     0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1168     0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1169     0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1170     0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1171     0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1172     0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1173     0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1174     0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1175     0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1176     0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1177     0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1178     0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1179     0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1180     0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1181     0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1182     0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1183     0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1184     0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1185     0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1186     0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1187     0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1188     0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1189     0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1190     0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1191     0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1192     0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1193     0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1194     0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1195     0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1196     0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1197     0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1198     0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1199     0xc461d84a, 0xb2dbe247,
1200 };
1201
1202 void DumpAddresses()
1203 {
1204     CAddrDB adb;
1205     adb.WriteAddrman(addrman);
1206 }
1207
1208 void ThreadDumpAddress2(void* parg)
1209 {
1210     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1211     while (!fShutdown)
1212     {
1213         DumpAddresses();
1214         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1215         Sleep(100000);
1216         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1217     }
1218     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1219 }
1220
1221 void ThreadDumpAddress(void* parg)
1222 {
1223     IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1224     try
1225     {
1226         ThreadDumpAddress2(parg);
1227     }
1228     catch (std::exception& e) {
1229         PrintException(&e, "ThreadDumpAddress()");
1230     }
1231     printf("ThreadDumpAddress exiting\n");
1232 }
1233
1234 void ThreadOpenConnections(void* parg)
1235 {
1236     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1237     try
1238     {
1239         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1240         ThreadOpenConnections2(parg);
1241         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1242     }
1243     catch (std::exception& e) {
1244         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1245         PrintException(&e, "ThreadOpenConnections()");
1246     } catch (...) {
1247         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1248         PrintException(NULL, "ThreadOpenConnections()");
1249     }
1250     printf("ThreadOpenConnections exiting\n");
1251 }
1252
1253 void ThreadOpenConnections2(void* parg)
1254 {
1255     printf("ThreadOpenConnections started\n");
1256
1257     // Connect to specific addresses
1258     if (mapArgs.count("-connect"))
1259     {
1260         for (int64 nLoop = 0;; nLoop++)
1261         {
1262             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1263             {
1264                 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1265                 if (addr.IsValid())
1266                     OpenNetworkConnection(addr);
1267                 for (int i = 0; i < 10 && i < nLoop; i++)
1268                 {
1269                     Sleep(500);
1270                     if (fShutdown)
1271                         return;
1272                 }
1273             }
1274         }
1275     }
1276
1277     // Initiate network connections
1278     int64 nStart = GetTime();
1279     loop
1280     {
1281         int nOutbound = 0;
1282
1283         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1284         Sleep(500);
1285         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1286         if (fShutdown)
1287             return;
1288
1289         // Limit outbound connections
1290         loop
1291         {
1292             nOutbound = 0;
1293             CRITICAL_BLOCK(cs_vNodes)
1294                 BOOST_FOREACH(CNode* pnode, vNodes)
1295                     if (!pnode->fInbound)
1296                         nOutbound++;
1297             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1298             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1299             if (nOutbound < nMaxOutboundConnections)
1300                 break;
1301             vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1302             Sleep(2000);
1303             vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1304             if (fShutdown)
1305                 return;
1306         }
1307
1308         // Add seed nodes if IRC isn't working
1309         bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1310         if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1311         {
1312             std::vector<CAddress> vAdd;
1313             for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
1314             {
1315                 // It'll only connect to one or two seed nodes because once it connects,
1316                 // it'll get a pile of addresses with newer timestamps.
1317                 // Seed nodes are given a random 'last seen time' of between one and two
1318                 // weeks ago.
1319                 const int64 nOneWeek = 7*24*60*60;
1320                 struct in_addr ip;
1321                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1322                 CAddress addr(CService(ip, GetDefaultPort()));
1323                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1324                 vAdd.push_back(addr);
1325             }
1326             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1327         }
1328
1329         //
1330         // Choose an address to connect to based on most recently seen
1331         //
1332         CAddress addrConnect;
1333
1334         // Only connect to one address per a.b.?.? range.
1335         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1336         set<vector<unsigned char> > setConnected;
1337         CRITICAL_BLOCK(cs_vNodes)
1338             BOOST_FOREACH(CNode* pnode, vNodes)
1339                 setConnected.insert(pnode->addr.GetGroup());
1340
1341         int64 nANow = GetAdjustedTime();
1342
1343         int nTries = 0;
1344         loop
1345         {
1346             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1347             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1348
1349             // if we selected an invalid address, restart
1350             if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1351                 break;
1352
1353             nTries++;
1354
1355             // only consider very recently tried nodes after 30 failed attempts
1356             if (nANow - addr.nLastTry < 600 && nTries < 30)
1357                 continue;
1358
1359             // do not allow non-default ports, unless after 50 invalid addresses selected already
1360             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1361                 continue;
1362
1363             addrConnect = addr;
1364             break;
1365         }
1366
1367         if (addrConnect.IsValid())
1368             OpenNetworkConnection(addrConnect);
1369     }
1370 }
1371
1372 void ThreadOpenAddedConnections(void* parg)
1373 {
1374     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1375     try
1376     {
1377         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1378         ThreadOpenAddedConnections2(parg);
1379         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1380     }
1381     catch (std::exception& e) {
1382         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1383         PrintException(&e, "ThreadOpenAddedConnections()");
1384     } catch (...) {
1385         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1386         PrintException(NULL, "ThreadOpenAddedConnections()");
1387     }
1388     printf("ThreadOpenAddedConnections exiting\n");
1389 }
1390
1391 void ThreadOpenAddedConnections2(void* parg)
1392 {
1393     printf("ThreadOpenAddedConnections started\n");
1394
1395     if (mapArgs.count("-addnode") == 0)
1396         return;
1397
1398     vector<vector<CService> > vservAddressesToAdd(0);
1399     BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1400     {
1401         vector<CService> vservNode(0);
1402         if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1403         {
1404             vservAddressesToAdd.push_back(vservNode);
1405             CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1406                 BOOST_FOREACH(CService& serv, vservNode)
1407                     setservAddNodeAddresses.insert(serv);
1408         }
1409     }
1410     loop
1411     {
1412         vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1413         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1414         // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1415         CRITICAL_BLOCK(cs_vNodes)
1416             BOOST_FOREACH(CNode* pnode, vNodes)
1417                 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1418                     BOOST_FOREACH(CService& addrNode, *(it))
1419                         if (pnode->addr == addrNode)
1420                         {
1421                             it = vservConnectAddresses.erase(it);
1422                             it--;
1423                             break;
1424                         }
1425         BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1426         {
1427             OpenNetworkConnection(CAddress(*(vserv.begin())));
1428             Sleep(500);
1429             if (fShutdown)
1430                 return;
1431         }
1432         if (fShutdown)
1433             return;
1434         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1435         Sleep(120000); // Retry every 2 minutes
1436         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1437         if (fShutdown)
1438             return;
1439     }
1440 }
1441
1442 bool OpenNetworkConnection(const CAddress& addrConnect)
1443 {
1444     //
1445     // Initiate outbound network connection
1446     //
1447     if (fShutdown)
1448         return false;
1449     if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1450         FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1451         return false;
1452
1453     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1454     CNode* pnode = ConnectNode(addrConnect);
1455     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1456     if (fShutdown)
1457         return false;
1458     if (!pnode)
1459         return false;
1460     pnode->fNetworkNode = true;
1461
1462     return true;
1463 }
1464
1465
1466
1467
1468
1469
1470
1471
1472 void ThreadMessageHandler(void* parg)
1473 {
1474     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1475     try
1476     {
1477         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1478         ThreadMessageHandler2(parg);
1479         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1480     }
1481     catch (std::exception& e) {
1482         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1483         PrintException(&e, "ThreadMessageHandler()");
1484     } catch (...) {
1485         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1486         PrintException(NULL, "ThreadMessageHandler()");
1487     }
1488     printf("ThreadMessageHandler exiting\n");
1489 }
1490
1491 void ThreadMessageHandler2(void* parg)
1492 {
1493     printf("ThreadMessageHandler started\n");
1494     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1495     while (!fShutdown)
1496     {
1497         vector<CNode*> vNodesCopy;
1498         CRITICAL_BLOCK(cs_vNodes)
1499         {
1500             vNodesCopy = vNodes;
1501             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1502                 pnode->AddRef();
1503         }
1504
1505         // Poll the connected nodes for messages
1506         CNode* pnodeTrickle = NULL;
1507         if (!vNodesCopy.empty())
1508             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1509         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1510         {
1511             // Receive messages
1512             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1513                 ProcessMessages(pnode);
1514             if (fShutdown)
1515                 return;
1516
1517             // Send messages
1518             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1519                 SendMessages(pnode, pnode == pnodeTrickle);
1520             if (fShutdown)
1521                 return;
1522         }
1523
1524         CRITICAL_BLOCK(cs_vNodes)
1525         {
1526             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1527                 pnode->Release();
1528         }
1529
1530         // Wait and allow messages to bunch up.
1531         // Reduce vnThreadsRunning so StopNode has permission to exit while
1532         // we're sleeping, but we must always check fShutdown after doing this.
1533         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1534         Sleep(100);
1535         if (fRequestShutdown)
1536             Shutdown(NULL);
1537         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1538         if (fShutdown)
1539             return;
1540     }
1541 }
1542
1543
1544
1545
1546
1547
1548 bool BindListenPort(string& strError)
1549 {
1550     strError = "";
1551     int nOne = 1;
1552     addrLocalHost.SetPort(GetListenPort());
1553
1554 #ifdef WIN32
1555     // Initialize Windows Sockets
1556     WSADATA wsadata;
1557     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1558     if (ret != NO_ERROR)
1559     {
1560         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1561         printf("%s\n", strError.c_str());
1562         return false;
1563     }
1564 #endif
1565
1566     // Create socket for listening for incoming connections
1567     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1568     if (hListenSocket == INVALID_SOCKET)
1569     {
1570         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1571         printf("%s\n", strError.c_str());
1572         return false;
1573     }
1574
1575 #ifdef SO_NOSIGPIPE
1576     // Different way of disabling SIGPIPE on BSD
1577     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1578 #endif
1579
1580 #ifndef WIN32
1581     // Allow binding if the port is still in TIME_WAIT state after
1582     // the program was closed and restarted.  Not an issue on windows.
1583     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1584 #endif
1585
1586 #ifdef WIN32
1587     // Set to nonblocking, incoming connections will also inherit this
1588     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1589 #else
1590     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1591 #endif
1592     {
1593         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1594         printf("%s\n", strError.c_str());
1595         return false;
1596     }
1597
1598     // The sockaddr_in structure specifies the address family,
1599     // IP address, and port for the socket that is being bound
1600     struct sockaddr_in sockaddr;
1601     memset(&sockaddr, 0, sizeof(sockaddr));
1602     sockaddr.sin_family = AF_INET;
1603     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1604     sockaddr.sin_port = htons(GetListenPort());
1605     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1606     {
1607         int nErr = WSAGetLastError();
1608         if (nErr == WSAEADDRINUSE)
1609             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1610         else
1611             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1612         printf("%s\n", strError.c_str());
1613         return false;
1614     }
1615     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1616
1617     // Listen for incoming connections
1618     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1619     {
1620         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1621         printf("%s\n", strError.c_str());
1622         return false;
1623     }
1624
1625     return true;
1626 }
1627
1628 void StartNode(void* parg)
1629 {
1630 #ifdef USE_UPNP
1631 #if USE_UPNP
1632     fUseUPnP = GetBoolArg("-upnp", true);
1633 #else
1634     fUseUPnP = GetBoolArg("-upnp", false);
1635 #endif
1636 #endif
1637
1638     if (pnodeLocalHost == NULL)
1639         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1640
1641 #ifdef WIN32
1642     // Get local host ip
1643     char pszHostName[1000] = "";
1644     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1645     {
1646         vector<CNetAddr> vaddr;
1647         if (LookupHost(pszHostName, vaddr))
1648             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1649                 if (!addr.IsLocal())
1650                 {
1651                     addrLocalHost.SetIP(addr);
1652                     break;
1653                 }
1654     }
1655 #else
1656     // Get local host ip
1657     struct ifaddrs* myaddrs;
1658     if (getifaddrs(&myaddrs) == 0)
1659     {
1660         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1661         {
1662             if (ifa->ifa_addr == NULL) continue;
1663             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1664             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1665             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1666             char pszIP[100];
1667             if (ifa->ifa_addr->sa_family == AF_INET)
1668             {
1669                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1670                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1671                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1672
1673                 // Take the first IP that isn't loopback 127.x.x.x
1674                 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1675                 if (addr.IsValid() && !addr.IsLocal())
1676                 {
1677                     addrLocalHost = addr;
1678                     break;
1679                 }
1680             }
1681             else if (ifa->ifa_addr->sa_family == AF_INET6)
1682             {
1683                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1684                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1685                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1686             }
1687         }
1688         freeifaddrs(myaddrs);
1689     }
1690 #endif
1691     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1692
1693     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1694     {
1695         // Proxies can't take incoming connections
1696         addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1697         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1698     }
1699     else
1700     {
1701         CreateThread(ThreadGetMyExternalIP, NULL);
1702     }
1703
1704     //
1705     // Start threads
1706     //
1707
1708     if (!GetBoolArg("-dnsseed", true))
1709         printf("DNS seeding disabled\n");
1710     else
1711         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1712             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1713
1714     // Map ports with UPnP
1715     if (fHaveUPnP)
1716         MapPort(fUseUPnP);
1717
1718     // Get addresses from IRC and advertise ours
1719     if (!CreateThread(ThreadIRCSeed, NULL))
1720         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1721
1722     // Send and receive from sockets, accept connections
1723     if (!CreateThread(ThreadSocketHandler, NULL))
1724         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1725
1726     // Initiate outbound connections from -addnode
1727     if (!CreateThread(ThreadOpenAddedConnections, NULL))
1728         printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1729
1730     // Initiate outbound connections
1731     if (!CreateThread(ThreadOpenConnections, NULL))
1732         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1733
1734     // Process messages
1735     if (!CreateThread(ThreadMessageHandler, NULL))
1736         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1737
1738     // Dump network addresses
1739     if (!CreateThread(ThreadDumpAddress, NULL))
1740         printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1741
1742     // Generate coins in the background
1743     GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1744 }
1745
1746 bool StopNode()
1747 {
1748     printf("StopNode()\n");
1749     fShutdown = true;
1750     nTransactionsUpdated++;
1751     int64 nStart = GetTime();
1752     do
1753     {
1754         int nThreadsRunning = 0;
1755         for (int n = 0; n < THREAD_MAX; n++)
1756             nThreadsRunning += vnThreadsRunning[n];
1757         if (nThreadsRunning == 0)
1758             break;
1759         if (GetTime() - nStart > 20)
1760             break;
1761         Sleep(20);
1762     } while(true);
1763     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1764     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1765     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1766     if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1767     if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1768     if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1769     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1770     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1771     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1772     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1773         Sleep(20);
1774     Sleep(50);
1775     DumpAddresses();
1776     return true;
1777 }
1778
1779 class CNetCleanup
1780 {
1781 public:
1782     CNetCleanup()
1783     {
1784     }
1785     ~CNetCleanup()
1786     {
1787         // Close sockets
1788         BOOST_FOREACH(CNode* pnode, vNodes)
1789             if (pnode->hSocket != INVALID_SOCKET)
1790                 closesocket(pnode->hSocket);
1791         if (hListenSocket != INVALID_SOCKET)
1792             if (closesocket(hListenSocket) == SOCKET_ERROR)
1793                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1794
1795 #ifdef WIN32
1796         // Shutdown Windows Sockets
1797         WSACleanup();
1798 #endif
1799     }
1800 }
1801 instance_of_cnetcleanup;