COMPSCI 356 Computer Network Architectures: Lab 1 Reliable transport

Introduction

Your task is to implement a reliable sliding window transport layer on top of the user datagram protocol (UDP) which is unreliable. For example, you should not rely on UDP's checksum to detect bit errors in packets.

In this assignment, you are provided with a library (rlib.h and rlib.c) and you have to implement some functions and data structures in reliable.c. rlib.[h|c] provides some useful helper functions. Your implementation should:

This reliable transport protocol supports two operation modes. The first mode is single-connection mode connecting the standard input and output of the two processes together. The second is multi-connection mode, in which a client accepts TCP (or unix-domain) socket connections and relays them over UDP to a server that connects to a TCP port or unix-domain socket. For more details, please refer to Labs1&2 in CS144 at Stanford University.

In our assignment, you should finish implementing the single-connection mode with sliding window with sizes > 1, the second server/client mode is NOT required. This means you don't need to handle demultiplex traffic at server side in server/client mode. In the first mode, one reliable transport layer should include both the sender component and receiver component. Correspondingly, one reliable connection bewteen two processes will support two-way data transmission simultaneously and asynchronously. In one of the data links, the sender will keep reading data from a stream (STDIN) until an EOF is met, break it into fixed-sized packets suitable for UDP transport, prepend a controlheader to the data, and transmit this packet to the receiver. The receiver will read these packets, and write the corresponding data, in order, to a reliable stream (STDOUT).

Getting started

You should be able to finish your assignment on the VM image in lab0.

Download and extract the reliable.tar.gz.

Your task will is filling in the some functions in reliable.c.

You should be able to run the command make to build the reliable program. We provide the binary code of a sample implementation, whose name is reference. After you finish your assignment, the reliable program should have same function with reference. An example of the working program is given here.

On your VM image, run:

./reference 6666 localhost:5555
[listening on UDP port 6666]

Keep the terminal open. On another terminal, run:

./reference 5555 localhost:6666
[listening on UDP port 5555]

Now anything you type on one termianl will show up on the other terminal.

Understanding the code

Packet format

There are two kinds of packets, Data packets and Ack-only packets. You can tell the type of a packet by length. Data packets vary from 12 to 512 bytes, and Ack packets are 8 bytes. The packet format is defined in rlib.h:

        struct packet {
          uint16_t cksum; /* Ack and Data */
          uint16_t len;   /* Ack and Data */
          uint32_t ackno; /* Ack and Data */
          uint32_t seqno; /* Data only */
          char data[500]; /* Data only; Can be less than 500 bytes*/
        }; typedef struct packet packet_t;

Every Data packet contains a 32-bit sequence number and 0 or more bytes of payload. Both Data and Ack packets contain the following fields. The length, seqno, and ackno fields are always in big-endian order (use htonl/htons to write and ntohl/ntohs to read):

The following fields only exist in a data packet:

Requirements

Your transport layer must support the following:

Implementation Details

You are provided with a library (rlib.[h|c]) and your task is to implement the following six functions: rel_create, rel_destroy, rel_recvpkt, rel_read, rel_output, rel_timer. As server/client mode is not required, leave rel_demux alone!

Testing and Debugging

For debugging purposes, you may find it useful to run ./reliable with the -d command-line option. This option will print all the packets your implementation sends and receives.

For testing purposes, you may wish to test your code against our reference implementation. Your program reliable should be able to communicate with the program reference.

NETEM

I will use netem emulator to simulate the packet loss, delay, packet re-ordering and packet corruption environment on loopback network interface (localhost) to test your program's functionality.

Setup emulator

Before you use emulator, you should remove existing emulation on it. Type following commands on your terminal:

sudo tc qdisc del dev lo root
            

The command will remove any network emulation on your lo network interface.

Packet loss

Run following command on your terminal:

sudo tc qdisc add dev lo root netem loss 50%
            

Now you have setup a emulator on your lo interface. Packet loss ratio of your lo interface becomes 50%. You can ping localhost to see packet loss ratio. Note that the 4th word in command above is "add". If you have already setup the emulator and want to modify the configuration, you should change "add" to "change".

Packet delay

Run following command on your terminal:

sudo tc qdisc change dev lo root netem delay 100ms 20ms distribution normal
            
You can refer to netem's offical page above to see other configuration command.

Submitting

To submit the assignment, add a file called README with names of your group members. Run the command make submit, this should create a file called reliable.tar.gz.

Collaboration policy

You should finish this assignment in a group of two or three.

Acknowledgement

We thank the course staff of CS144 at Stanford University for their support. This lab is adapted from one of their assignments.