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