diff options
| author | Steven Fackler <[email protected]> | 2017-11-04 13:32:18 -0700 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2017-11-04 13:32:18 -0700 |
| commit | a1a3219483977bef2c059b1681932d95eb20180e (patch) | |
| tree | 9a999676203740b1aecaf5f29c33f27a49ab3094 /openssl/src/ssl/error.rs | |
| parent | Merge pull request #747 from BrianOn99/symm (diff) | |
| download | rust-openssl-a1a3219483977bef2c059b1681932d95eb20180e.tar.xz rust-openssl-a1a3219483977bef2c059b1681932d95eb20180e.zip | |
Handle local retries
OpenSSL can return SSL_ERROR_WANT_READ even on blocking sockets after
renegotiation or heartbeats. Heartbeats ignore the flag that normally
makes these things handled internally anyway on 1.0.2. To handle this
more properly, we now have a special error type we use to signal this
event. The `Read` and `Write` implementation automatically retry in this
situation since that's what you normally want. People can use `ssl_read`
and `ssl_write` if they want the lower level control.
Closes #760
Diffstat (limited to 'openssl/src/ssl/error.rs')
| -rw-r--r-- | openssl/src/ssl/error.rs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/openssl/src/ssl/error.rs b/openssl/src/ssl/error.rs index db78e2c8..2244fd7f 100644 --- a/openssl/src/ssl/error.rs +++ b/openssl/src/ssl/error.rs @@ -66,6 +66,33 @@ impl From<ErrorStack> for Error { } } +/// An error indicating that the operation can be immediately retried. +/// +/// OpenSSL's [`SSL_read`] and [`SSL_write`] functions can return `SSL_ERROR_WANT_READ` even when +/// the underlying socket is performing blocking IO in certain cases. When this happens, the +/// the operation can be immediately retried. +/// +/// To signal this event, the `io::Error` inside of [`Error::WantRead`] will be constructed around +/// a `RetryError`. +/// +/// [`SSL_read`]: https://www.openssl.org/docs/manmaster/man3/SSL_read.html +/// [`SSL_write`]: https://www.openssl.org/docs/manmaster/man3/SSL_write.html +/// [`Error::WantRead`]: enum.Error.html#variant.WantRead +#[derive(Debug)] +pub struct RetryError; + +impl fmt::Display for RetryError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str(error::Error::description(self)) + } +} + +impl error::Error for RetryError { + fn description(&self) -> &str { + "operation must be retried" + } +} + /// An error or intermediate state after a TLS handshake attempt. #[derive(Debug)] pub enum HandshakeError<S> { |