DNS + network-journey visualizer

· updated

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).

Open fullscreen ↗

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.

PresetWhat it walks through
🔒 HTTPSDNS for www.example.com → TCP SYN/SYN-ACK/ACK → TLS 1.3 handshake → GET / over HTTP/2 → 200 OK → TCP FIN
🌐 HTTPDNS for www.iana.org → TCP handshake → plain GET / over HTTP/1.1 → FIN
WSSDNS for echo.websocket.org → TCP → TLS → HTTP Upgrade: websocket101 Switching Protocols → WS frame
Pure IPNo DNS at all — straight TCP to a hard-coded IP, demonstrating the bypass path
🌊 SubmarineDNS for www.qantas.com.au — forces a real cross-continent route via the .au TLD and Southern Cross submarine cable
NXDOMAINQueries 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 / mouseAction
spaceRun / pause
sStep one stage
shift+sStep ×10
rReset (reloads the default queue + clears cache)
vCycle Network → Packet → Cache
eFocus the query input
Mouse wheel on canvasZoom in / out (50%–400%, anchored on cursor)
Drag on canvasPan
zReset zoom + pan to 100%
clear (queue)Empty the pending queue
clear cacheWipe the resolver cache so the next query iterates from the root again

What’s “precise” about it

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.

← networking