Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!VAX.FTP.COM!jbvb From: jbvb@VAX.FTP.COM (James Van Bokkelen) Newsgroups: comp.protocols.tcp-ip Subject: What seems to be a glitch in the TCP spec. Message-ID: <8902240134.AA05182@vax.ftp.com> Date: 24 Feb 89 01:34:52 GMT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The Internet Lines: 71 Consider the following situation: A TCP connection is carrying intermittent, bidirectional traffic. Host A has just sent a burst which filled host B's window. B has enough data for a small segment, piggybacking the Ack and indicating a window of 0. A replies with an Ack, just as B's application consumes the data and B sends a segment to re-open the window. B's implementor has chosen to retransmit the first segment of un-acked data (if any) with window updates and Acks (B's cost/packet is much larger than the cost/byte). A's implementor has exactly followed pg. 69 of RFC 793, which says to discard segments with obsolete data before checking the Ack or Window values. Host A Host B 1. <- Seq 100, Ack 200, Data 20, Window 0 2. Seq 200, Ack 120, Data 0, Window 4076 -> (crosses w/3) 3. <- Seq 100, Ack 200, Data 20, Window 4096 (Dropped per pg. 69) 4. Seq 200, Ack 120, Data 0, Window 4076 -> (ignored, pg. 72) Segments 2 and 3 cross in transit, A drops 3 before checking either the Ack or the window and sends 4, which B drops as a duplicate Ack. At this point, A has more data to send, but B doesn't. Everyone has followed the spec, but A didn't see B's window re-open, and the connection will sit idle until A sends a window-probe segment. The user is unhappy, because a TCP-based window system glitches. I see four possible solutions: 1. Tell the user that he has found a glitch in the spec, and he should be glad that heterogenous networking works at all. See Figure 1. 2. Amend the spec to warn that "window updates and acks may be ignored if they accompany retransmitted data; therefore this should be avoided". 3. Amend the spec to require that the first window-probe segment be sent when the window stays zero for two round-trip times. If the probe is rejected, try again in a couple of minutes. 4. Amend the spec to require that, when a segment is about to be dropped per pg. 69, if the segment is immediately to the left of the window (e.g. (SEG.SEQ + SEG.LEN) == RCV.NXT), SEG.ACK should be checked, and if it is valid (SEG.ACK >= SND.UNA), both the Ack and the Window should be processed before the segment is discarded and the obligatory Ack sent. Note that pg. 72 of the RFC has an error. As corrected in the upcoming "Requirements for Internet Hosts" RFC, the send window should be updated even when SEG.ACK == SND.UNA (otherwise TCP could not continue without a window probe once the send window went to 0). I don't like solution 1 (after all, I want the customer's money). I have discussed this matter with some other TCP implementors, who don't like solution 2, particularly when applied to Telnet connections. Solution 3 is partially implemented in some TCPs (the first probe occurs after about 4 sec.), but there is still a glitch. I've fully implemented solution 4, and have two years of experience with it (in a commercial product). It seems to work, and the only objection I can think of is a miniscule increase in the probability of the connection being reset due to an old duplicate segment (the mechanism is "ack of unsent data", not accepting bad data, and the odds of this are still way below those of damaged data escaping detection by the TCP checksum). Comments? In particular, have I missed something relevant in RFC 793? Has someone else already addressed this issue in some publication other than an RFC? One TCP implementor I discussed this with asked: "Is there any particular reason why we couldn't amend the spec to say 'check all acks, regardless of the sequence field?'?" Any comments on this? James B. VanBokkelen 26 Princess St., Wakefield, MA 01880 FTP Software Inc. voice: (617) 246-0900 fax: (617) 246-0901