telltale-net Network edge
Listeners: UDP worker threads, TCP, DNS over TLS and HTTPS, PROXY protocol v2.
One UDP socket per worker thread and listen address (SO_REUSEPORT), so cores never contend for a socket. TCP, DoT and DoH (HTTP/2) run as tokio tasks and call the same synchronous handler, so every transport behaves the same. Certificates reload without a restart; DoT SNI and the DoH path can carry a client ID. This is the only crate allowed to use unsafe (socket options and syscalls), each use with a SAFETY note.
- Main types
UdpListener TcpServer DohServer QueryHandler CertStore ClientId- Uses
telltale-proto- Used by
telltale, telltale-filter- Libraries
bytes, h3, h3-quinn, http-body-util, hyper, hyper-util, libc, libmimalloc-sys, quinn, rustls, rustls-pki-types, socket2, tokio, tokio-rustls, tracing, webpki- Code
- crates/telltale-net/src: 3,509 lines of Rust in 12 files
ADR-015 ADR-023 ADR-039 DNS-001 DNS-002
telltale-proto Data plane: answering a query
Zero-copy DNS wire parser and writer for the hot path.
Reads the header, question and EDNS straight from the packet buffer without allocating, fingerprints the name (xxh3) for the cache and filter, and writes answers in place: blocked answers, error answers with extended DNS errors, and TTL patches. Anything it can't parse becomes FORMERR or a drop, never a panic.
- Main types
Query Header Edns ResponseBuilder Writer NameBuf- Budget
- Reading a question and fingerprinting it: about 53 ns.
- Uses
- no other TelltaleDNS crate
- Used by
telltale, telltale-cache, telltale-filter, telltale-net, telltale-policy, telltale-recursor, telltale-upstream- Libraries
thiserror, xxhash-rust- Code
- crates/telltale-proto/src: 1,858 lines of Rust in 9 files
ADR-002 DNS-019
telltale-policy Data plane: answering a query
Who is asking, which groups they're in, and the early checks.
Identifies the client by address, MAC (from EDNS or the neighbour table), or client ID; resolves its groups (devices and network groups); applies allowed networks, the per-client token-bucket rate limit, pauses, special-use names, and answers local names. The tables are read-mostly behind ArcSwap, so lookups never take a lock.
- Main types
ClientTable Identity RateLimiter LocalData Special Pause- Uses
telltale-config, telltale-proto- Used by
telltale- Libraries
arc-swap, parking_lot, xxhash-rust- Code
- crates/telltale-policy/src: 2,851 lines of Rust in 8 files
ADR-014 ADR-021 ADR-050 FLT-005 FLT-006 DNS-010 DNS-014
telltale-filter Data plane: answering a query
Blocklists: fetch, parse, compile into a snapshot, and match.
Downloads lists with ETag and If-Modified-Since, parses hosts files, AdBlock syntax and Pi-hole regexes, and compiles everything off the DNS path into one compact snapshot: FSTs of names plus a regex DFA, with a hash index for query time. A new snapshot replaces the old one atomically. Every decision keeps its list and line, which is what 'Why?' and explain show.
- Main types
Fetcher Snapshot Decision Explained CompileReport ListMeta- Budget
- About 9 bytes per blocked name; a lookup takes under a microsecond.
- Uses
telltale-config, telltale-net, telltale-proto- Used by
telltale- Libraries
blake3, bytes, fst, http, http-body-util, hyper, hyper-util, idna, rand, regex-automata, regex-syntax, rustls, serde, serde_json, thiserror, tokio, tokio-rustls, tracing, webpki-roots, xxhash-rust, zstd- Code
- crates/telltale-filter/src: 8,159 lines of Rust in 19 files
ADR-003 ADR-016 ADR-017 ADR-018 ADR-020 ADR-022 ADR-024 ADR-025 FLT-003 FLT-013
telltale-cache Data plane: answering a query
Sharded S3-FIFO cache of finished wire responses.
Keeps each upstream reply as bytes plus the offsets of its TTLs, so a hit is a copy and a few small writes (the client's ID, case, and the aged TTLs). Negative answers and SERVFAIL are cached too. Concurrent misses for one name share one upstream request (singleflight); popular names are prefetched before they expire, expired answers can be served while upstreams are down, and the cache can be saved across restarts.
- Main types
Cache CacheKey S3Fifo Lookup Singleflight- Budget
- Copy and patch a cached answer: about 5 ns; a full cache hit end to end: about 153 ns.
- Uses
telltale-proto- Used by
telltale- Libraries
parking_lot, tokio- Code
- crates/telltale-cache/src: 1,855 lines of Rust in 5 files
ADR-002 DNS-006
telltale-upstream Data plane: answering a query
Upstream servers: transports, groups, strategies, hedging, breakers, DNSSEC.
Plain DNS, DoT and DoH upstreams with connection pools and bootstrap addresses; groups with failover, round-robin, weighted, fastest, or parallel strategies; routes that send a domain (optionally only for some groups) to a chosen server. A slow server is hedged after about 3x its usual time and a failing one is benched by a circuit breaker. DNSSEC validation uses hickory's validator over the same upstream groups.
- Main types
Router Group Strategy Breaker Health Endpoint- Uses
telltale-config, telltale-proto, telltale-recursor- Used by
telltale- Libraries
bytes, crypto_box, ed25519-dalek, futures-util, h2, h3, h3-quinn, hickory-net, http, parking_lot, quinn, rand, ring, rustls, serde, thiserror, tokio, tokio-rustls, toml, tracing, webpki-roots- Code
- crates/telltale-upstream/src: 7,795 lines of Rust in 18 files
ADR-013 ADR-060 UPS-007 DNS-011
telltale-recursor Data plane: answering a query
Reserved for full recursive resolution; empty today.
A placeholder for iterative resolution from the root (planned after 1.0). DNSSEC validation, which the plan once put here, lives in telltale-upstream instead (ADR-060).
- Uses
telltale-proto- Used by
telltale-upstream- Libraries
parking_lot, rand, thiserror, tokio, tracing- Code
- crates/telltale-recursor/src: 1,372 lines of Rust in 4 files
ADR-060
telltale-telemetry Telemetry and storage
QueryEvents, lock-free rings, the aggregator, rollups, and Prometheus.
Every answer leaves a fixed-size QueryEvent in its worker's single-producer ring; the hot path never waits on telemetry, and a full ring drops and counts. One aggregator thread turns events into counters, top-K lists, HDR latency histograms, per-device baselines for anomaly detection, the live tail, and the query log.
- Main types
QueryEvent Aggregator Hub Engine Finding PromWriter- Uses
- no other TelltaleDNS crate
- Used by
telltale, telltale-api, telltale-store- Libraries
blake3, hdrhistogram, rtrb, serde- Code
- crates/telltale-telemetry/src: 7,231 lines of Rust in 15 files
ADR-006 ADR-019 ADR-026 ADR-031 ADR-043 OBS-001 OBS-002 OBS-004 OBS-005 OBS-013
telltale-store Telemetry and storage
The columnar query-log store and SQLite state.
The query log is one file per hour: 19 columns in zstd-compressed blocks with a name dictionary and a per-hour name filter, so a search skips hours and columns it doesn't need. SQLite (WAL) holds users, tokens, the hash-chained audit log, rollups, and devices and names made in the UI.
- Main types
Segment Reader Builder NameFilter Rollups AuditEntry- Budget
- About 14 bytes per logged query.
- Uses
telltale-telemetry- Used by
telltale, telltale-api- Libraries
blake3, memchr, regex-automata, rusqlite, serde, thiserror, xxhash-rust, zstd- Code
- crates/telltale-store/src: 6,800 lines of Rust in 14 files
ADR-006 ADR-027 ADR-033 ADR-040 OBS-003
telltale-api Control plane
The REST API, sign-in, OpenAPI, live tail, MCP, and the embedded UI.
axum on its own listener (8053 by default). Browser sessions with CSRF tokens, scoped API and agent tokens, opt-in HTTP Basic for scrapers, and OIDC; three roles. The OpenAPI document is generated from the code (utoipa). Server-Sent Events stream the live tail, and POST /mcp serves read-only MCP tools that call the same routes with the caller's rights. The Svelte UI is built into the binary.
- Main types
Auth AgentGrant Backend ApiDoc Mcp- Uses
telltale-store, telltale-telemetry- Used by
telltale- Libraries
argon2, axum, base64, blake3, futures-util, openidconnect, rand, rust-embed, serde, serde_json, tokio, totp-rs, tower, tracing, utoipa- Code
- crates/telltale-api/src: 28,950 lines of Rust in 36 files
ADR-028 ADR-029 ADR-030 ADR-032 ADR-034 ADR-064 ADR-065 API-003 API-005 AGT-001 AGT-006
telltale-cluster Control plane
Membership, PKI, replication, failover, and federation over mTLS.
Every node has a certificate from the cluster CA; nodes talk over one HTTP/2 mTLS channel carrying protobuf frames (hello, heartbeats with RTT and config version, manifests, key shares, votes). The primary publishes signed manifests of content-addressed blobs; replicas fetch only what changed and keep answering from their last copy. Failover is manual or elected with fencing epochs; the CA can be rotated without downtime.
- Main types
Cluster Identity ClusterManifest BlobStore Elector Heartbeat- Uses
- no other TelltaleDNS crate
- Used by
telltale- Libraries
blake3, bytes, http-body-util, hyper, hyper-util, prost, rand, rcgen, ring, rustix, rustls, rustls-pki-types, serde, serde_json, thiserror, time, tokio, tokio-rustls, tracing, x509-parser- Code
- crates/telltale-cluster/src: 7,950 lines of Rust in 13 files
ADR-005 ADR-044 ADR-047 ADR-051 ADR-056 ADR-057 ADR-059 ADR-066 CLU-001 CLU-003 CLU-004 CLU-005 CLU-010
telltale-config Control plane
The TOML schema, validation, defaults, and shared vs node-local sections.
One serde schema for every setting, with errors that point at the exact key. It also prints the JSON Schema that the configuration reference on this site is built from, and decides which sections are shared across a cluster and which stay on each node.
- Main types
Config ConfigError ClusterConfig FilterConfig GroupConfig- Uses
- no other TelltaleDNS crate
- Used by
telltale, telltale-filter, telltale-policy, telltale-upstream- Libraries
jiff, schemars, serde, serde_json, serde_path_to_error, thiserror, toml- Code
- crates/telltale-config/src: 6,191 lines of Rust in 9 files
ADR-047 ADR-052 CLU-006 CLU-010
telltale-git Control plane
Reads one file at a ref from a Git server (smart-HTTP v2), no Git binary.
A small client for the Git smart-HTTP protocol v2: it asks for one ref, fetches only the objects for one file, inflates them, and can check commit signatures against allowed signers. This is how the cluster's configuration can come from a Git repository.
- Main types
Request Fetched Commit AllowedSigners- Uses
- no other TelltaleDNS crate
- Used by
telltale- Libraries
base64, miniz_oxide, ring- Code
- crates/telltale-git/src: 942 lines of Rust in 5 files
ADR-049
telltale The binary
The binary: wires every crate together, plus the CLI.
Owns the query pipeline that calls the crates above in order, the server roles, replication and the Git source, query-log shipping, the importers (Pi-hole, Technitium), backups, self-update and the update check, the MCP stdio bridge, and every command (run, explain, lists, auth, cluster, import, backup, mcp, self-update).
- Main types
Pipeline- Uses
telltale-api, telltale-cache, telltale-cluster, telltale-config, telltale-filter, telltale-git, telltale-net, telltale-policy, telltale-proto, telltale-store, telltale-telemetry, telltale-upstream- Used by
- nothing (it's the top)
- Libraries
arc-swap, axum, base64, blake3, bytes, clap, dhat, http, hyper, hyper-util, mimalloc, minisign-verify, miniz_oxide, rand, rcgen, ring, rusqlite, rustls, serde, serde_json, socket2, tokio, tokio-rustls, toml, tracing, tracing-subscriber, webpki-roots, zstd- Code
- crates/telltale/src: 61,017 lines of Rust in 78 files
ADR-001 ADR-038 ADR-046 ADR-061 ADR-062 ADR-063 OBS-001