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