Skip to main content

edge_nal/
tcp.rs

1//! Trait for modeling TCP socket shutdown
2
3use embedded_io_async::ErrorType;
4
5/// Enum representing the different ways to close a TCP socket
6#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
7pub enum Close {
8    /// Close the read half of the socket
9    Read,
10    /// Close the write half of the socket
11    Write,
12    /// Close both the read and write halves of the socket
13    Both,
14}
15
16/// This trait is implemented by TCP sockets and models their shutdown functionality,
17/// which is unique to the TCP protocol (UDP sockets do not have a shutdown procedure).
18pub trait TcpShutdown: ErrorType {
19    /// Gracefully shutdown either or both the read and write halves of the socket.
20    ///
21    /// The write half is closed by sending a FIN packet to the peer and then waiting
22    /// until the FIN packet is ACKed.
23    ///
24    /// The read half is "closed" by reading from it until the peer indicates there is
25    /// no more data to read (i.e. it sends a FIN packet to the local socket).
26    /// Whether the other peer will send a FIN packet or not is not guaranteed, as that's
27    /// application protocol-specific. Usually, closing the write half means the peer will
28    /// notice and will send a FIN packet to the read half, thus "closing" it too.
29    ///
30    /// Note that - on certain platforms that don't have built-in timeouts - this method might never
31    /// complete if the peer is unreachable / misbehaving, so it has to be used with a
32    /// proper timeout in-place.
33    ///
34    /// Also note that calling this function multiple times may result in different behavior,
35    /// depending on the platform.
36    async fn close(&mut self, what: Close) -> Result<(), Self::Error>;
37
38    /// Abort the connection, sending an RST packet to the peer
39    ///
40    /// This method will not wait forever, because the RST packet is not ACKed by the peer.
41    ///
42    /// Note that on certain platforms (STD for example) this method might be a no-op
43    /// as the connection there is automatically aborted when the socket is dropped.
44    ///
45    /// Also note that calling this function multiple times may result in different behavior,
46    /// depending on the platform.
47    async fn abort(&mut self) -> Result<(), Self::Error>;
48}
49
50impl<T> TcpShutdown for &mut T
51where
52    T: TcpShutdown,
53{
54    async fn close(&mut self, what: Close) -> Result<(), Self::Error> {
55        (**self).close(what).await
56    }
57
58    async fn abort(&mut self) -> Result<(), Self::Error> {
59        (**self).abort().await
60    }
61}