If a message is received that is found to be a response to a forwarded query, have the server print the message:
“Message is a response to our query id: ” and print the query ID number
If a question has been found in the cache, have the server print the message: “DNS record is already in cache, respond to client”
If the query has to be forwarded to the Google DNS, have the server print the message: “DNS record not found in cache, forwarding to Google DNS”
Microsoft Word - ProgrammingAssignment3 - DNS.docx Programming Assignment #3 IS 477/677 Due: April 4, 2019 1 Programming Assignment #3: DNS Introduction: Every request for a URL requires that URL to be converted into an IP address. URLs provide a human readable address for identifying hosts and resources on those hosts. Hosts themselves are uniquely identified by their IP address and DNS provides the conversion between URLs and IP addresses. In this assignment you will be creating and sending DNS requests to a DNS nameserver running on the same computer. The nameserver will be caching DNS records that it receives. If the desired hostname is not in the nameserver cache, the request will be forwarded to the Google nameservers. You will be using python dictionaries to implement this cache. The nameserver you build is just a skeleton and will not provide all the features of a DNS nameserver. Installation: Python 3 is installed on the lab computers. If you would like to work on this assignment on your own computer, you will need to install Python3. This assignment will assume that you are programming on a lab computer using Notepad++ and executing your code in the Command Prompt. We will be using the dnspython library to format our data into real DNS messages. This library is not installed by default. You will need to install it using the same method we used to install the flask and requests libraries in Assignment 2. Please see the Assignment 2 instructions for installing those packages if you are unsure how to install the dnspython library. Submission: Once you have completed all the required steps in this assignment, you must upload your assignment3_server_FirstLast.py file to Canvas for grading. Instructions: Download the assignment3_tester.py and assignment3_server_starter.py files from Canvas. You will be modifying the server file, so rename that file with your first and last name: assignment3_server_FirstLast.py Programming Assignment #3 IS 477/677 Due: April 4, 2019 2 You will need to run two python programs at the same time as part of this assignment. First, run the assignment3_server_FirstLast.py code in one Command Prompt (with no arguments): py assignment3_server_starter.py and then each time you want to test your server code, run the assignment3_tester.py code in another Command Prompt (with a single argument, containing the hostname we want to get the IP address for): py assignment3_tester.py www.google.com The tester program sends a UDP message to the server program containing a DNS query for the hostname provided as a command line argument (www.google.com in the example above). The tester code is fully functional and does not require you to make any modifications. It is STRONGLY recommended that you read through the tester code and work out what it does. You may need to duplicate some of the things it does as part of your solution to the server code. Running the server code in the Command Prompt on Windows may cause the Command Prompt to stop listening to keyboard inputs, such as CTRL+C, which is needed to terminate the server. To get around this, you can kill the server by typing the following into a different Command Prompt: taskkill /F /IM python.exe This will hunt down and kill any python processes running. CTRL+C should work fine on Unix/Mac to terminate the server. In this assignment you are required to enhance the server code so that it: 1) Forwards new DNS queries to the Google DNS server and send the response back to the original requester 2) Caches any DNS responses from the Google DNS in a python dictionary 3) Uses the cache to answer any DNS queries that have already been answered before 4) [IS 677 only] Keeps entries in the cache for 1/10th of the TTL and removes them from the cache after that time The DNS queries sent and received in this assignment will be encoded using the dnspython library. Look at how the original DNS query is sent from the tester to the server code for hints on how to use the dnslibrary library. You may need to extract some of the properties of the DNS messages you are sending/receiving. The list of available methods and variables associated with a DNS message can be found at: http://www.dnspython.org/docs/1.15.0/dns.message.Message-class.html Programming Assignment #3 IS 477/677 Due: April 4, 2019 3 For a full list of the features of the dnspython library, please see: http://www.dnspython.org/docs/1.16.0/ You may notice that the first link is to version 1.15 but the general link is to 1.16. For some reason, some of the methods and variables are hidden in the 1.16 version of the documentation. An important thing to remember when forwarding the DNS queries to the Google DNS is that the process_message() function is executed every time a message is received by the server code. So when the DNS query is first received from the tester code, process_message() is executed. After you forward this request to the Google DNS, the process_message() function finishes and the server code ends up back in the while inputs loop waiting for another message to be received. When the response is returned by the Google DNS, it will cause the process_message() to be executed again. It is your task to identify whether a message received by the server code is from the tester code or is a response from a forwarded query. I recommend using the pending_requests dictionary. Read the comments in the server code for more information about how it can be used. At any point, if you want to see what is contained in your DNS message, you can use the to_text() method to print it (http://www.dnspython.org/docs/1.16.0/dns.message.Message-class.html#to_text). The cache needs to store DNS records received from the Google DNS, so that subsequent queries for that hostname can be answered without forwarding the query to the Google DNS. Your implementation needs to have the server print out three messages, depending on what happens: • If a message is received that is found to be a response to a forwarded query, have the server print the message: “Message is a response to our query id: ” and print the query ID number • If a question has been found in the cache, have the server print the message: “DNS record is already in cache, respond to client” • If the query has to be forwarded to the Google DNS, have the server print the message: “DNS record not found in cache, forwarding to Google DNS” All messages must be sent via a UDP socket. Do not use the dnspython library to actually send messages. Use dnspython to create and manipulate DNS messages, but they should be sent manually through the UDP socket. Your code shouldn’t output any errors and you should include reasonable comments and variable names. Comments should describe what the sections of your code are doing so that someone can read through just the comments and see what your code is supposed to do without understanding any python. Programming Assignment #3 IS 477/677 Due: April 4, 2019 4 [IS 677 only] Entries must be expired from the cache after the cache TTL has expired. We will use a value for the cache TTL of 1/10th of the TTL value contained in the record. For example, if the Google DNS sends us a record with a TTL of 300 seconds, we should expire it from our cache after 30 seconds have elapsed. Sometimes multiple records are returned, and they each have different TTLs (www.smh.com.au for example). Since we are storing DNS messages and not specific DNS records, store the DNS message with the TTL of the A record, as there should typically be only one. If there are multiple A records (www.cnn.com for example), use the TTL from the first A record. To extract the TTL from a record, remember that DNS records have a specific format, with separate details separated by spaces. See Lecture 7 for specifics. You don’t need to constantly be expiring records from the cache. It is recommended to simply check if a record is expired before it is returned to a requester. You don’t need to expire a record if there hasn’t been a request for it yet. Grading Rubric: Task Evaluation Score: Missing (0); Poor (.25); Not quite right (.5); Almost right (.75); Great (1) Weight Uploaded required .py files 0.15 0.1 Implementation uses dnspython library 0.05 Messages sent via UDP socket 0.55 0.1 New queries forwarded to Google DNS 0.1 Google responses forwarded to requester 0.1 Google responses stored in cache 0.1 Cache used to answer queries where possible 0.1 All 3 server messages output appropriately 0.05 No errors 0.3 0.05 Reasonable variable names 0.1 Clean code 0.1 Reasonable comments 0.05 [IS 677 only] Messages are cached with time information 0.25 0.1 [IS 677 only] Expired cache entries are removed from cache 0.15 Grade 1.0 [IS 677 only] Grade 1.25 Programming Assignment #3 IS 477/677 Due: April 4, 2019 5 Testing: Server code is running throughout all of these tests, so the cache is accumulating entries. Note: the contents of your DNS records may vary, different CNAMES, different IP addresses, different TTLs, different message IDs. [IS 677 only] Your responses may differ to those below depending on the time between requests and the TTL values. Test 1 Tester code INPUT: py assignment3_tester.py www.google.com Server code OUTPUT: Incoming message (61298) with question