From e50f31984236bb79879e2a9437017a5663665cd5 Mon Sep 17 00:00:00 2001 From: James Mayclin Date: Mon, 16 Dec 2024 14:59:17 -0800 Subject: [PATCH] refactor(bindings/bench): make harness own IO (#4847) --- bindings/rust/bench/benches/handshake.rs | 19 +-- bindings/rust/bench/benches/throughput.rs | 20 +-- bindings/rust/bench/src/harness/io.rs | 67 ++++++++ .../bench/src/{harness.rs => harness/mod.rs} | 154 +++--------------- bindings/rust/bench/src/lib.rs | 4 +- bindings/rust/bench/src/openssl.rs | 33 +--- bindings/rust/bench/src/rustls.rs | 38 ++--- bindings/rust/bench/src/s2n_tls.rs | 64 +++----- 8 files changed, 148 insertions(+), 251 deletions(-) create mode 100644 bindings/rust/bench/src/harness/io.rs rename bindings/rust/bench/src/{harness.rs => harness/mod.rs} (73%) diff --git a/bindings/rust/bench/benches/handshake.rs b/bindings/rust/bench/benches/handshake.rs index b86d0a81b0d..6b011278568 100644 --- a/bindings/rust/bench/benches/handshake.rs +++ b/bindings/rust/bench/benches/handshake.rs @@ -2,15 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 use bench::{ - harness::TlsBenchConfig, CipherSuite, ConnectedBuffer, CryptoConfig, HandshakeType, KXGroup, - Mode, OpenSslConnection, RustlsConnection, S2NConnection, SigType, TlsConnPair, TlsConnection, + harness::TlsBenchConfig, CipherSuite, CryptoConfig, HandshakeType, KXGroup, Mode, + OpenSslConnection, RustlsConnection, S2NConnection, SigType, TlsConnPair, TlsConnection, PROFILER_FREQUENCY, }; use criterion::{ criterion_group, criterion_main, measurement::WallTime, BatchSize, BenchmarkGroup, Criterion, }; use pprof::criterion::{Output, PProfProfiler}; -use std::error::Error; use strum::IntoEnumIterator; fn bench_handshake_for_library( @@ -33,19 +32,9 @@ fn bench_handshake_for_library( // only include negotiation and not config/connection initialization bench_group.bench_function(T::name(), |b| { b.iter_batched_ref( - || -> Result, Box> { - let connected_buffer = ConnectedBuffer::default(); - let client = T::new_from_config(&client_config, connected_buffer.clone_inverse())?; - let server = T::new_from_config(&server_config, connected_buffer)?; - Ok(TlsConnPair::wrap(client, server)) - }, + || -> TlsConnPair { TlsConnPair::from_configs(&client_config, &server_config) }, |conn_pair| { - // harnesses with certain parameters fail to initialize for - // some past versions of s2n-tls, but missing data can be - // visually interpolated in the historical performance graph - if let Ok(conn_pair) = conn_pair { - let _ = conn_pair.handshake(); - } + conn_pair.handshake().unwrap(); }, BatchSize::SmallInput, ) diff --git a/bindings/rust/bench/benches/throughput.rs b/bindings/rust/bench/benches/throughput.rs index b6785552320..ae43cf955b6 100644 --- a/bindings/rust/bench/benches/throughput.rs +++ b/bindings/rust/bench/benches/throughput.rs @@ -4,15 +4,14 @@ use bench::OpenSslConnection; use bench::RustlsConnection; use bench::{ - harness::TlsBenchConfig, CipherSuite, ConnectedBuffer, CryptoConfig, HandshakeType, KXGroup, - Mode, S2NConnection, SigType, TlsConnPair, TlsConnection, PROFILER_FREQUENCY, + harness::TlsBenchConfig, CipherSuite, CryptoConfig, HandshakeType, KXGroup, Mode, + S2NConnection, SigType, TlsConnPair, TlsConnection, PROFILER_FREQUENCY, }; use criterion::{ criterion_group, criterion_main, measurement::WallTime, BatchSize, BenchmarkGroup, Criterion, Throughput, }; use pprof::criterion::{Output, PProfProfiler}; -use std::error::Error; use strum::IntoEnumIterator; fn bench_throughput_for_library( @@ -31,18 +30,13 @@ fn bench_throughput_for_library( bench_group.bench_function(T::name(), |b| { b.iter_batched_ref( - || -> Result, Box> { - let connected_buffer = ConnectedBuffer::default(); - let client = T::new_from_config(&client_config, connected_buffer.clone_inverse())?; - let server = T::new_from_config(&server_config, connected_buffer)?; - let mut conn_pair = TlsConnPair::wrap(client, server); - conn_pair.handshake()?; - Ok(conn_pair) + || -> TlsConnPair { + let mut conn_pair = TlsConnPair::from_configs(&client_config, &server_config); + conn_pair.handshake().unwrap(); + conn_pair }, |conn_pair| { - if let Ok(conn_pair) = conn_pair { - let _ = conn_pair.round_trip_transfer(shared_buf); - } + let _ = conn_pair.round_trip_transfer(shared_buf); }, BatchSize::SmallInput, ) diff --git a/bindings/rust/bench/src/harness/io.rs b/bindings/rust/bench/src/harness/io.rs new file mode 100644 index 00000000000..732d41deaf3 --- /dev/null +++ b/bindings/rust/bench/src/harness/io.rs @@ -0,0 +1,67 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use std::{cell::RefCell, collections::VecDeque, io::ErrorKind, pin::Pin, rc::Rc}; + +pub type LocalDataBuffer = RefCell>; + +#[derive(Debug)] +pub struct TestPairIO { + /// a data buffer that the server writes to and the client reads from + pub server_tx_stream: Pin>, + /// a data buffer that the client writes to and the server reads from + pub client_tx_stream: Pin>, +} + +impl TestPairIO { + pub fn client_view(&self) -> ViewIO { + ViewIO { + send_ctx: self.client_tx_stream.clone(), + recv_ctx: self.server_tx_stream.clone(), + } + } + + pub fn server_view(&self) -> ViewIO { + ViewIO { + send_ctx: self.server_tx_stream.clone(), + recv_ctx: self.client_tx_stream.clone(), + } + } +} + +/// A "view" of the IO. +/// +/// This view is client/server specific, and notably implements the read and write +/// traits. +/// +// This struct is used by Openssl and Rustls which both rely on a "stream" abstraction +// which implements read and write. This is not used by s2n-tls, which relies on +// lower level callbacks. +pub struct ViewIO { + pub send_ctx: Pin>, + pub recv_ctx: Pin>, +} + +impl std::io::Read for ViewIO { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let res = self.recv_ctx.borrow_mut().read(buf); + if let Ok(0) = res { + // We are "faking" a TcpStream, where a read of length 0 indicates + // EoF. That is incorrect for this scenario. Instead we return WouldBlock + // to indicate that there is simply no more data to be read. + Err(std::io::Error::new(ErrorKind::WouldBlock, "blocking")) + } else { + res + } + } +} + +impl std::io::Write for ViewIO { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.send_ctx.borrow_mut().write(buf) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} diff --git a/bindings/rust/bench/src/harness.rs b/bindings/rust/bench/src/harness/mod.rs similarity index 73% rename from bindings/rust/bench/src/harness.rs rename to bindings/rust/bench/src/harness/mod.rs index eff9bc629e3..33420cc606c 100644 --- a/bindings/rust/bench/src/harness.rs +++ b/bindings/rust/bench/src/harness/mod.rs @@ -1,15 +1,11 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use std::{ - cell::RefCell, - collections::VecDeque, - error::Error, - fmt::Debug, - fs::read_to_string, - io::{ErrorKind, Read, Write}, - rc::Rc, -}; +mod io; +pub use io::{LocalDataBuffer, ViewIO}; + +use io::TestPairIO; +use std::{error::Error, fmt::Debug, fs::read_to_string, rc::Rc}; use strum::EnumIter; #[derive(Clone, Copy, EnumIter)] @@ -161,10 +157,7 @@ pub trait TlsConnection: Sized { fn name() -> String; /// Make connection from existing config and buffer - fn new_from_config( - config: &Self::Config, - connected_buffer: ConnectedBuffer, - ) -> Result>; + fn new_from_config(config: &Self::Config, io: ViewIO) -> Result>; /// Run one handshake step: receive msgs from other connection, process, and send new msgs fn handshake(&mut self) -> Result<(), Box>; @@ -184,29 +177,13 @@ pub trait TlsConnection: Sized { /// Read application data from ConnectedBuffer fn recv(&mut self, data: &mut [u8]) -> Result<(), Box>; - - /// Shrink buffers owned by the connection - fn shrink_connection_buffers(&mut self); - - /// Clear and shrink buffers used for IO with another connection - fn shrink_connected_buffer(&mut self); - - /// Get reference to internal connected buffer - fn connected_buffer(&self) -> &ConnectedBuffer; } +/// A TlsConnPair owns the client and server tls connections along with the IO buffers. pub struct TlsConnPair { - client: C, - server: S, -} - -impl TlsConnPair { - pub fn new(client_config: &C::Config, server_config: &S::Config) -> TlsConnPair { - let connected_buffer = ConnectedBuffer::default(); - let client = C::new_from_config(&client_config, connected_buffer.clone_inverse()).unwrap(); - let server = S::new_from_config(&server_config, connected_buffer).unwrap(); - Self { client, server } - } + pub client: C, + pub server: S, + pub io: TestPairIO, } impl Default for TlsConnPair @@ -242,7 +219,7 @@ where // handshake the client and server connections. This will result in // session ticket getting stored in client_config - let mut pair = TlsConnPair::::new(&client_config, &server_config); + let mut pair = TlsConnPair::::from_configs(&client_config, &server_config); pair.handshake()?; // NewSessionTicket messages are part of the application data and sent // after the handshake is complete, so we must trigger an additional @@ -255,10 +232,13 @@ where // on the connection. This results in the session ticket in // client_config (from the previous handshake) getting set on the // client connection. - return Ok(TlsConnPair::::new(&client_config, &server_config)); + return Ok(TlsConnPair::::from_configs( + &client_config, + &server_config, + )); } - Ok(TlsConnPair::::new( + Ok(TlsConnPair::::from_configs( &C::Config::make_config(Mode::Client, crypto_config, handshake_type).unwrap(), &S::Config::make_config(Mode::Server, crypto_config, handshake_type).unwrap(), )) @@ -270,13 +250,14 @@ where C: TlsConnection, S: TlsConnection, { - /// Wrap two TlsConnections into a TlsConnPair - pub fn wrap(client: C, server: S) -> Self { - assert!( - client.connected_buffer() == &server.connected_buffer().clone_inverse(), - "connected buffers don't match" - ); - Self { client, server } + pub fn from_configs(client_config: &C::Config, server_config: &S::Config) -> Self { + let io = TestPairIO { + server_tx_stream: Rc::pin(Default::default()), + client_tx_stream: Rc::pin(Default::default()), + }; + let client = C::new_from_config(client_config, io.client_view()).unwrap(); + let server = S::new_from_config(server_config, io.server_view()).unwrap(); + Self { client, server, io } } /// Take back ownership of individual connections in the TlsConnPair @@ -325,93 +306,6 @@ where Ok(()) } - - /// Shrink buffers owned by the connections - pub fn shrink_connection_buffers(&mut self) { - self.client.shrink_connection_buffers(); - self.server.shrink_connection_buffers(); - } - - /// Clear and shrink buffers used for IO between the connections - pub fn shrink_connected_buffers(&mut self) { - self.client.shrink_connected_buffer(); - self.server.shrink_connected_buffer(); - } -} - -/// Wrapper of two shared buffers to pass as stream -/// This wrapper `read()`s into one buffer and `write()`s to another -/// `Rc>>` allows sharing of references to the buffers for two connections -#[derive(Clone, Eq)] -pub struct ConnectedBuffer { - recv: Rc>>, - send: Rc>>, -} - -impl PartialEq for ConnectedBuffer { - /// ConnectedBuffers are equal if and only if they point to the same VecDeques - fn eq(&self, other: &ConnectedBuffer) -> bool { - Rc::ptr_eq(&self.recv, &other.recv) && Rc::ptr_eq(&self.send, &other.send) - } -} - -impl ConnectedBuffer { - /// Make a new struct with new internal buffers - pub fn new() -> Self { - let recv = Rc::new(RefCell::new(VecDeque::new())); - let send = Rc::new(RefCell::new(VecDeque::new())); - - // prevent (potentially slow) resizing of buffers for small data transfers, - // like with handshake - recv.borrow_mut().reserve(10000); - send.borrow_mut().reserve(10000); - - Self { recv, send } - } - - /// Makes a new ConnectedBuffer that shares internal buffers but swapped, - /// ex. `write()` writes to the buffer that the inverse `read()`s from - pub fn clone_inverse(&self) -> Self { - Self { - recv: self.send.clone(), - send: self.recv.clone(), - } - } - - /// Clears and shrinks buffers - pub fn shrink(&mut self) { - self.recv.borrow_mut().clear(); - self.recv.borrow_mut().shrink_to_fit(); - self.send.borrow_mut().clear(); - self.send.borrow_mut().shrink_to_fit(); - } -} - -impl Read for ConnectedBuffer { - fn read(&mut self, dest: &mut [u8]) -> Result { - let res = self.recv.borrow_mut().read(dest); - match res { - // rustls expects WouldBlock on read of length 0 - Ok(0) => Err(std::io::Error::new(ErrorKind::WouldBlock, "blocking")), - Ok(len) => Ok(len), - Err(err) => Err(err), - } - } -} - -impl Write for ConnectedBuffer { - fn write(&mut self, src: &[u8]) -> Result { - self.send.borrow_mut().write(src) - } - fn flush(&mut self) -> Result<(), std::io::Error> { - Ok(()) // data already available to destination - } -} - -impl Default for ConnectedBuffer { - fn default() -> Self { - Self::new() - } } #[cfg(test)] diff --git a/bindings/rust/bench/src/lib.rs b/bindings/rust/bench/src/lib.rs index 95d92b42ab4..b7b79bfa228 100644 --- a/bindings/rust/bench/src/lib.rs +++ b/bindings/rust/bench/src/lib.rs @@ -8,8 +8,8 @@ pub mod s2n_tls; pub use crate::{ harness::{ - get_cert_path, CipherSuite, ConnectedBuffer, CryptoConfig, HandshakeType, KXGroup, Mode, - PemType, SigType, TlsConnPair, TlsConnection, + get_cert_path, CipherSuite, CryptoConfig, HandshakeType, KXGroup, Mode, PemType, SigType, + TlsConnPair, TlsConnection, }, openssl::OpenSslConnection, rustls::RustlsConnection, diff --git a/bindings/rust/bench/src/openssl.rs b/bindings/rust/bench/src/openssl.rs index 24ec9e9e125..86c2538eaed 100644 --- a/bindings/rust/bench/src/openssl.rs +++ b/bindings/rust/bench/src/openssl.rs @@ -4,8 +4,8 @@ use crate::{ get_cert_path, harness::{ - CipherSuite, ConnectedBuffer, CryptoConfig, HandshakeType, KXGroup, Mode, TlsBenchConfig, - TlsConnection, + CipherSuite, CryptoConfig, HandshakeType, KXGroup, Mode, TlsBenchConfig, TlsConnection, + ViewIO, }, PemType::*, }; @@ -26,8 +26,7 @@ pub struct SessionTicketStorage { } pub struct OpenSslConnection { - connected_buffer: ConnectedBuffer, - connection: SslStream, + connection: SslStream, } impl Drop for OpenSslConnection { @@ -148,10 +147,7 @@ impl TlsConnection for OpenSslConnection { ) } - fn new_from_config( - config: &Self::Config, - connected_buffer: ConnectedBuffer, - ) -> Result> { + fn new_from_config(config: &Self::Config, io: ViewIO) -> Result> { // check if there is a session ticket available // a session ticket will only be available if the Config was created // with session resumption enabled @@ -170,11 +166,8 @@ impl TlsConnection for OpenSslConnection { unsafe { connection.set_session(ticket)? }; } - let connection = SslStream::new(connection, connected_buffer.clone())?; - Ok(Self { - connected_buffer, - connection, - }) + let connection = SslStream::new(connection, io)?; + Ok(Self { connection }) } fn handshake(&mut self) -> Result<(), Box> { @@ -241,20 +234,6 @@ impl TlsConnection for OpenSslConnection { Ok(()) } - /// With OpenSSL's API, not possible after connection initialization: - /// In order to shrink buffers owned by the connection, config has to built - /// with `builder.set_mode(SslMode::RELEASE_BUFFERS);`, which tells the - /// connection to release buffers only when it's idle - fn shrink_connection_buffers(&mut self) {} - - fn shrink_connected_buffer(&mut self) { - self.connected_buffer.shrink(); - } - - fn connected_buffer(&self) -> &ConnectedBuffer { - &self.connected_buffer - } - fn resumed_connection(&self) -> bool { self.connection.ssl().session_reused() } diff --git a/bindings/rust/bench/src/rustls.rs b/bindings/rust/bench/src/rustls.rs index 39da2777da9..91c0a665094 100644 --- a/bindings/rust/bench/src/rustls.rs +++ b/bindings/rust/bench/src/rustls.rs @@ -3,8 +3,8 @@ use crate::{ harness::{ - read_to_bytes, CipherSuite, ConnectedBuffer, CryptoConfig, HandshakeType, KXGroup, Mode, - TlsBenchConfig, TlsConnection, + read_to_bytes, CipherSuite, CryptoConfig, HandshakeType, KXGroup, Mode, TlsBenchConfig, + TlsConnection, ViewIO, }, PemType::{self, *}, SigType, @@ -32,7 +32,9 @@ use std::{ }; pub struct RustlsConnection { - connected_buffer: ConnectedBuffer, + // the rustls connection has to own the io view, because it is passed as an + // argument to read/write rather than being part of the connection configuration + io: ViewIO, connection: Connection, } @@ -74,7 +76,7 @@ impl RustlsConfig { rustls_pemfile::read_one(&mut BufReader::new(&*read_to_bytes(pem_type, sig_type))) .unwrap(); if let Some(rustls_pemfile::Item::Pkcs8Key(pkcs_8_key)) = key { - return pkcs_8_key.into(); + pkcs_8_key.into() } else { // https://docs.rs/rustls-pemfile/latest/rustls_pemfile/enum.Item.html panic!("unexpected key type: {:?}", key); @@ -168,10 +170,7 @@ impl TlsConnection for RustlsConnection { "rustls".to_string() } - fn new_from_config( - config: &Self::Config, - connected_buffer: ConnectedBuffer, - ) -> Result> { + fn new_from_config(config: &Self::Config, io: ViewIO) -> Result> { let connection = match config { RustlsConfig::Client(config) => Connection::Client(ClientConnection::new( config.clone(), @@ -182,14 +181,11 @@ impl TlsConnection for RustlsConnection { } }; - Ok(Self { - connected_buffer, - connection, - }) + Ok(Self { io, connection }) } fn handshake(&mut self) -> Result<(), Box> { - Self::ignore_block(self.connection.complete_io(&mut self.connected_buffer))?; + Self::ignore_block(self.connection.complete_io(&mut self.io))?; Ok(()) } @@ -220,7 +216,7 @@ impl TlsConnection for RustlsConnection { .writer() .write(&data[write_offset..data.len()])?; self.connection.writer().flush()?; - self.connection.complete_io(&mut self.connected_buffer)?; + self.connection.complete_io(&mut self.io)?; } Ok(()) } @@ -229,7 +225,7 @@ impl TlsConnection for RustlsConnection { let data_len = data.len(); let mut read_offset = 0; while read_offset < data.len() { - self.connection.complete_io(&mut self.connected_buffer)?; + self.connection.complete_io(&mut self.io)?; read_offset += Self::ignore_block( self.connection .reader() @@ -239,18 +235,6 @@ impl TlsConnection for RustlsConnection { Ok(()) } - fn shrink_connection_buffers(&mut self) { - self.connection.set_buffer_limit(Some(1)); - } - - fn shrink_connected_buffer(&mut self) { - self.connected_buffer.shrink(); - } - - fn connected_buffer(&self) -> &ConnectedBuffer { - &self.connected_buffer - } - fn resumed_connection(&self) -> bool { if let rustls::Connection::Server(s) = &self.connection { s.received_resumption_data().is_some() diff --git a/bindings/rust/bench/src/s2n_tls.rs b/bindings/rust/bench/src/s2n_tls.rs index 63fa42d70d4..5a0cdc2d489 100644 --- a/bindings/rust/bench/src/s2n_tls.rs +++ b/bindings/rust/bench/src/s2n_tls.rs @@ -3,8 +3,8 @@ use crate::{ harness::{ - read_to_bytes, CipherSuite, ConnectedBuffer, CryptoConfig, HandshakeType, KXGroup, Mode, - TlsConnection, + read_to_bytes, CipherSuite, CryptoConfig, HandshakeType, KXGroup, LocalDataBuffer, Mode, + TlsConnection, ViewIO, }, PemType::*, }; @@ -19,9 +19,8 @@ use std::{ borrow::BorrowMut, error::Error, ffi::c_void, - io::{ErrorKind, Read, Write}, + io::{Read, Write}, os::raw::c_int, - pin::Pin, sync::{Arc, Mutex}, task::Poll, time::SystemTime, @@ -153,8 +152,6 @@ impl crate::harness::TlsBenchConfig for S2NConfig { } pub struct S2NConnection { - // Pin> is to ensure long-term *mut to IO buffers remains valid - connected_buffer: Pin>, connection: Connection, handshake_completed: bool, } @@ -165,27 +162,34 @@ impl S2NConnection { /// s2n-tls IO is usually used with file descriptors to a TCP socket, but we /// reduce overhead and outside noise with a local buffer for benchmarking unsafe extern "C" fn send_cb(context: *mut c_void, data: *const u8, len: u32) -> c_int { - let context = &mut *(context as *mut ConnectedBuffer); + let context = &*(context as *const LocalDataBuffer); let data = core::slice::from_raw_parts(data, len as _); - context.write(data).unwrap() as _ + let bytes_written = context.borrow_mut().write(data).unwrap(); + bytes_written as c_int } - /// Unsafe callback for custom IO C API + // Note: this callback will be invoked multiple times in the event that + // the byte-slices of the VecDeque are not contiguous (wrap around). unsafe extern "C" fn recv_cb(context: *mut c_void, data: *mut u8, len: u32) -> c_int { - let context = &mut *(context as *mut ConnectedBuffer); + let context = &*(context as *const LocalDataBuffer); let data = core::slice::from_raw_parts_mut(data, len as _); - context.flush().unwrap(); - match context.read(data) { - Err(err) => { - // s2n-tls requires the callback to set errno if blocking happens - if let ErrorKind::WouldBlock = err.kind() { + match context.borrow_mut().read(data) { + Ok(len) => { + if len == 0 { + // returning a length of 0 indicates a channel close (e.g. a + // TCP Close) which would not be correct. To just communicate + // "no more data", we instead set the errno to WouldBlock and + // return -1. errno::set_errno(errno::Errno(libc::EWOULDBLOCK)); -1 } else { - panic!("{err:?}"); + len as c_int } } - Ok(len) => len as _, + Err(err) => { + // VecDeque IO Operations should never fail + panic!("{err:?}"); + } } } @@ -201,16 +205,13 @@ impl TlsConnection for S2NConnection { "s2n-tls".to_string() } - fn new_from_config( - config: &Self::Config, - connected_buffer: ConnectedBuffer, - ) -> Result> { + fn new_from_config(config: &Self::Config, io: ViewIO) -> Result> { let mode = match config.mode { Mode::Client => s2n_tls::enums::Mode::Client, Mode::Server => s2n_tls::enums::Mode::Server, }; - let mut connected_buffer = Box::pin(connected_buffer); + let io = Box::pin(io); let mut connection = Connection::new(mode); connection @@ -220,9 +221,11 @@ impl TlsConnection for S2NConnection { .set_receive_callback(Some(Self::recv_cb))?; unsafe { connection - .set_send_context(&mut *connected_buffer as *mut ConnectedBuffer as *mut c_void)? + .set_send_context( + &io.send_ctx as &LocalDataBuffer as *const LocalDataBuffer as *mut c_void, + )? .set_receive_context( - &mut *connected_buffer as *mut ConnectedBuffer as *mut c_void, + &io.recv_ctx as &LocalDataBuffer as *const LocalDataBuffer as *mut c_void, )?; } @@ -231,7 +234,6 @@ impl TlsConnection for S2NConnection { } Ok(Self { - connected_buffer, connection, handshake_completed: false, }) @@ -293,16 +295,4 @@ impl TlsConnection for S2NConnection { } Ok(()) } - - fn shrink_connection_buffers(&mut self) { - self.connection.release_buffers().unwrap(); - } - - fn shrink_connected_buffer(&mut self) { - self.connected_buffer.shrink(); - } - - fn connected_buffer(&self) -> &ConnectedBuffer { - &self.connected_buffer - } }