mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-09 12:12:41 +01:00
Merge bitcoin/bitcoin#28078: net, refactor: remove unneeded exports, use helpers over low-level code, use optional
4ecfd3eaf4Inline short, often-called, rarely-changed basic CNetAddr getters (Jon Atack)5316ae5dd8Convert GetLocal() to std::optional and remove out-param (Jon Atack)f1304db136Use higher-level CNetAddr and CNode helpers in net.cpp (Jon Atack)07f5891588Add CNetAddr::IsPrivacyNet() and CNode::IsConnectedThroughPrivacyNet() (Jon Atack)df488563b2GetLocal() type-safety, naming, const, and formatting cleanups (stickies-v)fb4265747cAdd and use CNetAddr::HasCJDNSPrefix() helper (Jon Atack)5ba73cd0eeMove GetLocal() declaration from header to implementation (Jon Atack)11426f6557Move CaptureMessageToFile() declaration from header to implementation (Jon Atack)deccf1c484Move IsPeerAddrLocalGood() declaration from header to implementation (Jon Atack) Pull request description: and other improvements noticed while reviewing #27411. Addresses https://github.com/bitcoin/bitcoin/pull/27411#discussion_r1263969104 and https://github.com/bitcoin/bitcoin/pull/27411#discussion_r1263967598. See commit messages for details. ACKs for top commit: achow101: ACK4ecfd3eaf4vasild: ACK4ecfd3eaf4stickies-v: ACK4ecfd3eaf4Tree-SHA512: d792bb2cb24690aeae9bedf97e92b64fb6fd080c39385a4bdb8ed05f37f3134d85bda99da025490829c03017fd56382afe7951cdd039aede1c08ba98fb1aa7f9
This commit is contained in:
59
src/net.cpp
59
src/net.cpp
@@ -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.
|
||||
|
||||
11
src/net.h
11
src/net.h
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user