Remove half-implemented publish/subscribe system
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "headers.h"
7 #include "irc.h"
8 #include "db.h"
9 #include "net.h"
10 #include "init.h"
11 #include "strlcpy.h"
12 #include "addrman.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 void ThreadOpenAddedConnections2(void* parg);
34 #ifdef USE_UPNP
35 void ThreadMapPort2(void* parg);
36 #endif
37 void ThreadDNSAddressSeed2(void* parg);
38 bool OpenNetworkConnection(const CAddress& addrConnect);
39
40
41
42 //
43 // Global state variables
44 //
45 bool fClient = false;
46 bool fAllowDNS = false;
47 static bool fUseUPnP = false;
48 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
49 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
50 static CNode* pnodeLocalHost = NULL;
51 uint64 nLocalHostNonce = 0;
52 array<int, THREAD_MAX> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
54 CAddrMan addrman;
55
56 vector<CNode*> vNodes;
57 CCriticalSection cs_vNodes;
58 map<CInv, CDataStream> mapRelay;
59 deque<pair<int64, CInv> > vRelayExpiration;
60 CCriticalSection cs_mapRelay;
61 map<CInv, int64> mapAlreadyAskedFor;
62
63
64 set<CNetAddr> setservAddNodeAddresses;
65 CCriticalSection cs_setservAddNodeAddresses;
66
67
68
69 unsigned short GetListenPort()
70 {
71     return (unsigned short)(GetArg("-port", GetDefaultPort()));
72 }
73
74 void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
75 {
76     // Filter out duplicate requests
77     if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
78         return;
79     pindexLastGetBlocksBegin = pindexBegin;
80     hashLastGetBlocksEnd = hashEnd;
81
82     PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
83 }
84
85
86
87 bool RecvLine(SOCKET hSocket, string& strLine)
88 {
89     strLine = "";
90     loop
91     {
92         char c;
93         int nBytes = recv(hSocket, &c, 1, 0);
94         if (nBytes > 0)
95         {
96             if (c == '\n')
97                 continue;
98             if (c == '\r')
99                 return true;
100             strLine += c;
101             if (strLine.size() >= 9000)
102                 return true;
103         }
104         else if (nBytes <= 0)
105         {
106             if (fShutdown)
107                 return false;
108             if (nBytes < 0)
109             {
110                 int nErr = WSAGetLastError();
111                 if (nErr == WSAEMSGSIZE)
112                     continue;
113                 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
114                 {
115                     Sleep(10);
116                     continue;
117                 }
118             }
119             if (!strLine.empty())
120                 return true;
121             if (nBytes == 0)
122             {
123                 // socket closed
124                 printf("socket closed\n");
125                 return false;
126             }
127             else
128             {
129                 // socket error
130                 int nErr = WSAGetLastError();
131                 printf("recv failed: %d\n", nErr);
132                 return false;
133             }
134         }
135     }
136 }
137
138
139
140 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
141 {
142     SOCKET hSocket;
143     if (!ConnectSocket(addrConnect, hSocket))
144         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
145
146     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
147
148     string strLine;
149     while (RecvLine(hSocket, strLine))
150     {
151         if (strLine.empty()) // HTTP response is separated from headers by blank line
152         {
153             loop
154             {
155                 if (!RecvLine(hSocket, strLine))
156                 {
157                     closesocket(hSocket);
158                     return false;
159                 }
160                 if (pszKeyword == NULL)
161                     break;
162                 if (strLine.find(pszKeyword) != -1)
163                 {
164                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
165                     break;
166                 }
167             }
168             closesocket(hSocket);
169             if (strLine.find("<") != -1)
170                 strLine = strLine.substr(0, strLine.find("<"));
171             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
172             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
173                 strLine.resize(strLine.size()-1);
174             CService addr(strLine,0,true);
175             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
176             if (!addr.IsValid() || !addr.IsRoutable())
177                 return false;
178             ipRet.SetIP(addr);
179             return true;
180         }
181     }
182     closesocket(hSocket);
183     return error("GetMyExternalIP() : connection closed");
184 }
185
186 // We now get our external IP from the IRC server first and only use this as a backup
187 bool GetMyExternalIP(CNetAddr& ipRet)
188 {
189     CService addrConnect;
190     const char* pszGet;
191     const char* pszKeyword;
192
193     if (fNoListen||fUseProxy)
194         return false;
195
196     for (int nLookup = 0; nLookup <= 1; nLookup++)
197     for (int nHost = 1; nHost <= 2; nHost++)
198     {
199         // We should be phasing out our use of sites like these.  If we need
200         // replacements, we should ask for volunteers to put this simple
201         // php file on their webserver that prints the client IP:
202         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
203         if (nHost == 1)
204         {
205             addrConnect = CService("91.198.22.70",80); // checkip.dyndns.org
206
207             if (nLookup == 1)
208             {
209                 CService addrIP("checkip.dyndns.org", 80, true);
210                 if (addrIP.IsValid())
211                     addrConnect = addrIP;
212             }
213
214             pszGet = "GET / HTTP/1.1\r\n"
215                      "Host: checkip.dyndns.org\r\n"
216                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
217                      "Connection: close\r\n"
218                      "\r\n";
219
220             pszKeyword = "Address:";
221         }
222         else if (nHost == 2)
223         {
224             addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
225
226             if (nLookup == 1)
227             {
228                 CService addrIP("www.showmyip.com", 80, true);
229                 if (addrIP.IsValid())
230                     addrConnect = addrIP;
231             }
232
233             pszGet = "GET /simple/ HTTP/1.1\r\n"
234                      "Host: www.showmyip.com\r\n"
235                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
236                      "Connection: close\r\n"
237                      "\r\n";
238
239             pszKeyword = NULL; // Returns just IP address
240         }
241
242         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
243             return true;
244     }
245
246     return false;
247 }
248
249 void ThreadGetMyExternalIP(void* parg)
250 {
251     // Wait for IRC to get it first
252     if (GetBoolArg("-irc", false))
253     {
254         for (int i = 0; i < 2 * 60; i++)
255         {
256             Sleep(1000);
257             if (fGotExternalIP || fShutdown)
258                 return;
259         }
260     }
261
262     // Fallback in case IRC fails to get it
263     if (GetMyExternalIP(addrLocalHost))
264     {
265         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
266         if (addrLocalHost.IsRoutable())
267         {
268             // If we already connected to a few before we had our IP, go back and addr them.
269             // setAddrKnown automatically filters any duplicate sends.
270             CAddress addr(addrLocalHost);
271             addr.nTime = GetAdjustedTime();
272             CRITICAL_BLOCK(cs_vNodes)
273                 BOOST_FOREACH(CNode* pnode, vNodes)
274                     pnode->PushAddress(addr);
275         }
276     }
277 }
278
279
280
281
282
283 void AddressCurrentlyConnected(const CService& addr)
284 {
285     addrman.Connected(addr);
286 }
287
288
289
290
291
292
293
294 CNode* FindNode(const CNetAddr& ip)
295 {
296     CRITICAL_BLOCK(cs_vNodes)
297     {
298         BOOST_FOREACH(CNode* pnode, vNodes)
299             if ((CNetAddr)pnode->addr == ip)
300                 return (pnode);
301     }
302     return NULL;
303 }
304
305 CNode* FindNode(const CService& addr)
306 {
307     CRITICAL_BLOCK(cs_vNodes)
308     {
309         BOOST_FOREACH(CNode* pnode, vNodes)
310             if ((CService)pnode->addr == addr)
311                 return (pnode);
312     }
313     return NULL;
314 }
315
316 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
317 {
318     if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
319         return NULL;
320
321     // Look for an existing connection
322     CNode* pnode = FindNode((CService)addrConnect);
323     if (pnode)
324     {
325         if (nTimeout != 0)
326             pnode->AddRef(nTimeout);
327         else
328             pnode->AddRef();
329         return pnode;
330     }
331
332     /// debug print
333     printf("trying connection %s lastseen=%.1fhrs\n",
334         addrConnect.ToString().c_str(),
335         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
336
337     addrman.Attempt(addrConnect);
338
339     // Connect
340     SOCKET hSocket;
341     if (ConnectSocket(addrConnect, hSocket))
342     {
343         /// debug print
344         printf("connected %s\n", addrConnect.ToString().c_str());
345
346         // Set to nonblocking
347 #ifdef WIN32
348         u_long nOne = 1;
349         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
350             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
351 #else
352         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
353             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
354 #endif
355
356         // Add node
357         CNode* pnode = new CNode(hSocket, addrConnect, false);
358         if (nTimeout != 0)
359             pnode->AddRef(nTimeout);
360         else
361             pnode->AddRef();
362         CRITICAL_BLOCK(cs_vNodes)
363             vNodes.push_back(pnode);
364
365         pnode->nTimeConnected = GetTime();
366         return pnode;
367     }
368     else
369     {
370         return NULL;
371     }
372 }
373
374 void CNode::CloseSocketDisconnect()
375 {
376     fDisconnect = true;
377     if (hSocket != INVALID_SOCKET)
378     {
379         if (fDebug)
380             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
381         printf("disconnecting node %s\n", addr.ToString().c_str());
382         closesocket(hSocket);
383         hSocket = INVALID_SOCKET;
384         vRecv.clear();
385     }
386 }
387
388 void CNode::Cleanup()
389 {
390 }
391
392
393 void CNode::PushVersion()
394 {
395     /// when NTP implemented, change to just nTime = GetAdjustedTime()
396     int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
397     CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
398     CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
399     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
400     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
401                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
402 }
403
404
405
406
407
408 std::map<CNetAddr, int64> CNode::setBanned;
409 CCriticalSection CNode::cs_setBanned;
410
411 void CNode::ClearBanned()
412 {
413     setBanned.clear();
414 }
415
416 bool CNode::IsBanned(CNetAddr ip)
417 {
418     bool fResult = false;
419     CRITICAL_BLOCK(cs_setBanned)
420     {
421         std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
422         if (i != setBanned.end())
423         {
424             int64 t = (*i).second;
425             if (GetTime() < t)
426                 fResult = true;
427         }
428     }
429     return fResult;
430 }
431
432 bool CNode::Misbehaving(int howmuch)
433 {
434     if (addr.IsLocal())
435     {
436         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
437         return false;
438     }
439
440     nMisbehavior += howmuch;
441     if (nMisbehavior >= GetArg("-banscore", 100))
442     {
443         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
444         CRITICAL_BLOCK(cs_setBanned)
445             if (setBanned[addr] < banTime)
446                 setBanned[addr] = banTime;
447         CloseSocketDisconnect();
448         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
449         return true;
450     }
451     return false;
452 }
453
454
455
456
457
458
459
460
461
462
463
464
465 void ThreadSocketHandler(void* parg)
466 {
467     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
468     try
469     {
470         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
471         ThreadSocketHandler2(parg);
472         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
473     }
474     catch (std::exception& e) {
475         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
476         PrintException(&e, "ThreadSocketHandler()");
477     } catch (...) {
478         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
479         throw; // support pthread_cancel()
480     }
481     printf("ThreadSocketHandler exiting\n");
482 }
483
484 void ThreadSocketHandler2(void* parg)
485 {
486     printf("ThreadSocketHandler started\n");
487     list<CNode*> vNodesDisconnected;
488     int nPrevNodeCount = 0;
489
490     loop
491     {
492         //
493         // Disconnect nodes
494         //
495         CRITICAL_BLOCK(cs_vNodes)
496         {
497             // Disconnect unused nodes
498             vector<CNode*> vNodesCopy = vNodes;
499             BOOST_FOREACH(CNode* pnode, vNodesCopy)
500             {
501                 if (pnode->fDisconnect ||
502                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
503                 {
504                     // remove from vNodes
505                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
506
507                     // close socket and cleanup
508                     pnode->CloseSocketDisconnect();
509                     pnode->Cleanup();
510
511                     // hold in disconnected pool until all refs are released
512                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
513                     if (pnode->fNetworkNode || pnode->fInbound)
514                         pnode->Release();
515                     vNodesDisconnected.push_back(pnode);
516                 }
517             }
518
519             // Delete disconnected nodes
520             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
521             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
522             {
523                 // wait until threads are done using it
524                 if (pnode->GetRefCount() <= 0)
525                 {
526                     bool fDelete = false;
527                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
528                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
529                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
530                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
531                         fDelete = true;
532                     if (fDelete)
533                     {
534                         vNodesDisconnected.remove(pnode);
535                         delete pnode;
536                     }
537                 }
538             }
539         }
540         if (vNodes.size() != nPrevNodeCount)
541         {
542             nPrevNodeCount = vNodes.size();
543             MainFrameRepaint();
544         }
545
546
547         //
548         // Find which sockets have data to receive
549         //
550         struct timeval timeout;
551         timeout.tv_sec  = 0;
552         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
553
554         fd_set fdsetRecv;
555         fd_set fdsetSend;
556         fd_set fdsetError;
557         FD_ZERO(&fdsetRecv);
558         FD_ZERO(&fdsetSend);
559         FD_ZERO(&fdsetError);
560         SOCKET hSocketMax = 0;
561
562         if(hListenSocket != INVALID_SOCKET)
563             FD_SET(hListenSocket, &fdsetRecv);
564         hSocketMax = max(hSocketMax, hListenSocket);
565         CRITICAL_BLOCK(cs_vNodes)
566         {
567             BOOST_FOREACH(CNode* pnode, vNodes)
568             {
569                 if (pnode->hSocket == INVALID_SOCKET)
570                     continue;
571                 FD_SET(pnode->hSocket, &fdsetRecv);
572                 FD_SET(pnode->hSocket, &fdsetError);
573                 hSocketMax = max(hSocketMax, pnode->hSocket);
574                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
575                     if (!pnode->vSend.empty())
576                         FD_SET(pnode->hSocket, &fdsetSend);
577             }
578         }
579
580         vnThreadsRunning[THREAD_SOCKETHANDLER]--;
581         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
582         vnThreadsRunning[THREAD_SOCKETHANDLER]++;
583         if (fShutdown)
584             return;
585         if (nSelect == SOCKET_ERROR)
586         {
587             int nErr = WSAGetLastError();
588             if (hSocketMax > -1)
589             {
590                 printf("socket select error %d\n", nErr);
591                 for (int i = 0; i <= hSocketMax; i++)
592                     FD_SET(i, &fdsetRecv);
593             }
594             FD_ZERO(&fdsetSend);
595             FD_ZERO(&fdsetError);
596             Sleep(timeout.tv_usec/1000);
597         }
598
599
600         //
601         // Accept new connections
602         //
603         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
604         {
605             struct sockaddr_in sockaddr;
606             socklen_t len = sizeof(sockaddr);
607             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
608             CAddress addr;
609             int nInbound = 0;
610
611             if (hSocket != INVALID_SOCKET)
612                 addr = CAddress(sockaddr);
613
614             CRITICAL_BLOCK(cs_vNodes)
615                 BOOST_FOREACH(CNode* pnode, vNodes)
616                 if (pnode->fInbound)
617                     nInbound++;
618
619             if (hSocket == INVALID_SOCKET)
620             {
621                 if (WSAGetLastError() != WSAEWOULDBLOCK)
622                     printf("socket error accept failed: %d\n", WSAGetLastError());
623             }
624             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
625             {
626                 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
627                     if (!setservAddNodeAddresses.count(addr))
628                         closesocket(hSocket);
629             }
630             else if (CNode::IsBanned(addr))
631             {
632                 printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
633                 closesocket(hSocket);
634             }
635             else
636             {
637                 printf("accepted connection %s\n", addr.ToString().c_str());
638                 CNode* pnode = new CNode(hSocket, addr, true);
639                 pnode->AddRef();
640                 CRITICAL_BLOCK(cs_vNodes)
641                     vNodes.push_back(pnode);
642             }
643         }
644
645
646         //
647         // Service each socket
648         //
649         vector<CNode*> vNodesCopy;
650         CRITICAL_BLOCK(cs_vNodes)
651         {
652             vNodesCopy = vNodes;
653             BOOST_FOREACH(CNode* pnode, vNodesCopy)
654                 pnode->AddRef();
655         }
656         BOOST_FOREACH(CNode* pnode, vNodesCopy)
657         {
658             if (fShutdown)
659                 return;
660
661             //
662             // Receive
663             //
664             if (pnode->hSocket == INVALID_SOCKET)
665                 continue;
666             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
667             {
668                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
669                 {
670                     CDataStream& vRecv = pnode->vRecv;
671                     unsigned int nPos = vRecv.size();
672
673                     if (nPos > ReceiveBufferSize()) {
674                         if (!pnode->fDisconnect)
675                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
676                         pnode->CloseSocketDisconnect();
677                     }
678                     else {
679                         // typical socket buffer is 8K-64K
680                         char pchBuf[0x10000];
681                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
682                         if (nBytes > 0)
683                         {
684                             vRecv.resize(nPos + nBytes);
685                             memcpy(&vRecv[nPos], pchBuf, nBytes);
686                             pnode->nLastRecv = GetTime();
687                         }
688                         else if (nBytes == 0)
689                         {
690                             // socket closed gracefully
691                             if (!pnode->fDisconnect)
692                                 printf("socket closed\n");
693                             pnode->CloseSocketDisconnect();
694                         }
695                         else if (nBytes < 0)
696                         {
697                             // error
698                             int nErr = WSAGetLastError();
699                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
700                             {
701                                 if (!pnode->fDisconnect)
702                                     printf("socket recv error %d\n", nErr);
703                                 pnode->CloseSocketDisconnect();
704                             }
705                         }
706                     }
707                 }
708             }
709
710             //
711             // Send
712             //
713             if (pnode->hSocket == INVALID_SOCKET)
714                 continue;
715             if (FD_ISSET(pnode->hSocket, &fdsetSend))
716             {
717                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
718                 {
719                     CDataStream& vSend = pnode->vSend;
720                     if (!vSend.empty())
721                     {
722                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
723                         if (nBytes > 0)
724                         {
725                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
726                             pnode->nLastSend = GetTime();
727                         }
728                         else if (nBytes < 0)
729                         {
730                             // error
731                             int nErr = WSAGetLastError();
732                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
733                             {
734                                 printf("socket send error %d\n", nErr);
735                                 pnode->CloseSocketDisconnect();
736                             }
737                         }
738                         if (vSend.size() > SendBufferSize()) {
739                             if (!pnode->fDisconnect)
740                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
741                             pnode->CloseSocketDisconnect();
742                         }
743                     }
744                 }
745             }
746
747             //
748             // Inactivity checking
749             //
750             if (pnode->vSend.empty())
751                 pnode->nLastSendEmpty = GetTime();
752             if (GetTime() - pnode->nTimeConnected > 60)
753             {
754                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
755                 {
756                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
757                     pnode->fDisconnect = true;
758                 }
759                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
760                 {
761                     printf("socket not sending\n");
762                     pnode->fDisconnect = true;
763                 }
764                 else if (GetTime() - pnode->nLastRecv > 90*60)
765                 {
766                     printf("socket inactivity timeout\n");
767                     pnode->fDisconnect = true;
768                 }
769             }
770         }
771         CRITICAL_BLOCK(cs_vNodes)
772         {
773             BOOST_FOREACH(CNode* pnode, vNodesCopy)
774                 pnode->Release();
775         }
776
777         Sleep(10);
778     }
779 }
780
781
782
783
784
785
786
787
788
789 #ifdef USE_UPNP
790 void ThreadMapPort(void* parg)
791 {
792     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
793     try
794     {
795         vnThreadsRunning[THREAD_UPNP]++;
796         ThreadMapPort2(parg);
797         vnThreadsRunning[THREAD_UPNP]--;
798     }
799     catch (std::exception& e) {
800         vnThreadsRunning[THREAD_UPNP]--;
801         PrintException(&e, "ThreadMapPort()");
802     } catch (...) {
803         vnThreadsRunning[THREAD_UPNP]--;
804         PrintException(NULL, "ThreadMapPort()");
805     }
806     printf("ThreadMapPort exiting\n");
807 }
808
809 void ThreadMapPort2(void* parg)
810 {
811     printf("ThreadMapPort started\n");
812
813     char port[6];
814     sprintf(port, "%d", GetListenPort());
815
816     const char * multicastif = 0;
817     const char * minissdpdpath = 0;
818     struct UPNPDev * devlist = 0;
819     char lanaddr[64];
820
821 #ifndef UPNPDISCOVER_SUCCESS
822     /* miniupnpc 1.5 */
823     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
824 #else
825     /* miniupnpc 1.6 */
826     int error = 0;
827     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
828 #endif
829
830     struct UPNPUrls urls;
831     struct IGDdatas data;
832     int r;
833
834     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
835     if (r == 1)
836     {
837         if (!addrLocalHost.IsRoutable())
838         {
839             char externalIPAddress[40];
840             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
841             if(r != UPNPCOMMAND_SUCCESS)
842                 printf("UPnP: GetExternalIPAddress() returned %d\n", r);
843             else
844             {
845                 if(externalIPAddress[0])
846                 {
847                     printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
848                     CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
849                     if (addrExternalFromUPnP.IsRoutable())
850                         addrLocalHost = addrExternalFromUPnP;
851                 }
852                 else
853                     printf("UPnP: GetExternalIPAddress failed.\n");
854             }
855         }
856
857         string strDesc = "Bitcoin " + FormatFullVersion();
858 #ifndef UPNPDISCOVER_SUCCESS
859         /* miniupnpc 1.5 */
860         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
861                             port, port, lanaddr, strDesc.c_str(), "TCP", 0);
862 #else
863         /* miniupnpc 1.6 */
864         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
865                             port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
866 #endif
867
868         if(r!=UPNPCOMMAND_SUCCESS)
869             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
870                 port, port, lanaddr, r, strupnperror(r));
871         else
872             printf("UPnP Port Mapping successful.\n");
873         int i = 1;
874         loop {
875             if (fShutdown || !fUseUPnP)
876             {
877                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
878                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
879                 freeUPNPDevlist(devlist); devlist = 0;
880                 FreeUPNPUrls(&urls);
881                 return;
882             }
883             if (i % 600 == 0) // Refresh every 20 minutes
884             {
885 #ifndef UPNPDISCOVER_SUCCESS
886                 /* miniupnpc 1.5 */
887                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
888                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0);
889 #else
890                 /* miniupnpc 1.6 */
891                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
892                                     port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
893 #endif
894
895                 if(r!=UPNPCOMMAND_SUCCESS)
896                     printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
897                         port, port, lanaddr, r, strupnperror(r));
898                 else
899                     printf("UPnP Port Mapping successful.\n");;
900             }
901             Sleep(2000);
902             i++;
903         }
904     } else {
905         printf("No valid UPnP IGDs found\n");
906         freeUPNPDevlist(devlist); devlist = 0;
907         if (r != 0)
908             FreeUPNPUrls(&urls);
909         loop {
910             if (fShutdown || !fUseUPnP)
911                 return;
912             Sleep(2000);
913         }
914     }
915 }
916
917 void MapPort(bool fMapPort)
918 {
919     if (fUseUPnP != fMapPort)
920     {
921         fUseUPnP = fMapPort;
922     }
923     if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
924     {
925         if (!CreateThread(ThreadMapPort, NULL))
926             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
927     }
928 }
929 #else
930 void MapPort(bool /* unused fMapPort */)
931 {
932     // Intentionally left blank.
933 }
934 #endif
935
936
937
938
939
940
941
942
943
944 // DNS seeds
945 // Each pair gives a source name and a seed name.
946 // The first name is used as information source for addrman.
947 // The second name should resolve to a list of seed addresses.
948 static const char *strDNSSeed[][2] = {
949     {"xf2.org", "bitseed.xf2.org"},
950     {"bluematt.me", "dnsseed.bluematt.me"},
951     {"bitcoin.sipa.be", "seed.bitcoin.sipa.be"},
952     {"dashjr.org", "dnsseed.bitcoin.dashjr.org"},
953 };
954
955 void ThreadDNSAddressSeed(void* parg)
956 {
957     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
958     try
959     {
960         vnThreadsRunning[THREAD_DNSSEED]++;
961         ThreadDNSAddressSeed2(parg);
962         vnThreadsRunning[THREAD_DNSSEED]--;
963     }
964     catch (std::exception& e) {
965         vnThreadsRunning[THREAD_DNSSEED]--;
966         PrintException(&e, "ThreadDNSAddressSeed()");
967     } catch (...) {
968         vnThreadsRunning[THREAD_DNSSEED]--;
969         throw; // support pthread_cancel()
970     }
971     printf("ThreadDNSAddressSeed exiting\n");
972 }
973
974 void ThreadDNSAddressSeed2(void* parg)
975 {
976     printf("ThreadDNSAddressSeed started\n");
977     int found = 0;
978
979     if (!fTestNet)
980     {
981         printf("Loading addresses from DNS seeds (could take a while)\n");
982
983         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
984             vector<CNetAddr> vaddr;
985             vector<CAddress> vAdd;
986             if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
987             {
988                 BOOST_FOREACH(CNetAddr& ip, vaddr)
989                 {
990                     int nOneDay = 24*3600;
991                     CAddress addr = CAddress(CService(ip, GetDefaultPort()));
992                     addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
993                     vAdd.push_back(addr);
994                     found++;
995                 }
996             }
997             addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
998         }
999     }
1000
1001     printf("%d addresses found from DNS seeds\n", found);
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015 unsigned int pnSeed[] =
1016 {
1017     0x959bd347, 0xf8de42b2, 0x73bc0518, 0xea6edc50, 0x21b00a4d, 0xc725b43d, 0xd665464d, 0x1a2a770e,
1018     0x27c93946, 0x65b2fa46, 0xb80ae255, 0x66b3b446, 0xb1877a3e, 0x6ee89e3e, 0xc3175b40, 0x2a01a83c,
1019     0x95b1363a, 0xa079ad3d, 0xe6ca801f, 0x027f4f4a, 0x34f7f03a, 0xf790f04a, 0x16ca801f, 0x2f4d5e40,
1020     0x3a4d5e40, 0xc43a322e, 0xc8159753, 0x14d4724c, 0x7919a118, 0xe0bdb34e, 0x68a16b2e, 0xff64b44d,
1021     0x6099115b, 0x9b57b05b, 0x7bd1b4ad, 0xdf95944f, 0x29d2b73d, 0xafa8db79, 0xe247ba41, 0x24078348,
1022     0xf722f03c, 0x33567ebc, 0xace64ed4, 0x984d3932, 0xb5f34e55, 0x27b7024d, 0x94579247, 0x8894042e,
1023     0x9357d34c, 0x1063c24b, 0xcaa228b1, 0xa3c5a8b2, 0x5dc64857, 0xa2c23643, 0xa8369a54, 0x31203077,
1024     0x00707c5c, 0x09fc0b3a, 0x272e9e2e, 0xf80f043e, 0x9449ca3e, 0x5512c33e, 0xd106b555, 0xe8024157,
1025     0xe288ec29, 0xc79c5461, 0xafb63932, 0xdb02ab4b, 0x0e512777, 0x8a145a4c, 0xb201ff4f, 0x5e09314b,
1026     0xcd9bfbcd, 0x1c023765, 0x4394e75c, 0xa728bd4d, 0x65331552, 0xa98420b1, 0x89ecf559, 0x6e80801f,
1027     0xf404f118, 0xefd62b51, 0x05918346, 0x9b186d5f, 0xacabab46, 0xf912e255, 0xc188ea62, 0xcc55734e,
1028     0xc668064d, 0xd77a4558, 0x46201c55, 0xf17dfc80, 0xf7142f2e, 0x87bfb718, 0x8aa54fb2, 0xc451d518,
1029     0xc4ae8831, 0x8dd44d55, 0x5bbd206c, 0x64536b5d, 0x5c667e60, 0x3b064242, 0xfe963a42, 0xa28e6dc8,
1030     0xe8a9604a, 0xc989464e, 0xd124a659, 0x50065140, 0xa44dfe5e, 0x1079e655, 0x3fb986d5, 0x47895b18,
1031     0x7d3ce4ad, 0x4561ba50, 0x296eec62, 0x255b41ad, 0xaed35ec9, 0x55556f12, 0xc7d3154d, 0x3297b65d,
1032     0x8930121f, 0xabf42e4e, 0x4a29e044, 0x1212685d, 0x676c1e40, 0xce009744, 0x383a8948, 0xa2dbd0ad,
1033     0xecc2564d, 0x07dbc252, 0x887ee24b, 0x5171644c, 0x6bb798c1, 0x847f495d, 0x4cbb7145, 0x3bb81c32,
1034     0x45eb262e, 0xc8015a4e, 0x250a361b, 0xf694f946, 0xd64a183e, 0xd4f1dd59, 0x8f20ffd4, 0x51d9e55c,
1035     0x09521763, 0x5e02002e, 0x32c8074d, 0xe685762e, 0x8290b0bc, 0x762a922e, 0xfc5ee754, 0x83a24829,
1036     0x775b224d, 0x6295bb4d, 0x38ec0555, 0xbffbba50, 0xe5560260, 0x86b16a7c, 0xd372234e, 0x49a3c24b,
1037     0x2f6a171f, 0x4d75ed60, 0xae94115b, 0xcb543744, 0x63080c59, 0x3f9c724c, 0xc977ce18, 0x532efb18,
1038     0x69dc3b2e, 0x5f94d929, 0x1732bb4d, 0x9c814b4d, 0xe6b3762e, 0xc024f662, 0x8face35b, 0x6b5b044d,
1039     0x798c7b57, 0x79a6b44c, 0x067d3057, 0xf9e94e5f, 0x91cbe15b, 0x71405eb2, 0x2662234e, 0xcbcc4a6d,
1040     0xbf69d54b, 0xa79b4e55, 0xec6d3e51, 0x7c0b3c02, 0x60f83653, 0x24c1e15c, 0x1110b62e, 0x10350f59,
1041     0xa56f1d55, 0x3509e7a9, 0xeb128354, 0x14268e2e, 0x934e28bc, 0x8e32692e, 0x8331a21f, 0x3e633932,
1042     0xc812b12e, 0xc684bf2e, 0x80112d2e, 0xe0ddc96c, 0xc630ca4a, 0x5c09b3b2, 0x0b580518, 0xc8e9d54b,
1043     0xd169aa43, 0x17d0d655, 0x1d029963, 0x7ff87559, 0xcb701f1f, 0x6fa3e85d, 0xe45e9a54, 0xf05d1802,
1044     0x44d03b2e, 0x837b692e, 0xccd4354e, 0x3d6da13c, 0x3423084d, 0xf707c34a, 0x55f6db3a, 0xad26e442,
1045     0x6233a21f, 0x09e80e59, 0x8caeb54d, 0xbe870941, 0xb407d20e, 0x20b51018, 0x56fb152e, 0x460d2a4e,
1046     0xbb9a2946, 0x560eb12e, 0xed83dd29, 0xd6724f53, 0xa50aafb8, 0x451346d9, 0x88348e2e, 0x7312fead,
1047     0x8ecaf96f, 0x1bda4e5f, 0xf1671e40, 0x3c8c3e3b, 0x4716324d, 0xdde24ede, 0xf98cd17d, 0xa91d4644,
1048     0x28124eb2, 0x147d5129, 0xd022042e, 0x61733d3b, 0xad0d5e02, 0x8ce2932e, 0xe5c18502, 0x549c1e32,
1049     0x9685801f, 0x86e217ad, 0xd948214b, 0x4110f462, 0x3a2e894e, 0xbd35492e, 0x87e0d558, 0x64b8ef7d,
1050     0x7c3eb962, 0x72a84b3e, 0x7cd667c9, 0x28370a2e, 0x4bc60e7b, 0x6fc1ec60, 0x14a6983f, 0x86739a4b,
1051     0x46954e5f, 0x32e2e15c, 0x2e9326cf, 0xe5801c5e, 0x379607b2, 0x32151145, 0xf0e39744, 0xacb54c55,
1052     0xa37dfb60, 0x83b55cc9, 0x388f7ca5, 0x15034f5f, 0x3e94965b, 0x68e0ffad, 0x35280f59, 0x8fe190cf,
1053     0x7c6ba5b2, 0xa5e9db43, 0x4ee1fc60, 0xd9d94e5f, 0x04040677, 0x0ea9b35e, 0x5961f14f, 0x67fda063,
1054     0xa48a5a31, 0xc6524e55, 0x283d325e, 0x3f37515f, 0x96b94b3e, 0xacce620e, 0x6481cc5b, 0xa4a06d4b,
1055     0x9e95d2d9, 0xe40c03d5, 0xc2f4514b, 0xb79aad44, 0xf64be843, 0xb2064070, 0xfca00455, 0x429dfa4e,
1056     0x2323f173, 0xeda4185e, 0xabd5227d, 0x9efd4d58, 0xb1104758, 0x4811e955, 0xbd9ab355, 0xe921f44b,
1057     0x9f166dce, 0x09e279b2, 0xe0c9ac7b, 0x7901a5ad, 0xa145d4b0, 0x79104671, 0xec31e35a, 0x4fe0b555,
1058     0xc7d9cbad, 0xad057f55, 0xe94cc759, 0x7fe0b043, 0xe4529f2e, 0x0d4dd4b2, 0x9f11a54d, 0x031e2e4e,
1059     0xe6014f5f, 0x11d1ca6c, 0x26bd7f61, 0xeb86854f, 0x4d347b57, 0x116bbe2e, 0xdba7234e, 0x7bcbfd2e,
1060     0x174dd4b2, 0x6686762e, 0xb089ba50, 0xc6258246, 0x087e767b, 0xc4a8cb4a, 0x595dba50, 0x7f0ae502,
1061     0x7b1dbd5a, 0xa0603492, 0x57d1af4b, 0x9e21ffd4, 0x6393064d, 0x7407376e, 0xe484762e, 0x122a4e53,
1062     0x4a37aa43, 0x3888a6be, 0xee77864e, 0x039c8dd5, 0x688d89af, 0x0e988f62, 0x08218246, 0xfc2f8246,
1063     0xd1d97040, 0xd64cd4b2, 0x5ae4a6b8, 0x7d0de9bc, 0x8d304d61, 0x06c5c672, 0xa4c8bd4d, 0xe0fd373b,
1064     0x575ebe4d, 0x72d26277, 0x55570f55, 0x77b154d9, 0xe214293a, 0xfc740f4b, 0xfe3f6a57, 0xa9c55f02,
1065     0xae4054db, 0x2394d918, 0xb511b24a, 0xb8741ab2, 0x0758e65e, 0xc7b5795b, 0xb0a30a4c, 0xaf7f170c,
1066     0xf3b4762e, 0x8179576d, 0x738a1581, 0x4b95b64c, 0x9829b618, 0x1bea932e, 0x7bdeaa4b, 0xcb5e0281,
1067     0x65618f54, 0x0658474b, 0x27066acf, 0x40556d65, 0x7d204d53, 0xf28bc244, 0xdce23455, 0xadc0ff54,
1068     0x3863c948, 0xcee34e5f, 0xdeb85e02, 0x2ed17a61, 0x6a7b094d, 0x7f0cfc40, 0x59603f54, 0x3220afbc,
1069     0xb5dfd962, 0x125d21c0, 0x13f8d243, 0xacfefb4e, 0x86c2c147, 0x3d8bbd59, 0xbd02a21f, 0x2593042e,
1070     0xc6a17a7c, 0x28925861, 0xb487ed44, 0xb5f4fd6d, 0x90c28a45, 0x5a14f74d, 0x43d71b4c, 0x728ebb5d,
1071     0x885bf950, 0x08134dd0, 0x38ec046e, 0xc575684b, 0x50082d2e, 0xa2f47757, 0x270f86ae, 0xf3ff6462,
1072     0x10ed3f4e, 0x4b58d462, 0xe01ce23e, 0x8c5b092e, 0x63e52f4e, 0x22c1e85d, 0xa908f54e, 0x8591624f,
1073     0x2c0fb94e, 0xa280ba3c, 0xb6f41b4c, 0x24f9aa47, 0x27201647, 0x3a3ea6dc, 0xa14fc3be, 0x3c34bdd5,
1074     0x5b8d4f5b, 0xaadeaf4b, 0xc71cab50, 0x15697a4c, 0x9a1a734c, 0x2a037d81, 0x2590bd59, 0x48ec2741,
1075     0x53489c5b, 0x7f00314b, 0x2170d362, 0xf2e92542, 0x42c10b44, 0x98f0f118, 0x883a3456, 0x099a932e,
1076     0xea38f7bc, 0x644e9247, 0xbb61b62e, 0x30e0863d, 0x5f51be54, 0x207215c7, 0x5f306c45, 0xaa7f3932,
1077     0x98da7d45, 0x4e339b59, 0x2e411581, 0xa808f618, 0xad2c0c59, 0x54476741, 0x09e99fd1, 0x5db8f752,
1078     0xc16df8bd, 0x1dd4b44f, 0x106edf2e, 0x9e15c180, 0x2ad6b56f, 0x633a5332, 0xff33787c, 0x077cb545,
1079     0x6610be6d, 0x75aad2c4, 0x72fb4d5b, 0xe81e0f59, 0x576f6332, 0x47333373, 0x351ed783, 0x2d90fb50,
1080     0x8d5e0f6c, 0x5b27a552, 0xdb293ebb, 0xe55ef950, 0x4b133ad8, 0x75df975a, 0x7b6a8740, 0xa899464b,
1081     0xfab15161, 0x10f8b64d, 0xd055ea4d, 0xee8e146b, 0x4b14afb8, 0x4bc1c44a, 0x9b961dcc, 0xd111ff43,
1082     0xfca0b745, 0xc800e412, 0x0afad9d1, 0xf751c350, 0xf9f0cccf, 0xa290a545, 0x8ef13763, 0x7ec70d59,
1083     0x2b066acf, 0x65496c45, 0xade02c1b, 0xae6eb077, 0x92c1e65b, 0xc064e6a9, 0xc649e56d, 0x5287a243,
1084     0x36de4f5b, 0x5b1df6ad, 0x65c39a59, 0xdba805b2, 0x20067aa8, 0x6457e56d, 0x3cee26cf, 0xfd3ff26d,
1085     0x04f86d4a, 0x06b8e048, 0xa93bcd5c, 0x91135852, 0xbe90a643, 0x8fa0094d, 0x06d8215f, 0x2677094d,
1086     0xd735685c, 0x164a00c9, 0x5209ac5f, 0xa9564c5c, 0x3b504f5f, 0xcc826bd0, 0x4615042e, 0x5fe13b4a,
1087     0x8c81b86d, 0x879ab68c, 0x1de564b8, 0x434487d8, 0x2dcb1b63, 0x82ab524a, 0xb0676abb, 0xa13d9c62,
1088     0xdbb5b86d, 0x5b7f4b59, 0xaddfb44d, 0xad773532, 0x3997054c, 0x72cebd89, 0xb194544c, 0xc5b8046e,
1089     0x6e1adeb2, 0xaa5abb51, 0xefb54b44, 0x15efc54f, 0xe9f1bc4d, 0x5f401b6c, 0x97f018ad, 0xc82f9252,
1090     0x2cdc762e, 0x8e52e56d, 0x1827175e, 0x9b7d7d80, 0xb2ad6845, 0x51065140, 0x71180a18, 0x5b27006c,
1091     0x0621e255, 0x721cbe58, 0x670c0cb8, 0xf8bd715d, 0xe0bdc5d9, 0xed843501, 0x4b84554d, 0x7f1a18bc,
1092     0x53bcaf47, 0x5729d35f, 0xf0dda246, 0x22382bd0, 0x4d641fb0, 0x316afcde, 0x50a22f1f, 0x73608046,
1093     0xc461d84a, 0xb2dbe247,
1094 };
1095
1096 void DumpAddresses()
1097 {
1098     CAddrDB adb;
1099     adb.WriteAddrman(addrman);
1100 }
1101
1102 void ThreadDumpAddress2(void* parg)
1103 {
1104     vnThreadsRunning[THREAD_DUMPADDRESS]++;
1105     while (!fShutdown)
1106     {
1107         DumpAddresses();
1108         vnThreadsRunning[THREAD_DUMPADDRESS]--;
1109         Sleep(100000);
1110         vnThreadsRunning[THREAD_DUMPADDRESS]++;
1111     }
1112     vnThreadsRunning[THREAD_DUMPADDRESS]--;
1113 }
1114
1115 void ThreadDumpAddress(void* parg)
1116 {
1117     IMPLEMENT_RANDOMIZE_STACK(ThreadDumpAddress(parg));
1118     try
1119     {
1120         ThreadDumpAddress2(parg);
1121     }
1122     catch (std::exception& e) {
1123         PrintException(&e, "ThreadDumpAddress()");
1124     }
1125     printf("ThreadDumpAddress exiting\n");
1126 }
1127
1128 void ThreadOpenConnections(void* parg)
1129 {
1130     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1131     try
1132     {
1133         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1134         ThreadOpenConnections2(parg);
1135         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1136     }
1137     catch (std::exception& e) {
1138         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1139         PrintException(&e, "ThreadOpenConnections()");
1140     } catch (...) {
1141         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1142         PrintException(NULL, "ThreadOpenConnections()");
1143     }
1144     printf("ThreadOpenConnections exiting\n");
1145 }
1146
1147 void ThreadOpenConnections2(void* parg)
1148 {
1149     printf("ThreadOpenConnections started\n");
1150
1151     // Connect to specific addresses
1152     if (mapArgs.count("-connect"))
1153     {
1154         for (int64 nLoop = 0;; nLoop++)
1155         {
1156             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1157             {
1158                 CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
1159                 if (addr.IsValid())
1160                     OpenNetworkConnection(addr);
1161                 for (int i = 0; i < 10 && i < nLoop; i++)
1162                 {
1163                     Sleep(500);
1164                     if (fShutdown)
1165                         return;
1166                 }
1167             }
1168         }
1169     }
1170
1171     // Initiate network connections
1172     int64 nStart = GetTime();
1173     loop
1174     {
1175         int nOutbound = 0;
1176
1177         vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1178         Sleep(500);
1179         vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1180         if (fShutdown)
1181             return;
1182
1183         // Limit outbound connections
1184         loop
1185         {
1186             nOutbound = 0;
1187             CRITICAL_BLOCK(cs_vNodes)
1188                 BOOST_FOREACH(CNode* pnode, vNodes)
1189                     if (!pnode->fInbound)
1190                         nOutbound++;
1191             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1192             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1193             if (nOutbound < nMaxOutboundConnections)
1194                 break;
1195             vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1196             Sleep(2000);
1197             vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1198             if (fShutdown)
1199                 return;
1200         }
1201
1202         bool fAddSeeds = false;
1203
1204         // Add seed nodes if IRC isn't working
1205         bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1206         if (addrman.size()==0 && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1207         {
1208             std::vector<CAddress> vAdd;
1209             for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1210             {
1211                 // It'll only connect to one or two seed nodes because once it connects,
1212                 // it'll get a pile of addresses with newer timestamps.
1213                 // Seed nodes are given a random 'last seen time' of between one and two
1214                 // weeks ago.
1215                 const int64 nOneWeek = 7*24*60*60;
1216                 struct in_addr ip;
1217                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1218                 CAddress addr(CService(ip, GetDefaultPort()));
1219                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1220                 vAdd.push_back(addr);
1221             }
1222             addrman.Add(vAdd, CNetAddr("127.0.0.1"));
1223         }
1224
1225         //
1226         // Choose an address to connect to based on most recently seen
1227         //
1228         CAddress addrConnect;
1229         int64 nBest = std::numeric_limits<int64>::min();
1230
1231         // Only connect to one address per a.b.?.? range.
1232         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1233         set<vector<unsigned char> > setConnected;
1234         CRITICAL_BLOCK(cs_vNodes)
1235             BOOST_FOREACH(CNode* pnode, vNodes)
1236                 setConnected.insert(pnode->addr.GetGroup());
1237
1238         int64 nANow = GetAdjustedTime();
1239
1240         int nTries = 0;
1241         loop
1242         {
1243             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1244             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1245
1246             // if we selected an invalid address, restart
1247             if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
1248                 break;
1249
1250             nTries++;
1251
1252             // only consider very recently tried nodes after 30 failed attempts
1253             if (nANow - addr.nLastTry < 600 && nTries < 30)
1254                 continue;
1255
1256             // do not allow non-default ports, unless after 50 invalid addresses selected already
1257             if (addr.GetPort() != GetDefaultPort() && nTries < 50)
1258                 continue;
1259
1260             addrConnect = addr;
1261             break;
1262         }
1263
1264         if (addrConnect.IsValid())
1265             OpenNetworkConnection(addrConnect);
1266     }
1267 }
1268
1269 void ThreadOpenAddedConnections(void* parg)
1270 {
1271     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1272     try
1273     {
1274         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1275         ThreadOpenAddedConnections2(parg);
1276         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1277     }
1278     catch (std::exception& e) {
1279         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1280         PrintException(&e, "ThreadOpenAddedConnections()");
1281     } catch (...) {
1282         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1283         PrintException(NULL, "ThreadOpenAddedConnections()");
1284     }
1285     printf("ThreadOpenAddedConnections exiting\n");
1286 }
1287
1288 void ThreadOpenAddedConnections2(void* parg)
1289 {
1290     printf("ThreadOpenAddedConnections started\n");
1291
1292     if (mapArgs.count("-addnode") == 0)
1293         return;
1294
1295     vector<vector<CService> > vservAddressesToAdd(0);
1296     BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1297     {
1298         vector<CService> vservNode(0);
1299         if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1300         {
1301             vservAddressesToAdd.push_back(vservNode);
1302             CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1303                 BOOST_FOREACH(CService& serv, vservNode)
1304                     setservAddNodeAddresses.insert(serv);
1305         }
1306     }
1307     loop
1308     {
1309         vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1310         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1311         // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1312         CRITICAL_BLOCK(cs_vNodes)
1313             BOOST_FOREACH(CNode* pnode, vNodes)
1314                 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1315                     BOOST_FOREACH(CService& addrNode, *(it))
1316                         if (pnode->addr == addrNode)
1317                         {
1318                             it = vservConnectAddresses.erase(it);
1319                             it--;
1320                             break;
1321                         }
1322         BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1323         {
1324             OpenNetworkConnection(CAddress(*(vserv.begin())));
1325             Sleep(500);
1326             if (fShutdown)
1327                 return;
1328         }
1329         if (fShutdown)
1330             return;
1331         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
1332         Sleep(120000); // Retry every 2 minutes
1333         vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
1334         if (fShutdown)
1335             return;
1336     }
1337 }
1338
1339 bool OpenNetworkConnection(const CAddress& addrConnect)
1340 {
1341     //
1342     // Initiate outbound network connection
1343     //
1344     if (fShutdown)
1345         return false;
1346     if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1347         FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1348         return false;
1349
1350     vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
1351     CNode* pnode = ConnectNode(addrConnect);
1352     vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
1353     if (fShutdown)
1354         return false;
1355     if (!pnode)
1356         return false;
1357     pnode->fNetworkNode = true;
1358
1359     return true;
1360 }
1361
1362
1363
1364
1365
1366
1367
1368
1369 void ThreadMessageHandler(void* parg)
1370 {
1371     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1372     try
1373     {
1374         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1375         ThreadMessageHandler2(parg);
1376         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1377     }
1378     catch (std::exception& e) {
1379         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1380         PrintException(&e, "ThreadMessageHandler()");
1381     } catch (...) {
1382         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1383         PrintException(NULL, "ThreadMessageHandler()");
1384     }
1385     printf("ThreadMessageHandler exiting\n");
1386 }
1387
1388 void ThreadMessageHandler2(void* parg)
1389 {
1390     printf("ThreadMessageHandler started\n");
1391     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1392     while (!fShutdown)
1393     {
1394         vector<CNode*> vNodesCopy;
1395         CRITICAL_BLOCK(cs_vNodes)
1396         {
1397             vNodesCopy = vNodes;
1398             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1399                 pnode->AddRef();
1400         }
1401
1402         // Poll the connected nodes for messages
1403         CNode* pnodeTrickle = NULL;
1404         if (!vNodesCopy.empty())
1405             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1406         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1407         {
1408             // Receive messages
1409             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1410                 ProcessMessages(pnode);
1411             if (fShutdown)
1412                 return;
1413
1414             // Send messages
1415             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1416                 SendMessages(pnode, pnode == pnodeTrickle);
1417             if (fShutdown)
1418                 return;
1419         }
1420
1421         CRITICAL_BLOCK(cs_vNodes)
1422         {
1423             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1424                 pnode->Release();
1425         }
1426
1427         // Wait and allow messages to bunch up.
1428         // Reduce vnThreadsRunning so StopNode has permission to exit while
1429         // we're sleeping, but we must always check fShutdown after doing this.
1430         vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
1431         Sleep(100);
1432         if (fRequestShutdown)
1433             Shutdown(NULL);
1434         vnThreadsRunning[THREAD_MESSAGEHANDLER]++;
1435         if (fShutdown)
1436             return;
1437     }
1438 }
1439
1440
1441
1442
1443
1444
1445 bool BindListenPort(string& strError)
1446 {
1447     strError = "";
1448     int nOne = 1;
1449     addrLocalHost.SetPort(GetListenPort());
1450
1451 #ifdef WIN32
1452     // Initialize Windows Sockets
1453     WSADATA wsadata;
1454     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1455     if (ret != NO_ERROR)
1456     {
1457         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1458         printf("%s\n", strError.c_str());
1459         return false;
1460     }
1461 #endif
1462
1463     // Create socket for listening for incoming connections
1464     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1465     if (hListenSocket == INVALID_SOCKET)
1466     {
1467         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1468         printf("%s\n", strError.c_str());
1469         return false;
1470     }
1471
1472 #ifdef SO_NOSIGPIPE
1473     // Different way of disabling SIGPIPE on BSD
1474     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1475 #endif
1476
1477 #ifndef WIN32
1478     // Allow binding if the port is still in TIME_WAIT state after
1479     // the program was closed and restarted.  Not an issue on windows.
1480     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1481 #endif
1482
1483 #ifdef WIN32
1484     // Set to nonblocking, incoming connections will also inherit this
1485     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1486 #else
1487     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1488 #endif
1489     {
1490         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1491         printf("%s\n", strError.c_str());
1492         return false;
1493     }
1494
1495     // The sockaddr_in structure specifies the address family,
1496     // IP address, and port for the socket that is being bound
1497     struct sockaddr_in sockaddr;
1498     memset(&sockaddr, 0, sizeof(sockaddr));
1499     sockaddr.sin_family = AF_INET;
1500     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1501     sockaddr.sin_port = htons(GetListenPort());
1502     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1503     {
1504         int nErr = WSAGetLastError();
1505         if (nErr == WSAEADDRINUSE)
1506             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1507         else
1508             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1509         printf("%s\n", strError.c_str());
1510         return false;
1511     }
1512     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1513
1514     // Listen for incoming connections
1515     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1516     {
1517         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1518         printf("%s\n", strError.c_str());
1519         return false;
1520     }
1521
1522     return true;
1523 }
1524
1525 void StartNode(void* parg)
1526 {
1527 #ifdef USE_UPNP
1528 #if USE_UPNP
1529     fUseUPnP = GetBoolArg("-upnp", true);
1530 #else
1531     fUseUPnP = GetBoolArg("-upnp", false);
1532 #endif
1533 #endif
1534
1535     if (pnodeLocalHost == NULL)
1536         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1537
1538 #ifdef WIN32
1539     // Get local host ip
1540     char pszHostName[1000] = "";
1541     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1542     {
1543         vector<CNetAddr> vaddr;
1544         if (LookupHost(pszHostName, vaddr))
1545             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1546                 if (!addr.IsLocal())
1547                 {
1548                     addrLocalHost.SetIP(addr);
1549                     break;
1550                 }
1551     }
1552 #else
1553     // Get local host ip
1554     struct ifaddrs* myaddrs;
1555     if (getifaddrs(&myaddrs) == 0)
1556     {
1557         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1558         {
1559             if (ifa->ifa_addr == NULL) continue;
1560             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1561             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1562             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1563             char pszIP[100];
1564             if (ifa->ifa_addr->sa_family == AF_INET)
1565             {
1566                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1567                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1568                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1569
1570                 // Take the first IP that isn't loopback 127.x.x.x
1571                 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1572                 if (addr.IsValid() && !addr.IsLocal())
1573                 {
1574                     addrLocalHost = addr;
1575                     break;
1576                 }
1577             }
1578             else if (ifa->ifa_addr->sa_family == AF_INET6)
1579             {
1580                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1581                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1582                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1583             }
1584         }
1585         freeifaddrs(myaddrs);
1586     }
1587 #endif
1588     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1589
1590     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1591     {
1592         // Proxies can't take incoming connections
1593         addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1594         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1595     }
1596     else
1597     {
1598         CreateThread(ThreadGetMyExternalIP, NULL);
1599     }
1600
1601     //
1602     // Start threads
1603     //
1604
1605     if (!GetBoolArg("-dnsseed", true))
1606         printf("DNS seeding disabled\n");
1607     else
1608         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1609             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1610
1611     // Map ports with UPnP
1612     if (fHaveUPnP)
1613         MapPort(fUseUPnP);
1614
1615     // Get addresses from IRC and advertise ours
1616     if (!CreateThread(ThreadIRCSeed, NULL))
1617         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1618
1619     // Send and receive from sockets, accept connections
1620     if (!CreateThread(ThreadSocketHandler, NULL))
1621         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1622
1623     // Initiate outbound connections from -addnode
1624     if (!CreateThread(ThreadOpenAddedConnections, NULL))
1625         printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1626
1627     // Initiate outbound connections
1628     if (!CreateThread(ThreadOpenConnections, NULL))
1629         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1630
1631     // Process messages
1632     if (!CreateThread(ThreadMessageHandler, NULL))
1633         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1634
1635     // Dump network addresses
1636     if (!CreateThread(ThreadDumpAddress, NULL))
1637         printf("Error; CreateThread(ThreadDumpAddress) failed\n");
1638
1639     // Generate coins in the background
1640     GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain);
1641 }
1642
1643 bool StopNode()
1644 {
1645     printf("StopNode()\n");
1646     fShutdown = true;
1647     nTransactionsUpdated++;
1648     int64 nStart = GetTime();
1649     do
1650     {
1651         int nThreadsRunning = 0;
1652         for (int n = 0; n < THREAD_MAX; n++)
1653             nThreadsRunning += vnThreadsRunning[n];
1654         if (nThreadsRunning == 0)
1655             break;
1656         if (GetTime() - nStart > 20)
1657             break;
1658         Sleep(20);
1659     } while(true);
1660     if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
1661     if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
1662     if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
1663     if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
1664     if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
1665     if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
1666     if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
1667     if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
1668     if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
1669     while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
1670         Sleep(20);
1671     Sleep(50);
1672     DumpAddresses();
1673     return true;
1674 }
1675
1676 class CNetCleanup
1677 {
1678 public:
1679     CNetCleanup()
1680     {
1681     }
1682     ~CNetCleanup()
1683     {
1684         // Close sockets
1685         BOOST_FOREACH(CNode* pnode, vNodes)
1686             if (pnode->hSocket != INVALID_SOCKET)
1687                 closesocket(pnode->hSocket);
1688         if (hListenSocket != INVALID_SOCKET)
1689             if (closesocket(hListenSocket) == SOCKET_ERROR)
1690                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1691
1692 #ifdef WIN32
1693         // Shutdown Windows Sockets
1694         WSACleanup();
1695 #endif
1696     }
1697 }
1698 instance_of_cnetcleanup;