* add: take_io method to LazyConfigAcceptor
The `take_io` method can be used to take back ownership of the client IO stream when an error occurs
during clientHello handshake.
An example of this is when a client tries to connect to an TLS socket expecting it to be plain text
connection. In this case take_io can be used to send a 400 response, "The plain HTTP request was
sent to HTTPS port", back to the client.
* rename test lazy_config_acceptor_take_io
* deps: update to rustls 0.21.0.
This commit updates tokio-rustls to use the freshly released Rustls
0.21.0 release tag, and the rustls-webpki fork of webpki.
* tests: improve server wait in early data test.
Previously the `test_0rtt` test had a hardcoded 1s sleep waiting for an
`openssl s_server` process to become ready.
If 1s waiting wasn't long enough, the test could fail with an error
like:
```
Error: Os { code: 10061, kind: ConnectionRefused, message: "No
connection could be made because the target machine actively refused
it." }
```
This commit replaces the hardcoded sleep with a sleep loop that
gradually increases the delay time up to a fixed maximum. This makes the
test run faster when the server is ready quickly and prevents an error
if it takes longer than 1s to stabilize.
* version: 0.23.4 -> 0.24.0
* Fix domain name in early-data test
* Run early data test in CI
* Add missing wake call
* Workaround: write to OpenSSL's input
This is necessary to work around an issue that only appears on Windows.
* Don't rerun other tests in CI
* implement AsRawFd for both tokio-rustls and tokio-native-tls TlsStream<S>
* implement windows' AsRawHandle
* typo in cfg(windows)
* use RawSocket, not RawHandle
* implement AsRawFd & AsRawSocket for tokio_rustls::client::TlsStream and tokio_rustls::TlsStream enum
* update to rustls 0.20
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* track simple renamings in rustls
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* use reader/writer methods
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* fix find and replace
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* use rustls-pemfile crate for pem file parsing
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* update misc api breakage
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* update client example with api changes
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* update server example with new APIs
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* update test_stream test
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* update tests to use new APIs
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* rm unused imports
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* handle rustls `WouldBlock` on eof
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* expect rustls to return wouldblock in tests
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* i think this is *actually* the right EOF behavior
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* bump version
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* okay that seems to fix it
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* update to track builder API changes
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* actually shutdown read side on close notify
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
* Further updates to rustls 0.20 (#68)
* Adapt to RootCertStore API changes
* Handle UnexpectedEof errors
* Rename would_block to io_pending
* Try to make badssl test failures more verbose
* Rebuild AsyncRead impl
* Upgrade to current rustls
* Revert to using assert!()
* Update to rustls 0.20
* Forward rustls features
Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
* native-tls: fix use of non-fmt panic in tests
* fix some misc. clippy lints
This branch fixes a number of lints. The most important one was the use
of a non-`format_args!` expression in a `panic!` macro, which generates
a compiler warning in recent Rust toolchains, which is breaking the CI
`cargo check` run on PR #64.
While I was here, I also fixed some miscellaneous Clippy lints, mostly
in tests. These include:
* Use of `clone()` on `SocketAddr`s (which implement `Copy`)
* Unnecessary single-path-segment imports (which probably used to be
`extern crate`s in earlier Rust?)
* `'static` lifetimes in `const` type annotations (`const`s always have
the `'static` lifetime)
None of these were breaking the build on CI, but I figured I'd address
them while I was fixing other lints.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
After this commit, this crate will support using TLS streams in a
half-closed state. Note that the TLS 1.3 spec in RFC 8446
says this should be supported:
```
Each party MUST send a "close_notify" alert before closing its write
side of the connection, unless it has already sent some error alert.
This does not have any effect on its read side of the connection. Note
that this is a change from versions of TLS prior to TLS 1.3 in which
implementations were required to react to a "close_notify" by discarding
pending writes and sending an immediate "close_notify" alert of their
own. That previous requirement could cause truncation in the read side.
Both parties need not wait to receive a "close_notify" alert before
closing their read side of the connection, though doing so would
introduce the possibility of truncation.
```
https://tools.ietf.org/html/rfc8446#page-87
The `rustls` crate raises such a clean closure of a
[`ClientSession`](https://docs.rs/rustls/0.18.0/rustls/struct.ClientSession.html#impl-Read)
or
[`ServerSesson`](https://docs.rs/rustls/0.18.0/rustls/struct.ServerSession.html#impl-Read)
read-side with `ErrorKind::ConnectionAborted`.
This crate's `TlsState` struct already encodes support for the
half-closed states `TlsState::ReadShutdown` and
`TlsState::WriteShutdown`, in addition to `TlsState::FullyShutdown`.
However, the current behavior of the `AsyncRead` implementation is that
it unconditionally shuts-down the write-half of a connection after the
read-half closes cleanly with `ErrorKind::ConnectionAborted`.
This change removes the `stream.session.send_close_notify()` and
`this.state.shutdown_write()` calls from `poll_read()`. Note that
`stream.session.send_close_notify()` is still called in
`poll_shutdown()`, which the application calls to cleanly shutdown the
write-half.
I highly suspect the logic of this can be simplified and cleaned up
further. Minimally, the edited match statement now has two identical
branches which could be combined into one. Additionally, perhaps the
`Stream` implementation should simply return `Ok(0)` for this case in
its implementation of
[`tokio::io::AsyncRead`](https://docs.rs/tokio/0.2/tokio/io/trait.AsyncRead.html),
since that's the defined way to indicate clean closure with EOF from
`AsyncRead`. However, I want to make the minimal changes and have them
reviewed for logical correctness first.
Co-authored-by: Braden Ehrat <braden@cloudflare.com>