3 use crate::io::{self, IoSlice, IoSliceMut};
4 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
6 use crate::sys::fd::FileDesc;
7 use crate::sys::{sgx_ineffective, unsupported, AsInner, FromInner, IntoInner, TryIntoInner};
8 use crate::time::Duration;
10 use super::abi::usercalls;
12 const DEFAULT_FAKE_TTL: u32 = 64;
14 #[derive(Debug, Clone)]
17 local_addr: Option<String>,
21 fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket {
22 Socket { inner: Arc::new(FileDesc::new(fd)), local_addr: Some(local_addr) }
26 impl AsInner<FileDesc> for Socket {
27 fn as_inner(&self) -> &FileDesc {
32 impl TryIntoInner<FileDesc> for Socket {
33 fn try_into_inner(self) -> Result<FileDesc, Socket> {
34 let Socket { inner, local_addr } = self;
35 Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr })
39 impl FromInner<(FileDesc, Option<String>)> for Socket {
40 fn from_inner((inner, local_addr): (FileDesc, Option<String>)) -> Socket {
41 Socket { inner: Arc::new(inner), local_addr }
46 pub struct TcpStream {
48 peer_addr: Option<String>,
51 impl fmt::Debug for TcpStream {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 let mut res = f.debug_struct("TcpStream");
55 if let Some(ref addr) = self.inner.local_addr {
56 res.field("addr", addr);
59 if let Some(ref peer) = self.peer_addr {
60 res.field("peer", peer);
63 res.field("fd", &self.inner.inner.as_inner()).finish()
67 fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
69 Ok(saddr) => Ok(saddr.to_string()),
70 // need to downcast twice because io::Error::into_inner doesn't return the original
71 // value if the conversion fails
73 if e.get_ref().and_then(|e| e.downcast_ref::<NonIpSockAddr>()).is_some() {
74 Ok(e.into_inner().unwrap().downcast::<NonIpSockAddr>().unwrap().host)
82 fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
84 .ok_or(io::ErrorKind::AddrNotAvailable)?
86 // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
87 .map(|mut it| it.next().unwrap())
91 pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
92 let addr = io_err_to_addr(addr)?;
93 let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
94 Ok(TcpStream { inner: Socket::new(fd, local_addr), peer_addr: Some(peer_addr) })
97 pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
98 if dur == Duration::default() {
99 return Err(io::const_io_error!(
100 io::ErrorKind::InvalidInput,
101 "cannot set a 0 duration timeout",
104 Self::connect(Ok(addr)) // FIXME: ignoring timeout
107 pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
109 Some(dur) if dur == Duration::default() => {
110 return Err(io::const_io_error!(
111 io::ErrorKind::InvalidInput,
112 "cannot set a 0 duration timeout",
115 _ => sgx_ineffective(()),
119 pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
121 Some(dur) if dur == Duration::default() => {
122 return Err(io::const_io_error!(
123 io::ErrorKind::InvalidInput,
124 "cannot set a 0 duration timeout",
127 _ => sgx_ineffective(()),
131 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
132 sgx_ineffective(None)
135 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
136 sgx_ineffective(None)
139 pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
143 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
144 self.inner.inner.read(buf)
147 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
148 self.inner.inner.read_vectored(bufs)
152 pub fn is_read_vectored(&self) -> bool {
153 self.inner.inner.is_read_vectored()
156 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
157 self.inner.inner.write(buf)
160 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
161 self.inner.inner.write_vectored(bufs)
165 pub fn is_write_vectored(&self) -> bool {
166 self.inner.inner.is_write_vectored()
169 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
170 addr_to_sockaddr(&self.peer_addr)
173 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
174 addr_to_sockaddr(&self.inner.local_addr)
177 pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
181 pub fn duplicate(&self) -> io::Result<TcpStream> {
185 pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> {
189 pub fn linger(&self) -> io::Result<Option<Duration>> {
190 sgx_ineffective(None)
193 pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
197 pub fn nodelay(&self) -> io::Result<bool> {
198 sgx_ineffective(false)
201 pub fn set_ttl(&self, _: u32) -> io::Result<()> {
205 pub fn ttl(&self) -> io::Result<u32> {
206 sgx_ineffective(DEFAULT_FAKE_TTL)
209 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
213 pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
218 impl AsInner<Socket> for TcpStream {
219 fn as_inner(&self) -> &Socket {
224 // `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly
225 // reconstructed if `Socket::try_into_inner` fails.
226 impl IntoInner<(Socket, Option<String>)> for TcpStream {
227 fn into_inner(self) -> (Socket, Option<String>) {
228 (self.inner, self.peer_addr)
232 impl FromInner<(Socket, Option<String>)> for TcpStream {
233 fn from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream {
234 TcpStream { inner, peer_addr }
239 pub struct TcpListener {
243 impl fmt::Debug for TcpListener {
244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 let mut res = f.debug_struct("TcpListener");
247 if let Some(ref addr) = self.inner.local_addr {
248 res.field("addr", addr);
251 res.field("fd", &self.inner.inner.as_inner()).finish()
256 pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
257 let addr = io_err_to_addr(addr)?;
258 let (fd, local_addr) = usercalls::bind_stream(&addr)?;
259 Ok(TcpListener { inner: Socket::new(fd, local_addr) })
262 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
263 addr_to_sockaddr(&self.inner.local_addr)
266 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
267 let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?;
268 let peer_addr = Some(peer_addr);
269 let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into());
270 Ok((TcpStream { inner: Socket::new(fd, local_addr), peer_addr }, ret_peer))
273 pub fn duplicate(&self) -> io::Result<TcpListener> {
277 pub fn set_ttl(&self, _: u32) -> io::Result<()> {
281 pub fn ttl(&self) -> io::Result<u32> {
282 sgx_ineffective(DEFAULT_FAKE_TTL)
285 pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
289 pub fn only_v6(&self) -> io::Result<bool> {
290 sgx_ineffective(false)
293 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
297 pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
302 impl AsInner<Socket> for TcpListener {
303 fn as_inner(&self) -> &Socket {
308 impl IntoInner<Socket> for TcpListener {
309 fn into_inner(self) -> Socket {
314 impl FromInner<Socket> for TcpListener {
315 fn from_inner(inner: Socket) -> TcpListener {
316 TcpListener { inner }
320 pub struct UdpSocket(!);
323 pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
327 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
331 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
335 pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
339 pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
343 pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
347 pub fn duplicate(&self) -> io::Result<UdpSocket> {
351 pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
355 pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
359 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
363 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
367 pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
371 pub fn broadcast(&self) -> io::Result<bool> {
375 pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
379 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
383 pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
387 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
391 pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
395 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
399 pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
403 pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
407 pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
411 pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
415 pub fn set_ttl(&self, _: u32) -> io::Result<()> {
419 pub fn ttl(&self) -> io::Result<u32> {
423 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
427 pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
431 pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
435 pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
439 pub fn send(&self, _: &[u8]) -> io::Result<usize> {
443 pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
448 impl fmt::Debug for UdpSocket {
449 fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
455 pub struct NonIpSockAddr {
459 impl error::Error for NonIpSockAddr {
461 fn description(&self) -> &str {
462 "Failed to convert address to SocketAddr"
466 impl fmt::Display for NonIpSockAddr {
467 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
468 write!(f, "Failed to convert address to SocketAddr: {}", self.host)
472 pub struct LookupHost(!);
475 fn new(host: String) -> io::Result<LookupHost> {
476 Err(io::Error::new(io::ErrorKind::Uncategorized, NonIpSockAddr { host }))
479 pub fn port(&self) -> u16 {
484 impl Iterator for LookupHost {
485 type Item = SocketAddr;
486 fn next(&mut self) -> Option<SocketAddr> {
491 impl TryFrom<&str> for LookupHost {
492 type Error = io::Error;
494 fn try_from(v: &str) -> io::Result<LookupHost> {
495 LookupHost::new(v.to_owned())
499 impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
500 type Error = io::Error;
502 fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
503 LookupHost::new(format!("{host}:{port}"))
509 pub const AF_INET: u8 = 0;
510 pub const AF_INET6: u8 = 1;
511 pub type sa_family_t = u8;
513 #[derive(Copy, Clone)]
518 #[derive(Copy, Clone)]
519 pub struct sockaddr_in {
520 pub sin_family: sa_family_t,
522 pub sin_addr: in_addr,
525 #[derive(Copy, Clone)]
526 pub struct in6_addr {
527 pub s6_addr: [u8; 16],
530 #[derive(Copy, Clone)]
531 pub struct sockaddr_in6 {
532 pub sin6_family: sa_family_t,
534 pub sin6_addr: in6_addr,
535 pub sin6_flowinfo: u32,
536 pub sin6_scope_id: u32,
539 #[derive(Copy, Clone)]
540 pub struct sockaddr {}