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