Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
0

Configure Feed

Select the types of activity you want to include in your feed.

ircd.rs / README.md
3.7 kB 77 lines
1# leveva — an idiomatic-Rust IRC daemon 2 3NOTE: by reading this README or any of the code, you hereby and irrevocably 4agree to leave the IRCNet team alone with regards to this repo. This experiment 5was done without their knowledge, consultation, or any belief on my part that 6this will be anything but an experiment to see what is possible with tools 7that exist today. 8 9This repo started as a *mechanical* C→Rust port of 10[ircnet/ircd](https://github.com/ircnet/ircd) 2.11 — a faithful, byte-for-byte 11translation kept honest against the original C as a differential oracle. That 12port did its job and is **gone**. What remains is what it was scaffolding for: 13**leveva**, a from-scratch, idiomatic-Rust IRC daemon that grew to feature parity 14against the mechanical port and then replaced it. 15 16So this is a finished [strangler fig](https://martinfowler.com/bliki/StranglerFigApplication.html): 17the C tree was strangled by a faithful Rust port, the faithful port was strangled 18by leveva, and now only leveva is left standing. 19 20## What leveva is 21 22A single-binary IRCnet-style daemon written in idiomatic async Rust: 23 24- **tokio** runtime, one task per connection — no `select()`/`poll()` loop, no 25 global buffers, no `unsafe` FFI seam. 26- **rustls** TLS (via `ring`, no system OpenSSL) with hot certificate reload. 27- **KDL** config (typed, validated) instead of the C daemon's pipe-delimited 28 single-letter lines. 29- Typed identifier strings (`Nick`/`ChanName`/`Uid`/`Sid`/…) that reject illegal 30 input at construction, and casemapping-aware string types. 31- The full IRCnet client surface (registration, channels + channel/user modes, 32 WHO/WHOIS/WHOX, OPER/STATS, …), the UID-based S2S link/burst/netsplit protocol 33 (UNICK/NJOIN/SAVE/EOB), and a growing IRCv3 track (CAP, message-tags + delivery 34 plane, away/account/invite/echo/server-time, MONITOR, chghost/setname, 35 multi-prefix, standard-replies, WebSocket transport, …). 36- In-process authentication (`leveva-iauth`: ident/dnsbl/socks/webproxy), running 37 as an `.await` in the per-connection task rather than a separate iauth process. 38 39The behavioral guarantees are carried by leveva's own self-contained test suite — 40boot-golden snapshots plus property-based (`proptest`) fuzzing for essentially 41every command. 42 43## Workspace layout 44 45| Crate | What it is | 46| -------------- | ----------------------------------------------------------------- | 47| `leveva` | the daemon (library + the `leveva` binary) | 48| `leveva-iauth` | in-process async authentication modules | 49 50## Build and run 51 52```sh 53cargo build --release -p leveva --bin leveva 54./target/release/leveva --config path/to/ircd.kdl 55``` 56 57Useful flags: `--check` (validate the config and exit), `--motd <file>`, 58`--log-level <level|RUST_LOG-filter>`. Example configs live in 59[`leveva/examples/`](./leveva/examples/) (`simple.kdl` is a good starting point). 60 61Container images build with [buildx bake](./docker-bake.hcl): 62 63```sh 64docker buildx bake leveva 65``` 66 67## History and how it was built 68 69leveva was built with Claude Code and the 70[superpowers](https://github.com/obra/superpowers) plugin, one differentially 71verified slice at a time. The full migration story — the mechanical port, the 724-layer test harness, the phase-by-phase plan, and the pivot to leveva — lives in 73[PLAN.md](./PLAN.md), with per-phase progress logs under 74[`docs/progress-log/`](./docs/progress-log/) and the generated specs/plans under 75[`docs/superpowers/`](./docs/superpowers/). The deleted mechanical port, the C 76source tree, and the differential oracles all remain recoverable from git 77history.