Do-nothing MapPort() ifndef USE_UPNP. fixes #450
[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 #else
1147 void MapPort(bool /* unused fMapPort */)
1148 {
1149     // Intentionally left blank.
1150 }
1151 #endif
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162 static const char *strDNSSeed[] = {
1163     "bitseed.xf2.org",
1164     "bitseed.bitcoin.org.uk",
1165     "dnsseed.bluematt.me",
1166 };
1167
1168 void DNSAddressSeed()
1169 {
1170     int found = 0;
1171
1172     if (!fTestNet)
1173     {
1174         printf("Loading addresses from DNS seeds (could take a while)\n");
1175         CAddrDB addrDB;
1176         addrDB.TxnBegin();
1177
1178         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1179             vector<CAddress> vaddr;
1180             if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
1181             {
1182                 BOOST_FOREACH (CAddress& addr, vaddr)
1183                 {
1184                     if (addr.GetByte(3) != 127)
1185                     {
1186                         addr.nTime = 0;
1187                         AddAddress(addr, 0, &addrDB);
1188                         found++;
1189                     }
1190                 }
1191             }
1192         }
1193
1194         addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1195     }
1196
1197     printf("%d addresses found from DNS seeds\n", found);
1198 }
1199
1200
1201
1202 unsigned int pnSeed[] =
1203 {
1204     0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57,
1205     0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018,
1206     0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041,
1207     0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445,
1208     0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b,
1209     0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652,
1210     0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959,
1211     0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63,
1212     0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae,
1213     0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5,
1214     0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad,
1215     0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153,
1216     0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445,
1217     0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5,
1218     0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661,
1219     0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf,
1220     0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56,
1221     0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144,
1222     0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e,
1223     0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742,
1224     0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc,
1225     0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5,
1226     0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254,
1227     0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163,
1228     0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d,
1229     0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b,
1230     0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53,
1231     0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc,
1232     0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5,
1233     0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80,
1234     0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544,
1235     0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3,
1236     0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b,
1237     0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6,
1238     0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555,
1239     0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047,
1240     0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c,
1241     0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c,
1242     0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1,
1243     0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad,
1244 };
1245
1246
1247
1248 void ThreadOpenConnections(void* parg)
1249 {
1250     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1251     try
1252     {
1253         vnThreadsRunning[1]++;
1254         ThreadOpenConnections2(parg);
1255         vnThreadsRunning[1]--;
1256     }
1257     catch (std::exception& e) {
1258         vnThreadsRunning[1]--;
1259         PrintException(&e, "ThreadOpenConnections()");
1260     } catch (...) {
1261         vnThreadsRunning[1]--;
1262         PrintException(NULL, "ThreadOpenConnections()");
1263     }
1264     printf("ThreadOpenConnections exiting\n");
1265 }
1266
1267 void ThreadOpenConnections2(void* parg)
1268 {
1269     printf("ThreadOpenConnections started\n");
1270
1271     // Connect to specific addresses
1272     if (mapArgs.count("-connect"))
1273     {
1274         for (int64 nLoop = 0;; nLoop++)
1275         {
1276             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1277             {
1278                 CAddress addr(strAddr, fAllowDNS);
1279                 if (addr.IsValid())
1280                     OpenNetworkConnection(addr);
1281                 for (int i = 0; i < 10 && i < nLoop; i++)
1282                 {
1283                     Sleep(500);
1284                     if (fShutdown)
1285                         return;
1286                 }
1287             }
1288         }
1289     }
1290
1291     // Connect to manually added nodes first
1292     if (mapArgs.count("-addnode"))
1293     {
1294         BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
1295         {
1296             CAddress addr(strAddr, fAllowDNS);
1297             if (addr.IsValid())
1298             {
1299                 OpenNetworkConnection(addr);
1300                 Sleep(500);
1301                 if (fShutdown)
1302                     return;
1303             }
1304         }
1305     }
1306
1307     // Initiate network connections
1308     int64 nStart = GetTime();
1309     loop
1310     {
1311         // Limit outbound connections
1312         vnThreadsRunning[1]--;
1313         Sleep(500);
1314         loop
1315         {
1316             int nOutbound = 0;
1317             CRITICAL_BLOCK(cs_vNodes)
1318                 BOOST_FOREACH(CNode* pnode, vNodes)
1319                     if (!pnode->fInbound)
1320                         nOutbound++;
1321             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1322             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1323             if (nOutbound < nMaxOutboundConnections)
1324                 break;
1325             Sleep(2000);
1326             if (fShutdown)
1327                 return;
1328         }
1329         vnThreadsRunning[1]++;
1330         if (fShutdown)
1331             return;
1332
1333         CRITICAL_BLOCK(cs_mapAddresses)
1334         {
1335             // Add seed nodes if IRC isn't working
1336             static bool fSeedUsed;
1337             bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
1338             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1339             {
1340                 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1341                 {
1342                     // It'll only connect to one or two seed nodes because once it connects,
1343                     // it'll get a pile of addresses with newer timestamps.
1344                     CAddress addr;
1345                     addr.ip = pnSeed[i];
1346                     addr.nTime = 0;
1347                     AddAddress(addr);
1348                 }
1349                 fSeedUsed = true;
1350             }
1351
1352             if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100)
1353             {
1354                 // Disconnect seed nodes
1355                 set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed));
1356                 static int64 nSeedDisconnected;
1357                 if (nSeedDisconnected == 0)
1358                 {
1359                     nSeedDisconnected = GetTime();
1360                     CRITICAL_BLOCK(cs_vNodes)
1361                         BOOST_FOREACH(CNode* pnode, vNodes)
1362                             if (setSeed.count(pnode->addr.ip))
1363                                 pnode->fDisconnect = true;
1364                 }
1365
1366                 // Keep setting timestamps to 0 so they won't reconnect
1367                 if (GetTime() - nSeedDisconnected < 60 * 60)
1368                 {
1369                     BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses)
1370                     {
1371                         if (setSeed.count(item.second.ip) && item.second.nTime != 0)
1372                         {
1373                             item.second.nTime = 0;
1374                             CAddrDB().WriteAddress(item.second);
1375                         }
1376                     }
1377                 }
1378             }
1379         }
1380
1381
1382         //
1383         // Choose an address to connect to based on most recently seen
1384         //
1385         CAddress addrConnect;
1386         int64 nBest = INT64_MIN;
1387
1388         // Only connect to one address per a.b.?.? range.
1389         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1390         set<unsigned int> setConnected;
1391         CRITICAL_BLOCK(cs_vNodes)
1392             BOOST_FOREACH(CNode* pnode, vNodes)
1393                 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1394
1395         CRITICAL_BLOCK(cs_mapAddresses)
1396         {
1397             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1398             {
1399                 const CAddress& addr = item.second;
1400                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1401                     continue;
1402                 int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime;
1403                 int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry;
1404
1405                 // Randomize the order in a deterministic way, putting the standard port first
1406                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
1407                 if (addr.port != htons(GetDefaultPort()))
1408                     nRandomizer += 2 * 60 * 60;
1409
1410                 // Last seen  Base retry frequency
1411                 //   <1 hour   10 min
1412                 //    1 hour    1 hour
1413                 //    4 hours   2 hours
1414                 //   24 hours   5 hours
1415                 //   48 hours   7 hours
1416                 //    7 days   13 hours
1417                 //   30 days   27 hours
1418                 //   90 days   46 hours
1419                 //  365 days   93 hours
1420                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1421
1422                 // Fast reconnect for one hour after last seen
1423                 if (nSinceLastSeen < 60 * 60)
1424                     nDelay = 10 * 60;
1425
1426                 // Limit retry frequency
1427                 if (nSinceLastTry < nDelay)
1428                     continue;
1429
1430                 // If we have IRC, we'll be notified when they first come online,
1431                 // and again every 24 hours by the refresh broadcast.
1432                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1433                     continue;
1434
1435                 // Only try the old stuff if we don't have enough connections
1436                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1437                     continue;
1438
1439                 // If multiple addresses are ready, prioritize by time since
1440                 // last seen and time since last tried.
1441                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1442                 if (nScore > nBest)
1443                 {
1444                     nBest = nScore;
1445                     addrConnect = addr;
1446                 }
1447             }
1448         }
1449
1450         if (addrConnect.IsValid())
1451             OpenNetworkConnection(addrConnect);
1452     }
1453 }
1454
1455 bool OpenNetworkConnection(const CAddress& addrConnect)
1456 {
1457     //
1458     // Initiate outbound network connection
1459     //
1460     if (fShutdown)
1461         return false;
1462     if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
1463         return false;
1464
1465     vnThreadsRunning[1]--;
1466     CNode* pnode = ConnectNode(addrConnect);
1467     vnThreadsRunning[1]++;
1468     if (fShutdown)
1469         return false;
1470     if (!pnode)
1471         return false;
1472     pnode->fNetworkNode = true;
1473
1474     return true;
1475 }
1476
1477
1478
1479
1480
1481
1482
1483
1484 void ThreadMessageHandler(void* parg)
1485 {
1486     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1487     try
1488     {
1489         vnThreadsRunning[2]++;
1490         ThreadMessageHandler2(parg);
1491         vnThreadsRunning[2]--;
1492     }
1493     catch (std::exception& e) {
1494         vnThreadsRunning[2]--;
1495         PrintException(&e, "ThreadMessageHandler()");
1496     } catch (...) {
1497         vnThreadsRunning[2]--;
1498         PrintException(NULL, "ThreadMessageHandler()");
1499     }
1500     printf("ThreadMessageHandler exiting\n");
1501 }
1502
1503 void ThreadMessageHandler2(void* parg)
1504 {
1505     printf("ThreadMessageHandler started\n");
1506     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1507     while (!fShutdown)
1508     {
1509         vector<CNode*> vNodesCopy;
1510         CRITICAL_BLOCK(cs_vNodes)
1511         {
1512             vNodesCopy = vNodes;
1513             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1514                 pnode->AddRef();
1515         }
1516
1517         // Poll the connected nodes for messages
1518         CNode* pnodeTrickle = NULL;
1519         if (!vNodesCopy.empty())
1520             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1521         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1522         {
1523             // Receive messages
1524             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1525                 ProcessMessages(pnode);
1526             if (fShutdown)
1527                 return;
1528
1529             // Send messages
1530             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1531                 SendMessages(pnode, pnode == pnodeTrickle);
1532             if (fShutdown)
1533                 return;
1534         }
1535
1536         CRITICAL_BLOCK(cs_vNodes)
1537         {
1538             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1539                 pnode->Release();
1540         }
1541
1542         // Wait and allow messages to bunch up.
1543         // Reduce vnThreadsRunning so StopNode has permission to exit while
1544         // we're sleeping, but we must always check fShutdown after doing this.
1545         vnThreadsRunning[2]--;
1546         Sleep(100);
1547         if (fRequestShutdown)
1548             Shutdown(NULL);
1549         vnThreadsRunning[2]++;
1550         if (fShutdown)
1551             return;
1552     }
1553 }
1554
1555
1556
1557
1558
1559
1560 bool BindListenPort(string& strError)
1561 {
1562     strError = "";
1563     int nOne = 1;
1564     addrLocalHost.port = htons(GetListenPort());
1565
1566 #ifdef __WXMSW__
1567     // Initialize Windows Sockets
1568     WSADATA wsadata;
1569     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1570     if (ret != NO_ERROR)
1571     {
1572         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1573         printf("%s\n", strError.c_str());
1574         return false;
1575     }
1576 #endif
1577
1578     // Create socket for listening for incoming connections
1579     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1580     if (hListenSocket == INVALID_SOCKET)
1581     {
1582         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1583         printf("%s\n", strError.c_str());
1584         return false;
1585     }
1586
1587 #ifdef BSD
1588     // Different way of disabling SIGPIPE on BSD
1589     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1590 #endif
1591
1592 #ifndef __WXMSW__
1593     // Allow binding if the port is still in TIME_WAIT state after
1594     // the program was closed and restarted.  Not an issue on windows.
1595     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1596 #endif
1597
1598 #ifdef __WXMSW__
1599     // Set to nonblocking, incoming connections will also inherit this
1600     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1601 #else
1602     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1603 #endif
1604     {
1605         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1606         printf("%s\n", strError.c_str());
1607         return false;
1608     }
1609
1610     // The sockaddr_in structure specifies the address family,
1611     // IP address, and port for the socket that is being bound
1612     struct sockaddr_in sockaddr;
1613     memset(&sockaddr, 0, sizeof(sockaddr));
1614     sockaddr.sin_family = AF_INET;
1615     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1616     sockaddr.sin_port = htons(GetListenPort());
1617     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1618     {
1619         int nErr = WSAGetLastError();
1620         if (nErr == WSAEADDRINUSE)
1621             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1622         else
1623             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1624         printf("%s\n", strError.c_str());
1625         return false;
1626     }
1627     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1628
1629     // Listen for incoming connections
1630     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1631     {
1632         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1633         printf("%s\n", strError.c_str());
1634         return false;
1635     }
1636
1637     return true;
1638 }
1639
1640 void StartNode(void* parg)
1641 {
1642     if (pnodeLocalHost == NULL)
1643         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
1644
1645 #ifdef __WXMSW__
1646     // Get local host ip
1647     char pszHostName[1000] = "";
1648     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1649     {
1650         vector<CAddress> vaddr;
1651         if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
1652             BOOST_FOREACH (const CAddress &addr, vaddr)
1653                 if (addr.GetByte(3) != 127)
1654                 {
1655                     addrLocalHost = addr;
1656                     break;
1657                 }
1658     }
1659 #else
1660     // Get local host ip
1661     struct ifaddrs* myaddrs;
1662     if (getifaddrs(&myaddrs) == 0)
1663     {
1664         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1665         {
1666             if (ifa->ifa_addr == NULL) continue;
1667             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1668             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1669             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1670             char pszIP[100];
1671             if (ifa->ifa_addr->sa_family == AF_INET)
1672             {
1673                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1674                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1675                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1676
1677                 // Take the first IP that isn't loopback 127.x.x.x
1678                 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
1679                 if (addr.IsValid() && addr.GetByte(3) != 127)
1680                 {
1681                     addrLocalHost = addr;
1682                     break;
1683                 }
1684             }
1685             else if (ifa->ifa_addr->sa_family == AF_INET6)
1686             {
1687                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1688                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1689                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1690             }
1691         }
1692         freeifaddrs(myaddrs);
1693     }
1694 #endif
1695     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1696
1697     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1698     {
1699         // Proxies can't take incoming connections
1700         addrLocalHost.ip = CAddress("0.0.0.0").ip;
1701         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1702     }
1703     else
1704     {
1705         CreateThread(ThreadGetMyExternalIP, NULL);
1706     }
1707
1708     //
1709     // Start threads
1710     //
1711
1712     // Map ports with UPnP
1713     if (fHaveUPnP)
1714         MapPort(fUseUPnP);
1715
1716     // Get addresses from IRC and advertise ours
1717     if (!CreateThread(ThreadIRCSeed, NULL))
1718         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1719
1720     // Send and receive from sockets, accept connections
1721     CreateThread(ThreadSocketHandler, NULL, true);
1722
1723     // Initiate outbound connections
1724     if (!CreateThread(ThreadOpenConnections, NULL))
1725         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1726
1727     // Process messages
1728     if (!CreateThread(ThreadMessageHandler, NULL))
1729         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1730
1731     // Generate coins in the background
1732     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1733 }
1734
1735 bool StopNode()
1736 {
1737     printf("StopNode()\n");
1738     fShutdown = true;
1739     nTransactionsUpdated++;
1740     int64 nStart = GetTime();
1741     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1742 #ifdef USE_UPNP
1743         || vnThreadsRunning[5] > 0
1744 #endif
1745     )
1746     {
1747         if (GetTime() - nStart > 20)
1748             break;
1749         Sleep(20);
1750     }
1751     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1752     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1753     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1754     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1755     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1756     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1757     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1758         Sleep(20);
1759     Sleep(50);
1760
1761     return true;
1762 }
1763
1764 class CNetCleanup
1765 {
1766 public:
1767     CNetCleanup()
1768     {
1769     }
1770     ~CNetCleanup()
1771     {
1772         // Close sockets
1773         BOOST_FOREACH(CNode* pnode, vNodes)
1774             if (pnode->hSocket != INVALID_SOCKET)
1775                 closesocket(pnode->hSocket);
1776         if (hListenSocket != INVALID_SOCKET)
1777             if (closesocket(hListenSocket) == SOCKET_ERROR)
1778                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1779
1780 #ifdef __WXMSW__
1781         // Shutdown Windows Sockets
1782         WSACleanup();
1783 #endif
1784     }
1785 }
1786 instance_of_cnetcleanup;