rgoussu@goussu: ~/library/system-administration/exercises
~/library/system-administration/exercises cat build-a-dns-resolver.md

Build a DNS resolver

# Build a recursive DNS resolver from raw UDP datagrams — hand-packed packets, name compression, a walk from the root servers to an authoritative answer — then prove it on the wire with annotated captures.

Exercisesaved 2026-08-09source #networking#dns#udp#sockets#wireshark#exercise

Goal

Implement a DNS resolver from the wire format up — build the query bytes by hand, parse the reply including name compression, then walk the delegation chain from a root server to an authoritative answer — and finish by reading your own packets, plus a full HTTPS exchange, in Wireshark. The network stops being an abstraction the first time you watch your own datagram come back.

Subject: full brief & instructions

Practices

  • Networking fundamentals — UDP vs. TCP in practice, DNS resolution (recursive vs. authoritative), TTLs, and the on-the-wire tooling this exercise makes routine.
  • Linux system deep dive — sockets as file descriptors; the syscalls under your sendto/recvfrom.

Milestones

  1. A query on the wire. Hand-pack a DNS query — 12-byte header, QNAME label encoding, type, class — into bytes (network byte order), send it over a UDP socket to a public resolver, and hexdump the reply you get back.
  2. Parse the reply. Decode header, question echo, and answer records — including name compression (the 0xC0 pointer scheme), the part every toy parser gets wrong. Verify against dig on the same names.
  3. Walk from the root. Iterative resolution with recursion desired off: ask a root server, follow the referral (NS records + glue) to the TLD servers, then to the authoritative server, until you hold the answer. Resolve a real domain starting from 198.41.0.4 and print the journey.
  4. Real-world records. CNAME chains (follow them, loop-bounded), AAAA and TXT, and a TTL-respecting cache so repeat lookups skip the walk. dig remains the oracle throughout.
  5. See it on the wire. Capture your own resolver's full walk with tcpdump and annotate it in Wireshark; then capture one complete HTTPS request to a real site and annotate every phase — TCP handshake, TLS negotiation, HTTP exchange, teardown. The two annotated captures are the module's proof artifact.

Stretch goals

  • Honor the TC (truncation) bit: retry over TCP with the 2-byte length prefix.
  • EDNS0 (OPT pseudo-record) to raise the UDP payload size — and see when it matters.
  • Resolve the same name over DoH (DNS-over-HTTPS) and compare what the wire shows.

Related