net: fix -connect never dialing its targets (empty-addr IsValid gate)

ConnectNode() rejected the connection on !addrConnect.IsValid() (and
!IsReachable(addrConnect)) BEFORE the pszDest branch. But -connect (and
-addnode host:port / "addnode <host> 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 <host>" 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=<A>` 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) <noreply@anthropic.com>
This commit is contained in:
2026-08-27 19:08:36 -05:00
parent 11766ec61b
commit 1745ee4e63

View File

@@ -470,6 +470,13 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) {
bool connected = false; bool connected = false;
std::unique_ptr<Sock> sock; std::unique_ptr<Sock> sock;
// When connecting by name (pszDest is set, e.g. -connect / -addnode host:port
// or "addnode <host> 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()) { if (!addrConnect.IsValid()) {
return NULL; return NULL;
} }
@@ -477,6 +484,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) {
if (!IsReachable(addrConnect)) { if (!IsReachable(addrConnect)) {
return NULL; return NULL;
} }
}
if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) { if (addrConnect.GetNetwork() == NET_I2P && m_i2p_sam_session.get() != nullptr) {
i2p::Connection conn; i2p::Connection conn;