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