diff --git a/libcoap/src/context.rs b/libcoap/src/context.rs index 2cd72a23..77595482 100644 --- a/libcoap/src/context.rs +++ b/libcoap/src/context.rs @@ -20,7 +20,7 @@ use libcoap_sys::{ coap_context_set_csm_timeout, coap_context_set_keepalive, coap_context_set_max_handshake_sessions, coap_context_set_max_idle_sessions, coap_context_set_psk2, coap_context_set_session_timeout, coap_context_t, coap_dtls_spsk_info_t, coap_dtls_spsk_t, coap_event_t, coap_free_context, coap_get_app_data, coap_io_process, - coap_new_context, coap_register_event_handler, coap_register_response_handler, coap_set_app_data, + coap_new_context, coap_proto_t, coap_register_event_handler, coap_register_response_handler, coap_set_app_data, COAP_BLOCK_SINGLE_BODY, COAP_BLOCK_USE_LIBCOAP, COAP_DTLS_SPSK_SETUP_VERSION, COAP_IO_WAIT, }; @@ -36,14 +36,14 @@ use crate::session::CoapSessionCommon; use crate::session::CoapServerSession; use crate::session::CoapSession; #[cfg(feature = "dtls")] -use crate::transport::CoapDtlsEndpoint; use crate::{ error::{ContextCreationError, EndpointCreationError, IoProcessError}, resource::{CoapResource, UntypedCoapResource}, session::session_response_handler, - transport::{CoapEndpoint, CoapUdpEndpoint, CoapTcpEndpoint}, }; +use crate::transport::CoapEndpoint; + #[derive(Debug)] struct CoapContextInner<'a> { /// Reference to the raw context this context wraps around. @@ -228,27 +228,24 @@ impl CoapContext<'_> { Ok(()) } - /// Creates a new UDP endpoint that is bound to the given address. - pub fn add_endpoint_udp(&mut self, addr: SocketAddr) -> Result<(), EndpointCreationError> { - // SAFETY: Because we never return an owned reference to the endpoint, it cannot outlive the - // context it is bound to (i.e. this one). - let endpoint = unsafe { CoapUdpEndpoint::new(self, addr)? }.into(); + /// Store reference to the endpoint + fn add_endpoint(&mut self, addr: SocketAddr, proto: coap_proto_t) -> Result<(), EndpointCreationError> { + let endpoint = CoapEndpoint::new_endpoint(self, addr, proto)?; + let mut inner_ref = self.inner.borrow_mut(); inner_ref.endpoints.push(endpoint); - // Cannot fail, we just pushed to the Vec. Ok(()) } + /// Creates a new UDP endpoint that is bound to the given address. + pub fn add_endpoint_udp(&mut self, addr: SocketAddr) -> Result<(), EndpointCreationError> { + self.add_endpoint(addr, coap_proto_t::COAP_PROTO_UDP) + } + /// Creates a new TCP endpoint that is bound to the given address. #[cfg(feature = "tcp")] pub fn add_endpoint_tcp(&mut self, addr: SocketAddr) -> Result<(), EndpointCreationError> { - // SAFETY: Because we never return an owned reference to the endpoint, it cannot outlive the - // context it is bound to (i.e. this one). - let endpoint = unsafe { CoapTcpEndpoint::new(self, addr)? }.into(); - let mut inner_ref = self.inner.borrow_mut(); - inner_ref.endpoints.push(endpoint); - // Cannot fail, we just pushed to the Vec. - Ok(()) + self.add_endpoint(addr, coap_proto_t::COAP_PROTO_TCP) } /// Creates a new DTLS endpoint that is bound to the given address. @@ -257,19 +254,14 @@ impl CoapContext<'_> { /// using [set_server_crypto_provider()](CoapContext::set_server_crypto_provider()) #[cfg(feature = "dtls")] pub fn add_endpoint_dtls(&mut self, addr: SocketAddr) -> Result<(), EndpointCreationError> { - // SAFETY: Provided context (i.e., this instance) will not outlive the endpoint, as we will - // drop it alongside this context and never hand out copies of it. - let endpoint = unsafe { CoapDtlsEndpoint::new(self, addr)? }.into(); - let mut inner_ref = self.inner.borrow_mut(); - inner_ref.endpoints.push(endpoint); - // Cannot fail, we just pushed to the Vec. - Ok(()) + self.add_endpoint(addr, coap_proto_t::COAP_PROTO_DTLS) } /// TODO #[cfg(all(feature = "tcp", feature = "dtls"))] pub fn add_endpoint_tls(&mut self, _addr: SocketAddr) -> Result<(), EndpointCreationError> { todo!() + // TODO: self.add_endpoint(addr, coap_proto_t::COAP_PROTO_TLS) } /// Adds the given resource to the resource pool of this context. diff --git a/libcoap/src/lib.rs b/libcoap/src/lib.rs index 36d050e6..f498166f 100644 --- a/libcoap/src/lib.rs +++ b/libcoap/src/lib.rs @@ -102,7 +102,7 @@ //! CoapRequestHandler, CoapResource, //! session::{CoapSessionCommon, CoapServerSession}, //! }; -//! +//! //! // This will give us a SocketAddress with a port in the local port range automatically //! // assigned by the operating system. //! // Because the UdpSocket goes out of scope, the Port will be free for usage by libcoap. diff --git a/libcoap/src/transport.rs b/libcoap/src/transport.rs new file mode 100644 index 00000000..23e26aa3 --- /dev/null +++ b/libcoap/src/transport.rs @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * transport/mod.rs - Module file for CoAP transports. + * This file is part of the libcoap-rs crate, see the README and LICENSE files for + * more information and terms of use. + * Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved. + * See the README as well as the LICENSE file for more information. + */ + +use std::{net::SocketAddr, os::raw::c_uint}; + +use libcoap_sys::{ + coap_endpoint_set_default_mtu, coap_endpoint_t, coap_free_endpoint, coap_new_endpoint, coap_proto_t, +}; + +use crate::{error::EndpointCreationError, types::CoapAddress, CoapContext}; + +pub type EndpointMtu = c_uint; + +#[derive(Debug)] +pub struct CoapEndpoint { + raw_endpoint: *mut coap_endpoint_t, +} + +/// Trait for functions common between all types of endpoints. +impl CoapEndpoint { + /// Sets the default MTU value of the endpoint. + pub fn set_default_mtu(&mut self, mtu: EndpointMtu) { + // SAFETY: as_mut_raw_endpoint cannot fail and will always return a valid reference. + // Modifying the state of the endpoint is also fine, because we have a mutable reference + // of the whole endpoint. + unsafe { + coap_endpoint_set_default_mtu(&mut *self.raw_endpoint, mtu); + } + } + + /// Method utilized by transport protocol specific constructors to actually create the endpoint in libcoap + pub(crate) fn new_endpoint( + context: &mut CoapContext, + addr: SocketAddr, + proto: coap_proto_t, + ) -> Result { + let endpoint = unsafe { + // SAFETY: coap_new_endpoint will return null if it is unable to add new endpoint. + // These states are processed further in the code + coap_new_endpoint( + context.as_mut_raw_context(), + CoapAddress::from(addr).as_raw_address(), + proto, + ) + }; + + if endpoint.is_null() { + Err(EndpointCreationError::Unknown) + } else { + Ok(Self { raw_endpoint: endpoint }) + } + } +} + +impl Drop for CoapEndpoint { + fn drop(&mut self) { + // SAFETY: Raw endpoint is guaranteed to exist for as long as the container exists. + unsafe { coap_free_endpoint(self.raw_endpoint) } + } +} diff --git a/libcoap/src/transport/dtls.rs b/libcoap/src/transport/dtls.rs deleted file mode 100644 index 12cd6a6f..00000000 --- a/libcoap/src/transport/dtls.rs +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * transport/dtls.rs - transport-specific code for DTLS. - * This file is part of the libcoap-rs crate, see the README and LICENSE files for - * more information and terms of use. - * Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved. - * See the README as well as the LICENSE file for more information. - */ - -use std::net::SocketAddr; - -use libcoap_sys::{coap_endpoint_t, coap_free_endpoint, coap_new_endpoint, coap_proto_t::COAP_PROTO_DTLS}; - -use crate::{context::CoapContext, error::EndpointCreationError, transport::EndpointCommon, types::CoapAddress}; - -#[derive(Debug)] -pub struct CoapDtlsEndpoint { - raw_endpoint: *mut coap_endpoint_t, -} - -impl CoapDtlsEndpoint { - /// Creates a new CoapUdpEndpoint and binds it to the supplied SocketAddr. - /// - /// This is an unsafe function (see #Safety for an explanation of why) used internally by - /// libcoap-rs to instantiate new endpoints. You should most likely not use this function, and - /// use one of the following alternatives instead: - /// - If you just want to add an endpoint to the coap context, use [CoapContext::add_endpoint_dtls()]. - /// - If you need to (unsafely) modify the underlying [coap_endpoint_t] directly, use - /// [CoapContext::add_endpoint_dtls()] to instantiate the endpoint and then [as_mut_raw_endpoint()] - /// to access the underlying struct. - /// - /// # Safety - /// All endpoint types defined in this crate contain a [coap_endpoint_t] instance, - /// which is the representation of endpoints used by the underlying libcoap C library. - /// - /// On instantiation, these [coap_endpoint_t] instances are bound to a context, which includes - /// adding them to a list maintained by the [CoapContext] (or — to be more specific — the - /// underlying [libcoap_sys::coap_context_t]. - /// - /// When the context that this endpoint is bound to is dropped, the context calls [libcoap_sys::coap_free_context()], - /// which will not only free the context, but also all [coap_endpoint_t] instances associated - /// with it, including the one this struct points to. - /// - /// Therefore, if you decide to use this function anyway, you have to ensure that the - /// CoapContext lives at least as long as this struct does. - /// Also note that unlike [CoapContext::add_endpoint_dtls()], this function does not add the - /// endpoint to the [CoapContext::endpoints] vector, while the underlying [coap_endpoint_t] is - /// added to the underlying [libcoap_sys::coap_context_t] - pub(crate) unsafe fn new( - context: &mut CoapContext, - addr: SocketAddr, - ) -> Result { - let endpoint = coap_new_endpoint( - context.as_mut_raw_context(), - CoapAddress::from(addr).as_raw_address(), - COAP_PROTO_DTLS, - ); - if endpoint.is_null() { - return Err(EndpointCreationError::Unknown); - } - Ok(CoapDtlsEndpoint { raw_endpoint: endpoint }) - } -} - -impl EndpointCommon for CoapDtlsEndpoint { - unsafe fn as_raw_endpoint(&self) -> &coap_endpoint_t { - // SAFETY: raw_endpoint is checked to be a valid pointer on struct instantiation, cannot be - // freed by anything outside of here (assuming the contract of this function is kept), and - // the default (elided) lifetimes are correct (the pointer is valid as long as the endpoint - // is). - &*self.raw_endpoint - } - - unsafe fn as_mut_raw_endpoint(&mut self) -> &mut coap_endpoint_t { - // SAFETY: raw_endpoint is checked to be a valid pointer on struct instantiation, is not - // freed by anything outside of here (assuming the contract of this function is kept), and - // the default (elided) lifetimes are correct (the pointer is valid as long as the endpoint - // is). - &mut *self.raw_endpoint - } -} - -impl Drop for CoapDtlsEndpoint { - fn drop(&mut self) { - // SAFETY: Raw endpoint is guaranteed to exist for as long as the container exists. - unsafe { coap_free_endpoint(self.raw_endpoint) } - } -} diff --git a/libcoap/src/transport/mod.rs b/libcoap/src/transport/mod.rs deleted file mode 100644 index 128fedcd..00000000 --- a/libcoap/src/transport/mod.rs +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * transport/mod.rs - Module file for CoAP transports. - * This file is part of the libcoap-rs crate, see the README and LICENSE files for - * more information and terms of use. - * Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved. - * See the README as well as the LICENSE file for more information. - */ - -use std::os::raw::c_uint; - -use libcoap_sys::{coap_endpoint_set_default_mtu, coap_endpoint_t}; - -#[cfg(feature = "dtls")] -pub use dtls::CoapDtlsEndpoint; -pub use udp::CoapUdpEndpoint; - -#[cfg(feature = "tcp")] -pub use tcp::CoapTcpEndpoint; - -#[cfg(feature = "dtls")] -mod dtls; -#[cfg(feature = "tcp")] -mod tcp; -#[cfg(all(feature = "dtls", feature = "tcp"))] -mod tls; -mod udp; - -pub type EndpointMtu = c_uint; - -/// Trait for functions common between all types of endpoints. -pub trait EndpointCommon { - /// Provides an immutable reference to the supplied endpoint. - /// - /// # Safety - /// Note that the endpoint expects the reference to be valid for as long as the endpoint - /// itself exists. Therefore, you should never call [coap_free_endpoint()](libcoap_sys::coap_free_endpoint()) - /// or attach the raw endpoint to a context that does not live for as long as the endpoint - /// itself ([coap_free_context()](libcoap_sys::coap_free_context()) is called when the - /// context goes out of scope and then also calls [coap_free_endpoint()](libcoap_sys::coap_free_endpoint())). - unsafe fn as_raw_endpoint(&self) -> &coap_endpoint_t; - - /// Provides a mutable reference to the supplied endpoint. - /// - /// # Safety - /// Note that the endpoint expects the reference to be valid for as long as the endpoint - /// itself exists. Therefore, you should never call [coap_free_endpoint()](libcoap_sys::coap_free_endpoint()) - /// or attach the raw endpoint to a context that does not live for as long as the endpoint - /// itself ([coap_free_context()](libcoap_sys::coap_free_context()) is called when the context - /// goes out of scope and then also calls [coap_free_endpoint()](libcoap_sys::coap_free_endpoint())). - unsafe fn as_mut_raw_endpoint(&mut self) -> &mut coap_endpoint_t; - - /// Sets the default MTU value of the endpoint. - fn set_default_mtu(&mut self, mtu: EndpointMtu) { - // SAFETY: as_mut_raw_endpoint cannot fail and will always return a valid reference. - // Modifying the state of the endpoint is also fine, because we have a mutable reference - // of the whole endpoint. - unsafe { - let raw_endpoint = self.as_mut_raw_endpoint(); - coap_endpoint_set_default_mtu(raw_endpoint, mtu); - } - } -} - -/// Enum representing CoAP endpoints of various types. -#[derive(Debug)] -pub enum CoapEndpoint { - Udp(CoapUdpEndpoint), - #[cfg(feature = "tcp")] - Tcp(CoapTcpEndpoint), - #[cfg(feature = "dtls")] - Dtls(CoapDtlsEndpoint), -} - -impl From for CoapEndpoint { - fn from(ep: CoapUdpEndpoint) -> Self { - CoapEndpoint::Udp(ep) - } -} - -#[cfg(feature = "tcp")] -impl From for CoapEndpoint { - fn from(ep: CoapTcpEndpoint) -> Self { - CoapEndpoint::Tcp(ep) - } -} - -#[cfg(feature = "dtls")] -impl From for CoapEndpoint { - fn from(ep: CoapDtlsEndpoint) -> Self { - CoapEndpoint::Dtls(ep) - } -} - -impl EndpointCommon for CoapEndpoint { - unsafe fn as_raw_endpoint(&self) -> &coap_endpoint_t { - match self { - CoapEndpoint::Udp(ep) => ep.as_raw_endpoint(), - #[cfg(feature = "tcp")] - CoapEndpoint::Tcp(ep) => ep.as_raw_endpoint(), - #[cfg(feature = "dtls")] - CoapEndpoint::Dtls(ep) => ep.as_raw_endpoint(), - } - } - - unsafe fn as_mut_raw_endpoint(&mut self) -> &mut coap_endpoint_t { - match self { - CoapEndpoint::Udp(ep) => ep.as_mut_raw_endpoint(), - #[cfg(feature = "tcp")] - CoapEndpoint::Tcp(ep) => ep.as_mut_raw_endpoint(), - #[cfg(feature = "dtls")] - CoapEndpoint::Dtls(ep) => ep.as_mut_raw_endpoint(), - } - } -} diff --git a/libcoap/src/transport/tcp.rs b/libcoap/src/transport/tcp.rs deleted file mode 100644 index ffda6d57..00000000 --- a/libcoap/src/transport/tcp.rs +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * transport/tcp.rs - transport-specific code for TCP. - * This file is part of the libcoap-rs crate, see the README and LICENSE files for - * more information and terms of use. - * Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved. - * See the README as well as the LICENSE file for more information. - */ - -use libcoap_sys::{coap_endpoint_t, coap_free_endpoint, coap_new_endpoint, coap_proto_t::COAP_PROTO_TCP}; - -use crate::{context::CoapContext, error::EndpointCreationError, transport::EndpointCommon, types::CoapAddress}; - -use std::net::SocketAddr; - -#[cfg(feature = "tcp")] -#[derive(Debug)] -pub struct CoapTcpEndpoint { - raw_endpoint: *mut coap_endpoint_t, -} - -impl CoapTcpEndpoint { - /// Creates a new CoapTcpEndpoint and binds it to the supplied SocketAddr. - /// - /// This is an unsafe function (see #Safety for an explanation of why) used internally by - /// libcoap-rs to instantiate new endpoints. You should most likely not use this function, and - /// use one of the following alternatives instead: - /// - If you just want to add an endpoint to the coap context, use [CoapContext::add_endpoint_tcp()]. - /// - If you need to modify the underlying [coap_endpoint_t] directly (in an unsafe manner), use - /// [CoapContext::add_endpoint_tcp()] to instantiate the endpoint and then [as_mut_raw_endpoint()] - /// to access the underlying struct. - /// - /// # Safety - /// All endpoint types defined in this crate contain a [coap_endpoint_t] instance, - /// which is the representation of endpoints used by the underlying libcoap C library. - /// - /// On instantiation, these [coap_endpoint_t] instances are bound to a context, which includes - /// adding them to a list maintained by the [CoapContext] (or – to be more specific – the - /// underlying [libcoap_sys::coap_context_t]. - /// - /// When the context that this endpoint is bound to is dropped, the context calls [libcoap_sys::coap_free_context()], - /// which will not only free the context, but also all [coap_endpoint_t] instances associated - /// with it, including the one this struct points to. - /// - /// Therefore, if you decide to use this function anyway, you have to ensure that the - /// CoapContext lives at least as long as this struct does. - /// Also note that unlike [CoapContext::add_endpoint_tcp()], this function does not add the - /// endpoint to the [CoapContext::endpoints] vector, while the underlying [coap_endpoint_t] is - /// added to the underlying [libcoap_sys::coap_context_t] - pub(crate) unsafe fn new(context: &mut CoapContext, addr: SocketAddr) -> Result { - let endpoint = coap_new_endpoint( - context.as_mut_raw_context(), - CoapAddress::from(addr).as_raw_address(), - COAP_PROTO_TCP, - ); - if endpoint.is_null() { - return Err(EndpointCreationError::Unknown); - } - Ok(Self { raw_endpoint: endpoint }) - } -} - -impl EndpointCommon for CoapTcpEndpoint { - unsafe fn as_raw_endpoint(&self) -> &coap_endpoint_t { - // SAFETY: raw_endpoint is checked to be a valid pointer on struct instantiation, cannot be - // freed by anything outside of here (assuming the contract of this function is kept), and - // the default (elided) lifetimes are correct (the pointer is valid as long as the endpoint - // is). - &*self.raw_endpoint - } - - unsafe fn as_mut_raw_endpoint(&mut self) -> &mut coap_endpoint_t { - // SAFETY: raw_endpoint is checked to be a valid pointer on struct instantiation, is not - // freed by anything outside of here (assuming the contract of this function is kept), and - // the default (elided) lifetimes are correct (the pointer is valid as long as the endpoint - // is). - &mut *self.raw_endpoint - } -} - -impl Drop for CoapTcpEndpoint { - fn drop(&mut self) { - // SAFETY: Raw endpoint is guaranteed to exist for as long as the container exists. - unsafe { coap_free_endpoint(self.raw_endpoint) } - } -} diff --git a/libcoap/src/transport/tls.rs b/libcoap/src/transport/tls.rs deleted file mode 100644 index 00f8b0a1..00000000 --- a/libcoap/src/transport/tls.rs +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * transport/dtls.rs - transport-specific code for TLS. - * This file is part of the libcoap-rs crate, see the README and LICENSE files for - * more information and terms of use. - * Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved. - * See the README as well as the LICENSE file for more information. - */ - -/// TODO -#[allow(dead_code)] -#[cfg(feature = "tcp")] -pub struct CoapTlsEndpoint {} diff --git a/libcoap/src/transport/udp.rs b/libcoap/src/transport/udp.rs deleted file mode 100644 index eaaf171a..00000000 --- a/libcoap/src/transport/udp.rs +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * transport/dtls.rs - transport-specific code for UDP. - * This file is part of the libcoap-rs crate, see the README and LICENSE files for - * more information and terms of use. - * Copyright © 2021-2023 The NAMIB Project Developers, all rights reserved. - * See the README as well as the LICENSE file for more information. - */ - -use std::net::SocketAddr; - -use libcoap_sys::{coap_endpoint_t, coap_free_endpoint, coap_new_endpoint, coap_proto_t::COAP_PROTO_UDP}; - -use crate::{context::CoapContext, error::EndpointCreationError, transport::EndpointCommon, types::CoapAddress}; - -#[derive(Debug)] -pub struct CoapUdpEndpoint { - raw_endpoint: *mut coap_endpoint_t, -} - -impl CoapUdpEndpoint { - /// Creates a new CoapUdpEndpoint and binds it to the supplied SocketAddr. - /// - /// This is an unsafe function (see #Safety for an explanation of why) used internally by - /// libcoap-rs to instantiate new endpoints. You should most likely not use this function, and - /// use one of the following alternatives instead: - /// - If you just want to add an endpoint to the coap context, use [CoapContext::add_endpoint_udp()]. - /// - If you need to modify the underlying [coap_endpoint_t] directly (in an unsafe manner), use - /// [CoapContext::add_endpoint_udp()] to instantiate the endpoint and then [as_mut_raw_endpoint()] - /// to access the underlying struct. - /// - /// # Safety - /// All endpoint types defined in this crate contain a [coap_endpoint_t] instance, - /// which is the representation of endpoints used by the underlying libcoap C library. - /// - /// On instantiation, these [coap_endpoint_t] instances are bound to a context, which includes - /// adding them to a list maintained by the [CoapContext] (or – to be more specific – the - /// underlying [libcoap_sys::coap_context_t]. - /// - /// When the context that this endpoint is bound to is dropped, the context calls [libcoap_sys::coap_free_context()], - /// which will not only free the context, but also all [coap_endpoint_t] instances associated - /// with it, including the one this struct points to. - /// - /// Therefore, if you decide to use this function anyway, you have to ensure that the - /// CoapContext lives at least as long as this struct does. - /// Also note that unlike [CoapContext::add_endpoint_udp()], this function does not add the - /// endpoint to the [CoapContext::endpoints] vector, while the underlying [coap_endpoint_t] is - /// added to the underlying [libcoap_sys::coap_context_t] - pub(crate) unsafe fn new( - context: &mut CoapContext, - addr: SocketAddr, - ) -> Result { - let endpoint = coap_new_endpoint( - context.as_mut_raw_context(), - CoapAddress::from(addr).as_raw_address(), - COAP_PROTO_UDP, - ); - if endpoint.is_null() { - return Err(EndpointCreationError::Unknown); - } - Ok(CoapUdpEndpoint { raw_endpoint: endpoint }) - } -} - -impl EndpointCommon for CoapUdpEndpoint { - unsafe fn as_raw_endpoint(&self) -> &coap_endpoint_t { - // SAFETY: raw_endpoint is checked to be a valid pointer on struct instantiation, cannot be - // freed by anything outside of here (assuming the contract of this function is kept), and - // the default (elided) lifetimes are correct (the pointer is valid as long as the endpoint - // is). - &*self.raw_endpoint - } - - unsafe fn as_mut_raw_endpoint(&mut self) -> &mut coap_endpoint_t { - // SAFETY: raw_endpoint is checked to be a valid pointer on struct instantiation, is not - // freed by anything outside of here (assuming the contract of this function is kept), and - // the default (elided) lifetimes are correct (the pointer is valid as long as the endpoint - // is). - &mut *self.raw_endpoint - } -} - -impl Drop for CoapUdpEndpoint { - fn drop(&mut self) { - // SAFETY: Raw endpoint is guaranteed to exist for as long as the container exists. - unsafe { coap_free_endpoint(self.raw_endpoint) } - } -}