merge bitcoin#22834: respect -onlynet= when making outbound connections

This commit is contained in:
Kittywhiskers Van Gogh 2021-08-30 14:33:29 +02:00
parent f9d1a9a00d
commit d52724d039
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
14 changed files with 74 additions and 52 deletions

View File

@ -60,11 +60,7 @@ logging` for more information.
Make outgoing connections only to I2P addresses. Incoming connections are not Make outgoing connections only to I2P addresses. Incoming connections are not
affected by this option. It can be specified multiple times to allow multiple affected by this option. It can be specified multiple times to allow multiple
network types, e.g. onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p. network types, e.g. onlynet=onion, onlynet=i2p.
Warning: if you use -onlynet with values other than onion, and the -onion or
-proxy option is set, then outgoing onion connections will still be made; use
-noonion or -onion=0 to disable outbound onion connections in this case.
I2P support was added to Dash Core in version 20.0 and there may be fewer I2P I2P support was added to Dash Core in version 20.0 and there may be fewer I2P
peers than Tor or IP ones. Therefore, using I2P alone without other networks may peers than Tor or IP ones. Therefore, using I2P alone without other networks may

View File

@ -0,0 +1,8 @@
Updated settings
----------------
- If `-proxy=` is given together with `-noonion` then the provided proxy will
not be set as a proxy for reaching the Tor network. So it will not be
possible to open manual connections to the Tor network for example with the
`addnode` RPC. To mimic the old behavior use `-proxy=` together with
`-onlynet=` listing all relevant networks except `onion`.

View File

@ -51,11 +51,7 @@ outgoing connections, but more is possible.
-onlynet=onion Make outgoing connections only to .onion addresses. Incoming -onlynet=onion Make outgoing connections only to .onion addresses. Incoming
connections are not affected by this option. This option can be connections are not affected by this option. This option can be
specified multiple times to allow multiple network types, e.g. specified multiple times to allow multiple network types, e.g.
onlynet=ipv4, onlynet=ipv6, onlynet=onion, onlynet=i2p. onlynet=onion, onlynet=i2p.
Warning: if you use -onlynet with values other than onion, and
the -onion or -proxy option is set, then outgoing onion
connections will still be made; use -noonion or -onion=0 to
disable outbound onion connections in this case.
An example how to start the client if the Tor proxy is running on local host on An example how to start the client if the Tor proxy is running on local host on
port 9050 and only allows .onion nodes to connect: port 9050 and only allows .onion nodes to connect:

View File

@ -584,7 +584,7 @@ void SetupServerArgs(NodeContext& node)
argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-i2psam=<ip:port>", "I2P SAM proxy to reach I2P peers and accept I2P connections (default: none)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-i2psam=<ip:port>", "I2P SAM proxy to reach I2P peers and accept I2P connections (default: none)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-i2pacceptincoming", strprintf("Whether to accept inbound I2P connections (default: %i). Ignored if -i2psam is not set. Listening for inbound I2P connections is done through the SAM proxy, not by binding to a local address and port.", DEFAULT_I2P_ACCEPT_INCOMING), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-i2pacceptincoming", strprintf("Whether to accept inbound I2P connections (default: %i). Ignored if -i2psam is not set. Listening for inbound I2P connections is done through the SAM proxy, not by binding to a local address and port.", DEFAULT_I2P_ACCEPT_INCOMING), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-onlynet=<net>", "Make outgoing connections only through network <net> (" + Join(GetNetworkNames(), ", ") + "). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks. Warning: if it is used with non-onion networks and the -onion or -proxy option is set, then outbound onion connections will still be made; use -noonion or -onion=0 to disable outbound onion connections in this case.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-onlynet=<net>", "Make automatic outgoing connections only through network <net> (" + Join(GetNetworkNames(), ", ") + "). Incoming connections are not affected by this option. This option can be specified multiple times to allow multiple networks.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerblockfilters", strprintf("Serve compact block filters to peers per BIP 157 (default: %u)", DEFAULT_PEERBLOCKFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peerbloomfilters", strprintf("Support filtering of blocks and transaction with bloom filters (default: %u)", DEFAULT_PEERBLOOMFILTERS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-peertimeout=<n>", strprintf("Specify a p2p connection timeout delay in seconds. After connecting to a peer, wait this amount of time before considering disconnection based on inactivity (minimum: 1, default: %d)", DEFAULT_PEER_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); argsman.AddArg("-peertimeout=<n>", strprintf("Specify a p2p connection timeout delay in seconds. After connecting to a peer, wait this amount of time before considering disconnection based on inactivity (minimum: 1, default: %d)", DEFAULT_PEER_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
@ -1797,27 +1797,27 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
// Check for host lookup allowed before parsing any network related parameters // Check for host lookup allowed before parsing any network related parameters
fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
Proxy onion_proxy;
bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
// -proxy sets a proxy for all outgoing network traffic // -proxy sets a proxy for all outgoing network traffic
// -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default
std::string proxyArg = args.GetArg("-proxy", ""); std::string proxyArg = args.GetArg("-proxy", "");
SetReachable(NET_ONION, false);
if (proxyArg != "" && proxyArg != "0") { if (proxyArg != "" && proxyArg != "0") {
CService proxyAddr; CService proxyAddr;
if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) { if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg)); return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg));
} }
proxyType addrProxy = proxyType(proxyAddr, proxyRandomize); Proxy addrProxy = Proxy(proxyAddr, proxyRandomize);
if (!addrProxy.IsValid()) if (!addrProxy.IsValid())
return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg)); return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg));
SetProxy(NET_IPV4, addrProxy); SetProxy(NET_IPV4, addrProxy);
SetProxy(NET_IPV6, addrProxy); SetProxy(NET_IPV6, addrProxy);
SetProxy(NET_ONION, addrProxy);
SetProxy(NET_CJDNS, addrProxy); SetProxy(NET_CJDNS, addrProxy);
SetNameProxy(addrProxy); SetNameProxy(addrProxy);
SetReachable(NET_ONION, true); // by default, -proxy sets onion as reachable, unless -noonion later onion_proxy = addrProxy;
} }
// -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
@ -1826,20 +1826,28 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
std::string onionArg = args.GetArg("-onion", ""); std::string onionArg = args.GetArg("-onion", "");
if (onionArg != "") { if (onionArg != "") {
if (onionArg == "0") { // Handle -noonion/-onion=0 if (onionArg == "0") { // Handle -noonion/-onion=0
SetReachable(NET_ONION, false); onion_proxy = Proxy{};
} else { } else {
CService onionProxy; CService addr;
if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) { if (!Lookup(onionArg, addr, 9050, fNameLookup) || !addr.IsValid()) {
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg)); return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
} }
proxyType addrOnion = proxyType(onionProxy, proxyRandomize); onion_proxy = Proxy{addr, proxyRandomize};
if (!addrOnion.IsValid())
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
SetProxy(NET_ONION, addrOnion);
SetReachable(NET_ONION, true);
} }
} }
if (onion_proxy.IsValid()) {
SetProxy(NET_ONION, onion_proxy);
} else {
if (args.IsArgSet("-onlynet") && IsReachable(NET_ONION)) {
return InitError(
_("Outbound connections restricted to Tor (-onlynet=onion) but the proxy for "
"reaching the Tor network is not provided (no -proxy= and no -onion= given) or "
"it is explicitly forbidden (-onion=0)"));
}
SetReachable(NET_ONION, false);
}
for (const std::string& strAddr : args.GetArgs("-externalip")) { for (const std::string& strAddr : args.GetArgs("-externalip")) {
CService addrLocal; CService addrLocal;
if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
@ -2539,8 +2547,7 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
if (!Lookup(i2psam_arg, addr, 7656, fNameLookup) || !addr.IsValid()) { if (!Lookup(i2psam_arg, addr, 7656, fNameLookup) || !addr.IsValid()) {
return InitError(strprintf(_("Invalid -i2psam address or hostname: '%s'"), i2psam_arg)); return InitError(strprintf(_("Invalid -i2psam address or hostname: '%s'"), i2psam_arg));
} }
SetReachable(NET_I2P, true); SetProxy(NET_I2P, Proxy{addr});
SetProxy(NET_I2P, proxyType{addr});
} else { } else {
SetReachable(NET_I2P, false); SetReachable(NET_I2P, false);
} }

View File

@ -32,7 +32,7 @@ class CNodeStats;
class Coin; class Coin;
class RPCTimerInterface; class RPCTimerInterface;
class UniValue; class UniValue;
class proxyType; class Proxy;
struct bilingual_str; struct bilingual_str;
enum class SynchronizationState; enum class SynchronizationState;
struct CNodeStateStats; struct CNodeStateStats;
@ -174,7 +174,7 @@ public:
virtual void mapPort(bool use_upnp, bool use_natpmp) = 0; virtual void mapPort(bool use_upnp, bool use_natpmp) = 0;
//! Get proxy. //! Get proxy.
virtual bool getProxy(Network net, proxyType& proxy_info) = 0; virtual bool getProxy(Network net, Proxy& proxy_info) = 0;
//! Get number of connections. //! Get number of connections.
virtual size_t getNodeCount(ConnectionDirection flags) = 0; virtual size_t getNodeCount(ConnectionDirection flags) = 0;

View File

@ -492,7 +492,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
// Connect // Connect
bool connected = false; bool connected = false;
std::unique_ptr<Sock> sock; std::unique_ptr<Sock> sock;
proxyType proxy; Proxy proxy;
CAddress addr_bind; CAddress addr_bind;
assert(!addr_bind.IsValid()); assert(!addr_bind.IsValid());
std::unique_ptr<i2p::sam::Session> i2p_transient_session; std::unique_ptr<i2p::sam::Session> i2p_transient_session;
@ -3397,7 +3397,7 @@ bool CConnman::Start(CDeterministicMNManager& dmnman, CMasternodeMetaMan& mn_met
return false; return false;
} }
proxyType i2p_sam; Proxy i2p_sam;
if (GetProxy(NET_I2P, i2p_sam) && connOptions.m_i2p_accept_incoming) { if (GetProxy(NET_I2P, i2p_sam) && connOptions.m_i2p_accept_incoming) {
m_i2p_sam_session = std::make_unique<i2p::sam::Session>(GetDataDir() / "i2p_private_key", m_i2p_sam_session = std::make_unique<i2p::sam::Session>(GetDataDir() / "i2p_private_key",
i2p_sam.proxy, &interruptNet); i2p_sam.proxy, &interruptNet);

View File

@ -30,8 +30,8 @@
// Settings // Settings
static Mutex g_proxyinfo_mutex; static Mutex g_proxyinfo_mutex;
static proxyType proxyInfo[NET_MAX] GUARDED_BY(g_proxyinfo_mutex); static Proxy proxyInfo[NET_MAX] GUARDED_BY(g_proxyinfo_mutex);
static proxyType nameProxy GUARDED_BY(g_proxyinfo_mutex); static Proxy nameProxy GUARDED_BY(g_proxyinfo_mutex);
int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
bool fNameLookup = DEFAULT_NAME_LOOKUP; bool fNameLookup = DEFAULT_NAME_LOOKUP;
@ -604,7 +604,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nT
return true; return true;
} }
bool SetProxy(enum Network net, const proxyType &addrProxy) { bool SetProxy(enum Network net, const Proxy &addrProxy) {
assert(net >= 0 && net < NET_MAX); assert(net >= 0 && net < NET_MAX);
if (!addrProxy.IsValid()) if (!addrProxy.IsValid())
return false; return false;
@ -613,7 +613,7 @@ bool SetProxy(enum Network net, const proxyType &addrProxy) {
return true; return true;
} }
bool GetProxy(enum Network net, proxyType &proxyInfoOut) { bool GetProxy(enum Network net, Proxy &proxyInfoOut) {
assert(net >= 0 && net < NET_MAX); assert(net >= 0 && net < NET_MAX);
LOCK(g_proxyinfo_mutex); LOCK(g_proxyinfo_mutex);
if (!proxyInfo[net].IsValid()) if (!proxyInfo[net].IsValid())
@ -622,7 +622,7 @@ bool GetProxy(enum Network net, proxyType &proxyInfoOut) {
return true; return true;
} }
bool SetNameProxy(const proxyType &addrProxy) { bool SetNameProxy(const Proxy &addrProxy) {
if (!addrProxy.IsValid()) if (!addrProxy.IsValid())
return false; return false;
LOCK(g_proxyinfo_mutex); LOCK(g_proxyinfo_mutex);
@ -630,7 +630,7 @@ bool SetNameProxy(const proxyType &addrProxy) {
return true; return true;
} }
bool GetNameProxy(proxyType &nameProxyOut) { bool GetNameProxy(Proxy &nameProxyOut) {
LOCK(g_proxyinfo_mutex); LOCK(g_proxyinfo_mutex);
if(!nameProxy.IsValid()) if(!nameProxy.IsValid())
return false; return false;
@ -652,7 +652,7 @@ bool IsProxy(const CNetAddr &addr) {
return false; return false;
} }
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed) bool ConnectThroughProxy(const Proxy& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed)
{ {
// first connect to proxy server // first connect to proxy server
if (!ConnectSocketDirectly(proxy.proxy, sock, nTimeout, true)) { if (!ConnectSocketDirectly(proxy.proxy, sock, nTimeout, true)) {

View File

@ -49,11 +49,11 @@ static inline bool operator&(ConnectionDirection a, ConnectionDirection b) {
return (underlying(a) & underlying(b)); return (underlying(a) & underlying(b));
} }
class proxyType class Proxy
{ {
public: public:
proxyType(): randomize_credentials(false) {} Proxy(): randomize_credentials(false) {}
explicit proxyType(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {} explicit Proxy(const CService &_proxy, bool _randomize_credentials=false): proxy(_proxy), randomize_credentials(_randomize_credentials) {}
bool IsValid() const { return proxy.IsValid(); } bool IsValid() const { return proxy.IsValid(); }
@ -77,8 +77,8 @@ enum Network ParseNetwork(const std::string& net);
std::string GetNetworkName(enum Network net); std::string GetNetworkName(enum Network net);
/** Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE. */ /** Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE. */
std::vector<std::string> GetNetworkNames(bool append_unroutable = false); std::vector<std::string> GetNetworkNames(bool append_unroutable = false);
bool SetProxy(enum Network net, const proxyType &addrProxy); bool SetProxy(enum Network net, const Proxy &addrProxy);
bool GetProxy(enum Network net, proxyType &proxyInfoOut); bool GetProxy(enum Network net, Proxy &proxyInfoOut);
bool IsProxy(const CNetAddr &addr); bool IsProxy(const CNetAddr &addr);
/** /**
* Set the name proxy to use for all connections to nodes specified by a * Set the name proxy to use for all connections to nodes specified by a
@ -96,9 +96,9 @@ bool IsProxy(const CNetAddr &addr);
* server in common use (most notably Tor) actually implements UDP * server in common use (most notably Tor) actually implements UDP
* support, and a DNS resolver is beyond the scope of this project. * support, and a DNS resolver is beyond the scope of this project.
*/ */
bool SetNameProxy(const proxyType &addrProxy); bool SetNameProxy(const Proxy &addrProxy);
bool HaveNameProxy(); bool HaveNameProxy();
bool GetNameProxy(proxyType &nameProxyOut); bool GetNameProxy(Proxy &nameProxyOut);
using DNSLookupFn = std::function<std::vector<CNetAddr>(const std::string&, bool)>; using DNSLookupFn = std::function<std::vector<CNetAddr>(const std::string&, bool)>;
extern DNSLookupFn g_dns_lookup; extern DNSLookupFn g_dns_lookup;
@ -223,7 +223,7 @@ bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nT
* *
* @returns Whether or not the operation succeeded. * @returns Whether or not the operation succeeded.
*/ */
bool ConnectThroughProxy(const proxyType& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed); bool ConnectThroughProxy(const Proxy& proxy, const std::string& strDest, uint16_t port, const Sock& sock, int nTimeout, bool& outProxyConnectionFailed);
/** Enable non-blocking mode for a socket */ /** Enable non-blocking mode for a socket */
bool SetSocketNonBlocking(const SOCKET& hSocket); bool SetSocketNonBlocking(const SOCKET& hSocket);

View File

@ -341,7 +341,7 @@ public:
} }
bool shutdownRequested() override { return ShutdownRequested(); } bool shutdownRequested() override { return ShutdownRequested(); }
void mapPort(bool use_upnp, bool use_natpmp) override { StartMapPort(use_upnp, use_natpmp); } void mapPort(bool use_upnp, bool use_natpmp) override { StartMapPort(use_upnp, use_natpmp); }
bool getProxy(Network net, proxyType& proxy_info) override { return GetProxy(net, proxy_info); } bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); }
size_t getNodeCount(ConnectionDirection flags) override size_t getNodeCount(ConnectionDirection flags) override
{ {
return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0; return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;

View File

@ -381,7 +381,7 @@ void ClientModel::unsubscribeFromCoreSignals()
bool ClientModel::getProxyInfo(std::string& ip_port) const bool ClientModel::getProxyInfo(std::string& ip_port) const
{ {
proxyType ipv4, ipv6; Proxy ipv4, ipv6;
if (m_node.getProxy((Network) 1, ipv4) && m_node.getProxy((Network) 2, ipv6)) { if (m_node.getProxy((Network) 1, ipv4) && m_node.getProxy((Network) 2, ipv6)) {
ip_port = ipv4.proxy.ToStringIPPort(); ip_port = ipv4.proxy.ToStringIPPort();
return true; return true;

View File

@ -485,7 +485,7 @@ void OptionsDialog::updateProxyValidationState()
void OptionsDialog::updateDefaultProxyNets() void OptionsDialog::updateDefaultProxyNets()
{ {
proxyType proxy; Proxy proxy;
std::string strProxy; std::string strProxy;
QString strDefaultProxyGUI; QString strDefaultProxyGUI;
@ -567,7 +567,7 @@ QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) cons
Q_UNUSED(pos); Q_UNUSED(pos);
// Validate the proxy // Validate the proxy
CService serv(LookupNumeric(input.toStdString(), DEFAULT_GUI_PROXY_PORT)); CService serv(LookupNumeric(input.toStdString(), DEFAULT_GUI_PROXY_PORT));
proxyType addrProxy = proxyType(serv, true); Proxy addrProxy = Proxy(serv, true);
if (addrProxy.IsValid()) if (addrProxy.IsValid())
return QValidator::Acceptable; return QValidator::Acceptable;

View File

@ -586,7 +586,7 @@ static UniValue GetNetworksInfo()
for (int n = 0; n < NET_MAX; ++n) { for (int n = 0; n < NET_MAX; ++n) {
enum Network network = static_cast<enum Network>(n); enum Network network = static_cast<enum Network>(n);
if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue; if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue;
proxyType proxy; Proxy proxy;
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
GetProxy(network, proxy); GetProxy(network, proxy);
obj.pushKV("name", GetNetworkName(network)); obj.pushKV("name", GetNetworkName(network));

View File

@ -374,9 +374,24 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
// if -onion isn't set to something else. // if -onion isn't set to something else.
if (gArgs.GetArg("-onion", "") == "") { if (gArgs.GetArg("-onion", "") == "") {
CService resolved(LookupNumeric("127.0.0.1", 9050)); CService resolved(LookupNumeric("127.0.0.1", 9050));
proxyType addrOnion = proxyType(resolved, true); Proxy addrOnion = Proxy(resolved, true);
SetProxy(NET_ONION, addrOnion); SetProxy(NET_ONION, addrOnion);
SetReachable(NET_ONION, true);
const auto onlynets = gArgs.GetArgs("-onlynet");
const bool onion_allowed_by_onlynet{
!gArgs.IsArgSet("-onlynet") ||
std::any_of(onlynets.begin(), onlynets.end(), [](const auto& n) {
return ParseNetwork(n) == NET_ONION;
})};
if (onion_allowed_by_onlynet) {
// If NET_ONION is reachable, then the below is a noop.
//
// If NET_ONION is not reachable, then none of -proxy or -onion was given.
// Since we are here, then -torcontrol and -torpassword were given.
SetReachable(NET_ONION, true);
}
} }
// Finally - now create the service // Finally - now create the service

View File

@ -280,7 +280,7 @@ class ProxyTest(BitcoinTestFramework):
n3 = networks_dict(self.nodes[3].getnetworkinfo()) n3 = networks_dict(self.nodes[3].getnetworkinfo())
assert_equal(NETWORKS, n3.keys()) assert_equal(NETWORKS, n3.keys())
for net in NETWORKS: for net in NETWORKS:
if net == NET_I2P: if net == NET_I2P or net == NET_ONION:
expected_proxy = '' expected_proxy = ''
else: else:
expected_proxy = f'[{self.conf3.addr[0]}]:{self.conf3.addr[1]}' expected_proxy = f'[{self.conf3.addr[0]}]:{self.conf3.addr[1]}'