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