Draft: draft-ietf-quic-http

Commentary: So it turns out that there are two different things called " reserved frame types " in HTTP/3 . There are the types reserved for greasing , and there are the types reserved to minimize confusion at code point overlap with HTTP/2 . This PR makes three changes , separable if there 's controversy : Adds " Reserved " to the frame type table , pointing to the Reserved Types section , and indicates they can be sent on all stream types . Clarifies in the Reserved section that GREASE frames can be sent on any open stream Calls out the reserved - for - H2 types as MUST NOT send , MAY error . Clarifies in the Extensibility section that , while you ignore frame types you do n't know , you do n't ignore that it was n't the frame you were expecting if a particular type was required to be in that position . 
 We 've had a long standing requirement that stream ( see Section 3.2.1 ) by each peer By the way I interpret this , I put a check in my implementation that does n't permit any frame until SETTINGS is received . Am I interpreting things correctly ? It would be more consistent to allow reserved frame types to appear at any point on any stream that carries frames . However , I 'm fine with this requirement as is but it means there is a little more effort needed to handle reserved frame types across streams . 
 In our implementation we are interpreting this in the same way : any frame on the control stream received before SETTINGS is a connection error . Even reserved frame types . In general the way we handle this is by discarding frame types that are forbidden rather than checking frame types that are allowed on each stream . Here is a snippet from our code . In this way we avoid the extra effort needed to handle reserved frame types that you mentioned , if I am reading your statement correctly . Basically , some frame types are explicitly disallowed . All other frame types are equal , reserved or non - reserved . Do you foresee an extension possibly benefiting from sending a frame before settings ? 
 Thanks you made me realise I asked the question wrong . This is about reserved and non - core frames . Section 7 says : extensible protocol elements . Implementations MUST discard frames ... I have no strong use case for delivering frames before SETTINGS . But I worry it falls into a slight grey area that might affect interop . I think the correct answer is that the control stream is special case and we should clarify that in Section 7 . 
 My preference goes to retaining the requirement as - is . This is the way H2 has worked , and I am not sure if there is a practical reason to change . FWIW , we have a similar requirement for PRIORITY frame too , which I 'm also fine with : A PRIORITY frame received after other frames on a request stream MUST be treated as a connection error of type HTTPUNEXPECTEDFRAME ( ) . 
 Ooh yeah , that 's a good catch too . Table 1 in section 4 seems to actually highlight this behaviour with the notation . And we sort of have some text that captures this in section 4 : We could add tweaks or further guidance to this paragraph ( in a PR that also that makes things explicitly clear . 
 On receipt , reserved is irrelevant -- it 's just an unknown frame type . The reservation is simply to permit senders to generate unknown frame types without accidental collision to a real extension the client might support . So the question is whether " ignoring " unknown frame types means pretending that they were n't even there , and therefore the subsequent frame might still be the first frame on the stream . I 'm inclined to say no -- you take no action on a frame you do n't recognize , but that does n't mean that the next frame was the first frame . 
 I think the overview table in HTTP/3 section 4 should probably also include reserved frame types . This will make it clear what streams these frames can appear on .
Paragraph (version A):
Frames of unknown types (extensions), including reserved frames
(frame-grease) MAY be sent on a request or push stream before, after,
or interleaved with other frames described in this section.
Paragraph (version B):
Frames of unknown types (extensions), including reserved frames
(frame-reserved) MAY be sent on a request or push stream before,
after, or interleaved with other frames described in this section.
Paragraph (version A):
Frame types of the format "0x1f * N + 0x21" for integer values of N
are reserved to exercise the requirement that unknown types be
ignored (extensions).  These frames have no semantics, and can be
sent when application-layer padding is desired.  They MAY also be
sent on connections where no data is currently being transferred.
Endpoints MUST NOT consider these frames to have any meaning upon
receipt.
Paragraph (version B):
Frame types of the format "0x1f * N + 0x21" for integer values of N
are reserved to exercise the requirement that unknown types be
ignored (extensions).  These frames have no semantics, and can be
sent on any open stream when application-layer padding is desired.
They MAY also be sent on connections where no data is currently being
transferred.  Endpoints MUST NOT consider these frames to have any
meaning upon receipt.
Paragraph (version B):
Frame types which were used in HTTP/2 where there is no corresponding
HTTP/3 frame have also been reserved (iana-frames).  These frame
types MUST NOT be sent, and receipt MAY be treated as an error of
type HTTP_UNEXPECTED_FRAME.
Paragraph (version A):
Implementations MUST ignore unknown or unsupported values in all
extensible protocol elements.  Implementations MUST discard frames
and unidirectional streams that have unknown or unsupported types.
This means that any of these extension points can be safely used by
extensions without prior arrangement or negotiation.
Paragraph (version B):
Implementations MUST ignore unknown or unsupported values in all
extensible protocol elements.  Implementations MUST discard frames
and unidirectional streams that have unknown or unsupported types.
This means that any of these extension points can be safely used by
extensions without prior arrangement or negotiation.  However, where
a known frame type is required to be in a specific location, such as
the SETTINGS frame as the first frame of the control stream (see
control-streams), an unknown frame type does not satisfy that
requirement and SHOULD be treated as an error.
Paragraph (version A):
Where HTTP/2 employs PADDING frames and Padding fields in other
frames to make a connection more resistant to traffic analysis,
HTTP/3 can either rely on transport-layer padding or employ the
reserved frame and stream types discussed in frame-grease and stream-
grease.  These methods of padding produce different results in terms
of the granularity of padding, the effect of packet loss and
recovery, and how an implementation might control padding.
Paragraph (version B):
Where HTTP/2 employs PADDING frames and Padding fields in other
frames to make a connection more resistant to traffic analysis,
HTTP/3 can either rely on transport-layer padding or employ the
reserved frame and stream types discussed in frame-reserved and
stream-grease.  These methods of padding produce different results in
terms of the granularity of padding, the effect of packet loss and
recovery, and how an implementation might control padding.