1 /*! Communication between endpoints. 2 3 The `socket` module deals with *network endpoints* and *buffering*. 4 It provides interfaces for accessing buffers of data, and protocol state machines 5 for filling and emptying these buffers. 6 7 The programming interface implemented here differs greatly from the common Berkeley socket 8 interface. Specifically, in the Berkeley interface the buffering is implicit: 9 the operating system decides on the good size for a buffer and manages it. 10 The interface implemented by this module uses explicit buffering: you decide on the good 11 size for a buffer, allocate it, and let the networking stack use it. 12 */ 13 14 use crate::iface::Context; 15 use crate::time::Instant; 16 17 #[cfg(feature = "socket-dhcpv4")] 18 pub mod dhcpv4; 19 #[cfg(feature = "socket-dns")] 20 pub mod dns; 21 #[cfg(feature = "socket-icmp")] 22 pub mod icmp; 23 #[cfg(feature = "socket-raw")] 24 pub mod raw; 25 #[cfg(feature = "socket-tcp")] 26 pub mod tcp; 27 #[cfg(feature = "socket-udp")] 28 pub mod udp; 29 30 #[cfg(feature = "async")] 31 mod waker; 32 33 #[cfg(feature = "async")] 34 pub(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))] 39 pub(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)] 59 pub 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 74 impl<'a> Socket<'a> { poll_at(&self, cx: &mut Context) -> PollAt75 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. 94 pub trait AnySocket<'a> { upcast(self) -> Socket<'a>95 fn upcast(self) -> Socket<'a>; downcast<'c>(socket: &'c Socket<'a>) -> Option<&'c Self> where Self: Sized96 fn downcast<'c>(socket: &'c Socket<'a>) -> Option<&'c Self> 97 where 98 Self: Sized; downcast_mut<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self> where Self: Sized99 fn downcast_mut<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self> 100 where 101 Self: Sized; 102 } 103 104 macro_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")] 131 from_socket!(raw::Socket<'a>, Raw); 132 #[cfg(feature = "socket-icmp")] 133 from_socket!(icmp::Socket<'a>, Icmp); 134 #[cfg(feature = "socket-udp")] 135 from_socket!(udp::Socket<'a>, Udp); 136 #[cfg(feature = "socket-tcp")] 137 from_socket!(tcp::Socket<'a>, Tcp); 138 #[cfg(feature = "socket-dhcpv4")] 139 from_socket!(dhcpv4::Socket<'a>, Dhcpv4); 140 #[cfg(feature = "socket-dns")] 141 from_socket!(dns::Socket<'a>, Dns); 142