aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2015-06-25 22:47:53 -0700
committerSteven Fackler <[email protected]>2015-06-25 22:47:53 -0700
commitc8d23f37a40afbb7ccb768241e429a51f94b8e7a (patch)
tree2564730c1ad43a5527fb27623213fb778acda0c0
parentMerge pull request #225 from semmaz/mingw-build-fix (diff)
downloadrust-openssl-c8d23f37a40afbb7ccb768241e429a51f94b8e7a.tar.xz
rust-openssl-c8d23f37a40afbb7ccb768241e429a51f94b8e7a.zip
Fix EOF handling in retry wrapper
-rw-r--r--openssl-sys/src/lib.rs5
-rw-r--r--openssl/src/bio/mod.rs6
-rw-r--r--openssl/src/ssl/mod.rs10
-rw-r--r--openssl/src/ssl/tests.rs2
4 files changed, 18 insertions, 5 deletions
diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs
index a1817803..8437a80f 100644
--- a/openssl-sys/src/lib.rs
+++ b/openssl-sys/src/lib.rs
@@ -116,6 +116,7 @@ pub type PasswordCallback = extern "C" fn(buf: *mut c_char, size: c_int,
-> c_int;
pub const BIO_CTRL_EOF: c_int = 2;
+pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
pub const CRYPTO_LOCK: c_int = 1;
@@ -271,6 +272,10 @@ pub unsafe fn SSL_CTX_set_options(ssl: *mut SSL_CTX, op: c_long) -> c_long {
SSL_CTX_ctrl(ssl, SSL_CTRL_OPTIONS, op, ptr::null_mut())
}
+pub unsafe fn BIO_set_mem_eof_return(b: *mut BIO, v: c_int) {
+ BIO_ctrl(b, BIO_C_SET_BUF_MEM_EOF_RETURN, v as c_long, ptr::null_mut());
+}
+
pub unsafe fn SSL_CTX_get_options(ssl: *mut SSL_CTX) -> c_long {
SSL_CTX_ctrl(ssl, SSL_CTRL_OPTIONS, 0, ptr::null_mut())
}
diff --git a/openssl/src/bio/mod.rs b/openssl/src/bio/mod.rs
index ad2f65c2..e81694a4 100644
--- a/openssl/src/bio/mod.rs
+++ b/openssl/src/bio/mod.rs
@@ -56,6 +56,12 @@ impl MemBio {
pub unsafe fn get_handle(&self) -> *mut ffi::BIO {
self.bio
}
+
+ /// Sets the BIO's EOF state.
+ pub fn set_eof(&self, eof: bool) {
+ let v = if eof { 0 } else { -1 };
+ unsafe { ffi::BIO_set_mem_eof_return(self.bio, v); }
+ }
}
impl Read for MemBio {
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 98611064..a0f97b17 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -758,7 +758,7 @@ pub struct SslStream<S> {
impl SslStream<net::TcpStream> {
/// Create a new independently owned handle to the underlying socket.
pub fn try_clone(&self) -> io::Result<SslStream<net::TcpStream>> {
- Ok(SslStream {
+ Ok(SslStream {
stream: try!(self.stream.try_clone()),
ssl: self.ssl.clone(),
buf: self.buf.clone(),
@@ -851,14 +851,16 @@ impl<S: Read+Write> SslStream<S> {
try_ssl_stream!(self.flush());
let len = try_ssl_stream!(self.stream.read(&mut self.buf[..]));
if len == 0 {
- return Ok(0);
+ self.ssl.get_rbio().set_eof(true);
+ } else {
+ try_ssl_stream!(self.ssl.get_rbio().write_all(&self.buf[..len]));
}
- try_ssl_stream!(self.ssl.get_rbio().write_all(&self.buf[..len]));
}
LibSslError::ErrorWantWrite => { try_ssl_stream!(self.flush()) }
LibSslError::ErrorZeroReturn => return Err(SslSessionClosed),
LibSslError::ErrorSsl => return Err(SslError::get()),
- err => panic!("unexpected error {:?}", err),
+ LibSslError::ErrorSyscall if ret == 0 => return Ok(0),
+ err => panic!("unexpected error {:?} with ret {}", err, ret),
}
}
}
diff --git a/openssl/src/ssl/tests.rs b/openssl/src/ssl/tests.rs
index ec4f2b01..028d9f09 100644
--- a/openssl/src/ssl/tests.rs
+++ b/openssl/src/ssl/tests.rs
@@ -369,7 +369,7 @@ fn test_pending() {
let pending = stream.pending();
let len = stream.read(&mut buf[1..]).unwrap();
assert_eq!(pending, len);
-}
+}
/// Tests that connecting with the client using NPN, but the server not does not
/// break the existing connection behavior.