]> Git Repo - VerusCoin.git/blob - src/net.cpp
Make bitcoin compile without wallet if "db_cxx.h" is not present
[VerusCoin.git] / src / net.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #if defined(HAVE_CONFIG_H)
7 #include "bitcoin-config.h"
8 #endif
9
10 #include "net.h"
11
12 #include "addrman.h"
13 #include "chainparams.h"
14 #include "core.h"
15 #include "ui_interface.h"
16
17 #ifdef WIN32
18 #include <string.h>
19 #else
20 #include <fcntl.h>
21 #endif
22
23 #ifdef USE_UPNP
24 #include <miniupnpc/miniupnpc.h>
25 #include <miniupnpc/miniwget.h>
26 #include <miniupnpc/upnpcommands.h>
27 #include <miniupnpc/upnperrors.h>
28 #endif
29
30 // Dump addresses to peers.dat every 15 minutes (900s)
31 #define DUMP_ADDRESSES_INTERVAL 900
32
33 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
34 #define MSG_NOSIGNAL 0
35 #endif
36
37 using namespace std;
38 using namespace boost;
39
40 static const int MAX_OUTBOUND_CONNECTIONS = 8;
41
42 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
43
44
45 struct LocalServiceInfo {
46     int nScore;
47     int nPort;
48 };
49
50 //
51 // Global state variables
52 //
53 bool fDiscover = true;
54 uint64_t nLocalServices = NODE_NETWORK;
55 static CCriticalSection cs_mapLocalHost;
56 static map<CNetAddr, LocalServiceInfo> mapLocalHost;
57 static bool vfReachable[NET_MAX] = {};
58 static bool vfLimited[NET_MAX] = {};
59 static CNode* pnodeLocalHost = NULL;
60 static CNode* pnodeSync = NULL;
61 uint64_t nLocalHostNonce = 0;
62 static std::vector<SOCKET> vhListenSocket;
63 CAddrMan addrman;
64 int nMaxConnections = 125;
65
66 vector<CNode*> vNodes;
67 CCriticalSection cs_vNodes;
68 map<CInv, CDataStream> mapRelay;
69 deque<pair<int64_t, CInv> > vRelayExpiration;
70 CCriticalSection cs_mapRelay;
71 limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
72
73 static deque<string> vOneShots;
74 CCriticalSection cs_vOneShots;
75
76 set<CNetAddr> setservAddNodeAddresses;
77 CCriticalSection cs_setservAddNodeAddresses;
78
79 vector<std::string> vAddedNodes;
80 CCriticalSection cs_vAddedNodes;
81
82 NodeId nLastNodeId = 0;
83 CCriticalSection cs_nLastNodeId;
84
85 static CSemaphore *semOutbound = NULL;
86
87 // Signals for message handling
88 static CNodeSignals g_signals;
89 CNodeSignals& GetNodeSignals() { return g_signals; }
90
91 void AddOneShot(string strDest)
92 {
93     LOCK(cs_vOneShots);
94     vOneShots.push_back(strDest);
95 }
96
97 unsigned short GetListenPort()
98 {
99     return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
100 }
101
102 // find 'best' local address for a particular peer
103 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
104 {
105     if (fNoListen)
106         return false;
107
108     int nBestScore = -1;
109     int nBestReachability = -1;
110     {
111         LOCK(cs_mapLocalHost);
112         for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
113         {
114             int nScore = (*it).second.nScore;
115             int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
116             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
117             {
118                 addr = CService((*it).first, (*it).second.nPort);
119                 nBestReachability = nReachability;
120                 nBestScore = nScore;
121             }
122         }
123     }
124     return nBestScore >= 0;
125 }
126
127 // get best local address for a particular peer as a CAddress
128 CAddress GetLocalAddress(const CNetAddr *paddrPeer)
129 {
130     CAddress ret(CService("0.0.0.0",0),0);
131     CService addr;
132     if (GetLocal(addr, paddrPeer))
133     {
134         ret = CAddress(addr);
135         ret.nServices = nLocalServices;
136         ret.nTime = GetAdjustedTime();
137     }
138     return ret;
139 }
140
141 bool RecvLine(SOCKET hSocket, string& strLine)
142 {
143     strLine = "";
144     while (true)
145     {
146         char c;
147         int nBytes = recv(hSocket, &c, 1, 0);
148         if (nBytes > 0)
149         {
150             if (c == '\n')
151                 continue;
152             if (c == '\r')
153                 return true;
154             strLine += c;
155             if (strLine.size() >= 9000)
156                 return true;
157         }
158         else if (nBytes <= 0)
159         {
160             boost::this_thread::interruption_point();
161             if (nBytes < 0)
162             {
163                 int nErr = WSAGetLastError();
164                 if (nErr == WSAEMSGSIZE)
165                     continue;
166                 if (nErr == WSAEWOULDBLOCK || nErr == WSAEINTR || nErr == WSAEINPROGRESS)
167                 {
168                     MilliSleep(10);
169                     continue;
170                 }
171             }
172             if (!strLine.empty())
173                 return true;
174             if (nBytes == 0)
175             {
176                 // socket closed
177                 LogPrint("net", "socket closed\n");
178                 return false;
179             }
180             else
181             {
182                 // socket error
183                 int nErr = WSAGetLastError();
184                 LogPrint("net", "recv failed: %d\n", nErr);
185                 return false;
186             }
187         }
188     }
189 }
190
191 // used when scores of local addresses may have changed
192 // pushes better local address to peers
193 void static AdvertizeLocal()
194 {
195     LOCK(cs_vNodes);
196     BOOST_FOREACH(CNode* pnode, vNodes)
197     {
198         if (pnode->fSuccessfullyConnected)
199         {
200             CAddress addrLocal = GetLocalAddress(&pnode->addr);
201             if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
202             {
203                 pnode->PushAddress(addrLocal);
204                 pnode->addrLocal = addrLocal;
205             }
206         }
207     }
208 }
209
210 void SetReachable(enum Network net, bool fFlag)
211 {
212     LOCK(cs_mapLocalHost);
213     vfReachable[net] = fFlag;
214     if (net == NET_IPV6 && fFlag)
215         vfReachable[NET_IPV4] = true;
216 }
217
218 // learn a new local address
219 bool AddLocal(const CService& addr, int nScore)
220 {
221     if (!addr.IsRoutable())
222         return false;
223
224     if (!fDiscover && nScore < LOCAL_MANUAL)
225         return false;
226
227     if (IsLimited(addr))
228         return false;
229
230     LogPrintf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
231
232     {
233         LOCK(cs_mapLocalHost);
234         bool fAlready = mapLocalHost.count(addr) > 0;
235         LocalServiceInfo &info = mapLocalHost[addr];
236         if (!fAlready || nScore >= info.nScore) {
237             info.nScore = nScore + (fAlready ? 1 : 0);
238             info.nPort = addr.GetPort();
239         }
240         SetReachable(addr.GetNetwork());
241     }
242
243     AdvertizeLocal();
244
245     return true;
246 }
247
248 bool AddLocal(const CNetAddr &addr, int nScore)
249 {
250     return AddLocal(CService(addr, GetListenPort()), nScore);
251 }
252
253 /** Make a particular network entirely off-limits (no automatic connects to it) */
254 void SetLimited(enum Network net, bool fLimited)
255 {
256     if (net == NET_UNROUTABLE)
257         return;
258     LOCK(cs_mapLocalHost);
259     vfLimited[net] = fLimited;
260 }
261
262 bool IsLimited(enum Network net)
263 {
264     LOCK(cs_mapLocalHost);
265     return vfLimited[net];
266 }
267
268 bool IsLimited(const CNetAddr &addr)
269 {
270     return IsLimited(addr.GetNetwork());
271 }
272
273 /** vote for a local address */
274 bool SeenLocal(const CService& addr)
275 {
276     {
277         LOCK(cs_mapLocalHost);
278         if (mapLocalHost.count(addr) == 0)
279             return false;
280         mapLocalHost[addr].nScore++;
281     }
282
283     AdvertizeLocal();
284
285     return true;
286 }
287
288 /** check whether a given address is potentially local */
289 bool IsLocal(const CService& addr)
290 {
291     LOCK(cs_mapLocalHost);
292     return mapLocalHost.count(addr) > 0;
293 }
294
295 /** check whether a given address is in a network we can probably connect to */
296 bool IsReachable(const CNetAddr& addr)
297 {
298     LOCK(cs_mapLocalHost);
299     enum Network net = addr.GetNetwork();
300     return vfReachable[net] && !vfLimited[net];
301 }
302
303 bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
304 {
305     SOCKET hSocket;
306     if (!ConnectSocket(addrConnect, hSocket))
307         return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
308
309     send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
310
311     string strLine;
312     while (RecvLine(hSocket, strLine))
313     {
314         if (strLine.empty()) // HTTP response is separated from headers by blank line
315         {
316             while (true)
317             {
318                 if (!RecvLine(hSocket, strLine))
319                 {
320                     closesocket(hSocket);
321                     return false;
322                 }
323                 if (pszKeyword == NULL)
324                     break;
325                 if (strLine.find(pszKeyword) != string::npos)
326                 {
327                     strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
328                     break;
329                 }
330             }
331             closesocket(hSocket);
332             if (strLine.find("<") != string::npos)
333                 strLine = strLine.substr(0, strLine.find("<"));
334             strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
335             while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
336                 strLine.resize(strLine.size()-1);
337             CService addr(strLine,0,true);
338             LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
339             if (!addr.IsValid() || !addr.IsRoutable())
340                 return false;
341             ipRet.SetIP(addr);
342             return true;
343         }
344     }
345     closesocket(hSocket);
346     return error("GetMyExternalIP() : connection closed");
347 }
348
349 bool GetMyExternalIP(CNetAddr& ipRet)
350 {
351     CService addrConnect;
352     const char* pszGet;
353     const char* pszKeyword;
354
355     for (int nLookup = 0; nLookup <= 1; nLookup++)
356     for (int nHost = 1; nHost <= 2; nHost++)
357     {
358         // We should be phasing out our use of sites like these. If we need
359         // replacements, we should ask for volunteers to put this simple
360         // php file on their web server that prints the client IP:
361         //  <?php echo $_SERVER["REMOTE_ADDR"]; ?>
362         if (nHost == 1)
363         {
364             addrConnect = CService("91.198.22.70", 80); // checkip.dyndns.org
365
366             if (nLookup == 1)
367             {
368                 CService addrIP("checkip.dyndns.org", 80, true);
369                 if (addrIP.IsValid())
370                     addrConnect = addrIP;
371             }
372
373             pszGet = "GET / HTTP/1.1\r\n"
374                      "Host: checkip.dyndns.org\r\n"
375                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
376                      "Connection: close\r\n"
377                      "\r\n";
378
379             pszKeyword = "Address:";
380         }
381         else if (nHost == 2)
382         {
383             addrConnect = CService("74.208.43.192", 80); // www.showmyip.com
384
385             if (nLookup == 1)
386             {
387                 CService addrIP("www.showmyip.com", 80, true);
388                 if (addrIP.IsValid())
389                     addrConnect = addrIP;
390             }
391
392             pszGet = "GET /simple/ HTTP/1.1\r\n"
393                      "Host: www.showmyip.com\r\n"
394                      "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
395                      "Connection: close\r\n"
396                      "\r\n";
397
398             pszKeyword = NULL; // Returns just IP address
399         }
400
401         if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
402             return true;
403     }
404
405     return false;
406 }
407
408 void ThreadGetMyExternalIP()
409 {
410     CNetAddr addrLocalHost;
411     if (GetMyExternalIP(addrLocalHost))
412     {
413         LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
414         AddLocal(addrLocalHost, LOCAL_HTTP);
415     }
416 }
417
418
419
420
421
422 void AddressCurrentlyConnected(const CService& addr)
423 {
424     addrman.Connected(addr);
425 }
426
427
428
429
430 uint64_t CNode::nTotalBytesRecv = 0;
431 uint64_t CNode::nTotalBytesSent = 0;
432 CCriticalSection CNode::cs_totalBytesRecv;
433 CCriticalSection CNode::cs_totalBytesSent;
434
435 CNode* FindNode(const CNetAddr& ip)
436 {
437     LOCK(cs_vNodes);
438     BOOST_FOREACH(CNode* pnode, vNodes)
439         if ((CNetAddr)pnode->addr == ip)
440             return (pnode);
441     return NULL;
442 }
443
444 CNode* FindNode(std::string addrName)
445 {
446     LOCK(cs_vNodes);
447     BOOST_FOREACH(CNode* pnode, vNodes)
448         if (pnode->addrName == addrName)
449             return (pnode);
450     return NULL;
451 }
452
453 CNode* FindNode(const CService& addr)
454 {
455     LOCK(cs_vNodes);
456     BOOST_FOREACH(CNode* pnode, vNodes)
457         if ((CService)pnode->addr == addr)
458             return (pnode);
459     return NULL;
460 }
461
462 CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
463 {
464     if (pszDest == NULL) {
465         if (IsLocal(addrConnect))
466             return NULL;
467
468         // Look for an existing connection
469         CNode* pnode = FindNode((CService)addrConnect);
470         if (pnode)
471         {
472             pnode->AddRef();
473             return pnode;
474         }
475     }
476
477
478     /// debug print
479     LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
480         pszDest ? pszDest : addrConnect.ToString().c_str(),
481         pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
482
483     // Connect
484     SOCKET hSocket;
485     if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
486     {
487         addrman.Attempt(addrConnect);
488
489         LogPrint("net", "connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
490
491         // Set to non-blocking
492 #ifdef WIN32
493         u_long nOne = 1;
494         if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
495             LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
496 #else
497         if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
498             LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
499 #endif
500
501         // Add node
502         CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
503         pnode->AddRef();
504
505         {
506             LOCK(cs_vNodes);
507             vNodes.push_back(pnode);
508         }
509
510         pnode->nTimeConnected = GetTime();
511         return pnode;
512     }
513     else
514     {
515         return NULL;
516     }
517 }
518
519 void CNode::CloseSocketDisconnect()
520 {
521     fDisconnect = true;
522     if (hSocket != INVALID_SOCKET)
523     {
524         LogPrint("net", "disconnecting node %s\n", addrName.c_str());
525         closesocket(hSocket);
526         hSocket = INVALID_SOCKET;
527     }
528
529     // in case this fails, we'll empty the recv buffer when the CNode is deleted
530     TRY_LOCK(cs_vRecvMsg, lockRecv);
531     if (lockRecv)
532         vRecvMsg.clear();
533
534     // if this was the sync node, we'll need a new one
535     if (this == pnodeSync)
536         pnodeSync = NULL;
537 }
538
539 void CNode::Cleanup()
540 {
541 }
542
543
544 void CNode::PushVersion()
545 {
546     int nBestHeight = g_signals.GetHeight().get_value_or(0);
547
548     /// when NTP implemented, change to just nTime = GetAdjustedTime()
549     int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
550     CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
551     CAddress addrMe = GetLocalAddress(&addr);
552     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
553     LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
554     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
555                 nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
556 }
557
558
559
560
561
562 std::map<CNetAddr, int64_t> CNode::setBanned;
563 CCriticalSection CNode::cs_setBanned;
564
565 void CNode::ClearBanned()
566 {
567     setBanned.clear();
568 }
569
570 bool CNode::IsBanned(CNetAddr ip)
571 {
572     bool fResult = false;
573     {
574         LOCK(cs_setBanned);
575         std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
576         if (i != setBanned.end())
577         {
578             int64_t t = (*i).second;
579             if (GetTime() < t)
580                 fResult = true;
581         }
582     }
583     return fResult;
584 }
585
586 bool CNode::Ban(const CNetAddr &addr) {
587     int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24);  // Default 24-hour ban
588     {
589         LOCK(cs_setBanned);
590         if (setBanned[addr] < banTime)
591             setBanned[addr] = banTime;
592     }
593     return true;
594 }
595
596 #undef X
597 #define X(name) stats.name = name
598 void CNode::copyStats(CNodeStats &stats)
599 {
600     stats.nodeid = this->GetId();
601     X(nServices);
602     X(nLastSend);
603     X(nLastRecv);
604     X(nTimeConnected);
605     X(addrName);
606     X(nVersion);
607     X(cleanSubVer);
608     X(fInbound);
609     X(nStartingHeight);
610     X(nSendBytes);
611     X(nRecvBytes);
612     stats.fSyncNode = (this == pnodeSync);
613
614     // It is common for nodes with good ping times to suddenly become lagged,
615     // due to a new block arriving or other large transfer.
616     // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
617     // since pingtime does not update until the ping is complete, which might take a while.
618     // So, if a ping is taking an unusually long time in flight,
619     // the caller can immediately detect that this is happening.
620     int64_t nPingUsecWait = 0;
621     if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
622         nPingUsecWait = GetTimeMicros() - nPingUsecStart;
623     }
624
625     // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
626     stats.dPingTime = (((double)nPingUsecTime) / 1e6);
627     stats.dPingWait = (((double)nPingUsecWait) / 1e6);
628
629     // Leave string empty if addrLocal invalid (not filled in yet)
630     stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
631 }
632 #undef X
633
634 // requires LOCK(cs_vRecvMsg)
635 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
636 {
637     while (nBytes > 0) {
638
639         // get current incomplete message, or create a new one
640         if (vRecvMsg.empty() ||
641             vRecvMsg.back().complete())
642             vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
643
644         CNetMessage& msg = vRecvMsg.back();
645
646         // absorb network data
647         int handled;
648         if (!msg.in_data)
649             handled = msg.readHeader(pch, nBytes);
650         else
651             handled = msg.readData(pch, nBytes);
652
653         if (handled < 0)
654                 return false;
655
656         pch += handled;
657         nBytes -= handled;
658     }
659
660     return true;
661 }
662
663 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
664 {
665     // copy data to temporary parsing buffer
666     unsigned int nRemaining = 24 - nHdrPos;
667     unsigned int nCopy = std::min(nRemaining, nBytes);
668
669     memcpy(&hdrbuf[nHdrPos], pch, nCopy);
670     nHdrPos += nCopy;
671
672     // if header incomplete, exit
673     if (nHdrPos < 24)
674         return nCopy;
675
676     // deserialize to CMessageHeader
677     try {
678         hdrbuf >> hdr;
679     }
680     catch (std::exception &e) {
681         return -1;
682     }
683
684     // reject messages larger than MAX_SIZE
685     if (hdr.nMessageSize > MAX_SIZE)
686             return -1;
687
688     // switch state to reading message data
689     in_data = true;
690     vRecv.resize(hdr.nMessageSize);
691
692     return nCopy;
693 }
694
695 int CNetMessage::readData(const char *pch, unsigned int nBytes)
696 {
697     unsigned int nRemaining = hdr.nMessageSize - nDataPos;
698     unsigned int nCopy = std::min(nRemaining, nBytes);
699
700     memcpy(&vRecv[nDataPos], pch, nCopy);
701     nDataPos += nCopy;
702
703     return nCopy;
704 }
705
706
707
708
709
710
711
712
713
714 // requires LOCK(cs_vSend)
715 void SocketSendData(CNode *pnode)
716 {
717     std::deque<CSerializeData>::iterator it = pnode->vSendMsg.begin();
718
719     while (it != pnode->vSendMsg.end()) {
720         const CSerializeData &data = *it;
721         assert(data.size() > pnode->nSendOffset);
722         int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
723         if (nBytes > 0) {
724             pnode->nLastSend = GetTime();
725             pnode->nSendBytes += nBytes;
726             pnode->nSendOffset += nBytes;
727             pnode->RecordBytesSent(nBytes);
728             if (pnode->nSendOffset == data.size()) {
729                 pnode->nSendOffset = 0;
730                 pnode->nSendSize -= data.size();
731                 it++;
732             } else {
733                 // could not send full message; stop sending more
734                 break;
735             }
736         } else {
737             if (nBytes < 0) {
738                 // error
739                 int nErr = WSAGetLastError();
740                 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
741                 {
742                     LogPrintf("socket send error %d\n", nErr);
743                     pnode->CloseSocketDisconnect();
744                 }
745             }
746             // couldn't send anything at all
747             break;
748         }
749     }
750
751     if (it == pnode->vSendMsg.end()) {
752         assert(pnode->nSendOffset == 0);
753         assert(pnode->nSendSize == 0);
754     }
755     pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
756 }
757
758 static list<CNode*> vNodesDisconnected;
759
760 void ThreadSocketHandler()
761 {
762     unsigned int nPrevNodeCount = 0;
763     while (true)
764     {
765         //
766         // Disconnect nodes
767         //
768         {
769             LOCK(cs_vNodes);
770             // Disconnect unused nodes
771             vector<CNode*> vNodesCopy = vNodes;
772             BOOST_FOREACH(CNode* pnode, vNodesCopy)
773             {
774                 if (pnode->fDisconnect ||
775                     (pnode->GetRefCount() <= 0 && pnode->vRecvMsg.empty() && pnode->nSendSize == 0 && pnode->ssSend.empty()))
776                 {
777                     // remove from vNodes
778                     vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
779
780                     // release outbound grant (if any)
781                     pnode->grantOutbound.Release();
782
783                     // close socket and cleanup
784                     pnode->CloseSocketDisconnect();
785                     pnode->Cleanup();
786
787                     // hold in disconnected pool until all refs are released
788                     if (pnode->fNetworkNode || pnode->fInbound)
789                         pnode->Release();
790                     vNodesDisconnected.push_back(pnode);
791                 }
792             }
793         }
794         {
795             // Delete disconnected nodes
796             list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
797             BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
798             {
799                 // wait until threads are done using it
800                 if (pnode->GetRefCount() <= 0)
801                 {
802                     bool fDelete = false;
803                     {
804                         TRY_LOCK(pnode->cs_vSend, lockSend);
805                         if (lockSend)
806                         {
807                             TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
808                             if (lockRecv)
809                             {
810                                 TRY_LOCK(pnode->cs_inventory, lockInv);
811                                 if (lockInv)
812                                     fDelete = true;
813                             }
814                         }
815                     }
816                     if (fDelete)
817                     {
818                         vNodesDisconnected.remove(pnode);
819                         delete pnode;
820                     }
821                 }
822             }
823         }
824         if(vNodes.size() != nPrevNodeCount) {
825             nPrevNodeCount = vNodes.size();
826             uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
827         }
828
829
830         //
831         // Find which sockets have data to receive
832         //
833         struct timeval timeout;
834         timeout.tv_sec  = 0;
835         timeout.tv_usec = 50000; // frequency to poll pnode->vSend
836
837         fd_set fdsetRecv;
838         fd_set fdsetSend;
839         fd_set fdsetError;
840         FD_ZERO(&fdsetRecv);
841         FD_ZERO(&fdsetSend);
842         FD_ZERO(&fdsetError);
843         SOCKET hSocketMax = 0;
844         bool have_fds = false;
845
846         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
847             FD_SET(hListenSocket, &fdsetRecv);
848             hSocketMax = max(hSocketMax, hListenSocket);
849             have_fds = true;
850         }
851         {
852             LOCK(cs_vNodes);
853             BOOST_FOREACH(CNode* pnode, vNodes)
854             {
855                 if (pnode->hSocket == INVALID_SOCKET)
856                     continue;
857                 FD_SET(pnode->hSocket, &fdsetError);
858                 hSocketMax = max(hSocketMax, pnode->hSocket);
859                 have_fds = true;
860
861                 // Implement the following logic:
862                 // * If there is data to send, select() for sending data. As this only
863                 //   happens when optimistic write failed, we choose to first drain the
864                 //   write buffer in this case before receiving more. This avoids
865                 //   needlessly queueing received data, if the remote peer is not themselves
866                 //   receiving data. This means properly utilizing TCP flow control signalling.
867                 // * Otherwise, if there is no (complete) message in the receive buffer,
868                 //   or there is space left in the buffer, select() for receiving data.
869                 // * (if neither of the above applies, there is certainly one message
870                 //   in the receiver buffer ready to be processed).
871                 // Together, that means that at least one of the following is always possible,
872                 // so we don't deadlock:
873                 // * We send some data.
874                 // * We wait for data to be received (and disconnect after timeout).
875                 // * We process a message in the buffer (message handler thread).
876                 {
877                     TRY_LOCK(pnode->cs_vSend, lockSend);
878                     if (lockSend && !pnode->vSendMsg.empty()) {
879                         FD_SET(pnode->hSocket, &fdsetSend);
880                         continue;
881                     }
882                 }
883                 {
884                     TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
885                     if (lockRecv && (
886                         pnode->vRecvMsg.empty() || !pnode->vRecvMsg.front().complete() ||
887                         pnode->GetTotalRecvSize() <= ReceiveFloodSize()))
888                         FD_SET(pnode->hSocket, &fdsetRecv);
889                 }
890             }
891         }
892
893         int nSelect = select(have_fds ? hSocketMax + 1 : 0,
894                              &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
895         boost::this_thread::interruption_point();
896
897         if (nSelect == SOCKET_ERROR)
898         {
899             if (have_fds)
900             {
901                 int nErr = WSAGetLastError();
902                 LogPrintf("socket select error %d\n", nErr);
903                 for (unsigned int i = 0; i <= hSocketMax; i++)
904                     FD_SET(i, &fdsetRecv);
905             }
906             FD_ZERO(&fdsetSend);
907             FD_ZERO(&fdsetError);
908             MilliSleep(timeout.tv_usec/1000);
909         }
910
911
912         //
913         // Accept new connections
914         //
915         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
916         if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
917         {
918 #ifdef USE_IPV6
919             struct sockaddr_storage sockaddr;
920 #else
921             struct sockaddr sockaddr;
922 #endif
923             socklen_t len = sizeof(sockaddr);
924             SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
925             CAddress addr;
926             int nInbound = 0;
927
928             if (hSocket != INVALID_SOCKET)
929                 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
930                     LogPrintf("Warning: Unknown socket family\n");
931
932             {
933                 LOCK(cs_vNodes);
934                 BOOST_FOREACH(CNode* pnode, vNodes)
935                     if (pnode->fInbound)
936                         nInbound++;
937             }
938
939             if (hSocket == INVALID_SOCKET)
940             {
941                 int nErr = WSAGetLastError();
942                 if (nErr != WSAEWOULDBLOCK)
943                     LogPrintf("socket error accept failed: %d\n", nErr);
944             }
945             else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
946             {
947                 {
948                     LOCK(cs_setservAddNodeAddresses);
949                     if (!setservAddNodeAddresses.count(addr))
950                         closesocket(hSocket);
951                 }
952             }
953             else if (CNode::IsBanned(addr))
954             {
955                 LogPrintf("connection from %s dropped (banned)\n", addr.ToString().c_str());
956                 closesocket(hSocket);
957             }
958             else
959             {
960                 LogPrint("net", "accepted connection %s\n", addr.ToString().c_str());
961                 CNode* pnode = new CNode(hSocket, addr, "", true);
962                 pnode->AddRef();
963                 {
964                     LOCK(cs_vNodes);
965                     vNodes.push_back(pnode);
966                 }
967             }
968         }
969
970
971         //
972         // Service each socket
973         //
974         vector<CNode*> vNodesCopy;
975         {
976             LOCK(cs_vNodes);
977             vNodesCopy = vNodes;
978             BOOST_FOREACH(CNode* pnode, vNodesCopy)
979                 pnode->AddRef();
980         }
981         BOOST_FOREACH(CNode* pnode, vNodesCopy)
982         {
983             boost::this_thread::interruption_point();
984
985             //
986             // Receive
987             //
988             if (pnode->hSocket == INVALID_SOCKET)
989                 continue;
990             if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
991             {
992                 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
993                 if (lockRecv)
994                 {
995                     {
996                         // typical socket buffer is 8K-64K
997                         char pchBuf[0x10000];
998                         int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
999                         if (nBytes > 0)
1000                         {
1001                             if (!pnode->ReceiveMsgBytes(pchBuf, nBytes))
1002                                 pnode->CloseSocketDisconnect();
1003                             pnode->nLastRecv = GetTime();
1004                             pnode->nRecvBytes += nBytes;
1005                             pnode->RecordBytesRecv(nBytes);
1006                         }
1007                         else if (nBytes == 0)
1008                         {
1009                             // socket closed gracefully
1010                             if (!pnode->fDisconnect)
1011                                 LogPrint("net", "socket closed\n");
1012                             pnode->CloseSocketDisconnect();
1013                         }
1014                         else if (nBytes < 0)
1015                         {
1016                             // error
1017                             int nErr = WSAGetLastError();
1018                             if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1019                             {
1020                                 if (!pnode->fDisconnect)
1021                                     LogPrintf("socket recv error %d\n", nErr);
1022                                 pnode->CloseSocketDisconnect();
1023                             }
1024                         }
1025                     }
1026                 }
1027             }
1028
1029             //
1030             // Send
1031             //
1032             if (pnode->hSocket == INVALID_SOCKET)
1033                 continue;
1034             if (FD_ISSET(pnode->hSocket, &fdsetSend))
1035             {
1036                 TRY_LOCK(pnode->cs_vSend, lockSend);
1037                 if (lockSend)
1038                     SocketSendData(pnode);
1039             }
1040
1041             //
1042             // Inactivity checking
1043             //
1044             if (pnode->vSendMsg.empty())
1045                 pnode->nLastSendEmpty = GetTime();
1046             if (GetTime() - pnode->nTimeConnected > 60)
1047             {
1048                 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1049                 {
1050                     LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1051                     pnode->fDisconnect = true;
1052                 }
1053                 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1054                 {
1055                     LogPrintf("socket not sending\n");
1056                     pnode->fDisconnect = true;
1057                 }
1058                 else if (GetTime() - pnode->nLastRecv > 90*60)
1059                 {
1060                     LogPrintf("socket inactivity timeout\n");
1061                     pnode->fDisconnect = true;
1062                 }
1063             }
1064         }
1065         {
1066             LOCK(cs_vNodes);
1067             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1068                 pnode->Release();
1069         }
1070
1071         MilliSleep(10);
1072     }
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083 #ifdef USE_UPNP
1084 void ThreadMapPort()
1085 {
1086     std::string port = strprintf("%u", GetListenPort());
1087     const char * multicastif = 0;
1088     const char * minissdpdpath = 0;
1089     struct UPNPDev * devlist = 0;
1090     char lanaddr[64];
1091
1092 #ifndef UPNPDISCOVER_SUCCESS
1093     /* miniupnpc 1.5 */
1094     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1095 #else
1096     /* miniupnpc 1.6 */
1097     int error = 0;
1098     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1099 #endif
1100
1101     struct UPNPUrls urls;
1102     struct IGDdatas data;
1103     int r;
1104
1105     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1106     if (r == 1)
1107     {
1108         if (fDiscover) {
1109             char externalIPAddress[40];
1110             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1111             if(r != UPNPCOMMAND_SUCCESS)
1112                 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1113             else
1114             {
1115                 if(externalIPAddress[0])
1116                 {
1117                     LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1118                     AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
1119                 }
1120                 else
1121                     LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1122             }
1123         }
1124
1125         string strDesc = "Bitcoin " + FormatFullVersion();
1126
1127         try {
1128             while (true) {
1129 #ifndef UPNPDISCOVER_SUCCESS
1130                 /* miniupnpc 1.5 */
1131                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1132                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1133 #else
1134                 /* miniupnpc 1.6 */
1135                 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1136                                     port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1137 #endif
1138
1139                 if(r!=UPNPCOMMAND_SUCCESS)
1140                     LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1141                         port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
1142                 else
1143                     LogPrintf("UPnP Port Mapping successful.\n");;
1144
1145                 MilliSleep(20*60*1000); // Refresh every 20 minutes
1146             }
1147         }
1148         catch (boost::thread_interrupted)
1149         {
1150             r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1151             LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
1152             freeUPNPDevlist(devlist); devlist = 0;
1153             FreeUPNPUrls(&urls);
1154             throw;
1155         }
1156     } else {
1157         LogPrintf("No valid UPnP IGDs found\n");
1158         freeUPNPDevlist(devlist); devlist = 0;
1159         if (r != 0)
1160             FreeUPNPUrls(&urls);
1161     }
1162 }
1163
1164 void MapPort(bool fUseUPnP)
1165 {
1166     static boost::thread* upnp_thread = NULL;
1167
1168     if (fUseUPnP)
1169     {
1170         if (upnp_thread) {
1171             upnp_thread->interrupt();
1172             upnp_thread->join();
1173             delete upnp_thread;
1174         }
1175         upnp_thread = new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort));
1176     }
1177     else if (upnp_thread) {
1178         upnp_thread->interrupt();
1179         upnp_thread->join();
1180         delete upnp_thread;
1181         upnp_thread = NULL;
1182     }
1183 }
1184
1185 #else
1186 void MapPort(bool)
1187 {
1188     // Intentionally left blank.
1189 }
1190 #endif
1191
1192
1193
1194
1195
1196
1197 void ThreadDNSAddressSeed()
1198 {
1199     const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
1200     int found = 0;
1201
1202     LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1203
1204     BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
1205         if (HaveNameProxy()) {
1206             AddOneShot(seed.host);
1207         } else {
1208             vector<CNetAddr> vIPs;
1209             vector<CAddress> vAdd;
1210             if (LookupHost(seed.host.c_str(), vIPs))
1211             {
1212                 BOOST_FOREACH(CNetAddr& ip, vIPs)
1213                 {
1214                     int nOneDay = 24*3600;
1215                     CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()));
1216                     addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1217                     vAdd.push_back(addr);
1218                     found++;
1219                 }
1220             }
1221             addrman.Add(vAdd, CNetAddr(seed.name, true));
1222         }
1223     }
1224
1225     LogPrintf("%d addresses found from DNS seeds\n", found);
1226 }
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239 void DumpAddresses()
1240 {
1241     int64_t nStart = GetTimeMillis();
1242
1243     CAddrDB adb;
1244     adb.Write(addrman);
1245
1246     LogPrint("net", "Flushed %d addresses to peers.dat  %"PRId64"ms\n",
1247            addrman.size(), GetTimeMillis() - nStart);
1248 }
1249
1250 void static ProcessOneShot()
1251 {
1252     string strDest;
1253     {
1254         LOCK(cs_vOneShots);
1255         if (vOneShots.empty())
1256             return;
1257         strDest = vOneShots.front();
1258         vOneShots.pop_front();
1259     }
1260     CAddress addr;
1261     CSemaphoreGrant grant(*semOutbound, true);
1262     if (grant) {
1263         if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
1264             AddOneShot(strDest);
1265     }
1266 }
1267
1268 void ThreadOpenConnections()
1269 {
1270     // Connect to specific addresses
1271     if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
1272     {
1273         for (int64_t nLoop = 0;; nLoop++)
1274         {
1275             ProcessOneShot();
1276             BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
1277             {
1278                 CAddress addr;
1279                 OpenNetworkConnection(addr, NULL, strAddr.c_str());
1280                 for (int i = 0; i < 10 && i < nLoop; i++)
1281                 {
1282                     MilliSleep(500);
1283                 }
1284             }
1285             MilliSleep(500);
1286         }
1287     }
1288
1289     // Initiate network connections
1290     int64_t nStart = GetTime();
1291     while (true)
1292     {
1293         ProcessOneShot();
1294
1295         MilliSleep(500);
1296
1297         CSemaphoreGrant grant(*semOutbound);
1298         boost::this_thread::interruption_point();
1299
1300         // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1301         if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1302             static bool done = false;
1303             if (!done) {
1304                 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1305                 addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
1306                 done = true;
1307             }
1308         }
1309
1310         //
1311         // Choose an address to connect to based on most recently seen
1312         //
1313         CAddress addrConnect;
1314
1315         // Only connect out to one peer per network group (/16 for IPv4).
1316         // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1317         int nOutbound = 0;
1318         set<vector<unsigned char> > setConnected;
1319         {
1320             LOCK(cs_vNodes);
1321             BOOST_FOREACH(CNode* pnode, vNodes) {
1322                 if (!pnode->fInbound) {
1323                     setConnected.insert(pnode->addr.GetGroup());
1324                     nOutbound++;
1325                 }
1326             }
1327         }
1328
1329         int64_t nANow = GetAdjustedTime();
1330
1331         int nTries = 0;
1332         while (true)
1333         {
1334             // use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
1335             CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
1336
1337             // if we selected an invalid address, restart
1338             if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
1339                 break;
1340
1341             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1342             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1343             // already-connected network ranges, ...) before trying new addrman addresses.
1344             nTries++;
1345             if (nTries > 100)
1346                 break;
1347
1348             if (IsLimited(addr))
1349                 continue;
1350
1351             // only consider very recently tried nodes after 30 failed attempts
1352             if (nANow - addr.nLastTry < 600 && nTries < 30)
1353                 continue;
1354
1355             // do not allow non-default ports, unless after 50 invalid addresses selected already
1356             if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1357                 continue;
1358
1359             addrConnect = addr;
1360             break;
1361         }
1362
1363         if (addrConnect.IsValid())
1364             OpenNetworkConnection(addrConnect, &grant);
1365     }
1366 }
1367
1368 void ThreadOpenAddedConnections()
1369 {
1370     {
1371         LOCK(cs_vAddedNodes);
1372         vAddedNodes = mapMultiArgs["-addnode"];
1373     }
1374
1375     if (HaveNameProxy()) {
1376         while(true) {
1377             list<string> lAddresses(0);
1378             {
1379                 LOCK(cs_vAddedNodes);
1380                 BOOST_FOREACH(string& strAddNode, vAddedNodes)
1381                     lAddresses.push_back(strAddNode);
1382             }
1383             BOOST_FOREACH(string& strAddNode, lAddresses) {
1384                 CAddress addr;
1385                 CSemaphoreGrant grant(*semOutbound);
1386                 OpenNetworkConnection(addr, &grant, strAddNode.c_str());
1387                 MilliSleep(500);
1388             }
1389             MilliSleep(120000); // Retry every 2 minutes
1390         }
1391     }
1392
1393     for (unsigned int i = 0; true; i++)
1394     {
1395         list<string> lAddresses(0);
1396         {
1397             LOCK(cs_vAddedNodes);
1398             BOOST_FOREACH(string& strAddNode, vAddedNodes)
1399                 lAddresses.push_back(strAddNode);
1400         }
1401
1402         list<vector<CService> > lservAddressesToAdd(0);
1403         BOOST_FOREACH(string& strAddNode, lAddresses)
1404         {
1405             vector<CService> vservNode(0);
1406             if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
1407             {
1408                 lservAddressesToAdd.push_back(vservNode);
1409                 {
1410                     LOCK(cs_setservAddNodeAddresses);
1411                     BOOST_FOREACH(CService& serv, vservNode)
1412                         setservAddNodeAddresses.insert(serv);
1413                 }
1414             }
1415         }
1416         // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1417         // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1418         {
1419             LOCK(cs_vNodes);
1420             BOOST_FOREACH(CNode* pnode, vNodes)
1421                 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1422                     BOOST_FOREACH(CService& addrNode, *(it))
1423                         if (pnode->addr == addrNode)
1424                         {
1425                             it = lservAddressesToAdd.erase(it);
1426                             it--;
1427                             break;
1428                         }
1429         }
1430         BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1431         {
1432             CSemaphoreGrant grant(*semOutbound);
1433             OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
1434             MilliSleep(500);
1435         }
1436         MilliSleep(120000); // Retry every 2 minutes
1437     }
1438 }
1439
1440 // if successful, this moves the passed grant to the constructed node
1441 bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
1442 {
1443     //
1444     // Initiate outbound network connection
1445     //
1446     boost::this_thread::interruption_point();
1447     if (!strDest)
1448         if (IsLocal(addrConnect) ||
1449             FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
1450             FindNode(addrConnect.ToStringIPPort().c_str()))
1451             return false;
1452     if (strDest && FindNode(strDest))
1453         return false;
1454
1455     CNode* pnode = ConnectNode(addrConnect, strDest);
1456     boost::this_thread::interruption_point();
1457
1458     if (!pnode)
1459         return false;
1460     if (grantOutbound)
1461         grantOutbound->MoveTo(pnode->grantOutbound);
1462     pnode->fNetworkNode = true;
1463     if (fOneShot)
1464         pnode->fOneShot = true;
1465
1466     return true;
1467 }
1468
1469
1470 // for now, use a very simple selection metric: the node from which we received
1471 // most recently
1472 double static NodeSyncScore(const CNode *pnode) {
1473     return -pnode->nLastRecv;
1474 }
1475
1476 void static StartSync(const vector<CNode*> &vNodes) {
1477     CNode *pnodeNewSync = NULL;
1478     double dBestScore = 0;
1479
1480     int nBestHeight = g_signals.GetHeight().get_value_or(0);
1481
1482     // Iterate over all nodes
1483     BOOST_FOREACH(CNode* pnode, vNodes) {
1484         // check preconditions for allowing a sync
1485         if (!pnode->fClient && !pnode->fOneShot &&
1486             !pnode->fDisconnect && pnode->fSuccessfullyConnected &&
1487             (pnode->nStartingHeight > (nBestHeight - 144)) &&
1488             (pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
1489             // if ok, compare node's score with the best so far
1490             double dScore = NodeSyncScore(pnode);
1491             if (pnodeNewSync == NULL || dScore > dBestScore) {
1492                 pnodeNewSync = pnode;
1493                 dBestScore = dScore;
1494             }
1495         }
1496     }
1497     // if a new sync candidate was found, start sync!
1498     if (pnodeNewSync) {
1499         pnodeNewSync->fStartSync = true;
1500         pnodeSync = pnodeNewSync;
1501     }
1502 }
1503
1504 void ThreadMessageHandler()
1505 {
1506     SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1507     while (true)
1508     {
1509         bool fHaveSyncNode = false;
1510
1511         vector<CNode*> vNodesCopy;
1512         {
1513             LOCK(cs_vNodes);
1514             vNodesCopy = vNodes;
1515             BOOST_FOREACH(CNode* pnode, vNodesCopy) {
1516                 pnode->AddRef();
1517                 if (pnode == pnodeSync)
1518                     fHaveSyncNode = true;
1519             }
1520         }
1521
1522         if (!fHaveSyncNode)
1523             StartSync(vNodesCopy);
1524
1525         // Poll the connected nodes for messages
1526         CNode* pnodeTrickle = NULL;
1527         if (!vNodesCopy.empty())
1528             pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
1529
1530         bool fSleep = true;
1531
1532         BOOST_FOREACH(CNode* pnode, vNodesCopy)
1533         {
1534             if (pnode->fDisconnect)
1535                 continue;
1536
1537             // Receive messages
1538             {
1539                 TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
1540                 if (lockRecv)
1541                 {
1542                     if (!g_signals.ProcessMessages(pnode))
1543                         pnode->CloseSocketDisconnect();
1544
1545                     if (pnode->nSendSize < SendBufferSize())
1546                     {
1547                         if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
1548                         {
1549                             fSleep = false;
1550                         }
1551                     }
1552                 }
1553             }
1554             boost::this_thread::interruption_point();
1555
1556             // Send messages
1557             {
1558                 TRY_LOCK(pnode->cs_vSend, lockSend);
1559                 if (lockSend)
1560                     g_signals.SendMessages(pnode, pnode == pnodeTrickle);
1561             }
1562             boost::this_thread::interruption_point();
1563         }
1564
1565         {
1566             LOCK(cs_vNodes);
1567             BOOST_FOREACH(CNode* pnode, vNodesCopy)
1568                 pnode->Release();
1569         }
1570
1571         if (fSleep)
1572             MilliSleep(100);
1573     }
1574 }
1575
1576
1577
1578
1579
1580
1581 bool BindListenPort(const CService &addrBind, string& strError)
1582 {
1583     strError = "";
1584     int nOne = 1;
1585
1586     // Create socket for listening for incoming connections
1587 #ifdef USE_IPV6
1588     struct sockaddr_storage sockaddr;
1589 #else
1590     struct sockaddr sockaddr;
1591 #endif
1592     socklen_t len = sizeof(sockaddr);
1593     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
1594     {
1595         strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
1596         LogPrintf("%s\n", strError.c_str());
1597         return false;
1598     }
1599
1600     SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1601     if (hListenSocket == INVALID_SOCKET)
1602     {
1603         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1604         LogPrintf("%s\n", strError.c_str());
1605         return false;
1606     }
1607
1608 #ifdef SO_NOSIGPIPE
1609     // Different way of disabling SIGPIPE on BSD
1610     setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1611 #endif
1612
1613 #ifndef WIN32
1614     // Allow binding if the port is still in TIME_WAIT state after
1615     // the program was closed and restarted.  Not an issue on windows.
1616     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1617 #endif
1618
1619
1620 #ifdef WIN32
1621     // Set to non-blocking, incoming connections will also inherit this
1622     if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1623 #else
1624     if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1625 #endif
1626     {
1627         strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1628         LogPrintf("%s\n", strError.c_str());
1629         return false;
1630     }
1631
1632 #ifdef USE_IPV6
1633     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1634     // and enable it by default or not. Try to enable it, if possible.
1635     if (addrBind.IsIPv6()) {
1636 #ifdef IPV6_V6ONLY
1637 #ifdef WIN32
1638         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
1639 #else
1640         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
1641 #endif
1642 #endif
1643 #ifdef WIN32
1644         int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
1645         int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
1646         // this call is allowed to fail
1647         setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
1648 #endif
1649     }
1650 #endif
1651
1652     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
1653     {
1654         int nErr = WSAGetLastError();
1655         if (nErr == WSAEADDRINUSE)
1656             strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
1657         else
1658             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
1659         LogPrintf("%s\n", strError.c_str());
1660         return false;
1661     }
1662     LogPrintf("Bound to %s\n", addrBind.ToString().c_str());
1663
1664     // Listen for incoming connections
1665     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1666     {
1667         strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1668         LogPrintf("%s\n", strError.c_str());
1669         return false;
1670     }
1671
1672     vhListenSocket.push_back(hListenSocket);
1673
1674     if (addrBind.IsRoutable() && fDiscover)
1675         AddLocal(addrBind, LOCAL_BIND);
1676
1677     return true;
1678 }
1679
1680 void static Discover(boost::thread_group& threadGroup)
1681 {
1682     if (!fDiscover)
1683         return;
1684
1685 #ifdef WIN32
1686     // Get local host IP
1687     char pszHostName[1000] = "";
1688     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1689     {
1690         vector<CNetAddr> vaddr;
1691         if (LookupHost(pszHostName, vaddr))
1692         {
1693             BOOST_FOREACH (const CNetAddr &addr, vaddr)
1694             {
1695                 AddLocal(addr, LOCAL_IF);
1696             }
1697         }
1698     }
1699 #else
1700     // Get local host ip
1701     struct ifaddrs* myaddrs;
1702     if (getifaddrs(&myaddrs) == 0)
1703     {
1704         for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1705         {
1706             if (ifa->ifa_addr == NULL) continue;
1707             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1708             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1709             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1710             if (ifa->ifa_addr->sa_family == AF_INET)
1711             {
1712                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1713                 CNetAddr addr(s4->sin_addr);
1714                 if (AddLocal(addr, LOCAL_IF))
1715                     LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1716             }
1717 #ifdef USE_IPV6
1718             else if (ifa->ifa_addr->sa_family == AF_INET6)
1719             {
1720                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1721                 CNetAddr addr(s6->sin6_addr);
1722                 if (AddLocal(addr, LOCAL_IF))
1723                     LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
1724             }
1725 #endif
1726         }
1727         freeifaddrs(myaddrs);
1728     }
1729 #endif
1730
1731     // Don't use external IPv4 discovery, when -onlynet="IPv6"
1732     if (!IsLimited(NET_IPV4))
1733         threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "ext-ip", &ThreadGetMyExternalIP));
1734 }
1735
1736 void StartNode(boost::thread_group& threadGroup)
1737 {
1738     if (semOutbound == NULL) {
1739         // initialize semaphore
1740         int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
1741         semOutbound = new CSemaphore(nMaxOutbound);
1742     }
1743
1744     if (pnodeLocalHost == NULL)
1745         pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
1746
1747     Discover(threadGroup);
1748
1749     //
1750     // Start threads
1751     //
1752
1753     if (!GetBoolArg("-dnsseed", true))
1754         LogPrintf("DNS seeding disabled\n");
1755     else
1756         threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
1757
1758 #ifdef USE_UPNP
1759     // Map ports with UPnP
1760     MapPort(GetBoolArg("-upnp", USE_UPNP));
1761 #endif
1762
1763     // Send and receive from sockets, accept connections
1764     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "net", &ThreadSocketHandler));
1765
1766     // Initiate outbound connections from -addnode
1767     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "addcon", &ThreadOpenAddedConnections));
1768
1769     // Initiate outbound connections
1770     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "opencon", &ThreadOpenConnections));
1771
1772     // Process messages
1773     threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "msghand", &ThreadMessageHandler));
1774
1775     // Dump network addresses
1776     threadGroup.create_thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, DUMP_ADDRESSES_INTERVAL * 1000));
1777 }
1778
1779 bool StopNode()
1780 {
1781     LogPrintf("StopNode()\n");
1782     MapPort(false);
1783     if (semOutbound)
1784         for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
1785             semOutbound->post();
1786     MilliSleep(50);
1787     DumpAddresses();
1788
1789     return true;
1790 }
1791
1792 class CNetCleanup
1793 {
1794 public:
1795     CNetCleanup()
1796     {
1797     }
1798     ~CNetCleanup()
1799     {
1800         // Close sockets
1801         BOOST_FOREACH(CNode* pnode, vNodes)
1802             if (pnode->hSocket != INVALID_SOCKET)
1803                 closesocket(pnode->hSocket);
1804         BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
1805             if (hListenSocket != INVALID_SOCKET)
1806                 if (closesocket(hListenSocket) == SOCKET_ERROR)
1807                     LogPrintf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1808
1809         // clean up some globals (to help leak detection)
1810         BOOST_FOREACH(CNode *pnode, vNodes)
1811             delete pnode;
1812         BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
1813             delete pnode;
1814         vNodes.clear();
1815         vNodesDisconnected.clear();
1816         delete semOutbound;
1817         semOutbound = NULL;
1818         delete pnodeLocalHost;
1819         pnodeLocalHost = NULL;
1820
1821 #ifdef WIN32
1822         // Shutdown Windows Sockets
1823         WSACleanup();
1824 #endif
1825     }
1826 }
1827 instance_of_cnetcleanup;
1828
1829
1830
1831
1832
1833
1834
1835 void RelayTransaction(const CTransaction& tx, const uint256& hash)
1836 {
1837     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1838     ss.reserve(10000);
1839     ss << tx;
1840     RelayTransaction(tx, hash, ss);
1841 }
1842
1843 void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss)
1844 {
1845     CInv inv(MSG_TX, hash);
1846     {
1847         LOCK(cs_mapRelay);
1848         // Expire old relay messages
1849         while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
1850         {
1851             mapRelay.erase(vRelayExpiration.front().second);
1852             vRelayExpiration.pop_front();
1853         }
1854
1855         // Save original serialized message so newer versions are preserved
1856         mapRelay.insert(std::make_pair(inv, ss));
1857         vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
1858     }
1859     LOCK(cs_vNodes);
1860     BOOST_FOREACH(CNode* pnode, vNodes)
1861     {
1862         if(!pnode->fRelayTxes)
1863             continue;
1864         LOCK(pnode->cs_filter);
1865         if (pnode->pfilter)
1866         {
1867             if (pnode->pfilter->IsRelevantAndUpdate(tx, hash))
1868                 pnode->PushInventory(inv);
1869         } else
1870             pnode->PushInventory(inv);
1871     }
1872 }
1873
1874 void CNode::RecordBytesRecv(uint64_t bytes)
1875 {
1876     LOCK(cs_totalBytesRecv);
1877     nTotalBytesRecv += bytes;
1878 }
1879
1880 void CNode::RecordBytesSent(uint64_t bytes)
1881 {
1882     LOCK(cs_totalBytesSent);
1883     nTotalBytesSent += bytes;
1884 }
1885
1886 uint64_t CNode::GetTotalBytesRecv()
1887 {
1888     LOCK(cs_totalBytesRecv);
1889     return nTotalBytesRecv;
1890 }
1891
1892 uint64_t CNode::GetTotalBytesSent()
1893 {
1894     LOCK(cs_totalBytesSent);
1895     return nTotalBytesSent;
1896 }
1897
1898 void CNode::Fuzz(int nChance)
1899 {
1900     if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
1901     if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
1902
1903     switch (GetRand(3))
1904     {
1905     case 0:
1906         // xor a random byte with a random value:
1907         if (!ssSend.empty()) {
1908             CDataStream::size_type pos = GetRand(ssSend.size());
1909             ssSend[pos] ^= (unsigned char)(GetRand(256));
1910         }
1911         break;
1912     case 1:
1913         // delete a random byte:
1914         if (!ssSend.empty()) {
1915             CDataStream::size_type pos = GetRand(ssSend.size());
1916             ssSend.erase(ssSend.begin()+pos);
1917         }
1918         break;
1919     case 2:
1920         // insert a random byte at a random position
1921         {
1922             CDataStream::size_type pos = GetRand(ssSend.size());
1923             char ch = (char)GetRand(256);
1924             ssSend.insert(ssSend.begin()+pos, ch);
1925         }
1926         break;
1927     }
1928     // Chance of more than one change half the time:
1929     // (more changes exponentially less likely):
1930     Fuzz(2);
1931 }
1932
1933 //
1934 // CAddrDB
1935 //
1936
1937 CAddrDB::CAddrDB()
1938 {
1939     pathAddr = GetDataDir() / "peers.dat";
1940 }
1941
1942 bool CAddrDB::Write(const CAddrMan& addr)
1943 {
1944     // Generate random temporary filename
1945     unsigned short randv = 0;
1946     RAND_bytes((unsigned char *)&randv, sizeof(randv));
1947     std::string tmpfn = strprintf("peers.dat.%04x", randv);
1948
1949     // serialize addresses, checksum data up to that point, then append csum
1950     CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
1951     ssPeers << FLATDATA(Params().MessageStart());
1952     ssPeers << addr;
1953     uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
1954     ssPeers << hash;
1955
1956     // open temp output file, and associate with CAutoFile
1957     boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
1958     FILE *file = fopen(pathTmp.string().c_str(), "wb");
1959     CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
1960     if (!fileout)
1961         return error("CAddrman::Write() : open failed");
1962
1963     // Write and commit header, data
1964     try {
1965         fileout << ssPeers;
1966     }
1967     catch (std::exception &e) {
1968         return error("CAddrman::Write() : I/O error");
1969     }
1970     FileCommit(fileout);
1971     fileout.fclose();
1972
1973     // replace existing peers.dat, if any, with new peers.dat.XXXX
1974     if (!RenameOver(pathTmp, pathAddr))
1975         return error("CAddrman::Write() : Rename-into-place failed");
1976
1977     return true;
1978 }
1979
1980 bool CAddrDB::Read(CAddrMan& addr)
1981 {
1982     // open input file, and associate with CAutoFile
1983     FILE *file = fopen(pathAddr.string().c_str(), "rb");
1984     CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
1985     if (!filein)
1986         return error("CAddrman::Read() : open failed");
1987
1988     // use file size to size memory buffer
1989     int fileSize = GetFilesize(filein);
1990     int dataSize = fileSize - sizeof(uint256);
1991     //Don't try to resize to a negative number if file is small
1992     if ( dataSize < 0 ) dataSize = 0;
1993     vector<unsigned char> vchData;
1994     vchData.resize(dataSize);
1995     uint256 hashIn;
1996
1997     // read data and checksum from file
1998     try {
1999         filein.read((char *)&vchData[0], dataSize);
2000         filein >> hashIn;
2001     }
2002     catch (std::exception &e) {
2003         return error("CAddrman::Read() 2 : I/O error or stream data corrupted");
2004     }
2005     filein.fclose();
2006
2007     CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
2008
2009     // verify stored checksum matches input data
2010     uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
2011     if (hashIn != hashTmp)
2012         return error("CAddrman::Read() : checksum mismatch; data corrupted");
2013
2014     unsigned char pchMsgTmp[4];
2015     try {
2016         // de-serialize file header (network specific magic number) and ..
2017         ssPeers >> FLATDATA(pchMsgTmp);
2018
2019         // ... verify the network matches ours
2020         if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
2021             return error("CAddrman::Read() : invalid network magic number");
2022
2023         // de-serialize address data into one CAddrMan object
2024         ssPeers >> addr;
2025     }
2026     catch (std::exception &e) {
2027         return error("CAddrman::Read() : I/O error or stream data corrupted");
2028     }
2029
2030     return true;
2031 }
This page took 0.13491 seconds and 4 git commands to generate.