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}