aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <[email protected]>2016-04-04 15:20:13 -0700
committerJoe Wilm <[email protected]>2016-04-04 16:08:38 -0700
commitc4b7b85d99b3e9ca154ba03be67bd6281825973c (patch)
tree018fbec8c85dfa250d16d0416186aced34d13e37
parentCleanup (diff)
downloadrust-openssl-c4b7b85d99b3e9ca154ba03be67bd6281825973c.tar.xz
rust-openssl-c4b7b85d99b3e9ca154ba03be67bd6281825973c.zip
Add safe wrapper BioMethod for ffi::BIO_METHOD
Adds a wrapper for ffi::BIO_METHOD located at ssl::bio::BioMethod. This enables SslStream to be Send without doing an unsafe impl on the ffi struct.
-rw-r--r--openssl/src/ssl/bio.rs41
-rw-r--r--openssl/src/ssl/mod.rs6
2 files changed, 29 insertions, 18 deletions
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs
index 5accb3e5..4adbfbe2 100644
--- a/openssl/src/ssl/bio.rs
+++ b/openssl/src/ssl/bio.rs
@@ -1,5 +1,5 @@
use libc::{c_char, c_int, c_long, c_void, strlen};
-use ffi::{BIO, BIO_METHOD, BIO_CTRL_FLUSH, BIO_TYPE_NONE, BIO_new};
+use ffi::{self, BIO, BIO_CTRL_FLUSH, BIO_TYPE_NONE, BIO_new};
use ffi_extras::{BIO_clear_retry_flags, BIO_set_retry_read, BIO_set_retry_write};
use std::any::Any;
use std::io;
@@ -17,19 +17,30 @@ pub struct StreamState<S> {
pub panic: Option<Box<Any + Send>>,
}
-pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BIO_METHOD>), SslError> {
- let method = Arc::new(BIO_METHOD {
- type_: BIO_TYPE_NONE,
- name: b"rust\0".as_ptr() as *const _,
- bwrite: Some(bwrite::<S>),
- bread: Some(bread::<S>),
- bputs: Some(bputs::<S>),
- bgets: None,
- ctrl: Some(ctrl::<S>),
- create: Some(create),
- destroy: Some(destroy::<S>),
- callback_ctrl: None,
- });
+/// Safe wrapper for BIO_METHOD
+pub struct BioMethod(ffi::BIO_METHOD);
+
+impl BioMethod {
+ pub fn new<S: Read + Write>() -> BioMethod {
+ BioMethod(ffi::BIO_METHOD {
+ type_: BIO_TYPE_NONE,
+ name: b"rust\0".as_ptr() as *const _,
+ bwrite: Some(bwrite::<S>),
+ bread: Some(bread::<S>),
+ bputs: Some(bputs::<S>),
+ bgets: None,
+ ctrl: Some(ctrl::<S>),
+ create: Some(create),
+ destroy: Some(destroy::<S>),
+ callback_ctrl: None,
+ })
+ }
+}
+
+unsafe impl Send for BioMethod {}
+
+pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BioMethod>), SslError> {
+ let method = Arc::new(BioMethod::new::<S>());
let state = Box::new(StreamState {
stream: stream,
@@ -38,7 +49,7 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BIO_METHOD>), Ss
});
unsafe {
- let bio = try_ssl_null!(BIO_new(&*method));
+ let bio = try_ssl_null!(BIO_new(&method.0));
(*bio).ptr = Box::into_raw(state) as *mut _;
(*bio).init = 1;
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index ebaffb18..7b5cf492 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -35,6 +35,8 @@ mod bio;
#[cfg(test)]
mod tests;
+use self::bio::BioMethod;
+
#[doc(inline)]
pub use ssl::error::Error;
@@ -1117,12 +1119,10 @@ make_LibSslError! {
/// A stream wrapper which handles SSL encryption for an underlying stream.
pub struct SslStream<S> {
ssl: Ssl,
- _method: Arc<ffi::BIO_METHOD>, // NOTE: this *must* be after the Ssl field so things drop right
+ _method: Arc<BioMethod>, // NOTE: this *must* be after the Ssl field so things drop right
_p: PhantomData<S>,
}
-unsafe impl<S: Send> Send for SslStream<S> {}
-
/// # Deprecated
///
/// This method does not behave as expected and will be removed in a future