Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
4.0 kB
Progress log — P0 (Scaffold + baseline + harness)#
See PLAN.md for the phase table and migration model.
- 2026‑06‑02 — P0a/P0b/P0c merged (scaffold + Rust‑driven baseline; bindgen full ABI + layout drift‑net; L1 differential harness
ircd-testkitwith thecref_*symbol‑renamed oracle archive). Seedocs/superpowers/plans/2026-06-01-p0{a,b,c}-*.md. - 2026‑06‑02 — P0‑L2 (golden harness) built. New workspace crate
ircd-goldenboots a pristine reference‑Circdand the in‑progress Rust‑drivenircdside‑by‑side, drives a scripted TCP client one action at a time, canonicalizes, and asserts byte‑identical wire output. First scenario — client registration (NICK/USER → welcome banner) — is byte‑identical between the two builds (alice!~alice@127.0.0.1, 16 lines through422 MOTD File is missing). This is the real P5 gate (command handlers can't be L1‑tested). Spec/plan:docs/superpowers/plans/2026-06-02-p0-l2-golden-harness.md.- Reference‑C runnable binary (new): the L1 oracle only ever produced renamed objects, never a runnable C ircd.
ircd-golden/build.rsnow builds one: recompile onlyircd.cwith a nativemain(cbuild/ircd.ocarries‑Dmain=c_ircd_main, so it has none) intoircd_ref.oviamake ‑‑eval(so the per‑object path defines$(IRCDCONF_PATH)/… expand identically), then link it with the pristine base objects (the plain.o, not the_link.opartial‑port variants) +version.o+‑lz ‑lm ‑lcrypt. Built intoOUT_DIR; path exported viacargo:rustc‑env. - DNS disabled project‑wide (
NO_DNS_LOOKUP):s_bsd.c add_connection's async reverse‑PTR lookup (gethost_byaddr→SetDNS) both embedded a nondeterministic resolved hostname in the banner and held registration across event‑loop iterations. Now‑DNO_DNS_LOOKUP(added toEXTRA_CFLAGSinircd‑sys/build.rs, so cref oracle + link set + Rust binary all share it) makes the lookup a no‑op:hostpstays NULL withoutSetDNS, clients register immediately with their numeric host (the same end‑state a no‑PTR lookup reaches; handled at the existing!cptr->hostppaths). TheUSE_IAUTHcache‑hit block that derefshostp->h_aliasesis compiled out under the same flag. Per the user: resolver behaviour is intentionally not maintained. - Keystone finding — DO NOT pin the clock to a constant. The PLAN's "LD_PRELOAD shim overriding
time()/gettimeofday()to a fixed value" breaks the server: a frozentime()freezes the globaltimeofday(set every loop atircd.c:1250), so the io_loop's scheduling never advances and the listen socket is never serviced — clients are never accepted (confirmed viastrace:poll()only ever watched the resolver fd). The harness uses the real clock and relies on the canonicalizer to mask the few time‑bearing tokens (242uptime,317idle/signon,391time;003/004are compile‑time‑stable across both builds). The registration banner embeds no runtime timestamps, so it needs none. (A future advancing‑from‑fixed‑epoch shim could tighten WHOIS‑idle/STATS scenarios.) - Config path redirect (no root):
CMDLINE_CONFIGis#undef→‑fis dead; both binariesopen("/usr/local/etc/ircd.conf")(s_conf.c:1395). A committed LD_PRELOAD shim (ircd-golden/csrc/l2shim.c) interceptsopen/open64and rewrites that one path to$IRCD_TEST_CONFIG. Boot flags:‑t(foreground)‑s(BOOT_NOIAUTH). Both bind the same fixture port (16667), so the test runs them sequentially, never concurrently. - Verification:
cargo test ‑p ircd‑golden→registration_banner_matches_referencePASS; fullcargo testgreen (golden + all 12*_diffL1 suites + layout 4/4);s_bsd.cis not L1‑tested so the DNS edit breaks no differential; 0 warnings.
- Reference‑C runnable binary (new): the L1 oracle only ever produced renamed objects, never a runnable C ircd.