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