diff options
| author | Manuel Schölling <[email protected]> | 2015-07-18 12:48:40 +0200 |
|---|---|---|
| committer | Manuel Schölling <[email protected]> | 2015-07-18 13:00:34 +0200 |
| commit | a43011d77c26b0a371565ffe284611091cfd1de3 (patch) | |
| tree | e88b02921780ee10e777678ea166f85da2939331 /openssl/src | |
| parent | Merge pull request #239 from jethrogb/topic/x509_extension_fix (diff) | |
| download | rust-openssl-a43011d77c26b0a371565ffe284611091cfd1de3.tar.xz rust-openssl-a43011d77c26b0a371565ffe284611091cfd1de3.zip | |
Fix probelms with DTLS when no packets are pending.
When using DTLS you might run into the situation where no packets
are pending, so SSL_read returns len=0. On a TLS connection this
means that the connection was closed, but on DTLS it does not
(a DTLS connection cannot be closed in the usual sense).
This commit fixes a bug introduced by c8d23f3.
Conflicts:
openssl/src/ssl/mod.rs
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/ssl/mod.rs | 36 | ||||
| -rw-r--r-- | openssl/src/ssl/tests.rs | 7 |
2 files changed, 41 insertions, 2 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 1338b1cb..bd077922 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -141,6 +141,25 @@ impl SslMethod { } } + unsafe fn from_raw(method: *const ffi::SSL_METHOD) -> Option<SslMethod> { + match method { + #[cfg(feature = "sslv2")] + x if x == ffi::SSLv2_method() => Some(SslMethod::Sslv2), + x if x == ffi::SSLv3_method() => Some(SslMethod::Sslv3), + x if x == ffi::TLSv1_method() => Some(SslMethod::Tlsv1), + x if x == ffi::SSLv23_method() => Some(SslMethod::Sslv23), + #[cfg(feature = "tlsv1_1")] + x if x == ffi::TLSv1_1_method() => Some(SslMethod::Tlsv1_1), + #[cfg(feature = "tlsv1_2")] + x if x == ffi::TLSv1_2_method() => Some(SslMethod::Tlsv1_2), + #[cfg(feature = "dtlsv1")] + x if x == ffi::DTLSv1_method() => Some(SslMethod::Dtlsv1), + #[cfg(feature = "dtlsv1_2")] + x if x == ffi::DTLSv1_2_method() => Some(SslMethod::Dtlsv1_2), + _ => None, + } + } + #[cfg(feature = "dtlsv1")] pub fn is_dtlsv1(&self) -> bool { *self == SslMethod::Dtlsv1 @@ -787,6 +806,13 @@ impl Ssl { ffi::SSL_pending(self.ssl) as usize } } + + pub fn get_ssl_method(&self) -> Option<SslMethod> { + unsafe { + let method = ffi::SSL_get_ssl_method(self.ssl); + SslMethod::from_raw(method) + } + } } macro_rules! make_LibSslError { @@ -888,8 +914,16 @@ impl<S: Read+Write> IndirectStream<S> { LibSslError::ErrorWantRead => { try_ssl_stream!(self.flush()); let len = try_ssl_stream!(self.stream.read(&mut self.buf[..])); + + if len == 0 { - self.ssl.get_rbio().set_eof(true); + let method = self.ssl.get_ssl_method(); + + if method.map(|m| m.is_dtls()).unwrap_or(false) { + return Ok(0); + } else { + self.ssl.get_rbio().set_eof(true); + } } else { try_ssl_stream!(self.ssl.get_rbio().write_all(&self.buf[..len])); } diff --git a/openssl/src/ssl/tests.rs b/openssl/src/ssl/tests.rs index 8401836d..3a8ffa2b 100644 --- a/openssl/src/ssl/tests.rs +++ b/openssl/src/ssl/tests.rs @@ -51,7 +51,7 @@ macro_rules! run_test( use std::net::TcpStream; use ssl; use ssl::SslMethod; - use ssl::{SslContext, SslStream, VerifyCallback}; + use ssl::{SslContext, Ssl, SslStream, VerifyCallback}; use ssl::SSL_VERIFY_PEER; use crypto::hash::Type::SHA256; use x509::X509StoreContext; @@ -86,6 +86,11 @@ run_test!(new_sslstream, |method, stream| { SslStream::connect_generic(&SslContext::new(method).unwrap(), stream).unwrap(); }); +run_test!(get_ssl_method, |method, _| { + let ssl = Ssl::new(&SslContext::new(method).unwrap()).unwrap(); + assert_eq!(ssl.get_ssl_method(), Some(method)); +}); + run_test!(verify_untrusted, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER, None); |