tokio_fast_udp/item.rs
1use std::net::SocketAddr;
2
3use crate::Ecn;
4
5/// A single outbound UDP datagram.
6///
7/// Build with [`SendItem::new`] and optionally chain [`ecn`] / [`segment_size`]
8/// to attach ancillary data.
9///
10/// When [`segment_size`] is set and the platform supports it (Linux GSO), the
11/// kernel will segment `data` into multiple datagrams of `segment_size` bytes
12/// each (the final segment may be shorter). This allows sending N packets in
13/// a single syscall.
14///
15/// [`ecn`]: SendItem::ecn
16/// [`segment_size`]: SendItem::segment_size
17#[derive(Clone, Copy)]
18pub struct SendItem<'a> {
19 pub(crate) data: &'a [u8],
20 pub(crate) destination: SocketAddr,
21 pub(crate) ecn: Option<Ecn>,
22 pub(crate) segment_size: Option<u16>,
23}
24
25impl<'a> SendItem<'a> {
26 /// Create a datagram targeting `destination` with the given `data` payload.
27 /// Address comes first, then data.
28 pub fn new(destination: SocketAddr, data: &'a [u8]) -> Self {
29 SendItem {
30 data,
31 destination,
32 ecn: None,
33 segment_size: None,
34 }
35 }
36
37 /// Attach an ECN codepoint to the outgoing datagram.
38 pub fn ecn(mut self, ecn: Ecn) -> Self {
39 self.ecn = Some(ecn);
40 self
41 }
42
43 /// Enable UDP segmentation offload (GSO on Linux). The kernel will split
44 /// `data` into consecutive chunks of `segment_size` bytes and send each as
45 /// a separate UDP datagram to the same `destination`.
46 ///
47 /// `data.len()` must be a multiple of `segment_size`, except for the final
48 /// segment which may be shorter.
49 pub fn segment_size(mut self, segment_size: u16) -> Self {
50 self.segment_size = Some(segment_size);
51 self
52 }
53}
54
55/// A single inbound UDP datagram slot.
56///
57/// Create with [`ReceiveItem::new`] passing a buffer, then call
58/// [`FastUdpSocket::receive_many`] to fill it. After a successful receive,
59/// [`data`] / [`source`] / [`ecn`] / [`len`] return the received datagram's
60/// metadata.
61///
62/// [`data`]: ReceiveItem::data
63/// [`source`]: ReceiveItem::source
64/// [`ecn`]: ReceiveItem::ecn
65/// [`len`]: ReceiveItem::len
66/// [`FastUdpSocket::receive_many`]: crate::FastUdpSocket::receive_many
67pub struct ReceiveItem<'a> {
68 pub(crate) buf: &'a mut [u8],
69 pub(crate) source: SocketAddr,
70 pub(crate) ecn: Option<Ecn>,
71 pub(crate) len: usize,
72}
73
74impl<'a> ReceiveItem<'a> {
75 /// Create an empty receive slot backed by `buf`.
76 pub fn new(buf: &'a mut [u8]) -> Self {
77 ReceiveItem {
78 buf,
79 source: SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED), 0),
80 ecn: None,
81 len: 0,
82 }
83 }
84
85 /// The received payload (first `len` bytes of the internal buffer).
86 pub fn data(&self) -> &[u8] {
87 &self.buf[..self.len]
88 }
89
90 /// The source address of the received datagram.
91 pub fn source(&self) -> SocketAddr {
92 self.source
93 }
94
95 /// The ECN codepoint received with the datagram, if any.
96 pub fn ecn(&self) -> Option<Ecn> {
97 self.ecn
98 }
99
100 /// Number of bytes received.
101 pub fn len(&self) -> usize {
102 self.len
103 }
104
105 /// Whether zero bytes were received.
106 pub fn is_empty(&self) -> bool {
107 self.len == 0
108 }
109}