Skip to content

Commit 936d414

Browse files
committed
std: make address resolution weirdness local to SGX
1 parent 5771665 commit 936d414

File tree

14 files changed

+273
-213
lines changed

14 files changed

+273
-213
lines changed

library/std/src/io/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ impl Error {
9595

9696
pub(crate) const ZERO_TIMEOUT: Self =
9797
const_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout");
98+
99+
pub(crate) const NO_ADDRESSES: Self =
100+
const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses");
98101
}
99102

100103
#[stable(feature = "rust1", since = "1.0.0")]

library/std/src/net/mod.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ pub use self::tcp::IntoIncoming;
3434
pub use self::tcp::{Incoming, TcpListener, TcpStream};
3535
#[stable(feature = "rust1", since = "1.0.0")]
3636
pub use self::udp::UdpSocket;
37-
use crate::io::{self, ErrorKind};
3837

3938
mod ip_addr;
4039
mod socket_addr;
@@ -67,23 +66,3 @@ pub enum Shutdown {
6766
#[stable(feature = "rust1", since = "1.0.0")]
6867
Both,
6968
}
70-
71-
fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
72-
where
73-
F: FnMut(io::Result<&SocketAddr>) -> io::Result<T>,
74-
{
75-
let addrs = match addr.to_socket_addrs() {
76-
Ok(addrs) => addrs,
77-
Err(e) => return f(Err(e)),
78-
};
79-
let mut last_err = None;
80-
for addr in addrs {
81-
match f(Ok(&addr)) {
82-
Ok(l) => return Ok(l),
83-
Err(e) => last_err = Some(e),
84-
}
85-
}
86-
Err(last_err.unwrap_or_else(|| {
87-
io::const_error!(ErrorKind::InvalidInput, "could not resolve to any addresses")
88-
}))
89-
}

library/std/src/net/tcp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl TcpStream {
167167
/// ```
168168
#[stable(feature = "rust1", since = "1.0.0")]
169169
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
170-
super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
170+
net_imp::TcpStream::connect(addr).map(TcpStream)
171171
}
172172

173173
/// Opens a TCP connection to a remote host with a timeout.
@@ -782,7 +782,7 @@ impl TcpListener {
782782
/// ```
783783
#[stable(feature = "rust1", since = "1.0.0")]
784784
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
785-
super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
785+
net_imp::TcpListener::bind(addr).map(TcpListener)
786786
}
787787

788788
/// Returns the local socket address of this listener.

library/std/src/net/udp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl UdpSocket {
120120
/// [`Ipv4Addr::UNSPECIFIED`] or [`Ipv6Addr::UNSPECIFIED`].
121121
#[stable(feature = "rust1", since = "1.0.0")]
122122
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
123-
super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
123+
net_imp::UdpSocket::bind(addr).map(UdpSocket)
124124
}
125125

126126
/// Receives a single datagram message on the socket. On success, returns the number
@@ -677,7 +677,7 @@ impl UdpSocket {
677677
/// on the platform.
678678
#[stable(feature = "net2_mutators", since = "1.9.0")]
679679
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
680-
super::each_addr(addr, |addr| self.0.connect(addr))
680+
self.0.connect(addr)
681681
}
682682

683683
/// Sends data on the socket to the remote address to which it is connected.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
cfg_if::cfg_if! {
2+
if #[cfg(any(
3+
all(target_family = "unix", not(target_os = "l4re")),
4+
target_os = "windows",
5+
target_os = "hermit",
6+
all(target_os = "wasi", target_env = "p2"),
7+
target_os = "solid_asp3",
8+
))] {
9+
mod socket;
10+
pub use socket::*;
11+
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
12+
mod sgx;
13+
pub use sgx::*;
14+
} else if #[cfg(all(target_os = "wasi", target_env = "p1"))] {
15+
mod wasip1;
16+
pub use wasip1::*;
17+
} else if #[cfg(target_os = "xous")] {
18+
mod xous;
19+
pub use xous::*;
20+
} else if #[cfg(target_os = "uefi")] {
21+
mod uefi;
22+
pub use uefi::*;
23+
} else {
24+
mod unsupported;
25+
pub use unsupported::*;
26+
}
27+
}
28+
29+
#[cfg_attr(
30+
// Make sure that this is used on some platforms at least.
31+
not(any(target_os = "linux", target_os = "windows")),
32+
allow(dead_code)
33+
)]
34+
fn each_addr<A: crate::net::ToSocketAddrs, F, T>(addr: A, mut f: F) -> crate::io::Result<T>
35+
where
36+
F: FnMut(&crate::net::SocketAddr) -> crate::io::Result<T>,
37+
{
38+
use crate::io::Error;
39+
40+
let mut last_err = None;
41+
for addr in addr.to_socket_addrs()? {
42+
match f(&addr) {
43+
Ok(l) => return Ok(l),
44+
Err(e) => last_err = Some(e),
45+
}
46+
}
47+
48+
match last_err {
49+
Some(err) => Err(err),
50+
None => Err(Error::NO_ADDRESSES),
51+
}
52+
}

library/std/src/sys/net/connection/sgx.rs

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
use crate::error;
2+
use crate::fmt::{self, Write};
13
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
24
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
35
use crate::sync::Arc;
46
use crate::sys::abi::usercalls;
57
use crate::sys::fd::FileDesc;
68
use crate::sys::{AsInner, FromInner, IntoInner, TryIntoInner, sgx_ineffective, unsupported};
79
use crate::time::Duration;
8-
use crate::{error, fmt};
910

1011
const DEFAULT_FAKE_TTL: u32 = 64;
1112

@@ -63,18 +64,51 @@ impl fmt::Debug for TcpStream {
6364
}
6465
}
6566

66-
fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
67-
match result {
68-
Ok(saddr) => Ok(saddr.to_string()),
69-
// need to downcast twice because io::Error::into_inner doesn't return the original
70-
// value if the conversion fails
71-
Err(e) => {
72-
if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
73-
Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
74-
} else {
75-
Err(e)
67+
/// Converts each address in `addr` into a hostname.
68+
///
69+
/// SGX doesn't support DNS resolution but rather accepts hostnames in
70+
/// the same place as socket addresses. So, to make e.g.
71+
/// ```rust
72+
/// TcpStream::connect("example.com:80")`
73+
/// ```
74+
/// work, the DNS lookup returns a special error (`NonIpSockAddr`) instead,
75+
/// which contains the hostname being looked up. When `.to_socket_addrs()`
76+
/// fails, we inspect the error and try recover the hostname from it. If that
77+
/// succeeds, we thus continue with the hostname.
78+
///
79+
/// This is a terrible hack and leads to buggy code. For instance, when users
80+
/// use the result of `.to_socket_addrs()` in their own `ToSocketAddrs`
81+
/// implementation to select from a list of possible URLs, the only URL used
82+
/// will be that of the last item tried.
83+
// FIXME: This is a terrible, terrible hack.
84+
fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
85+
where
86+
F: FnMut(&str) -> io::Result<T>,
87+
{
88+
match addr.to_socket_addrs() {
89+
Ok(addrs) => {
90+
let mut last_err = None;
91+
let mut encoded = String::new();
92+
for addr in addrs {
93+
write!(encoded, "{}", &addr).unwrap();
94+
match f(&encoded) {
95+
Ok(val) => return Ok(val),
96+
Err(err) => {
97+
last_err = Some(err);
98+
encoded.clear();
99+
}
100+
}
101+
}
102+
103+
match last_err {
104+
Some(err) => Err(err),
105+
None => Err(io::Error::NO_ADDRESSES),
76106
}
77107
}
108+
Err(err) => match err.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()) {
109+
Some(NonIpSockAddr { host }) => f(host),
110+
None => Err(err),
111+
},
78112
}
79113
}
80114

@@ -86,17 +120,18 @@ fn addr_to_sockaddr(addr: Option<&str>) -> io::Result<SocketAddr> {
86120
}
87121

88122
impl TcpStream {
89-
pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
90-
let addr = io_err_to_addr(addr)?;
91-
let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
92-
Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
123+
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
124+
each_addr(addr, |addr| {
125+
let (fd, local_addr, peer_addr) = usercalls::connect_stream(addr)?;
126+
Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
127+
})
93128
}
94129

95130
pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
96131
if dur == Duration::default() {
97132
return Err(io::Error::ZERO_TIMEOUT);
98133
}
99-
Self::connect(Ok(addr)) // FIXME: ignoring timeout
134+
Self::connect(addr) // FIXME: ignoring timeout
100135
}
101136

102137
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
@@ -247,10 +282,11 @@ impl fmt::Debug for TcpListener {
247282
}
248283

249284
impl TcpListener {
250-
pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
251-
let addr = io_err_to_addr(addr)?;
252-
let (fd, local_addr) = usercalls::bind_stream(&addr)?;
253-
Ok(TcpListener { inner: Socket::new(fd, local_addr) })
285+
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
286+
each_addr(addr, |addr| {
287+
let (fd, local_addr) = usercalls::bind_stream(addr)?;
288+
Ok(TcpListener { inner: Socket::new(fd, local_addr) })
289+
})
254290
}
255291

256292
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
@@ -316,7 +352,7 @@ impl FromInner<Socket> for TcpListener {
316352
pub struct UdpSocket(!);
317353

318354
impl UdpSocket {
319-
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
355+
pub fn bind<A: ToSocketAddrs>(_: A) -> io::Result<UdpSocket> {
320356
unsupported()
321357
}
322358

@@ -436,7 +472,7 @@ impl UdpSocket {
436472
self.0
437473
}
438474

439-
pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
475+
pub fn connect<A: ToSocketAddrs>(&self, _: A) -> io::Result<()> {
440476
self.0
441477
}
442478
}

0 commit comments

Comments
 (0)