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