Subject: 0-RTT Design for HTTP/2

From: "Martin Thomson" <[email-masked]>
Date: Wed, 16 Dec 2020 18:11:58 +1100

As part of our adoption call for HTTP/2 (reprise), I opened https://github.com/httpwg/http2-spec/issues/781 regarding the use of TLS early data.

I thought that it might be worth the time to go through the exercise of defining an extension to h2 that enabled saving of settings across connections.  Here it is:

   https://martinthomson.github.io/h2-0rtt/draft-thomson-httpbis-h2-0rtt.html

For those who prefer text: https://tools.ietf.org/html/draft-thomson-httpbis-h2-0rtt-00

Though this is conceptually simple (indicate 1 if you are prepared to remember settings), there are enough fiddly details here that I'm now unsure whether it is worthwhile trying to roll into our revision of HTTP/2.

I'm interested in what people think about this.  One of the major criticisms of the current arrangement is the time it takes to learn that an extension is available and this could help with that.

Cheers,
Martin

---

From: Cory Benfield <[email-masked]>
Date: Wed, 16 Dec 2020 10:33:37 +0000

> Though this is conceptually simple (indicate 1 if you are prepared to remember settings), there are enough fiddly details here that I'm now unsure whether it is worthwhile trying to roll into our r…

I am somewhat nervous here about how many servers will implement this.

Typical OSS server implementations have a somewhat arms-length
relationship with their TLS stack. This tends to mean they don't
actually know exactly when new session ticket messages were sent.
While this is not a hard limitation (OpenSSL has the requisite
functions) it's the kind of barrier to entry that could be quite
awkward. This may also lead to limitations in how many HTTP/2 stacks
go through the effort of implementing the extension.

With that said, I'm sure that CDNs and browsers would, and that may be enough.

---

From: Ian Swett <[email-masked]>
Date: Wed, 16 Dec 2020 07:27:30 -0500

Thanks for writing this up.  I need to talk with others before being sure
this is something we'd be interested in, but it seems likely.

Before we get to that, one Q on deployability: Does the working group think
enough of the ecosystem can handle this new EARLY_DATA_SETTINGS setting?
If no one sends it, even if they support the functionality, it sort of
defeats the purpose.

Ian

On Wed, Dec 16, 2020 at 5:36 AM Cory Benfield <[email-masked]> wrote:

> > As part of our adoption call for HTTP/2 (reprise), I opened
> https://github.com/httpwg/http2-spec/issues/781 regarding the use of TLS
> early data.
> >
> > I thought that it might be worth the time to go through the exercise of
> defining an extension to h2 that enabled saving of settings across
> connections.  Here it is:
> >
> >
> > For those who prefer text:
> https://tools.ietf.org/html/draft-thomson-httpbis-h2-0rtt-00
> >
> > Though this is conceptually simple (indicate 1 if you are prepared to
> remember settings), there are enough fiddly details here that I'm now
> unsure whether it is worthwhile trying to roll into our revision of HTTP/2.
>
> > I'm interested in what people think about this.  One of the major
> criticisms of the current arrangement is the time it takes to learn that an
> extension is available and this could help with that.
> >
> > Cheers,
> > Martin
> >
>
>

---

From: David Schinazi <[email-masked]>
Date: Wed, 16 Dec 2020 04:34:14 -0800

Hi,

If there's energy in the community to improve HTTP/2 SETTINGS,
I would personally prefer to direct that energy at also solving the
"not having SETTINGS when sending the first request" problem.
Once potential solution is ALPS [1]. Would it make sense to join
these two efforts to ensure we fix SETTINGS for good?

David

[1] https://tools.ietf.org/html/draft-vvv-tls-alps

On Wed, Dec 16, 2020 at 4:31 AM Ian Swett <[email-masked]> wrote:

> Before we get to that, one Q on deployability: Does the working group
> think enough of the ecosystem can handle this new EARLY_DATA_SETTINGS
> setting?  If no one sends it, even if they support the functionality, it
> sort of defeats the purpose.
>
> Ian
>
>
>

---

From: "Martin Thomson" <[email-masked]>
Date: Thu, 17 Dec 2020 12:42:11 +1100

Mega-reply...

> go through the effort of implementing the extension.

So there is a lot of text here, but it is very easy to implement the server side of this if you don't change settings often.  Just set the value to 1 in the preface and remember those values.  Confirm that the TLS stack isn't spitting out session tickets except during the handshake (which is the only place they appear in TLS 1.2) and you are good.

There is a risk with TLS 1.3 that sending session tickets might take some time.  This depends on things like ticket requests with large numbers and how the stack schedules those relative to application data.  Basically, you need to ensure that you delay any changes to settings (changes you might not be able to synchronize with ticket issuance properly) until you are reasonable sure that tickets aren't being sent.

BTW, I like how NSS manages this, and not just because it's my code :).  NSS makes it the responsibility of the application to send extra tickets [1].  It might send one, but that is sent ahead of any responses you might generate.

Short story: I believe that it is easy to implement this with TLS 1.2; TLS 1.3 might take a little care.

[1] https://searchfox.org/nss/rev/51b18ad6c1e627ada90028df9062f7200f7cec94/lib/ssl/sslexp.h#245-264 (I really need to promote that one from experimental some time.)

> these two efforts to ensure we fix SETTINGS for good?

I'm glad you raise ALPS David.  My view is that we can't really deploy ALPS in an incremental fashion for HTTP/2.  Part of what I'm looking for here is an incremental solution.

I do see the possibility of just trying ALPS when it is available.  However, I think that is enough of a different protocol that it requires a new ALPN to go along with it.

I've watched the discussion regarding the possibility of defining a new ALPN for HTTP/2 and my sense is that there isn't overwhelming support for the idea.  If we had that support, then it might be good to try to fix ALPS into the design of a new protocol, but that isn't how things appear to be going.

On Wed, Dec 16, 2020 at 4:31 AM Ian Swett <[email-masked]> wrote:
> Before we get to that, one Q on deployability: Does the working group think enough of the ecosystem can handle this new EARLY_DATA_SETTINGS setting?  If no one sends it, even if they support the functionality, it sort of defeats the purpose.

Good question and worth answering before considering this.  I think that the work Bence has done here shows that there is some hope of success on this front.  That goes back to the "new ALPN" question.  I'm reading a pretty strong desire to fix "h2" rather than give up on it, but I'm sure that everyone is open to conceding that the bustage cost is too high if that is where things stand.

---

From: David Schinazi <[email-masked]>
Date: Thu, 17 Dec 2020 18:52:37 +0100

Hi Martin,

Could you please elaborate on your statement "My view is that we can't
really deploy ALPS in an incremental fashion for HTTP/2.  Part of what I'm
looking for here is an incremental solution."? I'm not seeing what makes
your proposal more incremental than ALPS, so perhaps I'm missing something
here.

David

On Thu, Dec 17, 2020 at 2:46 AM Martin Thomson <[email-masked]> wrote:

> So there is a lot of text here, but it is very easy to implement the
> server side of this if you don't change settings often.  Just set the value
> to 1 in the preface and remember those values.  Confirm that the TLS stack
> isn't spitting out session tickets except during the handshake (which is
> the only place they appear in TLS 1.2) and you are good.
>
> There is a risk with TLS 1.3 that sending session tickets might take some
> time.  This depends on things like ticket requests with large numbers and
> how the stack schedules those relative to application data.  Basically, you
> need to ensure that you delay any changes to settings (changes you might
> not be able to synchronize with ticket issuance properly) until you are
> reasonable sure that tickets aren't being sent.
>
> BTW, I like how NSS manages this, and not just because it's my code :).
> NSS makes it the responsibility of the application to send extra tickets
> [1].  It might send one, but that is sent ahead of any responses you might
> generate.
>
> [1]
> https://searchfox.org/nss/rev/51b18ad6c1e627ada90028df9062f7200f7cec94/lib/ssl/sslexp.h#245-264
> (I really need to promote that one from experimental some time.)
>
> I'm glad you raise ALPS David.  My view is that we can't really deploy
> ALPS in an incremental fashion for HTTP/2.  Part of what I'm looking for
> here is an incremental solution.
>
> I do see the possibility of just trying ALPS when it is available.
> However, I think that is enough of a different protocol that it requires a
> new ALPN to go along with it.
>
> I've watched the discussion regarding the possibility of defining a new
> ALPN for HTTP/2 and my sense is that there isn't overwhelming support for
> the idea.  If we had that support, then it might be good to try to fix ALPS
> into the design of a new protocol, but that isn't how things appear to be
> going.
>
> Good question and worth answering before considering this.  I think that
> the work Bence has done here shows that there is some hope of success on
> this front.  That goes back to the "new ALPN" question.  I'm reading a
> pretty strong desire to fix "h2" rather than give up on it, but I'm sure
> that everyone is open to conceding that the bustage cost is too high if
> that is where things stand.
>
>

---

From: Mike Bishop <[email-masked]>
Date: Thu, 17 Dec 2020 20:06:32 +0000

Thanks for working on this, Martin.  A few thoughts:

*	There initially seems to be limited value in the client sending this
setting:

*	In a 1-RTT connection, the server does nothing with the client's
value - it has committed to store settings in the tickets and does so once
it has sent the setting.  The only value appears to be that it might disable
the feature and somewhat reduce ticket sizes if the client doesn't support
the feature.
*	In a 0-RTT connection, the server likely can't condition acceptance
of Early Data on the client sending this commitment, since the commitment is
itself contained in the Early Data.  Servers decide whether to accept or not
based purely on the ticket and their own state.

You later discuss that a server might not offer Early Data support in
tickets at all to clients which don't send the setting; this is a reasonable
argument and probably worth moving earlier.

*	The spec doesn't directly address this, but it carries the
implication that the client might prefer an older ticket where the server
committed to remembering values over a later ticket where the server does
not so commit.  That's worth calling out, that the TLS stack will need a way
not only to store settings alongside tickets, but a way to establish a
preference between old and new tickets on a connection.
*	4.1:  I presume you mean settings, instead of extensions
*	This is missing discussion of the interaction with the SETTINGS
frame(s) which arrive subsequently.  A few things that need to be covered,
coming from hashing this out in both HTTP/3 and QUIC TPs:

*	If a setting has a remembered non-default value, but is not
mentioned in the server's SETTINGS frame, what happens when the first
SETTINGS frame is received?
*	What settings apply when the client has received the server's
Finished, but has not yet received the server's SETTINGS frame?
*	Is the client required to remember settings values that it does not
support?  How does this interact with having added support for those
settings between the old session and the new one?

I have some thoughts on the relationship between this draft and ALPS, but I
think I need to re-read ALPS again before I go into that.

-----Original Message-----
From: Martin Thomson <[email-masked]> 
Sent: Wednesday, December 16, 2020 2:12 AM
To: [email-masked]
Subject: 0-RTT Design for HTTP/2

As part of our adoption call for HTTP/2 (reprise), I opened
<https://github.com/httpwg/http2-spec/issues/781>
https://github.com/httpwg/http2-spec/issues/781 regarding the use of TLS
early data.

 
<https://martinthomson.github.io/h2-0rtt/draft-thomson-httpbis-h2-0rtt.html>
https://martinthomson.github.io/h2-0rtt/draft-thomson-httpbis-h2-0rtt.html

For those who prefer text:
<https://tools.ietf.org/html/draft-thomson-httpbis-h2-0rtt-00>
https://tools.ietf.org/html/draft-thomson-httpbis-h2-0rtt-00

Though this is conceptually simple (indicate 1 if you are prepared to
remember settings), there are enough fiddly details here that I'm now unsure
whether it is worthwhile trying to roll into our revision of HTTP/2.

I'm interested in what people think about this.  One of the major criticisms
of the current arrangement is the time it takes to learn that an extension
is available and this could help with that.

Cheers,

Martin

---

From: "Martin Thomson" <[email-masked]>
Date: Fri, 18 Dec 2020 09:12:45 +1100

On Fri, Dec 18, 2020, at 04:52, David Schinazi wrote:
> really deploy ALPS in an incremental fashion for HTTP/2.  Part of what 
> I'm looking for here is an incremental solution."? I'm not seeing what 
> makes your proposal more incremental than ALPS, so perhaps I'm missing 
> something here.

I gave a longer response regarding suitability of ALPS in that thread. As did Cory.

I can see how you might choose to opportunistically use ALPS, but I don't think that you can add it trivially to HTTP/2 implementations.  It's more of a case of not wanting it than it being functionally impossible; we could likely make anything work if we assume good integration of stack layers, but that isn't how HTTP/2 has been deployed and retrofitting something in that way would only result in a privileged few having the capability.  I would rather see it deployed for new protocols than try to have its presence alter how this existing protocol works.

---

From: Willy Tarreau <[email-masked]>
Date: Sat, 19 Dec 2020 18:18:35 +0100

Hi Martin,

>    https://martinthomson.github.io/h2-0rtt/draft-thomson-httpbis-h2-0rtt.html

I'm confused, maybe due to some of my limitations regarding the language,
but I'm really confused by the fact that TLS is mixed in, and my knowledge
of TLS is rather limited and seeing some parts speaking about TLS tickets
totally lost me.

My understanding was that if the server advertises EARLY_DATA_SETTINGS=1,
then the client would assume the server kept the same settings. In my
opinion this should be sufficient to let the client safely reuse these
values for next connections. And BTW, this shouldn't prevent the server
from emitting its settings frame anyway so that the client can check if
anything changed.

I see that Cory mentioned the fact that most implementations do not see
the TLS layer, I can confirm this. For example in haproxy, h2 works on
top of a streaming transport protocol. It can be plain or TLS on top of
TCP, UNIX or socketpairs, we don't care. Early data, if any, are retrieved
by the TLS layer and are prepended in front of the other data (more or
less some details I don't remember regarding the necessary controls to
figure whether or not some early data were involved for the request).

Anything more complicated will likely become a showstopper I'm afraid.

Maybe I misundersood something in the proposal, though.

Cheers,
Willy

---

From: Ian Swett <[email-masked]>
Date: Sat, 19 Dec 2020 14:36:04 -0500

> that is where things stand.

I think Bence's work showed that the major servers can be fixed.  However,
upgrades still take time and I'm not sure if they've yet been completed.  I
suspect there's a long tail of servers out there that don't upgrade very
often(or ever :( ), and I feel a bit uncomfortable saying we're just going
to break them.

If I only had to send the SETTING client to server, I think that might be
deployable in the near future, though Chrome would have to run more
widespread tests.  I'm actually more concerned about the fact that the
server has to send the SETTING(which makes complete sense, given what
you're trying to accomplish).  It's impractical to wait for receipt of the
client SETTING before sending the server one, and the client ecosystem is
much slower to upgrade, unfortunately.

Given this, ALPS looks better from a deployability perspective.  To my
knowledge, there are no known issues deploying new TLS 1.3 extensions.
Given the lack of interest in a new h2 ALPN, I'm suggesting ALPS include a
GREASE recommendation, so if one deploys ALPS, it's also an indication it's
a fully compliant h2 implementation.

---

From: "Martin Thomson" <[email-masked]>
Date: Mon, 21 Dec 2020 09:39:33 +1100

> from emitting its settings frame anyway so that the client can check if

Yes, this is correct.  I've tweaked my copy to include mention of the connection preface in the resumed connection replacing the remembered values.
 
> Anything more complicated will likely become a showstopper I'm afraid.

I don't think that you need anything other than an API that allows you to determine whether early data was accepted.

Ideally, you also have a means of saving data to the session ticket and getting that data back when the connection is resumed.  Then you can save the settings in the ticket and then you don't have to remember on your own. A simple boolean doesn't give you a lot of flexibility in terms of how you deploy this.  With just a boolean you have to commit to discarding session tickets every time your server configuration changes.

---

From: "Martin Thomson" <[email-masked]>
Date: Mon, 21 Dec 2020 09:46:27 +1100

On Sun, Dec 20, 2020, at 06:36, Ian Swett wrote:
> If I only had to send the SETTING client to server, I think that might 
> be deployable in the near future, though Chrome would have to run more 
> you're trying to accomplish).  It's impractical to wait for receipt of 
> the client SETTING before sending the server one, and the client 
> ecosystem is much slower to upgrade, unfortunately.

My original write-up only had the server send the setting.  It certainly works that way.  You get most of the functionality.

If the client says nothing, the server can't condition its treatment on an indication of support from the client.  The consequence being that the server can't rely on the client respecting lower limits.  That's not a big loss though; even fairly low limits would be hard to exceed in the limited space available, either due to max_early_data or CWND limits.

> Given the lack of interest in a new h2 ALPN, I'm suggesting ALPS 
> include a GREASE recommendation, so if one deploys ALPS, it's also an 
> indication it's a fully compliant h2 implementation.

I suspect that that is not going to be an easy stipulation.  As others have observed, people update their TLS stacks independent of their h2 implementation.

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 21 Dec 2020 08:09:12 +0100

Hi Martin,

On Mon, Dec 21, 2020 at 09:39:33AM +1100, Martin Thomson wrote:
> Ideally, you also have a means of saving data to the session ticket and
> getting that data back when the connection is resumed.  Then you can save the
> settings in the ticket and then you don't have to remember on your own. A
> simple boolean doesn't give you a lot of flexibility in terms of how you
> deploy this.  With just a boolean you have to commit to discarding session
> tickets every time your server configuration changes.

OK, this is the part I didn't understand, thanks! Thus you were speaking
about the server saving its own settings in order to be able to reuse them
in case of config change.

Server-side settings changes are extremely unlikely, unless some serious
trouble are encountered with the current ones, in which case one will not
want to keep them anyway, even less across a whole server farm. In this
case I'd rather suggest users to proceed in two steps :
  - disable advertising of EARLY_DATA_SETTINGS and wait long enough for
    all clients to leave ;
  - perform the actual settings change and re-enable EARLY_DATA_SETTINGS

Just a point however, my understanding then is that EARLY_DATA_SETTINGS
isn't properly named. The purpose is not as much to send settings using
early data as it is to persist settings across connections. What about
PERSISTENT_SETTINGS instead ? Use of early data here is just a byproduct
of not having to wait for the server settings, and even requests can be
sent over early data in this case.

Willy

---

From: "Martin Thomson" <[email-masked]>
Date: Mon, 21 Dec 2020 18:16:21 +1100

Hi Willy,

On Mon, Dec 21, 2020, at 18:09, Willy Tarreau wrote:
> Server-side settings changes are extremely unlikely, 

Good point.  I've tried to capture this in https://github.com/martinthomson/h2-0rtt/issues/2

> sent over early data in this case.

I considered that, but it deliberately only says that it applies to early data.  There is a whole discussion about how this doesn't work for resumption in https://martinthomson.github.io/h2-0rtt/draft-thomson-httpbis-h2-0rtt.html#name-use-for-resumption - at least in the general case.

Cheers,
Martin

---

From: Ian Swett <[email-masked]>
Date: Mon, 21 Dec 2020 07:04:41 -0500

On Sun, Dec 20, 2020 at 5:46 PM Martin Thomson <[email-masked]> wrote:

> My original write-up only had the server send the setting.  It certainly
> works that way.  You get most of the functionality.
>
> If the client says nothing, the server can't condition its treatment on an
> indication of support from the client.  The consequence being that the
> server can't rely on the client respecting lower limits.  That's not a big
> loss though; even fairly low limits would be hard to exceed in the limited
> space available, either due to max_early_data or CWND limits.
>
> I suspect that that is not going to be an easy stipulation.  As others
> have observed, people update their TLS stacks independent of their h2
> implementation.
>

Yes, but ALPS has to be actively enabled by the application(h2 in this
case), so if the application is actively enabling it, it should be possible
to require a compliant h2 implementation.

---

From: Cory Benfield <[email-masked]>
Date: Tue, 22 Dec 2020 08:34:03 +0000

> On 20 Dec 2020, at 22:43, Martin Thomson <[email-masked]> wrote:
> 

With this kind of API to the TLS layer in mind it’s not clear that this proposal is any simpler for a server stack than ALPS: indeed, it might be harder. ALPS requires that implementations define an interface to send and receive out-of-band settings, but that interface is relatively straightforward. Interaction with session tickets is at the very least as complex (an out-of-band system for setting and retrieving settings), but the integration is vastly more complex.

I suspect it also behaves poorly in multi-host configurations in a way ALPS does not.

Neither of these proposals makes me very excited, but I think on balance ALPS is simpler.