pub struct UdpSocket<'a, 'd> { /* private fields */ }Expand description
A UDP socket borrowed from a Stack, returned by Stack::udp_socket.
Implementations§
Source§impl UdpSocket<'_, '_>
impl UdpSocket<'_, '_>
Sourcepub fn local_addr(&self) -> ListenSocketAddr
pub fn local_addr(&self) -> ListenSocketAddr
Return the bound local address.
See bind for details on how UDP socket binding works.
Returns ListenSocketAddr::UNSPECIFIED if not bound.
Sourcepub fn remote_addr(&self) -> ListenSocketAddr
pub fn remote_addr(&self) -> ListenSocketAddr
Return the bound remote address.
See bind for details on how UDP socket binding works.
Returns ListenSocketAddr::UNSPECIFIED if not bound.
Sourcepub fn hop_limit(&self) -> Option<u8>
pub fn hop_limit(&self) -> Option<u8>
Return the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
See also the set_hop_limit method.
Sourcepub fn set_hop_limit(
&mut self,
hop_limit: Option<u8>,
) -> Result<(), InvalidHopLimit>
pub fn set_hop_limit( &mut self, hop_limit: Option<u8>, ) -> Result<(), InvalidHopLimit>
Set the time-to-live (IPv4) or hop limit (IPv6) value used in outgoing packets.
A socket without an explicitly set hop limit value uses the default IANA recommended value (64).
§Errors
InvalidHopLimit: if the hop limit isSome(0). A host must not send a packet with a hop limit of zero (RFC 1122 § 3.2.1.7). The socket is left unchanged.
Sourcepub fn bind_to_iface(
&mut self,
iface: Option<IfaceHandle>,
) -> Result<(), BindError>
pub fn bind_to_iface( &mut self, iface: Option<IfaceHandle>, ) -> Result<(), BindError>
Bind the socket to an interface, or unbind it with None.
A socket bound to an interface only sends and receives packets on it:
- Destinations must be on-link on that iface, or have a route through it.
- Broadcast and multicast destinations go out on that iface only
- Local addresses will be picked from that iface only.
The socket must be closed. The binding is kept across
close, so a socket stays bound to its interface when
it is bound again.
Two sockets with otherwise identical tuples may coexist if they are bound to different interfaces. On ingress, a socket bound to the arrival interface wins over an unbound one with an equal tuple.
§Errors
InvalidState: if the socket is open.
Sourcepub fn bound_iface(&self) -> Option<IfaceHandle>
pub fn bound_iface(&self) -> Option<IfaceHandle>
Return the interface the socket is bound to, or None.
See bind_to_iface.
Sourcepub fn bind(
&mut self,
local: impl Into<ListenSocketAddr>,
remote: impl Into<ListenSocketAddr>,
) -> Result<(), BindError>
pub fn bind( &mut self, local: impl Into<ListenSocketAddr>, remote: impl Into<ListenSocketAddr>, ) -> Result<(), BindError>
Bind the socket.
This method opens the socket and configures which packets it will
send and receive. It is equivalent to bind() and/or connect() in the
BSD / Linux socket API.
§Local address
None: the socket sends/receives packets with any local address. It receives packets destined to unicast, multicast and broadcast addresses.Some(V4(UNSPECIFIED)): same asNone, but IPv4 packets only.Some(V6(UNSPECIFIED)): same asNone, but IPv6 packets only.Some(_): the socket sends/receives packets from/to the given local address only.- If unicast, the stack checks the address is ours, else returns
Unaddressable. - Multicast and broadcast addresses are allowed, but then the socket can receive only, not send.
- If unicast, the stack checks the address is ours, else returns
§Local port
0: the stack allocates an unused ephemeral port. You can retrieve it withlocal_addr.- non-zero: the given port is used.
The socket only receives packets to that port and sends from that port. A UDP socket must be bound to at least a port, there’s no way to make a UDP socket listen on all ports.
§Remote address
None: the socket sends/receives packets with any remote address.Some(V4(UNSPECIFIED)): same asNone, but IPv4 packets only.Some(V6(UNSPECIFIED)): same asNone, but IPv6 packets only.Some(_): the socket sends/receives packets to/from the given remote address only. Multicast and broadcast addresses are allowed, but then the socket can send only, not receive.
§Remote port
0: the socket sends/receives packets to/from any remote port.- non-zero: the socket sends/receives packets to/from the given port only.
Overlapping bindings between sockets are allowed as long as they’re
not identical. For example you can bind a socket to *:53 and another to
1.2.3.4:53, but you can’t bind two sockets to *:53. If a packet
matches multiple sockets, the one with the most specific binding wins.
Packets are not duplicated, only the winning socket will receive it.
Multicast groups are not joined automatically, you must call Iface::join_multicast_group yourself.
§Errors
InvalidState: if the socket is already bound (see is_open).InUse: on an identical bind.NoFreePorts: if the ephemeral range is exhausted.Unaddressable: on an address family mismatch, if the local address is not ours, or if no local address is available for the given remote.
Sourcepub fn register_recv_waker(&mut self, waker: &Waker)
pub fn register_recv_waker(&mut self, waker: &Waker)
Register a waker for receive operations.
The waker is woken on state changes that might affect the return value of
recv calls, such as receiving data, or the socket closing.
Notes:
- Only one waker can be registered at a time. If another waker was previously registered, it is overwritten and will no longer be woken.
- The Waker is woken only once. Once woken, you must register it again before incoming data may wake it again.
- “Spurious wakes” are allowed: a wake doesn’t guarantee the result of
recvhas changed.
Sourcepub fn register_send_waker(&mut self, waker: &Waker)
pub fn register_send_waker(&mut self, waker: &Waker)
Register a waker for send operations.
The waker is woken on state changes that might affect the return value of
send calls, such as:
- the socket is bound or closed.
- A send failed with
SendError::DeviceBusyand the driver becomes no longer busy.
It is not woken when a packet buffer is freed after
SendError::NoBuffer. Retry that on your own.
Notes:
- Only one waker can be registered at a time. If another waker was previously registered, it is overwritten and will no longer be woken.
- The Waker is woken only once. Once woken, you must register it again before it may be woken again.
- “Spurious wakes” are allowed: a wake doesn’t guarantee the result of
sendhas changed.
Sourcepub fn recv(&mut self) -> Result<RecvPacket, RecvError>
pub fn recv(&mut self) -> Result<RecvPacket, RecvError>
Dequeue a received datagram, as an owned packet (RecvPacket).
This is zero-copy: the returned value is the buffer the datagram arrived in.
§Errors
InvalidState: if the socket is not bound.Exhausted: if the RX queue is empty.IcmpError: with theicmp-errorsfeature, if an ICMP error is pending. It is reported before any queued datagram, once, and taking it clears it. Seetake_icmp_error.
Sourcepub fn recv_slice(
&mut self,
data: &mut [u8],
) -> Result<(usize, UdpMetadata), RecvError>
pub fn recv_slice( &mut self, data: &mut [u8], ) -> Result<(usize, UdpMetadata), RecvError>
Dequeue a received datagram, copying the payload into the given slice, and return the number of octets copied along with its metadata.
See also recv.
§Errors
InvalidState: if the socket is not bound.Exhausted: if the RX queue is empty.Truncated: ifdatais smaller than the payload. The packet is dropped.IcmpError: with theicmp-errorsfeature, if an ICMP error is pending. See recv.
Sourcepub fn peek(&mut self) -> Result<(&[u8], UdpMetadata), RecvError>
pub fn peek(&mut self) -> Result<(&[u8], UdpMetadata), RecvError>
Peek at the next received datagram without dequeueing it, returning its payload and its metadata.
§Errors
InvalidState: if the socket is not bound.Exhausted: if the RX queue is empty.
Sourcepub fn peek_slice(
&mut self,
data: &mut [u8],
) -> Result<(usize, UdpMetadata), RecvError>
pub fn peek_slice( &mut self, data: &mut [u8], ) -> Result<(usize, UdpMetadata), RecvError>
Peek at the next received datagram without dequeueing it, copying the payload into the given slice.
See also peek.
§Errors
InvalidState: if the socket is not bound.Exhausted: if the RX queue is empty.Truncated: ifdatais smaller than the payload. No data is copied and the packet stays in the queue.
Sourcepub fn take_icmp_error(&mut self) -> Option<(IcmpError, SocketAddr)>
pub fn take_icmp_error(&mut self) -> Option<(IcmpError, SocketAddr)>
Take the pending ICMP error, if one has been reported against this socket: the kind of error and the remote address the erring packet was sent to.
When an ICMP error message arrives, from the network (e.g. port
unreachable) or generated locally when neighbor resolution for a
destination fails, it is delivered to the most specific socket matching the
quoted packet’s flow, like ordinary ingress demux, and stored here. A single
error is kept (the newest wins), reported once through either this method or
recv, whichever is called first, and cleared by the report.
The RX waker is woken when an error is recorded.
The remote address is attached so that errors on unconnected sockets are attributable.
Sourcepub fn send_slice(
&mut self,
data: &[u8],
meta: impl Into<UdpMetadata>,
) -> Result<(), SendError>
pub fn send_slice( &mut self, data: &[u8], meta: impl Into<UdpMetadata>, ) -> Result<(), SendError>
Send a datagram to the given remote address, copying the payload from a slice.
See send_with.
Sourcepub fn send_with(
&mut self,
max_size: usize,
meta: impl Into<UdpMetadata>,
f: impl FnOnce(&mut [u8]) -> usize,
) -> Result<(), SendError>
pub fn send_with( &mut self, max_size: usize, meta: impl Into<UdpMetadata>, f: impl FnOnce(&mut [u8]) -> usize, ) -> Result<(), SendError>
Send a datagram, building the payload in place.
The destination is meta.remote_addr, with unspecified parts defaulted from
the socket’s bound remote address. On a connected socket, sending to
SocketAddr::UNSPECIFIED sends to the connected remote. An explicitly
specified destination is honored even on a connected socket.
The closure gets a max_size-byte slice inside a freshly allocated packet
buffer, and returns how many bytes it wrote. The datagram is then sent
immediately. If the destination’s neighbor is unresolved, the packet is queued
inside the stack and sent when resolution completes. This still counts as a
successful send.
meta.meta is attached to the packet and handed to the driver with it: an id
to tag the packet with, or a request to timestamp its transmission (see
Stack::poll_tx_timestamp).
§Errors
InvalidState: if the socket is not bound.Unaddressable: if the destination address or port is still unspecified after defaulting, the destination’s address family does not match the source address, no source address is available, or the source address is not assigned to any interface.BufferFull: if the payload cannot fit in a packet buffer.NoBuffer: if every packet buffer is in use.DeviceBusy: if the interface the datagram would go out of has no room for it right now.
Sourcepub fn alloc(&self) -> Option<PacketBuf>
pub fn alloc(&self) -> Option<PacketBuf>
Allocate an empty UDP payload buffer with headroom for the headers.
Allocation works before binding. Returns None if every packet buffer
is in use. Set the payload length with PacketBuf::set_len before writing.
Sourcepub fn send_headroom(&self) -> usize
pub fn send_headroom(&self) -> usize
Headroom to reserve in a buffer for send_packet, so
that the payload isn’t moved.
Sourcepub fn send_packet(
&mut self,
buf: PacketBuf,
meta: impl Into<UdpMetadata>,
) -> Result<(), (SendError, PacketBuf)>
pub fn send_packet( &mut self, buf: PacketBuf, meta: impl Into<UdpMetadata>, ) -> Result<(), (SendError, PacketBuf)>
Send an owned UDP payload, adding the UDP, IP, and link headers.
The buffer contains only the payload. Reserve
send_headroom to avoid moving it. Addresses and
packet metadata come from meta, as in send_with,
replacing the buffer’s metadata.
Errors return the buffer unchanged. Errors match send_with,
except this method allocates no payload buffer and never returns SendError::NoBuffer.
Success transfers ownership to the stack; it does not guarantee delivery.