DNS + network-journey visualizer
A self-contained, single-file visualizer of the full network journey a packet
takes to fetch https://www.example.com/ — not just the DNS lookup, but the
TCP three-way handshake, the TLS 1.3 handshake, the HTTP request/response,
and the WebSocket upgrade variant. The intermediate infrastructure is shown
on screen as named nodes: home router, Polish ISP edge (Orange AS5617), PLIX
IXP, Cloudflare 1.1.1.1 PoP, DE-CIX Frankfurt backbone, a submarine cable,
and the four target servers (Root, TLD, Authoritative, Web).
The DNS engine walks a multi-stage FSM —
app_call → stub_send → resolver_recv → cache_miss
→ query_root → root_referral
→ query_tld → tld_referral
→ query_auth → auth_answer
→ cache_store → stub_reply → app_reply
→ tcp_syn → tcp_synack → tcp_ack
→ tls_client_hello → tls_server_hello → tls_finished
→ http_request → http_response → tcp_close
→ done
— building real RFC-1035 DNS messages (header bits QR RD RA AA RCODE,
length-prefixed QNAME, all RR sections, EDNS0 OPT pseudo-RR per RFC 6891)
plus synthetic but realistic TCP/TLS/HTTP/WS frames on each post-DNS hop.
Three views: Network (11-node topology with animated packets), Packet (full DNS wire-format breakdown of the most recent message — header bits, question, RR sections, hex dump), Cache (every NS, glue, and answer record the resolver has memorised, with TTL bars that tick down each cycle).
Preset transactions
The Application node (top-left) hosts a live query queue and six preset buttons. Click one to enqueue a complete transaction; click multiple to chain them and watch the cache fill up.
| Preset | What it walks through |
|---|---|
| 🔒 HTTPS | DNS for www.example.com → TCP SYN/SYN-ACK/ACK → TLS 1.3 handshake → GET / over HTTP/2 → 200 OK → TCP FIN |
| 🌐 HTTP | DNS for www.iana.org → TCP handshake → plain GET / over HTTP/1.1 → FIN |
| ⚡ WSS | DNS for echo.websocket.org → TCP → TLS → HTTP Upgrade: websocket → 101 Switching Protocols → WS frame |
| ⊙ Pure IP | No DNS at all — straight TCP to a hard-coded IP, demonstrating the bypass path |
| 🌊 Submarine | DNS for www.qantas.com.au — forces a real cross-continent route via the .au TLD and Southern Cross submarine cable |
| ✗ NXDOMAIN | Queries an unknown TLD, walks root → NXDOMAIN response → propagates to the stub |
You can also type any custom domain into the input below the presets and press Enter. The custom query is enqueued behind whatever’s currently running.
The queue and cache each have a clear button so you can reset state without
restarting the whole simulator.
Controls
| Key / mouse | Action |
|---|---|
space | Run / pause |
s | Step one stage |
shift+s | Step ×10 |
r | Reset (reloads the default queue + clears cache) |
v | Cycle Network → Packet → Cache |
e | Focus the query input |
| Mouse wheel on canvas | Zoom in / out (50%–400%, anchored on cursor) |
| Drag on canvas | Pan |
z | Reset zoom + pan to 100% |
clear (queue) | Empty the pending queue |
clear cache | Wipe the resolver cache so the next query iterates from the root again |
What’s “precise” about it
-
Real endpoints. Root is
a.root-servers.net 198.41.0.4(the IP has been the same since the firstroot.cachefile). The.comTLD isa.gtld-servers.net 192.5.6.30.example.comis delegated toa.iana-servers.net 199.43.135.53/b.iana-servers.net 199.43.133.53, and the answer forwww.example.comis93.184.216.34— exactly what a livedigwould return. -
Real protocol bits. The header is encoded byte-for-byte: 16-bit
ID, the 16-bit flags word (QR Opcode AA TC RD RA Z RCODE), and the four count fields. The question section uses real length-prefixed labels. Every modern query carries an EDNS0OPTpseudo-RR in the additional section (advertising a 4096-byte UDP buffer). -
Real referral chain. The root’s response carries
com. NS a.gtld-servers.net.in the authority section and a192.5.6.30glue record in additional — the actual format roots use to delegate without recursing themselves. The TLD does the same forexample.com.. Only the authoritative reply hasAA=1. -
Real intermediate network. The packet path goes Application → home router (NAT) → ISP edge (AS5617 Orange Polska, BRAS) → PLIX IXP (AS9931) → Cloudflare PoP (AS13335) → DE-CIX Frankfurt (AS6695) → submarine cable. The cable name is chosen per query —
.au→ Southern Cross,.jp→ SEA-ME-WE-3,.br→ EllaLink, anything else → MAREA (US ↔ Spain). -
Real cache semantics. Delegations (NS + glue) have longer TTLs than answer records, so after the answer expires the resolver still skips straight to the authoritative on the next query. TTLs are compressed (60s for A, 180s for NS, 120s for MX) so cache aging is visible in seconds rather than days.
-
Real post-DNS handshake. TCP SYN with
seq=42, SYN-ACK withack=43, ACK withack=100→ ESTABLISHED. TLS 1.3 ClientHello announces ALPN / SNI; ServerHello carries the certificate; Finished switches to encrypted records. HTTP request includes a realHostheader. WSS demo upgrades viaSec-WebSocket-Keyand the101 Switching Protocolsresponse.
How it works
The simulator is a single HTML file with embedded CSS and JavaScript — no
build, no server, no toolchain. The resolver state machine emits a snapshot
each cycle (current stage, the in-flight packet, the cache, the
transaction’s post-DNS sequence); the visualizer subscribes directly and
draws to a canvas. The Application node is an HTML overlay positioned over
the canvas at the App box’s coordinates and tracked via a CSS transform
so it follows zoom and pan.