diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 6a051d8d386..f6d8209f072 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -123,7 +124,7 @@ public: virtual void mapPort(bool enable) = 0; //! Get proxy. - virtual bool getProxy(Network net, Proxy& proxy_info) = 0; + virtual std::optional getProxy(Network net) = 0; //! Get number of connections. virtual size_t getNodeCount(ConnectionDirection flags) = 0; diff --git a/src/net.cpp b/src/net.cpp index a47d132aa70..71befd292bd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -439,20 +439,15 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, // Connect std::unique_ptr sock; - Proxy proxy; CService addr_bind; assert(!addr_bind.IsValid()); std::unique_ptr i2p_transient_session; - for (auto& target_addr: connect_to) { + for (auto& target_addr : connect_to) { if (target_addr.IsValid()) { - bool use_proxy; - if (proxy_override.has_value()) { - use_proxy = true; - proxy = proxy_override.value(); - } else { - use_proxy = GetProxy(target_addr.GetNetwork(), proxy); - } + const std::optional use_proxy{ + proxy_override.has_value() ? proxy_override : GetProxy(target_addr.GetNetwork()), + }; bool proxyConnectionFailed = false; if (target_addr.IsI2P() && use_proxy) { @@ -469,7 +464,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, LOCK(m_unused_i2p_sessions_mutex); if (m_unused_i2p_sessions.empty()) { i2p_transient_session = - std::make_unique(proxy, m_interrupt_net); + std::make_unique(*use_proxy, m_interrupt_net); } else { i2p_transient_session.swap(m_unused_i2p_sessions.front()); m_unused_i2p_sessions.pop(); @@ -489,8 +484,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, addr_bind = conn.me; } } else if (use_proxy) { - LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", proxy.ToString(), target_addr.ToStringAddrPort()); - sock = ConnectThroughProxy(proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed); + LogDebug(BCLog::PROXY, "Using proxy: %s to connect to %s\n", use_proxy->ToString(), target_addr.ToStringAddrPort()); + sock = ConnectThroughProxy(*use_proxy, target_addr.ToStringAddr(), target_addr.GetPort(), proxyConnectionFailed); } else { // no proxy needed (none set for target network) sock = ConnectDirectly(target_addr, conn_type == ConnectionType::MANUAL); @@ -500,12 +495,14 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, // the proxy, mark this as an attempt. addrman.get().Attempt(target_addr, fCountFailure); } - } else if (pszDest && GetNameProxy(proxy)) { - std::string host; - uint16_t port{default_port}; - SplitHostPort(std::string(pszDest), port, host); - bool proxyConnectionFailed; - sock = ConnectThroughProxy(proxy, host, port, proxyConnectionFailed); + } else if (pszDest) { + if (const auto name_proxy = GetNameProxy()) { + std::string host; + uint16_t port{default_port}; + SplitHostPort(pszDest, port, host); + bool proxyConnectionFailed; + sock = ConnectThroughProxy(*name_proxy, host, port, proxyConnectionFailed); + } } // Check any other resolved address (if any) if we fail to connect if (!sock) { @@ -3120,9 +3117,10 @@ void CConnman::PrivateBroadcast::NumToOpenWait() const std::optional CConnman::PrivateBroadcast::ProxyForIPv4or6() const { - Proxy tor_proxy; - if (m_outbound_tor_ok_at_least_once.load() && GetProxy(NET_ONION, tor_proxy)) { - return tor_proxy; + if (m_outbound_tor_ok_at_least_once.load()) { + if (const auto tor_proxy = GetProxy(NET_ONION)) { + return tor_proxy; + } } return std::nullopt; } @@ -3479,10 +3477,11 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions) return false; } - Proxy i2p_sam; - if (GetProxy(NET_I2P, i2p_sam) && connOptions.m_i2p_accept_incoming) { - m_i2p_sam_session = std::make_unique(gArgs.GetDataDirNet() / "i2p_private_key", - i2p_sam, m_interrupt_net); + if (connOptions.m_i2p_accept_incoming) { + if (const auto i2p_sam = GetProxy(NET_I2P)) { + m_i2p_sam_session = std::make_unique(gArgs.GetDataDirNet() / "i2p_private_key", + *i2p_sam, m_interrupt_net); + } } // Randomize the order in which we may query seednode to potentially prevent connecting to the same one every restart (and signal that we have restarted) diff --git a/src/netbase.cpp b/src/netbase.cpp index c1c03c57259..5ac7d22af34 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -706,13 +706,14 @@ bool SetProxy(enum Network net, const Proxy &addrProxy) { return true; } -bool GetProxy(enum Network net, Proxy &proxyInfoOut) { +std::optional GetProxy(enum Network net) +{ assert(net >= 0 && net < NET_MAX); LOCK(g_proxyinfo_mutex); - if (!proxyInfo[net].IsValid()) - return false; - proxyInfoOut = proxyInfo[net]; - return true; + if (!proxyInfo[net].IsValid()) { + return std::nullopt; + } + return proxyInfo[net]; } bool SetNameProxy(const Proxy &addrProxy) { @@ -723,12 +724,13 @@ bool SetNameProxy(const Proxy &addrProxy) { return true; } -bool GetNameProxy(Proxy &nameProxyOut) { +std::optional GetNameProxy() +{ LOCK(g_proxyinfo_mutex); - if(!nameProxy.IsValid()) - return false; - nameProxyOut = nameProxy; - return true; + if (!nameProxy.IsValid()) { + return std::nullopt; + } + return nameProxy; } bool HaveNameProxy() { diff --git a/src/netbase.h b/src/netbase.h index 6e538a73c26..88cc69810b0 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -179,7 +180,7 @@ std::string GetNetworkName(enum Network net); /** Return a vector of publicly routable Network names; optionally append NET_UNROUTABLE. */ std::vector GetNetworkNames(bool append_unroutable = false); bool SetProxy(enum Network net, const Proxy &addrProxy); -bool GetProxy(enum Network net, Proxy &proxyInfoOut); +std::optional GetProxy(enum Network net); bool IsProxy(const CNetAddr &addr); /** * Set the name proxy to use for all connections to nodes specified by a @@ -199,7 +200,7 @@ bool IsProxy(const CNetAddr &addr); */ bool SetNameProxy(const Proxy &addrProxy); bool HaveNameProxy(); -bool GetNameProxy(Proxy &nameProxyOut); +std::optional GetNameProxy(); using DNSLookupFn = std::function(const std::string&, bool)>; extern DNSLookupFn g_dns_lookup; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 84fd5bb7947..a8d91bf6255 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -187,7 +187,7 @@ public: args().WriteSettingsFile(); } void mapPort(bool enable) override { StartMapPort(enable); } - bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); } + std::optional getProxy(Network net) override { return GetProxy(net); } size_t getNodeCount(ConnectionDirection flags) override { return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index cd7d9e32587..8c1598e702b 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -287,10 +287,11 @@ void ClientModel::unsubscribeFromCoreSignals() bool ClientModel::getProxyInfo(std::string& ip_port) const { - Proxy ipv4, ipv6; - if (m_node.getProxy((Network) 1, ipv4) && m_node.getProxy((Network) 2, ipv6)) { - ip_port = ipv4.proxy.ToStringAddrPort(); - return true; + const auto ipv4 = m_node.getProxy(NET_IPV4); + const auto ipv6 = m_node.getProxy(NET_IPV6); + if (ipv4 && ipv6) { + ip_port = ipv4->proxy.ToStringAddrPort(); + return true; } return false; } diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 12446206023..f68e5825bab 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -456,17 +456,14 @@ void OptionsDialog::updateDefaultProxyNets() proxyIpText = ui_proxy.ToStringAddrPort(); } - Proxy proxy; - bool has_proxy; + const auto proxy_ipv4 = model->node().getProxy(NET_IPV4); + ui->proxyReachIPv4->setChecked(proxy_ipv4 && proxy_ipv4->ToString() == proxyIpText); - has_proxy = model->node().getProxy(NET_IPV4, proxy); - ui->proxyReachIPv4->setChecked(has_proxy && proxy.ToString() == proxyIpText); + const auto proxy_ipv6 = model->node().getProxy(NET_IPV6); + ui->proxyReachIPv6->setChecked(proxy_ipv6 && proxy_ipv6->ToString() == proxyIpText); - has_proxy = model->node().getProxy(NET_IPV6, proxy); - ui->proxyReachIPv6->setChecked(has_proxy && proxy.ToString() == proxyIpText); - - has_proxy = model->node().getProxy(NET_ONION, proxy); - ui->proxyReachTor->setChecked(has_proxy && proxy.ToString() == proxyIpText); + const auto proxy_onion = model->node().getProxy(NET_ONION); + ui->proxyReachTor->setChecked(proxy_onion && proxy_onion->ToString() == proxyIpText); } ProxyAddressValidator::ProxyAddressValidator(QObject *parent) : diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index ea07c560cd6..03786351388 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -613,14 +613,17 @@ static UniValue GetNetworksInfo() for (int n = 0; n < NET_MAX; ++n) { enum Network network = static_cast(n); if (network == NET_UNROUTABLE || network == NET_INTERNAL) continue; - Proxy proxy; UniValue obj(UniValue::VOBJ); - GetProxy(network, proxy); obj.pushKV("name", GetNetworkName(network)); obj.pushKV("limited", !g_reachable_nets.Contains(network)); obj.pushKV("reachable", g_reachable_nets.Contains(network)); - obj.pushKV("proxy", proxy.IsValid() ? proxy.ToString() : std::string()); - obj.pushKV("proxy_randomize_credentials", proxy.m_tor_stream_isolation); + if (const auto proxy = GetProxy(network)) { + obj.pushKV("proxy", proxy->ToString()); + obj.pushKV("proxy_randomize_credentials", proxy->m_tor_stream_isolation); + } else { + obj.pushKV("proxy", std::string()); + obj.pushKV("proxy_randomize_credentials", false); + } networks.push_back(std::move(obj)); } return networks;