1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 The Bitcoin Core developers
3 // Distributed under the MIT 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 <config/bitcoin-config.h>
8 #endif
9 
10 #include <net.h>
11 
12 #include <banman.h>
13 #include <chainparams.h>
14 #include <clientversion.h>
15 #include <consensus/consensus.h>
16 #include <crypto/common.h>
17 #include <crypto/sha256.h>
18 #include <primitives/transaction.h>
19 #include <netbase.h>
20 #include <scheduler.h>
21 #include <ui_interface.h>
22 #include <util/strencodings.h>
23 
24 #ifdef WIN32
25 #include <string.h>
26 #else
27 #include <fcntl.h>
28 #endif
29 
30 #ifdef USE_POLL
31 #include <poll.h>
32 #endif
33 
34 #ifdef USE_UPNP
35 #include <miniupnpc/miniupnpc.h>
36 #include <miniupnpc/miniwget.h>
37 #include <miniupnpc/upnpcommands.h>
38 #include <miniupnpc/upnperrors.h>
39 #endif
40 
41 #include <unordered_map>
42 
43 #include <math.h>
44 
45 // Dump addresses to peers.dat every 15 minutes (900s)
46 static constexpr int DUMP_PEERS_INTERVAL = 15 * 60;
47 
48 // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
49 #define FEELER_SLEEP_WINDOW 1
50 
51 // MSG_NOSIGNAL is not available on some platforms, if it doesn't exist define it as 0
52 #if !defined(MSG_NOSIGNAL)
53 #define MSG_NOSIGNAL 0
54 #endif
55 
56 // MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0
57 #if !defined(MSG_DONTWAIT)
58 #define MSG_DONTWAIT 0
59 #endif
60 
61 /** Used to pass flags to the Bind() function */
62 enum BindFlags {
63     BF_NONE         = 0,
64     BF_EXPLICIT     = (1U << 0),
65     BF_REPORT_ERROR = (1U << 1),
66     BF_WHITELIST    = (1U << 2),
67 };
68 
69 // The set of sockets cannot be modified while waiting
70 // The sleep time needs to be small to avoid new sockets stalling
71 static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
72 
73 const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
74 
75 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
76 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
77 //
78 // Global state variables
79 //
80 bool fDiscover = true;
81 bool fListen = true;
82 bool g_relay_txes = !DEFAULT_BLOCKSONLY;
83 CCriticalSection cs_mapLocalHost;
84 std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
85 static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
86 std::string strSubVersion;
87 
88 limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
89 
AddOneShot(const std::string & strDest)90 void CConnman::AddOneShot(const std::string& strDest)
91 {
92     LOCK(cs_vOneShots);
93     vOneShots.push_back(strDest);
94 }
95 
GetListenPort()96 unsigned short GetListenPort()
97 {
98     return (unsigned short)(gArgs.GetArg("-port", Params().GetDefaultPort()));
99 }
100 
101 // find 'best' local address for a particular peer
GetLocal(CService & addr,const CNetAddr * paddrPeer)102 bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
103 {
104     if (!fListen)
105         return false;
106 
107     int nBestScore = -1;
108     int nBestReachability = -1;
109     {
110         LOCK(cs_mapLocalHost);
111         for (const auto& entry : mapLocalHost)
112         {
113             int nScore = entry.second.nScore;
114             int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
115             if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
116             {
117                 addr = CService(entry.first, entry.second.nPort);
118                 nBestReachability = nReachability;
119                 nBestScore = nScore;
120             }
121         }
122     }
123     return nBestScore >= 0;
124 }
125 
126 //! Convert the pnSeed6 array into usable address objects.
convertSeed6(const std::vector<SeedSpec6> & vSeedsIn)127 static std::vector<CAddress> convertSeed6(const std::vector<SeedSpec6> &vSeedsIn)
128 {
129     // It'll only connect to one or two seed nodes because once it connects,
130     // it'll get a pile of addresses with newer timestamps.
131     // Seed nodes are given a random 'last seen time' of between one and two
132     // weeks ago.
133     const int64_t nOneWeek = 7*24*60*60;
134     std::vector<CAddress> vSeedsOut;
135     vSeedsOut.reserve(vSeedsIn.size());
136     FastRandomContext rng;
137     for (const auto& seed_in : vSeedsIn) {
138         struct in6_addr ip;
139         memcpy(&ip, seed_in.addr, sizeof(ip));
140         CAddress addr(CService(ip, seed_in.port), GetDesirableServiceFlags(NODE_NONE));
141         addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
142         vSeedsOut.push_back(addr);
143     }
144     return vSeedsOut;
145 }
146 
147 // get best local address for a particular peer as a CAddress
148 // Otherwise, return the unroutable 0.0.0.0 but filled in with
149 // the normal parameters, since the IP may be changed to a useful
150 // one by discovery.
GetLocalAddress(const CNetAddr * paddrPeer,ServiceFlags nLocalServices)151 CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
152 {
153     CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices);
154     CService addr;
155     if (GetLocal(addr, paddrPeer))
156     {
157         ret = CAddress(addr, nLocalServices);
158     }
159     ret.nTime = GetAdjustedTime();
160     return ret;
161 }
162 
GetnScore(const CService & addr)163 static int GetnScore(const CService& addr)
164 {
165     LOCK(cs_mapLocalHost);
166     if (mapLocalHost.count(addr) == 0) return 0;
167     return mapLocalHost[addr].nScore;
168 }
169 
170 // Is our peer's addrLocal potentially useful as an external IP source?
IsPeerAddrLocalGood(CNode * pnode)171 bool IsPeerAddrLocalGood(CNode *pnode)
172 {
173     CService addrLocal = pnode->GetAddrLocal();
174     return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
175            IsReachable(addrLocal.GetNetwork());
176 }
177 
178 // pushes our own address to a peer
AdvertiseLocal(CNode * pnode)179 void AdvertiseLocal(CNode *pnode)
180 {
181     if (fListen && pnode->fSuccessfullyConnected)
182     {
183         CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
184         if (gArgs.GetBoolArg("-addrmantest", false)) {
185             // use IPv4 loopback during addrmantest
186             addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
187         }
188         // If discovery is enabled, sometimes give our peer the address it
189         // tells us that it sees us as in case it has a better idea of our
190         // address than we do.
191         FastRandomContext rng;
192         if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
193              rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0))
194         {
195             addrLocal.SetIP(pnode->GetAddrLocal());
196         }
197         if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
198         {
199             LogPrint(BCLog::NET, "AdvertiseLocal: advertising address %s\n", addrLocal.ToString());
200             pnode->PushAddress(addrLocal, rng);
201         }
202     }
203 }
204 
205 // learn a new local address
AddLocal(const CService & addr,int nScore)206 bool AddLocal(const CService& addr, int nScore)
207 {
208     if (!addr.IsRoutable())
209         return false;
210 
211     if (!fDiscover && nScore < LOCAL_MANUAL)
212         return false;
213 
214     if (!IsReachable(addr))
215         return false;
216 
217     LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
218 
219     {
220         LOCK(cs_mapLocalHost);
221         bool fAlready = mapLocalHost.count(addr) > 0;
222         LocalServiceInfo &info = mapLocalHost[addr];
223         if (!fAlready || nScore >= info.nScore) {
224             info.nScore = nScore + (fAlready ? 1 : 0);
225             info.nPort = addr.GetPort();
226         }
227     }
228 
229     return true;
230 }
231 
AddLocal(const CNetAddr & addr,int nScore)232 bool AddLocal(const CNetAddr &addr, int nScore)
233 {
234     return AddLocal(CService(addr, GetListenPort()), nScore);
235 }
236 
RemoveLocal(const CService & addr)237 void RemoveLocal(const CService& addr)
238 {
239     LOCK(cs_mapLocalHost);
240     LogPrintf("RemoveLocal(%s)\n", addr.ToString());
241     mapLocalHost.erase(addr);
242 }
243 
SetReachable(enum Network net,bool reachable)244 void SetReachable(enum Network net, bool reachable)
245 {
246     if (net == NET_UNROUTABLE || net == NET_INTERNAL)
247         return;
248     LOCK(cs_mapLocalHost);
249     vfLimited[net] = !reachable;
250 }
251 
IsReachable(enum Network net)252 bool IsReachable(enum Network net)
253 {
254     LOCK(cs_mapLocalHost);
255     return !vfLimited[net];
256 }
257 
IsReachable(const CNetAddr & addr)258 bool IsReachable(const CNetAddr &addr)
259 {
260     return IsReachable(addr.GetNetwork());
261 }
262 
263 /** vote for a local address */
SeenLocal(const CService & addr)264 bool SeenLocal(const CService& addr)
265 {
266     {
267         LOCK(cs_mapLocalHost);
268         if (mapLocalHost.count(addr) == 0)
269             return false;
270         mapLocalHost[addr].nScore++;
271     }
272     return true;
273 }
274 
275 
276 /** check whether a given address is potentially local */
IsLocal(const CService & addr)277 bool IsLocal(const CService& addr)
278 {
279     LOCK(cs_mapLocalHost);
280     return mapLocalHost.count(addr) > 0;
281 }
282 
FindNode(const CNetAddr & ip)283 CNode* CConnman::FindNode(const CNetAddr& ip)
284 {
285     LOCK(cs_vNodes);
286     for (CNode* pnode : vNodes) {
287       if (static_cast<CNetAddr>(pnode->addr) == ip) {
288             return pnode;
289         }
290     }
291     return nullptr;
292 }
293 
FindNode(const CSubNet & subNet)294 CNode* CConnman::FindNode(const CSubNet& subNet)
295 {
296     LOCK(cs_vNodes);
297     for (CNode* pnode : vNodes) {
298         if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
299             return pnode;
300         }
301     }
302     return nullptr;
303 }
304 
FindNode(const std::string & addrName)305 CNode* CConnman::FindNode(const std::string& addrName)
306 {
307     LOCK(cs_vNodes);
308     for (CNode* pnode : vNodes) {
309         if (pnode->GetAddrName() == addrName) {
310             return pnode;
311         }
312     }
313     return nullptr;
314 }
315 
FindNode(const CService & addr)316 CNode* CConnman::FindNode(const CService& addr)
317 {
318     LOCK(cs_vNodes);
319     for (CNode* pnode : vNodes) {
320         if (static_cast<CService>(pnode->addr) == addr) {
321             return pnode;
322         }
323     }
324     return nullptr;
325 }
326 
CheckIncomingNonce(uint64_t nonce)327 bool CConnman::CheckIncomingNonce(uint64_t nonce)
328 {
329     LOCK(cs_vNodes);
330     for (const CNode* pnode : vNodes) {
331         if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
332             return false;
333     }
334     return true;
335 }
336 
337 /** Get the bind address for a socket as CAddress */
GetBindAddress(SOCKET sock)338 static CAddress GetBindAddress(SOCKET sock)
339 {
340     CAddress addr_bind;
341     struct sockaddr_storage sockaddr_bind;
342     socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
343     if (sock != INVALID_SOCKET) {
344         if (!getsockname(sock, (struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
345             addr_bind.SetSockAddr((const struct sockaddr*)&sockaddr_bind);
346         } else {
347             LogPrint(BCLog::NET, "Warning: getsockname failed\n");
348         }
349     }
350     return addr_bind;
351 }
352 
ConnectNode(CAddress addrConnect,const char * pszDest,bool fCountFailure,bool manual_connection)353 CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection)
354 {
355     if (pszDest == nullptr) {
356         if (IsLocal(addrConnect))
357             return nullptr;
358 
359         // Look for an existing connection
360         CNode* pnode = FindNode(static_cast<CService>(addrConnect));
361         if (pnode)
362         {
363             LogPrintf("Failed to open new connection, already connected\n");
364             return nullptr;
365         }
366     }
367 
368     /// debug print
369     LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
370         pszDest ? pszDest : addrConnect.ToString(),
371         pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
372 
373     // Resolve
374     const int default_port = Params().GetDefaultPort();
375     if (pszDest) {
376         std::vector<CService> resolved;
377         if (Lookup(pszDest, resolved,  default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
378             addrConnect = CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
379             if (!addrConnect.IsValid()) {
380                 LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
381                 return nullptr;
382             }
383             // It is possible that we already have a connection to the IP/port pszDest resolved to.
384             // In that case, drop the connection that was just created, and return the existing CNode instead.
385             // Also store the name we used to connect in that CNode, so that future FindNode() calls to that
386             // name catch this early.
387             LOCK(cs_vNodes);
388             CNode* pnode = FindNode(static_cast<CService>(addrConnect));
389             if (pnode)
390             {
391                 pnode->MaybeSetAddrName(std::string(pszDest));
392                 LogPrintf("Failed to open new connection, already connected\n");
393                 return nullptr;
394             }
395         }
396     }
397 
398     // Connect
399     bool connected = false;
400     SOCKET hSocket = INVALID_SOCKET;
401     proxyType proxy;
402     if (addrConnect.IsValid()) {
403         bool proxyConnectionFailed = false;
404 
405         if (GetProxy(addrConnect.GetNetwork(), proxy)) {
406             hSocket = CreateSocket(proxy.proxy);
407             if (hSocket == INVALID_SOCKET) {
408                 return nullptr;
409             }
410             connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), hSocket, nConnectTimeout, &proxyConnectionFailed);
411         } else {
412             // no proxy needed (none set for target network)
413             hSocket = CreateSocket(addrConnect);
414             if (hSocket == INVALID_SOCKET) {
415                 return nullptr;
416             }
417             connected = ConnectSocketDirectly(addrConnect, hSocket, nConnectTimeout, manual_connection);
418         }
419         if (!proxyConnectionFailed) {
420             // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
421             // the proxy, mark this as an attempt.
422             addrman.Attempt(addrConnect, fCountFailure);
423         }
424     } else if (pszDest && GetNameProxy(proxy)) {
425         hSocket = CreateSocket(proxy.proxy);
426         if (hSocket == INVALID_SOCKET) {
427             return nullptr;
428         }
429         std::string host;
430         int port = default_port;
431         SplitHostPort(std::string(pszDest), port, host);
432         connected = ConnectThroughProxy(proxy, host, port, hSocket, nConnectTimeout, nullptr);
433     }
434     if (!connected) {
435         CloseSocket(hSocket);
436         return nullptr;
437     }
438 
439     // Add node
440     NodeId id = GetNewNodeId();
441     uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
442     CAddress addr_bind = GetBindAddress(hSocket);
443     CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", false);
444     pnode->AddRef();
445 
446     return pnode;
447 }
448 
CloseSocketDisconnect()449 void CNode::CloseSocketDisconnect()
450 {
451     fDisconnect = true;
452     LOCK(cs_hSocket);
453     if (hSocket != INVALID_SOCKET)
454     {
455         LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
456         CloseSocket(hSocket);
457     }
458 }
459 
IsWhitelistedRange(const CNetAddr & addr)460 bool CConnman::IsWhitelistedRange(const CNetAddr &addr) {
461     for (const CSubNet& subnet : vWhitelistedRange) {
462         if (subnet.Match(addr))
463             return true;
464     }
465     return false;
466 }
467 
GetAddrName() const468 std::string CNode::GetAddrName() const {
469     LOCK(cs_addrName);
470     return addrName;
471 }
472 
MaybeSetAddrName(const std::string & addrNameIn)473 void CNode::MaybeSetAddrName(const std::string& addrNameIn) {
474     LOCK(cs_addrName);
475     if (addrName.empty()) {
476         addrName = addrNameIn;
477     }
478 }
479 
GetAddrLocal() const480 CService CNode::GetAddrLocal() const {
481     LOCK(cs_addrLocal);
482     return addrLocal;
483 }
484 
SetAddrLocal(const CService & addrLocalIn)485 void CNode::SetAddrLocal(const CService& addrLocalIn) {
486     LOCK(cs_addrLocal);
487     if (addrLocal.IsValid()) {
488         error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
489     } else {
490         addrLocal = addrLocalIn;
491     }
492 }
493 
494 #undef X
495 #define X(name) stats.name = name
copyStats(CNodeStats & stats)496 void CNode::copyStats(CNodeStats &stats)
497 {
498     stats.nodeid = this->GetId();
499     X(nServices);
500     X(addr);
501     X(addrBind);
502     {
503         LOCK(cs_filter);
504         X(fRelayTxes);
505     }
506     X(nLastSend);
507     X(nLastRecv);
508     X(nTimeConnected);
509     X(nTimeOffset);
510     stats.addrName = GetAddrName();
511     X(nVersion);
512     {
513         LOCK(cs_SubVer);
514         X(cleanSubVer);
515     }
516     X(fInbound);
517     X(m_manual_connection);
518     X(nStartingHeight);
519     {
520         LOCK(cs_vSend);
521         X(mapSendBytesPerMsgCmd);
522         X(nSendBytes);
523     }
524     {
525         LOCK(cs_vRecv);
526         X(mapRecvBytesPerMsgCmd);
527         X(nRecvBytes);
528     }
529     X(fWhitelisted);
530     {
531         LOCK(cs_feeFilter);
532         X(minFeeFilter);
533     }
534 
535     // It is common for nodes with good ping times to suddenly become lagged,
536     // due to a new block arriving or other large transfer.
537     // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
538     // since pingtime does not update until the ping is complete, which might take a while.
539     // So, if a ping is taking an unusually long time in flight,
540     // the caller can immediately detect that this is happening.
541     int64_t nPingUsecWait = 0;
542     if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
543         nPingUsecWait = GetTimeMicros() - nPingUsecStart;
544     }
545 
546     // 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 :)
547     stats.dPingTime = (((double)nPingUsecTime) / 1e6);
548     stats.dMinPing  = (((double)nMinPingUsecTime) / 1e6);
549     stats.dPingWait = (((double)nPingUsecWait) / 1e6);
550 
551     // Leave string empty if addrLocal invalid (not filled in yet)
552     CService addrLocalUnlocked = GetAddrLocal();
553     stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
554 }
555 #undef X
556 
ReceiveMsgBytes(const char * pch,unsigned int nBytes,bool & complete)557 bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete)
558 {
559     complete = false;
560     int64_t nTimeMicros = GetTimeMicros();
561     LOCK(cs_vRecv);
562     nLastRecv = nTimeMicros / 1000000;
563     nRecvBytes += nBytes;
564     while (nBytes > 0) {
565 
566         // get current incomplete message, or create a new one
567         if (vRecvMsg.empty() ||
568             vRecvMsg.back().complete())
569             vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION));
570 
571         CNetMessage& msg = vRecvMsg.back();
572 
573         // absorb network data
574         int handled;
575         if (!msg.in_data)
576             handled = msg.readHeader(pch, nBytes);
577         else
578             handled = msg.readData(pch, nBytes);
579 
580         if (handled < 0)
581             return false;
582 
583         if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
584             LogPrint(BCLog::NET, "Oversized message from peer=%i, disconnecting\n", GetId());
585             return false;
586         }
587 
588         pch += handled;
589         nBytes -= handled;
590 
591         if (msg.complete()) {
592             //store received bytes per message command
593             //to prevent a memory DOS, only allow valid commands
594             mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
595             if (i == mapRecvBytesPerMsgCmd.end())
596                 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
597             assert(i != mapRecvBytesPerMsgCmd.end());
598             i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
599 
600             msg.nTime = nTimeMicros;
601             complete = true;
602         }
603     }
604 
605     return true;
606 }
607 
SetSendVersion(int nVersionIn)608 void CNode::SetSendVersion(int nVersionIn)
609 {
610     // Send version may only be changed in the version message, and
611     // only one version message is allowed per session. We can therefore
612     // treat this value as const and even atomic as long as it's only used
613     // once a version message has been successfully processed. Any attempt to
614     // set this twice is an error.
615     if (nSendVersion != 0) {
616         error("Send version already set for node: %i. Refusing to change from %i to %i", id, nSendVersion, nVersionIn);
617     } else {
618         nSendVersion = nVersionIn;
619     }
620 }
621 
GetSendVersion() const622 int CNode::GetSendVersion() const
623 {
624     // The send version should always be explicitly set to
625     // INIT_PROTO_VERSION rather than using this value until SetSendVersion
626     // has been called.
627     if (nSendVersion == 0) {
628         error("Requesting unset send version for node: %i. Using %i", id, INIT_PROTO_VERSION);
629         return INIT_PROTO_VERSION;
630     }
631     return nSendVersion;
632 }
633 
634 
readHeader(const char * pch,unsigned int nBytes)635 int CNetMessage::readHeader(const char *pch, unsigned int nBytes)
636 {
637     // copy data to temporary parsing buffer
638     unsigned int nRemaining = 24 - nHdrPos;
639     unsigned int nCopy = std::min(nRemaining, nBytes);
640 
641     memcpy(&hdrbuf[nHdrPos], pch, nCopy);
642     nHdrPos += nCopy;
643 
644     // if header incomplete, exit
645     if (nHdrPos < 24)
646         return nCopy;
647 
648     // deserialize to CMessageHeader
649     try {
650         hdrbuf >> hdr;
651     }
652     catch (const std::exception&) {
653         return -1;
654     }
655 
656     // reject messages larger than MAX_SIZE
657     if (hdr.nMessageSize > MAX_SIZE)
658         return -1;
659 
660     // switch state to reading message data
661     in_data = true;
662 
663     return nCopy;
664 }
665 
readData(const char * pch,unsigned int nBytes)666 int CNetMessage::readData(const char *pch, unsigned int nBytes)
667 {
668     unsigned int nRemaining = hdr.nMessageSize - nDataPos;
669     unsigned int nCopy = std::min(nRemaining, nBytes);
670 
671     if (vRecv.size() < nDataPos + nCopy) {
672         // Allocate up to 256 KiB ahead, but never more than the total message size.
673         vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
674     }
675 
676     hasher.Write((const unsigned char*)pch, nCopy);
677     memcpy(&vRecv[nDataPos], pch, nCopy);
678     nDataPos += nCopy;
679 
680     return nCopy;
681 }
682 
GetMessageHash() const683 const uint256& CNetMessage::GetMessageHash() const
684 {
685     assert(complete());
686     if (data_hash.IsNull())
687         hasher.Finalize(data_hash.begin());
688     return data_hash;
689 }
690 
SocketSendData(CNode * pnode) const691 size_t CConnman::SocketSendData(CNode *pnode) const EXCLUSIVE_LOCKS_REQUIRED(pnode->cs_vSend)
692 {
693     auto it = pnode->vSendMsg.begin();
694     size_t nSentSize = 0;
695 
696     while (it != pnode->vSendMsg.end()) {
697         const auto &data = *it;
698         assert(data.size() > pnode->nSendOffset);
699         int nBytes = 0;
700         {
701             LOCK(pnode->cs_hSocket);
702             if (pnode->hSocket == INVALID_SOCKET)
703                 break;
704             nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
705         }
706         if (nBytes > 0) {
707             pnode->nLastSend = GetSystemTimeInSeconds();
708             pnode->nSendBytes += nBytes;
709             pnode->nSendOffset += nBytes;
710             nSentSize += nBytes;
711             if (pnode->nSendOffset == data.size()) {
712                 pnode->nSendOffset = 0;
713                 pnode->nSendSize -= data.size();
714                 pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
715                 it++;
716             } else {
717                 // could not send full message; stop sending more
718                 break;
719             }
720         } else {
721             if (nBytes < 0) {
722                 // error
723                 int nErr = WSAGetLastError();
724                 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
725                 {
726                     LogPrintf("socket send error %s\n", NetworkErrorString(nErr));
727                     pnode->CloseSocketDisconnect();
728                 }
729             }
730             // couldn't send anything at all
731             break;
732         }
733     }
734 
735     if (it == pnode->vSendMsg.end()) {
736         assert(pnode->nSendOffset == 0);
737         assert(pnode->nSendSize == 0);
738     }
739     pnode->vSendMsg.erase(pnode->vSendMsg.begin(), it);
740     return nSentSize;
741 }
742 
743 struct NodeEvictionCandidate
744 {
745     NodeId id;
746     int64_t nTimeConnected;
747     int64_t nMinPingUsecTime;
748     int64_t nLastBlockTime;
749     int64_t nLastTXTime;
750     bool fRelevantServices;
751     bool fRelayTxes;
752     bool fBloomFilter;
753     CAddress addr;
754     uint64_t nKeyedNetGroup;
755     bool prefer_evict;
756 };
757 
ReverseCompareNodeMinPingTime(const NodeEvictionCandidate & a,const NodeEvictionCandidate & b)758 static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
759 {
760     return a.nMinPingUsecTime > b.nMinPingUsecTime;
761 }
762 
ReverseCompareNodeTimeConnected(const NodeEvictionCandidate & a,const NodeEvictionCandidate & b)763 static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
764 {
765     return a.nTimeConnected > b.nTimeConnected;
766 }
767 
CompareNetGroupKeyed(const NodeEvictionCandidate & a,const NodeEvictionCandidate & b)768 static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
769     return a.nKeyedNetGroup < b.nKeyedNetGroup;
770 }
771 
CompareNodeBlockTime(const NodeEvictionCandidate & a,const NodeEvictionCandidate & b)772 static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
773 {
774     // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
775     if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime;
776     if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
777     return a.nTimeConnected > b.nTimeConnected;
778 }
779 
CompareNodeTXTime(const NodeEvictionCandidate & a,const NodeEvictionCandidate & b)780 static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
781 {
782     // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn.
783     if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime;
784     if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes;
785     if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
786     return a.nTimeConnected > b.nTimeConnected;
787 }
788 
789 
790 //! Sort an array by the specified comparator, then erase the last K elements.
791 template<typename T, typename Comparator>
EraseLastKElements(std::vector<T> & elements,Comparator comparator,size_t k)792 static void EraseLastKElements(std::vector<T> &elements, Comparator comparator, size_t k)
793 {
794     std::sort(elements.begin(), elements.end(), comparator);
795     size_t eraseSize = std::min(k, elements.size());
796     elements.erase(elements.end() - eraseSize, elements.end());
797 }
798 
799 /** Try to find a connection to evict when the node is full.
800  *  Extreme care must be taken to avoid opening the node to attacker
801  *   triggered network partitioning.
802  *  The strategy used here is to protect a small number of peers
803  *   for each of several distinct characteristics which are difficult
804  *   to forge.  In order to partition a node the attacker must be
805  *   simultaneously better at all of them than honest peers.
806  */
AttemptToEvictConnection()807 bool CConnman::AttemptToEvictConnection()
808 {
809     std::vector<NodeEvictionCandidate> vEvictionCandidates;
810     {
811         LOCK(cs_vNodes);
812 
813         for (const CNode* node : vNodes) {
814             if (node->fWhitelisted)
815                 continue;
816             if (!node->fInbound)
817                 continue;
818             if (node->fDisconnect)
819                 continue;
820             LOCK(node->cs_filter);
821             NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
822                                                node->nLastBlockTime, node->nLastTXTime,
823                                                HasAllDesirableServiceFlags(node->nServices),
824                                                node->fRelayTxes, node->pfilter != nullptr, node->addr, node->nKeyedNetGroup,
825                                                node->m_prefer_evict};
826             vEvictionCandidates.push_back(candidate);
827         }
828     }
829 
830     // Protect connections with certain characteristics
831 
832     // Deterministically select 4 peers to protect by netgroup.
833     // An attacker cannot predict which netgroups will be protected
834     EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
835     // Protect the 8 nodes with the lowest minimum ping time.
836     // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
837     EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
838     // Protect 4 nodes that most recently sent us transactions.
839     // An attacker cannot manipulate this metric without performing useful work.
840     EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
841     // Protect 4 nodes that most recently sent us blocks.
842     // An attacker cannot manipulate this metric without performing useful work.
843     EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
844     // Protect the half of the remaining nodes which have been connected the longest.
845     // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
846     EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, vEvictionCandidates.size() / 2);
847 
848     if (vEvictionCandidates.empty()) return false;
849 
850     // If any remaining peers are preferred for eviction consider only them.
851     // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
852     //  then we probably don't want to evict it no matter what.
853     if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
854         vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
855                                   [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
856     }
857 
858     // Identify the network group with the most connections and youngest member.
859     // (vEvictionCandidates is already sorted by reverse connect time)
860     uint64_t naMostConnections;
861     unsigned int nMostConnections = 0;
862     int64_t nMostConnectionsTime = 0;
863     std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
864     for (const NodeEvictionCandidate &node : vEvictionCandidates) {
865         std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
866         group.push_back(node);
867         int64_t grouptime = group[0].nTimeConnected;
868 
869         if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
870             nMostConnections = group.size();
871             nMostConnectionsTime = grouptime;
872             naMostConnections = node.nKeyedNetGroup;
873         }
874     }
875 
876     // Reduce to the network group with the most connections
877     vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
878 
879     // Disconnect from the network group with the most connections
880     NodeId evicted = vEvictionCandidates.front().id;
881     LOCK(cs_vNodes);
882     for (CNode* pnode : vNodes) {
883         if (pnode->GetId() == evicted) {
884             pnode->fDisconnect = true;
885             return true;
886         }
887     }
888     return false;
889 }
890 
AcceptConnection(const ListenSocket & hListenSocket)891 void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
892     struct sockaddr_storage sockaddr;
893     socklen_t len = sizeof(sockaddr);
894     SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
895     CAddress addr;
896     int nInbound = 0;
897     int nMaxInbound = nMaxConnections - (nMaxOutbound + nMaxFeeler);
898 
899     if (hSocket != INVALID_SOCKET) {
900         if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
901             LogPrintf("Warning: Unknown socket family\n");
902         }
903     }
904 
905     bool whitelisted = hListenSocket.whitelisted || IsWhitelistedRange(addr);
906     {
907         LOCK(cs_vNodes);
908         for (const CNode* pnode : vNodes) {
909             if (pnode->fInbound) nInbound++;
910         }
911     }
912 
913     if (hSocket == INVALID_SOCKET)
914     {
915         int nErr = WSAGetLastError();
916         if (nErr != WSAEWOULDBLOCK)
917             LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
918         return;
919     }
920 
921     if (!fNetworkActive) {
922         LogPrintf("connection from %s dropped: not accepting new connections\n", addr.ToString());
923         CloseSocket(hSocket);
924         return;
925     }
926 
927     if (!IsSelectableSocket(hSocket))
928     {
929         LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
930         CloseSocket(hSocket);
931         return;
932     }
933 
934     // According to the internet TCP_NODELAY is not carried into accepted sockets
935     // on all platforms.  Set it again here just to be sure.
936     SetSocketNoDelay(hSocket);
937 
938     int bannedlevel = m_banman ? m_banman->IsBannedLevel(addr) : 0;
939 
940     // Don't accept connections from banned peers, but if our inbound slots aren't almost full, accept
941     // if the only banning reason was an automatic misbehavior ban.
942     if (!whitelisted && bannedlevel > ((nInbound + 1 < nMaxInbound) ? 1 : 0))
943     {
944         LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
945         CloseSocket(hSocket);
946         return;
947     }
948 
949     if (nInbound >= nMaxInbound)
950     {
951         if (!AttemptToEvictConnection()) {
952             // No connection to evict, disconnect the new connection
953             LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
954             CloseSocket(hSocket);
955             return;
956         }
957     }
958 
959     NodeId id = GetNewNodeId();
960     uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
961     CAddress addr_bind = GetBindAddress(hSocket);
962 
963     CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", true);
964     pnode->AddRef();
965     pnode->fWhitelisted = whitelisted;
966     pnode->m_prefer_evict = bannedlevel > 0;
967     m_msgproc->InitializeNode(pnode);
968 
969     LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
970 
971     {
972         LOCK(cs_vNodes);
973         vNodes.push_back(pnode);
974     }
975 }
976 
DisconnectNodes()977 void CConnman::DisconnectNodes()
978 {
979     {
980         LOCK(cs_vNodes);
981 
982         if (!fNetworkActive) {
983             // Disconnect any connected nodes
984             for (CNode* pnode : vNodes) {
985                 if (!pnode->fDisconnect) {
986                     LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
987                     pnode->fDisconnect = true;
988                 }
989             }
990         }
991 
992         // Disconnect unused nodes
993         std::vector<CNode*> vNodesCopy = vNodes;
994         for (CNode* pnode : vNodesCopy)
995         {
996             if (pnode->fDisconnect)
997             {
998                 // remove from vNodes
999                 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1000 
1001                 // release outbound grant (if any)
1002                 pnode->grantOutbound.Release();
1003 
1004                 // close socket and cleanup
1005                 pnode->CloseSocketDisconnect();
1006 
1007                 // hold in disconnected pool until all refs are released
1008                 pnode->Release();
1009                 vNodesDisconnected.push_back(pnode);
1010             }
1011         }
1012     }
1013     {
1014         // Delete disconnected nodes
1015         std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1016         for (CNode* pnode : vNodesDisconnectedCopy)
1017         {
1018             // wait until threads are done using it
1019             if (pnode->GetRefCount() <= 0) {
1020                 bool fDelete = false;
1021                 {
1022                     TRY_LOCK(pnode->cs_inventory, lockInv);
1023                     if (lockInv) {
1024                         TRY_LOCK(pnode->cs_vSend, lockSend);
1025                         if (lockSend) {
1026                             fDelete = true;
1027                         }
1028                     }
1029                 }
1030                 if (fDelete) {
1031                     vNodesDisconnected.remove(pnode);
1032                     DeleteNode(pnode);
1033                 }
1034             }
1035         }
1036     }
1037 }
1038 
NotifyNumConnectionsChanged()1039 void CConnman::NotifyNumConnectionsChanged()
1040 {
1041     size_t vNodesSize;
1042     {
1043         LOCK(cs_vNodes);
1044         vNodesSize = vNodes.size();
1045     }
1046     if(vNodesSize != nPrevNodeCount) {
1047         nPrevNodeCount = vNodesSize;
1048         if(clientInterface)
1049             clientInterface->NotifyNumConnectionsChanged(vNodesSize);
1050     }
1051 }
1052 
InactivityCheck(CNode * pnode)1053 void CConnman::InactivityCheck(CNode *pnode)
1054 {
1055     int64_t nTime = GetSystemTimeInSeconds();
1056     if (nTime - pnode->nTimeConnected > m_peer_connect_timeout)
1057     {
1058         if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1059         {
1060             LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d from %d\n", m_peer_connect_timeout, pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
1061             pnode->fDisconnect = true;
1062         }
1063         else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1064         {
1065             LogPrintf("socket sending timeout: %is\n", nTime - pnode->nLastSend);
1066             pnode->fDisconnect = true;
1067         }
1068         else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1069         {
1070             LogPrintf("socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1071             pnode->fDisconnect = true;
1072         }
1073         else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 < GetTimeMicros())
1074         {
1075             LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode->nPingUsecStart));
1076             pnode->fDisconnect = true;
1077         }
1078         else if (!pnode->fSuccessfullyConnected)
1079         {
1080             LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId());
1081             pnode->fDisconnect = true;
1082         }
1083     }
1084 }
1085 
GenerateSelectSet(std::set<SOCKET> & recv_set,std::set<SOCKET> & send_set,std::set<SOCKET> & error_set)1086 bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1087 {
1088     for (const ListenSocket& hListenSocket : vhListenSocket) {
1089         recv_set.insert(hListenSocket.socket);
1090     }
1091 
1092     {
1093         LOCK(cs_vNodes);
1094         for (CNode* pnode : vNodes)
1095         {
1096             // Implement the following logic:
1097             // * If there is data to send, select() for sending data. As this only
1098             //   happens when optimistic write failed, we choose to first drain the
1099             //   write buffer in this case before receiving more. This avoids
1100             //   needlessly queueing received data, if the remote peer is not themselves
1101             //   receiving data. This means properly utilizing TCP flow control signalling.
1102             // * Otherwise, if there is space left in the receive buffer, select() for
1103             //   receiving data.
1104             // * Hand off all complete messages to the processor, to be handled without
1105             //   blocking here.
1106 
1107             bool select_recv = !pnode->fPauseRecv;
1108             bool select_send;
1109             {
1110                 LOCK(pnode->cs_vSend);
1111                 select_send = !pnode->vSendMsg.empty();
1112             }
1113 
1114             LOCK(pnode->cs_hSocket);
1115             if (pnode->hSocket == INVALID_SOCKET)
1116                 continue;
1117 
1118             error_set.insert(pnode->hSocket);
1119             if (select_send) {
1120                 send_set.insert(pnode->hSocket);
1121                 continue;
1122             }
1123             if (select_recv) {
1124                 recv_set.insert(pnode->hSocket);
1125             }
1126         }
1127     }
1128 
1129     return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1130 }
1131 
1132 #ifdef USE_POLL
SocketEvents(std::set<SOCKET> & recv_set,std::set<SOCKET> & send_set,std::set<SOCKET> & error_set)1133 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1134 {
1135     std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1136     if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1137         interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1138         return;
1139     }
1140 
1141     std::unordered_map<SOCKET, struct pollfd> pollfds;
1142     for (SOCKET socket_id : recv_select_set) {
1143         pollfds[socket_id].fd = socket_id;
1144         pollfds[socket_id].events |= POLLIN;
1145     }
1146 
1147     for (SOCKET socket_id : send_select_set) {
1148         pollfds[socket_id].fd = socket_id;
1149         pollfds[socket_id].events |= POLLOUT;
1150     }
1151 
1152     for (SOCKET socket_id : error_select_set) {
1153         pollfds[socket_id].fd = socket_id;
1154         // These flags are ignored, but we set them for clarity
1155         pollfds[socket_id].events |= POLLERR|POLLHUP;
1156     }
1157 
1158     std::vector<struct pollfd> vpollfds;
1159     vpollfds.reserve(pollfds.size());
1160     for (auto it : pollfds) {
1161         vpollfds.push_back(std::move(it.second));
1162     }
1163 
1164     if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
1165 
1166     if (interruptNet) return;
1167 
1168     for (struct pollfd pollfd_entry : vpollfds) {
1169         if (pollfd_entry.revents & POLLIN)            recv_set.insert(pollfd_entry.fd);
1170         if (pollfd_entry.revents & POLLOUT)           send_set.insert(pollfd_entry.fd);
1171         if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1172     }
1173 }
1174 #else
SocketEvents(std::set<SOCKET> & recv_set,std::set<SOCKET> & send_set,std::set<SOCKET> & error_set)1175 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1176 {
1177     std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1178     if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1179         interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1180         return;
1181     }
1182 
1183     //
1184     // Find which sockets have data to receive
1185     //
1186     struct timeval timeout;
1187     timeout.tv_sec  = 0;
1188     timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
1189 
1190     fd_set fdsetRecv;
1191     fd_set fdsetSend;
1192     fd_set fdsetError;
1193     FD_ZERO(&fdsetRecv);
1194     FD_ZERO(&fdsetSend);
1195     FD_ZERO(&fdsetError);
1196     SOCKET hSocketMax = 0;
1197 
1198     for (SOCKET hSocket : recv_select_set) {
1199         FD_SET(hSocket, &fdsetRecv);
1200         hSocketMax = std::max(hSocketMax, hSocket);
1201     }
1202 
1203     for (SOCKET hSocket : send_select_set) {
1204         FD_SET(hSocket, &fdsetSend);
1205         hSocketMax = std::max(hSocketMax, hSocket);
1206     }
1207 
1208     for (SOCKET hSocket : error_select_set) {
1209         FD_SET(hSocket, &fdsetError);
1210         hSocketMax = std::max(hSocketMax, hSocket);
1211     }
1212 
1213     int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1214 
1215     if (interruptNet)
1216         return;
1217 
1218     if (nSelect == SOCKET_ERROR)
1219     {
1220         int nErr = WSAGetLastError();
1221         LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1222         for (unsigned int i = 0; i <= hSocketMax; i++)
1223             FD_SET(i, &fdsetRecv);
1224         FD_ZERO(&fdsetSend);
1225         FD_ZERO(&fdsetError);
1226         if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1227             return;
1228     }
1229 
1230     for (SOCKET hSocket : recv_select_set) {
1231         if (FD_ISSET(hSocket, &fdsetRecv)) {
1232             recv_set.insert(hSocket);
1233         }
1234     }
1235 
1236     for (SOCKET hSocket : send_select_set) {
1237         if (FD_ISSET(hSocket, &fdsetSend)) {
1238             send_set.insert(hSocket);
1239         }
1240     }
1241 
1242     for (SOCKET hSocket : error_select_set) {
1243         if (FD_ISSET(hSocket, &fdsetError)) {
1244             error_set.insert(hSocket);
1245         }
1246     }
1247 }
1248 #endif
1249 
SocketHandler()1250 void CConnman::SocketHandler()
1251 {
1252     std::set<SOCKET> recv_set, send_set, error_set;
1253     SocketEvents(recv_set, send_set, error_set);
1254 
1255     if (interruptNet) return;
1256 
1257     //
1258     // Accept new connections
1259     //
1260     for (const ListenSocket& hListenSocket : vhListenSocket)
1261     {
1262         if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1263         {
1264             AcceptConnection(hListenSocket);
1265         }
1266     }
1267 
1268     //
1269     // Service each socket
1270     //
1271     std::vector<CNode*> vNodesCopy;
1272     {
1273         LOCK(cs_vNodes);
1274         vNodesCopy = vNodes;
1275         for (CNode* pnode : vNodesCopy)
1276             pnode->AddRef();
1277     }
1278     for (CNode* pnode : vNodesCopy)
1279     {
1280         if (interruptNet)
1281             return;
1282 
1283         //
1284         // Receive
1285         //
1286         bool recvSet = false;
1287         bool sendSet = false;
1288         bool errorSet = false;
1289         {
1290             LOCK(pnode->cs_hSocket);
1291             if (pnode->hSocket == INVALID_SOCKET)
1292                 continue;
1293             recvSet = recv_set.count(pnode->hSocket) > 0;
1294             sendSet = send_set.count(pnode->hSocket) > 0;
1295             errorSet = error_set.count(pnode->hSocket) > 0;
1296         }
1297         if (recvSet || errorSet)
1298         {
1299             // typical socket buffer is 8K-64K
1300             char pchBuf[0x10000];
1301             int nBytes = 0;
1302             {
1303                 LOCK(pnode->cs_hSocket);
1304                 if (pnode->hSocket == INVALID_SOCKET)
1305                     continue;
1306                 nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1307             }
1308             if (nBytes > 0)
1309             {
1310                 bool notify = false;
1311                 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1312                     pnode->CloseSocketDisconnect();
1313                 RecordBytesRecv(nBytes);
1314                 if (notify) {
1315                     size_t nSizeAdded = 0;
1316                     auto it(pnode->vRecvMsg.begin());
1317                     for (; it != pnode->vRecvMsg.end(); ++it) {
1318                         if (!it->complete())
1319                             break;
1320                         nSizeAdded += it->vRecv.size() + CMessageHeader::HEADER_SIZE;
1321                     }
1322                     {
1323                         LOCK(pnode->cs_vProcessMsg);
1324                         pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1325                         pnode->nProcessQueueSize += nSizeAdded;
1326                         pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1327                     }
1328                     WakeMessageHandler();
1329                 }
1330             }
1331             else if (nBytes == 0)
1332             {
1333                 // socket closed gracefully
1334                 if (!pnode->fDisconnect) {
1335                     LogPrint(BCLog::NET, "socket closed\n");
1336                 }
1337                 pnode->CloseSocketDisconnect();
1338             }
1339             else if (nBytes < 0)
1340             {
1341                 // error
1342                 int nErr = WSAGetLastError();
1343                 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1344                 {
1345                     if (!pnode->fDisconnect)
1346                         LogPrintf("socket recv error %s\n", NetworkErrorString(nErr));
1347                     pnode->CloseSocketDisconnect();
1348                 }
1349             }
1350         }
1351 
1352         //
1353         // Send
1354         //
1355         if (sendSet)
1356         {
1357             LOCK(pnode->cs_vSend);
1358             size_t nBytes = SocketSendData(pnode);
1359             if (nBytes) {
1360                 RecordBytesSent(nBytes);
1361             }
1362         }
1363 
1364         InactivityCheck(pnode);
1365     }
1366     {
1367         LOCK(cs_vNodes);
1368         for (CNode* pnode : vNodesCopy)
1369             pnode->Release();
1370     }
1371 }
1372 
ThreadSocketHandler()1373 void CConnman::ThreadSocketHandler()
1374 {
1375     while (!interruptNet)
1376     {
1377         DisconnectNodes();
1378         NotifyNumConnectionsChanged();
1379         SocketHandler();
1380     }
1381 }
1382 
WakeMessageHandler()1383 void CConnman::WakeMessageHandler()
1384 {
1385     {
1386         std::lock_guard<std::mutex> lock(mutexMsgProc);
1387         fMsgProcWake = true;
1388     }
1389     condMsgProc.notify_one();
1390 }
1391 
1392 
1393 
1394 
1395 
1396 
1397 #ifdef USE_UPNP
1398 static CThreadInterrupt g_upnp_interrupt;
1399 static std::thread g_upnp_thread;
ThreadMapPort()1400 static void ThreadMapPort()
1401 {
1402     std::string port = strprintf("%u", GetListenPort());
1403     const char * multicastif = nullptr;
1404     const char * minissdpdpath = nullptr;
1405     struct UPNPDev * devlist = nullptr;
1406     char lanaddr[64];
1407 
1408 #ifndef UPNPDISCOVER_SUCCESS
1409     /* miniupnpc 1.5 */
1410     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1411 #elif MINIUPNPC_API_VERSION < 14
1412     /* miniupnpc 1.6 */
1413     int error = 0;
1414     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1415 #else
1416     /* miniupnpc 1.9.20150730 */
1417     int error = 0;
1418     devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1419 #endif
1420 
1421     struct UPNPUrls urls;
1422     struct IGDdatas data;
1423     int r;
1424 
1425     r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1426     if (r == 1)
1427     {
1428         if (fDiscover) {
1429             char externalIPAddress[40];
1430             r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1431             if(r != UPNPCOMMAND_SUCCESS)
1432                 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
1433             else
1434             {
1435                 if(externalIPAddress[0])
1436                 {
1437                     CNetAddr resolved;
1438                     if(LookupHost(externalIPAddress, resolved, false)) {
1439                         LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str());
1440                         AddLocal(resolved, LOCAL_UPNP);
1441                     }
1442                 }
1443                 else
1444                     LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1445             }
1446         }
1447 
1448         std::string strDesc = "Litecoin " + FormatFullVersion();
1449 
1450         do {
1451 #ifndef UPNPDISCOVER_SUCCESS
1452             /* miniupnpc 1.5 */
1453             r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1454                                 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
1455 #else
1456             /* miniupnpc 1.6 */
1457             r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1458                                 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
1459 #endif
1460 
1461             if(r!=UPNPCOMMAND_SUCCESS)
1462                 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1463                     port, port, lanaddr, r, strupnperror(r));
1464             else
1465                 LogPrintf("UPnP Port Mapping successful.\n");
1466         }
1467         while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20)));
1468 
1469         r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
1470         LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
1471         freeUPNPDevlist(devlist); devlist = nullptr;
1472         FreeUPNPUrls(&urls);
1473     } else {
1474         LogPrintf("No valid UPnP IGDs found\n");
1475         freeUPNPDevlist(devlist); devlist = nullptr;
1476         if (r != 0)
1477             FreeUPNPUrls(&urls);
1478     }
1479 }
1480 
StartMapPort()1481 void StartMapPort()
1482 {
1483     if (!g_upnp_thread.joinable()) {
1484         assert(!g_upnp_interrupt);
1485         g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
1486     }
1487 }
1488 
InterruptMapPort()1489 void InterruptMapPort()
1490 {
1491     if(g_upnp_thread.joinable()) {
1492         g_upnp_interrupt();
1493     }
1494 }
1495 
StopMapPort()1496 void StopMapPort()
1497 {
1498     if(g_upnp_thread.joinable()) {
1499         g_upnp_thread.join();
1500         g_upnp_interrupt.reset();
1501     }
1502 }
1503 
1504 #else
StartMapPort()1505 void StartMapPort()
1506 {
1507     // Intentionally left blank.
1508 }
InterruptMapPort()1509 void InterruptMapPort()
1510 {
1511     // Intentionally left blank.
1512 }
StopMapPort()1513 void StopMapPort()
1514 {
1515     // Intentionally left blank.
1516 }
1517 #endif
1518 
1519 
1520 
1521 
1522 
1523 
ThreadDNSAddressSeed()1524 void CConnman::ThreadDNSAddressSeed()
1525 {
1526     // goal: only query DNS seeds if address need is acute
1527     // Avoiding DNS seeds when we don't need them improves user privacy by
1528     //  creating fewer identifying DNS requests, reduces trust by giving seeds
1529     //  less influence on the network topology, and reduces traffic to the seeds.
1530     if ((addrman.size() > 0) &&
1531         (!gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
1532         if (!interruptNet.sleep_for(std::chrono::seconds(11)))
1533             return;
1534 
1535         LOCK(cs_vNodes);
1536         int nRelevant = 0;
1537         for (const CNode* pnode : vNodes) {
1538             nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
1539         }
1540         if (nRelevant >= 2) {
1541             LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1542             return;
1543         }
1544     }
1545 
1546     const std::vector<std::string> &vSeeds = Params().DNSSeeds();
1547     int found = 0;
1548 
1549     LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1550 
1551     for (const std::string &seed : vSeeds) {
1552         if (interruptNet) {
1553             return;
1554         }
1555         if (HaveNameProxy()) {
1556             AddOneShot(seed);
1557         } else {
1558             std::vector<CNetAddr> vIPs;
1559             std::vector<CAddress> vAdd;
1560             ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
1561             std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
1562             CNetAddr resolveSource;
1563             if (!resolveSource.SetInternal(host)) {
1564                 continue;
1565             }
1566             unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
1567             if (LookupHost(host.c_str(), vIPs, nMaxIPs, true))
1568             {
1569                 for (const CNetAddr& ip : vIPs)
1570                 {
1571                     int nOneDay = 24*3600;
1572                     CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1573                     addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
1574                     vAdd.push_back(addr);
1575                     found++;
1576                 }
1577                 addrman.Add(vAdd, resolveSource);
1578             } else {
1579                 // We now avoid directly using results from DNS Seeds which do not support service bit filtering,
1580                 // instead using them as a oneshot to get nodes with our desired service bits.
1581                 AddOneShot(seed);
1582             }
1583         }
1584     }
1585 
1586     LogPrintf("%d addresses found from DNS seeds\n", found);
1587 }
1588 
1589 
1590 
1591 
1592 
1593 
1594 
1595 
1596 
1597 
1598 
1599 
DumpAddresses()1600 void CConnman::DumpAddresses()
1601 {
1602     int64_t nStart = GetTimeMillis();
1603 
1604     CAddrDB adb;
1605     adb.Write(addrman);
1606 
1607     LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat  %dms\n",
1608            addrman.size(), GetTimeMillis() - nStart);
1609 }
1610 
ProcessOneShot()1611 void CConnman::ProcessOneShot()
1612 {
1613     std::string strDest;
1614     {
1615         LOCK(cs_vOneShots);
1616         if (vOneShots.empty())
1617             return;
1618         strDest = vOneShots.front();
1619         vOneShots.pop_front();
1620     }
1621     CAddress addr;
1622     CSemaphoreGrant grant(*semOutbound, true);
1623     if (grant) {
1624         OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true);
1625     }
1626 }
1627 
GetTryNewOutboundPeer()1628 bool CConnman::GetTryNewOutboundPeer()
1629 {
1630     return m_try_another_outbound_peer;
1631 }
1632 
SetTryNewOutboundPeer(bool flag)1633 void CConnman::SetTryNewOutboundPeer(bool flag)
1634 {
1635     m_try_another_outbound_peer = flag;
1636     LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
1637 }
1638 
1639 // Return the number of peers we have over our outbound connection limit
1640 // Exclude peers that are marked for disconnect, or are going to be
1641 // disconnected soon (eg one-shots and feelers)
1642 // Also exclude peers that haven't finished initial connection handshake yet
1643 // (so that we don't decide we're over our desired connection limit, and then
1644 // evict some peer that has finished the handshake)
GetExtraOutboundCount()1645 int CConnman::GetExtraOutboundCount()
1646 {
1647     int nOutbound = 0;
1648     {
1649         LOCK(cs_vNodes);
1650         for (const CNode* pnode : vNodes) {
1651             if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
1652                 ++nOutbound;
1653             }
1654         }
1655     }
1656     return std::max(nOutbound - nMaxOutbound, 0);
1657 }
1658 
ThreadOpenConnections(const std::vector<std::string> connect)1659 void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
1660 {
1661     // Connect to specific addresses
1662     if (!connect.empty())
1663     {
1664         for (int64_t nLoop = 0;; nLoop++)
1665         {
1666             ProcessOneShot();
1667             for (const std::string& strAddr : connect)
1668             {
1669                 CAddress addr(CService(), NODE_NONE);
1670                 OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), false, false, true);
1671                 for (int i = 0; i < 10 && i < nLoop; i++)
1672                 {
1673                     if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1674                         return;
1675                 }
1676             }
1677             if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1678                 return;
1679         }
1680     }
1681 
1682     // Initiate network connections
1683     int64_t nStart = GetTime();
1684 
1685     // Minimum time before next feeler connection (in microseconds).
1686     int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
1687     while (!interruptNet)
1688     {
1689         ProcessOneShot();
1690 
1691         if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1692             return;
1693 
1694         CSemaphoreGrant grant(*semOutbound);
1695         if (interruptNet)
1696             return;
1697 
1698         // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1699         if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
1700             static bool done = false;
1701             if (!done) {
1702                 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1703                 CNetAddr local;
1704                 local.SetInternal("fixedseeds");
1705                 addrman.Add(convertSeed6(Params().FixedSeeds()), local);
1706                 done = true;
1707             }
1708         }
1709 
1710         //
1711         // Choose an address to connect to based on most recently seen
1712         //
1713         CAddress addrConnect;
1714 
1715         // Only connect out to one peer per network group (/16 for IPv4).
1716         int nOutbound = 0;
1717         std::set<std::vector<unsigned char> > setConnected;
1718         {
1719             LOCK(cs_vNodes);
1720             for (const CNode* pnode : vNodes) {
1721                 if (!pnode->fInbound && !pnode->m_manual_connection) {
1722                     // Netgroups for inbound and addnode peers are not excluded because our goal here
1723                     // is to not use multiple of our limited outbound slots on a single netgroup
1724                     // but inbound and addnode peers do not use our outbound slots.  Inbound peers
1725                     // also have the added issue that they're attacker controlled and could be used
1726                     // to prevent us from connecting to particular hosts if we used them here.
1727                     setConnected.insert(pnode->addr.GetGroup());
1728                     nOutbound++;
1729                 }
1730             }
1731         }
1732 
1733         // Feeler Connections
1734         //
1735         // Design goals:
1736         //  * Increase the number of connectable addresses in the tried table.
1737         //
1738         // Method:
1739         //  * Choose a random address from new and attempt to connect to it if we can connect
1740         //    successfully it is added to tried.
1741         //  * Start attempting feeler connections only after node finishes making outbound
1742         //    connections.
1743         //  * Only make a feeler connection once every few minutes.
1744         //
1745         bool fFeeler = false;
1746 
1747         if (nOutbound >= nMaxOutbound && !GetTryNewOutboundPeer()) {
1748             int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
1749             if (nTime > nNextFeeler) {
1750                 nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL);
1751                 fFeeler = true;
1752             } else {
1753                 continue;
1754             }
1755         }
1756 
1757         addrman.ResolveCollisions();
1758 
1759         int64_t nANow = GetAdjustedTime();
1760         int nTries = 0;
1761         while (!interruptNet)
1762         {
1763             CAddrInfo addr = addrman.SelectTriedCollision();
1764 
1765             // SelectTriedCollision returns an invalid address if it is empty.
1766             if (!fFeeler || !addr.IsValid()) {
1767                 addr = addrman.Select(fFeeler);
1768             }
1769 
1770             // Require outbound connections, other than feelers, to be to distinct network groups
1771             if (!fFeeler && setConnected.count(addr.GetGroup())) {
1772                 break;
1773             }
1774 
1775             // if we selected an invalid or local address, restart
1776             if (!addr.IsValid() || IsLocal(addr)) {
1777                 break;
1778             }
1779 
1780             // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1781             // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1782             // already-connected network ranges, ...) before trying new addrman addresses.
1783             nTries++;
1784             if (nTries > 100)
1785                 break;
1786 
1787             if (!IsReachable(addr))
1788                 continue;
1789 
1790             // only consider very recently tried nodes after 30 failed attempts
1791             if (nANow - addr.nLastTry < 600 && nTries < 30)
1792                 continue;
1793 
1794             // for non-feelers, require all the services we'll want,
1795             // for feelers, only require they be a full node (only because most
1796             // SPV clients don't have a good address DB available)
1797             if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
1798                 continue;
1799             } else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
1800                 continue;
1801             }
1802 
1803             // do not allow non-default ports, unless after 50 invalid addresses selected already
1804             if (addr.GetPort() != Params().GetDefaultPort() && nTries < 50)
1805                 continue;
1806 
1807             addrConnect = addr;
1808             break;
1809         }
1810 
1811         if (addrConnect.IsValid()) {
1812 
1813             if (fFeeler) {
1814                 // Add small amount of random noise before connection to avoid synchronization.
1815                 int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
1816                 if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
1817                     return;
1818                 LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
1819             }
1820 
1821             OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, false, fFeeler);
1822         }
1823     }
1824 }
1825 
GetAddedNodeInfo()1826 std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo()
1827 {
1828     std::vector<AddedNodeInfo> ret;
1829 
1830     std::list<std::string> lAddresses(0);
1831     {
1832         LOCK(cs_vAddedNodes);
1833         ret.reserve(vAddedNodes.size());
1834         std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
1835     }
1836 
1837 
1838     // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
1839     std::map<CService, bool> mapConnected;
1840     std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
1841     {
1842         LOCK(cs_vNodes);
1843         for (const CNode* pnode : vNodes) {
1844             if (pnode->addr.IsValid()) {
1845                 mapConnected[pnode->addr] = pnode->fInbound;
1846             }
1847             std::string addrName = pnode->GetAddrName();
1848             if (!addrName.empty()) {
1849                 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1850             }
1851         }
1852     }
1853 
1854     for (const std::string& strAddNode : lAddresses) {
1855         CService service(LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort()));
1856         AddedNodeInfo addedNode{strAddNode, CService(), false, false};
1857         if (service.IsValid()) {
1858             // strAddNode is an IP:port
1859             auto it = mapConnected.find(service);
1860             if (it != mapConnected.end()) {
1861                 addedNode.resolvedAddress = service;
1862                 addedNode.fConnected = true;
1863                 addedNode.fInbound = it->second;
1864             }
1865         } else {
1866             // strAddNode is a name
1867             auto it = mapConnectedByName.find(strAddNode);
1868             if (it != mapConnectedByName.end()) {
1869                 addedNode.resolvedAddress = it->second.second;
1870                 addedNode.fConnected = true;
1871                 addedNode.fInbound = it->second.first;
1872             }
1873         }
1874         ret.emplace_back(std::move(addedNode));
1875     }
1876 
1877     return ret;
1878 }
1879 
ThreadOpenAddedConnections()1880 void CConnman::ThreadOpenAddedConnections()
1881 {
1882     while (true)
1883     {
1884         CSemaphoreGrant grant(*semAddnode);
1885         std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
1886         bool tried = false;
1887         for (const AddedNodeInfo& info : vInfo) {
1888             if (!info.fConnected) {
1889                 if (!grant.TryAcquire()) {
1890                     // If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
1891                     // the addednodeinfo state might change.
1892                     break;
1893                 }
1894                 tried = true;
1895                 CAddress addr(CService(), NODE_NONE);
1896                 OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), false, false, true);
1897                 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1898                     return;
1899             }
1900         }
1901         // Retry every 60 seconds if a connection was attempted, otherwise two seconds
1902         if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
1903             return;
1904     }
1905 }
1906 
1907 // if successful, this moves the passed grant to the constructed node
OpenNetworkConnection(const CAddress & addrConnect,bool fCountFailure,CSemaphoreGrant * grantOutbound,const char * pszDest,bool fOneShot,bool fFeeler,bool manual_connection)1908 void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection)
1909 {
1910     //
1911     // Initiate outbound network connection
1912     //
1913     if (interruptNet) {
1914         return;
1915     }
1916     if (!fNetworkActive) {
1917         return;
1918     }
1919     if (!pszDest) {
1920         if (IsLocal(addrConnect) ||
1921             FindNode(static_cast<CNetAddr>(addrConnect)) || (m_banman && m_banman->IsBanned(addrConnect)) ||
1922             FindNode(addrConnect.ToStringIPPort()))
1923             return;
1924     } else if (FindNode(std::string(pszDest)))
1925         return;
1926 
1927     CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection);
1928 
1929     if (!pnode)
1930         return;
1931     if (grantOutbound)
1932         grantOutbound->MoveTo(pnode->grantOutbound);
1933     if (fOneShot)
1934         pnode->fOneShot = true;
1935     if (fFeeler)
1936         pnode->fFeeler = true;
1937     if (manual_connection)
1938         pnode->m_manual_connection = true;
1939 
1940     m_msgproc->InitializeNode(pnode);
1941     {
1942         LOCK(cs_vNodes);
1943         vNodes.push_back(pnode);
1944     }
1945 }
1946 
ThreadMessageHandler()1947 void CConnman::ThreadMessageHandler()
1948 {
1949     while (!flagInterruptMsgProc)
1950     {
1951         std::vector<CNode*> vNodesCopy;
1952         {
1953             LOCK(cs_vNodes);
1954             vNodesCopy = vNodes;
1955             for (CNode* pnode : vNodesCopy) {
1956                 pnode->AddRef();
1957             }
1958         }
1959 
1960         bool fMoreWork = false;
1961 
1962         for (CNode* pnode : vNodesCopy)
1963         {
1964             if (pnode->fDisconnect)
1965                 continue;
1966 
1967             // Receive messages
1968             bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
1969             fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
1970             if (flagInterruptMsgProc)
1971                 return;
1972             // Send messages
1973             {
1974                 LOCK(pnode->cs_sendProcessing);
1975                 m_msgproc->SendMessages(pnode);
1976             }
1977 
1978             if (flagInterruptMsgProc)
1979                 return;
1980         }
1981 
1982         {
1983             LOCK(cs_vNodes);
1984             for (CNode* pnode : vNodesCopy)
1985                 pnode->Release();
1986         }
1987 
1988         WAIT_LOCK(mutexMsgProc, lock);
1989         if (!fMoreWork) {
1990             condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this] { return fMsgProcWake; });
1991         }
1992         fMsgProcWake = false;
1993     }
1994 }
1995 
1996 
1997 
1998 
1999 
2000 
BindListenPort(const CService & addrBind,std::string & strError,bool fWhitelisted)2001 bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, bool fWhitelisted)
2002 {
2003     strError = "";
2004     int nOne = 1;
2005 
2006     // Create socket for listening for incoming connections
2007     struct sockaddr_storage sockaddr;
2008     socklen_t len = sizeof(sockaddr);
2009     if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
2010     {
2011         strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString());
2012         LogPrintf("%s\n", strError);
2013         return false;
2014     }
2015 
2016     SOCKET hListenSocket = CreateSocket(addrBind);
2017     if (hListenSocket == INVALID_SOCKET)
2018     {
2019         strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
2020         LogPrintf("%s\n", strError);
2021         return false;
2022     }
2023 
2024     // Allow binding if the port is still in TIME_WAIT state after
2025     // the program was closed and restarted.
2026     setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int));
2027 
2028     // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
2029     // and enable it by default or not. Try to enable it, if possible.
2030     if (addrBind.IsIPv6()) {
2031 #ifdef IPV6_V6ONLY
2032         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
2033 #endif
2034 #ifdef WIN32
2035         int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2036         setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
2037 #endif
2038     }
2039 
2040     if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
2041     {
2042         int nErr = WSAGetLastError();
2043         if (nErr == WSAEADDRINUSE)
2044             strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
2045         else
2046             strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
2047         LogPrintf("%s\n", strError);
2048         CloseSocket(hListenSocket);
2049         return false;
2050     }
2051     LogPrintf("Bound to %s\n", addrBind.ToString());
2052 
2053     // Listen for incoming connections
2054     if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
2055     {
2056         strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
2057         LogPrintf("%s\n", strError);
2058         CloseSocket(hListenSocket);
2059         return false;
2060     }
2061 
2062     vhListenSocket.push_back(ListenSocket(hListenSocket, fWhitelisted));
2063 
2064     if (addrBind.IsRoutable() && fDiscover && !fWhitelisted)
2065         AddLocal(addrBind, LOCAL_BIND);
2066 
2067     return true;
2068 }
2069 
Discover()2070 void Discover()
2071 {
2072     if (!fDiscover)
2073         return;
2074 
2075 #ifdef WIN32
2076     // Get local host IP
2077     char pszHostName[256] = "";
2078     if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
2079     {
2080         std::vector<CNetAddr> vaddr;
2081         if (LookupHost(pszHostName, vaddr, 0, true))
2082         {
2083             for (const CNetAddr &addr : vaddr)
2084             {
2085                 if (AddLocal(addr, LOCAL_IF))
2086                     LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2087             }
2088         }
2089     }
2090 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2091     // Get local host ip
2092     struct ifaddrs* myaddrs;
2093     if (getifaddrs(&myaddrs) == 0)
2094     {
2095         for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
2096         {
2097             if (ifa->ifa_addr == nullptr) continue;
2098             if ((ifa->ifa_flags & IFF_UP) == 0) continue;
2099             if (strcmp(ifa->ifa_name, "lo") == 0) continue;
2100             if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
2101             if (ifa->ifa_addr->sa_family == AF_INET)
2102             {
2103                 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
2104                 CNetAddr addr(s4->sin_addr);
2105                 if (AddLocal(addr, LOCAL_IF))
2106                     LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2107             }
2108             else if (ifa->ifa_addr->sa_family == AF_INET6)
2109             {
2110                 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
2111                 CNetAddr addr(s6->sin6_addr);
2112                 if (AddLocal(addr, LOCAL_IF))
2113                     LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2114             }
2115         }
2116         freeifaddrs(myaddrs);
2117     }
2118 #endif
2119 }
2120 
SetNetworkActive(bool active)2121 void CConnman::SetNetworkActive(bool active)
2122 {
2123     LogPrint(BCLog::NET, "SetNetworkActive: %s\n", active);
2124 
2125     if (fNetworkActive == active) {
2126         return;
2127     }
2128 
2129     fNetworkActive = active;
2130 
2131     uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
2132 }
2133 
CConnman(uint64_t nSeed0In,uint64_t nSeed1In)2134 CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In) : nSeed0(nSeed0In), nSeed1(nSeed1In)
2135 {
2136     SetTryNewOutboundPeer(false);
2137 
2138     Options connOptions;
2139     Init(connOptions);
2140 }
2141 
GetNewNodeId()2142 NodeId CConnman::GetNewNodeId()
2143 {
2144     return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2145 }
2146 
2147 
Bind(const CService & addr,unsigned int flags)2148 bool CConnman::Bind(const CService &addr, unsigned int flags) {
2149     if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
2150         return false;
2151     std::string strError;
2152     if (!BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) {
2153         if ((flags & BF_REPORT_ERROR) && clientInterface) {
2154             clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
2155         }
2156         return false;
2157     }
2158     return true;
2159 }
2160 
InitBinds(const std::vector<CService> & binds,const std::vector<CService> & whiteBinds)2161 bool CConnman::InitBinds(const std::vector<CService>& binds, const std::vector<CService>& whiteBinds) {
2162     bool fBound = false;
2163     for (const auto& addrBind : binds) {
2164         fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
2165     }
2166     for (const auto& addrBind : whiteBinds) {
2167         fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST));
2168     }
2169     if (binds.empty() && whiteBinds.empty()) {
2170         struct in_addr inaddr_any;
2171         inaddr_any.s_addr = INADDR_ANY;
2172         struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2173         fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE);
2174         fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
2175     }
2176     return fBound;
2177 }
2178 
Start(CScheduler & scheduler,const Options & connOptions)2179 bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
2180 {
2181     Init(connOptions);
2182 
2183     {
2184         LOCK(cs_totalBytesRecv);
2185         nTotalBytesRecv = 0;
2186     }
2187     {
2188         LOCK(cs_totalBytesSent);
2189         nTotalBytesSent = 0;
2190         nMaxOutboundTotalBytesSentInCycle = 0;
2191         nMaxOutboundCycleStartTime = 0;
2192     }
2193 
2194     if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
2195         if (clientInterface) {
2196             clientInterface->ThreadSafeMessageBox(
2197                 _("Failed to listen on any port. Use -listen=0 if you want this."),
2198                 "", CClientUIInterface::MSG_ERROR);
2199         }
2200         return false;
2201     }
2202 
2203     for (const auto& strDest : connOptions.vSeedNodes) {
2204         AddOneShot(strDest);
2205     }
2206 
2207     if (clientInterface) {
2208         clientInterface->InitMessage(_("Loading P2P addresses..."));
2209     }
2210     // Load addresses from peers.dat
2211     int64_t nStart = GetTimeMillis();
2212     {
2213         CAddrDB adb;
2214         if (adb.Read(addrman))
2215             LogPrintf("Loaded %i addresses from peers.dat  %dms\n", addrman.size(), GetTimeMillis() - nStart);
2216         else {
2217             addrman.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2218             LogPrintf("Invalid or missing peers.dat; recreating\n");
2219             DumpAddresses();
2220         }
2221     }
2222 
2223     uiInterface.InitMessage(_("Starting network threads..."));
2224 
2225     fAddressesInitialized = true;
2226 
2227     if (semOutbound == nullptr) {
2228         // initialize semaphore
2229         semOutbound = MakeUnique<CSemaphore>(std::min((nMaxOutbound + nMaxFeeler), nMaxConnections));
2230     }
2231     if (semAddnode == nullptr) {
2232         // initialize semaphore
2233         semAddnode = MakeUnique<CSemaphore>(nMaxAddnode);
2234     }
2235 
2236     //
2237     // Start threads
2238     //
2239     assert(m_msgproc);
2240     InterruptSocks5(false);
2241     interruptNet.reset();
2242     flagInterruptMsgProc = false;
2243 
2244     {
2245         LOCK(mutexMsgProc);
2246         fMsgProcWake = false;
2247     }
2248 
2249     // Send and receive from sockets, accept connections
2250     threadSocketHandler = std::thread(&TraceThread<std::function<void()> >, "net", std::function<void()>(std::bind(&CConnman::ThreadSocketHandler, this)));
2251 
2252     if (!gArgs.GetBoolArg("-dnsseed", true))
2253         LogPrintf("DNS seeding disabled\n");
2254     else
2255         threadDNSAddressSeed = std::thread(&TraceThread<std::function<void()> >, "dnsseed", std::function<void()>(std::bind(&CConnman::ThreadDNSAddressSeed, this)));
2256 
2257     // Initiate outbound connections from -addnode
2258     threadOpenAddedConnections = std::thread(&TraceThread<std::function<void()> >, "addcon", std::function<void()>(std::bind(&CConnman::ThreadOpenAddedConnections, this)));
2259 
2260     if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2261         if (clientInterface) {
2262             clientInterface->ThreadSafeMessageBox(
2263                 _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
2264                 "", CClientUIInterface::MSG_ERROR);
2265         }
2266         return false;
2267     }
2268     if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty())
2269         threadOpenConnections = std::thread(&TraceThread<std::function<void()> >, "opencon", std::function<void()>(std::bind(&CConnman::ThreadOpenConnections, this, connOptions.m_specified_outgoing)));
2270 
2271     // Process messages
2272     threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
2273 
2274     // Dump network addresses
2275     scheduler.scheduleEvery(std::bind(&CConnman::DumpAddresses, this), DUMP_PEERS_INTERVAL * 1000);
2276 
2277     return true;
2278 }
2279 
2280 class CNetCleanup
2281 {
2282 public:
CNetCleanup()2283     CNetCleanup() {}
2284 
~CNetCleanup()2285     ~CNetCleanup()
2286     {
2287 #ifdef WIN32
2288         // Shutdown Windows Sockets
2289         WSACleanup();
2290 #endif
2291     }
2292 }
2293 instance_of_cnetcleanup;
2294 
Interrupt()2295 void CConnman::Interrupt()
2296 {
2297     {
2298         std::lock_guard<std::mutex> lock(mutexMsgProc);
2299         flagInterruptMsgProc = true;
2300     }
2301     condMsgProc.notify_all();
2302 
2303     interruptNet();
2304     InterruptSocks5(true);
2305 
2306     if (semOutbound) {
2307         for (int i=0; i<(nMaxOutbound + nMaxFeeler); i++) {
2308             semOutbound->post();
2309         }
2310     }
2311 
2312     if (semAddnode) {
2313         for (int i=0; i<nMaxAddnode; i++) {
2314             semAddnode->post();
2315         }
2316     }
2317 }
2318 
Stop()2319 void CConnman::Stop()
2320 {
2321     if (threadMessageHandler.joinable())
2322         threadMessageHandler.join();
2323     if (threadOpenConnections.joinable())
2324         threadOpenConnections.join();
2325     if (threadOpenAddedConnections.joinable())
2326         threadOpenAddedConnections.join();
2327     if (threadDNSAddressSeed.joinable())
2328         threadDNSAddressSeed.join();
2329     if (threadSocketHandler.joinable())
2330         threadSocketHandler.join();
2331 
2332     if (fAddressesInitialized)
2333     {
2334         DumpAddresses();
2335         fAddressesInitialized = false;
2336     }
2337 
2338     // Close sockets
2339     for (CNode* pnode : vNodes)
2340         pnode->CloseSocketDisconnect();
2341     for (ListenSocket& hListenSocket : vhListenSocket)
2342         if (hListenSocket.socket != INVALID_SOCKET)
2343             if (!CloseSocket(hListenSocket.socket))
2344                 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2345 
2346     // clean up some globals (to help leak detection)
2347     for (CNode *pnode : vNodes) {
2348         DeleteNode(pnode);
2349     }
2350     for (CNode *pnode : vNodesDisconnected) {
2351         DeleteNode(pnode);
2352     }
2353     vNodes.clear();
2354     vNodesDisconnected.clear();
2355     vhListenSocket.clear();
2356     semOutbound.reset();
2357     semAddnode.reset();
2358 }
2359 
DeleteNode(CNode * pnode)2360 void CConnman::DeleteNode(CNode* pnode)
2361 {
2362     assert(pnode);
2363     bool fUpdateConnectionTime = false;
2364     m_msgproc->FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
2365     if(fUpdateConnectionTime) {
2366         addrman.Connected(pnode->addr);
2367     }
2368     delete pnode;
2369 }
2370 
~CConnman()2371 CConnman::~CConnman()
2372 {
2373     Interrupt();
2374     Stop();
2375 }
2376 
GetAddressCount() const2377 size_t CConnman::GetAddressCount() const
2378 {
2379     return addrman.size();
2380 }
2381 
SetServices(const CService & addr,ServiceFlags nServices)2382 void CConnman::SetServices(const CService &addr, ServiceFlags nServices)
2383 {
2384     addrman.SetServices(addr, nServices);
2385 }
2386 
MarkAddressGood(const CAddress & addr)2387 void CConnman::MarkAddressGood(const CAddress& addr)
2388 {
2389     addrman.Good(addr);
2390 }
2391 
AddNewAddresses(const std::vector<CAddress> & vAddr,const CAddress & addrFrom,int64_t nTimePenalty)2392 void CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
2393 {
2394     addrman.Add(vAddr, addrFrom, nTimePenalty);
2395 }
2396 
GetAddresses()2397 std::vector<CAddress> CConnman::GetAddresses()
2398 {
2399     return addrman.GetAddr();
2400 }
2401 
AddNode(const std::string & strNode)2402 bool CConnman::AddNode(const std::string& strNode)
2403 {
2404     LOCK(cs_vAddedNodes);
2405     for (const std::string& it : vAddedNodes) {
2406         if (strNode == it) return false;
2407     }
2408 
2409     vAddedNodes.push_back(strNode);
2410     return true;
2411 }
2412 
RemoveAddedNode(const std::string & strNode)2413 bool CConnman::RemoveAddedNode(const std::string& strNode)
2414 {
2415     LOCK(cs_vAddedNodes);
2416     for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2417         if (strNode == *it) {
2418             vAddedNodes.erase(it);
2419             return true;
2420         }
2421     }
2422     return false;
2423 }
2424 
GetNodeCount(NumConnections flags)2425 size_t CConnman::GetNodeCount(NumConnections flags)
2426 {
2427     LOCK(cs_vNodes);
2428     if (flags == CConnman::CONNECTIONS_ALL) // Shortcut if we want total
2429         return vNodes.size();
2430 
2431     int nNum = 0;
2432     for (const auto& pnode : vNodes) {
2433         if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT)) {
2434             nNum++;
2435         }
2436     }
2437 
2438     return nNum;
2439 }
2440 
GetNodeStats(std::vector<CNodeStats> & vstats)2441 void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats)
2442 {
2443     vstats.clear();
2444     LOCK(cs_vNodes);
2445     vstats.reserve(vNodes.size());
2446     for (CNode* pnode : vNodes) {
2447         vstats.emplace_back();
2448         pnode->copyStats(vstats.back());
2449     }
2450 }
2451 
DisconnectNode(const std::string & strNode)2452 bool CConnman::DisconnectNode(const std::string& strNode)
2453 {
2454     LOCK(cs_vNodes);
2455     if (CNode* pnode = FindNode(strNode)) {
2456         pnode->fDisconnect = true;
2457         return true;
2458     }
2459     return false;
2460 }
2461 
DisconnectNode(const CSubNet & subnet)2462 bool CConnman::DisconnectNode(const CSubNet& subnet)
2463 {
2464     bool disconnected = false;
2465     LOCK(cs_vNodes);
2466     for (CNode* pnode : vNodes) {
2467         if (subnet.Match(pnode->addr)) {
2468             pnode->fDisconnect = true;
2469             disconnected = true;
2470         }
2471     }
2472     return disconnected;
2473 }
2474 
DisconnectNode(const CNetAddr & addr)2475 bool CConnman::DisconnectNode(const CNetAddr& addr)
2476 {
2477     return DisconnectNode(CSubNet(addr));
2478 }
2479 
DisconnectNode(NodeId id)2480 bool CConnman::DisconnectNode(NodeId id)
2481 {
2482     LOCK(cs_vNodes);
2483     for(CNode* pnode : vNodes) {
2484         if (id == pnode->GetId()) {
2485             pnode->fDisconnect = true;
2486             return true;
2487         }
2488     }
2489     return false;
2490 }
2491 
RecordBytesRecv(uint64_t bytes)2492 void CConnman::RecordBytesRecv(uint64_t bytes)
2493 {
2494     LOCK(cs_totalBytesRecv);
2495     nTotalBytesRecv += bytes;
2496 }
2497 
RecordBytesSent(uint64_t bytes)2498 void CConnman::RecordBytesSent(uint64_t bytes)
2499 {
2500     LOCK(cs_totalBytesSent);
2501     nTotalBytesSent += bytes;
2502 
2503     uint64_t now = GetTime();
2504     if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
2505     {
2506         // timeframe expired, reset cycle
2507         nMaxOutboundCycleStartTime = now;
2508         nMaxOutboundTotalBytesSentInCycle = 0;
2509     }
2510 
2511     // TODO, exclude whitebind peers
2512     nMaxOutboundTotalBytesSentInCycle += bytes;
2513 }
2514 
SetMaxOutboundTarget(uint64_t limit)2515 void CConnman::SetMaxOutboundTarget(uint64_t limit)
2516 {
2517     LOCK(cs_totalBytesSent);
2518     nMaxOutboundLimit = limit;
2519 }
2520 
GetMaxOutboundTarget()2521 uint64_t CConnman::GetMaxOutboundTarget()
2522 {
2523     LOCK(cs_totalBytesSent);
2524     return nMaxOutboundLimit;
2525 }
2526 
GetMaxOutboundTimeframe()2527 uint64_t CConnman::GetMaxOutboundTimeframe()
2528 {
2529     LOCK(cs_totalBytesSent);
2530     return nMaxOutboundTimeframe;
2531 }
2532 
GetMaxOutboundTimeLeftInCycle()2533 uint64_t CConnman::GetMaxOutboundTimeLeftInCycle()
2534 {
2535     LOCK(cs_totalBytesSent);
2536     if (nMaxOutboundLimit == 0)
2537         return 0;
2538 
2539     if (nMaxOutboundCycleStartTime == 0)
2540         return nMaxOutboundTimeframe;
2541 
2542     uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2543     uint64_t now = GetTime();
2544     return (cycleEndTime < now) ? 0 : cycleEndTime - GetTime();
2545 }
2546 
SetMaxOutboundTimeframe(uint64_t timeframe)2547 void CConnman::SetMaxOutboundTimeframe(uint64_t timeframe)
2548 {
2549     LOCK(cs_totalBytesSent);
2550     if (nMaxOutboundTimeframe != timeframe)
2551     {
2552         // reset measure-cycle in case of changing
2553         // the timeframe
2554         nMaxOutboundCycleStartTime = GetTime();
2555     }
2556     nMaxOutboundTimeframe = timeframe;
2557 }
2558 
OutboundTargetReached(bool historicalBlockServingLimit)2559 bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit)
2560 {
2561     LOCK(cs_totalBytesSent);
2562     if (nMaxOutboundLimit == 0)
2563         return false;
2564 
2565     if (historicalBlockServingLimit)
2566     {
2567         // keep a large enough buffer to at least relay each block once
2568         uint64_t timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
2569         uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SERIALIZED_SIZE;
2570         if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2571             return true;
2572     }
2573     else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2574         return true;
2575 
2576     return false;
2577 }
2578 
GetOutboundTargetBytesLeft()2579 uint64_t CConnman::GetOutboundTargetBytesLeft()
2580 {
2581     LOCK(cs_totalBytesSent);
2582     if (nMaxOutboundLimit == 0)
2583         return 0;
2584 
2585     return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2586 }
2587 
GetTotalBytesRecv()2588 uint64_t CConnman::GetTotalBytesRecv()
2589 {
2590     LOCK(cs_totalBytesRecv);
2591     return nTotalBytesRecv;
2592 }
2593 
GetTotalBytesSent()2594 uint64_t CConnman::GetTotalBytesSent()
2595 {
2596     LOCK(cs_totalBytesSent);
2597     return nTotalBytesSent;
2598 }
2599 
GetLocalServices() const2600 ServiceFlags CConnman::GetLocalServices() const
2601 {
2602     return nLocalServices;
2603 }
2604 
SetBestHeight(int height)2605 void CConnman::SetBestHeight(int height)
2606 {
2607     nBestHeight.store(height, std::memory_order_release);
2608 }
2609 
GetBestHeight() const2610 int CConnman::GetBestHeight() const
2611 {
2612     return nBestHeight.load(std::memory_order_acquire);
2613 }
2614 
GetReceiveFloodSize() const2615 unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
2616 
CNode(NodeId idIn,ServiceFlags nLocalServicesIn,int nMyStartingHeightIn,SOCKET hSocketIn,const CAddress & addrIn,uint64_t nKeyedNetGroupIn,uint64_t nLocalHostNonceIn,const CAddress & addrBindIn,const std::string & addrNameIn,bool fInboundIn)2617 CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, bool fInboundIn)
2618     : nTimeConnected(GetSystemTimeInSeconds()),
2619     addr(addrIn),
2620     addrBind(addrBindIn),
2621     fInbound(fInboundIn),
2622     nKeyedNetGroup(nKeyedNetGroupIn),
2623     addrKnown(5000, 0.001),
2624     filterInventoryKnown(50000, 0.000001),
2625     id(idIn),
2626     nLocalHostNonce(nLocalHostNonceIn),
2627     nLocalServices(nLocalServicesIn),
2628     nMyStartingHeight(nMyStartingHeightIn)
2629 {
2630     hSocket = hSocketIn;
2631     addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
2632     strSubVer = "";
2633     hashContinue = uint256();
2634     filterInventoryKnown.reset();
2635     pfilter = MakeUnique<CBloomFilter>();
2636 
2637     for (const std::string &msg : getAllNetMessageTypes())
2638         mapRecvBytesPerMsgCmd[msg] = 0;
2639     mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
2640 
2641     if (fLogIPs) {
2642         LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", addrName, id);
2643     } else {
2644         LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
2645     }
2646 }
2647 
~CNode()2648 CNode::~CNode()
2649 {
2650     CloseSocket(hSocket);
2651 }
2652 
AskFor(const CInv & inv)2653 void CNode::AskFor(const CInv& inv)
2654 {
2655     if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
2656         return;
2657     // a peer may not have multiple non-responded queue positions for a single inv item
2658     if (!setAskFor.insert(inv.hash).second)
2659         return;
2660 
2661     // We're using mapAskFor as a priority queue,
2662     // the key is the earliest time the request can be sent
2663     int64_t nRequestTime;
2664     limitedmap<uint256, int64_t>::const_iterator it = mapAlreadyAskedFor.find(inv.hash);
2665     if (it != mapAlreadyAskedFor.end())
2666         nRequestTime = it->second;
2667     else
2668         nRequestTime = 0;
2669     LogPrint(BCLog::NET, "askfor %s  %d (%s) peer=%d\n", inv.ToString(), nRequestTime, FormatISO8601Time(nRequestTime/1000000), id);
2670 
2671     // Make sure not to reuse time indexes to keep things in the same order
2672     int64_t nNow = GetTimeMicros() - 1000000;
2673     static int64_t nLastTime;
2674     ++nLastTime;
2675     nNow = std::max(nNow, nLastTime);
2676     nLastTime = nNow;
2677 
2678     // Each retry is 2 minutes after the last
2679     nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2680     if (it != mapAlreadyAskedFor.end())
2681         mapAlreadyAskedFor.update(it, nRequestTime);
2682     else
2683         mapAlreadyAskedFor.insert(std::make_pair(inv.hash, nRequestTime));
2684     mapAskFor.insert(std::make_pair(nRequestTime, inv));
2685 }
2686 
NodeFullyConnected(const CNode * pnode)2687 bool CConnman::NodeFullyConnected(const CNode* pnode)
2688 {
2689     return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
2690 }
2691 
PushMessage(CNode * pnode,CSerializedNetMsg && msg)2692 void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
2693 {
2694     size_t nMessageSize = msg.data.size();
2695     size_t nTotalSize = nMessageSize + CMessageHeader::HEADER_SIZE;
2696     LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n",  SanitizeString(msg.command.c_str()), nMessageSize, pnode->GetId());
2697 
2698     std::vector<unsigned char> serializedHeader;
2699     serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
2700     uint256 hash = Hash(msg.data.data(), msg.data.data() + nMessageSize);
2701     CMessageHeader hdr(Params().MessageStart(), msg.command.c_str(), nMessageSize);
2702     memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE);
2703 
2704     CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, serializedHeader, 0, hdr};
2705 
2706     size_t nBytesSent = 0;
2707     {
2708         LOCK(pnode->cs_vSend);
2709         bool optimisticSend(pnode->vSendMsg.empty());
2710 
2711         //log total amount of bytes per command
2712         pnode->mapSendBytesPerMsgCmd[msg.command] += nTotalSize;
2713         pnode->nSendSize += nTotalSize;
2714 
2715         if (pnode->nSendSize > nSendBufferMaxSize)
2716             pnode->fPauseSend = true;
2717         pnode->vSendMsg.push_back(std::move(serializedHeader));
2718         if (nMessageSize)
2719             pnode->vSendMsg.push_back(std::move(msg.data));
2720 
2721         // If write queue empty, attempt "optimistic write"
2722         if (optimisticSend == true)
2723             nBytesSent = SocketSendData(pnode);
2724     }
2725     if (nBytesSent)
2726         RecordBytesSent(nBytesSent);
2727 }
2728 
ForNode(NodeId id,std::function<bool (CNode * pnode)> func)2729 bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
2730 {
2731     CNode* found = nullptr;
2732     LOCK(cs_vNodes);
2733     for (auto&& pnode : vNodes) {
2734         if(pnode->GetId() == id) {
2735             found = pnode;
2736             break;
2737         }
2738     }
2739     return found != nullptr && NodeFullyConnected(found) && func(found);
2740 }
2741 
PoissonNextSendInbound(int64_t now,int average_interval_seconds)2742 int64_t CConnman::PoissonNextSendInbound(int64_t now, int average_interval_seconds)
2743 {
2744     if (m_next_send_inv_to_incoming < now) {
2745         // If this function were called from multiple threads simultaneously
2746         // it would possible that both update the next send variable, and return a different result to their caller.
2747         // This is not possible in practice as only the net processing thread invokes this function.
2748         m_next_send_inv_to_incoming = PoissonNextSend(now, average_interval_seconds);
2749     }
2750     return m_next_send_inv_to_incoming;
2751 }
2752 
PoissonNextSend(int64_t now,int average_interval_seconds)2753 int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
2754 {
2755     return now + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
2756 }
2757 
GetDeterministicRandomizer(uint64_t id) const2758 CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
2759 {
2760     return CSipHasher(nSeed0, nSeed1).Write(id);
2761 }
2762 
CalculateKeyedNetGroup(const CAddress & ad) const2763 uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const
2764 {
2765     std::vector<unsigned char> vchNetGroup(ad.GetGroup());
2766 
2767     return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
2768 }
2769