aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;