Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
3.7 kB
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‑entryreplies[]numeric→format table),s_id.rs(UID/SID/CID),s_numeric.rs(do_numeric),send.rs(the non‑variadic delivery coresend_message/send_queued/flush_connections/flush_fdary). Dropped from the link set:s_err.o,s_id.o,s_numeric.o; substituted:send.o→send_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 consumesva_listthrough a formatter (vsendprep/vsendpreprep/build_suffix), andvsendpreprep(send.c:384) consumesva_argper 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/svchansstay C; they vanish in P8 when call sites adoptformat!. 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 ofsend_message/send_queued/sendto_flog/setup_svchansare omitted from the Rust port.SCH_MAX=14. send_link.opartial‑port (extends P1/P2):send.ccompiled twice — pristinesend.ofor the oracle;send_link.owith-DPORT_SEND_P3that#ifndef‑guards the 4 ported delivery fns out of the link set and exposesdead_link(dropsstatic) so the Rust core can call that still‑variadic C fn. Built viamake --evalso the recursive-DFNAME_USERLOG/CONNLOG/SCH_PREFIXpath vars expand identically for the surviving Clogfiles_open. Pristinesend.o(dead_linkstatic,send_messagedefined) is unchanged.- Faithfulness notes (caught in review):
replies[]is not mechanically text‑extractable — it contains#if/#else/#endifconfig branches (WHOIS_SIGNON_TIME/USERS_RFC1459/ENABLE_SUMMON/TXT_NOSTATSK), two bare‑NULLentries, and an escaped\r\n(entry 384) that Rust source‑level CRLF normalization would silently corrupt → it is dumped from the compiledcref_repliesoracle 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_sidis#if 0(not ported).poolsize *= 1.1reproduced as(poolsize as f64 * 1.1) as u_int. - L1 coverage / L2 deferrals: L1 zero‑diff vs
cref_on thereplies[]table (all 1000 slots),ltoid/idtolround‑trip +sid_valid/cid_ok/check_uid,do_numeric's early‑out guards, andsend_messagesendQ buffering (bytes +sendM+lastsq) +send_queued's dead/empty early returns. Deferred to L2 (need full server state — initialized hash tables, registeredme,cref_'s separate globals, a live fd): thedo_numericbroadcast wire output and thesend_queueddeliver_itwrite path. - Verification:
cargo buildwarning‑free; Rust‑drivenircdlinks (send_link.o's variadic senders call the Rustsend_message; the Rust core calls Cdead_link/deliver_it); all*_diffL1 tests zero‑diff; layout net green.
- Keystone finding (refines the hazard table): the entire