Subject: [tcpinc] TCP-ENO draft 04 posted

From: [email-masked]
Date: Fri, 29 Jul 2016 14:17:19 -0700

I just posted a new draft of TCP-ENO, available here:

        https://datatracker.ietf.org/doc/draft-ietf-tcpinc-tcpeno/

This reflects the issues discussed in Berlin, as well as the first cut
at data in SYN segments.  Note that these changes are all open for
discussion, I just think that the discussion will be more useful if
framed in terms of concrete language of a draft document.  For that
reason, we will aim for shorter iteration cycles on ENO, and once ENO
stabilizes start updating the other documents to match.

Notable changes:

  * Specs are now TEPs.

  * General suboption renamed global suboption, and refered to more
    consistenly that way.

  * 'cs' (configuration/spec) bits in an initial suboption byte are now
    'glt' (global/length/TEP).

  * The 'm' bit is gone, and we now have z1, z2, z3 in the global
    suboption.

  * Length word is gone.

  * New Data in SYN segments section.

  * IANA considerations:  added some if(TBD == 69) instructions for the
    RFC-editor, and made clear legacy use of 69 can break connection and
    MUST be disabled if it can't be upgraded.

David

---

From: Joe Touch <[email-masked]>
Date: Fri, 29 Jul 2016 14:29:53 -0700

Hi, all,

I'm very confused by the new SYN data text.

First, if you really want state based on previous connections that
allows early use of SYN data  before the 3WHS, that seems to be the very
definition of TFO. So declaring that this solution is valid only where
TFO isn't used seems the opposite of what I would expect.

Second, the text doesn't cover the case where the endpoint abilities
have changed. Unless you use TFO cookies to verify that ability, you
should not assume you know it. Which means you can easily be sending
data you need to unroll - and the only safe way to do that (if the
endpoint turns out to be non-ENO even if you assumed otherwise) is to
terminate the connection.

Third, the claim that "Using data in SYNs deviates..." is incorrect.
Data in the SYN is valid for TCP. Did you mean "acting on received data
in the SYN before the 3WHS in the absence of TFO deviates..."?

Joe

On 7/29/2016 2:17 PM, [email-masked] wrote:
> _______________________________________________
> Tcpinc mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tcpinc

---

From: David Mazieres <[email-masked]>
Date: Fri, 29 Jul 2016 16:11:46 -0700

> TFO isn't used seems the opposite of what I would expect.

TFO requires sending plaintext.  ENO explicitly prohibits it.  Either or
both options could get munged by a middlebox.  Hence, it is much safer
to say that ENO specs can do something TFO-like than to allow ENO specs
to modify the semantics of TFO.

The principle here is that it is far more likely for a middlebox to
remove a TCP option than it is for a middlebox to add a TCP option
created out of thin air.

> terminate the connection.

Quite possibly.  However, the goal of section 4.7 is not to prevent TEPs
from doing "bad" things.  Rather, the goal is to impose the minimum
restrictions such that if different TEPs say different things about SYN
data, then it is always unambiguous which TEP specification governs a
particular SYN segment.  A secondary goal is to ensure that TEPs can
later be amended to take advantage of SYN data (because initial TEP
implementations MUST discard SYN data whose usage the old specification
did not define).

Questions about when to reset a connection (or whether to allow some
really weird behavior when the application has explicitly requested it)
should be deferred to the point at which a TEP actually wants to use SYN
data.  If you foresee problems with the current wording (as opposed to
what future TEPs might hypothetically do), then it would help to discuss
two questions separately:

  1. Is the current section 4.7 setting the right goals?
  2. Is the current section 4.7 achieving its goals?

> in the SYN before the 3WHS in the absence of TFO deviates..."?

I originally had "consuming" instead of "using," but thought that read
kind of weird.  Would you prefer "consuming"?  And yes I definitely
meant in the absence of TFO, since the absence of TFO is required.  (TFO
itself already claims to deviate from standard TCP semantics.)

David

---

From: Joe Touch <[email-masked]>
Date: Fri, 29 Jul 2016 16:23:12 -0700

> to modify the semantics of TFO.

Fair enough, but then you really need to re-implement the bulk of what
TFO does if you intend to act on previous state as if it were known for
future connections.

> remove a TCP option than it is for a middlebox to add a TCP option

TCP is a reliable transport protocol. That reliability is not predicated
on "likeliness".

>   1. Is the current section 4.7 setting the right goals?
IMO, it is incomplete.

The first goal should be correct TCP behavior in all cases.

A secondary goal can be optimization, but only when it does not
interfere with the first goal at all.

> itself already claims to deviate from standard TCP semantics.)

I appreciate the desire to avoid TFO with ENO, but then you need to
stick to non-TFO semantics.

That means that previous connection state can be used only as a hint,
and that the connection MUST be able to undo 100% of that hint when (not
if) it is wrong.

In that case, you have only two options:

   1) require that ENO never *send* SYN data

    2) require that failed ENO negotiation MUST result in a dropped
connection

In the case of #2, the question is what to do next. I don't see a good
way to make an *option* require a TCP retry. That's why I suggested #1,
unless - of course - you build some sort of TFO-like way to ensure that
you're not just talking to the same IP you spoke to before, but the same
endpoint stack.

Joe

---

From: David Mazieres <[email-masked]>
Date: Fri, 29 Jul 2016 17:24:57 -0700

> TFO does if you intend to act on previous state as if it were known for

Yes, except the reimplementation may turn out to be simplified by the
fact that A) TEPs have a cryptographically strong way to check data
integrity at their disposal, and B) there may be extrinsic information
about the server-side SYN handling.  E.g., if TCPINC ever integrates
with DANE, there could be a DNS record promising that a server always
implements some TEP and is always willing to engage in some server
authentication pre-protocol.  In that case, the client can count on the
server observing ENO's requirement to discard unexpected SYN data.

> The first goal should be correct TCP behavior in all cases.

I don't understand.  Don't we already have RFC793 and the whole IETF
process to ensure correct TCP behavior?  I'm not saying TCP-ENO should
advocate incorrect behavior, just that A) most correctness requirements
are implicit (or by normative citation of RFC793), and B) from
time to time the IETF sees value in deviating from RFC793 (e.g., TFO).
There's no reason to write the spec in such a way as to complicate or
redundantly prohibit future TFO-like things *if* the IETF wants to
pursue them.

> stick to non-TFO semantics.

Unless a TEP specifies TFO-like semantics, right?  There may be value in
having a TEP replicate or incorporate TFO, but for backwards
compatibility A) it should do so without including option 34, and B)
older versions of the TEP should ignore the SYN data.

> In the case of #2, the question is what to do next.

I could see going with #2 if that's the sentiment of the working group,
but my preference would be to leave it up to the individual TEP, for two
reasons.  First, we don't have any empirical evidence about SYN data
buffering, and it does seem like something that can be probed for or
annouced at a different layer of abstraction.  Second, as things evolve,
who's to say some future TEP won't have a better workaround for the
problem?

As a compromise, how about making #2 a SHOULD, so as to minimize the
chances of TEP accidentally messing this up without closing the door on
intentional deviations?

David

---

From: Joe Touch <[email-masked]>
Date: Fri, 29 Jul 2016 18:32:36 -0700

On 7/29/2016 5:24 PM, David Mazieres wrote:
> about the server-side SYN handling. 
Sure, but TFO achieves a way to rely on safe early use of SYN data that
doesn't change. That's what you get with a TFO-like solution.

...
>  E.g., if TCPINC ever integrates
DNS hints can tell you what might succeed, but can't guarantee it. You
don't know if TCP will be preceded by a DNS lookup - it's not integrated
inside TCP.

> process to ensure correct TCP behavior? 
If everyone follows it...(and that's the trick here)

>  I'm not saying TCP-ENO should
> advocate incorrect behavior, 
That's where we disagree - if you intend on sending SYN data that
changes if not ACKd, I do.

> just that A) most correctness requirements
Certainly - e.g., the meaning of the URG pointer changed too. But in all
cases there's a strong expectation that these changes do not affect
legacy TCP. In the case of URG, it was because we all believed strongly
that this was compliant with all known implementations and that the
failure mode was relatively gentle to TCP semantics.

> redundantly prohibit future TFO-like things *if* the IETF wants to
Agreed. But I'm still not sure that's what's going on here..

> Unless a TEP specifies TFO-like semantics, right? 

Yes, but that means success of TFO-like gives you permission to do more
with the SYN-data (or do it earlier). Even TFO doesn't give permission
to change data that hasn't yet been ACKd.

>  There may be value in
And legacy TCP cannot be required to discard the SYN-data. You cannot
control the server side if it's legacy.

> I could see going with #2 if that's the sentiment of the working group,
I've noted my concern there... (see the end of this message for more on
that)

> but my preference would be to leave it up to the individual TEP, 

Do you mean that you would let the TEP indicate which of the two above
is selected for a given endpoint? That's fine, as long as both work
(again, see the end of this thread)...

> for two
> buffering, 
Agreed...

> and it does seem like something that can be probed for or
> annouced at a different layer of abstraction.
On a per-connection basis, yes. As a persistent endpoint property, no -
for the same reason as the fact that you can't use ENO state from past
connections.

>   Second, as things evolve,

RFC793, until this issue is locked down in a different way, IMO.
> chances of TEP accidentally messing this up without closing the door on

#1 is a MUST unless you can guarantee that a given TCP stack will
automatically retry with different connection parameters (#2). Otherwise
you've made your TCP brittle by turning on ENO. I don't mind if you want
to shoot yourself in the foot that way, but I suspect few users of ENO
capability would want that.

(i.e., there's no room here for a SHOULD, unless you want to say "SHOULD
do #2 if the TCP stack implements automatic retry" -- however, you're
now hurting all connections that make the mistake of using ENO to a
legacy endpoint. That might be OK, if you think the hints you're using
are usually correct, though).

Joe