From 1745ee4e63401c2a8362407bc571a10474087879 Mon Sep 17 00:00:00 2001 From: DanS Date: Thu, 27 Aug 2026 19:08:36 -0500 Subject: [PATCH] net: fix -connect never dialing its targets (empty-addr IsValid gate) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConnectNode() rejected the connection on !addrConnect.IsValid() (and !IsReachable(addrConnect)) BEFORE the pszDest branch. But -connect (and -addnode host:port / "addnode onetry") reaches ConnectNode with an empty placeholder addrConnect and the real target in pszDest, resolved later by ConnectSocketByName(). An empty CAddress is invalid, so every -connect attempt returned NULL before a socket was ever opened — the peer logs "trying connection " then "ConnectNode FAILED" and never dials. (Introduced upstream with BIP155/addrv2; -connect went unused because normal operation connects via addrman with real, valid addresses.) Guard both early-return checks with `if (!pszDest)` so they apply only when dialing addrConnect directly. Connect-by-name now falls through to ConnectSocketByName() as intended. Direct-address connections (pszDest==NULL, the addrman path) are unchanged. Validated: two nodes on one host, B started with `-connect=` exclusively (no -addnode) now connects to A over TLS, syncs A's chain, and stays isolated (0 other peers) — previously B connected to nothing. Clean build, verifychain 4 0 = true. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/net.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 73e147c1a..2aab1dfcd 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -470,12 +470,20 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) { bool connected = false; std::unique_ptr sock; - if (!addrConnect.IsValid()) { - return NULL; - } + // When connecting by name (pszDest is set, e.g. -connect / -addnode host:port + // or "addnode onetry"), addrConnect is an empty placeholder — the real + // target is resolved from pszDest by ConnectSocketByName() below. Only validate + // addrConnect when we are dialing it directly (pszDest == NULL); otherwise + // IsValid()/IsReachable() on the empty address abort the connection before it is + // ever attempted, which silently breaks -connect. + if (!pszDest) { + if (!addrConnect.IsValid()) { + return NULL; + } - if (!IsReachable(addrConnect)) { - return NULL; + if (!IsReachable(addrConnect)) { + return NULL; + } } if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) {