1 use crate::wasi::clocks::monotonic_clock;
2 use crate::wasi::io::poll::{self, Pollable};
3 use crate::wasi::io::streams::{InputStream, OutputStream, StreamError};
4 use crate::wasi::sockets::instance_network;
5 use crate::wasi::sockets::ip_name_lookup;
6 use crate::wasi::sockets::network::{
7     ErrorCode, IpAddress, IpAddressFamily, IpSocketAddress, Ipv4SocketAddress, Ipv6SocketAddress,
8     Network,
9 };
10 use crate::wasi::sockets::tcp::TcpSocket;
11 use crate::wasi::sockets::udp::{
12     IncomingDatagram, IncomingDatagramStream, OutgoingDatagram, OutgoingDatagramStream, UdpSocket,
13 };
14 use crate::wasi::sockets::{tcp_create_socket, udp_create_socket};
15 use std::ops::Range;
16 
17 const TIMEOUT_NS: u64 = 1_000_000_000;
18 
19 impl Pollable {
20     pub fn block_until(&self, timeout: &Pollable) -> Result<(), ErrorCode> {
21         let ready = poll::poll(&[self, timeout]);
22         assert!(ready.len() > 0);
23         match ready[0] {
24             0 => Ok(()),
25             1 => Err(ErrorCode::Timeout),
26             _ => unreachable!(),
27         }
28     }
29 }
30 
31 impl OutputStream {
32     pub fn blocking_write_util(&self, mut bytes: &[u8]) -> Result<(), StreamError> {
33         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
34         let pollable = self.subscribe();
35 
36         while !bytes.is_empty() {
37             pollable.block_until(&timeout).expect("write timed out");
38 
39             let permit = self.check_write()?;
40 
41             let len = bytes.len().min(permit as usize);
42             let (chunk, rest) = bytes.split_at(len);
43 
44             self.write(chunk)?;
45 
46             self.blocking_flush()?;
47 
48             bytes = rest;
49         }
50         Ok(())
51     }
52 }
53 
54 impl Network {
55     pub fn default() -> Network {
56         instance_network::instance_network()
57     }
58 
59     pub fn blocking_resolve_addresses(&self, name: &str) -> Result<Vec<IpAddress>, ErrorCode> {
60         let stream = ip_name_lookup::resolve_addresses(&self, name)?;
61 
62         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
63         let pollable = stream.subscribe();
64 
65         let mut addresses = vec![];
66 
67         loop {
68             match stream.resolve_next_address() {
69                 Ok(Some(addr)) => {
70                     addresses.push(addr);
71                 }
72                 Ok(None) => match addresses[..] {
73                     [] => return Err(ErrorCode::NameUnresolvable),
74                     _ => return Ok(addresses),
75                 },
76                 Err(ErrorCode::WouldBlock) => {
77                     pollable.block_until(&timeout)?;
78                 }
79                 Err(err) => return Err(err),
80             }
81         }
82     }
83 }
84 
85 impl TcpSocket {
86     pub fn new(address_family: IpAddressFamily) -> Result<TcpSocket, ErrorCode> {
87         tcp_create_socket::create_tcp_socket(address_family)
88     }
89 
90     pub fn blocking_bind(
91         &self,
92         network: &Network,
93         local_address: IpSocketAddress,
94     ) -> Result<(), ErrorCode> {
95         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
96         let sub = self.subscribe();
97 
98         self.start_bind(&network, local_address)?;
99 
100         loop {
101             match self.finish_bind() {
102                 Err(ErrorCode::WouldBlock) => sub.block_until(&timeout)?,
103                 result => return result,
104             }
105         }
106     }
107 
108     pub fn blocking_listen(&self) -> Result<(), ErrorCode> {
109         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
110         let sub = self.subscribe();
111 
112         self.start_listen()?;
113 
114         loop {
115             match self.finish_listen() {
116                 Err(ErrorCode::WouldBlock) => sub.block_until(&timeout)?,
117                 result => return result,
118             }
119         }
120     }
121 
122     pub fn blocking_connect(
123         &self,
124         network: &Network,
125         remote_address: IpSocketAddress,
126     ) -> Result<(InputStream, OutputStream), ErrorCode> {
127         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
128         let sub = self.subscribe();
129 
130         self.start_connect(&network, remote_address)?;
131 
132         loop {
133             match self.finish_connect() {
134                 Err(ErrorCode::WouldBlock) => sub.block_until(&timeout)?,
135                 result => return result,
136             }
137         }
138     }
139 
140     pub fn blocking_accept(&self) -> Result<(TcpSocket, InputStream, OutputStream), ErrorCode> {
141         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
142         let sub = self.subscribe();
143 
144         loop {
145             match self.accept() {
146                 Err(ErrorCode::WouldBlock) => sub.block_until(&timeout)?,
147                 result => return result,
148             }
149         }
150     }
151 }
152 
153 impl UdpSocket {
154     pub fn new(address_family: IpAddressFamily) -> Result<UdpSocket, ErrorCode> {
155         udp_create_socket::create_udp_socket(address_family)
156     }
157 
158     pub fn blocking_bind(
159         &self,
160         network: &Network,
161         local_address: IpSocketAddress,
162     ) -> Result<(), ErrorCode> {
163         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
164         let sub = self.subscribe();
165 
166         self.start_bind(&network, local_address)?;
167 
168         loop {
169             match self.finish_bind() {
170                 Err(ErrorCode::WouldBlock) => sub.block_until(&timeout)?,
171                 result => return result,
172             }
173         }
174     }
175 
176     pub fn blocking_bind_unspecified(&self, network: &Network) -> Result<(), ErrorCode> {
177         let ip = IpAddress::new_unspecified(self.address_family());
178         let port = 0;
179 
180         self.blocking_bind(network, IpSocketAddress::new(ip, port))
181     }
182 }
183 
184 impl OutgoingDatagramStream {
185     fn blocking_check_send(&self, timeout: &Pollable) -> Result<u64, ErrorCode> {
186         let sub = self.subscribe();
187 
188         loop {
189             match self.check_send() {
190                 Ok(0) => sub.block_until(timeout)?,
191                 result => return result,
192             }
193         }
194     }
195 
196     pub fn blocking_send(&self, mut datagrams: &[OutgoingDatagram]) -> Result<(), ErrorCode> {
197         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
198 
199         while !datagrams.is_empty() {
200             let permit = self.blocking_check_send(&timeout)?;
201             let chunk_len = datagrams.len().min(permit as usize);
202             match self.send(&datagrams[..chunk_len]) {
203                 Ok(0) => {}
204                 Ok(packets_sent) => {
205                     let packets_sent = packets_sent as usize;
206                     datagrams = &datagrams[packets_sent..];
207                 }
208                 Err(err) => return Err(err),
209             }
210         }
211 
212         Ok(())
213     }
214 }
215 
216 impl IncomingDatagramStream {
217     pub fn blocking_receive(&self, count: Range<u64>) -> Result<Vec<IncomingDatagram>, ErrorCode> {
218         let timeout = monotonic_clock::subscribe_duration(TIMEOUT_NS);
219         let pollable = self.subscribe();
220         let mut datagrams = vec![];
221 
222         loop {
223             match self.receive(count.end - datagrams.len() as u64) {
224                 Ok(mut chunk) => {
225                     datagrams.append(&mut chunk);
226 
227                     if datagrams.len() >= count.start as usize {
228                         return Ok(datagrams);
229                     } else {
230                         pollable.block_until(&timeout)?;
231                     }
232                 }
233                 Err(err) => return Err(err),
234             }
235         }
236     }
237 }
238 
239 impl IpAddress {
240     pub const IPV4_BROADCAST: IpAddress = IpAddress::Ipv4((255, 255, 255, 255));
241 
242     pub const IPV4_LOOPBACK: IpAddress = IpAddress::Ipv4((127, 0, 0, 1));
243     pub const IPV6_LOOPBACK: IpAddress = IpAddress::Ipv6((0, 0, 0, 0, 0, 0, 0, 1));
244 
245     pub const IPV4_UNSPECIFIED: IpAddress = IpAddress::Ipv4((0, 0, 0, 0));
246     pub const IPV6_UNSPECIFIED: IpAddress = IpAddress::Ipv6((0, 0, 0, 0, 0, 0, 0, 0));
247 
248     pub const IPV4_MAPPED_LOOPBACK: IpAddress =
249         IpAddress::Ipv6((0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 0x0001));
250 
251     pub const fn new_loopback(family: IpAddressFamily) -> IpAddress {
252         match family {
253             IpAddressFamily::Ipv4 => Self::IPV4_LOOPBACK,
254             IpAddressFamily::Ipv6 => Self::IPV6_LOOPBACK,
255         }
256     }
257 
258     pub const fn new_unspecified(family: IpAddressFamily) -> IpAddress {
259         match family {
260             IpAddressFamily::Ipv4 => Self::IPV4_UNSPECIFIED,
261             IpAddressFamily::Ipv6 => Self::IPV6_UNSPECIFIED,
262         }
263     }
264 
265     pub const fn family(&self) -> IpAddressFamily {
266         match self {
267             IpAddress::Ipv4(_) => IpAddressFamily::Ipv4,
268             IpAddress::Ipv6(_) => IpAddressFamily::Ipv6,
269         }
270     }
271 }
272 
273 impl PartialEq for IpAddress {
274     fn eq(&self, other: &Self) -> bool {
275         match (self, other) {
276             (Self::Ipv4(left), Self::Ipv4(right)) => left == right,
277             (Self::Ipv6(left), Self::Ipv6(right)) => left == right,
278             _ => false,
279         }
280     }
281 }
282 
283 impl IpSocketAddress {
284     pub const fn new(ip: IpAddress, port: u16) -> IpSocketAddress {
285         match ip {
286             IpAddress::Ipv4(addr) => IpSocketAddress::Ipv4(Ipv4SocketAddress {
287                 port: port,
288                 address: addr,
289             }),
290             IpAddress::Ipv6(addr) => IpSocketAddress::Ipv6(Ipv6SocketAddress {
291                 port: port,
292                 address: addr,
293                 flow_info: 0,
294                 scope_id: 0,
295             }),
296         }
297     }
298 
299     pub const fn ip(&self) -> IpAddress {
300         match self {
301             IpSocketAddress::Ipv4(addr) => IpAddress::Ipv4(addr.address),
302             IpSocketAddress::Ipv6(addr) => IpAddress::Ipv6(addr.address),
303         }
304     }
305 
306     pub const fn port(&self) -> u16 {
307         match self {
308             IpSocketAddress::Ipv4(addr) => addr.port,
309             IpSocketAddress::Ipv6(addr) => addr.port,
310         }
311     }
312 
313     pub const fn family(&self) -> IpAddressFamily {
314         match self {
315             IpSocketAddress::Ipv4(_) => IpAddressFamily::Ipv4,
316             IpSocketAddress::Ipv6(_) => IpAddressFamily::Ipv6,
317         }
318     }
319 }
320 
321 impl PartialEq for Ipv4SocketAddress {
322     fn eq(&self, other: &Self) -> bool {
323         self.port == other.port && self.address == other.address
324     }
325 }
326 
327 impl PartialEq for Ipv6SocketAddress {
328     fn eq(&self, other: &Self) -> bool {
329         self.port == other.port
330             && self.flow_info == other.flow_info
331             && self.address == other.address
332             && self.scope_id == other.scope_id
333     }
334 }
335 
336 impl PartialEq for IpSocketAddress {
337     fn eq(&self, other: &Self) -> bool {
338         match (self, other) {
339             (Self::Ipv4(l0), Self::Ipv4(r0)) => l0 == r0,
340             (Self::Ipv6(l0), Self::Ipv6(r0)) => l0 == r0,
341             _ => false,
342         }
343     }
344 }
345