Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add wasi-0.3.0 draft #111

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d0f8ab5
feat: add `wasi-0.3.0` draft
rvolosatovs Jan 14, 2025
8cc04c8
refactor: replace `error-context` introspection by futures
rvolosatovs Jan 14, 2025
8a3b482
chore: bump `@since` to `0.3.0`
rvolosatovs Jan 14, 2025
a4ca7f6
feat(0.3): introduce `tcp-connection`
rvolosatovs Jan 15, 2025
955b5a4
Add TcpSocketOperationalSemantics-0.3.0-draft.md
badeend Jan 16, 2025
c5b9684
Remove resolve-address-stream
badeend Jan 16, 2025
26390db
Split lookup errors off from the general socket errors type
badeend Jan 16, 2025
bee1ffd
Remove the runtime `network` capability and rely solely on link-time …
badeend Jan 16, 2025
6de677f
Remove `create-tcp/udp-socket` methods & interfaces in favor of plain…
badeend Jan 16, 2025
4417d18
Rename `write` -> `send`, `read` -> `receive`
badeend Jan 16, 2025
544ec8c
Remove the TCP `shutdown` method. It is redundant now that we have pr…
badeend Jan 16, 2025
5134af0
Now that binding a socket doesn't require a runtime network handle an…
badeend Jan 16, 2025
3778219
Merge `listen` & `accept` into a single method that returns a stream …
badeend Jan 16, 2025
2752e1b
Update state names
badeend Jan 16, 2025
c48f6b9
Clarify EALREADY equivalence
badeend Jan 16, 2025
ee62973
Remove superfluous `concurrency-conflict` error code. `invalid-state`…
badeend Jan 16, 2025
c483c3a
Add Since annotations to tcp-connection
badeend Jan 16, 2025
401fc2b
Remove last references to wasi:io
badeend Jan 16, 2025
762a3ab
Remove outdated doc now that we have tcp-connection.
badeend Jan 16, 2025
7f3ec8d
Now that binding a socket doesn't require a runtime network handle an…
badeend Jan 16, 2025
0e8554f
feat(0.3): asyncify `resolve-address-stream`
rvolosatovs Jan 16, 2025
dbe26c7
Merge UDP `send` into `%stream`
badeend Jan 16, 2025
5ab0f73
Rename `%stream` to `transfer`. The `%stream` name was already subopt…
badeend Jan 16, 2025
2214d2f
Merge branch 'feat/0.3.0-draft' of https://github.com/rvolosatovs/was…
badeend Jan 16, 2025
60dd2e8
Rename `network.wit` to `types.wit` to match other proposals
badeend Jan 16, 2025
d1107f5
Move tcp-socket & udp-socket into types.wit to match other proposals.
badeend Jan 16, 2025
3abda6e
Make wit-bindgen work. It failed with:
badeend Jan 16, 2025
e92d144
Update TcpSocketOperationalSemantics-0.3.0-draft.md
badeend Jan 16, 2025
f646c25
feat: update wit-deps to 0.5.0
rvolosatovs Jan 16, 2025
bbebffa
Update wit-0.3.0-draft/types.wit
badeend Jan 17, 2025
074d948
Fix WSARecvMsg link
badeend Jan 19, 2025
5efd1e9
Document the distinction between permanent and transient errors on `l…
badeend Jan 19, 2025
7545a4b
Move `send` & `receive` into `tcp-socket`, simplifying the signatures…
badeend Jan 19, 2025
92248c5
Revert usage of `streams` for UDP. `stream`s can fail only once and t…
badeend Jan 19, 2025
148f43e
Remove inbound/outbound-datagram records. They were added in anticipa…
badeend Jan 19, 2025
dcf0b76
Remove outer result from `receive`
badeend Jan 19, 2025
0e6b058
Clarify `address-family`
badeend Jan 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions TcpSocketOperationalSemantics-0.3.0-draft.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Operational semantics of WASI TCP sockets

WASI TCP sockets must behave [as-if](https://en.wikipedia.org/wiki/As-if_rule) they are implemented using the state machine described in this document.

## States
> Note: These refer to the states of the TCP socket, not the [TCP connection](https://datatracker.ietf.org/doc/html/rfc9293#name-state-machine-overview)

In pseudo code:

```wit
interface tcp {
variant state {
unbound,
bound,
listening(accept-stream),
connecting(connect-future),
connected,
closed,
}
}
```

## Transitions
The following diagram describes the exhaustive set of all possible state transitions:

```mermaid
stateDiagram-v2
state "unbound" as Unbound
state "bound" as Bound
state "connecting" as Connecting
state "connected" as Connected
state "listening" as Listening
state "closed" as Closed


[*] --> Unbound: create-tcp-socket() -> ok
Unbound --> Bound: bind() -> ok
Unbound --> Connecting: connect()

Connecting --> Connected: «task resolves successfully»
Connecting --> Closed: «task resolves with error»

Connected --> Closed: «connection terminated»

Bound --> Connecting: connect()
Bound --> Listening: listen() -> ok
Unbound --> Listening: listen() -> ok
```

- Transitions annotated with `-> ok` only apply when the method returns successfully.
- Calling a method from the wrong state returns `error(invalid-state)` and does not affect the state of the socket.
- This diagram only includes the methods that impact the socket's state. For an overview of all methods and their required states, see [tcp.wit](./wit/tcp.wit)
- Client sockets returned by `listen()` are immediately in the `connected` state.
- A socket resource can be dropped in any state.
4 changes: 4 additions & 0 deletions wit-0.3.0-draft/deps.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[clocks]
url = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz"
sha256 = "26e315db0d371495f8834edfc0e479042f94152ce677d96d54d3623d0e4ffb1e"
sha512 = "e1c76f499435841316f9287b88d8173558e64f277c321ff390556de8707a0b18dd6c1749bbb17bbbba8d523da246ef6eb05c990ceddb762e03efb2ae30cacc76"
1 change: 1 addition & 0 deletions wit-0.3.0-draft/deps.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
clocks = "https://github.com/WebAssembly/wasi-clocks/archive/main.tar.gz"
45 changes: 45 additions & 0 deletions wit-0.3.0-draft/deps/clocks/monotonic-clock.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package wasi:clocks@0.3.0;
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A monotonic clock is a clock which has an unspecified initial value, and
/// successive reads of the clock will produce non-decreasing values.
@since(version = 0.3.0)
interface monotonic-clock {
/// An instant in time, in nanoseconds. An instant is relative to an
/// unspecified initial value, and can only be compared to instances from
/// the same monotonic-clock.
@since(version = 0.3.0)
type instant = u64;

/// A duration of time, in nanoseconds.
@since(version = 0.3.0)
type duration = u64;

/// Read the current value of the clock.
///
/// The clock is monotonic, therefore calling this function repeatedly will
/// produce a sequence of non-decreasing values.
@since(version = 0.3.0)
now: func() -> instant;

/// Query the resolution of the clock. Returns the duration of time
/// corresponding to a clock tick.
@since(version = 0.3.0)
resolution: func() -> duration;

/// Wait until the specified instant has occurred.
@since(version = 0.3.0)
wait-until: func(
when: instant,
);

/// Wait for the specified duration has elapsed.
@since(version = 0.3.0)
wait-for: func(
how-long: duration,
);
}
55 changes: 55 additions & 0 deletions wit-0.3.0-draft/deps/clocks/timezone.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package wasi:clocks@0.3.0;

@unstable(feature = clocks-timezone)
interface timezone {
@unstable(feature = clocks-timezone)
use wall-clock.{datetime};

/// Return information needed to display the given `datetime`. This includes
/// the UTC offset, the time zone name, and a flag indicating whether
/// daylight saving time is active.
///
/// If the timezone cannot be determined for the given `datetime`, return a
/// `timezone-display` for `UTC` with a `utc-offset` of 0 and no daylight
/// saving time.
@unstable(feature = clocks-timezone)
display: func(when: datetime) -> timezone-display;

/// The same as `display`, but only return the UTC offset.
@unstable(feature = clocks-timezone)
utc-offset: func(when: datetime) -> s32;

/// Information useful for displaying the timezone of a specific `datetime`.
///
/// This information may vary within a single `timezone` to reflect daylight
/// saving time adjustments.
@unstable(feature = clocks-timezone)
record timezone-display {
/// The number of seconds difference between UTC time and the local
/// time of the timezone.
///
/// The returned value will always be less than 86400 which is the
/// number of seconds in a day (24*60*60).
///
/// In implementations that do not expose an actual time zone, this
/// should return 0.
utc-offset: s32,

/// The abbreviated name of the timezone to display to a user. The name
/// `UTC` indicates Coordinated Universal Time. Otherwise, this should
/// reference local standards for the name of the time zone.
///
/// In implementations that do not expose an actual time zone, this
/// should be the string `UTC`.
///
/// In time zones that do not have an applicable name, a formatted
/// representation of the UTC offset may be returned, such as `-04:00`.
name: string,

/// Whether daylight saving time is active.
///
/// In implementations that do not expose an actual time zone, this
/// should return false.
in-daylight-saving-time: bool,
}
}
46 changes: 46 additions & 0 deletions wit-0.3.0-draft/deps/clocks/wall-clock.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package wasi:clocks@0.3.0;
/// WASI Wall Clock is a clock API intended to let users query the current
/// time. The name "wall" makes an analogy to a "clock on the wall", which
/// is not necessarily monotonic as it may be reset.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A wall clock is a clock which measures the date and time according to
/// some external reference.
///
/// External references may be reset, so this clock is not necessarily
/// monotonic, making it unsuitable for measuring elapsed time.
///
/// It is intended for reporting the current date and time for humans.
@since(version = 0.3.0)
interface wall-clock {
/// A time and date in seconds plus nanoseconds.
@since(version = 0.3.0)
record datetime {
seconds: u64,
nanoseconds: u32,
}

/// Read the current value of the clock.
///
/// This clock is not monotonic, therefore calling this function repeatedly
/// will not necessarily produce a sequence of non-decreasing values.
///
/// The returned timestamps represent the number of seconds since
/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch],
/// also known as [Unix Time].
///
/// The nanoseconds field of the output is always less than 1000000000.
///
/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
@since(version = 0.3.0)
now: func() -> datetime;

/// Query the resolution of the clock.
///
/// The nanoseconds field of the output is always less than 1000000000.
@since(version = 0.3.0)
resolution: func() -> datetime;
}
11 changes: 11 additions & 0 deletions wit-0.3.0-draft/deps/clocks/world.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package wasi:clocks@0.3.0;

@since(version = 0.3.0)
world imports {
@since(version = 0.3.0)
import monotonic-clock;
@since(version = 0.3.0)
import wall-clock;
@unstable(feature = clocks-timezone)
import timezone;
}
62 changes: 62 additions & 0 deletions wit-0.3.0-draft/ip-name-lookup.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
@since(version = 0.3.0)
interface ip-name-lookup {
@since(version = 0.3.0)
use types.{ip-address};

/// Lookup error codes.
@since(version = 0.3.0)
enum error-code {
/// Unknown error
unknown,

/// Access denied.
///
/// POSIX equivalent: EACCES, EPERM
access-denied,

/// `name` is a syntactically invalid domain name or IP address.
///
/// POSIX equivalent: EINVAL
invalid-argument,

/// Name does not exist or has no suitable associated IP addresses.
///
/// POSIX equivalent: EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY
name-unresolvable,

/// A temporary failure in name resolution occurred.
///
/// POSIX equivalent: EAI_AGAIN
temporary-resolver-failure,

/// A permanent failure in name resolution occurred.
///
/// POSIX equivalent: EAI_FAIL
permanent-resolver-failure,
}

/// Resolve an internet host name to a list of IP addresses.
///
/// Unicode domain names are automatically converted to ASCII using IDNA encoding.
/// If the input is an IP address string, the address is parsed and returned
/// as-is without making any external requests.
///
/// See the wasi-socket proposal README.md for a comparison with getaddrinfo.
///
/// The results are returned in connection order preference.
///
/// This function never succeeds with 0 results. It either fails or succeeds
/// with at least one address. Additionally, this function never returns
/// IPv4-mapped IPv6 addresses.
///
/// The returned future will resolve to an error code in case of failure.
/// It will resolve to success once the returned stream is exhausted.
///
/// # References:
/// - <https://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html>
/// - <https://man7.org/linux/man-pages/man3/getaddrinfo.3.html>
/// - <https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo>
/// - <https://man.freebsd.org/cgi/man.cgi?query=getaddrinfo&sektion=3>
@since(version = 0.3.0)
resolve-addresses: func(name: string) -> result<list<ip-address>, error-code>;
}
Loading