Skip to content

Commit 41cb17f

Browse files
committed
Merge bitcoin/bitcoin#28078: net, refactor: remove unneeded exports, use helpers over low-level code, use optional
4ecfd3e Inline short, often-called, rarely-changed basic CNetAddr getters (Jon Atack) 5316ae5 Convert GetLocal() to std::optional and remove out-param (Jon Atack) f1304db Use higher-level CNetAddr and CNode helpers in net.cpp (Jon Atack) 07f5891 Add CNetAddr::IsPrivacyNet() and CNode::IsConnectedThroughPrivacyNet() (Jon Atack) df48856 GetLocal() type-safety, naming, const, and formatting cleanups (stickies-v) fb42657 Add and use CNetAddr::HasCJDNSPrefix() helper (Jon Atack) 5ba73cd Move GetLocal() declaration from header to implementation (Jon Atack) 11426f6 Move CaptureMessageToFile() declaration from header to implementation (Jon Atack) deccf1c Move IsPeerAddrLocalGood() declaration from header to implementation (Jon Atack) Pull request description: and other improvements noticed while reviewing #27411. Addresses bitcoin/bitcoin#27411 (comment) and bitcoin/bitcoin#27411 (comment). See commit messages for details. ACKs for top commit: achow101: ACK 4ecfd3e vasild: ACK 4ecfd3e stickies-v: ACK 4ecfd3e Tree-SHA512: d792bb2cb24690aeae9bedf97e92b64fb6fd080c39385a4bdb8ed05f37f3134d85bda99da025490829c03017fd56382afe7951cdd039aede1c08ba98fb1aa7f9
2 parents 5027d41 + 4ecfd3e commit 41cb17f

File tree

4 files changed

+45
-66
lines changed

4 files changed

+45
-66
lines changed

src/net.cpp

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -158,39 +158,34 @@ uint16_t GetListenPort()
158158
return static_cast<uint16_t>(gArgs.GetIntArg("-port", Params().GetDefaultPort()));
159159
}
160160

161-
// find 'best' local address for a particular peer
162-
bool GetLocal(CService& addr, const CNode& peer)
161+
// Determine the "best" local address for a particular peer.
162+
[[nodiscard]] static std::optional<CService> GetLocal(const CNode& peer)
163163
{
164-
if (!fListen)
165-
return false;
164+
if (!fListen) return std::nullopt;
166165

166+
std::optional<CService> addr;
167167
int nBestScore = -1;
168168
int nBestReachability = -1;
169169
{
170170
LOCK(g_maplocalhost_mutex);
171-
for (const auto& entry : mapLocalHost)
172-
{
171+
for (const auto& [local_addr, local_service_info] : mapLocalHost) {
173172
// For privacy reasons, don't advertise our privacy-network address
174173
// to other networks and don't advertise our other-network address
175174
// to privacy networks.
176-
const Network our_net{entry.first.GetNetwork()};
177-
const Network peers_net{peer.ConnectedThroughNetwork()};
178-
if (our_net != peers_net &&
179-
(our_net == NET_ONION || our_net == NET_I2P ||
180-
peers_net == NET_ONION || peers_net == NET_I2P)) {
175+
if (local_addr.GetNetwork() != peer.ConnectedThroughNetwork()
176+
&& (local_addr.IsPrivacyNet() || peer.IsConnectedThroughPrivacyNet())) {
181177
continue;
182178
}
183-
int nScore = entry.second.nScore;
184-
int nReachability = entry.first.GetReachabilityFrom(peer.addr);
185-
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
186-
{
187-
addr = CService(entry.first, entry.second.nPort);
179+
const int nScore{local_service_info.nScore};
180+
const int nReachability{local_addr.GetReachabilityFrom(peer.addr)};
181+
if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
182+
addr.emplace(CService{local_addr, local_service_info.nPort});
188183
nBestReachability = nReachability;
189184
nBestScore = nScore;
190185
}
191186
}
192187
}
193-
return nBestScore >= 0;
188+
return addr;
194189
}
195190

196191
//! Convert the serialized seeds into usable address objects.
@@ -216,17 +211,13 @@ static std::vector<CAddress> ConvertSeeds(const std::vector<uint8_t> &vSeedsIn)
216211
return vSeedsOut;
217212
}
218213

219-
// get best local address for a particular peer as a CAddress
220-
// Otherwise, return the unroutable 0.0.0.0 but filled in with
214+
// Determine the "best" local address for a particular peer.
215+
// If none, return the unroutable 0.0.0.0 but filled in with
221216
// the normal parameters, since the IP may be changed to a useful
222217
// one by discovery.
223218
CService GetLocalAddress(const CNode& peer)
224219
{
225-
CService addr;
226-
if (GetLocal(addr, peer)) {
227-
return addr;
228-
}
229-
return CService{CNetAddr(), GetListenPort()};
220+
return GetLocal(peer).value_or(CService{CNetAddr(), GetListenPort()});
230221
}
231222

232223
static int GetnScore(const CService& addr)
@@ -237,7 +228,7 @@ static int GetnScore(const CService& addr)
237228
}
238229

239230
// Is our peer's addrLocal potentially useful as an external IP source?
240-
bool IsPeerAddrLocalGood(CNode *pnode)
231+
[[nodiscard]] static bool IsPeerAddrLocalGood(CNode *pnode)
241232
{
242233
CService addrLocal = pnode->GetAddrLocal();
243234
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
@@ -289,7 +280,7 @@ std::optional<CService> GetLocalAddrForPeer(CNode& node)
289280
CService MaybeFlipIPv6toCJDNS(const CService& service)
290281
{
291282
CService ret{service};
292-
if (ret.m_net == NET_IPV6 && ret.m_addr[0] == 0xfc && IsReachable(NET_CJDNS)) {
283+
if (ret.IsIPv6() && ret.HasCJDNSPrefix() && IsReachable(NET_CJDNS)) {
293284
ret.m_net = NET_CJDNS;
294285
}
295286
return ret;
@@ -505,7 +496,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
505496
const bool use_proxy{GetProxy(addrConnect.GetNetwork(), proxy)};
506497
bool proxyConnectionFailed = false;
507498

508-
if (addrConnect.GetNetwork() == NET_I2P && use_proxy) {
499+
if (addrConnect.IsI2P() && use_proxy) {
509500
i2p::Connection conn;
510501

511502
if (m_i2p_sam_session) {
@@ -637,6 +628,11 @@ Network CNode::ConnectedThroughNetwork() const
637628
return m_inbound_onion ? NET_ONION : addr.GetNetClass();
638629
}
639630

631+
bool CNode::IsConnectedThroughPrivacyNet() const
632+
{
633+
return m_inbound_onion || addr.IsPrivacyNet();
634+
}
635+
640636
#undef X
641637
#define X(name) stats.name = name
642638
void CNode::CopyStats(CNodeStats& stats)
@@ -3753,10 +3749,11 @@ uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& address) const
37533749
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup).Finalize();
37543750
}
37553751

3756-
void CaptureMessageToFile(const CAddress& addr,
3757-
const std::string& msg_type,
3758-
Span<const unsigned char> data,
3759-
bool is_incoming)
3752+
// Dump binary message to file, with timestamp.
3753+
static void CaptureMessageToFile(const CAddress& addr,
3754+
const std::string& msg_type,
3755+
Span<const unsigned char> data,
3756+
bool is_incoming)
37603757
{
37613758
// Note: This function captures the message at the time of processing,
37623759
// not at socket receive/send time.

src/net.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ enum
151151
LOCAL_MAX
152152
};
153153

154-
bool IsPeerAddrLocalGood(CNode *pnode);
155154
/** Returns a local address that we should advertise to this peer. */
156155
std::optional<CService> GetLocalAddrForPeer(CNode& node);
157156

@@ -170,7 +169,6 @@ bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
170169
void RemoveLocal(const CService& addr);
171170
bool SeenLocal(const CService& addr);
172171
bool IsLocal(const CService& addr);
173-
bool GetLocal(CService& addr, const CNode& peer);
174172
CService GetLocalAddress(const CNode& peer);
175173
CService MaybeFlipIPv6toCJDNS(const CService& service);
176174

@@ -834,6 +832,9 @@ class CNode
834832
*/
835833
Network ConnectedThroughNetwork() const;
836834

835+
/** Whether this peer connected through a privacy network. */
836+
[[nodiscard]] bool IsConnectedThroughPrivacyNet() const;
837+
837838
// We selected peer as (compact blocks) high-bandwidth peer (BIP152)
838839
std::atomic<bool> m_bip152_highbandwidth_to{false};
839840
// Peer selected us as (compact blocks) high-bandwidth peer (BIP152)
@@ -1575,12 +1576,6 @@ class CConnman
15751576
friend struct ConnmanTestMsg;
15761577
};
15771578

1578-
/** Dump binary message to file, with timestamp */
1579-
void CaptureMessageToFile(const CAddress& addr,
1580-
const std::string& msg_type,
1581-
Span<const unsigned char> data,
1582-
bool is_incoming);
1583-
15841579
/** Defaults to `CaptureMessageToFile()`, but can be overridden by unit tests. */
15851580
extern std::function<void(const CAddress& addr,
15861581
const std::string& msg_type,

src/netaddress.cpp

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,6 @@ bool CNetAddr::IsBindAny() const
309309
return std::all_of(m_addr.begin(), m_addr.end(), [](uint8_t b) { return b == 0; });
310310
}
311311

312-
bool CNetAddr::IsIPv4() const { return m_net == NET_IPV4; }
313-
314-
bool CNetAddr::IsIPv6() const { return m_net == NET_IPV6; }
315-
316312
bool CNetAddr::IsRFC1918() const
317313
{
318314
return IsIPv4() && (
@@ -400,22 +396,6 @@ bool CNetAddr::IsHeNet() const
400396
return IsIPv6() && HasPrefix(m_addr, std::array<uint8_t, 4>{0x20, 0x01, 0x04, 0x70});
401397
}
402398

403-
/**
404-
* Check whether this object represents a TOR address.
405-
* @see CNetAddr::SetSpecial(const std::string &)
406-
*/
407-
bool CNetAddr::IsTor() const { return m_net == NET_ONION; }
408-
409-
/**
410-
* Check whether this object represents an I2P address.
411-
*/
412-
bool CNetAddr::IsI2P() const { return m_net == NET_I2P; }
413-
414-
/**
415-
* Check whether this object represents a CJDNS address.
416-
*/
417-
bool CNetAddr::IsCJDNS() const { return m_net == NET_CJDNS; }
418-
419399
bool CNetAddr::IsLocal() const
420400
{
421401
// IPv4 loopback (127.0.0.0/8 or 0.0.0.0/8)
@@ -450,8 +430,7 @@ bool CNetAddr::IsValid() const
450430
return false;
451431
}
452432

453-
// CJDNS addresses always start with 0xfc
454-
if (IsCJDNS() && (m_addr[0] != 0xFC)) {
433+
if (IsCJDNS() && !HasCJDNSPrefix()) {
455434
return false;
456435
}
457436

src/netaddress.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ class CNetAddr
154154
bool SetSpecial(const std::string& addr);
155155

156156
bool IsBindAny() const; // INADDR_ANY equivalent
157-
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
158-
bool IsIPv6() const; // IPv6 address (not mapped IPv4, not Tor)
157+
[[nodiscard]] bool IsIPv4() const { return m_net == NET_IPV4; } // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
158+
[[nodiscard]] bool IsIPv6() const { return m_net == NET_IPV6; } // IPv6 address (not mapped IPv4, not Tor)
159159
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
160160
bool IsRFC2544() const; // IPv4 inter-network communications (198.18.0.0/15)
161161
bool IsRFC6598() const; // IPv4 ISP-level NAT (100.64.0.0/10)
@@ -171,14 +171,22 @@ class CNetAddr
171171
bool IsRFC6052() const; // IPv6 well-known prefix for IPv4-embedded address (64:FF9B::/96)
172172
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96) (actually defined in RFC2765)
173173
bool IsHeNet() const; // IPv6 Hurricane Electric - https://he.net (2001:0470::/36)
174-
bool IsTor() const;
175-
bool IsI2P() const;
176-
bool IsCJDNS() const;
174+
[[nodiscard]] bool IsTor() const { return m_net == NET_ONION; }
175+
[[nodiscard]] bool IsI2P() const { return m_net == NET_I2P; }
176+
[[nodiscard]] bool IsCJDNS() const { return m_net == NET_CJDNS; }
177+
[[nodiscard]] bool HasCJDNSPrefix() const { return m_addr[0] == 0xfc; }
177178
bool IsLocal() const;
178179
bool IsRoutable() const;
179180
bool IsInternal() const;
180181
bool IsValid() const;
181182

183+
/**
184+
* Whether this object is a privacy network.
185+
* TODO: consider adding IsCJDNS() here when more peers adopt CJDNS, see:
186+
* https://github.com/bitcoin/bitcoin/pull/27411#issuecomment-1497176155
187+
*/
188+
[[nodiscard]] bool IsPrivacyNet() const { return IsTor() || IsI2P(); }
189+
182190
/**
183191
* Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
184192
*/

0 commit comments

Comments
 (0)