[66] in 6.033-lab

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

A clarification of EOF's

daemon@ATHENA.MIT.EDU (David Mazieres)
Fri Feb 27 23:21:12 1998

Date: Fri, 20 Feb 1998 15:19:18 -0500 (EST)
From: David Mazieres <dm@reeducation-labor.lcs.mit.edu>
To: 6.033-lab@MIT.EDU
Resent-To: 6.033-lab-mtg@menelaus.MIT.EDU
Resent-From: "Kevin 'Bob' Fu" <fubob@mit.edu>

People asked how their TCP proxies should handle EOF in my recitation.
I'd like to clarify my response as none of the handouts we gave you
talk about the shutdown system call:

int shutdown (int fd, int how);
	how == 0  -> reading
        how == 1  -> writing
	how == 2  -> both

The shutdown system call informs the kernel that one is no longer
interested in reading or writing to a file descriptor.  It can be
particularly useful on TCP sockets with how set to 1.

Suppose process A has a TCP socket sa connected to socket sb in
process B on another machine.  If A calls
     shutdown (sa, 1);

then any future reads B performs on sb (after B has read all the data
A wrote to sa) will return 0, indicating EOF.  Though A can no longer
write to sa, it can still read from it.  Many applications make use of
the fact that they can continue to read from a socket even after
sending an EOF.


So how should you handle an EOF or error in your TCP proxy?  Suppose
s1 and s2 are two sockets, one connected to a client, and one
connected to the server you are proxying.  You should be concerned
with the following cases:

  A read or write to s1 returns an error (other than EAGAIN), or a
  write to s1 returns EOF:

    In this case, you can close (s1), finish writing any buffered data
    you might have to s2, and then close s2.

  A read on s1 returns EOF:

    The fact that s1 no longer wants to write data does not mean it
    isn't still interested in reading the rest of what arrives on s2.

    Thus, you should pass on the EOF by calling shutdown (s2, 1)
    after writing any buffered data you might have for s2.

    If you subsequently read an EOF from s2, then no more data will be
    sent in either direction.  You can close (s2), finish writing any
    buffered data you might have to s1, and close s1.

This situation is symmetric.  You can exchange s1 and s2 in the text
above.

David

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