Subject: [quicwg/base-drafts] Http/complete settings (#2972)

From: Mike Bishop <[email-masked]>
Date: Fri, 16 Aug 2019 10:34:56 -0700

This is an alternative to #2958 that sticks closer to the current design / the pattern of HTTP/2.

It tightens constraints around SETTINGS in a couple of ways:
- Servers are now required to send complete SETTINGS frames -- they can still omit settings which match the default, but not settings which match the session being resumed.
- What happens if either side is uncertain which settings apply to a ticket?  Clients assume defaults; servers MUST NOT accept early data (though they could still accept a resumption).

Fixes #2790; fixes #2945; closes #2958.
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/2972

-- Commit Summary --

  * SETTINGS must be complete
  * I do not recall.

-- File Changes --

    M draft-ietf-quic-http.md (15)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/2972.patch
https://github.com/quicwg/base-drafts/pull/2972.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 16 Aug 2019 11:02:36 -0700

LPardue commented on this pull request.

>  server's SETTINGS frame has arrived.  This removes the need for a client to wait
 for the SETTINGS frame before sending requests.
 
 A server can remember the settings that it advertised, or store an
 integrity-protected copy of the values in the ticket and recover the information
 when accepting 0-RTT data. A server uses the HTTP/3 settings values in
-determining whether to accept 0-RTT data.
+determining whether to accept 0-RTT data.  If the server cannot recover the
+settings from a session being resumed, it MUST NOT accept 0-RTT data.

by my reading, the paragraph describes to methods: remember or recover. This new clause seems to imply if you can't recover, then remember is not allowed.

Is it more aligned with the intent to say that when a server chooses the recover method, and encodes the data in a ticket, and a client presents a ticket, then the server MUST recover the settings or else reject 0-RTT?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-276091117

---

From: David Schinazi <[email-masked]>
Date: Fri, 16 Aug 2019 13:21:12 -0700

DavidSchinazi commented on this pull request.

> @@ -1396,22 +1396,25 @@ servers, the initial value of each client setting is the default value.
 For clients using a 1-RTT QUIC connection, the initial value of each server
 setting is the default value. When a 0-RTT QUIC connection is being used, the
 initial value of each server setting is the value used in the previous session.
-Clients MUST store the settings the server provided in the session being resumed
-and MUST comply with stored settings until the current server settings are
-received.  A client can use these initial values to send requests before the
+Clients SHOULD store the settings the server provided in the session being
+resumed and MUST comply with stored settings until the current server settings

I might be confused, but how can you have `MUST comply with stored` if storing is a `SHOULD`?

Can we elaborate on what `recover` means? Does assuming the defaults count as `recover`? Also, how can the server recover them if it doesn't know if the client stored them or not?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-276151530

---

From: Nick Harper <[email-masked]>
Date: Fri, 16 Aug 2019 15:26:09 -0700

It's great to see the change that the server MUST send all settings that differ from defaults instead of just those that differ from the implied settings for early data.

I'm a bit concerned that this says effectively says that it's optional (not RFC 2119 word) for clients to remember SETTINGS when sending early data, because now a server can't assume that a client is using the remembered SETTINGS in early data instead of the default settings.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#issuecomment-522169894

---

From: Martin Thomson <[email-masked]>
Date: Sun, 18 Aug 2019 18:14:37 -0700

martinthomson commented on this pull request.

Yeah, this complicates the text somewhat.  If the intent is to have clients comply with either defaults or whatever they remember, then maybe:

Clients SHOULD store the settings the server provided in the connection where resumption information was provided.  A client MUST comply with either stored settings - or default values if no values are stored - when attempting 0-RTT.  Once a server has provided new settings, clients MUST comply with those values.

 For clients using a 1-RTT QUIC connection, the initial value of each server
 setting is the default value. When a 0-RTT QUIC connection is being used, the
 initial value of each server setting is the value used in the previous session.
-Clients MUST store the settings the server provided in the session being resumed
-and MUST comply with stored settings until the current server settings are
-received.  A client can use these initial values to send requests before the
+Clients SHOULD store the settings the server provided in the session being
+resumed and MUST comply with stored settings until the current server settings
+are received.  If the client did not store, or did not receive, server settings
+from the previous session, the initial value of each setting is the default
+value.  A client can use these initial values to send requests before the

This business about defaults can be split into a new paragraph, ideally one preceding this more complicated part.

> Settings assume default values prior to receiving a SETTINGS frame, or if the SETTINGS frame does not include a value for the setting.  Endpoints can use these default values to send requests before receiving the a SETTINGS frame.

I don't think that we're mandating the use of session tickets, even if that is the most common method of implementing these.

I think that "recover" is probably still right, though it might be clearer here if we say "If a server cannot determine that the settings remembered by a client are compatible with its current settings, it MUST reject 0-RTT."

Then we need to define what "compatible" means.

 A server MAY accept 0-RTT and subsequently provide different settings in its
 SETTINGS frame. If 0-RTT data is accepted by the server, its SETTINGS frame MUST
 NOT reduce any limits or alter any values that might be violated by the client
-with its 0-RTT data.  The server MAY omit settings from its SETTINGS frame which
-are unchanged from the initial value.
+with its 0-RTT data.  The server MUST include all settings which differ from
+their default values, even if the value is unchanged from the previous session.

I might drop the bit from the comma onwards.  The only case we have two values is in 0-RTT (not resumption, as this implies) and that text is now very clear that the remembered values only apply until SETTINGS arrives.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-276307666

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 18 Aug 2019 23:41:15 -0700

kazuho commented on this pull request.

The proposed text looks good, though I do not think it covers all the issues being discussed in #2945. Specifically, the text does not update _when_ a SETTINGS frame is expected to be sent.

If we are to follow the design pattern of HTTP/2, I think that we should clarify that an endpoint MUST send a SETTINGS frame as soon as it becomes possible to send application data, even when the SETTINGS frame would be empty. Otherwise, we should clarify that a SETTINGS frame is to be sent only when one of the following conditions are met: a feature depending on non-default value of a settings parameter is to be used, or a frame other than a SETTINGS frame is to be transmitted on the control stream.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-276364001

---

From: Mike Bishop <[email-masked]>
Date: Mon, 19 Aug 2019 12:44:44 -0700

@MikeBishop pushed 1 commit.

fd25617e356f23dc3e40413d9d794ae6076f1aa8  Rearrange per feedback

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/b275e4e96ff0ac6079f44f7a5c43dfcdf2b3a2fb..fd25617e356f23dc3e40413d9d794ae6076f1aa8

---

From: Mike Bishop <[email-masked]>
Date: Mon, 19 Aug 2019 13:03:10 -0700

> I'm a bit concerned that this says effectively says that it's optional (not RFC 2119 word) for clients to remember SETTINGS when sending early data, because now a server can't assume that a client…

That should be okay, because the defaults are intentionally the most restrictive settings possible.  If the client opts to retain/use a ticket for which it has no settings, then it doesn't get to use anything fancy until it sees the SETTINGS frame.

@kazuho:
> Specifically, the text does not update _when_ a SETTINGS frame is expected to be sent.
> 

I think this is ultimately intractable.  You can't tell the difference between the control stream having a delay due to packet loss vs. the server simply not sending the settings until it has something else to send, or even not sending it at all.  If either party opts to run on pure defaults, we can't really stop them and getting an empty SETTINGS frame out of them doesn't really solve anything.

We shouldn't mandate a delay, which is how I read your second case.  We can lay down some encouragement to send it ASAP -- getting to use non-default settings in 0-RTT next time and being able to use any features of the control stream both push in that direction -- but failure to do so is probably not obvious and therefore a poor candidate for a MUST.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#issuecomment-522732029

---

From: Kazuho Oku <[email-masked]>
Date: Mon, 19 Aug 2019 17:50:33 -0700

@MikeBishop 
> I think this is ultimately intractable. You can't tell the difference between the control stream having a delay due to packet loss vs. the server simply not sending the settings until it has something else to send, or even not sending it at all.

I disagree. If we are to require endpoints to send SETTINGS frame right after the connection is established, not sending anything until receiving the SETTINGS frame is a totally acceptable behavior (even though it might be less performant in some cases). It is no different than waiting for a Handshake packet before becoming possible to process a 1-RTT packet.

I think we should clarify if an endpoint can be implemented that way, because we have seen interop issues due to some doing that, and because that is the way H2 is designed. Maybe something like https://github.com/quicwg/base-drafts/commit/5fadbbbff7a5e566a2c951376be7999aca2c7edb.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#issuecomment-522808046

---

From: David Benjamin <[email-masked]>
Date: Wed, 21 Aug 2019 19:26:17 -0700

davidben commented on this pull request.

-Clients MUST store the settings the server provided in the session being resumed
-and MUST comply with stored settings until the current server settings are
-received.  A client can use these initial values to send requests before the
-server's SETTINGS frame has arrived.  This removes the need for a client to wait
-for the SETTINGS frame before sending requests.
+Clients SHOULD store the settings the server provided in the connection where
+resumption information was provided. A client MUST comply with either stored
+settings -- or default values, if no values are stored -- when attempting 0-RTT.
+Once a server has provided new settings, clients MUST comply with those values.

This does smooth over the worst of this mess, but since the ordering issue is not obvious, I think it's worth calling out explicitly that the client may choose not to store the settings if things were received in the wrong order.

 A server can remember the settings that it advertised, or store an
 integrity-protected copy of the values in the ticket and recover the information
 when accepting 0-RTT data. A server uses the HTTP/3 settings values in
-determining whether to accept 0-RTT data.
+determining whether to accept 0-RTT data.  If the server cannot determine that
+the settings remembered by a client are compatible with its current settings, it
+MUST NOT accept 0-RTT data.  (Remembered settings are compatible if a client
+complying with those settings would not violate the server's current settings.)

(I expect our implementation will just require an exact byte-for-byte match. It saves adding a funny callback and I wouldn't expect the values to actually change much. Same for the QUIC transport parameters.)

+their default values.

What should the client do if it sees the server reduce limits or otherwise alter values?
What if it sees the server do so implicitly by omitting a non-default setting that was previously set in the remembered SETTINGS frame?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-278161580

---

From: Martin Thomson <[email-masked]>
Date: Wed, 21 Aug 2019 19:36:54 -0700

Storing a version number in place of storing settings is entirely appropriate.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r316475949

---

From: David Benjamin <[email-masked]>
Date: Wed, 21 Aug 2019 19:45:09 -0700

Sure, that's a plausible optimization. Although that's orthogonal to whether you believe in equality or a weaker comparison.

(Whether the optimization is worth it, I'm not sure. The benefit is slightly smaller tickets. The cost is you need to make sure the meaning of your version number is consistent, which is a hidden sharp edge to deployment.)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r316477208

---

From: Mike Bishop <[email-masked]>
Date: Thu, 22 Aug 2019 07:52:14 -0700

MikeBishop commented on this pull request.

Good point.  We currently don't require clients to police that, but it falls in the bucket of trivially-detectable protocol violations.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r316723156

---

From: Mike Bishop <[email-masked]>
Date: Thu, 22 Aug 2019 07:57:58 -0700

5c8dcbee632a64fc380211800b979c03ab9ceba7  Feedback from review

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/fd25617e356f23dc3e40413d9d794ae6076f1aa8..5c8dcbee632a64fc380211800b979c03ab9ceba7

---

From: Mike Bishop <[email-masked]>
Date: Thu, 22 Aug 2019 14:19:29 -0700

>From discussion on #2945, this will merge soon.  (I have marked it not to close #2958.)  If there's additional feedback, please give it now.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#issuecomment-524081947

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 22 Aug 2019 14:28:00 -0700

@MikeBishop I would appreciate it if you could consider adopting the proposed change in https://github.com/quicwg/base-drafts/pull/2972#issuecomment-522808046 (i.e., https://github.com/quicwg/base-drafts/commit/5fadbbbff7a5e566a2c951376be7999aca2c7edb), as I believe it is a clarification of status quo.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#issuecomment-524084654

---

From: Mike Bishop <[email-masked]>
Date: Fri, 23 Aug 2019 07:02:06 -0700

@kazuho, I was attempting to respond to that comment with this text, already in the PR:
> Endpoints MUST NOT require any data to be received from the peer prior to
sending the SETTINGS frame; settings SHOULD be sent as soon as the transport is
ready to send data.

This seems to mirror the current state of #2986.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#issuecomment-524327126

---

From: ianswett <[email-masked]>
Date: Fri, 23 Aug 2019 08:02:09 -0700

ianswett commented on this pull request.

I think in our editor's meeting we agreed not to close Nick's PR with this PR?

Also, I'm not sure this really solves #2945 fully?

> @@ -1389,29 +1389,45 @@ for more details.
 #### Initialization
 
 An HTTP implementation MUST NOT send frames or requests which would be invalid
-based on its current understanding of the peer's settings.  All settings begin
-at an initial value, and are updated upon receipt of a SETTINGS frame.  For
-servers, the initial value of each client setting is the default value.
+based on its current understanding of the peer's settings.
+
+All settings begin at an initial value.  Each endpoint MAY use these initial
+values to send messages before the peer's SETTINGS frame has arrived.  When

messages?

> @@ -1389,29 +1389,45 @@ for more details.
 #### Initialization
 
 An HTTP implementation MUST NOT send frames or requests which would be invalid
-based on its current understanding of the peer's settings.  All settings begin
-at an initial value, and are updated upon receipt of a SETTINGS frame.  For
-servers, the initial value of each client setting is the default value.
+based on its current understanding of the peer's settings.
+
+All settings begin at an initial value.  Each endpoint MAY use these initial
+values to send messages before the peer's SETTINGS frame has arrived.  When
+the SETTINGS frame arrives, any settings are changed to their new values.
+
+This removes the need to wait for the SETTINGS frame before sending messages.
+Endpoints MUST NOT require any data to be received from the peer prior to
+sending the SETTINGS frame; settings SHOULD be sent as soon as the transport is
+ready to send data.

I think it's worth adding an Implementation Note along the lines of:
"For clients using a 1-RTT QUIC connection, the 1-RTT keys will always become available prior to SETTINGS arriving, even if the server send SETTINGS immediately.  Clients SHOULD NOT wait indefinitely for SETTINGS to arrive before sending requests, but SHOULD process received datagrams in order to increase the likelihood of processing SETTINGS before sending the first request."

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-279049201

---

From: Mike Bishop <[email-masked]>
Date: Mon, 26 Aug 2019 11:14:59 -0700

#### Initialization

Generic reference to requests and responses both final and non-final.  See Section 4.1.  I can add a cross-ref, if you like.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r317730146

---

From: Mike Bishop <[email-masked]>
Date: Mon, 26 Aug 2019 11:17:48 -0700

#### Initialization

I'm okay with that advice.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r317731365

---

From: Mike Bishop <[email-masked]>
Date: Mon, 26 Aug 2019 11:18:19 -0700

edc6296c7d37ff00c9305e7c6a7a2e148b44240a  Advice

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/5c8dcbee632a64fc380211800b979c03ab9ceba7..edc6296c7d37ff00c9305e7c6a7a2e148b44240a

---

From: Martin Thomson <[email-masked]>
Date: Mon, 26 Aug 2019 16:44:21 -0700

martinthomson approved this pull request.

This seems like the right answer to me.

I get the desire to find a more general solution, but I am concerned that we don't know what "general" looks like.  This works well enough.  It's complicated to write it down, but I don't think that it's all that complicated in practice.

> -initial value of each server setting is the value used in the previous session.
-Clients MUST store the settings the server provided in the session being resumed
-and MUST comply with stored settings until the current server settings are
-received.  A client can use these initial values to send requests before the
-server's SETTINGS frame has arrived.  This removes the need for a client to wait
-for the SETTINGS frame before sending requests.
+setting is the default value.  1-RTT keys will always become available prior to
+SETTINGS arriving, even if the server sends SETTINGS immediately. Clients SHOULD
+NOT wait indefinitely for SETTINGS to arrive before sending requests, but SHOULD
+process received datagrams in order to increase the likelihood of processing
+SETTINGS before sending the first request.
+
+When a 0-RTT QUIC connection is being used, the initial value of each server
+setting is the value used in the previous session. Clients SHOULD store the
+settings the server provided in the connection where resumption information was
+provided, but MAY opt not to store settings in certain cases (e.g. if the

```suggestion
provided, but MAY opt not to store settings in certain cases (e.g., if the
```

```suggestion
MUST NOT accept 0-RTT data.  Remembered settings are compatible if a client
```

```suggestion
complying with those settings would not violate the server's current settings.
```

 A server MAY accept 0-RTT and subsequently provide different settings in its
 SETTINGS frame. If 0-RTT data is accepted by the server, its SETTINGS frame MUST
 NOT reduce any limits or alter any values that might be violated by the client
-with its 0-RTT data.  The server MAY omit settings from its SETTINGS frame which
-are unchanged from the initial value.
+with its 0-RTT data.  The server MUST include all settings which differ from
+their default values.  If a server accepts 0-RTT, but then sends a SETTINGS
+frame which reduces a setting the client understands or omits a value that was
+previous specified, this MUST be treated as a connection error of type

```suggestion
previously specified to have a non-default value, this MUST be treated as a connection error of type
```

The "ly" is just grammar, but I think that it would be OK to have a server send a default value in connection 1 and omit the value in connection 2.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-279891170

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Aug 2019 08:41:05 -0700

6a10fd195242a3dd41a86d47c4707df60568a8f6  Apply suggestions from code review

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/edc6296c7d37ff00c9305e7c6a7a2e148b44240a..6a10fd195242a3dd41a86d47c4707df60568a8f6

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Aug 2019 08:41:57 -0700

3fab912692b51358d2a0bbaa4d43553d3b970fb7  Rewrap

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/6a10fd195242a3dd41a86d47c4707df60568a8f6..3fab912692b51358d2a0bbaa4d43553d3b970fb7

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 27 Aug 2019 08:47:24 -0700

+previously specified to have a non-default value, this MUST be treated as a
+connection error of type HTTP_SETTINGS_ERROR.

a bit tangential but the description of HTTP_SETTINGS_ERROR doesn't mention this case 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#pullrequestreview-280295438

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Aug 2019 11:38:12 -0700

34778c30c9f7e077dffebec12bf06a5a1dcb51c8  clarify that an endpoint cannot block on SETTINGS (#2986)

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/3fab912692b51358d2a0bbaa4d43553d3b970fb7..34778c30c9f7e077dffebec12bf06a5a1dcb51c8

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Aug 2019 11:40:46 -0700

Honestly, that description looks a little overlong and overspecific anyway.  How about I just drop the examples and leave it as "An endpoint detected an error in the payload of a SETTINGS frame."?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r318236763

---

From: Lucas Pardue <[email-masked]>
Date: Tue, 27 Aug 2019 11:56:04 -0700

Sgtm

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#discussion_r318243500

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Aug 2019 11:57:59 -0700

aea79ee436527e0d3b61c0476a050ec5690b994f  Less specific error description

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972/files/34778c30c9f7e077dffebec12bf06a5a1dcb51c8..aea79ee436527e0d3b61c0476a050ec5690b994f

---

From: Mike Bishop <[email-masked]>
Date: Tue, 27 Aug 2019 11:59:54 -0700

Merged #2972 into master.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/2972#event-2588151650