Skip to content

[noq-udp] Retransmit failing GSO packets and split batches#746

Open
kixelated wants to merge 3 commits into
n0-computer:mainfrom
kixelated:port-quinn-gso-slicing-fix
Open

[noq-udp] Retransmit failing GSO packets and split batches#746
kixelated wants to merge 3 commits into
n0-computer:mainfrom
kixelated:port-quinn-gso-slicing-fix

Conversation

@kixelated

Copy link
Copy Markdown
Contributor

IDK if quinn-rs/quinn#2653 will ever get merged.

The main benefit is not adding ~500ms or whatever to the QUIC connection time on devices where GSO immediately fails, apparently Android. This should also fix disabling GSO if the batch size gets too large somehow (but I don't know how to trigger that).

@n0bot n0bot Bot added this to iroh Jul 9, 2026
@github-project-automation github-project-automation Bot moved this to 🚑 Needs Triage in iroh Jul 9, 2026
@kixelated

Copy link
Copy Markdown
Contributor Author

Alternatively: quinn-rs/quinn#2724

@flub

flub commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

The Initial ending up in a GSO batch surprised me, but I guess that's a PQC thing where you could end up with two packets for the Initial.

@flub flub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree that this is desirable. It's not even that complex.

Once interesting consequence from this is that it maybe no longer pays off for the caller to try and figure out what batch sizes etc are needed. It can just pick a default batch size and always throw it in (if it's congestion control and pacing is fine with that). The socket will than send it. Though there are the other platforms to worry about and I wouldn't be in a hurry to adopt that strategy. But an interesting thought.

Comment thread noq-udp/src/unix.rs
let mut pos = 0;
while pos < transmit.contents.len() {
let remaining = transmit.contents.len() - pos;
let batch_end = pos + next_batch_bytes(remaining, max_bytes, segment_size);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like these two helpers that take so many usize args, it is too easy to get confused. I'm tempted to go all out and build a TransmitSplitter that you can construct with the original transmit and then keep calling TransmitSplitter.next_transmit(&UdpSocketState) and TransmitSplitter.advance() if the transmit did send successfully.

Though the current code isn't terrible. And I could be convinced that it is fine too if you really don't like that for some reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🚑 Needs Triage

Development

Successfully merging this pull request may close these issues.

2 participants