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

From: Matt Mathis <[email-masked]>
Date: Fri, 1 Aug 2008 15:04:41 -0400 (EDT)

Opps I posted to the wrong thread.   Sorry folks..

Doesn't this create a huge opportunity for a DoS attack, since an attacker can 
send requests with forged from addresses, and the server has to
burn cycles and/or commit memory, when it is never going to see the next 
packet?

I believe that this problem is fundamental to anything that is piggybacked on 
the SYN and has killed every attempt at using the handshake to
eliminate later transactions.  The server wants to know for sure that the 
client is alive and responding before committing more than incidental
resources (e.g. SYN queue, constructing a SYN-cookie, etc) to the connection.

Thanks,
--MM--
-------------------------------------------
Matt Mathis     http://staff.psc.edu/mathis
Work:412.268.3319    Home/Cell:412.654.7529
-------------------------------------------
Evil is defined by mortals who think they know
"The Truth" and use force to apply it to others.

On Thu, 31 Jul 2008, Adam Langley wrote:

> I posted this a while back and it gathered a little discussion:
>
> http://www.ietf.org/internet-drafts/draft-agl-tcpm-sadata-00.txt
> (implementation in [1])
>
> I would like to have this published as Experimental and to get an
> option number assigned.
>
> The spec itself includes a somewhat rambling justification because I
> wanted to decouple the spec, which is more general, from the exact
> reason that I wish to start testing this over the Internet at large.
> However, in order to provoke discussion I think I should explain my
> motivation:
>
> This spec allows for opportunistic encryption of TCP connections with
> no additional round trips. Details of the project can be found at [2],
> however a quick summary follows:
>
> Although SYN/ACK payloads could be used to accelerate many protocols,
> I'm proposing that, for HTTP, the SYN/ACK payload contains an 8-byte
> random nonce and a 32-byte eliptic-curve public value. The client can
> then perform key agreement and send it's own public value, nonce and
> any encrypted payload in the final ACK. (Or in a following packet,
> that works fine too). Data is then encrypted using Salsa20/8 where the
> key is SHA256(diffie-hellman output + server nonce + client nonce) and
> the IVs are 0 and 2**63 for client->server and server->client, resp.
>
> Obviously, this open to both a downgrade and man-in-the-middle attack.
> For a specific user, it offers little real security. However,
> amortised over a large set of users, any ISPs performing these attacks
> on a large scale will be detected. (I plan on building a network of
> hosts probing for large scale attacks.) Thus, eavesdroppers are
> removed from the equation and, against the rest, it can protect most
> of the people, most of the time.
>
> I also plan to sign the resulting packets with TCP-AO at some point,
> if possible. However, given that that is still under development I'm
> going to make that part of the negotiation, above, so that it can be
> deployed without it for now.
>
> Obviously, this system can only prove itself in time. However, it
> can't prove itself with an option number assigned. And thus, I'm
> looking for a consensus that this is an interesting experiment.
>
> Thanks
>
> Having spoken to quite a few people about this, I now have an FAQ on
> the design which is included below:
>
> * Why Elliptic-curves?
>
> The payload must be short otherwise SYN-floods could use this as an
> amplification
> to backscatter DDoS another host.
>
> Also, the reduced computation cost (as compared to Diffie-Hellman over a
> multiplicative finite field) is very nice.
>
> * Why 25519?
>
> It's very fast (2000 ops/sec with my C code. 4000 ops/sec with asm). Also, the
> server's public value must be constant, otherwise an attacker could eat CPU
> time with a SYN flood and curve25519 is designed for that.
>
> Since this is constant for all connections, there is no perfect forward
> secrecy.
>
> * Can't you fit the client's public value in the SYN?
>
> A SYN generally has 20 bytes of free option space these days. (We can't use the
> payload space in a SYN). Since this can't be the last option ever, we need to
> leave 4 bytes spare. 2 bytes for the option header means 14 bytes for the
> public value. The closest prime is 2**112-75.
>
> I'm a bear of little brain and picking my own curve is already a hell of a
> task, but assuming that I can:
>
> The best, general algorithm currently known for breaking the DH problem on
> elliptic curves is Pollard's Rho. The work involved in this attack is sqrt(n),
> which is 2**56 in this case. Critically, once you have solved a single instance
> you can precompute tables to speed up breaking more instances. With a petabyte
> of storage, you could break 112-bit curves in 2**12 operations, which is very
> fast.
>
> * Can't you use a smaller field anyway?
>
> Some speedup could be gained by using an EC with a field size around 200 bits.
> However the effort of defining such a curve is pretty huge. The standard NIST
> curves around that size are slower:
>
> http://www.cacr.math.uwaterloo.ca/techreports/2003/corr2003-18.pdf (table 6)
>
> * Why Salsa20/8?
>
> It encrypts at two cycles per byte on modern CPUs[1]. The best attack on this,
> reduced round, variant is 2**251. It's very unlikely that an attack would ever
> break it to the point that it's easier than performing a downgrade attack.
>
> http://cr.yp.to/streamciphers/phase3speed-20080331.pdf
>
>
>
> [1] http://code.google.com/p/obstcp/source/browse/trunk/patches/synack-payload
> [2] http://code.google.com/p/obstcp/
>
> -- 
> Adam Langley [email-masked] http://www.imperialviolet.org
> _______________________________________________
> tcpm mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tcpm
>
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: "Adam Langley" <[email-masked]>
Date: Fri, 1 Aug 2008 12:23:57 -0700

On Fri, Aug 1, 2008 at 12:04 PM, Matt Mathis <[email-masked]> wrote:
> Doesn't this create a huge opportunity for a DoS attack, since an attacker
> can send requests with forged from addresses, and the server has to

The additional requirements on the server when processing a SYN under
my scheme are:
  * At most, an additional 12 bytes of state in the request sock. At
least, another 5 bytes (depending on alignment etc)
  * Generating 8 random bytes
  * Transmitting an additional 45 bytes in the SYNACK frame (3 bytes
of option + 8 random bytes + 32 bytes of elliptic curve point + 2
bytes header)

The additional storage isn't that bad. Currently, in Linux a
tcp_request_sock is 96 bytes:
(gdb) print ((struct tcp_request_sock *) 0)[1]
Cannot access memory at address 0x60

So the additional space isn't that great. Random number generation
isn't too bad either. Also, the spec explicitly says that hosts can
decide not to support it under load (e.g. if they are switching to SYN
cookies).

I did consider defining a special echo option to save on the server's
storage, but decided that I didn't think it was worth the extra
complexity.

Of course, these are subjective judgements; one might reasonably
consider that to be too much work for a SYN.

Cheers

AGL

---

From: Joe Touch <[email-masked]>
Date: Fri, 01 Aug 2008 11:17:27 -0700

Hi, Adam,

Adam Langley wrote:
| On Thu, Jul 31, 2008 at 4:02 PM, Joe Touch <[email-masked]> wrote:
|> - - TCP is already permitted to send data in the SYN-ACK
|>        prohibiting it when the SA-PP option is missing violates
|>        RFC1122 sec 4.2.2.5 -- unknown options are silently ignored
|>
|>        options that change TCP need to be explicitly acknowledged,
|>        and current (legacy) behavior should be assumed if not
|>        acknowledged
|
| Ah, I didn't know this. Thank you!
|
| I don't believe changing TCP to disallow this is a good idea. However,
| it's important that userland knows weather this experiment is in
| effect.

It's not an experiment; it's valid TCP behavior.

Why does the application need to know? As you note, it speeds up
application performance, but the app never knows how long the SYN
exchange takes anyway - or whether there are retransmissions.

- ------

Although there is more detailed feedback below, it might be useful to
raise this up a level.

If the purpose of this option is to encourage servers that know about
the option to potentially speed up their data transmission, then it
might be sufficient to just send the hint in the SYN. The SA would then
have the data if the server wanted to.

What if the server just assumed this? It seems like nothing
should break and it would work where it should anyway...

I.e., Nike's rule applies: "Just do it."
(no  need for an option)

(side note) Such an option might be useful, but might also be an issue.
It tests the fact that TCPs ignore unknown options, a test that might
fail. It also tests the fact that middleboxes should pass options
unmodified, which also might fail. Although either of these behaviors
would be out of spec, I wonder whether it's useful to try to optimize a
connection at the expense of it possibly failing.

If this option is intended to 'definitively speed up' connections,
there's nothing in TCP that is 'realtime'. Applications can't see things
like retransmission, or the fact that data in the SYN (and thus SYN-ACK)
need not be ACKd when the SYN (or SYNACK) is ACK'd. Application data
boundaries (writes) don't need to correspond to data segmentation
either. Overall, there seem like too many ways in which valid TCP
behavior can stall things for an extra RTT or so *anytime* during a
connection (including the handshake); forcing data into the SYNACK
doesn't seem productive if that's the case.

A change to TCP that makes this option visible seems like it's a change
to TCP semantics that requires broader modifications - the API needs to
be redefined, socket options (or the equivalent) need to be defined,
etc. For very short exchanges for which 1 RTT savings would be
significant, perhaps TCP isn't the right protocol to use, IMO. For
longer connections, the savings would be masked by other RTTs anyway.

- ------

The following are details, but it would be more useful to focus on the
above first...

- -- Joe

| Thus, I believe that I should echo the SA-PP option in the
| SYNACK.

You can, but it doesn't really matter. The SA-PP can be considered a
hint to the other end to encourage it to send data in the SA. If the SA
contains data, either the other end was suitably encouraged, or it
didn't need encouragement. Either way, the presence of the data in the
SA tells you what you need to know - that the other end sent data.

Either way, once your end receives SA data, it can allow its app layer
to access the data once the subsequent ACK is sent. As far as the
initiating end is concerned, the TWHS ends when that ACK is sent anyway.

| Also, it should probably change names: SYN/ACK Payloads
| Processed or some similar.
|
|> - - The rule "For a given SYN, if any resulting SYNACK frame has a
payload
|> then all resulting frames MUST have a payload" appears to disable
|> persists and ACKs as would be needed for proper operation when data is
|> not available in one or more direction
|
| That's badly worded on my part. It should read:
| "For a given SYN, if any resulting SYNACK frame has a payload then all
| resulting SYNACK frames MUST have a payload"

There is only one SYNACK segment in a connection in a given direction,
excepting retransmissions. There is no reason why retransmissions need
to include data - if the SA with data is received, either the SA is ACKd
or the SA and data are ACKd; if the SA without data is received, it
would be ACKd.

The result is that either the ACK says the SA data got there or not. If
not, then it would be retransmitted in a regular data packet.

Again, since TCP is NOT a 'realtime' protocol - and doesn't have a
'realtime' handshake', the application can't know or care about the
difference.

| (i.e. the restriction only apply to SYNACK frames. It's just so a host
| cannot decide the retransmit a different SYNACK)

See above; I don't see why it would, but I don't see why the application
could care.

...
|> - - the diagrams need to include some corner cases:
|>        - when KX is larger than the PMTU in fig 3 (or NList is
|>        larger than the PMTU in fig 2)
|>        (i.e., it seems like there is a missing MUST NOT on the length)
|
| It's suggested that the payload be limited to 64-bytes to prevent
| amplification backscatter from a SYN flood. Thus these bytestrings
| have to fit within the MTU. If an implementation doesn't enforce this,
| then it has to drop support when replying on a link where the MTU is
| insufficient.

A 576 MTU is the smallest size that endpoints agree to reassemble; it is
NOT the smallest MTU all links agree to support in the Internet. The
smallest MTU is 68 bytes - i.e., IP with all possible options, TCP with
none, and the smallest possible fragment (8 bytes) [see RFC791]. As a
result, a 64-byte payload is too large to assume that it won't be
fragmented (that may be true practically in many cases, but it isn't a
requirement).

|>        - how do you handle simultaneous opens?
|
| I believe that simultaneous opens work just fine, although both sides
| will believe that the other doesn't support this experiment since the
| option won't be echoed in the SYN.

A SA is just a SYN with an ACK. In simultaneous opens, the ACK for each
SYN comes alone. In that case, whether the ACK of the SYN (which, in
simultaneous open is just an ACK) could include the option and data if
it is sent after the other side's SYN is received. I.e., depending on
how the SYNs cross, the handshake might succeed or might not.

If confirming the option is critical, you need to handle this case. As
noted above, it might not be critical (or even necessary).

|> - - can you explain why you use a bit-field for the TCP option flag,
|> rather than just using a 2-byte option? (i.e., KIND, length)
|
| My hope was that by defining a flags option like this, future options
| that require only to signal their presence in a SYN could save space.

That might be a useful to document as a separate issue, since it's
orthogonal to this option. However, you'd need more rules, like the fact
that the responder needs to clear (or truncate) all bits it doesn't
understand or doesn't agree to.

It'd be useful to develop this more fully and get WG feedback on it
separately, IMO.

It's not always as efficient as it appears, FWIW: it trades efficiency
when many flags are set for inefficiency when only recent flags are
defined. E.g., the 25th such flag pays an extra 3-byte penalty when no
other flags are used.

---

From: "Adam Langley" <[email-masked]>
Date: Sat, 2 Aug 2008 12:00:50 -0700

> It's not an experiment; it's valid TCP behavior.

Whenever I'm speaking about an experiment, I mean this draft - it
being "experimental"

> Although there is more detailed feedback below, it might be useful to

Thanks for your detailed response, I fear that there's a
misunderstanding somewhere and that's almost certainly the fault of my
inadequate writeups. Please let me try again:

At the moment, almost no stacks will send payloads in the SYNACK even
though they could as an optimisation. This springs from a few reasons:
  R1) Processing time for a SYN must be minimal to mitigate the
effects of SYN floods. Even waking up an application to process a SYN
would greatly increase the costs.
  R2) Replies to SYNs must be small, otherwise it provides a way to
amplify a DDoS attacks using false source IP addresses.
  R3) The ubiquitous sockets API doesn't make it easy to do so.

I'm proposing that a constant payload (optionally with 8 random bytes)
overcomes R1 and R3. And limiting the size of that payload to 64 bytes
overcomes R2.

There are protocols that could immediately benefit from a gradual
deployment of hosts which supported a setsockopt to set a constant
payload and hosts that would ACK and enqueue such a payload. (I
currently know of no stacks that do either however.) SMTP would be one
such protocol: clients wait for a 200 code banner from the server
before starting their part of the exchange and the banner is small and
constant. SMTP is also a protocol which ends up making many, short
connections.

Additionally, this would also be easy to deploy. For clients that
don't support it, they will ACK only the SYN flag and then the server
knows to include the payload again in the next frame.

However, the sockets API has guided the design of many application
level protocols. Because of this, these protocols are often designed
such that
  * The client starts the exchange: see HTTP
  * The exchange is large, since there's little space pressure: SSH
algorithm agreement uses strings like "diffie-hellman-group14-sha1"
(28 bytes) because of this.

Modifications to take advantage of SYNACK payloads would then require
changes to the application level protocol. This could be managed by
assigning new ports, trying connections on the new ports first,
backing off etc. However, given that this is a partly a latency
optimisation, that's an anathema.

So I additionally define an option that the application layer can set
and query that advertises support for this trick and allows many more
application level protocols to take advantage of it.

So, fundamentally, we end up with an opportunistic experiment that can
provide advantages, but may also have some costs if middleware gets
upset etc, as you note:

> unmodified, which also might fail.

Because of this, I wanted to make sure that clients were free to retry
a connection without the option in the case that something was
reacting badly to it. Many of the words in the draft are then
dedicated to making sure that both endpoints reach a consistent view
of when this option is in effect. Like the prohibition of not
including the option in a SYNACK if the previous SYNACK included it.
If that were to happen, the endpoint couldn't know which SYNACK the
peer saw and thus wouldn't know if the option was in effect or not.

For all of your comments that I have removed below, I hope that I've
addressed them in the above. If not, please highlight them again and I
will attempt to better do so.

Also, if the above was clearer then I should consider using it in the draft.

> fragmented (that may be true practically in many cases, but it isn't a

I don't believe that we should specify this. If a host finds itself in
a situation where the SYNACK payload is problematic in the face of the
MTU it may, validly, choose to fragment or to not echo the option. I
think the implementations have better information about which is the
best course of action.

> noted above, it might not be critical (or even necessary).

I believe that both sides will end up with a consistent view of
weather the option is in effect (neither will believe it to be so).

> understand or doesn't agree to.

Yes, I'll add that words to that effect.

Looking at the list of currently assigned options, very few of them
are binary flags like this (SACK permitted is the other major one,
"Partial Order Connection Permitted", etc), suggesting that it might
not be worthwhile. As you point out:

> the 25th such flag pays an extra 3-byte penalty when no
> other flags are used.

Which is true. I'm happy with whatever the consensus is.

Cheers

AGL

---

From: Joe Touch <[email-masked]>
Date: Sun, 03 Aug 2008 06:26:08 -0700

Hi, Adam,

Again, popping up a level, you've made a good case for a socket option
that lets the server app signal its TCP to try to send data in the
SYNACK. TCPs that do this will; TCPs that don't will fail on the socket
option, and the server will know.

I am unclear why the client TCP is involved in this; if the data is
sent, it will either be acknowledged or retransmitted. There is no
change to the semantics, and only a change to timing (which NOTHING in
TCP ensures anyway).

As a minor note, it doesn't seem useful to extend that socket option to
say how much data to put in the SYNACK; nothing else in TCP knows about
application data boundaries, and I think it would be a mistake to assume
that. You might add something like:

	setsockopt(SEND_SA_DATA, bytecount)

where:
	bytecount = number of data bytes the app is *suggesting*
	the SA include; this is NOT guaranteed to be enforced
	by TCP

if the sockopt succeeds, the app should reasonably assume that bytecount
bytes are sent in the SYNACK if available when the SYNACK is sent

As a final question (I'm not a sockets expert), it might be that there
are other socket modifications to allow users to write to connections
that are not yet open (or can they just be queued up? in which case, it
seems like the socket must be completely bound, i.e., this might not
work for unbound LISTENs).

Specific notes below...

Joe

Adam Langley wrote:
...
| Thanks for your detailed response, I fear that there's a
| misunderstanding somewhere and that's almost certainly the fault of my
| inadequate writeups. Please let me try again:
|
| At the moment, almost no stacks will send payloads in the SYNACK even
| though they could as an optimisation. This springs from a few reasons:
|   R1) Processing time for a SYN must be minimal to mitigate the
| effects of SYN floods. Even waking up an application to process a SYN
| would greatly increase the costs.
|   R2) Replies to SYNs must be small, otherwise it provides a way to
| amplify a DDoS attacks using false source IP addresses.
|   R3) The ubiquitous sockets API doesn't make it easy to do so.

This sounds like a really good reason to extend the API to have a flag
that allows the server app to ask its TCP to send data in the SYN-ACK if
possible. That sounds consistent with the overall TCP model, AFAICT.

I see no good way to have the application tell TCP how many bytes to
send, or to have TCP tell the app this. That is an API change that lets
the app know about segment boundaries, and that's inconsistent with
TCP's API semantics.

| I'm proposing that a constant payload (optionally with 8 random bytes)
| overcomes R1 and R3. And limiting the size of that payload to 64 bytes
| overcomes R2.

I don't understand the "8 random bytes" issue; the data path should be
sending data from the app only, and that's not random.

| There are protocols that could immediately benefit from a gradual
| deployment of hosts which supported a setsockopt to set a constant
| payload and hosts that would ACK and enqueue such a payload.

The sockopt sounds OK - but I'm not too sure about knowing the payload
boundaries at the app layer. Again, that is inconsistent with TCP
presenting a stream model.

~ > Additionally, this would also be easy to deploy. For clients that
| don't support it, they will ACK only the SYN flag and then the server
| knows to include the payload again in the next frame.

Sure.

| However, the sockets API has guided the design of many application
| level protocols. Because of this, these protocols are often designed
| such that
|   * The client starts the exchange: see HTTP
|   * The exchange is large, since there's little space pressure: SSH
| algorithm agreement uses strings like "diffie-hellman-group14-sha1"
| (28 bytes) because of this.

Sure.

| Modifications to take advantage of SYNACK payloads would then require
| changes to the application level protocol. This could be managed by
| assigning new ports, trying connections on the new ports first,
| backing off etc. However, given that this is a partly a latency
| optimisation, that's an anathema.

I don't see this at all. Apps don't need any modification, other than to
set the "send data early in the SYNACK" flag. That can be set by default
on a per-port basis, or set within the app directly.

| So I additionally define an option that the application layer can set
| and query that advertises support for this trick and allows many more
| application level protocols to take advantage of it.

***this is the big question***

Why do you need an option that does this? Seems like the app can always
TRY to do it, and the data just gets retransmitted if dropped (i.e., not
supported at the receiver).

|> (side note) Such an option might be useful, but might also be an issue.
|> It tests the fact that TCPs ignore unknown options, a test that might
|> fail. It also tests the fact that middleboxes should pass options
|> unmodified, which also might fail.
|
| Because of this, I wanted to make sure that clients were free to retry
| a connection without the option in the case that something was
| reacting badly to it.

Wouldn't it be simpler to do this without an option at all, then?
_______________________________________________
tcpm mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/tcpm

---

From: "Adam Langley" <[email-masked]>
Date: Sun, 3 Aug 2008 11:06:31 -0700

On Sun, Aug 3, 2008 at 6:26 AM, Joe Touch <[email-masked]> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> that.

For protocols like SMTP where a constant banner is sent at the
beginning of every connection, that's true. As long as the data, if
not sent in the SYNACK, is enqueued to be sent anyway, that would
certainly work.

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
  ...

Given the latency sensitivity, nobody actually probes for
opportunistic TLS like this.

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.

With SYNACK payloads, we can add this very useful banner without add a
round trip. However, servers can't just start including the banner
whenever the server's kernel supports the SYNACK payload setsockopt
because it would break all the existing clients who wouldn't know what
to make of it.

Had SYNACK payloads been generally available when HTTP was created, we
would have ended up with a different protocol. So, to take advantage
of SYNACK payloads in HTTP we need to make a backwards incompatible
modification to the protocol. Thus, the option is to decide if this
different protocol is in effect. That's why both sides need to reach a
consistent view of it.

This same logic applies to any protocol that eschewed a server banner
for latency reasons. So the new application level exchange looks like:

Client <--- Banner --- Server
Client --- Request ---> Server
Client <--- Reply --- Server

But, because of SYNACK payloads, the number of round trips can be the same.

> work for unbound LISTENs).

This would be a major change to the sockets API. Additionally, it
would require waking up userspace processes for every SYN, making SYN
floods more effective.

To avoid this, I'm fixing the logic that the application can use and
moving it to the kernel. I propose that the logic be:

unsigned payload_length;
u8 *payload = applications_constant_payload(&payload_length);

if (include_random_nonce && payload_length >= 8) {
   u8 random[8];
   generate_random_bytes(random, 8);
   memcpy(payload, random, 8);
}

if (only_send_if_requested) {
  if (SA_PP_option_seen_in_syn) {
    write(payload, payload_length);
  }
} else {
  write(payload, payload_length);
}

> the app know about segment boundaries, and that's inconsistent with

In correctness terms, you are correct. It doesn't matter when the
banner gets sent, or if it gets split over several packets. However,
applications would very much like to know how many bytes the kernel
will agree to transmit in reply to a SYN frame because, if a banner
would cost an extra round trip they might prefer not to include it.
It's because of this that the draft specifies the 64 bytes number.
This does expose aspects of segmentation to userspace. However, many
scarifies are made in the name of DDoS mitigation.

> sending data from the app only, and that's not random.

The optional inclusion of random bytes covers the one case where
requiring a constant payload is problematic: cryptographic protocols
very often want to include a random nonce. Because of this, I'm making
an exception to the "constant payload" rule because the kernel can
easily fulfill this.

[1] (justification that HTTP is very latency sensitive:)

I have access to private data that confirms that user-perceived
latency is very important, but here are some public quotes to that
effect:

"In A/B tests (at Amazon.com), we tried delaying the page in
increments of 100 milliseconds and found that even very small delays
would result in substantial and costly drops in revenue."
(http://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html)

"would you like 10, 20, or 30 results (from a Google search). Users
unanimously wanted 30. But 10 did way better in A/B testing (30 was
20% worse) due to lower latency of 10 results. 30 is about twice the
latency of 10" (http://perspectives.mvdirona.com/2008/05/29/IO2008RoughNotesFromMarissaMayerDay2KeynoteAtGoogleIO.aspx)

Cheers,

AGL

---

From: Joe Touch <[email-masked]>
Date: Sun, 03 Aug 2008 14:13:56 -0700

Hi, Adam,

Adam Langley wrote:
| On Sun, Aug 3, 2008 at 6:26 AM, Joe Touch <[email-masked]> wrote:
|> -----BEGIN PGP SIGNED MESSAGE-----
|> As a minor note, it doesn't seem useful to extend that socket option to
|> say how much data to put in the SYNACK; nothing else in TCP knows about
|> application data boundaries, and I think it would be a mistake to assume
|> that.
|
| For protocols like SMTP where a constant banner is sent at the
| beginning of every connection, that's true. As long as the data, if
| not sent in the SYNACK, is enqueued to be sent anyway, that would
| certainly work.
|
| 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].

This has been known for a while ;-)

e.g.: John Heidemann, Katia Obraczka, and Joe Touch, "Modeling the
Performance of HTTP Over Several Transport Protocols", IEEE/ACM
Transactions on Networking, V5, N5, Oct. 1997, pp.616-630.

| 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
|   ...
|
| Given the latency sensitivity, nobody actually probes for
| opportunistic TLS like this.
|
| If HTTP sent a banner, like SMTP servers, then my life would be a lot
| easier! The banner could advertise all the extensions supported.

That sounds like a useful thing to raise to the httpbis WG, FWIW.

| However, without SYNACK payloads, this banner would cost another round
| trip.

I have noted this before; an extra RTT doesn't do much of anything.
There are more delays in HTTP over TCP that incur round trips, e.g.,
dealing with interactions with sending an ACK every other segment, as
well as apps that fail to disable Nagle optimizations (as  they should
when they're interactive and have messages longer than a single byte).

| With SYNACK payloads, we can add this very useful banner without add a
| round trip. However, servers can't just start including the banner
| whenever the server's kernel supports the SYNACK payload setsockopt
| because it would break all the existing clients who wouldn't know what
| to make of it.

This is where you've lost me. Server TCPs can send data in the SYNACK.
Clients that ACK just the SYN cause the server to retransmit; clients
that ACK the whole segment work as you intend.

What part if this isn't sufficient?

| Had SYNACK payloads been generally available when HTTP was created, we
| would have ended up with a different protocol.

Please explain. From the app point of view, *nothing changes*. TCP is a
stream oriented protocol, and ***NOTHING*** the app does necessarily
correlates to particular segments. The app sees the data get there.

I.e., apps that require any sort of realtime behavior ought not be using
TCP.

...
|> As a final question (I'm not a sockets expert), it might be that there
|> are other socket modifications to allow users to write to connections
|> that are not yet open (or can they just be queued up? in which case, it
|> seems like the socket must be completely bound, i.e., this might not
|> work for unbound LISTENs).
|
| This would be a major change to the sockets API.

I agree, but isn't that where this is going? If not, how do you expect
it to be used?

...
| To avoid this, I'm fixing the logic that the application can use and
| moving it to the kernel. I propose that the logic be:
|
| unsigned payload_length;
| u8 *payload = applications_constant_payload(&payload_length);
|
| if (include_random_nonce && payload_length >= 8) {
|    u8 random[8];
|    generate_random_bytes(random, 8);
|    memcpy(payload, random, 8);
| }
|
| if (only_send_if_requested) {
|   if (SA_PP_option_seen_in_syn) {
|     write(payload, payload_length);
|   }
| } else {
|   write(payload, payload_length);
| }

This code is confusing; is it a library that happens to be in the
kernel, or is it intended to be code inside TCP?

If it's just a library, it doesn't matter where it is. To TCP, the
"write" calls are its "application". There is no such thing as a payload
length at that point; the app has no knowledge of how writes correspond
to payload entities.

If this is intended inside TCP, you're having TCP insert data into the
user stream. That changes TCP semantics.

Can you explain which of the above applies, or some other interpretation
that explains the code without such inconsistencies?

|> I see no good way to have the application tell TCP how many bytes to
|> send, or to have TCP tell the app this. That is an API change that lets
|> the app know about segment boundaries, and that's inconsistent with
|> TCP's API semantics.
|
| In correctness terms, you are correct. It doesn't matter when the
| banner gets sent, or if it gets split over several packets. However,
| applications would very much like to know how many bytes the kernel
| will agree to transmit in reply to a SYN frame because, if a banner
| would cost an extra round trip they might prefer not to include it.

***WHY???***

I know I'm repeating myself here, but ***TCP IS NOT A REALTIME
PROTOCOL***, and there is *no correlation between user writes and
segment boundaries*.

...
| [1] (justification that HTTP is very latency sensitive:)
|
| I have access to private data that confirms that user-perceived
| latency is very important, but here are some public quotes to that
| effect:
|
| "In A/B tests (at Amazon.com), we tried delaying the page in
| increments of 100 milliseconds and found that even very small delays
| would result in substantial and costly drops in revenue."
| (http://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html)
|
| "would you like 10, 20, or 30 results (from a Google search). Users
| unanimously wanted 30. But 10 did way better in A/B testing (30 was
| 20% worse) due to lower latency of 10 results. 30 is about twice the
| latency of 10"
(http://perspectives.mvdirona.com/2008/05/29/IO2008RoughNotesFromMarissaMayerDay2KeynoteAtGoogleIO.aspx)

Did you actually try reducing the overal latency of a single TCP
connection by 1 RTT and see if it actually matters? If these apps are
using persistent connections, then the first RTT exchange is all they'll
see anyway.

Joe

---

From: "Anantha Ramaiah (ananth)" <[email-masked]>
Date: Sun, 3 Aug 2008 21:56:01 -0700

Adam,
    I managed to read this draft on my return flight and had marked some
comments. I have only cursorily glanced at the other comments and hence
there could be a possibility of overlap with what has been already
mentioned.

Abstract

- fix the sentence : "we should how this has...."

- you mention "cryptographic applications" would benefit with this
proposal, and give example of SSH in your draft. It would be really
interesting to know how many very commonly used TCP applications would
really benefit with this ? Atleast the draft can mention those..

- with the SSH example which you give, it appears that one of the
advantages of this proposal is that you can tear down the connection
before the connection moves to ESTAB if the authentication fails?  (For
eg:- some implementations don't create a full blown TCB before TWHS
completes)

Section 3 :

- Can you elaborate on the flags option? It simply mentions that the
meaning of this would be assigned by IANA? Again this is not infinite
(2+n, n is finite) since it should be bounded by the TCP header length
inclusive of options?

- the doc says (section 3 ) "host MUST not include data payload in
SYN+ACK resulting from a SYN frame without SYNACK payload permitted"
But RFC 793 does permit data in SYN which includes SYN+ACK, so this
statement raises a new level of ambiguity.

Section 4:

You mention 64 bytes of payload is enough to include sufficient crypto
material. Just wondering the interoperability of this statement with TCP
auth (TCP MD5 and TCP AO for example)

What about Kamikaze like packets ? where SYN, FIN are set the
applications can send data and also set the FIN bit in the oriinal SYN
(Not sure if 793 talks about it but Stevens book does mention it and so
as BSD implementatiosns which support this type of packets) Would those
still work within your proposal?

Also, the applications need to change to make use of this proposal (the
HTTP example which you mention below) In other words, it would be nice
if you can explain the "opportunistic encryption" scheme and how
applications (which all) can benefit from your proposal in more detail
in the draft.

-Anantha

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On 
> Behalf Of Adam Langley
> Sent: Thursday, July 31, 2008 12:52 PM
> To: [email-masked]
> Subject: [tcpm] Faster application handshakes with SYN/ACK payloads
> 
> I would like to have this published as Experimental and to 
> get an option number assigned.
> 
> The spec itself includes a somewhat rambling justification 
> because I wanted to decouple the spec, which is more general, 
> from the exact reason that I wish to start testing this over 
> the Internet at large.
> This spec allows for opportunistic encryption of TCP 
> connections with no additional round trips. Details of the 
> project can be found at [2], however a quick summary follows:
> 
> Although SYN/ACK payloads could be used to accelerate many 
> protocols, I'm proposing that, for HTTP, the SYN/ACK payload 
> contains an 8-byte random nonce and a 32-byte eliptic-curve 
> public value. The client can then perform key agreement and 
> send it's own public value, nonce and any encrypted payload 
> in the final ACK. (Or in a following packet, that works fine 
> too). Data is then encrypted using Salsa20/8 where the key is 
> SHA256(diffie-hellman output + server nonce + client nonce) 
> and the IVs are 0 and 2**63 for client->server and 
> server->client, resp.
> 
> amortised over a large set of users, any ISPs performing 
> these attacks on a large scale will be detected. (I plan on 
> building a network of hosts probing for large scale attacks.) 
> Thus, eavesdroppers are removed from the equation and, 
> against the rest, it can protect most of the people, most of the time.
> 
> I also plan to sign the resulting packets with TCP-AO at some 
> point, if possible. However, given that that is still under 
> development I'm going to make that part of the negotiation, 
> above, so that it can be deployed without it for now.
> 
> Obviously, this system can only prove itself in time. 
> However, it can't prove itself with an option number 
> assigned. And thus, I'm looking for a consensus that this is 
> an interesting experiment.
> 
> Thanks
> 
> Having spoken to quite a few people about this, I now have an 
> FAQ on the design which is included below:
> 
> * Why Elliptic-curves?
> 
> The payload must be short otherwise SYN-floods could use this 
> as an amplification to backscatter DDoS another host.
> 
> Also, the reduced computation cost (as compared to 
> Diffie-Hellman over a multiplicative finite field) is very nice.
> 
> * Why 25519?
> 
> It's very fast (2000 ops/sec with my C code. 4000 ops/sec 
> with asm). Also, the server's public value must be constant, 
> otherwise an attacker could eat CPU time with a SYN flood and 
> curve25519 is designed for that.
> 
> Since this is constant for all connections, there is no 
> perfect forward secrecy.
> 
> A SYN generally has 20 bytes of free option space these days. 
> (We can't use the payload space in a SYN). Since this can't 
> be the last option ever, we need to leave 4 bytes spare. 2 
> bytes for the option header means 14 bytes for the public 
> value. The closest prime is 2**112-75.
> 
> I'm a bear of little brain and picking my own curve is 
> already a hell of a task, but assuming that I can:
> 
> The best, general algorithm currently known for breaking the 
> DH problem on elliptic curves is Pollard's Rho. The work 
> involved in this attack is sqrt(n), which is 2**56 in this 
> case. Critically, once you have solved a single instance you 
> can precompute tables to speed up breaking more instances. 
> With a petabyte of storage, you could break 112-bit curves in 
> 2**12 operations, which is very fast.
> 
> However the effort of defining such a curve is pretty huge. 
> The standard NIST curves around that size are slower:
> 
> It encrypts at two cycles per byte on modern CPUs[1]. The 
> best attack on this, reduced round, variant is 2**251. It's 
> very unlikely that an attack would ever break it to the point 
> that it's easier than performing a downgrade attack.
> 
> [1] 
> http://code.google.com/p/obstcp/source/browse/trunk/patches/sy
> nack-payload

---

From: "Adam Langley" <[email-masked]>
Date: Mon, 4 Aug 2008 10:25:01 -0700

> when they're interactive and have messages longer than a single byte).

A extra round trip is very important. See the two quotes that I
highlighted above for some evidence. At Google we work to shave off
every millisecond and anything which required a whole extra round trip
would, rightly, be dismissed immediately. I wouldn't even bother
proposing such a scheme.

> What part if this isn't sufficient?

Taking HTTP as an example, the very first bytes from the server must
be the reply to the first request from the client. If servers started
sending something else before hand, no matter what packet it's carried
in, all existing HTTP clients would break.

I'm suggesting that, if the ability to get a short banner from the
server to the client in the SYNACK had been generally available when
HTTP was created, the authors would have used it and the
application-level protocol would have been different. The fact that it
otherwise requires an extra round trip was strong reason for the
client to start the exchange.

However, since it wasn't availible, in order for some protocols (inc
HTTP) to take advantage of such a capability we need an option to
signal to both ends that they can use a slightly different application
level protocol. At the server side, to add the extra banner, and at
the client side to expect it.

> I agree, but isn't that where this is going? If not, how do you expect

I expect it to be a setsockopt at both the client and server ends.

> that explains the code without such inconsistencies?

Imaging that we change the sockets interface such that applications
get a callback when a SYN frame is received on a listening socket.
Applications could inspect the SYN frame and choose to enqueue data to
be written. Hopefully the kernel would send some of that data in the
SYNACK, but that's unimportant here.

There are stacks which could do that[1]. However, for most stacks that
would be painfully incongruent and the additional load would make SYN
floods a real problem.

So, as an implementation detail, we might have that function in the
kernel. Since few kernels are happy with userspace machine code
running in kernelspace, I expect that most implementations will choose
to allow the application to configure a fixed function. The code was
pseudocode for what that fixed function might look like. Applications
would be able to configure the inputs: payload, payload_length,
include_random_nonce and only_send_if_requested in that example.

It might be the case that all such details, being implementation
specific, shouldn't be included in the spec. I didn't want to spec to
be too abstract, however.

[1] http://tservice.net.ru/~s0mbre/old/?section=projects&item=unetstack

> PROTOCOL***, and there is *no correlation between user writes and

"realtime" to me means that there are known latency bounds. My this
definition, TCP isn't a realtime protocol. However, average latency
still matters very much.

> using persistent connections, then the first RTT exchange is all they'll

Yes. These are internal numbers, sadly, but a RTT really does matter.
For well connected users, an RTT might be only 20ms to multi-homed
service. That, I'll agree, is fairly inconsequential. But San
Francisco <-> London is about 150ms and if you're in less well
connected continents (like Africa), RTTs are hundreds of milliseconds
to anywhere. An RTT really matters.

AGL

---

From: "Adam Langley" <[email-masked]>
Date: Mon, 4 Aug 2008 10:52:33 -0700

> - fix the sentence : "we should how this has...."

Thanks! will do.

> really benefit with this ? Atleast the draft can mention those..

Will do with the next draft.

> eg:- some implementations don't create a full blown TCB before TWHS

Indeed. Although I believe that a (short lived) TCB would actually be
created in this case for current, common stacks, that's an
implementation limit. It would be possible, with the authentication
that I sketched, for neither end to create a TCB if the server's
public value didn't match.

> (2+n, n is finite) since it should be bounded by the TCP header length

The flags option was designed to allow future flag options to be
assigned bits, rather than option numbers. Consider that, if SACK
permitted has been designed this way, then this proposed option
wouldn't need any extra options space, it could just take a bit in an
option that it already ubiquitous. However, it might well be the case
that I should just stick to a standard, 2 byte, option for this.

> statement raises a new level of ambiguity.

Thanks. Joe pointed out this ambiguity also. It will be fixed in the
next draft by echoing the option in the SYNACK.

> auth (TCP MD5 and TCP AO for example)

The method for upgrading a normal connection to TCP AO is currently
not specified, although there has been discussion of it. In my
current, very rough, patches there's an option that I'm calling LATCH
that allows a connection to upgrade to TCP AO. Also, I have userspace
software that uses SYNACK payloads and LATCH to establish a connection
and upgrade to TCP AO using the agreed key (and no additional round
trips). Fundamentally, however, these drafts are independent.

> still work within your proposal?

I would have to investigate how the BSD stacks handle this. Linux
would ack only the SYN flag, to the other host would have to
retransmit any data and the FIN anyway. BSD stacks, I hope, would not
deliver data to userspace with an unauthenticated source IP address,
so may do the same. But it isn't incompatible with my scheme. The
SYNACK payload, if configured, would be sent as part of the data
stream.

> applications (which all) can benefit from your proposal in more detail

Since several people have suggested this, I certain shall in the next
draft (which should be in the next couple of days)

Thanks for your comments.

AGL

---

From: Joe Touch <[email-masked]>
Date: Mon, 04 Aug 2008 11:20:39 -0700

Hi, Adam.

Adam Langley wrote:
| On Sun, Aug 3, 2008 at 2:13 PM, Joe Touch <[email-masked]> wrote:
|> | However, without SYNACK payloads, this banner would cost another round
|> | trip.
|>
|> I have noted this before; an extra RTT doesn't do much of anything.
|> There are more delays in HTTP over TCP that incur round trips, e.g.,
|> dealing with interactions with sending an ACK every other segment, as
|> well as apps that fail to disable Nagle optimizations (as  they should
|> when they're interactive and have messages longer than a single byte).
|
| A extra round trip is very important. See the two quotes that I
| highlighted above for some evidence. At Google we work to shave off
| every millisecond and anything which required a whole extra round trip
| would, rightly, be dismissed immediately.

IMO, you are confusing TCP with RTP if that's the case. I appreciate the
idea of optimizing TCP, but there are so many other places where RTTs
are not under your control, and so many RTTs in a connection, that
removing (or adding) a single one anywhere seems in the noise.

Let's agree to disagree on that point, and let others weigh in. Moving on...

|> | With SYNACK payloads, we can add this very useful banner without add a
|> | round trip. However, servers can't just start including the banner
|> | whenever the server's kernel supports the SYNACK payload setsockopt
|> | because it would break all the existing clients who wouldn't know what
|> | to make of it.
|>
|> This is where you've lost me. Server TCPs can send data in the SYNACK.
|> Clients that ACK just the SYN cause the server to retransmit; clients
|> that ACK the whole segment work as you intend.
|>
|> What part if this isn't sufficient?
|
| Taking HTTP as an example, the very first bytes from the server must
| be the reply to the first request from the client. If servers started
| sending something else before hand, no matter what packet it's carried
| in, all existing HTTP clients would break.
|
| I'm suggesting that, if the ability to get a short banner from the
| server to the client in the SYNACK had been generally available when
| HTTP was created, the authors would have used it and the
| application-level protocol would have been different. The fact that it
| otherwise requires an extra round trip was strong reason for the
| client to start the exchange.
|
| However, since it wasn't availible, in order for some protocols (inc
| HTTP) to take advantage of such a capability we need an option to
| signal to both ends that they can use a slightly different application
| level protocol. At the server side, to add the extra banner, and at
| the client side to expect it.

That seems like - as you note - an application layer protocol issue. It
doesn't seem to have anything to do with TCP.

...
|> This code is confusing; is it a library that happens to be in the
|> kernel, or is it intended to be code inside TCP?
|>
|> If this is intended inside TCP, you're having TCP insert data into the
|> user stream. That changes TCP semantics.
|>
|> Can you explain which of the above applies, or some other interpretation
|> that explains the code without such inconsistencies?
|
| Imaging that we change the sockets interface such that applications
| get a callback when a SYN frame is received on a listening socket.
| Applications could inspect the SYN frame and choose to enqueue data to
| be written. Hopefully the kernel would send some of that data in the
| SYNACK, but that's unimportant here.

Why wouldn't the application just enqueue the data? Why does it need to
know that the other end supports this?

...
|> Did you actually try reducing the overal latency of a single TCP
|> connection by 1 RTT and see if it actually matters? If these apps are
|> using persistent connections, then the first RTT exchange is all they'll
|> see anyway.
|
| Yes. These are internal numbers, sadly, but a RTT really does matter.
| For well connected users, an RTT might be only 20ms to multi-homed
| service. That, I'll agree, is fairly inconsequential. But San
| Francisco <-> London is about 150ms and if you're in less well
| connected continents (like Africa), RTTs are hundreds of milliseconds
| to anywhere. An RTT really matters.

150ms is large when considered in the context of a small number of RTTs,
but in the context of a connection that lasts 10 RTTs, it's 10%; the
impact drops as you keep the connection going.

I.e., a reduction of a single RTT is important only when the total
exchange lasts 2-3 RTTs. That's 8KB-16KB of data - and it matters only
for the first chunk of data in a persistent connection. For web pages
with dozens of embedded components (in specific, more than 4, which is
the typical limit for simultaneous connections), again this seems very
much in the noise...

Joe

---

From: "Adam Langley" <[email-masked]>
Date: Tue, 5 Aug 2008 11:27:55 -0700

> know that the other end supports this?

It doesn't always. SMTP, IRC and SSH protocols, for example, all
include a banner from the server to the client. In this case, the data
can be unconditionally enqueued for transmission. It's for protocols
which don't already start with a server->client transmission, and for
which we wish to add one, that the client must signal that we're
changing the application level protocol for this connection.

> the typical limit for simultaneous connections), again this seems very

Many Google users are now using search bars to submit queries. Thus
they type into a text field in the browser, hit enter and the browser
makes a connection, sends the query encoded in a GET and displays the
result. This is one example of a situation where the connection
latency isn't amortised. There are many others, but obviously, this is
the example that usually dominates my thinking. And, in this
situation, it turns out that every 10ms makes a difference.

I might be wrong here. This might be an overcomplex solution. But I
think only time will tell, which is why I wish to have it published as
an experimental spec. If, in a couple of years, it doesn't work the
option number can be released, ready for the next guy.

Cheers,

AGL

---

From: Joe Touch <[email-masked]>
Date: Tue, 05 Aug 2008 16:46:44 -0700

Hi, Adam,

Adam Langley wrote:
| On Mon, Aug 4, 2008 at 11:20 AM, Joe Touch <[email-masked]> wrote:
|> | Imaging that we change the sockets interface such that applications
|> | get a callback when a SYN frame is received on a listening socket.
|> | Applications could inspect the SYN frame and choose to enqueue data to
|> | be written. Hopefully the kernel would send some of that data in the
|> | SYNACK, but that's unimportant here.
|>
|> Why wouldn't the application just enqueue the data? Why does it need to
|> know that the other end supports this?
|
| It doesn't always. SMTP, IRC and SSH protocols, for example, all
| include a banner from the server to the client. In this case, the data
| can be unconditionally enqueued for transmission. It's for protocols
| which don't already start with a server->client transmission, and for
| which we wish to add one, that the client must signal that we're
| changing the application level protocol for this connection.

Using a transport signal to change the application protocol seems very
strange to me. Others can comment on that. My view is that this is a
case where perhaps you want something that is better encoded by using a
different port number (thus a different application service, explicitly)
than a TCP option that implies that application behavior.

|> 150ms is large when considered in the context of a small number of RTTs,
|> but in the context of a connection that lasts 10 RTTs, it's 10%; the
|> impact drops as you keep the connection going.
|>
|> I.e., a reduction of a single RTT is important only when the total
|> exchange lasts 2-3 RTTs. That's 8KB-16KB of data - and it matters only
|> for the first chunk of data in a persistent connection. For web pages
|> with dozens of embedded components (in specific, more than 4, which is
|> the typical limit for simultaneous connections), again this seems very
|> much in the noise...
|
| Many Google users are now using search bars to submit queries. Thus
| they type into a text field in the browser, hit enter and the browser
| makes a connection, sends the query encoded in a GET and displays the
| result. This is one example of a situation where the connection
| latency isn't amortised. There are many others, but obviously, this is
| the example that usually dominates my thinking. And, in this
| situation, it turns out that every 10ms makes a difference.

Understood and appreciated. Can you see if the port solution might work??

Joe

---

From: "Adam Langley" <[email-masked]>
Date: Tue, 5 Aug 2008 17:14:57 -0700

On Tue, Aug 5, 2008 at 4:46 PM, Joe Touch <[email-masked]> wrote:

I've just posted a new version of the draft, incorporating your
comments, which I hope is a lot clearer. Thanks for everything so far.

> than a TCP option that implies that application behavior.

It is strange, I agree. My usual test about such things is if I get an
"ick" reaction and, in this case, I don't. Although, that might just
be me.

Two reasonable questions arise:

"Where will this stop?"  - obviously, the TCP option space shouldn't
be a repository for application data. In this case, at least, the
option is advertising a certain minimum capability of the TCP stack,
as defined in the draft. Also, I'll claim that this is the last such
need in this area:

The SYNACK payload sizes is a decision for the server (within the
advertised window). No more client options could be needed to
advertise support for larger ones.

Since the SYNACK payload is (nearly) constant, and TCP stacks are not
going to differ sufficiently to change this in the next 20 years,
applications don't gain anything else by stuffing anything more in the
SYN option space.

So I don't think this sets an unreasonable precedent.

"Is it really needed?" - If you consider examples one and three from
the 01 draft that I just posted, I'm claiming that it would at least
be very useful. Of course, alternative ports solve the problem but I
believe that such a solution is messy enough as to be not a going
concern. Much of the time, SYNs to a closed port on a public server
will result in no reply at all, meaning that timeouts have to trigger
the back off.

The above is the sort of stuff that I should have put in the revised
draft :) I probably shall include it in -02.

Cheers

AGL

---

From: "Adam Langley" <[email-masked]>
Date: Tue, 5 Aug 2008 17:16:16 -0700

> comments, which I hope is a lot clearer. Thanks for everything so far.

The URL for which:

http://www.ietf.org/internet-drafts/draft-agl-tcpm-sadata-01.txt

AGL