Skip to content

CWIST v3.9

Choose a tag to compare

@gg582 gg582 released this 05 Oct 13:42
· 595 commits to main since this release

CWIST v3.9: TLS observability, HTTPS performance gates, and WebRTC DataChannel

v3.9 adds TLS observability and CI performance gates so HTTPS regressions show up before they ship, and adds WebRTC DataChannel support. It is also the first release cut on main since v3.7.2, so main now includes v3.8's changes too: Rust FFI Phase 2, supported opt-in full-GC, and the features promoted to supported (see the v3.8 notes). Long-running experimental dev work, such as the native WebTransport client and its lsquic pin, is still not included.

Major changes compared to v3.8:

  1. HTTPS handshake latency fix (#306, #307)

    • The ~640 handshakes/s plateau was a Nagle/delayed-ACK stall, not a crypto or shard limit. The kernel drops TCP_QUICKACK during the TLS handshake. A client without TCP_NODELAY then holds its first request until the server's delayed ACK, about 40 ms later.
    • CWIST now re-arms TCP_QUICKACK around the handshake (9eea519). Measured on a Ryzen 5600X: request RTT for such clients 43 ms → 0.08 ms; HTTPS connection churn ~680/s → ~1,650/s.
  2. TLS observability in /metrics (5fa7b13)

    • New counters: cwist_tls_handshakes_total, cwist_tls_handshakes_resumed_total, cwist_tls_connections_active, cwist_tls_handshakes_tls12_total, cwist_tls_handshakes_tls13_total, and cwist_tls_ciphers_{aes128_gcm,aes256_gcm,chacha20,other}_total. Covered by test_https_metrics.
    • The counters are per process. With prefork workers, each worker's /metrics reports only its own connections.
  3. HTTPS performance gates in CI (dbac164, 2a190f4, 73ffa4f, 0c9ccac)

    • Perf — HTTPS gates measures TLS RTT, connection churn, keep-alive throughput and 1 MiB transfer over HTTPS, with plaintext controls.
    • Gates use absolute backstops, HTTPS/HTTP ratios measured in the same run, and a comparison against earlier runs on the same runner CPU. History is kept in benchmarks/https_gates.json.
    • Checked against the real regression: with the #307 fix disabled, the RTT gate fails (0.08 → 43 ms) on any CPU.
  4. WebRTC DataChannel (0026a48, 714acdf)

    • New cwist/net/webrtc.h: SDP offer/answer, ICE-lite, DTLS 1.2 (vendored BoringSSL), SCTP DataChannels via the new lib/usrsctp submodule, and DCEP. DataChannel only, no media.
    • Runs on the cwist reactor:
      • cwist_webrtc_ctx_new() creates its own reactor and thread; cwist_webrtc_ctx_new_on() attaches to a reactor you already run.
      • Every callback runs on the reactor thread. send, close, handle_offer and ctx_free can be called from any thread.
      • Connections are reference counted (cwist_webrtc_conn_retain/release), and a close handler reports when one goes away.
      • Text and binary messages are told apart (cwist_webrtc_data_type), and empty messages are supported.
      • Messages are capped at 256 KiB, and at most 4 MiB can be queued per connection (cwist_webrtc_conn_buffered_amount).
    • Interop: verified against headless Chromium with make test_webrtc_browser. Text, a 200,000-byte binary message and an empty string all round-trip. The channel opens in about 8 ms.
    • Loopback numbers (make bench_webrtc): about 970k msg/s at 64 B, about 184 MB/s at 64 KiB, about 11 wakeups/s when idle.
    • example/webrtc/: an echo server with HTTP signaling, one ctx per HTTP worker process.
    • Compiled in by default. Build with CWIST_WEBRTC=0 to leave it out.
  5. Reactor one-shot timers (b08df73)

    • New public API: cwist_reactor_timer_init/arm/cancel/armed. Timers are kept in a min-heap per reactor and fire on its run thread.
    • The io_uring, epoll and kqueue waits are shortened to the next deadline, so a reactor with no armed timer wakes no more often than before.
    • cwist_reactor_stop() now writes the run flag atomically, since it is called from other threads.
  6. Fixes

    • Rust: App::use_builtin_middleware accepts only CWIST's own middleware (8f4b1cb); rust-hello is built and served in CI (de8bc92).
    • cwist_app_listen() restores the caller's SIGTERM/SIGINT handlers when it returns (fd94139).
    • make install: cwist.pc now lists libusrsctp when WebRTC is built, so programs using the WebRTC API link through pkg-config (41f7e9a).
    • Allocator use in the WebRTC module goes through cwist_alloc/cwist_free (5db07b2, bf545c6).
  7. Dependencies and docs

    • libttak pinned to v3.3.1 (4f2eae8).
    • Doxygen comments for every function in src/ that lacked one (bb4389c, 42062b2, 27b70b1). API reference page for sse.h (b2e269a, #271).
    • #294 closed: cwist_app_listen() does use the sharded handshake shepherds (measured), and v3.8's default of at least 4 shards (cap 16) needs no change.

Known limitations / deferred:

  • WebRTC:
    • ICE-lite only: no STUN/TURN servers, no trickle ICE, IPv4 host candidates only.
    • The peer certificate fingerprint is not yet checked against the SDP.
    • Ordered, reliable channels only, with no per-channel close.
    • Firefox has not been tested.
  • TLS counters are not yet summed across prefork workers.
  • WebTransport stays experimental until v4.1. The lsquic re-pin and the HTTP/3 connection-close fixes are still waiting on upstream lsquic.