pub struct SslStream<S: Unpin> { /* private fields */ }Expand description
An asynchronous version of openssl::ssl::SslStream.
§Buffered output
OpenSSL writes into a buffer, from which the transport takes what it can. As with a
BufWriter, a write completes once OpenSSL has encrypted its bytes, and
a handshake call can complete with its last flight still buffered. Buffered output goes out
with later writes, flushes and closes, and with reads, peeks and handshake calls that read from
the transport, which flush it before they wait for the peer. flush
returns once everything was sent and the transport flushed. close
the stream rather than drop it, or close or flush its transport directly, or buffered output is
lost.
A write first waits for buffered output, and for a transport flush that OpenSSL asked for:
until then it returns Pending without writing, so it can be dropped or polled again with
other bytes. Each write hands OpenSSL at most 16 KiB. Reads, peeks and handshake calls do not
wait for output, so a peer that stops reading until it is read from cannot deadlock the
stream, unless more than 64 KiB is waiting (what OpenSSL wrote by itself while reading or
handshaking, on top of what writes left).
§Errors
A transport error while sending buffered output is returned by the write, flush or close that sends it, or by a call that would otherwise wait for the peer, who may be waiting for that output. A write whose own bytes the transport refuses still completes: OpenSSL wrote them. The output stays buffered and the error is not kept: a later call reports it if it recurs, so a transient error loses nothing.
Reads and writes return transport errors as they were, without passing them to OpenSSL.
Peeks, handshake calls and read_early_data return them through
OpenSSL, inside an ssl::Error. OpenSSL 4 then fails the session, unless the error is
WouldBlock or NotConnected,
which rust-openssl asks it to retry. LibreSSL replaces the error with its own, and may report
the transport error again later as the cause of an unrelated end of stream.
write_early_data never returns them.
A transport end without close_notify after the handshake reads as the end of the stream on
OpenSSL 1.1.1, 3.x and LibreSSL, as with rust-openssl’s own streams. On OpenSSL 4 it is an
error, and a close then fails too, unless the session has SslOptions::IGNORE_UNEXPECTED_EOF.
A transport end or a close_notify during a handshake that a read drives, renegotiation
included, is always an error.
§Closing
A close sends buffered output, writes close_notify once, sends it and closes the transport.
A send error is returned with the transport left open, so that closing again retries; dropping
the stream releases the transport. After the peer’s close_notify, failing to send ours is no
error. Without a session to close (no handshake, a handshake or post-handshake exchange in
progress, or a failed session), a close closes the transport and returns an error: the
transport’s if closing it failed, else OpenSSL’s reason, if any. So does every later close. No
write goes out after a close.
§Tasks
Waiting tasks are woken when the transport is ready or another task’s call failed to send, and those waiting for the peer also when another task’s call read from the transport. Keep one waker per task: each new one costs an extra wake, and more than 32 tasks waiting at once keep waking each other.
A panic in the transport poisons the stream: every later call that uses the transport fails.
Implementations§
Source§impl<S> SslStream<S>
impl<S> SslStream<S>
Sourcepub fn new(ssl: Ssl, stream: S) -> Result<Self, ErrorStack>
pub fn new(ssl: Ssl, stream: S) -> Result<Self, ErrorStack>
Like SslStream::new.
Sourcepub fn poll_connect(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), Error>>
pub fn poll_connect( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>
Like SslStream::connect.
It can complete while its last flight is still buffered, and returns transport errors through OpenSSL, as described.
Sourcepub async fn connect(self: Pin<&mut Self>) -> Result<(), Error>
pub async fn connect(self: Pin<&mut Self>) -> Result<(), Error>
A convenience method wrapping poll_connect.
Sourcepub fn poll_accept(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), Error>>
pub fn poll_accept( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>
Like SslStream::accept.
It can complete while its last flight is still buffered, and returns transport errors through OpenSSL, as described.
Sourcepub async fn accept(self: Pin<&mut Self>) -> Result<(), Error>
pub async fn accept(self: Pin<&mut Self>) -> Result<(), Error>
A convenience method wrapping poll_accept.
Sourcepub fn poll_do_handshake(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), Error>>
pub fn poll_do_handshake( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<(), Error>>
Like SslStream::do_handshake.
It can complete while its last flight is still buffered, and returns transport errors through OpenSSL, as described.
Sourcepub async fn do_handshake(self: Pin<&mut Self>) -> Result<(), Error>
pub async fn do_handshake(self: Pin<&mut Self>) -> Result<(), Error>
A convenience method wrapping poll_do_handshake.
Sourcepub fn poll_peek(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, Error>>
pub fn poll_peek( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize, Error>>
Like SslStream::ssl_peek.
Like a read, it sends buffered output without waiting for it below the limit, and it returns transport errors through OpenSSL, as described.
Sourcepub async fn peek(self: Pin<&mut Self>, buf: &mut [u8]) -> Result<usize, Error>
pub async fn peek(self: Pin<&mut Self>, buf: &mut [u8]) -> Result<usize, Error>
A convenience method wrapping poll_peek.
Sourcepub fn poll_read_early_data(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, Error>>
pub fn poll_read_early_data( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<Result<usize, Error>>
Like SslStream::read_early_data, except that a
handshake failure, or a transport failure or end, right after the early data is an error,
not the end of early data (Ok(0)). After the end of early data, it advances the handshake
without waiting; accept finishes it.
An empty buffer returns Ok(0) if no early data was accepted or it is over, and an error
once an early-data record arrives.
Requires OpenSSL 1.1.1 or newer (LibreSSL only has stubs for early data).
Sourcepub async fn read_early_data(
self: Pin<&mut Self>,
buf: &mut [u8],
) -> Result<usize, Error>
pub async fn read_early_data( self: Pin<&mut Self>, buf: &mut [u8], ) -> Result<usize, Error>
A convenience method wrapping poll_read_early_data.
Requires OpenSSL 1.1.1 or newer.
Sourcepub fn poll_write_early_data(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, Error>>
pub fn poll_write_early_data( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize, Error>>
Like SslStream::write_early_data.
Like a write, it first waits for buffered output, and writes at
most 16 KiB. Unlike a write, it goes on after a transport error, which it cannot return: an
ssl::Error only carries one that OpenSSL read, and SSL_write_early_data never reads.
The next call that sends reports it if it recurs. Until then, the output it leaves is
bounded by the session’s maximum early data on a client, and only by the caller on a
server.
Requires OpenSSL 1.1.1 or newer (LibreSSL only has stubs for early data).
Sourcepub async fn write_early_data(
self: Pin<&mut Self>,
buf: &[u8],
) -> Result<usize, Error>
pub async fn write_early_data( self: Pin<&mut Self>, buf: &[u8], ) -> Result<usize, Error>
A convenience method wrapping poll_write_early_data.
Requires OpenSSL 1.1.1 or newer.
Source§impl<S: Unpin> SslStream<S>
impl<S: Unpin> SslStream<S>
Sourcepub fn ssl(&self) -> &SslRef
pub fn ssl(&self) -> &SslRef
Returns a shared reference to the Ssl object associated with this stream.
Sourcepub fn get_mut(&mut self) -> &mut S
pub fn get_mut(&mut self) -> &mut S
Returns a mutable reference to the underlying stream.
§Warning
Reading from or writing to the underlying stream directly will corrupt the TLS session, and closing or flushing it directly misses the buffered output.
Sourcepub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut S>
pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut S>
Returns a pinned mutable reference to the underlying stream.
§Warning
Reading from or writing to the underlying stream directly will corrupt the TLS session, and closing or flushing it directly misses the buffered output.
Trait Implementations§
Source§impl<S> AsyncRead for SslStream<S>
impl<S> AsyncRead for SslStream<S>
Source§impl<S> AsyncWrite for SslStream<S>
impl<S> AsyncWrite for SslStream<S>
Source§fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize>>
fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>
buf into the object. Read more