Revert "Use standard C99 (and Qt) types for 64-bit integers"
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "irc.h"
8 #include "db.h"
9 #include "net.h"
10 #include "init.h"
11 #include "strlcpy.h"
12
13 #ifdef WIN32
14 #include <string.h>
15 #endif
16
17 #ifdef USE_UPNP
18 #include <miniupnpc/miniwget.h>
19 #include <miniupnpc/miniupnpc.h>
20 #include <miniupnpc/upnpcommands.h>
21 #include <miniupnpc/upnperrors.h>
22 #endif
23
24 using namespace std;
25 using namespace boost;
26
27 static const int MAX_OUTBOUND_CONNECTIONS = 8;
28
29 void ThreadMessageHandler2(void* parg);
30 void ThreadSocketHandler2(void* parg);
31 void ThreadOpenConnections2(void* parg);
32 #ifdef USE_UPNP
33 void ThreadMapPort2(void* parg);
34 #endif
35 void ThreadDNSAddressSeed2(void* parg);
36 bool OpenNetworkConnection(const CAddress& addrConnect);
37
38
39
40
41
42 //
43 // Global state variables
44 //
45 bool fClient = false;
46 bool fAllowDNS = false;
47 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
48 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
49 static CNode* pnodeLocalHost = NULL;
50 uint64 nLocalHostNonce = 0;
51 array<int, 10> vnThreadsRunning;
52 static SOCKET hListenSocket = INVALID_SOCKET;
53
54 vector<CNode*> vNodes;
55 CCriticalSection cs_vNodes;
56 map<vector<unsigned char>, CAddress> mapAddresses;
57 CCriticalSection cs_mapAddresses;
58 map<CInv, CDataStream> mapRelay;
59 deque<pair<int64, CInv> > vRelayExpiration;
60 CCriticalSection cs_mapRelay;
61 map<CInv, int64> mapAlreadyAskedFor;
62
63 // Settings
64 int fUseProxy = false;
65 int nConnectTimeout = 5000;
66 CAddress addrProxy("127.0.0.1",9050);
67
68
69
70
71 unsigned short GetListenPort()
72 {
73     return (unsigned short)(GetArg("-port", GetDefaultPort()));
74 }
75
76 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
77 {
78     // Filter out duplicate requests
79     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
80         return;
81     pindexLastGetBlocksBegin = pindexBegin;
82     hashLastGetBlocksEnd = hashEnd;
83
84     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
85 }
86
87
88
89
90
91 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
92 {
93     hSocketRet = INVALID_SOCKET;
94
95     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
96     if (hSocket == INVALID_SOCKET)
97         return false;
98 #ifdef SO_NOSIGPIPE
99     int set = 1;
100     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
101 #endif
102
103     bool fProxy = (fUseProxy && addrConnect.IsRoutable());
104     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
105
106 #ifdef WIN32
107     u_long fNonblock = 1;
108     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
109 #else
110     int fFlags = fcntl(hSocket, F_GETFL, 0);
111     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
112 #endif
113     {
114         closesocket(hSocket);
115         return false;
116     }
117
118
119     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
120     {
121         // WSAEINVAL is here because some legacy version of winsock uses it
122         if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
123         {
124             struct timeval timeout;
125             timeout.tv_sec  = nTimeout / 1000;
126             timeout.tv_usec = (nTimeout % 1000) * 1000;
127
128             fd_set fdset;
129             FD_ZERO(&fdset);
130             FD_SET(hSocket, &fdset);
131             int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
132             if (nRet == 0)
133             {
134                 printf("connection timeout\n");
135                 closesocket(hSocket);
136                 return false;
137             }
138             if (nRet == SOCKET_ERROR)
139             {
140                 printf("select() for connection failed: %i\n",WSAGetLastError());
141                 closesocket(hSocket);
142                 return false;
143             }
144             socklen_t nRetSize = sizeof(nRet);
145 #ifdef WIN32
146             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
147 #else
148             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
149 #endif
150             {
151                 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
152                 closesocket(hSocket);
153                 return false;
154             }
155             if (nRet != 0)
156             {
157                 printf("connect() failed after select(): %s\n",strerror(nRet));
158                 closesocket(hSocket);
159                 return false;
160             }
161         }
162 #ifdef WIN32
163         else if (WSAGetLastError() != WSAEISCONN)
164 #else
165         else
166 #endif
167         {
168             printf("connect() failed: %i\n",WSAGetLastError());
169             closesocket(hSocket);
170             return false;
171         }
172     }
173
174     /*
175     this isn't even strictly necessary
176     CNode::ConnectNode immediately turns the socket back to non-blocking
177     but we'll turn it back to blocking just in case
178     */
179 #ifdef WIN32
180     fNonblock = 0;
181     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
182 #else
183     fFlags = fcntl(hSocket, F_GETFL, 0);
184     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
185 #endif
186     {
187         closesocket(hSocket);
188         return false;
189     }
190
191     if (fProxy)
192     {
193         printf("proxy connecting %s\n", addrConnect.ToString().c_str());
194         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
195         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
196         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
197         char* pszSocks4 = pszSocks4IP;
198         int nSize = sizeof(pszSocks4IP);
199
200         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
201         if (ret != nSize)
202         {
203             closesocket(hSocket);
204             return error("Error sending to proxy");
205         }
206         char pchRet[8];
207         if (recv(hSocket, pchRet, 8, 0) != 8)
208         {
209             closesocket(hSocket);
210             return error("Error reading proxy response");
211         }
212         if (pchRet[1] != 0x5a)
213         {
214             closesocket(hSocket);
215             if (pchRet[1] != 0x5b)
216                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
217             return false;
218         }
219         printf("proxy connected %s\n", addrConnect.ToString().c_str());
220     }
221
222     hSocketRet = hSocket;
223     return true;
224 }
225
226 // portDefault is in host order
227 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
228 {
229     vaddr.clear();
230     if (pszName[0] == 0)
231         return false;
232     int port = portDefault;
233     char psz[256];
234     char *pszHost = psz;
235     strlcpy(psz, pszName, sizeof(psz));
236     if (fAllowPort)
237     {
238         char* pszColon = strrchr(psz+1,':');
239         char *pszPortEnd = NULL;
240         int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
241         if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
242         {
243             if (psz[0] == '[' && pszColon[-1] == ']')
244             {
245                 // Future: enable IPv6 colon-notation inside []
246                 pszHost = psz+1;
247                 pszColon[-1] = 0;
248             }
249             else
250                 pszColon[0] = 0;
251             port = portParsed;
252             if (port < 0 || port > std::numeric_limits<unsigned short>::max())
253                 port = std::numeric_limits<unsigned short>::max();
254         }
255     }
256
257     unsigned int addrIP = inet_addr(pszHost);
258     if (addrIP != INADDR_NONE)
259     {
260         // valid IP address passed
261         vaddr.push_back(CAddress(addrIP, port, nServices));
262         return true;
263     }
264
265     if (!fAllowLookup)
266         return false;
267
268     struct hostent* phostent = gethostbyname(pszHost);
269     if (!phostent)
270         return false;
271
272     if (phostent->h_addrtype != AF_INET)
273         return false;
274
275     char** ppAddr = phostent->h_addr_list;
276     while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
277     {
278         CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
279         if (addr.IsValid())
280             vaddr.push_back(addr);
281         ppAddr++;
282     }
283
284     return (vaddr.size() > 0);
285 }
286
287 // portDefault is in host order
288 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
289 {
290     vector<CAddress> vaddr;
291     bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
292     if (fRet)
293         addr = vaddr[0];
294     return fRet;
295 }
296
297 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
298 {
299     SOCKET hSocket;
300     if (!ConnectSocket(addrConnect, hSocket))
301         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
302
303     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
304
305     string strLine;
306     while (RecvLine(hSocket, strLine))
307     {
308         if (strLine.empty()) // HTTP response is separated from headers by blank line
309         {
310             loop
311             {
312                 if (!RecvLine(hSocket, strLine))
313                 {
314                     closesocket(hSocket);
315                     return false;
316                 }
317                 if (pszKeyword == NULL)
318                     break;
319                 if (strLine.find(pszKeyword) != -1)
320                 {
321                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
322                     break;
323                 }
324             }
325             closesocket(hSocket);
326             if (strLine.find("<") != -1)
327                 strLine = strLine.substr(0, strLine.find("<"));
328             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
329             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
330                 strLine.resize(strLine.size()-1);
331             CAddress addr(strLine,0,true);
332             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
333             if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
334                 return false;
335             ipRet = addr.ip;
336             return true;
337         }
338     }
339     closesocket(hSocket);
340     return error("GetMyExternalIP() : connection closed");
341 }
342
343 // We now get our external IP from the IRC server first and only use this as a backup
344 bool GetMyExternalIP(unsigned int& ipRet)
345 {
346     CAddress addrConnect;
347     const char* pszGet;
348     const char* pszKeyword;
349
350     if (fUseProxy)
351         return false;
352
353     for (int nLookup = 0; nLookup <= 1; nLookup++)
354     for (int nHost = 1; nHost <= 2; nHost++)
355     {
356         // We should be phasing out our use of sites like these.  If we need
357         // replacements, we should ask for volunteers to put this simple
358         // php file on their webserver that prints the client IP:
359         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
360         if (nHost == 1)
361         {
362             addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
363
364             if (nLookup == 1)
365             {
366                 CAddress addrIP("checkip.dyndns.org", 80, true);
367                 if (addrIP.IsValid())
368                     addrConnect = addrIP;
369             }
370
371             pszGet = "GET / HTTP/1.1\r\n"
372                      "Host: checkip.dyndns.org\r\n"
373                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
374                      "Connection: close\r\n"
375                      "\r\n";
376
377             pszKeyword = "Address:";
378         }
379         else if (nHost == 2)
380         {
381             addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
382
383             if (nLookup == 1)
384             {
385                 CAddress addrIP("www.showmyip.com", 80, true);
386                 if (addrIP.IsValid())
387                     addrConnect = addrIP;
388             }
389
390             pszGet = "GET /simple/ HTTP/1.1\r\n"
391                      "Host: www.showmyip.com\r\n"
392                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
393                      "Connection: close\r\n"
394                      "\r\n";
395
396             pszKeyword = NULL; // Returns just IP address
397         }
398
399         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
400             return true;
401     }
402
403     return false;
404 }
405
406 void ThreadGetMyExternalIP(void* parg)
407 {
408     // Wait for IRC to get it first
409     if (!GetBoolArg("-noirc"))
410     {
411         for (int i = 0; i < 2 * 60; i++)
412         {
413             Sleep(1000);
414             if (fGotExternalIP || fShutdown)
415                 return;
416         }
417     }
418
419     // Fallback in case IRC fails to get it
420     if (GetMyExternalIP(addrLocalHost.ip))
421     {
422         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
423         if (addrLocalHost.IsRoutable())
424         {
425             // If we already connected to a few before we had our IP, go back and addr them.
426             // setAddrKnown automatically filters any duplicate sends.
427             CAddress addr(addrLocalHost);
428             addr.nTime = GetAdjustedTime();
429             CRITICAL_BLOCK(cs_vNodes)
430                 BOOST_FOREACH(CNode* pnode, vNodes)
431                     pnode->PushAddress(addr);
432         }
433     }
434 }
435
436
437
438
439
440 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
441 {
442     if (!addr.IsRoutable())
443         return false;
444     if (addr.ip == addrLocalHost.ip)
445         return false;
446     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
447     bool fUpdated = false;
448     bool fNew = false;
449     CAddress addrFound = addr;
450
451     CRITICAL_BLOCK(cs_mapAddresses)
452     {
453         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
454         if (it == mapAddresses.end())
455         {
456             // New address
457             printf("AddAddress(%s)\n", addr.ToString().c_str());
458             mapAddresses.insert(make_pair(addr.GetKey(), addr));
459             fUpdated = true;
460             fNew = true;
461         }
462         else
463         {
464             addrFound = (*it).second;
465             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
466             {
467                 // Services have been added
468                 addrFound.nServices |= addr.nServices;
469                 fUpdated = true;
470             }
471             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
472             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
473             if (addrFound.nTime < addr.nTime - nUpdateInterval)
474             {
475                 // Periodically update most recently seen time
476                 addrFound.nTime = addr.nTime;
477                 fUpdated = true;
478             }
479         }
480     }
481     // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
482     // CRITICAL_BLOCK:
483     // Thread 1:  begin db transaction (locks inside-db-mutex)
484     //            then AddAddress (locks cs_mapAddresses)
485     // Thread 2:  AddAddress (locks cs_mapAddresses)
486     //             ... then db operation hangs waiting for inside-db-mutex
487     if (fUpdated)
488     {
489         if (pAddrDB)
490             pAddrDB->WriteAddress(addrFound);
491         else
492             CAddrDB().WriteAddress(addrFound);
493     }
494     return fNew;
495 }
496
497 void AddressCurrentlyConnected(const CAddress& addr)
498 {
499     CRITICAL_BLOCK(cs_mapAddresses)
500     {
501         // Only if it's been published already
502         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
503         if (it != mapAddresses.end())
504         {
505             CAddress& addrFound = (*it).second;
506             int64 nUpdateInterval = 20 * 60;
507             if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
508             {
509                 // Periodically update most recently seen time
510                 addrFound.nTime = GetAdjustedTime();
511                 CAddrDB addrdb;
512                 addrdb.WriteAddress(addrFound);
513             }
514         }
515     }
516 }
517
518
519
520
521
522 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
523 {
524     // If the dialog might get closed before the reply comes back,
525     // call this in the destructor so it doesn't get called after it's deleted.
526     CRITICAL_BLOCK(cs_vNodes)
527     {
528         BOOST_FOREACH(CNode* pnode, vNodes)
529         {
530             CRITICAL_BLOCK(pnode->cs_mapRequests)
531             {
532                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
533                 {
534                     CRequestTracker& tracker = (*mi).second;
535                     if (tracker.fn == fn && tracker.param1 == param1)
536                         pnode->mapRequests.erase(mi++);
537                     else
538                         mi++;
539                 }
540             }
541         }
542     }
543 }
544
545
546
547
548
549
550
551 //
552 // Subscription methods for the broadcast and subscription system.
553 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
554 //
555 // The subscription system uses a meet-in-the-middle strategy.
556 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
557 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
558 //
559
560 bool AnySubscribed(unsigned int nChannel)
561 {
562     if (pnodeLocalHost->IsSubscribed(nChannel))
563         return true;
564     CRITICAL_BLOCK(cs_vNodes)
565         BOOST_FOREACH(CNode* pnode, vNodes)
566             if (pnode->IsSubscribed(nChannel))
567                 return true;
568     return false;
569 }
570
571 bool CNode::IsSubscribed(unsigned int nChannel)
572 {
573     if (nChannel >= vfSubscribe.size())
574         return false;
575     return vfSubscribe[nChannel];
576 }
577
578 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
579 {
580     if (nChannel >= vfSubscribe.size())
581         return;
582
583     if (!AnySubscribed(nChannel))
584     {
585         // Relay subscribe
586         CRITICAL_BLOCK(cs_vNodes)
587             BOOST_FOREACH(CNode* pnode, vNodes)
588                 if (pnode != this)
589                     pnode->PushMessage("subscribe", nChannel, nHops);
590     }
591
592     vfSubscribe[nChannel] = true;
593 }
594
595 void CNode::CancelSubscribe(unsigned int nChannel)
596 {
597     if (nChannel >= vfSubscribe.size())
598         return;
599
600     // Prevent from relaying cancel if wasn't subscribed
601     if (!vfSubscribe[nChannel])
602         return;
603     vfSubscribe[nChannel] = false;
604
605     if (!AnySubscribed(nChannel))
606     {
607         // Relay subscription cancel
608         CRITICAL_BLOCK(cs_vNodes)
609             BOOST_FOREACH(CNode* pnode, vNodes)
610                 if (pnode != this)
611                     pnode->PushMessage("sub-cancel", nChannel);
612     }
613 }
614
615
616
617
618
619
620
621
622
623 CNode* FindNode(unsigned int ip)
624 {
625     CRITICAL_BLOCK(cs_vNodes)
626     {
627         BOOST_FOREACH(CNode* pnode, vNodes)
628             if (pnode->addr.ip == ip)
629                 return (pnode);
630     }
631     return NULL;
632 }
633
634 CNode* FindNode(CAddress addr)
635 {
636     CRITICAL_BLOCK(cs_vNodes)
637     {
638         BOOST_FOREACH(CNode* pnode, vNodes)
639             if (pnode->addr == addr)
640                 return (pnode);
641     }
642     return NULL;
643 }
644
645 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
646 {
647     if (addrConnect.ip == addrLocalHost.ip)
648         return NULL;
649
650     // Look for an existing connection
651     CNode* pnode = FindNode(addrConnect.ip);
652     if (pnode)
653     {
654         if (nTimeout != 0)
655             pnode->AddRef(nTimeout);
656         else
657             pnode->AddRef();
658         return pnode;
659     }
660
661     /// debug print
662     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
663         addrConnect.ToString().c_str(),
664         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
665         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
666
667     CRITICAL_BLOCK(cs_mapAddresses)
668         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
669
670     // Connect
671     SOCKET hSocket;
672     if (ConnectSocket(addrConnect, hSocket))
673     {
674         /// debug print
675         printf("connected %s\n", addrConnect.ToString().c_str());
676
677         // Set to nonblocking
678 #ifdef WIN32
679         u_long nOne = 1;
680         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
681             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
682 #else
683         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
684             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
685 #endif
686
687         // Add node
688         CNode* pnode = new CNode(hSocket, addrConnect, false);
689         if (nTimeout != 0)
690             pnode->AddRef(nTimeout);
691         else
692             pnode->AddRef();
693         CRITICAL_BLOCK(cs_vNodes)
694             vNodes.push_back(pnode);
695
696         pnode->nTimeConnected = GetTime();
697         return pnode;
698     }
699     else
700     {
701         return NULL;
702     }
703 }
704
705 void CNode::CloseSocketDisconnect()
706 {
707     fDisconnect = true;
708     if (hSocket != INVALID_SOCKET)
709     {
710         if (fDebug)
711             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
712         printf("disconnecting node %s\n", addr.ToString().c_str());
713         closesocket(hSocket);
714         hSocket = INVALID_SOCKET;
715     }
716 }
717
718 void CNode::Cleanup()
719 {
720     // All of a nodes broadcasts and subscriptions are automatically torn down
721     // when it goes down, so a node has to stay up to keep its broadcast going.
722
723     // Cancel subscriptions
724     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
725         if (vfSubscribe[nChannel])
726             CancelSubscribe(nChannel);
727 }
728
729
730 void CNode::PushVersion()
731 {
732     /// when NTP implemented, change to just nTime = GetAdjustedTime()
733     int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
734     CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
735     CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
736     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
737     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
738                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
739 }
740
741
742
743
744
745 std::map<unsigned int, int64> CNode::setBanned;
746 CCriticalSection CNode::cs_setBanned;
747
748 void CNode::ClearBanned()
749 {
750     setBanned.clear();
751 }
752
753 bool CNode::IsBanned(unsigned int ip)
754 {
755     bool fResult = false;
756     CRITICAL_BLOCK(cs_setBanned)
757     {
758         std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
759         if (i != setBanned.end())
760         {
761             int64 t = (*i).second;
762             if (GetTime() < t)
763                 fResult = true;
764         }
765     }
766     return fResult;
767 }
768
769 bool CNode::Misbehaving(int howmuch)
770 {
771     if (addr.IsLocal())
772     {
773         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
774         return false;
775     }
776
777     nMisbehavior += howmuch;
778     if (nMisbehavior >= GetArg("-banscore", 100))
779     {
780         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
781         CRITICAL_BLOCK(cs_setBanned)
782             if (setBanned[addr.ip] < banTime)
783                 setBanned[addr.ip] = banTime;
784         CloseSocketDisconnect();
785         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
786         return true;
787     }
788     return false;
789 }
790
791
792
793
794
795
796
797
798
799
800
801
802 void ThreadSocketHandler(void* parg)
803 {
804     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
805     try
806     {
807         vnThreadsRunning[0]++;
808         ThreadSocketHandler2(parg);
809         vnThreadsRunning[0]--;
810     }
811     catch (std::exception& e) {
812         vnThreadsRunning[0]--;
813         PrintException(&e, "ThreadSocketHandler()");
814     } catch (...) {
815         vnThreadsRunning[0]--;
816         throw; // support pthread_cancel()
817     }
818     printf("ThreadSocketHandler exiting\n");
819 }
820
821 void ThreadSocketHandler2(void* parg)
822 {
823     printf("ThreadSocketHandler started\n");
824     list<CNode*> vNodesDisconnected;
825     int nPrevNodeCount = 0;
826
827     loop
828     {
829         //
830         // Disconnect nodes
831         //
832         CRITICAL_BLOCK(cs_vNodes)
833         {
834             // Disconnect unused nodes
835             vector<CNode*> vNodesCopy = vNodes;
836             BOOST_FOREACH(CNode* pnode, vNodesCopy)
837             {
838                 if (pnode->fDisconnect ||
839                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
840                 {
841                     // remove from vNodes
842                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
843
844                     // close socket and cleanup
845                     pnode->CloseSocketDisconnect();
846                     pnode->Cleanup();
847
848                     // hold in disconnected pool until all refs are released
849                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
850                     if (pnode->fNetworkNode || pnode->fInbound)
851                         pnode->Release();
852                     vNodesDisconnected.push_back(pnode);
853                 }
854             }
855
856             // Delete disconnected nodes
857             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
858             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
859             {
860                 // wait until threads are done using it
861                 if (pnode->GetRefCount() <= 0)
862                 {
863                     bool fDelete = false;
864                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
865                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
866                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
867                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
868                         fDelete = true;
869                     if (fDelete)
870                     {
871                         vNodesDisconnected.remove(pnode);
872                         delete pnode;
873                     }
874                 }
875             }
876         }
877         if (vNodes.size() != nPrevNodeCount)
878         {
879             nPrevNodeCount = vNodes.size();
880             MainFrameRepaint();
881         }
882
883
884         //
885         // Find which sockets have data to receive
886         //
887         struct timeval timeout;
888         timeout.tv_sec  = 0;
889         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
890
891         fd_set fdsetRecv;
892         fd_set fdsetSend;
893         fd_set fdsetError;
894         FD_ZERO(&fdsetRecv);
895         FD_ZERO(&fdsetSend);
896         FD_ZERO(&fdsetError);
897         SOCKET hSocketMax = 0;
898
899         if(hListenSocket != INVALID_SOCKET)
900             FD_SET(hListenSocket, &fdsetRecv);
901         hSocketMax = max(hSocketMax, hListenSocket);
902         CRITICAL_BLOCK(cs_vNodes)
903         {
904             BOOST_FOREACH(CNode* pnode, vNodes)
905             {
906                 if (pnode->hSocket == INVALID_SOCKET)
907                     continue;
908                 FD_SET(pnode->hSocket, &fdsetRecv);
909                 FD_SET(pnode->hSocket, &fdsetError);
910                 hSocketMax = max(hSocketMax, pnode->hSocket);
911                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
912                     if (!pnode->vSend.empty())
913                         FD_SET(pnode->hSocket, &fdsetSend);
914             }
915         }
916
917         vnThreadsRunning[0]--;
918         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
919         vnThreadsRunning[0]++;
920         if (fShutdown)
921             return;
922         if (nSelect == SOCKET_ERROR)
923         {
924             int nErr = WSAGetLastError();
925             if (hSocketMax > -1)
926             {
927                 printf("socket select error %d\n", nErr);
928                 for (int i = 0; i <= hSocketMax; i++)
929                     FD_SET(i, &fdsetRecv);
930             }
931             FD_ZERO(&fdsetSend);
932             FD_ZERO(&fdsetError);
933             Sleep(timeout.tv_usec/1000);
934         }
935
936
937         //
938         // Accept new connections
939         //
940         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
941         {
942             struct sockaddr_in sockaddr;
943             socklen_t len = sizeof(sockaddr);
944             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
945             CAddress addr(sockaddr);
946             int nInbound = 0;
947
948             CRITICAL_BLOCK(cs_vNodes)
949                 BOOST_FOREACH(CNode* pnode, vNodes)
950                 if (pnode->fInbound)
951                     nInbound++;
952             if (hSocket == INVALID_SOCKET)
953             {
954                 if (WSAGetLastError() != WSAEWOULDBLOCK)
955                     printf("socket error accept failed: %d\n", WSAGetLastError());
956             }
957             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
958             {
959                 closesocket(hSocket);
960             }
961             else if (CNode::IsBanned(addr.ip))
962             {
963                 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
964                 closesocket(hSocket);
965             }
966             else
967             {
968                 printf("accepted connection %s\n", addr.ToString().c_str());
969                 CNode* pnode = new CNode(hSocket, addr, true);
970                 pnode->AddRef();
971                 CRITICAL_BLOCK(cs_vNodes)
972                     vNodes.push_back(pnode);
973             }
974         }
975
976
977         //
978         // Service each socket
979         //
980         vector<CNode*> vNodesCopy;
981         CRITICAL_BLOCK(cs_vNodes)
982         {
983             vNodesCopy = vNodes;
984             BOOST_FOREACH(CNode* pnode, vNodesCopy)
985                 pnode->AddRef();
986         }
987         BOOST_FOREACH(CNode* pnode, vNodesCopy)
988         {
989             if (fShutdown)
990                 return;
991
992             //
993             // Receive
994             //
995             if (pnode->hSocket == INVALID_SOCKET)
996                 continue;
997             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
998             {
999                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1000                 {
1001                     CDataStream& vRecv = pnode->vRecv;
1002                     unsigned int nPos = vRecv.size();
1003
1004                     if (nPos > ReceiveBufferSize()) {
1005                         if (!pnode->fDisconnect)
1006                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
1007                         pnode->CloseSocketDisconnect();
1008                     }
1009                     else {
1010                         // typical socket buffer is 8K-64K
1011                         char pchBuf[0x10000];
1012                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1013                         if (nBytes > 0)
1014                         {
1015                             vRecv.resize(nPos + nBytes);
1016                             memcpy(&vRecv[nPos], pchBuf, nBytes);
1017                             pnode->nLastRecv = GetTime();
1018                         }
1019                         else if (nBytes == 0)
1020                         {
1021                             // socket closed gracefully
1022                             if (!pnode->fDisconnect)
1023                                 printf("socket closed\n");
1024                             pnode->CloseSocketDisconnect();
1025                         }
1026                         else if (nBytes < 0)
1027                         {
1028                             // error
1029                             int nErr = WSAGetLastError();
1030                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1031                             {
1032                                 if (!pnode->fDisconnect)
1033                                     printf("socket recv error %d\n", nErr);
1034                                 pnode->CloseSocketDisconnect();
1035                             }
1036                         }
1037                     }
1038                 }
1039             }
1040
1041             //
1042             // Send
1043             //
1044             if (pnode->hSocket == INVALID_SOCKET)
1045                 continue;
1046             if (FD_ISSET(pnode->hSocket, &fdsetSend))
1047             {
1048                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1049                 {
1050                     CDataStream& vSend = pnode->vSend;
1051                     if (!vSend.empty())
1052                     {
1053                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
1054                         if (nBytes > 0)
1055                         {
1056                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1057                             pnode->nLastSend = GetTime();
1058                         }
1059                         else if (nBytes < 0)
1060                         {
1061                             // error
1062                             int nErr = WSAGetLastError();
1063                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1064                             {
1065                                 printf("socket send error %d\n", nErr);
1066                                 pnode->CloseSocketDisconnect();
1067                             }
1068                         }
1069                         if (vSend.size() > SendBufferSize()) {
1070                             if (!pnode->fDisconnect)
1071                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1072                             pnode->CloseSocketDisconnect();
1073                         }
1074                     }
1075                 }
1076             }
1077
1078             //
1079             // Inactivity checking
1080             //
1081             if (pnode->vSend.empty())
1082                 pnode->nLastSendEmpty = GetTime();
1083             if (GetTime() - pnode->nTimeConnected > 60)
1084             {
1085                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1086                 {
1087                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1088                     pnode->fDisconnect = true;
1089                 }
1090                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1091                 {
1092                     printf("socket not sending\n");
1093                     pnode->fDisconnect = true;
1094                 }
1095                 else if (GetTime() - pnode->nLastRecv > 90*60)
1096                 {
1097                     printf("socket inactivity timeout\n");
1098                     pnode->fDisconnect = true;
1099                 }
1100             }
1101         }
1102         CRITICAL_BLOCK(cs_vNodes)
1103         {
1104             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1105                 pnode->Release();
1106         }
1107
1108         Sleep(10);
1109     }
1110 }
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 #ifdef USE_UPNP
1121 void ThreadMapPort(void* parg)
1122 {
1123     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1124     try
1125     {
1126         vnThreadsRunning[5]++;
1127         ThreadMapPort2(parg);
1128         vnThreadsRunning[5]--;
1129     }
1130     catch (std::exception& e) {
1131         vnThreadsRunning[5]--;
1132         PrintException(&e, "ThreadMapPort()");
1133     } catch (...) {
1134         vnThreadsRunning[5]--;
1135         PrintException(NULL, "ThreadMapPort()");
1136     }
1137     printf("ThreadMapPort exiting\n");
1138 }
1139
1140 void ThreadMapPort2(void* parg)
1141 {
1142     printf("ThreadMapPort started\n");
1143
1144     char port[6];
1145     sprintf(port, "%d", GetListenPort());
1146
1147     const char * rootdescurl = 0;
1148     const char * multicastif = 0;
1149     const char * minissdpdpath = 0;
1150     struct UPNPDev * devlist = 0;
1151     char lanaddr[64];
1152
1153 #ifndef UPNPDISCOVER_SUCCESS
1154     /* miniupnpc 1.5 */
1155     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1156 #else
1157     /* miniupnpc 1.6 */
1158     int error = 0;
1159     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1160 #endif
1161
1162     struct UPNPUrls urls;
1163     struct IGDdatas data;
1164     int r;
1165
1166     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1167     if (r == 1)
1168     {
1169         char intClient[16];
1170         char intPort[6];
1171         string strDesc = "Bitcoin " + FormatFullVersion();
1172 #ifndef UPNPDISCOVER_SUCCESS
1173     /* miniupnpc 1.5 */
1174         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1175                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1176 #else
1177     /* miniupnpc 1.6 */
1178         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1179                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1180 #endif
1181
1182         if(r!=UPNPCOMMAND_SUCCESS)
1183             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1184                 port, port, lanaddr, r, strupnperror(r));
1185         else
1186             printf("UPnP Port Mapping successful.\n");
1187         loop {
1188             if (fShutdown || !fUseUPnP)
1189             {
1190                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1191                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1192                 freeUPNPDevlist(devlist); devlist = 0;
1193                 FreeUPNPUrls(&urls);
1194                 return;
1195             }
1196             Sleep(2000);
1197         }
1198     } else {
1199         printf("No valid UPnP IGDs found\n");
1200         freeUPNPDevlist(devlist); devlist = 0;
1201         if (r != 0)
1202             FreeUPNPUrls(&urls);
1203         loop {
1204             if (fShutdown || !fUseUPnP)
1205                 return;
1206             Sleep(2000);
1207         }
1208     }
1209 }
1210
1211 void MapPort(bool fMapPort)
1212 {
1213     if (fUseUPnP != fMapPort)
1214     {
1215         fUseUPnP = fMapPort;
1216         WriteSetting("fUseUPnP", fUseUPnP);
1217     }
1218     if (fUseUPnP && vnThreadsRunning[5] < 1)
1219     {
1220         if (!CreateThread(ThreadMapPort, NULL))
1221             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1222     }
1223 }
1224 #else
1225 void MapPort(bool /* unused fMapPort */)
1226 {
1227     // Intentionally left blank.
1228 }
1229 #endif
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240 static const char *strDNSSeed[] = {
1241     "bitseed.xf2.org",
1242     "dnsseed.bluematt.me",
1243     "seed.bitcoin.sipa.be",
1244     "dnsseed.bitcoin.dashjr.org",
1245 };
1246
1247 void ThreadDNSAddressSeed(void* parg)
1248 {
1249     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1250     try
1251     {
1252         vnThreadsRunning[6]++;
1253         ThreadDNSAddressSeed2(parg);
1254         vnThreadsRunning[6]--;
1255     }
1256     catch (std::exception& e) {
1257         vnThreadsRunning[6]--;
1258         PrintException(&e, "ThreadDNSAddressSeed()");
1259     } catch (...) {
1260         vnThreadsRunning[6]--;
1261         throw; // support pthread_cancel()
1262     }
1263     printf("ThreadDNSAddressSeed exiting\n");
1264 }
1265
1266 void ThreadDNSAddressSeed2(void* parg)
1267 {
1268     printf("ThreadDNSAddressSeed started\n");
1269     int found = 0;
1270
1271     if (!fTestNet)
1272     {
1273         printf("Loading addresses from DNS seeds (could take a while)\n");
1274         CAddrDB addrDB;
1275         addrDB.TxnBegin();
1276
1277         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1278             vector<CAddress> vaddr;
1279             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1280             {
1281                 BOOST_FOREACH (CAddress& addr, vaddr)
1282                 {
1283                     if (addr.GetByte(3) != 127)
1284                     {
1285                         addr.nTime = 0;
1286                         AddAddress(addr, 0, &addrDB);
1287                         found++;
1288                     }
1289                 }
1290             }
1291         }
1292
1293         addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1294     }
1295
1296     printf("%d addresses found from DNS seeds\n", found);
1297 }
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310 unsigned int pnSeed[] =
1311 {
1312     0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1313     0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1314     0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1315     0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1316     0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1317     0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1318     0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1319     0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1320     0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1321     0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1322     0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1323     0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1324     0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1325     0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1326     0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1327     0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1328     0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1329     0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1330     0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1331     0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1332     0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1333     0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1334     0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1335     0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1336     0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1337     0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1338     0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1339     0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1340     0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1341     0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1342     0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1343     0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1344     0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1345     0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1346     0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1347     0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1348     0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1349     0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1350     0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1351     0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1352     0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1353     0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1354     0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1355     0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1356     0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1357     0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1358     0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1359     0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1360     0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1361     0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1362     0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1363     0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1364     0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1365     0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1366     0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1367     0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1368     0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1369     0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1370     0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1371     0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1372     0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1373     0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1374     0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1375     0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1376 };
1377
1378
1379
1380 void ThreadOpenConnections(void* parg)
1381 {
1382     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1383     try
1384     {
1385         vnThreadsRunning[1]++;
1386         ThreadOpenConnections2(parg);
1387         vnThreadsRunning[1]--;
1388     }
1389     catch (std::exception& e) {
1390         vnThreadsRunning[1]--;
1391         PrintException(&e, "ThreadOpenConnections()");
1392     } catch (...) {
1393         vnThreadsRunning[1]--;
1394         PrintException(NULL, "ThreadOpenConnections()");
1395     }
1396     printf("ThreadOpenConnections exiting\n");
1397 }
1398
1399 void ThreadOpenConnections2(void* parg)
1400 {
1401     printf("ThreadOpenConnections started\n");
1402
1403     // Connect to specific addresses
1404     if (mapArgs.count("-connect"))
1405     {
1406         for (int64 nLoop = 0;; nLoop++)
1407         {
1408             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1409             {
1410                 CAddress addr(strAddr, fAllowDNS);
1411                 if (addr.IsValid())
1412                     OpenNetworkConnection(addr);
1413                 for (int i = 0; i < 10 && i < nLoop; i++)
1414                 {
1415                     Sleep(500);
1416                     if (fShutdown)
1417                         return;
1418                 }
1419             }
1420         }
1421     }
1422
1423     // Connect to manually added nodes first
1424     if (mapArgs.count("-addnode"))
1425     {
1426         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1427         {
1428             CAddress addr(strAddr, fAllowDNS);
1429             if (addr.IsValid())
1430             {
1431                 OpenNetworkConnection(addr);
1432                 Sleep(500);
1433                 if (fShutdown)
1434                     return;
1435             }
1436         }
1437     }
1438
1439     // Initiate network connections
1440     int64 nStart = GetTime();
1441     loop
1442     {
1443         // Limit outbound connections
1444         vnThreadsRunning[1]--;
1445         Sleep(500);
1446         loop
1447         {
1448             int nOutbound = 0;
1449             CRITICAL_BLOCK(cs_vNodes)
1450                 BOOST_FOREACH(CNode* pnode, vNodes)
1451                     if (!pnode->fInbound)
1452                         nOutbound++;
1453             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1454             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1455             if (nOutbound < nMaxOutboundConnections)
1456                 break;
1457             Sleep(2000);
1458             if (fShutdown)
1459                 return;
1460         }
1461         vnThreadsRunning[1]++;
1462         if (fShutdown)
1463             return;
1464
1465         CRITICAL_BLOCK(cs_mapAddresses)
1466         {
1467             // Add seed nodes if IRC isn't working
1468             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1469             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1470             {
1471                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1472                 {
1473                     // It'll only connect to one or two seed nodes because once it connects,
1474                     // it'll get a pile of addresses with newer timestamps.
1475                     // Seed nodes are given a random 'last seen time' of between one and two
1476                     // weeks ago.
1477                     const int64 nOneWeek = 7*24*60*60;
1478                     CAddress addr;
1479                     addr.ip = pnSeed[i];
1480                     addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1481                     AddAddress(addr);
1482                 }
1483             }
1484         }
1485
1486
1487         //
1488         // Choose an address to connect to based on most recently seen
1489         //
1490         CAddress addrConnect;
1491         int64 nBest = std::numeric_limits<int64>::min();
1492
1493         // Only connect to one address per a.b.?.? range.
1494         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1495         set<unsigned int> setConnected;
1496         CRITICAL_BLOCK(cs_vNodes)
1497             BOOST_FOREACH(CNode* pnode, vNodes)
1498                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1499
1500         int64 nANow = GetAdjustedTime();
1501
1502         CRITICAL_BLOCK(cs_mapAddresses)
1503         {
1504             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1505             {
1506                 const CAddress& addr = item.second;
1507                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1508                     continue;
1509                 int64 nSinceLastSeen = nANow - addr.nTime;
1510                 int64 nSinceLastTry = nANow - addr.nLastTry;
1511
1512                 // Randomize the order in a deterministic way, putting the standard port first
1513                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1514                 if (addr.port != htons(GetDefaultPort()))
1515                     nRandomizer += 2 * 60 * 60;
1516
1517                 // Last seen  Base retry frequency
1518                 //   <1 hour   10 min
1519                 //    1 hour    1 hour
1520                 //    4 hours   2 hours
1521                 //   24 hours   5 hours
1522                 //   48 hours   7 hours
1523                 //    7 days   13 hours
1524                 //   30 days   27 hours
1525                 //   90 days   46 hours
1526                 //  365 days   93 hours
1527                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1528
1529                 // Fast reconnect for one hour after last seen
1530                 if (nSinceLastSeen < 60 * 60)
1531                     nDelay = 10 * 60;
1532
1533                 // Limit retry frequency
1534                 if (nSinceLastTry < nDelay)
1535                     continue;
1536
1537                 // If we have IRC, we'll be notified when they first come online,
1538                 // and again every 24 hours by the refresh broadcast.
1539                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1540                     continue;
1541
1542                 // Only try the old stuff if we don't have enough connections
1543                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1544                     continue;
1545
1546                 // If multiple addresses are ready, prioritize by time since
1547                 // last seen and time since last tried.
1548                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1549                 if (nScore > nBest)
1550                 {
1551                     nBest = nScore;
1552                     addrConnect = addr;
1553                 }
1554             }
1555         }
1556
1557         if (addrConnect.IsValid())
1558             OpenNetworkConnection(addrConnect);
1559     }
1560 }
1561
1562 bool OpenNetworkConnection(const CAddress& addrConnect)
1563 {
1564     //
1565     // Initiate outbound network connection
1566     //
1567     if (fShutdown)
1568         return false;
1569     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1570         FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
1571         return false;
1572
1573     vnThreadsRunning[1]--;
1574     CNode* pnode = ConnectNode(addrConnect);
1575     vnThreadsRunning[1]++;
1576     if (fShutdown)
1577         return false;
1578     if (!pnode)
1579         return false;
1580     pnode->fNetworkNode = true;
1581
1582     return true;
1583 }
1584
1585
1586
1587
1588
1589
1590
1591
1592 void ThreadMessageHandler(void* parg)
1593 {
1594     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1595     try
1596     {
1597         vnThreadsRunning[2]++;
1598         ThreadMessageHandler2(parg);
1599         vnThreadsRunning[2]--;
1600     }
1601     catch (std::exception& e) {
1602         vnThreadsRunning[2]--;
1603         PrintException(&e, "ThreadMessageHandler()");
1604     } catch (...) {
1605         vnThreadsRunning[2]--;
1606         PrintException(NULL, "ThreadMessageHandler()");
1607     }
1608     printf("ThreadMessageHandler exiting\n");
1609 }
1610
1611 void ThreadMessageHandler2(void* parg)
1612 {
1613     printf("ThreadMessageHandler started\n");
1614     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1615     while (!fShutdown)
1616     {
1617         vector<CNode*> vNodesCopy;
1618         CRITICAL_BLOCK(cs_vNodes)
1619         {
1620             vNodesCopy = vNodes;
1621             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1622                 pnode->AddRef();
1623         }
1624
1625         // Poll the connected nodes for messages
1626         CNode* pnodeTrickle = NULL;
1627         if (!vNodesCopy.empty())
1628             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1629         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1630         {
1631             // Receive messages
1632             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1633                 ProcessMessages(pnode);
1634             if (fShutdown)
1635                 return;
1636
1637             // Send messages
1638             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1639                 SendMessages(pnode, pnode == pnodeTrickle);
1640             if (fShutdown)
1641                 return;
1642         }
1643
1644         CRITICAL_BLOCK(cs_vNodes)
1645         {
1646             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1647                 pnode->Release();
1648         }
1649
1650         // Wait and allow messages to bunch up.
1651         // Reduce vnThreadsRunning so StopNode has permission to exit while
1652         // we're sleeping, but we must always check fShutdown after doing this.
1653         vnThreadsRunning[2]--;
1654         Sleep(100);
1655         if (fRequestShutdown)
1656             Shutdown(NULL);
1657         vnThreadsRunning[2]++;
1658         if (fShutdown)
1659             return;
1660     }
1661 }
1662
1663
1664
1665
1666
1667
1668 bool BindListenPort(string& strError)
1669 {
1670     strError = "";
1671     int nOne = 1;
1672     addrLocalHost.port = htons(GetListenPort());
1673
1674 #ifdef WIN32
1675     // Initialize Windows Sockets
1676     WSADATA wsadata;
1677     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1678     if (ret != NO_ERROR)
1679     {
1680         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1681         printf("%s\n", strError.c_str());
1682         return false;
1683     }
1684 #endif
1685
1686     // Create socket for listening for incoming connections
1687     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1688     if (hListenSocket == INVALID_SOCKET)
1689     {
1690         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1691         printf("%s\n", strError.c_str());
1692         return false;
1693     }
1694
1695 #ifdef SO_NOSIGPIPE
1696     // Different way of disabling SIGPIPE on BSD
1697     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1698 #endif
1699
1700 #ifndef WIN32
1701     // Allow binding if the port is still in TIME_WAIT state after
1702     // the program was closed and restarted.  Not an issue on windows.
1703     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1704 #endif
1705
1706 #ifdef WIN32
1707     // Set to nonblocking, incoming connections will also inherit this
1708     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1709 #else
1710     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1711 #endif
1712     {
1713         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1714         printf("%s\n", strError.c_str());
1715         return false;
1716     }
1717
1718     // The sockaddr_in structure specifies the address family,
1719     // IP address, and port for the socket that is being bound
1720     struct sockaddr_in sockaddr;
1721     memset(&sockaddr, 0, sizeof(sockaddr));
1722     sockaddr.sin_family = AF_INET;
1723     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1724     sockaddr.sin_port = htons(GetListenPort());
1725     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1726     {
1727         int nErr = WSAGetLastError();
1728         if (nErr == WSAEADDRINUSE)
1729             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1730         else
1731             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1732         printf("%s\n", strError.c_str());
1733         return false;
1734     }
1735     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1736
1737     // Listen for incoming connections
1738     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1739     {
1740         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1741         printf("%s\n", strError.c_str());
1742         return false;
1743     }
1744
1745     return true;
1746 }
1747
1748 void StartNode(void* parg)
1749 {
1750     if (pnodeLocalHost == NULL)
1751         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1752
1753 #ifdef WIN32
1754     // Get local host ip
1755     char pszHostName[1000] = "";
1756     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1757     {
1758         vector<CAddress> vaddr;
1759         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1760             BOOST_FOREACH (const CAddress &addr, vaddr)
1761                 if (addr.GetByte(3) != 127)
1762                 {
1763                     addrLocalHost = addr;
1764                     break;
1765                 }
1766     }
1767 #else
1768     // Get local host ip
1769     struct ifaddrs* myaddrs;
1770     if (getifaddrs(&myaddrs) == 0)
1771     {
1772         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1773         {
1774             if (ifa->ifa_addr == NULL) continue;
1775             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1776             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1777             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1778             char pszIP[100];
1779             if (ifa->ifa_addr->sa_family == AF_INET)
1780             {
1781                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1782                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1783                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1784
1785                 // Take the first IP that isn't loopback 127.x.x.x
1786                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1787                 if (addr.IsValid() && addr.GetByte(3) != 127)
1788                 {
1789                     addrLocalHost = addr;
1790                     break;
1791                 }
1792             }
1793             else if (ifa->ifa_addr->sa_family == AF_INET6)
1794             {
1795                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1796                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1797                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1798             }
1799         }
1800         freeifaddrs(myaddrs);
1801     }
1802 #endif
1803     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1804
1805     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1806     {
1807         // Proxies can't take incoming connections
1808         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1809         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1810     }
1811     else
1812     {
1813         CreateThread(ThreadGetMyExternalIP, NULL);
1814     }
1815
1816     //
1817     // Start threads
1818     //
1819
1820     if (GetBoolArg("-nodnsseed"))
1821         printf("DNS seeding disabled\n");
1822     else
1823         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1824             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1825
1826     // Map ports with UPnP
1827     if (fHaveUPnP)
1828         MapPort(fUseUPnP);
1829
1830     // Get addresses from IRC and advertise ours
1831     if (!CreateThread(ThreadIRCSeed, NULL))
1832         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1833
1834     // Send and receive from sockets, accept connections
1835     if (!CreateThread(ThreadSocketHandler, NULL))
1836         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1837
1838     // Initiate outbound connections
1839     if (!CreateThread(ThreadOpenConnections, NULL))
1840         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1841
1842     // Process messages
1843     if (!CreateThread(ThreadMessageHandler, NULL))
1844         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1845
1846     // Generate coins in the background
1847     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1848 }
1849
1850 bool StopNode()
1851 {
1852     printf("StopNode()\n");
1853     fShutdown = true;
1854     nTransactionsUpdated++;
1855     int64 nStart = GetTime();
1856     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1857 #ifdef USE_UPNP
1858         || vnThreadsRunning[5] > 0
1859 #endif
1860     )
1861     {
1862         if (GetTime() - nStart > 20)
1863             break;
1864         Sleep(20);
1865     }
1866     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1867     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1868     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1869     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1870     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1871     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1872     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1873     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1874         Sleep(20);
1875     Sleep(50);
1876
1877     return true;
1878 }
1879
1880 class CNetCleanup
1881 {
1882 public:
1883     CNetCleanup()
1884     {
1885     }
1886     ~CNetCleanup()
1887     {
1888         // Close sockets
1889         BOOST_FOREACH(CNode* pnode, vNodes)
1890             if (pnode->hSocket != INVALID_SOCKET)
1891                 closesocket(pnode->hSocket);
1892         if (hListenSocket != INVALID_SOCKET)
1893             if (closesocket(hListenSocket) == SOCKET_ERROR)
1894                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1895
1896 #ifdef WIN32
1897         // Shutdown Windows Sockets
1898         WSACleanup();
1899 #endif
1900     }
1901 }
1902 instance_of_cnetcleanup;