Subject: [tcpm] Some ideas building on draft-ietf-tcpm-fastopen-01

From: <[email-masked]>
Date: Fri, 27 Jul 2012 06:19:49 +0100

Yuchung, Jerry, Sivasankar, Arvind,

I liked this enough to want to work on improving it. I have a couple of proposals that occurred to me, which I've finally made time to write up.

(I'll send editorial nits from reviewing the draft later)

==Proposal #1/ ==
Fast Open Cookie Request MUST (SHOULD?) be on a FIN

I believe it would be better for the reasons below if:
* the client put a fast open cookie request in its FIN, not its SYN (whether or not the server has sent a FIN first).
* Then the server can send the fastopen cookie on the FIN-ACK.
* If the client times out waiting for a FIN-ACK, it just re-sends as usual.
* If the server's FIN-ACK never arrives (perhaps because a middlebox has eaten it), the client just doesn't have a cookie for the next session and uses a 3WHS as normal.

Note, only the Request would have to be on a FIN. The Fast Open Cookie itself would obviously still be on the SYN of subsequent connections. Then, when a subsequent connection finishes, it can refresh the cookie on its FIN, ready for another connection later.

This solves a couple of potential problems with a fastopen request-response on the initial SYN exchange:
a) A FIN-cookie sidesteps the risk of unpredictable delay of the very first SYN due to some middleboxes dropping new TCP options (any timeouts due to non-delivery don't hold up the session, which has already finished)
b) Transports GETting typical Web pages could (ab)use the fastopen cookie on the SYN exchange by opening multiple TCP connections during the initial connection without each one suffering the delay of a 3WHS. This creates a perverse incentive to use multiple parallel connections, because you can get the same latency benefit as HTTP pipelining [Yoshifumi posed this problem some time ago].  If clients can only request a fastopen cookie on a FIN, they don't have this perverse incentive to not bother with pipelining.

I have no evidence, but it seems intuitive that if the TCP option got through on the first FIN, it might be more likely to get through on the next SYN, altho I admit options on SYNs are looked at more closely by middleboxes.

==Proposal #2/ ==
Fastopen cookies (optionally) authenticate both the client's network address and the its knowledge of the TCP timestamp option on the segment carrying the server's cookie.

I would like to propose that if the server TCP-timestamps the segment carrying its cookie, the client MUST use a timestamp option on the segment that starts the subsequent fast open, and in its timestamp echo field it must echo the timestamp sent with the earlier cookie. Then:
i) the server can use the timestamp as part of the material for generating and validating the cookie and
ii) the server can set an expiry_duration, and check whether the echoed timestamp is older than time(now) - expiry_duration.

Reasoning:
The draft currently says:
"   3. The cookie expires after a certain amount of time. The reason is
       detailed in the "Security Consideration" section. This can be
       done by either periodically changing the server key used to
       generate cookies or including a timestamp in the cookie.
"

Let's take each in turn:
* Periodically changing the server key: Let's imagine the key changes every 30 min. Then all cookies issued in the last 30 mins stop being useful, even those just issued a second ago, or a minute ago, or 15 minutes ago...
* Including a timestamp in the cookie. This is only useful if the timestamp is in the clear within the cookie, otherwise the server cannot use it to key the cookie. But a timestamp in the clear takes valuable bits away from the cookie, weakening its strength. This is unnecessary if there's already space for a timestamp option on the segment (which is very common).

Security Considerations mentions only two ways a client can collect valid cookies from other hosts:
i) compromising other hosts, or
ii) (legally) taking over the lease of an IP address from a DHCP server.
But there is a much more problematic third way:
iii) sitting behind the same NAT as a neighbour (esp. a carrier-grade NAT serving thousands of clients), where the NAT uses a common IP address for many clients.

As it stands, the cookie is only dependent on the client's network address. Binding a TCP timestamp option into the cookie as well adds a lot more entropy.

With only the IP address for entropy, a client behind a NAT (or an attacker in control of a compromised host behind a NAT) can get its own (valid) cookie and use it in a brute-force spoof of numerous neighbouring clients - to either SYN-flood the server or launch a reflection attack on its neighbours by fast-opening loads of new TCP connections requesting large data items on behalf of its neighbours, bypassing the safety check of the 3WHS.

In contrast, if a cookie depends on both the client's network address and server's timestamp, a cookie requested by a client behind a NAT will only be the same as a neighbours cookie served by the same server within the same clock tick.

This doesn't stop attackers getting valid cookies from compromised hosts, but it does effectively prevent these more trivial attacks on neighbours.

==Proposal #3/ ==
Special cookie values

(A minor point compared to the two above)

4.1.2 Server Cookie handling

"  Also note the server may want to use special cookie values, e.g.,
   "0", for specific scenarios. For example, the server wants to notify
   the client the support of TFO, but chooses not to return a valid
   cookie for security or performance reasons upon receiving a TFO
   request.
"

I suggest the server just returns the cookie option with length 2 and no cookie data, to show it supports the option, but chooses not to give a cookie. Then the server doesn't have to run an extra 'if' test every time it generates a cookie, just to check the cookie doesn't collide with a special value.

This would require the value of the cookie option request kind to be different from the cookie option kind. Otherwise a response meaning "cookie supported but empty" would be confused with a cookie request for the half-connection in the opposite direction.

== Outstanding concern ==

Similar to a concern of Joe Touch's and Richard Scheffeneger's: dividing up TCP implementations into ones with idempotent semantics and ones without. This confuses the simple applicability of TCP. We need to work on that - but manyana.

Bob

[PS. Apologies if you already got this once - I've been 'experimenting' with my email]

---

From: <[email-masked]>
Date: Mon, 30 Jul 2012 21:49:26 +0100

Jerry,

Re-instating tcpm list on distr. Inline...

At 19:41 30/07/2012, Jerry Chu wrote:
Hi Bob,

Thanks for your interest and sorry for the delay (Yuchung has been
traveling and I've
been busy preparing TFO's server side implementation for publication).

On Thu, Jul 26, 2012 at 9:35 PM, Bob Briscoe <[email-masked]> wrote:
> I liked this enough to want to work on improving it. I have a couple of
> proposals that occurred to me, which I've finally made time to write up.
>

Sure.

> * If the server's FIN-ACK never arrives (perhaps because a middlebox has
> eaten it), the client just doesn't have a cookie for the next session and
> uses a 3WHS as normal.

Very interesting idea.

>
> Note, only the Request would have to be on a FIN. The Fast Open Cookie
> itself would obviously still be on the SYN of subsequent connections. Then,
> when a subsequent connection finishes, it can refresh the cookie on its FIN,
> ready for another connection later.
>
> a) A FIN-cookie sidesteps the risk of unpredictable delay of the very first
> SYN due to some middleboxes dropping new TCP options (any timeouts due to
> non-delivery don't hold up the session, which has already finished)

This is a good point but from our experience unknown TCP options don't seem
to pose a real problem wrt middleboxes, SYN pkts w/ data do.

This is only half the reason for doing it (ie the two reasons together stregthen the case).

Also if there is middlebox on the route that will drop SYN pkts with
unrecognized
TCP options, requesting TFO cookie in FIN pkt only postpones the delay for
those servers that support TFO, i.e., to the subsequent connections with TFO
cookie+data.

My point is that sending the risky packet after you've sent all the data doesn't delay anything the user cares about - you just retransmit the FIN to close the connection - no big deal for anyone.

But I agree if there is still non-negligible % of
middleboxes dropping

The refs say there might be problems (today) with 6% of paths. In future it might be more. Might be less. That's not negligible.

SYN w/ unrecognized TCP option then requesting TFO cookie through FIN can
avoid the delay for those cases where the server doesn't support TFO.

Getting really bad delay variance on a proposal to cut delay isn't good.

> b) Transports GETting typical Web pages could (ab)use the fastopen cookie on
> the SYN exchange by opening multiple TCP connections during the initial
> connection without each one suffering the delay of a 3WHS. This creates a
> perverse incentive to use multiple parallel connections, because you can get
> the same latency benefit as HTTP pipelining [Yoshifumi posed this problem
> some time ago].  If clients can only request a fastopen cookie on a FIN,
> they don't have this perverse incentive to not bother with pipelining.

Interesting point. A motivated abuser may rush to FIN to get a cookie first.

Client can't send a FIN without closing the connection. That's the dilemma I'm proposing it has to face.

I'm not talking about an attack. I'm talking about lazy Web developers. This removes the benefit that fast-open gives to those who shard connections. If they want to avoid 3WHS for the /current/ set of objects they are trying to get, they have to use pipelining or SPDY.

Cookie on FIN deliberately defers the benefit of no 3WHS to subsequent connections.

>
> I have no evidence, but it seems intuitive that if the TCP option got
> through on the first FIN, it might be more likely to get through on the next
> SYN, altho I admit options on SYNs are looked at more closely by
> middleboxes.
>

I won't worry about the difference here because the real test for the middlebox
is SYN+data I think. Again do you have data showing middlebox still
having trouble
with unrecognized TCP options?

6% of paths - From memory this was Michio's work in the Trilogy project that you cite in the draft.

Will comment on your following proposals later.

Understood

Bob

Jerry