COSC 4377 - Introduction to Computer Networks

Spring 2012

MW 1:00-2:30pm at PGH347

InstructorOmprakash Gnawali

Homework 12 : HTTP over DNS

Due: midnight April 30, 2012
Hard deadline, no extensions or late days

In this assignment, we will learn how to tunnel HTTP over DNS.

The Idea

As shown in the picture above, we want to be able to exchange HTTP message. But one of the links above only allows DNS traffic. How can we still enable HTTP protocol between the browser and the web server?

The idea is to use encapsulate HTTP messages within DNS messages on the link that only allows DNS. The Proxy server can package the HTTP message into a DNS message and send it to the custom DNS server. The custom DNS server receives the DNS message and extracts the HTTP message from it, then fectches the page using HTTP, and sends it back to the proxy by encoding the HTTP message within a DNS message. Finally, the proxy receives the DNS message, decodes the HTTP message, and sends it to the browser. This encoding and decoding is transparent to the browser, i.e., the browser does not know if the connection between the browser and the webserver is a straight HTTP connection (like in our webserver assignment) or it is going through this encoding and decoding.

Required parts

You are welcome to implement the protocol just like what we show in the diagram but we are requiring small pieces of the whole system but still learn about how to run HTTP over DNS. We are requiring these three functionalities:
  1. A DNS client being able to send a URL to the custom DNS server. This is a major part of an HTTP request.
  2. The DNS server being able to fetch a webpage given a URL.
  3. DNS server being able to send a webpage to a custom DNS client. The key is to make sure the protocol is still DNS.

Implementation Guide

The only way for a DNS client to send a message to a DNS server is a DNS query. Think of a way by which we can send a URL to the custom DNS server as a DNS lookup. You are required to use dig as the DNS client for this part. On the client side, we ask that you create a short script (Perl, Python, or shell script) or a C file with the name dnshttpfetch (or dnshttpfetch.c). Your script or C program should execute the standard dig binary on bayou. If you decide to use a C program to execute dig and parse the output from dig, the binary dnshttpfetch should be created using the Makefile in your folder, i.e., when one types make in the folder it should create two binaries: dnshttpfetch and dnsserver.

Once the DNS server knows the URL that the client is interested in fetching, it can use HTTP to connect to the server and download the page. You should be able to reuse your code from HTTP client homework for this part.

The only way for a DNS server to a send a message to a DNS client is a DNS reply. Think of a way by which we can have our custom DNS server send a webpage as a valid DNS reply. It is helpful to think about different types of data a server might send to a client in a reply.

Your DNS queries and replies must be compliant with RFC 1035. Otherwise dig will complain.

Testing

We will execute your DNS server as:

./dnsserver -p port

For example:

./dnsserver -p 10001

Here we execute the DNS server on port 10001.

We will launch dnshttpfetch on bayou as:


./dnshttpfetch port URL

Example:

./dnshttpfetch 10001 http://www2.cs.uh.edu/~gnawali/courses/cosc4377-s12/hw12/hello1

In the example above, we are telling dnshttpfetch that our custom DNS server is running on port 10001 and we would like to fetch the given URL. The dnshttpfetch script should execute the dig command to send a request, and parse the reply received by dig. It should save three files:
  1. file1.txt - the command line used to execute dig
  2. file2.txt - the output of the dig command
  3. file3.txt - the content of the html file downloaded

The dnshttpfetch should print to stdout the arguments that it is passing to dig when it executes dig. Example:


Executing dig with these arguments:

@bayou.cs.uh.edu -p 10005 myname.edu

The dnsserver should print to stdout the request it received from the client and the content of the file after fetching from the web. Example:

Received request for URL:

http://myname.edu

Content of http://myname.edu is:

hello world.

It is sufficient if your system works with small files, such as the ones pointed to by these URLs:

  1. http://www2.cs.uh.edu/~gnawali/courses/cosc4377-s12/hw12/hello1
  2. http://www2.cs.uh.edu/~gnawali/courses/cosc4377-s12/hw12/hello2
Because we require that your DNS server is standard compliant, it should still be able to answer the standard address query to an unmodified DNS client, just like in the previous homework.

Questions

  1. How did you decide to send a URL to a DNS server?
  2. How does your DNS server send a response back to the client?
  3. If the webpage does not fit in a single DNS packet, how would you redesign your system so you can fetch those larger files?

Submission

Please include a file answers.pdf with answers to the three questions. Please include the source(s) and Makefile in a folder with the name: uhid_hw12, where uhid is the prefix of your .uh.edu email address. Then, zip the directory and upload the zip file using Blackboard. When we unzip your file and type "make" within that folder, it should create an executable called dnsserver. When we type "dnshttpfetch" from inside that folder, the script should execute without any external dependency. Your program must compile and execute on bayou.