Skip to content

proto: Add option to pad all application data packets to MTU #2274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 4, 2025

Conversation

FlorianUekermann
Copy link
Contributor

@FlorianUekermann FlorianUekermann commented Jun 20, 2025

The goal is to provide an option to pad all outgoing packets that contain application data to MTU. Our usecase is a VPN, which transmits packets via QUIC datagrams. The benefit is that src <-> relay packets (the tunnel) can't be as easily associated with resulting relay <-> dest traffic if all tunnel packets are padded to MTU.
This generally mitigates some fingerprinting concerns in other usecases as well.

@djc
Copy link
Member

djc commented Jun 20, 2025

Why?

@FlorianUekermann
Copy link
Contributor Author

I updated the PR description with our motivation.

@Ralith
Copy link
Collaborator

Ralith commented Jun 20, 2025

Can't roughly the same analysis still be performed based on timing?

@FlorianUekermann
Copy link
Contributor Author

Can't roughly the same analysis still be performed based on timing?

For our usecase:

Yes, both timing and size are relevant features. Removing size makes association of individual packets within a time window a lot harder. And the application layer is free to delay delay packets or even generate fake traffic. Packet size is just the one traffic feature where the transport implementation (e.g. quinn) needs to cooperate.
Note that with many users sharing an outgoing relay IP, association has to happen per connection (basically the pair of outgoing port + dest), so for some connections the amount of observable information is very limited and attribution of relay <-> dest traffic to a tunnel has to be done per connection.

In general (affects our usecase and others):

Packet sizes patterns can can be used as client or traffic type fingerprints [1].

[1] https://www.usenix.org/conference/usenixsecurity24/presentation/xue-fingerprinting

Copy link
Collaborator

@Ralith Ralith left a comment

Choose a reason for hiding this comment

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

Ah, yeah, makes sense that this would be pretty effective when there's many users.

@FlorianUekermann FlorianUekermann force-pushed the pad-to-mtu branch 2 times, most recently from 8bb5ee1 to 969dc67 Compare June 24, 2025 18:29
@FlorianUekermann FlorianUekermann requested a review from Ralith June 24, 2025 18:48
Copy link
Collaborator

@Ralith Ralith left a comment

Choose a reason for hiding this comment

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

I still need to take a careful look at the interaction with GSO batching.

Copy link
Collaborator

@Ralith Ralith left a comment

Choose a reason for hiding this comment

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

LGTM. It's a little non-obvious how segment_size is guaranteed to always be the MTU when this option is set, but I don't immediately see a way to make that clearer, the change in logic is basically simple, and I am satisfied that it's correct.

@djc djc added this pull request to the merge queue Jul 4, 2025
@djc
Copy link
Member

djc commented Jul 4, 2025

Thanks!

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jul 4, 2025
@djc
Copy link
Member

djc commented Jul 4, 2025

Hmm, not sure why CI is failing in the merge queue:

error[E0283]: type annotations needed
    --> quinn-proto/src/tests/mod.rs:3256:52
     |
3256 |     assert_eq!(pair.client.outbound[0].0.size, MTU.into());
     |                                                    ^^^^
     |
     = note: cannot satisfy `_: From<u16>`
     = note: required for `u16` to implement `Into<_>`
help: try using a fully qualified path to specify the expected types
     |
3256 -     assert_eq!(pair.client.outbound[0].0.size, MTU.into());
3256 +     assert_eq!(pair.client.outbound[0].0.size, <u16 as Into<T>>::into(MTU));

@FlorianUekermann
Copy link
Contributor Author

Strange... Maybe a different Rust version? I'll change MTU.into() to usize::from(MTU). The error looks like that would fix it.

@djc djc added this pull request to the merge queue Jul 4, 2025
Merged via the queue into quinn-rs:main with commit 6fb6b42 Jul 4, 2025
20 checks passed
@FlorianUekermann FlorianUekermann deleted the pad-to-mtu branch July 4, 2025 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants