Computer Networks Project 2 -- Aloha


The goals of this project are:

  1. to learn more about the Aloha protocol
  2. to practice using UDP and the sockets interface, especially sendto(3XN) and recvfrom(3XN)
  3. to learn about using select(3C) (or threads) and random(3C)
  4. to implement a simple "talk" or "chat" application

This is a group project. You may work alone or in groups of up to 4 people. Choose your team-mates carefully -- you will all get the same grade. You may discuss concepts and ideas and you will have to test with other groups, but you should be the sole authors and debuggers of all your code.

The project is due Monday March 12th 2001 (any time). Submission is electronic. Late submissions lose 20% of the grade for being one day late, and get no credit thereafter. So please submit what you have on the due date.

The assignment is to write software to simulate an Aloha hub and Aloha end-stations.

Aloha Protocol

The Aloha protocol is very simple. Data is sent by the end systems to the hub. The hub re-broadcasts everything it receives to all the end systems it knows about. Before re-broadcasting, the hub computes the checksum of the packet it received, to make sure there was no error. If the checksum is incorrect, the packet is dropped.

For this simulation, we will use UDP to carry packets -- the hub should open and bind a single UDP socket, and do all its communication using recvfrom and sendto. Since there can be no actual collisions when using UDP, your hub must listen for 100ms (0.1 seconds) after receiving each packet: if any additional packet is received during that interval, both packets are dropped. Also, the hub must checksum each packet (the Internet checksum is described in RFC 1071), and if the checksum adds up to anything other than 0xffff, the packet must be dropped. After a packet has survived the collision process, the hub must also randomly drop the packet with 1% probability.

If the checksum is correct and there was no collision and we did not drop the packet to simulate errors, the hub must send the packet to every end system it has ever gotten packets from. Before rebroadcasting, the hub must randomly set 1 byte in 1000 (0.1% byte error rate) to the value 0x32, to simulate transmission errors. Note that the hub never needs to add a checksum to the packet -- if the packet is received with the correct checksum, it will go out with the correct checksum, except when the "transmission errors" corrupt one or more of the outgoing bytes.

The end stations are implementing a simple chat protocol. Each end station must simultaneously read its network interface (UDP socket) and its keyboard (stdin) using fgets(3S). Data received from the network is printed to the screen (stdout), data received from the keyboard is echoed to the screen and also sent to the hub.

For reliability, each end station can only send one packet (one line of text) at a time. After that it must wait up to one second to get that same line back from the broadcaster. If the packet is not returned within 1 second, the end station should resend it, up to a maximum of 5 times total (1 original transmission, and 4 retransmissions). If the packet is not returned 1 second after the 5th transmission, the end system should print a message to the screen to the effect that contact with the hub has been lost, and terminate (exit) -- the user can always restart it if they so desire. You do not need to read the keyboard while waiting for a packet to return, but you may if you want to. If you do, you will have to buffer the data internally until the data that has been sent is correctly received and you can start sending the buffered data. If you do not read the data while waiting for a response, the operating system will buffer it for you.

The end stations must compute the 16-bit Internet checksum, and prepend it (as a 16-bit header) to each message sent. After computing the checksum, randomly set 1 byte in 1000 (0.1% of the bytes the end station sends) to the value 0x37, to simulate noise in the channel.

If an end station receives a message (including its own), it must checksum it, and drop the packet if the checksum is incorrect. Otherwise, the message should be displayed on the screen.

Project Deliverables

I will expect the following from each group (only one copy from each group please, unless you are working alone):
  1. The source code (source, makefile, and a status file listing your level of functionality and the names and emails of the members of the group -- no objects, binaries, or random files) for your implementation. The source code must compile and run on uhunix2. Compilation must be achieved by running ``make'' with no arguments (see make(1S)).
  2. Place your source files and your makefile and status file, and no other files, in a directory in your account on uhunix2.
  3. cd to that directory.
  4. run the script /home/1/esb/proj/done which will copy your files to the instructor's account (calling "done" more than once will overwrite previous versions of the files)

The name of your hub must be ahub. The name of your end-station must be achat. Their command-line parameters are as follows:

I may provide you with my own copies of ahub and achat later on for testing -- but for full credit on this project you must successfully interoperate with at least one other team (describe this in the status file, and make sure they mention you in their status file). Interoperation is accomplished when both of these are achieved:
  1. Your achat and their achat can communicate in both directions via their ahub, and
  2. Your achat and their achat can communicate in both directions via your ahub
Specifically, your status file must list:
  1. all the names and email addresses of the members of your team
  2. For ahub:
  3. For achat:
  4. you are welcome to provide any other comments that you think would be helpful when I grade this project

Testing, Suggestions, and Hints

  1. I suggest looking at select(2) for details of how to listen for a packet for only a 100ms. If you prefer, you can use threads instead.
  2. A good C function for random number generation is random(3C). Do NOT use rand(3C).
  3. You may want to have a compile-time switch to turn the error-inserting behavior on and off.
  4. There is no point in testing with others until you have your own achat talking reliably to your own ahub
  5. The hub must keep track of all the end systems it has ever heard from (hence the use of recvfrom, which tells you who the sender of a UDP packet was), and send new each packet to all of them. For this project, the data structure for this can be guaranteed to not be bigger than 1,000 entries. If a sendto fails, you can generally ignore the failure (except while debugging). If your socket gets closed (this you should check for), re-establish it and bind to the same port, sleeping if necessary until it becomes available.
  6. uhunix2 and its siblings are shared machines, so please be considerate of your fellow students. Be sure you do not create long-lived processes, or if you do, be sure to kill them once you are done with them
    (ps -u yourlogin helps you identify them).
  7. The one area where you may co-operate with other teams is if you have a hard time figuring out how to build your makefile -- you may ask for and get help setting up a makefile (please do not use the ICS 451 mailing list for this purpose).
  8. You may use the ICS 451 mailing list to look for other groups that are ready to test.
  9. I always find it useful in my networking program to have a compile-time switch that allows me to print all the packets I send and receive (this prints received packets as soon as received, and sent packets right before sending) and saves them in a log file, together with the exact time of sending or receiving. While studying such a log file can be very tedious, it is also sometimes the only way to find transient errors. In studying the log files, we are basically trying to answer the question "did my program do what it was supposed to?" Since some of the behavior is time-dependent and very little of the behavior is visible to the end user, the log file often proves very useful.

Additional Challenges

Some people like additional challenges, so I'm listing some possibilities. Be sure to get the basic system working first, since none of these carry any credit.

Use threads instead of select. You'll have to figure out how to use synchronization primitives as well. This might be a good exercise if you choose to do it, since the next project may have threads.

Use a variable-sized data structure in the hub to store a variable number of end-system addresses. You can also time out end-systems if you don't hear from them for a certain time (3 minutes for testing, an hour to 24 hours for production).