aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2023-09-21 11:25:31 -0400
committerAndrew Chow <github@achow101.com>2023-09-21 11:26:16 -0400
commit41cb17fdb656c806e54a8410c7f24c78278d9e6f (patch)
tree5202e8c57ce93760f660ce5900995636e9a01e57
parent5027d41988d4a92be5a9fc846a680e805fc71383 (diff)
parent4ecfd3eaf434d868455466e001adae4b68515ab8 (diff)
Merge bitcoin/bitcoin#28078: net, refactor: remove unneeded exports, use helpers over low-level code, use optional
4ecfd3eaf434d868455466e001adae4b68515ab8 Inline short, often-called, rarely-changed basic CNetAddr getters (Jon Atack) 5316ae5dd8d90623f9bb883bb253fa6463ee4d34 Convert GetLocal() to std::optional and remove out-param (Jon Atack) f1304db136bbeac70b52522b5a4522165bfb3fc0 Use higher-level CNetAddr and CNode helpers in net.cpp (Jon Atack) 07f589158835151a7613e4b2a508c0dd61a18fd7 Add CNetAddr::IsPrivacyNet() and CNode::IsConnectedThroughPrivacyNet() (Jon Atack) df488563b280c63f5d74d5ac0fcb1a2cad489d55 GetLocal() type-safety, naming, const, and formatting cleanups (stickies-v) fb4265747c9eb022d80c6f2988e574c689130348 Add and use CNetAddr::HasCJDNSPrefix() helper (Jon Atack) 5ba73cd0ee1e661ec4d041ac8ae7a60cfd31f0c0 Move GetLocal() declaration from header to implementation (Jon Atack) 11426f6557ac09489d5e13bf3b9d94fbd5073c8e Move CaptureMessageToFile() declaration from header to implementation (Jon Atack) deccf1c4848620cfff2a9642c5a6b5acdfbc33bd 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: ACK 4ecfd3eaf434d868455466e001adae4b68515ab8 vasild: ACK 4ecfd3eaf434d868455466e001adae4b68515ab8 stickies-v: ACK 4ecfd3eaf434d868455466e001adae4b68515ab8 Tree-SHA512: d792bb2cb24690aeae9bedf97e92b64fb6fd080c39385a4bdb8ed05f37f3134d85bda99da025490829c03017fd56382afe7951cdd039aede1c08ba98fb1aa7f9
-rw-r--r--src/net.cpp59
-rw-r--r--src/net.h11
-rw-r--r--src/netaddress.cpp23
-rw-r--r--src/netaddress.h18
4 files changed, 45 insertions, 66 deletions
diff --git a/src/net.cpp b/src/net.cpp
index ef1135bb8c..0c6dac572d 100644
--- a/src/net.cpp
+++ b/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.
diff --git a/src/net.h b/src/net.h
index 145b5cf666..5ab693876c 100644
--- a/src/net.h
+++ b/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,
diff --git a/src/netaddress.cpp b/src/netaddress.cpp
index 4758f24680..7530334db1 100644
--- a/src/netaddress.cpp
+++ b/src/netaddress.cpp
@@ -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;
}
diff --git a/src/netaddress.h b/src/netaddress.h
index 7d3659a11a..ad09f16799 100644
--- a/src/netaddress.h
+++ b/src/netaddress.h
@@ -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,15 +171,23 @@ 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.
*/
bool IsAddrV1Compatible() const;