Skip to content

Switch to async DNS resolution#854

Open
tnull wants to merge 2 commits intolightningdevkit:mainfrom
tnull:2026-03-switch-to-async-lookup
Open

Switch to async DNS resolution#854
tnull wants to merge 2 commits intolightningdevkit:mainfrom
tnull:2026-03-switch-to-async-lookup

Conversation

@tnull
Copy link
Copy Markdown
Collaborator

@tnull tnull commented Mar 30, 2026

Previously, we used std::net::ToSocketAddrs for DNS resolution. While this generally worked, we also used the blocking to_socket_addrs call in async contexts, blocking a runtime task during resolution. This isn't great, so here we switch to use tokio::net::lookup_host for async resolution.

tnull added 2 commits March 30, 2026 10:03
Extract the connection logic into `do_connect_peer_internal` and have
`do_connect_peer` act as a thin wrapper that always calls
`propagate_result_to_subscribers` with the result. This removes the
need to manually propagate at every error site, making the code less
error-prone.

Co-Authored-By: HAL 9000
Replace the synchronous, blocking `std::net::ToSocketAddrs::to_socket_addrs()`
calls with async `tokio::net::lookup_host` to avoid blocking the tokio
runtime during DNS resolution.

Additionally, instead of only using the first resolved address, we now
iterate over all resolved addresses and try connecting to each in
sequence until one succeeds. This improves connectivity for hostnames
that resolve to multiple addresses (e.g., dual-stack IPv4/IPv6).

Co-Authored-By: HAL 9000
@tnull tnull requested a review from tankyleo March 30, 2026 08:12
@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented Mar 30, 2026

👋 Thanks for assigning @tankyleo as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

proxy_addr,
Arc::clone(&self.keys_manager),
);
res = self.await_connection(connection_future, node_id, addr.clone()).await;
Copy link
Copy Markdown
Contributor

@tankyleo tankyleo Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If res.is_err() here, we don't know whether we failed to connect to the proxy, or we failed to connect to the peer. Do you think this is worth fixing on the tor_connect_outbound API ?

If we failed to connect to the peer, but nonetheless successfully connected to the proxy, we'd try connecting again using a new resolved address for the proxy, even though the previous one worked fine.

I can see how this is intended behavior, as we could make a successful connection to the peer upon trying again with a different proxy address.

Arc::clone(&self.keys_manager),
);
res = self.await_connection(connection_future, node_id, addr.clone()).await;
if res.is_ok() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the err case, do we want to add a trace / debug log here to give a small heads up "hey we failed here" ? If we eventually succeed on a subsequent iteration, the transient error would go unnoticed.

socket_addr,
);
res = self.await_connection(connection_future, node_id, addr.clone()).await;
if res.is_ok() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above, do we want to be more verbose in the logs here ? ie "hey this IP address failed, but eventually succeeded with this other IP address".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants