It was a friday night when I saw that someone had commented on an issue saying that the site was down. I created udpquiz back in 2022, and it seemed like a good time to give it a fresh coat of paint.
For the update, I thought it'd be pretty interesting if it were only available over udp (fits the theme, amirite?). The solution to this is to serve the site over HTTP/3 that uses the QUIC transport layer (udp-only).
Serving the site over only HTTP/3 was as simple as adding
protocols h3
to the Caddyfile.
That's not enough though - the browser needs some way to figure out that the server actually offers HTTP/3 support. This is accomplished in two ways.
Alt-Svc header when a client
requests the page over HTTP/1.1 or HTTP/2. Since we aren't offering
the page via these protocols, this isn't an option for us.
no-default-alpn alpn="h3" ipv4hint="SERVER_IP". We
specify no-default-alpn to signal that the server doesn't offer any
default protocol (HTTP/1.1).
However, with just the h3 protocol enabled, caddy struggles with automatic certificate provisioning. I didn't spend much time debugging this, instead opting to use dns-01 challenge.
The last step is to modify the eBPF filter to pass quic packets to caddy unmodified. QUIC v1 has a fixed bit 6 in every packet header we could check, but RFC 9287 introduced later allows greasing this bit to be any value. In the end, I decided to simply pass any incoming udp packet on port 443 to caddy and add a note to the home page.
No, we're not done yet. Let's dive into browser support.
Additionally, it works on all platforms if you enable DNS over HTTPS in the firefox settings.
Originally, the site did not work on google chrome (all platforms). Having your site not working on the browser that most people use is not a good sign.
After digging for a bit, I found this in the chromium source code:
net/dns/dns_response_result_extractor.cc // Ignore all records if they all mark "no-default-alpn". Domains should // always provide at least one endpoint allowing default ALPN to ensure a // reasonable expectation of connection success. // draft-ietf-dnsop-svcb-https-12#section-7.1.2 if (!default_alpn_found) { metadatas.clear(); }
and well, yes, the rfc mentioned in the comment does say:
To ensure consistency of behavior, clients MAY reject the entire SVCB RRset and fall back to basic connection establishment if all of the compatible RRs indicate "no-default-alpn", even if connection could have succeeded using a non-default ALPN protocol.
C'mon, it says MAY. @Chromium devs reading this, please fix this.
Anyway, I had a big brain moment and simply added a second (lower priority) HTTPS record, this time without the no-default-alpn part. It's not exactly correct since we don't offer HTTP/1.1, but it works.
With that, the compatibility matrix is basically the same as Firefox. And if you turn on Secure DNS in the settings and choose a non-OS resolver, it works on all platforms.
The site randomly works on Safari, no clue what's happening, feels non-deterministic. Needs to be investigated.
Anyway, thanks for reading!