draft-ietf-masque-h3-datagram-00.txt | draft-ietf-masque-h3-datagram-01.txt | |||
---|---|---|---|---|
Network Working Group D. Schinazi | MASQUE D. Schinazi | |||
Internet-Draft Google LLC | Internet-Draft Google LLC | |||
Intended status: Standards Track L. Pardue | Intended status: Standards Track L. Pardue | |||
Expires: 2 August 2021 Cloudflare | Expires: 14 November 2021 Cloudflare | |||
29 January 2021 | 13 May 2021 | |||
Using QUIC Datagrams with HTTP/3 | Using QUIC Datagrams with HTTP/3 | |||
draft-ietf-masque-h3-datagram-00 | draft-ietf-masque-h3-datagram-01 | |||
Abstract | Abstract | |||
The QUIC DATAGRAM extension provides application protocols running | The QUIC DATAGRAM extension provides application protocols running | |||
over QUIC with a mechanism to send unreliable data while leveraging | over QUIC with a mechanism to send unreliable data while leveraging | |||
the security and congestion-control properties of QUIC. However, | the security and congestion-control properties of QUIC. However, | |||
QUIC DATAGRAM frames do not provide a means to demultiplex | QUIC DATAGRAM frames do not provide a means to demultiplex | |||
application contexts. This document defines how to use QUIC DATAGRAM | application contexts. This document describes how to use QUIC | |||
frames when the application protocol running over QUIC is HTTP/3 by | DATAGRAM frames when the application protocol running over QUIC is | |||
adding an identifier at the start of the frame payload. This allows | HTTP/3. It associates datagrams with client-initiated bidirectional | |||
HTTP messages to convey related information using unreliable DATAGRAM | streams and defines an optional additional demultiplexing layer. | |||
frames, ensuring those frames are properly associated with an HTTP | ||||
message. | ||||
Discussion of this work is encouraged to happen on the MASQUE IETF | Discussion of this work is encouraged to happen on the MASQUE IETF | |||
mailing list (masque@ietf.org (mailto:masque@ietf.org)) or on the | mailing list (masque@ietf.org (mailto:masque@ietf.org)) or on the | |||
GitHub repository which contains the draft: https://github.com/ietf- | GitHub repository which contains the draft: https://github.com/ietf- | |||
wg-masque/draft-ietf-masque-h3-datagram. | wg-masque/draft-ietf-masque-h3-datagram. | |||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
skipping to change at page 1, line 45 ¶ | skipping to change at page 1, line 43 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on 2 August 2021. | This Internet-Draft will expire on 14 November 2021. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2021 IETF Trust and the persons identified as the | Copyright (c) 2021 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents (https://trustee.ietf.org/ | |||
license-info) in effect on the date of publication of this document. | license-info) in effect on the date of publication of this document. | |||
Please review these documents carefully, as they describe your rights | Please review these documents carefully, as they describe your rights | |||
and restrictions with respect to this document. Code Components | and restrictions with respect to this document. Code Components | |||
extracted from this document must include Simplified BSD License text | extracted from this document must include Simplified BSD License text | |||
as described in Section 4.e of the Trust Legal Provisions and are | as described in Section 4.e of the Trust Legal Provisions and are | |||
provided without warranty as described in the Simplified BSD License. | provided without warranty as described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
1.1. Conventions and Definitions . . . . . . . . . . . . . . . 3 | 1.1. Conventions and Definitions . . . . . . . . . . . . . . . 3 | |||
2. Flow Identifiers . . . . . . . . . . . . . . . . . . . . . . 3 | 2. Multiplexing . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
3. Flow Identifier Allocation . . . . . . . . . . . . . . . . . 3 | 2.1. Datagram Contexts . . . . . . . . . . . . . . . . . . . . 3 | |||
4. HTTP/3 DATAGRAM Frame Format . . . . . . . . . . . . . . . . 4 | 2.2. Context ID Allocation . . . . . . . . . . . . . . . . . . 4 | |||
5. The H3_DATAGRAM HTTP/3 SETTINGS Parameter . . . . . . . . . . 4 | 3. HTTP/3 DATAGRAM Frame Format . . . . . . . . . . . . . . . . 4 | |||
6. Datagram-Flow-Id Header Field Definition . . . . . . . . . . 5 | 4. CAPSULE HTTP/3 Frame Definition . . . . . . . . . . . . . . . 5 | |||
7. HTTP Intermediaries . . . . . . . . . . . . . . . . . . . . . 7 | 4.1. The REGISTER_DATAGRAM_CONTEXT Capsule . . . . . . . . . . 6 | |||
8. Security Considerations . . . . . . . . . . . . . . . . . . . 7 | 4.2. The CLOSE_DATAGRAM_CONTEXT Capsule . . . . . . . . . . . 7 | |||
9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7 | 4.3. The DATAGRAM Capsule . . . . . . . . . . . . . . . . . . 8 | |||
9.1. HTTP SETTINGS Parameter . . . . . . . . . . . . . . . . . 7 | 5. The H3_DATAGRAM HTTP/3 SETTINGS Parameter . . . . . . . . . . 9 | |||
9.2. HTTP Header Field . . . . . . . . . . . . . . . . . . . . 8 | 6. HTTP/1.x and HTTP/2 Support . . . . . . . . . . . . . . . . . 9 | |||
9.3. Flow Identifier Parameters . . . . . . . . . . . . . . . 8 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 10 | |||
10. Normative References . . . . . . . . . . . . . . . . . . . . 8 | 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 | |||
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 8.1. HTTP/3 CAPSULE Frame . . . . . . . . . . . . . . . . . . 10 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 10 | 8.2. HTTP SETTINGS Parameter . . . . . . . . . . . . . . . . . 10 | |||
8.3. Capsule Types . . . . . . . . . . . . . . . . . . . . . . 10 | ||||
8.4. Context Extension Keys . . . . . . . . . . . . . . . . . 11 | ||||
9. Normative References . . . . . . . . . . . . . . . . . . . . 11 | ||||
Appendix A. Examples . . . . . . . . . . . . . . . . . . . . . . 12 | ||||
A.1. CONNECT-UDP . . . . . . . . . . . . . . . . . . . . . . . 12 | ||||
A.2. CONNECT-UDP with Timestamp Extension . . . . . . . . . . 13 | ||||
A.3. CONNECT-IP with IP compression . . . . . . . . . . . . . 14 | ||||
A.4. WebTransport . . . . . . . . . . . . . . . . . . . . . . 15 | ||||
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 16 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 16 | ||||
1. Introduction | 1. Introduction | |||
The QUIC DATAGRAM extension [DGRAM] provides application protocols | The QUIC DATAGRAM extension [DGRAM] provides application protocols | |||
running over QUIC [QUIC] with a mechanism to send unreliable data | running over QUIC [QUIC] with a mechanism to send unreliable data | |||
while leveraging the security and congestion-control properties of | while leveraging the security and congestion-control properties of | |||
QUIC. However, QUIC DATAGRAM frames do not provide a means to | QUIC. However, QUIC DATAGRAM frames do not provide a means to | |||
demultiplex application contexts. This document defines how to use | demultiplex application contexts. This document describes how to use | |||
QUIC DATAGRAM frames when the application protocol running over QUIC | QUIC DATAGRAM frames when the application protocol running over QUIC | |||
is HTTP/3 [H3] by adding an identifier at the start of the frame | is HTTP/3 [H3]. It associates datagrams with client-initiated | |||
payload. This allows HTTP messages to convey related information | bidirectional streams and defines an optional additional | |||
using unreliable DATAGRAM frames, ensuring those frames are properly | demultiplexing layer. | |||
associated with an HTTP message. | ||||
This design mimics the use of Stream Types in HTTP/3, which provide a | ||||
demultiplexing identifier at the start of each unidirectional stream. | ||||
Discussion of this work is encouraged to happen on the MASQUE IETF | Discussion of this work is encouraged to happen on the MASQUE IETF | |||
mailing list (masque@ietf.org (mailto:masque@ietf.org)) or on the | mailing list (masque@ietf.org (mailto:masque@ietf.org)) or on the | |||
GitHub repository which contains the draft: https://github.com/ietf- | GitHub repository which contains the draft: https://github.com/ietf- | |||
wg-masque/draft-ietf-masque-h3-datagram. | wg-masque/draft-ietf-masque-h3-datagram. | |||
1.1. Conventions and Definitions | 1.1. Conventions and Definitions | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
"OPTIONAL" in this document are to be interpreted as described in BCP | "OPTIONAL" in this document are to be interpreted as described in BCP | |||
14 [RFC2119] [RFC8174] when, and only when, they appear in all | 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
capitals, as shown here. | capitals, as shown here. | |||
2. Flow Identifiers | 2. Multiplexing | |||
Flow identifiers represent bidirectional flows of datagrams within a | In order to allow multiple exchanges of datagrams to coexist on a | |||
single QUIC connection. These are conceptually similar to streams in | given QUIC connection, HTTP datagrams contain two layers of | |||
the sense that they allow multiplexing of application data. Flows | multiplexing. First, the QUIC DATAGRAM frame payload starts with an | |||
lack any of the ordering or reliability guarantees of streams. | encoded stream identifier that associates the datagram with a given | |||
QUIC stream. Second, datagrams carry a context identifier (see | ||||
Section 2.1) that allows multiplexing multiple datagram contexts | ||||
related to a given HTTP request. Conceptually, the first layer of | ||||
multiplexing is per-hop, while the second is end-to-end. | ||||
Beyond this, a sender SHOULD ensure that DATAGRAM frames within a | 2.1. Datagram Contexts | |||
single flow are transmitted in order relative to one another. If | ||||
multiple DATAGRAM frames can be packed into a single QUIC packet, the | ||||
sender SHOULD group them by flow identifier to promote fate-sharing | ||||
within a specific flow and improve the ability to process batches of | ||||
datagram messages efficiently on the receiver. | ||||
3. Flow Identifier Allocation | Within the scope of a given HTTP request, contexts provide an | |||
additional demultiplexing layer. Contexts determine the encoding of | ||||
datagrams, and can be used to implicitly convey metadata. For | ||||
example, contexts can be used for compression to elide some parts of | ||||
the datagram: the context identifier then maps to a compression | ||||
context that the receiver can use to reconstruct the elided data. | ||||
Implementations of HTTP/3 that support the DATAGRAM extension MUST | Contexts are identified within the scope of a given request by a | |||
provide a flow identifier allocation service. That service will | numeric value, referred to as the context ID. A context ID is a | |||
allow applications co-located with HTTP/3 to request a unique flow | 62-bit integer (0 to 2^62-1). | |||
identifier that they can subsequently use for their own purposes. | ||||
The HTTP/3 implementation will then parse the flow identifier of | ||||
incoming DATAGRAM frames and use it to deliver the frame to the | ||||
appropriate application. | ||||
Even-numbered flow identifiers are client-initiated, while odd- | While stream IDs are a per-hop concept, context IDs are an end-to-end | |||
numbered flow identifiers are server-initiated. This means that an | concept. In other words, if a datagram travels through one or more | |||
HTTP/3 client implementation of the flow identifier allocation | intermediaries on its way from client to server, the stream ID will | |||
service MUST only provide even-numbered identifiers, while a server | most likely change from hop to hop, but the context ID will remain | |||
implementation MUST only provide odd-numbered identifiers. Note | the same. Context IDs are opaque to intermediaries. | |||
that, once allocated, any flow identifier can be used by both client | ||||
and server - only allocation carries separate namespaces to avoid | ||||
requiring synchronization. | ||||
The flow allocation service SHOULD also provide a mechanism for | 2.2. Context ID Allocation | |||
applications to indicate they have completed their usage of a flow | ||||
identifier and will no longer be using that flow identifier, this | ||||
process is called "retiring" a flow identifier. Applications MUST | ||||
NOT retire a flow identifier until after they have received | ||||
confirmation that the peer has also stopped using that flow | ||||
identifier. The flow identifier allocation service MAY reuse | ||||
previously retired flow identifiers once they have ascertained that | ||||
there are no packets with DATAGRAM frames using that flow identifier | ||||
still in flight. Reusing flow identifiers can improve performance by | ||||
transmitting the flow identifier using a shorter variable-length | ||||
integer encoding. | ||||
4. HTTP/3 DATAGRAM Frame Format | Implementations of HTTP/3 that support the DATAGRAM extension MUST | |||
provide a context ID allocation service. That service will allow | ||||
applications co-located with HTTP/3 to request a unique context ID | ||||
that they can subsequently use for their own purposes. The HTTP/3 | ||||
implementation will then parse the context ID of incoming DATAGRAM | ||||
frames and use it to deliver the frame to the appropriate application | ||||
context. | ||||
Even-numbered context IDs are client-initiated, while odd-numbered | ||||
context IDs are server-initiated. This means that an HTTP/3 client | ||||
implementation of the context ID allocation service MUST only provide | ||||
even-numbered IDs, while a server implementation MUST only provide | ||||
odd-numbered IDs. Note that, once allocated, any context ID can be | ||||
used by both client and server - only allocation carries separate | ||||
namespaces to avoid requiring synchronization. Additionally, note | ||||
that the context ID namespace is tied to a given HTTP request: it is | ||||
possible for the same numeral context ID to be used simultaneously in | ||||
distinct requests. | ||||
3. HTTP/3 DATAGRAM Frame Format | ||||
When used with HTTP/3, the Datagram Data field of QUIC DATAGRAM | When used with HTTP/3, the Datagram Data field of QUIC DATAGRAM | |||
frames uses the following format (using the notation from the | frames uses the following format (using the notation from the | |||
"Notational Conventions" section of [QUIC]): | "Notational Conventions" section of [QUIC]): | |||
HTTP/3 DATAGRAM Frame { | HTTP/3 Datagram { | |||
Flow Identifier (i), | Quarter Stream ID (i), | |||
Context ID (i), | ||||
HTTP/3 Datagram Payload (..), | HTTP/3 Datagram Payload (..), | |||
} | } | |||
Figure 1: HTTP/3 DATAGRAM Frame Format | Figure 1: HTTP/3 DATAGRAM Frame Format | |||
Flow Identifier: A variable-length integer indicating the Flow | Quarter Stream ID: A variable-length integer that contains the value | |||
Identifier of the datagram (see Section 2). | of the client-initiated bidirectional stream that this datagram is | |||
associated with, divided by four. (The division by four stems | ||||
from the fact that HTTP requests are sent on client-initiated | ||||
bidirectional streams, and those have stream IDs that are | ||||
divisible by four.) | ||||
Context ID: A variable-length integer indicating the context ID of | ||||
the datagram (see Section 2.1). | ||||
HTTP/3 Datagram Payload: The payload of the datagram, whose | HTTP/3 Datagram Payload: The payload of the datagram, whose | |||
semantics are defined by individual applications. Note that this | semantics are defined by individual applications. Note that this | |||
field can be empty. | field can be empty. | |||
Endpoints MUST treat receipt of a DATAGRAM frame whose payload is too | Intermediaries parse the Quarter Stream ID field in order to | |||
short to parse the flow identifier as an HTTP/3 connection error of | associate the QUIC DATAGRAM frame with a stream. If an intermediary | |||
type H3_GENERAL_PROTOCOL_ERROR. | receives a QUIC DATAGRAM frame whose payload is too short to allow | |||
parsing the Quarter Stream ID field, the intermediary MUST treat it | ||||
as an HTTP/3 connection error of type H3_GENERAL_PROTOCOL_ERROR. | ||||
Intermediaries MUST ignore any HTTP/3 Datagram fields after the | ||||
Quarter Stream ID. | ||||
Endpoints parse both the Quarter Stream ID field and the Context ID | ||||
field in order to associate the QUIC DATAGRAM frame with a stream and | ||||
context within that stream. If an endpoint receives a QUIC DATAGRAM | ||||
frame whose payload is too short to allow parsing the Quarter Stream | ||||
ID field, the endpoint MUST treat it as an HTTP/3 connection error of | ||||
type H3_GENERAL_PROTOCOL_ERROR. If an endpoint receives a QUIC | ||||
DATAGRAM frame whose payload is long enough to allow parsing the | ||||
Quarter Stream ID field but too short to allow parsing the Context ID | ||||
field, the endpoint MUST abruptly terminate the corresponding stream | ||||
with a stream error of type H3_GENERAL_PROTOCOL_ERROR. | ||||
If a DATAGRAM frame is received and its Quarter Stream ID maps to a | ||||
stream that has already been closed, the receiver MUST silently drop | ||||
that frame. If a DATAGRAM frame is received and its Quarter Stream | ||||
ID maps to a stream that has not yet been created, the receiver SHALL | ||||
either drop that frame silently or buffer it temporarily while | ||||
awaiting the creation of the corresponding stream. | ||||
4. CAPSULE HTTP/3 Frame Definition | ||||
CAPSULE allows reliably sending request-related information end-to- | ||||
end, even in the presence of HTTP intermediaries. | ||||
CAPSULE is an HTTP/3 Frame (as opposed to a QUIC frame) which SHALL | ||||
only be sent in client-initiated bidirectional streams. | ||||
Intermediaries MUST forward all received CAPSULE frames in their | ||||
unmodified entirety on the same stream where it would forward DATA | ||||
frames. Intermediaries MUST NOT send any CAPSULE frames other than | ||||
the ones it is forwarding. | ||||
This specification of CAPSULE currently uses HTTP/3 frame type | ||||
0xffcab5. If this document is approved, a lower number will be | ||||
requested from IANA. | ||||
CAPSULE HTTP/3 Frame { | ||||
Type (i) = 0xffcab5, | ||||
Length (i), | ||||
Capsule Type (i), | ||||
Capsule Data (..), | ||||
} | ||||
Figure 2: CAPSULE HTTP/3 Frame Format | ||||
The Type and Length fields follows the definition of HTTP/3 frames | ||||
from [H3]. The payload consists of: | ||||
Capsule Type: The type of this capsule. | ||||
Capsule Data: Data whose semantics depends on the Capsule Type. | ||||
Endpoints which receive a Capsule with an unknown Capsule Type MUST | ||||
silently drop that Capsule. Intermediaries MUST forward Capsules, | ||||
even if they do not know the Capsule Type or cannot parse the Capsule | ||||
Data. | ||||
4.1. The REGISTER_DATAGRAM_CONTEXT Capsule | ||||
The REGISTER_DATAGRAM_CONTEXT capsule (type=0x00) allows an endpoint | ||||
to inform its peer of the encoding and semantics of datagrams | ||||
associated with a given context ID. Its Capsule Data field consists | ||||
of: | ||||
REGISTER_DATAGRAM_CONTEXT Capsule { | ||||
Context ID (i), | ||||
Extension String (..), | ||||
} | ||||
Figure 3: REGISTER_DATAGRAM_CONTEXT Capsule Format | ||||
Context ID: The context ID to register. | ||||
Extension String: A string of comma-separated key-value pairs to | ||||
enable extensibility. Keys are registered with IANA, see | ||||
Section 8.4. | ||||
The ABNF for the Extension String field is as follows (using syntax | ||||
from Section 3.2.6 of [RFC7230]): | ||||
extension-string = [ ext-member *( "," ext-member ) ] | ||||
ext-member = ext-member-key "=" ext-member-value | ||||
ext-member-key = token | ||||
ext-member-value = token | ||||
Note that these registrations are unilateral and bidirectional: the | ||||
sender of the frame unilaterally defines the semantics it will apply | ||||
to the datagrams it sends and receives using this context ID. Once a | ||||
context ID is registered, it can be used in both directions. | ||||
Endpoints MUST NOT send DATAGRAM frames using a Context ID until they | ||||
have either sent or received a REGISTER_DATAGRAM_CONTEXT Capsule with | ||||
the same Context ID. However, due to reordering, an endpoint that | ||||
receives a DATAGRAM frame with an unknown Context ID MUST NOT treat | ||||
it as an error, it SHALL instead drop the DATAGRAM frame silently, or | ||||
buffer it temporarily while awaiting the corresponding | ||||
REGISTER_DATAGRAM_CONTEXT Capsule. | ||||
Endpoints MUST NOT register the same Context ID twice on the same | ||||
stream. This also applies to Context IDs that have been closed using | ||||
a CLOSE_DATAGRAM_CONTEXT capsule. Clients MUST NOT register server- | ||||
initiated Context IDs and servers MUST NOT register client-initiated | ||||
Context IDs. If an endpoint receives a REGISTER_DATAGRAM_CONTEXT | ||||
capsule that violates one or more of these requirements, the endpoint | ||||
MUST abruptly terminate the corresponding stream with a stream error | ||||
of type H3_GENERAL_PROTOCOL_ERROR. | ||||
4.2. The CLOSE_DATAGRAM_CONTEXT Capsule | ||||
The CLOSE_DATAGRAM_CONTEXT capsule (type=0x01) allows an endpoint to | ||||
inform its peer that it will no longer send or parse received | ||||
datagrams associated with a given context ID. Its Capsule Data field | ||||
consists of: | ||||
CLOSE_DATAGRAM_CONTEXT Capsule { | ||||
Context ID (i), | ||||
Extension String (..), | ||||
} | ||||
Figure 4: CLOSE_DATAGRAM_CONTEXT Capsule Format | ||||
Context ID: The context ID to close. | ||||
Extension String: A string of comma-separated key-value pairs to | ||||
enable extensibility, see the definition of the same field in | ||||
Section 4.1 for details. | ||||
Note that this close is unilateral and bidirectional: the sender of | ||||
the frame unilaterally informs its peer of the closure. Endpoints | ||||
can use CLOSE_DATAGRAM_CONTEXT capsules to close a context that was | ||||
initially registered by either themselves, or by their peer. | ||||
Endpoints MAY use the CLOSE_DATAGRAM_CONTEXT capsule to immediately | ||||
reject a context that was just registered using a | ||||
REGISTER_DATAGRAM_CONTEXT capsule if they find its Extension String | ||||
to be unacceptable. | ||||
After an endpoint has either sent or received a | ||||
CLOSE_DATAGRAM_CONTEXT frame, it MUST NOT send any DATAGRAM frames | ||||
with that Context ID. However, due to reordering, an endpoint that | ||||
receives a DATAGRAM frame with a closed Context ID MUST NOT treat it | ||||
as an error, it SHALL instead drop the DATAGRAM frame silently. | ||||
Endpoints MUST NOT close a Context ID that was not previously | ||||
registered. Endpoints MUST NOT close a Context ID that has already | ||||
been closed. If an endpoint receives a CLOSE_DATAGRAM_CONTEXT | ||||
capsule that violates one or more of these requirements, the endpoint | ||||
MUST abruptly terminate the corresponding stream with a stream error | ||||
of type H3_GENERAL_PROTOCOL_ERROR. | ||||
4.3. The DATAGRAM Capsule | ||||
The DATAGRAM capsule (type=0x02) allows an endpoint to send a | ||||
datagram frame over an HTTP stream. This is particularly useful when | ||||
using a version of HTTP that does not support QUIC DATAGRAM frames. | ||||
Its Capsule Data field consists of: | ||||
DATAGRAM Capsule { | ||||
Context ID (i), | ||||
HTTP/3 Datagram Payload (..), | ||||
} | ||||
Figure 5: DATAGRAM Capsule Format | ||||
Context ID: A variable-length integer indicating the context ID of | ||||
the datagram (see Section 2.1). | ||||
HTTP/3 Datagram Payload: The payload of the datagram, whose | ||||
semantics are defined by individual applications. Note that this | ||||
field can be empty. | ||||
Datagrams sent using the DATAGRAM Capsule have the exact same | ||||
semantics as datagrams sent in QUIC DATAGRAM frames. | ||||
5. The H3_DATAGRAM HTTP/3 SETTINGS Parameter | 5. The H3_DATAGRAM HTTP/3 SETTINGS Parameter | |||
Implementations of HTTP/3 that support this mechanism can indicate | Implementations of HTTP/3 that support this mechanism can indicate | |||
that to their peer by sending the H3_DATAGRAM SETTINGS parameter with | that to their peer by sending the H3_DATAGRAM SETTINGS parameter with | |||
a value of 1. The value of the H3_DATAGRAM SETTINGS parameter MUST | a value of 1. The value of the H3_DATAGRAM SETTINGS parameter MUST | |||
be either 0 or 1. A value of 0 indicates that this mechanism is not | be either 0 or 1. A value of 0 indicates that this mechanism is not | |||
supported. An endpoint that receives the H3_DATAGRAM SETTINGS | supported. An endpoint that receives the H3_DATAGRAM SETTINGS | |||
parameter with a value that is neither 0 or 1 MUST terminate the | parameter with a value that is neither 0 or 1 MUST terminate the | |||
connection with error H3_SETTINGS_ERROR. | connection with error H3_SETTINGS_ERROR. | |||
skipping to change at page 5, line 25 ¶ | skipping to change at page 9, line 35 ¶ | |||
0-RTT data, they MUST send a H3_DATAGRAM SETTINGS parameter greater | 0-RTT data, they MUST send a H3_DATAGRAM SETTINGS parameter greater | |||
than or equal to the value they sent to the client in the connection | than or equal to the value they sent to the client in the connection | |||
where they sent them the NewSessionTicket message. If a client | where they sent them the NewSessionTicket message. If a client | |||
stores the value of the H3_DATAGRAM SETTINGS parameter with their | stores the value of the H3_DATAGRAM SETTINGS parameter with their | |||
0-RTT state, they MUST validate that the new value of the H3_DATAGRAM | 0-RTT state, they MUST validate that the new value of the H3_DATAGRAM | |||
SETTINGS parameter sent by the server in the handshake is greater | SETTINGS parameter sent by the server in the handshake is greater | |||
than or equal to the stored value; if not, the client MUST terminate | than or equal to the stored value; if not, the client MUST terminate | |||
the connection with error H3_SETTINGS_ERROR. In all cases, the | the connection with error H3_SETTINGS_ERROR. In all cases, the | |||
maximum permitted value of the H3_DATAGRAM SETTINGS parameter is 1. | maximum permitted value of the H3_DATAGRAM SETTINGS parameter is 1. | |||
6. Datagram-Flow-Id Header Field Definition | 6. HTTP/1.x and HTTP/2 Support | |||
"Datagram-Flow-Id" is a List Structured Field [STRUCT-FIELD], whose | ||||
members MUST all be Items of type Integer. Its ABNF is: | ||||
Datagram-Flow-Id = sf-list | ||||
The "Datagram-Flow-Id" header field is used to associate one or more | ||||
datagram flow identifiers with an HTTP message. As a simple example | ||||
using a single identifier, the definition of an HTTP method could | ||||
instruct the client to use its flow identifier allocation service to | ||||
allocate a new flow identifier, and then the client will add the | ||||
"Datagram-Flow-Id" header field to its request to communicate that | ||||
value to the server. In this example, the resulting header field | ||||
could look like: | ||||
Datagram-Flow-Id = 2 | ||||
List members are flow identifier elements, which can be named or | ||||
unnamed. One element in the list is allowed to be unnamed, but all | ||||
but one elements MUST carry a name. The name of an element is | ||||
encoded in the key of the first parameter of that element (parameters | ||||
are defined in Section 3.1.2 of [STRUCT-FIELD]). Each name MUST NOT | ||||
appear more than once in the list. The value of the first parameter | ||||
of each named element (whose corresponding key conveys the element | ||||
name) MUST be of type Boolean and equal to true. The value of the | ||||
first parameter of the unnamed element MUST NOT be of type Boolean. | ||||
The ordering of the list does not carry any semantics. For example, | ||||
an HTTP method that wishes to use four datagram flow identifiers for | ||||
the lifetime of its request stream could look like this: | ||||
Datagram-Flow-Id = 42, 44; ecn-ect0, 46; ecn-ect1, 48; ecn-ce | We can provide DATAGRAM support in HTTP/2 by defining the CAPSULE | |||
frame in HTTP/2. | ||||
In this example, 42 is the unnamed flow identifier, 44 represents the | We can provide DATAGRAM support in HTTP/1.x by defining its data | |||
name "ecn-ect0", 46 represents "ecn-ect1", and 48 represents "ecn- | stream format to a sequence of length-value capsules. | |||
ce". Note that, since the list ordering does not carry semantics, | ||||
this example can be equivalently encoded as: | ||||
Datagram-Flow-Id = 44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1 | TODO: Refactor this document into "HTTP Datagrams" with definitions | |||
for HTTP/1.x, HTTP/2, and HTTP/3. | ||||
Even if a sender attempts to communicate the meaning of a flow | 7. Security Considerations | |||
identifier before it uses it in an HTTP/3 datagram, it is possible | ||||
that its peer will receive an HTTP/3 datagram with a flow identifier | ||||
that it does not know as it has not yet received the corresponding | ||||
"Datagram-Flow-Id" header field. (For example, this could happen if | ||||
the QUIC STREAM frame that contains the "Datagram-Flow-Id" header | ||||
field is reordered and arrives afer the DATAGRAM frame.) Endpoints | ||||
MUST NOT treat that scenario as an error; they MUST either silently | ||||
discard the datagram or buffer it until they receive the "Datagram- | ||||
Flow-Id" header field. | ||||
Distinct HTTP requests MAY refer to the same flow identifier in their | Since this feature requires sending an HTTP/3 Settings parameter, it | |||
respective "Datagram-Flow-Id" header fields. | "sticks out". In other words, probing clients can learn whether a | |||
server supports this feature. Implementations that support this | ||||
feature SHOULD always send this Settings parameter to avoid leaking | ||||
the fact that there are applications using HTTP/3 datagrams enabled | ||||
on this endpoint. | ||||
Note that integer structured fields can only encode values up to | 8. IANA Considerations | |||
10^15-1, therefore the maximum possible value of an element of the | ||||
"Datagram-Flow-Id" header field is lower then the theoretical maximum | ||||
value of a flow identifier which is 2^62-1 due to the QUIC variable | ||||
length integer encoding. If the flow identifier allocation service | ||||
of an endpoint runs out of values lower than 10^15-1, the endpoint | ||||
MUST fail the flow identifier allocation. An HTTP message that | ||||
carries a "Datagram-Flow-Id" header field with a flow identifier | ||||
value above 10^15-1 is malformed (see Section 8.1.2.6 of [H2]). | ||||
7. HTTP Intermediaries | 8.1. HTTP/3 CAPSULE Frame | |||
HTTP/3 DATAGRAM flow identifiers are specific to a given HTTP/3 | This document will request IANA to register the following entry in | |||
connection. However, in some cases, an HTTP request may travel | the "HTTP/3 Frames" registry: | |||
across multiple HTTP connections if there are HTTP intermediaries | ||||
involved; see Section 2.3 of [RFC7230]. | ||||
If an intermediary has sent the H3_DATAGRAM SETTINGS parameter with a | +------------+----------+---------------+ | |||
value of 1 on its client-facing connection, it MUST inspect all HTTP | | Frame Type | Value | Specification | | |||
requests from that connection and check for the presence of the | +============+==========+===============+ | |||
"Datagram-Flow-Id" header field. If the HTTP method of the request | | CAPSULE | 0xffcab5 | This Document | | |||
is not supported by the intermediary, it MUST remove the "Datagram- | +------------+----------+---------------+ | |||
Flow-Id" header field before forwarding the request. If the | ||||
intermediary supports the method, it MUST either remove the header | ||||
field or adhere to the requirements leveraged by that method on | ||||
intermediaries. | ||||
If an intermediary has sent the H3_DATAGRAM SETTINGS parameter with a | 8.2. HTTP SETTINGS Parameter | |||
value of 1 on its server-facing connection, it MUST inspect all HTTP | ||||
responses from that connection and check for the presence of the | ||||
"Datagram-Flow-Id" header field. If the HTTP method of the request | ||||
is not supported by the intermediary, it MUST remove the "Datagram- | ||||
Flow-Id" header field before forwarding the response. If the | ||||
intermediary supports the method, it MUST either remove the header | ||||
field or adhere to the requirements leveraged by that method on | ||||
intermediaries. | ||||
If an intermediary processes distinct HTTP requests that refer to the | This document will request IANA to register the following entry in | |||
same flow identifier in their respective "Datagram-Flow-Id" header | the "HTTP/3 Settings" registry: | |||
fields, it MUST ensure that those requests are routed to the same | ||||
backend. | ||||
8. Security Considerations | +--------------+----------+---------------+---------+ | |||
| Setting Name | Value | Specification | Default | | ||||
+==============+==========+===============+=========+ | ||||
| H3_DATAGRAM | 0xffd276 | This Document | 0 | | ||||
+--------------+----------+---------------+---------+ | ||||
This document does not have additional security considerations beyond | 8.3. Capsule Types | |||
those defined in [QUIC] and [DGRAM]. | ||||
9. IANA Considerations | This document establishes a registry for HTTP/3 frame type codes. | |||
The "HTTP Capsule Types" registry governs a 62-bit space. | ||||
Registrations in this registry MUST include the following fields: | ||||
9.1. HTTP SETTINGS Parameter | Type: | |||
This document will request IANA to register the following entry in | A name or label for the capsule type. | |||
the "HTTP/3 Settings" registry: | ||||
+--------------+-------+---------------+---------+ | Value: The value of the Capsule Type field (see Section 4) is a | |||
| Setting Name | Value | Specification | Default | | 62bit integer. | |||
+==============+=======+===============+=========+ | ||||
| H3_DATAGRAM | 0x276 | This Document | 0 | | ||||
+--------------+-------+---------------+---------+ | ||||
9.2. HTTP Header Field | Reference: An optional reference to a specification for the type. | |||
This field MAY be empty. | ||||
This document will request IANA to register the "Datagram-Flow-Id" | Registrations follow the "First Come First Served" policy (see | |||
header field in the "Permanent Message Header Field Names" registry | Section 4.4 of [IANA-POLICY]) where two registrations MUST NOT have | |||
maintained at <https://www.iana.org/assignments/message-headers>. | the same Type. | |||
+-------------------+----------+--------+---------------+ | This registry initially contains the following entries: | |||
| Header Field Name | Protocol | Status | Reference | | ||||
+-------------------+----------+--------+---------------+ | ||||
| Datagram-Flow-Id | http | std | This document | | ||||
+-------------------+----------+--------+---------------+ | ||||
9.3. Flow Identifier Parameters | +---------------------------+-------+---------------+ | |||
| Capsule Type | Value | Specification | | ||||
+---------------------------+-------+---------------+ | ||||
| REGISTER_DATAGRAM_CONTEXT | 0x00 | This Document | | ||||
+---------------------------+-------+---------------+ | ||||
| CLOSE_DATAGRAM_CONTEXT | 0x01 | This Document | | ||||
+---------------------------+-------+---------------+ | ||||
| DATAGRAM | 0x02 | This Document | | ||||
+---------------------------+-------+---------------+ | ||||
This document will request IANA to create an "HTTP Datagram Flow | 8.4. Context Extension Keys | |||
Identifier Parameters" registry. Registrations in this registry MUST | ||||
include the following fields: | ||||
Key: The key of a parameter that is associated with a datagram flow | REGISTER_DATAGRAM_CONTEXT capsules carry key-value pairs, see | |||
identifier list member (see Section 6). Keys MUST be valid | Section 4.1. This document will request IANA to create an "HTTP | |||
structured field parameter keys (see Section 3.1.2 of | Datagram Context Extension Keys" registry. Registrations in this | |||
[STRUCT-FIELD]). | registry MUST include the following fields: | |||
Description: A brief description of the parameter semantics, which | Key: The key (see Section 4.1). Keys MUST be valid tokens as | |||
MAY be a summary if a specification reference is provided. | defined in Section 3.2.6 of [RFC7230]. | |||
Is Name: This field MUST be either Yes or No. Yes indicates that | Description: A brief description of the key semantics, which MAY be | |||
this parameter is the name of a named element (see Section 6). No | a summary if a specification reference is provided. | |||
indicates that it is a parameter that is not a name. | ||||
Reference: An optional reference to a specification for the | Reference: An optional reference to a specification for the | |||
parameter. This field MAY be empty. | parameter. This field MAY be empty. | |||
Registrations follow the "First Come First Served" policy (see | Registrations follow the "First Come First Served" policy (see | |||
Section 4.4 of [IANA-POLICY]) where two registrations MUST NOT have | Section 4.4 of [IANA-POLICY]) where two registrations MUST NOT have | |||
the same Key. This registry is initially empty. | the same Key. This registry is initially empty. | |||
10. Normative References | 9. Normative References | |||
[DGRAM] Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable | [DGRAM] Pauly, T., Kinnear, E., and D. Schinazi, "An Unreliable | |||
Datagram Extension to QUIC", Work in Progress, Internet- | Datagram Extension to QUIC", Work in Progress, Internet- | |||
Draft, draft-ietf-quic-datagram-01, 24 August 2020, | Draft, draft-ietf-quic-datagram-02, 16 February 2021, | |||
<http://www.ietf.org/internet-drafts/draft-ietf-quic- | <https://tools.ietf.org/html/draft-ietf-quic-datagram-02>. | |||
datagram-01.txt>. | ||||
[H2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | ||||
Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | ||||
DOI 10.17487/RFC7540, May 2015, | ||||
<https://www.rfc-editor.org/info/rfc7540>. | ||||
[H3] Bishop, M., "Hypertext Transfer Protocol Version 3 | [H3] Bishop, M., "Hypertext Transfer Protocol Version 3 | |||
(HTTP/3)", Work in Progress, Internet-Draft, draft-ietf- | (HTTP/3)", Work in Progress, Internet-Draft, draft-ietf- | |||
quic-http-33, 15 December 2020, <http://www.ietf.org/ | quic-http-34, 2 February 2021, | |||
internet-drafts/draft-ietf-quic-http-33.txt>. | <https://tools.ietf.org/html/draft-ietf-quic-http-34>. | |||
[IANA-POLICY] | [IANA-POLICY] | |||
Cotton, M., Leiba, B., and T. Narten, "Guidelines for | Cotton, M., Leiba, B., and T. Narten, "Guidelines for | |||
Writing an IANA Considerations Section in RFCs", BCP 26, | Writing an IANA Considerations Section in RFCs", BCP 26, | |||
RFC 8126, DOI 10.17487/RFC8126, June 2017, | RFC 8126, DOI 10.17487/RFC8126, June 2017, | |||
<https://www.rfc-editor.org/info/rfc8126>. | <https://www.rfc-editor.org/rfc/rfc8126>. | |||
[QUIC] Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed | [QUIC] Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed | |||
and Secure Transport", Work in Progress, Internet-Draft, | and Secure Transport", Work in Progress, Internet-Draft, | |||
draft-ietf-quic-transport-34, 14 January 2021, | draft-ietf-quic-transport-34, 14 January 2021, | |||
<http://www.ietf.org/internet-drafts/draft-ietf-quic- | <https://tools.ietf.org/html/draft-ietf-quic-transport- | |||
transport-34.txt>. | 34>. | |||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Requirement Levels", BCP 14, RFC 2119, | Requirement Levels", BCP 14, RFC 2119, | |||
DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
<https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/rfc/rfc2119>. | |||
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | |||
Protocol (HTTP/1.1): Message Syntax and Routing", | Protocol (HTTP/1.1): Message Syntax and Routing", | |||
RFC 7230, DOI 10.17487/RFC7230, June 2014, | RFC 7230, DOI 10.17487/RFC7230, June 2014, | |||
<https://www.rfc-editor.org/info/rfc7230>. | <https://www.rfc-editor.org/rfc/rfc7230>. | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. | |||
[STRUCT-FIELD] | Appendix A. Examples | |||
Nottingham, M. and P. Kamp, "Structured Field Values for | ||||
HTTP", Work in Progress, Internet-Draft, draft-ietf- | A.1. CONNECT-UDP | |||
httpbis-header-structure-19, 3 June 2020, | Client Server | |||
<http://www.ietf.org/internet-drafts/draft-ietf-httpbis- | ||||
header-structure-19.txt>. | STREAM(44): HEADERS --------> | |||
:method = CONNECT-UDP | ||||
:scheme = https | ||||
:path = / | ||||
:authority = target.example.org:443 | ||||
STREAM(44): CAPSULE --------> | ||||
Capsule Type = REGISTER_DATAGRAM_CONTEXT | ||||
Context ID = 0 | ||||
Extension String = "" | ||||
DATAGRAM --------> | ||||
Quarter Stream ID = 11 | ||||
Context ID = 0 | ||||
Payload = Encapsulated UDP Payload | ||||
<-------- STREAM(44): HEADERS | ||||
:status = 200 | ||||
/* Wait for target server to respond to UDP packet. */ | ||||
<-------- DATAGRAM | ||||
Quarter Stream ID = 11 | ||||
Context ID = 0 | ||||
Payload = Encapsulated UDP Payload | ||||
A.2. CONNECT-UDP with Timestamp Extension | ||||
Client Server | ||||
STREAM(44): HEADERS --------> | ||||
:method = CONNECT-UDP | ||||
:scheme = https | ||||
:path = / | ||||
:authority = target.example.org:443 | ||||
STREAM(44): CAPSULE --------> | ||||
Capsule Type = REGISTER_DATAGRAM_CONTEXT | ||||
Context ID = 0 | ||||
Extension String = "" | ||||
DATAGRAM --------> | ||||
Quarter Stream ID = 11 | ||||
Context ID = 0 | ||||
Payload = Encapsulated UDP Payload | ||||
<-------- STREAM(44): HEADERS | ||||
:status = 200 | ||||
/* Wait for target server to respond to UDP packet. */ | ||||
<-------- DATAGRAM | ||||
Quarter Stream ID = 11 | ||||
Context ID = 0 | ||||
Payload = Encapsulated UDP Payload | ||||
STREAM(44): CAPSULE --------> | ||||
Capsule Type = REGISTER_DATAGRAM_CONTEXT | ||||
Context ID = 2 | ||||
Extension String = "timestamp" | ||||
DATAGRAM --------> | ||||
Quarter Stream ID = 11 | ||||
Context ID = 2 | ||||
Payload = Encapsulated UDP Payload With Timestamp | ||||
A.3. CONNECT-IP with IP compression | ||||
Client Server | ||||
STREAM(44): HEADERS --------> | ||||
:method = CONNECT-IP | ||||
:scheme = https | ||||
:path = / | ||||
:authority = proxy.example.org:443 | ||||
<-------- STREAM(44): HEADERS | ||||
:status = 200 | ||||
/* Exchange CONNECT-IP configuration information. */ | ||||
STREAM(44): CAPSULE --------> | ||||
Capsule Type = REGISTER_DATAGRAM_CONTEXT | ||||
Context ID = 0 | ||||
Extension String = "" | ||||
DATAGRAM --------> | ||||
Quarter Stream ID = 11 | ||||
Context ID = 0 | ||||
Payload = Encapsulated IP Packet | ||||
/* Endpoint happily exchange encapsulated IP packets */ | ||||
/* using Quarter Stream ID 11 and Context ID 0. */ | ||||
DATAGRAM --------> | ||||
Quarter Stream ID = 11 | ||||
Context ID = 0 | ||||
Payload = Encapsulated IP Packet | ||||
/* After performing some analysis on traffic patterns, */ | ||||
/* the client decides it wants to compress a 5-tuple. */ | ||||
STREAM(44): CAPSULE --------> | ||||
Capsule Type = REGISTER_DATAGRAM_CONTEXT | ||||
Context ID = 2 | ||||
Extension String = "ip=192.0.2.42,port=443" | ||||
DATAGRAM --------> | ||||
Quarter Stream ID = 11 | ||||
Context ID = 2 | ||||
Payload = Compressed IP Packet | ||||
A.4. WebTransport | ||||
Client Server | ||||
STREAM(44): HEADERS --------> | ||||
:method = CONNECT | ||||
:scheme = https | ||||
:method = webtransport | ||||
:path = /hello | ||||
:authority = webtransport.example.org:443 | ||||
Origin = https://www.example.org:443 | ||||
STREAM(44): CAPSULE --------> | ||||
Capsule Type = REGISTER_DATAGRAM_CONTEXT | ||||
Context ID = 0 | ||||
Extension String = "" | ||||
<-------- STREAM(44): HEADERS | ||||
:status = 200 | ||||
/* Both endpoints can now send WebTransport datagrams. */ | ||||
Acknowledgments | Acknowledgments | |||
The DATAGRAM flow identifier was previously part of the DATAGRAM | The DATAGRAM context identifier was previously part of the DATAGRAM | |||
frame definition itself, the author would like to acknowledge the | frame definition itself, the authors would like to acknowledge the | |||
authors of that document and the members of the IETF MASQUE working | authors of that document and the members of the IETF MASQUE working | |||
group for their suggestions. Additionally, the author would like to | group for their suggestions. Additionally, the authors would like to | |||
thank Martin Thomson for suggesting the use of an HTTP/3 SETTINGS | thank Martin Thomson for suggesting the use of an HTTP/3 SETTINGS | |||
parameter. | parameter. Furthermore, the authors would like to thank Ben Schwartz | |||
for writing the first proposal that used two layers of indirection. | ||||
Authors' Addresses | Authors' Addresses | |||
David Schinazi | David Schinazi | |||
Google LLC | Google LLC | |||
1600 Amphitheatre Parkway | 1600 Amphitheatre Parkway | |||
Mountain View, California 94043, | Mountain View, California 94043, | |||
United States of America | United States of America | |||
Email: dschinazi.ietf@gmail.com | Email: dschinazi.ietf@gmail.com | |||
End of changes. 58 change blocks. | ||||
226 lines changed or deleted | 487 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |