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.

Progress log — P3 (Transport & format)#

See PLAN.md for the phase table and migration model.

  • 2026‑06‑02 — P3 (Transport & format) merged. Ported into ircd-common: s_err.rs (the 1000‑entry replies[] numeric→format table), s_id.rs (UID/SID/CID), s_numeric.rs (do_numeric), send.rs (the non‑variadic delivery core send_message/send_queued/flush_connections/flush_fdary). Dropped from the link set: s_err.o, s_id.o, s_numeric.o; substituted: send.osend_link.o. Spec: docs/superpowers/specs/2026-06-02-p3-transport-format-design.md; plan: docs/superpowers/plans/2026-06-02-p3-transport-format.md.
    • Keystone finding (refines the hazard table): the entire sendto_* (send.c) + esendto_* (s_send.c) family is irreducibly C trampolines — every one is C‑variadic and consumes va_list through a formatter (vsendprep/vsendpreprep/build_suffix), and vsendpreprep (send.c:384) consumes va_arg per recipient, so there is no "format once → Rust core" reduction. The Rust "cores" P3 actually extracts are the delivery fns, not the senders. The senders + vsendto_one/sendto_flog/logfiles_*/setup_svchans + the static buffers/anon/svchans stay C; they vanish in P8 when call sites adopt format!. s_send.c is therefore 100% C in P3 (nothing ported).
    • Verified config gates (all OFF): USE_SERVICES, LOG_SERVER_CHANNELS, USE_SYSLOG, LOG_OLDFORMAT, ZIP_LINKS, CLIENTS_CHANNEL, JAPANESE, POOLSIZE_LIMITED → the corresponding branches of send_message/send_queued/sendto_flog/setup_svchans are omitted from the Rust port. SCH_MAX=14.
    • send_link.o partial‑port (extends P1/P2): send.c compiled twice — pristine send.o for the oracle; send_link.o with -DPORT_SEND_P3 that #ifndef‑guards the 4 ported delivery fns out of the link set and exposes dead_link (drops static) so the Rust core can call that still‑variadic C fn. Built via make --eval so the recursive -DFNAME_USERLOG/CONNLOG/SCH_PREFIX path vars expand identically for the surviving C logfiles_open. Pristine send.o (dead_link static, send_message defined) is unchanged.
    • Faithfulness notes (caught in review): replies[] is not mechanically text‑extractable — it contains #if/#else/#endif config branches (WHOIS_SIGNON_TIME/USERS_RFC1459/ENABLE_SUMMON/TXT_NOSTATSK), two bare‑NULL entries, and an escaped \r\n (entry 384) that Rust source‑level CRLF normalization would silently corrupt → it is dumped from the compiled cref_replies oracle with byte‑level escaping. alphabet_id[256] in s_id.c is partially initialized (249 explicit values) so indices 249..=255 default to 0 (reproduced verbatim). init_sid is #if 0 (not ported). poolsize *= 1.1 reproduced as (poolsize as f64 * 1.1) as u_int.
    • L1 coverage / L2 deferrals: L1 zero‑diff vs cref_ on the replies[] table (all 1000 slots), ltoid/idtol round‑trip + sid_valid/cid_ok/check_uid, do_numeric's early‑out guards, and send_message sendQ buffering (bytes + sendM + lastsq) + send_queued's dead/empty early returns. Deferred to L2 (need full server state — initialized hash tables, registered me, cref_'s separate globals, a live fd): the do_numeric broadcast wire output and the send_queued deliver_it write path.
    • Verification: cargo build warning‑free; Rust‑driven ircd links (send_link.o's variadic senders call the Rust send_message; the Rust core calls C dead_link/deliver_it); all *_diff L1 tests zero‑diff; layout net green.