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