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