Homework 6: Reliable Communication

In this homework, we implement reliable communication over an unreliable link, just like TCP. The homework template is available at:

git.uicbits.net:cs450-f13/public/homeworks/hw6

MININET SETUP

We use Mininet to simulate an unreliable link between sender and receiver.

Mininet allows you to create a virtualized software defined network on your computer - either your physical computer or a virtual machine. When you launch a mininet instance for this assignment, three additional console terminals will pop up on your screen. One is a management console that you don’t need to worry about, the other two simulate different hosts with their own IP addresses separated from each other by a link that can be high-latency or lossy. These hosts share the host OS and filesystem so you can use them to easily run your own code. Mininet relies on Xterms to present you with these multiple interactive consoles, so you’ll either need XMing on windows, or XQuartz on OSX, and regardless you’ll need to make sure you have activated X11 forwarding for your ssh connection: at the command line you can add the -X flag to ssh on OSX and linux, and for PuTTY you’ll need to use these instructions.

To set up mininet on your EC2 machine, follow the directions at this page, option 2. If you want to work with Mininet on your own machine, you can use option 1 and download the mininet VM image and use that.

Either way, I would strongly recommend that you get mininet set up ASAP so that you’ll have sufficient time to work on the assignment.

After setting up the environment, you need to create a virtual network with two hosts. Run

$ sudo mn --link tc,delay='10ms',loss=5,max_queue_size=2 -x

This will drop you into a mininet shell. To pull up a terminal on each of your new virtual network hosts, run this in the mininet shell:

mininet> xterm h1 h2

This creates a minimal network topology with two hosts connected to a switch with 10ms latency on each link, 5% packet loss on each link, and a buffer of size 2. Note that there is no space between parameters.

All the operations you perform within these windows are just like if you were using the main linux VM. They work independently like different machines but share the same files on the machine. Usually h1 has IP address 10.0.0.1 and h2 has 10.0.0.2. Try to ping each other. And here are some commands may be useful if you don’t use GUI. For more tips, see here.

help % display commands
exit % quit
pingall % all the machine ping each other to test connectivity 
xterm h1 % display h1 termial window

HOMEWORK DESCRIPTION

At a high level, your job is to change the reliable transport protocol implementation in the template so that the following example execution always produces the correct result. In one terminal(say h2), you run the receiver in the following way, and it produces output as shown below.

./hw6_receiver base_port > RECEIVED_FILE
# later on, this happens...
File received, exiting.

In a separate terminal of h1, you run the sender:

cat ORIGINAL_FILE | ./hw6_sender 10.0.0.2 base_port
Sent 1020544 bytes in 25 seconds: 35 kB/s
Estimated RTT: 1029 ms

The link has a total buffer size of two packets (including packets in both directions). This is specified using the parameter max_queue_size=2. This leaves enough room for a single ack and a single packet in flight at the same time. So you only need to implement a simple TCP with ACK works, no pipelining. If you send a second packet before the first one arrives at the destination, chances are that either an ack or the second packet will be lost, so it is important that you get your timeouts and your acknowledgments right.

A few things to pay attention to:

  1. hw6_sender.c, hw6_receiver.c - these are to be thought of as ‘applications’, using the ‘library’ you implement in hw6.c. You may change these files, but we will use the original files when grading.

  2. hw6.c - this is where your code should go. You will need to make major changes to rel_socket(), rel_connect(), rel_send(), rel_receive() and rel_close().

  3. The file transferred: your program should work for any file, and reproduce it exactly. You can check this with the md5sum utility, or diff.

  4. The RTT: you are to dynamically estimate the RTT using the EWMA technique, and use this to set your timeout period. With correctly tuned timeouts, lower RTT will result in higher throughput.

  5. Keep your packets smaller than or equal to MAX_PACKET (1400 bytes).

  6. Pay attention to the end of the connection. Ensure that both sides of the connection finish without user assistance, even if packet losses occur, while guaranteeing that the entire file is transferred. Look at the FIN/FINACK/ACK sequence in TCP for ideas.

HINTS

  1. For trying out your code, you can tune the packet loss ratios and round-trip latencies by changing the parameters when creating the mininet.

  2. In rel_close(), you may want to just wait for some time, to make sure the last ack didn’t get lost (leaving one end hanging).

TURN-IN INSTRUCTIONS

Same story as previous homeworks, except that your makefile should generate two binaries called hw6_ receiver and hw6_sender.

GRADING

Grading script usage is following:

./hw6_score username base_port score_file

The grading script for this assignment is available in public repository, which you can use to check whether your code meet the requirement of this homework. There are three script files and one file to be transmitted. For rel_tcp.py, it can start a single test case to check your program. For hw6_score, it runs 6 cases and check whether your program can transmit data fast enough. For kill_controller, it can kill processes, when your program doesn’t exit normally.

The grading script will pull your code from git server, copy a file supplied in the grading script directory to your directory and run 6 testcases with different latency and forwarding probability. For each test case, there is a minimum throughput requirement and a timeout for your program to exit. The timeout is set as 50% more than the corresponding required throughput. If your program exits normally before the timeout but the content of the received file is invalid then there is 0 point. However, if the program exits normally before the timeout and the received file’s content is valid but the throughput obtained is lower than the required minimum throughput then you will get 0.5 point. Finally, if your program doesn’t exit before the timeout then it will be killed after timeout and hence the content of the file will be incorrect and you will get 0 point. Sample output from the grading script is following:

[SUCCESS] latency=1000ms packet loss=0% [1]: 1 [throughput (kB/s)=0.26] 
[SUCCESS] latency=100ms packet loss=0% [1]: 1 [throughput (kB/s)=3.11] 
[SUCCESS] latency=10ms packet loss=0% [1]: 1 [throughput (kB/s)=28.78] 
[SUCCESS] latency=100ms packet loss=5% [1]: 1 [throughput (kB/s)=1.36] 
[SUCCESS] latency=10ms packet loss=5% [1]: 1 [throughput (kB/s)=16.22] 
[SUCCESS] latency=10ms packet loss=10% [1]: 1 [throughput (kB/s)=4.86] 
Total score: 6