Bitcoin Core 22.99.0
P2P Digital Currency
net.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2020 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)
8#endif
9
10#include <net.h>
11
12#include <addrdb.h>
13#include <banman.h>
14#include <clientversion.h>
15#include <compat.h>
16#include <consensus/consensus.h>
17#include <crypto/sha256.h>
18#include <i2p.h>
19#include <net_permissions.h>
20#include <netaddress.h>
21#include <netbase.h>
22#include <node/ui_interface.h>
23#include <protocol.h>
24#include <random.h>
25#include <scheduler.h>
26#include <util/sock.h>
27#include <util/strencodings.h>
29#include <util/system.h>
30#include <util/thread.h>
31#include <util/trace.h>
32#include <util/translation.h>
33
34#ifdef WIN32
35#include <string.h>
36#else
37#include <fcntl.h>
38#endif
39
40#if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
41#include <ifaddrs.h>
42#endif
43
44#ifdef USE_POLL
45#include <poll.h>
46#endif
47
48#include <algorithm>
49#include <array>
50#include <cstdint>
51#include <functional>
52#include <optional>
53#include <unordered_map>
54
55#include <math.h>
56
58static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS = 2;
59static_assert (MAX_BLOCK_RELAY_ONLY_ANCHORS <= static_cast<size_t>(MAX_BLOCK_RELAY_ONLY_CONNECTIONS), "MAX_BLOCK_RELAY_ONLY_ANCHORS must not exceed MAX_BLOCK_RELAY_ONLY_CONNECTIONS.");
61const char* const ANCHORS_DATABASE_FILENAME = "anchors.dat";
62
63// How often to dump addresses to peers.dat
64static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
65
67static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
68
78static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
79static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
80static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000; // "many" vs "few" peers
81
83static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME{60 * 60 * 24};
84
85// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
86#define FEELER_SLEEP_WINDOW 1
87
91 BF_EXPLICIT = (1U << 0),
92 BF_REPORT_ERROR = (1U << 1),
97 BF_DONT_ADVERTISE = (1U << 2),
98};
99
100// The set of sockets cannot be modified while waiting
101// The sleep time needs to be small to avoid new sockets stalling
102static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
103
104const std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
105
106static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL; // SHA256("netgroup")[0:8]
107static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL; // SHA256("localhostnonce")[0:8]
108static const uint64_t RANDOMIZER_ID_ADDRCACHE = 0x1cf2e4ddd306dda9ULL; // SHA256("addrcache")[0:8]
109//
110// Global state variables
111//
112bool fDiscover = true;
113bool fListen = true;
115std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(cs_mapLocalHost);
116static bool vfLimited[NET_MAX] GUARDED_BY(cs_mapLocalHost) = {};
117std::string strSubVersion;
118
119void CConnman::AddAddrFetch(const std::string& strDest)
120{
122 m_addr_fetches.push_back(strDest);
123}
124
126{
127 return static_cast<uint16_t>(gArgs.GetIntArg("-port", Params().GetDefaultPort()));
128}
129
130// find 'best' local address for a particular peer
131bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
132{
133 if (!fListen)
134 return false;
135
136 int nBestScore = -1;
137 int nBestReachability = -1;
138 {
140 for (const auto& entry : mapLocalHost)
141 {
142 int nScore = entry.second.nScore;
143 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
144 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
145 {
146 addr = CService(entry.first, entry.second.nPort);
147 nBestReachability = nReachability;
148 nBestScore = nScore;
149 }
150 }
151 }
152 return nBestScore >= 0;
153}
154
156static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
157{
158 // It'll only connect to one or two seed nodes because once it connects,
159 // it'll get a pile of addresses with newer timestamps.
160 // Seed nodes are given a random 'last seen time' of between one and two
161 // weeks ago.
162 const int64_t nOneWeek = 7*24*60*60;
163 std::vector<CAddress> vSeedsOut;
166 while (!s.eof()) {
167 CService endpoint;
168 s >> endpoint;
170 addr.nTime = GetTime() - rng.randrange(nOneWeek) - nOneWeek;
171 LogPrint(BCLog::NET, "Added hardcoded seed: %s\n", addr.ToString());
172 vSeedsOut.push_back(addr);
173 }
174 return vSeedsOut;
175}
176
177// get best local address for a particular peer as a CAddress
178// Otherwise, return the unroutable 0.0.0.0 but filled in with
179// the normal parameters, since the IP may be changed to a useful
180// one by discovery.
181CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
182{
183 CAddress ret(CService(CNetAddr(),GetListenPort()), nLocalServices);
184 CService addr;
185 if (GetLocal(addr, paddrPeer))
186 {
187 ret = CAddress(addr, nLocalServices);
188 }
189 ret.nTime = GetAdjustedTime();
190 return ret;
191}
192
193static int GetnScore(const CService& addr)
194{
196 const auto it = mapLocalHost.find(addr);
197 return (it != mapLocalHost.end()) ? it->second.nScore : 0;
198}
199
200// Is our peer's addrLocal potentially useful as an external IP source?
202{
203 CService addrLocal = pnode->GetAddrLocal();
204 return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
205 IsReachable(addrLocal.GetNetwork());
206}
207
208std::optional<CAddress> GetLocalAddrForPeer(CNode *pnode)
209{
210 CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
211 if (gArgs.GetBoolArg("-addrmantest", false)) {
212 // use IPv4 loopback during addrmantest
213 addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
214 }
215 // If discovery is enabled, sometimes give our peer the address it
216 // tells us that it sees us as in case it has a better idea of our
217 // address than we do.
219 if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
220 rng.randbits((GetnScore(addrLocal) > LOCAL_MANUAL) ? 3 : 1) == 0))
221 {
222 addrLocal.SetIP(pnode->GetAddrLocal());
223 }
224 if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
225 {
226 LogPrint(BCLog::NET, "Advertising address %s to peer=%d\n", addrLocal.ToString(), pnode->GetId());
227 return addrLocal;
228 }
229 // Address is unroutable. Don't advertise.
230 return std::nullopt;
231}
232
241{
242 CService ret{service};
243 if (ret.m_net == NET_IPV6 && ret.m_addr[0] == 0xfc && IsReachable(NET_CJDNS)) {
244 ret.m_net = NET_CJDNS;
245 }
246 return ret;
247}
248
249// learn a new local address
250bool AddLocal(const CService& addr_, int nScore)
251{
252 CService addr{MaybeFlipIPv6toCJDNS(addr_)};
253
254 if (!addr.IsRoutable())
255 return false;
256
257 if (!fDiscover && nScore < LOCAL_MANUAL)
258 return false;
259
260 if (!IsReachable(addr))
261 return false;
262
263 LogPrintf("AddLocal(%s,%i)\n", addr.ToString(), nScore);
264
265 {
267 const auto [it, is_newly_added] = mapLocalHost.emplace(addr, LocalServiceInfo());
268 LocalServiceInfo &info = it->second;
269 if (is_newly_added || nScore >= info.nScore) {
270 info.nScore = nScore + (is_newly_added ? 0 : 1);
271 info.nPort = addr.GetPort();
272 }
273 }
274
275 return true;
276}
277
278bool AddLocal(const CNetAddr &addr, int nScore)
279{
280 return AddLocal(CService(addr, GetListenPort()), nScore);
281}
282
283void RemoveLocal(const CService& addr)
284{
286 LogPrintf("RemoveLocal(%s)\n", addr.ToString());
287 mapLocalHost.erase(addr);
288}
289
290void SetReachable(enum Network net, bool reachable)
291{
292 if (net == NET_UNROUTABLE || net == NET_INTERNAL)
293 return;
295 vfLimited[net] = !reachable;
296}
297
298bool IsReachable(enum Network net)
299{
301 return !vfLimited[net];
302}
303
304bool IsReachable(const CNetAddr &addr)
305{
306 return IsReachable(addr.GetNetwork());
307}
308
310bool SeenLocal(const CService& addr)
311{
313 const auto it = mapLocalHost.find(addr);
314 if (it == mapLocalHost.end()) return false;
315 ++it->second.nScore;
316 return true;
317}
318
319
321bool IsLocal(const CService& addr)
322{
324 return mapLocalHost.count(addr) > 0;
325}
326
328{
330 for (CNode* pnode : vNodes) {
331 if (static_cast<CNetAddr>(pnode->addr) == ip) {
332 return pnode;
333 }
334 }
335 return nullptr;
336}
337
339{
341 for (CNode* pnode : vNodes) {
342 if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
343 return pnode;
344 }
345 }
346 return nullptr;
347}
348
349CNode* CConnman::FindNode(const std::string& addrName)
350{
352 for (CNode* pnode : vNodes) {
353 if (pnode->m_addr_name == addrName) {
354 return pnode;
355 }
356 }
357 return nullptr;
358}
359
361{
363 for (CNode* pnode : vNodes) {
364 if (static_cast<CService>(pnode->addr) == addr) {
365 return pnode;
366 }
367 }
368 return nullptr;
369}
370
372{
373 return FindNode(static_cast<CNetAddr>(addr)) || FindNode(addr.ToStringIPPort());
374}
375
377{
379 for (const CNode* pnode : vNodes) {
380 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
381 return false;
382 }
383 return true;
384}
385
388{
389 CAddress addr_bind;
390 struct sockaddr_storage sockaddr_bind;
391 socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
392 if (sock != INVALID_SOCKET) {
393 if (!getsockname(sock, (struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
394 addr_bind.SetSockAddr((const struct sockaddr*)&sockaddr_bind);
395 } else {
396 LogPrint(BCLog::NET, "Warning: getsockname failed\n");
397 }
398 }
399 return addr_bind;
400}
401
402CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
403{
404 assert(conn_type != ConnectionType::INBOUND);
405
406 if (pszDest == nullptr) {
407 if (IsLocal(addrConnect))
408 return nullptr;
409
410 // Look for an existing connection
411 CNode* pnode = FindNode(static_cast<CService>(addrConnect));
412 if (pnode)
413 {
414 LogPrintf("Failed to open new connection, already connected\n");
415 return nullptr;
416 }
417 }
418
420 LogPrint(BCLog::NET, "trying connection %s lastseen=%.1fhrs\n",
421 pszDest ? pszDest : addrConnect.ToString(),
422 pszDest ? 0.0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
423
424 // Resolve
425 const uint16_t default_port{pszDest != nullptr ? Params().GetDefaultPort(pszDest) :
427 if (pszDest) {
428 std::vector<CService> resolved;
429 if (Lookup(pszDest, resolved, default_port, fNameLookup && !HaveNameProxy(), 256) && !resolved.empty()) {
430 const CService rnd{resolved[GetRand(resolved.size())]};
431 addrConnect = CAddress{MaybeFlipIPv6toCJDNS(rnd), NODE_NONE};
432 if (!addrConnect.IsValid()) {
433 LogPrint(BCLog::NET, "Resolver returned invalid address %s for %s\n", addrConnect.ToString(), pszDest);
434 return nullptr;
435 }
436 // It is possible that we already have a connection to the IP/port pszDest resolved to.
437 // In that case, drop the connection that was just created.
439 CNode* pnode = FindNode(static_cast<CService>(addrConnect));
440 if (pnode) {
441 LogPrintf("Failed to open new connection, already connected\n");
442 return nullptr;
443 }
444 }
445 }
446
447 // Connect
448 bool connected = false;
449 std::unique_ptr<Sock> sock;
450 proxyType proxy;
451 CAddress addr_bind;
452 assert(!addr_bind.IsValid());
453
454 if (addrConnect.IsValid()) {
455 bool proxyConnectionFailed = false;
456
457 if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) {
458 i2p::Connection conn;
459 if (m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed)) {
460 connected = true;
461 sock = std::move(conn.sock);
462 addr_bind = CAddress{conn.me, NODE_NONE};
463 }
464 } else if (GetProxy(addrConnect.GetNetwork(), proxy)) {
465 sock = CreateSock(proxy.proxy);
466 if (!sock) {
467 return nullptr;
468 }
469 connected = ConnectThroughProxy(proxy, addrConnect.ToStringIP(), addrConnect.GetPort(),
470 *sock, nConnectTimeout, proxyConnectionFailed);
471 } else {
472 // no proxy needed (none set for target network)
473 sock = CreateSock(addrConnect);
474 if (!sock) {
475 return nullptr;
476 }
477 connected = ConnectSocketDirectly(addrConnect, *sock, nConnectTimeout,
478 conn_type == ConnectionType::MANUAL);
479 }
480 if (!proxyConnectionFailed) {
481 // If a connection to the node was attempted, and failure (if any) is not caused by a problem connecting to
482 // the proxy, mark this as an attempt.
483 addrman.Attempt(addrConnect, fCountFailure);
484 }
485 } else if (pszDest && GetNameProxy(proxy)) {
486 sock = CreateSock(proxy.proxy);
487 if (!sock) {
488 return nullptr;
489 }
490 std::string host;
491 uint16_t port{default_port};
492 SplitHostPort(std::string(pszDest), port, host);
493 bool proxyConnectionFailed;
494 connected = ConnectThroughProxy(proxy, host, port, *sock, nConnectTimeout,
495 proxyConnectionFailed);
496 }
497 if (!connected) {
498 return nullptr;
499 }
500
501 // Add node
502 NodeId id = GetNewNodeId();
504 if (!addr_bind.IsValid()) {
505 addr_bind = GetBindAddress(sock->Get());
506 }
507 CNode* pnode = new CNode(id, nLocalServices, sock->Release(), addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type, /* inbound_onion */ false);
508 pnode->AddRef();
509
510 // We're making a new connection, harvest entropy from the time (and our peer count)
511 RandAddEvent((uint32_t)id);
512
513 return pnode;
514}
515
517{
518 fDisconnect = true;
520 if (hSocket != INVALID_SOCKET)
521 {
522 LogPrint(BCLog::NET, "disconnecting peer=%d\n", id);
523 CloseSocket(hSocket);
524 }
525}
526
528 for (const auto& subnet : vWhitelistedRange) {
529 if (subnet.m_subnet.Match(addr)) NetPermissions::AddFlag(flags, subnet.m_flags);
530 }
531}
532
534{
535 switch (conn_type) {
537 return "inbound";
539 return "manual";
541 return "feeler";
543 return "outbound-full-relay";
545 return "block-relay-only";
547 return "addr-fetch";
548 } // no default case, so the compiler can warn about missing cases
549
550 assert(false);
551}
552
554{
556 return addrLocal;
557}
558
559void CNode::SetAddrLocal(const CService& addrLocalIn) {
561 if (addrLocal.IsValid()) {
562 error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
563 } else {
564 addrLocal = addrLocalIn;
565 }
566}
567
569{
571}
572
573#undef X
574#define X(name) stats.name = name
576{
577 stats.nodeid = this->GetId();
578 X(nServices);
579 X(addr);
580 X(addrBind);
582 if (m_tx_relay != nullptr) {
583 LOCK(m_tx_relay->cs_filter);
584 stats.fRelayTxes = m_tx_relay->fRelayTxes;
585 } else {
586 stats.fRelayTxes = false;
587 }
588 X(nLastSend);
589 X(nLastRecv);
590 X(nLastTXTime);
593 X(nTimeOffset);
594 X(m_addr_name);
595 X(nVersion);
596 {
598 X(cleanSubVer);
599 }
600 stats.fInbound = IsInboundConn();
603 {
604 LOCK(cs_vSend);
605 X(mapSendBytesPerMsgCmd);
606 X(nSendBytes);
607 }
608 {
609 LOCK(cs_vRecv);
610 X(mapRecvBytesPerMsgCmd);
611 X(nRecvBytes);
612 }
614 if (m_tx_relay != nullptr) {
615 stats.minFeeFilter = m_tx_relay->minFeeFilter;
616 } else {
617 stats.minFeeFilter = 0;
618 }
619
622
623 // Leave string empty if addrLocal invalid (not filled in yet)
624 CService addrLocalUnlocked = GetAddrLocal();
625 stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
626
627 X(m_conn_type);
628}
629#undef X
630
631bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
632{
633 complete = false;
634 const auto time = GetTime<std::chrono::microseconds>();
635 LOCK(cs_vRecv);
636 nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count();
637 nRecvBytes += msg_bytes.size();
638 while (msg_bytes.size() > 0) {
639 // absorb network data
640 int handled = m_deserializer->Read(msg_bytes);
641 if (handled < 0) {
642 // Serious header problem, disconnect from the peer.
643 return false;
644 }
645
646 if (m_deserializer->Complete()) {
647 // decompose a transport agnostic CNetMessage from the deserializer
648 bool reject_message{false};
649 CNetMessage msg = m_deserializer->GetMessage(time, reject_message);
650 if (reject_message) {
651 // Message deserialization failed. Drop the message but don't disconnect the peer.
652 // store the size of the corrupt message
653 mapRecvBytesPerMsgCmd.at(NET_MESSAGE_COMMAND_OTHER) += msg.m_raw_message_size;
654 continue;
655 }
656
657 // Store received bytes per message command
658 // to prevent a memory DOS, only allow valid commands
659 auto i = mapRecvBytesPerMsgCmd.find(msg.m_command);
660 if (i == mapRecvBytesPerMsgCmd.end()) {
661 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
662 }
663 assert(i != mapRecvBytesPerMsgCmd.end());
664 i->second += msg.m_raw_message_size;
665
666 // push the message to the process queue,
667 vRecvMsg.push_back(std::move(msg));
668
669 complete = true;
670 }
671 }
672
673 return true;
674}
675
677{
678 // copy data to temporary parsing buffer
679 unsigned int nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
680 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
681
682 memcpy(&hdrbuf[nHdrPos], msg_bytes.data(), nCopy);
683 nHdrPos += nCopy;
684
685 // if header incomplete, exit
687 return nCopy;
688
689 // deserialize to CMessageHeader
690 try {
691 hdrbuf >> hdr;
692 }
693 catch (const std::exception&) {
694 LogPrint(BCLog::NET, "Header error: Unable to deserialize, peer=%d\n", m_node_id);
695 return -1;
696 }
697
698 // Check start string, network magic
700 LogPrint(BCLog::NET, "Header error: Wrong MessageStart %s received, peer=%d\n", HexStr(hdr.pchMessageStart), m_node_id);
701 return -1;
702 }
703
704 // reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH
706 LogPrint(BCLog::NET, "Header error: Size too large (%s, %u bytes), peer=%d\n", SanitizeString(hdr.GetCommand()), hdr.nMessageSize, m_node_id);
707 return -1;
708 }
709
710 // switch state to reading message data
711 in_data = true;
712
713 return nCopy;
714}
715
717{
718 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
719 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
720
721 if (vRecv.size() < nDataPos + nCopy) {
722 // Allocate up to 256 KiB ahead, but never more than the total message size.
723 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
724 }
725
726 hasher.Write(msg_bytes.first(nCopy));
727 memcpy(&vRecv[nDataPos], msg_bytes.data(), nCopy);
728 nDataPos += nCopy;
729
730 return nCopy;
731}
732
734{
735 assert(Complete());
736 if (data_hash.IsNull())
738 return data_hash;
739}
740
741CNetMessage V1TransportDeserializer::GetMessage(const std::chrono::microseconds time, bool& reject_message)
742{
743 // Initialize out parameter
744 reject_message = false;
745 // decompose a single CNetMessage from the TransportDeserializer
746 CNetMessage msg(std::move(vRecv));
747
748 // store command string, time, and sizes
749 msg.m_command = hdr.GetCommand();
750 msg.m_time = time;
753
754 uint256 hash = GetMessageHash();
755
756 // We just received a message off the wire, harvest entropy from the time (and the message checksum)
757 RandAddEvent(ReadLE32(hash.begin()));
758
759 // Check checksum and header command string
760 if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0) {
761 LogPrint(BCLog::NET, "Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
765 m_node_id);
766 reject_message = true;
767 } else if (!hdr.IsCommandValid()) {
768 LogPrint(BCLog::NET, "Header error: Invalid message type (%s, %u bytes), peer=%d\n",
770 reject_message = true;
771 }
772
773 // Always reset the network deserializer (prepare for the next message)
774 Reset();
775 return msg;
776}
777
778void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) {
779 // create dbl-sha256 checksum
780 uint256 hash = Hash(msg.data);
781
782 // create header
783 CMessageHeader hdr(Params().MessageStart(), msg.m_type.c_str(), msg.data.size());
785
786 // serialize header
787 header.reserve(CMessageHeader::HEADER_SIZE);
789}
790
792{
793 auto it = node.vSendMsg.begin();
794 size_t nSentSize = 0;
795
796 while (it != node.vSendMsg.end()) {
797 const auto& data = *it;
798 assert(data.size() > node.nSendOffset);
799 int nBytes = 0;
801 LOCK(node.cs_hSocket);
802 if (node.hSocket == INVALID_SOCKET)
803 break;
804 nBytes = send(node.hSocket, reinterpret_cast<const char*>(data.data()) + node.nSendOffset, data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
805 }
806 if (nBytes > 0) {
807 node.nLastSend = GetTimeSeconds();
808 node.nSendBytes += nBytes;
809 node.nSendOffset += nBytes;
810 nSentSize += nBytes;
811 if (node.nSendOffset == data.size()) {
812 node.nSendOffset = 0;
813 node.nSendSize -= data.size();
814 node.fPauseSend = node.nSendSize > nSendBufferMaxSize;
815 it++;
816 } else {
817 // could not send full message; stop sending more
818 break;
819 }
820 } else {
821 if (nBytes < 0) {
822 // error
823 int nErr = WSAGetLastError();
824 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) {
825 LogPrint(BCLog::NET, "socket send error for peer=%d: %s\n", node.GetId(), NetworkErrorString(nErr));
826 node.CloseSocketDisconnect();
827 }
828 }
829 // couldn't send anything at all
830 break;
831 }
832 }
833
834 if (it == node.vSendMsg.end()) {
835 assert(node.nSendOffset == 0);
836 assert(node.nSendSize == 0);
837 }
838 node.vSendMsg.erase(node.vSendMsg.begin(), it);
839 return nSentSize;
840}
841
843{
844 return a.m_min_ping_time > b.m_min_ping_time;
845}
846
848{
849 return a.nTimeConnected > b.nTimeConnected;
850}
851
853 return a.nKeyedNetGroup < b.nKeyedNetGroup;
854}
855
857{
858 // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
861 return a.nTimeConnected > b.nTimeConnected;
862}
863
865{
866 // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn.
867 if (a.nLastTXTime != b.nLastTXTime) return a.nLastTXTime < b.nLastTXTime;
868 if (a.fRelayTxes != b.fRelayTxes) return b.fRelayTxes;
869 if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
870 return a.nTimeConnected > b.nTimeConnected;
871}
872
873// Pick out the potential block-relay only peers, and sort them by last block time.
875{
876 if (a.fRelayTxes != b.fRelayTxes) return a.fRelayTxes;
879 return a.nTimeConnected > b.nTimeConnected;
880}
881
891 const bool m_is_local;
893 CompareNodeNetworkTime(bool is_local, Network network) : m_is_local(is_local), m_network(network) {}
895 {
896 if (m_is_local && a.m_is_local != b.m_is_local) return b.m_is_local;
897 if ((a.m_network == m_network) != (b.m_network == m_network)) return b.m_network == m_network;
898 return a.nTimeConnected > b.nTimeConnected;
899 };
900};
901
903template <typename T, typename Comparator>
905 std::vector<T>& elements, Comparator comparator, size_t k,
906 std::function<bool(const NodeEvictionCandidate&)> predicate = [](const NodeEvictionCandidate& n) { return true; })
907{
908 std::sort(elements.begin(), elements.end(), comparator);
909 size_t eraseSize = std::min(k, elements.size());
910 elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
911}
912
913void ProtectEvictionCandidatesByRatio(std::vector<NodeEvictionCandidate>& eviction_candidates)
914{
915 // Protect the half of the remaining nodes which have been connected the longest.
916 // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
917 // To favorise the diversity of our peer connections, reserve up to half of these protected
918 // spots for Tor/onion, localhost and I2P peers, even if they're not longest uptime overall.
919 // This helps protect these higher-latency peers that tend to be otherwise
920 // disadvantaged under our eviction criteria.
921 const size_t initial_size = eviction_candidates.size();
922 const size_t total_protect_size{initial_size / 2};
923
924 // Disadvantaged networks to protect: I2P, localhost, Tor/onion. In case of equal counts, earlier
925 // array members have first opportunity to recover unused slots from the previous iteration.
926 struct Net { bool is_local; Network id; size_t count; };
927 std::array<Net, 3> networks{
928 {{false, NET_I2P, 0}, {/* localhost */ true, NET_MAX, 0}, {false, NET_ONION, 0}}};
929
930 // Count and store the number of eviction candidates per network.
931 for (Net& n : networks) {
932 n.count = std::count_if(eviction_candidates.cbegin(), eviction_candidates.cend(),
933 [&n](const NodeEvictionCandidate& c) {
934 return n.is_local ? c.m_is_local : c.m_network == n.id;
935 });
936 }
937 // Sort `networks` by ascending candidate count, to give networks having fewer candidates
938 // the first opportunity to recover unused protected slots from the previous iteration.
939 std::stable_sort(networks.begin(), networks.end(), [](Net a, Net b) { return a.count < b.count; });
940
941 // Protect up to 25% of the eviction candidates by disadvantaged network.
942 const size_t max_protect_by_network{total_protect_size / 2};
943 size_t num_protected{0};
944
945 while (num_protected < max_protect_by_network) {
946 // Count the number of disadvantaged networks from which we have peers to protect.
947 auto num_networks = std::count_if(networks.begin(), networks.end(), [](const Net& n) { return n.count; });
948 if (num_networks == 0) {
949 break;
950 }
951 const size_t disadvantaged_to_protect{max_protect_by_network - num_protected};
952 const size_t protect_per_network{std::max(disadvantaged_to_protect / num_networks, static_cast<size_t>(1))};
953 // Early exit flag if there are no remaining candidates by disadvantaged network.
954 bool protected_at_least_one{false};
955
956 for (Net& n : networks) {
957 if (n.count == 0) continue;
958 const size_t before = eviction_candidates.size();
959 EraseLastKElements(eviction_candidates, CompareNodeNetworkTime(n.is_local, n.id),
960 protect_per_network, [&n](const NodeEvictionCandidate& c) {
961 return n.is_local ? c.m_is_local : c.m_network == n.id;
962 });
963 const size_t after = eviction_candidates.size();
964 if (before > after) {
965 protected_at_least_one = true;
966 const size_t delta{before - after};
967 num_protected += delta;
968 if (num_protected >= max_protect_by_network) {
969 break;
970 }
971 n.count -= delta;
972 }
973 }
974 if (!protected_at_least_one) {
975 break;
976 }
977 }
978
979 // Calculate how many we removed, and update our total number of peers that
980 // we want to protect based on uptime accordingly.
981 assert(num_protected == initial_size - eviction_candidates.size());
982 const size_t remaining_to_protect{total_protect_size - num_protected};
983 EraseLastKElements(eviction_candidates, ReverseCompareNodeTimeConnected, remaining_to_protect);
984}
985
986[[nodiscard]] std::optional<NodeId> SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates)
987{
988 // Protect connections with certain characteristics
989
990 // Deterministically select 4 peers to protect by netgroup.
991 // An attacker cannot predict which netgroups will be protected
992 EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
993 // Protect the 8 nodes with the lowest minimum ping time.
994 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
995 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
996 // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
997 // An attacker cannot manipulate this metric without performing useful work.
998 EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
999 // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
1000 EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
1001 [](const NodeEvictionCandidate& n) { return !n.fRelayTxes && n.fRelevantServices; });
1002
1003 // Protect 4 nodes that most recently sent us novel blocks.
1004 // An attacker cannot manipulate this metric without performing useful work.
1005 EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
1006
1007 // Protect some of the remaining eviction candidates by ratios of desirable
1008 // or disadvantaged characteristics.
1009 ProtectEvictionCandidatesByRatio(vEvictionCandidates);
1010
1011 if (vEvictionCandidates.empty()) return std::nullopt;
1012
1013 // If any remaining peers are preferred for eviction consider only them.
1014 // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
1015 // then we probably don't want to evict it no matter what.
1016 if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
1017 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1018 [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
1019 }
1020
1021 // Identify the network group with the most connections and youngest member.
1022 // (vEvictionCandidates is already sorted by reverse connect time)
1023 uint64_t naMostConnections;
1024 unsigned int nMostConnections = 0;
1025 int64_t nMostConnectionsTime = 0;
1026 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1027 for (const NodeEvictionCandidate &node : vEvictionCandidates) {
1028 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
1029 group.push_back(node);
1030 const int64_t grouptime = group[0].nTimeConnected;
1031
1032 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1033 nMostConnections = group.size();
1034 nMostConnectionsTime = grouptime;
1035 naMostConnections = node.nKeyedNetGroup;
1036 }
1037 }
1038
1039 // Reduce to the network group with the most connections
1040 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1041
1042 // Disconnect from the network group with the most connections
1043 return vEvictionCandidates.front().id;
1044}
1045
1055{
1056 std::vector<NodeEvictionCandidate> vEvictionCandidates;
1057 {
1058
1059 LOCK(cs_vNodes);
1060 for (const CNode* node : vNodes) {
1061 if (node->HasPermission(NetPermissionFlags::NoBan))
1062 continue;
1063 if (!node->IsInboundConn())
1064 continue;
1065 if (node->fDisconnect)
1066 continue;
1067 bool peer_relay_txes = false;
1068 bool peer_filter_not_null = false;
1069 if (node->m_tx_relay != nullptr) {
1070 LOCK(node->m_tx_relay->cs_filter);
1071 peer_relay_txes = node->m_tx_relay->fRelayTxes;
1072 peer_filter_not_null = node->m_tx_relay->pfilter != nullptr;
1073 }
1074 NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->m_min_ping_time,
1075 node->nLastBlockTime, node->nLastTXTime,
1077 peer_relay_txes, peer_filter_not_null, node->nKeyedNetGroup,
1078 node->m_prefer_evict, node->addr.IsLocal(),
1079 node->ConnectedThroughNetwork()};
1080 vEvictionCandidates.push_back(candidate);
1081 }
1082 }
1083 const std::optional<NodeId> node_id_to_evict = SelectNodeToEvict(std::move(vEvictionCandidates));
1084 if (!node_id_to_evict) {
1085 return false;
1086 }
1087 LOCK(cs_vNodes);
1088 for (CNode* pnode : vNodes) {
1089 if (pnode->GetId() == *node_id_to_evict) {
1090 LogPrint(BCLog::NET, "selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId());
1091 pnode->fDisconnect = true;
1092 return true;
1093 }
1094 }
1095 return false;
1096}
1097
1098void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
1099 struct sockaddr_storage sockaddr;
1100 socklen_t len = sizeof(sockaddr);
1101 SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len);
1102 CAddress addr;
1103
1104 if (hSocket == INVALID_SOCKET) {
1105 const int nErr = WSAGetLastError();
1106 if (nErr != WSAEWOULDBLOCK) {
1107 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr));
1108 }
1109 return;
1110 }
1111
1112 if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) {
1113 LogPrintf("Warning: Unknown socket family\n");
1114 } else {
1116 }
1117
1118 const CAddress addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(hSocket)), NODE_NONE};
1119
1121 hListenSocket.AddSocketPermissionFlags(permissionFlags);
1122
1123 CreateNodeFromAcceptedSocket(hSocket, permissionFlags, addr_bind, addr);
1124}
1125
1127 NetPermissionFlags permissionFlags,
1128 const CAddress& addr_bind,
1129 const CAddress& addr)
1130{
1131 int nInbound = 0;
1132 int nMaxInbound = nMaxConnections - m_max_outbound;
1133
1134 AddWhitelistPermissionFlags(permissionFlags, addr);
1141 }
1142
1143 {
1144 LOCK(cs_vNodes);
1145 for (const CNode* pnode : vNodes) {
1146 if (pnode->IsInboundConn()) nInbound++;
1147 }
1148 }
1149
1150 if (!fNetworkActive) {
1151 LogPrint(BCLog::NET, "connection from %s dropped: not accepting new connections\n", addr.ToString());
1152 CloseSocket(hSocket);
1153 return;
1154 }
1155
1156 if (!IsSelectableSocket(hSocket))
1157 {
1158 LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString());
1159 CloseSocket(hSocket);
1160 return;
1161 }
1162
1163 // According to the internet TCP_NODELAY is not carried into accepted sockets
1164 // on all platforms. Set it again here just to be sure.
1165 SetSocketNoDelay(hSocket);
1166
1167 // Don't accept connections from banned peers.
1168 bool banned = m_banman && m_banman->IsBanned(addr);
1169 if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && banned)
1170 {
1171 LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
1172 CloseSocket(hSocket);
1173 return;
1174 }
1175
1176 // Only accept connections from discouraged peers if our inbound slots aren't (almost) full.
1177 bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1178 if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && nInbound + 1 >= nMaxInbound && discouraged)
1179 {
1180 LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString());
1181 CloseSocket(hSocket);
1182 return;
1183 }
1184
1185 if (nInbound >= nMaxInbound)
1186 {
1187 if (!AttemptToEvictConnection()) {
1188 // No connection to evict, disconnect the new connection
1189 LogPrint(BCLog::NET, "failed to find an eviction candidate - connection dropped (full)\n");
1190 CloseSocket(hSocket);
1191 return;
1192 }
1193 }
1194
1195 NodeId id = GetNewNodeId();
1197
1198 ServiceFlags nodeServices = nLocalServices;
1200 nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
1201 }
1202
1203 const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1204 CNode* pnode = new CNode(id, nodeServices, hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND, inbound_onion);
1205 pnode->AddRef();
1206 pnode->m_permissionFlags = permissionFlags;
1207 pnode->m_prefer_evict = discouraged;
1208 m_msgproc->InitializeNode(pnode);
1209
1210 LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToString());
1211
1212 {
1213 LOCK(cs_vNodes);
1214 vNodes.push_back(pnode);
1215 }
1216
1217 // We received a new connection, harvest entropy from the time (and our peer count)
1218 RandAddEvent((uint32_t)id);
1219}
1220
1221bool CConnman::AddConnection(const std::string& address, ConnectionType conn_type)
1222{
1223 std::optional<int> max_connections;
1224 switch (conn_type) {
1228 return false;
1230 max_connections = m_max_outbound_full_relay;
1231 break;
1233 max_connections = m_max_outbound_block_relay;
1234 break;
1235 // no limit for ADDR_FETCH because -seednode has no limit either
1237 break;
1238 } // no default case, so the compiler can warn about missing cases
1239
1240 // Count existing connections
1241 int existing_connections = WITH_LOCK(cs_vNodes,
1242 return std::count_if(vNodes.begin(), vNodes.end(), [conn_type](CNode* node) { return node->m_conn_type == conn_type; }););
1243
1244 // Max connections of specified type already exist
1245 if (max_connections != std::nullopt && existing_connections >= max_connections) return false;
1246
1247 // Max total outbound connections already exist
1248 CSemaphoreGrant grant(*semOutbound, true);
1249 if (!grant) return false;
1250
1251 OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type);
1252 return true;
1253}
1254
1256{
1257 {
1258 LOCK(cs_vNodes);
1259
1260 if (!fNetworkActive) {
1261 // Disconnect any connected nodes
1262 for (CNode* pnode : vNodes) {
1263 if (!pnode->fDisconnect) {
1264 LogPrint(BCLog::NET, "Network not active, dropping peer=%d\n", pnode->GetId());
1265 pnode->fDisconnect = true;
1266 }
1267 }
1268 }
1269
1270 // Disconnect unused nodes
1271 std::vector<CNode*> vNodesCopy = vNodes;
1272 for (CNode* pnode : vNodesCopy)
1273 {
1274 if (pnode->fDisconnect)
1275 {
1276 // remove from vNodes
1277 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1278
1279 // release outbound grant (if any)
1280 pnode->grantOutbound.Release();
1281
1282 // close socket and cleanup
1283 pnode->CloseSocketDisconnect();
1284
1285 // hold in disconnected pool until all refs are released
1286 pnode->Release();
1287 vNodesDisconnected.push_back(pnode);
1288 }
1289 }
1290 }
1291 {
1292 // Delete disconnected nodes
1293 std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1294 for (CNode* pnode : vNodesDisconnectedCopy)
1295 {
1296 // Destroy the object only after other threads have stopped using it.
1297 if (pnode->GetRefCount() <= 0) {
1298 vNodesDisconnected.remove(pnode);
1299 DeleteNode(pnode);
1300 }
1301 }
1302 }
1303}
1304
1306{
1307 size_t vNodesSize;
1308 {
1309 LOCK(cs_vNodes);
1310 vNodesSize = vNodes.size();
1311 }
1312 if(vNodesSize != nPrevNodeCount) {
1313 nPrevNodeCount = vNodesSize;
1314 if (m_client_interface) {
1315 m_client_interface->NotifyNumConnectionsChanged(vNodesSize);
1316 }
1317 }
1318}
1319
1320bool CConnman::ShouldRunInactivityChecks(const CNode& node, int64_t now) const
1321{
1322 return node.nTimeConnected + m_peer_connect_timeout < now;
1323}
1324
1326{
1327 // Use non-mockable system time (otherwise these timers will pop when we
1328 // use setmocktime in the tests).
1329 int64_t now = GetTimeSeconds();
1330
1331 if (!ShouldRunInactivityChecks(node, now)) return false;
1332
1333 if (node.nLastRecv == 0 || node.nLastSend == 0) {
1334 LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d peer=%d\n", m_peer_connect_timeout, node.nLastRecv != 0, node.nLastSend != 0, node.GetId());
1335 return true;
1336 }
1337
1338 if (now > node.nLastSend + TIMEOUT_INTERVAL) {
1339 LogPrint(BCLog::NET, "socket sending timeout: %is peer=%d\n", now - node.nLastSend, node.GetId());
1340 return true;
1341 }
1342
1343 if (now > node.nLastRecv + TIMEOUT_INTERVAL) {
1344 LogPrint(BCLog::NET, "socket receive timeout: %is peer=%d\n", now - node.nLastRecv, node.GetId());
1345 return true;
1346 }
1347
1348 if (!node.fSuccessfullyConnected) {
1349 LogPrint(BCLog::NET, "version handshake timeout peer=%d\n", node.GetId());
1350 return true;
1351 }
1352
1353 return false;
1354}
1355
1356bool CConnman::GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1357{
1358 for (const ListenSocket& hListenSocket : vhListenSocket) {
1359 recv_set.insert(hListenSocket.socket);
1360 }
1361
1362 {
1363 LOCK(cs_vNodes);
1364 for (CNode* pnode : vNodes)
1365 {
1366 // Implement the following logic:
1367 // * If there is data to send, select() for sending data. As this only
1368 // happens when optimistic write failed, we choose to first drain the
1369 // write buffer in this case before receiving more. This avoids
1370 // needlessly queueing received data, if the remote peer is not themselves
1371 // receiving data. This means properly utilizing TCP flow control signalling.
1372 // * Otherwise, if there is space left in the receive buffer, select() for
1373 // receiving data.
1374 // * Hand off all complete messages to the processor, to be handled without
1375 // blocking here.
1376
1377 bool select_recv = !pnode->fPauseRecv;
1378 bool select_send;
1379 {
1380 LOCK(pnode->cs_vSend);
1381 select_send = !pnode->vSendMsg.empty();
1382 }
1383
1384 LOCK(pnode->cs_hSocket);
1385 if (pnode->hSocket == INVALID_SOCKET)
1386 continue;
1387
1388 error_set.insert(pnode->hSocket);
1389 if (select_send) {
1390 send_set.insert(pnode->hSocket);
1391 continue;
1392 }
1393 if (select_recv) {
1394 recv_set.insert(pnode->hSocket);
1395 }
1396 }
1397 }
1398
1399 return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1400}
1401
1402#ifdef USE_POLL
1403void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1404{
1405 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1406 if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1407 interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1408 return;
1409 }
1410
1411 std::unordered_map<SOCKET, struct pollfd> pollfds;
1412 for (SOCKET socket_id : recv_select_set) {
1413 pollfds[socket_id].fd = socket_id;
1414 pollfds[socket_id].events |= POLLIN;
1415 }
1416
1417 for (SOCKET socket_id : send_select_set) {
1418 pollfds[socket_id].fd = socket_id;
1419 pollfds[socket_id].events |= POLLOUT;
1420 }
1421
1422 for (SOCKET socket_id : error_select_set) {
1423 pollfds[socket_id].fd = socket_id;
1424 // These flags are ignored, but we set them for clarity
1425 pollfds[socket_id].events |= POLLERR|POLLHUP;
1426 }
1427
1428 std::vector<struct pollfd> vpollfds;
1429 vpollfds.reserve(pollfds.size());
1430 for (auto it : pollfds) {
1431 vpollfds.push_back(std::move(it.second));
1432 }
1433
1434 if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0) return;
1435
1436 if (interruptNet) return;
1437
1438 for (struct pollfd pollfd_entry : vpollfds) {
1439 if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1440 if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1441 if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1442 }
1443}
1444#else
1445void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1446{
1447 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1448 if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1449 interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1450 return;
1451 }
1452
1453 //
1454 // Find which sockets have data to receive
1455 //
1456 struct timeval timeout;
1457 timeout.tv_sec = 0;
1458 timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000; // frequency to poll pnode->vSend
1459
1460 fd_set fdsetRecv;
1461 fd_set fdsetSend;
1462 fd_set fdsetError;
1463 FD_ZERO(&fdsetRecv);
1464 FD_ZERO(&fdsetSend);
1465 FD_ZERO(&fdsetError);
1466 SOCKET hSocketMax = 0;
1467
1468 for (SOCKET hSocket : recv_select_set) {
1469 FD_SET(hSocket, &fdsetRecv);
1470 hSocketMax = std::max(hSocketMax, hSocket);
1471 }
1472
1473 for (SOCKET hSocket : send_select_set) {
1474 FD_SET(hSocket, &fdsetSend);
1475 hSocketMax = std::max(hSocketMax, hSocket);
1476 }
1477
1478 for (SOCKET hSocket : error_select_set) {
1479 FD_SET(hSocket, &fdsetError);
1480 hSocketMax = std::max(hSocketMax, hSocket);
1481 }
1482
1483 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1484
1485 if (interruptNet)
1486 return;
1487
1488 if (nSelect == SOCKET_ERROR)
1489 {
1490 int nErr = WSAGetLastError();
1491 LogPrintf("socket select error %s\n", NetworkErrorString(nErr));
1492 for (unsigned int i = 0; i <= hSocketMax; i++)
1493 FD_SET(i, &fdsetRecv);
1494 FD_ZERO(&fdsetSend);
1495 FD_ZERO(&fdsetError);
1496 if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1497 return;
1498 }
1499
1500 for (SOCKET hSocket : recv_select_set) {
1501 if (FD_ISSET(hSocket, &fdsetRecv)) {
1502 recv_set.insert(hSocket);
1503 }
1504 }
1505
1506 for (SOCKET hSocket : send_select_set) {
1507 if (FD_ISSET(hSocket, &fdsetSend)) {
1508 send_set.insert(hSocket);
1509 }
1510 }
1511
1512 for (SOCKET hSocket : error_select_set) {
1513 if (FD_ISSET(hSocket, &fdsetError)) {
1514 error_set.insert(hSocket);
1515 }
1516 }
1517}
1518#endif
1519
1521{
1522 std::set<SOCKET> recv_set, send_set, error_set;
1523 SocketEvents(recv_set, send_set, error_set);
1524
1525 if (interruptNet) return;
1526
1527 //
1528 // Accept new connections
1529 //
1530 for (const ListenSocket& hListenSocket : vhListenSocket)
1531 {
1532 if (hListenSocket.socket != INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1533 {
1534 AcceptConnection(hListenSocket);
1535 }
1536 }
1537
1538 //
1539 // Service each socket
1540 //
1541 std::vector<CNode*> vNodesCopy;
1542 {
1543 LOCK(cs_vNodes);
1544 vNodesCopy = vNodes;
1545 for (CNode* pnode : vNodesCopy)
1546 pnode->AddRef();
1547 }
1548 for (CNode* pnode : vNodesCopy)
1549 {
1550 if (interruptNet)
1551 return;
1552
1553 //
1554 // Receive
1555 //
1556 bool recvSet = false;
1557 bool sendSet = false;
1558 bool errorSet = false;
1559 {
1560 LOCK(pnode->cs_hSocket);
1561 if (pnode->hSocket == INVALID_SOCKET)
1562 continue;
1563 recvSet = recv_set.count(pnode->hSocket) > 0;
1564 sendSet = send_set.count(pnode->hSocket) > 0;
1565 errorSet = error_set.count(pnode->hSocket) > 0;
1566 }
1567 if (recvSet || errorSet)
1568 {
1569 // typical socket buffer is 8K-64K
1570 uint8_t pchBuf[0x10000];
1571 int nBytes = 0;
1572 {
1573 LOCK(pnode->cs_hSocket);
1574 if (pnode->hSocket == INVALID_SOCKET)
1575 continue;
1576 nBytes = recv(pnode->hSocket, (char*)pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
1577 }
1578 if (nBytes > 0)
1579 {
1580 bool notify = false;
1581 if (!pnode->ReceiveMsgBytes(Span<const uint8_t>(pchBuf, nBytes), notify))
1582 pnode->CloseSocketDisconnect();
1583 RecordBytesRecv(nBytes);
1584 if (notify) {
1585 size_t nSizeAdded = 0;
1586 auto it(pnode->vRecvMsg.begin());
1587 for (; it != pnode->vRecvMsg.end(); ++it) {
1588 // vRecvMsg contains only completed CNetMessage
1589 // the single possible partially deserialized message are held by TransportDeserializer
1590 nSizeAdded += it->m_raw_message_size;
1591 }
1592 {
1593 LOCK(pnode->cs_vProcessMsg);
1594 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1595 pnode->nProcessQueueSize += nSizeAdded;
1596 pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1597 }
1599 }
1600 }
1601 else if (nBytes == 0)
1602 {
1603 // socket closed gracefully
1604 if (!pnode->fDisconnect) {
1605 LogPrint(BCLog::NET, "socket closed for peer=%d\n", pnode->GetId());
1606 }
1607 pnode->CloseSocketDisconnect();
1608 }
1609 else if (nBytes < 0)
1610 {
1611 // error
1612 int nErr = WSAGetLastError();
1613 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1614 {
1615 if (!pnode->fDisconnect) {
1616 LogPrint(BCLog::NET, "socket recv error for peer=%d: %s\n", pnode->GetId(), NetworkErrorString(nErr));
1617 }
1618 pnode->CloseSocketDisconnect();
1619 }
1620 }
1621 }
1622
1623 if (sendSet) {
1624 // Send data
1625 size_t bytes_sent = WITH_LOCK(pnode->cs_vSend, return SocketSendData(*pnode));
1626 if (bytes_sent) RecordBytesSent(bytes_sent);
1627 }
1628
1629 if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
1630 }
1631 {
1632 LOCK(cs_vNodes);
1633 for (CNode* pnode : vNodesCopy)
1634 pnode->Release();
1635 }
1636}
1637
1639{
1641 while (!interruptNet)
1642 {
1645 SocketHandler();
1646 }
1647}
1648
1650{
1651 {
1653 fMsgProcWake = true;
1654 }
1655 condMsgProc.notify_one();
1656}
1657
1659{
1662 std::vector<std::string> seeds = Params().DNSSeeds();
1663 Shuffle(seeds.begin(), seeds.end(), rng);
1664 int seeds_right_now = 0; // Number of seeds left before testing if we have enough connections
1665 int found = 0;
1666
1667 if (gArgs.GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED)) {
1668 // When -forcednsseed is provided, query all.
1669 seeds_right_now = seeds.size();
1670 } else if (addrman.size() == 0) {
1671 // If we have no known peers, query all.
1672 // This will occur on the first run, or if peers.dat has been
1673 // deleted.
1674 seeds_right_now = seeds.size();
1675 }
1676
1677 // goal: only query DNS seed if address need is acute
1678 // * If we have a reasonable number of peers in addrman, spend
1679 // some time trying them first. This improves user privacy by
1680 // creating fewer identifying DNS requests, reduces trust by
1681 // giving seeds less influence on the network topology, and
1682 // reduces traffic to the seeds.
1683 // * When querying DNS seeds query a few at once, this ensures
1684 // that we don't give DNS seeds the ability to eclipse nodes
1685 // that query them.
1686 // * If we continue having problems, eventually query all the
1687 // DNS seeds, and if that fails too, also try the fixed seeds.
1688 // (done in ThreadOpenConnections)
1689 const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
1690
1691 for (const std::string& seed : seeds) {
1692 if (seeds_right_now == 0) {
1693 seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1694
1695 if (addrman.size() > 0) {
1696 LogPrintf("Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1697 std::chrono::seconds to_wait = seeds_wait_time;
1698 while (to_wait.count() > 0) {
1699 // if sleeping for the MANY_PEERS interval, wake up
1700 // early to see if we have enough peers and can stop
1701 // this thread entirely freeing up its resources
1702 std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
1703 if (!interruptNet.sleep_for(w)) return;
1704 to_wait -= w;
1705
1706 int nRelevant = 0;
1707 {
1708 LOCK(cs_vNodes);
1709 for (const CNode* pnode : vNodes) {
1710 if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant;
1711 }
1712 }
1713 if (nRelevant >= 2) {
1714 if (found > 0) {
1715 LogPrintf("%d addresses found from DNS seeds\n", found);
1716 LogPrintf("P2P peers available. Finished DNS seeding.\n");
1717 } else {
1718 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1719 }
1720 return;
1721 }
1722 }
1723 }
1724 }
1725
1726 if (interruptNet) return;
1727
1728 // hold off on querying seeds if P2P network deactivated
1729 if (!fNetworkActive) {
1730 LogPrintf("Waiting for network to be reactivated before querying DNS seeds.\n");
1731 do {
1732 if (!interruptNet.sleep_for(std::chrono::seconds{1})) return;
1733 } while (!fNetworkActive);
1734 }
1735
1736 LogPrintf("Loading addresses from DNS seed %s\n", seed);
1737 if (HaveNameProxy()) {
1738 AddAddrFetch(seed);
1739 } else {
1740 std::vector<CNetAddr> vIPs;
1741 std::vector<CAddress> vAdd;
1742 ServiceFlags requiredServiceBits = GetDesirableServiceFlags(NODE_NONE);
1743 std::string host = strprintf("x%x.%s", requiredServiceBits, seed);
1744 CNetAddr resolveSource;
1745 if (!resolveSource.SetInternal(host)) {
1746 continue;
1747 }
1748 unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
1749 if (LookupHost(host, vIPs, nMaxIPs, true)) {
1750 for (const CNetAddr& ip : vIPs) {
1751 int nOneDay = 24*3600;
1752 CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits);
1753 addr.nTime = GetTime() - 3*nOneDay - rng.randrange(4*nOneDay); // use a random age between 3 and 7 days old
1754 vAdd.push_back(addr);
1755 found++;
1756 }
1757 addrman.Add(vAdd, resolveSource);
1758 } else {
1759 // We now avoid directly using results from DNS Seeds which do not support service bit filtering,
1760 // instead using them as a addrfetch to get nodes with our desired service bits.
1761 AddAddrFetch(seed);
1762 }
1763 }
1764 --seeds_right_now;
1765 }
1766 LogPrintf("%d addresses found from DNS seeds\n", found);
1767}
1768
1770{
1771 int64_t nStart = GetTimeMillis();
1772
1774
1775 LogPrint(BCLog::NET, "Flushed %d addresses to peers.dat %dms\n",
1776 addrman.size(), GetTimeMillis() - nStart);
1777}
1778
1780{
1781 std::string strDest;
1782 {
1784 if (m_addr_fetches.empty())
1785 return;
1786 strDest = m_addr_fetches.front();
1787 m_addr_fetches.pop_front();
1788 }
1789 CAddress addr;
1790 CSemaphoreGrant grant(*semOutbound, true);
1791 if (grant) {
1792 OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
1793 }
1794}
1795
1797{
1799}
1800
1802{
1804 LogPrint(BCLog::NET, "net: setting try another outbound peer=%s\n", flag ? "true" : "false");
1805}
1806
1807// Return the number of peers we have over our outbound connection limit
1808// Exclude peers that are marked for disconnect, or are going to be
1809// disconnected soon (eg ADDR_FETCH and FEELER)
1810// Also exclude peers that haven't finished initial connection handshake yet
1811// (so that we don't decide we're over our desired connection limit, and then
1812// evict some peer that has finished the handshake)
1814{
1815 int full_outbound_peers = 0;
1816 {
1817 LOCK(cs_vNodes);
1818 for (const CNode* pnode : vNodes) {
1819 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsFullOutboundConn()) {
1820 ++full_outbound_peers;
1821 }
1822 }
1823 }
1824 return std::max(full_outbound_peers - m_max_outbound_full_relay, 0);
1825}
1826
1828{
1829 int block_relay_peers = 0;
1830 {
1831 LOCK(cs_vNodes);
1832 for (const CNode* pnode : vNodes) {
1833 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsBlockOnlyConn()) {
1834 ++block_relay_peers;
1835 }
1836 }
1837 }
1838 return std::max(block_relay_peers - m_max_outbound_block_relay, 0);
1839}
1840
1841void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
1842{
1844 // Connect to specific addresses
1845 if (!connect.empty())
1846 {
1847 for (int64_t nLoop = 0;; nLoop++)
1848 {
1850 for (const std::string& strAddr : connect)
1851 {
1852 CAddress addr(CService(), NODE_NONE);
1853 OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
1854 for (int i = 0; i < 10 && i < nLoop; i++)
1855 {
1856 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1857 return;
1858 }
1859 }
1860 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1861 return;
1862 }
1863 }
1864
1865 // Initiate network connections
1866 auto start = GetTime<std::chrono::microseconds>();
1867
1868 // Minimum time before next feeler connection (in microseconds).
1869 auto next_feeler = PoissonNextSend(start, FEELER_INTERVAL);
1870 auto next_extra_block_relay = PoissonNextSend(start, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
1871 const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
1872 bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
1873
1874 if (!add_fixed_seeds) {
1875 LogPrintf("Fixed seeds are disabled\n");
1876 }
1877
1878 while (!interruptNet)
1879 {
1881
1882 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1883 return;
1884
1886 if (interruptNet)
1887 return;
1888
1889 if (add_fixed_seeds && addrman.size() == 0) {
1890 // When the node starts with an empty peers.dat, there are a few other sources of peers before
1891 // we fallback on to fixed seeds: -dnsseed, -seednode, -addnode
1892 // If none of those are available, we fallback on to fixed seeds immediately, else we allow
1893 // 60 seconds for any of those sources to populate addrman.
1894 bool add_fixed_seeds_now = false;
1895 // It is cheapest to check if enough time has passed first.
1896 if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
1897 add_fixed_seeds_now = true;
1898 LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
1899 }
1900
1901 // Checking !dnsseed is cheaper before locking 2 mutexes.
1902 if (!add_fixed_seeds_now && !dnsseed) {
1904 if (m_addr_fetches.empty() && vAddedNodes.empty()) {
1905 add_fixed_seeds_now = true;
1906 LogPrintf("Adding fixed seeds as -dnsseed=0, -addnode is not provided and all -seednode(s) attempted\n");
1907 }
1908 }
1909
1910 if (add_fixed_seeds_now) {
1911 CNetAddr local;
1912 local.SetInternal("fixedseeds");
1913 addrman.Add(ConvertSeeds(Params().FixedSeeds()), local);
1914 add_fixed_seeds = false;
1915 }
1916 }
1917
1918 //
1919 // Choose an address to connect to based on most recently seen
1920 //
1921 CAddress addrConnect;
1922
1923 // Only connect out to one peer per network group (/16 for IPv4).
1924 int nOutboundFullRelay = 0;
1925 int nOutboundBlockRelay = 0;
1926 std::set<std::vector<unsigned char> > setConnected;
1927
1928 {
1929 LOCK(cs_vNodes);
1930 for (const CNode* pnode : vNodes) {
1931 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1932 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1933
1934 // Netgroups for inbound and manual peers are not excluded because our goal here
1935 // is to not use multiple of our limited outbound slots on a single netgroup
1936 // but inbound and manual peers do not use our outbound slots. Inbound peers
1937 // also have the added issue that they could be attacker controlled and used
1938 // to prevent us from connecting to particular hosts if we used them here.
1939 switch (pnode->m_conn_type) {
1942 break;
1947 setConnected.insert(pnode->addr.GetGroup(addrman.GetAsmap()));
1948 } // no default case, so the compiler can warn about missing cases
1949 }
1950 }
1951
1953 auto now = GetTime<std::chrono::microseconds>();
1954 bool anchor = false;
1955 bool fFeeler = false;
1956
1957 // Determine what type of connection to open. Opening
1958 // BLOCK_RELAY connections to addresses from anchors.dat gets the highest
1959 // priority. Then we open OUTBOUND_FULL_RELAY priority until we
1960 // meet our full-relay capacity. Then we open BLOCK_RELAY connection
1961 // until we hit our block-relay-only peer limit.
1962 // GetTryNewOutboundPeer() gets set when a stale tip is detected, so we
1963 // try opening an additional OUTBOUND_FULL_RELAY connection. If none of
1964 // these conditions are met, check to see if it's time to try an extra
1965 // block-relay-only peer (to confirm our tip is current, see below) or the next_feeler
1966 // timer to decide if we should open a FEELER.
1967
1968 if (!m_anchors.empty() && (nOutboundBlockRelay < m_max_outbound_block_relay)) {
1969 conn_type = ConnectionType::BLOCK_RELAY;
1970 anchor = true;
1971 } else if (nOutboundFullRelay < m_max_outbound_full_relay) {
1972 // OUTBOUND_FULL_RELAY
1973 } else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
1974 conn_type = ConnectionType::BLOCK_RELAY;
1975 } else if (GetTryNewOutboundPeer()) {
1976 // OUTBOUND_FULL_RELAY
1977 } else if (now > next_extra_block_relay && m_start_extra_block_relay_peers) {
1978 // Periodically connect to a peer (using regular outbound selection
1979 // methodology from addrman) and stay connected long enough to sync
1980 // headers, but not much else.
1981 //
1982 // Then disconnect the peer, if we haven't learned anything new.
1983 //
1984 // The idea is to make eclipse attacks very difficult to pull off,
1985 // because every few minutes we're finding a new peer to learn headers
1986 // from.
1987 //
1988 // This is similar to the logic for trying extra outbound (full-relay)
1989 // peers, except:
1990 // - we do this all the time on a poisson timer, rather than just when
1991 // our tip is stale
1992 // - we potentially disconnect our next-youngest block-relay-only peer, if our
1993 // newest block-relay-only peer delivers a block more recently.
1994 // See the eviction logic in net_processing.cpp.
1995 //
1996 // Because we can promote these connections to block-relay-only
1997 // connections, they do not get their own ConnectionType enum
1998 // (similar to how we deal with extra outbound peers).
1999 next_extra_block_relay = PoissonNextSend(now, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
2000 conn_type = ConnectionType::BLOCK_RELAY;
2001 } else if (now > next_feeler) {
2002 next_feeler = PoissonNextSend(now, FEELER_INTERVAL);
2003 conn_type = ConnectionType::FEELER;
2004 fFeeler = true;
2005 } else {
2006 // skip to next iteration of while loop
2007 continue;
2008 }
2009
2011
2012 int64_t nANow = GetAdjustedTime();
2013 int nTries = 0;
2014 while (!interruptNet)
2015 {
2016 if (anchor && !m_anchors.empty()) {
2017 const CAddress addr = m_anchors.back();
2018 m_anchors.pop_back();
2019 if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) ||
2021 setConnected.count(addr.GetGroup(addrman.GetAsmap()))) continue;
2022 addrConnect = addr;
2023 LogPrint(BCLog::NET, "Trying to make an anchor connection to %s\n", addrConnect.ToString());
2024 break;
2025 }
2026
2027 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
2028 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
2029 // already-connected network ranges, ...) before trying new addrman addresses.
2030 nTries++;
2031 if (nTries > 100)
2032 break;
2033
2034 CAddress addr;
2035 int64_t addr_last_try{0};
2036
2037 if (fFeeler) {
2038 // First, try to get a tried table collision address. This returns
2039 // an empty (invalid) address if there are no collisions to try.
2040 std::tie(addr, addr_last_try) = addrman.SelectTriedCollision();
2041
2042 if (!addr.IsValid()) {
2043 // No tried table collisions. Select a new table address
2044 // for our feeler.
2045 std::tie(addr, addr_last_try) = addrman.Select(true);
2046 } else if (AlreadyConnectedToAddress(addr)) {
2047 // If test-before-evict logic would have us connect to a
2048 // peer that we're already connected to, just mark that
2049 // address as Good(). We won't be able to initiate the
2050 // connection anyway, so this avoids inadvertently evicting
2051 // a currently-connected peer.
2052 addrman.Good(addr);
2053 // Select a new table address for our feeler instead.
2054 std::tie(addr, addr_last_try) = addrman.Select(true);
2055 }
2056 } else {
2057 // Not a feeler
2058 std::tie(addr, addr_last_try) = addrman.Select();
2059 }
2060
2061 // Require outbound connections, other than feelers, to be to distinct network groups
2062 if (!fFeeler && setConnected.count(addr.GetGroup(addrman.GetAsmap()))) {
2063 break;
2064 }
2065
2066 // if we selected an invalid or local address, restart
2067 if (!addr.IsValid() || IsLocal(addr)) {
2068 break;
2069 }
2070
2071 if (!IsReachable(addr))
2072 continue;
2073
2074 // only consider very recently tried nodes after 30 failed attempts
2075 if (nANow - addr_last_try < 600 && nTries < 30)
2076 continue;
2077
2078 // for non-feelers, require all the services we'll want,
2079 // for feelers, only require they be a full node (only because most
2080 // SPV clients don't have a good address DB available)
2081 if (!fFeeler && !HasAllDesirableServiceFlags(addr.nServices)) {
2082 continue;
2083 } else if (fFeeler && !MayHaveUsefulAddressDB(addr.nServices)) {
2084 continue;
2085 }
2086
2087 // Do not allow non-default ports, unless after 50 invalid
2088 // addresses selected already. This is to prevent malicious peers
2089 // from advertising themselves as a service on another host and
2090 // port, causing a DoS attack as nodes around the network attempt
2091 // to connect to it fruitlessly.
2092 if (addr.GetPort() != Params().GetDefaultPort(addr.GetNetwork()) && nTries < 50) {
2093 continue;
2094 }
2095
2096 addrConnect = addr;
2097 break;
2098 }
2099
2100 if (addrConnect.IsValid()) {
2101
2102 if (fFeeler) {
2103 // Add small amount of random noise before connection to avoid synchronization.
2104 int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000);
2105 if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
2106 return;
2107 LogPrint(BCLog::NET, "Making feeler connection to %s\n", addrConnect.ToString());
2108 }
2109
2110 OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, nullptr, conn_type);
2111 }
2112 }
2113}
2114
2115std::vector<CAddress> CConnman::GetCurrentBlockRelayOnlyConns() const
2116{
2117 std::vector<CAddress> ret;
2118 LOCK(cs_vNodes);
2119 for (const CNode* pnode : vNodes) {
2120 if (pnode->IsBlockOnlyConn()) {
2121 ret.push_back(pnode->addr);
2122 }
2123 }
2124
2125 return ret;
2126}
2127
2128std::vector<AddedNodeInfo> CConnman::GetAddedNodeInfo() const
2129{
2130 std::vector<AddedNodeInfo> ret;
2131
2132 std::list<std::string> lAddresses(0);
2133 {
2135 ret.reserve(vAddedNodes.size());
2136 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
2137 }
2138
2139
2140 // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
2141 std::map<CService, bool> mapConnected;
2142 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2143 {
2144 LOCK(cs_vNodes);
2145 for (const CNode* pnode : vNodes) {
2146 if (pnode->addr.IsValid()) {
2147 mapConnected[pnode->addr] = pnode->IsInboundConn();
2148 }
2149 std::string addrName{pnode->m_addr_name};
2150 if (!addrName.empty()) {
2151 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(), static_cast<const CService&>(pnode->addr));
2152 }
2153 }
2154 }
2155
2156 for (const std::string& strAddNode : lAddresses) {
2157 CService service(LookupNumeric(strAddNode, Params().GetDefaultPort(strAddNode)));
2158 AddedNodeInfo addedNode{strAddNode, CService(), false, false};
2159 if (service.IsValid()) {
2160 // strAddNode is an IP:port
2161 auto it = mapConnected.find(service);
2162 if (it != mapConnected.end()) {
2163 addedNode.resolvedAddress = service;
2164 addedNode.fConnected = true;
2165 addedNode.fInbound = it->second;
2166 }
2167 } else {
2168 // strAddNode is a name
2169 auto it = mapConnectedByName.find(strAddNode);
2170 if (it != mapConnectedByName.end()) {
2171 addedNode.resolvedAddress = it->second.second;
2172 addedNode.fConnected = true;
2173 addedNode.fInbound = it->second.first;
2174 }
2175 }
2176 ret.emplace_back(std::move(addedNode));
2177 }
2178
2179 return ret;
2180}
2181
2183{
2185 while (true)
2186 {
2188 std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
2189 bool tried = false;
2190 for (const AddedNodeInfo& info : vInfo) {
2191 if (!info.fConnected) {
2192 if (!grant.TryAcquire()) {
2193 // If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
2194 // the addednodeinfo state might change.
2195 break;
2196 }
2197 tried = true;
2198 CAddress addr(CService(), NODE_NONE);
2199 OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
2200 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
2201 return;
2202 }
2203 }
2204 // Retry every 60 seconds if a connection was attempted, otherwise two seconds
2205 if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
2206 return;
2207 }
2208}
2209
2210// if successful, this moves the passed grant to the constructed node
2211void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
2212{
2213 assert(conn_type != ConnectionType::INBOUND);
2214
2215 //
2216 // Initiate outbound network connection
2217 //
2218 if (interruptNet) {
2219 return;
2220 }
2221 if (!fNetworkActive) {
2222 return;
2223 }
2224 if (!pszDest) {
2225 bool banned_or_discouraged = m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect));
2226 if (IsLocal(addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress(addrConnect)) {
2227 return;
2228 }
2229 } else if (FindNode(std::string(pszDest)))
2230 return;
2231
2232 CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2233
2234 if (!pnode)
2235 return;
2236 if (grantOutbound)
2237 grantOutbound->MoveTo(pnode->grantOutbound);
2238
2239 m_msgproc->InitializeNode(pnode);
2240 {
2241 LOCK(cs_vNodes);
2242 vNodes.push_back(pnode);
2243 }
2244}
2245
2247{
2250 while (!flagInterruptMsgProc)
2251 {
2252 std::vector<CNode*> vNodesCopy;
2253 {
2254 LOCK(cs_vNodes);
2255 vNodesCopy = vNodes;
2256 for (CNode* pnode : vNodesCopy) {
2257 pnode->AddRef();
2258 }
2259 }
2260
2261 bool fMoreWork = false;
2262
2263 // Randomize the order in which we process messages from/to our peers.
2264 // This prevents attacks in which an attacker exploits having multiple
2265 // consecutive connections in the vNodes list.
2266 Shuffle(vNodesCopy.begin(), vNodesCopy.end(), rng);
2267
2268 for (CNode* pnode : vNodesCopy)
2269 {
2270 if (pnode->fDisconnect)
2271 continue;
2272
2273 // Receive messages
2274 bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
2275 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2277 return;
2278 // Send messages
2279 {
2280 LOCK(pnode->cs_sendProcessing);
2281 m_msgproc->SendMessages(pnode);
2282 }
2283
2285 return;
2286 }
2287
2288 {
2289 LOCK(cs_vNodes);
2290 for (CNode* pnode : vNodesCopy)
2291 pnode->Release();
2292 }
2293
2294 WAIT_LOCK(mutexMsgProc, lock);
2295 if (!fMoreWork) {
2296 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [this]() EXCLUSIVE_LOCKS_REQUIRED(mutexMsgProc) { return fMsgProcWake; });
2297 }
2298 fMsgProcWake = false;
2299 }
2300}
2301
2303{
2304 static constexpr auto err_wait_begin = 1s;
2305 static constexpr auto err_wait_cap = 5min;
2306 auto err_wait = err_wait_begin;
2307
2308 bool advertising_listen_addr = false;
2309 i2p::Connection conn;
2310
2311 while (!interruptNet) {
2312
2313 if (!m_i2p_sam_session->Listen(conn)) {
2314 if (advertising_listen_addr && conn.me.IsValid()) {
2315 RemoveLocal(conn.me);
2316 advertising_listen_addr = false;
2317 }
2318
2319 interruptNet.sleep_for(err_wait);
2320 if (err_wait < err_wait_cap) {
2321 err_wait *= 2;
2322 }
2323
2324 continue;
2325 }
2326
2327 if (!advertising_listen_addr) {
2328 AddLocal(conn.me, LOCAL_MANUAL);
2329 advertising_listen_addr = true;
2330 }
2331
2332 if (!m_i2p_sam_session->Accept(conn)) {
2333 continue;
2334 }
2335
2337 CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
2338 }
2339}
2340
2341bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions)
2342{
2343 int nOne = 1;
2344
2345 // Create socket for listening for incoming connections
2346 struct sockaddr_storage sockaddr;
2347 socklen_t len = sizeof(sockaddr);
2348 if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
2349 {
2350 strError = strprintf(Untranslated("Error: Bind address family for %s not supported"), addrBind.ToString());
2351 LogPrintf("%s\n", strError.original);
2352 return false;
2353 }
2354
2355 std::unique_ptr<Sock> sock = CreateSock(addrBind);
2356 if (!sock) {
2357 strError = strprintf(Untranslated("Error: Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError()));
2358 LogPrintf("%s\n", strError.original);
2359 return false;
2360 }
2361
2362 // Allow binding if the port is still in TIME_WAIT state after
2363 // the program was closed and restarted.
2364 setsockopt(sock->Get(), SOL_SOCKET, SO_REUSEADDR, (sockopt_arg_type)&nOne, sizeof(int));
2365
2366 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
2367 // and enable it by default or not. Try to enable it, if possible.
2368 if (addrBind.IsIPv6()) {
2369#ifdef IPV6_V6ONLY
2370 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_V6ONLY, (sockopt_arg_type)&nOne, sizeof(int));
2371#endif
2372#ifdef WIN32
2373 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2374 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int));
2375#endif
2376 }
2377
2378 if (::bind(sock->Get(), (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
2379 {
2380 int nErr = WSAGetLastError();
2381 if (nErr == WSAEADDRINUSE)
2382 strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
2383 else
2384 strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
2385 LogPrintf("%s\n", strError.original);
2386 return false;
2387 }
2388 LogPrintf("Bound to %s\n", addrBind.ToString());
2389
2390 // Listen for incoming connections
2391 if (listen(sock->Get(), SOMAXCONN) == SOCKET_ERROR)
2392 {
2393 strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
2394 LogPrintf("%s\n", strError.original);
2395 return false;
2396 }
2397
2398 vhListenSocket.push_back(ListenSocket(sock->Release(), permissions));
2399 return true;
2400}
2401
2403{
2404 if (!fDiscover)
2405 return;
2406
2407#ifdef WIN32
2408 // Get local host IP
2409 char pszHostName[256] = "";
2410 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
2411 {
2412 std::vector<CNetAddr> vaddr;
2413 if (LookupHost(pszHostName, vaddr, 0, true))
2414 {
2415 for (const CNetAddr &addr : vaddr)
2416 {
2417 if (AddLocal(addr, LOCAL_IF))
2418 LogPrintf("%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2419 }
2420 }
2421 }
2422#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2423 // Get local host ip
2424 struct ifaddrs* myaddrs;
2425 if (getifaddrs(&myaddrs) == 0)
2426 {
2427 for (struct ifaddrs* ifa = myaddrs; ifa != nullptr; ifa = ifa->ifa_next)
2428 {
2429 if (ifa->ifa_addr == nullptr) continue;
2430 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
2431 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
2432 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
2433 if (ifa->ifa_addr->sa_family == AF_INET)
2434 {
2435 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
2436 CNetAddr addr(s4->sin_addr);
2437 if (AddLocal(addr, LOCAL_IF))
2438 LogPrintf("%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2439 }
2440 else if (ifa->ifa_addr->sa_family == AF_INET6)
2441 {
2442 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
2443 CNetAddr addr(s6->sin6_addr);
2444 if (AddLocal(addr, LOCAL_IF))
2445 LogPrintf("%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.ToString());
2446 }
2447 }
2448 freeifaddrs(myaddrs);
2449 }
2450#endif
2451}
2452
2454{
2455 LogPrintf("%s: %s\n", __func__, active);
2456
2457 if (fNetworkActive == active) {
2458 return;
2459 }
2460
2461 fNetworkActive = active;
2462
2463 if (m_client_interface) {
2464 m_client_interface->NotifyNetworkActiveChanged(fNetworkActive);
2465 }
2466}
2467
2468CConnman::CConnman(uint64_t nSeed0In, uint64_t nSeed1In, AddrMan& addrman_in, bool network_active)
2469 : addrman(addrman_in), nSeed0(nSeed0In), nSeed1(nSeed1In)
2470{
2471 SetTryNewOutboundPeer(false);
2472
2473 Options connOptions;
2474 Init(connOptions);
2475 SetNetworkActive(network_active);
2476}
2477
2479{
2480 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2481}
2482
2483
2484bool CConnman::Bind(const CService& addr_, unsigned int flags, NetPermissionFlags permissions)
2485{
2486 const CService addr{MaybeFlipIPv6toCJDNS(addr_)};
2487
2488 if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) {
2489 return false;
2490 }
2491 bilingual_str strError;
2492 if (!BindListenPort(addr, strError, permissions)) {
2494 m_client_interface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
2495 }
2496 return false;
2497 }
2498
2499 if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::NoBan)) {
2500 AddLocal(addr, LOCAL_BIND);
2501 }
2502
2503 return true;
2504}
2505
2506bool CConnman::InitBinds(const Options& options)
2507{
2508 bool fBound = false;
2509 for (const auto& addrBind : options.vBinds) {
2510 fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::None);
2511 }
2512 for (const auto& addrBind : options.vWhiteBinds) {
2513 fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
2514 }
2515 for (const auto& addr_bind : options.onion_binds) {
2517 }
2518 if (options.bind_on_any) {
2519 struct in_addr inaddr_any;
2520 inaddr_any.s_addr = htonl(INADDR_ANY);
2521 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2522 fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::None);
2523 fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::None);
2524 }
2525 return fBound;
2526}
2527
2528bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
2529{
2530 Init(connOptions);
2531
2532 if (fListen && !InitBinds(connOptions)) {
2533 if (m_client_interface) {
2534 m_client_interface->ThreadSafeMessageBox(
2535 _("Failed to listen on any port. Use -listen=0 if you want this."),
2537 }
2538 return false;
2539 }
2540
2541 proxyType i2p_sam;
2542 if (GetProxy(NET_I2P, i2p_sam)) {
2543 m_i2p_sam_session = std::make_unique<i2p::sam::Session>(gArgs.GetDataDirNet() / "i2p_private_key",
2544 i2p_sam.proxy, &interruptNet);
2545 }
2546
2547 for (const auto& strDest : connOptions.vSeedNodes) {
2548 AddAddrFetch(strDest);
2549 }
2550
2552 // Load addresses from anchors.dat
2556 }
2557 LogPrintf("%i block-relay-only anchors will be tried for connections.\n", m_anchors.size());
2558 }
2559
2560 if (m_client_interface) {
2561 m_client_interface->InitMessage(_("Starting network threads…").translated);
2562 }
2563
2564 fAddressesInitialized = true;
2565
2566 if (semOutbound == nullptr) {
2567 // initialize semaphore
2568 semOutbound = std::make_unique<CSemaphore>(std::min(m_max_outbound, nMaxConnections));
2569 }
2570 if (semAddnode == nullptr) {
2571 // initialize semaphore
2572 semAddnode = std::make_unique<CSemaphore>(nMaxAddnode);
2573 }
2574
2575 //
2576 // Start threads
2577 //
2579 InterruptSocks5(false);
2581 flagInterruptMsgProc = false;
2582
2583 {
2585 fMsgProcWake = false;
2586 }
2587
2588 // Send and receive from sockets, accept connections
2589 threadSocketHandler = std::thread(&util::TraceThread, "net", [this] { ThreadSocketHandler(); });
2590
2591 if (!gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED))
2592 LogPrintf("DNS seeding disabled\n");
2593 else
2594 threadDNSAddressSeed = std::thread(&util::TraceThread, "dnsseed", [this] { ThreadDNSAddressSeed(); });
2595
2596 // Initiate manual connections
2597 threadOpenAddedConnections = std::thread(&util::TraceThread, "addcon", [this] { ThreadOpenAddedConnections(); });
2598
2599 if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2600 if (m_client_interface) {
2601 m_client_interface->ThreadSafeMessageBox(
2602 _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
2604 }
2605 return false;
2606 }
2607 if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty()) {
2608 threadOpenConnections = std::thread(
2609 &util::TraceThread, "opencon",
2610 [this, connect = connOptions.m_specified_outgoing] { ThreadOpenConnections(connect); });
2611 }
2612
2613 // Process messages
2614 threadMessageHandler = std::thread(&util::TraceThread, "msghand", [this] { ThreadMessageHandler(); });
2615
2616 if (connOptions.m_i2p_accept_incoming && m_i2p_sam_session.get() != nullptr) {
2618 std::thread(&util::TraceThread, "i2paccept", [this] { ThreadI2PAcceptIncoming(); });
2619 }
2620
2621 // Dump network addresses
2622 scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
2623
2624 return true;
2625}
2626
2628{
2629public:
2631
2633 {
2634#ifdef WIN32
2635 // Shutdown Windows Sockets
2636 WSACleanup();
2637#endif
2638 }
2639};
2641
2643{
2644 {
2646 flagInterruptMsgProc = true;
2647 }
2648 condMsgProc.notify_all();
2649
2650 interruptNet();
2651 InterruptSocks5(true);
2652
2653 if (semOutbound) {
2654 for (int i=0; i<m_max_outbound; i++) {
2655 semOutbound->post();
2656 }
2657 }
2658
2659 if (semAddnode) {
2660 for (int i=0; i<nMaxAddnode; i++) {
2661 semAddnode->post();
2662 }
2663 }
2664}
2665
2667{
2668 if (threadI2PAcceptIncoming.joinable()) {
2670 }
2671 if (threadMessageHandler.joinable())
2672 threadMessageHandler.join();
2673 if (threadOpenConnections.joinable())
2674 threadOpenConnections.join();
2675 if (threadOpenAddedConnections.joinable())
2677 if (threadDNSAddressSeed.joinable())
2678 threadDNSAddressSeed.join();
2679 if (threadSocketHandler.joinable())
2680 threadSocketHandler.join();
2681}
2682
2684{
2686 DumpAddresses();
2687 fAddressesInitialized = false;
2688
2690 // Anchor connections are only dumped during clean shutdown.
2691 std::vector<CAddress> anchors_to_dump = GetCurrentBlockRelayOnlyConns();
2692 if (anchors_to_dump.size() > MAX_BLOCK_RELAY_ONLY_ANCHORS) {
2693 anchors_to_dump.resize(MAX_BLOCK_RELAY_ONLY_ANCHORS);
2694 }
2696 }
2697 }
2698
2699 // Delete peer connections.
2700 std::vector<CNode*> nodes;
2701 WITH_LOCK(cs_vNodes, nodes.swap(vNodes));
2702 for (CNode* pnode : nodes) {
2703 pnode->CloseSocketDisconnect();
2704 DeleteNode(pnode);
2705 }
2706
2707 // Close listening sockets.
2708 for (ListenSocket& hListenSocket : vhListenSocket) {
2709 if (hListenSocket.socket != INVALID_SOCKET) {
2710 if (!CloseSocket(hListenSocket.socket)) {
2711 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2712 }
2713 }
2714 }
2715
2716 for (CNode* pnode : vNodesDisconnected) {
2717 DeleteNode(pnode);
2718 }
2719 vNodesDisconnected.clear();
2720 vhListenSocket.clear();
2721 semOutbound.reset();
2722 semAddnode.reset();
2723}
2724
2726{
2727 assert(pnode);
2728 m_msgproc->FinalizeNode(*pnode);
2729 delete pnode;
2730}
2731
2733{
2734 Interrupt();
2735 Stop();
2736}
2737
2738std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct, std::optional<Network> network) const
2739{
2740 std::vector<CAddress> addresses = addrman.GetAddr(max_addresses, max_pct, network);
2741 if (m_banman) {
2742 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2743 [this](const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
2744 addresses.end());
2745 }
2746 return addresses;
2747}
2748
2749std::vector<CAddress> CConnman::GetAddresses(CNode& requestor, size_t max_addresses, size_t max_pct)
2750{
2751 auto local_socket_bytes = requestor.addrBind.GetAddrBytes();
2753 .Write(requestor.addr.GetNetwork())
2754 .Write(local_socket_bytes.data(), local_socket_bytes.size())
2755 .Finalize();
2756 const auto current_time = GetTime<std::chrono::microseconds>();
2757 auto r = m_addr_response_caches.emplace(cache_id, CachedAddrResponse{});
2758 CachedAddrResponse& cache_entry = r.first->second;
2759 if (cache_entry.m_cache_entry_expiration < current_time) { // If emplace() added new one it has expiration 0.
2760 cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);
2761 // Choosing a proper cache lifetime is a trade-off between the privacy leak minimization
2762 // and the usefulness of ADDR responses to honest users.
2763 //
2764 // Longer cache lifetime makes it more difficult for an attacker to scrape
2765 // enough AddrMan data to maliciously infer something useful.
2766 // By the time an attacker scraped enough AddrMan records, most of
2767 // the records should be old enough to not leak topology info by
2768 // e.g. analyzing real-time changes in timestamps.
2769 //
2770 // It takes only several hundred requests to scrape everything from an AddrMan containing 100,000 nodes,
2771 // so ~24 hours of cache lifetime indeed makes the data less inferable by the time
2772 // most of it could be scraped (considering that timestamps are updated via
2773 // ADDR self-announcements and when nodes communicate).
2774 // We also should be robust to those attacks which may not require scraping *full* victim's AddrMan
2775 // (because even several timestamps of the same handful of nodes may leak privacy).
2776 //
2777 // On the other hand, longer cache lifetime makes ADDR responses
2778 // outdated and less useful for an honest requestor, e.g. if most nodes
2779 // in the ADDR response are no longer active.
2780 //
2781 // However, the churn in the network is known to be rather low. Since we consider
2782 // nodes to be "terrible" (see IsTerrible()) if the timestamps are older than 30 days,
2783 // max. 24 hours of "penalty" due to cache shouldn't make any meaningful difference
2784 // in terms of the freshness of the response.
2785 cache_entry.m_cache_entry_expiration = current_time + std::chrono::hours(21) + GetRandMillis(std::chrono::hours(6));
2786 }
2787 return cache_entry.m_addrs_response_cache;
2788}
2789
2790bool CConnman::AddNode(const std::string& strNode)
2791{
2793 for (const std::string& it : vAddedNodes) {
2794 if (strNode == it) return false;
2795 }
2796
2797 vAddedNodes.push_back(strNode);
2798 return true;
2799}
2800
2801bool CConnman::RemoveAddedNode(const std::string& strNode)
2802{
2804 for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2805 if (strNode == *it) {
2806 vAddedNodes.erase(it);
2807 return true;
2808 }
2809 }
2810 return false;
2811}
2812
2814{
2815 LOCK(cs_vNodes);
2816 if (flags == ConnectionDirection::Both) // Shortcut if we want total
2817 return vNodes.size();
2818
2819 int nNum = 0;
2820 for (const auto& pnode : vNodes) {
2821 if (flags & (pnode->IsInboundConn() ? ConnectionDirection::In : ConnectionDirection::Out)) {
2822 nNum++;
2823 }
2824 }
2825
2826 return nNum;
2827}
2828
2829void CConnman::GetNodeStats(std::vector<CNodeStats>& vstats) const
2830{
2831 vstats.clear();
2832 LOCK(cs_vNodes);
2833 vstats.reserve(vNodes.size());
2834 for (CNode* pnode : vNodes) {
2835 vstats.emplace_back();
2836 pnode->CopyStats(vstats.back());
2837 vstats.back().m_mapped_as = pnode->addr.GetMappedAS(addrman.GetAsmap());
2838 }
2839}
2840
2841bool CConnman::DisconnectNode(const std::string& strNode)
2842{
2843 LOCK(cs_vNodes);
2844 if (CNode* pnode = FindNode(strNode)) {
2845 LogPrint(BCLog::NET, "disconnect by address%s matched peer=%d; disconnecting\n", (fLogIPs ? strprintf("=%s", strNode) : ""), pnode->GetId());
2846 pnode->fDisconnect = true;
2847 return true;
2848 }
2849 return false;
2850}
2851
2853{
2854 bool disconnected = false;
2855 LOCK(cs_vNodes);
2856 for (CNode* pnode : vNodes) {
2857 if (subnet.Match(pnode->addr)) {
2858 LogPrint(BCLog::NET, "disconnect by subnet%s matched peer=%d; disconnecting\n", (fLogIPs ? strprintf("=%s", subnet.ToString()) : ""), pnode->GetId());
2859 pnode->fDisconnect = true;
2860 disconnected = true;
2861 }
2862 }
2863 return disconnected;
2864}
2865
2867{
2868 return DisconnectNode(CSubNet(addr));
2869}
2870
2872{
2873 LOCK(cs_vNodes);
2874 for(CNode* pnode : vNodes) {
2875 if (id == pnode->GetId()) {
2876 LogPrint(BCLog::NET, "disconnect by id peer=%d; disconnecting\n", pnode->GetId());
2877 pnode->fDisconnect = true;
2878 return true;
2879 }
2880 }
2881 return false;
2882}
2883
2884void CConnman::RecordBytesRecv(uint64_t bytes)
2885{
2887 nTotalBytesRecv += bytes;
2888}
2889
2890void CConnman::RecordBytesSent(uint64_t bytes)
2891{
2893 nTotalBytesSent += bytes;
2894
2895 const auto now = GetTime<std::chrono::seconds>();
2896 if (nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME < now)
2897 {
2898 // timeframe expired, reset cycle
2899 nMaxOutboundCycleStartTime = now;
2900 nMaxOutboundTotalBytesSentInCycle = 0;
2901 }
2902
2903 // TODO, exclude peers with download permission
2904 nMaxOutboundTotalBytesSentInCycle += bytes;
2905}
2906
2908{
2910 return nMaxOutboundLimit;
2911}
2912
2913std::chrono::seconds CConnman::GetMaxOutboundTimeframe() const
2914{
2915 return MAX_UPLOAD_TIMEFRAME;
2916}
2917
2919{
2921 if (nMaxOutboundLimit == 0)
2922 return 0s;
2923
2924 if (nMaxOutboundCycleStartTime.count() == 0)
2925 return MAX_UPLOAD_TIMEFRAME;
2926
2927 const std::chrono::seconds cycleEndTime = nMaxOutboundCycleStartTime + MAX_UPLOAD_TIMEFRAME;
2928 const auto now = GetTime<std::chrono::seconds>();
2929 return (cycleEndTime < now) ? 0s : cycleEndTime - now;
2930}
2931
2932bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit) const
2933{
2935 if (nMaxOutboundLimit == 0)
2936 return false;
2937
2938 if (historicalBlockServingLimit)
2939 {
2940 // keep a large enough buffer to at least relay each block once
2941 const std::chrono::seconds timeLeftInCycle = GetMaxOutboundTimeLeftInCycle();
2942 const uint64_t buffer = timeLeftInCycle / std::chrono::minutes{10} * MAX_BLOCK_SERIALIZED_SIZE;
2943 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2944 return true;
2945 }
2946 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2947 return true;
2948
2949 return false;
2950}
2951
2953{
2955 if (nMaxOutboundLimit == 0)
2956 return 0;
2957
2958 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2959}
2960
2962{
2964 return nTotalBytesRecv;
2965}
2966
2968{
2970 return nTotalBytesSent;
2971}
2972
2974{
2975 return nLocalServices;
2976}
2977
2978unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; }
2979
2980CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
2981 : nTimeConnected(GetTimeSeconds()),
2982 addr(addrIn),
2983 addrBind(addrBindIn),
2984 m_addr_name{addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn},
2985 m_inbound_onion(inbound_onion),
2986 nKeyedNetGroup(nKeyedNetGroupIn),
2987 id(idIn),
2988 nLocalHostNonce(nLocalHostNonceIn),
2989 m_conn_type(conn_type_in),
2990 nLocalServices(nLocalServicesIn)
2991{
2992 if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND);
2993 hSocket = hSocketIn;
2994 if (conn_type_in != ConnectionType::BLOCK_RELAY) {
2995 m_tx_relay = std::make_unique<TxRelay>();
2996 }
2997
2998 for (const std::string &msg : getAllNetMessageTypes())
2999 mapRecvBytesPerMsgCmd[msg] = 0;
3000 mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
3001
3002 if (fLogIPs) {
3003 LogPrint(BCLog::NET, "Added connection to %s peer=%d\n", m_addr_name, id);
3004 } else {
3005 LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
3006 }
3007
3008 m_deserializer = std::make_unique<V1TransportDeserializer>(V1TransportDeserializer(Params(), id, SER_NETWORK, INIT_PROTO_VERSION));
3009 m_serializer = std::make_unique<V1TransportSerializer>(V1TransportSerializer());
3010}
3011
3013{
3014 CloseSocket(hSocket);
3015}
3016
3018{
3019 return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
3020}
3021
3023{
3024 size_t nMessageSize = msg.data.size();
3025 LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", msg.m_type, nMessageSize, pnode->GetId());
3026 if (gArgs.GetBoolArg("-capturemessages", false)) {
3027 CaptureMessage(pnode->addr, msg.m_type, msg.data, /* incoming */ false);
3028 }
3029
3030 TRACE6(net, outbound_message,
3031 pnode->GetId(),
3032 pnode->m_addr_name.c_str(),
3033 pnode->ConnectionTypeAsString().c_str(),
3034 msg.m_type.c_str(),
3035 msg.data.size(),
3036 msg.data.data()
3037 );
3038
3039 // make sure we use the appropriate network transport format
3040 std::vector<unsigned char> serializedHeader;
3041 pnode->m_serializer->prepareForTransport(msg, serializedHeader);
3042 size_t nTotalSize = nMessageSize + serializedHeader.size();
3043
3044 size_t nBytesSent = 0;
3045 {
3046 LOCK(pnode->cs_vSend);
3047 bool optimisticSend(pnode->vSendMsg.empty());
3048
3049 //log total amount of bytes per message type
3050 pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
3051 pnode->nSendSize += nTotalSize;
3052
3053 if (pnode->nSendSize > nSendBufferMaxSize) pnode->fPauseSend = true;
3054 pnode->vSendMsg.push_back(std::move(serializedHeader));
3055 if (nMessageSize) pnode->vSendMsg.push_back(std::move(msg.data));
3056
3057 // If write queue empty, attempt "optimistic write"
3058 if (optimisticSend) nBytesSent = SocketSendData(*pnode);
3059 }
3060 if (nBytesSent) RecordBytesSent(nBytesSent);
3061}
3062
3063bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
3064{
3065 CNode* found = nullptr;
3066 LOCK(cs_vNodes);
3067 for (auto&& pnode : vNodes) {
3068 if(pnode->GetId() == id) {
3069 found = pnode;
3070 break;
3071 }
3072 }
3073 return found != nullptr && NodeFullyConnected(found) && func(found);
3074}
3075
3076std::chrono::microseconds CConnman::PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
3077{
3078 if (m_next_send_inv_to_incoming.load() < now) {
3079 // If this function were called from multiple threads simultaneously
3080 // it would possible that both update the next send variable, and return a different result to their caller.
3081 // This is not possible in practice as only the net processing thread invokes this function.
3082 m_next_send_inv_to_incoming = PoissonNextSend(now, average_interval);
3083 }
3085}
3086
3087std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
3088{
3089 double unscaled = -log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */);
3090 return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);
3091}
3092
3094{
3095 return CSipHasher(nSeed0, nSeed1).Write(id);
3096}
3097
3099{
3100 std::vector<unsigned char> vchNetGroup(ad.GetGroup(addrman.GetAsmap()));
3101
3102 return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
3103}
3104
3105void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Span<const unsigned char>& data, bool is_incoming)
3106{
3107 // Note: This function captures the message at the time of processing,
3108 // not at socket receive/send time.
3109 // This ensures that the messages are always in order from an application
3110 // layer (processing) perspective.
3111 auto now = GetTime<std::chrono::microseconds>();
3112
3113 // Windows folder names can not include a colon
3114 std::string clean_addr = addr.ToString();
3115 std::replace(clean_addr.begin(), clean_addr.end(), ':', '_');
3116
3117 fs::path base_path = gArgs.GetDataDirNet() / "message_capture" / clean_addr;
3118 fs::create_directories(base_path);
3119
3120 fs::path path = base_path / (is_incoming ? "msgs_recv.dat" : "msgs_sent.dat");
3122
3123 ser_writedata64(f, now.count());
3124 f.write(msg_type.data(), msg_type.length());
3125 for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
3126 f << uint8_t{'\0'};
3127 }
3128 uint32_t size = data.size();
3129 ser_writedata32(f, size);
3130 f.write((const char*)data.data(), data.size());
3131}
bool DumpPeerAddresses(const ArgsManager &args, const AddrMan &addr)
Definition: addrdb.cpp:173
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:213
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
Definition: addrdb.cpp:207
#define PACKAGE_NAME
int flags
Definition: bitcoin-tx.cpp:525
const CChainParams & Params()
Return the currently selected parameters.
Stochastic address manager.
Definition: addrman.h:55
std::pair< CAddress, int64_t > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict.
Definition: addrman.cpp:1173
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:1183
const std::vector< bool > & GetAsmap() const
Definition: addrman.cpp:1198
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Attempt to add one or more addresses to addrman's new table.
Definition: addrman.cpp:1153
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible, possibly moving it from "new" to "tried".
Definition: addrman.cpp:1158
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
Definition: addrman.cpp:1168
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
Definition: addrman.cpp:1163
size_t size() const
Return the number of (unique) addresses in all tables.
Definition: addrman.cpp:1148
std::pair< CAddress, int64_t > Select(bool newOnly=false) const
Choose an address to connect to.
Definition: addrman.cpp:1178
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:288
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:596
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:602
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
Definition: banman.cpp:75
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
Definition: banman.cpp:69
A CService with information about it as peer.
Definition: protocol.h:359
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
Definition: protocol.h:442
uint32_t nTime
Always included in serialization.
Definition: protocol.h:440
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:565
void write(const char *pch, size_t nSize)
Definition: streams.h:638
const CMessageHeader::MessageStartChars & MessageStart() const
Definition: chainparams.h:83
uint16_t GetDefaultPort() const
Definition: chainparams.h:84
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
Definition: chainparams.h:114
void CreateNodeFromAcceptedSocket(SOCKET hSocket, NetPermissionFlags permissionFlags, 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 vNodes member...
Definition: net.cpp:1126
std::condition_variable condMsgProc
Definition: net.h:1136
std::thread threadMessageHandler
Definition: net.h:1158
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time left in the current max outbound cycle in case of no limit, it will always return 0
Definition: net.cpp:2918
void ThreadOpenAddedConnections()
Definition: net.cpp:2182
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
Definition: net.cpp:2932
CClientUIInterface * m_client_interface
Definition: net.h:1119
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
Definition: net.cpp:791
void SocketHandler()
Definition: net.cpp:1520
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
Definition: net.cpp:3063
std::vector< AddedNodeInfo > GetAddedNodeInfo() const
Definition: net.cpp:2128
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
Definition: net.cpp:1221
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
Definition: net.cpp:402
void DeleteNode(CNode *pnode)
Definition: net.cpp:2725
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
Definition: net.cpp:1054
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
Definition: net.cpp:371
int m_max_outbound
Definition: net.h:1117
void AddAddrFetch(const std::string &strDest)
Definition: net.cpp:119
RecursiveMutex cs_vNodes
Definition: net.h:1059
ServiceFlags nLocalServices
Services this instance offers.
Definition: net.h:1102
bool GetTryNewOutboundPeer() const
Definition: net.cpp:1796
void Stop()
Definition: net.h:806
int m_max_outbound_block_relay
Definition: net.h:1113
void ProcessAddrFetch()
Definition: net.cpp:1779
std::thread threadI2PAcceptIncoming
Definition: net.h:1159
void SetTryNewOutboundPeer(bool flag)
Definition: net.cpp:1801
std::atomic< bool > flagInterruptMsgProc
Definition: net.h:1138
unsigned int GetReceiveFloodSize() const
Definition: net.cpp:2978
std::list< CNode * > vNodesDisconnected
Definition: net.h:1058
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Definition: net.cpp:1445
NodeId GetNewNodeId()
Definition: net.cpp:2478
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
Definition: net.h:1146
std::unique_ptr< CSemaphore > semAddnode
Definition: net.h:1105
std::atomic< NodeId > nLastNodeId
Definition: net.h:1060
std::atomic< std::chrono::microseconds > m_next_send_inv_to_incoming
Definition: net.h:1172
bool ShouldRunInactivityChecks(const CNode &node, int64_t secs_now) const
Return true if we should disconnect the peer for failing an inactivity check.
Definition: net.cpp:1320
void RecordBytesSent(uint64_t bytes)
Definition: net.cpp:2890
int GetExtraBlockRelayCount() const
Definition: net.cpp:1827
BanMan * m_banman
Pointer to this node's banman.
Definition: net.h:1122
void Interrupt()
Definition: net.cpp:2642
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:2952
std::thread threadDNSAddressSeed
Definition: net.h:1154
void ThreadOpenConnections(std::vector< std::string > connect)
Definition: net.cpp:1841
void ThreadI2PAcceptIncoming()
Definition: net.cpp:2302
const uint64_t nSeed1
Definition: net.h:1131
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
Definition: net.h:1128
RecursiveMutex m_addr_fetches_mutex
Definition: net.h:1054
std::chrono::seconds GetMaxOutboundTimeframe() const
Definition: net.cpp:2913
unsigned int nPrevNodeCount
Definition: net.h:1061
void NotifyNumConnectionsChanged()
Definition: net.cpp:1305
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
Definition: net.cpp:2973
bool DisconnectNode(const std::string &node)
Definition: net.cpp:2841
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 This t...
Definition: net.h:1164
bool InitBinds(const Options &options)
Definition: net.cpp:2506
std::vector< ListenSocket > vhListenSocket
Definition: net.h:1049
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
Definition: net.cpp:2115
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
Definition: net.cpp:3093
uint64_t GetMaxOutboundTarget() const
Definition: net.cpp:2907
std::unique_ptr< CSemaphore > semOutbound
Definition: net.h:1104
std::vector< NetWhitelistPermissions > vWhitelistedRange
Definition: net.h:1044
void ThreadSocketHandler()
Definition: net.cpp:1638
RecursiveMutex cs_totalBytesSent
Definition: net.h:1030
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
Definition: net.cpp:2484
std::thread threadOpenConnections
Definition: net.h:1157
size_t GetNodeCount(ConnectionDirection) const
Definition: net.cpp:2813
int64_t m_peer_connect_timeout
Definition: net.h:1040
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
Definition: net.cpp:1325
CNode * FindNode(const CNetAddr &ip)
Definition: net.cpp:327
void Init(const Options &connOptions)
Definition: net.h:773
void GetNodeStats(std::vector< CNodeStats > &vstats) const
Definition: net.cpp:2829
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
Definition: net.h:1131
unsigned int nReceiveFloodSize
Definition: net.h:1047
int GetExtraFullOutboundCount() const
Definition: net.cpp:1813
uint64_t GetTotalBytesRecv() const
Definition: net.cpp:2961
RecursiveMutex cs_totalBytesRecv
Definition: net.h:1029
static bool NodeFullyConnected(const CNode *pnode)
Definition: net.cpp:3017
int nMaxConnections
Definition: net.h:1106
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:2738
void WakeMessageHandler()
Definition: net.cpp:1649
void SetNetworkActive(bool active)
Definition: net.cpp:2453
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
Definition: net.cpp:2211
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
Definition: net.cpp:527
bool Start(CScheduler &scheduler, const Options &options)
Definition: net.cpp:2528
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Definition: net.cpp:1356
void ThreadDNSAddressSeed()
Definition: net.cpp:1658
AddrMan & addrman
Definition: net.h:1052
void ThreadMessageHandler()
Definition: net.cpp:2246
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
Definition: net.cpp:3098
Mutex mutexMsgProc
Definition: net.h:1137
bool fAddressesInitialized
Definition: net.h:1051
std::chrono::microseconds PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
Attempts to obfuscate tx time through exponentially distributed emitting.
Definition: net.cpp:3076
~CConnman()
Definition: net.cpp:2732
void StopThreads()
Definition: net.cpp:2666
RecursiveMutex cs_vAddedNodes
Definition: net.h:1056
std::thread threadOpenAddedConnections
Definition: net.h:1156
bool CheckIncomingNonce(uint64_t nonce)
Definition: net.cpp:376
int m_max_outbound_full_relay
Definition: net.h:1109
int nMaxAddnode
Definition: net.h:1115
void RecordBytesRecv(uint64_t bytes)
Definition: net.cpp:2884
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
Definition: net.cpp:3022
void StopNodes()
Definition: net.cpp:2683
unsigned int nSendBufferMaxSize
Definition: net.h:1046
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
Definition: net.h:1152
bool m_use_addrman_outgoing
Definition: net.h:1118
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:1088
NetEventsInterface * m_msgproc
Definition: net.h:1120
std::atomic< bool > fNetworkActive
Definition: net.h:1050
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
Definition: net.h:1170
void DisconnectNodes()
Definition: net.cpp:1255
CConnman(uint64_t seed0, uint64_t seed1, AddrMan &addrman, bool network_active=true)
Definition: net.cpp:2468
void DumpAddresses()
Definition: net.cpp:1769
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:1178
bool AddNode(const std::string &node)
Definition: net.cpp:2790
std::thread threadSocketHandler
Definition: net.h:1155
uint64_t GetTotalBytesSent() const
Definition: net.cpp:2967
bool RemoveAddedNode(const std::string &node)
Definition: net.cpp:2801
void AcceptConnection(const ListenSocket &hListenSocket)
Definition: net.cpp:1098
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
Definition: net.cpp:2341
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:205
void resize(size_type n, value_type c=0)
Definition: streams.h:257
bool eof() const
Definition: streams.h:356
size_type size() const
Definition: streams.h:255
void Finalize(Span< unsigned char > output)
Definition: hash.h:30
CHash256 & Write(Span< const unsigned char > input)
Definition: hash.h:37
Message header.
Definition: protocol.h:31
char pchMessageStart[MESSAGE_START_SIZE]
Definition: protocol.h:54
static constexpr size_t CHECKSUM_SIZE
Definition: protocol.h:36
static constexpr size_t HEADER_SIZE
Definition: protocol.h:39
uint8_t pchChecksum[CHECKSUM_SIZE]
Definition: protocol.h:57
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:33
std::string GetCommand() const
Definition: protocol.cpp:102
static constexpr size_t COMMAND_SIZE
Definition: protocol.h:34
uint32_t nMessageSize
Definition: protocol.h:56
bool IsCommandValid() const
Definition: protocol.cpp:107
Network address.
Definition: netaddress.h:119
Network GetNetClass() const
Definition: netaddress.cpp:707
std::string ToStringIP() const
Definition: netaddress.cpp:608
void SetIP(const CNetAddr &ip)
Definition: netaddress.cpp:107
std::vector< unsigned char > GetAddrBytes() const
Definition: netaddress.cpp:826
std::string ToString() const
Definition: netaddress.cpp:631
bool IsRoutable() const
Definition: netaddress.cpp:490
Network m_net
Network to which this address belongs.
Definition: netaddress.h:130
bool IsValid() const
Definition: netaddress.cpp:451
bool IsIPv6() const
Definition: netaddress.cpp:320
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:173
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
Definition: netaddress.cpp:766
enum Network GetNetwork() const
Definition: netaddress.cpp:524
~CNetCleanup()
Definition: net.cpp:2632
CNetCleanup()
Definition: net.cpp:2630
Transport protocol agnostic message container.
Definition: net.h:282
uint32_t m_message_size
size of the payload
Definition: net.h:286
std::chrono::microseconds m_time
time of message receipt
Definition: net.h:285
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
Definition: net.h:287
std::string m_command
Definition: net.h:288
Information about a peer.
Definition: net.h:394
std::atomic< int64_t > nLastSend
Definition: net.h:423
const CAddress addrBind
Definition: net.h:431
bool m_prefer_evict
Definition: net.h:442
std::atomic< int > nVersion
Definition: net.h:435
bool IsInboundConn() const
Definition: net.h:495
NodeId GetId() const
Definition: net.h:585
std::atomic< int64_t > nTimeOffset
Definition: net.h:427
const std::string m_addr_name
Definition: net.h:432
std::string ConnectionTypeAsString() const
Definition: net.h:661
std::atomic< bool > m_bip152_highbandwidth_to
Definition: net.h:527
std::list< CNetMessage > vRecvMsg
Definition: net.h:692
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
Definition: net.cpp:559
std::atomic< bool > m_bip152_highbandwidth_from
Definition: net.h:529
std::atomic_bool fSuccessfullyConnected
fSuccessfullyConnected is set to true on receiving VERACK from the peer.
Definition: net.h:449
std::atomic< ServiceFlags > nServices
Definition: net.h:403
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
Definition: net.cpp:631
RecursiveMutex cs_SubVer
Definition: net.h:436
const CAddress addr
Definition: net.h:429
RecursiveMutex cs_addrLocal
Definition: net.h:696
CSemaphoreGrant grantOutbound
Definition: net.h:453
const int64_t nTimeConnected
Unix epoch time at peer connection, in seconds.
Definition: net.h:426
Mutex cs_hSocket
Definition: net.h:412
void CopyStats(CNodeStats &stats)
Definition: net.cpp:575
void CloseSocketDisconnect()
Definition: net.cpp:516
std::unique_ptr< TransportSerializer > m_serializer
Definition: net.h:400
Mutex cs_vSend
Definition: net.h:411
CNode * AddRef()
Definition: net.h:624
std::atomic_bool fPauseSend
Definition: net.h:458
std::unique_ptr< TxRelay > m_tx_relay
Definition: net.h:558
std::unique_ptr< TransportDeserializer > m_deserializer
Definition: net.h:399
NetPermissionFlags m_permissionFlags
Definition: net.h:402
std::atomic< int64_t > nLastRecv
Definition: net.h:424
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
Definition: net.h:571
const ConnectionType m_conn_type
Definition: net.h:672
Network ConnectedThroughNetwork() const
Get network the peer connected through.
Definition: net.cpp:568
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
Definition: net.h:574
CNode(NodeId id, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
Definition: net.cpp:2980
ServiceFlags GetLocalServices() const
Definition: net.h:656
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e. connected via our Tor onion service.
Definition: net.h:434
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
Definition: net.h:578
Mutex cs_vRecv
Definition: net.h:413
~CNode()
Definition: net.cpp:3012
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
Definition: net.h:565
std::atomic_bool fDisconnect
Definition: net.h:452
CService GetAddrLocal() const
Definition: net.cpp:553
std::string addrLocal
Definition: net.h:266
bool fRelayTxes
Definition: net.h:243
bool fInbound
Definition: net.h:253
CAmount minFeeFilter
Definition: net.h:264
Network m_network
Definition: net.h:272
NodeId nodeid
Definition: net.h:241
Simple class for background tasks that should be run periodically or once "after a while".
Definition: scheduler.h:34
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
Definition: scheduler.cpp:112
RAII-style semaphore lock.
Definition: sync.h:310
bool TryAcquire()
Definition: sync.h:332
void MoveTo(CSemaphoreGrant &grant)
Definition: sync.h:339
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:523
std::string ToStringIPPort() const
std::string ToString() const
uint16_t GetPort() const
Definition: netaddress.cpp:966
bool SetSockAddr(const struct sockaddr *paddr)
Definition: netaddress.cpp:952
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
Definition: netaddress.cpp:993
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:76
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
Definition: siphash.cpp:28
std::string ToString() const
bool Match(const CNetAddr &addr) const
bool sleep_for(std::chrono::milliseconds rel_time)
Fast randomness source.
Definition: random.h:120
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:172
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:190
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
virtual void InitializeNode(CNode *pnode)=0
Initialize a peer (setup state, queue any initial messages)
virtual bool SendMessages(CNode *pnode) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
Send queued protocol messages to a given node.
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Process protocol messages received from a given node.
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)
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:93
constexpr std::size_t size() const noexcept
Definition: span.h:182
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
Definition: span.h:199
constexpr C * data() const noexcept
Definition: span.h:169
const CChainParams & m_chain_params
Definition: net.h:318
CDataStream vRecv
Definition: net.h:325
CMessageHeader hdr
Definition: net.h:324
CNetMessage GetMessage(std::chrono::microseconds time, bool &reject_message) override
Definition: net.cpp:741
const uint256 & GetMessageHash() const
Definition: net.cpp:733
const NodeId m_node_id
Definition: net.h:319
int readData(Span< const uint8_t > msg_bytes)
Definition: net.cpp:716
int readHeader(Span< const uint8_t > msg_bytes)
Definition: net.cpp:676
unsigned int nHdrPos
Definition: net.h:326
bool Complete() const override
Definition: net.h:354
CHash256 hasher
Definition: net.h:320
CDataStream hdrbuf
Definition: net.h:323
uint256 data_hash
Definition: net.h:321
unsigned int nDataPos
Definition: net.h:327
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
Definition: net.cpp:778
unsigned char * begin()
Definition: uint256.h:58
bool IsNull() const
Definition: uint256.h:31
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:34
CService proxy
Definition: netbase.h:56
256-bit opaque blob.
Definition: uint256.h:124
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
#define INVALID_SOCKET
Definition: compat.h:53
#define WSAEWOULDBLOCK
Definition: compat.h:46
#define SOCKET_ERROR
Definition: compat.h:54
#define WSAGetLastError()
Definition: compat.h:43
static bool IsSelectableSocket(const SOCKET &s)
Definition: compat.h:100
#define WSAEMSGSIZE
Definition: compat.h:48
#define MSG_NOSIGNAL
Definition: compat.h:110
#define MSG_DONTWAIT
Definition: compat.h:115
unsigned int SOCKET
Definition: compat.h:41
void * sockopt_arg_type
Definition: compat.h:88
#define WSAEINPROGRESS
Definition: compat.h:50
#define WSAEADDRINUSE
Definition: compat.h:51
#define WSAEINTR
Definition: compat.h:49
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
Definition: consensus.h:13
static uint32_t ReadLE32(const unsigned char *ptr)
Definition: common.h:24
static NodeId id
static CService ip(uint32_t i)
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Definition: hash.h:75
bool fLogIPs
Definition: logging.cpp:38
#define LogPrint(category,...)
Definition: logging.h:191
#define LogPrintf(...)
Definition: logging.h:187
unsigned int nonce
Definition: miner_tests.cpp:54
@ NET
Definition: logging.h:38
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:25
void TraceThread(const char *thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
Definition: thread.cpp:13
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
Definition: net.cpp:181
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:856
bool IsPeerAddrLocalGood(CNode *pnode)
Definition: net.cpp:201
uint16_t GetListenPort()
Definition: net.cpp:125
static void EraseLastKElements(std::vector< T > &elements, Comparator comparator, size_t k, std::function< bool(const NodeEvictionCandidate &)> predicate=[](const NodeEvictionCandidate &n) { return true;})
Sort an array by the specified comparator, then erase the last K elements where predicate is true.
Definition: net.cpp:904
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
Definition: net.cpp:67
bool IsLocal(const CService &addr)
check whether a given address is potentially local
Definition: net.cpp:321
static const uint64_t RANDOMIZER_ID_NETGROUP
Definition: net.cpp:106
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
Definition: net.cpp:102
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:874
void RemoveLocal(const CService &addr)
Definition: net.cpp:283
BindFlags
Used to pass flags to the Bind() function.
Definition: net.cpp:89
@ BF_REPORT_ERROR
Definition: net.cpp:92
@ BF_NONE
Definition: net.cpp:90
@ BF_EXPLICIT
Definition: net.cpp:91
@ BF_DONT_ADVERTISE
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections,...
Definition: net.cpp:97
bool fDiscover
Definition: net.cpp:112
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
Definition: net.cpp:107
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
Definition: net.cpp:64
bool AddLocal(const CService &addr_, int nScore)
Definition: net.cpp:250
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
Definition: net.cpp:80
bool fListen
Definition: net.cpp:113
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
Definition: net.cpp:58
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
Definition: net.cpp:131
RecursiveMutex cs_mapLocalHost
Definition: net.cpp:114
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:847
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:852
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
Definition: net.cpp:387
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
Definition: net.cpp:78
static const uint64_t RANDOMIZER_ID_ADDRCACHE
Definition: net.cpp:108
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition: net.cpp:117
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(cs_mapLocalHost)
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
Definition: net.cpp:913
const std::string NET_MESSAGE_COMMAND_OTHER
Definition: net.cpp:104
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
Definition: net.cpp:986
#define X(name)
Definition: net.cpp:574
void CaptureMessage(const CAddress &addr, const std::string &msg_type, const Span< const unsigned char > &data, bool is_incoming)
Dump binary message to file, with timestamp.
Definition: net.cpp:3105
std::optional< CAddress > GetLocalAddrForPeer(CNode *pnode)
Returns a local address that we should advertise to this peer.
Definition: net.cpp:208
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:290
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:864
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
Definition: net.cpp:61
CService MaybeFlipIPv6toCJDNS(const CService &service)
If an IPv6 address belongs to the address range used by the CJDNS network and the CJDNS network is re...
Definition: net.cpp:240
static std::vector< CAddress > ConvertSeeds(const std::vector< uint8_t > &vSeedsIn)
Convert the serialized seeds into usable address objects.
Definition: net.cpp:156
#define FEELER_SLEEP_WINDOW
Definition: net.cpp:86
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
Definition: net.cpp:79
static int GetnScore(const CService &addr)
Definition: net.cpp:193
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
Definition: net.cpp:533
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Definition: net.cpp:842
static CNetCleanup instance_of_cnetcleanup
Definition: net.cpp:2640
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
Definition: net.cpp:83
void Discover()
Definition: net.cpp:2402
bool IsReachable(enum Network net)
Definition: net.cpp:298
bool SeenLocal(const CService &addr)
vote for a local address
Definition: net.cpp:310
std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
Definition: net.cpp:3087
static constexpr bool DEFAULT_FIXEDSEEDS
Definition: net.h:83
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
Definition: net.h:48
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
Definition: net.h:57
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
Definition: net.h:46
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
Definition: net.h:55
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
Definition: net.h:51
static constexpr bool DEFAULT_FORCEDNSSEED
Definition: net.h:81
ConnectionType
Different types of connections to a peer.
Definition: net.h:120
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
@ 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.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
static constexpr bool DEFAULT_DNSSEED
Definition: net.h:82
int64_t NodeId
Definition: net.h:87
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
Definition: net.h:53
@ LOCAL_MANUAL
Definition: net.h:193
@ LOCAL_BIND
Definition: net.h:191
@ LOCAL_IF
Definition: net.h:190
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
Definition: net.h:65
NetPermissionFlags
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
Definition: netaddress.h:34
Network
A network type.
Definition: netaddress.h:45
@ NET_I2P
I2P.
Definition: netaddress.h:59
@ NET_CJDNS
CJDNS.
Definition: netaddress.h:62
@ 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_IPV6
IPv6.
Definition: netaddress.h:53
@ 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:634
bool HaveNameProxy()
Definition: netbase.cpp:642
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:617
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
Definition: netbase.cpp:747
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:656
std::function< std::unique_ptr< Sock >(const CService &)> CreateSock
Socket factory.
Definition: netbase.cpp:529
void InterruptSocks5(bool interrupt)
Definition: netbase.cpp:754
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:541
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:198
bool fNameLookup
Definition: netbase.cpp:37
int nConnectTimeout
Definition: netbase.cpp:36
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:230
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:170
ConnectionDirection
Definition: netbase.h:32
const std::vector< std::string > & getAllNetMessageTypes()
Definition: protocol.cpp:179
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
Definition: protocol.cpp:127
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
Definition: protocol.h:343
ServiceFlags
nServices flags
Definition: protocol.h:271
@ NODE_NONE
Definition: protocol.h:274
@ NODE_BLOOM
Definition: protocol.h:281
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:352
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
Definition: random.cpp:591
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
Definition: random.cpp:587
int GetRandInt(int nMax) noexcept
Definition: random.cpp:596
constexpr auto GetRandMillis
Definition: random.h:84
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:231
static RPCHelpMan send()
Definition: rpcwallet.cpp:4258
@ SER_DISK
Definition: serialize.h:139
@ SER_NETWORK
Definition: serialize.h:138
void ser_writedata32(Stream &s, uint32_t obj)
Definition: serialize.h:74
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
Definition: serialize.h:31
void ser_writedata64(Stream &s, uint64_t obj)
Definition: serialize.h:84
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
Definition: sock.cpp:313
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
Definition: sock.cpp:331
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
Cache responses to addr requests to minimize privacy leak.
Definition: net.h:1069
std::chrono::microseconds m_cache_entry_expiration
Definition: net.h:1071
std::vector< CAddress > m_addrs_response_cache
Definition: net.h:1070
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
Definition: net.h:951
std::vector< NetWhitebindPermissions > vWhiteBinds
Definition: net.h:761
std::vector< CService > onion_binds
Definition: net.h:763
std::vector< std::string > m_specified_outgoing
Definition: net.h:768
std::vector< CService > vBinds
Definition: net.h:762
bool m_i2p_accept_incoming
Definition: net.h:770
std::vector< std::string > vSeedNodes
Definition: net.h:759
bool m_use_addrman_outgoing
Definition: net.h:767
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0....
Definition: net.h:766
std::string m_type
Definition: net.h:110
std::vector< unsigned char > data
Definition: net.h:109
Sort eviction candidates by network/localhost and connection uptime.
Definition: net.cpp:890
CompareNodeNetworkTime(bool is_local, Network network)
Definition: net.cpp:893
const Network m_network
Definition: net.cpp:892
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) const
Definition: net.cpp:894
const bool m_is_local
Definition: net.cpp:891
uint16_t nPort
Definition: net.h:229
int nScore
Definition: net.h:228
int64_t nLastBlockTime
Definition: net.h:1195
Network m_network
Definition: net.h:1203
int64_t nTimeConnected
Definition: net.h:1193
bool fRelevantServices
Definition: net.h:1197
int64_t nLastTXTime
Definition: net.h:1196
std::chrono::microseconds m_min_ping_time
Definition: net.h:1194
uint64_t nKeyedNetGroup
Definition: net.h:1200
Bilingual messages:
Definition: translation.h:16
std::string original
Definition: translation.h:17
An established connection with another peer.
Definition: i2p.h:31
std::unique_ptr< Sock > sock
Connected socket.
Definition: i2p.h:33
CService me
Our I2P address.
Definition: i2p.h:36
#define WAIT_LOCK(cs, name)
Definition: sync.h:231
#define LOCK2(cs1, cs2)
Definition: sync.h:227
#define LOCK(cs)
Definition: sync.h:226
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:270
void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
static int count
Definition: tests.c:41
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:117
int64_t GetTimeSeconds()
Returns the system time (not mockable)
Definition: time.cpp:127
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
Definition: time.cpp:26
int64_t GetAdjustedTime()
Definition: timedata.cpp:35
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
#define TRACE6(context, event, a, b, c, d, e, f)
Definition: trace.h:34
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:63
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:46
ArgsManager gArgs
Definition: system.cpp:85
assert(!tx.IsCoinBase())
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:15
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12