Re: [tcpm] Handling of FIN in the reassembly queue

David Borman <dab@weston.borman.com> Fri, 22 February 2008 18:18 UTC

Return-Path: <tcpm-bounces@ietf.org>
X-Original-To: ietfarch-tcpm-archive@core3.amsl.com
Delivered-To: ietfarch-tcpm-archive@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 1365128C451; Fri, 22 Feb 2008 10:18:50 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.239
X-Spam-Level:
X-Spam-Status: No, score=-0.239 tagged_above=-999 required=5 tests=[AWL=-0.402, BAYES_00=-2.599, FH_RELAY_NODNS=1.451, HELO_MISMATCH_ORG=0.611, J_CHICKENPOX_33=0.6, RDNS_NONE=0.1]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eoBONeStvu-6; Fri, 22 Feb 2008 10:18:48 -0800 (PST)
Received: from core3.amsl.com (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 36E3628C25B; Fri, 22 Feb 2008 10:18:47 -0800 (PST)
X-Original-To: tcpm@core3.amsl.com
Delivered-To: tcpm@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 4656728C25B for <tcpm@core3.amsl.com>; Fri, 22 Feb 2008 10:18:46 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zC61Rsg-Bksd for <tcpm@core3.amsl.com>; Fri, 22 Feb 2008 10:18:45 -0800 (PST)
Received: from frantic.weston.borman.com (frantic-dmz.weston.BORMAN.COM [206.196.54.22]) by core3.amsl.com (Postfix) with ESMTP id 46FCE28C420 for <tcpm@ietf.org>; Fri, 22 Feb 2008 10:17:29 -0800 (PST)
Received: from [127.0.0.1] (frantic.weston.borman.com [206.196.45.33]) by frantic.weston.borman.com (8.12.5/8.12.5) with ESMTP id m1MIHB5G025919; Fri, 22 Feb 2008 12:17:11 -0600 (CST)
Message-Id: <03D0C184-E5FB-4FA3-AE2E-1DBF9906492F@weston.borman.com>
From: David Borman <dab@weston.borman.com>
To: Anantha Ramaiah (ananth) <ananth@cisco.com>
In-Reply-To: <0C53DCFB700D144284A584F54711EC5804BCF302@xmb-sjc-21c.amer.cisco.com>
Mime-Version: 1.0 (Apple Message framework v919.2)
Date: Fri, 22 Feb 2008 12:17:10 -0600
References: <47BE04A2.8000000@freebsd.org> <0C53DCFB700D144284A584F54711EC5804BCF302@xmb-sjc-21c.amer.cisco.com>
X-Mailer: Apple Mail (2.919.2)
Cc: tcpm@ietf.org
Subject: Re: [tcpm] Handling of FIN in the reassembly queue
X-BeenThere: tcpm@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <tcpm.ietf.org>
List-Unsubscribe: <http://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=unsubscribe>
List-Post: <mailto:tcpm@ietf.org>
List-Help: <mailto:tcpm-request@ietf.org?subject=help>
List-Subscribe: <http://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=subscribe>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: tcpm-bounces@ietf.org
Errors-To: tcpm-bounces@ietf.org

Andre (and Anantha),

On Feb 21, 2008, at 8:23 PM, Anantha Ramaiah (ananth) wrote:

> Andre,
>
>> -----Original Message-----
>> From: tcpm-bounces@ietf.org [mailto:tcpm-bounces@ietf.org] On
>> Behalf Of Andre Oppermann
>> Sent: Thursday, February 21, 2008 3:09 PM
>> To: tcpm@ietf.org
>> Subject: [tcpm] Handling of FIN in the reassembly queue
>>
>> The TCP reassembly queue is very good at handling and queuing
>> out of order data.  However correctly handling and queuing an
>> out of order FIN seems to be a bit tricky for a number of
>> (broken) edge cases:
>>
>>  1. FIN points into the middle of already queuedh data (or hole);
>>       Ignore the FIN and integrate the data?
>>       Ignore the whole segment with the bogus FIN?
>>       Integrate the data, move the FIN and flush excess data?
>
> I would think discarding the FIN would be fine, but if the FIN gets
> retransmitted again, then this puts a question mark on the data  
> sitting
> on the reassembly queue and in such cases we can possibly conclude the
> data in the reassembly queue is bogus?

First, an important point:  Despite the fact that the BSD code calls  
it a reassembly queue, TCP does *NOT* have a reassembly queue, it has  
a *resequencing* queue.  This distinction is important, because its  
purpose is to defer processing of packets that were received out-of- 
order.  TCP packets are processed in sequence, as ordered by SEG.SEQ.   
In the resequencing queue, optimizations can be done to coalesce  
adjacent packets, but that doesn't change the fact that it is still a  
resequencing queue, for packets that have not yet been processed.   
(But as a side note, that's not entirely true.  Some processing of out- 
of-order packets has to happen when the packets arrive.  For example,  
the ACK field needs to be processed, as well as the Urgent pointer,  
but I won't go into the details here.)

For any TCP connection, in each direction there can be only one FIN,  
it will never move, and there will never be any valid data transmitted  
after the FIN.  So, if you get into this situation, you already have a  
problem, you just don't know what the problem is.  Either the  
previously received out-of-sequence data is bad, or the current packet  
with the FIN is bad, but you don't know which.

As to what to do if this scenario should actually happen:  If these  
packets were received in sequence, the packet with the FIN would put  
us into CLOSE-WAIT state.  The data in the packets with SEG.SEQ after  
the FIN would then be ignored, see page 75 in RFC 793.  So, it seems  
that the thing to do would be to integrate the data with the FIN, and  
flush the previously received data that is after the FIN.

>
>
> This brings up another question  : suppose a TCP stack has sent s1, s2
> s3 and s3 with FIN, assume s1 is dropped, is it ok to retransmit s1  
> with
> FIN bit set (some stacks might see the state and blindly color the
> segment with FIN) I don't think this is allowed?

Absolutely not.  The FIN is part of the sequence space, it occupies  
one byte at the end of s3.  If you set FIN on s1, that is the same  
place in the sequence space as the first byte of s2.

>
>
>>
>>  2. FIN was already received and another one arrives pointing
>>     into the middle of already queue data (or hole);
>>       Ignore the FIN and integrate the data?
>>       Ignore the whole segment with the bogus FIN?
>>       Integrate the data, move the FIN and flush excess data?
>
> In the regular case (in-order) if the data is already consumed by the
> application and the window has slided, TCP simply ignores the  
> duplicate
> data. Now for data sitting in the retransmission queue, we should
> probably do the same, I would ignore the whole segment. [ I know in  
> this
> case FIN is extra]

You should be consistent.  Once again, I'd say integrate the data and  
FIN into the resequencing queue, and flush the excess data beyond this  
FIN.

>
>
>>
>>  3. FIN was already received and another one arrives pointing
>>     beyond the previous one;
>>       Ignore the FIN and integrate the data (if within previous FIN)?
>>       Ignore the whole segment with the bogus FIN?
>>       Integrate the data and move the FIN?
>
> Ignore the FIN.

Being consistent, throw away this new packet, since it is beyond the  
previous FIN.


>
>
>>
>>  4. FIN without data pointing beyond already queued data;
>>       Queuing a standalone FIN w/o data and not directly attaching
>>       to the end of the queue complicates the implementation a lot.
>>       Is it acceptable to ignore the FIN for the moment and have it
>>       retransmitted (with or without data) later?

Yes, you can always throw away any out-of-sequence packets.  It's the  
same as if the packet got lost and never arrived in the first place.   
It'll arrive again either with the missing data just before the FIN,  
or in a separate retranmission or any other non-data packets with the  
same sequence number as the FIN.

>>
>
> Actually it depends on how the reassembly queue is implemented, if you
> have a descriptor block for each data element sitting in the  
> reassembly
> queue, then you simply set a bit that indicating FIN is present which
> you could do for the last segment sitting in the reassembly queue.

The FIN occupies a specific byte in the sequence space.  You should  
still be able to attach the FIN at the end of the resequencing queue  
with a specific sequence number, you'd just have a length of zero with  
a bit saying that it contains the FIN.  Otherwise, you can always just  
ignore the FIN.

>> For reference the traditional reassembly queue implementation
>> doesn't care and queues any segment with FIN in any place.
>> Depending on the hole situation this can lead to strange
>> behavior and only ever partly dequeued data.

Yes, some interesting things could happen with the scenarios you  
mention, and not always the right thing.

			-David Borman

>>
>>
>> Any input, insight and discussion welcome. :-)
>
> I think it is an interesting discussion for sure :-). There are other
> cases which come to mind as well (half-close and simultaneous close
> cases)
>
> -Anantha
>>
>> --
>> Andre
>>
>> _______________________________________________
>> tcpm mailing list
>> tcpm@ietf.org
>> http://www.ietf.org/mailman/listinfo/tcpm
>>
> _______________________________________________
> tcpm mailing list
> tcpm@ietf.org
> http://www.ietf.org/mailman/listinfo/tcpm

_______________________________________________
tcpm mailing list
tcpm@ietf.org
http://www.ietf.org/mailman/listinfo/tcpm