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