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