Files
punktfunk/crates/punktfunk-core
enricobuehler 9afcbcd307 feat(transport): Windows DSCP via qWAVE flows — PUNKTFUNK_DSCP now real on the wire there
Networking-audit deferred plan §4 (the qos.rs follow-up). On Windows
set_tos_v4 succeeds but the stack strips the mark without a qWAVE flow, so
PUNKTFUNK_DSCP=1 was a silent wire no-op there. Now (Apollo/Sunshine's
approach): QOSCreateHandle once per process; QOSAddSocketToFlow per
connected media socket — video → QOSTrafficTypeAudioVideo, audio →
QOSTrafficTypeVoice (QOS_NON_ADAPTIVE_FLOW) — then best-effort
QOSSetFlow(QOSSetOutgoingDSCPValue, 40/48) to pin the exact CS5/CS6 the
other platforms mark. The pin lands for elevated processes (the host runs
as the SYSTEM service — exactly where the video egress is) or under the
"allow non-admin DSCP" policy; otherwise the traffic-type default marking
stands (still WMM-useful). Gating + contract unchanged: opt-in via
dscp_enabled(), every step debug-logs and continues.

set_media_qos now returns an RAII QosFlow guard (QOSRemoveSocketFromFlow on
drop) that must outlive the socket's traffic: stored in UdpTransport
(declared before the socket, so drop order removes the flow first) and held
for the stream's scope by the GameStream video/audio senders — whose
tagging moved after connect(), since qWAVE derives the flow's 5-tuple from
the connected socket (behavior-neutral on Linux). Off-Windows the guard is
inert and never constructed.

Validated: cargo check -p punktfunk-core --target x86_64-pc-windows-msvc
green (the full host can't cross-check from Linux — aws-lc-sys needs MSVC
tooling; it builds on-box via deploy-host.ps1). Remaining on the next
Windows pass per plan: deploy to the RTX box and pktmon/Wireshark the
client side — DSCP ≠ 0 on video egress with PUNKTFUNK_DSCP=1, 0 without.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 15:59:23 +02:00
..

punktfunk-core

The shared protocol core — the one place where punktfunk's transport, forward error correction, and crypto live. It's linked into the host and every native client, so there's exactly one implementation of the wire format everywhere.

Written in Rust with no async on the per-frame path (native threads only). It exposes both a normal Rust API and a stable, versioned C ABI, so the Swift and Kotlin clients — and any C embedder — link the same code as the Rust ones.

What's in here

  • Transport & session (session.rs, transport/, packet.rs) — the punktfunk/1 data plane over raw UDP: packetization, reassembly (with attacker-bounded limits), pacing, and socket tuning.
  • FEC (fec/) — the wall-breaker. Two codes:
    • GF(2⁸) classic ReedSolomon with the Cauchy generator matrix — byte-identical to the nanors library Moonlight uses, so our parity is decodable by a stock Moonlight client.
    • GF(2¹⁶) Leopard-RS (SIMD, O(n log n)) — up to 65535 shards/block, which removes the ~1 Gbps FEC ceiling. punktfunk/1 negotiates this one.
  • Crypto (crypto.rs) — AES-128-GCM session encryption with per-direction nonce salts and sequence-as-AAD; SPAKE2 PIN pairing lives behind the quic feature.
  • QUIC control plane (quic.rs, client.rs, feature quic) — the Hello/Welcome/Start handshake, cert pinning/TOFU, reverse audio, and the embeddable NativeClient connector. This is the only place tokio/quinn are allowed; the feature is off by default so the core stays runtime-free.
  • C ABI (abi.rs) — the versioned surface (punktfunk_abi_version(), PunktfunkConfig carrying its own struct_size) that generates include/punktfunk_core.h via cbindgen at build time.

Build outputs

The crate builds three ways at once (crate-type = ["lib", "cdylib", "staticlib"]):

Output Used by
lib (rlib) the host, probe, and tools link it as a normal Rust crate
cdylib (.so/.dylib) the Swift / Kotlin clients via the C ABI
staticlib (.a) the C test harness and static embedding

Test

cargo test -p punktfunk-core                 # unit + proptest + loopback
cargo run  -p loss-harness                   # FEC loss-resilience sweep (no network needed)
bash crates/punktfunk-core/tests/c/run.sh    # standalone C-ABI link + round-trip proof

Design invariants (do not regress)

  • One core, linked everywhere — protocol/FEC/crypto live only here, behind the stable C ABI.
  • No async on the hot path — the per-frame pipeline is native threads only; quic (tokio/quinn) is control-plane only, feature-gated, off by default.
  • Security hardening stays intact — the reassembler bounds attacker-controlled fields before allocating; AES-GCM keeps per-direction nonce salts + seq-as-AAD; the ABI checks struct_size. Regression tests exist — keep them green.
  • punktfunk-host — the streaming host built on this core
  • Clients — the apps that link this core over the C ABI (or directly, in Rust)
  • punktfunk-planning: implementation-plan.md (internal planning repo) — why GF(2¹⁶) FEC, the latency budget, and the architecture thesis