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