Skip to content

refactor(tuic): unify wind-tuiche into wind-tuic over the wind-quic abstraction#21

Merged
Itsusinn merged 1 commit into
mainfrom
feat/unify-tuic-backends
Jun 11, 2026
Merged

refactor(tuic): unify wind-tuiche into wind-tuic over the wind-quic abstraction#21
Itsusinn merged 1 commit into
mainfrom
feat/unify-tuic-backends

Conversation

@Itsusinn

Copy link
Copy Markdown
Member

What & why

Folds the wind-tuiche (tokio-quiche) crate into wind-tuic, writing the TUIC server once generic over wind_quic::QuicConnection. Both the quinn and quiche backends now run that single implementation, so the two engines no longer carry parallel copies of the TUIC protocol logic.

This is the follow-up to #20 (the wind-quic abstraction), realizing its purpose: wind-tuiche is deleted, including its ~993-line bespoke sans-IO driver.rs, which is replaced by the shared server core driven over the wind-quic bridge.

Structure

Generic protocol core (wind-tuic/src/):

  • server/serve_connection<C: QuicConnection> + the auth handshake, the three accept loops (datagram/uni/bi), command dispatch, and the per-association UDP session manager. One implementation, shared by both backends.
  • proto/ClientProtoExt<C>, UdpStream<C>, encode_and_send_uni<C>. TCP relays use tokio::io::join(recv, send) + wind_core::io::copy_io (replacing the quinn-specific QuinnCompat).
  • client/ — generic ClientTaskExt<C>.

Backends are thin connection providers, preserving the public type names so consumer churn is just import paths:

  • wind_tuic::quinn::{TuicInbound, TuicInboundOpts, TuicOutbound, TuicOutboundOpts, …}unchanged signatures; wind, tuic-client, and wind-test compile untouched. Endpoint/handshake stays here; the per-connection body delegates to the shared core via QuinnConnection.
  • wind_tuic::quiche::{TuicheInbound(Builder), TuicheOutbound(Builder), CertStore, ConnectionOpts, CongestionControl, UdpRelayMode} — mirrors the former wind-tuiche surface, running the same core via QuicheConnection.

Supporting changes

  • wind-quic: gains quiche certificate hot-reload — CertStore/CertReloadHook (boring-based, pure QUIC-TLS infra) moved in from wind-tuiche; wind_quic::quiche::bind_server takes an optional &CertStore that installs the per-handshake ConnectionHook.
  • wind-core: AbstractTcpStream drops its vestigial Sync bound. Relay streams are only ever moved into a spawned task (Send suffices, not Sync), and the quiche backend's stream halves are PollSender/mpsc-backed and therefore !Sync. Confirmed no consumer relied on Sync.
  • Consumers repointed: tuic-server (quiche feature → wind-tuic/quiche; use wind_tuiche::…use wind_tuic::quiche::…; dropped the wind_tuiche log target) and tuic-tests (64-bit wind-tuiche dep → wind-tuic/quiche feature; quiche_cert_reload.rs import).
  • crates/wind-tuiche deleted.

Scope note

The quiche client stays a config-only stub, exactly as in wind-tuiche. No test exercises a quiche client (the quiche e2e tests use the quinn client against the quiche server), and the quinn client is the functional path — so making it "functional for free" would ship untested networking. Deferred. The server unification, which is where the duplication actually lived, is complete.

Verification

  • Builds: wind-tuic with quinn / quiche / both / quiche-only, plus the full workspace.
  • Quinn regression (refactor safety): wind-test 14/14, tuic-tests integration 7/7, protocol 14/14.
  • Unified quiche path (key validation): quiche_integration (TCP+UDP relay), quiche_cert_reload (hot-reload via wind_tuic::quiche), quiche_zero_rtt — all pass against the new server.
  • cargo clippy -D warnings clean on every changed crate; nightly cargo fmt --check clean.

Reviewer notes

  • cargo clippy --workspace --all-targets surfaces 3 lints in wind-test test helpers (socks5.rs, tuic.rs) — these are pre-existing on main in files this PR does not touch.
  • The wind-quic quiche bridge's documented inbound back-pressure caveat now carries production TCP/UDP relay traffic; the quiche integration tests pass, but it is the area to watch under heavy load.

🤖 Generated with Claude Code

…bstraction

The TUIC server is now written once, generic over wind_quic::QuicConnection, and both the quinn and quiche (tokio-quiche) backends run that single implementation. This deletes wind-tuiche entirely, including its ~993-line bespoke sans-IO driver, which is replaced by the shared server core over the wind-quic bridge.

Generic protocol core (wind-tuic/src): server/ (serve_connection<C> + handlers + UDP session manager), proto/ (ClientProtoExt<C>, UdpStream<C>, encode_and_send_uni<C>; relays via tokio::io::join + copy_io), client/ (ClientTaskExt<C>).

Backends are thin providers preserving the public type names: wind_tuic::quinn::{TuicInbound, TuicOutbound, ...} keep unchanged signatures (wind/tuic-client/wind-test compile untouched); wind_tuic::quiche::{TuicheInbound(Builder), TuicheOutbound(Builder), CertStore, ConnectionOpts, ...} mirror the former wind-tuiche surface.

Supporting changes: wind-quic gains quiche cert hot-reload (CertStore moved in; bind_server takes an optional store). wind-core::AbstractTcpStream drops its vestigial Sync bound (relay streams are only moved into tasks, so Send suffices; quiche stream halves are PollSender/mpsc-backed and not Sync). Consumers repointed: tuic-server and tuic-tests now use wind_tuic::quiche + the wind-tuic/quiche feature.

The quiche client remains a config-only stub (as in wind-tuiche); no test exercises a quiche client and the quinn client is the functional path. Verified: full workspace builds; quinn regression (wind-test 14, integration 7, protocol 14) and quiche e2e (integration, cert-reload, 0-RTT) all pass; clippy -D warnings clean on changed crates; nightly fmt clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Itsusinn Itsusinn merged commit e2c25e7 into main Jun 11, 2026
17 checks passed
@Itsusinn Itsusinn deleted the feat/unify-tuic-backends branch June 11, 2026 15:10
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.

1 participant