2542 Commits
Author SHA1 Message Date
Alessandro Ghedini 77d50358f9 stream: handle peer frames for implicitly opened local streams
Opening a higher-numbered stream implicitly opens lower streams of the
same type, even when no Stream object exists. Accept peer frames for
those local streams while rejecting frames for streams not yet opened.

Apply this check to STOP_SENDING, STREAM, RESET_STREAM, and
MAX_STREAM_DATA, and cover the behavior with transport tests.
2026-10-01 12:15:11 +01:00
Alessandro Ghediniandvendemiat d393d9c62b stream: preserve stopped-stream errors until reported
Track unreported STOP_SENDING errors independently of writable queue
membership. A stopped stream can be popped from the queue before the
application tries to send and still needs to return StreamStopped.

Keep stopped streams visible to writable polling when connection send
capacity is zero. Collect completed streams after reporting the error.

Also collect completed streams when the receive side finishes without
an application read, such as after stream_shutdown(Read). The send
side is only complete once its FIN is acknowledged, so a queued FIN is
still delivered first.

Co-Authored-By: vendemiat <vicky@geeks.net.np>
2026-10-01 12:15:10 +01:00
Nuno Diegues 52907dbd1d datagram-socket: allow sendmmsg to carry an extra payload added to every msg 2026-10-01 11:06:49 +00:00
Harald Gutmann fc9fe129da skip PING ACKs during handshake close 2026-10-01 10:59:24 +01:00
Yiğit Tanrıverdi af8788e034 stream: track FIN acknowledgements separately
SendBuf::is_complete() used acknowledged byte ranges as a proxy for FIN acknowledgement. A zero-length FIN contributes no byte range, so an ACK for an earlier data-only frame is indistinguishable from an ACK for the FIN.

Fixes #2525.
2026-10-01 11:26:49 +02:00
Benedikt Spies ce57b25cfe cid: avoid spurious error on duplicate RETIRE_CONNECTION_ID frame
Fixes #1833.
2026-10-01 11:14:40 +02:00
Lars Eggert 639429d780 Cargo: loosen serde_with requirement to any 3.x
Only skip_serializing_none is used, stable since 1.3.0. The 3.20.0
floor is unnecessary and forces consumers on older 3.x to bump.
2026-10-01 10:07:52 +01:00
Magistone cdf610571c ffi: populate max_rtt in PathStats
The FFI function `quiche_conn_path_stats` was missing a setter for `max_rtt` resulting in max_rtt always being 0 when used via FFI
2026-09-21 12:54:21 +00:00
Alessandro Ghedini 4d23d85916 opencode: replace .opencode/skills/ with symlink to .codex
Codex CLI doesn't like if its .codex/ path is a symlink as it breaks its
sandbox, but OpenCode doesn't care.
2026-09-18 11:06:58 +01:00
Alessandro Ghedini 1c8e976173 h3i: release 0.7.0 h3i-0.7.0 2026-09-17 17:17:49 +01:00
Alessandro Ghedini 540d33aa3d tokio-quiche: release 0.20.0 tokio-quiche-0.20.0 2026-09-17 17:16:50 +01:00
Alessandro Ghedini be47c50112 quiche: release 0.30.0 0.30.0 2026-09-17 17:00:29 +01:00
Esteban b6281fbf24 recovery: emit app-limited state in qlog 2026-09-17 16:51:01 +01:00
Alessandro Ghedini ad2fabd1db tokio-quiche: make Http3Settings non-exhaustive
Prevent additions to HTTP/3 driver settings from breaking downstream
crates. Update integration tests to configure settings through a default
value because external crates can no longer use struct literals.
2026-09-17 16:25:58 +01:00
James Baldassari a64d972144 fix connection flow-control double-counting from zero-length STREAM frames
A zero-length non-fin STREAM frame advances the peer's largest received
offset for the stream (RFC 9000 Section 19.8). The receive path charges
connection-level flow control from that offset, but RecvBuf::write()
discarded empty non-fin buffers without recording the new high-water
mark, so the gap up to the frame's offset was charged a second time
when the in-flight data covering it arrived.

The sender produces exactly such frames: send_single encoded a STREAM
frame even when emit() returned zero bytes without fin. That happens
when packet packing leaves exactly header-sized space, which requires
the header to exceed MAX_STREAM_OVERHEAD — a two-byte stream id varint
plus an eight-byte offset varint — so it surfaces on long-running bulk
streams past 1 GiB of transfer.

Between two quiche endpoints the receiver-side inflation accumulates
silently until a legal, contiguous frame appears to exceed MAX_DATA and
the receiver closes the connection with FLOW_CONTROL_ERROR, while the
sender has consumed exactly the credit it was granted. Observed in
long-running bulk transfers over a lossy path at 1-3 spurious
connection kills per hour; instrumented captures showed rx_data
exceeding the sum of per-stream high-water marks by exact whole-frame
multiples.

Fix both halves:

- RecvBuf::write() advances the high-water mark for empty non-fin
  buffers before the early return, keeping the flow-control charge and
  the stream state in lockstep. This is the load-bearing fix and also
  defends against any other sender emitting such frames.
- send_single skips zero-length non-fin frames entirely. The bytes such
  a frame references were already charged to tx_data when buffered, so
  this is defensive/efficiency behavior: the frame is pure overhead
  plus a consistency hazard for receivers. The skip is excluded from
  the on_app_limited() transition via stream_data_skipped, since data
  is pending and the sender is size-limited on that packet, not
  application-limited.

Tests:

- empty_stream_frame expectations updated to the consistent semantics;
  the old sequence also accepted a final size below the largest
  received offset, which RFC 9000 Section 4.5 forbids and which no real
  quiche sender can produce (fin_off >= off_front).
- New flow_control_empty_stream_frame_not_double_counted pipe test
  injects an empty forward frame and verifies the charge lands exactly
  once; it fails on the previous code with a spurious Error::FlowControl.
- New zero_length_stream_frame_not_sent test seeds a stream's send
  state at 2^30 via a #[cfg(test)] seam and sweeps output-buffer sizes
  across the header-only window; without the sender fix it fails at
  exactly the cap that leaves header-sized space, and it verifies the
  skipped data is delivered afterwards.

* Keep draining stream's read offset in sync with empty STREAM frames

An empty non-fin STREAM frame now advances RecvBuf::len, but on a
draining stream the early return skipped the `off = len` update the
buffered path performs. Connection already counts the frame's offset
delta as consumed for a draining stream, so a later RESET_STREAM
credited `final_size - off` a second time.

Also drop the redundant flushable-queue bookkeeping from the sender-side
skip (a stream reaching it is still flushable), restore off_back()'s
misplaced doc comment, and trim the new comments.

* Keep rotating incremental streams when a STREAM frame is skipped

Dropping the whole flushable-queue update from the header-only skip
left the skipped stream at the head of the queue. Since packet space is
also bounded by the congestion window, the same size can recur on every
send() until an ACK arrives, so an incremental stream with a long header
would block other same-urgency incremental streams whose data does fit.

Restore the rotation (the not-flushable branch stays removed: a stream
reaching the skip still has data queued) and add a regression test.

Fixes #2696.
2026-09-17 09:08:36 -05:00
Alessandro Ghedini 5aff70b3a9 build(deps): update intrusive-collections to 0.10.3
Pick up upstream fixes for undefined behavior in RBTree iterators and
races when mutating atomic links. Quiche uses both for stream priority
queues, so update to the release containing these safety fixes.

Version 0.10 changes the intrusive_adapter! link-field separator. Update
the stream priority adapters to use the new syntax while preserving
their existing behavior.
2026-09-17 13:46:16 +01:00
dependabot[bot] 8b9a03ca1b build(deps): update table_to_html requirement from 0.9.0 to 0.11.0
Updates the requirements on [table_to_html](https://github.com/zhiburt/tabled) to permit the latest version.
- [Changelog](https://github.com/zhiburt/tabled/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zhiburt/tabled/compare/v0.9.0...v0.11.0)

---
updated-dependencies:
- dependency-name: table_to_html
  dependency-version: 0.11.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-17 13:18:00 +01:00
dependabot[bot] d7c7f26afe build(deps): update wasm-streams requirement from 0.4 to 0.6
Updates the requirements on [wasm-streams](https://github.com/MattiasBuelens/wasm-streams) to permit the latest version.
- [Release notes](https://github.com/MattiasBuelens/wasm-streams/releases)
- [Changelog](https://github.com/MattiasBuelens/wasm-streams/blob/main/CHANGELOG.md)
- [Commits](https://github.com/MattiasBuelens/wasm-streams/compare/v0.4.0...v0.6.0)

---
updated-dependencies:
- dependency-name: wasm-streams
  dependency-version: 0.6.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-17 13:17:54 +01:00
dependabot[bot] 89d01d2337 build(deps): update getrandom requirement from 0.3 to 0.4
Updates the requirements on [getrandom](https://github.com/rust-random/getrandom) to permit the latest version.
- [Changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-random/getrandom/compare/v0.3.0...v0.4.2)

---
updated-dependencies:
- dependency-name: getrandom
  dependency-version: 0.4.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-17 13:17:49 +01:00
dependabot[bot] bb92c421c7 build(deps): update nix requirement from 0.30.1 to 0.31.3
Updates the requirements on [nix](https://github.com/nix-rust/nix) to permit the latest version.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.30.1...v0.31.3)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 0.31.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-17 13:17:40 +01:00
Harald Gutmann 0f6a4fd6ea h3i: add send capacity factor config option 2026-09-17 13:16:42 +01:00
dependabot[bot] 0976bc3dd0 build(deps): update ipnetwork requirement from 0.20 to 0.21
Updates the requirements on [ipnetwork](https://github.com/achanda/ipnetwork) to permit the latest version.
- [Release notes](https://github.com/achanda/ipnetwork/releases)
- [Changelog](https://github.com/achanda/ipnetwork/blob/master/CHANGELOG.md)
- [Commits](https://github.com/achanda/ipnetwork/compare/v0.20.0...v0.21.1)

---
updated-dependencies:
- dependency-name: ipnetwork
  dependency-version: 0.21.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-17 11:00:37 +01:00
Kaustubh Kelkar 5f00e83a93 path: add PMTU path event
Notify applications when PMTU discovery changes the validated packet size
limit for a network path.
2026-09-17 09:10:07 +00:00
Antonio Vicente 1b5e3e2495 Add BBR param to configure cwnd lower bound (#2732) 2026-09-16 16:11:36 -05:00
Kaustubh Kelkar dd714f1255 tokio-quiche: Add path event callback
Forward existing path events from each tokio-quiche worker to the
    configured connection hook.
2026-09-15 12:57:15 +01:00
Christopher Patton 1372018558 build: upgrade boring to 5.2 with 4.19 compatibility
Upgrade the default boring dependency from 4.3 to 5.2 while retaining
support for consumers pinned to boring 4.19. Use boring-sys build
metadata to select version-specific RPK APIs and test expectations.

Boring 5 enables post-quantum key shares by default, which can split the
ClientHello across multiple Initial packets. Update affected size and
packet-count expectations. Tests that require one Initial disable
post-quantum groups through Config::set_curves_list().

Update the fuzz build to use Boring 5's consolidated unsafe-mode define.
Exercise the minimum supported version and the RPK feature in CI.
2026-09-15 12:44:14 +01:00
Christopher Patton 6f4f63ac47 ci: prepare i686 multiarch builds for boring 5
BoringSSL's x86 assembly requires SSE2. boring-sys normally supplies
the necessary flags only when the host and target differ, but the cross
i686 image is 32-bit native.

Add target-scoped CFLAGS and CXXFLAGS passthrough entries so the flags
reach the BoringSSL build. These flags work with both boring 4 and 5, so
the preparation can land before the dependency upgrade.
2026-09-15 12:44:14 +01:00
Christopher Patton 2a3d27afec loosen initial_cwnd's bbr2_gcongestion tolerance in tests
`tests::initial_cwnd` asserts that `tx_cap` falls in `[expected,
expected + 1]` after the handshake. For BBR2 in Startup the
congestion window grows by exactly `bytes_acked` per ACK, so the
post-handshake `tx_cap` equals `initial_cwnd` plus the bytes the
server sent during the handshake that the client has acknowledged.
That total is sensitive to the encoded length of the ACK frame's
`ack_delay` field (a VarInt of microseconds since receipt), which
can shift by a byte between architectures.

On aarch64 and armv7 (under `cross`'s Docker+QEMU) we observe
`tx_cap = expected + 2`, just outside the existing tolerance.
Allow a 4-byte upper-bound tolerance and replace the prior
`TODO understand` comment with an explanation of what the test is
actually measuring.
2026-09-15 12:44:14 +01:00
Christopher Patton 3d67367374 ci: use MSYS2 for Windows MinGW jobs
boring-sys 5.x's build script unconditionally passes
`CMAKE_MSVC_RUNTIME_LIBRARY` for any `target_os == "windows"`. Combined
with cmake's default Windows behaviour, this makes cmake look for
`cl.exe` even on `*-windows-gnu` targets, where only MinGW gcc is
available, and the build fails during compiler detection.

Replace the `bwoodsend/setup-winlibs-action` step with a setup that
mirrors `boring`'s own CI:

  - For `x86_64-pc-windows-gnu`, point CC/CXX/include/library at the
    MSYS2 toolchain preinstalled at `C:\msys64`.
  - For `i686-pc-windows-gnu`, install a 32-bit MSYS2 environment via
    `msys2/setup-msys2@v2` (the runner's preinstalled MSYS2 is 64-bit
    only) and force `CMAKE_GENERATOR="MinGW Makefiles"` so cmake-rs
    doesn't fall back to "MSYS Makefiles" + cl.exe.

Also set `CXXFLAGS=-msse2` for `i686-pc-windows-msvc` to satisfy
BoringSSL's x86 SSE2 requirement on that target.
2026-09-15 12:44:14 +01:00
Christopher Patton 6b08b88ee3 examples: link the C examples with the C++ compiler driver
BoringSSL 5.x emits C++ symbols (vtables, exception personality,
std::optional, etc.) into its static archives. Linking `libquiche.a`
into the C example binaries with `cc` therefore fails with undefined
references to the C++ runtime.

Switch the link step to `$(CXX)` so libc++/libstdc++ is pulled in
automatically. Wrap the source with `-x c ... -x none` to keep the C
language semantics for the .c file and let clang re-detect the
following `.a` archive normally.
2026-09-15 12:44:14 +01:00
Christopher Patton 83f261a8c2 tls: add set_curves_list() to C and Rust APIs
Expose the TLS curve preference list through Config and the C API. This
allows callers and tests to disable post-quantum groups when they need a
smaller ClientHello or deterministic handshake packet sizes.
2026-09-15 12:44:14 +01:00
Alessandro Ghedini 9de9bd56a7 tls: apply in-handshake config for accepted 0-RTT (#2730)
BoringSSL can report handshake success after accepting early data while
the handshake is still in progress. The success path skipped applying
configuration staged by handshake callbacks, so the next call rebuilt
ExData from the original congestion control settings.

Commit 2e67e72c8 ("Allow updates to the recovery config after sending
ACK-only packets") relaxed the recovery reinitialization guard, but
continued to apply callback changes only after Error::Done. Apply those
changes after either non-fatal TLS result.
2026-09-14 13:53:57 -07:00
Alessandro Ghedini 5207452bd9 tokio-quiche: report stats for active path
Select the path marked active when collecting connection statistics as
the iterator order does not guarantee that the first path is active,
which can report telemetry for a stale path after migration.
2026-09-14 12:29:32 +01:00
Alessandro Ghedini c8da372daa stream: compress collected stream tracking into ranges
Store collected stream sequences in separate range sets for each stream
type so adjacent completed streams share a range instead of separate
hash set entries. This reduces retained memory for sequential stream
usage without changing stream lifecycle or credit behavior.

Add exact RangeSet membership checks and cover type separation,
out-of-order collection, implicit gaps, and stream limit rejection.
2026-09-11 13:32:08 +01:00
Alessandro Ghedini 16ad936627 ci: add Bonk pull request reviews
Run Bonk automatically for same-repository pull requests and allow
authorized organization members to request reviews through comments.

Use GPT-5.6 Sol through the organization AI Gateway credentials and
prevent the reviewer from pushing changes.
2026-09-11 11:12:53 +01:00
Alessandro Ghedini a16f662446 h3i: update command-line parsing to clap 4
Migrate the argument builder, flag actions, and match accessors to the
clap 4 API. Define clap in the workspace so all member crates share the
same dependency version.
2026-09-10 18:37:10 +01:00
Alessandro Ghedini 9f96daa2c2 octets: release 0.3.7 octets-0.3.7 2026-09-07 14:24:05 +01:00
Alessandro Ghedini d2e1f64740 octets: add generic Huffman encoding writer
Move HPACK Huffman output behind a small writer trait so callers can
reuse the encoder with sinks other than OctetsMut. Keep the existing
OctetsMut API by delegating through the trait implementation and add
tests for custom sink output and error propagation.

This makes the encoder useful for streaming or segmented output where
building one contiguous temporary buffer would be unnecessary (e.g.
for HTTP/2 HEADERS+CONTINUATION frames).
2026-09-04 15:42:47 +01:00
Alessandro Ghedini 816a80141c octets: move tests to integration files
Move the public API tests out of src/lib.rs into octets/tests so
the crate code no longer carries a large inline test module. Keep the
Huffman-specific coverage in its own feature-gated test file.
2026-09-04 15:42:47 +01:00
Alessandro Ghedini 5d938ef83e reformat comments
Newer nightly rustfmt wraps comments differently now, so update the
existing formatting.

Some comments are reworded to improve readability and avoid awkward
wrapping.
2026-09-04 11:09:03 +01:00
Alessandro Ghedini cdfb65edaa crypto: let BoringSSL allocate EVP_AEAD_CTX
Use EVP_AEAD_CTX_new() and EVP_AEAD_CTX_free() so BoringSSL owns the
context layout and cleanup. This removes the copied layout that needed
to track upstream changes.
2026-09-04 11:03:01 +01:00
dineshadhi 0b1a89af34 apps: apply initial cwnd setting to quiche-client 2026-08-13 10:02:29 +01:00
Lynn Li e97798e16b tokio-quiche: make body_recv_buf max size configurable, default 16 KiB
Follow-up to !2547 (size body_recv_buf to readable length). The buffer is
still sized to the amount readable on the stream, but the upper bound of
the clamp is now configurable via Http3Settings::max_recv_body_buf_size
instead of being hardcoded to BufFactory::MAX_BUF_SIZE (64 KiB).

The default when unset is lowered to 16 KiB (DEFAULT_MAX_BODY_RECV_BUF_SIZE)
so a request that carries a body no longer pins a large allocation for the
life of the stream; a larger streamed body simply reallocates once per
driver read-cycle. Downstream users can override the cap.

Because MIN_BODY_RECV_BUF_SIZE (1 KiB) is a soft floor while the cap is
now configurable, body_recv_buf_size caps the floor by the configured max
(clamp over [min(floor, max), max]) so a cap below the floor still bounds
the allocation and never inverts the clamp range.
2026-08-06 17:24:45 +02:00
Jannes Timm ee28072d14 fix cleanup of h3 streams of type unknown 2026-07-30 17:04:33 +02:00
Eli Lebeau 039d2a9612 Avoid float RTT dwell rounding in HMM detector (#2559) 2026-07-29 12:18:36 -05:00
Alessandro Ghedini d5c6668c64 opencode: add draft release skill
Add a project-local opencode skill for preparing quiche GitHub draft
releases from either a release commit hash or an existing release tag.

The helper script validates the quiche version bump, infers the previous
quiche release tag, and creates draft releases with --target when the tag
has not been created yet.
2026-07-29 15:55:17 +02:00
Alessandro Ghedini 106d6a162a ci: require quiche release draft
Quiche release PRs are opened before the release tag exists, so check
for a GitHub draft release using the version from quiche/Cargo.toml.
The workflow is scoped to quiche version bumps and uses contents: write
so the token can see draft releases.
2026-07-29 15:03:47 +02:00
Linlin Li 000090137d tokio-quiche: release exhausted H3 body buffer (#2558) 2026-07-28 13:20:06 -07:00
Linlin Li 49479ed9aa tokio-quiche: pool the IO egress buffer per worker (#2554) 2026-07-27 15:13:15 -07:00
Eli Lebeau d7c3b1e426 add HMM RTT jump detector 2026-07-27 15:51:52 +01:00