1 #![deny(unsafe_op_in_unsafe_fn)]
6 use crate::io::{self, IoSlice, IoSliceMut};
7 use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
8 use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
9 use crate::sys::unsupported;
10 use crate::sys_common::{AsInner, FromInner, IntoInner};
11 use crate::time::Duration;
13 pub struct Socket(WasiFd);
15 pub struct TcpStream {
19 impl AsInner<WasiFd> for Socket {
20 fn as_inner(&self) -> &WasiFd {
25 impl IntoInner<WasiFd> for Socket {
26 fn into_inner(self) -> WasiFd {
31 impl FromInner<WasiFd> for Socket {
32 fn from_inner(inner: WasiFd) -> Socket {
37 impl AsFd for Socket {
38 fn as_fd(&self) -> BorrowedFd<'_> {
43 impl AsRawFd for Socket {
44 fn as_raw_fd(&self) -> RawFd {
49 impl IntoRawFd for Socket {
50 fn into_raw_fd(self) -> RawFd {
55 impl FromRawFd for Socket {
56 unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
57 unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) }
62 pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
66 pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
70 pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
74 pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
78 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
82 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
86 pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
90 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
91 self.read_vectored(&mut [IoSliceMut::new(buf)])
94 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
95 self.socket().as_inner().read(bufs)
98 pub fn is_read_vectored(&self) -> bool {
102 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
103 self.write_vectored(&[IoSlice::new(buf)])
106 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
107 self.socket().as_inner().write(bufs)
110 pub fn is_write_vectored(&self) -> bool {
114 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
118 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
122 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
123 let wasi_how = match how {
124 Shutdown::Read => wasi::SDFLAGS_RD,
125 Shutdown::Write => wasi::SDFLAGS_WR,
126 Shutdown::Both => wasi::SDFLAGS_RD | wasi::SDFLAGS_WR,
129 unsafe { wasi::sock_shutdown(self.socket().as_raw_fd() as _, wasi_how).map_err(err2io) }
132 pub fn duplicate(&self) -> io::Result<TcpStream> {
136 pub fn set_linger(&self, _: Option<Duration>) -> io::Result<()> {
140 pub fn linger(&self) -> io::Result<Option<Duration>> {
144 pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
148 pub fn nodelay(&self) -> io::Result<bool> {
152 pub fn set_ttl(&self, _: u32) -> io::Result<()> {
156 pub fn ttl(&self) -> io::Result<u32> {
160 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
164 pub fn set_nonblocking(&self, state: bool) -> io::Result<()> {
165 let fdstat = unsafe {
166 wasi::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasi::Fd).map_err(err2io)?
169 let mut flags = fdstat.fs_flags;
172 flags |= wasi::FDFLAGS_NONBLOCK;
174 flags &= !wasi::FDFLAGS_NONBLOCK;
178 wasi::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasi::Fd, flags)
183 pub fn socket(&self) -> &Socket {
187 pub fn into_socket(self) -> Socket {
192 impl FromInner<Socket> for TcpStream {
193 fn from_inner(socket: Socket) -> TcpStream {
194 TcpStream { inner: socket }
198 impl fmt::Debug for TcpStream {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 f.debug_struct("TcpStream").field("fd", &self.inner.as_raw_fd()).finish()
204 pub struct TcpListener {
209 pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
213 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
217 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
219 wasi::sock_accept(self.as_inner().as_inner().as_raw_fd() as _, 0).map_err(err2io)?
223 TcpStream::from_inner(unsafe { Socket::from_raw_fd(fd as _) }),
224 // WASI has no concept of SocketAddr yet
225 // return an unspecified IPv4Addr
226 SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0),
230 pub fn duplicate(&self) -> io::Result<TcpListener> {
234 pub fn set_ttl(&self, _: u32) -> io::Result<()> {
238 pub fn ttl(&self) -> io::Result<u32> {
242 pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
246 pub fn only_v6(&self) -> io::Result<bool> {
250 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
254 pub fn set_nonblocking(&self, state: bool) -> io::Result<()> {
255 let fdstat = unsafe {
256 wasi::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasi::Fd).map_err(err2io)?
259 let mut flags = fdstat.fs_flags;
262 flags |= wasi::FDFLAGS_NONBLOCK;
264 flags &= !wasi::FDFLAGS_NONBLOCK;
268 wasi::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasi::Fd, flags)
273 pub fn socket(&self) -> &Socket {
277 pub fn into_socket(self) -> Socket {
282 impl AsInner<Socket> for TcpListener {
283 fn as_inner(&self) -> &Socket {
288 impl IntoInner<Socket> for TcpListener {
289 fn into_inner(self) -> Socket {
294 impl FromInner<Socket> for TcpListener {
295 fn from_inner(inner: Socket) -> TcpListener {
296 TcpListener { inner }
300 impl fmt::Debug for TcpListener {
301 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
302 f.debug_struct("TcpListener").field("fd", &self.inner.as_raw_fd()).finish()
306 pub struct UdpSocket {
311 pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
315 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
319 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
323 pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
327 pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
331 pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
335 pub fn duplicate(&self) -> io::Result<UdpSocket> {
339 pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
343 pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
347 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
351 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
355 pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
359 pub fn broadcast(&self) -> io::Result<bool> {
363 pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
367 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
371 pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
375 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
379 pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
383 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
387 pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
391 pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
395 pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> {
399 pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> {
403 pub fn set_ttl(&self, _: u32) -> io::Result<()> {
407 pub fn ttl(&self) -> io::Result<u32> {
411 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
415 pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
419 pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
423 pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
427 pub fn send(&self, _: &[u8]) -> io::Result<usize> {
431 pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
435 pub fn socket(&self) -> &Socket {
439 pub fn into_socket(self) -> Socket {
444 impl AsInner<Socket> for UdpSocket {
445 fn as_inner(&self) -> &Socket {
450 impl IntoInner<Socket> for UdpSocket {
451 fn into_inner(self) -> Socket {
456 impl FromInner<Socket> for UdpSocket {
457 fn from_inner(inner: Socket) -> UdpSocket {
462 impl fmt::Debug for UdpSocket {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 f.debug_struct("UdpSocket").field("fd", &self.inner.as_raw_fd()).finish()
468 pub struct LookupHost(!);
471 pub fn port(&self) -> u16 {
476 impl Iterator for LookupHost {
477 type Item = SocketAddr;
478 fn next(&mut self) -> Option<SocketAddr> {
483 impl<'a> TryFrom<&'a str> for LookupHost {
484 type Error = io::Error;
486 fn try_from(_v: &'a str) -> io::Result<LookupHost> {
491 impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
492 type Error = io::Error;
494 fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
499 #[allow(nonstandard_style)]
501 pub const AF_INET: u8 = 0;
502 pub const AF_INET6: u8 = 1;
503 pub type sa_family_t = u8;
505 #[derive(Copy, Clone)]
510 #[derive(Copy, Clone)]
511 pub struct sockaddr_in {
512 pub sin_family: sa_family_t,
514 pub sin_addr: in_addr,
517 #[derive(Copy, Clone)]
518 pub struct in6_addr {
519 pub s6_addr: [u8; 16],
522 #[derive(Copy, Clone)]
523 pub struct sockaddr_in6 {
524 pub sin6_family: sa_family_t,
526 pub sin6_addr: in6_addr,
527 pub sin6_flowinfo: u32,
528 pub sin6_scope_id: u32,
531 #[derive(Copy, Clone)]
532 pub struct sockaddr {}