Skip to content

mohosy/dns-resolver-from-scratch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dns-resolver-from-scratch

Python License Dependencies

An iterative DNS resolver that walks the delegation chain starting at the root servers, builds DNS packets by hand, and parses responses without using socket.getaddrinfo, dnspython, or libc resolver hooks. Built to showcase low-level networking, bit-level packet work, and careful data-structure choices that FAANG interviewers love to see.

Why This Is Cool

  • Fully manual DNS wire-format encoder/decoder (RFC 1035) including compression pointers.
  • Real iterative resolution: follows NS referrals from roots → TLDs → authoritative servers.
  • TTL-aware in-memory cache to avoid redundant queries.
  • Zero dependencies; everything is standard library for portability and inspection.

Quickstart

git clone https://github.com/mohosy/dns-resolver-from-scratch.git
cd dns-resolver-from-scratch
PYTHONPATH=. python3 -m src.cli example.com --trace

Example trace (recorded Jan 24, 2026):

[query] example.com A @ 198.41.0.4
[query] example.com A @ 192.41.162.30
[query] example.com A @ 108.162.192.162
[answer] ['example.com 300s A 104.18.27.120', 'example.com 300s A 104.18.26.120'] (ttl=300)
---
example.com 300s A 104.18.27.120
example.com 300s A 104.18.26.120

Architecture

  • src/message.py — DNS header/question/RR dataclasses plus wire-format encoding & decoding (handles name compression, multiple record types, and TTL parsing).
  • src/resolver.py — Iterative resolver that walks delegations, retries on timeouts, resolves glue when missing, and exposes a simple resolve() API.
  • src/cache.py — TTL-aware hash map (dictionary) to memoize recent answers; chosen because O(1) lookups map perfectly to DNS query keys.
  • src/servers.py — Static root server list for deterministic bootstrapping.
  • src/cli.py — Minimal CLI with trace option for debugging the delegation path.

Data structure callouts:

  • Hash map cache: O(1) keyed by (name, type) with TTL eviction. DNS traffic is bursty; constant-time lookups keep latency down and avoid over-querying upstreams.
  • Lists for traversal order: We prepend newly discovered NS glue IPs to explore depth-first along a delegation chain, mirroring how resolvers chase referrals quickly.

Usage

# Basic A record
PYTHONPATH=. python3 -m src.cli example.com

# AAAA record with trace
PYTHONPATH=. python3 -m src.cli cloudflare.com --type AAAA --trace

Testing

PYTHONPATH=. python3 -m unittest discover -s tests -p 'test*.py'

Notes / Future Ideas

  • Add EDNS0 + larger UDP payload support and TCP fallback for truncated responses.
  • Expand record parsing (MX, TXT) and negative caching (NXDOMAIN with SOA MINIMUM).
  • Optional JSON output for automation.

Author

Mo Shirmohammadi — GitHub · LinkedIn

About

Iterative DNS resolver from root servers using raw UDP sockets. Zero dependencies.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages