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