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