mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-23 15:20:49 +01:00
Merge bitcoin/bitcoin#28078: net, refactor: remove unneeded exports, use helpers over low-level code, use optional
4ecfd3eaf4
Inline short, often-called, rarely-changed basic CNetAddr getters (Jon Atack)5316ae5dd8
Convert GetLocal() to std::optional and remove out-param (Jon Atack)f1304db136
Use higher-level CNetAddr and CNode helpers in net.cpp (Jon Atack)07f5891588
Add CNetAddr::IsPrivacyNet() and CNode::IsConnectedThroughPrivacyNet() (Jon Atack)df488563b2
GetLocal() type-safety, naming, const, and formatting cleanups (stickies-v)fb4265747c
Add and use CNetAddr::HasCJDNSPrefix() helper (Jon Atack)5ba73cd0ee
Move GetLocal() declaration from header to implementation (Jon Atack)11426f6557
Move CaptureMessageToFile() declaration from header to implementation (Jon Atack)deccf1c484
Move 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: ACK4ecfd3eaf4
vasild: ACK4ecfd3eaf4
stickies-v: ACK4ecfd3eaf4
Tree-SHA512: d792bb2cb24690aeae9bedf97e92b64fb6fd080c39385a4bdb8ed05f37f3134d85bda99da025490829c03017fd56382afe7951cdd039aede1c08ba98fb1aa7f9
This commit is contained in:
commit
41cb17fdb6
4 changed files with 45 additions and 66 deletions
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.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue