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

Sync changes from wasmtime repo #70

Merged
merged 3 commits into from
Nov 11, 2023

Conversation

badeend
Copy link
Collaborator

@badeend badeend commented Nov 8, 2023

TCP

  • Allow accept() to return transient errors.
    The original provision was added to align with preview3 streams that may only fail once. However, after discussing with Dan Gohman, we came to the conclusion that a stream of result<> could do the trick fine too.
    Fixes: How to report ECONNABORTED errors from accept? #22
  • Fold ephemeral-ports-exhausted into address-in-use. There is no cross-platform way to know the distinction between them.
  • Remove concurrency-conflict clutter,
    and just document it to be always possible.
  • Simplify "not supported", "invalid argument" and "invalid state" error cases.
    There is a myriad of reasons why an argument might be invalid or an operation might be not supported. But there is few cross platform consistency in which of those error cases result in which error codes. Many wasi-sockets codes were unnecessarily detailed and had no standardized equivalent in POSIX, so wasi-libc will probably just map them all back into a single EOPNOTSUPP or EINVAL or ...
  • Remove create-tcp/udp-socket not supported errors.
    These stem from back when the entire wasi-sockets proposal was one big single thing. In this day and age, when an implementation doesn't want to support TCP and/or UDP, it can simply not implement that interface, rather than returning an error at runtime.
  • Document that connect may return ECONNABORTED
  • Document the set of socket options that are inherited through accept
  • Clarify connect failure state:
	POSIX mentions:
	> If connect() fails, the state of the socket is unspecified. Conforming applications should
	> close the file descriptor and create a new socket before attempting to reconnect.

	WASI prescribes the following behavior:
	- If `connect` fails because an input/state validation error, the socket should remain usable.
	- If a connection was actually attempted but failed, the socket should become unusable for further network communication.
  • Clarify local-address behavior on unbound socket:
POSIX mentions:
> If the socket has not been bound to a local name, the value
> stored in the object pointed to by `address` is unspecified.

WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet.
  • Remove TCP_NODELAY for the time being. The semantics of TCP_NODELAY (and TCP_CORK for that matter) and its effects on the output-stream needs to investigated and specified. I don't expect there to be anything insurmountable. Its just that I haven't had the time to do so yet and I can't promise to have it done before the stabilization Preview2. So, in order to get wasi-sockets ready for Preview2, it was discussed to temporarily remove no-delay and reevaluate its inclusion before Preview3.
  • Add support for the socket options:
    • is-listening (SO_ACCEPTCONN)
    • keep-alive-count (TCP_KEEPCNT)
    • keep-alive-idle-time (TCP_KEEPIDLE)
    • keep-alive-interval (TCP_KEEPINTVL)
  • Rename keep-alive to keep-alive-enabled, since it is no longer the only "keep-alive"-related option.
  • Rename (set-)unicast-hop-limit to (set-)hop-limit, because the "unicast" qualifier is redundant for TCP.
  • Clarify what implementations must and must not accept as valid inputs for:
    • set-listen-backlog-size
    • set-hop-limit
    • set-receive-buffer-size
    • set-send-buffer-size

UDP

  • Introduce new incoming-datagram-stream and outgoing-datagram-stream types and moved receive and send methods to those respectively. These streams are returned by stream and can be individually subscribed to. This resolves a design issue where a UDP server would end up in a spin loop because receive returned EWOULDBLOCK but poll_* always returned immediately because the socket was ready for sending. In this new setup, users can poll each direction separately. Fixes UDP subscribe can't be split between read/write #64
  • Dropped the network parameter from the connect call, because bind is now required to perform IO.
  • Enable send-like behaviour by making outgoing-datagram::remote-address optional. Fixes UDP: Enable send-like behaviour #57
  • Clarify what implementations must and must not accept as valid inputs for:
    • set-unicast-hop-limit
    • set-receive-buffer-size
    • set-send-buffer-size

IP name lookup

  • Remove the non-essential parameters for now. Post-preview2 these can be reevaluated again.
  • Lift the restriction against parsing IP addresses. Before, implementations still needed to parse IP addresses to decide whether or not to return an error.

- Allow `accept()` to return transient errors.
  The original provision was added to align with preview3 streams that may only fail once. However, after discussing with Dan Gohman, we came to the conclusion that a `stream` of `result<>` could do the trick fine too.
    Fixes: WebAssembly#22
- Fold `ephemeral-ports-exhausted` into `address-in-use`. There is no cross-platform way to know the distinction between them.
- Remove `concurrency-conflict` clutter,
  and just document it to be always possible.
- Simplify "not supported", "invalid argument" and "invalid state" error cases.
  There is a myriad of reasons why an argument might be invalid or an operation might be not supported. But there is few cross platform consistency in which of those error cases result in which error codes. Many wasi-sockets codes were unnecessarily detailed and had no standardized equivalent in POSIX, so wasi-libc will probably just map them all back into a single EOPNOTSUPP or EINVAL or ...
- Remove create-tcp/udp-socket not supported errors.
  These stem from back when the entire wasi-sockets proposal was one big single thing. In this day and age, when an implementation doesn't want to support TCP and/or UDP, it can simply _not_ implement that interface, rather than returning an error at runtime.
- Document that `connect` may return ECONNABORTED
- Document the set of socket options that are inherited through `accept`
- Clarify `connect` failure state:
```md
	POSIX mentions:
	> If connect() fails, the state of the socket is unspecified. Conforming applications should
	> close the file descriptor and create a new socket before attempting to reconnect.

	WASI prescribes the following behavior:
	- If `connect` fails because an input/state validation error, the socket should remain usable.
	- If a connection was actually attempted but failed, the socket should become unusable for further network communication.
```
- Clarify `local-address` behavior on unbound socket:
```md
POSIX mentions:
> If the socket has not been bound to a local name, the value
> stored in the object pointed to by `address` is unspecified.

WASI is stricter and requires `local-address` to return `not-bound` when the socket hasn't been bound yet.
```
- Remove TCP_NODELAY for the time being. The semantics of TCP_NODELAY (and TCP_CORK for that matter) and its effects on the output-stream needs to investigated and specified. I don't expect there to be anything insurmountable. Its just that I haven't had the time to do so yet and I can't promise to have it done before the stabilization Preview2. So, in order to get wasi-sockets ready for Preview2, it was discussed to temporarily remove `no-delay` and reevaluate its inclusion before Preview3.

- Introduce new `incoming-datagram-stream` and `outgoing-datagram-stream` types and moved `receive` and `send` methods to those respectively. These streams are returned by `stream` and can be individually subscribed to. This resolves a design issue where a UDP server would end up in a spin loop because `receive` returned EWOULDBLOCK but poll_* always returned immediately because the socket was ready for sending. In this new setup, users can poll each direction separately. Fixes WebAssembly#64
- Dropped the `network` parameter from the `connect` call, because `bind` is now _required_ to perform IO.
- Enable send-like behaviour by making `outgoing-datagram::remote-address` optional. Fixes WebAssembly#57

- Remove the non-essential parameters for now. Post-preview2 these can be reevaluated again.
- Lift the restriction against parsing IP addresses. Before, implementations still needed to parse IP addresses to decide whether or not to return an error.
@pchickey
Copy link
Contributor

pchickey commented Nov 11, 2023

I missed that this PR hadn't landed yet before tagging the RC in #71, so I reverted that PR in #72. Can we merge this as soon as possible, and I'll continue with the release candidate tagging then?

- Add support for the socket options:
  - `is-listening` (`SO_ACCEPTCONN`)
  - `keep-alive-count` (`TCP_KEEPCNT`)
  - `keep-alive-idle-time` (`TCP_KEEPIDLE`)
  - `keep-alive-interval` (`TCP_KEEPINTVL`)
- Tweak existing socket options:
  - Rename `keep-alive` to `keep-alive-enabled`, since it is no longer the only "keep-alive"-related option.
  - Rename `(set-)unicast-hop-limit` to `(set-)hop-limit`, because the "unicast" qualifier is redundant for TCP.
  - Be stricter in that `0` is not a valid value for:
    - `set-listen-backlog-size`
    - `set-hop-limit`
    - `set-receive-buffer-size`
    - `set-send-buffer-size`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UDP subscribe can't be split between read/write How to report ECONNABORTED errors from accept?
2 participants