aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorManuel Schölling <[email protected]>2015-07-18 12:48:40 +0200
committerManuel Schölling <[email protected]>2015-07-18 13:00:34 +0200
commita43011d77c26b0a371565ffe284611091cfd1de3 (patch)
treee88b02921780ee10e777678ea166f85da2939331 /openssl/src
parentMerge pull request #239 from jethrogb/topic/x509_extension_fix (diff)
downloadrust-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.rs36
-rw-r--r--openssl/src/ssl/tests.rs7
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);