pub struct Datagrams<'a> {
pub destination: SocketAddr,
pub src_ip: Option<IpAddr>,
pub ecn: Option<EcnCodepoint>,
pub segment_size: Option<usize>,
pub contents: &'a [u8],
}Expand description
One send: a destination, and between one and many datagrams.
Fields§
§destination: SocketAddr§src_ip: Option<IpAddr>The source address to send from. Needed when the socket is bound to a wildcard v6 address and the stack has to keep answering from the address a peer first saw.
ecn: Option<EcnCodepoint>The ECN codepoint to mark these datagrams with, if any.
segment_size: Option<usize>Some(n) is GSO: contents is a run of datagrams of n bytes each
(the last may be shorter), to be sent by one syscall. None is a
single datagram.
A socket whose UdpCaps::max_send_segments is 1 must never
receive a Some(_) covering more than one datagram — see
Datagrams::reject_unsupported — and must never quietly send the
whole buffer as one oversized datagram, which is what “graceful
degradation” would look like here and would put a 3600-byte packet
on a 1200-byte path.
contents: &'a [u8]Implementations§
Source§impl Datagrams<'_>
impl Datagrams<'_>
Sourcepub fn reject_unsupported(&self, caps: UdpCaps) -> Result<()>
pub fn reject_unsupported(&self, caps: UdpCaps) -> Result<()>
Fail when this send asks for an offload caps says the socket does
not have — the twin of TcpOpts::reject_unsupported, and the only
sanctioned answer to an offload that cannot be applied, since
applying it invisibly-not-at-all is not one.
§The two offloads are not symmetric, and pretending otherwise would break QUIC
GSO can refuse, and must. A caller reads
UdpCaps::max_send_segments before it batches, so a
segment_size describing more datagrams than the socket declared is
a bug in the caller, not a fact about the environment. Refusing puts
the error where the bug is. Not refusing puts a 3600-byte datagram
on a 1200-byte path, where it is dropped by something that will
never tell anyone why.
ECN cannot refuse on send, and this is the one degradation this
module permits. A QUIC stack marks unconditionally; a socket that
failed every send on a kernel with no IP_TOS support would make
QUIC unusable exactly where the stack itself works fine. So a socket
may drop the marking — but only while it declares ecn: false,
and this check is what makes that conditional real: a socket that
claims ecn: true and is handed a codepoint it will not apply is
refused, so the declaration is a contract rather than a decoration.
The permission is one-directional: nothing here lets a socket
under-report on the receive side, where the cost is a congestion
controller acting on a marking that never happened
(RecvMeta::ecn).
An offload not asked for is not an offence: a Datagrams with
segment_size: None and ecn: None passes against
UdpCaps::NONE, so the weakest socket still serves every caller
that wanted nothing.