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