Merge 41cb17fdb6 into merged_master (Bitcoin PR bitcoin/bitcoin#28078)

This commit is contained in:
Byron Hambly 2025-08-04 10:11:46 +02:00
commit d005c49dfc
No known key found for this signature in database
GPG key ID: DE8F6EA20A661697
4 changed files with 45 additions and 66 deletions

View file

@ -158,39 +158,34 @@ uint16_t GetListenPort()
return static_cast<uint16_t>(gArgs.GetIntArg("-port", Params().GetDefaultPort()));
}
// find 'best' local address for a particular peer
bool GetLocal(CService& addr, const CNode& peer)
// Determine the "best" local address for a particular peer.
[[nodiscard]] static std::optional<CService> GetLocal(const CNode& peer)
{
if (!fListen)
return false;
if (!fListen) return std::nullopt;
std::optional<CService> addr;
int nBestScore = -1;
int nBestReachability = -1;
{
LOCK(g_maplocalhost_mutex);
for (const auto& entry : mapLocalHost)
{
for (const auto& [local_addr, local_service_info] : mapLocalHost) {
// For privacy reasons, don't advertise our privacy-network address
// to other networks and don't advertise our other-network address
// to privacy networks.
const Network our_net{entry.first.GetNetwork()};
const Network peers_net{peer.ConnectedThroughNetwork()};
if (our_net != peers_net &&
(our_net == NET_ONION || our_net == NET_I2P ||
peers_net == NET_ONION || peers_net == NET_I2P)) {
if (local_addr.GetNetwork() != peer.ConnectedThroughNetwork()
&& (local_addr.IsPrivacyNet() || peer.IsConnectedThroughPrivacyNet())) {
continue;
}
int nScore = entry.second.nScore;
int nReachability = entry.first.GetReachabilityFrom(peer.addr);
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
{
addr = CService(entry.first, entry.second.nPort);
const int nScore{local_service_info.nScore};
const int nReachability{local_addr.GetReachabilityFrom(peer.addr)};
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
addr.emplace(CService{local_addr, local_service_info.nPort});
nBestReachability = nReachability;
nBestScore = nScore;
}
}
}
return nBestScore >= 0;
return addr;
}
//! Convert the serialized seeds into usable address objects.
@ -216,17 +211,13 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
return vSeedsOut;
}
// get best local address for a particular peer as a CAddress
// Otherwise, return the unroutable 0.0.0.0 but filled in with
// Determine the "best" local address for a particular peer.
// If none, return the unroutable 0.0.0.0 but filled in with
// the normal parameters, since the IP may be changed to a useful
// one by discovery.
CService GetLocalAddress(const CNode& peer)
{
CService addr;
if (GetLocal(addr, peer)) {
return addr;
}
return CService{CNetAddr(), GetListenPort()};
return GetLocal(peer).value_or(CService{CNetAddr(), GetListenPort()});
}
static int GetnScore(const CService& addr)
@ -237,7 +228,7 @@ static int GetnScore(const CService& addr)
}
// Is our peer's addrLocal potentially useful as an external IP source?
bool IsPeerAddrLocalGood(CNode *pnode)
[[nodiscard]] static bool IsPeerAddrLocalGood(CNode *pnode)
{
CService addrLocal = pnode->GetAddrLocal();
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
@ -289,7 +280,7 @@ std::optional<CService> GetLocalAddrForPeer(CNode& node)
CService MaybeFlipIPv6toCJDNS(const CService& service)
{
CService ret{service};
if (ret.m_net == NET_IPV6 && ret.m_addr[0] == 0xfc && IsReachable(NET_CJDNS)) {
if (ret.IsIPv6() && ret.HasCJDNSPrefix() && IsReachable(NET_CJDNS)) {
ret.m_net = NET_CJDNS;
}
return ret;
@ -505,7 +496,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
const bool use_proxy{GetProxy(addrConnect.GetNetwork(), proxy)};
bool proxyConnectionFailed = false;
if (addrConnect.GetNetwork() == NET_I2P && use_proxy) {
if (addrConnect.IsI2P() && use_proxy) {
i2p::Connection conn;
if (m_i2p_sam_session) {
@ -637,6 +628,11 @@ Network CNode::ConnectedThroughNetwork() const
return m_inbound_onion ? NET_ONION : addr.GetNetClass();
}
bool CNode::IsConnectedThroughPrivacyNet() const
{
return m_inbound_onion || addr.IsPrivacyNet();
}
#undef X
#define X(name) stats.name = name
void CNode::CopyStats(CNodeStats& stats)
@ -3753,10 +3749,11 @@ uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& address) const
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup).Finalize();
}
void CaptureMessageToFile(const CAddress& addr,
const std::string& msg_type,
Span<const unsigned char> data,
bool is_incoming)
// Dump binary message to file, with timestamp.
static void CaptureMessageToFile(const CAddress& addr,
const std::string& msg_type,
Span<const unsigned char> data,
bool is_incoming)
{
// Note: This function captures the message at the time of processing,
// not at socket receive/send time.

View file

@ -151,7 +151,6 @@ enum
LOCAL_MAX
};
bool IsPeerAddrLocalGood(CNode *pnode);
/** Returns a local address that we should advertise to this peer. */
std::optional<CService> GetLocalAddrForPeer(CNode& node);
@ -170,7 +169,6 @@ bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
void RemoveLocal(const CService& addr);
bool SeenLocal(const CService& addr);
bool IsLocal(const CService& addr);
bool GetLocal(CService& addr, const CNode& peer);
CService GetLocalAddress(const CNode& peer);
CService MaybeFlipIPv6toCJDNS(const CService& service);
@ -834,6 +832,9 @@ public:
*/
Network ConnectedThroughNetwork() const;
/** Whether this peer connected through a privacy network. */
[[nodiscard]] bool IsConnectedThroughPrivacyNet() const;
// We selected peer as (compact blocks) high-bandwidth peer (BIP152)
std::atomic<bool> m_bip152_highbandwidth_to{false};
// Peer selected us as (compact blocks) high-bandwidth peer (BIP152)
@ -1575,12 +1576,6 @@ private:
friend struct ConnmanTestMsg;
};
/** Dump binary message to file, with timestamp */
void CaptureMessageToFile(const CAddress& addr,
const std::string& msg_type,
Span<const unsigned char> data,
bool is_incoming);
/** Defaults to `CaptureMessageToFile()`, but can be overridden by unit tests. */
extern std::function<void(const CAddress& addr,
const std::string& msg_type,

View file

@ -309,10 +309,6 @@ bool CNetAddr::IsBindAny() const
return std::all_of(m_addr.begin(), m_addr.end(), [](uint8_t b) { return b == 0; });
}
bool CNetAddr::IsIPv4() const { return m_net == NET_IPV4; }
bool CNetAddr::IsIPv6() const { return m_net == NET_IPV6; }
bool CNetAddr::IsRFC1918() const
{
return IsIPv4() && (
@ -400,22 +396,6 @@ bool CNetAddr::IsHeNet() const
return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 4>{0x20, 0x01, 0x04, 0x70});
}
/**
* Check whether this object represents a TOR address.
* @see CNetAddr::SetSpecial(const std::string &)
*/
bool CNetAddr::IsTor() const { return m_net == NET_ONION; }
/**
* Check whether this object represents an I2P address.
*/
bool CNetAddr::IsI2P() const { return m_net == NET_I2P; }
/**
* Check whether this object represents a CJDNS address.
*/
bool CNetAddr::IsCJDNS() const { return m_net == NET_CJDNS; }
bool CNetAddr::IsLocal() const
{
// IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)
@ -450,8 +430,7 @@ bool CNetAddr::IsValid() const
return false;
}
// CJDNS addresses always start with 0xfc
if (IsCJDNS() && (m_addr[0] != 0xFC)) {
if (IsCJDNS() && !HasCJDNSPrefix()) {
return false;
}

View file

@ -154,8 +154,8 @@ public:
bool SetSpecial(const std::string& addr);
bool IsBindAny() const; // INADDR_ANY equivalent
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
[[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
[[nodiscard]] bool IsIPv6() const { return m_net == NET_IPV6; } // IPv6 address (not mapped IPv4, not Tor)
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)
bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
@ -171,14 +171,22 @@ public:
bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96)
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765)
bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)
bool IsTor() const;
bool IsI2P() const;
bool IsCJDNS() const;
[[nodiscard]] bool IsTor() const { return m_net == NET_ONION; }
[[nodiscard]] bool IsI2P() const { return m_net == NET_I2P; }
[[nodiscard]] bool IsCJDNS() const { return m_net == NET_CJDNS; }
[[nodiscard]] bool HasCJDNSPrefix() const { return m_addr[0] == 0xfc; }
bool IsLocal() const;
bool IsRoutable() const;
bool IsInternal() const;
bool IsValid() const;
/**
* Whether this object is a privacy network.
* TODO: consider adding IsCJDNS() here when more peers adopt CJDNS, see:
* https://github.com/bitcoin/bitcoin/pull/27411#issuecomment-1497176155
*/
[[nodiscard]] bool IsPrivacyNet() const { return IsTor() || IsI2P(); }
/**
* Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
*/