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