Subject: Re: [tcpm] Faster application handshakes with SYN/ACK payloads

From: Stefanos Harhalakis <[email-masked]>
Date: Sun, 21 Sep 2008 02:05:08 +0300

Hello Adam,

I've just looked again at this. Its 1.5 month late but time runs fast.

> However, it appears that I've not made the case for the option yet. To
> do this, let me take HTTP as an example.
>
> HTTP is very latency sensitive[1]. Because of this, and guided by the
> sockets API, the client starts the exchange. Thus, if the client
> wishes to probe for optional features (like TLS upgrade: RFC2817) the
> exchange works like this:
>   Client --- OPTIONS ---> Server
>   Client <--- 101 Switching --- Server
>   Client --- GET ---> Server

AFAIKT, you're proposing that whenever the server side detects the SA option 
it switches to a different protocol behavior. Why not extend this even more 
and provide a generalized framework for more advanced customization?

I believe that this was not proposed before so here it goes:

Add a generic 'user data' option for SYN fields that would carry user data. 
Something like this:

KIND | LENGTH | DATA

Most of the time it should be: 

KIND | 3 | "1 Byte of data"

This is easy to implement (at the client side) and will allow for premature 
negotiation. For example this could include the client side application layer 
protocol capabilities. It can also be symmetric so that server side also 
sents some out-of-band data but most probably this should not be required 
with SA data (but an echo/acknowledge is required).

The implementation at the client will just require a setsockopt() that would 
set the extra header data and perhaps a getsockopt() that would get the reply 
(if any). This part needs some working.

> If HTTP sent a banner, like SMTP servers, then my life would be a lot
> easier! The banner could advertise all the extensions supported.
> However, without SYNACK payloads, this banner would cost another round
> trip.

Such a solution would allow the HTTP protocol to switch to HTTP-with-banner as 
you wished, without braking compatibility. Of course there can be many other 
uses for it. It is also 100% TCP friendly since a receiver that doesn't 
support such an option will just ignore it.
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Joe Touch <[email-masked]>
Date: Sat, 20 Sep 2008 23:17:44 -0700

Hi, Stefanos,

> KIND | 3 | "1 Byte of data"

I've been calling a a user data option for that reason, but I feel that
it changes TCP semantics. You're using a SYN option to change the
behavior of a service on a port. This requires substantial changes to
the interface as outlined in RFC793 (and implemented in sockets). In
particular, you need the server to be able to read the SYN options from
a socket before writing the response to a SYN-ACK.

This is outlined in previous emails to the list; it might be useful to
review them.

> negotiation. 

As per above and in previous emails, it seems impossible to implement in
existing stacks without substantial modification of the socket interface.

> For example this could include the client side application layer 

The issue is that the data is carried in the DATA of the SYN, not in the
option (in the SYN-ACK reply once negotiated). A different issue is that
TCP cannot ensure that data, once written, is solely in the SYN - it
could be retransmitted in subsequent data packets anyway, so it should
not be assumed to be inside the SYN.

Joe

---

From: Joe Touch <[email-masked]>
Date: Sat, 20 Sep 2008 23:38:07 -0700

Stefanos,

Here's a more brief, self-contained reply:

> Stefanos Harhalakis wrote:
...
>> Add a generic 'user data' option for SYN fields that would carry user data. 

There are two reasons for doing this:

	1- to send an out-of-band signal

	2- to send a signal that the server acts on before the
	handshake completes

#2 violates TCP semantics, so the SYN-ACK cannot have application data
that depends on the SYN's user data option (which is the desired result
here). The signal can't be acted on at the application layer until the
handshake completes.

#1 changes TCP semantics as well, since TCP does not have an out-of-band
signal path, and this would add that. However, because it cannot be
acted on until after the handshake completes, it cannot modify
application behavior that isn't required to wait until the handshake
finishes - i.e., apps that can write to the socket before the handshake
completes (e.g., to write data available to a SYN-ACK) would never
change because of this signal. The utility of this feature depends on
application behavior, which cannot be known, and thus cannot be relied upon.

As a result, I cannot see how this feature can be used to extend TCP.

Joe

---

From: Stefanos Harhalakis <[email-masked]>
Date: Sun, 21 Sep 2008 12:44:30 +0300

> application behavior, which cannot be known, and thus cannot be relied

What I proposed is what you describe in #1. It is different from the 
SA-with-data proposal and thus it hasn't to do anything with #2. As I said in 
the original mail, it has to do with what Adam said:

"If HTTP sent a banner, like SMTP servers, then my life would be a lot
easier! The banner could advertise all the extensions supported.
However, without SYNACK payloads, this banner would cost another round
trip."

and more specifically with the first sentence. Supposing that (a hypothetical) 
HTTP/1.3 would support an optional banner, such an option would allow the 
server side to send it without braking backwards compatibility:

Client --> SYN+DATA --> Server
Client <-- SYNACK+? <-- Server
Client -->   ACK    --> Server
Client <--  BANNER  <-- Server

Without changing current behavior (It is not required that data be sent with 
the SYNACK option).

Also, this is not exactly "data" as there is space for a very small amount of 
information (some bits). Considering the possibilities of this, it can be 
used in many situations such as:
* HTTP or other protocols that use a well-known-port, to negotiate different
  behavior without introducing a new port number (SSL over port 80?).
* Cryptographic applications
* Anything that someone out there can think of. 8 bits (or a little more) of 
  information can be used for many things.

Wrong?

p.s: I can write a draft if this would clarify things.
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: "Adam Langley" <[email-masked]>
Date: Sun, 21 Sep 2008 07:08:38 -0700

>  information can be used for many things.

Firstly, one counterargument that several have used in the past is
that a round-trip-time is unimportant and any such scheme can be
achieved without TCP changes by burning an RTT. I disagree with this,
but I can't release any data to back up that assertion, so it's still
a reasonable counterargument.

I also wonder how much of an advantage 8 bits, as opposed to a single
bit, gives you. Although, once you have defined an option, 8 bits is
almost as cheap as a single bit, so 'why not' is a reasonable
position.

Just from a personal point of view. I'm now using information from DNS
and from previous connections to the same host to achieve this "early"
information entirely within userspace. However, I still needed a new
port because "transparent" proxies aren't very transparent when you
stop speaking HTTP over port 80.

AGL

-- 
Adam Langley [email-masked] http://www.imperialviolet.org
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Joe Touch <[email-masked]>
Date: Sun, 21 Sep 2008 09:30:39 -0700

> However, without SYNACK payloads, this banner would cost another round

HTTP does send a banner of that type; the issue is that you want #2
above - if you don't act on the banner info until after the TWHS, you
"waste" an RTT waiting for the connection to be established before the
server can reply.

That's a **design feature** and requirement of TCP, not a "waste".

> Client <--  BANNER  <-- Server

The server can start sending data before the TWHS completes (let's call
the above "sequence 1" and the below "sequence 2"):

In sequence 1, the banner can depend on the SYN+DATA data. In BOTH
sequences, however, the SYNACK+? "?" **cannot** depend on the SYN+DATA data.

> p.s: I can write a draft if this would clarify things.

I think you're exploring the space of the discussion that has already
been had on this list...

Joe

---

From: Stefanos Harhalakis <[email-masked]>
Date: Sun, 21 Sep 2008 21:39:53 +0300

Hello,

I'm sending this reply mostly to clarify the things. Perhaps there is 
something that I don't understand or I don't express well. If it is so, 
please excuse the stubbornness of mine.

> That's a **design feature** and requirement of TCP, not a "waste".

I don't exactly understand what you mean by saying that HTTP sends a banner. 
An HTTP server will never send anything unless it is triggered to do so by a 
client request. Creating an HTTP version that sends an initial one-line (or 
more) will break backwards compatibility. (no?)

> > and more specifically with the first sentence. Supposing that (a
> > hypothetical) HTTP/1.3 would support an optional banner, such an option
> > would allow the server side to send it without braking backwards
> > compatibility:
> >

I believe that I didn't describe well what I meant (or else I don't completely 
understand what you're saying).

I'm talking about (lets say) 8 bits of out-of-band information that the client 
can send to the server side and vice-versa. The server side application will 
most probably get those data after the TWHS completes. There is no placed 
requirement to do otherwise.

So, a complete trace (with most function arguments ommited or altered for 
simplicity, no error handling, etc etc :-) of a non-well thought proposal 
(there are issues) would be:

(C: Client, S: Server)

# Server side listens for connections, supports USER_DATA
S: s0=socket()
S: setsockopt(s0, SO_USER_DATA, 0x02)
S: bind(s0, 0.0.0.0, 80)
S: listen(s0)

# Client attempts connection. Sends USER_DATA
C: s=socket()
C: setsockopt(s, SO_USER_DATA, 0x01)
C: connect(1.2.3.4, 80)

# Connection is established. Remote USER_DATA is available to both ends
S: s=accept()
S: getsockopt(s, SO_REMOTE_USER_DATA, &mybuf)
C: getsockopt(s, SO_REMOTE_USER_DATA, &mybuf)

At this point, the client side has connected to the server side and they have 
exchanged one byte of out-of-band data (C->S: 0x01, S-C: 0x02). This is all 
done without messing with the TWHS.

>From the TCP's point of view, the above would look like:

* Client sends SYN with TCP option USER_DATA, length 1, data 0x01
* Server receives SYN, supports USER_DATA, responds with SYNACK with option 
USER_DATA length 1, data 0x02 and *no* data in the segment.
* Client receives SYNACK and responds with ACK
* Everything continues normally

The only difference with existing TCP behavior is that a 3-bytes TCP option is 
included in the SYN and SYNACK segments. There is no messing with user data 
in SYNACK at all. Perhaps the USER_DATA option name is confussing. USER_DATA 
is just an arbitrary name for a KIND of an option.

> I think you're exploring the space of the discussion that has already

Adam's proposal was that data (outside of TCP options) would be sent with the 
SYNACK field. I still believe that the USER_DATA option is not related to 
that. Perhaps if I hadn't initially related this proposal with Adam's 
proposal (since it is related to his 'wish' and not to his proposal) it would 
be clearer?

I'm *really* sorry if what you say above is true and I just don't understand 
something. 

p.s. Do you know if there is a way to force the tcpm mailing list to send me 
duplicates for mails that are CC'd to me too? It seems that all mails that 
I'm CC'd are only sent directly and not via the list. I've set the "Avoid 
duplicate copies of messages?" to "No" in the mailman options but there was 
no change.
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Stefanos Harhalakis <[email-masked]>
Date: Sun, 21 Sep 2008 21:49:54 +0300

On Sunday 21 September 2008, Adam Langley wrote:
> > Also, this is not exactly "data" as there is space for a very small
> > amount of information (some bits). Considering the possibilities of this,
> > it can be used in many situations such as:
> > * HTTP or other protocols that use a well-known-port, to negotiate
> > different behavior without introducing a new port number (SSL over port
> > 80?). * Cryptographic applications
> > * Anything that someone out there can think of. 8 bits (or a little more)
> > of information can be used for many things.
>

I don't believe that this is always possible when trying to keep backwards 
compatibility. Some (stupid ?) examples that just passed from my mind:
* (generic) Early protocol selection
* SSL over port 80, 25, etc
* Early virtualhost selection (with cooperation from the DNS)
* Hidden backdoors :P
* A kind of tunneling
* Anything that someone out there can imagine

> almost as cheap as a single bit, so 'why not' is a reasonable

That's a good question that I don't have an answer for :-)
Indeed, everything that 8 bits can do can also be done with 1 bit and 
everything else in the data part. The only exception I can think of that of 
an intermediate firewall/NAT-box that may make a decision based on that 
field.

> stop speaking HTTP over port 80.

I don't see how transparent proxies will be affected by this. If they don't 
(want to) support the USER_DATA option then they will not reply to it and 
there will be no harm at all.
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: Joe Touch <[email-masked]>
Date: Sun, 21 Sep 2008 14:52:46 -0700

Hi, Stefanos,

> more) will break backwards compatibility. (no?)

Yes - that would be a different service, which is also why it should sit
on a different port.

> requirement to do otherwise.

If the data is "out of band", then the application needs to understand
what it means. TCP ports currently specify services with no out-of-band
information. If you want a service that understands that kind of
additional information, those would be a different service.

...

Understood; you're setting up a second data channel, and ACKing it
separately.

First, that can't be used to help reduce the RTT as Adam has suggested
without changing the "app doesn't get data until the handshake
completes" semantics.

Second, that information can't be used by the app unless you change the
*service* semantics, which means these are different services.

TCP options are for changing TCP behavior, not changing application
semantics, IMO.

> duplicate copies of messages?" to "No" in the mailman options but there was 

You should take this up with the list manager; I'm not sure of how TCPM
is setup.

Joe