Add -keepnode which attempts to -addnode and keep a connection open
[novacoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 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
13 #ifdef WIN32
14 #include <string.h>
15 #endif
16
17 #ifdef USE_UPNP
18 #include <miniupnpc/miniwget.h>
19 #include <miniupnpc/miniupnpc.h>
20 #include <miniupnpc/upnpcommands.h>
21 #include <miniupnpc/upnperrors.h>
22 #endif
23
24 using namespace std;
25 using namespace boost;
26
27 static const int MAX_OUTBOUND_CONNECTIONS = 8;
28
29 void ThreadMessageHandler2(void* parg);
30 void ThreadSocketHandler2(void* parg);
31 void ThreadOpenConnections2(void* parg);
32 void ThreadOpenAddedConnections2(void* parg);
33 #ifdef USE_UPNP
34 void ThreadMapPort2(void* parg);
35 #endif
36 void ThreadDNSAddressSeed2(void* parg);
37 bool OpenNetworkConnection(const CAddress& addrConnect);
38
39
40
41
42
43 //
44 // Global state variables
45 //
46 bool fClient = false;
47 bool fAllowDNS = false;
48 uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
49 CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
50 static CNode* pnodeLocalHost = NULL;
51 uint64 nLocalHostNonce = 0;
52 array<int, 10> vnThreadsRunning;
53 static SOCKET hListenSocket = INVALID_SOCKET;
54
55 vector<CNode*> vNodes;
56 CCriticalSection cs_vNodes;
57 map<vector<unsigned char>, CAddress> mapAddresses;
58 CCriticalSection cs_mapAddresses;
59 map<CInv, CDataStream> mapRelay;
60 deque<pair<int64, CInv> > vRelayExpiration;
61 CCriticalSection cs_mapRelay;
62 map<CInv, int64> mapAlreadyAskedFor;
63
64
65 set<CNetAddr> setservAddNodeAddresses;
66 CCriticalSection cs_setservAddNodeAddresses;
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 GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
92 {
93     SOCKET hSocket;
94     if (!ConnectSocket(addrConnect, hSocket))
95         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
96
97     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
98
99     string strLine;
100     while (RecvLine(hSocket, strLine))
101     {
102         if (strLine.empty()) // HTTP response is separated from headers by blank line
103         {
104             loop
105             {
106                 if (!RecvLine(hSocket, strLine))
107                 {
108                     closesocket(hSocket);
109                     return false;
110                 }
111                 if (pszKeyword == NULL)
112                     break;
113                 if (strLine.find(pszKeyword) != -1)
114                 {
115                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
116                     break;
117                 }
118             }
119             closesocket(hSocket);
120             if (strLine.find("<") != -1)
121                 strLine = strLine.substr(0, strLine.find("<"));
122             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
123             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
124                 strLine.resize(strLine.size()-1);
125             CService addr(strLine,0,true);
126             printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
127             if (!addr.IsValid() || !addr.IsRoutable())
128                 return false;
129             ipRet.SetIP(addr);
130             return true;
131         }
132     }
133     closesocket(hSocket);
134     return error("GetMyExternalIP() : connection closed");
135 }
136
137 // We now get our external IP from the IRC server first and only use this as a backup
138 bool GetMyExternalIP(CNetAddr& ipRet)
139 {
140     CAddress addrConnect;
141     const char* pszGet;
142     const char* pszKeyword;
143
144     if (fUseProxy)
145         return false;
146
147     for (int nLookup = 0; nLookup <= 1; nLookup++)
148     for (int nHost = 1; nHost <= 2; nHost++)
149     {
150         // We should be phasing out our use of sites like these.  If we need
151         // replacements, we should ask for volunteers to put this simple
152         // php file on their webserver that prints the client IP:
153         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
154         if (nHost == 1)
155         {
156             addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
157
158             if (nLookup == 1)
159             {
160                 CService addrIP("checkip.dyndns.org", 80, true);
161                 if (addrIP.IsValid())
162                     addrConnect = addrIP;
163             }
164
165             pszGet = "GET / HTTP/1.1\r\n"
166                      "Host: checkip.dyndns.org\r\n"
167                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
168                      "Connection: close\r\n"
169                      "\r\n";
170
171             pszKeyword = "Address:";
172         }
173         else if (nHost == 2)
174         {
175             addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
176
177             if (nLookup == 1)
178             {
179                 CService addrIP("www.showmyip.com", 80, true);
180                 if (addrIP.IsValid())
181                     addrConnect = addrIP;
182             }
183
184             pszGet = "GET /simple/ HTTP/1.1\r\n"
185                      "Host: www.showmyip.com\r\n"
186                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
187                      "Connection: close\r\n"
188                      "\r\n";
189
190             pszKeyword = NULL; // Returns just IP address
191         }
192
193         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
194             return true;
195     }
196
197     return false;
198 }
199
200 void ThreadGetMyExternalIP(void* parg)
201 {
202     // Wait for IRC to get it first
203     if (!GetBoolArg("-noirc"))
204     {
205         for (int i = 0; i < 2 * 60; i++)
206         {
207             Sleep(1000);
208             if (fGotExternalIP || fShutdown)
209                 return;
210         }
211     }
212
213     // Fallback in case IRC fails to get it
214     if (GetMyExternalIP(addrLocalHost))
215     {
216         printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
217         if (addrLocalHost.IsRoutable())
218         {
219             // If we already connected to a few before we had our IP, go back and addr them.
220             // setAddrKnown automatically filters any duplicate sends.
221             CAddress addr(addrLocalHost);
222             addr.nTime = GetAdjustedTime();
223             CRITICAL_BLOCK(cs_vNodes)
224                 BOOST_FOREACH(CNode* pnode, vNodes)
225                     pnode->PushAddress(addr);
226         }
227     }
228 }
229
230
231
232
233
234 bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
235 {
236     if (!addr.IsRoutable())
237         return false;
238     if ((CService)addr == (CService)addrLocalHost)
239         return false;
240     addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
241     bool fUpdated = false;
242     bool fNew = false;
243     CAddress addrFound = addr;
244
245     CRITICAL_BLOCK(cs_mapAddresses)
246     {
247         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
248         if (it == mapAddresses.end())
249         {
250             // New address
251             printf("AddAddress(%s)\n", addr.ToString().c_str());
252             mapAddresses.insert(make_pair(addr.GetKey(), addr));
253             fUpdated = true;
254             fNew = true;
255         }
256         else
257         {
258             addrFound = (*it).second;
259             if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
260             {
261                 // Services have been added
262                 addrFound.nServices |= addr.nServices;
263                 fUpdated = true;
264             }
265             bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
266             int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
267             if (addrFound.nTime < addr.nTime - nUpdateInterval)
268             {
269                 // Periodically update most recently seen time
270                 addrFound.nTime = addr.nTime;
271                 fUpdated = true;
272             }
273         }
274     }
275     // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
276     // CRITICAL_BLOCK:
277     // Thread 1:  begin db transaction (locks inside-db-mutex)
278     //            then AddAddress (locks cs_mapAddresses)
279     // Thread 2:  AddAddress (locks cs_mapAddresses)
280     //             ... then db operation hangs waiting for inside-db-mutex
281     if (fUpdated)
282     {
283         if (pAddrDB)
284             pAddrDB->WriteAddress(addrFound);
285         else
286             CAddrDB().WriteAddress(addrFound);
287     }
288     return fNew;
289 }
290
291 void AddressCurrentlyConnected(const CService& addr)
292 {
293     CAddress *paddrFound = NULL;
294
295     CRITICAL_BLOCK(cs_mapAddresses)
296     {
297         // Only if it's been published already
298         map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
299         if (it != mapAddresses.end())
300             paddrFound = &(*it).second;
301     }
302
303     if (paddrFound)
304     {
305         int64 nUpdateInterval = 20 * 60;
306         if (paddrFound->nTime < GetAdjustedTime() - nUpdateInterval)
307         {
308             // Periodically update most recently seen time
309             paddrFound->nTime = GetAdjustedTime();
310             CAddrDB addrdb;
311             addrdb.WriteAddress(*paddrFound);
312         }
313     }
314 }
315
316
317
318
319
320 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
321 {
322     // If the dialog might get closed before the reply comes back,
323     // call this in the destructor so it doesn't get called after it's deleted.
324     CRITICAL_BLOCK(cs_vNodes)
325     {
326         BOOST_FOREACH(CNode* pnode, vNodes)
327         {
328             CRITICAL_BLOCK(pnode->cs_mapRequests)
329             {
330                 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
331                 {
332                     CRequestTracker& tracker = (*mi).second;
333                     if (tracker.fn == fn && tracker.param1 == param1)
334                         pnode->mapRequests.erase(mi++);
335                     else
336                         mi++;
337                 }
338             }
339         }
340     }
341 }
342
343
344
345
346
347
348
349 //
350 // Subscription methods for the broadcast and subscription system.
351 // Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
352 //
353 // The subscription system uses a meet-in-the-middle strategy.
354 // With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
355 // subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
356 //
357
358 bool AnySubscribed(unsigned int nChannel)
359 {
360     if (pnodeLocalHost->IsSubscribed(nChannel))
361         return true;
362     CRITICAL_BLOCK(cs_vNodes)
363         BOOST_FOREACH(CNode* pnode, vNodes)
364             if (pnode->IsSubscribed(nChannel))
365                 return true;
366     return false;
367 }
368
369 bool CNode::IsSubscribed(unsigned int nChannel)
370 {
371     if (nChannel >= vfSubscribe.size())
372         return false;
373     return vfSubscribe[nChannel];
374 }
375
376 void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
377 {
378     if (nChannel >= vfSubscribe.size())
379         return;
380
381     if (!AnySubscribed(nChannel))
382     {
383         // Relay subscribe
384         CRITICAL_BLOCK(cs_vNodes)
385             BOOST_FOREACH(CNode* pnode, vNodes)
386                 if (pnode != this)
387                     pnode->PushMessage("subscribe", nChannel, nHops);
388     }
389
390     vfSubscribe[nChannel] = true;
391 }
392
393 void CNode::CancelSubscribe(unsigned int nChannel)
394 {
395     if (nChannel >= vfSubscribe.size())
396         return;
397
398     // Prevent from relaying cancel if wasn't subscribed
399     if (!vfSubscribe[nChannel])
400         return;
401     vfSubscribe[nChannel] = false;
402
403     if (!AnySubscribed(nChannel))
404     {
405         // Relay subscription cancel
406         CRITICAL_BLOCK(cs_vNodes)
407             BOOST_FOREACH(CNode* pnode, vNodes)
408                 if (pnode != this)
409                     pnode->PushMessage("sub-cancel", nChannel);
410     }
411 }
412
413
414
415
416
417
418
419
420
421 CNode* FindNode(const CNetAddr& ip)
422 {
423     CRITICAL_BLOCK(cs_vNodes)
424     {
425         BOOST_FOREACH(CNode* pnode, vNodes)
426             if ((CNetAddr)pnode->addr == ip)
427                 return (pnode);
428     }
429     return NULL;
430 }
431
432 CNode* FindNode(const CService& addr)
433 {
434     CRITICAL_BLOCK(cs_vNodes)
435     {
436         BOOST_FOREACH(CNode* pnode, vNodes)
437             if ((CService)pnode->addr == addr)
438                 return (pnode);
439     }
440     return NULL;
441 }
442
443 CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
444 {
445     if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
446         return NULL;
447
448     // Look for an existing connection
449     CNode* pnode = FindNode((CService)addrConnect);
450     if (pnode)
451     {
452         if (nTimeout != 0)
453             pnode->AddRef(nTimeout);
454         else
455             pnode->AddRef();
456         return pnode;
457     }
458
459     /// debug print
460     printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
461         addrConnect.ToString().c_str(),
462         (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
463         (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
464
465     CRITICAL_BLOCK(cs_mapAddresses)
466         mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
467
468     // Connect
469     SOCKET hSocket;
470     if (ConnectSocket(addrConnect, hSocket))
471     {
472         /// debug print
473         printf("connected %s\n", addrConnect.ToString().c_str());
474
475         // Set to nonblocking
476 #ifdef WIN32
477         u_long nOne = 1;
478         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
479             printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
480 #else
481         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
482             printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
483 #endif
484
485         // Add node
486         CNode* pnode = new CNode(hSocket, addrConnect, false);
487         if (nTimeout != 0)
488             pnode->AddRef(nTimeout);
489         else
490             pnode->AddRef();
491         CRITICAL_BLOCK(cs_vNodes)
492             vNodes.push_back(pnode);
493
494         pnode->nTimeConnected = GetTime();
495         return pnode;
496     }
497     else
498     {
499         return NULL;
500     }
501 }
502
503 void CNode::CloseSocketDisconnect()
504 {
505     fDisconnect = true;
506     if (hSocket != INVALID_SOCKET)
507     {
508         if (fDebug)
509             printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
510         printf("disconnecting node %s\n", addr.ToString().c_str());
511         closesocket(hSocket);
512         hSocket = INVALID_SOCKET;
513     }
514 }
515
516 void CNode::Cleanup()
517 {
518     // All of a nodes broadcasts and subscriptions are automatically torn down
519     // when it goes down, so a node has to stay up to keep its broadcast going.
520
521     // Cancel subscriptions
522     for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
523         if (vfSubscribe[nChannel])
524             CancelSubscribe(nChannel);
525 }
526
527
528 void CNode::PushVersion()
529 {
530     /// when NTP implemented, change to just nTime = GetAdjustedTime()
531     int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
532     CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
533     CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
534     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
535     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
536                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
537 }
538
539
540
541
542
543 std::map<CNetAddr, int64> CNode::setBanned;
544 CCriticalSection CNode::cs_setBanned;
545
546 void CNode::ClearBanned()
547 {
548     setBanned.clear();
549 }
550
551 bool CNode::IsBanned(CNetAddr ip)
552 {
553     bool fResult = false;
554     CRITICAL_BLOCK(cs_setBanned)
555     {
556         std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
557         if (i != setBanned.end())
558         {
559             int64 t = (*i).second;
560             if (GetTime() < t)
561                 fResult = true;
562         }
563     }
564     return fResult;
565 }
566
567 bool CNode::Misbehaving(int howmuch)
568 {
569     if (addr.IsLocal())
570     {
571         printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
572         return false;
573     }
574
575     nMisbehavior += howmuch;
576     if (nMisbehavior >= GetArg("-banscore", 100))
577     {
578         int64 banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
579         CRITICAL_BLOCK(cs_setBanned)
580             if (setBanned[addr] < banTime)
581                 setBanned[addr] = banTime;
582         CloseSocketDisconnect();
583         printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
584         return true;
585     }
586     return false;
587 }
588
589
590
591
592
593
594
595
596
597
598
599
600 void ThreadSocketHandler(void* parg)
601 {
602     IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
603     try
604     {
605         vnThreadsRunning[0]++;
606         ThreadSocketHandler2(parg);
607         vnThreadsRunning[0]--;
608     }
609     catch (std::exception& e) {
610         vnThreadsRunning[0]--;
611         PrintException(&e, "ThreadSocketHandler()");
612     } catch (...) {
613         vnThreadsRunning[0]--;
614         throw; // support pthread_cancel()
615     }
616     printf("ThreadSocketHandler exiting\n");
617 }
618
619 void ThreadSocketHandler2(void* parg)
620 {
621     printf("ThreadSocketHandler started\n");
622     list<CNode*> vNodesDisconnected;
623     int nPrevNodeCount = 0;
624
625     loop
626     {
627         //
628         // Disconnect nodes
629         //
630         CRITICAL_BLOCK(cs_vNodes)
631         {
632             // Disconnect unused nodes
633             vector<CNode*> vNodesCopy = vNodes;
634             BOOST_FOREACH(CNode* pnode, vNodesCopy)
635             {
636                 if (pnode->fDisconnect ||
637                     (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
638                 {
639                     // remove from vNodes
640                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
641
642                     // close socket and cleanup
643                     pnode->CloseSocketDisconnect();
644                     pnode->Cleanup();
645
646                     // hold in disconnected pool until all refs are released
647                     pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
648                     if (pnode->fNetworkNode || pnode->fInbound)
649                         pnode->Release();
650                     vNodesDisconnected.push_back(pnode);
651                 }
652             }
653
654             // Delete disconnected nodes
655             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
656             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
657             {
658                 // wait until threads are done using it
659                 if (pnode->GetRefCount() <= 0)
660                 {
661                     bool fDelete = false;
662                     TRY_CRITICAL_BLOCK(pnode->cs_vSend)
663                      TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
664                       TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
665                        TRY_CRITICAL_BLOCK(pnode->cs_inventory)
666                         fDelete = true;
667                     if (fDelete)
668                     {
669                         vNodesDisconnected.remove(pnode);
670                         delete pnode;
671                     }
672                 }
673             }
674         }
675         if (vNodes.size() != nPrevNodeCount)
676         {
677             nPrevNodeCount = vNodes.size();
678             MainFrameRepaint();
679         }
680
681
682         //
683         // Find which sockets have data to receive
684         //
685         struct timeval timeout;
686         timeout.tv_sec  = 0;
687         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
688
689         fd_set fdsetRecv;
690         fd_set fdsetSend;
691         fd_set fdsetError;
692         FD_ZERO(&fdsetRecv);
693         FD_ZERO(&fdsetSend);
694         FD_ZERO(&fdsetError);
695         SOCKET hSocketMax = 0;
696
697         if(hListenSocket != INVALID_SOCKET)
698             FD_SET(hListenSocket, &fdsetRecv);
699         hSocketMax = max(hSocketMax, hListenSocket);
700         CRITICAL_BLOCK(cs_vNodes)
701         {
702             BOOST_FOREACH(CNode* pnode, vNodes)
703             {
704                 if (pnode->hSocket == INVALID_SOCKET)
705                     continue;
706                 FD_SET(pnode->hSocket, &fdsetRecv);
707                 FD_SET(pnode->hSocket, &fdsetError);
708                 hSocketMax = max(hSocketMax, pnode->hSocket);
709                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
710                     if (!pnode->vSend.empty())
711                         FD_SET(pnode->hSocket, &fdsetSend);
712             }
713         }
714
715         vnThreadsRunning[0]--;
716         int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
717         vnThreadsRunning[0]++;
718         if (fShutdown)
719             return;
720         if (nSelect == SOCKET_ERROR)
721         {
722             int nErr = WSAGetLastError();
723             if (hSocketMax > -1)
724             {
725                 printf("socket select error %d\n", nErr);
726                 for (int i = 0; i <= hSocketMax; i++)
727                     FD_SET(i, &fdsetRecv);
728             }
729             FD_ZERO(&fdsetSend);
730             FD_ZERO(&fdsetError);
731             Sleep(timeout.tv_usec/1000);
732         }
733
734
735         //
736         // Accept new connections
737         //
738         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
739         {
740             struct sockaddr_in sockaddr;
741             socklen_t len = sizeof(sockaddr);
742             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
743             CAddress addr(sockaddr);
744             int nInbound = 0;
745
746             CRITICAL_BLOCK(cs_vNodes)
747                 BOOST_FOREACH(CNode* pnode, vNodes)
748                 if (pnode->fInbound)
749                     nInbound++;
750             if (hSocket == INVALID_SOCKET)
751             {
752                 if (WSAGetLastError() != WSAEWOULDBLOCK)
753                     printf("socket error accept failed: %d\n", WSAGetLastError());
754             }
755             else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
756             {
757                 CRITICAL_BLOCK(cs_setservAddNodeAddresses)
758                     if (!setservAddNodeAddresses.count(addr))
759                         closesocket(hSocket);
760             }
761             else if (CNode::IsBanned(addr))
762             {
763                 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
764                 closesocket(hSocket);
765             }
766             else
767             {
768                 printf("accepted connection %s\n", addr.ToString().c_str());
769                 CNode* pnode = new CNode(hSocket, addr, true);
770                 pnode->AddRef();
771                 CRITICAL_BLOCK(cs_vNodes)
772                     vNodes.push_back(pnode);
773             }
774         }
775
776
777         //
778         // Service each socket
779         //
780         vector<CNode*> vNodesCopy;
781         CRITICAL_BLOCK(cs_vNodes)
782         {
783             vNodesCopy = vNodes;
784             BOOST_FOREACH(CNode* pnode, vNodesCopy)
785                 pnode->AddRef();
786         }
787         BOOST_FOREACH(CNode* pnode, vNodesCopy)
788         {
789             if (fShutdown)
790                 return;
791
792             //
793             // Receive
794             //
795             if (pnode->hSocket == INVALID_SOCKET)
796                 continue;
797             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
798             {
799                 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
800                 {
801                     CDataStream& vRecv = pnode->vRecv;
802                     unsigned int nPos = vRecv.size();
803
804                     if (nPos > ReceiveBufferSize()) {
805                         if (!pnode->fDisconnect)
806                             printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
807                         pnode->CloseSocketDisconnect();
808                     }
809                     else {
810                         // typical socket buffer is 8K-64K
811                         char pchBuf[0x10000];
812                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
813                         if (nBytes > 0)
814                         {
815                             vRecv.resize(nPos + nBytes);
816                             memcpy(&vRecv[nPos], pchBuf, nBytes);
817                             pnode->nLastRecv = GetTime();
818                         }
819                         else if (nBytes == 0)
820                         {
821                             // socket closed gracefully
822                             if (!pnode->fDisconnect)
823                                 printf("socket closed\n");
824                             pnode->CloseSocketDisconnect();
825                         }
826                         else if (nBytes < 0)
827                         {
828                             // error
829                             int nErr = WSAGetLastError();
830                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
831                             {
832                                 if (!pnode->fDisconnect)
833                                     printf("socket recv error %d\n", nErr);
834                                 pnode->CloseSocketDisconnect();
835                             }
836                         }
837                     }
838                 }
839             }
840
841             //
842             // Send
843             //
844             if (pnode->hSocket == INVALID_SOCKET)
845                 continue;
846             if (FD_ISSET(pnode->hSocket, &fdsetSend))
847             {
848                 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
849                 {
850                     CDataStream& vSend = pnode->vSend;
851                     if (!vSend.empty())
852                     {
853                         int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
854                         if (nBytes > 0)
855                         {
856                             vSend.erase(vSend.begin(), vSend.begin() + nBytes);
857                             pnode->nLastSend = GetTime();
858                         }
859                         else if (nBytes < 0)
860                         {
861                             // error
862                             int nErr = WSAGetLastError();
863                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
864                             {
865                                 printf("socket send error %d\n", nErr);
866                                 pnode->CloseSocketDisconnect();
867                             }
868                         }
869                         if (vSend.size() > SendBufferSize()) {
870                             if (!pnode->fDisconnect)
871                                 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
872                             pnode->CloseSocketDisconnect();
873                         }
874                     }
875                 }
876             }
877
878             //
879             // Inactivity checking
880             //
881             if (pnode->vSend.empty())
882                 pnode->nLastSendEmpty = GetTime();
883             if (GetTime() - pnode->nTimeConnected > 60)
884             {
885                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
886                 {
887                     printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
888                     pnode->fDisconnect = true;
889                 }
890                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
891                 {
892                     printf("socket not sending\n");
893                     pnode->fDisconnect = true;
894                 }
895                 else if (GetTime() - pnode->nLastRecv > 90*60)
896                 {
897                     printf("socket inactivity timeout\n");
898                     pnode->fDisconnect = true;
899                 }
900             }
901         }
902         CRITICAL_BLOCK(cs_vNodes)
903         {
904             BOOST_FOREACH(CNode* pnode, vNodesCopy)
905                 pnode->Release();
906         }
907
908         Sleep(10);
909     }
910 }
911
912
913
914
915
916
917
918
919
920 #ifdef USE_UPNP
921 void ThreadMapPort(void* parg)
922 {
923     IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
924     try
925     {
926         vnThreadsRunning[5]++;
927         ThreadMapPort2(parg);
928         vnThreadsRunning[5]--;
929     }
930     catch (std::exception& e) {
931         vnThreadsRunning[5]--;
932         PrintException(&e, "ThreadMapPort()");
933     } catch (...) {
934         vnThreadsRunning[5]--;
935         PrintException(NULL, "ThreadMapPort()");
936     }
937     printf("ThreadMapPort exiting\n");
938 }
939
940 void ThreadMapPort2(void* parg)
941 {
942     printf("ThreadMapPort started\n");
943
944     char port[6];
945     sprintf(port, "%d", GetListenPort());
946
947     const char * rootdescurl = 0;
948     const char * multicastif = 0;
949     const char * minissdpdpath = 0;
950     struct UPNPDev * devlist = 0;
951     char lanaddr[64];
952
953 #ifndef UPNPDISCOVER_SUCCESS
954     /* miniupnpc 1.5 */
955     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
956 #else
957     /* miniupnpc 1.6 */
958     int error = 0;
959     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
960 #endif
961
962     struct UPNPUrls urls;
963     struct IGDdatas data;
964     int r;
965
966     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
967     if (r == 1)
968     {
969         char intClient[16];
970         char intPort[6];
971         string strDesc = "Bitcoin " + FormatFullVersion();
972 #ifndef UPNPDISCOVER_SUCCESS
973     /* miniupnpc 1.5 */
974         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
975                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
976 #else
977     /* miniupnpc 1.6 */
978         r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
979                                 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
980 #endif
981
982         if(r!=UPNPCOMMAND_SUCCESS)
983             printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
984                 port, port, lanaddr, r, strupnperror(r));
985         else
986             printf("UPnP Port Mapping successful.\n");
987         loop {
988             if (fShutdown || !fUseUPnP)
989             {
990                 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
991                 printf("UPNP_DeletePortMapping() returned : %d\n", r);
992                 freeUPNPDevlist(devlist); devlist = 0;
993                 FreeUPNPUrls(&urls);
994                 return;
995             }
996             Sleep(2000);
997         }
998     } else {
999         printf("No valid UPnP IGDs found\n");
1000         freeUPNPDevlist(devlist); devlist = 0;
1001         if (r != 0)
1002             FreeUPNPUrls(&urls);
1003         loop {
1004             if (fShutdown || !fUseUPnP)
1005                 return;
1006             Sleep(2000);
1007         }
1008     }
1009 }
1010
1011 void MapPort(bool fMapPort)
1012 {
1013     if (fUseUPnP != fMapPort)
1014     {
1015         fUseUPnP = fMapPort;
1016         WriteSetting("fUseUPnP", fUseUPnP);
1017     }
1018     if (fUseUPnP && vnThreadsRunning[5] < 1)
1019     {
1020         if (!CreateThread(ThreadMapPort, NULL))
1021             printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1022     }
1023 }
1024 #else
1025 void MapPort(bool /* unused fMapPort */)
1026 {
1027     // Intentionally left blank.
1028 }
1029 #endif
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 static const char *strDNSSeed[] = {
1041     "bitseed.xf2.org",
1042     "dnsseed.bluematt.me",
1043     "seed.bitcoin.sipa.be",
1044     "dnsseed.bitcoin.dashjr.org",
1045 };
1046
1047 void ThreadDNSAddressSeed(void* parg)
1048 {
1049     IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1050     try
1051     {
1052         vnThreadsRunning[6]++;
1053         ThreadDNSAddressSeed2(parg);
1054         vnThreadsRunning[6]--;
1055     }
1056     catch (std::exception& e) {
1057         vnThreadsRunning[6]--;
1058         PrintException(&e, "ThreadDNSAddressSeed()");
1059     } catch (...) {
1060         vnThreadsRunning[6]--;
1061         throw; // support pthread_cancel()
1062     }
1063     printf("ThreadDNSAddressSeed exiting\n");
1064 }
1065
1066 void ThreadDNSAddressSeed2(void* parg)
1067 {
1068     printf("ThreadDNSAddressSeed started\n");
1069     int found = 0;
1070
1071     if (!fTestNet)
1072     {
1073         printf("Loading addresses from DNS seeds (could take a while)\n");
1074
1075         for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1076             vector<CNetAddr> vaddr;
1077             if (LookupHost(strDNSSeed[seed_idx], vaddr))
1078             {
1079                 CAddrDB addrDB;
1080                 addrDB.TxnBegin();
1081                 BOOST_FOREACH (CNetAddr& ip, vaddr)
1082                 {
1083                     if (ip.IsRoutable())
1084                     {
1085                         CAddress addr(CService(ip, GetDefaultPort()), NODE_NETWORK);
1086                         addr.nTime = 0;
1087                         AddAddress(addr, 0, &addrDB);
1088                         found++;
1089                     }
1090                 }
1091                 addrDB.TxnCommit();  // Save addresses (it's ok if this fails)
1092             }
1093         }
1094     }
1095
1096     printf("%d addresses found from DNS seeds\n", found);
1097 }
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110 unsigned int pnSeed[] =
1111 {
1112     0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1113     0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1114     0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1115     0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1116     0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1117     0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1118     0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1119     0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1120     0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1121     0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1122     0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1123     0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1124     0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1125     0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1126     0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1127     0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1128     0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1129     0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1130     0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1131     0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1132     0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1133     0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1134     0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1135     0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1136     0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1137     0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1138     0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1139     0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1140     0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1141     0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1142     0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1143     0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1144     0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1145     0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1146     0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1147     0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1148     0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1149     0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1150     0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1151     0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1152     0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1153     0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1154     0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1155     0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1156     0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1157     0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1158     0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1159     0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1160     0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1161     0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1162     0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1163     0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1164     0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1165     0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1166     0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1167     0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1168     0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1169     0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1170     0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1171     0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1172     0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1173     0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1174     0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1175     0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
1176 };
1177
1178
1179
1180 void ThreadOpenConnections(void* parg)
1181 {
1182     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1183     try
1184     {
1185         vnThreadsRunning[1]++;
1186         ThreadOpenConnections2(parg);
1187         vnThreadsRunning[1]--;
1188     }
1189     catch (std::exception& e) {
1190         vnThreadsRunning[1]--;
1191         PrintException(&e, "ThreadOpenConnections()");
1192     } catch (...) {
1193         vnThreadsRunning[1]--;
1194         PrintException(NULL, "ThreadOpenConnections()");
1195     }
1196     printf("ThreadOpenConnections exiting\n");
1197 }
1198
1199 void ThreadOpenConnections2(void* parg)
1200 {
1201     printf("ThreadOpenConnections started\n");
1202
1203     // Connect to specific addresses
1204     if (mapArgs.count("-connect"))
1205     {
1206         for (int64 nLoop = 0;; nLoop++)
1207         {
1208             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1209             {
1210                 CAddress addr(strAddr, fAllowDNS);
1211                 if (addr.IsValid())
1212                     OpenNetworkConnection(addr);
1213                 for (int i = 0; i < 10 && i < nLoop; i++)
1214                 {
1215                     Sleep(500);
1216                     if (fShutdown)
1217                         return;
1218                 }
1219             }
1220         }
1221     }
1222
1223     // Initiate network connections
1224     int64 nStart = GetTime();
1225     loop
1226     {
1227         // Limit outbound connections
1228         vnThreadsRunning[1]--;
1229         Sleep(500);
1230         loop
1231         {
1232             int nOutbound = 0;
1233             CRITICAL_BLOCK(cs_vNodes)
1234                 BOOST_FOREACH(CNode* pnode, vNodes)
1235                     if (!pnode->fInbound)
1236                         nOutbound++;
1237             int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
1238             nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
1239             if (nOutbound < nMaxOutboundConnections)
1240                 break;
1241             Sleep(2000);
1242             if (fShutdown)
1243                 return;
1244         }
1245         vnThreadsRunning[1]++;
1246         if (fShutdown)
1247             return;
1248
1249         bool fAddSeeds = false;
1250
1251         CRITICAL_BLOCK(cs_mapAddresses)
1252         {
1253             // Add seed nodes if IRC isn't working
1254             bool fTOR = (fUseProxy && addrProxy.GetPort() == 9050);
1255             if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
1256                 fAddSeeds = true;
1257         }
1258
1259         if (fAddSeeds)
1260         {
1261             for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1262             {
1263                 // It'll only connect to one or two seed nodes because once it connects,
1264                 // it'll get a pile of addresses with newer timestamps.
1265                 // Seed nodes are given a random 'last seen time' of between one and two
1266                 // weeks ago.
1267                 const int64 nOneWeek = 7*24*60*60;
1268                 struct in_addr ip;
1269                 memcpy(&ip, &pnSeed[i], sizeof(ip));
1270                 CAddress addr(CService(ip, GetDefaultPort()));
1271                 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
1272                 AddAddress(addr);
1273             }
1274         }
1275
1276         //
1277         // Choose an address to connect to based on most recently seen
1278         //
1279         CAddress addrConnect;
1280         int64 nBest = std::numeric_limits<int64>::min();
1281
1282         // Only connect to one address per a.b.?.? range.
1283         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1284         set<vector<unsigned char> > setConnected;
1285         CRITICAL_BLOCK(cs_vNodes)
1286             BOOST_FOREACH(CNode* pnode, vNodes)
1287                 setConnected.insert(pnode->addr.GetGroup());
1288
1289         int64 nANow = GetAdjustedTime();
1290
1291         CRITICAL_BLOCK(cs_mapAddresses)
1292         {
1293             BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
1294             {
1295                 const CAddress& addr = item.second;
1296                 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()))
1297                     continue;
1298                 int64 nSinceLastSeen = nANow - addr.nTime;
1299                 int64 nSinceLastTry = nANow - addr.nLastTry;
1300
1301                 // Randomize the order in a deterministic way, putting the standard port first
1302                 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.GetHash()) % (2 * 60 * 60);
1303                 if (addr.GetPort() != GetDefaultPort())
1304                     nRandomizer += 2 * 60 * 60;
1305
1306                 // Last seen  Base retry frequency
1307                 //   <1 hour   10 min
1308                 //    1 hour    1 hour
1309                 //    4 hours   2 hours
1310                 //   24 hours   5 hours
1311                 //   48 hours   7 hours
1312                 //    7 days   13 hours
1313                 //   30 days   27 hours
1314                 //   90 days   46 hours
1315                 //  365 days   93 hours
1316                 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1317
1318                 // Fast reconnect for one hour after last seen
1319                 if (nSinceLastSeen < 60 * 60)
1320                     nDelay = 10 * 60;
1321
1322                 // Limit retry frequency
1323                 if (nSinceLastTry < nDelay)
1324                     continue;
1325
1326                 // If we have IRC, we'll be notified when they first come online,
1327                 // and again every 24 hours by the refresh broadcast.
1328                 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1329                     continue;
1330
1331                 // Only try the old stuff if we don't have enough connections
1332                 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1333                     continue;
1334
1335                 // If multiple addresses are ready, prioritize by time since
1336                 // last seen and time since last tried.
1337                 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1338                 if (nScore > nBest)
1339                 {
1340                     nBest = nScore;
1341                     addrConnect = addr;
1342                 }
1343             }
1344         }
1345
1346         if (addrConnect.IsValid())
1347             OpenNetworkConnection(addrConnect);
1348     }
1349 }
1350
1351 void ThreadOpenAddedConnections(void* parg)
1352 {
1353     IMPLEMENT_RANDOMIZE_STACK(ThreadOpenAddedConnections(parg));
1354     try
1355     {
1356         vnThreadsRunning[7]++;
1357         ThreadOpenAddedConnections2(parg);
1358         vnThreadsRunning[7]--;
1359     }
1360     catch (std::exception& e) {
1361         vnThreadsRunning[7]--;
1362         PrintException(&e, "ThreadOpenAddedConnections()");
1363     } catch (...) {
1364         vnThreadsRunning[7]--;
1365         PrintException(NULL, "ThreadOpenAddedConnections()");
1366     }
1367     printf("ThreadOpenAddedConnections exiting\n");
1368 }
1369
1370 void ThreadOpenAddedConnections2(void* parg)
1371 {
1372     printf("ThreadOpenAddedConnections started\n");
1373
1374     if (mapArgs.count("-addnode") == 0)
1375         return;
1376
1377     vector<vector<CService> > vservAddressesToAdd(0);
1378     BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
1379     {
1380         vector<CService> vservNode(0);
1381         if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
1382         {
1383             vservAddressesToAdd.push_back(vservNode);
1384             CRITICAL_BLOCK(cs_setservAddNodeAddresses)
1385                 BOOST_FOREACH(CService& serv, vservNode)
1386                     setservAddNodeAddresses.insert(serv);
1387         }
1388     }
1389     loop
1390     {
1391         vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
1392         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1393         // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
1394         CRITICAL_BLOCK(cs_vNodes)
1395             BOOST_FOREACH(CNode* pnode, vNodes)
1396                 for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
1397                     BOOST_FOREACH(CService& addrNode, *(it))
1398                         if (pnode->addr == addrNode)
1399                         {
1400                             it = vservConnectAddresses.erase(it);
1401                             it--;
1402                             break;
1403                         }
1404         BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
1405         {
1406             OpenNetworkConnection(CAddress(*(vserv.begin())));
1407             Sleep(500);
1408             if (fShutdown)
1409                 return;
1410         }
1411         if (fShutdown)
1412             return;
1413         vnThreadsRunning[7]--;
1414         Sleep(120000); // Retry every 2 minutes
1415         vnThreadsRunning[7]++;
1416         if (fShutdown)
1417             return;
1418     }
1419 }
1420
1421 bool OpenNetworkConnection(const CAddress& addrConnect)
1422 {
1423     //
1424     // Initiate outbound network connection
1425     //
1426     if (fShutdown)
1427         return false;
1428     if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
1429         FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
1430         return false;
1431
1432     vnThreadsRunning[1]--;
1433     CNode* pnode = ConnectNode(addrConnect);
1434     vnThreadsRunning[1]++;
1435     if (fShutdown)
1436         return false;
1437     if (!pnode)
1438         return false;
1439     pnode->fNetworkNode = true;
1440
1441     return true;
1442 }
1443
1444
1445
1446
1447
1448
1449
1450
1451 void ThreadMessageHandler(void* parg)
1452 {
1453     IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1454     try
1455     {
1456         vnThreadsRunning[2]++;
1457         ThreadMessageHandler2(parg);
1458         vnThreadsRunning[2]--;
1459     }
1460     catch (std::exception& e) {
1461         vnThreadsRunning[2]--;
1462         PrintException(&e, "ThreadMessageHandler()");
1463     } catch (...) {
1464         vnThreadsRunning[2]--;
1465         PrintException(NULL, "ThreadMessageHandler()");
1466     }
1467     printf("ThreadMessageHandler exiting\n");
1468 }
1469
1470 void ThreadMessageHandler2(void* parg)
1471 {
1472     printf("ThreadMessageHandler started\n");
1473     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1474     while (!fShutdown)
1475     {
1476         vector<CNode*> vNodesCopy;
1477         CRITICAL_BLOCK(cs_vNodes)
1478         {
1479             vNodesCopy = vNodes;
1480             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1481                 pnode->AddRef();
1482         }
1483
1484         // Poll the connected nodes for messages
1485         CNode* pnodeTrickle = NULL;
1486         if (!vNodesCopy.empty())
1487             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1488         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1489         {
1490             // Receive messages
1491             TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1492                 ProcessMessages(pnode);
1493             if (fShutdown)
1494                 return;
1495
1496             // Send messages
1497             TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1498                 SendMessages(pnode, pnode == pnodeTrickle);
1499             if (fShutdown)
1500                 return;
1501         }
1502
1503         CRITICAL_BLOCK(cs_vNodes)
1504         {
1505             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1506                 pnode->Release();
1507         }
1508
1509         // Wait and allow messages to bunch up.
1510         // Reduce vnThreadsRunning so StopNode has permission to exit while
1511         // we're sleeping, but we must always check fShutdown after doing this.
1512         vnThreadsRunning[2]--;
1513         Sleep(100);
1514         if (fRequestShutdown)
1515             Shutdown(NULL);
1516         vnThreadsRunning[2]++;
1517         if (fShutdown)
1518             return;
1519     }
1520 }
1521
1522
1523
1524
1525
1526
1527 bool BindListenPort(string& strError)
1528 {
1529     strError = "";
1530     int nOne = 1;
1531     addrLocalHost.SetPort(GetListenPort());
1532
1533 #ifdef WIN32
1534     // Initialize Windows Sockets
1535     WSADATA wsadata;
1536     int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1537     if (ret != NO_ERROR)
1538     {
1539         strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1540         printf("%s\n", strError.c_str());
1541         return false;
1542     }
1543 #endif
1544
1545     // Create socket for listening for incoming connections
1546     hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1547     if (hListenSocket == INVALID_SOCKET)
1548     {
1549         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1550         printf("%s\n", strError.c_str());
1551         return false;
1552     }
1553
1554 #ifdef SO_NOSIGPIPE
1555     // Different way of disabling SIGPIPE on BSD
1556     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1557 #endif
1558
1559 #ifndef WIN32
1560     // Allow binding if the port is still in TIME_WAIT state after
1561     // the program was closed and restarted.  Not an issue on windows.
1562     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1563 #endif
1564
1565 #ifdef WIN32
1566     // Set to nonblocking, incoming connections will also inherit this
1567     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1568 #else
1569     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1570 #endif
1571     {
1572         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1573         printf("%s\n", strError.c_str());
1574         return false;
1575     }
1576
1577     // The sockaddr_in structure specifies the address family,
1578     // IP address, and port for the socket that is being bound
1579     struct sockaddr_in sockaddr;
1580     memset(&sockaddr, 0, sizeof(sockaddr));
1581     sockaddr.sin_family = AF_INET;
1582     sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
1583     sockaddr.sin_port = htons(GetListenPort());
1584     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1585     {
1586         int nErr = WSAGetLastError();
1587         if (nErr == WSAEADDRINUSE)
1588             strError = strprintf(_("Unable to bind to port %d on this computer.  Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
1589         else
1590             strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1591         printf("%s\n", strError.c_str());
1592         return false;
1593     }
1594     printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1595
1596     // Listen for incoming connections
1597     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1598     {
1599         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1600         printf("%s\n", strError.c_str());
1601         return false;
1602     }
1603
1604     return true;
1605 }
1606
1607 void StartNode(void* parg)
1608 {
1609     if (pnodeLocalHost == NULL)
1610         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1611
1612 #ifdef WIN32
1613     // Get local host ip
1614     char pszHostName[1000] = "";
1615     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1616     {
1617         vector<CNetAddr> vaddr;
1618         if (LookupHost(pszHostName, vaddr))
1619             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1620                 if (!addr.IsLocal())
1621                 {
1622                     addrLocalHost.SetIP(addr);
1623                     break;
1624                 }
1625     }
1626 #else
1627     // Get local host ip
1628     struct ifaddrs* myaddrs;
1629     if (getifaddrs(&myaddrs) == 0)
1630     {
1631         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1632         {
1633             if (ifa->ifa_addr == NULL) continue;
1634             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1635             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1636             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1637             char pszIP[100];
1638             if (ifa->ifa_addr->sa_family == AF_INET)
1639             {
1640                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1641                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1642                     printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1643
1644                 // Take the first IP that isn't loopback 127.x.x.x
1645                 CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
1646                 if (addr.IsValid() && !addr.IsLocal())
1647                 {
1648                     addrLocalHost = addr;
1649                     break;
1650                 }
1651             }
1652             else if (ifa->ifa_addr->sa_family == AF_INET6)
1653             {
1654                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1655                 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1656                     printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1657             }
1658         }
1659         freeifaddrs(myaddrs);
1660     }
1661 #endif
1662     printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1663
1664     if (fUseProxy || mapArgs.count("-connect") || fNoListen)
1665     {
1666         // Proxies can't take incoming connections
1667         addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
1668         printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1669     }
1670     else
1671     {
1672         CreateThread(ThreadGetMyExternalIP, NULL);
1673     }
1674
1675     //
1676     // Start threads
1677     //
1678
1679     if (GetBoolArg("-nodnsseed"))
1680         printf("DNS seeding disabled\n");
1681     else
1682         if (!CreateThread(ThreadDNSAddressSeed, NULL))
1683             printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1684
1685     // Map ports with UPnP
1686     if (fHaveUPnP)
1687         MapPort(fUseUPnP);
1688
1689     // Get addresses from IRC and advertise ours
1690     if (!CreateThread(ThreadIRCSeed, NULL))
1691         printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1692
1693     // Send and receive from sockets, accept connections
1694     if (!CreateThread(ThreadSocketHandler, NULL))
1695         printf("Error: CreateThread(ThreadSocketHandler) failed\n");
1696
1697     // Initiate outbound connections from -addnode
1698     if (!CreateThread(ThreadOpenAddedConnections, NULL))
1699         printf("Error: CreateThread(ThreadOpenAddedConnections) failed\n");
1700
1701     // Initiate outbound connections
1702     if (!CreateThread(ThreadOpenConnections, NULL))
1703         printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1704
1705     // Process messages
1706     if (!CreateThread(ThreadMessageHandler, NULL))
1707         printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1708
1709     // Generate coins in the background
1710     GenerateBitcoins(fGenerateBitcoins, pwalletMain);
1711 }
1712
1713 bool StopNode()
1714 {
1715     printf("StopNode()\n");
1716     fShutdown = true;
1717     nTransactionsUpdated++;
1718     int64 nStart = GetTime();
1719     while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 || vnThreadsRunning[6] > 0 || vnThreadsRunning[7] > 0
1720 #ifdef USE_UPNP
1721         || vnThreadsRunning[5] > 0
1722 #endif
1723     )
1724     {
1725         if (GetTime() - nStart > 20)
1726             break;
1727         Sleep(20);
1728     }
1729     if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1730     if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1731     if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1732     if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1733     if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
1734     if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
1735     if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
1736     if (vnThreadsRunning[7] > 0) printf("ThreadOpenAddedConnections still running\n");
1737     while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1738         Sleep(20);
1739     Sleep(50);
1740
1741     return true;
1742 }
1743
1744 class CNetCleanup
1745 {
1746 public:
1747     CNetCleanup()
1748     {
1749     }
1750     ~CNetCleanup()
1751     {
1752         // Close sockets
1753         BOOST_FOREACH(CNode* pnode, vNodes)
1754             if (pnode->hSocket != INVALID_SOCKET)
1755                 closesocket(pnode->hSocket);
1756         if (hListenSocket != INVALID_SOCKET)
1757             if (closesocket(hListenSocket) == SOCKET_ERROR)
1758                 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1759
1760 #ifdef WIN32
1761         // Shutdown Windows Sockets
1762         WSACleanup();
1763 #endif
1764     }
1765 }
1766 instance_of_cnetcleanup;