diff options
| author | Steven Fackler <[email protected]> | 2015-12-09 21:43:02 -0800 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2015-12-09 21:43:02 -0800 |
| commit | 9ee6f1c5785bb170c04a825ef173d4e336c957b2 (patch) | |
| tree | dc5af83adc869786753164c40fa54ba55ff48b89 /openssl/src/ssl/bio.rs | |
| parent | Custom BIO infrastructure (diff) | |
| download | rust-openssl-9ee6f1c5785bb170c04a825ef173d4e336c957b2.tar.xz rust-openssl-9ee6f1c5785bb170c04a825ef173d4e336c957b2.zip | |
IT LIVES
Diffstat (limited to 'openssl/src/ssl/bio.rs')
| -rw-r--r-- | openssl/src/ssl/bio.rs | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs index 92479b37..1009c0bc 100644 --- a/openssl/src/ssl/bio.rs +++ b/openssl/src/ssl/bio.rs @@ -1,25 +1,38 @@ 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_extras::{BIO_clear_retry_flags, BIO_set_retry_read, BIO_set_retry_write}; -use std::any::Any; use std::io; use std::io::prelude::*; -use std::marker::PhantomData; use std::mem; use std::slice; -use std::sync::Mutex; use std::ptr; use ssl::error::SslError; +// "rust" +const NAME: [c_char; 5] = [114, 117, 115, 116, 0]; + +// we use this after removing the stream from the BIO so that we don't have to +// worry about freeing the heap allocated BIO_METHOD after freeing the BIO. +static DESTROY_METHOD: BIO_METHOD = BIO_METHOD { + type_: BIO_TYPE_NONE, + name: &NAME[0], + bwrite: None, + bread: None, + bputs: None, + bgets: None, + ctrl: None, + create: None, + destroy: Some(destroy), + callback_ctrl: None, +}; + pub struct StreamState<S> { pub stream: S, pub error: Option<io::Error>, } -pub fn new_bio<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>), SslError> { - // "rust" - static NAME: [c_char; 5] = [114, 117, 115, 116, 0]; +pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>), SslError> { let method = Box::new(BIO_METHOD { type_: BIO_TYPE_NONE, @@ -30,7 +43,7 @@ pub fn new_bio<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>) bgets: None, ctrl: Some(ctrl::<S>), create: Some(create), - destroy: Some(destroy), + destroy: None, // covered in the replacement BIO_METHOD callback_ctrl: None, }); @@ -40,12 +53,9 @@ pub fn new_bio<S: Read + Write>(stream: S) -> Result<(*mut BIO, Box<BIO_METHOD>) }); unsafe { - let bio = BIO_new(&*method); - if bio.is_null() { - return Err(SslError::get()); - } - + let bio = try_ssl_null!(BIO_new(&*method)); (*bio).ptr = Box::into_raw(state) as *mut _; + (*bio).init = 1; return Ok((bio, method)); } @@ -59,9 +69,20 @@ pub unsafe fn take_error<S>(bio: *mut BIO) -> Option<io::Error> { pub unsafe fn take_stream<S>(bio: *mut BIO) -> S { let state: Box<StreamState<S>> = Box::from_raw((*bio).ptr as *mut _); (*bio).ptr = ptr::null_mut(); + (*bio).method = &DESTROY_METHOD as *const _ as *mut _; + (*bio).init = 0; state.stream } +pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S { + let state: &'a StreamState<S> = mem::transmute((*bio).ptr); + &state.stream +} + +pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S { + &mut state(bio).stream +} + unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> { mem::transmute((*bio).ptr) } @@ -106,8 +127,8 @@ unsafe extern "C" fn bputs<S: Write>(bio: *mut BIO, s: *const c_char) -> c_int { unsafe extern "C" fn ctrl<S: Write>(bio: *mut BIO, cmd: c_int, - num: c_long, - ptr: *mut c_void) + _num: c_long, + _ptr: *mut c_void) -> c_long { if cmd == BIO_CTRL_FLUSH { let state = state::<S>(bio); |