fn classify_datagram(kind: ActionKind, cx: &CapCtx) -> SupportExpand description
The datagram site.
§A datagram is policed and never paced, and that is a decision
Truncate and ResetStream name a stream and a datagram has none, so
those two are a type error wearing a refusal. Delay and Hold are
refused for a different reason, and an author who reaches that refusal is
owed the reason rather than the mechanism.
A rate aimed at datagrams drops what it cannot cover, at the instant the
datagram arrived. forward_datagrams asks the class’s bucket and
discards every answer but now — including Later, where an instant does
exist and the datagram could have been held until it. So a datagram-mode
track can be held to a rate; what it cannot be is smoothed.
Smoothing would need a per-connection queue, and the argument against one is not that it is hard:
- It would model nothing. A bottleneck queues by link, not by track: a router does not know which track a datagram belongs to. Class-aware policing is a real box — an operator rate-limiter drops over rate — and class-aware smoothing is a scheduler inside a router, which is not a condition a player is ever placed in.
- It would impose an order the protocol does not have. A datagram belongs to no stream and has no successor to renumber. A FIFO would make this proxy the one hop on the path that never reorders, which is a less faithful network, not a more controlled one.
- The capability already exists one layer down.
quinn-netemdelays, jitters and reorders at the socket, under the whole connection — which is exactly the scope a link-level queue has. It is not class-aware, and that is the correct scope for it rather than a gap in it.
So the answer for smooth this traffic is quinn-netem, and the answer
for hold this track to a rate is a class over a bucket, which is here.
The framed sites keep Delay and Hold because a stream has a
delivery order: holding object N and then N+1 preserves a guarantee the
protocol makes, where holding two datagrams would manufacture one.
tests/actions_shaping.rs pins both halves — that a dry bucket discards,
and that a live rate discards too rather than deferring to the instant
it names, which is the assertion a queue would break.