[package] name = "punktfunk-core" description = "punktfunk shared protocol/transport/FEC core, exposed over a stable C ABI" version.workspace = true edition.workspace = true rust-version.workspace = true license.workspace = true authors.workspace = true repository.workspace = true [lib] name = "punktfunk_core" # `lib` — so punktfunk-host / punktfunk-probe / tools link it as a normal Rust crate. # `staticlib` — `libpunktfunk_core.a` for the C test harness and static embedding. # `cdylib` — `libpunktfunk_core.{so,dylib}` for Swift/Kotlin clients via the C ABI. crate-type = ["lib", "cdylib", "staticlib"] [features] default = [] # Control-plane QUIC (pairing, config, reverse audio). tokio is permitted ONLY here, # never on the per-frame hot path. Off by default so the core stays runtime-free. quic = ["dep:quinn", "dep:tokio", "dep:rustls", "dep:rcgen", "dep:rustls-pki-types", "dep:sha2", "dep:hmac", "dep:spake2", "dep:opus"] [dependencies] reed-solomon-simd = "3.1" # GF(2^16) Leopard-RS, SIMD, O(n log n) — the wall-breaker (P2) # Vendored fork of fec-rs: GF(2^8) classic RS with the *Cauchy* generator matrix # (M[j][i] = inv[(m+i)^j]) — byte-identical to the `nanors` library Moonlight uses, so our # parity is decodable by a stock Moonlight client. (reed-solomon-erasure is Vandermonde and is # NOT interoperable.) See vendor/fec-rs/LICENSE (BSD-2-Clause). fec-rs = { path = "vendor/fec-rs" } aes-gcm = "0.10" # AES-128-GCM session crypto, matches GameStream zerocopy = { version = "0.8", features = ["derive"] } bytes = "1" socket2 = { version = "0.6", features = [ "all", ] } # SO_SNDBUF/SO_RCVBUF growth (default UDP buffers too small for 4K/5K bursts) + DSCP/SO_PRIORITY media QoS thiserror = "2" tracing = { version = "0.1", default-features = false, features = ["std"] } rand = "0.9" zeroize = "1" quinn = { version = "0.11", optional = true } rustls = { version = "0.23", optional = true, default-features = false, features = ["ring", "std"] } # Crypto backend pinned to `ring` (matching rustls/quinn above) so the whole quic tree is # ring-only: no aws-lc-rs/aws-lc-sys (heavy C dep, needs cmake) is pulled in. Keeps the # Android/iOS cdylib lean and the cross-compile cmake-free. `generate_simple_self_signed` # is backend-agnostic, so the swap is transparent. rcgen = { version = "0.13", optional = true, default-features = false, features = ["ring", "pem"] } rustls-pki-types = { version = "1", optional = true } sha2 = { version = "0.10", optional = true } hmac = { version = "0.12", optional = true } spake2 = { version = "0.4", optional = true } tokio = { version = "1", optional = true, features = ["rt-multi-thread", "net", "sync", "macros"] } # In-core Opus (multistream) DECODE for the C-ABI `punktfunk_connection_next_audio_pcm` path — # used by embedders without a multistream-capable Opus decoder (Apple's AudioToolbox is # stereo-only). The Rust clients link `opus` themselves and decode the raw `next_audio` frames, # so this only matters when the connection API (quic) is built. Same libopus the host vendors; # cargo unifies the build. Multistream API: `opus::MSDecoder` (lib.rs:1187). opus = { version = "0.3", optional = true } # `libc` for batched UDP syscalls: `sendmmsg`/`recvmmsg` on Linux (the 1 Gbps+ lever) and the # `recv(MSG_DONTWAIT)` drain on the other unix (Apple/BSD) targets, which have no `recvmmsg` # (see transport/udp.rs `recv_batch`). Needed on every unix target — non-unix (Windows) uses # the scalar fallbacks. Cross-compiles (iOS/tvOS) don't pull libc transitively the way the # macOS host build does, so it must be a direct dep here or those slices fail to link `libc::`. [target.'cfg(unix)'.dependencies] libc = "0.2" # Windows UDP Send Offload (USO): `WSASendMsg` + `UDP_SEND_MSG_SIZE` is the Windows analogue of # Linux UDP GSO — the 1 Gbps+ send lever (the host otherwise sends one packet per `send` syscall, # which caps throughput at high packet rates). See transport/udp.rs. [target.'cfg(windows)'.dependencies] # windows-sys (raw FFI, the quinn-udp choice): the high-level `windows` crate doesn't bind the # `WSASendMsg` extension function. WinSock feature gives WSASendMsg + WSAMSG/WSABUF/CMSGHDR. # Win32_System_IO too: WSASendMsg's signature references OVERLAPPED, so it's gated on that feature. windows-sys = { version = "0.59", features = ["Win32_Networking_WinSock", "Win32_System_IO"] } [dev-dependencies] proptest = "1" # Tier-1 microbenchmarks (benches/pipeline.rs). default-features off → no plotters/HTML (headless # CI just needs the measurement + target/criterion/**/estimates.json for the regression compare). criterion = { version = "0.5", default-features = false, features = ["cargo_bench_support"] } [[bench]] name = "pipeline" harness = false [build-dependencies] cbindgen = "0.29"