aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/error.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2017-11-04 13:32:18 -0700
committerSteven Fackler <[email protected]>2017-11-04 13:32:18 -0700
commita1a3219483977bef2c059b1681932d95eb20180e (patch)
tree9a999676203740b1aecaf5f29c33f27a49ab3094 /openssl/src/ssl/error.rs
parentMerge pull request #747 from BrianOn99/symm (diff)
downloadrust-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.rs27
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> {