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.
This commit is contained in:
Vasil Dimov 2023-02-07 13:30:37 +01:00
parent c42ded3d9b
commit 6e308651c4
No known key found for this signature in database
GPG key ID: 54DF06F64B55CBBF
9 changed files with 129 additions and 97 deletions

View file

@ -1305,30 +1305,24 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} }
if (args.IsArgSet("-onlynet")) { if (args.IsArgSet("-onlynet")) {
std::set<enum Network> nets; g_reachable_nets.RemoveAll();
for (const std::string& snet : args.GetArgs("-onlynet")) { for (const std::string& snet : args.GetArgs("-onlynet")) {
enum Network net = ParseNetwork(snet); enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE) if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet)); return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
nets.insert(net); g_reachable_nets.Add(net);
}
for (int n = 0; n < NET_MAX; n++) {
enum Network net = (enum Network)n;
assert(IsReachable(net));
if (!nets.count(net))
SetReachable(net, false);
} }
} }
if (!args.IsArgSet("-cjdnsreachable")) { if (!args.IsArgSet("-cjdnsreachable")) {
if (args.IsArgSet("-onlynet") && IsReachable(NET_CJDNS)) { if (args.IsArgSet("-onlynet") && g_reachable_nets.Contains(NET_CJDNS)) {
return InitError( return InitError(
_("Outbound connections restricted to CJDNS (-onlynet=cjdns) but " _("Outbound connections restricted to CJDNS (-onlynet=cjdns) but "
"-cjdnsreachable is not provided")); "-cjdnsreachable is not provided"));
} }
SetReachable(NET_CJDNS, false); g_reachable_nets.Remove(NET_CJDNS);
} }
// Now IsReachable(NET_CJDNS) is true if: // Now g_reachable_nets.Contains(NET_CJDNS) is true if:
// 1. -cjdnsreachable is given and // 1. -cjdnsreachable is given and
// 2.1. -onlynet is not given or // 2.1. -onlynet is not given or
// 2.2. -onlynet=cjdns is given // 2.2. -onlynet=cjdns is given
@ -1336,7 +1330,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// Requesting DNS seeds entails connecting to IPv4/IPv6, which -onlynet options may prohibit: // Requesting DNS seeds entails connecting to IPv4/IPv6, which -onlynet options may prohibit:
// If -dnsseed=1 is explicitly specified, abort. If it's left unspecified by the user, we skip // If -dnsseed=1 is explicitly specified, abort. If it's left unspecified by the user, we skip
// the DNS seeds by adjusting -dnsseed in InitParameterInteraction. // the DNS seeds by adjusting -dnsseed in InitParameterInteraction.
if (args.GetBoolArg("-dnsseed") == true && !IsReachable(NET_IPV4) && !IsReachable(NET_IPV6)) { if (args.GetBoolArg("-dnsseed") == true && !g_reachable_nets.Contains(NET_IPV4) && !g_reachable_nets.Contains(NET_IPV6)) {
return InitError(strprintf(_("Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6"))); return InitError(strprintf(_("Incompatible options: -dnsseed=1 was explicitly specified, but -onlynet forbids connections to IPv4/IPv6")));
}; };
@ -1366,7 +1360,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
onion_proxy = addrProxy; onion_proxy = addrProxy;
} }
const bool onlynet_used_with_onion{args.IsArgSet("-onlynet") && IsReachable(NET_ONION)}; const bool onlynet_used_with_onion{args.IsArgSet("-onlynet") && g_reachable_nets.Contains(NET_ONION)};
// -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses
// -noonion (or -onion=0) disables connecting to .onion entirely // -noonion (or -onion=0) disables connecting to .onion entirely
@ -1401,7 +1395,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
"reaching the Tor network is not provided: none of -proxy, -onion or " "reaching the Tor network is not provided: none of -proxy, -onion or "
"-listenonion is given")); "-listenonion is given"));
} }
SetReachable(NET_ONION, false); g_reachable_nets.Remove(NET_ONION);
} }
for (const std::string& strAddr : args.GetArgs("-externalip")) { for (const std::string& strAddr : args.GetArgs("-externalip")) {
@ -1876,12 +1870,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} }
SetProxy(NET_I2P, Proxy{addr.value()}); SetProxy(NET_I2P, Proxy{addr.value()});
} else { } else {
if (args.IsArgSet("-onlynet") && IsReachable(NET_I2P)) { if (args.IsArgSet("-onlynet") && g_reachable_nets.Contains(NET_I2P)) {
return InitError( return InitError(
_("Outbound connections restricted to i2p (-onlynet=i2p) but " _("Outbound connections restricted to i2p (-onlynet=i2p) but "
"-i2psam is not provided")); "-i2psam is not provided"));
} }
SetReachable(NET_I2P, false); g_reachable_nets.Remove(NET_I2P);
} }
connOptions.m_i2p_accept_incoming = args.GetBoolArg("-i2pacceptincoming", DEFAULT_I2P_ACCEPT_INCOMING); connOptions.m_i2p_accept_incoming = args.GetBoolArg("-i2pacceptincoming", DEFAULT_I2P_ACCEPT_INCOMING);

View file

@ -115,7 +115,6 @@ bool fDiscover = true;
bool fListen = true; bool fListen = true;
GlobalMutex g_maplocalhost_mutex; GlobalMutex g_maplocalhost_mutex;
std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(g_maplocalhost_mutex); std::map<CNetAddr, LocalServiceInfo> mapLocalHost GUARDED_BY(g_maplocalhost_mutex);
static bool vfLimited[NET_MAX] GUARDED_BY(g_maplocalhost_mutex) = {};
std::string strSubVersion; std::string strSubVersion;
size_t CSerializedNetMsg::GetMemoryUsage() const noexcept size_t CSerializedNetMsg::GetMemoryUsage() const noexcept
@ -232,7 +231,7 @@ static int GetnScore(const CService& addr)
{ {
CService addrLocal = pnode->GetAddrLocal(); CService addrLocal = pnode->GetAddrLocal();
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() && return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
IsReachable(addrLocal.GetNetwork()); g_reachable_nets.Contains(addrLocal);
} }
std::optional<CService> GetLocalAddrForPeer(CNode& node) std::optional<CService> GetLocalAddrForPeer(CNode& node)
@ -280,7 +279,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.IsIPv6() && ret.HasCJDNSPrefix() && IsReachable(NET_CJDNS)) { if (ret.IsIPv6() && ret.HasCJDNSPrefix() && g_reachable_nets.Contains(NET_CJDNS)) {
ret.m_net = NET_CJDNS; ret.m_net = NET_CJDNS;
} }
return ret; return ret;
@ -297,7 +296,7 @@ bool AddLocal(const CService& addr_, int nScore)
if (!fDiscover && nScore < LOCAL_MANUAL) if (!fDiscover && nScore < LOCAL_MANUAL)
return false; return false;
if (!IsReachable(addr)) if (!g_reachable_nets.Contains(addr))
return false; return false;
LogPrintf("AddLocal(%s,%i)\n", addr.ToStringAddrPort(), nScore); LogPrintf("AddLocal(%s,%i)\n", addr.ToStringAddrPort(), nScore);
@ -327,25 +326,6 @@ void RemoveLocal(const CService& addr)
mapLocalHost.erase(addr); mapLocalHost.erase(addr);
} }
void SetReachable(enum Network net, bool reachable)
{
if (net == NET_UNROUTABLE || net == NET_INTERNAL)
return;
LOCK(g_maplocalhost_mutex);
vfLimited[net] = !reachable;
}
bool IsReachable(enum Network net)
{
LOCK(g_maplocalhost_mutex);
return !vfLimited[net];
}
bool IsReachable(const CNetAddr &addr)
{
return IsReachable(addr.GetNetwork());
}
/** vote for a local address */ /** vote for a local address */
bool SeenLocal(const CService& addr) bool SeenLocal(const CService& addr)
{ {
@ -2433,7 +2413,7 @@ std::unordered_set<Network> CConnman::GetReachableEmptyNetworks() const
for (int n = 0; n < NET_MAX; n++) { for (int n = 0; n < NET_MAX; n++) {
enum Network net = (enum Network)n; enum Network net = (enum Network)n;
if (net == NET_UNROUTABLE || net == NET_INTERNAL) continue; if (net == NET_UNROUTABLE || net == NET_INTERNAL) continue;
if (IsReachable(net) && addrman.Size(net, std::nullopt) == 0) { if (g_reachable_nets.Contains(net) && addrman.Size(net, std::nullopt) == 0) {
networks.insert(net); networks.insert(net);
} }
} }
@ -2453,7 +2433,7 @@ bool CConnman::MaybePickPreferredNetwork(std::optional<Network>& network)
LOCK(m_nodes_mutex); LOCK(m_nodes_mutex);
for (const auto net : nets) { for (const auto net : nets) {
if (IsReachable(net) && m_network_conn_counts[net] == 0 && addrman.Size(net) != 0) { if (g_reachable_nets.Contains(net) && m_network_conn_counts[net] == 0 && addrman.Size(net) != 0) {
network = net; network = net;
return true; return true;
} }
@ -2683,7 +2663,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
if (anchor && !m_anchors.empty()) { if (anchor && !m_anchors.empty()) {
const CAddress addr = m_anchors.back(); const CAddress addr = m_anchors.back();
m_anchors.pop_back(); m_anchors.pop_back();
if (!addr.IsValid() || IsLocal(addr) || !IsReachable(addr) || if (!addr.IsValid() || IsLocal(addr) || !g_reachable_nets.Contains(addr) ||
!HasAllDesirableServiceFlags(addr.nServices) || !HasAllDesirableServiceFlags(addr.nServices) ||
outbound_ipv46_peer_netgroups.count(m_netgroupman.GetGroup(addr))) continue; outbound_ipv46_peer_netgroups.count(m_netgroupman.GetGroup(addr))) continue;
addrConnect = addr; addrConnect = addr;
@ -2738,8 +2718,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
break; break;
} }
if (!IsReachable(addr)) if (!g_reachable_nets.Contains(addr)) {
continue; continue;
}
// only consider very recently tried nodes after 30 failed attempts // only consider very recently tried nodes after 30 failed attempts
if (current_time - addr_last_try < 10min && nTries < 30) { if (current_time - addr_last_try < 10min && nTries < 30) {

View file

@ -160,16 +160,6 @@ enum
/** 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);
/**
* Mark a network as reachable or unreachable (no automatic connects to it)
* @note Networks are reachable by default
*/
void SetReachable(enum Network net, bool reachable);
/** @returns true if the network is reachable, false otherwise */
bool IsReachable(enum Network net);
/** @returns true if the address is in a reachable network, false otherwise */
bool IsReachable(const CNetAddr& addr);
bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
void RemoveLocal(const CService& addr); void RemoveLocal(const CService& addr);

View file

@ -3823,15 +3823,16 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
continue; continue;
} }
++num_proc; ++num_proc;
bool fReachable = IsReachable(addr); const bool reachable{g_reachable_nets.Contains(addr)};
if (addr.nTime > current_a_time - 10min && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) { if (addr.nTime > current_a_time - 10min && !peer->m_getaddr_sent && vAddr.size() <= 10 && addr.IsRoutable()) {
// Relay to a limited number of other nodes // Relay to a limited number of other nodes
RelayAddress(pfrom.GetId(), addr, fReachable); RelayAddress(pfrom.GetId(), addr, reachable);
} }
// Do not store addresses outside our network // Do not store addresses outside our network
if (fReachable) if (reachable) {
vAddrOk.push_back(addr); vAddrOk.push_back(addr);
} }
}
peer->m_addr_processed += num_proc; peer->m_addr_processed += num_proc;
peer->m_addr_rate_limited += num_rate_limit; peer->m_addr_rate_limited += num_rate_limit;
LogPrint(BCLog::NET, "Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n", LogPrint(BCLog::NET, "Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",

View file

@ -32,6 +32,8 @@ bool fNameLookup = DEFAULT_NAME_LOOKUP;
std::chrono::milliseconds g_socks5_recv_timeout = 20s; std::chrono::milliseconds g_socks5_recv_timeout = 20s;
static std::atomic<bool> interruptSocks5Recv(false); static std::atomic<bool> interruptSocks5Recv(false);
ReachableNets g_reachable_nets;
std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_lookup) std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_lookup)
{ {
addrinfo ai_hint{}; addrinfo ai_hint{};

View file

@ -19,6 +19,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <unordered_set>
#include <vector> #include <vector>
extern int nConnectTimeout; extern int nConnectTimeout;
@ -64,6 +65,61 @@ struct ProxyCredentials
std::string password; std::string password;
}; };
/**
* List of reachable networks. Everything is reachable by default.
*/
class ReachableNets {
public:
void Add(Network net) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
AssertLockNotHeld(m_mutex);
LOCK(m_mutex);
m_reachable.insert(net);
}
void Remove(Network net) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
AssertLockNotHeld(m_mutex);
LOCK(m_mutex);
m_reachable.erase(net);
}
void RemoveAll() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
AssertLockNotHeld(m_mutex);
LOCK(m_mutex);
m_reachable.clear();
}
[[nodiscard]] bool Contains(Network net) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
AssertLockNotHeld(m_mutex);
LOCK(m_mutex);
return m_reachable.count(net) > 0;
}
[[nodiscard]] bool Contains(const CNetAddr& addr) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
{
AssertLockNotHeld(m_mutex);
return Contains(addr.GetNetwork());
}
private:
mutable Mutex m_mutex;
std::unordered_set<Network> m_reachable GUARDED_BY(m_mutex){
NET_UNROUTABLE,
NET_IPV4,
NET_IPV6,
NET_ONION,
NET_I2P,
NET_CJDNS,
NET_INTERNAL
};
};
extern ReachableNets g_reachable_nets;
/** /**
* Wrapper for getaddrinfo(3). Do not use directly: call Lookup/LookupHost/LookupNumeric/LookupSubNet. * Wrapper for getaddrinfo(3). Do not use directly: call Lookup/LookupHost/LookupNumeric/LookupSubNet.
*/ */

View file

@ -585,8 +585,8 @@ static UniValue GetNetworksInfo()
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
GetProxy(network, proxy); GetProxy(network, proxy);
obj.pushKV("name", GetNetworkName(network)); obj.pushKV("name", GetNetworkName(network));
obj.pushKV("limited", !IsReachable(network)); obj.pushKV("limited", !g_reachable_nets.Contains(network));
obj.pushKV("reachable", IsReachable(network)); obj.pushKV("reachable", g_reachable_nets.Contains(network));
obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringAddrPort() : std::string()); obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringAddrPort() : std::string());
obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials); obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials);
networks.push_back(obj); networks.push_back(obj);

View file

@ -718,47 +718,55 @@ BOOST_AUTO_TEST_CASE(get_local_addr_for_peer_port)
BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network) BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
{ {
BOOST_CHECK(IsReachable(NET_IPV4)); BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));
BOOST_CHECK(IsReachable(NET_IPV6)); BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));
BOOST_CHECK(IsReachable(NET_ONION)); BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));
BOOST_CHECK(IsReachable(NET_I2P)); BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));
BOOST_CHECK(IsReachable(NET_CJDNS)); BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));
SetReachable(NET_IPV4, false); g_reachable_nets.Remove(NET_IPV4);
SetReachable(NET_IPV6, false); g_reachable_nets.Remove(NET_IPV6);
SetReachable(NET_ONION, false); g_reachable_nets.Remove(NET_ONION);
SetReachable(NET_I2P, false); g_reachable_nets.Remove(NET_I2P);
SetReachable(NET_CJDNS, false); g_reachable_nets.Remove(NET_CJDNS);
BOOST_CHECK(!IsReachable(NET_IPV4)); BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV4));
BOOST_CHECK(!IsReachable(NET_IPV6)); BOOST_CHECK(!g_reachable_nets.Contains(NET_IPV6));
BOOST_CHECK(!IsReachable(NET_ONION)); BOOST_CHECK(!g_reachable_nets.Contains(NET_ONION));
BOOST_CHECK(!IsReachable(NET_I2P)); BOOST_CHECK(!g_reachable_nets.Contains(NET_I2P));
BOOST_CHECK(!IsReachable(NET_CJDNS)); BOOST_CHECK(!g_reachable_nets.Contains(NET_CJDNS));
SetReachable(NET_IPV4, true); g_reachable_nets.Add(NET_IPV4);
SetReachable(NET_IPV6, true); g_reachable_nets.Add(NET_IPV6);
SetReachable(NET_ONION, true); g_reachable_nets.Add(NET_ONION);
SetReachable(NET_I2P, true); g_reachable_nets.Add(NET_I2P);
SetReachable(NET_CJDNS, true); g_reachable_nets.Add(NET_CJDNS);
BOOST_CHECK(IsReachable(NET_IPV4)); BOOST_CHECK(g_reachable_nets.Contains(NET_IPV4));
BOOST_CHECK(IsReachable(NET_IPV6)); BOOST_CHECK(g_reachable_nets.Contains(NET_IPV6));
BOOST_CHECK(IsReachable(NET_ONION)); BOOST_CHECK(g_reachable_nets.Contains(NET_ONION));
BOOST_CHECK(IsReachable(NET_I2P)); BOOST_CHECK(g_reachable_nets.Contains(NET_I2P));
BOOST_CHECK(IsReachable(NET_CJDNS)); BOOST_CHECK(g_reachable_nets.Contains(NET_CJDNS));
} }
BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal) BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
{ {
BOOST_CHECK(IsReachable(NET_UNROUTABLE)); // Should be reachable by default.
BOOST_CHECK(IsReachable(NET_INTERNAL)); BOOST_CHECK(g_reachable_nets.Contains(NET_UNROUTABLE));
BOOST_CHECK(g_reachable_nets.Contains(NET_INTERNAL));
SetReachable(NET_UNROUTABLE, false); g_reachable_nets.RemoveAll();
SetReachable(NET_INTERNAL, false);
BOOST_CHECK(IsReachable(NET_UNROUTABLE)); // Ignored for both networks BOOST_CHECK(!g_reachable_nets.Contains(NET_UNROUTABLE));
BOOST_CHECK(IsReachable(NET_INTERNAL)); BOOST_CHECK(!g_reachable_nets.Contains(NET_INTERNAL));
g_reachable_nets.Add(NET_IPV4);
g_reachable_nets.Add(NET_IPV6);
g_reachable_nets.Add(NET_ONION);
g_reachable_nets.Add(NET_I2P);
g_reachable_nets.Add(NET_CJDNS);
g_reachable_nets.Add(NET_UNROUTABLE);
g_reachable_nets.Add(NET_INTERNAL);
} }
CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
@ -776,13 +784,13 @@ BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
{ {
CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1 CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
SetReachable(NET_IPV4, true); g_reachable_nets.Add(NET_IPV4);
BOOST_CHECK(IsReachable(addr)); BOOST_CHECK(g_reachable_nets.Contains(addr));
SetReachable(NET_IPV4, false); g_reachable_nets.Remove(NET_IPV4);
BOOST_CHECK(!IsReachable(addr)); BOOST_CHECK(!g_reachable_nets.Contains(addr));
SetReachable(NET_IPV4, true); // have to reset this, because this is stateful. g_reachable_nets.Add(NET_IPV4); // have to reset this, because this is stateful.
} }
@ -790,7 +798,7 @@ BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
{ {
CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000 CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
SetReachable(NET_IPV4, true); g_reachable_nets.Add(NET_IPV4);
BOOST_CHECK(!IsLocal(addr)); BOOST_CHECK(!IsLocal(addr));
BOOST_CHECK(AddLocal(addr, 1000)); BOOST_CHECK(AddLocal(addr, 1000));
@ -915,7 +923,7 @@ BOOST_AUTO_TEST_CASE(advertise_local_address)
ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::OUTBOUND_FULL_RELAY,
/*inbound_onion=*/false); /*inbound_onion=*/false);
}; };
SetReachable(NET_CJDNS, true); g_reachable_nets.Add(NET_CJDNS);
CAddress addr_ipv4{Lookup("1.2.3.4", 8333, false).value(), NODE_NONE}; CAddress addr_ipv4{Lookup("1.2.3.4", 8333, false).value(), NODE_NONE};
BOOST_REQUIRE(addr_ipv4.IsValid()); BOOST_REQUIRE(addr_ipv4.IsValid());

View file

@ -409,7 +409,7 @@ void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlRe
// //
// If NET_ONION is not reachable, then none of -proxy or -onion was given. // If NET_ONION is not reachable, then none of -proxy or -onion was given.
// Since we are here, then -torcontrol and -torpassword were given. // Since we are here, then -torcontrol and -torpassword were given.
SetReachable(NET_ONION, true); g_reachable_nets.Add(NET_ONION);
} }
} }