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