[84] in 6.033-lab

home help back first fref pref prev next nref lref last post

Lab 1 Proxy

daemon@ATHENA.MIT.EDU (Constantine P Sapuntzakis)
Thu Apr 2 17:11:52 1998

Date: Thu, 2 Apr 1998 17:11:39 -0500 (EST)
From: Constantine P Sapuntzakis <csapuntz@MIT.EDU>
To: 6.033-lab@MIT.EDU


This document describes some of the common problems we found with the
graded TCP proxies. Many of you on the list have already received a
personal e-mail with a substantially similar document. This document is
for the benefit of those on the list who are just listening.

Source code for a working proxy can be found in the 6.033 locker in
/mit/6.033/lab/src/proxy.

Common problems

Busy waiting, also known as polling, was a common mistake in this
lab. Instead of waiting until the operating system inform them of some
event (e.g. the arrival of data), these programs repeatedly ask the
operating system for the status, looping until the event occurs. There
were many different ways of busy waiting:

1) Blatant: Programs just looped trying to read from client and server
   until data appeared or was written

2) Select-based: Some programs managed to busy wait despite their use
   of the select command. Many of these programs were constantly
   select'ing for write, even when they had nothing to write to the
   socket. Selecting for write asks whether there's room to write to
   the server and this is often the case. As such, select returns
   immediately, but since the programs having nothing to do, they call
   select again, looping.

3) Callbacks (i.e. async.c): Many programs had callbacks registered
   for writing when they had no data to write. Since the connection to
   the server is usually ready-to-write, this callback was being
   constantly executed. Many people forgot to deactivate callbacks
   (using cb_free) when they were no longer interested in writing or
   reading.

The second most common mistake was blocking on writes.  This behavior
is extremely bad as it can lead to deadlock. In some designs, when the
proxy is blocked on the write, it cannot accept data in the other
direction, thus leading to such a deadlock. For example, deadlock
occurs when the proxy is trying to write data to the client but the
client is not accepting any and blocked trying to write data to the
proxy.

Another common mistake was forgetting to close file descriptors, which
caused some of the proxies to quickly run out and fail.

Testing

To determine whether a proxy functioned correctly, it was run
using a testing program, which exercised the proxy. The testing
program is available online in /mit/6.033/lab/src/testproxy.  An
example proxy is included in that directory and another in
/mit/6.033/lab/src/proxy.

The testing program exercised the proxy in six separate phases with some
of the phases being subdivided:

Phase 1 - Ascertain how many simultaneous connections the proxy supports
Phase 2 - Make sure data passes bidirectionally without corruption or truncation
   A) 1 connection, 1 simultaneous client
   B) 200 connections, 1 simultaneous client
   C) 200 connections, 20 simultaneous clients

Phase 3 - Proxy handles end-of-file condition correctly
   A) 1 connection, 1 simultaneous client
   B) 200 connections, 1 simultaneous client
   C) 200 connections, 20 simultaneous clients

Phase 4 - Proxy handles unbounded writes by server without commensurate reads
   A) Client->Server
   B) Server->Client

Phase 5 - Proxy deals with server suddenly dying and leaving data in the pipe
Phase 6 - Proxy does not block on writes to server or client


-Costa

home help back first fref pref prev next nref lref last post