Skip to content

Repository files navigation

Castr

A cross-platform LAN multicast file transfer tool. A trusted sender broadcasts a file once over IP multicast; any number of receivers on the network pick it up simultaneously, verify it via a signed, chunk-hashed manifest, decrypt it (chunk payloads are encrypted end-to-end with ChaCha20-Poly1305, not just signed — see below), and repair any lost chunks by requesting them from peer receivers rather than re-asking the sender.

Runs on Windows, macOS, and Linux with full IP multicast; iOS and Android join the same swarm as unicast clients over LAN-discovered peers, since neither OS allows apps to reliably join true multicast groups.

See it in action

Castr desktop GUI: a live multicast transfer between two windows, trust prompt and progress in real time

One sender, any number of receivers, one broadcast — a LAN party mod pack push, a sysadmin scripting a fleet config rollout, a test lab loading the same dataset onto every bench machine at once. See all three, with GIFs of the CLI, the colorful TUI dashboard, and the desktop GUI →

Interested in how the performance work was actually done — including the fix we shipped first and had to reverse, and why we read UFTP's source and then declined to copy its congestion control? METHODOLOGY.md covers the approaches and the reasoning; docs/benchmarks/throughput-runs.md keeps every raw measurement behind it.

Status

M0 (scaffolding) through M8 are complete. M5 shipped the showcase docs below; M6 root-caused and fixed a receiver-side throughput bottleneck (wiki/synthesis/m6-throughput-pipelining.md); M7 removed a self-inflicted repair storm that was sending the file roughly twice, cutting wire amplification from 2.39× to 1.13× and eliminating a burst/stall delivery pattern (wiki/synthesis/m7-repair-amplification.md); M8 raised the default chunk size to the 256 KB that Castr.Core and the wire protocol had specified all along. Throughput work is not finished — per-datagram syscall cost currently caps transfers near ~37 MB/s, and raising the datagram budget is the tracked next step. Formal release automation (tag-triggered releases, checksums/signatures) also remains open. Both are in wiki/synthesis/roadmap.md, and every measurement behind these claims is in docs/benchmarks/throughput-runs.md. Chunk payloads are ChaCha20-Poly1305-encrypted end-to-end and travel over MTU-safe wire packets (chunks split/reassembled below the crypto layer) — see wiki/synthesis/m1.5-encryption-summary.md and wiki/synthesis/m3-test-ci-hardening-summary.md. castr send/castr receive/castr trust, a live Spectre.Console dashboard (--tui), and an Avalonia desktop GUI are all working — see wiki/synthesis/m2-ui-summary.md. Mobile (iOS/Android) joins as a unicast swarm client over LAN-discovered peers (native NsdManager/NWBrowser discovery, TCP pull, the same signed-manifest/Merkle/AEAD verification the desktop multicast tier uses) — Castr.Gui.Android produces a real debug-signed sideloadable APK; Castr.Gui.iOS builds and links its native discovery bindings against real Xcode, though the full app-level Simulator link is currently blocked by an upstream libsodium packaging gap — see wiki/synthesis/m4-mobile-summary.md. CI runs a real 3-OS build+test matrix, a Docker-gated multi-container E2E fan-out job with real induced packet loss, and dedicated Android/iOS mobile-build workflows on real SDK/Xcode-provisioned runners — see wiki/synthesis/m3-test-ci-hardening-summary.md and wiki/synthesis/m4-mobile-summary.md. See wiki/synthesis/roadmap.md for milestone status and wiki/ generally for the accumulated design decisions (ADRs, spike results). The full architecture — wire protocol, repair algorithm, security model, and milestone plan — lives in the project plan; a synthesis of it is ingested into wiki/ as the project's first source so it survives session restarts.

Repo layout

  • src/Castr.Core — protocol state machines, chunker, Merkle/manifest, trust store, transport abstractions (no UI, no platform-specific code)
  • src/Castr.Core.Discovery — peer discovery abstraction + platform mDNS impls (used by the mobile unicast tier)
  • src/Castr.Cli — command-line entrypoint (System.CommandLine): send, receive, trust list|add|block|remove
  • src/Castr.Tui — colorful live transfer dashboard (Spectre.Console), consumed by Castr.Cli --tui
  • src/Castr.Gui, src/Castr.Gui.Desktop — Avalonia GUI: shared views/viewmodels and the Windows/macOS/Linux desktop head
  • src/Castr.Gui.Android, src/Castr.Gui.iOS — Avalonia mobile GUI heads (unicast swarm client), built on top of Castr.Core.Discovery + the TCP swarm-pull tier in Castr.Core; each opt-in-multitargeted so a default dotnet build/CI matrix never requires mobile workloads
  • tests/ — unit, loopback-multicast integration, CLI, TUI, GUI, and discovery test projects, one per corresponding src/ project's concerns, plus Castr.Core.E2ETests: a Testcontainers-driven multi-container fan-out suite (real Docker bridge multicast + kernel-level tc netem loss), opt-in via CASTR_E2E=1 and gated on Docker being reachable
  • wiki/, raw/ — the project's persistent knowledge base (llm-wiki), the durable memory across sessions
  • graphify-out/ — generated codebase knowledge graph (query this instead of re-reading the whole tree when resuming work)

Building

dotnet build
dotnet test

Requires the .NET 10 SDK (LTS, pinned via global.json).

Every push to main also builds self-contained, per-platform zips of castr (CLI) and the desktop GUI for win-x64, win-arm64, osx-x64, osx-arm64, and linux-x64, uploaded as downloadable artifacts on that CI run's Actions page (see the package job in .github/workflows/ci.yml). These are unsigned CI convenience builds, not versioned/checksummed releases — that's tracked for M5.

License

Apache-2.0 — see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages