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