Subject: Re: [tcpm] draft-ietf-tcpm-tcpsecure-00.txt

From: Mark Allman <[email-masked]>
Date: Tue, 04 May 2004 12:10:38 -0400

> I don't agree that the current proposal uses the "behavior
> described in 793" for protection.  Responding to a RST is
> not a correct behavior.  It is very clear in RFC 793 what
> a RST means.  A stack can ignore the RST (pretend that the
> RST is dropped elsewhere (-:), but responding to it is bad.
> I think any proposal suggesting a response to a RST is not
> acceptable to a host vendor.

I agree that the proposed scheme is not rfc793 conformant.  But, I don't
see how the last sentence above follows from the previous few.  We can
evolve and change.  RFC793 has been and will continue to be updated.
(I'm not arguing that the proposed change is The Way To Go, just trying
to understand your argument.)

Thanks!

allman

--
Mark Allman -- ICIR -- http://www.icir.org/mallman/

---

From: Mitesh Dalal <[email-masked]>
Date: Tue, 4 May 2004 11:24:43 -0700 (PDT)

> to understand your argument.)

Here are few of my thoughts to the above discussion:

There are 2 main aspects of our solution that needs justification
as to how they may fit into the existing spec.

1. Only an exact match RST is acceptable.
(as opposed to a RST within window)

2. Sending an ACK for an in-window RST
(as opposed to aborting the connection).

The case 1 above is easy to see. An RST is unreliable and can be
dropped in the network. Hence if we drop a RST that was in window
but not an exact match, we can safely assume that it was never send.
No harm done. I believe Kacheong and others have already figured this out.

Now case 2 above:

Here is a scenario which can readily happen with base spec.  A and
B are peers in ESTAB state.  B is sendind data to A.  data 2 gets
dropped.  B has a critical failure, decides to send a RST.  sequence
number 4 is within window of A.  A sends ACKs; which are in flight
relative to RST 4, for data 1 and 3 (hence I have shown the RST
to reach A after the ACK has been sent out).  But as far as B (and the
imaginary middlebox) is concerned, it appeared later in time wrt to
RST and may have actually be triggered by the RST itself.  B has no
way of knowing this. It will ultimately send an RST with a sequence
number that was borrowed from the ACK. So, if this scenario cannot be
successfully handled by middleboxes and endhosts, it may not be able
to handle our changes as well. The point I am trying to emphasize is
sending an ACK looks totally benign and is still looks like a plausible
scenario within the semantics of the base spec.

A				  B
|<----1---2-----3--------<--------|
|				  |
|               <--RST--4---------|
|---------> ACK 1-------->	  |
|---------> ACK 1 (for 3)	  |
|<---RST-4---			  |
|				  |
| <--RST-1------------------------|

similarly for the SYN part, ACKs from A to B maybe in flight, when
a SYN lands up at A. Middleboxes and endhost have no way of knowing
if the ACK was send after the SYN was received at A or otherwise and
given the liberal principle, they will still need to act on it based
on the guidelines laid down in 793.
Further, I even hypothesize that the middleboxes on receiving the
SYN, will actually send a RST to the inside endhost and not
simply forward the SYN and hence converting the SYN scenario to
a RST scenario. If there are no middleboxes, our fix is even more
cleaner (except for the very rare scenario where the SYN carries
an ISN that matches our rcv.nxt-1)

The above logic can be extrapolated if we put in a middlebox.
Difference will be seen based on where the RST gets dropped, between
the middlebox and B or between the middlebox and A. But since both
of them have equal probability of happening, we can safely disregard
the details.

Thanks
Mitesh

_______________________________________________
tcpm mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/tcpm

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Tue, 04 May 2004 15:34:17 -0400

Mitesh:

I agree with your logic.. but I think the salient point
that Kacheong and others are trying to make is on
a "hypothetical middle box"

This middle box:

a) When seeing a RST caches it in its state and marks the
     entry to be destroyed (the peer is gone now).
b) The RST arrives with the wrong seq number so the
     draft has them send  back an ACK.
c) The middle box gets this and realizes that the peer is
    gone (and so is the pin-hole in the firewall) so instead of
    following RFC793 it resends the cached RST instead of
    creating one from the ACK like it should
d) goto step <b>

Now first of all:

1) This is really silly behaviour... after all if you were to
     follow the spec you need LESS code and LESS state, i.e.
     why would you want to save a RST when you have to be
     capable of creating one from an ACK anyway (imagine the
     connection goes dormant for a LONG time.. and the middle
     box state gets cleaned up.. it has to know how to send a
     RST from the ACK).. and you store less in memory in your
     state blob..

2) No one has yet pointed to a middle box that does this... It is
    nothing but ... hey this could happen with a buggy middle box...AFAIK

I would like someone to point out an actual box that does this.. not 
something
from ten years ago.. but some network gear that is out there and
waiting for this pit to happen.. if it does exists then it is a concern 
since
you would have an ACK war until after the middle box cleaned up
its state (that could last minutes or more).

If this mythical box does not exist.. then its a moot point and not
an issue...

I can dream up hundreds of "broken middle box" scenarios that break
existing TCP and cause all sorts of other horrible things.. hey this and 
others
may be out there.. I would like to know if it is true... or just 
imagination...

R

-- 
Randall R. Stewart
ITD - Transport Technologies
815-477-2127(o) or 815-342-5222(c)

---

From: Kacheong Poon <[email-masked]>
Date: Tue, 04 May 2004 19:16:05 -0700

> to understand your argument.)

Having seen some ACK wars interacting with middlebox, I am not
comfortable with a change which responds to a RST, which is
supposed to tell the other side to stop sending.  It is similar to
responding to an ACK with an ACK.  As I mentioned before, I am
not against changing TCP.  But I think we should be careful
in doing it.

-- 

						K. Poon.
						[email-masked]

---

From: Mark Allman <[email-masked]>
Date: Tue, 04 May 2004 22:46:06 -0400

On the general notion, not any specifics that have been discussed thus
far ...

> existing TCP and cause all sorts of other horrible things.. hey this
> and others may be out there.. I would like to know if it is true... or
> just imagination...

There is some experience with throwing new things out that middleboxes
don't grok and therefore deal badly with (e.g., ECN).  So, I don't think
the middlebox concern is irrational.  However, I agree that we can take
this way too far and wave our hands at dozens or hundreds of potential
screw ups that are just not there.

It'd be good to run any suggestions through some common middleboxes to
see what might or might not happen.

allman

---

From: Kacheong Poon <[email-masked]>
Date: Tue, 04 May 2004 20:31:49 -0700

> scenario within the semantics of the base spec.

There are 1 ACK (because of the RST-4) and 2 more RSTs (because
of the 2 ACKs) missing from the above picture.  This brings up a
question.  The number of extra segments exchanged can be very
large.  The draft should at least put down the formula stating the
upper bound of the number of extra segments exchanged for a RFC793
conforming TCP as the sender of RST.  Note that the above case is
not the worst.  Another case can be like this.  Assume that there is
no re-ordering in the network, segment 2 is not lost in the above
picture but RST-4 is lost, and A does not do delayed ACK (just for
simplicity).  For every ACK B receives except the last ACK-3, it will
send a RST using an unacceptable sequence number to A.  And for each
of those RSTs, the modified stack will in turn send back an ACK,
which will trigger a RST, but should be acceptable to A now, from B.
This is not the worst case.  If re-ordering takes place, the extra
exchange can be worse.

Now if there is a middlebox which behaves in some interesting way...

The above scenario brings up an interesting observation.  Assume
that the RST attack is very easy to do and that the stack is modified
to send back an ACK for defense as described in the draft.  Since
the ACKs are most likely treated as duplicate ACKs in the receiver
of those ACKs and duplicate ACKs trigger fast retransmit and halving
the congestion window, does it mean that the RST attack is changed
to another form of DoS attack, slowing down the sender to always
have a cwnd of 1 MSS and trigger a lot of unnecessary retransmissions?
Actually, I think this slow down can also easily be done by simply
generating unacceptable segment as TCP will respond with an ACK.
Should this be also dealt with?

> of them have equal probability of happening, we can safely disregard

Honestly, I don't know how middlebox can behave.  But a one time
"challenge/response" can become an infinite loop.  I don't think the
gain justifies the risk.  Anyway, this is the last time I'll raise
this point again.  Other host vendors can voice their opinions,
maybe they are completely opposite to what I said...

-- 

						K. Poon.
						[email-masked]

---

From: Kacheong Poon <[email-masked]>
Date: Tue, 04 May 2004 20:37:54 -0700

Randall Stewart (cisco) wrote:

...

> may be out there.. I would like to know if it is true... or just 

I think Randy will probably have a different opinion if he had ever
worked in a company selling machines which need to talk to a lot of
broken TCP stacks...  No one knows who that broken box will hit, and
it may hit at the worst possible time.  There goes any uptime
guarantee...

-- 

						K. Poon.
						[email-masked]

---

From: Allwyn Carvalho <[email-masked]>
Date: Tue, 04 May 2004 22:04:41 -0700

I'm no TCP expert, but like someone else on this list, I've had to look into this issue because of the panic this vulnerability has created.

My first reaction to the Vulnerability Advisory was that it was overblown.  That said, my first reaction to the proposed fixes were that they were simple, clever, ingenous, and even though buggy, were at least in the right direction for a solution.

After going through the mail archives, I think some very valid points have been brought up.  If this i-d progresses, like others on this list, I think the possibility of a RST/ACK-war needs to be addressed, even if it's the fault of the other router/host/middlebox.

Another point I haven't seen discussed -- for the SYN attack, the i-d proposed solution is:

   A) If the SYN bit is set and the sequence number is outside the
      expected window, send an ACK back to the peer.
   B) If the SYN bit is set and the sequence number is an exact match to
      the next expected sequence (RCV.NXT == SEG.SEQ) then send an ACK
      segment to the peer but before sending the ACK segment subtract
      one from value being acknowledged.
   C) If the SYN bit is set and the sequence number is acceptable i.e.:
      (RCV.NXT < SEG.SEQ <= RCV.NXT+RCV.WND) then send an ACK segment to
      the peer.

Couple of questions:

1. For case B, I think you need to worry about RCV.NXT being in the range of [SEG.SEQ, SEG.SEQ + SEG.LEN] instead of simply being equal to SEG.SEQ.  For example, if SEG.SEQ is 1000 and RCV.NXT is 1001, it is still a special case.

2. Isn't the treatment of case C the same as case A?  If so, shouldn't this be re-phrased to make it less confusing?

Allwyn.

---

From: Mitesh Dalal <[email-masked]>
Date: Tue, 4 May 2004 22:05:08 -0700 (PDT)

> of the 2 ACKs) missing from the above picture.  This brings up a

thanks for clarifying the omission.

> conforming TCP as the sender of RST.  Note that the above case is

yes, something to this effect will be put in the next version of the draft.

> of those RSTs, the modified stack will in turn send back an ACK,

actually they will not be acceptable, since rcv.nxt would have moved
and the seq number of those incoming RSTs will now fall outside the
window of A and hence only the RST corresponding to the last ACK-3 will be
an exact match and acceptable.

> have a cwnd of 1 MSS and trigger a lot of unnecessary retransmissions?

yes, this was brought up earlier in the discussion by Wesley E. and
Mika L.

> generating unacceptable segment as TCP will respond with an ACK.

and thats what was my reply too ;)

> Should this be also dealt with?

this is one of the scenario in which the data injection part of our
fix will help.

thx
Mitesh

---

From: Anantha Ramaiah <[email-masked]>
Date: Tue, 4 May 2004 22:52:01 -0700 (PDT)

Allwyn,

> 1. For case B, I think you need to worry about RCV.NXT being in the range of [SEG.SEQ, SEG.SEQ + SEG.LEN] instead of simply being equal to SEG.SEQ.  For example, if SEG.SEQ is 1000 and RCV.NXT is 1…

Actually the revision to the draft (which will be posted soon) will
clarify the above more clearly and list out one of the corner cases where
if the sequence # chosen by the restarted host happens to be (seq# ==
RCV.NXT - 1) it would receive back an ACK = RCV.NXT which is an acceptable
ACK in which case the RST wouldn't be sent back and the host would timeout
the SYN. The next time if it attempts the SYN the initial sequence number
would be different and should work hunky-dory.

Actually some implementations treat a RST with SNDUNA -1 as a RST of a
keepalive packet and would consider the RST valid, but agreed it is
implementation specific. The reason I am pointing this is because we could
exploit this for modified case B) which would be re-worded as :
"if the SYN bit is set and the sequence # == next expected sequence - 1,
then send ACK to the peer with ACK# = RCVNXT - 1.

Actually there is no issue with B) above. Pl see my reply to one of
the earlier emails in this thread.

> 2. Isn't the treatment of case C the same as case A?  If so, shouldn't this be re-phrased to make it less confusing?

The reason it was posted seperately was that original RFC behaviour was to
abort the connection and send RST, in the current solution we send ACK
even for this case...

-Anantha

---

From: Mika Liljeberg <[email-masked]>
Date: Wed, 05 May 2004 18:57:09 +0300

> then send ACK to the peer with ACK# = RCVNXT - 1.

Actually, because of delayed acks, RCV.NXT may be different from the
left edge of the last advertised window. Hence, some implementations
store the last advertised window, and use that to validate incoming
RSTs.

	MikaL

---

From: Allwyn Carvalho <[email-masked]>
Date: Wed, 05 May 2004 09:13:41 -0700

Hi Anantha,
Thanks for your response.  See reply inline.

Anantha Ramaiah wrote:
[snip]
>>1. For case B, I think you need to worry about RCV.NXT being in the range of
>>[SEG.SEQ, SEG.SEQ + SEG.LEN] instead of simply being equal to SEG.SEQ.  For 
>>example, if SEG.SEQ is 1000 and RCV.NXT is 1001, it is still a special case.
> 
> 

I believe there are applications out there that will send <SYN, data, FIN> all in the 
first segment, and no it doesn't violate RFC 793.   I'm not so sure what will happen if 
they are partially acked.  Just making sure you cover this.

> abort the connection and send RST, in the current solution we send ACK

If you continue to keep A) and C) as separate cases, can you at least make sure that the 
wording is consistent.  One says "send an ACK back" and one says "send an ACK segment". 
It's a minor point, but I think it's important to be consistent.

Allwyn.

---

From: Mark Allman <[email-masked]>
Date: Wed, 05 May 2004 12:22:44 -0400

> comfortable with a change which responds to a RST, which is supposed
> to tell the other side to stop sending.  It is similar to responding
> to an ACK with an ACK.

I disagree.  ACKing an ACK is ... err, pointless (at least at first
blush).  Having some form of handshake to bring down a connection is
not, IMO.  I think these are two fundementally different situations.  If
we were to start from scratch today, we'd no-doubt invent some scheme so
that a RST had to include a handshake sort of thing, or that the RST had
to include some sort of a hash or nonce or something to prove it saw the
segment it is responding to (ala, the SCTP vtag scheme).  Given that,
can we make some sort of modest change to TCP to get such functionality?
Of course, we're not designing from a clean slate and so this is more
difficult.  But, I think ruling out a verification scheme out-of-hand is
not the right approach, because that is fundementally what we need.

> As I mentioned before, I am not against changing TCP.  But I think we
> should be careful in doing it.

Absolutely.

allman

---

From: Mark Allman <[email-masked]>
Date: Wed, 05 May 2004 12:37:11 -0400

> Since the ACKs are most likely treated as duplicate ACKs in the
> receiver of those ACKs and duplicate ACKs trigger fast retransmit and
> halving the congestion window, does it mean that the RST attack is
> changed to another form of DoS attack, slowing down the sender to
> always have a cwnd of 1 MSS and trigger a lot of unnecessary
> retransmissions?

Wes Eddy and I iterated about this and he posted this a couple weeks
ago: 

>> A connection could be slightly disturbed by RST probing that sent 3
>> segments per slice of sequence space.  If 3 duplicate acks were
>> generated then there could be an unwarranted congestion response as a
>> result of the RST attack on the other side.  Although not breaking
>> the connection, it could be slowed a bit, and the process might be
>> repeated.  This is probably not a huge issue.
>> 
>> The fix would just consist of not sending repeated ACKs for multiple
>> RSTs within the same window.

Someone then pointed out that this was really quite a minor interuption
-- especially compared to the massive number of RSTs required to trigger
it.  Wes and I agreed.

But, I am wondering if the above proposed rule (don't send repeated
"challenges" to RSTs in a given window ... or, maybe not more than 2) is
useful in preventing the infinite ACK/RST patterns you're worrying
about.  In other words, we take the stance that there is no reason to be
challenging a bunch of RSTs in a window and so they silently get
dropped.  The worst case is that the RSTs were legit (in window, but not
exact) and the challenges (ACKs) get lost.  In that case the connection
ends up holding state for a long time.  Does that case have low enough
probability to not worry about?

allman

---

From: Joe Touch <[email-masked]>
Date: Wed, 05 May 2004 10:15:35 -0700

Mark Allman wrote:
...
> probability to not worry about?

Doesn't this mean you can defeat someone else's ability to RST a 
connection by flooding them with RSTs?

Holding state for a long time in that case means one party can't reset a 
connection they want - or need to, doesn't it?

Joe

---

From: "Paul Goyette" <[email-masked]>
Date: Wed, 5 May 2004 10:15:27 -0700

> probability to not worry about?

Perhaps "Don't send repeated challenges with the same ACK value" would
be adequate?  Then you only need to keep track of one new state value,
the last value sent in a challenge ACK.  This should eliminate the ACK
war scenario.

---

From: Mark Allman <[email-masked]>
Date: Wed, 05 May 2004 13:22:57 -0400

> > "challenges" to RSTs in a given window ... or, maybe not more than
> > 2) is useful in preventing the infinite ACK/RST patterns you're
> > worrying about.  In other words, we take the stance that there is no
> > reason to be challenging a bunch of RSTs in a window and so they
> > silently get dropped.  The worst case is that the RSTs were legit
> > (in window, but not exact) and the challenges (ACKs) get lost.  In
> > that case the connection ends up holding state for a long time.
> > Does that case have low enough probability to not worry about?
> > allman
> 

I was sort of wondering if this could be gamed while I was typing.

> Holding state for a long time in that case means one party can't
> reset a connection they want - or need to, doesn't it?

So, sure ... if someone RSTs in your window and then a party in the
connection also wants to RST in that same window then you could be
hosed.  Seems like a low probability sort of event to me.  (At least
From a blind attacker -- which is the context of the fix.)  Am I
misrepresenting the chances of this?

allman

---

From: Mark Allman <[email-masked]>
Date: Wed, 05 May 2004 13:26:12 -0400

> the last value sent in a challenge ACK.  This should eliminate the ACK

But, then you're depending on the other side.  If you just place a limit
on the number of acceptable RSTs a host will accept (& respond to) then
that's a local decision.  If the point is to avoid a war because of some
sort of buggy something then it would seem best to pick an avoidance
strategy that didn't also involve the buggy something.  (At least that
makes sense to me as an initial thought.  I could be wrong.)

allman

---

From: Mark Allman <[email-masked]>
Date: Wed, 05 May 2004 13:27:50 -0400

> reset a connection they want - or need to, doesn't it?

Oh, well another approach I'll throw out is not more than one RST
challenge per time period.  E.g., no more than 1/second.  That limits
the damage of an ACK war without allowing someone to deny the legitimate
ripping down of a connection for minutes.  (At the expense of some
state.)

allman

---

From: Joe Touch <[email-masked]>
Date: Wed, 05 May 2004 10:30:59 -0700

Low probability for sure, but if we're talking about security, it should 
be included in the revision at least...

Joe

---

From: Mark Allman <[email-masked]>
Date: Wed, 05 May 2004 13:55:35 -0400

> Low probability for sure, but if we're talking about security, it
> should be included in the revision at least...

Oh, sure!  If one were to include an idea like this in any draft then it
and its implications and failings should be fully addressed.

allman

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Wed, 05 May 2004 14:02:44 -0400

Allwyn:

One comment in line has editor/typest :-0

Allwyn Carvalho wrote:

>>> [SEG.SEQ, SEG.SEQ + SEG.LEN] instead of simply being equal to 
>>> SEG.SEQ.  For example, if SEG.SEQ is 1000 and RCV.NXT is 1001, it is 
>>> still a special case.
>>
>>
>>
> I believe there are applications out there that will send <SYN, data, 
> FIN> all in the first segment, and no it doesn't violate RFC 793.   
> I'm not so sure what will happen if they are partially acked.  Just 
> making sure you cover this.
>
>>
>>> 2. Isn't the treatment of case C the same as case A?  If so, 
>>> shouldn't this be re-phrased to make it less confusing?
>>
>>
>>
> If you continue to keep A) and C) as separate cases, can you at least 
> make sure that the wording is consistent.  One says "send an ACK back" 
> and one says "send an ACK segment". It's a minor point, but I think 
> it's important to be consistent. 

Ok I have changed these to both say
send an ACK segment....

R

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Thu, 06 May 2004 06:29:47 -0400

>not the right approach, because that is fundementally what we need.
Well, has Kacheong as put forward earlier.. one could
always use a similar scheme to SCTP... pick a random hash
and add it to every packet. Then RST's and such could
validate this hash. But that does not cover the SYN
in window issue I think.. or am I missing something?

In SCTP we always respond to the SYN equivilant  (INIT) with
a SYN-ACK sort of thing (INIT-ACK) but we never change the
state of the existing connection... The SYN sender must instead
send back a cooke that is in the INIT-ACK...  and then finally
a COOKIE-ACK is sent (a fourth leg in the handshake).
I do know that cookie's have been done in TCP and some
implementations do them.. not sure how they work since
I know its still a 3-way handshake and I think the SYN problem
still exists... ???

R

Of course I

---

From: "Paul Goyette" <[email-masked]>
Date: Thu, 6 May 2004 06:50:11 -0700

> the last value sent in a challenge ACK.  This should eliminate the ACK

At least one person took this to mean that I was suggesting we select a
_new_ ACK value for repeated RST segments.  That's not what I meant.

The intent of this is "If the value in the challenge ACK would be the
same as the value sent in the previous challenge ACK, don't send any
ACK at all."

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Thu, 06 May 2004 11:30:49 -0400

>same as the value sent in the previous challenge ACK, don't send any

Hmm.. that would surely prevent any ACK war from
occuring...

R

---

From: "Paul Goyette" <[email-masked]>
Date: Thu, 6 May 2004 08:58:20 -0700

> > ... "If the value in the challenge ACK would be the
> > same as the value sent in the previous challenge ACK, don't 
> > send any ACK at all."
>  
> Hmm.. that would surely prevent any ACK war from occuring...

Of course, if the one-and-only challenge ACK we send gets lost
in transit (or blocked by a middlebox), then the peer doesn't 
get a chance to send us a corrected RST, and we won't ever tear 
down our half of the session.  But that's no different than if
the RST got lost.

---

From: Tim Shepard <[email-masked]>
Date: Thu, 06 May 2004 13:09:00 -0400

> Hmm.. that would surely prevent any ACK war from

But what if the previous challenge ACK was dropped?

			-Tim Shepard
			 [email-masked]

---

From: Mark Allman <[email-masked]>
Date: Thu, 06 May 2004 13:24:43 -0400

> same as the value sent in the previous challenge ACK, don't send any

As the one person, I'll just note that I didn't understand what Paul
was saying and that the above sounds fine to me -- even though that
might not have been the impression I gave yesterday.

allman

---

From: Mark Allman <[email-masked]>
Date: Thu, 06 May 2004 13:52:51 -0400

> But what if the previous challenge ACK was dropped?

I think you have to allow a small number to be sent.  Like three sounds
like a good number.  It seems that the probabilities are way on your
side at that point.  And, the downside is that one connection is going
to hang around in established far too long -- which could be a resource
problem.  But, given the probability of all this happening I am
comfortable with it.  But, that's just me.

allman

---

From: Mitesh Dalal <[email-masked]>
Date: Fri, 7 May 2004 09:45:09 -0700 (PDT)

> Hmm.. that would surely prevent any ACK war from

this might not work. For a long lived connection, your rcv.nxt wouldnt
budge much in between data transfers. So  if an attacker sends you 1
RST in window, it would effectively shut you down from sending any
more challenges as long we are at the same rcv.nxt ? Did I read this
correctly ?

thanks
Mitesh

---

From: David Borman <[email-masked]>
Date: Fri, 7 May 2004 13:02:42 -0500

A few thoughts.

First, one should not think of this as the RST is getting ACKed.  I 
think of it more as a potentially bogus RST has arrived, so we drop it, 
but then do a probe of the remote side by sending a current ACK, on the 
off chance that it was a valid RST.  The ACK is not generated using any 
state from the RST packet, it is generated entirely from our current 
connection state.

Second, aside from the ABORT case (RFC 793, pg 62), all RST packets are 
generated in direct response to an invalid packet being received, and 
the RST takes its seq or ack value directly from the RST packet.  If 
the ACK bit was set in the offending packet, the RST is:
		<SEQ=SEG.ACK><CTL=RST>
And if the ACK bit is not set, the RST is:
		<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
Any implementation that generates RST packets and does not take the 
seq/ack value from the offending packet is in violation of RFC793.

If the spontaneous RST generated due to an ABORT is questionable (if 
data was sent and lost before the ABORT), then the ACK generated by the 
remote side will cause a new RST to be generated, and it should be 
acceptable since it takes its values from the ACK packet.

Third, I think the conservative approach would be to limit the RST 
challenge to ESTABLISHED state, since that is the state at which the 
main problem lies.  And while a misbehaving middle should not be 
ignored, they should not have undue influence on changes to TCP.  By 
their very nature they get in the way of TCP.  Any box can get into 
trouble when another host changes is some manner, causing the box to go 
down a processing path that it hasn't used before.  The broken box 
needs to be fixed, the rest of the world shouldn't change to 
accommodate the broken box.

Fourth, somthing that I haven't seen yet, RST packets that have the ACK 
bit set should probably always be ignored in ESTABLISHED and later 
states.  Assuming we are sending proper packets, we should only get a 
RST-ACK in response to our SYN.  About the only valid scenario that I 
can see for that is if we send a SYN, retransmit the SYN (or it gets 
duplicated in the network), then get a SYN-ACK in response to the first 
SYN, and we send our SYN-ACK and enter ESTABLISHED state.  Meanwhile, 
the other side aborted the connection while in the SYN-RECEIVED state, 
before the second SYN arrives, and so when the retransmitted SYN 
arrives, a RST is generated with the ACK bit set.  But we should also 
get a RST in response to our SYN-ACK, without the ACK bit set, so if we 
ignore the RST with the ACK bit, we'll still get the connection closed 
by the second RST.  (Note: The RST generated due to the ABORT call will 
be <SEQ=SND.NXT><CTL=RST>, so that should also be acceptable and cause 
our side to be dropped.)

			-David Borman

---

From: "Paul Goyette" <[email-masked]>
Date: Fri, 7 May 2004 11:07:57 -0700

you read it right.

But the effect of this is no different than if the RST gets lost.

If an attacker sends us the RST, then the real peer tries to reset,
we would ignore the real peer, and things would just have to time
out.

-----Original Message-----
From: Mitesh Dalal [mailto:[email-masked]]
Sent: Friday, May 07, 2004 9:45 AM
To: Randall Stewart (cisco)
Cc: Paul Goyette; [email-masked]
Subject: Re: [tcpm] draft-ietf-tcpm-tcpsecure-00.txt

thanks
Mitesh

---

From: Joe Touch <[email-masked]>
Date: Fri, 07 May 2004 11:35:37 -0700

> state from the RST packet, it is generated entirely from our current 

This is confusing. The current connection state isn't what causes the 
ACK to occur - i.e., it's not a timeout, etc.

The received RST is what causes the ACK. It may be interesting that the 
contents of the ACK are otherwise unrelated to the RST, except for the 
following fields:
	IP src/dst address
	TCP src/dst port numbers
	RST seq number (inside the window, but not at the end)
That seems like the ACK is directly generated from the RST to me ;-)

> the RST takes its seq or ack value directly from the RST packet.  If the 
                                      ^^^^^^^^^^^^^^^^^^^^^
directly from the invalid packet, right?

> ACK bit was set in the offending packet, the RST is:
>         <SEQ=SEG.ACK><CTL=RST>

As already discussed, in the meantime new data can arrive at the 
receiver (out of order delivery), in which case it's possible that there 
are as many additional ACKs and RSTs flinged about as there were packets 
in the pipe. At least - more if data is lost.

> down a processing path that it hasn't used before.  The broken box needs 
> to be fixed, the rest of the world shouldn't change to accommodate the 
> broken box.
> 
> states. 

I thought the RST-ACKs' being mentioned were really just ACKs, not RSTs 
with the ACK bit set. Setting the RST bit overrides the ACK bit anyway 
(it gets processed first), and will kill the other side ;-)

> Assuming we are sending proper packets, we should only get a

---

From: Mitesh Dalal <[email-masked]>
Date: Fri, 7 May 2004 12:35:36 -0700 (PDT)

> That seems like the ACK is directly generated from the RST to me ;-)

the point that David is trying to make, IMO, is that looking at the
ACK there is no way you can tell that it was caused because of an RST.
It might have been a valid ACK or caused by an out of seq segment, or
an invalid ACK or out of window SYN coming in an ESTAB or other places
that 793 tells you to send an ACK.

> > the RST takes its seq or ack value directly from the RST packet.  If the

yes.

> in the pipe. At least - more if data is lost.

but in this case, the ack/rst rtt will not be more than 2. (there
might be more packets, but no more than 2 loops)

thx
Mitesh

---

From: David Borman <[email-masked]>
Date: Fri, 7 May 2004 14:37:20 -0500

On May 7, 2004, at 1:35 PM, Joe Touch wrote:

>> think of it more as a potentially bogus RST has arrived, so we drop 
>> it, but then do a probe of the remote side by sending a current ACK, 
>> on the off chance that it was a valid RST.  The ACK is not generated 
>> using any state from the RST packet, it is generated entirely from 
>> our current connection state.
>
> The received RST is what causes the ACK. It may be interesting that 
> the contents of the ACK are otherwise unrelated to the RST, except for 
> the following fields:
> 	IP src/dst address
> 	TCP src/dst port numbers

One can view a RST as an out-of-band mechanism to tell someone to abort 
a connection (FIN is the in-band mechanism).  If I'm told to abort a 
connection, but I don't think the request came from the other side, 
then the smart thing to do is to explicitly ask the other side if they 
really want to close the connection.  The ACK is generated using 
connection state, not the information in the RST packet.  The fact that 
the src/dst addr/port are the same between the connection state and the 
RST packet is a red herring; if they weren't the same, the RST would 
never has been associated with this connection.  What is important is 
that the SEG.SEQ   SEG.ACK fields are filled in with information from 
the connection state, not from any information in the RST packet.
>
>> Second, aside from the ABORT case (RFC 793, pg 62), all RST packets 
>> are generated in direct response to an invalid packet being received, 
>> and the RST takes its seq or ack value directly from the RST packet.  
>> If the
>                                      ^^^^^^^^^^^^^^^^^^^^^
Yes, that's what I meant to say.

>> data was sent and lost before the ABORT), then the ACK generated by 
>> the remote side will cause a new RST to be generated, and it should 
>> be acceptable since it takes its values from the ACK packet.
>
> receiver (out of order delivery), in which case it's possible that 
> there are as many additional ACKs and RSTs flinged about as there were 
> packets in the pipe. At least - more if data is lost.

Yes, I know, but it is still deterministic.  Even with the way things 
are today, if you send a bunch of data (that gets reordered along the 
way), and then ABORT the connection, the receiver will still be 
generating ACKs for all the out-of-order packets, each of which will 
cause another RST to be sent back to us.  The fact that we can 
construct scenarios where there is a flurry of packets while things 
converge doesn't bother me a lot, as long as things are deterministic 
and we don't get into infinite loops.  And the only way I see getting 
into infinite loops is by a broken implementation.

>> trouble when another host changes is some manner, causing the box to 
>> go down a processing path that it hasn't used before.  The broken box 
>> Fourth, somthing that I haven't seen yet, RST packets that have the 
>> ACK bit set should probably always be ignored in ESTABLISHED and 
>> later states.
>
> I thought the RST-ACKs' being mentioned were really just ACKs, not 
> RSTs with the ACK bit set. Setting the RST bit overrides the ACK bit 
> anyway (it gets processed first), and will kill the other side ;-)

Which could be a bad thing, because if you get a RST with the ACK bit 
set, the only thing you should use to verify the RST is the ack field, 
but the RST gets processed first, killing the connection even if the 
ack field was bogus.  The SEG.SEQ value should be zero, so if the 
sequence number checks are applied even though it isn't valid, then it 
gets tossed early.  (Another thought is that if you get an RST with the 
ACK bit set and SEG.SEQ != 0, that's a bogus RST and should be tossed.  
In all instances in 793 where the ACK bit is set when generating a RST, 
the SEG.SEQ is explicitly set to zero.)  In SYN-SENT state 793 verifies 
SEG.ACK before checking the RST bit.  In ESTABLISHED and later, SEG.SEQ 
is verified first, then the RST bit, then SEG.ACK is verified.  But if 
both the RST and ACK bits are set, we shouldn't be doing SEG.SEQ 
checks, because SEG.SEQ is not valid, and we should be verifying 
SEG.ACK before accepting the RST.

			-David Borman

---

From: Joe Touch <[email-masked]>
Date: Fri, 07 May 2004 13:00:33 -0700

> that 793 tells you to send an ACK.

Certainly; I took the point as relating to the RST/ACK wars issue, 
though. In that sense, they are directly related.

....
> might be more packets, but no more than 2 loops)

Each data ACK, as you observe above, cannot be distinguished from a 
RST-triggered "here's my end of window" ACK. Which means EVERY ACK will 
generate a RST.

I.e., there could be as many RST/ACKs as there are packets in the pipe.

Joe

---

From: Joe Touch <[email-masked]>
Date: Fri, 07 May 2004 13:07:36 -0700

David Borman wrote:

> connection, but I don't think the request came from the other side, then 
> the smart thing to do is to explicitly ask the other side if they really 
> want to close the connection.  The ACK is generated using connection 
> state, not the information in the RST packet.  The fact that the src/dst 
> addr/port are the same between the connection state and the RST packet 
> is a red herring; if they weren't the same, the RST would never has been 
> associated with this connection.  What is important is that the 
> SEG.SEQ   SEG.ACK fields are filled in with information from the 
> connection state, not from any information in the RST packet.

The event of the ACK is the reaction to the event of the RST 
(cause/effect). The contents of the ACK may not be directly related, but 
the events are, which is why the RST/ACK flurry can ensue. If they were 
completely decoupled (cause/effect), flurries couldn't occur.

...
> cause another RST to be sent back to us.  The fact that we can construct 
> scenarios where there is a flurry of packets while things converge 
> doesn't bother me a lot, as long as things are deterministic and we 
> don't get into infinite loops.  And the only way I see getting into 
> infinite loops is by a broken implementation.

Agreed - not a loop, but it can persist, during which a large number of 
RSTs go into the pipe.

If any one of them wins, subsequent RSTs can abort further connection 
attempts - or possibly even kill new connections (consider a case where 
a RST goes by a long path and the path changes enough that the new short 
path enables a three-way handshake in the meantime). Maybe that's not 
critical, but worth considering.

> but the RST gets processed first, killing the connection even if the ack 
> field was bogus. 

Even the current rules in 793 indicate checking that the segment is 
inside the window FIRST, before acting on the RST.  (I'm not sure how 
the rest of this paragraph applies in that case).

Joe

> The SEG.SEQ value should be zero, so if the sequence 
> number checks are applied even though it isn't valid, then it gets 
> tossed early.  (Another thought is that if you get an RST with the ACK 
> bit set and SEG.SEQ != 0, that's a bogus RST and should be tossed.  In 
> all instances in 793 where the ACK bit is set when generating a RST, the 
> SEG.SEQ is explicitly set to zero.)  In SYN-SENT state 793 verifies 
> both the RST and ACK bits are set, we shouldn't be doing SEG.SEQ checks, 
> because SEG.SEQ is not valid, and we should be verifying SEG.ACK before 
> accepting the RST.
> 
>             -David Borman

---

From: David Borman <[email-masked]>
Date: Fri, 7 May 2004 15:25:14 -0500

On May 7, 2004, at 3:07 PM, Joe Touch wrote:

>> set, the only thing you should use to verify the RST is the ack 
>> field, but the RST gets processed first, killing the connection even 
>> if the ack field was bogus.
>

That's checking that SEG.SEQ is inside the window.  But if you get a 
RST packet with the ACK bit set, then SEG.SEQ is invalid (and should 
always be zero), so you should not be submitting it to the normal 
in-window SEG.SEQ number checks.  RFC 793 does not address this 
situation.

			-David Borman

---

From: Joe Touch <[email-masked]>
Date: Fri, 07 May 2004 14:03:53 -0700

David Borman wrote:

> That's checking that SEG.SEQ is inside the window.  But if you get a RST 
> packet with the ACK bit set, then SEG.SEQ is invalid (and should always 
> be zero), so you should not be submitting it to the normal in-window 
> SEG.SEQ number checks.  RFC 793 does not address this situation.
> 
>             -David Borman

If you're in ESTABLISHED, there's a 4-case window check. (pg 79 rfc793) 
That happens before any RST or ACK processing. It seems like it's 
directly addressed, perhaps not in the way you suggest though.

Joe

---

From: "Randall Stewart (cisco)" <[email-masked]>
Date: Fri, 07 May 2004 17:38:39 -0400

Paul:

Then I must be reading something wrong :-0

I thought you meant that if I receive a RST(SEQ=X) then
I would do the first time:

send-ack(challege)
store X in Last_RST_At

The next time I receive a reset in window I would do
if(Last_RST_At != Seq) {
   send-ack(challeng)
   store X in Last_RST_At
}

So you end up with one mark within the valid rcv-window that
is "ignore this and send no challege"...

So if A real guy happens to send a RST().. you would challenge
as long as by chance the guy did not pick that 1 in your window
value...

R

---

From: David Borman <[email-masked]>
Date: Fri, 7 May 2004 16:40:21 -0500

...
>>> inside the window FIRST, before acting on the RST.  (I'm not sure 
>>> how the rest of this paragraph applies in that case).
> If you're in ESTABLISHED, there's a 4-case window check. (pg 79 
> rfc793) That happens before any RST or ACK processing. It seems like 
> it's directly addressed, perhaps not in the way you suggest though.

No.  That 4-case window check is all about verifying SEG.SEQ, and in 
the case of a RST with the ACK bit set, SEG.SEQ is invalid.  It doesn't 
make sense to check something that is by definition invalid.

			-David Borman

---

From: Joe Touch <[email-masked]>
Date: Fri, 07 May 2004 14:45:08 -0700

David Borman wrote:

> No.  That 4-case window check is all about verifying SEG.SEQ, and in the 
> case of a RST with the ACK bit set, SEG.SEQ is invalid.  It doesn't make 
> sense to check something that is by definition invalid.
> 
>             -David Borman

I agree, but it seems that RFC793 is fairly clear on doing the check 
anyway, isn't it?

Joe

---

From: Mika Liljeberg <[email-masked]>
Date: Sat, 08 May 2004 01:09:31 +0300

> in-window SEG.SEQ number checks.  RFC 793 does not address this 

That's not entirely accurate. The reset generation rules in RFC 793
leave ack undefined for an RST generated in synchronised state in
response to a segment with the ACK bit set:

    If the incoming segment has an ACK field, the reset takes its
    sequence number from the ACK field of the segment, otherwise the
    reset has sequence number zero and the ACK field is set to the sum
    of the sequence number and segment length of the incoming segment.
    The connection remains in the same state.

Therefore an RST sent in synchronised state may or may not have the ACK
bit set. The reset validation rules are consistent with this. Only the
sequence number is checked, the ack is not.

	MikaL

---

From: David Borman <[email-masked]>
Date: Fri, 7 May 2004 22:00:44 -0500

On May 7, 2004, at 4:45 PM, Joe Touch wrote:

>>>> rfc793) That happens before any RST or ACK processing. It seems 
>>>> like it's directly addressed, perhaps not in the way you suggest 
>>>> though.
>> the case of a RST with the ACK bit set, SEG.SEQ is invalid.  It 
>> doesn't make sense to check something that is by definition invalid.
>>             -David Borman
>

Sure its clear, but that doesn't make it right.  RFC 793 is not 
perfect, RFC 1122 is proof of that.

			-David Borman

---

From: Joe Touch <[email-masked]>
Date: Mon, 10 May 2004 11:20:42 -0700

David Borman wrote:

> Sure its clear, but that doesn't make it right.  RFC 793 is not perfect, 
> RFC 1122 is proof of that.
> 
>             -David Borman

Certainly; I didn't catch whether you were talking about what 793 said 
or should say.

FWIW, Ian Heavens had a small group in 1997 that was looking into 
various mods to RSTs, which included adding 'types' and possibly ACKs. 
He also had a draft that looked at the probabilty of a number of kinds 
of RST attacks and failures in a 1997 I-D. ;-)

Perhaps it's worth revisiting this sort of "RST Taxonomy", including 
proposed mods (to discuss them, rather than recommend any)?

Joe