First post, delivered late by a router
This is the first post. Before it existed, the site already had a static generator, a search index, a WebAssembly build, a Nix flake, a web server and an SNI router in front of it. I would read that ordering less as an accident and more as a fairly accurate portrait of the author.
Who writes here
By day I tune SQL in old ERP systems, the kind full of well-meant integrations: queries that ran fine for ten years, until a consultant and a developer had an idea. I was hired to do analytics on a data warehouse; the performance work found me anyway.
By night it is algebra, discrete math and bit tricks, mostly in Rust, and
further down than is reasonable, which lately means compilers. The handle is
might_sleep(), the kernel's annotation for a function that may sleep: call
it from the wrong context and you get a warning. Given the hours, it fit.
These days most of the night shift ends up in the Rust data stack, arrow-rs, DataFusion and Vortex, because that is where the two shifts meet: the day job is databases, the night is bit tricks, and a columnar engine is mostly bit tricks pretending to be a database. A few small patches of mine got merged there. The rest went into hakmem, a crate that tries to treat bit tricks as an algebra with laws instead of a bag of one-line spells, named after a 1972 MIT memo it will never live up to, and into a Vulkan renderer whose geometry pass has been "almost working" for long enough to count as a research topic.
The pattern, if you squint: a weakness for problems that look serial but hide an algebra. A scan that is secretly a monoid. A predicate that is secretly a truth table. A curve that is secretly a Gray code.
What you will find
Short posts about such things, each with code and, where it helps, a demo that runs right in the page. Rust, C, occasional trace amounts of functional programming and good database design (usually by accident).
Measurements will always come with the method, because designing it is sometimes more interesting than the speedup itself. Some posts will admit that an idea turned out slower. Those are the ones you learn the most from, and let's be honest, they are not exactly a thrilling read for most normal people.
Posting schedule: yes.
Tech stack
Zola renders Markdown, Pagefind builds a search index that runs entirely in
your browser, and each demo is a small Rust crate built with wasm-bindgen.
One Nix derivation turns all of it into a directory, and a deploy is a new
directory plus a flipped pointer.
It is served by Ferron, a web server written in Rust, from a small container at vpsFree. In front of it sits a router I wrote over this weekend: it reads the TLS ClientHello, looks at the server name and forwards the connection without decrypting anything. About four hundred lines, plus two hundred and fifty lines of tests, which took most of the time.
Below is roughly the first thing your browser sent to get this page, built in Rust and checked against the router's own parser, compiled to WebAssembly. Type another name, split the hello across more records, or press send and watch the bytes arrive the way TCP delivers them. The router never decrypts anything; it follows a few lengths, skips everything else, and only answers once the whole message is in.
What broke on the way
The ordering in the first paragraph has a price, and it is only fair to list it.
The certificate that renewed itself into the void. The domain has two DNS views: Cloudflare answers the public internet, and a resolver of my own answers inside a private network, with records nobody outside should see. Let's Encrypt checks ownership through a TXT record that only Cloudflare holds. The ACME client then waited for that record to propagate by asking the system resolver, which was my own one, which is authoritative for the domain and has never heard of the record. Renewal became a lottery, and on 21 September the lottery lost. The fix is one line telling it to ask 1.1.1.1. Split-horizon DNS is a fine idea right until something needs to see both horizons.
The resolver. The same box runs Hickory as a recursive resolver, validating
DNSSEC from the root down. Version 0.26.3 had three bugs that all showed up in
one evening: a validation loop on unsigned delegations, answers with the
address before the CNAME that leads to it, and a validator that shuffled the
answer again through a HashSet even after the second bug was patched. glibc
reads the chain in order and gives up, so about a quarter of lookups for
cache.nixos.org ended in "Could not resolve host". I spent half a day
patching 0.26 before checking that main had already fixed all three. It now
runs a pinned commit from main, which is not a sentence I expected to write
about a DNS server.
The ghost on port 443. Before the web server, tailscale serve exposed a
dashboard. I deleted the systemd unit that set it up, and the web server
refused to start: address already in use. The serve config lives in
tailscaled's own state, not in the unit, and outlives it. tailscale serve reset. Declarative configuration, meet the one imperative command that
remembers.
The router I almost misconfigured. The plan was simple: the router reads
SNI, sends one name to another service and everything else to the existing web
server. But that web server picks a virtual host by the HTTP Host header,
not by SNI. A client could say "public site" in the handshake and "internal
dashboard" in the request, and get the dashboard from the internet. Domain
fronting, self-hosted. The public site therefore gets its own web server
instance that knows only public hosts.
Each of these ended as a one-line fix and a comment three times longer than the fix. That ratio is probably the most honest metric on this site.
Feedback
If something here is wrong, slow, or already in a 1972 memo, I want to know. GitHub: mightsleep, email: acannix@proton.me.