Grookie 1a26a8b064 test(proto): fix flaky open_path_validation_fails_server_side (#797)
## Description

We saw `open_path_validation_fails_server_side` fail intermittently in
[daily CI on
FreeBSD](https://github.com/n0-computer/noq/actions/runs/33142246096),
and matheus23 asked me to look into it. The test advanced with a single
`advance_time()`, which jumps to the earliest timer pending on *either*
endpoint, and assumed that jump lands on the client's 8s path-idle
deadline for the blackholed path. It usually does. When the client
happens to do a routine key update shortly before that deadline — PN
phase exhaustion, which depends on the randomly chosen initial packet
number — the server arms `KeyDiscard` at 3x PTO, and that fires about
100ms earlier. The jump lands there instead, `drive()` then stops
stepping because `Connection::is_idle` discounts the idle timers that
remain, and virtual time never reaches the deadline. The path-idle timer
stays armed the whole time and the connection behaves correctly; the
single jump in the test is the bug.

The fix, as suggested by matheus23: a `drive_until_timer` helper that
steps to each next wakeup and drives both endpoints until the target
timer is no longer armed. `drive()` can't reach an idle timeout on its
own — `is_idle` discounts exactly the timers a test would be waiting for
— so this needs its own loop. The test now calls it instead of
`advance_time()`.

## API Changes

None, test changes only.

## Notes & open questions

- I'm an agent posting from my own account (`n0-grookie`), so I left the
"created by a human" box below unticked. matheus23 asked for the PR
after reviewing the commits.
- Measured on a seeded sweep over `StdRng::seed_from_u64()` driving the
same `ConnPair` setup as the test: 82 of 20000 seeds failed before, 0 of
50000 after. Seed-dependent rather than platform-dependent — the same
seeds fail on Linux, which is how I measured it. The sweep is scratch
code and not in the commit; it can go in behind an `#[ignore]` if a
repeatable sweep is worth having.
- `drive_until_timer` panics rather than hangs if the timer is still
armed after 1024 steps, and a *cancelled* timer also ends the loop —
callers should keep asserting on the event they expect. Both are in the
doc comment.
- I went through the other `advance_time()` call sites in `src/tests`.
They step to the next scheduled timer and assert on whatever arrives
(`multipath.rs:2124` expects `Established`, the `mod.rs:4746` pair
checks draining delays), so they don't carry this test's assumption that
the jump lands on a specific deadline. Left them as they are.
- No issue linked: it came out of daily CI and the fix was reviewed out
of band.

## Change checklist

- [x] Self-review.
- [x] Documentation updates following the [style
guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text),
if relevant.
- [x] Tests if relevant.
- [ ] This PR was created by a human that thought critically about the
      proposed change and wrote an as clear and concise description as
      they could.
- [x] This PR isn't slop, and is carefully crafted to do have the
      intented effect.
- [x] `cargo make` passes locally.

---------

Co-authored-by: n0-grookie <322172879+n0-grookie@users.noreply.github.com>
2026-09-10 06:41:01 +00:00
2026-02-06 10:04:56 +00:00
2026-09-09 12:44:54 -04:00
2025-03-24 15:57:34 +00:00
2026-09-09 12:44:54 -04:00
2026-09-09 12:44:54 -04:00
2026-09-09 12:44:54 -04:00
2026-03-09 14:40:18 +01:00
2020-01-27 10:21:10 -08:00
2026-03-09 14:45:33 +01:00
2025-02-23 11:52:46 +00:00

noq

Documentation Crates.io Chat License: MIT License: Apache 2.0

General purpose implementation of the QUIC transport protocol in pure Rust. Noq is built as an async-friendly API in the noq crate on top of a sans-io protocol library in noq-proto.

Noq started out as a fork of the excellent Quinn project. The main focus of development has been towards adding support for more QUIC (draft) extensions:

Features

  • Easy to use futures-based async API.
  • Client and server server functionality.
  • 0-RTT and 0.5-RTT data support.
  • Ordered and unordered stream reads.
  • Custom and zero-length connection identifiers.
  • Fully pluggable crypto API with a Rustls implementation using ring or aws-lc-rs provided by default for convenience.
  • Broad platform support, including Linux, Windows, macOS, android, iOS and wasm.

Standards

The noq library aims to be correct implementation of various QUIC standards:

Getting started

Examples at https://github.com/n0-computer/noq/blob/main/noq/examples

$ cargo run --example server ./
$ cargo run --example client https://localhost:4433/Cargo.toml

This launches an HTTP 0.9 server over the QUIC transport on the loopback address serving the current working directory, with the client fetching ./Cargo.toml. By default, the server generates a self-signed certificate and stores it to disk, where the client will automatically find and trust it.

License

Copyright 2025 The quinn developers Copyright 2025 N0, INC.

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

S
Description
noq, a QUIC implementation in Rust
Readme 106 MiB
Languages
Rust 99.3%
Python 0.5%
Shell 0.2%