wasmtime_wasi/p3/sockets/
conv.rs

1use crate::p3::bindings::sockets::types;
2use crate::p3::sockets::SocketError;
3use crate::sockets::SocketAddressFamily;
4use crate::sockets::util::{from_ipv4_addr, from_ipv6_addr, to_ipv4_addr, to_ipv6_addr};
5use core::net::{IpAddr, SocketAddr, SocketAddrV4, SocketAddrV6};
6use rustix::io::Errno;
7use std::net::ToSocketAddrs;
8use tracing::debug;
9
10impl From<IpAddr> for types::IpAddress {
11    fn from(addr: IpAddr) -> Self {
12        match addr {
13            IpAddr::V4(v4) => Self::Ipv4(from_ipv4_addr(v4)),
14            IpAddr::V6(v6) => Self::Ipv6(from_ipv6_addr(v6)),
15        }
16    }
17}
18
19impl From<types::IpAddress> for IpAddr {
20    fn from(addr: types::IpAddress) -> Self {
21        match addr {
22            types::IpAddress::Ipv4(v4) => Self::V4(to_ipv4_addr(v4)),
23            types::IpAddress::Ipv6(v6) => Self::V6(to_ipv6_addr(v6)),
24        }
25    }
26}
27
28impl From<types::IpSocketAddress> for SocketAddr {
29    fn from(addr: types::IpSocketAddress) -> Self {
30        match addr {
31            types::IpSocketAddress::Ipv4(ipv4) => Self::V4(ipv4.into()),
32            types::IpSocketAddress::Ipv6(ipv6) => Self::V6(ipv6.into()),
33        }
34    }
35}
36
37impl From<SocketAddr> for types::IpSocketAddress {
38    fn from(addr: SocketAddr) -> Self {
39        match addr {
40            SocketAddr::V4(v4) => Self::Ipv4(v4.into()),
41            SocketAddr::V6(v6) => Self::Ipv6(v6.into()),
42        }
43    }
44}
45
46impl From<types::Ipv4SocketAddress> for SocketAddrV4 {
47    fn from(addr: types::Ipv4SocketAddress) -> Self {
48        Self::new(to_ipv4_addr(addr.address), addr.port)
49    }
50}
51
52impl From<SocketAddrV4> for types::Ipv4SocketAddress {
53    fn from(addr: SocketAddrV4) -> Self {
54        Self {
55            address: from_ipv4_addr(*addr.ip()),
56            port: addr.port(),
57        }
58    }
59}
60
61impl From<types::Ipv6SocketAddress> for SocketAddrV6 {
62    fn from(addr: types::Ipv6SocketAddress) -> Self {
63        Self::new(
64            to_ipv6_addr(addr.address),
65            addr.port,
66            addr.flow_info,
67            addr.scope_id,
68        )
69    }
70}
71
72impl From<SocketAddrV6> for types::Ipv6SocketAddress {
73    fn from(addr: SocketAddrV6) -> Self {
74        Self {
75            address: from_ipv6_addr(*addr.ip()),
76            port: addr.port(),
77            flow_info: addr.flowinfo(),
78            scope_id: addr.scope_id(),
79        }
80    }
81}
82
83impl ToSocketAddrs for types::IpSocketAddress {
84    type Iter = <SocketAddr as ToSocketAddrs>::Iter;
85
86    fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
87        SocketAddr::from(*self).to_socket_addrs()
88    }
89}
90
91impl ToSocketAddrs for types::Ipv4SocketAddress {
92    type Iter = <SocketAddrV4 as ToSocketAddrs>::Iter;
93
94    fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
95        SocketAddrV4::from(*self).to_socket_addrs()
96    }
97}
98
99impl ToSocketAddrs for types::Ipv6SocketAddress {
100    type Iter = <SocketAddrV6 as ToSocketAddrs>::Iter;
101
102    fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
103        SocketAddrV6::from(*self).to_socket_addrs()
104    }
105}
106
107impl From<types::IpAddressFamily> for cap_net_ext::AddressFamily {
108    fn from(family: types::IpAddressFamily) -> Self {
109        match family {
110            types::IpAddressFamily::Ipv4 => Self::Ipv4,
111            types::IpAddressFamily::Ipv6 => Self::Ipv6,
112        }
113    }
114}
115
116impl From<cap_net_ext::AddressFamily> for types::IpAddressFamily {
117    fn from(family: cap_net_ext::AddressFamily) -> Self {
118        match family {
119            cap_net_ext::AddressFamily::Ipv4 => Self::Ipv4,
120            cap_net_ext::AddressFamily::Ipv6 => Self::Ipv6,
121        }
122    }
123}
124
125impl From<SocketAddressFamily> for types::IpAddressFamily {
126    fn from(family: SocketAddressFamily) -> Self {
127        match family {
128            SocketAddressFamily::Ipv4 => Self::Ipv4,
129            SocketAddressFamily::Ipv6 => Self::Ipv6,
130        }
131    }
132}
133
134impl From<types::IpAddressFamily> for SocketAddressFamily {
135    fn from(family: types::IpAddressFamily) -> Self {
136        match family {
137            types::IpAddressFamily::Ipv4 => Self::Ipv4,
138            types::IpAddressFamily::Ipv6 => Self::Ipv6,
139        }
140    }
141}
142
143impl From<std::io::Error> for types::ErrorCode {
144    fn from(value: std::io::Error) -> Self {
145        (&value).into()
146    }
147}
148
149impl From<&std::io::Error> for types::ErrorCode {
150    fn from(value: &std::io::Error) -> Self {
151        // Attempt the more detailed native error code first:
152        if let Some(errno) = Errno::from_io_error(value) {
153            return errno.into();
154        }
155
156        match value.kind() {
157            std::io::ErrorKind::AddrInUse => Self::AddressInUse,
158            std::io::ErrorKind::AddrNotAvailable => Self::AddressNotBindable,
159            std::io::ErrorKind::ConnectionAborted => Self::ConnectionAborted,
160            std::io::ErrorKind::ConnectionRefused => Self::ConnectionRefused,
161            std::io::ErrorKind::ConnectionReset => Self::ConnectionReset,
162            std::io::ErrorKind::InvalidInput => Self::InvalidArgument,
163            std::io::ErrorKind::NotConnected => Self::InvalidState,
164            std::io::ErrorKind::OutOfMemory => Self::OutOfMemory,
165            std::io::ErrorKind::PermissionDenied => Self::AccessDenied,
166            std::io::ErrorKind::TimedOut => Self::Timeout,
167            std::io::ErrorKind::Unsupported => Self::NotSupported,
168            _ => {
169                debug!("unknown I/O error: {value}");
170                Self::Unknown
171            }
172        }
173    }
174}
175
176impl From<Errno> for types::ErrorCode {
177    fn from(value: Errno) -> Self {
178        (&value).into()
179    }
180}
181
182impl From<&Errno> for types::ErrorCode {
183    fn from(value: &Errno) -> Self {
184        match *value {
185            #[cfg(not(windows))]
186            Errno::PERM => Self::AccessDenied,
187            Errno::ACCESS => Self::AccessDenied,
188            Errno::ADDRINUSE => Self::AddressInUse,
189            Errno::ADDRNOTAVAIL => Self::AddressNotBindable,
190            Errno::TIMEDOUT => Self::Timeout,
191            Errno::CONNREFUSED => Self::ConnectionRefused,
192            Errno::CONNRESET => Self::ConnectionReset,
193            Errno::CONNABORTED => Self::ConnectionAborted,
194            Errno::INVAL => Self::InvalidArgument,
195            Errno::HOSTUNREACH => Self::RemoteUnreachable,
196            Errno::HOSTDOWN => Self::RemoteUnreachable,
197            Errno::NETDOWN => Self::RemoteUnreachable,
198            Errno::NETUNREACH => Self::RemoteUnreachable,
199            #[cfg(target_os = "linux")]
200            Errno::NONET => Self::RemoteUnreachable,
201            Errno::ISCONN => Self::InvalidState,
202            Errno::NOTCONN => Self::InvalidState,
203            Errno::DESTADDRREQ => Self::InvalidState,
204            Errno::MSGSIZE => Self::DatagramTooLarge,
205            #[cfg(not(windows))]
206            Errno::NOMEM => Self::OutOfMemory,
207            Errno::NOBUFS => Self::OutOfMemory,
208            Errno::OPNOTSUPP => Self::NotSupported,
209            Errno::NOPROTOOPT => Self::NotSupported,
210            Errno::PFNOSUPPORT => Self::NotSupported,
211            Errno::PROTONOSUPPORT => Self::NotSupported,
212            Errno::PROTOTYPE => Self::NotSupported,
213            Errno::SOCKTNOSUPPORT => Self::NotSupported,
214            Errno::AFNOSUPPORT => Self::NotSupported,
215
216            // FYI, EINPROGRESS should have already been handled by connect.
217            _ => {
218                debug!("unknown I/O error: {value}");
219                Self::Unknown
220            }
221        }
222    }
223}
224
225impl From<crate::sockets::util::ErrorCode> for types::ErrorCode {
226    fn from(code: crate::sockets::util::ErrorCode) -> Self {
227        match code {
228            crate::sockets::util::ErrorCode::Unknown => Self::Unknown,
229            crate::sockets::util::ErrorCode::AccessDenied => Self::AccessDenied,
230            crate::sockets::util::ErrorCode::NotSupported => Self::NotSupported,
231            crate::sockets::util::ErrorCode::InvalidArgument => Self::InvalidArgument,
232            crate::sockets::util::ErrorCode::OutOfMemory => Self::OutOfMemory,
233            crate::sockets::util::ErrorCode::Timeout => Self::Timeout,
234            crate::sockets::util::ErrorCode::InvalidState => Self::InvalidState,
235            crate::sockets::util::ErrorCode::AddressNotBindable => Self::AddressNotBindable,
236            crate::sockets::util::ErrorCode::AddressInUse => Self::AddressInUse,
237            crate::sockets::util::ErrorCode::RemoteUnreachable => Self::RemoteUnreachable,
238            crate::sockets::util::ErrorCode::ConnectionRefused => Self::ConnectionRefused,
239            crate::sockets::util::ErrorCode::ConnectionReset => Self::ConnectionReset,
240            crate::sockets::util::ErrorCode::ConnectionAborted => Self::ConnectionAborted,
241            crate::sockets::util::ErrorCode::DatagramTooLarge => Self::DatagramTooLarge,
242            crate::sockets::util::ErrorCode::NotInProgress => Self::InvalidState,
243            crate::sockets::util::ErrorCode::ConcurrencyConflict => Self::InvalidState,
244        }
245    }
246}
247
248impl From<crate::sockets::util::ErrorCode> for SocketError {
249    fn from(code: crate::sockets::util::ErrorCode) -> Self {
250        SocketError::from(types::ErrorCode::from(code))
251    }
252}