Skip to content

Commit 6e30865

Browse files
committed
net: move IsReachable() code to netbase and encapsulate it
`vfLimited`, `IsReachable()`, `SetReachable()` need not be in the `net` module. Move them to `netbase` because they will be needed in `LookupSubNet()` to possibly flip the result to CJDNS (if that network is reachable). In the process, encapsulate them in a class. `NET_UNROUTABLE` and `NET_INTERNAL` are no longer ignored when adding or removing reachable networks. This was unnecessary.
1 parent c42ded3 commit 6e30865

File tree

9 files changed

+135
-103
lines changed

9 files changed

+135
-103
lines changed

src/init.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,38 +1305,32 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
13051305
}
13061306

13071307
if (args.IsArgSet("-onlynet")) {
1308-
std::set<enum Network> nets;
1308+
g_reachable_nets.RemoveAll();
13091309
for (const std::string& snet : args.GetArgs("-onlynet")) {
13101310
enum Network net = ParseNetwork(snet);
13111311
if (net == NET_UNROUTABLE)
13121312
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
1313-
nets.insert(net);
1314-
}
1315-
for (int n = 0; n < NET_MAX; n++) {
1316-
enum Network net = (enum Network)n;
1317-
assert(IsReachable(net));
1318-
if (!nets.count(net))
1319-
SetReachable(net, false);
1313+
g_reachable_nets.Add(net);
13201314
}
13211315
}
13221316

13231317
if (!args.IsArgSet("-cjdnsreachable")) {
1324-
if (args.IsArgSet("-onlynet") && IsReachable(NET_CJDNS)) {
1318+
if (args.IsArgSet("-onlynet") && g_reachable_nets.Contains(NET_CJDNS)) {
13251319
return InitError(
13261320
_("Outbound connections restricted to CJDNS (-onlynet=cjdns) but "
13271321
"-cjdnsreachable is not provided"));
13281322
}
1329-
SetReachable(NET_CJDNS, false);
1323+
g_reachable_nets.Remove(NET_CJDNS);
13301324
}
1331-
// Now IsReachable(NET_CJDNS) is true if:
1325+
// Now g_reachable_nets.Contains(NET_CJDNS) is true if:
13321326
// 1. -cjdnsreachable is given and
13331327
// 2.1. -onlynet is not given or
13341328
// 2.2. -onlynet=cjdns is given
13351329

13361330
// Requesting DNS seeds entails connecting to IPv4/IPv6, which -onlynet options may prohibit:
13371331
// If -dnsseed=1 is explicitly specified, abort. If it's left unspecified by the user, we skip
13381332
// the DNS seeds by adjusting -dnsseed in InitParameterInteraction.
1339-
if (args.GetBoolArg("-dnsseed") == true && !IsReachable(NET_IPV4) && !IsReachable(NET_IPV6)) {
1333+
if (args.GetBoolArg("-dnsseed") == true && !g_reachable_nets.Contains(NET_IPV4) && !g_reachable_nets.Contains(NET_IPV6)) {
13401334
return InitError(strprintf(_("Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6")));
13411335
};
13421336

@@ -1366,7 +1360,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
13661360
onion_proxy = addrProxy;
13671361
}
13681362

1369-
const bool onlynet_used_with_onion{args.IsArgSet("-onlynet") && IsReachable(NET_ONION)};
1363+
const bool onlynet_used_with_onion{args.IsArgSet("-onlynet") && g_reachable_nets.Contains(NET_ONION)};
13701364

13711365
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
13721366
// -noonion (or -onion=0) disables connecting to .onion entirely
@@ -1401,7 +1395,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14011395
"reaching the Tor network is not provided: none of -proxy, -onion or "
14021396
"-listenonion is given"));
14031397
}
1404-
SetReachable(NET_ONION, false);
1398+
g_reachable_nets.Remove(NET_ONION);
14051399
}
14061400

14071401
for (const std::string& strAddr : args.GetArgs("-externalip")) {
@@ -1876,12 +1870,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
18761870
}
18771871
SetProxy(NET_I2P, Proxy{addr.value()});
18781872
} else {
1879-
if (args.IsArgSet("-onlynet") && IsReachable(NET_I2P)) {
1873+
if (args.IsArgSet("-onlynet") && g_reachable_nets.Contains(NET_I2P)) {
18801874
return InitError(
18811875
_("Outbound connections restricted to i2p (-onlynet=i2p) but "
18821876
"-i2psam is not provided"));
18831877
}
1884-
SetReachable(NET_I2P, false);
1878+
g_reachable_nets.Remove(NET_I2P);
18851879
}
18861880

18871881
connOptions.m_i2p_accept_incoming = args.GetBoolArg("-i2pacceptincoming", DEFAULT_I2P_ACCEPT_INCOMING);

src/net.cpp

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ bool fDiscover = true;
115115
bool fListen = true;
116116
GlobalMutex g_maplocalhost_mutex;
117117
std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(g_maplocalhost_mutex);
118-
static bool vfLimited[NET_MAX] GUARDED_BY(g_maplocalhost_mutex) = {};
119118
std::string strSubVersion;
120119

121120
size_t CSerializedNetMsg::GetMemoryUsage() const noexcept
@@ -232,7 +231,7 @@ static int GetnScore(const CService& addr)
232231
{
233232
CService addrLocal = pnode->GetAddrLocal();
234233
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
235-
IsReachable(addrLocal.GetNetwork());
234+
g_reachable_nets.Contains(addrLocal);
236235
}
237236

238237
std::optional<CService> GetLocalAddrForPeer(CNode& node)
@@ -280,7 +279,7 @@ std::optional<CService> GetLocalAddrForPeer(CNode& node)
280279
CService MaybeFlipIPv6toCJDNS(const CService& service)
281280
{
282281
CService ret{service};
283-
if (ret.IsIPv6() && ret.HasCJDNSPrefix() && IsReachable(NET_CJDNS)) {
282+
if (ret.IsIPv6() && ret.HasCJDNSPrefix() && g_reachable_nets.Contains(NET_CJDNS)) {
284283
ret.m_net = NET_CJDNS;
285284
}
286285
return ret;
@@ -297,7 +296,7 @@ bool AddLocal(const CService& addr_, int nScore)
297296
if (!fDiscover && nScore < LOCAL_MANUAL)
298297
return false;
299298

300-
if (!IsReachable(addr))
299+
if (!g_reachable_nets.Contains(addr))
301300
return false;
302301

303302
LogPrintf("AddLocal(%s,%i)\n", addr.ToStringAddrPort(), nScore);
@@ -327,25 +326,6 @@ void RemoveLocal(const CService& addr)
327326
mapLocalHost.erase(addr);
328327
}
329328

330-
void SetReachable(enum Network net, bool reachable)
331-
{
332-
if (net == NET_UNROUTABLE || net == NET_INTERNAL)
333-
return;
334-
LOCK(g_maplocalhost_mutex);
335-
vfLimited[net] = !reachable;
336-
}
337-
338-
bool IsReachable(enum Network net)
339-
{
340-
LOCK(g_maplocalhost_mutex);
341-
return !vfLimited[net];
342-
}
343-
344-
bool IsReachable(const CNetAddr &addr)
345-
{
346-
return IsReachable(addr.GetNetwork());
347-
}
348-
349329
/** vote for a local address */
350330
bool SeenLocal(const CService& addr)
351331
{
@@ -2433,7 +2413,7 @@ std::unordered_set<Network> CConnman::GetReachableEmptyNetworks() const
24332413
for (int n = 0; n < NET_MAX; n++) {
24342414
enum Network net = (enum Network)n;
24352415
if (net == NET_UNROUTABLE || net == NET_INTERNAL) continue;
2436-
if (IsReachable(net) && addrman.Size(net, std::nullopt) == 0) {
2416+
if (g_reachable_nets.Contains(net) && addrman.Size(net, std::nullopt) == 0) {
24372417
networks.insert(net);
24382418
}
24392419
}
@@ -2453,7 +2433,7 @@ bool CConnman::MaybePickPreferredNetwork(std::optional<Network>& network)
24532433

24542434
LOCK(m_nodes_mutex);
24552435
for (const auto net : nets) {
2456-
if (IsReachable(net) && m_network_conn_counts[net] == 0 && addrman.Size(net) != 0) {
2436+
if (g_reachable_nets.Contains(net) && m_network_conn_counts[net] == 0 && addrman.Size(net) != 0) {
24572437
network = net;
24582438
return true;
24592439
}
@@ -2683,7 +2663,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
26832663
if (anchor && !m_anchors.empty()) {
26842664
const CAddress addr = m_anchors.back();
26852665
m_anchors.pop_back();
2686-
if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) ||
2666+
if (!addr.IsValid() || IsLocal(addr) || !g_reachable_nets.Contains(addr) ||
26872667
!HasAllDesirableServiceFlags(addr.nServices) ||
26882668
outbound_ipv46_peer_netgroups.count(m_netgroupman.GetGroup(addr))) continue;
26892669
addrConnect = addr;
@@ -2738,8 +2718,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
27382718
break;
27392719
}
27402720

2741-
if (!IsReachable(addr))
2721+
if (!g_reachable_nets.Contains(addr)) {
27422722
continue;
2723+
}
27432724

27442725
// only consider very recently tried nodes after 30 failed attempts
27452726
if (current_time - addr_last_try < 10min && nTries < 30) {

src/net.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,6 @@ enum
160160
/** Returns a local address that we should advertise to this peer. */
161161
std::optional<CService> GetLocalAddrForPeer(CNode& node);
162162

163-
/**
164-
* Mark a network as reachable or unreachable (no automatic connects to it)
165-
* @note Networks are reachable by default
166-
*/
167-
void SetReachable(enum Network net, bool reachable);
168-
/** @returns true if the network is reachable, false otherwise */
169-
bool IsReachable(enum Network net);
170-
/** @returns true if the address is in a reachable network, false otherwise */
171-
bool IsReachable(const CNetAddr& addr);
172-
173163
bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
174164
bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
175165
void RemoveLocal(const CService& addr);

src/net_processing.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3823,14 +3823,15 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
38233823
continue;
38243824
}
38253825
++num_proc;
3826-
bool fReachable = IsReachable(addr);
3826+
const bool reachable{g_reachable_nets.Contains(addr)};
38273827
if (addr.nTime > current_a_time - 10min && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) {
38283828
// Relay to a limited number of other nodes
3829-
RelayAddress(pfrom.GetId(), addr, fReachable);
3829+
RelayAddress(pfrom.GetId(), addr, reachable);
38303830
}
38313831
// Do not store addresses outside our network
3832-
if (fReachable)
3832+
if (reachable) {
38333833
vAddrOk.push_back(addr);
3834+
}
38343835
}
38353836
peer->m_addr_processed += num_proc;
38363837
peer->m_addr_rate_limited += num_rate_limit;

src/netbase.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ bool fNameLookup = DEFAULT_NAME_LOOKUP;
3232
std::chrono::milliseconds g_socks5_recv_timeout = 20s;
3333
static std::atomic<bool> interruptSocks5Recv(false);
3434

35+
ReachableNets g_reachable_nets;
36+
3537
std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_lookup)
3638
{
3739
addrinfo ai_hint{};

src/netbase.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <stdint.h>
2020
#include <string>
2121
#include <type_traits>
22+
#include <unordered_set>
2223
#include <vector>
2324

2425
extern int nConnectTimeout;
@@ -64,6 +65,61 @@ struct ProxyCredentials
6465
std::string password;
6566
};
6667

68+
/**
69+
* List of reachable networks. Everything is reachable by default.
70+
*/
71+
class ReachableNets {
72+
public:
73+
void Add(Network net) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
74+
{
75+
AssertLockNotHeld(m_mutex);
76+
LOCK(m_mutex);
77+
m_reachable.insert(net);
78+
}
79+
80+
void Remove(Network net) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
81+
{
82+
AssertLockNotHeld(m_mutex);
83+
LOCK(m_mutex);
84+
m_reachable.erase(net);
85+
}
86+
87+
void RemoveAll() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
88+
{
89+
AssertLockNotHeld(m_mutex);
90+
LOCK(m_mutex);
91+
m_reachable.clear();
92+
}
93+
94+
[[nodiscard]] bool Contains(Network net) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
95+
{
96+
AssertLockNotHeld(m_mutex);
97+
LOCK(m_mutex);
98+
return m_reachable.count(net) > 0;
99+
}
100+
101+
[[nodiscard]] bool Contains(const CNetAddr& addr) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
102+
{
103+
AssertLockNotHeld(m_mutex);
104+
return Contains(addr.GetNetwork());
105+
}
106+
107+
private:
108+
mutable Mutex m_mutex;
109+
110+
std::unordered_set<Network> m_reachable GUARDED_BY(m_mutex){
111+
NET_UNROUTABLE,
112+
NET_IPV4,
113+
NET_IPV6,
114+
NET_ONION,
115+
NET_I2P,
116+
NET_CJDNS,
117+
NET_INTERNAL
118+
};
119+
};
120+
121+
extern ReachableNets g_reachable_nets;
122+
67123
/**
68124
* Wrapper for getaddrinfo(3). Do not use directly: call Lookup/LookupHost/LookupNumeric/LookupSubNet.
69125
*/

src/rpc/net.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,8 @@ static UniValue GetNetworksInfo()
585585
UniValue obj(UniValue::VOBJ);
586586
GetProxy(network, proxy);
587587
obj.pushKV("name", GetNetworkName(network));
588-
obj.pushKV("limited", !IsReachable(network));
589-
obj.pushKV("reachable", IsReachable(network));
588+
obj.pushKV("limited", !g_reachable_nets.Contains(network));
589+
obj.pushKV("reachable", g_reachable_nets.Contains(network));
590590
obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringAddrPort() : std::string());
591591
obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials);
592592
networks.push_back(obj);

0 commit comments

Comments
 (0)