quinn-proto: Fix RTT measurements with max_ack_delay timer resolution - #2681
conradludgate wants to merge 4 commits into
Conversation
|
Thanks for the PR! Your compromise makes intuitive sense to me, and this isn't an interop hazard, so I'm inclined to accept that as written. I'm ready to approve this, except for one reservation: why are we both setting the timer early and advertising extra time? Isn't that double-counting the slop? |
Good question, might be overcompensating. In my testing, the tokio timers would fire uniformly in the range of 0..2ms late, never early. I was accounting for the max expected delay (2 * TIMER_GRANULARITY), but the P50 delay is <=1ms. Happy to drop down to just the 1ms slop, or happy to fix the code to only go in one direction (either under-sleep or over-report, not both) |
Because tokio timers are roughly 0-2ms late (uniform distribution in my testing), the max_ack_delay can sometimes be 2ms late (1ms on average). I found the following scenario would play out:
I saw the following guidance in https://www.rfc-editor.org/rfc/rfc9000.html#section-18.2-4.28.1
So, if we expect a 1ms delay, we should add that to the the reported max_ack_delay.
However, I (well, Claude Fable 5) found a potential issue when testing this. From the following https://www.rfc-editor.org/rfc/rfc9002.html#section-5.3-7.4
Now that the delay is closer to what we actually expect, when performing
latest_rtt - delayit has a natural tendency to fall around themin_rttvalue. In the current code, if this occurs we always take thelatest_rttvalue to update thesmoothed_rtt, which in this case would be ~27ms. So by accounting for the timing delay in themax_ack_delay, we end up making thesmoothed_rttvalue explode higher. This is more likely to manifest if the first handshake is slower than the network latency (eg, public-key cryptography compared to loopback network).Right now, the simple "fix" was to clamp the
adjusted_rtttomin_rttin this event, rather thanlatest_rtt. But I'm not confident that it's really the correct thing to do, according to the spec.I'll add, this problem only occurred with light load with a unidirectional stream. Once we introduced additional bidirectional streams, the problem went away. I imagine in this scenario the
min_rttwill also be updated accordingly to avoid the issue described above.