[695] in linux-net channel archive

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

Re: TCP bug and potential fix

daemon@ATHENA.MIT.EDU (Rob Janssen reading Linux mailingl)
Sat Jul 15 13:35:52 1995

From: linux@pe1chl.ampr.org (Rob Janssen reading Linux mailinglist)
To: yarvis@FICUS.CS.UCLA.EDU (Mark Yarvis)
Date: Sat, 15 Jul 1995 13:42:02 +0200 (MET DST)
Cc: linux-net@vger.rutgers.edu
In-Reply-To: <9507141725.AA06450@albans.cs.ucla.edu> from "Mark Yarvis" at Jul 14, 95 10:25:10 am
Reply-To: linux-vger@wab-tis.rabobank.nl

According to Mark Yarvis:
[...]
> 5.  Tracking Down the Extra ACK
> 
>    Further kernel debugging revealed that the second ACK was being sent
>    in the function tcp_read_wakeup().  In this function, an ACK is sent
>    to update the window on the remote end.
> 
>    This extra ACK is being sent from this function after the socket has
>    already acknowledged a FIN.  At this point, the local socket is
>    either CLOSED or in the TIME_WAIT state.  The remote socket is CLOSED
>    and should not receive any packets.
> 
> 6.  Possible Solutions
> 
>    There are three possible solutions:
> 
>    A.  Delay the reporting of a RST to the user.  This would allow the
>        user to perform read() calls to obtain the remaining data.  I do
>        not believe, however, that this conforms to RFC 793.
> 
>    B.  Prevent tcp_read_wakeup() from being called on a CLOSED socket.
>        It is my belief, however, that tcp_read_wakeup() is being called
>        from outside the TCP layer.  If this is the case, then the
>        calling code does not know the status of the socket.
> 
>    C.  Prevent tcp_read_wakeup() from sending an ACK if it is in the
>        CLOSED or TIME_WAIT states.  This should work correctly since a
>        socket should only be in these two states if the remote socket is
>        CLOSED.  This will avoid sending an ACK to a CLOSED socket.

The extra ACK not only can cause trouble (like the one you found) but
it also is an unnecessary load on the network.
This is quite noticable on the amateur packet network, where bandwidth
is low.  Each TCP segment sent to a Linux system is acked twice.  Once
with a WINDOW of (maxwindow-segmentsize) and then again with a WINDOW
of maxwindow (14335).

I think something should be done about this.  There seem to be some options:

- delay the first ACK (with the smaller window) a short while, to see if
  the client reads the data.

- send the second ACK (with full window) only when the last sent ACK had a
  'significantly' smaller window (because a lot of data had piled up before
  the client read it).

The first could hurt transfer rate on fast networks with some delay.  One
of the RFC's mentions that ACKs should only be delayed for a short interval,
and some ACKs should always be sent immediately.  This is done to enable
the sender to accurately time the roundtrip delay.

The second is less problematic.  One implementation I know in detail (KA9Q)
even sends the second ACK only when it previously had sent an ACK with
window 0.  It could be done less drastically, e.g. sending the second ACK
only when the window is opened by more than half the maximum size, or
more that 2 times MSS.

Such a change will half the number of ACKs sent back, especially on a
lightly-loaded (interactive) TCP connection.

Rob

-- 
+------------------------------------+--------------------------------------+
| Rob Janssen         rob@knoware.nl | AMPRnet:   rob@pe1chl.ampr.org       |
| e-mail: pe1chl@wab-tis.rabobank.nl | AX.25 BBS: PE1CHL@PI8WNO.#UTR.NLD.EU |
+------------------------------------+--------------------------------------+

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