Decision records
ADR-0030: Kernel TLS for HTTPS/1.1 file bodies (opt-in)
- Status: Accepted (2026-10-06), opt-in
- Extends ADR-0027 (sendfile) to TLS connections.
Context
Most traffic is HTTPS. ADR-0027 sends large files with sendfile(2) only on plain TCP:
with rustls the data has to pass through user space to be encrypted. Linux kernel TLS
(tls module, 4.13+) can encrypt in the kernel, so sendfile/writev on the socket
carry plaintext and the kernel produces TLS records.
Decision
server.ktls: true(default false; needsmodprobe tls). At start scalwsd probes which cipher suites the kernel accepts (ktls::CompatibleCiphers; the probe briefly listens on an ephemeral port on all interfaces). If none, it logs a warning and serves TLS as before.- The rustls handshake runs as usual over
ktls::CorkStream, which lets the stream be drained exactly at a record boundary. When the client negotiatedhttp/1.1and a kernel-supported suite, the session keys are handed to the kernel (config_ktls_server; rustlsenable_secret_extraction). HTTP/2 connections and other suites stay on rustls. KtlsStreamreads (it handles TLS control messages); writes bypass it to theSendfileIounderneath, vectored, so hyper keeps queueing body buffers and the placeholder protocol of ADR-0027 works unchanged (KtlsStreamalone does not support vectored writes, which would make hyper copy — and thus zero — placeholders). Shutdown goes throughKtlsStream(close_notify).- A failure while switching to kTLS closes that connection (the TLS stream is consumed by the switch); the start-up probe makes this rare.
Consequences
- Encryption cost moves into the kernel and is accounted to the process as system time.
- TLS 1.3 key updates are handled by the kernel only on recent kernels;
ktlsrefuses them otherwise, which ends the connection (clients reconnect).