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