CIS 410/510 Introduction to Networks
Winter 1998

Program #1: Address Lookup and File Transfer

Handed Out: 21 January 1998
Due: 18 February 1998 by 5pm (Revised Deadline)

Description

  1. Address Lookup

    For this part, you should write a UDP client and server to perform address lookup using a text-based protocol. The client sends queries to the server of the form:

    type=query
    host=[name]
    Request lookup of a host name.
    The server responds in one of the following ways:
    type=response
    host=[name]
    address=[address]
    The server maps the host name to an IP address by looking in its host table and returns this mapping to the client. The host table is loaded from a file at startup.
    type=redirect
    host=[name]
    server=[name]
    address=[address]
    The server does not have a direct mapping in its host table, but does have a reference for another server. It returns the name of this secondary server and its IP address.
    type=unknown
    host=[name]
    The server does not have an IP address or a reference for another server in its host table for the queried host.
    type=error
    [query]
    The server is not able to parse the query because it does not have the right format.
    The server's loads its host table from a file with one entry on each line. An entry has the form:
    host=[name],type=response,address=[address]
    or
    host=[name],type=redirect,server=[name],address=[address]
    The client loads two files at startup. First, it loads a host table at startup so that it can map from the server name to an IP address. The client's host table has the same format, but does not contain any redirect entries. Second, it loads a list of queries that it will send to the server. Each line of this file has the format:
    type=query,host=[name]

    The UDP server should be run with arguments listing the port it will listen on and the name of its host table file:

    udpserver [port] [table]
    The client should run with arguments listing the UDP server it will contact, the port the server is on, the name of its host table file, and a file containing a list of queries:
    client [server] [port] [table] [queries]
    The server should run indefinitely, handling all queries. The client should exit gracefully after completing all queries.

  2. File Transfer

    For this part, you should modify your UDP client to connect to a TCP server and download a file. After the UDP client is able to resolve the host name to an IP address (receiving zero or more redirects and one response), it should open a TCP socket to a TCP server residing at that address. It will ask the server to send it a file and the server will send that file over the socket. After receiving the entire file, the client closes the socket.

    The query the client sends to the TCP server is of the form:

    type=download
    file=[name]
    Request a file from the server.
    The TCP server responds in one of the following ways:
    type=file
    file=[file contents]
    The server sends the file to the client. The name of the file should correspond to a file in the same directory that the server is running; paths are not supported.
    type=unknown
    file=[name]
    The server does not have a file with that name.
    type=error
    [query]
    The server is not able to parse the query because it does not have the right format.
    The TCP server should be run with one argument listing the port it will listen on:
    tcpserver [TCPport]
    The modified client (now using both UDP and TCP) should run with one additional argument listing the TCP port to use:
    client [server] [port] [table] [queries] [TCPport]
    The server should run indefinitely, handling all queries. The client should exit gracefully after completing all queries. For this part, the file of queries has the form:
    type=download,host=[name],file=[name]
  3. Unreliability
    (undergrads:optional, grads:required)

    Modify the UDP server so that it randomly drops some queries (i.e. it does not respond to the client). Modify the UDP client so that it can cope with this unreliability by re-sending an unanswered query with an exponential backoff timer (An exponential backoff timer means that if the client waits time T before re-sending a query, then the next consecutive time it waits time T*2. When it receives a response then T is set back to an initial value.) To set a timeout for a socket, you should use the select() system call.

    The UDP server should be run with two additional arguments giving the seed for a random number generator and the drop probability:

    udpserver [port] [table] [seed] [drop]
    Run your server with varying drop probabilities and report the number of retransmitted queries the client sends for a simple scenario with no redirects. At what point does the client become unusable? Note: this is a qualitative answer ... state your assumptions and justify your conclusion.

Output

Your program should produce the following output for each of the parts:
  1. Address Lookup
    Querying UDP server [name]/[address]/[port] for host [name] ...
    Redirecting to server [name]/[address]/[port] ...
    Resolved to address [address]
    You should have 0 or more redirects, depending on the host tables you use. You are required to handle redirects so be sure to test them.

  2. File Transfer
    Querying UDP server [name]/[address]/[port] for host [name] ...
    Redirecting to server [name]/[address]/[port] ...
    Resolved to address [address]
    Querying TCP server [name]/[address]/[TCPport] for file [name] ...
    Received file:
    [file]
    You should have 0 or more redirects, depending on the host tables you use. You are required to handle redirects so be sure to test them.

  3. Unreliability
    Querying UDP server [name]/[address]/[port] for host [name] ...
    Lost request detected, backing of for [time] ...
    Re-transmitting query for host [name] ...
    Resolved to address [address]
    Querying TCP server [name]/[address]/[TCPport] for file [name] ...
    Received file:
    [file]
    You should have 0 or more backoffs and re-transmits. You are required to handle drops, so be sure to test them.

For all parts, you should handle errors. Malformed queries should be answered with an error, and hosts not in the host table should be answered with an unknown. Be sure to test that you handle these correctly. After printing out an error message, the program should stop processing the query and go on to the next one. System call failures should be handled by printing out a useful error message and then exiting the program completely.

Note, for testing purposes you can run both servers and the client on the same machine. Your host tables just need to list the same IP address for every name -- the address of the machine you are running on. You may also want to try running the client and several copies of the servers on different machines to be sure they work across the network.

Deliverables

Things you should turn in on paper:

You should turn in a printout of all your source code and your Makefile. All code should be well documented so that I can understand what you have written. Use your judgement on the amount of documentation you think is needed to fulfill this purpose. You should also turn in a printout of sample output using a battery of tests that you have designed to test all cases given above. Organize the printouts so that I understand what each piece of paper is demonstrating.

Things you should turn in online:

Submit your source code and your Makefile (or a batch file that compiles everything if you don't know how to do Makefiles). Do not submit any object code. Use the submit program documented in the Assignments section of the class web page.

Grading

Grading will be based on a battery of tests based on the scenarios outlined above and judged on the output your program produces. Borderline grades can be pushed up or down a level by the quality of the documentation.