Repository navigation
net: dial a proxied DNS seed by name - #1100
Conversation
With --proxy the DNS seeds are queued as addr-fetch dials by host name. e56eb9d made prepare_outbound_session take DialTarget::net_addr() for every dial, and net_addr() expected a Domain to parse as an overlay NetAddr. A DNS name does not, so every seed dial panicked the task. A Domain that is not an overlay host now keeps the 0.0.0.0:port identity it had before that change, and the connect goes through Dialer::connect_domain, which hands overlay hosts to connect_net. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Summary
The patch does what it claims. DialTarget::net_addr() no longer expects every Domain to be an overlay address: a name that does not parse as onion, I2P, or a socket falls back to version_socket() (0.0.0.0:port), and prepare_outbound_session dials Domain targets with Dialer::connect_domain instead of connect_net on that placeholder. Overlay names still round-trip through connect_domain into connect_net (.onion / .b32.i2p, then the existing SOCKS or SAM path). DNS seeds are the only dial_domain caller, and they are queued only when --proxy is set, so this path sends SOCKS ATYP 0x03 and does not resolve locally. The new test’s mock matches Dialer::socks(proxy, false) (method 0x02 plus RFC 1929 user/pass), asserts ATYP domain before the session result, and would not go green on the old expect panic or on a connect that never reached the proxy.
A separate security pass checked the same delta. DialTarget::Domain is built only by from_net (onion or I2P, re-encoded from an already parsed NetAddr) and by dial_domain (compiled-in seeds under --proxy). SOCKS rejects an empty host or one longer than 255 bytes and length-prefixes the name before the port. The shared 0.0.0.0:port identity is not a discourage key (0.0.0.0/8 is skipped), is not an inbound-eviction or full-relay slot key, and unroutable-gossip filters drop it before the address book or addr relay. No correctness or security defect in the diff.
The fast clean exit while a fresh --proxy datadir is still waiting on addr-fetch is the limitation called out in the PR body. It is unchanged by this dial fix.
Issue counts by severity
- bugs: 0
- suggestions: 0
- nits: 0
Problem
With
--proxy, a fresh node queues each DNS seed as an addr-fetch dial by host name (queue_proxy_seed_addrfetch). Since e56eb9d,prepare_outbound_sessioncallsDialTarget::net_addr()for every dial, andnet_addr()expects aDomainto parse as an overlayNetAddr. A DNS name does not, so every seed dial panics its task:Seen on a mainnet host running
--proxy 127.0.0.1:9050 --tor-control … --listen-onion.Fix
DialTarget::net_addr(): aDomainthat is not an overlay host is the0.0.0.0:portversion_socketidentity, which is what the peer row had before e56eb9d.prepare_outbound_session: aDomainconnects throughDialer::connect_domain(SOCKS by name). That function already hands.onion/.b32.i2ptoconnect_net, so overlay dials are unchanged.Test
service::tests::proxied_dns_seed_dials_by_name_through_socksdrivesrun_outbound_session_with_abortwith aDomainaddr-fetch through a mock SOCKS5 proxy and asserts that the proxy gets an ATYP-domain CONNECT forseed.example:8333. It fails onmasterwith the panic above.Local:
cargo fmt --check,cargo clippy --workspace --all-targets -D warnings,cargo test --workspace,./scripts/ci-os-smoke.shall pass.cargo denyandast-grepare not installed on this host, so those are left toqc. A signet run through Tor--proxyno longer panics.Related: fresh
--proxybootstrapThis is one of five PRs that together let a fresh
--proxydatadir bootstrap. Each one stands alone againstmaster:getaddrreply, then disconnect--proxyseed answer before catch-upWith all five, fresh signet and mainnet datadirs bootstrap through Tor
--proxyand start IBD.🤖 Generated with Claude Code