rust: bssl-tls: Split TlsMode

The I/O contract is completely different between a stream socket
and a datagram socket.
We should keep them separated.

Signed-off-by: Xiangfei Ding <xfding@google.com>
Change-Id: I5a4009ae6b26faf66d98739dbd5be6d96a6a6964
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/92948
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/rust/bssl-tls/src/connection/lifecycle.rs b/rust/bssl-tls/src/connection/lifecycle.rs
index 749e2ea..a8779ff 100644
--- a/rust/bssl-tls/src/connection/lifecycle.rs
+++ b/rust/bssl-tls/src/connection/lifecycle.rs
@@ -33,6 +33,7 @@
         methods::HasTlsConnectionMethod, //
     },
     context::{
+        HasBasicIo,
         SupportedMode,
         TlsMode, //
     },
@@ -220,7 +221,10 @@
     }
 }
 
-impl<R> EstablishedTlsConnection<'_, R, TlsMode> {
+impl<R, M> EstablishedTlsConnection<'_, R, M>
+where
+    M: HasTlsConnectionMethod + HasBasicIo,
+{
     /// Perform synchronising shutdown.
     ///
     /// # Shutdown protocol
diff --git a/rust/bssl-tls/src/connection/methods.rs b/rust/bssl-tls/src/connection/methods.rs
index f4b04bd..5dfca0d 100644
--- a/rust/bssl-tls/src/connection/methods.rs
+++ b/rust/bssl-tls/src/connection/methods.rs
@@ -33,6 +33,7 @@
     Methods,
     abort_on_panic,
     context::{
+        DtlsMode,
         QuicMode,
         TlsMode, //
     },
@@ -248,6 +249,15 @@
     }
 }
 
+impl HasTlsConnectionMethod for DtlsMode {
+    #[inline(always)]
+    fn registration() -> c_int {
+        static TLS_CONTEXT_METHOD: Lazy<c_int> =
+            Lazy::new(register_tls_connection_vtable::<DtlsMode>);
+        *TLS_CONTEXT_METHOD
+    }
+}
+
 impl HasTlsConnectionMethod for QuicMode {
     #[inline(always)]
     fn registration() -> c_int {
diff --git a/rust/bssl-tls/src/connection/transport.rs b/rust/bssl-tls/src/connection/transport.rs
index c84864b..1de8762 100644
--- a/rust/bssl-tls/src/connection/transport.rs
+++ b/rust/bssl-tls/src/connection/transport.rs
@@ -16,8 +16,11 @@
 //!
 
 use crate::{
-    connection::TlsConnectionRef,
-    context::TlsMode,
+    connection::{
+        TlsConnectionRef,
+        methods::HasTlsConnectionMethod, //
+    },
+    context::HasBasicIo,
     errors::Error,
     io::{
         AbstractReader,
@@ -30,7 +33,10 @@
 /// # Transport configurations
 ///
 /// These are the methods to configure the underlying IO drivers and transport configurations.
-impl<R> TlsConnectionRef<R, TlsMode> {
+impl<R, M> TlsConnectionRef<R, M>
+where
+    M: HasBasicIo + HasTlsConnectionMethod,
+{
     /// Set up underlying transport driver.
     pub fn set_io<S: 'static + AbstractSocket>(&mut self, socket: S) -> Result<&mut Self, Error> {
         let bio = RustBio::new_duplex(socket)?;
diff --git a/rust/bssl-tls/src/context.rs b/rust/bssl-tls/src/context.rs
index 3bccb99..60f4196 100644
--- a/rust/bssl-tls/src/context.rs
+++ b/rust/bssl-tls/src/context.rs
@@ -42,15 +42,24 @@
 /// TLS or DTLS mode
 pub enum TlsMode {}
 
+/// DTLS mode
+pub enum DtlsMode {}
+
 /// QUIC mode
 pub enum QuicMode {}
 
+pub(crate) trait HasBasicIo {}
+
 /// A collection of supported mode of operations.
 pub trait SupportedMode: HasTlsContextMethod + HasTlsConnectionMethod {}
 
 impl SupportedMode for TlsMode {}
+impl SupportedMode for DtlsMode {}
 impl SupportedMode for QuicMode {}
 
+impl HasBasicIo for TlsMode {}
+impl HasBasicIo for DtlsMode {}
+
 /// General TLS configuration
 ///
 /// The `Mode` generic can be either [`TlsMode`] or [`QuicMode`].
@@ -105,7 +114,10 @@
             bssl_sys::TLS_method()
         })
     }
+}
 
+/// # Make a DTLS context builder operating in pure DTLS mode
+impl TlsContextBuilder<DtlsMode> {
     /// Creates a new DTLS context builder.
     pub fn new_dtls() -> Self {
         Self::new_inner(unsafe {
diff --git a/rust/bssl-tls/src/context/methods.rs b/rust/bssl-tls/src/context/methods.rs
index 3f40245..ae2d319 100644
--- a/rust/bssl-tls/src/context/methods.rs
+++ b/rust/bssl-tls/src/context/methods.rs
@@ -23,6 +23,7 @@
 use crate::{
     Methods,
     context::{
+        DtlsMode,
         QuicMode,
         TlsMode, //
     },
@@ -85,6 +86,14 @@
     }
 }
 
+impl HasTlsContextMethod for DtlsMode {
+    #[inline(always)]
+    fn registration() -> c_int {
+        static TLS_CONTEXT_METHOD: Lazy<c_int> = Lazy::new(register_tls_context_vtable::<DtlsMode>);
+        *TLS_CONTEXT_METHOD
+    }
+}
+
 impl HasTlsContextMethod for QuicMode {
     #[inline(always)]
     fn registration() -> c_int {