Comp 343/443 Networks Peter Dordal October 27, 2003 Due: Wednesday, Dec 3 The final exam is Monday Dec 8. IMPLEMENTING THE BLAST RPC LAYER You are to implement the client side of the BLAST protocol, as described in chapter 5.3 of Peterson & Davie. You will send a request packet (consisting of a single 4-byte number representing the "request number") to a designated port on a designated server (currently port 2222 on host ulam.math.luc.edu), and a BLAST server on the host will send your end an appropriate message, divided by BLAST into fragments. You will have to manage the sending of SRR's (selective ACKs here), and also the timers LAST_FRAG and RETRY. Your program should also handle the DONE timer in the following sense: if *nothing* is received after the initial request is sent within interval DONE, then your client should give up. In other words, you do *not* retransmit the original requests if nothing happens. The current implementation of the server sends its reply from a *new* port; your client will have to be aware of this, and should make an effort to determine that all BLAST fragments actually come from the same server port. Note that the *first* fragment will have to be treated separately in this regard; until it arrives, you do not know the port number for the others. ERROR CHECKING An important part of the project is to check for error conditions that may occur. Here is a list. Note that some of these are logically *ordered*; for example, if a packet isn't from the right host, then you shouldn't worry about whether it has a complete header! And if it doesn't have a complete header, you shouldn't worry about whether the header *fields* are right. * error in reading from network * packet from wrong host (or port, except for packet 1) * packet with incomplete header (ie size < HEADERSIZE) * wrong MID field (we will not use ProtNum) * wrong Type * wrong NumFrags (all packets should have the same value here) * FragMask has multiple bits set Receiving a duplicate fragment is *not* an error. Note that inconsistent MID or NumFrags (or port) values will be detectable only upon receiving packets after the first; upon receiving the *first* packet you simply set these for subsequent reference. Ideally, if the first packet has an incomplete header (or comes from the wrong host), you should ignore it completely (ie do *not* record its MID value, etc). SRRs You will send back an SRR if you receive the last fragment (as indicated by the fact that the bit that is turned on in FragMask is in position NumFrags-1). You will also send back the current SRR whenever a timer expires (except when it is time to give up). Finally, you should send back the final SRR once all the fragments have arrived. In Fig 5.12 in the text, the final SRR is sent upon receipt of Fragment 5, because all the other fragments (including Fragment 6) have already been received. TERMINATION Your transfer has been successful if you have received each fragment indicated by the NumFrags field of the original packet. The SRR you send back will then have all bits from 0 to NumFrags-1 turned on. (To turn on the ith bit of a variable mask, use "mask |= (1 << i)".) An unsuccessful transfer is one where the RETRY timer has fired for MAX_RETRIES, or some other *unrecoverable* error has occurred. Note that good network design means that you should avoid treating errors as recoverable unless absolutely necessary: Be conservative in what you send, but liberal in what you accept. FILES I am working on java versions of the files. TESTING If you ask for message 0 from my server, a message is returned containing the *number* N of other messages currently supported (as a single 32-bit word, in network byte order). You should then request each of these messages, 1 through N, in turn. For each message, you should print out: information about every packet received the final message size a message checksum (I'm still looking for appropriate code here) Some of the messages will have packet losses or reordering artificially introduced by my server; it will be the job of your client to straighten these out. You do *not* need to print out the message received. However, it should be *possible* to do so, to the stdout; in order to preserve this as a way of printing messages, NOTHING ELSE SHOULD GO TO STDOUT. All other messages (including the every-packet status messages) should go to stderr!