Simple DNS

Tay KimTay Kim
3 min read

Last semester, I took a course on Data Communication and Networks. One of the assignments in this course was to explore how the Domain Name System (DNS) works. In this article, I’ll walk through the assignment and explain how it was structured.

Here is the link to the GitHub repo.

The assignment involved building and containerizing three separate servers:

  1. Authoritative Server (AS): Acts as the DNS server. It registers records and responds to DNS queries.

  2. Fibonacci Server (FS): A Flask backend server that responds to user requests. It’s called the Fibonacci Server because it returns Fibonacci numbers upon request.

  3. User Server (US): A Flask server responsible for client-side logic. It queries the AS to resolve hostnames and then sends HTTP requests to the FS to retrieve Fibonacci values.

Let’s take a closer look at each component.


Authoritative Server

The Authoritative Server (AS) accepts and handles two types of UDP requests.

First, it listens for registration requests. For example, if it receives a message like TYPE=A\nNAME=fibonacci.com\nVALUE=172.18.0.2\nTTL=10, it registers a new A record that maps the hostname fibonacci.com to the IP address 172.18.0.2. For simplicity, these records are saved in a local text file called records.txt.

The AS also handles DNS queries. When the User Server sends a request to resolve fibonacci.com, the AS looks up the record and returns the corresponding IP address, assuming it was registered beforehand.

Fibonacci Server

The Fibonacci Server (FS) is the backend server that handles user requests for Fibonacci numbers. For instance, if it receives a request like GET /fibonacci?number=5, it responds with the corresponding Fibonacci value: {"fibonacci": 3}.

For the sake of this assignment, the FS also exposes a PUT endpoint at /register that allows it to register its own DNS record with the AS. In a real-world scenario, publicly exposing an endpoint like /register would be a security concern. But here, it’s included to simplify testing and give us explicit control over when and how FS registers itself with the AS.

User Server

Last but not least, we have the User Server (US). The US starts by querying the AS to resolve the hostname fibonacci.com. Once it gets back the corresponding IP address, it sends an HTTP GET request to the FS to retrieve the desired Fibonacci number.

Like the FS, the US exposes a GET endpoint at /fibonacci. Hitting this endpoint kicks off the entire sequence described above, giving us full control over how the system behaves during testing.

Testing

To test the full system, follow these steps:

  1. Start all servers using Docker Compose.

  2. Register the FS with the AS by sending a PUT request to the FS's /register endpoint. This will trigger a DNS registration, and the AS will store an A record that maps the FS hostname to its IP address.

  3. Send a GET request to the US at /fibonacci. This triggers the US to:

    1. Query the AS to resolve the FS hostname.

    2. Use the resolved IP to send a request to the FS and return the Fibonacci result.


Conclusion

While the assignment has its limits, it’s a solid illustration of how DNS works in practice. More importantly, it gave me hands-on experience with concepts that are often abstracted — like DNS record registration, hostname resolution, and basic client-server communication.

Beyond the networking logic, I learned a lot from containerizing each server with Docker and connecting them via a shared network using docker-compose. This helped me understand how real-world distributed systems are structured and tested.

Thanks for reading! I'll be back when I'm done with my next side project. 🚀

0
Subscribe to my newsletter

Read articles from Tay Kim directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tay Kim
Tay Kim