xref: /drstd/src/std/sys/sgx/net.rs (revision 9670759b785600bf6315e4173e46a602f16add7a)
1 use crate::std::error;
2 use crate::std::fmt;
3 use crate::std::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
4 use crate::std::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
5 use crate::std::sync::Arc;
6 use crate::std::sys::fd::FileDesc;
7 use crate::std::sys::{sgx_ineffective, unsupported, AsInner, FromInner, IntoInner, TryIntoInner};
8 use crate::std::time::Duration;
9 
10 use super::abi::usercalls;
11 
12 const DEFAULT_FAKE_TTL: u32 = 64;
13 
14 #[derive(Debug, Clone)]
15 pub struct Socket {
16     inner: Arc<FileDesc>,
17     local_addr: Option<String>,
18 }
19 
20 impl Socket {
new(fd: usercalls::raw::Fd, local_addr: String) -> Socket21     fn new(fd: usercalls::raw::Fd, local_addr: String) -> Socket {
22         Socket {
23             inner: Arc::new(FileDesc::new(fd)),
24             local_addr: Some(local_addr),
25         }
26     }
27 }
28 
29 impl AsInner<FileDesc> for Socket {
30     #[inline]
as_inner(&self) -> &FileDesc31     fn as_inner(&self) -> &FileDesc {
32         &self.inner
33     }
34 }
35 
36 impl TryIntoInner<FileDesc> for Socket {
try_into_inner(self) -> Result<FileDesc, Socket>37     fn try_into_inner(self) -> Result<FileDesc, Socket> {
38         let Socket { inner, local_addr } = self;
39         Arc::try_unwrap(inner).map_err(|inner| Socket { inner, local_addr })
40     }
41 }
42 
43 impl FromInner<(FileDesc, Option<String>)> for Socket {
from_inner((inner, local_addr): (FileDesc, Option<String>)) -> Socket44     fn from_inner((inner, local_addr): (FileDesc, Option<String>)) -> Socket {
45         Socket {
46             inner: Arc::new(inner),
47             local_addr,
48         }
49     }
50 }
51 
52 #[derive(Clone)]
53 pub struct TcpStream {
54     inner: Socket,
55     peer_addr: Option<String>,
56 }
57 
58 impl fmt::Debug for TcpStream {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result59     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60         let mut res = f.debug_struct("TcpStream");
61 
62         if let Some(ref addr) = self.inner.local_addr {
63             res.field("addr", addr);
64         }
65 
66         if let Some(ref peer) = self.peer_addr {
67             res.field("peer", peer);
68         }
69 
70         res.field("fd", &self.inner.inner.as_inner()).finish()
71     }
72 }
73 
io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String>74 fn io_err_to_addr(result: io::Result<&SocketAddr>) -> io::Result<String> {
75     match result {
76         Ok(saddr) => Ok(saddr.to_string()),
77         // need to downcast twice because io::Error::into_inner doesn't return the original
78         // value if the conversion fails
79         Err(e) => {
80             if e.get_ref()
81                 .and_then(|e| e.downcast_ref::<NonIpSockAddr>())
82                 .is_some()
83             {
84                 Ok(e.into_inner()
85                     .unwrap()
86                     .downcast::<NonIpSockAddr>()
87                     .unwrap()
88                     .host)
89             } else {
90                 Err(e)
91             }
92         }
93     }
94 }
95 
addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr>96 fn addr_to_sockaddr(addr: &Option<String>) -> io::Result<SocketAddr> {
97     addr.as_ref()
98         .ok_or(io::ErrorKind::AddrNotAvailable)?
99         .to_socket_addrs()
100         // unwrap OK: if an iterator is returned, we're guaranteed to get exactly one entry
101         .map(|mut it| it.next().unwrap())
102 }
103 
104 impl TcpStream {
connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream>105     pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
106         let addr = io_err_to_addr(addr)?;
107         let (fd, local_addr, peer_addr) = usercalls::connect_stream(&addr)?;
108         Ok(TcpStream {
109             inner: Socket::new(fd, local_addr),
110             peer_addr: Some(peer_addr),
111         })
112     }
113 
connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream>114     pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result<TcpStream> {
115         if dur == Duration::default() {
116             return Err(io::const_io_error!(
117                 io::ErrorKind::InvalidInput,
118                 "cannot set a 0 duration timeout",
119             ));
120         }
121         Self::connect(Ok(addr)) // FIXME: ignoring timeout
122     }
123 
set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()>124     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
125         match dur {
126             Some(dur) if dur == Duration::default() => {
127                 return Err(io::const_io_error!(
128                     io::ErrorKind::InvalidInput,
129                     "cannot set a 0 duration timeout",
130                 ));
131             }
132             _ => sgx_ineffective(()),
133         }
134     }
135 
set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()>136     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
137         match dur {
138             Some(dur) if dur == Duration::default() => {
139                 return Err(io::const_io_error!(
140                     io::ErrorKind::InvalidInput,
141                     "cannot set a 0 duration timeout",
142                 ));
143             }
144             _ => sgx_ineffective(()),
145         }
146     }
147 
read_timeout(&self) -> io::Result<Option<Duration>>148     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
149         sgx_ineffective(None)
150     }
151 
write_timeout(&self) -> io::Result<Option<Duration>>152     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
153         sgx_ineffective(None)
154     }
155 
peek(&self, _: &mut [u8]) -> io::Result<usize>156     pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
157         Ok(0)
158     }
159 
read(&self, buf: &mut [u8]) -> io::Result<usize>160     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
161         self.inner.inner.read(buf)
162     }
163 
read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()>164     pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> {
165         self.inner.inner.read_buf(buf)
166     }
167 
read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>168     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
169         self.inner.inner.read_vectored(bufs)
170     }
171 
172     #[inline]
is_read_vectored(&self) -> bool173     pub fn is_read_vectored(&self) -> bool {
174         self.inner.inner.is_read_vectored()
175     }
176 
write(&self, buf: &[u8]) -> io::Result<usize>177     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
178         self.inner.inner.write(buf)
179     }
180 
write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize>181     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
182         self.inner.inner.write_vectored(bufs)
183     }
184 
185     #[inline]
is_write_vectored(&self) -> bool186     pub fn is_write_vectored(&self) -> bool {
187         self.inner.inner.is_write_vectored()
188     }
189 
peer_addr(&self) -> io::Result<SocketAddr>190     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
191         addr_to_sockaddr(&self.peer_addr)
192     }
193 
socket_addr(&self) -> io::Result<SocketAddr>194     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
195         addr_to_sockaddr(&self.inner.local_addr)
196     }
197 
shutdown(&self, _: Shutdown) -> io::Result<()>198     pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
199         sgx_ineffective(())
200     }
201 
duplicate(&self) -> io::Result<TcpStream>202     pub fn duplicate(&self) -> io::Result<TcpStream> {
203         Ok(self.clone())
204     }
205 
set_linger(&self, _: Option<Duration>) -> io::Result<()>206     pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> {
207         sgx_ineffective(())
208     }
209 
linger(&self) -> io::Result<Option<Duration>>210     pub fn linger(&self) -> io::Result<Option<Duration>> {
211         sgx_ineffective(None)
212     }
213 
set_nodelay(&self, _: bool) -> io::Result<()>214     pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
215         sgx_ineffective(())
216     }
217 
nodelay(&self) -> io::Result<bool>218     pub fn nodelay(&self) -> io::Result<bool> {
219         sgx_ineffective(false)
220     }
221 
set_ttl(&self, _: u32) -> io::Result<()>222     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
223         sgx_ineffective(())
224     }
225 
ttl(&self) -> io::Result<u32>226     pub fn ttl(&self) -> io::Result<u32> {
227         sgx_ineffective(DEFAULT_FAKE_TTL)
228     }
229 
take_error(&self) -> io::Result<Option<io::Error>>230     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
231         Ok(None)
232     }
233 
set_nonblocking(&self, _: bool) -> io::Result<()>234     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
235         sgx_ineffective(())
236     }
237 }
238 
239 impl AsInner<Socket> for TcpStream {
240     #[inline]
as_inner(&self) -> &Socket241     fn as_inner(&self) -> &Socket {
242         &self.inner
243     }
244 }
245 
246 // `Inner` includes `peer_addr` so that a `TcpStream` maybe correctly
247 // reconstructed if `Socket::try_into_inner` fails.
248 impl IntoInner<(Socket, Option<String>)> for TcpStream {
into_inner(self) -> (Socket, Option<String>)249     fn into_inner(self) -> (Socket, Option<String>) {
250         (self.inner, self.peer_addr)
251     }
252 }
253 
254 impl FromInner<(Socket, Option<String>)> for TcpStream {
from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream255     fn from_inner((inner, peer_addr): (Socket, Option<String>)) -> TcpStream {
256         TcpStream { inner, peer_addr }
257     }
258 }
259 
260 #[derive(Clone)]
261 pub struct TcpListener {
262     inner: Socket,
263 }
264 
265 impl fmt::Debug for TcpListener {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result266     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267         let mut res = f.debug_struct("TcpListener");
268 
269         if let Some(ref addr) = self.inner.local_addr {
270             res.field("addr", addr);
271         }
272 
273         res.field("fd", &self.inner.inner.as_inner()).finish()
274     }
275 }
276 
277 impl TcpListener {
bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener>278     pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
279         let addr = io_err_to_addr(addr)?;
280         let (fd, local_addr) = usercalls::bind_stream(&addr)?;
281         Ok(TcpListener {
282             inner: Socket::new(fd, local_addr),
283         })
284     }
285 
socket_addr(&self) -> io::Result<SocketAddr>286     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
287         addr_to_sockaddr(&self.inner.local_addr)
288     }
289 
accept(&self) -> io::Result<(TcpStream, SocketAddr)>290     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
291         let (fd, local_addr, peer_addr) = usercalls::accept_stream(self.inner.inner.raw())?;
292         let peer_addr = Some(peer_addr);
293         let ret_peer = addr_to_sockaddr(&peer_addr).unwrap_or_else(|_| ([0; 4], 0).into());
294         Ok((
295             TcpStream {
296                 inner: Socket::new(fd, local_addr),
297                 peer_addr,
298             },
299             ret_peer,
300         ))
301     }
302 
duplicate(&self) -> io::Result<TcpListener>303     pub fn duplicate(&self) -> io::Result<TcpListener> {
304         Ok(self.clone())
305     }
306 
set_ttl(&self, _: u32) -> io::Result<()>307     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
308         sgx_ineffective(())
309     }
310 
ttl(&self) -> io::Result<u32>311     pub fn ttl(&self) -> io::Result<u32> {
312         sgx_ineffective(DEFAULT_FAKE_TTL)
313     }
314 
set_only_v6(&self, _: bool) -> io::Result<()>315     pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
316         sgx_ineffective(())
317     }
318 
only_v6(&self) -> io::Result<bool>319     pub fn only_v6(&self) -> io::Result<bool> {
320         sgx_ineffective(false)
321     }
322 
take_error(&self) -> io::Result<Option<io::Error>>323     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
324         Ok(None)
325     }
326 
set_nonblocking(&self, _: bool) -> io::Result<()>327     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
328         sgx_ineffective(())
329     }
330 }
331 
332 impl AsInner<Socket> for TcpListener {
333     #[inline]
as_inner(&self) -> &Socket334     fn as_inner(&self) -> &Socket {
335         &self.inner
336     }
337 }
338 
339 impl IntoInner<Socket> for TcpListener {
into_inner(self) -> Socket340     fn into_inner(self) -> Socket {
341         self.inner
342     }
343 }
344 
345 impl FromInner<Socket> for TcpListener {
from_inner(inner: Socket) -> TcpListener346     fn from_inner(inner: Socket) -> TcpListener {
347         TcpListener { inner }
348     }
349 }
350 
351 pub struct UdpSocket(!);
352 
353 impl UdpSocket {
bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket>354     pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
355         unsupported()
356     }
357 
peer_addr(&self) -> io::Result<SocketAddr>358     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
359         self.0
360     }
361 
socket_addr(&self) -> io::Result<SocketAddr>362     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
363         self.0
364     }
365 
recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)>366     pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
367         self.0
368     }
369 
peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)>370     pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
371         self.0
372     }
373 
send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize>374     pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
375         self.0
376     }
377 
duplicate(&self) -> io::Result<UdpSocket>378     pub fn duplicate(&self) -> io::Result<UdpSocket> {
379         self.0
380     }
381 
set_read_timeout(&self, _: Option<Duration>) -> io::Result<()>382     pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
383         self.0
384     }
385 
set_write_timeout(&self, _: Option<Duration>) -> io::Result<()>386     pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
387         self.0
388     }
389 
read_timeout(&self) -> io::Result<Option<Duration>>390     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
391         self.0
392     }
393 
write_timeout(&self) -> io::Result<Option<Duration>>394     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
395         self.0
396     }
397 
set_broadcast(&self, _: bool) -> io::Result<()>398     pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
399         self.0
400     }
401 
broadcast(&self) -> io::Result<bool>402     pub fn broadcast(&self) -> io::Result<bool> {
403         self.0
404     }
405 
set_multicast_loop_v4(&self, _: bool) -> io::Result<()>406     pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
407         self.0
408     }
409 
multicast_loop_v4(&self) -> io::Result<bool>410     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
411         self.0
412     }
413 
set_multicast_ttl_v4(&self, _: u32) -> io::Result<()>414     pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
415         self.0
416     }
417 
multicast_ttl_v4(&self) -> io::Result<u32>418     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
419         self.0
420     }
421 
set_multicast_loop_v6(&self, _: bool) -> io::Result<()>422     pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
423         self.0
424     }
425 
multicast_loop_v6(&self) -> io::Result<bool>426     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
427         self.0
428     }
429 
join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()>430     pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
431         self.0
432     }
433 
join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()>434     pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
435         self.0
436     }
437 
leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()>438     pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
439         self.0
440     }
441 
leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()>442     pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
443         self.0
444     }
445 
set_ttl(&self, _: u32) -> io::Result<()>446     pub fn set_ttl(&self, _: u32) -> io::Result<()> {
447         self.0
448     }
449 
ttl(&self) -> io::Result<u32>450     pub fn ttl(&self) -> io::Result<u32> {
451         self.0
452     }
453 
take_error(&self) -> io::Result<Option<io::Error>>454     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
455         self.0
456     }
457 
set_nonblocking(&self, _: bool) -> io::Result<()>458     pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
459         self.0
460     }
461 
recv(&self, _: &mut [u8]) -> io::Result<usize>462     pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
463         self.0
464     }
465 
peek(&self, _: &mut [u8]) -> io::Result<usize>466     pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
467         self.0
468     }
469 
send(&self, _: &[u8]) -> io::Result<usize>470     pub fn send(&self, _: &[u8]) -> io::Result<usize> {
471         self.0
472     }
473 
connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()>474     pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
475         self.0
476     }
477 }
478 
479 impl fmt::Debug for UdpSocket {
fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result480     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
481         self.0
482     }
483 }
484 
485 #[derive(Debug)]
486 pub struct NonIpSockAddr {
487     host: String,
488 }
489 
490 impl error::Error for NonIpSockAddr {
491     #[allow(deprecated)]
description(&self) -> &str492     fn description(&self) -> &str {
493         "Failed to convert address to SocketAddr"
494     }
495 }
496 
497 impl fmt::Display for NonIpSockAddr {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result498     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499         write!(f, "Failed to convert address to SocketAddr: {}", self.host)
500     }
501 }
502 
503 pub struct LookupHost(!);
504 
505 impl LookupHost {
new(host: String) -> io::Result<LookupHost>506     fn new(host: String) -> io::Result<LookupHost> {
507         Err(io::Error::new(
508             io::ErrorKind::Uncategorized,
509             NonIpSockAddr { host },
510         ))
511     }
512 
port(&self) -> u16513     pub fn port(&self) -> u16 {
514         self.0
515     }
516 }
517 
518 impl Iterator for LookupHost {
519     type Item = SocketAddr;
next(&mut self) -> Option<SocketAddr>520     fn next(&mut self) -> Option<SocketAddr> {
521         self.0
522     }
523 }
524 
525 impl TryFrom<&str> for LookupHost {
526     type Error = io::Error;
527 
try_from(v: &str) -> io::Result<LookupHost>528     fn try_from(v: &str) -> io::Result<LookupHost> {
529         LookupHost::new(v.to_owned())
530     }
531 }
532 
533 impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
534     type Error = io::Error;
535 
try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost>536     fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
537         LookupHost::new(format!("{host}:{port}"))
538     }
539 }
540 
541 #[allow(bad_style)]
542 pub mod netc {
543     pub const AF_INET: u8 = 0;
544     pub const AF_INET6: u8 = 1;
545     pub type sa_family_t = u8;
546 
547     #[derive(Copy, Clone)]
548     pub struct in_addr {
549         pub s_addr: u32,
550     }
551 
552     #[derive(Copy, Clone)]
553     pub struct sockaddr_in {
554         pub sin_family: sa_family_t,
555         pub sin_port: u16,
556         pub sin_addr: in_addr,
557     }
558 
559     #[derive(Copy, Clone)]
560     pub struct in6_addr {
561         pub s6_addr: [u8; 16],
562     }
563 
564     #[derive(Copy, Clone)]
565     pub struct sockaddr_in6 {
566         pub sin6_family: sa_family_t,
567         pub sin6_port: u16,
568         pub sin6_addr: in6_addr,
569         pub sin6_flowinfo: u32,
570         pub sin6_scope_id: u32,
571     }
572 
573     #[derive(Copy, Clone)]
574     pub struct sockaddr {}
575 }
576