wasmer_wasix/syscalls/wasix/
resolve.rs

1use super::*;
2use crate::syscalls::*;
3
4/// ### `resolve()`
5/// Resolves a hostname and a port to one or more IP addresses.
6///
7/// Note: This is similar to `getaddrinfo` in POSIX
8///
9/// When successful, the contents of the output buffer consist of a sequence of
10/// IPv4 and/or IPv6 addresses. Each address entry consists of a addr_t object.
11/// This function fills the output buffer as much as possible.
12///
13/// ## Parameters
14///
15/// * `host` - Host to resolve
16/// * `port` - Port hint (zero if no hint is supplied)
17/// * `addrs` - The buffer where addresses will be stored
18///
19/// ## Return
20///
21/// The number of IP addresses returned during the DNS resolution.
22#[instrument(level = "trace", skip_all, fields(host = field::Empty, %port), ret)]
23pub fn resolve<M: MemorySize>(
24    mut ctx: FunctionEnvMut<'_, WasiEnv>,
25    host: WasmPtr<u8, M>,
26    host_len: M::Offset,
27    port: u16,
28    addrs: WasmPtr<__wasi_addr_t, M>,
29    naddrs: M::Offset,
30    ret_naddrs: WasmPtr<M::Offset, M>,
31) -> Result<Errno, WasiError> {
32    WasiEnv::do_pending_operations(&mut ctx)?;
33
34    let naddrs: usize = wasi_try_ok!(naddrs.try_into().map_err(|_| Errno::Inval));
35    let mut env = ctx.data();
36    let host_str = {
37        let memory = unsafe { env.memory_view(&ctx) };
38        unsafe { get_input_str_ok!(&memory, host, host_len) }
39    };
40    Span::current().record("host", host_str.as_str());
41
42    let port = if port > 0 { Some(port) } else { None };
43
44    let net = env.net().clone();
45    let tasks = env.tasks().clone();
46    let found_ips = wasi_try_ok!(__asyncify(&mut ctx, None, async move {
47        net.resolve(host_str.as_str(), port, None)
48            .await
49            .map_err(net_error_into_wasi_err)
50    })?);
51    env = ctx.data();
52
53    let mut idx = 0;
54    let memory = unsafe { env.memory_view(&ctx) };
55    let addrs = wasi_try_mem_ok!(addrs.slice(&memory, wasi_try_ok!(to_offset::<M>(naddrs))));
56    for found_ip in found_ips.iter().take(naddrs) {
57        crate::net::write_ip(&memory, addrs.index(idx).as_ptr::<M>(), *found_ip);
58        idx += 1;
59    }
60
61    let idx: M::Offset = wasi_try_ok!(idx.try_into().map_err(|_| Errno::Overflow));
62    wasi_try_mem_ok!(ret_naddrs.write(&memory, idx));
63
64    Ok(Errno::Success)
65}