Files
punktfunk/clients/probe
enricobuehler 290d760ea4 feat(core/wire): per-frame shard geometry, jumbo ceiling, Hello advertisement
Phase 0 of mid-session shard-payload renegotiation (planning
design/shard-payload-reneg.md), stacked on the leg-1 MTU resilience. All
three legs are client-side and forward-compatible: deployed clients that
carry them accept a mid-session shard change the moment a future host
sends one, and nothing changes on the wire until then.

- W0.1 — the reassembler's strict shard_bytes firewall becomes per-frame
  pinning: a frame's first-arriving packet pins that frame's shard size
  (bounds-checked to [min_shard_bytes, max_shard_bytes], even), later
  packets must match the pin, and the per-frame block ceiling derives
  from the pinned size (a session-level cap would reject legitimate
  post-shrink frames). The reorder race between an ordered control
  message and unordered video dies structurally: old-geometry frames in
  flight complete under their own pin while new frames arrive under the
  new one, and no cross-geometry splice can land in one buffer. The
  in-flight budget stays byte-based and exact.
- W0.2 — MAX_DATAGRAM_BYTES 2048 → 9216: every receive path (transport
  RECV_BUF, the recvmmsg ring) now accepts sealed jumbo datagrams
  (9000-MTU LAN ≈ 8908-byte shards). Static buffers over resize-on-ack:
  the ring delta is 128 × ~7 KiB ≈ 896 KiB per client session, lazily
  allocated, hosts unaffected. Grep verdict: no embedder uses the
  constant directly, so no C ABI bump — the regenerated header rides
  along (drift gate).
- W0.3 — trailing Hello field max_shard_payload: u16 (0/absent =
  legacy), the append-with-placeholder discipline of video_caps/
  client_caps. One field is both the renegotiation capability flag and
  the jumbo ceiling; core's pump advertises it for all client families,
  the probe too.
- Host seam for Phase 1, dead until wired: Packetizer::set_shard_payload
  (re-derives the block ceilings; construction delegates to it) +
  Session::set_shard_payload (host-only, Config::validate parity).

Verification (the 0.23.0 lesson — geometry changes breed sizing bugs):
the slice-wire suite re-runs at shard 512/1216/1408/8908 (exact-multiple
sweep, lossy + reversed roundtrips, sentinel path, in-flight budget);
mid-stream shrink→grow→revert delivery; the old-geometry reorder race;
cross-geometry splice rejection; firewall bounds non-vacuous both ways;
a 48-case mixed-geometry reorder-torture proptest asserting per-frame
byte-identical DELIVERY and an exactly-zero final budget; and a sealed
loopback session test (continuous crypto/replay) delivering frames
across live re-keys — every test asserts delivered frames, never the
absence of errors.

core: 294/294 --features quic + clippy -D warnings (macOS), fmt.
2026-08-04 19:27:09 +02:00
..

punktfunk — probe (reference client)

punktfunk-probe is the headless reference client for the punktfunk/1 protocol — a command-line tool for testing, latency measurement, and validating host behavior. It's not a streaming app you'd watch on; it connects, exercises a plane, and reports numbers. If you want to actually stream, use the Linux, Windows, Apple, or Android clients.

Because it links the same punktfunk-core as every other client, it's also the canonical example of driving the protocol end to end: QUIC control plane, UDP data plane, and the side planes (input, audio, rumble) over QUIC datagrams.

What it does

  • Receives a real stream, writes a playable elementary stream (.h265/.h264/.av1 — the extension tracks the negotiated codec; the probe advertises all three and the host picks), and reports per-frame capture→received latency percentiles (the host stamps each frame with its capture clock).
  • Verification mode against a synthetic host — byte-checks deterministic test frames.
  • Exercises every plane with scripted test traffic: --input-test (mouse/keyboard), --mic-test (a 440 Hz Opus tone up to the host mic), --touch-test (a synthetic finger), --rich-input-test (DualSense touchpad + motion, logging the HID-output feedback that comes back).
  • Trust--pin <64-hex> pins the host fingerprint; --pair <PIN> runs the SPAKE2 pairing ceremony and prints the verified fingerprint to pin from then on. Without a pin it trusts on first use.
  • Discovery--discover [secs] browses the LAN for _punktfunk._udp hosts and prints each (name, addr:port, pairing requirement, cert fingerprint), then exits.
  • Negotiation knobs--mode WxHxFPS, --remode (mid-stream mode change), --bitrate, --codec auto|h264|hevc|av1 (preference; the host resolves), --audio-channels (stereo / 5.1 / 7.1), --compositor, --gamepad, --launch, --speed-test. Env: PUNKTFUNK_CLIENT_10BIT=1 / PUNKTFUNK_CLIENT_444=1 advertise the 10-bit / 4:4:4 client caps (for testing a host's PUNKTFUNK_10BIT/PUNKTFUNK_444).

Usage

# stream 720p120 from a host, save the video, and print latency percentiles:
cargo run -p punktfunk-probe -- --mode 1280x720x120 --connect HOST:PORT --out /tmp/a.h265

# list hosts on the LAN:
cargo run -p punktfunk-probe -- --discover

# pair with a host that requires it (read the PIN off the host), then stream:
cargo run -p punktfunk-probe -- --connect HOST:PORT --pair 1234
cargo run -p punktfunk-probe -- --connect HOST:PORT --pin <64-hex> --input-test

Full flag reference is in the module doc-comment at the top of src/main.rs.

  • Project README — the host, the streaming clients, and the protocol
  • punktfunk-host punktfunk1-host — the persistent native-protocol listener to probe against (see the "Running on this box" section of the repo README / CLAUDE.md)