smoltcp/socket/
mod.rs

1/*! Communication between endpoints.
2
3The `socket` module deals with *network endpoints* and *buffering*.
4It provides interfaces for accessing buffers of data, and protocol state machines
5for filling and emptying these buffers.
6
7The programming interface implemented here differs greatly from the common Berkeley socket
8interface. Specifically, in the Berkeley interface the buffering is implicit:
9the operating system decides on the good size for a buffer and manages it.
10The interface implemented by this module uses explicit buffering: you decide on the good
11size for a buffer, allocate it, and let the networking stack use it.
12*/
13
14use crate::iface::Context;
15use crate::time::Instant;
16
17#[cfg(feature = "socket-dhcpv4")]
18pub mod dhcpv4;
19#[cfg(feature = "socket-dns")]
20pub mod dns;
21#[cfg(feature = "socket-icmp")]
22pub mod icmp;
23#[cfg(feature = "socket-raw")]
24pub mod raw;
25#[cfg(feature = "socket-tcp")]
26pub mod tcp;
27#[cfg(feature = "socket-udp")]
28pub mod udp;
29
30#[cfg(feature = "async")]
31mod waker;
32
33#[cfg(feature = "async")]
34pub(crate) use self::waker::WakerRegistration;
35
36/// Gives an indication on the next time the socket should be polled.
37#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
38#[cfg_attr(feature = "defmt", derive(defmt::Format))]
39pub(crate) enum PollAt {
40    /// The socket needs to be polled immediately.
41    Now,
42    /// The socket needs to be polled at given [Instant][struct.Instant].
43    Time(Instant),
44    /// The socket does not need to be polled unless there are external changes.
45    Ingress,
46}
47
48/// A network socket.
49///
50/// This enumeration abstracts the various types of sockets based on the IP protocol.
51/// To downcast a `Socket` value to a concrete socket, use the [AnySocket] trait,
52/// e.g. to get `udp::Socket`, call `udp::Socket::downcast(socket)`.
53///
54/// It is usually more convenient to use [SocketSet::get] instead.
55///
56/// [AnySocket]: trait.AnySocket.html
57/// [SocketSet::get]: struct.SocketSet.html#method.get
58#[derive(Debug)]
59pub enum Socket<'a> {
60    #[cfg(feature = "socket-raw")]
61    Raw(raw::Socket<'a>),
62    #[cfg(feature = "socket-icmp")]
63    Icmp(icmp::Socket<'a>),
64    #[cfg(feature = "socket-udp")]
65    Udp(udp::Socket<'a>),
66    #[cfg(feature = "socket-tcp")]
67    Tcp(tcp::Socket<'a>),
68    #[cfg(feature = "socket-dhcpv4")]
69    Dhcpv4(dhcpv4::Socket<'a>),
70    #[cfg(feature = "socket-dns")]
71    Dns(dns::Socket<'a>),
72}
73
74impl<'a> Socket<'a> {
75    pub(crate) fn poll_at(&self, cx: &mut Context) -> PollAt {
76        match self {
77            #[cfg(feature = "socket-raw")]
78            Socket::Raw(s) => s.poll_at(cx),
79            #[cfg(feature = "socket-icmp")]
80            Socket::Icmp(s) => s.poll_at(cx),
81            #[cfg(feature = "socket-udp")]
82            Socket::Udp(s) => s.poll_at(cx),
83            #[cfg(feature = "socket-tcp")]
84            Socket::Tcp(s) => s.poll_at(cx),
85            #[cfg(feature = "socket-dhcpv4")]
86            Socket::Dhcpv4(s) => s.poll_at(cx),
87            #[cfg(feature = "socket-dns")]
88            Socket::Dns(s) => s.poll_at(cx),
89        }
90    }
91}
92
93/// A conversion trait for network sockets.
94pub trait AnySocket<'a> {
95    fn upcast(self) -> Socket<'a>;
96    fn downcast<'c>(socket: &'c Socket<'a>) -> Option<&'c Self>
97    where
98        Self: Sized;
99    fn downcast_mut<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self>
100    where
101        Self: Sized;
102}
103
104macro_rules! from_socket {
105    ($socket:ty, $variant:ident) => {
106        impl<'a> AnySocket<'a> for $socket {
107            fn upcast(self) -> Socket<'a> {
108                Socket::$variant(self)
109            }
110
111            fn downcast<'c>(socket: &'c Socket<'a>) -> Option<&'c Self> {
112                #[allow(unreachable_patterns)]
113                match socket {
114                    Socket::$variant(socket) => Some(socket),
115                    _ => None,
116                }
117            }
118
119            fn downcast_mut<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self> {
120                #[allow(unreachable_patterns)]
121                match socket {
122                    Socket::$variant(socket) => Some(socket),
123                    _ => None,
124                }
125            }
126        }
127    };
128}
129
130#[cfg(feature = "socket-raw")]
131from_socket!(raw::Socket<'a>, Raw);
132#[cfg(feature = "socket-icmp")]
133from_socket!(icmp::Socket<'a>, Icmp);
134#[cfg(feature = "socket-udp")]
135from_socket!(udp::Socket<'a>, Udp);
136#[cfg(feature = "socket-tcp")]
137from_socket!(tcp::Socket<'a>, Tcp);
138#[cfg(feature = "socket-dhcpv4")]
139from_socket!(dhcpv4::Socket<'a>, Dhcpv4);
140#[cfg(feature = "socket-dns")]
141from_socket!(dns::Socket<'a>, Dns);