-
Notifications
You must be signed in to change notification settings - Fork 13.8k
std: make address resolution weirdness local to SGX #145327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
} | ||
} | ||
|
||
mod connection; |
There was a problem hiding this comment.
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.
This comment has been minimized.
This comment has been minimized.
936d414
to
842d4de
Compare
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 |
☔ The latest upstream changes (presumably #145489) made this pull request unmergeable. Please resolve the merge conflicts. |
Could you please ping all target maintainers? @raoulstrackx @aditijannu |
The SGX part looks good to me! |
842d4de
to
641242c
Compare
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. |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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?
641242c
to
207a01e
Compare
// FIXME: This is a terrible, terrible hack. Fixing this requires Fortanix to | ||
// add a method for resolving addresses. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this 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)
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
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`
Currently, the implementations of
TcpStream::connect
and its cousins take anio::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.
work, the DNS lookup returns a special error (
NonIpSockAddr
) instead, which contains the hostname being looked up. When.to_socket_addrs()
fails, theeach_addr
function used to select an address will pass the error to the innerTcpStream::connect
implementation, which in SGX's case will inspect the error and try recover the hostname from it. Ifthat 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 ownToSocketAddrs
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 theToSocketAddrs
type directly and calleach_addr
(which is moved tosys::net::connection
) themselves. On SGX, the implementation uses a specialeach_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