6.033 Lab - Computer System Engineering | Lab 1 - February 11, 2000 |
The first programming project in 6.033 is meant to prepare you for the next two projects by acquainting you with UNIX programming, especially network programming. Unlike the other labs, we will start you off with some code for setting up network connections, since the code for doing this is very mechanical. From this point, you will build a fully functional TCP proxy.
We'll be using a trivial client/server program as our stepping stone. The C sources for the program can be found in the 6033 locker in the lab/src/one directory. You should copy the contents of the directory to a directory under your control.
Now, build the client and server. Start the server by typing ./server. In another window, type ./client name, where name is the name of the machine on which the server is running. You can find out the name of a machine you are using into by typing hostname. Every time you run the client, the server will print the notorious "hello, world!" message.
Once you get the programs running, you should study the code and try to understand it. The specifics of each UNIX networking call can be found in the manual pages (e.g., type man socket). If you cannot make sense out of the program using the sources and the man pages, you might want to borrow "UNIX network programming," written by Richard Stevens; or, get in touch with your TA.
A TCP proxy server is a server which acts as an intermediary between a client and another server, called the destination server. Clients establish connections to the TCP proxy server, which then establishes a connection to the destination server. The proxy server sends data received from the client to the destination server and forwards data received from the destination server to the client. Interestingly, the TCP proxy server is actually both a server and a client. It is a server to its client and a client to its destination server.
A TCP proxy server can be useful to get around services which restrict connections based on the network addresses. For example, there are many servers at MIT which will only serve data to addresses within the MIT network. By running a proxy server on the MIT network, clients from outside MIT can use those servers by connecting through the proxy server. The MIT servers will think they are serving data to a machine on the MIT network (namely the proxy server machine) and they'll be right. However, the proxy is forwarding the data out of the MIT subnet, thus subverting the protection mechanism. This is a violation of the rules of use on most of those server, so we do not encourage you to do this.
The proxy server you will build for this lab will be invoked at the command line as follows:
% ./proxy destination-host destination-port listen-portFor example, to redirect all connections to port 3000 on your local machine to the MIT web server, do:
% ./proxy web.mit.edu 80 3000 &The proxy server will accept connections from multiple clients and forward them using multiple connections to the server. No client or server should be able to hang the proxy server by refusing to read or write data on its connection. For instance, if one client suddenly stops reading from the socket to the proxy, other clients should not notice interruptions of service through the proxy. You will need asynchronous behavior, described in "Using TCP Through Sockets".
Additionally, if a connection hangs for more than 30 seconds, it must be terminated. The proxy server should dump to stderr a message stating that the connection has been dropped. The message should include ip address of the client or server that hang.
Tells the dispatcher to call function fn with argument arg when ms number of milliseconds have gone by, starting from now. cb_timer should create and manage a list of timers. cb_timer should return an identifier used for the timer.
Cancels the timer specified by id. id should be a timer identifier returned by cb_timer_add.
This should be a best effort timer facility: if the proxy is waiting in select for activities on descriptors, it should call a callback immediately when the timer associated with this callback expires. But if a timer expires while the proxy is not waiting in select (e.g. executing another timer callback), it is acceptable for the callback of the expiring timer to be called later. Furthermore, timer expiration callbacks should be handled at a lower priority than read or write callbacks.
Hand in your asynchronous library and multifinger program in a tar image named "timers.tar". The tar image should include a valid Makefile that creates a library named libasync.a and a program named multifinger. Prior to coming to recitation, place this image in your home directory. Please make sure the tar image is readable by 6.033. The tar images will be collected sometimes after recitation.
We will test both your multifinger program and asynchronous library. If your library fails to work properly, we will try your multifinger program with our own library. You can place comments and/or directions in a README file.