abe@j.cc.purdue.edu (Vic Abell) (08/21/86)
Symptom: A 2.9BSD client writes a stream of data to a remote peer and closes the socket. The remote peer sometimes receives an ECONNRESET error instead of an EOF. Cause: Any segment received by tcp_input.c after a 2.9BSD socket has been closed causes it to return an RST to the remote peer. If the application in the remote peer has not yet read all the data in transit, the data will be flushed and the peer will receive an ECONNRESET error reply to its read call. Cure: Modify tcp_input.c to avoid the reset if no data accompanies the segment. move lines 353 through 361 that read: /* * If data is received on a connection after the * user processes are gone, then RST the other end. */ if (so->so_state & SS_USERGONE) { tcp_close(tp); tp = 0; goto dropwithreset; } before the comment at lines 290 through 294 that reads: /* * States other than LISTEN or SYN_SENT. * First check that at least some bytes of segment are within * receive window. */ modifying them to be: /* * If data is received on a connection after the * user processes are gone, then RST the other end. */ if (so->so_state & SS_USERGONE) { tcp_close(tp); tp = 0; if (ti->ti_len) goto dropwithreset; goto drop; } This code has been lifted (with tailoring for 2.9BSD) from 4.2BSD and 4.3BSD. It has the additional virtue that sockets disappear very quickly after two peers have closed them by mutual agreement. Vic Abell, Purdue University Computing Center, abe@j.cc.purdue.edu