Source code
Revision control
Copy as Markdown
Other Tools
# 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<PersistedRecord>
(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\<u8\> | Peer ID string (host:port + OA suffix) |
| `expiration_time` | i64 | PRTime (µs since epoch) |
| `token` | Vec\<u8\> | 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).