d697788213559f9177f290f6d57b17069d374aa2
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "headers.h"
6 #include "irc.h"
7 #include "db.h"
8 #include "net.h"
9 #include "init.h"
10 #include "strlcpy.h"
11
12 #ifdef __WXMSW__
13 #include <string.h>
14 // This file can be downloaded as a part of the Windows Platform SDK
15 // and is required for Bitcoin binaries to work properly on versions
16 // of Windows before XP.  If you are doing builds of Bitcoin for
17 // public release, you should uncomment this line.
18 //#include <WSPiApi.h>
19 #endif
20
21 #ifdef USE_UPNP
22 #include <miniupnpc/miniwget.h>
23 #include <miniupnpc/miniupnpc.h>
24 #include <miniupnpc/upnpcommands.h>
25 #include <miniupnpc/upnperrors.h>
26 #endif
27
28 using namespace std;
29 using namespace boost;
30
31 static const int MAX_OUTBOUND_CONNECTIONS = 8;
32
33 void ThreadMessageHandler2(void* parg);
34 void ThreadSocketHandler2(void* parg);
35 void ThreadOpenConnections2(void* parg);
36 #ifdef USE_UPNP
37 void ThreadMapPort2(void* parg);
38 #endif
39 bool OpenNetworkConnection(const CAddress& addrConnect);
40
41
42
43
44
45 //
46 // Global state variables
47 //
48 bool fClient = false;
49 bool fAllowDNS = false;
50 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
51 CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
52 CNode* pnodeLocalHost = NULL;
53 uint64 nLocalHostNonce = 0;
54 array<int, 10> vnThreadsRunning;
55 SOCKET hListenSocket = INVALID_SOCKET;
56
57 vector<CNode*> vNodes;
58 CCriticalSection cs_vNodes;
59 map<vector<unsigned char>, CAddress> mapAddresses;
60 CCriticalSection cs_mapAddresses;
61 map<CInv, CDataStream> mapRelay;
62 deque<pair<int64, CInv> > vRelayExpiration;
63 CCriticalSection cs_mapRelay;
64 map<CInv, int64> mapAlreadyAskedFor;
65
66 // Settings
67 int fUseProxy = false;
68 int nConnectTimeout = 5000;
69 CAddress addrProxy("127.0.0.1",9050);
70
71
72
73
74 unsigned short GetListenPort()
75 {
76     return (unsigned short)(GetArg("-port", GetDefaultPort()));
77 }
78
79 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
80 {
81     // Filter out duplicate requests
82     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
83         return;
84     pindexLastGetBlocksBegin = pindexBegin;
85     hashLastGetBlocksEnd = hashEnd;
86
87     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
88 }
89
90
91
92
93
94 bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
95 {
96     hSocketRet = INVALID_SOCKET;
97
98     SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
99     if (hSocket == INVALID_SOCKET)
100         return false;
101 #ifdef BSD
102     int set = 1;
103     setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
104 #endif
105
106     bool fProxy = (fUseProxy && addrConnect.IsRoutable());
107     struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
108
109 #ifdef __WXMSW__
110     u_long fNonblock = 1;
111     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
112 #else
113     int fFlags = fcntl(hSocket, F_GETFL, 0);
114     if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
115 #endif
116     {
117         closesocket(hSocket);
118         return false;
119     }
120
121
122     if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
123     {
124         // WSAEINVAL is here because some legacy version of winsock uses it
125         if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
126         {
127             struct timeval timeout;
128             timeout.tv_sec  = nTimeout / 1000;
129             timeout.tv_usec = (nTimeout % 1000) * 1000;
130
131             fd_set fdset;
132             FD_ZERO(&fdset);
133             FD_SET(hSocket, &fdset);
134             int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
135             if (nRet == 0)
136             {
137                 printf("connection timeout\n");
138                 closesocket(hSocket);
139                 return false;
140             }
141             if (nRet == SOCKET_ERROR)
142             {
143                 printf("select() for connection failed: %i\n",WSAGetLastError());
144                 closesocket(hSocket);
145                 return false;
146             }
147             socklen_t nRetSize = sizeof(nRet);
148 #ifdef __WXMSW__
149             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
150 #else
151             if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
152 #endif
153             {
154                 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
155                 closesocket(hSocket);
156                 return false;
157             }
158             if (nRet != 0)
159             {
160                 printf("connect() failed after select(): %s\n",strerror(nRet));
161                 closesocket(hSocket);
162                 return false;
163             }
164         }
165 #ifdef __WXMSW__
166         else if (WSAGetLastError() != WSAEISCONN)
167 #else
168         else
169 #endif
170         {
171             printf("connect() failed: %i\n",WSAGetLastError());
172             closesocket(hSocket);
173             return false;
174         }
175     }
176
177     /*
178     this isn't even strictly necessary
179     CNode::ConnectNode immediately turns the socket back to non-blocking
180     but we'll turn it back to blocking just in case
181     */
182 #ifdef __WXMSW__
183     fNonblock = 0;
184     if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
185 #else
186     fFlags = fcntl(hSocket, F_GETFL, 0);
187     if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
188 #endif
189     {
190         closesocket(hSocket);
191         return false;
192     }
193
194     if (fProxy)
195     {
196         printf("proxy connecting %s\n", addrConnect.ToString().c_str());
197         char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
198         memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
199         memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
200         char* pszSocks4 = pszSocks4IP;
201         int nSize = sizeof(pszSocks4IP);
202
203         int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
204         if (ret != nSize)
205         {
206             closesocket(hSocket);
207             return error("Error sending to proxy");
208         }
209         char pchRet[8];
210         if (recv(hSocket, pchRet, 8, 0) != 8)
211         {
212             closesocket(hSocket);
213             return error("Error reading proxy response");
214         }
215         if (pchRet[1] != 0x5a)
216         {
217             closesocket(hSocket);
218             if (pchRet[1] != 0x5b)
219                 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
220             return false;
221         }
222         printf("proxy connected %s\n", addrConnect.ToString().c_str());
223     }
224
225     hSocketRet = hSocket;
226     return true;
227 }
228
229 // portDefault is in host order
230 bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
231 {
232     vaddr.clear();
233     if (pszName[0] == 0)
234         return false;
235     int port = portDefault;
236     char psz[256];
237     char *pszHost = psz;
238     strlcpy(psz, pszName, sizeof(psz));
239     if (fAllowPort)
240     {
241         char* pszColon = strrchr(psz+1,':');
242         char *pszPortEnd = NULL;
243         int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
244         if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
245         {
246             if (psz[0] == '[' && pszColon[-1] == ']')
247             {
248                 // Future: enable IPv6 colon-notation inside []
249                 pszHost = psz+1;
250                 pszColon[-1] = 0;
251             }
252             else
253                 pszColon[0] = 0;
254             port = portParsed;
255             if (port < 0 || port > USHRT_MAX)
256                 port = USHRT_MAX;
257         }
258     }
259
260     unsigned int addrIP = inet_addr(pszHost);
261     if (addrIP != INADDR_NONE)
262     {
263         // valid IP address passed
264         vaddr.push_back(CAddress(addrIP, port, nServices));
265         return true;
266     }
267
268     if (!fAllowLookup)
269         return false;
270
271     struct hostent* phostent = gethostbyname(pszHost);
272     if (!phostent)
273         return false;
274
275     if (phostent->h_addrtype != AF_INET)
276         return false;
277
278     char** ppAddr = phostent->h_addr_list;
279     while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
280     {
281         CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
282         if (addr.IsValid())
283             vaddr.push_back(addr);
284         ppAddr++;
285     }
286
287     return (vaddr.size() > 0);
288 }
289
290 // portDefault is in host order
291 bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
292 {
293     vector<CAddress> vaddr;
294     bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
295     if (fRet)
296         addr = vaddr[0];
297     return fRet;
298 }
299
300 bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
301 {
302     SOCKET hSocket;
303     if (!ConnectSocket(addrConnect, hSocket))
304         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
305
306     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
307
308     string strLine;
309     while (RecvLine(hSocket, strLine))
310     {
311         if (strLine.empty()) // HTTP response is separated from headers by blank line
312         {
313             loop
314             {
315                 if (!RecvLine(hSocket, strLine))
316                 {
317                     closesocket(hSocket);
318                     return false;
319                 }
320                 if (pszKeyword == NULL)
321                     break;
322                 if (strLine.find(pszKeyword) != -1)
323                 {
324                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
325                     break;
326                 }
327             }
328             closesocket(hSocket);
329             if (strLine.find("<") != -1)
330                 strLine = strLine.substr(0, strLine.find("<"));
331             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
332             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
333                 strLine.resize(strLine.size()-1);
334             CAddress addr(strLine,0,true);
335             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
336             if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
337                 return false;
338             ipRet = addr.ip;
339             return true;
340         }
341     }
342     closesocket(hSocket);
343     return error("GetMyExternalIP() : connection closed");
344 }
345
346 // We now get our external IP from the IRC server first and only use this as a backup
347 bool GetMyExternalIP(unsigned int& ipRet)
348 {
349     CAddress addrConnect;
350     const char* pszGet;
351     const char* pszKeyword;
352
353     if (fUseProxy)
354         return false;
355
356     for (int nLookup = 0; nLookup <= 1; nLookup++)
357     for (int nHost = 1; nHost <= 2; nHost++)
358     {
359         // We should be phasing out our use of sites like these.  If we need
360         // replacements, we should ask for volunteers to put this simple
361         // php file on their webserver that prints the client IP:
362         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
363         if (nHost == 1)
364         {
365             addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
366
367             if (nLookup == 1)
368             {
369                 CAddress addrIP("checkip.dyndns.org", 80, true);
370                 if (addrIP.IsValid())
371                     addrConnect = addrIP;
372             }
373
374             pszGet = "GET / HTTP/1.1\r\n"
375                      "Host: checkip.dyndns.org\r\n"
376                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
377                      "Connection: close\r\n"
378                      "\r\n";
379
380             pszKeyword = "Address:";
381         }
382         else if (nHost == 2)
383         {
384             addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
385
386             if (nLookup == 1)
387             {
388                 CAddress addrIP("www.showmyip.com", 80, true);
389                 if (addrIP.IsValid())
390                     addrConnect = addrIP;
391             }
392
393             pszGet = "GET /simple/ HTTP/1.1\r\n"
394                      "Host: www.showmyip.com\r\n"
395                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
396                      "Connection: close\r\n"
397                      "\r\n";
398
399             pszKeyword = NULL; // Returns just IP address
400         }
401
402         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
403             return true;
404     }
405
406     return false;
407 }
408
409 void ThreadGetMyExternalIP(void* parg)
410 {
411     // Wait for IRC to get it first
412     if (!GetBoolArg("-noirc"))
413     {
414         for (int i = 0; i < 2 * 60; i++)
415         {
416             Sleep(1000);
417             if (fGotExternalIP || fShutdown)
418                 return;
419         }
420     }
421
422     // Fallback in case IRC fails to get it
423     if (GetMyExternalIP(addrLocalHost.ip))
424     {
425         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
426         if (addrLocalHost.IsRoutable())
427         {
428             // If we already connected to a few before we had our IP, go back and addr them.
429             // setAddrKnown automatically filters any duplicate sends.
430             CAddress addr(addrLocalHost);
431             addr.nTime = GetAdjustedTime();
432             CRITICAL_BLOCK(cs_vNodes)
433                 BOOST_FOREACH(CNode* pnode, vNodes)
434                     pnode->PushAddress(addr);
435         }
436     }
437 }
438
439
440
441
442
443 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
444 {
445     if (!addr.IsRoutable())
446         return false;
447     if (addr.ip == addrLocalHost.ip)
448         return false;
449     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
450     CRITICAL_BLOCK(cs_mapAddresses)
451     {
452         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
453         if (it == mapAddresses.end())
454         {
455             // New address
456             printf("AddAddress(%s)\n", addr.ToString().c_str());
457             mapAddresses.insert(make_pair(addr.GetKey(), addr));
458             if (pAddrDB)
459                 pAddrDB->WriteAddress(addr);
460             else
461                 CAddrDB().WriteAddress(addr);
462             return true;
463         }
464         else
465         {
466             bool fUpdated = false;
467             CAddress& addrFound = (*it).second;
468             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
469             {
470                 // Services have been added
471                 addrFound.nServices |= addr.nServices;
472                 fUpdated = true;
473             }
474             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
475             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
476             if (addrFound.nTime < addr.nTime - nUpdateInterval)
477             {
478                 // Periodically update most recently seen time
479                 addrFound.nTime = addr.nTime;
480                 fUpdated = true;
481             }
482             if (fUpdated)
483             {
484                 if (pAddrDB)
485                     pAddrDB->WriteAddress(addrFound);
486                 else
487                     CAddrDB().WriteAddress(addrFound);
488             }
489         }
490     }
491     return false;
492 }
493
494 void AddressCurrentlyConnected(const CAddress& addr)
495 {
496     CRITICAL_BLOCK(cs_mapAddresses)
497     {
498         // Only if it's been published already
499         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
500         if (it != mapAddresses.end())
501         {
502             CAddress& addrFound = (*it).second;
503             int64 nUpdateInterval = 20 * 60;
504             if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
505             {
506                 // Periodically update most recently seen time
507                 addrFound.nTime = GetAdjustedTime();
508                 CAddrDB addrdb;
509                 addrdb.WriteAddress(addrFound);
510             }
511         }
512     }
513 }
514
515
516
517
518
519 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
520 {
521     // If the dialog might get closed before the reply comes back,
522     // call this in the destructor so it doesn't get called after it's deleted.
523     CRITICAL_BLOCK(cs_vNodes)
524     {
525         BOOST_FOREACH(CNode* pnode, vNodes)
526         {
527             CRITICAL_BLOCK(pnode->cs_mapRequests)
528             {
529                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
530                 {
531                     CRequestTracker& tracker = (*mi).second;
532                     if (tracker.fn == fn && tracker.param1 == param1)
533                         pnode->mapRequests.erase(mi++);
534                     else
535                         mi++;
536                 }
537             }
538         }
539     }
540 }
541
542
543
544
545
546
547
548 //
549 // Subscription methods for the broadcast and subscription system.
550 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
551 //
552 // The subscription system uses a meet-in-the-middle strategy.
553 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
554 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
555 //
556
557 bool AnySubscribed(unsigned int nChannel)
558 {
559     if (pnodeLocalHost->IsSubscribed(nChannel))
560         return true;
561     CRITICAL_BLOCK(cs_vNodes)
562         BOOST_FOREACH(CNode* pnode, vNodes)
563             if (pnode->IsSubscribed(nChannel))
564                 return true;
565     return false;
566 }
567
568 bool CNode::IsSubscribed(unsigned int nChannel)
569 {
570     if (nChannel >= vfSubscribe.size())
571         return false;
572     return vfSubscribe[nChannel];
573 }
574
575 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
576 {
577     if (nChannel >= vfSubscribe.size())
578         return;
579
580     if (!AnySubscribed(nChannel))
581     {
582         // Relay subscribe
583         CRITICAL_BLOCK(cs_vNodes)
584             BOOST_FOREACH(CNode* pnode, vNodes)
585                 if (pnode != this)
586                     pnode->PushMessage("subscribe", nChannel, nHops);
587     }
588
589     vfSubscribe[nChannel] = true;
590 }
591
592 void CNode::CancelSubscribe(unsigned int nChannel)
593 {
594     if (nChannel >= vfSubscribe.size())
595         return;
596
597     // Prevent from relaying cancel if wasn't subscribed
598     if (!vfSubscribe[nChannel])
599         return;
600     vfSubscribe[nChannel] = false;
601
602     if (!AnySubscribed(nChannel))
603     {
604         // Relay subscription cancel
605         CRITICAL_BLOCK(cs_vNodes)
606             BOOST_FOREACH(CNode* pnode, vNodes)
607                 if (pnode != this)
608                     pnode->PushMessage("sub-cancel", nChannel);
609     }
610 }
611
612
613
614
615
616
617
618
619
620 CNode* FindNode(unsigned int ip)
621 {
622     CRITICAL_BLOCK(cs_vNodes)
623     {
624         BOOST_FOREACH(CNode* pnode, vNodes)
625             if (pnode->addr.ip == ip)
626                 return (pnode);
627     }
628     return NULL;
629 }
630
631 CNode* FindNode(CAddress addr)
632 {
633     CRITICAL_BLOCK(cs_vNodes)
634     {
635         BOOST_FOREACH(CNode* pnode, vNodes)
636             if (pnode->addr == addr)
637                 return (pnode);
638     }
639     return NULL;
640 }
641
642 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
643 {
644     if (addrConnect.ip == addrLocalHost.ip)
645         return NULL;
646
647     // Look for an existing connection
648     CNode* pnode = FindNode(addrConnect.ip);
649     if (pnode)
650     {
651         if (nTimeout != 0)
652             pnode->AddRef(nTimeout);
653         else
654             pnode->AddRef();
655         return pnode;
656     }
657
658     /// debug print
659     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
660         addrConnect.ToString().c_str(),
661         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
662         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
663
664     CRITICAL_BLOCK(cs_mapAddresses)
665         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
666
667     // Connect
668     SOCKET hSocket;
669     if (ConnectSocket(addrConnect, hSocket))
670     {
671         /// debug print
672         printf("connected %s\n", addrConnect.ToString().c_str());
673
674         // Set to nonblocking
675 #ifdef __WXMSW__
676         u_long nOne = 1;
677         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
678             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
679 #else
680         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
681             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
682 #endif
683
684         // Add node
685         CNode* pnode = new CNode(hSocket, addrConnect, false);
686         if (nTimeout != 0)
687             pnode->AddRef(nTimeout);
688         else
689             pnode->AddRef();
690         CRITICAL_BLOCK(cs_vNodes)
691             vNodes.push_back(pnode);
692
693         pnode->nTimeConnected = GetTime();
694         return pnode;
695     }
696     else
697     {
698         return NULL;
699     }
700 }
701
702 void CNode::CloseSocketDisconnect()
703 {
704     fDisconnect = true;
705     if (hSocket != INVALID_SOCKET)
706     {
707         if (fDebug)
708             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
709         printf("disconnecting node %s\n", addr.ToString().c_str());
710         closesocket(hSocket);
711         hSocket = INVALID_SOCKET;
712     }
713 }
714
715 void CNode::Cleanup()
716 {
717     // All of a nodes broadcasts and subscriptions are automatically torn down
718     // when it goes down, so a node has to stay up to keep its broadcast going.
719
720     // Cancel subscriptions
721     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
722         if (vfSubscribe[nChannel])
723             CancelSubscribe(nChannel);
724 }
725
726
727
728
729
730
731
732
733
734
735
736
737
738 void ThreadSocketHandler(void* parg)
739 {
740     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
741     try
742     {
743         vnThreadsRunning[0]++;
744         ThreadSocketHandler2(parg);
745         vnThreadsRunning[0]--;
746     }
747     catch (std::exception& e) {
748         vnThreadsRunning[0]--;
749         PrintException(&e, "ThreadSocketHandler()");
750     } catch (...) {
751         vnThreadsRunning[0]--;
752         throw; // support pthread_cancel()
753     }
754     printf("ThreadSocketHandler exiting\n");
755 }
756
757 void ThreadSocketHandler2(void* parg)
758 {
759     printf("ThreadSocketHandler started\n");
760     list<CNode*> vNodesDisconnected;
761     int nPrevNodeCount = 0;
762
763     loop
764     {
765         //
766         // Disconnect nodes
767         //
768         CRITICAL_BLOCK(cs_vNodes)
769         {
770             // Disconnect unused nodes
771             vector<CNode*> vNodesCopy = vNodes;
772             BOOST_FOREACH(CNode* pnode, vNodesCopy)
773             {
774                 if (pnode->fDisconnect ||
775                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
776                 {
777                     // remove from vNodes
778                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
779
780                     // close socket and cleanup
781                     pnode->CloseSocketDisconnect();
782                     pnode->Cleanup();
783
784                     // hold in disconnected pool until all refs are released
785                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
786                     if (pnode->fNetworkNode || pnode->fInbound)
787                         pnode->Release();
788                     vNodesDisconnected.push_back(pnode);
789                 }
790             }
791
792             // Delete disconnected nodes
793             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
794             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
795             {
796                 // wait until threads are done using it
797                 if (pnode->GetRefCount() <= 0)
798                 {
799                     bool fDelete = false;
800                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
801                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
802                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
803                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
804                         fDelete = true;
805                     if (fDelete)
806                     {
807                         vNodesDisconnected.remove(pnode);
808                         delete pnode;
809                     }
810                 }
811             }
812         }
813         if (vNodes.size() != nPrevNodeCount)
814         {
815             nPrevNodeCount = vNodes.size();
816             MainFrameRepaint();
817         }
818
819
820         //
821         // Find which sockets have data to receive
822         //
823         struct timeval timeout;
824         timeout.tv_sec  = 0;
825         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
826
827         fd_set fdsetRecv;
828         fd_set fdsetSend;
829         fd_set fdsetError;
830         FD_ZERO(&fdsetRecv);
831         FD_ZERO(&fdsetSend);
832         FD_ZERO(&fdsetError);
833         SOCKET hSocketMax = 0;
834
835         if(hListenSocket != INVALID_SOCKET)
836             FD_SET(hListenSocket, &fdsetRecv);
837         hSocketMax = max(hSocketMax, hListenSocket);
838         CRITICAL_BLOCK(cs_vNodes)
839         {
840             BOOST_FOREACH(CNode* pnode, vNodes)
841             {
842                 if (pnode->hSocket == INVALID_SOCKET)
843                     continue;
844                 FD_SET(pnode->hSocket, &fdsetRecv);
845                 FD_SET(pnode->hSocket, &fdsetError);
846                 hSocketMax = max(hSocketMax, pnode->hSocket);
847                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
848                     if (!pnode->vSend.empty())
849                         FD_SET(pnode->hSocket, &fdsetSend);
850             }
851         }
852
853         vnThreadsRunning[0]--;
854         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
855         vnThreadsRunning[0]++;
856         if (fShutdown)
857             return;
858         if (nSelect == SOCKET_ERROR)
859         {
860             int nErr = WSAGetLastError();
861             if (hSocketMax > -1)
862             {
863                 printf("socket select error %d\n", nErr);
864                 for (int i = 0; i <= hSocketMax; i++)
865                     FD_SET(i, &fdsetRecv);
866             }
867             FD_ZERO(&fdsetSend);
868             FD_ZERO(&fdsetError);
869             Sleep(timeout.tv_usec/1000);
870         }
871
872
873         //
874         // Accept new connections
875         //
876         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
877         {
878             struct sockaddr_in sockaddr;
879             socklen_t len = sizeof(sockaddr);
880             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
881             CAddress addr(sockaddr);
882             int nInbound = 0;
883
884             CRITICAL_BLOCK(cs_vNodes)
885                 BOOST_FOREACH(CNode* pnode, vNodes)
886                 if (pnode->fInbound)
887                     nInbound++;
888             if (hSocket == INVALID_SOCKET)
889             {
890                 if (WSAGetLastError() != WSAEWOULDBLOCK)
891                     printf("socket error accept failed: %d\n", WSAGetLastError());
892             }
893             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
894             {
895                 closesocket(hSocket);
896             }
897             else
898             {
899                 printf("accepted connection %s\n", addr.ToString().c_str());
900                 CNode* pnode = new CNode(hSocket, addr, true);
901                 pnode->AddRef();
902                 CRITICAL_BLOCK(cs_vNodes)
903                     vNodes.push_back(pnode);
904             }
905         }
906
907
908         //
909         // Service each socket
910         //
911         vector<CNode*> vNodesCopy;
912         CRITICAL_BLOCK(cs_vNodes)
913         {
914             vNodesCopy = vNodes;
915             BOOST_FOREACH(CNode* pnode, vNodesCopy)
916                 pnode->AddRef();
917         }
918         BOOST_FOREACH(CNode* pnode, vNodesCopy)
919         {
920             if (fShutdown)
921                 return;
922
923             //
924             // Receive
925             //
926             if (pnode->hSocket == INVALID_SOCKET)
927                 continue;
928             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
929             {
930                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
931                 {
932                     CDataStream& vRecv = pnode->vRecv;
933                     unsigned int nPos = vRecv.size();
934
935                     if (nPos > ReceiveBufferSize()) {
936                         if (!pnode->fDisconnect)
937                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
938                         pnode->CloseSocketDisconnect();
939                     }
940                     else {
941                         // typical socket buffer is 8K-64K
942                         char pchBuf[0x10000];
943                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
944                         if (nBytes > 0)
945                         {
946                             vRecv.resize(nPos + nBytes);
947                             memcpy(&vRecv[nPos], pchBuf, nBytes);
948                             pnode->nLastRecv = GetTime();
949                         }
950                         else if (nBytes == 0)
951                         {
952                             // socket closed gracefully
953                             if (!pnode->fDisconnect)
954                                 printf("socket closed\n");
955                             pnode->CloseSocketDisconnect();
956                         }
957                         else if (nBytes < 0)
958                         {
959                             // error
960                             int nErr = WSAGetLastError();
961                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
962                             {
963                                 if (!pnode->fDisconnect)
964                                     printf("socket recv error %d\n", nErr);
965                                 pnode->CloseSocketDisconnect();
966                             }
967                         }
968                     }
969                 }
970             }
971
972             //
973             // Send
974             //
975             if (pnode->hSocket == INVALID_SOCKET)
976                 continue;
977             if (FD_ISSET(pnode->hSocket, &fdsetSend))
978             {
979                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
980                 {
981                     CDataStream& vSend = pnode->vSend;
982                     if (!vSend.empty())
983                     {
984                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
985                         if (nBytes > 0)
986                         {
987                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
988                             pnode->nLastSend = GetTime();
989                         }
990                         else if (nBytes < 0)
991                         {
992                             // error
993                             int nErr = WSAGetLastError();
994                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
995                             {
996                                 printf("socket send error %d\n", nErr);
997                                 pnode->CloseSocketDisconnect();
998                             }
999                         }
1000                         if (vSend.size() > SendBufferSize()) {
1001                             if (!pnode->fDisconnect)
1002                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1003                             pnode->CloseSocketDisconnect();
1004                         }
1005                     }
1006                 }
1007             }
1008
1009             //
1010             // Inactivity checking
1011             //
1012             if (pnode->vSend.empty())
1013                 pnode->nLastSendEmpty = GetTime();
1014             if (GetTime() - pnode->nTimeConnected > 60)
1015             {
1016                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1017                 {
1018                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1019                     pnode->fDisconnect = true;
1020                 }
1021                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1022                 {
1023                     printf("socket not sending\n");
1024                     pnode->fDisconnect = true;
1025                 }
1026                 else if (GetTime() - pnode->nLastRecv > 90*60)
1027                 {
1028                     printf("socket inactivity timeout\n");
1029                     pnode->fDisconnect = true;
1030                 }
1031             }
1032         }
1033         CRITICAL_BLOCK(cs_vNodes)
1034         {
1035             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1036                 pnode->Release();
1037         }
1038
1039         Sleep(10);
1040     }
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 #ifdef USE_UPNP
1052 void ThreadMapPort(void* parg)
1053 {
1054     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1055     try
1056     {
1057         vnThreadsRunning[5]++;
1058         ThreadMapPort2(parg);
1059         vnThreadsRunning[5]--;
1060     }
1061     catch (std::exception& e) {
1062         vnThreadsRunning[5]--;
1063         PrintException(&e, "ThreadMapPort()");
1064     } catch (...) {
1065         vnThreadsRunning[5]--;
1066         PrintException(NULL, "ThreadMapPort()");
1067     }
1068     printf("ThreadMapPort exiting\n");
1069 }
1070
1071 void ThreadMapPort2(void* parg)
1072 {
1073     printf("ThreadMapPort started\n");
1074
1075     char port[6];
1076     sprintf(port, "%d", GetListenPort());
1077
1078     const char * rootdescurl = 0;
1079     const char * multicastif = 0;
1080     const char * minissdpdpath = 0;
1081     struct UPNPDev * devlist = 0;
1082     char lanaddr[64];
1083
1084     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1085
1086     struct UPNPUrls urls;
1087     struct IGDdatas data;
1088     int r;
1089
1090     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1091     if (r == 1)
1092     {
1093         char intClient[16];
1094         char intPort[6];
1095         string strDesc = "Bitcoin " + FormatFullVersion();
1096
1097 #ifndef __WXMSW__
1098         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1099                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1100 #else
1101         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1102                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
1103 #endif
1104         if(r!=UPNPCOMMAND_SUCCESS)
1105             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1106                 port, port, lanaddr, r, strupnperror(r));
1107         else
1108             printf("UPnP Port Mapping successful.\n");
1109         loop {
1110             if (fShutdown || !fUseUPnP)
1111             {
1112                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1113                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1114                 freeUPNPDevlist(devlist); devlist = 0;
1115                 FreeUPNPUrls(&urls);
1116                 return;
1117             }
1118             Sleep(2000);
1119         }
1120     } else {
1121         printf("No valid UPnP IGDs found\n");
1122         freeUPNPDevlist(devlist); devlist = 0;
1123         if (r != 0)
1124             FreeUPNPUrls(&urls);
1125         loop {
1126             if (fShutdown || !fUseUPnP)
1127                 return;
1128             Sleep(2000);
1129         }
1130     }
1131 }
1132
1133 void MapPort(bool fMapPort)
1134 {
1135     if (fUseUPnP != fMapPort)
1136     {
1137         fUseUPnP = fMapPort;
1138         WriteSetting("fUseUPnP", fUseUPnP);
1139     }
1140     if (fUseUPnP && vnThreadsRunning[5] < 1)
1141     {
1142         if (!CreateThread(ThreadMapPort, NULL))
1143             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1144     }
1145 }
1146 #endif
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157 static const char *strDNSSeed[] = {
1158     "bitseed.xf2.org",
1159     "bitseed.bitcoin.org.uk",
1160     "dnsseed.bluematt.me",
1161 };
1162
1163 void DNSAddressSeed()
1164 {
1165     int found = 0;
1166
1167     if (!fTestNet)
1168     {
1169         printf("Loading addresses from DNS seeds (could take a while)\n");
1170         CAddrDB addrDB;
1171         addrDB.TxnBegin();
1172
1173         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1174             vector<CAddress> vaddr;
1175             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1176             {
1177                 BOOST_FOREACH (CAddress& addr, vaddr)
1178                 {
1179                     if (addr.GetByte(3) != 127)
1180                     {
1181                         addr.nTime = 0;
1182                         AddAddress(addr, 0, &addrDB);
1183                         found++;
1184                     }
1185                 }
1186             }
1187         }
1188
1189         addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1190     }
1191
1192     printf("%d addresses found from DNS seeds\n", found);
1193 }
1194
1195
1196
1197 unsigned int pnSeed[] =
1198 {
1199     0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1200     0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1201     0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1202     0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1203     0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1204     0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1205     0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1206     0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1207     0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1208     0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1209     0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1210     0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1211     0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1212     0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1213     0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1214     0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1215     0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1216     0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1217     0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1218     0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1219     0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1220     0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1221     0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1222     0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1223     0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1224     0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1225     0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1226     0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1227     0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1228     0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1229     0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1230     0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1231     0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1232     0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1233     0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1234     0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1235     0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1236     0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1237     0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1238     0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1239 };
1240
1241
1242
1243 void ThreadOpenConnections(void* parg)
1244 {
1245     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1246     try
1247     {
1248         vnThreadsRunning[1]++;
1249         ThreadOpenConnections2(parg);
1250         vnThreadsRunning[1]--;
1251     }
1252     catch (std::exception& e) {
1253         vnThreadsRunning[1]--;
1254         PrintException(&e, "ThreadOpenConnections()");
1255     } catch (...) {
1256         vnThreadsRunning[1]--;
1257         PrintException(NULL, "ThreadOpenConnections()");
1258     }
1259     printf("ThreadOpenConnections exiting\n");
1260 }
1261
1262 void ThreadOpenConnections2(void* parg)
1263 {
1264     printf("ThreadOpenConnections started\n");
1265
1266     // Connect to specific addresses
1267     if (mapArgs.count("-connect"))
1268     {
1269         for (int64 nLoop = 0;; nLoop++)
1270         {
1271             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1272             {
1273                 CAddress addr(strAddr, fAllowDNS);
1274                 if (addr.IsValid())
1275                     OpenNetworkConnection(addr);
1276                 for (int i = 0; i < 10 && i < nLoop; i++)
1277                 {
1278                     Sleep(500);
1279                     if (fShutdown)
1280                         return;
1281                 }
1282             }
1283         }
1284     }
1285
1286     // Connect to manually added nodes first
1287     if (mapArgs.count("-addnode"))
1288     {
1289         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1290         {
1291             CAddress addr(strAddr, fAllowDNS);
1292             if (addr.IsValid())
1293             {
1294                 OpenNetworkConnection(addr);
1295                 Sleep(500);
1296                 if (fShutdown)
1297                     return;
1298             }
1299         }
1300     }
1301
1302     // Initiate network connections
1303     int64 nStart = GetTime();
1304     loop
1305     {
1306         // Limit outbound connections
1307         vnThreadsRunning[1]--;
1308         Sleep(500);
1309         loop
1310         {
1311             int nOutbound = 0;
1312             CRITICAL_BLOCK(cs_vNodes)
1313                 BOOST_FOREACH(CNode* pnode, vNodes)
1314                     if (!pnode->fInbound)
1315                         nOutbound++;
1316             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1317             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1318             if (nOutbound < nMaxOutboundConnections)
1319                 break;
1320             Sleep(2000);
1321             if (fShutdown)
1322                 return;
1323         }
1324         vnThreadsRunning[1]++;
1325         if (fShutdown)
1326             return;
1327
1328         CRITICAL_BLOCK(cs_mapAddresses)
1329         {
1330             // Add seed nodes if IRC isn't working
1331             static bool fSeedUsed;
1332             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1333             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1334             {
1335                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1336                 {
1337                     // It'll only connect to one or two seed nodes because once it connects,
1338                     // it'll get a pile of addresses with newer timestamps.
1339                     CAddress addr;
1340                     addr.ip = pnSeed[i];
1341                     addr.nTime = 0;
1342                     AddAddress(addr);
1343                 }
1344                 fSeedUsed = true;
1345             }
1346
1347             if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1348             {
1349                 // Disconnect seed nodes
1350                 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1351                 static int64 nSeedDisconnected;
1352                 if (nSeedDisconnected == 0)
1353                 {
1354                     nSeedDisconnected = GetTime();
1355                     CRITICAL_BLOCK(cs_vNodes)
1356                         BOOST_FOREACH(CNode* pnode, vNodes)
1357                             if (setSeed.count(pnode->addr.ip))
1358                                 pnode->fDisconnect = true;
1359                 }
1360
1361                 // Keep setting timestamps to 0 so they won't reconnect
1362                 if (GetTime() - nSeedDisconnected < 60 * 60)
1363                 {
1364                     BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1365                     {
1366                         if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1367                         {
1368                             item.second.nTime = 0;
1369                             CAddrDB().WriteAddress(item.second);
1370                         }
1371                     }
1372                 }
1373             }
1374         }
1375
1376
1377         //
1378         // Choose an address to connect to based on most recently seen
1379         //
1380         CAddress addrConnect;
1381         int64 nBest = INT64_MIN;
1382
1383         // Only connect to one address per a.b.?.? range.
1384         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1385         set<unsigned int> setConnected;
1386         CRITICAL_BLOCK(cs_vNodes)
1387             BOOST_FOREACH(CNode* pnode, vNodes)
1388                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1389
1390         CRITICAL_BLOCK(cs_mapAddresses)
1391         {
1392             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1393             {
1394                 const CAddress& addr = item.second;
1395                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1396                     continue;
1397                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1398                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1399
1400                 // Randomize the order in a deterministic way, putting the standard port first
1401                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1402                 if (addr.port != htons(GetDefaultPort()))
1403                     nRandomizer += 2 * 60 * 60;
1404
1405                 // Last seen  Base retry frequency
1406                 //   <1 hour   10 min
1407                 //    1 hour    1 hour
1408                 //    4 hours   2 hours
1409                 //   24 hours   5 hours
1410                 //   48 hours   7 hours
1411                 //    7 days   13 hours
1412                 //   30 days   27 hours
1413                 //   90 days   46 hours
1414                 //  365 days   93 hours
1415                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1416
1417                 // Fast reconnect for one hour after last seen
1418                 if (nSinceLastSeen < 60 * 60)
1419                     nDelay = 10 * 60;
1420
1421                 // Limit retry frequency
1422                 if (nSinceLastTry < nDelay)
1423                     continue;
1424
1425                 // If we have IRC, we'll be notified when they first come online,
1426                 // and again every 24 hours by the refresh broadcast.
1427                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1428                     continue;
1429
1430                 // Only try the old stuff if we don't have enough connections
1431                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1432                     continue;
1433
1434                 // If multiple addresses are ready, prioritize by time since
1435                 // last seen and time since last tried.
1436                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1437                 if (nScore > nBest)
1438                 {
1439                     nBest = nScore;
1440                     addrConnect = addr;
1441                 }
1442             }
1443         }
1444
1445         if (addrConnect.IsValid())
1446             OpenNetworkConnection(addrConnect);
1447     }
1448 }
1449
1450 bool OpenNetworkConnection(const CAddress& addrConnect)
1451 {
1452     //
1453     // Initiate outbound network connection
1454     //
1455     if (fShutdown)
1456         return false;
1457     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1458         return false;
1459
1460     vnThreadsRunning[1]--;
1461     CNode* pnode = ConnectNode(addrConnect);
1462     vnThreadsRunning[1]++;
1463     if (fShutdown)
1464         return false;
1465     if (!pnode)
1466         return false;
1467     pnode->fNetworkNode = true;
1468
1469     return true;
1470 }
1471
1472
1473
1474
1475
1476
1477
1478
1479 void ThreadMessageHandler(void* parg)
1480 {
1481     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1482     try
1483     {
1484         vnThreadsRunning[2]++;
1485         ThreadMessageHandler2(parg);
1486         vnThreadsRunning[2]--;
1487     }
1488     catch (std::exception& e) {
1489         vnThreadsRunning[2]--;
1490         PrintException(&e, "ThreadMessageHandler()");
1491     } catch (...) {
1492         vnThreadsRunning[2]--;
1493         PrintException(NULL, "ThreadMessageHandler()");
1494     }
1495     printf("ThreadMessageHandler exiting\n");
1496 }
1497
1498 void ThreadMessageHandler2(void* parg)
1499 {
1500     printf("ThreadMessageHandler started\n");
1501     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1502     while (!fShutdown)
1503     {
1504         vector<CNode*> vNodesCopy;
1505         CRITICAL_BLOCK(cs_vNodes)
1506         {
1507             vNodesCopy = vNodes;
1508             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1509                 pnode->AddRef();
1510         }
1511
1512         // Poll the connected nodes for messages
1513         CNode* pnodeTrickle = NULL;
1514         if (!vNodesCopy.empty())
1515             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1516         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1517         {
1518             // Receive messages
1519             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1520                 ProcessMessages(pnode);
1521             if (fShutdown)
1522                 return;
1523
1524             // Send messages
1525             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1526                 SendMessages(pnode, pnode == pnodeTrickle);
1527             if (fShutdown)
1528                 return;
1529         }
1530
1531         CRITICAL_BLOCK(cs_vNodes)
1532         {
1533             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1534                 pnode->Release();
1535         }
1536
1537         // Wait and allow messages to bunch up.
1538         // Reduce vnThreadsRunning so StopNode has permission to exit while
1539         // we're sleeping, but we must always check fShutdown after doing this.
1540         vnThreadsRunning[2]--;
1541         Sleep(100);
1542         if (fRequestShutdown)
1543             Shutdown(NULL);
1544         vnThreadsRunning[2]++;
1545         if (fShutdown)
1546             return;
1547     }
1548 }
1549
1550
1551
1552
1553
1554
1555 bool BindListenPort(string& strError)
1556 {
1557     strError = "";
1558     int nOne = 1;
1559     addrLocalHost.port = htons(GetListenPort());
1560
1561 #ifdef __WXMSW__
1562     // Initialize Windows Sockets
1563     WSADATA wsadata;
1564     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1565     if (ret != NO_ERROR)
1566     {
1567         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1568         printf("%s\n", strError.c_str());
1569         return false;
1570     }
1571 #endif
1572
1573     // Create socket for listening for incoming connections
1574     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1575     if (hListenSocket == INVALID_SOCKET)
1576     {
1577         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1578         printf("%s\n", strError.c_str());
1579         return false;
1580     }
1581
1582 #ifdef BSD
1583     // Different way of disabling SIGPIPE on BSD
1584     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1585 #endif
1586
1587 #ifndef __WXMSW__
1588     // Allow binding if the port is still in TIME_WAIT state after
1589     // the program was closed and restarted.  Not an issue on windows.
1590     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1591 #endif
1592
1593 #ifdef __WXMSW__
1594     // Set to nonblocking, incoming connections will also inherit this
1595     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1596 #else
1597     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1598 #endif
1599     {
1600         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1601         printf("%s\n", strError.c_str());
1602         return false;
1603     }
1604
1605     // The sockaddr_in structure specifies the address family,
1606     // IP address, and port for the socket that is being bound
1607     struct sockaddr_in sockaddr;
1608     memset(&sockaddr, 0, sizeof(sockaddr));
1609     sockaddr.sin_family = AF_INET;
1610     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1611     sockaddr.sin_port = htons(GetListenPort());
1612     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1613     {
1614         int nErr = WSAGetLastError();
1615         if (nErr == WSAEADDRINUSE)
1616             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1617         else
1618             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1619         printf("%s\n", strError.c_str());
1620         return false;
1621     }
1622     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1623
1624     // Listen for incoming connections
1625     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1626     {
1627         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1628         printf("%s\n", strError.c_str());
1629         return false;
1630     }
1631
1632     return true;
1633 }
1634
1635 void StartNode(void* parg)
1636 {
1637     if (pnodeLocalHost == NULL)
1638         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1639
1640 #ifdef __WXMSW__
1641     // Get local host ip
1642     char pszHostName[1000] = "";
1643     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1644     {
1645         vector<CAddress> vaddr;
1646         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1647             BOOST_FOREACH (const CAddress &addr, vaddr)
1648                 if (addr.GetByte(3) != 127)
1649                 {
1650                     addrLocalHost = addr;
1651                     break;
1652                 }
1653     }
1654 #else
1655     // Get local host ip
1656     struct ifaddrs* myaddrs;
1657     if (getifaddrs(&myaddrs) == 0)
1658     {
1659         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1660         {
1661             if (ifa->ifa_addr == NULL) continue;
1662             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1663             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1664             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1665             char pszIP[100];
1666             if (ifa->ifa_addr->sa_family == AF_INET)
1667             {
1668                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1669                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1670                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1671
1672                 // Take the first IP that isn't loopback 127.x.x.x
1673                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1674                 if (addr.IsValid() && addr.GetByte(3) != 127)
1675                 {
1676                     addrLocalHost = addr;
1677                     break;
1678                 }
1679             }
1680             else if (ifa->ifa_addr->sa_family == AF_INET6)
1681             {
1682                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1683                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1684                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1685             }
1686         }
1687         freeifaddrs(myaddrs);
1688     }
1689 #endif
1690     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1691
1692     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1693     {
1694         // Proxies can't take incoming connections
1695         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1696         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1697     }
1698     else
1699     {
1700         CreateThread(ThreadGetMyExternalIP, NULL);
1701     }
1702
1703     //
1704     // Start threads
1705     //
1706
1707     // Map ports with UPnP
1708     if (fHaveUPnP)
1709         MapPort(fUseUPnP);
1710
1711     // Get addresses from IRC and advertise ours
1712     if (!CreateThread(ThreadIRCSeed, NULL))
1713         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1714
1715     // Send and receive from sockets, accept connections
1716     CreateThread(ThreadSocketHandler, NULL, true);
1717
1718     // Initiate outbound connections
1719     if (!CreateThread(ThreadOpenConnections, NULL))
1720         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1721
1722     // Process messages
1723     if (!CreateThread(ThreadMessageHandler, NULL))
1724         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1725
1726     // Generate coins in the background
1727     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1728 }
1729
1730 bool StopNode()
1731 {
1732     printf("StopNode()\n");
1733     fShutdown = true;
1734     nTransactionsUpdated++;
1735     int64 nStart = GetTime();
1736     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1737 #ifdef USE_UPNP
1738         || vnThreadsRunning[5] > 0
1739 #endif
1740     )
1741     {
1742         if (GetTime() - nStart > 20)
1743             break;
1744         Sleep(20);
1745     }
1746     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1747     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1748     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1749     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1750     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1751     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1752     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1753         Sleep(20);
1754     Sleep(50);
1755
1756     return true;
1757 }
1758
1759 class CNetCleanup
1760 {
1761 public:
1762     CNetCleanup()
1763     {
1764     }
1765     ~CNetCleanup()
1766     {
1767         // Close sockets
1768         BOOST_FOREACH(CNode* pnode, vNodes)
1769             if (pnode->hSocket != INVALID_SOCKET)
1770                 closesocket(pnode->hSocket);
1771         if (hListenSocket != INVALID_SOCKET)
1772             if (closesocket(hListenSocket) == SOCKET_ERROR)
1773                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1774
1775 #ifdef __WXMSW__
1776         // Shutdown Windows Sockets
1777         WSACleanup();
1778 #endif
1779     }
1780 }
1781 instance_of_cnetcleanup;