Skip to content

Conversation

joboet
Copy link
Member

@joboet joboet commented Aug 12, 2025

Currently, the implementations of TcpStream::connect and its cousins take an io::Result<&SocketAddr> as argument, which is very weird, as most of them then ?-try the result immediately to access the actual address. This weirdness is however necessitated by a peculiarity of the SGX networking implementation:

SGX doesn't support DNS resolution but rather accepts hostnames in the same place as socket addresses. So, to make e.g.

TcpStream::connect("example.com:80")`

work, the DNS lookup returns a special error (NonIpSockAddr) instead, which contains the hostname being looked up. When .to_socket_addrs() fails, the each_addr function used to select an address will pass the error to the inner TcpStream::connect implementation, which in SGX's case will inspect the error and try recover the hostname from it. If
that succeeds, it continues with the found hostname.

This is pretty obviously a terrible hack and leads to buggy code (for instance, when users use the result of .to_socket_addrs() in their own ToSocketAddrs implementation to select from a list of possible URLs, the only URL used will be that of the last item tried). Still, without changes to the SGX usercall ABI, it cannot be avoided.

Therefore, this PR aims to minimise the impact of that weirdness and remove it from all non-SGX platforms. The inner TcpStream::connect, et al. functions now receive the ToSocketAddrs type directly and call each_addr (which is moved to sys::net::connection) themselves. On SGX, the implementation uses a special each_addr which contains the whole pass-hostname-through-error hack.

As well as making the code cleaner, this also opens up the possibility of reusing newly created sockets even if a connection request fails – but I've left that for another PR.

CC @raoulstrackx

@rustbot
Copy link
Collaborator

rustbot commented Aug 12, 2025

r? @tgross35

rustbot has assigned @tgross35.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 12, 2025
}
}

mod connection;
Copy link
Member Author

Choose a reason for hiding this comment

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

If you were wondering why this is its own module, it's to facilitate #135141, which has a different platform distribution.

@rust-log-analyzer

This comment has been minimized.

@joboet joboet force-pushed the net-addr-sgx-hack branch from 936d414 to 842d4de Compare August 13, 2025 11:57
@tgross35
Copy link
Contributor

I've just started taking a look here, but cc @jethrogb in case there is anything you'd like to review from the SGX side

@bors
Copy link
Collaborator

bors commented Aug 19, 2025

☔ The latest upstream changes (presumably #145489) made this pull request unmergeable. Please resolve the merge conflicts.

@jethrogb
Copy link
Contributor

Could you please ping all target maintainers? @raoulstrackx @aditijannu

@raoulstrackx
Copy link
Contributor

The SGX part looks good to me!

@joboet joboet force-pushed the net-addr-sgx-hack branch from 842d4de to 641242c Compare August 29, 2025 14:24
@rustbot
Copy link
Collaborator

rustbot commented Aug 29, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've moved the whole platform-matching into this new file so there's a place to put each_addr.

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a doc comment here and/or net/mod.rs about what is intended to be in each module?

Copy link
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

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

This looks awesome! Few small requests then r=me

@rustbot author

View changes since this review

Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a doc comment here and/or net/mod.rs about what is intended to be in each module?

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 5, 2025
Comment on lines +83 to +84
// FIXME: This is a terrible, terrible hack. Fixing this requires Fortanix to
// add a method for resolving addresses.
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I agree with this statement. Address resolution is unlikely to be added to the platform as it belongs outside the enclave from a security architecture perspective.

Copy link
Member Author

Choose a reason for hiding this comment

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

I stand by the "terrible hack" part – don't get me wrong, it's clever, but it introduces bugs. Unfortunately for SGX, the whole networking interface of std is built around the notion that DNS resolution is separated from socket connection. I very much think that that this is well-justified, after all, it is sometimes useful to know which IP address a connection will be made to (even though an enclave obviously cannot rely on this information). Could you explain why is it unreasonable for an enclave runner to forward DNS requests from the enclave to the OS?

Copy link
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

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

Thanks for the updates, LGTM. (Assume you want to wait if Jethro has a more accurate comment)

View changes since this review

@joboet
Copy link
Member Author

joboet commented Sep 10, 2025

@bors r=@tgross35
Even if there are good reasons for not supporting DNS lookup from the enclave, the comment would be inaccurate – DNS lookup is required for removing the hack.

@bors
Copy link
Collaborator

bors commented Sep 10, 2025

📌 Commit 207a01e has been approved by tgross35

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 10, 2025
bors added a commit that referenced this pull request Sep 10, 2025
Rollup of 8 pull requests

Successful merges:

 - #145327 (std: make address resolution weirdness local to SGX)
 - #145879 (default auto traits: use default supertraits instead of `Self: Trait` bounds on associated items)
 - #146123 (Suggest examples of format specifiers in error messages)
 - #146311 (Minor symbol comment fixes.)
 - #146322 (Make Barrier RefUnwindSafe again)
 - #146327 (Add tests for deref on pin)
 - #146340 (Strip frontmatter in fewer places)
 - #146342 (Improve C-variadic error messages: part 2)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit e79630d into rust-lang:master Sep 11, 2025
10 checks passed
@rustbot rustbot added this to the 1.91.0 milestone Sep 11, 2025
rust-timer added a commit that referenced this pull request Sep 11, 2025
Rollup merge of #145327 - joboet:net-addr-sgx-hack, r=tgross35

std: make address resolution weirdness local to SGX

Currently, the implementations of `TcpStream::connect` and its cousins take an `io::Result<&SocketAddr>` as argument, which is very weird, as most of them then `?`-try the result immediately to access the actual address. This weirdness is however necessitated by a peculiarity of the SGX networking implementation:

SGX doesn't support DNS resolution but rather accepts hostnames in the same place as socket addresses. So, to make e.g.
```rust
TcpStream::connect("example.com:80")`
```
work, the DNS lookup returns a special error (`NonIpSockAddr`) instead, which contains the hostname being looked up. When `.to_socket_addrs()` fails, the `each_addr` function used to select an address will pass the error to the inner `TcpStream::connect` implementation, which in SGX's case will inspect the error and try recover the hostname from it. If
that succeeds, it continues with the found hostname.

This is pretty obviously a terrible hack and leads to buggy code (for instance, when users use the result of `.to_socket_addrs()` in their own `ToSocketAddrs` implementation to select from a list of possible URLs, the only URL used will be that of the last item tried). Still, without changes to the SGX usercall ABI, it cannot be avoided.

Therefore, this PR aims to minimise the impact of that weirdness and remove it from all non-SGX platforms. The inner `TcpStream::connect`, et al. functions now receive the `ToSocketAddrs` type directly and call `each_addr` (which is moved to `sys::net::connection`) themselves. On SGX, the implementation uses a special `each_addr` which contains the whole pass-hostname-through-error hack.

As well as making the code cleaner, this also opens up the possibility of reusing newly created sockets even if a connection request fails – but I've left that for another PR.

CC `@raoulstrackx`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants