From e2be42aa53623b8c460ec247ec5d2df36503cd78 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 5 Oct 2013 20:36:45 -0700 Subject: [PATCH] Stuff roughly working We can't shutdown in Drop since generic destructors are broken :( --- src/ssl/ffi.rs | 2 +- src/ssl/lib.rs | 53 +++++++++++++++++++++++++++++++------------------ src/ssl/test.rs | 9 ++++++--- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/ssl/ffi.rs b/src/ssl/ffi.rs index e12bb3c2..f87625ba 100644 --- a/src/ssl/ffi.rs +++ b/src/ssl/ffi.rs @@ -37,9 +37,9 @@ externfn!(fn SSL_connect(ssl: *SSL) -> c_int) externfn!(fn SSL_get_error(ssl: *SSL, ret: c_int) -> c_int) externfn!(fn SSL_read(ssl: *SSL, buf: *c_void, num: c_int) -> c_int) externfn!(fn SSL_write(ssl: *SSL, buf: *c_void, num: c_int) -> c_int) +externfn!(fn SSL_shutdown(ssl: *SSL) -> c_int) externfn!(fn BIO_s_mem() -> *BIO_METHOD) externfn!(fn BIO_new(type_: *BIO_METHOD) -> *BIO) -externfn!(fn BIO_free(a: *BIO) -> c_int) externfn!(fn BIO_read(b: *BIO, buf: *c_void, len: c_int) -> c_int) externfn!(fn BIO_write(b: *BIO, buf: *c_void, len: c_int) -> c_int) diff --git a/src/ssl/lib.rs b/src/ssl/lib.rs index 5cc59330..4d79152b 100644 --- a/src/ssl/lib.rs +++ b/src/ssl/lib.rs @@ -1,3 +1,5 @@ +#[link(name="ssl")]; + use std::rt::io::{Reader, Writer, Stream, Decorator}; use std::unstable::atomics::{AtomicBool, INIT_ATOMIC_BOOL, Acquire, Release}; use std::task; @@ -60,6 +62,19 @@ impl SslCtx { } } +#[deriving(Eq, TotalEq, ToStr)] +enum SslError { + ErrorNone, + ErrorSsl, + ErrorWantRead, + ErrorWantWrite, + ErrorWantX509Lookup, + ErrorSyscall, + ErrorZeroReturn, + ErrorWantConnect, + ErrorWantAccept, +} + struct Ssl { ssl: *ffi::SSL } @@ -70,18 +85,6 @@ impl Drop for Ssl { } } -#[deriving(Eq, TotalEq, ToStr)] -enum SslError { - ErrorNone, - ErrorSsl, - ErrorWantRead, - ErrorWantWrite, - ErrorWantX509Lookup, - ErrorZeroReturn, - ErrorWantConnect, - ErrorWantAccept, -} - impl Ssl { fn new(ctx: &SslCtx) -> Ssl { let ssl = unsafe { ffi::SSL_new(ctx.ctx) }; @@ -109,10 +112,11 @@ impl Ssl { ffi::SSL_ERROR_WANT_READ => ErrorWantRead, ffi::SSL_ERROR_WANT_WRITE => ErrorWantWrite, ffi::SSL_ERROR_WANT_X509_LOOKUP => ErrorWantX509Lookup, + ffi::SSL_ERROR_SYSCALL => ErrorSyscall, ffi::SSL_ERROR_ZERO_RETURN => ErrorZeroReturn, ffi::SSL_ERROR_WANT_CONNECT => ErrorWantConnect, ffi::SSL_ERROR_WANT_ACCEPT => ErrorWantAccept, - _ => unreachable!() + err => fail2!("Unknown error {}", err) } } @@ -129,18 +133,17 @@ impl Ssl { buf.len() as c_int) as int } } + + fn shutdown(&self) -> int { + unsafe { ffi::SSL_shutdown(self.ssl) as int } + } } +// BIOs are freed by SSL_free struct MemBio { bio: *ffi::BIO } -impl Drop for MemBio { - fn drop(&mut self) { - unsafe { ffi::BIO_free(self.bio); } - } -} - impl MemBio { fn new() -> MemBio { let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) }; @@ -240,6 +243,18 @@ impl SslStream { self.stream.write(self.buf.slice_to(len)); } } + + pub fn shutdown(&mut self) { + loop { + let ret = do self.in_retry_wrapper |ssl| { + ssl.ssl.shutdown() + }; + + if ret != Ok(0) { + break; + } + } + } } impl Reader for SslStream { diff --git a/src/ssl/test.rs b/src/ssl/test.rs index 7a6dc997..36969e1b 100644 --- a/src/ssl/test.rs +++ b/src/ssl/test.rs @@ -1,6 +1,6 @@ extern mod ssl; -use std::rt::io::{Writer}; +use std::rt::io::{Writer, Reader}; use std::rt::io::net::tcp::TcpStream; use std::vec; @@ -13,14 +13,17 @@ fn test_new_ctx() { #[test] fn test_new_sslstream() { - let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()); + let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap(); SslStream::new(SslCtx::new(Sslv23), stream); } #[test] fn test_write() { - let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()); + let stream = TcpStream::connect(FromStr::from_str("127.0.0.1:15418").unwrap()).unwrap(); let mut stream = SslStream::new(SslCtx::new(Sslv23), stream); stream.write("hello".as_bytes()); stream.flush(); + stream.write(" there".as_bytes()); + stream.flush(); + stream.shutdown(); }