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