Assignment 10 CS594-ipp05 revised: 11/29/05 Assigned: 11/15/05 Due: 6:00pm 12/5/05 (NO lates!) Objective: implementation -- NewReno over UDP Points: 40 Overview: Modify your UDP client and server from assignment 4 so that you can "do" NewReno like congestion control (RFC 2582). Your client will need to do slow-start and New Reno congestion control on 3 dup ACKs or timeout. You will need to update the ACK server to do TCP-like ACK management. ACK server: Your ACK server must behave like TCP (no delayed ACKs), sending back the packet number+1 of the last good (contiguous) packet received. If there are dropped or out of order packets, your ACK server must buffer up the out of order packet numbers, so that when the missing packet arrives, you can send a cumulative ACK. Careful, there may be other missing packets in your buffered packet numbers. Your server can assume that the window size will never be bigger than 4096 packets. The packet number is in network-byte order in the first 4 bytes of the packet. Your ACK should contain the packet number of the next good packet expected. You must ctrl-c and restart your ACK server for each test. Client: Your UDP client needs to accept up to 5 command-line arguments. hostname port number window size in packets (default 10) duration in seconds (default 10) debug level (default 0) The first two arguments are mandatory, and your program should complain if they aren't provided. Preset parameters for your client: initial packet number: 1 initial cwnd for slow start: 1 (packet) dup threshold: 3 max window size: 4096 initial value for ssthresh: 4096 MSS (packet size): 1000 bytes Newreno: Your client should provide New Reno congestion control. You should use variables like ssthresh and cwnd (see final output and tracing). Do packet counting (like ns) rather than byte counting. You should use slow-start (cwnd = 1) for initial startup and whenever a timeout occurs. If 3 consecutive dup ACK's arrive, you should set ssthresh to cwnd/2, set cwnd to cwnd/2, and retransmit the missing packet. Don't let cwnd grow bigger than max window size parameter. You should never have more than cwnd unacknowledged packets in flight. Handle partial ACK's and transmit new packets during recovery if there is "room". Your client will need to keep track of the last ACK'd packet, and the max packet number sent so far. (You don't need SYN/FINs, and ACK server isn't advertising an available window, it just returns ACKs.)` Timeouts: Your code should provide a 1 second timeout for the ACK of a packet. If a timeout occurs, you should retransmit the oldest un ACK'd packet and reset the timer and set cwnd to 1 (do slow-start). You only need to time one packet at a time. When an ACK arrives for the packet you are timing, reset the timer. If a packet is not ACK'd after three retries, your program should exit with a message indicating the failed packet number. Use alarm(1) with signal handler for timeouts as in assignment 4. You don't need any exponential backoff. Final output: When your client has run for the specified duration, print out the following stats before exiting: elapsed time packets out ACKs in last packet # sent data rate timeouts partial ACKs dup ACKs bad ACKs (ACKs less than left edge of window, or bigger than right edge) retransmitted packets cwnd ssthresh Tracing: If debug > 0, for each packet sent or received fprintf to stderr a line with the following fields: for a received ACK: etime ACK# ack sending a packet: etime packet# cwnd ssthresh etime is elapsed time in seconds (%f) double precision seconds since when your client first started up. Use gettimeofday() for microsecond precision. Drop list: When your client starts up it should look to see if it can read a file called "drop.tmp". drop.tmp will have one line with up to 10 packet numbers separated by blank, e.g. 10 11 11 21 Retrieve the packets to be dropped, and add code to your client so that just before the sendto() you check your drop list, and if the packet number of the packet to be sent matches the "next" packet number in the drop list, don't do the sendto() ! Remove that packet number from the drop list. This will allow your client to induce packet loss for testing purposes. Example, 11 11, will cause packet 11 to be dropped, and dropped again when it is retransmitted (this should cause a timeout in your client, and 11 should be sent again, successfully). Other debugging tips: you might want to fprintf to stderr whenver you do a retransmit. Testing: (provide final output for each case) all tests are 10 seconds (1000 byte MSS) 1) tests with your ACK server a) window of 10 b) window of 20, droplist: 14 c) window of 20, droplist: 104 106 2) tests with my ACK server on comp3.cs.utk.edu (10.0.0.3) port 5555, your client must be running on cetus1.cs.utk.edu See note below on getting socket address from first recvfrom. If comp3 isn't working, try comp1.cs.utk.edu a) what is RTT from cetus1 to comp3? b) window of 10 c) window of 90 d) window of 10, droplist: 14 14 e) window of 10, droplist: 14 14 14 14 f) window of 90, droplist: 104 106 g) window of 90, droplist: 400 900 turn on your debugging, to get per packet trace from your client and provide plot of cwnd vs time paste all of you results into an ANSWERS file that you submit with your plot, C source code and any makefile etc. that is required for the TA to build and run your code. Use ~cs594ipp/594submit from one of the CS lab machines. Check the error return values of all network functions! See the http://www.cs.utk.edu/~dunigan/ipp05/policy.txt for information on how to document your C code and what is "acceptable" collaboration. Notes: Get as much of it working as you can, points for working components are as follows: points component 5 ACK server 5 slow-start 10 reno (fast retrasnmit, AIMD) 5 newreno (fast recovery, partial ACK) 5 timeout 5 drop list To work with my ACK server on comp3 (concurrent UDP server), you must use sendto() and recvfrom() in your client. You must NOT use connect() in your client, AND after you send the first packet and receive the first ACK packet, you need to copy the socket struct info from the recvfrom() into the socket struct you use for the remainder of your sendto(). (Do you know why?) Run your client on cetus1. If your client is printing a lot of stuff, you probably should redirect output to a file so performance is less affected, e.g. newreno comp3 5555 100 >& out.tmp Compare your results with your buddies to see if your client is working ... In ~dunigan/ipp05/ns is asn10.tcl, an ns Newreno script with a topology similar to cetus1-comp3, you could compare your tests with ns tests. ask questions