fix(proto): let server-side paths use recoverability hint on network change#579
fix(proto): let server-side paths use recoverability hint on network change#579
Conversation
…change Previously, `handle_network_change()` only checked `is_path_recoverable()` on the client side. The server side always assumed paths were recoverable, based on the assumption that servers have stable addresses. This assumption breaks when the server's uplink changes (e.g., mobile device acting as server replugs to a different network). The dead direct path would linger until the 15s idle timeout instead of being immediately abandoned. Now both sides use the hint when provided. When no hint is given, clients default to non-recoverable (existing behavior) and servers default to recoverable (existing behavior), preserving backwards compatibility.
|
Documentation for this PR has been generated and is available at: https://n0-computer.github.io/noq/pr/579/docs/noq/ Last updated: 2026-04-13T15:44:34Z |
Performance Comparison Report
|
| Scenario | noq | upstream | Delta | CPU (avg/max) |
|---|---|---|---|---|
| large-single | 5375.2 Mbps | 7937.4 Mbps | -32.3% | 91.2% / 97.2% |
| medium-concurrent | 5370.1 Mbps | 7624.2 Mbps | -29.6% | 94.1% / 100.0% |
| medium-single | 3778.7 Mbps | 4740.8 Mbps | -20.3% | 87.8% / 96.3% |
| small-concurrent | 3745.5 Mbps | 5187.7 Mbps | -27.8% | 88.5% / 98.4% |
| small-single | 3402.4 Mbps | 4798.7 Mbps | -29.1% | 92.0% / 100.0% |
Netsim Benchmarks (network simulation)
| Condition | noq | upstream | Delta |
|---|---|---|---|
| ideal | 3138.2 Mbps | 4092.5 Mbps | -23.3% |
| lan | 782.5 Mbps | 810.3 Mbps | -3.4% |
| lossy | 69.8 Mbps | 69.8 Mbps | ~0% |
| wan | 83.8 Mbps | 83.8 Mbps | ~0% |
Summary
noq is 27.2% slower on average
a8ede51fced3a99111bbfaa25e42a26ca4506b51 - artifacts
No results available
3776bce507cda343c3fb96bdf575e34bc3da8d02 - artifacts
Raw Benchmarks (localhost)
| Scenario | noq | upstream | Delta | CPU (avg/max) |
|---|---|---|---|---|
| large-single | 5583.9 Mbps | 7804.5 Mbps | -28.5% | 97.1% / 147.0% |
| medium-concurrent | 5241.9 Mbps | 7926.2 Mbps | -33.9% | 95.5% / 148.0% |
| medium-single | 3863.9 Mbps | 4749.9 Mbps | -18.7% | 91.5% / 100.0% |
| small-concurrent | 3674.0 Mbps | 4867.5 Mbps | -24.5% | 92.1% / 100.0% |
| small-single | 3573.1 Mbps | 4652.0 Mbps | -23.2% | 98.5% / 152.0% |
Netsim Benchmarks (network simulation)
| Condition | noq | upstream | Delta |
|---|---|---|---|
| ideal | 3198.4 Mbps | 4082.1 Mbps | -21.7% |
| lan | 782.4 Mbps | 821.8 Mbps | -4.8% |
| lossy | 69.9 Mbps | 69.8 Mbps | ~0% |
| wan | 83.8 Mbps | 83.8 Mbps | ~0% |
Summary
noq is 25.6% slower on average
0d043254fb3cd0224380bf626437ffb04b2f6e8e - artifacts
Raw Benchmarks (localhost)
| Scenario | noq | upstream | Delta | CPU (avg/max) |
|---|---|---|---|---|
| large-single | 5524.2 Mbps | 8029.6 Mbps | -31.2% | 95.8% / 97.5% |
| medium-concurrent | 5617.2 Mbps | 7960.2 Mbps | -29.4% | 96.9% / 98.5% |
| medium-single | 3877.6 Mbps | 4579.3 Mbps | -15.3% | 96.8% / 98.7% |
| small-concurrent | 4006.8 Mbps | 5003.3 Mbps | -19.9% | 97.3% / 99.7% |
| small-single | 3728.4 Mbps | 4774.6 Mbps | -21.9% | 97.1% / 99.0% |
Netsim Benchmarks (network simulation)
| Condition | noq | upstream | Delta |
|---|---|---|---|
| ideal | N/A | 3953.0 Mbps | N/A |
| lan | N/A | 810.3 Mbps | N/A |
| lossy | N/A | 55.9 Mbps | N/A |
| wan | N/A | 83.8 Mbps | N/A |
Summary
noq is 25.0% slower on average
flub
left a comment
There was a problem hiding this comment.
Seems sensible. Can we do a proto-level test for this? Maybe one with two paths and one is recoverable, the other not. You should end up with one path or something. And another test with just one path that's not recoverable where it does not close the path because it is the last one and you can't close that.
|
@flub I pushed tests. |
flub
left a comment
There was a problem hiding this comment.
Thanks for the tests!
I think it's fine, but I am a little nervous about this. We definitely need to do dogfooding with this.
Co-authored-by: Floris Bruynooghe <flub@n0.computer>
Description
Currently
handle_network_changeonly checksis_path_recoverable()on the client side. The server side always assumed paths are recoverable, based on the assumption that servers have stable addresses.This assumption breaks when the server's uplink changes (e.g., mobile device acting as server replugs to a different network). The dead direct path would linger until the 3*PTO idle timeout instead of being immediately abandoned.
Now both sides use the hint when provided. When no hint is given, clients default to non-recoverable (existing behavior) and servers default to recoverable (existing behavior).
Breaking Changes
Notes & open questions