Skip to content
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

fix packet encoding/decoding which seems to break after 2 billions packets sent #1743

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

frochet
Copy link
Contributor

@frochet frochet commented Mar 13, 2024

Hello,

Long story short, I've been using the encoding/decoding logic of packet number for another purpose than encoding pn, and observed that it would start decoding incorrect values when reaching 2^31.

I dived into RFC9000, on the Appendix for the algorithmic details of encoding/decoding, and observed that the encoding algorithm in quiche does not match the encoding algorithm suggested by the RFC. I suppose there is a reason for this, but it eludes me.

So, this pull request does an implementation close to what is suggested (hopefully more efficient), and fixes my problem, and the bug with packet numbers too. I've also added test cases for packet encoding/decoding using example values from the RFC.

This passes all unit tests, and a simple integration test in which I downloaded a 5 GiB file through the H3 module using quiche-[client/server]. However, I am unsure about:

  1. Why the largest acked value on a path can be bigger than the current packet number on that path.
  2. Why largest_acked values were initialized to UINT64::MAX; I changed this to 0, and removed a condition checking for UIN64::MAX. I had to do this, because pkt_num_len() is now using information from the largest_acked value.
  3. Whether the original pkt encoding is a bug, a forgotten todo, or something else. The fact that there were no test cases suggests a forgotten todo?

@frochet frochet requested a review from a team as a code owner March 13, 2024 10:32
// computes ceil of num_unacked.log2()
let min_bits = u64::BITS - num_unacked.leading_zeros();
// get the num len in bytes
Ok((min_bits as f32 / 8.).ceil() as usize)
Copy link

Choose a reason for hiding this comment

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

Ok((num_bits + 7) / 8 as usize) should be faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks right! Good catch. The Result is not useful anymore either, and I removed it.

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.

None yet

2 participants