ya_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")]
18mod dhcpv4;
19#[cfg(feature = "socket-icmp")]
20mod icmp;
21#[cfg(feature = "socket-raw")]
22mod raw;
23#[cfg(feature = "socket-tcp")]
24mod tcp;
25#[cfg(feature = "socket-udp")]
26mod udp;
27
28#[cfg(feature = "async")]
29mod waker;
30
31#[cfg(feature = "socket-dhcpv4")]
32pub use self::dhcpv4::{Config as Dhcpv4Config, Dhcpv4Socket, Event as Dhcpv4Event};
33#[cfg(feature = "socket-icmp")]
34pub use self::icmp::{Endpoint as IcmpEndpoint, IcmpPacketMetadata, IcmpSocket, IcmpSocketBuffer};
35#[cfg(feature = "socket-raw")]
36pub use self::raw::{RawPacketMetadata, RawSocket, RawSocketBuffer};
37#[cfg(feature = "socket-tcp")]
38pub use self::tcp::{SocketBuffer as TcpSocketBuffer, State as TcpState, TcpSocket};
39#[cfg(feature = "socket-udp")]
40pub use self::udp::{UdpPacketMetadata, UdpSocket, UdpSocketBuffer};
41
42#[cfg(feature = "async")]
43pub(crate) use self::waker::WakerRegistration;
44
45/// Gives an indication on the next time the socket should be polled.
46#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
47#[cfg_attr(feature = "defmt", derive(defmt::Format))]
48pub(crate) enum PollAt {
49    /// The socket needs to be polled immidiately.
50    Now,
51    /// The socket needs to be polled at given [Instant][struct.Instant].
52    Time(Instant),
53    /// The socket does not need to be polled unless there are external changes.
54    Ingress,
55}
56
57/// A network socket.
58///
59/// This enumeration abstracts the various types of sockets based on the IP protocol.
60/// To downcast a `Socket` value to a concrete socket, use the [AnySocket] trait,
61/// e.g. to get `UdpSocket`, call `UdpSocket::downcast(socket)`.
62///
63/// It is usually more convenient to use [SocketSet::get] instead.
64///
65/// [AnySocket]: trait.AnySocket.html
66/// [SocketSet::get]: struct.SocketSet.html#method.get
67#[derive(Debug)]
68pub enum Socket<'a> {
69    #[cfg(feature = "socket-raw")]
70    Raw(RawSocket<'a>),
71    #[cfg(feature = "socket-icmp")]
72    Icmp(IcmpSocket<'a>),
73    #[cfg(feature = "socket-udp")]
74    Udp(UdpSocket<'a>),
75    #[cfg(feature = "socket-tcp")]
76    Tcp(TcpSocket<'a>),
77    #[cfg(feature = "socket-dhcpv4")]
78    Dhcpv4(Dhcpv4Socket),
79}
80
81impl<'a> Socket<'a> {
82    pub(crate) fn poll_at(&self, cx: &mut Context) -> PollAt {
83        match self {
84            #[cfg(feature = "socket-raw")]
85            Socket::Raw(s) => s.poll_at(cx),
86            #[cfg(feature = "socket-icmp")]
87            Socket::Icmp(s) => s.poll_at(cx),
88            #[cfg(feature = "socket-udp")]
89            Socket::Udp(s) => s.poll_at(cx),
90            #[cfg(feature = "socket-tcp")]
91            Socket::Tcp(s) => s.poll_at(cx),
92            #[cfg(feature = "socket-dhcpv4")]
93            Socket::Dhcpv4(s) => s.poll_at(cx),
94        }
95    }
96}
97
98/// A conversion trait for network sockets.
99pub trait AnySocket<'a>: Sized {
100    fn upcast(self) -> Socket<'a>;
101    fn downcast<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self>;
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 mut Socket<'a>) -> Option<&'c mut Self> {
112                #[allow(unreachable_patterns)]
113                match socket {
114                    Socket::$variant(socket) => Some(socket),
115                    _ => None,
116                }
117            }
118        }
119    };
120}
121
122#[cfg(feature = "socket-raw")]
123from_socket!(RawSocket<'a>, Raw);
124#[cfg(feature = "socket-icmp")]
125from_socket!(IcmpSocket<'a>, Icmp);
126#[cfg(feature = "socket-udp")]
127from_socket!(UdpSocket<'a>, Udp);
128#[cfg(feature = "socket-tcp")]
129from_socket!(TcpSocket<'a>, Tcp);
130#[cfg(feature = "socket-dhcpv4")]
131from_socket!(Dhcpv4Socket, Dhcpv4);