From 591001959a039eb8cd357ae3ede96959c734c4a3 Mon Sep 17 00:00:00 2001 From: hairetikos <19870044+hairetikos@users.noreply.github.com> Date: Mon, 23 Feb 2026 01:31:01 +0000 Subject: [PATCH] fix `onion=` outbound when `proxy=` is not specified MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit quirk: when zclassic was configured with `onion=127.0.0.1:9050` but WITHOUT also `proxy=127.0.0.1:9050`, it caused outbound onion V3 to silently fail, but inbound V3 was working. this was a bug/quirk inherited from earlier BTC/Zcash code technical cause: When a node uses -onion= without -proxy=, HaveNameProxy() returns false, causing ThreadOpenAddedConnections() to take the Lookup() branch — which silently drops .onion addnode peers since they can't be DNS-resolved. Added support for .onion addresses routing through the NET_ONION proxy even when `proxy=` is not specified along with `onion=` --- src/net.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index bc3d314c6e5..81246d88664 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1457,6 +1457,26 @@ void ThreadOpenAddedConnections() list > lservAddressesToAdd(0); BOOST_FOREACH(const std::string& strAddNode, lAddresses) { + // Detect .onion addresses — they cannot be DNS-resolved. + // Route them through the NET_ONION proxy (set by -onion=) if available, + // using the string-based ConnectSocketByName path. + { + std::string strHost; + int nPort = Params().GetDefaultPort(); + SplitHostPort(strAddNode, nPort, strHost); + if (strHost.size() > 6 && + strHost.substr(strHost.size() - 6) == ".onion") + { + proxyType onionProxy; + if (GetProxy(NET_ONION, onionProxy)) { + CSemaphoreGrant grant(*semOutbound); + OpenNetworkConnection(CAddress(), &grant, strAddNode.c_str()); + MilliSleep(500); + } + continue; + } + } + vector vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) {