diff options
| author | Steven Fackler <[email protected]> | 2013-09-19 12:54:01 -0700 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2013-09-19 12:54:01 -0700 |
| commit | a7dab3624e8424bd6c498e7ef14509dfd2a2434f (patch) | |
| tree | 043babcfb6e2a945c494091ab4bea50b089d04eb /src/ssl/lib.rs | |
| parent | Connect working (diff) | |
| download | rust-openssl-a7dab3624e8424bd6c498e7ef14509dfd2a2434f.tar.xz rust-openssl-a7dab3624e8424bd6c498e7ef14509dfd2a2434f.zip | |
Sketched out implementation
doesn't work
Diffstat (limited to 'src/ssl/lib.rs')
| -rw-r--r-- | src/ssl/lib.rs | 93 |
1 files changed, 74 insertions, 19 deletions
diff --git a/src/ssl/lib.rs b/src/ssl/lib.rs index 401a7b3d..5cc59330 100644 --- a/src/ssl/lib.rs +++ b/src/ssl/lib.rs @@ -1,4 +1,4 @@ -use std::rt::io::{Stream, Decorator}; +use std::rt::io::{Reader, Writer, Stream, Decorator}; use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release}; use std::task; use std::ptr; @@ -70,6 +70,7 @@ impl Drop for Ssl { } } +#[deriving(Eq, TotalEq, ToStr)] enum SslError { ErrorNone, ErrorSsl, @@ -114,6 +115,20 @@ impl Ssl { _ => unreachable!() } } + + fn read(&self, buf: &[u8]) -> int { + unsafe { + ffi::SSL_read(self.ssl, vec::raw::to_ptr(buf) as *c_void, + buf.len() as c_int) as int + } + } + + fn write(&self, buf: &[u8]) -> int { + unsafe { + ffi::SSL_write(self.ssl, vec::raw::to_ptr(buf) as *c_void, + buf.len() as c_int) as int + } + } } struct MemBio { @@ -150,9 +165,10 @@ impl MemBio { let ret = ffi::BIO_read(self.bio, vec::raw::to_ptr(buf) as *c_void, buf.len() as c_int); if ret < 0 { - fail2!("read returned {}", ret); + 0 + } else { + ret as uint } - ret as uint } } } @@ -179,47 +195,86 @@ impl<S: Stream> SslStream<S> { let mut stream = SslStream { ctx: ctx, ssl: ssl, + // Max record size for SSLv3/TLSv1 is 16k buf: vec::from_elem(16 * 1024, 0u8), rbio: rbio, wbio: wbio, stream: stream }; - stream.connect(); + do stream.in_retry_wrapper |ssl| { + ssl.ssl.connect() + }; stream } - fn connect(&mut self) { - info!("in connect"); + fn in_retry_wrapper(&mut self, blk: &fn(&mut SslStream<S>) -> int) + -> Result<int, SslError> { loop { - let ret = self.ssl.connect(); - info2!("connect returned {}", ret); - if ret == 1 { - return; + let ret = blk(self); + if ret > 0 { + return Ok(ret); } match self.ssl.get_error(ret) { ErrorWantRead => { - info2!("want read"); self.flush(); match self.stream.read(self.buf) { Some(len) => self.rbio.write(self.buf.slice_to(len)), - None => unreachable!() + None => unreachable!() // FIXME } } - ErrorWantWrite => { - info2!("want write"); - self.flush(); - } - _ => unreachable!() + ErrorWantWrite => self.flush(), + err => return Err(err) } } } + fn write_through(&mut self) { + loop { + let len = self.wbio.read(self.buf); + if len == 0 { + return; + } + self.stream.write(self.buf.slice_to(len)); + } + } +} + +impl<S: Stream> Reader for SslStream<S> { + fn read(&mut self, buf: &mut [u8]) -> Option<uint> { + let ret = do self.in_retry_wrapper |ssl| { + ssl.ssl.read(buf) + }; + + match ret { + Ok(num) => Some(num as uint), + Err(_) => None + } + } + + fn eof(&mut self) -> bool { + self.stream.eof() + } +} + +impl<S: Stream> Writer for SslStream<S> { + fn write(&mut self, buf: &[u8]) { + let ret = do self.in_retry_wrapper |ssl| { + ssl.ssl.write(buf) + }; + + match ret { + Ok(_) => (), + Err(err) => fail2!("Write error: {}", err.to_str()) + } + + self.write_through(); + } + fn flush(&mut self) { - let len = self.wbio.read(self.buf); - self.stream.write(self.buf.slice_to(len)); + self.write_through(); self.stream.flush(); } } |