refactor(core): split quic.rs (3.2k lines) into src/quic/ — pure move

Networking-audit deferred plan §3. One file per concern, zero logic edits:

  quic/mod.rs      MAGIC/CTL_MAGIC + re-exports (every crate::quic::X path
                   compiles unchanged across host + all clients)
  quic/msgs.rs     Hello/Welcome/Start, typed control msgs + type bytes,
                   resolve_codec, ColorInfo, window_loss_ppm, pairing msgs
  quic/pake.rs     the SPAKE2 pairing exchange
  quic/datagram.rs 0xC9–0xCF plane codecs (audio/rumble/mic/rich-input/
                   hidout/HdrMeta/HostTiming)
  quic/io.rs       length-prefixed stream IO
  quic/clock.rs    clock_offset_ns estimator, clock_sync, ClockResync
  quic/endpoint.rs quinn config, ALPN, pinning verifiers, keep-alive
  quic/tests.rs    the cross-cutting test module, unchanged

Mechanical deltas only: the nested `pub mod` wrappers became files (one
dedent), submodules import what they previously inherited from the parent
scope, and the three RichInput kind tags are pub(super) for the tests
(same-module before). Verified line-multiset-identical after normalizing
indentation. cargo check --workspace, core tests (quic), clippy, and
cargo ndk check all green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 15:51:15 +02:00
parent d4467a44e2
commit e9b2eacf87
9 changed files with 3249 additions and 3227 deletions
+64
View File
@@ -0,0 +1,64 @@
//! `punktfunk/1` — the native control plane, gated behind the `quic` feature.
//!
//! GameStream is punktfunk's compatibility layer; this is the start of its own protocol. A QUIC
//! connection (quinn, tokio — control plane only, never the per-frame path) carries a
//! length-prefixed binary handshake on one bidirectional stream:
//!
//! ```text
//! client → host Hello { abi_version }
//! host → client Welcome { abi_version, session: full data-plane Config + mode + UDP port }
//! client → host Start { client_udp_port }
//! ```
//!
//! after which both sides bring up a [`crate::session::Session`] over a plain
//! [`UdpTransport`](crate::transport::udp) (native threads, no async) and the host streams.
//! The Welcome carries everything the core negotiates — FEC scheme (including GF(2¹⁶)
//! Leopard, which GameStream can't express), shard sizing, crypto key/salt — so the data
//! plane is exactly the hardened core `Session`.
//!
//! Transport security: the host presents a long-lived self-signed certificate
//! ([`endpoint::server_with_identity`]) and the client pins its SHA-256 fingerprint
//! ([`endpoint::client_pinned`]; no pin = trust-on-first-use, with the observed fingerprint
//! reported back for persisting). The data plane adds AES-GCM on top.
//! All integers little-endian; every message is `u16 length || payload`.
//!
//! Split by concern (networking-audit deferred plan §3 — a pure move): [`msgs`] the
//! handshake + typed control messages, [`pake`] the pairing SPAKE2, [`datagram`] the
//! 0xC90xCF plane codecs, [`io`] framed stream IO, [`clock`] skew estimation + mid-stream
//! re-sync, [`endpoint`] the quinn constructors. Every item is re-exported here, so all
//! existing `crate::quic::X` paths compile unchanged.
/// Protocol magic + version, first bytes of the positional handshake (Hello/Welcome/Start).
pub const MAGIC: &[u8; 4] = b"PKF1";
/// Magic for typed post-handshake / pairing control messages. A distinct magic keeps the
/// typed namespace disjoint from the positional handshake: a `Hello` (whose abi_version
/// byte sits where a type byte would) can never be misparsed as a control message, and
/// vice-versa, regardless of field values.
pub const CTL_MAGIC: &[u8; 4] = b"PKFc";
mod clock;
mod datagram;
mod msgs;
/// quinn endpoint constructors. Host: self-signed identity (fresh, or persisted PEMs via
/// [`endpoint::server_with_identity`]). Client: fingerprint pinning / TOFU via
/// [`endpoint::client_pinned`] ([`endpoint::client_insecure`] is the no-pin special case).
pub mod endpoint;
/// Async framed-message IO over a quinn stream (`u16 LE length || payload`).
pub mod io;
/// SPAKE2 over Ed25519 for the pairing ceremony. The two roles use the asymmetric flow so
/// the identities are ordered; each side binds **both** certificate fingerprints as the
/// SPAKE2 identities, so the derived key only matches when client and host agree on the PIN
/// *and* saw the same two certificates (a MITM, presenting different certs to each leg,
/// cannot reach a shared key).
pub mod pake;
pub use clock::*;
pub use datagram::*;
pub use msgs::*;
#[cfg(test)]
mod tests;