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

Jakob Heitz <> Sun, 24 February 2008 02:00 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id B0B9A3A6AE1; Sat, 23 Feb 2008 18:00:41 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -0.378
X-Spam-Status: No, score=-0.378 tagged_above=-999 required=5 tests=[AWL=-0.540, 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 ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 5-hXp9o3qyvl; Sat, 23 Feb 2008 18:00:40 -0800 (PST)
Received: from (localhost []) by (Postfix) with ESMTP id 819E53A68A7; Sat, 23 Feb 2008 18:00:40 -0800 (PST)
Received: from localhost (localhost []) by (Postfix) with ESMTP id E8E383A6AC3 for <>; Sat, 23 Feb 2008 18:00:38 -0800 (PST)
X-Virus-Scanned: amavisd-new at
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id fzn-1QZk3i-6 for <>; Sat, 23 Feb 2008 18:00:37 -0800 (PST)
Received: from ( []) by (Postfix) with ESMTP id DCCF93A6780 for <>; Sat, 23 Feb 2008 18:00:37 -0800 (PST)
Received: from localhost (localhost []) by (Postfix) with ESMTP id 43E4A56FB26; Sat, 23 Feb 2008 18:00:33 -0800 (PST)
Received: from ([]) by localhost (prattle []) (amavisd-new, port 10024) with ESMTP id 15762-03; Sat, 23 Feb 2008 18:00:33 -0800 (PST)
Received: from [] ( []) by (Postfix) with ESMTP id 5F75E56FB24; Sat, 23 Feb 2008 18:00:32 -0800 (PST)
Message-ID: <>
Date: Sat, 23 Feb 2008 18:00:33 -0800
From: Jakob Heitz <>
User-Agent: Thunderbird (Windows/20071031)
MIME-Version: 1.0
To: Andre Oppermann <>
References: <> <> <> <> <> <>
In-Reply-To: <>
X-Virus-Scanned: by amavisd-new at
Cc: David Borman <>,, "Anantha Ramaiah (ananth)" <>
Subject: Re: [tcpm] Handling of FIN in the reassembly queue
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <>
List-Unsubscribe: <>, <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Andre Oppermann wrote:
> David Borman wrote:
>> On Feb 22, 2008, at 1:38 PM, Anantha Ramaiah (ananth) wrote:
> David, Anantha,
>>> David,
>>>   Pl see inline..
>>>> 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.
>>> Agreed. Just to be clear, the rationale for me suggesting to drop the
>>> segment with FIN in this case is :
>>> If this is a genuine FIN, it would get retransmitted again. So you know
>>> what to do the next time, ie., So just give it a chance one time, I
>>> think this is more safer and robust but YMMV.
>> Well, now you have to remember that you previously got this FIN, so that 
>> if it shows up again out of sequence you can do something different.  I 
>> don't like that additional complexity.  Keep it simple.  (Or are you 
>> saying just keep ignoring the out-of-sequence FIN until the holes are 
>> filled and it shows up in sequence?)
>>>>>> 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.
>>> Well, we have already received a FIN, which means that ( going by your
>>> CLOSEWAIT state example) we don't want to accept any data beyond this as
>>> per RFC. Now we got a FIN which is way before the current sequence
>>> number, in which case I would think it makes sense to ignore it. My
>>> consistency reasons are :-
>>> - if it would have been received in-order, we would have moved to
>>> CLOSEWAIT and would have discarded the new FIN as duplicate ( the
>>> receive window already slided, app might have already the data). TCP
>>> window slides forward and in this and there is no provision for data
>>> "overwrite".
>> But we haven't processed that data & FIN yet, because they came out of 
>> order.  They are to be processed in SEG.SEQ order, which means the 
>> earlier FIN is processed first (unless you received something like 
>> SEG1.SEQ=100,LEN=100,FIN and then SEG2.SEQ=150,LEN=0,FIN, in which case 
>> the later sequenced FIN would be processed first...)
>> The bottom line is that if you have two FINs, or data beyond a FIN, the 
>> connection is screwed up and it probably isn't worth putting much effort 
>> into dealing with this scenario.  Certainly it is not worth trying to 
>> optimize.  Your safest bet is to go to a fallback position and toss all 
>> the suspect data.  So, I'll stick with my original suggestion that all 
>> the out of sequence data after the earlier (sequence numbered) FIN be 
>> thrown away.  But we should probably also throw away the earlier FIN 
>> (and any data that it arrived with).  Then we've tossed all the suspect 
>> data, and the other side can retransmit what it thinks is the correct 
>> data, assuming it is able to do so.
> After reading and sleeping one night over this excellent discussion I realized
> that we are unsafe at any speed here.
> We may get hit with a FIN attack just as we may get hit with a RST attack.
> A FIN anywhere in the window is valid and gets queued in the reassembly
> queue for later processing.  This wrecks a TCP session by either ending
> it prematurely in one direction (accepting the FIN closest to left edge),
> or by preventing its legitimate ending (accepting only the first FIN and
> waiting for data that never comes).  This is a serious threat.  Maybe even
> more so than a pure RST attack with the same complexity.  It is much more
> subtle and can cause long hangs for TCP based protocols that do not have
> their own keepalive ping exchange.  tcpsecure doesn't even mention it.
> I guess nodoby thought of the reassembly and its effects yet.  FIN deserves
> its own section as well.
> The solution I've come up with is to only accept a FIN when it matches the
> left edge (rcv_nxt) either perfectly or accompanied by data that advances
> rcv_nxt (the missing segment).  All data beyond that point in the reassembly
> queue is then to be flushed.  All FINs that do not fulfill this condition are
> to be ignored and not queued.  The only remaining question then is whether to
> ignore the whole segment data that came with the FIN.  Probably not.  We can't
> say if this is real FIN or not and consequently we can't say whether the
> segment data is real or not.  We however have to assume it is real because
> we don't have any evidence to the contrary (provided all tcp input validity
> checks have been done previously).  This is a quite simple solution and it
> avoids a lot of complexity in FIN handling in the reassembly queue.
> If my reasoning and rationale is agreed with I can write up a FIN section
> for tcpsecure over the next few days.

You are free to drop any received data (including FIN) that you
have not yet acknowledged. The peer will retransmit. I suggest you
drop any segment that contains a suspicious FIN, and I stress drop
the whole segment. After all, if the FIN is suspicious, it will make
the rest of the segment suspicious too. I would call a FIN suspicious
if the resequencing queue contains any data (or another FIN) with a
higher sequence number. I would then drop all of this data higher in
the resequencing queue as well. All data in the resequencing queue
has not been acknowledged (even if it's SACKed) and the peer will

Jakob Heitz.
tcpm mailing list