Commit 3bcb977b authored by Steven Fackler's avatar Steven Fackler
Browse files

Merge pull request #372 from jwilm/safe-bio-method-wrapper

Add safe wrapper BioMethod for ffi::BIO_METHOD
parents 02f114fa c4b7b85d
Loading
Loading
Loading
Loading
+26 −15
Original line number Diff line number Diff line
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,8 +17,12 @@ 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 {
/// 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>),
@@ -29,7 +33,14 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BIO_METHOD>), Ss
                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;

+3 −3
Original line number Diff line number Diff line
@@ -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