Subject: [tcpm] another basic option question - can TCP enable options on the SYN/ACK?

From: Joe Touch <[email-masked]>
Date: Tue, 21 Oct 2014 18:34:45 -0700

Hi, all,

Another key issue that has arisen in the discussion of option processing
is whether options can be enabled during a SYN/ACK.

I think that Dave Borman and I agree, but want to hear from others:

	Can an option be enabled on the SYN/ACK?

E.g.:

	host A			host B

	SYN w/X ->

				<- SYN/ACK w/X,Y

What does A do here?

	i) always send ACK w/X

	ii) send ACK w/X,Y if it supports Y
		or just ACK w/X if not

	iii) send ACK w/-

AFAICT, Dave and I agree that the answer is (i). Does anyone else agree?

A key aspect of this question is whether the options in the ACK have any
utility, or whether the SYN, SYN/ACK exchange is the only exchange that
matters for option negotiation.

Joe

---

From: Yoshifumi Nishida <[email-masked]>
Date: Tue, 21 Oct 2014 20:54:20 -0700

(as an individual of course..)

I'm wondering if all negotiations need to be negotiated. For a option like
window scale, I believe it has to be negotiated.
I also believe it should be included in the third ACK so that we can be
robust against the case where the option in SYN/ACK has been removed.
(although it's not a perfect protection)
However, I'm not very sure if we should include MSS option in the third
ACK.
I'm thinking that there might be two different types of options. One
requires negotiation.
The other is used for informational, something like: "BTW, here's my info.
you can use it for what ever you want."

So, my preference for now is it depends on each option. Please let me know
if I overlook something.

Thanks,
--
Yoshi

On Tue, Oct 21, 2014 at 6:34 PM, Joe Touch <[email-masked]> wrote:

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

---

From: Tim Shepard <[email-masked]>
Date: Wed, 22 Oct 2014 00:43:38 -0400

I'm not so sure that it makes sense to try and definitively give
answers to your questions for future TCP options we haven't even
invented yet.  It's not clear to me that there's any value in
deciding things now that would preclude doing something useful in the
future that might be contrary to some decision we might make now.

It's not like there's generic option-negotiation code in any stack
implementation (that I'm aware of) where code was written to negotiate
an option on or off where the author of that code has no clue what the
option is or is unable to know what its semantics are.

So I would expect (hope) that someone implementing a new TCP option
would be able to do the right thing for that particular sort of
option.

Yes, allowing options to show up for the first time on the 2nd packet
(of the 3 or 4 WHS) is new and we don't have stacks that do that now,
so maybe we need to think some things through to make sure the right
things happen.

But it is not obvious to me that we can do so for any and all options
(past and future) in a generic way that would be the right thing for
all (future) options.

And yes, the potential interactions between options might get more
complicated.  But again, I'm not sure we can make any good decisions
without getting specific about which particular options we are talking
about.  And it's probably easier to figure out what the right thing to
do would be in the case of specific options.

I guess we should think carefully about what a stack should do if it
sees an option that it doesn't understand.  Today, if an option that
you don't understand shows up on a SYN, you just ignore it.  And I
think we would pretty much have to say that if a new option shows up
on a SYN/ACK that you don't understand, just ignore it.  (RST in that
case, if deployed, would preclude being able to extend how some future
option gets negotiated.)

Imagine that you ran out of option space on the initial SYN and were
unable to include all the options you would have liked to.  But at
least one of the options you included on that initial SYN implies that
you are modern enough to cope with additional options appearing for
the first time on the SYN/ACK.  Say that the window scale was one of
the options ommitted from the initial SYN due to lack of space.  The
responding host may now include the window scale option on the SYN/ACK
packet.  In this case, since we're not sure that the initial host even
implements window scaling, the SYN/ACK packet's window will be an
unscaled value.   If the initiating host includes a window scale
option on the packet that carries the ACK of the SYN/ACK, then window
scale has been turned on (and that packet carries a scaled window).
If the ACK of the SYN/ACK does not include a window scale option (and
window scale option was not present on the SYN), then proceed with no
window scaling.

Did I get that one right?   (If not, we can probably figure out what
the right thing to do is.)

All of this more modern mechanism would only be active if there was
*some* option on the initial SYN that implied extendend option
negotiation is allowed.

And window scale seems like it is exactly the sort of option whose
utility is not damaged (much at all) by delaying its negotiation by
half a round trip time.  There may (someday, if not today) be other
such options.

Oh, I guess it doesn't work so well if the server is not modern enough
to initiate the negotiation of that option on the second half of the
first round trip.   Then you wind up without the option turned on.
So maybe the initiator needs a hint of the servers capabilities.

But if we were trying to add a window scale option after we had
succeeded in extending the option space with an option that is carried
on the SYN (perhaps without any extra option space there) and then
additional option space being available on the SYN/ACK and all
subsequent packets), then we could have done window scale this way,
and things would be OK.

If going forward we ensure that any stack that implements new options
(that won't fit today in the room remaining in TCP option space) allow
for this sort of option negotiation starting with the SYN/ACK (where
there can somehow be more space for options), then we can deploy those
options in the SYN/ACK (until we run out of MTU) or even later (if we
can get the later option negotiation explicitly acknowledged after the
SYNs have already been acknowledged).

			-Tim Shepard
			 [email-masked]

---

From: David Borman <[email-masked]>
Date: Wed, 22 Oct 2014 13:48:08 -0500

> On Oct 21, 2014, at 11:43 PM, Tim Shepard <[email-masked]> wrote:
> 

Yes, the point of the Four-Way handshake is to provide a framework
that can be used in the future to get past the limitation of the
option space in the initial SYN of the Three-Way handshake.

> so maybe we need to think some things through to make sure the right

Actually it isn’t new.  RFC 1072 originally defined the Window Scale,
Echo and SACK Permitted options as being put into any packet that
contained the SYN bit.  It wasn’t until RFC 1323 that we added the
optimization that there wasn’t any point in putting these options into
the SYN/ACK if they weren’t received in the SYN, because they wouldn’t
be enabled anyway (replacing Echo with Timestamps).

If implementations forget what they sent in the SYN and rely on what
is in the SYN/ACK to determine which options are enabled, then that’s
a bug in the implementation.  With a Three-Way handshake, even if the
SYN/ACK contains a Window Scale option and the initial SYN didn’t
contain the Window Scale option, it must not be enabled on either side.

> (past and future) in a generic way that would be the right thing for

At the generic level, there shouldn’t be any problem with putting
options into the SYN/ACK that weren’t received in the SYN, RFC1122
already states that any unknown options must be silently ignored.

> do would be in the case of specific options.

Yep, I totally agree.  The best we can do is provide a framework, and
then the individual options need to be defined how they can operate
in that framework.

> case, if deployed, would preclude being able to extend how some future

That’s what RFC 1122 says.  Any unknown options are silently ignored.

> the right thing to do is.)

Not quite.  With the Three-Way handshake, if the SYN/ACK has a
Window scale and the initial SYN didn’t have it, then the Window
Scale is ignored and not enabled.

It’s the Four-Way handshake that allows it to still be enabled,
by the client then including the Window scale in its SYN/ACK.
It’s the addition of another packet from the client with the
SYN bit set that allows it to fit nicely with the existing
RFC7323 style option enablement (enabled by sending and receiving
the option in a packet with the SYN bit set).

> *some* option on the initial SYN that implied extendend option

That’s what the 4WAY bit (or 4WAY option) is for.

> subsequent packets), then we could have done window scale this way,

The more expensive route is for the client to send a SYN, and if it
gets back a SYN/ACK that indicates EDO support, restart the Three-Way
handshake by sending a SYN making use of the EDO option.  The downside
of this is that it adds an entire RTT to connection establishment, the
Four-Way handshake tries to find middle ground between that and the
Three-Way handshake.

> SYNs have already been acknowledged).

Yes, we put a stake in the ground saying that all new TCP options must
require that implementations also support Four-Way handshake and EDO.

		-David

---

From: Joe Touch <[email-masked]>
Date: Thu, 23 Oct 2014 10:10:00 -0700

On 10/21/2014 8:54 PM, Yoshifumi Nishida wrote:
> I'm wondering if all negotiations need to be negotiated. 

The ones specified in RFC793 do not.

All others need to be negotiated *if* you care that the other end
supports it. That negotiation can happen at any point in the connection,
but if it doesn't happen during the opening handshake then the option
needs to be specified with its own 3WHS mechanism that can operate
independently of segment loss and retransmission (which, IMO, is a bad
idea).

Some are confirmed in both directions (such as TS and WS), but others
may need to have a "response" to a specific "request".

Finally, there are options that aren't as much negotiated as they are
either supported or not, e.g., MD5 and AO. There's no handshake. If the
option is required on that connection and isn't present, segments are
ignored anyway.

I.e., a taxonomy should include, at a minimum:

	- always supported
		end-of-list
		NOP
		MSS

	- supported if enabled in both directions during the 3WHS
		TS, WS

	- request/response
		TFO, MPTCP, SACK

	- supported if enabled throughout the connection
		MD5, AO

Joe

---

From: John Leslie <[email-masked]>
Date: Thu, 23 Oct 2014 15:19:02 -0400

> The ones specified in RFC793 do not.

   (Of course!)

> supports it.

   Quite true. But note that it's easy to imagine options where one
endpoint _doesn't_ care if the other endpoint supports it.

   In fact, I expect to shortly submit a draft where this is the case.
An endpoint sending it announces its own support for it; but unless
the other endpoint also sends it, the first endpoint won't know whether
it has been acted on in any way.

> That negotiation can happen at any point in the connection,

   Currently, most options _are_ noted in the originating SYN, for
several different reasons. First, the SYN and SYN-ACK are the only
place in a TCP connection that you know the options won't be quietly
dropped due to congestion. Also, there is a belief that TCP stacks
are likely to fail to process options after the initial handshake
unless they were negotiated during the SYN - SYN-ACK. (I am not aware
of much evidence either way on that.)

> independently of segment loss and retransmission (which, IMO, is a bad

   I don't agree it's a "bad" idea, but it surely is more complicated.

   Please note, however, that a 3-way HandShake isn't the only way to
synchronize sender's and receiver's views of an option being enabled.
(It is usually the best, but not the only...)

> may need to have a "response" to a specific "request".

   That indeed is common; and it becomes complicated because either the
request or the response can get dropped.

> option is required on that connection and isn't present, segments are

   True. And, IMHO, this is a rather important case.

> 	- supported if enabled throughout the connection

   I'm hesitant to make statements like this: Each option should be
defined to detail its rules; and we can never hope to cover the entire
range of possible rules.

   Nonetheless, Joe is correct, so far as this goes.

--
John Leslie <[email-masked]>

---

From: David Borman <[email-masked]>
Date: Thu, 23 Oct 2014 14:36:43 -0500

> On Oct 23, 2014, at 12:10 PM, Joe Touch <[email-masked]> wrote:
> 
> 
> 
> may need to have a "response" to a specific "request”.

Despite the muddled wording in RFC7323, it is the sending and receiving
of the option in a packet with the SYN bit set that enables it.

In the simultaneous open case, if you send <SYN,TSopt> and then receive
<SYN,TSopt>, the option is enabled at that point.  So the TSopt in the
crossing <SYN,ACK,TSopt> packets is there because the option has already
been enabled, not to enable it.  But if for some reason the <SYN,ACK>
didn’t have TSopt, TSopt would still be enabled.

Also with the simultaneous open case, TSopt can still be enabled even
if one of the sides omitted it in its <SYN> (and thus the other side
omits it in its <SYN,ACK>):

       <SYN>            <->    <SYN,TSopt>
       <SYN,ACK,TSopt>  <->    <SYN,ACK>

In this case TSopt is still enabled, because it was sent and received
in a packet with the SYN bit.  The left side enables it when it sends
the <SYN,ACK,TSopt>, the right side enables it when it receives the
<SYN,ACK,TSopt>.

Though it shouldn’t happen, for completeness sake, this exchange would
also enable TSopt:
       <SYN>            <->    <SYN>
       <SYN,ACK,TSopt>  <->    <SYN,ACK,TSopt>

All this also applies to WS.

> 	- supported if enabled in both directions during the 3WHS

SACK isn’t request/response.  If you receive SACK-Permitted in a SYN
packet, then SACK is enabled for output and you can send SACK in non-<SYN>
packets.  Thus it can be enabled in one direction only.

---

From: Joe Touch <[email-masked]>
Date: Thu, 23 Oct 2014 12:53:37 -0700

> of the option in a packet with the SYN bit set that enables it.

That enables the options in 7323, which are not all options.

> <SYN,TSopt>, the option is enabled at that point.

>From page 12 of RFC7323:
   Once TSopt has been successfully negotiated, that is both <SYN> and
   <SYN,ACK> contain TSopt,

I.e., TS is not strictly enabled until both the SYN and SYN/ACK contain TS.

I appreciate that I'm arguing with the author of that option, but it is
the document that specifies the option, not the author's intent.
Further, the only case it would matter is simultaneous open when both
party sets TS in the SYNs and one decides to not set it in the SYN/ACK,
which shouldn't happen anyway.

> So the TSopt in the

IMO, RFC7323 is clear in stating the opposite. Again, there are other
reasons why this case shouldn't happen anyway.

> the <SYN,ACK,TSopt>, the right side enables it when it receives the

For similar reasons, I disagree. In this case, the left side should not
send TS in the SYN/ACK anyway if it didn't send it in the SYN, IMO, so I
don't think it should happen anyway either.

> All this also applies to WS.

WS doesn't have the caveat that TS has, so I could imagine compliant
implementations behaving differently in this case.

> packets.  Thus it can be enabled in one direction only.

Oh - yes. That's a new case:

	- indicate support
		SACK

i.e., unidirectional indication of a feature to be used in the reverse
direction.

Joe

---

From: David Borman <[email-masked]>
Date: Thu, 23 Oct 2014 15:44:59 -0500

> On Oct 23, 2014, at 2:53 PM, Joe Touch <[email-masked]> wrote:
...
> reasons why this case shouldn't happen anyway.

RFC7323 is too explicit in its documentation of the optimization that
during the normal 3WHS, if you don’t receive the option in the <SYN>,
there is no point putting it into the <SYN,ACK> because it won’t be
enabled anyway.  That was always just an optimization from RFC 1072
which had the options being put in all SYN packets.  It is the
sending and receiving of the option in a SYN packet that enables
the option, a SYN packet being one with the SYN bit set, so either
a <SYN> or a <SYN,ACK> packet.

> don't think it should happen anyway either.

RFC7323 doesn’t say that.  To quote another part in the same section
you quoted:

   A TCP MAY send the TSopt in an initial <SYN> segment (i.e., segment
   containing a SYN bit and no ACK bit), and MAY send a TSopt in
   <SYN,ACK> only if it received a TSopt in the initial <SYN> segment
   for the connection.

The left side received <SYN,TSopt> so it can send <SYN,ACK,TSopt>, and
the option is enabled.

RFC7323 is missing the clear distinction that it is the sending and
receiving of the TS/WS in packets with the SYN bit set that enable
that option, irregardless of whether or not the packet has the ACK
bit set.  The wording in RFC7323 is the specific case of this for
the 3WHS, e.g., the <SYN> from the client and <SYN,ACK> from the
server are the only two packets with the SYN bit set.

			-David