forked from WebAssembly/wasi-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is derived from files in WebAssembly/wasi-sockets#16 and minimally renames and adjusts things to fit the very latest wasi-proposal-repo layout.
- Loading branch information
1 parent
fef6f5a
commit 3ca1770
Showing
9 changed files
with
1,531 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
/// This interface provides a value-export of the default network handle.. | ||
default interface instance-network { | ||
use pkg.network.{network} | ||
|
||
/// Get a handle to the default network. | ||
instance-network: func() -> network | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
|
||
default interface ip-name-lookup { | ||
use poll.poll.{pollable} | ||
use pkg.network.{network, error, ip-address, ip-address-family} | ||
|
||
|
||
/// Resolve an internet host name to a list of IP addresses. | ||
/// | ||
/// See the wasi-socket proposal README.md for a comparison with getaddrinfo. | ||
/// | ||
/// Parameters: | ||
/// - `name`: The name to look up. IP addresses are not allowed. Unicode domain names are automatically converted | ||
/// to ASCII using IDNA encoding. | ||
/// - `address-family`: If provided, limit the results to addresses of this specific address family. | ||
/// - `include-unavailable`: When set to true, this function will also return addresses of which the runtime | ||
/// thinks (or knows) can't be connected to at the moment. For example, this will return IPv6 addresses on | ||
/// systems without an active IPv6 interface. Notes: | ||
/// - Even when no public IPv6 interfaces are present or active, names like "localhost" can still resolve to an IPv6 address. | ||
/// - Whatever is "available" or "unavailable" is volatile and can change everytime a network cable is unplugged. | ||
/// | ||
/// This function never blocks. It either immediately returns successfully with a `resolve-address-stream` | ||
/// that can be used to (asynchronously) fetch the results. | ||
/// Or it immediately fails whenever `name` is: | ||
/// - empty | ||
/// - an IP address | ||
/// - a syntactically invalid domain name in another way | ||
/// | ||
/// References: | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html | ||
/// - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html | ||
/// | ||
resolve-addresses: func(network: network, name: string, address-family: option<ip-address-family>, include-unavailable: bool) -> result<resolve-address-stream, error> | ||
|
||
|
||
|
||
type resolve-address-stream = u32 | ||
|
||
/// Returns the next address from the resolver. | ||
/// | ||
/// This function should be called multiple times. On each call, it will | ||
/// return the next address in connection order preference. If all | ||
/// addresses have been exhausted, this function returns `none`. | ||
/// After which, you should release the stream with `drop-resolve-address-stream`. | ||
/// | ||
/// This function never returns IPv4-mapped IPv6 addresses. | ||
resolve-next-address: func(this: resolve-address-stream) -> result<option<ip-address>, error> | ||
|
||
|
||
|
||
/// Dispose of the specified `resolve-address-stream`, after which it may no longer be used. | ||
/// | ||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. | ||
drop-resolve-address-stream: func(this: resolve-address-stream) | ||
|
||
/// Get/set the blocking mode of the stream. | ||
/// | ||
/// By default a stream is in "blocking" mode, meaning that any function blocks and waits for its completion. | ||
/// When switched to "non-blocking" mode, operations that would block return an `again` error. After which | ||
/// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. | ||
/// | ||
/// Note: these functions are here for WASI Preview2 only. | ||
/// They're planned to be removed when `future` is natively supported in Preview3. | ||
non-blocking: func(this: resolve-address-stream) -> result<bool, error> | ||
set-non-blocking: func(this: resolve-address-stream, value: bool) -> result<_, error> | ||
|
||
/// Create a `pollable` which will resolve once the stream is ready for I/O. | ||
/// | ||
/// Note: this function is here for WASI Preview2 only. | ||
/// It's planned to be removed when `future` is natively supported in Preview3. | ||
subscribe: func(this: resolve-address-stream) -> pollable | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
|
||
default interface network { | ||
/// 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. | ||
/// | ||
/// FYI, In the future this will be replaced by handle types. | ||
type network = u32 | ||
|
||
/// Dispose of the specified `network`, after which it may no longer be used. | ||
/// | ||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. | ||
drop-network: func(this: network) | ||
|
||
|
||
|
||
enum error { | ||
unknown, | ||
again, | ||
// TODO ... | ||
} | ||
|
||
enum ip-address-family { | ||
/// Similar to `AF_INET` in POSIX. | ||
ipv4, | ||
|
||
/// Similar to `AF_INET6` in POSIX. | ||
ipv6, | ||
} | ||
|
||
type ipv4-address = tuple<u8, u8, u8, u8> | ||
type ipv6-address = tuple<u16, u16, u16, u16, u16, u16, u16, u16> | ||
|
||
variant ip-address { | ||
ipv4(ipv4-address), | ||
ipv6(ipv6-address), | ||
} | ||
|
||
record ipv4-socket-address { | ||
port: u16, // sin_port | ||
address: ipv4-address, // sin_addr | ||
} | ||
|
||
record ipv6-socket-address { | ||
port: u16, // sin6_port | ||
flow-info: u32, // sin6_flowinfo | ||
address: ipv6-address, // sin6_addr | ||
scope-id: u32, // sin6_scope_id | ||
} | ||
|
||
variant ip-socket-address { | ||
ipv4(ipv4-socket-address), | ||
ipv6(ipv6-socket-address), | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
|
||
default interface tcp-create-socket { | ||
use pkg.network.{network, error, ip-address-family} | ||
use pkg.tcp.{tcp-socket} | ||
|
||
/// Create a new TCP socket. | ||
/// | ||
/// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. | ||
/// | ||
/// 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`/`listen`/`connect` | ||
/// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. | ||
/// | ||
/// References: | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html | ||
/// - https://man7.org/linux/man-pages/man2/socket.2.html | ||
/// | ||
create-tcp-socket: func(address-family: ip-address-family) -> result<tcp-socket, error> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
|
||
default interface tcp { | ||
use io.streams.{input-stream, output-stream} | ||
use poll.poll.{pollable} | ||
use pkg.network.{network, error, ip-socket-address, ip-address-family} | ||
|
||
/// A TCP socket handle. | ||
type tcp-socket = u32 | ||
|
||
|
||
enum shutdown-type { | ||
/// Similar to `SHUT_RD` in POSIX. | ||
receive, | ||
|
||
/// Similar to `SHUT_WR` in POSIX. | ||
send, | ||
|
||
/// Similar to `SHUT_RDWR` in POSIX. | ||
both, | ||
} | ||
|
||
|
||
/// Bind the socket to a specific network on the provided IP address and port. | ||
/// | ||
/// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which | ||
/// network interface(s) to bind to. | ||
/// If the TCP/UDP port is zero, the socket will be bound to a random free port. | ||
/// | ||
/// When a socket is not explicitly bound, the first invocation to a listen or connect operation will | ||
/// implicitly bind the socket. | ||
/// | ||
/// Fails when: | ||
/// - the socket is already bound. | ||
/// | ||
/// References | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/bind.html | ||
/// - https://man7.org/linux/man-pages/man2/bind.2.html | ||
bind: func(this: tcp-socket, network: network, local-address: ip-socket-address) -> result<_, error> | ||
|
||
/// Connect to a remote endpoint. | ||
/// | ||
/// On success: | ||
/// - the socket is transitioned into the Connection state | ||
/// - a pair of streams is returned that can be used to read & write to the connection | ||
/// | ||
/// Fails when: | ||
/// - the socket is already bound to a different network. | ||
/// - the provided network does not allow connections to the specified endpoint. | ||
/// - the socket is already in the Connection or Listener state. | ||
/// - either the remote IP address or port is 0. | ||
/// | ||
/// References | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html | ||
/// - https://man7.org/linux/man-pages/man2/connect.2.html | ||
connect: func(this: tcp-socket, network: network, remote-address: ip-socket-address) -> result<tuple<input-stream, output-stream>, error> | ||
|
||
/// Start listening for new connections. | ||
/// | ||
/// Transitions the socket into the Listener state. | ||
/// | ||
/// Fails when: | ||
/// - the socket is already bound to a different network. | ||
/// - the provided network does not allow listening on the specified address. | ||
/// - the socket is already in the Connection or Listener state. | ||
/// | ||
/// References | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html | ||
/// - https://man7.org/linux/man-pages/man2/listen.2.html | ||
listen: func(this: tcp-socket, network: network) -> result<_, error> | ||
|
||
/// Accept a new client socket. | ||
/// | ||
/// The returned socket is bound and in the Connection state. | ||
/// | ||
/// On success, this function returns the newly accepted client socket along with | ||
/// a pair of streams that can be used to read & write to the connection. | ||
/// | ||
/// Fails when this socket is not in the Listening state. | ||
/// | ||
/// References: | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html | ||
/// - https://man7.org/linux/man-pages/man2/accept.2.html | ||
accept: func(this: tcp-socket) -> result<tuple<tcp-socket, input-stream, output-stream>, error> | ||
|
||
/// Get the bound local address. | ||
/// | ||
/// Returns an error if the socket is not bound. | ||
/// | ||
/// References | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html | ||
/// - https://man7.org/linux/man-pages/man2/getsockname.2.html | ||
local-address: func(this: tcp-socket) -> result<ip-socket-address, error> | ||
|
||
/// Get the bound remote address. | ||
/// | ||
/// Fails when the socket is not in the Connection state. | ||
/// | ||
/// References | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html | ||
/// - https://man7.org/linux/man-pages/man2/getpeername.2.html | ||
remote-address: func(this: tcp-socket) -> result<ip-socket-address, error> | ||
|
||
/// Whether this is a IPv4 or IPv6 socket. | ||
/// | ||
/// Equivalent to the SO_DOMAIN socket option. | ||
address-family: func(this: tcp-socket) -> result<ip-address-family, error> | ||
|
||
/// Whether IPv4 compatibility (dual-stack) mode is disabled or not. | ||
/// Implementations are not required to support dual-stack mode. Calling `set-ipv6-only(false)` might fail. | ||
/// | ||
/// Fails when called on an IPv4 socket. | ||
/// | ||
/// Equivalent to the IPV6_V6ONLY socket option. | ||
ipv6-only: func(this: tcp-socket) -> result<bool, error> | ||
set-ipv6-only: func(this: tcp-socket, value: bool) -> result<_, error> | ||
|
||
/// Hints the desired listen queue size. Implementations are free to ignore this. | ||
set-listen-backlog-size: func(this: tcp-socket, value: u64) -> result<_, error> | ||
|
||
/// Equivalent to the SO_KEEPALIVE socket option. | ||
keep-alive: func(this: tcp-socket) -> result<bool, error> | ||
set-keep-alive: func(this: tcp-socket, value: bool) -> result<_, error> | ||
|
||
/// Equivalent to the TCP_NODELAY socket option. | ||
no-delay: func(this: tcp-socket) -> result<bool, error> | ||
set-no-delay: func(this: tcp-socket, value: bool) -> result<_, error> | ||
|
||
/// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. | ||
unicast-hop-limit: func(this: tcp-socket) -> result<u8, error> | ||
set-unicast-hop-limit: func(this: tcp-socket, value: u8) -> result<_, error> | ||
|
||
/// The kernel buffer space reserved for sends/receives on this socket. | ||
/// | ||
/// Note #1: an implementation may choose to cap or round the buffer size when setting the value. | ||
/// In other words, after setting a value, reading the same setting back may return a different value. | ||
/// | ||
/// Note #2: there is not necessarily a direct relationship between the kernel buffer size and the bytes of | ||
/// actual data to be sent/received by the application, because the kernel might also use the buffer space | ||
/// for internal metadata structures. | ||
/// | ||
/// Fails when this socket is in the Listening state. | ||
/// | ||
/// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. | ||
receive-buffer-size: func(this: tcp-socket) -> result<u64, error> | ||
set-receive-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> | ||
send-buffer-size: func(this: tcp-socket) -> result<u64, error> | ||
set-send-buffer-size: func(this: tcp-socket, value: u64) -> result<_, error> | ||
|
||
/// Get/set the blocking mode of the socket. | ||
/// | ||
/// By default a socket is in "blocking" mode, meaning that any function blocks and waits for its completion. | ||
/// When switched to "non-blocking" mode, operations that would block return an `again` error. After which | ||
/// the API consumer is expected to call `subscribe` and wait for completion using the wasi-poll module. | ||
/// | ||
/// Note: these functions are here for WASI Preview2 only. | ||
/// They're planned to be removed when `future` is natively supported in Preview3. | ||
non-blocking: func(this: tcp-socket) -> result<bool, error> | ||
set-non-blocking: func(this: tcp-socket, value: bool) -> result<_, error> | ||
|
||
/// Create a `pollable` which will resolve once the socket is ready for I/O. | ||
/// | ||
/// Note: this function is here for WASI Preview2 only. | ||
/// It's planned to be removed when `future` is natively supported in Preview3. | ||
subscribe: func(this: tcp-socket) -> pollable | ||
|
||
/// Gracefully shut down the connection. | ||
/// | ||
/// - receive: the socket is not expecting to receive any more data from the peer. All subsequent read | ||
/// operations on the `input-stream` associated with this socket will return an End Of Stream indication. | ||
/// Any data still in the receive queue at time of calling `shutdown` will be discarded. | ||
/// - send: the socket is not expecting to send any more data to the peer. All subsequent write | ||
/// operations on the `output-stream` associated with this socket will return an error. | ||
/// - both: same effect as receive & send combined. | ||
/// | ||
/// The shutdown function does not close the socket. | ||
/// | ||
/// Fails when the socket is not in the Connection state. | ||
/// | ||
/// References | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/shutdown.html | ||
/// - https://man7.org/linux/man-pages/man2/shutdown.2.html | ||
shutdown: func(this: tcp-socket, shutdown-type: shutdown-type) -> result<_, error> | ||
|
||
/// Dispose of the specified `tcp-socket`, after which it may no longer be used. | ||
/// | ||
/// Note: this function is scheduled to be removed when Resources are natively supported in Wit. | ||
drop-tcp-socket: func(this: tcp-socket) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
|
||
default interface udp-create-socket { | ||
use pkg.network.{network, error, ip-address-family} | ||
use pkg.udp.{udp-socket} | ||
|
||
/// Create a new UDP socket. | ||
/// | ||
/// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. | ||
/// | ||
/// 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`/`connect` is called, | ||
/// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. | ||
/// | ||
/// References: | ||
/// - https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html | ||
/// - https://man7.org/linux/man-pages/man2/socket.2.html | ||
/// | ||
create-udp-socket: func(address-family: ip-address-family) -> result<udp-socket, error> | ||
} |
Oops, something went wrong.