# ssl_tokens_cache Rust crate that persists the in-memory TLS session resumption token cache (`SSLTokensCache`) to a single flat binary file in the Firefox profile directory (`ssl_tokens_cache.bin`), enabling 0-RTT on first connections after a browser restart. ## On-disk format ``` [Header — 5 bytes total] magic: 4 bytes "STCF" version: u8 (currently 1) [Body] zlib-compressed bincode-serialized Vec (Adler-32 integrity check embedded in the zlib stream) ``` Each `PersistedRecord` contains: | Field | Type | Description | |---------------------|---------|-------------------------------------------| | `id` | u64 | Session-internal ID; re-assigned on load | | `key` | Vec\ | Peer ID string (host:port + OA suffix) | | `expiration_time` | i64 | PRTime (µs since epoch) | | `token` | Vec\ | Opaque NSS session resumption ticket | | `ev_status` | u8 | Extended-validation status | | `ct_status` | u16 | Certificate Transparency status | | `overridable_error` | u8 | Cert-error override category | Certificate chain data (`server_cert`, `succeeded_chain`, `handshake_certs`) is intentionally **not** persisted — a new TLS handshake will deliver fresh cert data, making the storage cost (~8–10 KB/record) not worthwhile. ## Eviction policy The in-memory cache is bounded by `network.ssl_tokens_cache_capacity`. When a new record would exceed this budget, the cache evicts the record with the **soonest expiration time** until the budget is met. This matches the semantics of session ticket expiry: tokens that will expire first are least useful, so they are discarded first. At most `network.ssl_tokens_cache_records_per_entry` tokens are kept per host; when the per-host limit is hit, the oldest-inserted record for that host is dropped to make room for the new one. Expired records are discarded lazily on `Get()`, not proactively, so the on-disk snapshot may contain tokens that have already expired. These are filtered out during loading. ## Typical sizes - Token: ~200 bytes - Key: ~30 bytes - Record total: ~250 bytes - Typical file size for a normal browsing session: 10–100 KB ## File lifecycle - Cache written: asynchronously on `application-background` (e.g. when the user switches away from Firefox on Android, before any OOM kill); on `idle-daily`; and via an `nsIAsyncShutdownBlocker` on `ProfileBeforeChange` (off the main thread). `SSLTokensCache::Shutdown()` (called by `nsIOService`) provides a synchronous fallback for test environments where the async shutdown service is unavailable. - Cache written atomically: data → `ssl_tokens_cache.tmp` → rename to `ssl_tokens_cache.bin`. - Cache deleted: when `SSLTokensCache::Clear()` is called (e.g. "Clear All History", site data clearing for a partition).