Simple DNS Resolver in Rust
A basic DNS resolver that returns the IP Address of the URL provided.
I picked up this project from the Coding Challenge by John Crickett. I dived into the challenge thinking it would be easy, but as I completed this challenge, I did realise and understand what goes into making a DNS resolver.
So without further adieu.. Let’s get into it.
Hey Guys,
Please, leave a comment after you read this newsletter. It would help me get feedback on my writing so that it can be improved. Thanks.
What is a DNS?
If I had to describe DNS or Domain Name Server in a sentence, it would go something like this: “It’s like a phone book (if you remember those) but for the internet, if you provide the name of a website it gives you back the IP address of the website”.
The internet largely works on URLs. Why? Well, it is easier to remember them. So if we want to use Google we type in “www.google.com” and then we are directed to Google’s webpage (sounds simple !). However, the underlying working is a bit more complex, your browser asks the DNS server for the IP address of a specific URL. The DNS server resolves the URL into an IP address and provides it to the browser.
How to Program a Simple DNS Resolver?
Before we jump into coding let us understand how the DNS protocol works. For that let’s use our favorite packet sniffer. Yes, you guessed it right Wireshark.
Firstly, from the above image, we can see that the DNS query uses the UDP protocol. Second, we connect to address 8.8.8.8 and port 53 which is Google’s DNS. Thirdly, the DNS query has a certain structure, i.e. it has headers which have to be specified to get the answer from the DNS.
With all this in mind … let’s get to coding.
UDP Sockets
Since DNS uses UDP protocol, we must open UDP sockets in order to communicate with the DNS.
Building the Query
The most important part of this program is to build the query. You can get the structure of the DNS headers from RFC 1035 Section 4.1.1.
We generate a random transaction ID, which is used to match the response’s transaction ID. We set the recurring bit to 1 and the question bit to 1.
The rest will be 0.
The hostname (the URL for which we want the IP address) is set in the query buffer with the length of the hostname.
After building the query and sending a request to DNS. We must ensure that we read the returned response and extract the IP Address.
We first match the transaction ID and then using the offset extract the IP address.
TIP: Use a wireshark output to understand the answer structure.
Here is an example:
For the entire source code, please check my GitHub:-
If it’s too early to subscribe, please do share the post.
Awesome, please consider sharing here too: https://github.com/CodingChallegesFYI/SharedSolutions