Bitcoin ABC 0.30.5
P2P Digital Currency
net.cpp
Go to the documentation of this file.
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 <addrdb.h>
13#include <addrman.h>
14#include <avalanche/avalanche.h>
15#include <banman.h>
16#include <clientversion.h>
17#include <common/args.h>
18#include <compat.h>
19#include <config.h>
20#include <consensus/consensus.h>
21#include <crypto/sha256.h>
22#include <dnsseeds.h>
23#include <i2p.h>
24#include <logging.h>
25#include <netaddress.h>
26#include <netbase.h>
27#include <node/ui_interface.h>
28#include <protocol.h>
29#include <random.h>
30#include <scheduler.h>
31#include <util/fs.h>
32#include <util/sock.h>
33#include <util/strencodings.h>
34#include <util/thread.h>
35#include <util/trace.h>
36#include <util/translation.h>
37
38#ifdef WIN32
39#include <cstring>
40#else
41#include <fcntl.h>
42#endif
43
44#ifdef USE_POLL
45#include <poll.h>
46#endif
47
48#include <algorithm>
49#include <array>
50#include <cmath>
51#include <cstdint>
52#include <functional>
53#include <limits>
54#include <optional>
55#include <unordered_map>
56
58static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS = 2;
59static_assert(MAX_BLOCK_RELAY_ONLY_ANCHORS <=
60 static_cast<size_t>(MAX_BLOCK_RELAY_ONLY_CONNECTIONS),
61 "MAX_BLOCK_RELAY_ONLY_ANCHORS must not exceed "
62 "MAX_BLOCK_RELAY_ONLY_CONNECTIONS.");
64const char *const ANCHORS_DATABASE_FILENAME = "anchors.dat";
65
66// How often to dump addresses to peers.dat
67static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
68
72static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
73
84static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
85static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
86// "many" vs "few" peers
87static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000;
88
90static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME{60 * 60 * 24};
91
92// We add a random period time (0 to 1 seconds) to feeler connections to prevent
93// synchronization.
94#define FEELER_SLEEP_WINDOW 1
95
99 BF_EXPLICIT = (1U << 0),
100 BF_REPORT_ERROR = (1U << 1),
105 BF_DONT_ADVERTISE = (1U << 2),
106};
107
108// The set of sockets cannot be modified while waiting
109// The sleep time needs to be small to avoid new sockets stalling
110static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
111
112const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
113
114// SHA256("netgroup")[0:8]
115static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
116// SHA256("localhostnonce")[0:8]
117static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
118// SHA256("localhostnonce")[8:16]
119static const uint64_t RANDOMIZER_ID_EXTRAENTROPY = 0x94b05d41679a4ff7ULL;
120// SHA256("addrcache")[0:8]
121static const uint64_t RANDOMIZER_ID_ADDRCACHE = 0x1cf2e4ddd306dda9ULL;
122//
123// Global state variables
124//
125bool fDiscover = true;
126bool fListen = true;
128std::map<CNetAddr, LocalServiceInfo>
130static bool vfLimited[NET_MAX] GUARDED_BY(g_maplocalhost_mutex) = {};
131
132void CConnman::AddAddrFetch(const std::string &strDest) {
134 m_addr_fetches.push_back(strDest);
135}
136
137uint16_t GetListenPort() {
138 // If -bind= is provided with ":port" part, use that (first one if multiple
139 // are provided).
140 for (const std::string &bind_arg : gArgs.GetArgs("-bind")) {
141 CService bind_addr;
142 constexpr uint16_t dummy_port = 0;
143
144 if (Lookup(bind_arg, bind_addr, dummy_port, /*fAllowLookup=*/false)) {
145 if (bind_addr.GetPort() != dummy_port) {
146 return bind_addr.GetPort();
147 }
148 }
149 }
150
151 // Otherwise, if -whitebind= without NetPermissionFlags::NoBan is provided,
152 // use that
153 // (-whitebind= is required to have ":port").
154 for (const std::string &whitebind_arg : gArgs.GetArgs("-whitebind")) {
155 NetWhitebindPermissions whitebind;
157 if (NetWhitebindPermissions::TryParse(whitebind_arg, whitebind,
158 error)) {
159 if (!NetPermissions::HasFlag(whitebind.m_flags,
161 return whitebind.m_service.GetPort();
162 }
163 }
164 }
165
166 // Otherwise, if -port= is provided, use that. Otherwise use the default
167 // port.
168 return static_cast<uint16_t>(
169 gArgs.GetIntArg("-port", Params().GetDefaultPort()));
170}
171
172// find 'best' local address for a particular peer
173bool GetLocal(CService &addr, const CNetAddr *paddrPeer) {
174 if (!fListen) {
175 return false;
176 }
177
178 int nBestScore = -1;
179 int nBestReachability = -1;
180 {
182 for (const auto &entry : mapLocalHost) {
183 int nScore = entry.second.nScore;
184 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
185 if (nReachability > nBestReachability ||
186 (nReachability == nBestReachability && nScore > nBestScore)) {
187 addr = CService(entry.first, entry.second.nPort);
188 nBestReachability = nReachability;
189 nBestScore = nScore;
190 }
191 }
192 }
193 return nBestScore >= 0;
194}
195
197static std::vector<CAddress>
198convertSeed6(const std::vector<SeedSpec6> &vSeedsIn) {
199 // It'll only connect to one or two seed nodes because once it connects,
200 // it'll get a pile of addresses with newer timestamps. Seed nodes are given
201 // a random 'last seen time' of between one and two weeks ago.
202 const auto one_week{7 * 24h};
203 std::vector<CAddress> vSeedsOut;
204 vSeedsOut.reserve(vSeedsIn.size());
206 for (const auto &seed_in : vSeedsIn) {
207 struct in6_addr ip;
208 memcpy(&ip, seed_in.addr, sizeof(ip));
209 CAddress addr(CService(ip, seed_in.port),
211 addr.nTime =
212 rng.rand_uniform_delay(Now<NodeSeconds>() - one_week, -one_week);
213 vSeedsOut.push_back(addr);
214 }
215 return vSeedsOut;
216}
217
218// Get best local address for a particular peer as a CService. Otherwise, return
219// the unroutable 0.0.0.0 but filled in with the normal parameters, since the IP
220// may be changed to a useful one by discovery.
223 CService addr;
224 if (GetLocal(addr, &addrPeer)) {
225 ret = CService{addr};
226 }
227 return ret;
228}
229
230static int GetnScore(const CService &addr) {
232 const auto it = mapLocalHost.find(addr);
233 return (it != mapLocalHost.end()) ? it->second.nScore : 0;
234}
235
236// Is our peer's addrLocal potentially useful as an external IP source?
238 CService addrLocal = pnode->GetAddrLocal();
239 return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
240 IsReachable(addrLocal.GetNetwork());
241}
242
243std::optional<CService> GetLocalAddrForPeer(CNode &node) {
244 CService addrLocal{GetLocalAddress(node.addr)};
245 if (gArgs.GetBoolArg("-addrmantest", false)) {
246 // use IPv4 loopback during addrmantest
247 addrLocal = CService(LookupNumeric("127.0.0.1", GetListenPort()));
248 }
249 // If discovery is enabled, sometimes give our peer the address it
250 // tells us that it sees us as in case it has a better idea of our
251 // address than we do.
254 (!addrLocal.IsRoutable() ||
255 rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0)) {
256 if (node.IsInboundConn()) {
257 // For inbound connections, assume both the address and the port
258 // as seen from the peer.
259 addrLocal = CService{node.GetAddrLocal()};
260 } else {
261 // For outbound connections, assume just the address as seen from
262 // the peer and leave the port in `addrLocal` as returned by
263 // `GetLocalAddress()` above. The peer has no way to observe our
264 // listening port when we have initiated the connection.
265 addrLocal.SetIP(node.GetAddrLocal());
266 }
267 }
268 if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false)) {
269 LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n",
270 addrLocal.ToString(), node.GetId());
271 return addrLocal;
272 }
273 // Address is unroutable. Don't advertise.
274 return std::nullopt;
275}
276
277// Learn a new local address.
278bool AddLocal(const CService &addr, int nScore) {
279 if (!addr.IsRoutable()) {
280 return false;
281 }
282
283 if (!fDiscover && nScore < LOCAL_MANUAL) {
284 return false;
285 }
286
287 if (!IsReachable(addr)) {
288 return false;
289 }
290
291 LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
292
293 {
295 const auto [it, is_newly_added] =
296 mapLocalHost.emplace(addr, LocalServiceInfo());
297 LocalServiceInfo &info = it->second;
298 if (is_newly_added || nScore >= info.nScore) {
299 info.nScore = nScore + !is_newly_added;
300 info.nPort = addr.GetPort();
301 }
302 }
303
304 return true;
305}
306
307bool AddLocal(const CNetAddr &addr, int nScore) {
308 return AddLocal(CService(addr, GetListenPort()), nScore);
309}
310
311void RemoveLocal(const CService &addr) {
313 LogPrintf("RemoveLocal(%s)\n", addr.ToString());
314 mapLocalHost.erase(addr);
315}
316
317void SetReachable(enum Network net, bool reachable) {
318 if (net == NET_UNROUTABLE || net == NET_INTERNAL) {
319 return;
320 }
322 vfLimited[net] = !reachable;
323}
324
325bool IsReachable(enum Network net) {
327 return !vfLimited[net];
328}
329
330bool IsReachable(const CNetAddr &addr) {
331 return IsReachable(addr.GetNetwork());
332}
333
335bool SeenLocal(const CService &addr) {
337 const auto it = mapLocalHost.find(addr);
338 if (it == mapLocalHost.end()) {
339 return false;
340 }
341 ++it->second.nScore;
342 return true;
343}
344
346bool IsLocal(const CService &addr) {
348 return mapLocalHost.count(addr) > 0;
349}
350
353 for (CNode *pnode : m_nodes) {
354 if (static_cast<CNetAddr>(pnode->addr) == ip) {
355 return pnode;
356 }
357 }
358 return nullptr;
359}
360
363 for (CNode *pnode : m_nodes) {
364 if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
365 return pnode;
366 }
367 }
368 return nullptr;
369}
370
371CNode *CConnman::FindNode(const std::string &addrName) {
373 for (CNode *pnode : m_nodes) {
374 if (pnode->m_addr_name == addrName) {
375 return pnode;
376 }
377 }
378 return nullptr;
379}
380
383 for (CNode *pnode : m_nodes) {
384 if (static_cast<CService>(pnode->addr) == addr) {
385 return pnode;
386 }
387 }
388 return nullptr;
389}
390
392 return FindNode(static_cast<CNetAddr>(addr)) ||
393 FindNode(addr.ToStringIPPort());
394}
395
396bool CConnman::CheckIncomingNonce(uint64_t nonce) {
398 for (const CNode *pnode : m_nodes) {
399 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() &&
400 pnode->GetLocalNonce() == nonce) {
401 return false;
402 }
403 }
404 return true;
405}
406
409 CAddress addr_bind;
410 struct sockaddr_storage sockaddr_bind;
411 socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
412 if (sock != INVALID_SOCKET) {
413 if (!getsockname(sock, (struct sockaddr *)&sockaddr_bind,
414 &sockaddr_bind_len)) {
415 addr_bind.SetSockAddr((const struct sockaddr *)&sockaddr_bind);
416 } else {
417 LogPrint(BCLog::NET, "Warning: getsockname failed\n");
418 }
419 }
420 return addr_bind;
421}
422
423CNode *CConnman::ConnectNode(CAddress addrConnect, const char *pszDest,
424 bool fCountFailure, ConnectionType conn_type) {
425 assert(conn_type != ConnectionType::INBOUND);
426
427 if (pszDest == nullptr) {
428 if (IsLocal(addrConnect)) {
429 return nullptr;
430 }
431
432 // Look for an existing connection
433 CNode *pnode = FindNode(static_cast<CService>(addrConnect));
434 if (pnode) {
435 LogPrintf("Failed to open new connection, already connected\n");
436 return nullptr;
437 }
438 }
439
440 LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
441 pszDest ? pszDest : addrConnect.ToString(),
442 Ticks<HoursDouble>(
443 pszDest ? 0h : Now<NodeSeconds>() - addrConnect.nTime));
444
445 // Resolve
446 const uint16_t default_port{pszDest != nullptr
447 ? Params().GetDefaultPort(pszDest)
448 : Params().GetDefaultPort()};
449 if (pszDest) {
450 std::vector<CService> resolved;
451 if (Lookup(pszDest, resolved, default_port,
452 fNameLookup && !HaveNameProxy(), 256) &&
453 !resolved.empty()) {
454 addrConnect =
455 CAddress(resolved[GetRand(resolved.size())], NODE_NONE);
456 if (!addrConnect.IsValid()) {
458 "Resolver returned invalid address %s for %s\n",
459 addrConnect.ToString(), pszDest);
460 return nullptr;
461 }
462 // It is possible that we already have a connection to the IP/port
463 // pszDest resolved to. In that case, drop the connection that was
464 // just created.
466 CNode *pnode = FindNode(static_cast<CService>(addrConnect));
467 if (pnode) {
468 LogPrintf("Failed to open new connection, already connected\n");
469 return nullptr;
470 }
471 }
472 }
473
474 // Connect
475 bool connected = false;
476 std::unique_ptr<Sock> sock;
477 proxyType proxy;
478 CAddress addr_bind;
479 assert(!addr_bind.IsValid());
480
481 if (addrConnect.IsValid()) {
482 bool proxyConnectionFailed = false;
483
484 if (addrConnect.GetNetwork() == NET_I2P &&
485 m_i2p_sam_session.get() != nullptr) {
486 i2p::Connection conn;
487 if (m_i2p_sam_session->Connect(addrConnect, conn,
488 proxyConnectionFailed)) {
489 connected = true;
490 sock = std::move(conn.sock);
491 addr_bind = CAddress{conn.me, NODE_NONE};
492 }
493 } else if (GetProxy(addrConnect.GetNetwork(), proxy)) {
494 sock = CreateSock(proxy.proxy);
495 if (!sock) {
496 return nullptr;
497 }
498 connected = ConnectThroughProxy(
499 proxy, addrConnect.ToStringIP(), addrConnect.GetPort(), *sock,
500 nConnectTimeout, proxyConnectionFailed);
501 } else {
502 // no proxy needed (none set for target network)
503 sock = CreateSock(addrConnect);
504 if (!sock) {
505 return nullptr;
506 }
507 connected =
508 ConnectSocketDirectly(addrConnect, *sock, nConnectTimeout,
509 conn_type == ConnectionType::MANUAL);
510 }
511 if (!proxyConnectionFailed) {
512 // If a connection to the node was attempted, and failure (if any)
513 // is not caused by a problem connecting to the proxy, mark this as
514 // an attempt.
515 addrman.Attempt(addrConnect, fCountFailure);
516 }
517 } else if (pszDest && GetNameProxy(proxy)) {
518 sock = CreateSock(proxy.proxy);
519 if (!sock) {
520 return nullptr;
521 }
522 std::string host;
523 uint16_t port{default_port};
524 SplitHostPort(std::string(pszDest), port, host);
525 bool proxyConnectionFailed;
526 connected = ConnectThroughProxy(proxy, host, port, *sock,
527 nConnectTimeout, proxyConnectionFailed);
528 }
529 if (!connected) {
530 return nullptr;
531 }
532
534 std::vector<NetWhitelistPermissions> whitelist_permissions =
535 conn_type == ConnectionType::MANUAL
537 : std::vector<NetWhitelistPermissions>{};
538 AddWhitelistPermissionFlags(permission_flags, addrConnect,
539 whitelist_permissions);
540
541 // Add node
542 NodeId id = GetNewNodeId();
544 .Write(id)
545 .Finalize();
546 uint64_t extra_entropy =
548 .Write(id)
549 .Finalize();
550 if (!addr_bind.IsValid()) {
551 addr_bind = GetBindAddress(sock->Get());
552 }
553 CNode *pnode = new CNode(
554 id, std::move(sock), addrConnect, CalculateKeyedNetGroup(addrConnect),
555 nonce, extra_entropy, addr_bind, pszDest ? pszDest : "", conn_type,
556 /* inbound_onion */ false,
557 CNodeOptions{.permission_flags = permission_flags});
558 pnode->AddRef();
559
560 // We're making a new connection, harvest entropy from the time (and our
561 // peer count)
562 RandAddEvent(uint32_t(id));
563
564 return pnode;
565}
566
568 fDisconnect = true;
570 if (m_sock) {
571 LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
572 m_sock.reset();
573 }
574}
575
577 NetPermissionFlags &flags, const CNetAddr &addr,
578 const std::vector<NetWhitelistPermissions> &ranges) const {
579 for (const auto &subnet : ranges) {
580 if (subnet.m_subnet.Match(addr)) {
581 NetPermissions::AddFlag(flags, subnet.m_flags);
582 }
583 }
588 }
589 if (whitelist_relay) {
591 }
594 }
595}
596
598 switch (conn_type) {
600 return "inbound";
602 return "manual";
604 return "feeler";
606 return "outbound-full-relay";
608 return "block-relay-only";
610 return "addr-fetch";
612 return "avalanche";
613 } // no default case, so the compiler can warn about missing cases
614
615 assert(false);
616}
617
621 return addrLocal;
622}
623
624void CNode::SetAddrLocal(const CService &addrLocalIn) {
627 if (addrLocal.IsValid()) {
628 error("Addr local already set for node: %i. Refusing to change from %s "
629 "to %s",
630 id, addrLocal.ToString(), addrLocalIn.ToString());
631 } else {
632 addrLocal = addrLocalIn;
633 }
634}
635
638}
639
641 stats.nodeid = this->GetId();
642 stats.addr = addr;
643 stats.addrBind = addrBind;
645 stats.m_last_send = m_last_send;
646 stats.m_last_recv = m_last_recv;
650 stats.m_connected = m_connected;
651 stats.nTimeOffset = nTimeOffset;
652 stats.m_addr_name = m_addr_name;
653 stats.nVersion = nVersion;
654 {
656 stats.cleanSubVer = cleanSubVer;
657 }
658 stats.fInbound = IsInboundConn();
661 {
662 LOCK(cs_vSend);
663 stats.mapSendBytesPerMsgCmd = mapSendBytesPerMsgCmd;
664 stats.nSendBytes = nSendBytes;
665 }
666 {
667 LOCK(cs_vRecv);
668 stats.mapRecvBytesPerMsgCmd = mapRecvBytesPerMsgCmd;
669 stats.nRecvBytes = nRecvBytes;
670 }
672
675
676 // Leave string empty if addrLocal invalid (not filled in yet)
677 CService addrLocalUnlocked = GetAddrLocal();
678 stats.addrLocal =
679 addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
680
681 stats.m_conn_type = m_conn_type;
682
684 ? std::make_optional(getAvailabilityScore())
685 : std::nullopt;
686}
687
689 bool &complete) {
690 complete = false;
691 const auto time = GetTime<std::chrono::microseconds>();
692 LOCK(cs_vRecv);
693 m_last_recv = std::chrono::duration_cast<std::chrono::seconds>(time);
694 nRecvBytes += msg_bytes.size();
695 while (msg_bytes.size() > 0) {
696 // Absorb network data.
697 int handled = m_deserializer->Read(config, msg_bytes);
698 if (handled < 0) {
699 return false;
700 }
701
702 if (m_deserializer->Complete()) {
703 // decompose a transport agnostic CNetMessage from the deserializer
704 CNetMessage msg = m_deserializer->GetMessage(config, time);
705
706 // Store received bytes per message command to prevent a memory DOS,
707 // only allow valid commands.
708 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.m_type);
709 if (i == mapRecvBytesPerMsgCmd.end()) {
710 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
711 }
712
713 assert(i != mapRecvBytesPerMsgCmd.end());
714 i->second += msg.m_raw_message_size;
715
716 // push the message to the process queue,
717 vRecvMsg.push_back(std::move(msg));
718
719 complete = true;
720 }
721 }
722
723 return true;
724}
725
727 Span<const uint8_t> msg_bytes) {
728 // copy data to temporary parsing buffer
729 uint32_t nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
730 uint32_t nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
731
732 memcpy(&hdrbuf[nHdrPos], msg_bytes.data(), nCopy);
733 nHdrPos += nCopy;
734
735 // if header incomplete, exit
737 return nCopy;
738 }
739
740 // deserialize to CMessageHeader
741 try {
742 hdrbuf >> hdr;
743 } catch (const std::exception &) {
744 return -1;
745 }
746
747 // Reject oversized messages
748 if (hdr.IsOversized(config)) {
749 LogPrint(BCLog::NET, "Oversized header detected\n");
750 return -1;
751 }
752
753 // switch state to reading message data
754 in_data = true;
755
756 return nCopy;
757}
758
760 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
761 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
762
763 if (vRecv.size() < nDataPos + nCopy) {
764 // Allocate up to 256 KiB ahead, but never more than the total message
765 // size.
766 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
767 }
768
769 hasher.Write(msg_bytes.first(nCopy));
770 memcpy(&vRecv[nDataPos], msg_bytes.data(), nCopy);
771 nDataPos += nCopy;
772
773 return nCopy;
774}
775
777 assert(Complete());
778 if (data_hash.IsNull()) {
780 }
781 return data_hash;
782}
783
786 const std::chrono::microseconds time) {
787 // decompose a single CNetMessage from the TransportDeserializer
788 CNetMessage msg(std::move(vRecv));
789
790 // store state about valid header, netmagic and checksum
791 msg.m_valid_header = hdr.IsValid(config);
792 // FIXME Split CheckHeaderMagicAndCommand() into CheckHeaderMagic() and
793 // CheckCommand() to prevent the net magic check code duplication.
794 msg.m_valid_netmagic =
795 (memcmp(std::begin(hdr.pchMessageStart),
796 std::begin(config.GetChainParams().NetMagic()),
798 uint256 hash = GetMessageHash();
799
800 // store command string, payload size
801 msg.m_type = hdr.GetCommand();
804
805 // We just received a message off the wire, harvest entropy from the time
806 // (and the message checksum)
807 RandAddEvent(ReadLE32(hash.begin()));
808
809 msg.m_valid_checksum = (memcmp(hash.begin(), hdr.pchChecksum,
811
812 if (!msg.m_valid_checksum) {
814 "CHECKSUM ERROR (%s, %u bytes), expected %s was %s\n",
818 }
819
820 // store receive time
821 msg.m_time = time;
822
823 // reset the network deserializer (prepare for the next message)
824 Reset();
825 return msg;
826}
827
830 std::vector<uint8_t> &header) {
831 // create dbl-sha256 checksum
832 uint256 hash = Hash(msg.data);
833
834 // create header
835 CMessageHeader hdr(config.GetChainParams().NetMagic(), msg.m_type.c_str(),
836 msg.data.size());
838
839 // serialize header
840 header.reserve(CMessageHeader::HEADER_SIZE);
842}
843
844std::pair<size_t, bool> CConnman::SocketSendData(CNode &node) const {
845 size_t nSentSize = 0;
846 size_t nMsgCount = 0;
847
848 for (const auto &data : node.vSendMsg) {
849 assert(data.size() > node.nSendOffset);
850 int nBytes = 0;
851
852 {
853 LOCK(node.m_sock_mutex);
854 if (!node.m_sock) {
855 break;
856 }
857
858 nBytes = node.m_sock->Send(
859 reinterpret_cast<const char *>(data.data()) + node.nSendOffset,
860 data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
861 }
862
863 if (nBytes == 0) {
864 // couldn't send anything at all
865 break;
866 }
867
868 if (nBytes < 0) {
869 // error
870 int nErr = WSAGetLastError();
871 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE &&
872 nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
873 LogPrint(BCLog::NET, "socket send error for peer=%d: %s\n",
874 node.GetId(), NetworkErrorString(nErr));
875 node.CloseSocketDisconnect();
876 }
877
878 break;
879 }
880
881 assert(nBytes > 0);
882 node.m_last_send = GetTime<std::chrono::seconds>();
883 node.nSendBytes += nBytes;
884 node.nSendOffset += nBytes;
885 nSentSize += nBytes;
886 if (node.nSendOffset != data.size()) {
887 // could not send full message; stop sending more
888 break;
889 }
890
891 node.nSendOffset = 0;
892 node.nSendSize -= data.size();
893 node.fPauseSend = node.nSendSize > nSendBufferMaxSize;
894 nMsgCount++;
895 }
896
897 node.vSendMsg.erase(node.vSendMsg.begin(),
898 node.vSendMsg.begin() + nMsgCount);
899
900 if (node.vSendMsg.empty()) {
901 assert(node.nSendOffset == 0);
902 assert(node.nSendSize == 0);
903 }
904
905 return {nSentSize, !node.vSendMsg.empty()};
906}
907
909 const NodeEvictionCandidate &b) {
910 return a.m_min_ping_time > b.m_min_ping_time;
911}
912
914 const NodeEvictionCandidate &b) {
915 return a.m_connected > b.m_connected;
916}
917
919 const NodeEvictionCandidate &b) {
920 return a.nKeyedNetGroup < b.nKeyedNetGroup;
921}
922
924 const NodeEvictionCandidate &b) {
925 // There is a fall-through here because it is common for a node to have many
926 // peers which have not yet relayed a block.
929 }
930
932 return b.fRelevantServices;
933 }
934
935 return a.m_connected > b.m_connected;
936}
937
939 const NodeEvictionCandidate &b) {
940 // There is a fall-through here because it is common for a node to have more
941 // than a few peers that have not yet relayed txn.
942 if (a.m_last_tx_time != b.m_last_tx_time) {
943 return a.m_last_tx_time < b.m_last_tx_time;
944 }
945
946 if (a.m_relay_txs != b.m_relay_txs) {
947 return b.m_relay_txs;
948 }
949
950 if (a.fBloomFilter != b.fBloomFilter) {
951 return a.fBloomFilter;
952 }
953
954 return a.m_connected > b.m_connected;
955}
956
958 const NodeEvictionCandidate &b) {
959 // There is a fall-through here because it is common for a node to have more
960 // than a few peers that have not yet relayed proofs. This fallback is also
961 // used in the case avalanche is not enabled.
964 }
965
966 return a.m_connected > b.m_connected;
967}
968
969// Pick out the potential block-relay only peers, and sort them by last block
970// time.
972 const NodeEvictionCandidate &b) {
973 if (a.m_relay_txs != b.m_relay_txs) {
974 return a.m_relay_txs;
975 }
976
979 }
980
982 return b.fRelevantServices;
983 }
984
985 return a.m_connected > b.m_connected;
986}
987
989 const NodeEvictionCandidate &b) {
990 // Equality can happen if the nodes have no score or it has not been
991 // computed yet.
994 }
995
996 return a.m_connected > b.m_connected;
997}
998
1010 const bool m_is_local;
1012 CompareNodeNetworkTime(bool is_local, Network network)
1013 : m_is_local(is_local), m_network(network) {}
1015 const NodeEvictionCandidate &b) const {
1016 if (m_is_local && a.m_is_local != b.m_is_local) {
1017 return b.m_is_local;
1018 }
1019 if ((a.m_network == m_network) != (b.m_network == m_network)) {
1020 return b.m_network == m_network;
1021 }
1022 return a.m_connected > b.m_connected;
1023 };
1024};
1025
1028template <typename T, typename Comparator>
1030 std::vector<T> &elements, Comparator comparator, size_t k,
1031 std::function<bool(const NodeEvictionCandidate &)> predicate =
1032 [](const NodeEvictionCandidate &n) { return true; }) {
1033 std::sort(elements.begin(), elements.end(), comparator);
1034 size_t eraseSize = std::min(k, elements.size());
1035 elements.erase(
1036 std::remove_if(elements.end() - eraseSize, elements.end(), predicate),
1037 elements.end());
1038}
1039
1041 std::vector<NodeEvictionCandidate> &eviction_candidates) {
1042 // Protect the half of the remaining nodes which have been connected the
1043 // longest. This replicates the non-eviction implicit behavior, and
1044 // precludes attacks that start later.
1045 // To promote the diversity of our peer connections, reserve up to half of
1046 // these protected spots for Tor/onion, localhost and I2P peers, even if
1047 // they're not the longest uptime overall. This helps protect these
1048 // higher-latency peers that tend to be otherwise disadvantaged under our
1049 // eviction criteria.
1050 const size_t initial_size = eviction_candidates.size();
1051 const size_t total_protect_size{initial_size / 2};
1052
1053 // Disadvantaged networks to protect: I2P, localhost and Tor/onion. In case
1054 // of equal counts, earlier array members have first opportunity to recover
1055 // unused slots from the previous iteration.
1056 struct Net {
1057 bool is_local;
1058 Network id;
1059 size_t count;
1060 };
1061 std::array<Net, 3> networks{{{false, NET_I2P, 0},
1062 {/* localhost */ true, NET_MAX, 0},
1063 {false, NET_ONION, 0}}};
1064
1065 // Count and store the number of eviction candidates per network.
1066 for (Net &n : networks) {
1067 n.count = std::count_if(
1068 eviction_candidates.cbegin(), eviction_candidates.cend(),
1069 [&n](const NodeEvictionCandidate &c) {
1070 return n.is_local ? c.m_is_local : c.m_network == n.id;
1071 });
1072 }
1073 // Sort `networks` by ascending candidate count, to give networks having
1074 // fewer candidates the first opportunity to recover unused protected slots
1075 // from the previous iteration.
1076 std::stable_sort(networks.begin(), networks.end(),
1077 [](Net a, Net b) { return a.count < b.count; });
1078
1079 // Protect up to 25% of the eviction candidates by disadvantaged network.
1080 const size_t max_protect_by_network{total_protect_size / 2};
1081 size_t num_protected{0};
1082
1083 while (num_protected < max_protect_by_network) {
1084 // Count the number of disadvantaged networks from which we have peers
1085 // to protect.
1086 auto num_networks = std::count_if(networks.begin(), networks.end(),
1087 [](const Net &n) { return n.count; });
1088 if (num_networks == 0) {
1089 break;
1090 }
1091 const size_t disadvantaged_to_protect{max_protect_by_network -
1092 num_protected};
1093 const size_t protect_per_network{std::max(
1094 disadvantaged_to_protect / num_networks, static_cast<size_t>(1))};
1095
1096 // Early exit flag if there are no remaining candidates by disadvantaged
1097 // network.
1098 bool protected_at_least_one{false};
1099
1100 for (Net &n : networks) {
1101 if (n.count == 0) {
1102 continue;
1103 }
1104 const size_t before = eviction_candidates.size();
1106 eviction_candidates, CompareNodeNetworkTime(n.is_local, n.id),
1107 protect_per_network, [&n](const NodeEvictionCandidate &c) {
1108 return n.is_local ? c.m_is_local : c.m_network == n.id;
1109 });
1110 const size_t after = eviction_candidates.size();
1111 if (before > after) {
1112 protected_at_least_one = true;
1113 const size_t delta{before - after};
1114 num_protected += delta;
1115 if (num_protected >= max_protect_by_network) {
1116 break;
1117 }
1118 n.count -= delta;
1119 }
1120 }
1121 if (!protected_at_least_one) {
1122 break;
1123 }
1124 }
1125
1126 // Calculate how many we removed, and update our total number of peers that
1127 // we want to protect based on uptime accordingly.
1128 assert(num_protected == initial_size - eviction_candidates.size());
1129 const size_t remaining_to_protect{total_protect_size - num_protected};
1131 remaining_to_protect);
1132}
1133
1134[[nodiscard]] std::optional<NodeId>
1135SelectNodeToEvict(std::vector<NodeEvictionCandidate> &&vEvictionCandidates) {
1136 // Protect connections with certain characteristics
1137
1138 // Deterministically select 4 peers to protect by netgroup.
1139 // An attacker cannot predict which netgroups will be protected
1140 EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
1141 // Protect the 8 nodes with the lowest minimum ping time.
1142 // An attacker cannot manipulate this metric without physically moving nodes
1143 // closer to the target.
1144 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
1145 // Protect 4 nodes that most recently sent us novel transactions accepted
1146 // into our mempool. An attacker cannot manipulate this metric without
1147 // performing useful work.
1148 EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
1149 // Protect 4 nodes that most recently sent us novel proofs accepted
1150 // into our proof pool. An attacker cannot manipulate this metric without
1151 // performing useful work.
1152 // TODO this filter must happen before the last tx time once avalanche is
1153 // enabled for pre-consensus.
1154 EraseLastKElements(vEvictionCandidates, CompareNodeProofTime, 4);
1155 // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
1156 EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
1157 [](const NodeEvictionCandidate &n) {
1158 return !n.m_relay_txs && n.fRelevantServices;
1159 });
1160
1161 // Protect 4 nodes that most recently sent us novel blocks.
1162 // An attacker cannot manipulate this metric without performing useful work.
1163 EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
1164
1165 // Protect up to 128 nodes that have the highest avalanche availability
1166 // score.
1167 EraseLastKElements(vEvictionCandidates, CompareNodeAvailabilityScore, 128,
1168 [](NodeEvictionCandidate const &n) {
1169 return n.availabilityScore > 0.;
1170 });
1171
1172 // Protect some of the remaining eviction candidates by ratios of desirable
1173 // or disadvantaged characteristics.
1174 ProtectEvictionCandidatesByRatio(vEvictionCandidates);
1175
1176 if (vEvictionCandidates.empty()) {
1177 return std::nullopt;
1178 }
1179
1180 // If any remaining peers are preferred for eviction consider only them.
1181 // This happens after the other preferences since if a peer is really the
1182 // best by other criteria (esp relaying blocks)
1183 // then we probably don't want to evict it no matter what.
1184 if (std::any_of(
1185 vEvictionCandidates.begin(), vEvictionCandidates.end(),
1186 [](NodeEvictionCandidate const &n) { return n.prefer_evict; })) {
1187 vEvictionCandidates.erase(
1188 std::remove_if(
1189 vEvictionCandidates.begin(), vEvictionCandidates.end(),
1190 [](NodeEvictionCandidate const &n) { return !n.prefer_evict; }),
1191 vEvictionCandidates.end());
1192 }
1193
1194 // Identify the network group with the most connections and youngest member.
1195 // (vEvictionCandidates is already sorted by reverse connect time)
1196 uint64_t naMostConnections;
1197 unsigned int nMostConnections = 0;
1198 std::chrono::seconds nMostConnectionsTime{0};
1199 std::map<uint64_t, std::vector<NodeEvictionCandidate>> mapNetGroupNodes;
1200 for (const NodeEvictionCandidate &node : vEvictionCandidates) {
1201 std::vector<NodeEvictionCandidate> &group =
1202 mapNetGroupNodes[node.nKeyedNetGroup];
1203 group.push_back(node);
1204 const auto grouptime{group[0].m_connected};
1205 size_t group_size = group.size();
1206 if (group_size > nMostConnections ||
1207 (group_size == nMostConnections &&
1208 grouptime > nMostConnectionsTime)) {
1209 nMostConnections = group_size;
1210 nMostConnectionsTime = grouptime;
1211 naMostConnections = node.nKeyedNetGroup;
1212 }
1213 }
1214
1215 // Reduce to the network group with the most connections
1216 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1217
1218 // Disconnect from the network group with the most connections
1219 return vEvictionCandidates.front().id;
1220}
1221
1231 std::vector<NodeEvictionCandidate> vEvictionCandidates;
1232 {
1234 for (const CNode *node : m_nodes) {
1235 if (node->HasPermission(NetPermissionFlags::NoBan)) {
1236 continue;
1237 }
1238 if (!node->IsInboundConn()) {
1239 continue;
1240 }
1241 if (node->fDisconnect) {
1242 continue;
1243 }
1244
1245 NodeEvictionCandidate candidate = {
1246 node->GetId(),
1247 node->m_connected,
1248 node->m_min_ping_time,
1249 node->m_last_block_time,
1250 node->m_last_proof_time,
1251 node->m_last_tx_time,
1252 node->m_has_all_wanted_services,
1253 node->m_relays_txs.load(),
1254 node->m_bloom_filter_loaded.load(),
1255 node->nKeyedNetGroup,
1256 node->m_prefer_evict,
1257 node->addr.IsLocal(),
1258 node->ConnectedThroughNetwork(),
1259 node->m_avalanche_enabled
1260 ? node->getAvailabilityScore()
1261 : -std::numeric_limits<double>::infinity()};
1262 vEvictionCandidates.push_back(candidate);
1263 }
1264 }
1265 const std::optional<NodeId> node_id_to_evict =
1266 SelectNodeToEvict(std::move(vEvictionCandidates));
1267 if (!node_id_to_evict) {
1268 return false;
1269 }
1271 for (CNode *pnode : m_nodes) {
1272 if (pnode->GetId() == *node_id_to_evict) {
1273 LogPrint(
1274 BCLog::NET,
1275 "selected %s connection for eviction peer=%d; disconnecting\n",
1276 pnode->ConnectionTypeAsString(), pnode->GetId());
1277 pnode->fDisconnect = true;
1278 return true;
1279 }
1280 }
1281 return false;
1282}
1283
1284void CConnman::AcceptConnection(const ListenSocket &hListenSocket) {
1285 struct sockaddr_storage sockaddr;
1286 socklen_t len = sizeof(sockaddr);
1287 auto sock = hListenSocket.sock->Accept((struct sockaddr *)&sockaddr, &len);
1288 CAddress addr;
1289
1290 if (!sock) {
1291 const int nErr = WSAGetLastError();
1292 if (nErr != WSAEWOULDBLOCK) {
1293 LogPrintf("socket error accept failed: %s\n",
1294 NetworkErrorString(nErr));
1295 }
1296 return;
1297 }
1298
1299 if (!addr.SetSockAddr((const struct sockaddr *)&sockaddr)) {
1300 LogPrintf("Warning: Unknown socket family\n");
1301 }
1302
1303 const CAddress addr_bind = GetBindAddress(sock->Get());
1304
1306 hListenSocket.AddSocketPermissionFlags(permission_flags);
1307
1308 CreateNodeFromAcceptedSocket(std::move(sock), permission_flags, addr_bind,
1309 addr);
1310}
1311
1312void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock> &&sock,
1313 NetPermissionFlags permission_flags,
1314 const CAddress &addr_bind,
1315 const CAddress &addr) {
1316 int nInbound = 0;
1317 int nMaxInbound = nMaxConnections - m_max_outbound;
1318
1319 AddWhitelistPermissionFlags(permission_flags, addr,
1321
1322 {
1324 for (const CNode *pnode : m_nodes) {
1325 if (pnode->IsInboundConn()) {
1326 nInbound++;
1327 }
1328 }
1329 }
1330
1331 if (!fNetworkActive) {
1333 "connection from %s dropped: not accepting new connections\n",
1334 addr.ToString());
1335 return;
1336 }
1337
1338 if (!IsSelectableSocket(sock->Get())) {
1339 LogPrintf("connection from %s dropped: non-selectable socket\n",
1340 addr.ToString());
1341 return;
1342 }
1343
1344 // According to the internet TCP_NODELAY is not carried into accepted
1345 // sockets on all platforms. Set it again here just to be sure.
1346 SetSocketNoDelay(sock->Get());
1347
1348 // Don't accept connections from banned peers.
1349 bool banned = m_banman && m_banman->IsBanned(addr);
1350 if (!NetPermissions::HasFlag(permission_flags, NetPermissionFlags::NoBan) &&
1351 banned) {
1352 LogPrint(BCLog::NET, "connection from %s dropped (banned)\n",
1353 addr.ToString());
1354 return;
1355 }
1356
1357 // Only accept connections from discouraged peers if our inbound slots
1358 // aren't (almost) full.
1359 bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1360 if (!NetPermissions::HasFlag(permission_flags, NetPermissionFlags::NoBan) &&
1361 nInbound + 1 >= nMaxInbound && discouraged) {
1362 LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n",
1363 addr.ToString());
1364 return;
1365 }
1366
1367 if (nInbound >= nMaxInbound) {
1368 if (!AttemptToEvictConnection()) {
1369 // No connection to evict, disconnect the new connection
1370 LogPrint(BCLog::NET, "failed to find an eviction candidate - "
1371 "connection dropped (full)\n");
1372 return;
1373 }
1374 }
1375
1376 NodeId id = GetNewNodeId();
1378 .Write(id)
1379 .Finalize();
1380 uint64_t extra_entropy =
1382 .Write(id)
1383 .Finalize();
1384
1385 const bool inbound_onion =
1386 std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) !=
1387 m_onion_binds.end();
1388 CNode *pnode = new CNode(
1389 id, std::move(sock), addr, CalculateKeyedNetGroup(addr), nonce,
1390 extra_entropy, addr_bind, "", ConnectionType::INBOUND, inbound_onion,
1392 .permission_flags = permission_flags,
1393 .prefer_evict = discouraged,
1394 });
1395 pnode->AddRef();
1396 for (auto interface : m_msgproc) {
1397 interface->InitializeNode(*config, *pnode, nLocalServices);
1398 }
1399
1400 LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1401
1402 {
1404 m_nodes.push_back(pnode);
1405 }
1406
1407 // We received a new connection, harvest entropy from the time (and our peer
1408 // count)
1409 RandAddEvent(uint32_t(id));
1410}
1411
1412bool CConnman::AddConnection(const std::string &address,
1413 ConnectionType conn_type) {
1414 std::optional<int> max_connections;
1415 switch (conn_type) {
1418 return false;
1420 max_connections = m_max_outbound_full_relay;
1421 break;
1423 max_connections = m_max_outbound_block_relay;
1424 break;
1425 // no limit for ADDR_FETCH because -seednode has no limit either
1427 break;
1428 // no limit for FEELER connections since they're short-lived
1430 break;
1432 max_connections = m_max_avalanche_outbound;
1433 break;
1434 } // no default case, so the compiler can warn about missing cases
1435
1436 // Count existing connections
1437 int existing_connections =
1439 return std::count_if(
1440 m_nodes.begin(), m_nodes.end(), [conn_type](CNode *node) {
1441 return node->m_conn_type == conn_type;
1442 }););
1443
1444 // Max connections of specified type already exist
1445 if (max_connections != std::nullopt &&
1446 existing_connections >= max_connections) {
1447 return false;
1448 }
1449
1450 // Max total outbound connections already exist
1451 CSemaphoreGrant grant(*semOutbound, true);
1452 if (!grant) {
1453 return false;
1454 }
1455
1456 OpenNetworkConnection(CAddress(), false, &grant, address.c_str(),
1457 conn_type);
1458 return true;
1459}
1460
1462 {
1464
1465 if (!fNetworkActive) {
1466 // Disconnect any connected nodes
1467 for (CNode *pnode : m_nodes) {
1468 if (!pnode->fDisconnect) {
1470 "Network not active, dropping peer=%d\n",
1471 pnode->GetId());
1472 pnode->fDisconnect = true;
1473 }
1474 }
1475 }
1476
1477 // Disconnect unused nodes
1478 std::vector<CNode *> nodes_copy = m_nodes;
1479 for (CNode *pnode : nodes_copy) {
1480 if (pnode->fDisconnect) {
1481 // remove from m_nodes
1482 m_nodes.erase(remove(m_nodes.begin(), m_nodes.end(), pnode),
1483 m_nodes.end());
1484
1485 // release outbound grant (if any)
1486 pnode->grantOutbound.Release();
1487
1488 // close socket and cleanup
1489 pnode->CloseSocketDisconnect();
1490
1491 // hold in disconnected pool until all refs are released
1492 pnode->Release();
1493 m_nodes_disconnected.push_back(pnode);
1494 }
1495 }
1496 }
1497 {
1498 // Delete disconnected nodes
1499 std::list<CNode *> nodes_disconnected_copy = m_nodes_disconnected;
1500 for (CNode *pnode : nodes_disconnected_copy) {
1501 // Destroy the object only after other threads have stopped using
1502 // it.
1503 if (pnode->GetRefCount() <= 0) {
1504 m_nodes_disconnected.remove(pnode);
1505 DeleteNode(pnode);
1506 }
1507 }
1508 }
1509}
1510
1512 size_t nodes_size;
1513 {
1515 nodes_size = m_nodes.size();
1516 }
1517 if (nodes_size != nPrevNodeCount) {
1518 nPrevNodeCount = nodes_size;
1519 if (m_client_interface) {
1520 m_client_interface->NotifyNumConnectionsChanged(nodes_size);
1521 }
1522 }
1523}
1524
1526 std::chrono::seconds now) const {
1527 return node.m_connected + m_peer_connect_timeout < now;
1528}
1529
1531 // Tests that see disconnects after using mocktime can start nodes with a
1532 // large timeout. For example, -peertimeout=999999999.
1533 const auto now{GetTime<std::chrono::seconds>()};
1534 const auto last_send{node.m_last_send.load()};
1535 const auto last_recv{node.m_last_recv.load()};
1536
1537 if (!ShouldRunInactivityChecks(node, now)) {
1538 return false;
1539 }
1540
1541 if (last_recv.count() == 0 || last_send.count() == 0) {
1543 "socket no message in first %i seconds, %d %d peer=%d\n",
1544 count_seconds(m_peer_connect_timeout), last_recv.count() != 0,
1545 last_send.count() != 0, node.GetId());
1546 return true;
1547 }
1548
1549 if (now > last_send + TIMEOUT_INTERVAL) {
1550 LogPrint(BCLog::NET, "socket sending timeout: %is peer=%d\n",
1551 count_seconds(now - last_send), node.GetId());
1552 return true;
1553 }
1554
1555 if (now > last_recv + TIMEOUT_INTERVAL) {
1556 LogPrint(BCLog::NET, "socket receive timeout: %is peer=%d\n",
1557 count_seconds(now - last_recv), node.GetId());
1558 return true;
1559 }
1560
1561 if (!node.fSuccessfullyConnected) {
1562 LogPrint(BCLog::NET, "version handshake timeout peer=%d\n",
1563 node.GetId());
1564 return true;
1565 }
1566
1567 return false;
1568}
1569
1571 Sock::EventsPerSock events_per_sock;
1572
1573 for (const ListenSocket &hListenSocket : vhListenSocket) {
1574 events_per_sock.emplace(hListenSocket.sock, Sock::Events{Sock::RECV});
1575 }
1576
1577 for (CNode *pnode : nodes) {
1578 bool select_recv = !pnode->fPauseRecv;
1579 bool select_send =
1580 WITH_LOCK(pnode->cs_vSend, return !pnode->vSendMsg.empty());
1581 if (!select_recv && !select_send) {
1582 continue;
1583 }
1584
1585 LOCK(pnode->m_sock_mutex);
1586 if (pnode->m_sock) {
1587 Sock::Event event =
1588 (select_send ? Sock::SEND : 0) | (select_recv ? Sock::RECV : 0);
1589 events_per_sock.emplace(pnode->m_sock, Sock::Events{event});
1590 }
1591 }
1592
1593 return events_per_sock;
1594}
1595
1597 Sock::EventsPerSock events_per_sock;
1598
1599 {
1600 const NodesSnapshot snap{*this, /*shuffle=*/false};
1601
1602 const auto timeout =
1603 std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS);
1604
1605 // Check for the readiness of the already connected sockets and the
1606 // listening sockets in one call ("readiness" as in poll(2) or
1607 // select(2)). If none are ready, wait for a short while and return
1608 // empty sets.
1609 events_per_sock = GenerateWaitSockets(snap.Nodes());
1610 if (events_per_sock.empty() ||
1611 !events_per_sock.begin()->first->WaitMany(timeout,
1612 events_per_sock)) {
1613 interruptNet.sleep_for(timeout);
1614 }
1615
1616 // Service (send/receive) each of the already connected nodes.
1617 SocketHandlerConnected(snap.Nodes(), events_per_sock);
1618 }
1619
1620 // Accept new connections from listening sockets.
1621 SocketHandlerListening(events_per_sock);
1622}
1623
1625 const std::vector<CNode *> &nodes,
1626 const Sock::EventsPerSock &events_per_sock) {
1627 for (CNode *pnode : nodes) {
1628 if (interruptNet) {
1629 return;
1630 }
1631
1632 //
1633 // Receive
1634 //
1635 bool recvSet = false;
1636 bool sendSet = false;
1637 bool errorSet = false;
1638 {
1639 LOCK(pnode->m_sock_mutex);
1640 if (!pnode->m_sock) {
1641 continue;
1642 }
1643 const auto it = events_per_sock.find(pnode->m_sock);
1644 if (it != events_per_sock.end()) {
1645 recvSet = it->second.occurred & Sock::RECV;
1646 sendSet = it->second.occurred & Sock::SEND;
1647 errorSet = it->second.occurred & Sock::ERR;
1648 }
1649 }
1650
1651 if (sendSet) {
1652 // Send data
1653 auto [bytes_sent, data_left] =
1654 WITH_LOCK(pnode->cs_vSend, return SocketSendData(*pnode));
1655 if (bytes_sent) {
1656 RecordBytesSent(bytes_sent);
1657
1658 // If both receiving and (non-optimistic) sending were possible,
1659 // we first attempt sending. If that succeeds, but does not
1660 // fully drain the send queue, do not attempt to receive. This
1661 // avoids needlessly queueing data if the remote peer is slow at
1662 // receiving data, by means of TCP flow control. We only do this
1663 // when sending actually succeeded to make sure progress is
1664 // always made; otherwise a deadlock would be possible when both
1665 // sides have data to send, but neither is receiving.
1666 if (data_left) {
1667 recvSet = false;
1668 }
1669 }
1670 }
1671
1672 if (recvSet || errorSet) {
1673 // typical socket buffer is 8K-64K
1674 uint8_t pchBuf[0x10000];
1675 int32_t nBytes = 0;
1676 {
1677 LOCK(pnode->m_sock_mutex);
1678 if (!pnode->m_sock) {
1679 continue;
1680 }
1681 nBytes =
1682 pnode->m_sock->Recv(pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1683 }
1684 if (nBytes > 0) {
1685 bool notify = false;
1686 if (!pnode->ReceiveMsgBytes(*config, {pchBuf, (size_t)nBytes},
1687 notify)) {
1688 pnode->CloseSocketDisconnect();
1689 }
1690 RecordBytesRecv(nBytes);
1691 if (notify) {
1692 size_t nSizeAdded = 0;
1693 auto it(pnode->vRecvMsg.begin());
1694 for (; it != pnode->vRecvMsg.end(); ++it) {
1695 // vRecvMsg contains only completed CNetMessage
1696 // the single possible partially deserialized message
1697 // are held by TransportDeserializer
1698 nSizeAdded += it->m_raw_message_size;
1699 }
1700 {
1701 LOCK(pnode->cs_vProcessMsg);
1702 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(),
1703 pnode->vRecvMsg,
1704 pnode->vRecvMsg.begin(), it);
1705 pnode->nProcessQueueSize += nSizeAdded;
1706 pnode->fPauseRecv =
1707 pnode->nProcessQueueSize > nReceiveFloodSize;
1708 }
1710 }
1711 } else if (nBytes == 0) {
1712 // socket closed gracefully
1713 if (!pnode->fDisconnect) {
1714 LogPrint(BCLog::NET, "socket closed for peer=%d\n",
1715 pnode->GetId());
1716 }
1717 pnode->CloseSocketDisconnect();
1718 } else if (nBytes < 0) {
1719 // error
1720 int nErr = WSAGetLastError();
1721 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE &&
1722 nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
1723 if (!pnode->fDisconnect) {
1725 "socket recv error for peer=%d: %s\n",
1726 pnode->GetId(), NetworkErrorString(nErr));
1727 }
1728 pnode->CloseSocketDisconnect();
1729 }
1730 }
1731 }
1732
1733 if (InactivityCheck(*pnode)) {
1734 pnode->fDisconnect = true;
1735 }
1736 }
1737}
1738
1740 const Sock::EventsPerSock &events_per_sock) {
1741 for (const ListenSocket &listen_socket : vhListenSocket) {
1742 if (interruptNet) {
1743 return;
1744 }
1745 const auto it = events_per_sock.find(listen_socket.sock);
1746 if (it != events_per_sock.end() && it->second.occurred & Sock::RECV) {
1747 AcceptConnection(listen_socket);
1748 }
1749 }
1750}
1751
1753 while (!interruptNet) {
1756 SocketHandler();
1757 }
1758}
1759
1761 {
1763 fMsgProcWake = true;
1764 }
1765 condMsgProc.notify_one();
1766}
1767
1770 std::vector<std::string> seeds =
1772 // Number of seeds left before testing if we have enough connections
1773 int seeds_right_now = 0;
1774 int found = 0;
1775
1776 if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
1777 // When -forcednsseed is provided, query all.
1778 seeds_right_now = seeds.size();
1779 } else if (addrman.size() == 0) {
1780 // If we have no known peers, query all.
1781 // This will occur on the first run, or if peers.dat has been
1782 // deleted.
1783 seeds_right_now = seeds.size();
1784 }
1785
1786 // goal: only query DNS seed if address need is acute
1787 // * If we have a reasonable number of peers in addrman, spend
1788 // some time trying them first. This improves user privacy by
1789 // creating fewer identifying DNS requests, reduces trust by
1790 // giving seeds less influence on the network topology, and
1791 // reduces traffic to the seeds.
1792 // * When querying DNS seeds query a few at once, this ensures
1793 // that we don't give DNS seeds the ability to eclipse nodes
1794 // that query them.
1795 // * If we continue having problems, eventually query all the
1796 // DNS seeds, and if that fails too, also try the fixed seeds.
1797 // (done in ThreadOpenConnections)
1798 const std::chrono::seconds seeds_wait_time =
1802
1803 for (const std::string &seed : seeds) {
1804 if (seeds_right_now == 0) {
1805 seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1806
1807 if (addrman.size() > 0) {
1808 LogPrintf("Waiting %d seconds before querying DNS seeds.\n",
1809 seeds_wait_time.count());
1810 std::chrono::seconds to_wait = seeds_wait_time;
1811 while (to_wait.count() > 0) {
1812 // if sleeping for the MANY_PEERS interval, wake up
1813 // early to see if we have enough peers and can stop
1814 // this thread entirely freeing up its resources
1815 std::chrono::seconds w =
1816 std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
1817 if (!interruptNet.sleep_for(w)) {
1818 return;
1819 }
1820 to_wait -= w;
1821
1822 int nRelevant = 0;
1823 {
1825 for (const CNode *pnode : m_nodes) {
1826 if (pnode->fSuccessfullyConnected &&
1827 pnode->IsFullOutboundConn()) {
1828 ++nRelevant;
1829 }
1830 }
1831 }
1832 if (nRelevant >= 2) {
1833 if (found > 0) {
1834 LogPrintf("%d addresses found from DNS seeds\n",
1835 found);
1836 LogPrintf(
1837 "P2P peers available. Finished DNS seeding.\n");
1838 } else {
1839 LogPrintf(
1840 "P2P peers available. Skipped DNS seeding.\n");
1841 }
1842 return;
1843 }
1844 }
1845 }
1846 }
1847
1848 if (interruptNet) {
1849 return;
1850 }
1851
1852 // hold off on querying seeds if P2P network deactivated
1853 if (!fNetworkActive) {
1854 LogPrintf("Waiting for network to be reactivated before querying "
1855 "DNS seeds.\n");
1856 do {
1857 if (!interruptNet.sleep_for(std::chrono::seconds{1})) {
1858 return;
1859 }
1860 } while (!fNetworkActive);
1861 }
1862
1863 LogPrintf("Loading addresses from DNS seed %s\n", seed);
1864 if (HaveNameProxy()) {
1865 AddAddrFetch(seed);
1866 } else {
1867 std::vector<CNetAddr> vIPs;
1868 std::vector<CAddress> vAdd;
1869 ServiceFlags requiredServiceBits =
1871 std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
1872 CNetAddr resolveSource;
1873 if (!resolveSource.SetInternal(host)) {
1874 continue;
1875 }
1876
1877 // Limits number of IPs learned from a DNS seed
1878 unsigned int nMaxIPs = 256;
1879 if (LookupHost(host, vIPs, nMaxIPs, true)) {
1880 for (const CNetAddr &ip : vIPs) {
1881 CAddress addr = CAddress(
1883 requiredServiceBits);
1884 // Use a random age between 3 and 7 days old.
1885 addr.nTime = rng.rand_uniform_delay(
1886 Now<NodeSeconds>() - 3 * 24h, -4 * 24h);
1887 vAdd.push_back(addr);
1888 found++;
1889 }
1890 addrman.Add(vAdd, resolveSource);
1891 } else {
1892 // We now avoid directly using results from DNS Seeds which do
1893 // not support service bit filtering, instead using them as a
1894 // addrfetch to get nodes with our desired service bits.
1895 AddAddrFetch(seed);
1896 }
1897 }
1898 --seeds_right_now;
1899 }
1900 LogPrintf("%d addresses found from DNS seeds\n", found);
1901}
1902
1904 int64_t nStart = GetTimeMillis();
1905
1907
1908 LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1909 addrman.size(), GetTimeMillis() - nStart);
1910}
1911
1913 std::string strDest;
1914 {
1916 if (m_addr_fetches.empty()) {
1917 return;
1918 }
1919 strDest = m_addr_fetches.front();
1920 m_addr_fetches.pop_front();
1921 }
1922 CAddress addr;
1923 CSemaphoreGrant grant(*semOutbound, true);
1924 if (grant) {
1925 OpenNetworkConnection(addr, false, &grant, strDest.c_str(),
1927 }
1928}
1929
1932}
1933
1936 LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n",
1937 flag ? "true" : "false");
1938}
1939
1940// Return the number of peers we have over our outbound connection limit.
1941// Exclude peers that are marked for disconnect, or are going to be disconnected
1942// soon (eg ADDR_FETCH and FEELER).
1943// Also exclude peers that haven't finished initial connection handshake yet (so
1944// that we don't decide we're over our desired connection limit, and then evict
1945// some peer that has finished the handshake).
1947 int full_outbound_peers = 0;
1948 {
1950 for (const CNode *pnode : m_nodes) {
1951 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect &&
1952 pnode->IsFullOutboundConn()) {
1953 ++full_outbound_peers;
1954 }
1955 }
1956 }
1957 return std::max(full_outbound_peers - m_max_outbound_full_relay -
1959 0);
1960}
1961
1963 int block_relay_peers = 0;
1964 {
1966 for (const CNode *pnode : m_nodes) {
1967 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect &&
1968 pnode->IsBlockOnlyConn()) {
1969 ++block_relay_peers;
1970 }
1971 }
1972 }
1973 return std::max(block_relay_peers - m_max_outbound_block_relay, 0);
1974}
1975
1977 const std::vector<std::string> connect,
1978 std::function<void(const CAddress &, ConnectionType)> mockOpenConnection) {
1979 // Connect to specific addresses
1980 if (!connect.empty()) {
1981 for (int64_t nLoop = 0;; nLoop++) {
1983 for (const std::string &strAddr : connect) {
1984 CAddress addr(CService(), NODE_NONE);
1985 OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(),
1987 for (int i = 0; i < 10 && i < nLoop; i++) {
1989 std::chrono::milliseconds(500))) {
1990 return;
1991 }
1992 }
1993 }
1994 if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
1995 return;
1996 }
1997 }
1998 }
1999
2000 // Initiate network connections
2001 auto start = GetTime<std::chrono::microseconds>();
2002
2003 // Minimum time before next feeler connection (in microseconds).
2004 auto next_feeler = GetExponentialRand(start, FEELER_INTERVAL);
2005 auto next_extra_block_relay =
2007 const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
2008 bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
2009
2010 if (!add_fixed_seeds) {
2011 LogPrintf("Fixed seeds are disabled\n");
2012 }
2013
2014 while (!interruptNet) {
2016
2017 // No need to sleep the thread if we are mocking the network connection
2018 if (!mockOpenConnection &&
2019 !interruptNet.sleep_for(std::chrono::milliseconds(500))) {
2020 return;
2021 }
2022
2024 if (interruptNet) {
2025 return;
2026 }
2027
2028 if (add_fixed_seeds && addrman.size() == 0) {
2029 // When the node starts with an empty peers.dat, there are a few
2030 // other sources of peers before we fallback on to fixed seeds:
2031 // -dnsseed, -seednode, -addnode If none of those are available, we
2032 // fallback on to fixed seeds immediately, else we allow 60 seconds
2033 // for any of those sources to populate addrman.
2034 bool add_fixed_seeds_now = false;
2035 // It is cheapest to check if enough time has passed first.
2036 if (GetTime<std::chrono::seconds>() >
2037 start + std::chrono::minutes{1}) {
2038 add_fixed_seeds_now = true;
2039 LogPrintf("Adding fixed seeds as 60 seconds have passed and "
2040 "addrman is empty\n");
2041 }
2042
2043 // Checking !dnsseed is cheaper before locking 2 mutexes.
2044 if (!add_fixed_seeds_now && !dnsseed) {
2046 if (m_addr_fetches.empty() && m_added_nodes.empty()) {
2047 add_fixed_seeds_now = true;
2048 LogPrintf(
2049 "Adding fixed seeds as -dnsseed=0, -addnode is not "
2050 "provided and all -seednode(s) attempted\n");
2051 }
2052 }
2053
2054 if (add_fixed_seeds_now) {
2055 CNetAddr local;
2056 local.SetInternal("fixedseeds");
2058 local);
2059 add_fixed_seeds = false;
2060 }
2061 }
2062
2063 //
2064 // Choose an address to connect to based on most recently seen
2065 //
2066 CAddress addrConnect;
2067
2068 // Only connect out to one peer per network group (/16 for IPv4).
2069 int nOutboundFullRelay = 0;
2070 int nOutboundBlockRelay = 0;
2071 int nOutboundAvalanche = 0;
2072 std::set<std::vector<uint8_t>> setConnected;
2073
2074 {
2076 for (const CNode *pnode : m_nodes) {
2077 if (pnode->IsAvalancheOutboundConnection()) {
2078 nOutboundAvalanche++;
2079 } else if (pnode->IsFullOutboundConn()) {
2080 nOutboundFullRelay++;
2081 } else if (pnode->IsBlockOnlyConn()) {
2082 nOutboundBlockRelay++;
2083 }
2084
2085 // Netgroups for inbound and manual peers are not excluded
2086 // because our goal here is to not use multiple of our
2087 // limited outbound slots on a single netgroup but inbound
2088 // and manual peers do not use our outbound slots. Inbound
2089 // peers also have the added issue that they could be attacker
2090 // controlled and could be used to prevent us from connecting
2091 // to particular hosts if we used them here.
2092 switch (pnode->m_conn_type) {
2095 break;
2101 setConnected.insert(
2102 pnode->addr.GetGroup(addrman.GetAsmap()));
2103 } // no default case, so the compiler can warn about missing
2104 // cases
2105 }
2106 }
2107
2109 auto now = GetTime<std::chrono::microseconds>();
2110 bool anchor = false;
2111 bool fFeeler = false;
2112
2113 // Determine what type of connection to open. Opening
2114 // BLOCK_RELAY connections to addresses from anchors.dat gets the
2115 // highest priority. Then we open AVALANCHE_OUTBOUND connection until we
2116 // hit our avalanche outbound peer limit, which is 0 if avalanche is not
2117 // enabled. We fallback after 50 retries to OUTBOUND_FULL_RELAY if the
2118 // peer is not avalanche capable until we meet our full-relay capacity.
2119 // Then we open BLOCK_RELAY connection until we hit our block-relay-only
2120 // peer limit.
2121 // GetTryNewOutboundPeer() gets set when a stale tip is detected, so we
2122 // try opening an additional OUTBOUND_FULL_RELAY connection. If none of
2123 // these conditions are met, check to see if it's time to try an extra
2124 // block-relay-only peer (to confirm our tip is current, see below) or
2125 // the next_feeler timer to decide if we should open a FEELER.
2126
2127 if (!m_anchors.empty() &&
2128 (nOutboundBlockRelay < m_max_outbound_block_relay)) {
2129 conn_type = ConnectionType::BLOCK_RELAY;
2130 anchor = true;
2131 } else if (nOutboundAvalanche < m_max_avalanche_outbound) {
2133 } else if (nOutboundFullRelay < m_max_outbound_full_relay) {
2134 // OUTBOUND_FULL_RELAY
2135 } else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
2136 conn_type = ConnectionType::BLOCK_RELAY;
2137 } else if (GetTryNewOutboundPeer()) {
2138 // OUTBOUND_FULL_RELAY
2139 } else if (now > next_extra_block_relay &&
2141 // Periodically connect to a peer (using regular outbound selection
2142 // methodology from addrman) and stay connected long enough to sync
2143 // headers, but not much else.
2144 //
2145 // Then disconnect the peer, if we haven't learned anything new.
2146 //
2147 // The idea is to make eclipse attacks very difficult to pull off,
2148 // because every few minutes we're finding a new peer to learn
2149 // headers from.
2150 //
2151 // This is similar to the logic for trying extra outbound
2152 // (full-relay) peers, except:
2153 // - we do this all the time on an exponential timer, rather than
2154 // just when our tip is stale
2155 // - we potentially disconnect our next-youngest block-relay-only
2156 // peer, if our newest block-relay-only peer delivers a block more
2157 // recently.
2158 // See the eviction logic in net_processing.cpp.
2159 //
2160 // Because we can promote these connections to block-relay-only
2161 // connections, they do not get their own ConnectionType enum
2162 // (similar to how we deal with extra outbound peers).
2163 next_extra_block_relay =
2165 conn_type = ConnectionType::BLOCK_RELAY;
2166 } else if (now > next_feeler) {
2167 next_feeler = GetExponentialRand(now, FEELER_INTERVAL);
2168 conn_type = ConnectionType::FEELER;
2169 fFeeler = true;
2170 } else {
2171 // skip to next iteration of while loop
2172 continue;
2173 }
2174
2176
2177 const auto current_time{NodeClock::now()};
2178 int nTries = 0;
2179 while (!interruptNet) {
2180 if (anchor && !m_anchors.empty()) {
2181 const CAddress addr = m_anchors.back();
2182 m_anchors.pop_back();
2183 if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) ||
2185 setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2186 continue;
2187 }
2188 addrConnect = addr;
2190 "Trying to make an anchor connection to %s\n",
2191 addrConnect.ToString());
2192 break;
2193 }
2194 // If we didn't find an appropriate destination after trying 100
2195 // addresses fetched from addrman, stop this loop, and let the outer
2196 // loop run again (which sleeps, adds seed nodes, recalculates
2197 // already-connected network ranges, ...) before trying new addrman
2198 // addresses.
2199 nTries++;
2200 if (nTries > 100) {
2201 break;
2202 }
2203
2204 CAddress addr;
2205 NodeSeconds addr_last_try{0s};
2206
2207 if (fFeeler) {
2208 // First, try to get a tried table collision address. This
2209 // returns an empty (invalid) address if there are no collisions
2210 // to try.
2211 std::tie(addr, addr_last_try) = addrman.SelectTriedCollision();
2212
2213 if (!addr.IsValid()) {
2214 // No tried table collisions. Select a new table address
2215 // for our feeler.
2216 std::tie(addr, addr_last_try) = addrman.Select(true);
2217 } else if (AlreadyConnectedToAddress(addr)) {
2218 // If test-before-evict logic would have us connect to a
2219 // peer that we're already connected to, just mark that
2220 // address as Good(). We won't be able to initiate the
2221 // connection anyway, so this avoids inadvertently evicting
2222 // a currently-connected peer.
2223 addrman.Good(addr);
2224 // Select a new table address for our feeler instead.
2225 std::tie(addr, addr_last_try) = addrman.Select(true);
2226 }
2227 } else {
2228 // Not a feeler
2229 std::tie(addr, addr_last_try) = addrman.Select();
2230 }
2231
2232 // Require outbound connections, other than feelers and avalanche,
2233 // to be to distinct network groups
2234 if (!fFeeler && conn_type != ConnectionType::AVALANCHE_OUTBOUND &&
2235 setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2236 break;
2237 }
2238
2239 // if we selected an invalid or local address, restart
2240 if (!addr.IsValid() || IsLocal(addr)) {
2241 break;
2242 }
2243
2244 if (!IsReachable(addr)) {
2245 continue;
2246 }
2247
2248 // only consider very recently tried nodes after 30 failed attempts
2249 if (current_time - addr_last_try < 10min && nTries < 30) {
2250 continue;
2251 }
2252
2253 // for non-feelers, require all the services we'll want,
2254 // for feelers, only require they be a full node (only because most
2255 // SPV clients don't have a good address DB available)
2256 if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
2257 continue;
2258 }
2259
2260 if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
2261 continue;
2262 }
2263
2264 // Do not connect to bad ports, unless 50 invalid addresses have
2265 // been selected already.
2266 if (nTries < 50 && (addr.IsIPv4() || addr.IsIPv6()) &&
2267 IsBadPort(addr.GetPort())) {
2268 continue;
2269 }
2270
2271 // For avalanche peers, check they have the avalanche service bit
2272 // set.
2273 if (conn_type == ConnectionType::AVALANCHE_OUTBOUND &&
2274 !(addr.nServices & NODE_AVALANCHE)) {
2275 // If this peer is not suitable as an avalanche one and we tried
2276 // over 20 addresses already, see if we can fallback to a non
2277 // avalanche full outbound.
2278 if (nTries < 20 ||
2279 nOutboundFullRelay >= m_max_outbound_full_relay ||
2280 setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2281 // Fallback is not desirable or possible, try another one
2282 continue;
2283 }
2284
2285 // Fallback is possible, update the connection type accordingly
2287 }
2288
2289 addrConnect = addr;
2290 break;
2291 }
2292
2293 if (addrConnect.IsValid()) {
2294 if (fFeeler) {
2295 // Add small amount of random noise before connection to avoid
2296 // synchronization.
2297 int randsleep = GetRand<int>(FEELER_SLEEP_WINDOW * 1000);
2299 std::chrono::milliseconds(randsleep))) {
2300 return;
2301 }
2302 LogPrint(BCLog::NET, "Making feeler connection to %s\n",
2303 addrConnect.ToString());
2304 }
2305
2306 // This mock is for testing purpose only. It prevents the thread
2307 // from attempting the connection which is useful for testing.
2308 if (mockOpenConnection) {
2309 mockOpenConnection(addrConnect, conn_type);
2310 } else {
2311 OpenNetworkConnection(addrConnect,
2312 int(setConnected.size()) >=
2313 std::min(nMaxConnections - 1, 2),
2314 &grant, nullptr, conn_type);
2315 }
2316 }
2317 }
2318}
2319
2320std::vector<CAddress> CConnman::GetCurrentBlockRelayOnlyConns() const {
2321 std::vector<CAddress> ret;
2323 for (const CNode *pnode : m_nodes) {
2324 if (pnode->IsBlockOnlyConn()) {
2325 ret.push_back(pnode->addr);
2326 }
2327 }
2328
2329 return ret;
2330}
2331
2332std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() const {
2333 std::vector<AddedNodeInfo> ret;
2334
2335 std::list<std::string> lAddresses(0);
2336 {
2338 ret.reserve(m_added_nodes.size());
2339 std::copy(m_added_nodes.cbegin(), m_added_nodes.cend(),
2340 std::back_inserter(lAddresses));
2341 }
2342
2343 // Build a map of all already connected addresses (by IP:port and by name)
2344 // to inbound/outbound and resolved CService
2345 std::map<CService, bool> mapConnected;
2346 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2347 {
2349 for (const CNode *pnode : m_nodes) {
2350 if (pnode->addr.IsValid()) {
2351 mapConnected[pnode->addr] = pnode->IsInboundConn();
2352 }
2353 std::string addrName{pnode->m_addr_name};
2354 if (!addrName.empty()) {
2355 mapConnectedByName[std::move(addrName)] =
2356 std::make_pair(pnode->IsInboundConn(),
2357 static_cast<const CService &>(pnode->addr));
2358 }
2359 }
2360 }
2361
2362 for (const std::string &strAddNode : lAddresses) {
2363 CService service(
2364 LookupNumeric(strAddNode, Params().GetDefaultPort(strAddNode)));
2365 AddedNodeInfo addedNode{strAddNode, CService(), false, false};
2366 if (service.IsValid()) {
2367 // strAddNode is an IP:port
2368 auto it = mapConnected.find(service);
2369 if (it != mapConnected.end()) {
2370 addedNode.resolvedAddress = service;
2371 addedNode.fConnected = true;
2372 addedNode.fInbound = it->second;
2373 }
2374 } else {
2375 // strAddNode is a name
2376 auto it = mapConnectedByName.find(strAddNode);
2377 if (it != mapConnectedByName.end()) {
2378 addedNode.resolvedAddress = it->second.second;
2379 addedNode.fConnected = true;
2380 addedNode.fInbound = it->second.first;
2381 }
2382 }
2383 ret.emplace_back(std::move(addedNode));
2384 }
2385
2386 return ret;
2387}
2388
2390 while (true) {
2392 std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
2393 bool tried = false;
2394 for (const AddedNodeInfo &info : vInfo) {
2395 if (!info.fConnected) {
2396 if (!grant.TryAcquire()) {
2397 // If we've used up our semaphore and need a new one, let's
2398 // not wait here since while we are waiting the
2399 // addednodeinfo state might change.
2400 break;
2401 }
2402 tried = true;
2403 CAddress addr(CService(), NODE_NONE);
2404 OpenNetworkConnection(addr, false, &grant,
2405 info.strAddedNode.c_str(),
2407 if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) {
2408 return;
2409 }
2410 }
2411 }
2412 // Retry every 60 seconds if a connection was attempted, otherwise two
2413 // seconds.
2414 if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2))) {
2415 return;
2416 }
2417 }
2418}
2419
2420// If successful, this moves the passed grant to the constructed node.
2422 bool fCountFailure,
2423 CSemaphoreGrant *grantOutbound,
2424 const char *pszDest,
2425 ConnectionType conn_type) {
2426 assert(conn_type != ConnectionType::INBOUND);
2427
2428 //
2429 // Initiate outbound network connection
2430 //
2431 if (interruptNet) {
2432 return;
2433 }
2434 if (!fNetworkActive) {
2435 return;
2436 }
2437 if (!pszDest) {
2438 bool banned_or_discouraged =
2439 m_banman && (m_banman->IsDiscouraged(addrConnect) ||
2440 m_banman->IsBanned(addrConnect));
2441 if (IsLocal(addrConnect) || banned_or_discouraged ||
2442 AlreadyConnectedToAddress(addrConnect)) {
2443 return;
2444 }
2445 } else if (FindNode(std::string(pszDest))) {
2446 return;
2447 }
2448
2449 CNode *pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2450
2451 if (!pnode) {
2452 return;
2453 }
2454 if (grantOutbound) {
2455 grantOutbound->MoveTo(pnode->grantOutbound);
2456 }
2457
2458 for (auto interface : m_msgproc) {
2459 interface->InitializeNode(*config, *pnode, nLocalServices);
2460 }
2461
2462 {
2464 m_nodes.push_back(pnode);
2465 }
2466}
2467
2469
2472
2473 while (!flagInterruptMsgProc) {
2474 bool fMoreWork = false;
2475
2476 {
2477 // Randomize the order in which we process messages from/to our
2478 // peers. This prevents attacks in which an attacker exploits having
2479 // multiple consecutive connections in the vNodes list.
2480 const NodesSnapshot snap{*this, /*shuffle=*/true};
2481
2482 for (CNode *pnode : snap.Nodes()) {
2483 if (pnode->fDisconnect) {
2484 continue;
2485 }
2486
2487 bool fMoreNodeWork = false;
2488 // Receive messages
2489 for (auto interface : m_msgproc) {
2490 fMoreNodeWork |= interface->ProcessMessages(
2491 *config, pnode, flagInterruptMsgProc);
2492 }
2493 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2495 return;
2496 }
2497
2498 // Send messages
2499 for (auto interface : m_msgproc) {
2500 interface->SendMessages(*config, pnode);
2501 }
2502
2504 return;
2505 }
2506 }
2507 }
2508
2509 WAIT_LOCK(mutexMsgProc, lock);
2510 if (!fMoreWork) {
2511 condMsgProc.wait_until(lock,
2512 std::chrono::steady_clock::now() +
2513 std::chrono::milliseconds(100),
2514 [this]() EXCLUSIVE_LOCKS_REQUIRED(
2515 mutexMsgProc) { return fMsgProcWake; });
2516 }
2517 fMsgProcWake = false;
2518 }
2519}
2520
2522 static constexpr auto err_wait_begin = 1s;
2523 static constexpr auto err_wait_cap = 5min;
2524 auto err_wait = err_wait_begin;
2525
2526 bool advertising_listen_addr = false;
2527 i2p::Connection conn;
2528
2529 while (!interruptNet) {
2530 if (!m_i2p_sam_session->Listen(conn)) {
2531 if (advertising_listen_addr && conn.me.IsValid()) {
2532 RemoveLocal(conn.me);
2533 advertising_listen_addr = false;
2534 }
2535
2536 interruptNet.sleep_for(err_wait);
2537 if (err_wait < err_wait_cap) {
2538 err_wait *= 2;
2539 }
2540
2541 continue;
2542 }
2543
2544 if (!advertising_listen_addr) {
2545 AddLocal(conn.me, LOCAL_MANUAL);
2546 advertising_listen_addr = true;
2547 }
2548
2549 if (!m_i2p_sam_session->Accept(conn)) {
2550 continue;
2551 }
2552
2554 std::move(conn.sock), NetPermissionFlags::None,
2555 CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
2556 }
2557}
2558
2559bool CConnman::BindListenPort(const CService &addrBind, bilingual_str &strError,
2560 NetPermissionFlags permissions) {
2561 int nOne = 1;
2562
2563 // Create socket for listening for incoming connections
2564 struct sockaddr_storage sockaddr;
2565 socklen_t len = sizeof(sockaddr);
2566 if (!addrBind.GetSockAddr((struct sockaddr *)&sockaddr, &len)) {
2567 strError = strprintf(
2568 Untranslated("Error: Bind address family for %s not supported"),
2569 addrBind.ToString());
2570 LogPrintf("%s\n", strError.original);
2571 return false;
2572 }
2573
2574 std::unique_ptr<Sock> sock = CreateSock(addrBind);
2575 if (!sock) {
2576 strError =
2577 strprintf(Untranslated("Error: Couldn't open socket for incoming "
2578 "connections (socket returned error %s)"),
2580 LogPrintf("%s\n", strError.original);
2581 return false;
2582 }
2583
2584 // Allow binding if the port is still in TIME_WAIT state after
2585 // the program was closed and restarted.
2586 setsockopt(sock->Get(), SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne,
2587 sizeof(int));
2588
2589 // Some systems don't have IPV6_V6ONLY but are always v6only; others do have
2590 // the option and enable it by default or not. Try to enable it, if
2591 // possible.
2592 if (addrBind.IsIPv6()) {
2593#ifdef IPV6_V6ONLY
2594 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_V6ONLY,
2595 (sockopt_arg_type)&nOne, sizeof(int));
2596#endif
2597#ifdef WIN32
2598 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2599 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_PROTECTION_LEVEL,
2600 (sockopt_arg_type)&nProtLevel, sizeof(int));
2601#endif
2602 }
2603
2604 if (::bind(sock->Get(), (struct sockaddr *)&sockaddr, len) ==
2605 SOCKET_ERROR) {
2606 int nErr = WSAGetLastError();
2607 if (nErr == WSAEADDRINUSE) {
2608 strError = strprintf(_("Unable to bind to %s on this computer. %s "
2609 "is probably already running."),
2610 addrBind.ToString(), PACKAGE_NAME);
2611 } else {
2612 strError = strprintf(_("Unable to bind to %s on this computer "
2613 "(bind returned error %s)"),
2614 addrBind.ToString(), NetworkErrorString(nErr));
2615 }
2616 LogPrintf("%s\n", strError.original);
2617 return false;
2618 }
2619 LogPrintf("Bound to %s\n", addrBind.ToString());
2620
2621 // Listen for incoming connections
2622 if (listen(sock->Get(), SOMAXCONN) == SOCKET_ERROR) {
2623 strError = strprintf(_("Error: Listening for incoming connections "
2624 "failed (listen returned error %s)"),
2626 LogPrintf("%s\n", strError.original);
2627 return false;
2628 }
2629
2630 vhListenSocket.emplace_back(std::move(sock), permissions);
2631 return true;
2632}
2633
2634void Discover() {
2635 if (!fDiscover) {
2636 return;
2637 }
2638
2639#ifdef WIN32
2640 // Get local host IP
2641 char pszHostName[256] = "";
2642 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) {
2643 std::vector<CNetAddr> vaddr;
2644 if (LookupHost(pszHostName, vaddr, 0, true)) {
2645 for (const CNetAddr &addr : vaddr) {
2646 if (AddLocal(addr, LOCAL_IF)) {
2647 LogPrintf("%s: %s - %s\n", __func__, pszHostName,
2648 addr.ToString());
2649 }
2650 }
2651 }
2652 }
2653#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2654 // Get local host ip
2655 struct ifaddrs *myaddrs;
2656 if (getifaddrs(&myaddrs) == 0) {
2657 for (struct ifaddrs *ifa = myaddrs; ifa != nullptr;
2658 ifa = ifa->ifa_next) {
2659 if (ifa->ifa_addr == nullptr || (ifa->ifa_flags & IFF_UP) == 0 ||
2660 strcmp(ifa->ifa_name, "lo") == 0 ||
2661 strcmp(ifa->ifa_name, "lo0") == 0) {
2662 continue;
2663 }
2664 if (ifa->ifa_addr->sa_family == AF_INET) {
2665 struct sockaddr_in *s4 =
2666 reinterpret_cast<struct sockaddr_in *>(ifa->ifa_addr);
2667 CNetAddr addr(s4->sin_addr);
2668 if (AddLocal(addr, LOCAL_IF)) {
2669 LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name,
2670 addr.ToString());
2671 }
2672 } else if (ifa->ifa_addr->sa_family == AF_INET6) {
2673 struct sockaddr_in6 *s6 =
2674 reinterpret_cast<struct sockaddr_in6 *>(ifa->ifa_addr);
2675 CNetAddr addr(s6->sin6_addr);
2676 if (AddLocal(addr, LOCAL_IF)) {
2677 LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name,
2678 addr.ToString());
2679 }
2680 }
2681 }
2682 freeifaddrs(myaddrs);
2683 }
2684#endif
2685}
2686
2688 LogPrintf("%s: %s\n", __func__, active);
2689
2690 if (fNetworkActive == active) {
2691 return;
2692 }
2693
2694 fNetworkActive = active;
2695
2696 if (m_client_interface) {
2697 m_client_interface->NotifyNetworkActiveChanged(fNetworkActive);
2698 }
2699}
2700
2701CConnman::CConnman(const Config &configIn, uint64_t nSeed0In, uint64_t nSeed1In,
2702 AddrMan &addrmanIn, bool network_active)
2703 : config(&configIn), addrman(addrmanIn), nSeed0(nSeed0In),
2704 nSeed1(nSeed1In) {
2705 SetTryNewOutboundPeer(false);
2706
2707 Options connOptions;
2708 Init(connOptions);
2709 SetNetworkActive(network_active);
2710}
2711
2713 return nLastNodeId.fetch_add(1);
2714}
2715
2716bool CConnman::Bind(const CService &addr, unsigned int flags,
2717 NetPermissionFlags permissions) {
2718 if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
2719 return false;
2720 }
2721 bilingual_str strError;
2722 if (!BindListenPort(addr, strError, permissions)) {
2724 m_client_interface->ThreadSafeMessageBox(
2725 strError, "", CClientUIInterface::MSG_ERROR);
2726 }
2727 return false;
2728 }
2729
2730 if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) &&
2732 AddLocal(addr, LOCAL_BIND);
2733 }
2734
2735 return true;
2736}
2737
2738bool CConnman::InitBinds(const Options &options) {
2739 bool fBound = false;
2740 for (const auto &addrBind : options.vBinds) {
2741 fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR),
2743 }
2744 for (const auto &addrBind : options.vWhiteBinds) {
2745 fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR),
2746 addrBind.m_flags);
2747 }
2748 for (const auto &addr_bind : options.onion_binds) {
2749 fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE,
2751 }
2752 if (options.bind_on_any) {
2753 struct in_addr inaddr_any;
2754 inaddr_any.s_addr = htonl(INADDR_ANY);
2755 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2756 fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE,
2758 fBound |=
2759 Bind(CService(inaddr_any, GetListenPort()),
2761 }
2762 return fBound;
2763}
2764
2765bool CConnman::Start(CScheduler &scheduler, const Options &connOptions) {
2766 Init(connOptions);
2767
2768 if (fListen && !InitBinds(connOptions)) {
2769 if (m_client_interface) {
2770 m_client_interface->ThreadSafeMessageBox(
2771 _("Failed to listen on any port. Use -listen=0 if you want "
2772 "this."),
2774 }
2775 return false;
2776 }
2777
2778 proxyType i2p_sam;
2779 if (GetProxy(NET_I2P, i2p_sam)) {
2780 m_i2p_sam_session = std::make_unique<i2p::sam::Session>(
2781 gArgs.GetDataDirNet() / "i2p_private_key", i2p_sam.proxy,
2782 &interruptNet);
2783 }
2784
2785 for (const auto &strDest : connOptions.vSeedNodes) {
2786 AddAddrFetch(strDest);
2787 }
2788
2790 // Load addresses from anchors.dat
2791 m_anchors =
2796 }
2797 LogPrintf(
2798 "%i block-relay-only anchors will be tried for connections.\n",
2799 m_anchors.size());
2800 }
2801
2802 if (m_client_interface) {
2803 m_client_interface->InitMessage(
2804 _("Starting network threads...").translated);
2805 }
2806
2807 fAddressesInitialized = true;
2808
2809 if (semOutbound == nullptr) {
2810 // initialize semaphore
2811 semOutbound = std::make_unique<CSemaphore>(
2812 std::min(m_max_outbound, nMaxConnections));
2813 }
2814 if (semAddnode == nullptr) {
2815 // initialize semaphore
2816 semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
2817 }
2818
2819 //
2820 // Start threads
2821 //
2822 assert(m_msgproc.size() > 0);
2823 InterruptSocks5(false);
2825 flagInterruptMsgProc = false;
2826
2827 {
2829 fMsgProcWake = false;
2830 }
2831
2832 // Send and receive from sockets, accept connections
2833 threadSocketHandler = std::thread(&util::TraceThread, "net",
2834 [this] { ThreadSocketHandler(); });
2835
2836 if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED)) {
2837 LogPrintf("DNS seeding disabled\n");
2838 } else {
2839 threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed",
2840 [this] { ThreadDNSAddressSeed(); });
2841 }
2842
2843 // Initiate manual connections
2844 threadOpenAddedConnections = std::thread(
2845 &util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); });
2846
2847 if (connOptions.m_use_addrman_outgoing &&
2848 !connOptions.m_specified_outgoing.empty()) {
2849 if (m_client_interface) {
2850 m_client_interface->ThreadSafeMessageBox(
2851 _("Cannot provide specific connections and have addrman find "
2852 "outgoing connections at the same."),
2854 }
2855 return false;
2856 }
2857 if (connOptions.m_use_addrman_outgoing ||
2858 !connOptions.m_specified_outgoing.empty()) {
2860 std::thread(&util::TraceThread, "opencon",
2861 [this, connect = connOptions.m_specified_outgoing] {
2862 ThreadOpenConnections(connect, nullptr);
2863 });
2864 }
2865
2866 // Process messages
2867 threadMessageHandler = std::thread(&util::TraceThread, "msghand",
2868 [this] { ThreadMessageHandler(); });
2869
2870 if (connOptions.m_i2p_accept_incoming &&
2871 m_i2p_sam_session.get() != nullptr) {
2873 std::thread(&util::TraceThread, "i2paccept",
2874 [this] { ThreadI2PAcceptIncoming(); });
2875 }
2876
2877 // Dump network addresses
2878 scheduler.scheduleEvery(
2879 [this]() {
2880 this->DumpAddresses();
2881 return true;
2882 },
2884
2885 return true;
2886}
2887
2889public:
2891
2893#ifdef WIN32
2894 // Shutdown Windows Sockets
2895 WSACleanup();
2896#endif
2897 }
2898};
2900
2902 {
2904 flagInterruptMsgProc = true;
2905 }
2906 condMsgProc.notify_all();
2907
2908 interruptNet();
2909 InterruptSocks5(true);
2910
2911 if (semOutbound) {
2912 for (int i = 0; i < m_max_outbound; i++) {
2913 semOutbound->post();
2914 }
2915 }
2916
2917 if (semAddnode) {
2918 for (int i = 0; i < nMaxAddnode; i++) {
2919 semAddnode->post();
2920 }
2921 }
2922}
2923
2925 if (threadI2PAcceptIncoming.joinable()) {
2927 }
2928 if (threadMessageHandler.joinable()) {
2929 threadMessageHandler.join();
2930 }
2931 if (threadOpenConnections.joinable()) {
2932 threadOpenConnections.join();
2933 }
2934 if (threadOpenAddedConnections.joinable()) {
2936 }
2937 if (threadDNSAddressSeed.joinable()) {
2938 threadDNSAddressSeed.join();
2939 }
2940 if (threadSocketHandler.joinable()) {
2941 threadSocketHandler.join();
2942 }
2943}
2944
2947 DumpAddresses();
2948 fAddressesInitialized = false;
2949
2951 // Anchor connections are only dumped during clean shutdown.
2952 std::vector<CAddress> anchors_to_dump =
2954 if (anchors_to_dump.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) {
2955 anchors_to_dump.resize(MAX_BLOCK_RELAY_ONLY_ANCHORS);
2956 }
2959 anchors_to_dump);
2960 }
2961 }
2962
2963 // Delete peer connections.
2964 std::vector<CNode *> nodes;
2965 WITH_LOCK(m_nodes_mutex, nodes.swap(m_nodes));
2966 for (CNode *pnode : nodes) {
2967 pnode->CloseSocketDisconnect();
2968 DeleteNode(pnode);
2969 }
2970
2971 for (CNode *pnode : m_nodes_disconnected) {
2972 DeleteNode(pnode);
2973 }
2974 m_nodes_disconnected.clear();
2975 vhListenSocket.clear();
2976 semOutbound.reset();
2977 semAddnode.reset();
2978}
2979
2981 assert(pnode);
2982 for (auto interface : m_msgproc) {
2983 interface->FinalizeNode(*config, *pnode);
2984 }
2985 delete pnode;
2986}
2987
2989 Interrupt();
2990 Stop();
2991}
2992
2993std::vector<CAddress>
2994CConnman::GetAddresses(size_t max_addresses, size_t max_pct,
2995 std::optional<Network> network) const {
2996 std::vector<CAddress> addresses =
2997 addrman.GetAddr(max_addresses, max_pct, network);
2998 if (m_banman) {
2999 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
3000 [this](const CAddress &addr) {
3001 return m_banman->IsDiscouraged(
3002 addr) ||
3003 m_banman->IsBanned(addr);
3004 }),
3005 addresses.end());
3006 }
3007 return addresses;
3008}
3009
3010std::vector<CAddress>
3011CConnman::GetAddresses(CNode &requestor, size_t max_addresses, size_t max_pct) {
3012 auto local_socket_bytes = requestor.addrBind.GetAddrBytes();
3013 uint64_t cache_id =
3015 .Write(requestor.addr.GetNetwork())
3016 .Write(local_socket_bytes.data(), local_socket_bytes.size())
3017 .Finalize();
3018 const auto current_time = GetTime<std::chrono::microseconds>();
3019 auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
3020 CachedAddrResponse &cache_entry = r.first->second;
3021 // New CachedAddrResponse have expiration 0.
3022 if (cache_entry.m_cache_entry_expiration < current_time) {
3023 cache_entry.m_addrs_response_cache =
3024 GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);
3025 // Choosing a proper cache lifetime is a trade-off between the privacy
3026 // leak minimization and the usefulness of ADDR responses to honest
3027 // users.
3028 //
3029 // Longer cache lifetime makes it more difficult for an attacker to
3030 // scrape enough AddrMan data to maliciously infer something useful. By
3031 // the time an attacker scraped enough AddrMan records, most of the
3032 // records should be old enough to not leak topology info by e.g.
3033 // analyzing real-time changes in timestamps.
3034 //
3035 // It takes only several hundred requests to scrape everything from an
3036 // AddrMan containing 100,000 nodes, so ~24 hours of cache lifetime
3037 // indeed makes the data less inferable by the time most of it could be
3038 // scraped (considering that timestamps are updated via ADDR
3039 // self-announcements and when nodes communicate). We also should be
3040 // robust to those attacks which may not require scraping *full*
3041 // victim's AddrMan (because even several timestamps of the same handful
3042 // of nodes may leak privacy).
3043 //
3044 // On the other hand, longer cache lifetime makes ADDR responses
3045 // outdated and less useful for an honest requestor, e.g. if most nodes
3046 // in the ADDR response are no longer active.
3047 //
3048 // However, the churn in the network is known to be rather low. Since we
3049 // consider nodes to be "terrible" (see IsTerrible()) if the timestamps
3050 // are older than 30 days, max. 24 hours of "penalty" due to cache
3051 // shouldn't make any meaningful difference in terms of the freshness of
3052 // the response.
3053 cache_entry.m_cache_entry_expiration =
3054 current_time + std::chrono::hours(21) +
3055 GetRandMillis(std::chrono::hours(6));
3056 }
3057 return cache_entry.m_addrs_response_cache;
3058}
3059
3060bool CConnman::AddNode(const std::string &strNode) {
3062 for (const std::string &it : m_added_nodes) {
3063 if (strNode == it) {
3064 return false;
3065 }
3066 }
3067
3068 m_added_nodes.push_back(strNode);
3069 return true;
3070}
3071
3072bool CConnman::RemoveAddedNode(const std::string &strNode) {
3074 for (std::vector<std::string>::iterator it = m_added_nodes.begin();
3075 it != m_added_nodes.end(); ++it) {
3076 if (strNode == *it) {
3077 m_added_nodes.erase(it);
3078 return true;
3079 }
3080 }
3081 return false;
3082}
3083
3086 // Shortcut if we want total
3088 return m_nodes.size();
3089 }
3090
3091 int nNum = 0;
3092 for (const auto &pnode : m_nodes) {
3093 if (flags & (pnode->IsInboundConn() ? ConnectionDirection::In
3095 nNum++;
3096 }
3097 }
3098
3099 return nNum;
3100}
3101
3102void CConnman::GetNodeStats(std::vector<CNodeStats> &vstats) const {
3103 vstats.clear();
3105 vstats.reserve(m_nodes.size());
3106 for (CNode *pnode : m_nodes) {
3107 vstats.emplace_back();
3108 pnode->copyStats(vstats.back());
3109 vstats.back().m_mapped_as = pnode->addr.GetMappedAS(addrman.GetAsmap());
3110 }
3111}
3112
3113bool CConnman::DisconnectNode(const std::string &strNode) {
3115 if (CNode *pnode = FindNode(strNode)) {
3117 "disconnect by address%s matched peer=%d; disconnecting\n",
3118 (fLogIPs ? strprintf("=%s", strNode) : ""), pnode->GetId());
3119 pnode->fDisconnect = true;
3120 return true;
3121 }
3122 return false;
3123}
3124
3126 bool disconnected = false;
3128 for (CNode *pnode : m_nodes) {
3129 if (subnet.Match(pnode->addr)) {
3131 "disconnect by subnet%s matched peer=%d; disconnecting\n",
3132 (fLogIPs ? strprintf("=%s", subnet.ToString()) : ""),
3133 pnode->GetId());
3134 pnode->fDisconnect = true;
3135 disconnected = true;
3136 }
3137 }
3138 return disconnected;
3139}
3140
3142 return DisconnectNode(CSubNet(addr));
3143}
3144
3147 for (CNode *pnode : m_nodes) {
3148 if (id == pnode->GetId()) {
3149 LogPrint(BCLog::NET, "disconnect by id peer=%d; disconnecting\n",
3150 pnode->GetId());
3151 pnode->fDisconnect = true;
3152 return true;
3153 }
3154 }
3155 return false;
3156}
3157
3158void CConnman::RecordBytesRecv(uint64_t bytes) {
3159 nTotalBytesRecv += bytes;
3160}
3161
3162void CConnman::RecordBytesSent(uint64_t bytes) {
3164 nTotalBytesSent += bytes;
3165
3166 const auto now = GetTime<std::chrono::seconds>();
3167 if (nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME < now) {
3168 // timeframe expired, reset cycle
3169 nMaxOutboundCycleStartTime = now;
3170 nMaxOutboundTotalBytesSentInCycle = 0;
3171 }
3172
3173 // TODO, exclude peers with download permission
3174 nMaxOutboundTotalBytesSentInCycle += bytes;
3175}
3176
3179 return nMaxOutboundLimit;
3180}
3181
3182std::chrono::seconds CConnman::GetMaxOutboundTimeframe() const {
3183 return MAX_UPLOAD_TIMEFRAME;
3184}
3185
3186std::chrono::seconds CConnman::GetMaxOutboundTimeLeftInCycle() const {
3188 if (nMaxOutboundLimit == 0) {
3189 return 0s;
3190 }
3191
3192 if (nMaxOutboundCycleStartTime.count() == 0) {
3193 return MAX_UPLOAD_TIMEFRAME;
3194 }
3195
3196 const std::chrono::seconds cycleEndTime =
3197 nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME;
3198 const auto now = GetTime<std::chrono::seconds>();
3199 return (cycleEndTime < now) ? 0s : cycleEndTime - now;
3200}
3201
3202bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit) const {
3204 if (nMaxOutboundLimit == 0) {
3205 return false;
3206 }
3207
3208 if (historicalBlockServingLimit) {
3209 // keep a large enough buffer to at least relay each block once.
3210 const std::chrono::seconds timeLeftInCycle =
3212 const uint64_t buffer =
3213 timeLeftInCycle / std::chrono::minutes{10} * ONE_MEGABYTE;
3214 if (buffer >= nMaxOutboundLimit ||
3215 nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer) {
3216 return true;
3217 }
3218 } else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) {
3219 return true;
3220 }
3221
3222 return false;
3223}
3224
3227 if (nMaxOutboundLimit == 0) {
3228 return 0;
3229 }
3230
3231 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
3232 ? 0
3233 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
3234}
3235
3237 return nTotalBytesRecv;
3238}
3239
3242 return nTotalBytesSent;
3243}
3244
3246 return nLocalServices;
3247}
3248
3249unsigned int CConnman::GetReceiveFloodSize() const {
3250 return nReceiveFloodSize;
3251}
3252
3253void CNode::invsPolled(uint32_t count) {
3254 invCounters += count;
3255}
3256
3257void CNode::invsVoted(uint32_t count) {
3258 invCounters += uint64_t(count) << 32;
3259}
3260
3261void CNode::updateAvailabilityScore(double decayFactor) {
3262 if (!m_avalanche_enabled) {
3263 return;
3264 }
3265
3266 uint64_t windowInvCounters = invCounters.exchange(0);
3267 double previousScore = availabilityScore;
3268
3269 int64_t polls = windowInvCounters & std::numeric_limits<uint32_t>::max();
3270 int64_t votes = windowInvCounters >> 32;
3271
3273 decayFactor * (2 * votes - polls) + (1. - decayFactor) * previousScore;
3274}
3275
3277 // The score is set atomically so there is no need to lock the statistics
3278 // when reading.
3279 return availabilityScore;
3280}
3281
3282CNode::CNode(NodeId idIn, std::shared_ptr<Sock> sock, const CAddress &addrIn,
3283 uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
3284 uint64_t nLocalExtraEntropyIn, const CAddress &addrBindIn,
3285 const std::string &addrNameIn, ConnectionType conn_type_in,
3286 bool inbound_onion, CNodeOptions &&node_opts)
3287 : m_permission_flags{node_opts.permission_flags}, m_sock{sock},
3288 m_connected(GetTime<std::chrono::seconds>()), addr(addrIn),
3289 addrBind(addrBindIn),
3290 m_addr_name{addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn},
3291 m_inbound_onion(inbound_onion), m_prefer_evict{node_opts.prefer_evict},
3292 nKeyedNetGroup(nKeyedNetGroupIn),
3293 // Don't relay addr messages to peers that we connect to as
3294 // block-relay-only peers (to prevent adversaries from inferring these
3295 // links from addr traffic).
3296 id(idIn), nLocalHostNonce(nLocalHostNonceIn),
3297 nLocalExtraEntropy(nLocalExtraEntropyIn), m_conn_type(conn_type_in) {
3298 if (inbound_onion) {
3299 assert(conn_type_in == ConnectionType::INBOUND);
3300 }
3301
3302 for (const std::string &msg : getAllNetMessageTypes()) {
3303 mapRecvBytesPerMsgCmd[msg] = 0;
3304 }
3305 mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
3306
3307 if (fLogIPs) {
3308 LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", m_addr_name,
3309 id);
3310 } else {
3311 LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
3312 }
3313
3314 m_deserializer = std::make_unique<V1TransportDeserializer>(
3315 V1TransportDeserializer(GetConfig().GetChainParams().NetMagic(),
3317 m_serializer =
3318 std::make_unique<V1TransportSerializer>(V1TransportSerializer());
3319}
3320
3322 return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
3323}
3324
3326 size_t nMessageSize = msg.data.size();
3327 LogPrint(BCLog::NETDEBUG, "sending %s (%d bytes) peer=%d\n", msg.m_type,
3328 nMessageSize, pnode->GetId());
3329 if (gArgs.GetBoolArg("-capturemessages", false)) {
3330 CaptureMessage(pnode->addr, msg.m_type, msg.data,
3331 /*is_incoming=*/false);
3332 }
3333
3334 TRACE6(net, outbound_message, pnode->GetId(), pnode->m_addr_name.c_str(),
3335 pnode->ConnectionTypeAsString().c_str(), msg.m_type.c_str(),
3336 msg.data.size(), msg.data.data());
3337
3338 // make sure we use the appropriate network transport format
3339 std::vector<uint8_t> serializedHeader;
3340 pnode->m_serializer->prepareForTransport(*config, msg, serializedHeader);
3341 size_t nTotalSize = nMessageSize + serializedHeader.size();
3342
3343 size_t nBytesSent = 0;
3344 {
3345 LOCK(pnode->cs_vSend);
3346 bool optimisticSend(pnode->vSendMsg.empty());
3347
3348 // log total amount of bytes per message type
3349 pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
3350 pnode->nSendSize += nTotalSize;
3351
3352 if (pnode->nSendSize > nSendBufferMaxSize) {
3353 pnode->fPauseSend = true;
3354 }
3355 pnode->vSendMsg.push_back(std::move(serializedHeader));
3356 if (nMessageSize) {
3357 pnode->vSendMsg.push_back(std::move(msg.data));
3358 }
3359
3360 // If write queue empty, attempt "optimistic write"
3361 bool data_left;
3362 if (optimisticSend) {
3363 std::tie(nBytesSent, data_left) = SocketSendData(*pnode);
3364 }
3365 }
3366 if (nBytesSent) {
3367 RecordBytesSent(nBytesSent);
3368 }
3369}
3370
3371bool CConnman::ForNode(NodeId id, std::function<bool(CNode *pnode)> func) {
3372 CNode *found = nullptr;
3374 for (auto &&pnode : m_nodes) {
3375 if (pnode->GetId() == id) {
3376 found = pnode;
3377 break;
3378 }
3379 }
3380 return found != nullptr && NodeFullyConnected(found) && func(found);
3381}
3382
3384 return CSipHasher(nSeed0, nSeed1).Write(id);
3385}
3386
3388 std::vector<uint8_t> vchNetGroup(ad.GetGroup(addrman.GetAsmap()));
3389
3391 .Write(vchNetGroup.data(), vchNetGroup.size())
3392 .Finalize();
3393}
3394
3409std::string getSubVersionEB(uint64_t MaxBlockSize) {
3410 // Prepare EB string we are going to add to SubVer:
3411 // 1) translate from byte to MB and convert to string
3412 // 2) limit the EB string to the first decimal digit (floored)
3413 std::stringstream ebMBs;
3414 ebMBs << (MaxBlockSize / (ONE_MEGABYTE / 10));
3415 std::string eb = ebMBs.str();
3416 eb.insert(eb.size() - 1, ".", 1);
3417 if (eb.substr(0, 1) == ".") {
3418 eb = "0" + eb;
3419 }
3420 return eb;
3421}
3422
3423std::string userAgent(const Config &config) {
3424 // format excessive blocksize value
3425 std::string eb = getSubVersionEB(config.GetMaxBlockSize());
3426 std::vector<std::string> uacomments;
3427 uacomments.push_back("EB" + eb);
3428
3429 // Comments are checked for char compliance at startup, it is safe to add
3430 // them to the user agent string
3431 for (const std::string &cmt : gArgs.GetArgs("-uacomment")) {
3432 uacomments.push_back(cmt);
3433 }
3434
3435 const std::string client_name = gArgs.GetArg("-uaclientname", CLIENT_NAME);
3436 const std::string client_version =
3437 gArgs.GetArg("-uaclientversion", FormatVersion(CLIENT_VERSION));
3438
3439 // Size compliance is checked at startup, it is safe to not check it again
3440 return FormatUserAgent(client_name, client_version, uacomments);
3441}
3442
3443void CaptureMessageToFile(const CAddress &addr, const std::string &msg_type,
3444 Span<const uint8_t> data, bool is_incoming) {
3445 // Note: This function captures the message at the time of processing,
3446 // not at socket receive/send time.
3447 // This ensures that the messages are always in order from an application
3448 // layer (processing) perspective.
3449 auto now = GetTime<std::chrono::microseconds>();
3450
3451 // Windows folder names can not include a colon
3452 std::string clean_addr = addr.ToString();
3453 std::replace(clean_addr.begin(), clean_addr.end(), ':', '_');
3454
3455 fs::path base_path = gArgs.GetDataDirNet() / "message_capture" / clean_addr;
3456 fs::create_directories(base_path);
3457
3458 fs::path path =
3459 base_path / (is_incoming ? "msgs_recv.dat" : "msgs_sent.dat");
3460 AutoFile f{fsbridge::fopen(path, "ab")};
3461
3462 ser_writedata64(f, now.count());
3463 f.write(MakeByteSpan(msg_type));
3464 for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
3465 f << uint8_t{'\0'};
3466 }
3467 uint32_t size = data.size();
3468 ser_writedata32(f, size);
3469 f.write(AsBytes(data));
3470}
3471
3472std::function<void(const CAddress &addr, const std::string &msg_type,
3473 Span<const uint8_t> data, bool is_incoming)>
std::vector< CAddress > ReadAnchors(const CChainParams &chainParams, const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:225
bool DumpPeerAddresses(const CChainParams &chainParams, const ArgsManager &args, const AddrMan &addr)
Definition: addrdb.cpp:152
void DumpAnchors(const CChainParams &chainParams, const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:215
ArgsManager gArgs
Definition: args.cpp:38
int flags
Definition: bitcoin-tx.cpp:541
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:19
Stochastic address manager.
Definition: addrman.h:68
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
Definition: addrman.cpp:1346
const std::vector< bool > & GetAsmap() const
Definition: addrman.cpp:1359
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as connection attempted to.
Definition: addrman.cpp:1329
std::pair< CAddress, NodeSeconds > Select(bool newOnly=false) const
Choose an address to connect to.
Definition: addrman.cpp:1342
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.cpp:1334
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.cpp:1315
void Good(const CService &addr, bool test_before_evict=true, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as accessible, possibly moving it from "new" to "tried".
Definition: addrman.cpp:1324
std::pair< CAddress, NodeSeconds > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict.
Definition: addrman.cpp:1338
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty=0s)
Attempt to add one or more addresses to addrman's new table.
Definition: addrman.cpp:1319
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: args.cpp:371
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:215
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: args.cpp:526
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:494
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: args.cpp:556
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:528
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
Definition: banman.cpp:89
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
Definition: banman.cpp:84
A CService with information about it as peer.
Definition: protocol.h:442
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
Definition: protocol.h:546
NodeSeconds nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
Definition: protocol.h:544
const CMessageHeader::MessageMagic & NetMagic() const
Definition: chainparams.h:94
const std::vector< SeedSpec6 > & FixedSeeds() const
Definition: chainparams.h:133
uint16_t GetDefaultPort() const
Definition: chainparams.h:95
RAII helper to atomically create a copy of m_nodes and add a reference to each of the nodes.
Definition: net.h:1402
bool whitelist_relay
flag for adding 'relay' permission to whitelisted inbound and manual peers with default permissions.
Definition: net.h:1395
std::condition_variable condMsgProc
Definition: net.h:1341
std::thread threadMessageHandler
Definition: net.h:1363
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time in second left in the current max outbound cycle in case of no limit,...
Definition: net.cpp:3186
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached.
Definition: net.cpp:3202
std::vector< NetWhitelistPermissions > vWhitelistedRangeIncoming
Definition: net.h:1242
CClientUIInterface * m_client_interface
Definition: net.h:1320
void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:2470
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
Definition: net.cpp:3371
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
Definition: net.cpp:1412
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
Definition: net.cpp:423
void DeleteNode(CNode *pnode)
Definition: net.cpp:2980
bool RemoveAddedNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:3072
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
Definition: net.cpp:1230
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
Definition: net.cpp:391
int m_max_outbound
Definition: net.h:1318
ServiceFlags nLocalServices
Services this node offers.
Definition: net.h:1300
bool GetTryNewOutboundPeer() const
Definition: net.cpp:1930
void Stop()
Definition: net.h:942
int m_max_outbound_block_relay
Definition: net.h:1311
std::thread threadI2PAcceptIncoming
Definition: net.h:1364
void SetTryNewOutboundPeer(bool flag)
Definition: net.cpp:1934
std::atomic< bool > flagInterruptMsgProc
Definition: net.h:1343
unsigned int GetReceiveFloodSize() const
Definition: net.cpp:3249
void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:2389
void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:2901
void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
Definition: net.cpp:1768
Sock::EventsPerSock GenerateWaitSockets(Span< CNode *const > nodes)
Generate a collection of sockets to check for IO readiness.
Definition: net.cpp:1570
void SocketHandlerConnected(const std::vector< CNode * > &nodes, const Sock::EventsPerSock &events_per_sock) EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Do the read/write for connected sockets that are ready for IO.
Definition: net.cpp:1624
NodeId GetNewNodeId()
Definition: net.cpp:2712
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
Definition: net.h:1351
std::unique_ptr< CSemaphore > semAddnode
Definition: net.h:1303
bool Start(CScheduler &scheduler, const Options &options) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
Definition: net.cpp:2765
std::atomic< NodeId > nLastNodeId
Definition: net.h:1260
void RecordBytesSent(uint64_t bytes)
Definition: net.cpp:3162
int GetExtraBlockRelayCount() const
Definition: net.cpp:1962
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:1760
BanMan * m_banman
Pointer to this node's banman.
Definition: net.h:1327
uint64_t GetOutboundTargetBytesLeft() const
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
Definition: net.cpp:3225
std::thread threadDNSAddressSeed
Definition: net.h:1359
void ThreadI2PAcceptIncoming()
Definition: net.cpp:2521
const uint64_t nSeed1
Definition: net.h:1336
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
Definition: net.h:1333
std::chrono::seconds GetMaxOutboundTimeframe() const
Definition: net.cpp:3182
bool whitelist_forcerelay
flag for adding 'forcerelay' permission to whitelisted inbound and manual peers with default permissi...
Definition: net.h:1389
unsigned int nPrevNodeCount
Definition: net.h:1261
void NotifyNumConnectionsChanged()
Definition: net.cpp:1511
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
Definition: net.cpp:3245
bool DisconnectNode(const std::string &node)
Definition: net.cpp:3113
std::chrono::seconds m_peer_connect_timeout
Definition: net.h:1238
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay.
Definition: net.h:1370
bool InitBinds(const Options &options)
Definition: net.cpp:2738
void AddAddrFetch(const std::string &strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex)
Definition: net.cpp:132
std::vector< ListenSocket > vhListenSocket
Definition: net.h:1249
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
Definition: net.cpp:2320
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
Definition: net.cpp:3383
uint64_t GetMaxOutboundTarget() const
Definition: net.cpp:3177
std::unique_ptr< CSemaphore > semOutbound
Definition: net.h:1302
RecursiveMutex cs_totalBytesSent
Definition: net.h:1227
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
Definition: net.cpp:2716
std::thread threadOpenConnections
Definition: net.h:1362
size_t GetNodeCount(ConnectionDirection) const
Definition: net.cpp:3084
Mutex m_addr_fetches_mutex
Definition: net.h:1254
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
Definition: net.cpp:1530
CNode * FindNode(const CNetAddr &ip)
Definition: net.cpp:351
void GetNodeStats(std::vector< CNodeStats > &vstats) const
Definition: net.cpp:3102
std::vector< AddedNodeInfo > GetAddedNodeInfo() const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:2332
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
Definition: net.h:1336
unsigned int nReceiveFloodSize
Definition: net.h:1247
int GetExtraFullOutboundCount() const
Definition: net.cpp:1946
uint64_t GetTotalBytesRecv() const
Definition: net.cpp:3236
std::pair< size_t, bool > SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
(Try to) send data from node's vSendMsg.
Definition: net.cpp:844
RecursiveMutex m_nodes_mutex
Definition: net.h:1259
static bool NodeFullyConnected(const CNode *pnode)
Definition: net.cpp:3321
void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex)
Definition: net.cpp:1912
int nMaxConnections
Definition: net.h:1304
CConnman(const Config &configIn, uint64_t seed0, uint64_t seed1, AddrMan &addrmanIn, bool network_active=true)
Definition: net.cpp:2701
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
Definition: net.cpp:2994
void SetNetworkActive(bool active)
Definition: net.cpp:2687
std::list< CNode * > m_nodes_disconnected
Definition: net.h:1258
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
Definition: net.cpp:2421
AddrMan & addrman
Definition: net.h:1252
void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Check connected and listening sockets for IO readiness and process them accordingly.
Definition: net.cpp:1596
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
Definition: net.cpp:3387
Mutex mutexMsgProc
Definition: net.h:1342
bool fAddressesInitialized
Definition: net.h:1251
~CConnman()
Definition: net.cpp:2988
void StopThreads()
Definition: net.cpp:2924
bool AddNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.cpp:3060
std::thread threadOpenAddedConnections
Definition: net.h:1361
Mutex m_added_nodes_mutex
Definition: net.h:1256
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr, const std::vector< NetWhitelistPermissions > &ranges) const
Definition: net.cpp:576
const Config * config
Definition: net.h:1224
void Init(const Options &connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Definition: net.h:890
bool CheckIncomingNonce(uint64_t nonce)
Definition: net.cpp:396
int m_max_outbound_full_relay
Definition: net.h:1307
int nMaxAddnode
Definition: net.h:1316
void RecordBytesRecv(uint64_t bytes)
Definition: net.cpp:3158
bool ShouldRunInactivityChecks(const CNode &node, std::chrono::seconds now) const
Return true if we should disconnect the peer for failing an inactivity check.
Definition: net.cpp:1525
void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
Definition: net.cpp:1752
void CreateNodeFromAcceptedSocket(std::unique_ptr< Sock > &&sock, NetPermissionFlags permission_flags, const CAddress &addr_bind, const CAddress &addr)
Create a CNode object from a socket that has just been accepted and add the node to the m_nodes membe...
Definition: net.cpp:1312
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
Definition: net.cpp:3325
void StopNodes()
Definition: net.cpp:2945
unsigned int nSendBufferMaxSize
Definition: net.h:1246
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
Definition: net.h:1357
bool m_use_addrman_outgoing
Definition: net.h:1319
std::vector< NetWhitelistPermissions > vWhitelistedRangeOutgoing
Definition: net.h:1244
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
Definition: net.h:1288
std::atomic< uint64_t > nTotalBytesRecv
Definition: net.h:1228
std::atomic< bool > fNetworkActive
Definition: net.h:1250
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
Definition: net.h:1377
void DisconnectNodes()
Definition: net.cpp:1461
void SocketHandlerListening(const Sock::EventsPerSock &events_per_sock)
Accept incoming connections, one from each read-ready listening socket.
Definition: net.cpp:1739
void DumpAddresses()
Definition: net.cpp:1903
std::vector< CService > m_onion_binds
A vector of -bind=<address>:<port>=onion arguments each of which is an address and port that are desi...
Definition: net.h:1383
std::vector< NetEventsInterface * > m_msgproc
Definition: net.h:1322
std::thread threadSocketHandler
Definition: net.h:1360
uint64_t GetTotalBytesSent() const
Definition: net.cpp:3240
void ThreadOpenConnections(std::vector< std::string > connect, std::function< void(const CAddress &, ConnectionType)> mockOpenConnection) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
Definition: net.cpp:1976
void AcceptConnection(const ListenSocket &hListenSocket)
Definition: net.cpp:1284
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
Definition: net.cpp:2559
int m_max_avalanche_outbound
Definition: net.h:1314
void resize(size_type n, value_type c=value_type{})
Definition: streams.h:225
size_type size() const
Definition: streams.h:223
CHash256 & Write(Span< const uint8_t > input)
Definition: hash.h:36
void Finalize(Span< uint8_t > output)
Definition: hash.h:29
Message header.
Definition: protocol.h:34
bool IsValid(const Config &config) const
Definition: protocol.cpp:153
static constexpr size_t CHECKSUM_SIZE
Definition: protocol.h:39
MessageMagic pchMessageStart
Definition: protocol.h:69
bool IsOversized(const Config &config) const
Definition: protocol.cpp:194
static constexpr size_t HEADER_SIZE
Definition: protocol.h:44
uint8_t pchChecksum[CHECKSUM_SIZE]
Definition: protocol.h:72
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:36
std::string GetCommand() const
Definition: protocol.cpp:119
static constexpr size_t COMMAND_SIZE
Definition: protocol.h:37
uint32_t nMessageSize
Definition: protocol.h:71
Network address.
Definition: netaddress.h:121
Network GetNetClass() const
Definition: netaddress.cpp:744
std::string ToStringIP() const
Definition: netaddress.cpp:626
std::string ToString() const
Definition: netaddress.cpp:671
bool IsRoutable() const
Definition: netaddress.cpp:512
bool IsValid() const
Definition: netaddress.cpp:477
bool IsIPv4() const
Definition: netaddress.cpp:340
bool IsIPv6() const
Definition: netaddress.cpp:344
std::vector< uint8_t > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
Definition: netaddress.cpp:806
std::vector< uint8_t > GetAddrBytes() const
Definition: netaddress.cpp:861
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:188
enum Network GetNetwork() const
Definition: netaddress.cpp:549
~CNetCleanup()
Definition: net.cpp:2892
CNetCleanup()
Definition: net.cpp:2890
Transport protocol agnostic message container.
Definition: net.h:330
uint32_t m_message_size
size of the payload
Definition: net.h:340
std::chrono::microseconds m_time
time of message receipt
Definition: net.h:335
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
Definition: net.h:342
std::string m_type
Definition: net.h:343
bool m_valid_checksum
Definition: net.h:338
bool m_valid_header
Definition: net.h:337
bool m_valid_netmagic
Definition: net.h:336
Information about a peer.
Definition: net.h:460
const CAddress addrBind
Definition: net.h:505
const std::chrono::seconds m_connected
Unix epoch time at peer connection.
Definition: net.h:500
std::atomic< int > nVersion
Definition: net.h:510
std::atomic< double > availabilityScore
The last computed score.
Definition: net.h:796
bool IsInboundConn() const
Definition: net.h:570
NodeId GetId() const
Definition: net.h:724
std::atomic< int64_t > nTimeOffset
Definition: net.h:501
const std::string m_addr_name
Definition: net.h:506
std::string ConnectionTypeAsString() const
Definition: net.h:770
std::atomic< bool > m_bip152_highbandwidth_to
Definition: net.h:608
std::list< CNetMessage > vRecvMsg
Definition: net.h:782
std::atomic< bool > m_bip152_highbandwidth_from
Definition: net.h:610
std::atomic_bool fSuccessfullyConnected
Definition: net.h:526
CNode(NodeId id, std::shared_ptr< Sock > sock, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, uint64_t nLocalExtraEntropyIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion, CNodeOptions &&node_opts={})
Definition: net.cpp:3282
const CAddress addr
Definition: net.h:503
void SetAddrLocal(const CService &addrLocalIn) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
May not be called more than once.
Definition: net.cpp:624
CSemaphoreGrant grantOutbound
Definition: net.h:530
std::unique_ptr< TransportSerializer > m_serializer
Definition: net.h:466
Mutex m_subver_mutex
cleanSubVer is a sanitized string of the user agent byte array we read from the wire.
Definition: net.h:519
Mutex cs_vSend
Definition: net.h:487
CNode * AddRef()
Definition: net.h:757
std::atomic_bool fPauseSend
Definition: net.h:535
std::unique_ptr< TransportDeserializer > m_deserializer
Definition: net.h:465
double getAvailabilityScore() const
Definition: net.cpp:3276
const ConnectionType m_conn_type
Definition: net.h:778
Network ConnectedThroughNetwork() const
Get network the peer connected through.
Definition: net.cpp:636
void copyStats(CNodeStats &stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex
Definition: net.cpp:640
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
Definition: net.h:698
void updateAvailabilityScore(double decayFactor)
The availability score is calculated using an exponentially weighted average.
Definition: net.cpp:3261
const NetPermissionFlags m_permission_flags
Definition: net.h:468
bool ReceiveMsgBytes(const Config &config, Span< const uint8_t > msg_bytes, bool &complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv)
Receive bytes from the buffer and deserialize them into messages.
Definition: net.cpp:688
void invsPolled(uint32_t count)
The node was polled for count invs.
Definition: net.cpp:3253
Mutex m_addr_local_mutex
Definition: net.h:785
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e.
Definition: net.h:509
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
Definition: net.h:704
std::atomic< std::chrono::seconds > m_last_proof_time
UNIX epoch time of the last proof received from this peer that we had not yet seen (e....
Definition: net.h:695
Mutex cs_vRecv
Definition: net.h:489
std::atomic< bool > m_avalanche_enabled
Definition: net.h:631
std::atomic< std::chrono::seconds > m_last_block_time
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
Definition: net.h:679
std::atomic< uint64_t > invCounters
The inventories polled and voted counters since last score computation, stored as a pair of uint32_t ...
Definition: net.h:793
Mutex m_sock_mutex
Definition: net.h:488
std::atomic_bool fDisconnect
Definition: net.h:529
std::atomic< std::chrono::seconds > m_last_recv
Definition: net.h:498
std::atomic< std::chrono::seconds > m_last_tx_time
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
Definition: net.h:687
CService GetAddrLocal() const EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
Definition: net.cpp:618
void invsVoted(uint32_t count)
The node voted for count invs.
Definition: net.cpp:3257
void CloseSocketDisconnect() EXCLUSIVE_LOCKS_REQUIRED(!m_sock_mutex)
Definition: net.cpp:567
std::atomic< std::chrono::seconds > m_last_send
Definition: net.h:497
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:41
void scheduleEvery(Predicate p, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat p until it return false.
Definition: scheduler.cpp:114
RAII-style semaphore lock.
Definition: sync.h:397
bool TryAcquire()
Definition: sync.h:419
void MoveTo(CSemaphoreGrant &grant)
Definition: sync.h:426
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:545
std::string ToStringIPPort() const
std::string ToString() const
uint16_t GetPort() const
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:993
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
SipHash-2-4.
Definition: siphash.h:13
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:82
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
Definition: siphash.cpp:36
std::string ToString() const
bool Match(const CNetAddr &addr) const
bool sleep_for(std::chrono::milliseconds rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut)
Minimal stream for overwriting and/or appending to an existing byte vector.
Definition: streams.h:65
Definition: config.h:19
virtual uint64_t GetMaxBlockSize() const =0
virtual const CChainParams & GetChainParams() const =0
Fast randomness source.
Definition: random.h:156
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range)
Return the time point advanced by a uniform random duration.
Definition: random.h:260
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:211
Different type to mark Mutex at global scope.
Definition: sync.h:144
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
Definition: net.h:810
NetPermissionFlags m_flags
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
static bool TryParse(const std::string &str, NetWhitebindPermissions &output, bilingual_str &error)
static constexpr Event SEND
If passed to Wait(), then it will wait for readiness to send to the socket.
Definition: sock.h:141
uint8_t Event
Definition: sock.h:129
static constexpr Event ERR
Ignored if passed to Wait(), but could be set in the occurred events if an exceptional condition has ...
Definition: sock.h:148
static constexpr Event RECV
If passed to Wait(), then it will wait for readiness to read from the socket.
Definition: sock.h:135
std::unordered_map< std::shared_ptr< const Sock >, Events, HashSharedPtrSock, EqualSharedPtrSock > EventsPerSock
On which socket to wait for what events in WaitMany().
Definition: sock.h:205
constexpr std::size_t size() const noexcept
Definition: span.h:209
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:227
constexpr C * data() const noexcept
Definition: span.h:198
CNetMessage GetMessage(const Config &config, std::chrono::microseconds time) override
Definition: net.cpp:785
CDataStream vRecv
Definition: net.h:381
CMessageHeader hdr
Definition: net.h:379
const uint256 & GetMessageHash() const
Definition: net.cpp:776
uint32_t nDataPos
Definition: net.h:383
uint32_t nHdrPos
Definition: net.h:382
int readData(Span< const uint8_t > msg_bytes)
Definition: net.cpp:759
bool Complete() const override
Definition: net.h:409
int readHeader(const Config &config, Span< const uint8_t > msg_bytes)
Definition: net.cpp:726
CHash256 hasher
Definition: net.h:371
CDataStream hdrbuf
Definition: net.h:377
uint256 data_hash
Definition: net.h:372
void prepareForTransport(const Config &config, CSerializedNetMsg &msg, std::vector< uint8_t > &header) override
Definition: net.cpp:828
uint8_t * begin()
Definition: uint256.h:85
bool IsNull() const
Definition: uint256.h:32
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
CService proxy
Definition: netbase.h:60
256-bit opaque blob.
Definition: uint256.h:129
std::string FormatVersion(int nVersion)
std::string FormatUserAgent(const std::string &name, const std::string &version, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec.
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
const std::string CLIENT_NAME
#define INVALID_SOCKET
Definition: compat.h:52
#define WSAEWOULDBLOCK
Definition: compat.h:45
#define SOCKET_ERROR
Definition: compat.h:53
#define WSAGetLastError()
Definition: compat.h:42
static bool IsSelectableSocket(const SOCKET &s)
Definition: compat.h:102
#define WSAEMSGSIZE
Definition: compat.h:47
#define MSG_NOSIGNAL
Definition: compat.h:113
#define MSG_DONTWAIT
Definition: compat.h:119
unsigned int SOCKET
Definition: compat.h:40
void * sockopt_arg_type
Definition: compat.h:87
#define WSAEINPROGRESS
Definition: compat.h:49
#define WSAEADDRINUSE
Definition: compat.h:50
#define WSAEINTR
Definition: compat.h:48
const Config & GetConfig()
Definition: config.cpp:40
static const uint64_t ONE_MEGABYTE
1MB
Definition: consensus.h:12
static uint32_t ReadLE32(const uint8_t *ptr)
Definition: common.h:23
const std::vector< std::string > GetRandomizedDNSSeeds(const CChainParams &params)
Return the list of hostnames to look up for DNS seeds.
Definition: dnsseeds.cpp:11
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:74
bool fLogIPs
Definition: logging.cpp:17
bool error(const char *fmt, const Args &...args)
Definition: logging.h:226
#define LogPrint(category,...)
Definition: logging.h:211
#define LogPrintf(...)
Definition: logging.h:207
static unsigned char elements[DATACOUNT][DATALEN]
Definition: tests_impl.h:36
@ NETDEBUG
Definition: logging.h:69
@ NET
Definition: logging.h:40
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
Definition: fs.h:179
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:30
Definition: init.h:28
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
void TraceThread(const char *thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
Definition: thread.cpp:13
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:923
bool IsPeerAddrLocalGood(CNode *pnode)
Definition: net.cpp:237
uint16_t GetListenPort()
Definition: net.cpp:137
static void EraseLastKElements(std::vector< T > &elements, Comparator comparator, size_t k, std::function< bool(const NodeEvictionCandidate &)> predicate=[](const NodeEvictionCandidate &n) { return true;})
Sort an array by the specified comparator, then erase the last K elements where predicate is true.
Definition: net.cpp:1029
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
Definition: net.cpp:72
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:346
static const uint64_t RANDOMIZER_ID_NETGROUP
Definition: net.cpp:115
CService GetLocalAddress(const CNetAddr &addrPeer)
Definition: net.cpp:221
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
Definition: net.cpp:110
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:971
void RemoveLocal(const CService &addr)
Definition: net.cpp:311
BindFlags
Used to pass flags to the Bind() function.
Definition: net.cpp:97
@ BF_REPORT_ERROR
Definition: net.cpp:100
@ BF_NONE
Definition: net.cpp:98
@ BF_EXPLICIT
Definition: net.cpp:99
@ BF_DONT_ADVERTISE
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections,...
Definition: net.cpp:105
bool fDiscover
Definition: net.cpp:125
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
Definition: net.cpp:117
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
Definition: net.cpp:67
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
Definition: net.cpp:87
bool fListen
Definition: net.cpp:126
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
Definition: net.cpp:58
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
Definition: net.cpp:173
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:913
static bool CompareNodeAvailabilityScore(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:988
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:918
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
Definition: net.cpp:408
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
Definition: net.cpp:84
static const uint64_t RANDOMIZER_ID_ADDRCACHE
Definition: net.cpp:121
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
Definition: net.cpp:1040
const std::string NET_MESSAGE_COMMAND_OTHER
Definition: net.cpp:112
std::optional< CService > GetLocalAddrForPeer(CNode &node)
Returns a local address that we should advertise to this peer.
Definition: net.cpp:243
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
Definition: net.cpp:1135
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:317
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:938
std::function< void(const CAddress &addr, const std::string &msg_type, Span< const uint8_t > data, bool is_incoming)> CaptureMessage
Defaults to CaptureMessageToFile(), but can be overridden by unit tests.
Definition: net.cpp:3474
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
Definition: net.cpp:64
std::string getSubVersionEB(uint64_t MaxBlockSize)
This function convert MaxBlockSize from byte to MB with a decimal precision one digit rounded down E....
Definition: net.cpp:3409
GlobalMutex g_maplocalhost_mutex
Definition: net.cpp:127
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(g_maplocalhost_mutex)
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:278
static bool CompareNodeProofTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:957
#define FEELER_SLEEP_WINDOW
Definition: net.cpp:94
void CaptureMessageToFile(const CAddress &addr, const std::string &msg_type, Span< const uint8_t > data, bool is_incoming)
Dump binary message to file, with timestamp.
Definition: net.cpp:3443
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
Definition: net.cpp:85
static int GetnScore(const CService &addr)
Definition: net.cpp:230
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
Definition: net.cpp:597
static const uint64_t RANDOMIZER_ID_EXTRAENTROPY
Definition: net.cpp:119
static std::vector< CAddress > convertSeed6(const std::vector< SeedSpec6 > &vSeedsIn)
Convert the pnSeed6 array into usable address objects.
Definition: net.cpp:198
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:908
static CNetCleanup instance_of_cnetcleanup
Definition: net.cpp:2899
std::string userAgent(const Config &config)
Definition: net.cpp:3423
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
Definition: net.cpp:90
void Discover()
Look up IP addresses from all interfaces on the machine and add them to the list of local addresses t...
Definition: net.cpp:2634
bool IsReachable(enum Network net)
Definition: net.cpp:325
bool SeenLocal(const CService &addr)
vote for a local address
Definition: net.cpp:335
static constexpr std::chrono::minutes TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
Definition: net.h:60
static const bool DEFAULT_FORCEDNSSEED
Definition: net.h:100
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
Definition: net.h:64
static const bool DEFAULT_FIXEDSEEDS
Definition: net.h:102
ConnectionType
Different types of connections to a peer.
Definition: net.h:148
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly inputted via the addnode RPC,...
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
@ INBOUND
Inbound connections are those initiated by a peer.
@ AVALANCHE_OUTBOUND
Special case of connection to a full relay outbound with avalanche service enabled.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
Definition: net.h:62
static const bool DEFAULT_DNSSEED
Definition: net.h:101
@ LOCAL_MANUAL
Definition: net.h:239
@ LOCAL_BIND
Definition: net.h:235
@ LOCAL_IF
Definition: net.h:233
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
Definition: net.h:75
NetPermissionFlags
Network
A network type.
Definition: netaddress.h:44
@ NET_I2P
I2P.
Definition: netaddress.h:59
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
Definition: netaddress.h:69
@ NET_ONION
TOR (v2 or v3)
Definition: netaddress.h:56
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
Definition: netaddress.h:47
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:66
bool GetNameProxy(proxyType &nameProxyOut)
Definition: netbase.cpp:734
bool HaveNameProxy()
Definition: netbase.cpp:743
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:715
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
Definition: netbase.cpp:843
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, uint16_t port, const Sock &sock, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
Definition: netbase.cpp:758
void InterruptSocks5(bool interrupt)
Definition: netbase.cpp:850
std::function< std::unique_ptr< Sock >(const CService &)> CreateSock
Socket factory.
Definition: netbase.cpp:615
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
Definition: netbase.cpp:629
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:223
bool fNameLookup
Definition: netbase.cpp:38
int nConnectTimeout
Definition: netbase.cpp:37
CService LookupNumeric(const std::string &name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
Resolve a service string with a numeric IP to its first corresponding service.
Definition: netbase.cpp:261
bool IsBadPort(uint16_t port)
Determine if a port is "bad" from the perspective of attempting to connect to a node on that port.
Definition: netbase.cpp:854
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
Definition: netbase.cpp:191
ConnectionDirection
Definition: netbase.h:32
int64_t NodeId
Definition: nodeid.h:10
const std::vector< std::string > & getAllNetMessageTypes()
Get a vector of all valid message types (see above)
Definition: protocol.cpp:243
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
Definition: protocol.cpp:204
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
Definition: protocol.h:427
ServiceFlags
nServices flags.
Definition: protocol.h:335
@ NODE_NONE
Definition: protocol.h:338
@ NODE_AVALANCHE
Definition: protocol.h:380
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
Definition: protocol.h:435
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en....
Definition: random.cpp:794
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:649
constexpr auto GetRandMillis
Definition: random.h:107
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition: random.h:85
static uint16_t GetDefaultPort()
Definition: bitcoin.h:18
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:69
@ SER_NETWORK
Definition: serialize.h:152
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:79
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: sock.cpp:398
Span< const std::byte > MakeByteSpan(V &&v) noexcept
Definition: span.h:301
Span< const std::byte > AsBytes(Span< T > s) noexcept
Definition: span.h:294
Cache responses to addr requests to minimize privacy leak.
Definition: net.h:1269
std::chrono::microseconds m_cache_entry_expiration
Definition: net.h:1271
std::vector< CAddress > m_addrs_response_cache
Definition: net.h:1270
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
Definition: net.h:1096
std::shared_ptr< Sock > sock
Definition: net.h:1095
std::vector< NetWhitebindPermissions > vWhiteBinds
Definition: net.h:876
std::vector< CService > onion_binds
Definition: net.h:878
std::vector< std::string > m_specified_outgoing
Definition: net.h:883
std::vector< CService > vBinds
Definition: net.h:877
bool m_i2p_accept_incoming
Definition: net.h:885
std::vector< std::string > vSeedNodes
Definition: net.h:873
bool m_use_addrman_outgoing
Definition: net.h:882
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0....
Definition: net.h:881
NetPermissionFlags permission_flags
Definition: net.h:455
POD that contains various stats about a node.
Definition: net.h:287
std::string addrLocal
Definition: net.h:313
CAddress addrBind
Definition: net.h:317
uint64_t nRecvBytes
Definition: net.h:307
mapMsgCmdSize mapSendBytesPerMsgCmd
Definition: net.h:306
std::chrono::microseconds m_last_ping_time
Definition: net.h:310
bool fInbound
Definition: net.h:299
uint64_t nSendBytes
Definition: net.h:305
std::chrono::seconds m_last_recv
Definition: net.h:290
std::optional< double > m_availabilityScore
Definition: net.h:322
std::chrono::seconds m_last_proof_time
Definition: net.h:292
ConnectionType m_conn_type
Definition: net.h:321
std::chrono::seconds m_last_send
Definition: net.h:289
std::chrono::seconds m_last_tx_time
Definition: net.h:291
CAddress addr
Definition: net.h:315
std::chrono::microseconds m_min_ping_time
Definition: net.h:311
int64_t nTimeOffset
Definition: net.h:295
std::chrono::seconds m_connected
Definition: net.h:294
bool m_bip152_highbandwidth_from
Definition: net.h:303
bool m_bip152_highbandwidth_to
Definition: net.h:301
std::string m_addr_name
Definition: net.h:296
mapMsgCmdSize mapRecvBytesPerMsgCmd
Definition: net.h:308
int nVersion
Definition: net.h:297
std::chrono::seconds m_last_block_time
Definition: net.h:293
Network m_network
Definition: net.h:319
NodeId nodeid
Definition: net.h:288
std::string cleanSubVer
Definition: net.h:298
NetPermissionFlags m_permission_flags
Definition: net.h:309
std::vector< uint8_t > data
Definition: net.h:131
std::string m_type
Definition: net.h:132
Sort eviction candidates by network/localhost and connection uptime.
Definition: net.cpp:1009
CompareNodeNetworkTime(bool is_local, Network network)
Definition: net.cpp:1012
const Network m_network
Definition: net.cpp:1011
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) const
Definition: net.cpp:1014
const bool m_is_local
Definition: net.cpp:1010
uint16_t nPort
Definition: net.h:271
int nScore
Definition: net.h:270
static time_point now() noexcept
Return current system time or mocked time, if set.
Definition: time.cpp:71
std::chrono::seconds m_last_tx_time
Definition: net.h:1454
Network m_network
Definition: net.h:1461
double availabilityScore
Definition: net.h:1462
std::chrono::seconds m_connected
Definition: net.h:1450
std::chrono::seconds m_last_block_time
Definition: net.h:1452
bool fRelevantServices
Definition: net.h:1455
std::chrono::microseconds m_min_ping_time
Definition: net.h:1451
std::chrono::seconds m_last_proof_time
Definition: net.h:1453
uint64_t nKeyedNetGroup
Definition: net.h:1458
Auxiliary requested/occurred events to wait for in WaitMany().
Definition: sock.h:170
Bilingual messages:
Definition: translation.h:17
std::string original
Definition: translation.h:18
An established connection with another peer.
Definition: i2p.h:31
std::unique_ptr< Sock > sock
Connected socket.
Definition: i2p.h:33
CService me
Our I2P address.
Definition: i2p.h:36
#define WAIT_LOCK(cs, name)
Definition: sync.h:317
#define AssertLockNotHeld(cs)
Definition: sync.h:163
#define LOCK2(cs1, cs2)
Definition: sync.h:309
#define LOCK(cs)
Definition: sync.h:306
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
static int count
Definition: tests.c:31
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:101
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
Definition: time.cpp:109
constexpr int64_t count_seconds(std::chrono::seconds t)
Definition: time.h:55
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
Definition: time.h:25
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
#define TRACE6(context, event, a, b, c, d, e, f)
Definition: trace.h:45
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
void SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
assert(!tx.IsCoinBase())
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:14