cloudflare / cloudflare/quiche

Immediate datagram sending

Open
#1,618 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
11.8k
Forks
1.1k
Avg merge
21h 9m
Merged PRs (30d)
6

Description

I'm working on an application that sends lots and lots of datagrams (for video), and it strikes me that the current API for datagrams is not very flexible or optimized. This seems to be a result of integrating the datagram functionality into the normal `send` path, despite datagrams not needing to be interleaved with stream packets at all, per my lackluster understanding of QUIC.

In the worst case, I have a `Bytes` with some data I want to send. I call `dgram_send(&buf)`. The packet first gets copied into the queue here:

https://github.com/cloudflare/quiche/blob/883a616f0bf3258f1898e0fad0c3707c630f81b0/quiche/src/lib.rs#L5347

(Note that there's a `dgram_send_vec` which doesn't copy, but it's pretty tricky to have a `Vec` at that point.)

Then, when I call `send`, I have no control over whether the datagrams are prioritized. If they are picked out of the queue, there's another copy into the packet buffer:

https://github.com/cloudflare/quiche/blob/883a616f0bf3258f1898e0fad0c3707c630f81b0/quiche/src/lib.rs#L3975-L3976

I may be misunderstanding some nuance of QUIC's internal state tracking, but for me the ideal API would be an immediate packet construction helper, similar to how `retry` or `negotiate_version` work:

```rust
/// Writes a complete datagram packet to out.
pub fn datagram(&mut self, data: &[u8], out: &mut [u8]) -> Result;
```

A bonus would be if it could somehow handle `data` and `out` being overlapping, to allow adding the header and encrypting in-place. I'm not familiar enough with rust's slice type to know if that's easy or not. Otherwise it would be another fn:

```rust
/// Writes a datagram header to the provider buffer and encrypts
/// in-place. The offset indicated by `data_off` must be greater than
/// XXX to allow space for the header. The resulting tuple indicates
/// the begin and end offsets of the completed packet.
pub fn datagram_inplace(&mut self, buf: &mut [u8], data_off: usize) -> Result<(usize, usize)>;
```

Thanks for reading! I'm happy to open a PR for this if the API seems workable.

Contributor guide

Open the contributing guide

Research direction

Start in quiche/src/lib.rs at the dgram_send queueing code around line 5347 and the datagram handling in send around lines 3975-3976. Compare the immediate packet construction patterns used by retry and negotiate_version, then determine whether the proposed datagram or datagram_inplace API can provide the requested prioritization and reduced copying; done means an agreed workable API and behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
networking
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.