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