feat(p3): implement wasi:tls by badeend · Pull Request #12834 · bytecodealliance/wasmtime
This implements the wasi:tls P3 host, superseding #12174 (shoutout @rvolosatovs for laying the groundwork).
Builds on the existing TlsProvider abstraction already used by the P2 implementation, delegating async I/O and waker marshalling to the established tokio TLS wrappers (tokio-rustls, tokio-native-tls, tokio-openssl). This means it runs on all three backends.
Quick overview
The Connector resource holds a Shared<Deferred<TlsStream>> which represents a lazily-resolved handle to a TLS stream. When the guest calls send and receive, pipes are set up between the guest streams and the (not-yet-known) TLS stream. When connect is called, the TLS handshake is performed; on success the connected TlsStream is installed into the shared handle, unblocking both the read and write sides simultaneously. On failure, a Closed sentinel is installed instead, which will wake up the reader/writers with an error.
The close_notify shutdown sequence is driven by a component-model task spawned on the Store. The task sits idle throughout the entire connection and waits for the guest to close the cleartext send stream. At that point it calls .shutdown().await on the TLS stream to emit and flush the close_notify alert.
Future improvements
For now I've focused on portability and correctness, leaving as much of the tricky bits to external packages. Ideally:
- We shouldn't need to spawn tasks and instead somehow drive the close_notify sequence from within the StreamProducer returned by
send. - We shouldn't need the
pipe()and its buffer when using the rustls backend. rustls provides direct read/write access into its internal buffer, so thepipe()introduces a redundant intermediate copy. The other backends don't offer that possibility, though. So I don't know what the best approach is yet on this point.