1use std::os::fd::AsRawFd;
2
3use foreign_types_shared::ForeignType;
4
5use crate::ffi::BIO_NOCLOSE;
6
7pub struct SslStream {
8 _tcp: std::net::TcpStream,
9 ssl: openssl::ssl::Ssl,
10}
11impl SslStream {
12 pub fn new(tcp: std::net::TcpStream, ssl: openssl::ssl::Ssl) -> Self {
14 let sock_bio = unsafe { openssl_sys::BIO_new_socket(tcp.as_raw_fd(), BIO_NOCLOSE) };
15 assert!(!sock_bio.is_null(), "Failed to create socket BIO");
16 unsafe {
17 openssl_sys::SSL_set_bio(ssl.as_ptr(), sock_bio, sock_bio);
18 }
19 SslStream { _tcp: tcp, ssl }
20 }
21
22 pub fn connect(&self) -> Result<(), crate::error::Error> {
24 let result = unsafe { openssl_sys::SSL_connect(self.ssl.as_ptr()) };
25 if result <= 0 {
26 Err(crate::error::Error::make(result, self.ssl()))
27 } else {
28 Ok(())
29 }
30 }
31
32 pub fn accept(&self) -> Result<(), crate::error::Error> {
33 let result = unsafe { openssl_sys::SSL_accept(self.ssl.as_ptr()) };
34 if result <= 0 {
35 Err(crate::error::Error::make(result, self.ssl()))
36 } else {
37 Ok(())
38 }
39 }
40
41 pub fn ssl(&self) -> &openssl::ssl::Ssl {
42 &self.ssl
43 }
44
45 pub fn shutdown(&self) -> Result<(), crate::error::Error> {
46 let result = unsafe { openssl_sys::SSL_shutdown(self.ssl.as_ptr()) };
47 if result < 0 {
48 Err(crate::error::Error::make(result, self.ssl()))
49 } else {
50 Ok(())
51 }
52 }
53
54 pub fn ktls_send_enabled(&self) -> bool {
55 unsafe {
56 let wbio = openssl_sys::SSL_get_wbio(self.ssl.as_ptr());
57 crate::ffi::BIO_get_ktls_send(wbio) != 0
58 }
59 }
60
61 pub fn ktls_recv_enabled(&self) -> bool {
62 unsafe {
63 let rbio = openssl_sys::SSL_get_rbio(self.ssl.as_ptr());
64 crate::ffi::BIO_get_ktls_recv(rbio) != 0
65 }
66 }
67}
68
69impl std::io::Read for SslStream {
70 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
71 unsafe {
72 let len = openssl_sys::SSL_read(
73 self.ssl.as_ptr(),
74 buf.as_mut_ptr() as *mut _,
75 buf.len().try_into().unwrap(),
76 );
77 if len < 0 {
78 Err(std::io::Error::other(crate::error::Error::make(
79 len,
80 self.ssl(),
81 )))
82 } else {
83 Ok(len as usize)
84 }
85 }
86 }
87}
88
89impl std::io::Write for SslStream {
90 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
91 if buf.is_empty() {
92 return Ok(0);
93 }
94
95 unsafe {
96 let len = openssl_sys::SSL_write(
97 self.ssl.as_ptr(),
98 buf.as_ptr() as *const _,
99 buf.len().try_into().unwrap(),
100 );
101 if len < 0 {
102 Err(std::io::Error::other(crate::error::Error::make(
103 len,
104 self.ssl(),
105 )))
106 } else {
107 Ok(len as usize)
108 }
109 }
110 }
111
112 fn flush(&mut self) -> std::io::Result<()> {
113 Ok(())
114 }
115}
116
117impl Drop for SslStream {
118 fn drop(&mut self) {
119 }
126}