DNS Resolver
DNS Resolver
This collaborative project is a toy DNS resolver written in C and based on Julia Evans’ Implement DNS in a Weekend Python guide.
Overview
The program features DNSQuery
, DNSHeader
, DNSQuestion
, and DNSRecord
structs that structure the various component parts of a DNS query and the parsed DNS response. At a high level, the program recursively resolves a given domain using the resolve()
function. Each iteration of resolve does the following:
- open a socket file descriptor using
socket()
- instantiate and populate a
DNSQuery
struct with details about the DNS request using constructor functionNewDNSQuery()
- send above
DNSQuery
struct bytes usingsendto()
- receive response with
recvfrom()
and store response bytes in a buffer - close socket file descriptor with `close()
- parse response into a
DNSPacket
struct comprising ofheader
,questions
,answers
,authorities
, andadditionals
members. With the exception of theheader
member (aDNSHeader
struct), the other components are linked lists ofDNSQuestion
andDNSRecord
structs.
Based on the response, resolve()
does one of three things:
- If the response packet’s
answers
member contains anDNSRecord
struct with a valid answer, we’re done! - Else if the response packet’s
additionals
member contains aDNSRecord
struct with a valid A record, send a new query for the original domain name to that nameserver IP. - Else if the response packet’s
authorities
member contains aDNSRecord
struct with a valid NS (nameserver) record, recursivelyresolve
that nameserver domain for its IP address and, once obtained, send a new query for the original domain name to that newly-obtained nameserver IP.
Sandbox and Side Projects
The sandbox/
directory contains a number of DNS-related and DNS-adjacent experients and toy projects designed to improve intuition about networking in general and C’s networking systems calls.