Types
use resource networksince 0.2.0
from wasi:sockets/network@0.2.6
An opaque resource that represents access to (a subset of) the network. This enables context-based security for networking. There is no need for this to map 1:1 to a physical network interface.
use enum error-codesince 0.2.0
from wasi:sockets/network@0.2.6
Error codes.
In theory, every API can return any error code. In practice, API's typically only return the errors documented per API combined with a couple of errors that are always possible:
unknownaccess-deniednot-supportedout-of-memoryconcurrency-conflict
See each individual API for what the POSIX equivalents are. They sometimes differ per API.
unknownUnknown error
access-deniedAccess denied.
POSIX equivalent: EACCES, EPERM
not-supportedThe operation is not supported.
POSIX equivalent: EOPNOTSUPP
invalid-argumentOne of the arguments is invalid.
POSIX equivalent: EINVAL
out-of-memoryNot enough memory to complete the operation.
POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY
timeoutThe operation timed out before it could finish completely.
concurrency-conflictThis operation is incompatible with another asynchronous operation that is already in progress.
POSIX equivalent: EALREADY
not-in-progressTrying to finish an asynchronous operation that:
- has not been started yet, or:
- was already finished by a previous
finish-*call.
Note: this is scheduled to be removed when
futures are natively supported.would-blockThe operation has been aborted because it could not be completed immediately.
Note: this is scheduled to be removed when
futures are natively supported.invalid-stateThe operation is not valid in the socket's current state.
new-socket-limitA new socket resource could not be created because of a system limit.
address-not-bindableA bind operation failed because the provided address is not an address that the
networkcan bind to.address-in-useA bind operation failed because the provided address is already in use or because there are no ephemeral ports available.
remote-unreachableThe remote address is not reachable
connection-refusedThe TCP connection was forcefully rejected
connection-resetThe TCP connection was reset.
connection-abortedA TCP connection was aborted.
datagram-too-largeThe size of a datagram sent to a UDP socket exceeded the maximum supported size.
name-unresolvableName does not exist or has no suitable associated IP addresses.
temporary-resolver-failureA temporary failure in name resolution occurred.
permanent-resolver-failureA permanent failure in name resolution occurred.
use enum ip-address-familysince 0.2.0
from wasi:sockets/network@0.2.6
ipv4Similar to
AF_INETin POSIX.ipv6Similar to
AF_INET6in POSIX.
use resource udp-socketsince 0.2.0
A UDP socket handle.
start-bind: func( network: borrow<network>, local-address: ip-socket-address, ) -> result<_, error-code>since 0.2.0Bind the socket to a specific network on the provided IP address and port.
If the IP address is zero (
0.0.0.0in IPv4,::in IPv6), it is left to the implementation to decide which network interface(s) to bind to. If the port is zero, the socket will be bound to a random free port.Typical errors
invalid-argument: Thelocal-addresshas the wrong address family. (EAFNOSUPPORT, EFAULT on Windows)invalid-state: The socket is already bound. (EINVAL)address-in-use: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows)address-in-use: Address is already in use. (EADDRINUSE)address-not-bindable:local-addressis not an address that thenetworkcan bind to. (EADDRNOTAVAIL)not-in-progress: Abindoperation is not in progress.would-block: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN)
Implementors note
Unlike in POSIX, in WASI the bind operation is async. This enables interactive WASI hosts to inject permission prompts. Runtimes that don't want to make use of this ability can simply call the native
bindas part of eitherstart-bindorfinish-bind.References
finish-bind: func() -> result<_, error-code>since 0.2.0stream: func( remote-address: option<ip-socket-address>, ) -> result<tuple<incoming-datagram-stream, outgoing-datagram-stream>, error-code>since 0.2.0Set up inbound & outbound communication channels, optionally to a specific peer.
This function only changes the local socket configuration and does not generate any network traffic. On success, the
remote-addressof the socket is updated. Thelocal-addressmay be updated as well, based on the best network path toremote-address.When a
remote-addressis provided, the returned streams are limited to communicating with that specific peer:sendcan only be used to send to this destination.receivewill only return datagrams sent from the providedremote-address.
This method may be called multiple times on the same socket to change its association, but only the most recently returned pair of streams will be operational. Implementations may trap if the streams returned by a previous invocation haven't been dropped yet before calling
streamagain.The POSIX equivalent in pseudo-code is:
if (was previously connected) { connect(s, AF_UNSPEC) } if (remote_address is Some) { connect(s, remote_address) }Unlike in POSIX, the socket must already be explicitly bound.
Typical errors
invalid-argument: Theremote-addresshas the wrong address family. (EAFNOSUPPORT)invalid-argument: The IP address inremote-addressis set to INADDR_ANY (0.0.0.0/::). (EDESTADDRREQ, EADDRNOTAVAIL)invalid-argument: The port inremote-addressis set to 0. (EDESTADDRREQ, EADDRNOTAVAIL)invalid-state: The socket is not bound.address-in-use: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD)remote-unreachable: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET)connection-refused: The connection was refused. (ECONNREFUSED)
References
local-address: func() -> result<ip-socket-address, error-code>since 0.2.0Get the current bound address.
POSIX mentions:
If the socket has not been bound to a local name, the value stored in the object pointed to by
addressis unspecified.WASI is stricter and requires
local-addressto returninvalid-statewhen the socket hasn't been bound yet.Typical errors
invalid-state: The socket is not bound to any local address.
References
remote-address: func() -> result<ip-socket-address, error-code>since 0.2.0Get the address the socket is currently streaming to.
Typical errors
invalid-state: The socket is not streaming to a specific remote address. (ENOTCONN)
References
address-family: func() -> ip-address-familysince 0.2.0Whether this is a IPv4 or IPv6 socket.
Equivalent to the SO_DOMAIN socket option.
unicast-hop-limit: func() -> result<u8, error-code>since 0.2.0Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options.
If the provided value is 0, an
invalid-argumenterror is returned.Typical errors
invalid-argument: (set) The TTL value must be 1 or higher.
set-unicast-hop-limit: func(value: u8) -> result<_, error-code>since 0.2.0receive-buffer-size: func() -> result<u64, error-code>since 0.2.0The kernel buffer space reserved for sends/receives on this socket.
If the provided value is 0, an
invalid-argumenterror is returned. Any other value will never cause an error, but it might be silently clamped and/or rounded. I.e. after setting a value, reading the same setting back may return a different value.Equivalent to the SO_RCVBUF and SO_SNDBUF socket options.
Typical errors
invalid-argument: (set) The provided value was 0.
set-receive-buffer-size: func(value: u64) -> result<_, error-code>since 0.2.0send-buffer-size: func() -> result<u64, error-code>since 0.2.0set-send-buffer-size: func(value: u64) -> result<_, error-code>since 0.2.0subscribe: func() -> pollablesince 0.2.0Create a
pollablewhich will resolve once the socket is ready for I/O.Note: this function is here for WASI 0.2 only. It's planned to be removed when
futureis natively supported in Preview3.
Functions
create-udp-socket: func(
address-family: ip-address-family,
) -> result<udp-socket, error-code>since 0.2.0
Create a new UDP socket.
Similar to socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP) in POSIX.
On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.
This function does not require a network capability handle. This is considered to be safe because
at time of creation, the socket is not bound to any network yet. Up to the moment bind is called,
the socket is effectively an in-memory configuration object, unable to communicate with the outside world.
All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.
Typical errors
not-supported: The specifiedaddress-familyis not supported. (EAFNOSUPPORT)new-socket-limit: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
References:
WIT
@since(version = 0.2.0)
interface udp-create-socket {
@since(version = 0.2.0)
use network.{network, error-code, ip-address-family};
@since(version = 0.2.0)
use udp.{udp-socket};
/// Create a new UDP socket.
///
/// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX.
/// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise.
///
/// This function does not require a network capability handle. This is considered to be safe because
/// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called,
/// the socket is effectively an in-memory configuration object, unable to communicate with the outside world.
///
/// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations.
///
/// # Typical errors
/// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT)
/// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE)
///
/// # References:
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html>
/// - <https://man7.org/linux/man-pages/man2/socket.2.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketw>
/// - <https://man.freebsd.org/cgi/man.cgi?query=socket&sektion=2>
@since(version = 0.2.0)
create-udp-socket: func(address-family: ip-address-family) -> result<udp-socket, error-code>;
}