rust: bssl-tls: Move DTLS methods into the correct typestate Update-Note: previously dtlsv1_handle_timeout and dtlsv1_get_timeout are incorrectly associated with connections under all modes. This is a design error and they have moved into the correct typestate to prevent misuses. Signed-off-by: Xiangfei Ding <xfding@google.com> Change-Id: I0b3aafa6b97345eda994dbbc882edd506a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/98789 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/rust/bssl-tls/src/connection/transport.rs b/rust/bssl-tls/src/connection/transport.rs index 67bc9ca..30d44dd 100644 --- a/rust/bssl-tls/src/connection/transport.rs +++ b/rust/bssl-tls/src/connection/transport.rs
@@ -15,7 +15,10 @@ //! TLS Connection transport settings //! -use core::mem::{MaybeUninit, transmute}; +use core::mem::{ + MaybeUninit, + transmute, // +}; use crate::{ check_lib_error, @@ -26,6 +29,7 @@ TlsConnectionBuilder, methods::HasTlsConnectionMethod, // }, + context::DtlsMode, context::HasBasicIo, errors::Error, io::{ @@ -77,60 +81,6 @@ Ok(self) } - /// **For DTLS only**, trigger timeout handling on the connection. - /// - /// On success, this method call returns `true` when a timeout is hit and successfully handled; - /// `false` when no timeout has expired yet. - pub fn dtlsv1_handle_timeout(&mut self) -> Result<bool, Error> { - let conn = self.ptr(); - let rc = unsafe { - // Safety: the connection handle here is still valid. - bssl_sys::DTLSv1_handle_timeout(conn) - }; - if rc == 0 { - return Ok(false); - } - let _ = check_tls_error!(conn, rc); - Ok(true) - } - - /// **For DTLS only**, get connection's remaining timeout. - /// - /// If a timeout is in effect, this method call returns the remaining seconds, - /// followed by the remaining microseconds. - pub fn dtlsv1_get_timeout(&self) -> Option<(i64, i64)> { - #[cfg(windows)] - #[repr(C)] - struct timeval { - tv_sec: core::ffi::c_long, - tv_usec: core::ffi::c_long, - } - #[cfg(not(windows))] - use bssl_sys::timeval; - - let mut timeval = MaybeUninit::<timeval>::zeroed(); - let rc = unsafe { - // Safety: - // - the validity of the handle `self.0` is witnessed by `self`; - // - the buffer for timeval is valid. - // - on Windows, the timeval structure should match the winsock2.h definition precisely. - bssl_sys::DTLSv1_get_timeout(self.ptr(), transmute(timeval.as_mut_ptr())) - }; - match rc { - 1 => { - let timeval = unsafe { - // Safety: timeval is now valid as per BoringSSL specification. - timeval.assume_init() - }; - Some((timeval.tv_sec as i64, timeval.tv_usec as i64)) - } - 0 => None, - rc => { - unreachable!("BoringSSL should never return {rc} when calling dtlsv1_get_timeout") - } - } - } - /// Check if the underlying **transport** has closed its write end. pub fn is_write_closed(&self) -> bool { self.get_connection_methods_ref() @@ -185,3 +135,60 @@ Ok(self) } } + +/// # DTLS +impl<R> TlsConnection<R, DtlsMode> { + /// Trigger timeout handling on the connection. + /// + /// On success, this method call returns `true` when a timeout is hit and successfully handled; + /// `false` when no timeout has expired yet. + pub fn dtlsv1_handle_timeout(&mut self) -> Result<bool, Error> { + let conn = self.ptr(); + let rc = unsafe { + // Safety: the connection handle here is still valid. + bssl_sys::DTLSv1_handle_timeout(conn) + }; + if rc == 0 { + return Ok(false); + } + let _ = check_tls_error!(conn, rc); + Ok(true) + } + + /// Get connection's remaining timeout. + /// + /// If a timeout is in effect, this method call returns the remaining seconds, + /// followed by the remaining microseconds. + pub fn dtlsv1_get_timeout(&self) -> Option<(i64, i64)> { + #[cfg(windows)] + #[repr(C)] + struct timeval { + tv_sec: core::ffi::c_long, + tv_usec: core::ffi::c_long, + } + #[cfg(not(windows))] + use bssl_sys::timeval; + + let mut timeval = MaybeUninit::<timeval>::zeroed(); + let rc = unsafe { + // Safety: + // - the validity of the handle `self.0` is witnessed by `self`; + // - the buffer for timeval is valid. + // - on Windows, the timeval structure should match the winsock2.h definition precisely. + bssl_sys::DTLSv1_get_timeout(self.ptr(), transmute(timeval.as_mut_ptr())) + }; + match rc { + 1 => { + let timeval = unsafe { + // Safety: timeval is now valid as per BoringSSL specification. + timeval.assume_init() + }; + Some((timeval.tv_sec as i64, timeval.tv_usec as i64)) + } + 0 => None, + rc => { + unreachable!("BoringSSL should never return {rc} when calling dtlsv1_get_timeout") + } + } + } +}