wasmtime_wasi/p3/sockets/
conv.rs1use 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<SocketAddressFamily> for types::IpAddressFamily {
108 fn from(family: SocketAddressFamily) -> Self {
109 match family {
110 SocketAddressFamily::Ipv4 => Self::Ipv4,
111 SocketAddressFamily::Ipv6 => Self::Ipv6,
112 }
113 }
114}
115
116impl From<types::IpAddressFamily> for SocketAddressFamily {
117 fn from(family: types::IpAddressFamily) -> Self {
118 match family {
119 types::IpAddressFamily::Ipv4 => Self::Ipv4,
120 types::IpAddressFamily::Ipv6 => Self::Ipv6,
121 }
122 }
123}
124
125impl From<std::io::Error> for types::ErrorCode {
126 fn from(value: std::io::Error) -> Self {
127 (&value).into()
128 }
129}
130
131impl From<&std::io::Error> for types::ErrorCode {
132 fn from(value: &std::io::Error) -> Self {
133 if let Some(errno) = Errno::from_io_error(value) {
135 return errno.into();
136 }
137
138 match value.kind() {
139 std::io::ErrorKind::AddrInUse => Self::AddressInUse,
140 std::io::ErrorKind::AddrNotAvailable => Self::AddressNotBindable,
141 std::io::ErrorKind::ConnectionAborted => Self::ConnectionAborted,
142 std::io::ErrorKind::ConnectionRefused => Self::ConnectionRefused,
143 std::io::ErrorKind::ConnectionReset => Self::ConnectionReset,
144 std::io::ErrorKind::InvalidInput => Self::InvalidArgument,
145 std::io::ErrorKind::NotConnected => Self::InvalidState,
146 std::io::ErrorKind::OutOfMemory => Self::OutOfMemory,
147 std::io::ErrorKind::PermissionDenied => Self::AccessDenied,
148 std::io::ErrorKind::TimedOut => Self::Timeout,
149 std::io::ErrorKind::Unsupported => Self::NotSupported,
150 _ => {
151 debug!("unknown I/O error: {value}");
152 Self::Other(None)
153 }
154 }
155 }
156}
157
158impl From<Errno> for types::ErrorCode {
159 fn from(value: Errno) -> Self {
160 (&value).into()
161 }
162}
163
164impl From<&Errno> for types::ErrorCode {
165 fn from(value: &Errno) -> Self {
166 match *value {
167 #[cfg(not(windows))]
168 Errno::PERM => Self::AccessDenied,
169 Errno::ACCESS => Self::AccessDenied,
170 Errno::ADDRINUSE => Self::AddressInUse,
171 Errno::ADDRNOTAVAIL => Self::AddressNotBindable,
172 Errno::TIMEDOUT => Self::Timeout,
173 Errno::CONNREFUSED => Self::ConnectionRefused,
174 Errno::CONNRESET => Self::ConnectionReset,
175 Errno::CONNABORTED => Self::ConnectionAborted,
176 Errno::INVAL => Self::InvalidArgument,
177 Errno::HOSTUNREACH => Self::RemoteUnreachable,
178 Errno::HOSTDOWN => Self::RemoteUnreachable,
179 Errno::NETDOWN => Self::RemoteUnreachable,
180 Errno::NETUNREACH => Self::RemoteUnreachable,
181 #[cfg(target_os = "linux")]
182 Errno::NONET => Self::RemoteUnreachable,
183 Errno::ISCONN => Self::InvalidState,
184 Errno::NOTCONN => Self::InvalidState,
185 Errno::DESTADDRREQ => Self::InvalidState,
186 Errno::MSGSIZE => Self::DatagramTooLarge,
187 #[cfg(not(windows))]
188 Errno::NOMEM => Self::OutOfMemory,
189 Errno::NOBUFS => Self::OutOfMemory,
190 Errno::OPNOTSUPP => Self::NotSupported,
191 Errno::NOPROTOOPT => Self::NotSupported,
192 Errno::PFNOSUPPORT => Self::NotSupported,
193 Errno::PROTONOSUPPORT => Self::NotSupported,
194 Errno::PROTOTYPE => Self::NotSupported,
195 Errno::SOCKTNOSUPPORT => Self::NotSupported,
196 Errno::AFNOSUPPORT => Self::NotSupported,
197
198 _ => {
200 debug!("unknown I/O error: {value}");
201 Self::Other(None)
202 }
203 }
204 }
205}
206
207impl From<crate::sockets::util::ErrorCode> for types::ErrorCode {
208 fn from(code: crate::sockets::util::ErrorCode) -> Self {
209 match code {
210 crate::sockets::util::ErrorCode::Unknown => Self::Other(None),
211 crate::sockets::util::ErrorCode::AccessDenied => Self::AccessDenied,
212 crate::sockets::util::ErrorCode::NotSupported => Self::NotSupported,
213 crate::sockets::util::ErrorCode::InvalidArgument => Self::InvalidArgument,
214 crate::sockets::util::ErrorCode::OutOfMemory => Self::OutOfMemory,
215 crate::sockets::util::ErrorCode::Timeout => Self::Timeout,
216 crate::sockets::util::ErrorCode::InvalidState => Self::InvalidState,
217 crate::sockets::util::ErrorCode::AddressNotBindable => Self::AddressNotBindable,
218 crate::sockets::util::ErrorCode::AddressInUse => Self::AddressInUse,
219 crate::sockets::util::ErrorCode::RemoteUnreachable => Self::RemoteUnreachable,
220 crate::sockets::util::ErrorCode::ConnectionRefused => Self::ConnectionRefused,
221 crate::sockets::util::ErrorCode::ConnectionReset => Self::ConnectionReset,
222 crate::sockets::util::ErrorCode::ConnectionAborted => Self::ConnectionAborted,
223 crate::sockets::util::ErrorCode::DatagramTooLarge => Self::DatagramTooLarge,
224 crate::sockets::util::ErrorCode::NotInProgress => Self::InvalidState,
225 crate::sockets::util::ErrorCode::ConcurrencyConflict => Self::InvalidState,
226 }
227 }
228}
229
230impl From<crate::sockets::util::ErrorCode> for SocketError {
231 fn from(code: crate::sockets::util::ErrorCode) -> Self {
232 SocketError::from(types::ErrorCode::from(code))
233 }
234}