aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-11-11 15:10:30 +0000
committerSteven Fackler <[email protected]>2016-11-11 15:10:30 +0000
commit898e7f02df5ca722f4b4b42a8e116f96f72b9452 (patch)
tree8a55b2b556c11d091d54ea38fb50b907c007017c /openssl/src
parentUpdate to 1.1.0c for tests (diff)
downloadrust-openssl-898e7f02df5ca722f4b4b42a8e116f96f72b9452.tar.xz
rust-openssl-898e7f02df5ca722f4b4b42a8e116f96f72b9452.zip
Fix EOF detection
See https://github.com/openssl/openssl/issues/1903 for details
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/ssl/mod.rs54
1 files changed, 35 insertions, 19 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 1e7efc63..c92bf56b 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -1323,10 +1323,14 @@ impl<S: Read + Write> SslStream<S> {
/// value will identify if OpenSSL is waiting on read or write readiness.
pub fn ssl_read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
let ret = self.ssl.read(buf);
- if ret >= 0 {
+ if ret > 0 {
Ok(ret as usize)
} else {
- Err(self.make_error(ret))
+ match self.make_error(ret) {
+ // Don't treat unexpected EOFs as errors when reading
+ Error::Stream(ref e) if e.kind() == io::ErrorKind::ConnectionAborted => Ok(0),
+ e => Err(e),
+ }
}
}
@@ -1336,7 +1340,7 @@ impl<S: Read + Write> SslStream<S> {
/// value will identify if OpenSSL is waiting on read or write readiness.
pub fn ssl_write(&mut self, buf: &[u8]) -> Result<usize, Error> {
let ret = self.ssl.write(buf);
- if ret >= 0 {
+ if ret > 0 {
Ok(ret as usize)
} else {
Err(self.make_error(ret))
@@ -1373,19 +1377,38 @@ impl<S> SslStream<S> {
ffi::SSL_ERROR_SYSCALL => {
let errs = ErrorStack::get();
if errs.errors().is_empty() {
- if ret == 0 {
- Error::Stream(io::Error::new(io::ErrorKind::ConnectionAborted,
- "unexpected EOF observed"))
- } else {
- Error::Stream(self.get_bio_error())
+ match self.get_bio_error() {
+ Some(err) => Error::Stream(err),
+ None => {
+ Error::Stream(io::Error::new(io::ErrorKind::ConnectionAborted,
+ "unexpected EOF observed"))
+ }
}
} else {
Error::Ssl(errs)
}
}
ffi::SSL_ERROR_ZERO_RETURN => Error::ZeroReturn,
- ffi::SSL_ERROR_WANT_WRITE => Error::WantWrite(self.get_bio_error()),
- ffi::SSL_ERROR_WANT_READ => Error::WantRead(self.get_bio_error()),
+ ffi::SSL_ERROR_WANT_WRITE => {
+ let err = match self.get_bio_error() {
+ Some(err) => err,
+ None => {
+ io::Error::new(io::ErrorKind::Other,
+ "BUG: got an SSL_ERROR_WANT_WRITE with no error in the BIO")
+ }
+ };
+ Error::WantWrite(err)
+ },
+ ffi::SSL_ERROR_WANT_READ => {
+ let err = match self.get_bio_error() {
+ Some(err) => err,
+ None => {
+ io::Error::new(io::ErrorKind::Other,
+ "BUG: got an SSL_ERROR_WANT_WRITE with no error in the BIO")
+ }
+ };
+ Error::WantRead(err)
+ },
err => {
Error::Stream(io::Error::new(io::ErrorKind::InvalidData,
format!("unexpected error {}", err)))
@@ -1399,15 +1422,8 @@ impl<S> SslStream<S> {
}
}
- fn get_bio_error(&mut self) -> io::Error {
- let error = unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) };
- match error {
- Some(error) => error,
- None => {
- io::Error::new(io::ErrorKind::Other,
- "BUG: got an ErrorSyscall without an error in the BIO?")
- }
- }
+ fn get_bio_error(&mut self) -> Option<io::Error> {
+ unsafe { bio::take_error::<S>(self.ssl.get_raw_rbio()) }
}
/// Returns a reference to the underlying stream.