title: "The keystone wasn't the monster" desc: "Post four and post sixteen both named sendto_one the scary one: ~478 call sites and a formatting decision made per recipient. When I finally pulled it, the per-recipient horror was in a different function entirely, and the only hard thing left was that there were 435 of them." date: 2026-06-08#
I ended post sixteen nervous. The first
variadic trampoline had come out like a loose tooth, but I closed by naming the two
I was actually scared of — sendto_one, with something like 478 call sites, and
sendto_flag with around 255 — and admitting I hadn't solved the thing that made
them frightening: a formatting decision made per recipient, deep in
vsendpreprep, where there's no "format once at the call site" to hoist out.
P8 is done now. Every variadic sender is Rust. The keystone — sendto_one, the
single-client sender behind very nearly every numeric reply the daemon emits — came
out, and the part worth writing down is that the thing I was scared of wasn't in it.
Here's the punchline up front: I called sendto_one the keystone because of its
call-site count, and that turned out to be the only hard thing about it. The
per-recipient formatting horror — the real monster from post
four — lives in a different function, and I'd
already dealt with it a few cuts earlier without quite clocking that's where it had
been hiding the whole time.
The thing I was actually afraid of#
Back up to post four. The reason a sendto_*
function had to stay a C variadic was never the ... by itself — stable Rust can
call those fine. It was vsendpreprep (send.c:388), the worker behind the
prefix senders, the ones that emit :nick!user@host PRIVMSG .... That function
re-walks its va_list once per recipient, because the prefix it builds differs for
each one: a local client who knows you gets the full nick!user@host, a server
downstream gets a bare :nick. You cannot format the line once and reuse it. The
format depends on who's reading it.
That's the monster, and it's real — I'm not waving it away. But notice what it's a
property of: vsendpreprep, and the senders that lean on it. sendto_one is not
one of them.
sendto_one was the easy shape all along#
Look at what sendto_one actually does, stripped to bones. It's a variadic wrapper
around vsendto_one, which calls vsendprep (send.c:385): take the pattern and
args, format them once with libc vsprintf into a buffer, cap the body at 510
bytes, append CRLF, hand it to send_message for the one target. That's the whole
function. One format, one delivery. There's no per-recipient branch because there's
exactly one recipient.
Which makes it — mechanically — the same shape as sendto_iauth from post
sixteen: a variadic shell wrapped around a
format-once worker. The trick that made that one a loose tooth applies here
unchanged. Move the va_start work out to the callers, where the arguments already
live, and the function left behind takes finished bytes:
// ircd-common/src/send.rs:553
pub unsafe fn sendto_one(to: *mut aClient, body: &[u8]) -> c_int {
let mut buf = [0u8; 520];
let len = prep_line(body, &mut buf);
send_message(to, buf.as_mut_ptr() as *mut c_char, len);
len
}
prep_line is the faithful vsendprep: copy at most 510 body bytes, append \r\n,
return the length. The 510 cap is the real one from the C, not a round number I
liked — it's the line-length limit every IRC client expects, and getting it wrong by
a byte shifts the truncation point on long lines. The core returns that prepped
length because a couple of callers read it (two rlen += sendto_one(...) sites in
channel.rs that tally how much they've queued).
Cadey (aha): I spent two posts treating
sendto_onelike it'd be the hard one, and the whole time it wassendto_iauthwith a bigger guest list. The keystone isn't keystone-shaped. It's just popular.
I was wrong about needing leveva first#
There's a second thing I got wrong, and it's the more interesting mistake.
When I first sketched this rip-out I assumed sendto_one was blocked — that I
couldn't touch it until I'd built leveva's typed Numeric layer over in P10. The
reasoning: most of these call sites don't pass a literal format string. They pass
reply(ERR_NOSUCHNICK), a lookup into the replies[] table that hands back a
char * format string at runtime. So the format string is data, chosen at
runtime, and you can't fold a runtime-chosen format into a compile-time wire!
builder. Therefore, I told myself, I need the typed numeric layer first.
That's wrong, and it's wrong in a way worth being precise about. The delivery path
I'm replacing — vsendprep — formats with libc vsprintf. Plain libc. Not the
in-tree irc_vsprintf, just the C library's printf. So all I need to come out
byte-identical is the same printf engine, and libc has a snprintf I can call
straight from Rust. The runtime format string stops being a problem; I hand it to
snprintf exactly the way C handed it to vsprintf, and the bytes match. No typed
numeric layer required to be faithful. That's a P11 nicety, not a P8 blocker.
So that's all reply_one! is (send.rs:519): render the runtime format string and
its args through libc snprintf into a scratch buffer, then hand the resulting C
string to the non-variadic sendto_one core.
// ircd-common/src/send.rs:519
macro_rules! reply_one {
($to:expr, $fmt:expr $(, $arg:expr)* $(,)?) => {{
let mut __rbuf = [0 as ::std::os::raw::c_char; 2048];
::libc::snprintf(
__rbuf.as_mut_ptr(),
__rbuf.len(),
$fmt as *const ::std::os::raw::c_char,
$($arg,)*
);
$crate::send::sendto_one($to, $crate::send::cstr_bytes(__rbuf.as_ptr()));
}};
}
The buffer is oversized on purpose — 2048 bytes for a line that gets truncated to 510 — so its own cap never bites before the real one. It's the same printf engine, called the same way the C called it. That's the whole reason the bytes match, and it holds for the literal sites and the runtime ones alike.
Mara (hacker): The thing that makes this safe is narrow, and worth stating exactly. It's not "snprintf and vsprintf are both printf, close enough." It's that the C I'm matching also went through the libc engine — so I'm not reimplementing printf, I'm calling the identical implementation with the identical format string and args. If the original had used
irc_vsprintf(the custom in-tree formatter, with its own quirks), this would not hold and I'd be back to needing a faithful port of that. The faithfulness comes from both paths sharing libc, not fromsnprintfbeing "standard."
Two builders, one core#
So the call sites split cleanly into two kinds, and they get two builders feeding
one core. The 58 sites with a literal pattern — c":%s NOTICE %s :%s" and friends —
use wire!, the raw-byte line builder, which stitches byte-literals and char *
pointers together without routing through a lossy UTF-8 String. The roughly 375
sites that pull a format string out of replies[] use reply_one!. And two
stragglers in channel.rs that read the return value call the core directly.
Here's why the split is forced, in one real pair. The reply helper is nothing but
a replies[] lookup:
// ircd-common/src/s_user.rs:116
unsafe fn reply(i: u32) -> *mut c_char {
*(addr_of!(replies) as *const *mut c_char).add(i as usize)
}
A real WHO reply — the classic 352 — threads that runtime-fetched format string and
a dozen client fields through reply_one!:
// ircd-common/src/s_user.rs:473
crate::reply_one!(
sptr,
reply(RPL_WHOREPLY),
me_name(),
bad_to((*sptr).name),
if repchan.is_null() { c"*".as_ptr() as *mut c_char } else { chname_ptr(repchan) },
(*user).username.as_ptr(),
(*user).host.as_ptr(),
(*user).server,
(*acptr).name,
status_p,
(*acptr).hopcount,
(*(*user).servp).sid.as_ptr(),
// ...
);
You can't wire! that. The format string reply(RPL_WHOREPLY) is a pointer fetched
from a table at runtime; wire! would need the literal at compile time to interleave
the pieces. reply_one! doesn't care — it hands the whole thing to snprintf the
way the C handed it to vsprintf.
435 edits is a job you delegate#
So if the formatting wasn't hard and the blocker wasn't real, what was the work? Volume.
There were about 435 call sites across fifteen files. Post four guessed 478 and post
sixteen repeated it; the real count when I got there was 435, which is the kind of
small honesty I'd rather log than quietly correct. None of them is hard alone. Each
is a mechanical rewrite: find the sendto_one(to, fmt, args...), decide whether it's
a literal (wire!) or a replies[] lookup (reply_one!), rewrite it, move on. Four
hundred and thirty-five times.
I did not do that by hand, and I'm not going to pretend I did. I ran it as a fan-out:
fifteen agents, one per file, each told to convert only its file's call sites to the
two builders, with a single central pass afterward that built the whole workspace and
ran the differential. Edit-only workers, central verify. The judgment was in
designing the two builders and proving the snprintf path byte-identical; the other
435 reps were the careful-but-boring kind of work you hand off and then check.
Cadey (coffee): There's a version of this post where I describe 435 hand edits as a feat of endurance. That'd be a lie. The feat was the two builders and the proof that
snprintfmatchesvsprintf. Once that was nailed the edits were a loop, and I ran the loop in parallel. The judgment lives in the part you can't parallelize — deciding the line is byte-safe — not the part you can.
How you check 435 rewrites at once#
Verification is the same A/B-then-snapshot shape as every other cut in this phase, so I'll keep it short.
The original L1 test (sendto_one_diff.rs) built two parallel worlds — the Rust core
fed pre-formatted bytes, and the still-variadic cref_sendto_one oracle, the
renamed C copy — pointed each at a fresh client on a dead fd,
and diffed the bytes that landed in the target's send queue. Because the oracle is
still C, it's allowed to be the variadic I can't write, exactly as in post sixteen.
Once that diff was green, the test was migrated to a self-contained snapshot of just
the Rust side, because by P8's end the C oracle is going away.
Cases are chosen for what a format-once-then-truncate sender can get wrong: a literal
wire! line, a reply_one! template with string args, the same with %d/%02d
numerics through the printf engine, a NULL %s arg where glibc emits the literal
(null) and I want that byte-for-byte, and the 510-byte truncation boundary:
// ircd-common/tests/sendto_one_snap.rs
#[test]
fn truncation_at_510() {
let r = target();
let long = vec![b'x'; 600];
let fmt = c":%s NOTICE bob :%s".as_ptr();
let longc = std::ffi::CString::new(long).unwrap();
reply_one!(r, fmt, c"irc.test".as_ptr(), longc.as_ptr());
let bytes = map_bytes(r);
assert_eq!(bytes.len(), 512, "truncated to 510 + CRLF");
insta::assert_debug_snapshot!("truncation_at_510", snap_bytes(&bytes));
}
Six hundred bytes in, 512 out — 510 of body plus the CRLF. That one assertion is the
whole faithfulness contract for long lines: the C capped at 510, prep_line caps at
510, and if either ever drifts the byte count moves and the snapshot screams.
On top of the L1, the full golden suite — 111 scripted end-to-end scenarios — runs
byte-for-byte identical, minus the two STATS flakes I've written about
before, where the reference C
prints uninitialized garbage and the Rust is the correct one. Since sendto_one sits
behind nearly every numeric reply, those 111 scenarios are in effect 111 more tests
of this one function — the coverage-by-ubiquity I leaned on in post
ten, except here it's honest,
because a botched format would corrupt visible replies in basically every scenario at
once, loudly.
What the keystone actually was#
So the keystone is Rust, and the lesson is that I'd mislabeled it. sendto_one
earned the name because it has the most call sites in the program, and call-site
count measures how central a function is, not how hard it is to port. Different
axes. The hard axis — the per-recipient formatting — belongs to vsendpreprep and
the prefix senders, which I'd already pulled a few cuts earlier (sendto_prefix_one
and its relatives), and which deserve their own post, because that's where the
format-depends-on-the-reader problem actually got solved.
The honest shape of P8, now that it's finished: the famous function was the easy kind in big numbers, and the genuinely hard one is a function almost nobody's heard of. I spent two posts pointing at the wrong one. That's not a humblebrag — it's the thing the differential harness is for. I can be wrong about which function scares me, run the byte-diff, and find out the fear was misfiled. The test doesn't care what I named the keystone.
What's left after this is the prefix-sender story I keep gesturing at, and then the part where the whole C oracle gets switched off for good. The keystone's out. It just wasn't holding up what I thought it was.
The port is in ircd-common/src/send.rs —
sendto_one at line 553, with the wire! builder and the reply_one! bridge just
above it. The byte-diff lives on as
ircd-common/tests/sendto_one_snap.rs,
migrated from the original cref_ differential. The phase plan is
PLAN.md. Post four is why these
functions had to be C; post sixteen is the
first one out and the format-at-the-callsite trick this reuses; post
three is the cref_ rename the test leans on.
And the standing reminder, true on every post here: this is an unsanctioned experiment on someone else's code. Leave the IRCNet team out of it. The keystone I mislabeled and the monster I'd already pulled are both mine.