c0nrad's c0rner

Learning and learning

Mar 11, 2026 - 2 minute read - programming dns

DNS Stub Resolver

I realized I haven’t done much learning in a while ( https://dmarcdefender.io is my current project, but it’s just standard SaaS work). So I figured I might try to spend an hour or two each day learning something new.

Today’s project was building a super simple DNS resolver. The goal was just to resolve the A record for c0nrad.io into an IP address.

Result

https://gist.github.com/c0nrad/d464cbb70b1923b6f36723148926e350

> tsx stub-resolve.ts

Received 59 bytes from 8.8.8.8:53
<Buffer 05 39 81 80 00 01 00 02 00 00 00 00 06 63 30 6e 72 61 64 02 69 6f 00 00 01 00 01 c0 0c 00 01 00 01 00 00 00 3c 00 04 03 84 ba d3 c0 0c 00 01 00 01 00 ... 9 more bytes>
{
  id: 1337,
  flags: 33152,
  qdcount: 1,
  ancount: 2,
  nscount: 0,
  arcount: 0
}
{ name: 'c0nrad.io', qtype: 1, qclass: 1 }
{
  name: 'c0nrad.io',
  type: 1,
  class_: 1,
  ttl: 60,
  rdata: <Buffer 03 84 ba d3>,
  ipAddress: '3.132.186.211'
}
{
  name: 'c0nrad.io',
  type: 1,
  class_: 1,
  ttl: 60,
  rdata: <Buffer 03 17 f0 88>,
  ipAddress: '3.23.240.136'
}

Learnings / Refreshers

  • If you’re doing iterative resolution, each query will usually return either an answer or a referral.
  • A stub resolver is the simple client that asks a recursive resolver to fetch the query result.
  • The actual recursive lookup is often performed by your ISP or by a public resolver.
  • We could run a recursive resolver locally, but it’s usually more time-efficient to use your ISP’s resolver or hard-code 8.8.8.8 (Google) / 1.1.1.1 (Cloudflare).
  • The authoritative server contains the “zone file.”
  • The DNS Class field is pretty much unused.
    • Everything is “Internet”. Historically “Chaos” and “Hesiod”, but unused.
  • Cloudflare has one.one.one.one/help, which creates a custom DNS request on load to understand your DNS connection.
  • Buffer is Node.js’s binary data type; I used a Node.js Buffer, but I could instead use something like new DataView(new ArrayBuffer(12)).
  • To save space, resulting records don’t repeat the DNS name. They use “message compression” by pointing to existing DNS names in the response message.

Conclusion

Pretty neat. Maybe a future project will be to make it recursive.