Skip to content

fix: keep PTOs within the anti-amplification limit - #4098

Open
larseggert wants to merge 2 commits into
mainfrom
fix-pto-amplification
Open

larseggert wants to merge 2 commits into
mainfrom
fix-pto-amplification

Conversation

@larseggert

Copy link
Copy Markdown
Collaborator

A PTO datagram is sent only if a full MTU still fits.


Stack created with GitHub Stacks CLI • Give Feedback 💬

Copilot AI balanced review requested due to automatic review settings October 19, 2026 12:05
@larseggert
larseggert added this pull request to stack #4100 October 19, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused guards reuse existing budget semantics, and the regression test covers exhaustion with no blocking issues identified.

No open issues 🎉

What changed in this PR

This PR keeps QUIC probe sends within the anti-amplification limit by requiring enough budget for a full MTU.

Changes:

  • Apply the existing budget check to timeout and recovery probes.
  • Add a regression test covering partial-budget exhaustion.
File Description
neqo-transport/​src/​recovery/​mod.rs Guard both probe paths with the budget check.
neqo-transport/​src/​connection/​tests/​handshake.rs Test server probe behavior as the amplification budget runs out.

Review effort: Balanced

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No findings.

@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.04%. Comparing base (0a535c2) to head (4c9b93f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4098      +/-   ##
==========================================
- Coverage   97.19%   97.04%   -0.15%     
==========================================
  Files         113      118       +5     
  Lines       41835    42182     +347     
  Branches    41835    42182     +347     
==========================================
+ Hits        40662    40936     +274     
- Misses       1159     1222      +63     
- Partials       14       24      +10     
Flag Coverage Δ
freebsd 94.65% <100.00%> (-0.14%) ⬇️
linux 97.25% <100.00%> (+<0.01%) ⬆️
macos 95.42% <100.00%> (+<0.01%) ⬆️
windows 95.51% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
neqo-common 99.31% <ø> (ø)
neqo-http3 95.44% <ø> (ø)
neqo-qpack 97.10% <ø> (ø)
neqo-transport 98.04% <100.00%> (+<0.01%) ⬆️
neqo-udp 95.37% <ø> (ø)
mtu 89.13% <ø> (ø)

@codspeed

codspeed Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will degrade performance by 2.84%

⚠️ 1 benchmark spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

⚡ 1 improved benchmark
❌ 6 regressed benchmarks
✅ 94 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Walltime 1-conn/10_000-parallel-1b-resp (aka. RPS) 80.4 ms 85.3 ms -5.77%
❌ Walltime walltime/1000-streams/each-1-bytes 4.4 ms 4.6 ms -4.53%
❌ Walltime walltime/10-streams/each-1048576-bytes 34 ms 35.2 ms -3.48%
❌ CPU Simulation simulated/pacing-true/same-seed 58.2 ms 60.2 ms -3.22%
❌ Walltime walltime/pacing-true/same-seed 4.3 ms 4.4 ms -3.07%
❌ Walltime walltime/1-streams/each-4194304-bytes 12.7 ms 13 ms -2.58%
⚡ Walltime 1-conn/1-100mb-req (aka. Upload) 60 ms 58.3 ms +3%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix-pto-amplification (4c9b93f) with main (0a535c2)

Open in CodSpeed

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No findings.

@larseggert
larseggert force-pushed the fix-pto-amplification branch from 1ceee6d to 4c9b93f Compare October 21, 2026 06:29

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No findings.

@github-actions

Copy link
Copy Markdown
Contributor

Failed Interop Tests

QUIC Interop Runner, client vs. server, differences relative to main at 0a535c2.

neqo-pr as clientneqo-pr as server
neqo-pr vs. go-x-net: BP BA
neqo-pr vs. haproxy: BP BA
neqo-pr vs. kwik: ⚠️H LR R 🚀B ⚠️Z U L1 C1 🚀6
neqo-pr vs. linuxquic: baseline result missing
neqo-pr vs. lsquic: L1 C1
neqo-pr vs. msquic: Z A L1 C1
neqo-pr vs. mvfst: A ⚠️C1 BA
neqo-pr vs. neqo: Z A
neqo-pr vs. nginx: BP BA
neqo-pr vs. ngtcp2: Z L1 C1 CM
neqo-pr vs. picoquic: Z A
neqo-pr vs. quic-go: A
neqo-pr vs. quiche: BP BA
neqo-pr vs. s2n-quic: CM
neqo-pr vs. tquic: S BP BA
neqo-pr vs. xquic: S R Z A L1 C1
go-x-net vs. neqo-pr: CM
kwik vs. neqo-pr: BP BA CM
linuxquic vs. neqo-pr: run cancelled after 20 min
msquic vs. neqo-pr: CM
mvfst vs. neqo-pr: Z L1 C1 CM
neqo vs. neqo-pr: Z A
openssl vs. neqo-pr: LR M A CM
quic-go vs. neqo-pr: CM
quic-zig vs. neqo-pr: CM
quiche vs. neqo-pr: CM
quinn vs. neqo-pr: ⚠️L1 V2 CM
s2n-quic vs. neqo-pr: CM
tquic vs. neqo-pr: CM
xquic vs. neqo-pr: M CM
All results

Succeeded Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

Unsupported Interop Tests

QUIC Interop Runner, client vs. server

neqo-pr as client

neqo-pr as server

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

No significant performance differences relative to a8809b4.

All results
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500
       time:   [59.216 ms 59.263 ms 59.312 ms]
       thrpt:  [1.6465 GiB/s 1.6478 GiB/s 1.6492 GiB/s]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severe
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500
       time:   [59.358 ms 59.406 ms 59.456 ms]
       thrpt:  [1.6425 GiB/s 1.6439 GiB/s 1.6452 GiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500
       time:   [3.5433 ms 3.5443 ms 3.5452 ms]
       thrpt:  [282.07   B/s 282.15   B/s 282.22   B/s]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severe
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500
       time:   [80.884 ms 81.019 ms 81.161 ms]
       thrpt:  [123.21 Kelem/s 123.43 Kelem/s 123.63 Kelem/s]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) low mild
2 (2.00%) high mild
1 (1.00%) high severe
streams-flow-controlled/walltime/1-streams/each-4194304-bytes
       time:   [12.485 ms 12.489 ms 12.494 ms]
       thrpt:  [320.15 MiB/s 320.27 MiB/s 320.40 MiB/s]
streams-flow-controlled/walltime/10-streams/each-1048576-bytes
       time:   [34.250 ms 34.265 ms 34.280 ms]
       thrpt:  [291.72 MiB/s 291.84 MiB/s 291.97 MiB/s]
streams/walltime/1-streams/each-1000-bytes
       time:   [156.61 µs 157.22 µs 158.02 µs]
       thrpt:  [6.0350 MiB/s 6.0657 MiB/s 6.0896 MiB/s]
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
streams/walltime/1000-streams/each-1-bytes
       time:   [4.4693 ms 4.4751 ms 4.4806 ms]
       thrpt:  [217.95 KiB/s 218.22 KiB/s 218.50 KiB/s]
Found 4 outliers among 100 measurements (4.00%)
4 (4.00%) low mild
streams/walltime/1000-streams/each-1000-bytes
       time:   [14.743 ms 14.755 ms 14.768 ms]
       thrpt:  [64.576 MiB/s 64.632 MiB/s 64.688 MiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/walltime/pacing-false/same-seed
       time:   [3.9392 ms 3.9418 ms 3.9443 ms]
       thrpt:  [1014.1 MiB/s 1014.8 MiB/s 1015.4 MiB/s]
transfer/walltime/pacing-false/varying-seeds
       time:   [3.8176 ms 3.8192 ms 3.8212 ms]
       thrpt:  [1.0223 GiB/s 1.0228 GiB/s 1.0232 GiB/s]
Found 1 outliers among 100 measurements (1.00%)
1 (1.00%) high mild
transfer/walltime/pacing-true/same-seed
       time:   [4.1131 ms 4.1163 ms 4.1201 ms]
       thrpt:  [970.85 MiB/s 971.76 MiB/s 972.51 MiB/s]
transfer/walltime/pacing-true/varying-seeds
       time:   [4.2189 ms 4.2225 ms 4.2269 ms]
       thrpt:  [946.33 MiB/s 947.32 MiB/s 948.12 MiB/s]

Instructions per cycle

Criterion reported no significant timing changes.

All benchmarks
Benchmark IPC before IPC after ΔIPC
transfer/1-conn/1-100mb-resp (aka. Download)/mtu-1500 3.20 3.25 +1.7%
streams-flow-controlled/walltime/10-streams/each-1048576-bytes 3.18 3.14 -1.2%
streams-flow-controlled/walltime/1-streams/each-4194304-bytes 3.01 3.03 +0.7%
streams/walltime/1000-streams/each-1-bytes 3.28 3.29 +0.5%
transfer/1-conn/1-100mb-req (aka. Upload)/mtu-1500 3.13 3.14 +0.4%
transfer/walltime/pacing-true/varying-seeds 2.86 2.87 +0.4%
transfer/walltime/pacing-false/varying-seeds 2.87 2.86 -0.3%
streams/walltime/1-streams/each-1000-bytes 2.56 2.56 +0.1%
streams/walltime/1000-streams/each-1000-bytes 2.97 2.97 +0.1%
transfer/1-conn/1-1b-resp (aka. HPS)/mtu-1500 2.22 2.22 -0.1%
transfer/walltime/pacing-false/same-seed 2.87 2.87 -0.1%
transfer/walltime/pacing-true/same-seed 2.87 2.87 -0.1%
transfer/1-conn/10_000-parallel-1b-resp (aka. RPS)/mtu-1500 3.22 3.21 -0.1%
Profiles for profiler.firefox.com (64)

Download data for profiler.firefox.com or download performance comparison data.

@github-actions

Copy link
Copy Markdown
Contributor

Client/server transfer results

Performance differences relative to a8809b4.

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server Mean±σ Min–Max Median±MAD MiB/s±σ ΔMedian
google-neqo-cubic 80.5 ± 0.6 79.1 – 82.3 80.6 ± 0.7 397.5 ± 3.2 💔 +1.4 (+1.8%)
neqo-google-cubic 259.4 ± 46.7 202.2 – 347.5 275.9 ± 56.8 123.4 ± 22.2 💔 +69.4 (+33.6%)
neqo-neqo-cubic 23.5 ± 0.2 23.2 – 24.0 23.4 ± 0.1 1364.0 ± 9.5 💚 -0.3 (-1.2%)
neqo-neqo-cubic-nopacing 23.3 ± 0.2 22.9 – 23.8 23.3 ± 0.2 1373.3 ± 10.5 💔 +0.3 (+1.2%)
neqo-neqo-newreno 23.5 ± 0.2 23.2 – 24.1 23.4 ± 0.2 1364.3 ± 11.6 💚 -0.3 (-1.2%)

Table above only shows statistically significant changes. See all results below.

All results

Transfer of 33554432 bytes over loopback, min. 100 runs. All unit-less numbers are in milliseconds.

Client vs. server Mean±σ Min–Max Median±MAD MiB/s±σ ΔMedian
google-google 154.8 ± 0.7 153.2 – 156.4 154.9 ± 0.8 206.7 ± 0.9
google-neqo-cubic 80.5 ± 0.6 79.1 – 82.3 80.6 ± 0.7 397.5 ± 3.2 💔 +1.4 (+1.8%)
neqo-google-cubic 259.4 ± 46.7 202.2 – 347.5 275.9 ± 56.8 123.4 ± 22.2 💔 +69.4 (+33.6%)
neqo-neqo-cubic 23.5 ± 0.2 23.2 – 24.0 23.4 ± 0.1 1364.0 ± 9.5 💚 -0.3 (-1.2%)
neqo-neqo-cubic-nopacing 23.3 ± 0.2 22.9 – 23.8 23.3 ± 0.2 1373.3 ± 10.5 💔 +0.3 (+1.2%)
neqo-neqo-newreno 23.5 ± 0.2 23.2 – 24.1 23.4 ± 0.2 1364.3 ± 11.6 💚 -0.3 (-1.2%)
neqo-neqo-newreno-nopacing 23.0 ± 0.2 22.6 – 23.6 22.9 ± 0.2 1394.2 ± 10.7 -0.2 (-0.7%)
neqo-quiche-cubic 34.3 ± 0.4 33.5 – 35.4 34.3 ± 0.4 933.8 ± 10.3 +0.1 (+0.1%)
neqo-s2n-cubic 44.8 ± 0.2 44.1 – 45.2 44.9 ± 0.2 713.9 ± 3.7 -0.0 (-0.0%)
quiche-neqo-cubic 36.2 ± 0.7 35.1 – 38.5 36.1 ± 0.6 883.8 ± 17.0 +0.1 (+0.3%)
quiche-quiche 41.9 ± 0.3 41.4 – 42.7 41.8 ± 0.2 764.5 ± 4.8
s2n-neqo-cubic 127.5 ± 0.7 125.9 – 130.2 127.5 ± 0.6 250.9 ± 1.3 +0.3 (+0.3%)
s2n-s2n ⚠️ 174.1 ± 24.7 145.3 – 342.1 170.3 ± 1.0 183.8 ± 26.1

Download data for profiler.firefox.com or download performance comparison data.

This branch has not been deployed

No deployments
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.

2 participants