Repository navigation
CWIST v3.9
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:
-
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_QUICKACKduring the TLS handshake. A client withoutTCP_NODELAYthen holds its first request until the server's delayed ACK, about 40 ms later. - CWIST now re-arms
TCP_QUICKACKaround 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.
- The ~640 handshakes/s plateau was a Nagle/delayed-ACK stall, not a crypto or shard limit. The kernel drops
-
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, andcwist_tls_ciphers_{aes128_gcm,aes256_gcm,chacha20,other}_total. Covered bytest_https_metrics. - The counters are per process. With prefork workers, each worker's
/metricsreports only its own connections.
- New counters:
-
HTTPS performance gates in CI (dbac164, 2a190f4, 73ffa4f, 0c9ccac)
Perf — HTTPS gatesmeasures 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.
-
WebRTC DataChannel (0026a48, 714acdf)
- New
cwist/net/webrtc.h: SDP offer/answer, ICE-lite, DTLS 1.2 (vendored BoringSSL), SCTP DataChannels via the newlib/usrsctpsubmodule, 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_offerandctx_freecan 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=0to leave it out.
- New
-
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.
- New public API:
-
Fixes
- Rust:
App::use_builtin_middlewareaccepts only CWIST's own middleware (8f4b1cb);rust-hellois built and served in CI (de8bc92). cwist_app_listen()restores the caller's SIGTERM/SIGINT handlers when it returns (fd94139).make install:cwist.pcnow listslibusrsctpwhen 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).
- Rust:
-
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 forsse.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.