mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-12 05:34:57 +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()));
|
return static_cast<uint16_t>(gArgs.GetIntArg("-port", Params().GetDefaultPort()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// find 'best' local address for a particular peer
|
// Determine the "best" local address for a particular peer.
|
||||||
bool GetLocal(CService& addr, const CNode& peer)
|
[[nodiscard]] static std::optional<CService> GetLocal(const CNode& peer)
|
||||||
{
|
{
|
||||||
if (!fListen)
|
if (!fListen) return std::nullopt;
|
||||||
return false;
|
|
||||||
|
|
||||||
|
std::optional<CService> addr;
|
||||||
int nBestScore = -1;
|
int nBestScore = -1;
|
||||||
int nBestReachability = -1;
|
int nBestReachability = -1;
|
||||||
{
|
{
|
||||||
LOCK(g_maplocalhost_mutex);
|
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
|
// For privacy reasons, don't advertise our privacy-network address
|
||||||
// to other networks and don't advertise our other-network address
|
// to other networks and don't advertise our other-network address
|
||||||
// to privacy networks.
|
// to privacy networks.
|
||||||
const Network our_net{entry.first.GetNetwork()};
|
if (local_addr.GetNetwork() != peer.ConnectedThroughNetwork()
|
||||||
const Network peers_net{peer.ConnectedThroughNetwork()};
|
&& (local_addr.IsPrivacyNet() || peer.IsConnectedThroughPrivacyNet())) {
|
||||||
if (our_net != peers_net &&
|
|
||||||
(our_net == NET_ONION || our_net == NET_I2P ||
|
|
||||||
peers_net == NET_ONION || peers_net == NET_I2P)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int nScore = entry.second.nScore;
|
const int nScore{local_service_info.nScore};
|
||||||
int nReachability = entry.first.GetReachabilityFrom(peer.addr);
|
const int nReachability{local_addr.GetReachabilityFrom(peer.addr)};
|
||||||
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
|
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
|
||||||
{
|
addr.emplace(CService{local_addr, local_service_info.nPort});
|
||||||
addr = CService(entry.first, entry.second.nPort);
|
|
||||||
nBestReachability = nReachability;
|
nBestReachability = nReachability;
|
||||||
nBestScore = nScore;
|
nBestScore = nScore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nBestScore >= 0;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Convert the serialized seeds into usable address objects.
|
//! 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;
|
return vSeedsOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get best local address for a particular peer as a CAddress
|
// Determine the "best" local address for a particular peer.
|
||||||
// Otherwise, return the unroutable 0.0.0.0 but filled in with
|
// 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
|
// the normal parameters, since the IP may be changed to a useful
|
||||||
// one by discovery.
|
// one by discovery.
|
||||||
CService GetLocalAddress(const CNode& peer)
|
CService GetLocalAddress(const CNode& peer)
|
||||||
{
|
{
|
||||||
CService addr;
|
return GetLocal(peer).value_or(CService{CNetAddr(), GetListenPort()});
|
||||||
if (GetLocal(addr, peer)) {
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
return CService{CNetAddr(), GetListenPort()};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetnScore(const CService& addr)
|
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?
|
// 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();
|
CService addrLocal = pnode->GetAddrLocal();
|
||||||
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
|
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
|
||||||
@@ -289,7 +280,7 @@ std::optional<CService> GetLocalAddrForPeer(CNode& node)
|
|||||||
CService MaybeFlipIPv6toCJDNS(const CService& service)
|
CService MaybeFlipIPv6toCJDNS(const CService& service)
|
||||||
{
|
{
|
||||||
CService ret{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;
|
ret.m_net = NET_CJDNS;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -505,7 +496,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||||||
const bool use_proxy{GetProxy(addrConnect.GetNetwork(), proxy)};
|
const bool use_proxy{GetProxy(addrConnect.GetNetwork(), proxy)};
|
||||||
bool proxyConnectionFailed = false;
|
bool proxyConnectionFailed = false;
|
||||||
|
|
||||||
if (addrConnect.GetNetwork() == NET_I2P && use_proxy) {
|
if (addrConnect.IsI2P() && use_proxy) {
|
||||||
i2p::Connection conn;
|
i2p::Connection conn;
|
||||||
|
|
||||||
if (m_i2p_sam_session) {
|
if (m_i2p_sam_session) {
|
||||||
@@ -637,6 +628,11 @@ Network CNode::ConnectedThroughNetwork() const
|
|||||||
return m_inbound_onion ? NET_ONION : addr.GetNetClass();
|
return m_inbound_onion ? NET_ONION : addr.GetNetClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CNode::IsConnectedThroughPrivacyNet() const
|
||||||
|
{
|
||||||
|
return m_inbound_onion || addr.IsPrivacyNet();
|
||||||
|
}
|
||||||
|
|
||||||
#undef X
|
#undef X
|
||||||
#define X(name) stats.name = name
|
#define X(name) stats.name = name
|
||||||
void CNode::CopyStats(CNodeStats& stats)
|
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();
|
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup).Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureMessageToFile(const CAddress& addr,
|
// Dump binary message to file, with timestamp.
|
||||||
const std::string& msg_type,
|
static void CaptureMessageToFile(const CAddress& addr,
|
||||||
Span<const unsigned char> data,
|
const std::string& msg_type,
|
||||||
bool is_incoming)
|
Span<const unsigned char> data,
|
||||||
|
bool is_incoming)
|
||||||
{
|
{
|
||||||
// Note: This function captures the message at the time of processing,
|
// Note: This function captures the message at the time of processing,
|
||||||
// not at socket receive/send time.
|
// not at socket receive/send time.
|
||||||
|
|||||||
11
src/net.h
11
src/net.h
@@ -151,7 +151,6 @@ enum
|
|||||||
LOCAL_MAX
|
LOCAL_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
bool IsPeerAddrLocalGood(CNode *pnode);
|
|
||||||
/** Returns a local address that we should advertise to this peer. */
|
/** Returns a local address that we should advertise to this peer. */
|
||||||
std::optional<CService> GetLocalAddrForPeer(CNode& node);
|
std::optional<CService> GetLocalAddrForPeer(CNode& node);
|
||||||
|
|
||||||
@@ -170,7 +169,6 @@ bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
|
|||||||
void RemoveLocal(const CService& addr);
|
void RemoveLocal(const CService& addr);
|
||||||
bool SeenLocal(const CService& addr);
|
bool SeenLocal(const CService& addr);
|
||||||
bool IsLocal(const CService& addr);
|
bool IsLocal(const CService& addr);
|
||||||
bool GetLocal(CService& addr, const CNode& peer);
|
|
||||||
CService GetLocalAddress(const CNode& peer);
|
CService GetLocalAddress(const CNode& peer);
|
||||||
CService MaybeFlipIPv6toCJDNS(const CService& service);
|
CService MaybeFlipIPv6toCJDNS(const CService& service);
|
||||||
|
|
||||||
@@ -834,6 +832,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
Network ConnectedThroughNetwork() const;
|
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)
|
// We selected peer as (compact blocks) high-bandwidth peer (BIP152)
|
||||||
std::atomic<bool> m_bip152_highbandwidth_to{false};
|
std::atomic<bool> m_bip152_highbandwidth_to{false};
|
||||||
// Peer selected us as (compact blocks) high-bandwidth peer (BIP152)
|
// Peer selected us as (compact blocks) high-bandwidth peer (BIP152)
|
||||||
@@ -1575,12 +1576,6 @@ private:
|
|||||||
friend struct ConnmanTestMsg;
|
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. */
|
/** Defaults to `CaptureMessageToFile()`, but can be overridden by unit tests. */
|
||||||
extern std::function<void(const CAddress& addr,
|
extern std::function<void(const CAddress& addr,
|
||||||
const std::string& msg_type,
|
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; });
|
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
|
bool CNetAddr::IsRFC1918() const
|
||||||
{
|
{
|
||||||
return IsIPv4() && (
|
return IsIPv4() && (
|
||||||
@@ -400,22 +396,6 @@ bool CNetAddr::IsHeNet() const
|
|||||||
return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 4>{0x20, 0x01, 0x04, 0x70});
|
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
|
bool CNetAddr::IsLocal() const
|
||||||
{
|
{
|
||||||
// IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)
|
// IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)
|
||||||
@@ -450,8 +430,7 @@ bool CNetAddr::IsValid() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CJDNS addresses always start with 0xfc
|
if (IsCJDNS() && !HasCJDNSPrefix()) {
|
||||||
if (IsCJDNS() && (m_addr[0] != 0xFC)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,8 +154,8 @@ public:
|
|||||||
bool SetSpecial(const std::string& addr);
|
bool SetSpecial(const std::string& addr);
|
||||||
|
|
||||||
bool IsBindAny() const; // INADDR_ANY equivalent
|
bool IsBindAny() const; // INADDR_ANY equivalent
|
||||||
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
|
[[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
|
||||||
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
|
[[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 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 IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)
|
||||||
bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
|
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 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 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 IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)
|
||||||
bool IsTor() const;
|
[[nodiscard]] bool IsTor() const { return m_net == NET_ONION; }
|
||||||
bool IsI2P() const;
|
[[nodiscard]] bool IsI2P() const { return m_net == NET_I2P; }
|
||||||
bool IsCJDNS() const;
|
[[nodiscard]] bool IsCJDNS() const { return m_net == NET_CJDNS; }
|
||||||
|
[[nodiscard]] bool HasCJDNSPrefix() const { return m_addr[0] == 0xfc; }
|
||||||
bool IsLocal() const;
|
bool IsLocal() const;
|
||||||
bool IsRoutable() const;
|
bool IsRoutable() const;
|
||||||
bool IsInternal() const;
|
bool IsInternal() const;
|
||||||
bool IsValid() 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.
|
* Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user