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