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