| draft-ietf-quic-qcram-00.txt | draft-ietf-quic-qcram-latest.txt | |||
|---|---|---|---|---|
| QUIC Working Group C. Krasic | QUIC Working Group C. Krasic | |||
| Internet-Draft Google, Inc | Internet-Draft Google, Inc | |||
| Intended status: Standards Track M. Bishop | Intended status: Standards Track M. Bishop | |||
| Expires: August 24, 2018 Akamai Technologies | Expires: November 20, 2025 Akamai Technologies | |||
| A. Frindell, Ed. | A. Frindell, Ed. | |||
| February 20, 2018 | May 19, 2025 | |||
| Header Compression for HTTP over QUIC | Header Compression for HTTP over QUIC | |||
| draft-ietf-quic-qcram-00 | draft-ietf-quic-qcram-latest | |||
| Abstract | Abstract | |||
| The design of the core QUIC transport subsumes many HTTP/2 features, | This specification defines QCRAM, a compression format for | |||
| prominent among them stream multiplexing. A key advantage of the | efficiently representing HTTP header fields, to be used in HTTP over | |||
| QUIC transport is stream multiplexing free of head-of-line (HoL) | QUIC. This is a variation of HPACK header compression that seeks to | |||
| blocking between streams. In HTTP/2, multiplexed streams can suffer | reduce head-of-line blocking. | |||
| HoL blocking due to TCP. | ||||
| If HTTP/2's HPACK is used for header compression, HTTP/QUIC is still | Note to Readers | |||
| vulnerable to HoL blocking, because of HPACK's assumption of in-order | ||||
| delivery. This draft defines QCRAM, a variation of HPACK and | Discussion of this draft takes place on the QUIC working group | |||
| mechanisms in the HTTP/QUIC mapping that allow the flexibility to | mailing list (quic@ietf.org), which is archived at | |||
| avoid header-compression-induced HoL blocking. | https://mailarchive.ietf.org/arch/search/?email_list=quic [1]. | |||
| Working Group information can be found at https://github.com/quicwg | ||||
| [2]; source code and issues list for this draft can be found at | ||||
| https://github.com/quicwg/base-drafts/labels/-qcram [3]. | ||||
| 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. | |||
| 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 August 24, 2018. | This Internet-Draft will expire on November 20, 2025. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2018 IETF Trust and the persons identified as the | Copyright (c) 2025 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 | Provisions Relating to IETF Documents | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | |||
| 1.1. Head-of-Line Blocking in HPACK . . . . . . . . . . . . . 3 | 1.1. Head-of-Line Blocking in HPACK . . . . . . . . . . . . . 3 | |||
| 1.2. Avoiding Head-of-Line Blocking in HTTP/QUIC . . . . . . . 3 | 1.2. Avoiding Head-of-Line Blocking in HTTP/QUIC . . . . . . . 3 | |||
| 2. HTTP over QUIC mapping extensions . . . . . . . . . . . . . . 4 | 2. HPACK extensions . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2.1. HEADERS and PUSH_PROMISE . . . . . . . . . . . . . . . . 4 | 2.1. Allowed Instructions . . . . . . . . . . . . . . . . . . 4 | |||
| 2.2. HEADER_ACK . . . . . . . . . . . . . . . . . . . . . . . 5 | 2.2. Header Block Prefix . . . . . . . . . . . . . . . . . . . 5 | |||
| 3. HPACK extensions . . . . . . . . . . . . . . . . . . . . . . 5 | 2.3. Hybrid absolute-relative indexing . . . . . . . . . . . . 5 | |||
| 3.1. Allowed Instructions . . . . . . . . . . . . . . . . . . 5 | 2.4. Preventing Eviction Races . . . . . . . . . . . . . . . . 6 | |||
| 3.2. Header Block Prefix . . . . . . . . . . . . . . . . . . . 5 | 2.4.1. Blocked Evictions . . . . . . . . . . . . . . . . . . 7 | |||
| 3.3. Hybrid absolute-relative indexing . . . . . . . . . . . . 6 | 2.5. Refreshing Entries with Duplication . . . . . . . . . . . 7 | |||
| 3.4. Preventing Eviction Races . . . . . . . . . . . . . . . . 7 | 3. Performance considerations . . . . . . . . . . . . . . . . . 7 | |||
| 3.4.1. Blocked Evictions . . . . . . . . . . . . . . . . . . 7 | 3.1. Speculative table updates . . . . . . . . . . . . . . . . 7 | |||
| 3.5. Refreshing Entries with Duplication . . . . . . . . . . . 8 | 3.2. Additional state beyond HPACK. . . . . . . . . . . . . . 8 | |||
| 4. Performance considerations . . . . . . . . . . . . . . . . . 8 | 3.2.1. Vulnerable Entries . . . . . . . . . . . . . . . . . 8 | |||
| 4.1. Speculative table updates . . . . . . . . . . . . . . . . 8 | 3.2.2. Safe evictions . . . . . . . . . . . . . . . . . . . 8 | |||
| 4.2. Additional state beyond HPACK. . . . . . . . . . . . . . 8 | 3.2.3. Decoder Blocking . . . . . . . . . . . . . . . . . . 8 | |||
| 4.2.1. Vulnerable Entries . . . . . . . . . . . . . . . . . 8 | 3.2.4. Fixed overhead. . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2.2. Safe evictions . . . . . . . . . . . . . . . . . . . 9 | 4. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2.3. Decoder Blocking . . . . . . . . . . . . . . . . . . 9 | 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2.4. Fixed overhead. . . . . . . . . . . . . . . . . . . . 9 | 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 5. Security Considerations . . . . . . . . . . . . . . . . . . . 10 | 6.1. Normative References . . . . . . . . . . . . . . . . . . 9 | |||
| 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 | 6.2. Informative References . . . . . . . . . . . . . . . . . 9 | |||
| 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 10 | 6.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 8. References . . . . . . . . . . . . . . . . . . . . . . . . . 10 | Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 8.1. Normative References . . . . . . . . . . . . . . . . . . 10 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 8.2. Informative References . . . . . . . . . . . . . . . . . 11 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 11 | ||||
| 1. Introduction | 1. Introduction | |||
| The QUIC transport protocol was designed from the outset to support | The QUIC transport protocol was designed from the outset to support | |||
| HTTP semantics, and its design subsumes many of the features of | HTTP semantics, and its design subsumes many of the features of | |||
| HTTP/2. QUIC's stream multiplexing comes into some conflict with | HTTP/2. QUIC's stream multiplexing comes into some conflict with | |||
| header compression. A key goal of the design of QUIC is to improve | header compression. A key goal of the design of QUIC is to improve | |||
| stream multiplexing relative to HTTP/2 by eliminating HoL (head of | stream multiplexing relative to HTTP/2 by eliminating HoL (head of | |||
| line) blocking, which can occur in HTTP/2. HoL blocking can happen | line) blocking, which can occur in HTTP/2. HoL blocking can happen | |||
| because all HTTP/2 streams are multiplexed onto a single TCP | because all HTTP/2 streams are multiplexed onto a single TCP | |||
| skipping to change at page 4, line 8 ¶ | skipping to change at page 4, line 10 ¶ | |||
| 1.2. Avoiding Head-of-Line Blocking in HTTP/QUIC | 1.2. Avoiding Head-of-Line Blocking in HTTP/QUIC | |||
| In the example above, the second stream contained a reference to data | In the example above, the second stream contained a reference to data | |||
| which might not yet have been processed by the recipient. Such | which might not yet have been processed by the recipient. Such | |||
| references are called "vulnerable," because the loss of a different | references are called "vulnerable," because the loss of a different | |||
| packet can keep the reference from being usable. | packet can keep the reference from being usable. | |||
| The encoder can choose on a per-header-block basis whether to favor | The encoder can choose on a per-header-block basis whether to favor | |||
| higher compression ratio (by permitting vulnerable references) or HoL | higher compression ratio (by permitting vulnerable references) or HoL | |||
| resilience (by avoiding them). This is signaled by the BLOCKING flag | resilience (by avoiding them). This is signaled by the BLOCKING flag | |||
| in HEADERS and PUSH_PROMISE frames (see Section 2). | in HEADERS and PUSH_PROMISE frames (see [QUIC-HTTP]). | |||
| If a header block contains no vulnerable header fields, BLOCKING MUST | If a header block contains no vulnerable header fields, BLOCKING MUST | |||
| be 0. This implies that the header fields are represented either as | be 0. This implies that the header fields are represented either as | |||
| references to dynamic table entries which are known to have been | references to dynamic table entries which are known to have been | |||
| received, or as Literal header fields (see [RFC7541] Section 6.2). | received, or as Literal header fields (see Section 6.2 of [RFC7541]). | |||
| If a header block contains any header field which references dynamic | If a header block contains any header field which references dynamic | |||
| table state which the peer might not have received yet, the BLOCKING | table state which the peer might not have received yet, the BLOCKING | |||
| flag MUST be set. If the peer does not yet have the appropriate | flag MUST be set. If the peer does not yet have the appropriate | |||
| state, such blocks might not be processed on arrival. | state, such blocks might not be processed on arrival. | |||
| The header block contains a prefix (Section 3.2). This prefix | The header block contains a prefix (Section 2.2). This prefix | |||
| contains table offset information that establishes total ordering | contains table offset information that establishes total ordering | |||
| among all headers, regardless of reordering in the transport (see | among all headers, regardless of reordering in the transport (see | |||
| Section 3.3). | Section 2.3). | |||
| In blocking mode, the prefix additionally identifies the minimum | In blocking mode, the prefix additionally identifies the minimum | |||
| state required to process any vulnerable references in the header | state required to process any vulnerable references in the header | |||
| block (see "Depends Index" in Section 3.3). The decoder keeps track | block (see "Depends Index" in Section 2.3). The decoder keeps track | |||
| of which entries have been added to its dynamic table. The stream | of which entries have been added to its dynamic table. The stream | |||
| for a header with BLOCKING flag set is considered blocked by the | for a header with BLOCKING flag set is considered blocked by the | |||
| decoder and can not be processed until all entries in the range "[1, | decoder and can not be processed until all entries in the range "[1, | |||
| Depends Index]" have been added. While blocked, header field data | Depends Index]" have been added. While blocked, header field data | |||
| MUST remain in the blocked stream's flow control window. | MUST remain in the blocked stream's flow control window. | |||
| 2. HTTP over QUIC mapping extensions | 2. HPACK extensions | |||
| 2.1. HEADERS and PUSH_PROMISE | ||||
| HEADERS and PUSH_PROMISE frames define a new flag. | ||||
| BLOCKING (0x01): Indicates the stream might need to wait for | ||||
| dependent headers before processing. If 0, the frame can be | ||||
| processed immediately upon receipt. | ||||
| HEADERS frames can be sent on the Connection Control Stream as well | ||||
| as on request / push streams. The value of BLOCKING MUST be 0 for | ||||
| HEADERS frames on the Connection Control Stream, since they can only | ||||
| depend on previous HEADERS on the same stream. | ||||
| 2.2. HEADER_ACK | ||||
| The HEADER_ACK frame (type=0x8) is sent from the decoder to the | ||||
| encoder on the Control Stream when the decoder has fully processed a | ||||
| header block. It is used by the encoder to determine whether | ||||
| subsequent indexed representations that might reference that block | ||||
| are vulnerable to HoL blocking, and to prevent eviction races (see | ||||
| Section 3.4). | ||||
| The HEADER_ACK frame indicates the stream on which the header block | ||||
| was processed by encoding the Stream ID as a variable-length integer. | ||||
| The same Stream ID can be identified multiple times, as multiple | ||||
| header-containing blocks can be sent on a single stream in the case | ||||
| of intermediate responses, trailers, pushed requests, etc. as well as | ||||
| on the Control Streams. Since header frames on each stream are | ||||
| received and processed in order, this gives the encoder precise | ||||
| feedback on which header blocks within a stream have been fully | ||||
| processed. | ||||
| 0 1 2 3 4 5 6 7 | ||||
| +---+---+---+---+---+---+---+---+ | ||||
| | Stream ID [i] | | ||||
| +---+---------------------------+ | ||||
| HEADER_ACK frame | ||||
| The HEADER_ACK frame does not define any flags. | ||||
| 3. HPACK extensions | ||||
| 3.1. Allowed Instructions | 2.1. Allowed Instructions | |||
| HEADERS frames on the Control Stream SHOULD contain only Literal with | HEADERS frames on the Control Stream SHOULD contain only Literal with | |||
| Incremental Indexing and Indexed with Duplication (see Section 3.5) | Incremental Indexing and Indexed with Duplication (see Section 2.5) | |||
| representations. Frames on this stream modify the dynamic table | representations. Frames on this stream modify the dynamic table | |||
| state without generating output to any particular request. | state without generating output to any particular request. | |||
| HEADERS and PUSH_PROMISE frames on request and push streams MUST NOT | HEADERS and PUSH_PROMISE frames on request and push streams MUST NOT | |||
| contain Literal with Incremental Indexing and Indexed with | contain Literal with Incremental Indexing and Indexed with | |||
| Duplication representations. Frames on these streams reference the | Duplication representations. Frames on these streams reference the | |||
| dynamic table in a particular state without modifying it, but emit | dynamic table in a particular state without modifying it, but emit | |||
| the headers for an HTTP request or response. | the headers for an HTTP request or response. | |||
| 3.2. Header Block Prefix | 2.2. Header Block Prefix | |||
| For request and push promise streams, in HEADERS and PUSH_PROMISE | For request and push promise streams, in HEADERS and PUSH_PROMISE | |||
| frames, HPACK Header data is prefixed by an integer: "Base Index". | frames, HPACK Header data is prefixed by an integer: "Base Index". | |||
| "Base index" is the cumulative number of entries added to the dynamic | "Base index" is the cumulative number of entries added to the dynamic | |||
| table prior to encoding the current block, including any entries | table prior to encoding the current block, including any entries | |||
| already evicted. It is encoded as a single 8-bit prefix integer: | already evicted. It is encoded as a single 8-bit prefix integer: | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+ | |||
| |Base Index (8+)| | |Base Index (8+)| | |||
| +---------------+ | +---------------+ | |||
| Figure 1: Absolute indexing (BLOCKING=0x0) | Figure 1: Absolute indexing (BLOCKING=0x0) | |||
| Section 3.3 describes the role of "Base Index". | Section 2.3 describes the role of "Base Index". | |||
| When the BLOCKING flag is 0x1, a the prefix additionally contains a | When the BLOCKING flag is 0x1, a the prefix additionally contains a | |||
| second HPACK integer (8-bit prefix) 'Depends': | second HPACK integer (8-bit prefix) 'Depends': | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+ | |||
| |Base Index (8+)| | |Base Index (8+)| | |||
| +---------------+ | +---------------+ | |||
| |Depends (8+)| | |Depends (8+)| | |||
| +---------------+ | +---------------+ | |||
| Figure 2: Absolute indexing (BLOCKING=0x1) | Figure 2: Absolute indexing (BLOCKING=0x1) | |||
| Depends is used to identify header dependencies (see Section 1.2). | Depends is used to identify header dependencies (see Section 1.2). | |||
| The encoder computes a value "Depends Index" which is the largest | The encoder computes a value "Depends Index" which is the largest | |||
| (absolute) index referenced by the following header block. To help | (absolute) index referenced by the following header block. To help | |||
| keep the prefix smaller, "Depends Index" is converted to a relative | keep the prefix smaller, "Depends Index" is converted to a relative | |||
| value: "Depends = Base Index - Depends Index". | value: "Depends = Base Index - Depends Index". | |||
| 3.3. Hybrid absolute-relative indexing | 2.3. Hybrid absolute-relative indexing | |||
| HPACK indexed entries refer to an entry by its current position in | HPACK indexed entries refer to an entry by its current position in | |||
| the dynamic table. As Figure 1 of [RFC7541] illustrates, newer | the dynamic table. As Figure 1 of [RFC7541] illustrates, newer | |||
| entries have smaller indices, and older entries are evicted first if | entries have smaller indices, and older entries are evicted first if | |||
| the table is full. Under this scheme, each insertion to the table | the table is full. Under this scheme, each insertion to the table | |||
| causes the index of all existing entries to change (implicitly). | causes the index of all existing entries to change (implicitly). | |||
| Implicit index updates are acceptable for HTTP/2 because TCP is | Implicit index updates are acceptable for HTTP/2 because TCP is | |||
| totally ordered, but are problematic in the out-of-order context of | totally ordered, but are problematic in the out-of-order context of | |||
| QUIC. | QUIC. | |||
| skipping to change at page 7, line 4 ¶ | skipping to change at page 6, line 9 ¶ | |||
| Implicit index updates are acceptable for HTTP/2 because TCP is | Implicit index updates are acceptable for HTTP/2 because TCP is | |||
| totally ordered, but are problematic in the out-of-order context of | totally ordered, but are problematic in the out-of-order context of | |||
| QUIC. | QUIC. | |||
| QCRAM uses a hybrid absolute-relative indexing approach. | QCRAM uses a hybrid absolute-relative indexing approach. | |||
| When the encoder adds a new entry to its header table, it can compute | When the encoder adds a new entry to its header table, it can compute | |||
| an absolute index: | an absolute index: | |||
| "entry.absoluteIndex = baseIndex++;" | "entry.absoluteIndex = baseIndex++;" | |||
| Since literals with indexing are only sent on the control stream, the | Since literals with indexing are only sent on the control stream, the | |||
| decoder can be guaranteed to compute the same absolute index values | decoder can be guaranteed to compute the same absolute index values | |||
| when it adds corresponding entries to its table, just as in HPACK and | when it adds corresponding entries to its table, just as in HPACK and | |||
| HTTP/2. | HTTP/2. | |||
| When encoding indexed representations, the following holds for | When encoding indexed representations, the following holds for | |||
| (relative) HPACK indices: | (relative) HPACK indices: | |||
| "relative index = baseIndex - entry.absoluteIndex + staticTable.size" | "relative index = baseIndex - entry.absoluteIndex + staticTable.size" | |||
| Header blocks on request and push streams do not modify the dynamic | Header blocks on request and push streams do not modify the dynamic | |||
| table state, so they never change the "baseIndex". However, since | table state, so they never change the "baseIndex". However, since | |||
| ordering between streams is not guaranteed, the value of "baseIndex" | ordering between streams is not guaranteed, the value of "baseIndex" | |||
| can not be synchronized implicitly. Instead then, QCRAM sends | can not be synchronized implicitly. Instead then, QCRAM sends | |||
| encoder's "Base Index" explicitly as part of the prefix (see | encoder's "Base Index" explicitly as part of the prefix (see | |||
| Section 3.2), so that the decoder can compute the same absolute | Section 2.2), so that the decoder can compute the same absolute | |||
| indices that the encoder used: | indices that the encoder used: | |||
| "absoluteIndex = prefix.baseIndex + staticTable.size - | "absoluteIndex = prefix.baseIndex + staticTable.size - | |||
| relativeIndex;" | relativeIndex;" | |||
| In this way, even if request or push stream headers are decoded in a | In this way, even if request or push stream headers are decoded in a | |||
| different order than encoded, the absolute indices will still | different order than encoded, the absolute indices will still | |||
| identify the correct table entries. | identify the correct table entries. | |||
| It is an error if the HPACK decoder encounters an indexed | It is an error if the HPACK decoder encounters an indexed | |||
| representation that refers to an entry missing from the table, and | representation that refers to an entry missing from the table, and | |||
| the connection MUST be closed with the | the connection MUST be closed with the | |||
| "HTTP_HPACK_DECOMPRESSION_FAILED" error code. | "HTTP_HPACK_DECOMPRESSION_FAILED" error code. | |||
| 3.4. Preventing Eviction Races | 2.4. Preventing Eviction Races | |||
| Due to out-of-order arrival, QCRAM's eviction algorithm requires | Due to out-of-order arrival, QCRAM's eviction algorithm requires | |||
| changes (relative to HPACK) to avoid the possibility that an indexed | changes (relative to HPACK) to avoid the possibility that an indexed | |||
| representation is decoded after the referenced entry has already been | representation is decoded after the referenced entry has already been | |||
| evicted. QCRAM employs a two-phase eviction algorithm, in which the | evicted. QCRAM employs a two-phase eviction algorithm, in which the | |||
| encoder will not evict entries that have outstanding (unacknowledged) | encoder will not evict entries that have outstanding (unacknowledged) | |||
| references. | references. | |||
| 3.4.1. Blocked Evictions | 2.4.1. Blocked Evictions | |||
| The encoder MUST NOT permit an entry to be evicted while a reference | The encoder MUST NOT permit an entry to be evicted while a reference | |||
| to that entry remains unacknowledged. If a new header to be inserted | to that entry remains unacknowledged. If a new header to be inserted | |||
| into the dynamic table would cause the eviction of such an entry, the | into the dynamic table would cause the eviction of such an entry, the | |||
| encoder MUST NOT emit the insert instruction until the reference has | encoder MUST NOT emit the insert instruction until the reference has | |||
| been processed by the decoder and acknowledged. | been processed by the decoder and acknowledged. | |||
| The encoder can emit a literal representation for the new header in | The encoder can emit a literal representation for the new header in | |||
| order to avoid encoding delays, and MAY insert the header into the | order to avoid encoding delays, and MAY insert the header into the | |||
| table later if desired. | table later if desired. | |||
| To ensure that the blocked eviction case is rare, references to the | To ensure that the blocked eviction case is rare, references to the | |||
| oldest entries in the dynamic table SHOULD be avoided. When one of | oldest entries in the dynamic table SHOULD be avoided. When one of | |||
| the oldest entries in the table is still actively used for | the oldest entries in the table is still actively used for | |||
| references, the encoder SHOULD emit an Indexed-Duplicate | references, the encoder SHOULD emit an Indexed-Duplicate | |||
| representation instead (see Section 3.5). | representation instead (see Section 2.5). | |||
| 3.5. Refreshing Entries with Duplication | 2.5. Refreshing Entries with Duplication | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+ | |||
| |0|0|1|Index(5+)| | |0|0|1|Index(5+)| | |||
| +-+-+-+---------+ | +-+-+-+---------+ | |||
| Figure 3: Indexed Header Field with Duplication | Figure 3: Indexed Header Field with Duplication | |||
| _Indexed-Duplicates_ insert a new entry into the dynamic table which | _Indexed-Duplicates_ insert a new entry into the dynamic table which | |||
| duplicates an existing entry. [RFC7541] allows duplicate HPACK table | duplicates an existing entry. [RFC7541] allows duplicate HPACK table | |||
| entries, that is entries that have the same name and value. | entries, that is entries that have the same name and value. | |||
| This replaces the HPACK instruction for Dynamic Table Size Update | This replaces the HPACK instruction for Dynamic Table Size Update | |||
| (see Section 6.3 of [RFC7541], which is not supported by HTTP over | (see Section 6.3 of [RFC7541], which is not supported by HTTP over | |||
| QUIC. | QUIC. | |||
| 4. Performance considerations | 3. Performance considerations | |||
| 4.1. Speculative table updates | 3.1. Speculative table updates | |||
| Implementations can _speculatively_ send header frames on the HTTP | Implementations can _speculatively_ send header frames on the HTTP | |||
| Control Streams which are not needed for any current HTTP request or | Control Streams which are not needed for any current HTTP request or | |||
| response. Such headers could be used strategically to improve | response. Such headers could be used strategically to improve | |||
| performance. For instance, the encoder might decide to _refresh_ by | performance. For instance, the encoder might decide to _refresh_ by | |||
| sending Indexed-Duplicate representations for popular header fields | sending Indexed-Duplicate representations for popular header fields | |||
| (Section 3.2), ensuring they have small indices and hence minimal | (Section 2.2), ensuring they have small indices and hence minimal | |||
| size on the wire. | size on the wire. | |||
| 4.2. Additional state beyond HPACK. | 3.2. Additional state beyond HPACK. | |||
| 4.2.1. Vulnerable Entries | 3.2.1. Vulnerable Entries | |||
| For header blocks encoded in non-blocking mode, the encoder needs to | For header blocks encoded in non-blocking mode, the encoder needs to | |||
| forego indexed representations that refer to vulnerable entries (see | forego indexed representations that refer to vulnerable entries (see | |||
| Section 1.2). An implementation could extend the header table entry | Section 1.2). An implementation could extend the header table entry | |||
| with a boolean to track vulnerability. However, the number of | with a boolean to track vulnerability. However, the number of | |||
| entries in the table that are vulnerable is likely to be small in | entries in the table that are vulnerable is likely to be small in | |||
| practice, much less than the total number of entries, so a data | practice, much less than the total number of entries, so a data | |||
| tracking only vulnerable (un-acknowledged) entries, separate from the | tracking only vulnerable (un-acknowledged) entries, separate from the | |||
| main header table, might be more space efficient. | main header table, might be more space efficient. | |||
| 4.2.2. Safe evictions | 3.2.2. Safe evictions | |||
| Section Section 3.4 describes how QCRAM avoids invalid references | Section Section 2.4 describes how QCRAM avoids invalid references | |||
| that might result from out-of-order delivery. When the encoder | that might result from out-of-order delivery. When the encoder | |||
| processes a HEADER_ACK, it dereferences table entries that were | processes a HEADER_ACK, it dereferences table entries that were | |||
| indexed in the acknowledged header. To track which entries must be | indexed in the acknowledged header. To track which entries must be | |||
| dereferenced, it can maintain a map from unacknowledged headers to | dereferenced, it can maintain a map from unacknowledged headers to | |||
| lists of (absolute) indices. The simplest place to store the actual | lists of (absolute) indices. The simplest place to store the actual | |||
| reference count might be the table entries. In practice the number | reference count might be the table entries. In practice the number | |||
| of entries in the table with a non-zero reference count is likely to | of entries in the table with a non-zero reference count is likely to | |||
| stay quite small. A data structure tracking only entries with non- | stay quite small. A data structure tracking only entries with non- | |||
| zero reference counts, separate from the main header table, could be | zero reference counts, separate from the main header table, could be | |||
| more space efficient. | more space efficient. | |||
| 4.2.3. Decoder Blocking | 3.2.3. Decoder Blocking | |||
| To support blocking, the decoder needs to keep track of entries it | To support blocking, the decoder needs to keep track of entries it | |||
| has added to the dynamic table (see Section 1.2), and it needs to | has added to the dynamic table (see Section 1.2), and it needs to | |||
| track blocked streams. | track blocked streams. | |||
| Tracking added entries might be done in a brute force fashion without | Tracking added entries might be done in a brute force fashion without | |||
| additional space. However, this would have O(N) cost where N is the | additional space. However, this would have O(N) cost where N is the | |||
| number of entries in the dynamic table. Alternatively, a dedicated | number of entries in the dynamic table. Alternatively, a dedicated | |||
| data structure might improve on brute force in exchange a small | data structure might improve on brute force in exchange a small | |||
| amount of additional space. For example, a set of pairs (of | amount of additional space. For example, a set of pairs (of | |||
| indices), representing non-overlapping sub-ranges can be used. Each | indices), representing non-overlapping sub-ranges can be used. Each | |||
| operation (add, or query) can be done within O(log M) complexity. | operation (add, or query) can be done within O(log M) complexity. | |||
| Here set size M is the number of sub-ranges. In practice M would be | Here set size M is the number of sub-ranges. In practice M would be | |||
| very small, as most table entries would be concentrated in the first | very small, as most table entries would be concentrated in the first | |||
| sub-range [1, M]. | sub-range "[1,M]". | |||
| To track blocked streams, an ordered map (e.g. multi-map) from | To track blocked streams, an ordered map (e.g. multi-map) from | |||
| "Depends Index" values to streams can be used. Whenever the decoder | "Depends Index" values to streams can be used. Whenever the decoder | |||
| processes a header block, it can drain any members of the blocked | processes a header block, it can drain any members of the blocked | |||
| streams map that have "Depends Index <= M" where "[1,M]" is the first | streams map that have "Depends Index <= M" where "[1,M]" is the first | |||
| member of the added- entries sub-ranges set. Again, the complexity | member of the added- entries sub-ranges set. Again, the complexity | |||
| of operations would be at most O(log N), N being the number of | of operations would be at most O(log N), N being the number of | |||
| concurrently blocked streams. | concurrently blocked streams. | |||
| 4.2.4. Fixed overhead. | 3.2.4. Fixed overhead. | |||
| HPACK defines overhead as 32 bytes ([RFC7541] Section 4.1). As | HPACK defines overhead as 32 bytes ([RFC7541], Section 4.1). As | |||
| described above, QCRAM adds some per-connection state, and possibly | described above, QCRAM adds some per-connection state, and possibly | |||
| some per-entry state to track acknowledgment status and eviction | some per-entry state to track acknowledgment status and eviction | |||
| reference count. A larger value than 32 might be more accurate for | reference count. A larger value than 32 might be more accurate for | |||
| QCRAM. | QCRAM. | |||
| 5. Security Considerations | 4. Security Considerations | |||
| TBD. | TBD. | |||
| 6. IANA Considerations | 5. IANA Considerations | |||
| This document registers a new frame type, HEADER_ACK, for HTTP/QUIC. | This document registers a new frame type, HEADER_ACK, for HTTP/QUIC. | |||
| This will need to be added to the IANA Considerations of [QUIC-HTTP]. | This will need to be added to the IANA Considerations of [QUIC-HTTP]. | |||
| 7. Acknowledgments | 6. References | |||
| This draft draws heavily on the text of [RFC7541]. The indirect | ||||
| input of those authors is gratefully acknowledged, as well as ideas | ||||
| from: | ||||
| o Mike Bishop | ||||
| o Alan Frindell | ||||
| o Ryan Hamilton | ||||
| o Patrick McManus | ||||
| o Kazuho Oku | ||||
| o Biren Roy | ||||
| o Ian Swett | ||||
| o Dmitri Tikhonov | ||||
| 8. References | ||||
| 8.1. Normative References | 6.1. Normative References | |||
| [QUIC-HTTP] | [QUIC-HTTP] | |||
| Bishop, M., "Hypertext Transfer Protocol (HTTP) over | Bishop, M., "HTTP/3", draft-ietf-quic-http-34 (work in | |||
| QUIC", draft-ietf-quic-http-09 (work in progress), January | progress), February 2021. | |||
| 2018. | ||||
| [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | |||
| HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | |||
| <https://www.rfc-editor.org/info/rfc7541>. | <https://www.rfc-editor.org/info/rfc7541>. | |||
| 8.2. Informative References | 6.2. Informative References | |||
| [QUIC-TRANSPORT] | [QUIC-TRANSPORT] | |||
| Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed | Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed | |||
| and Secure Transport", draft-ietf-quic-transport-09 (work | and Secure Transport", draft-ietf-quic-transport-34 (work | |||
| in progress), January 2018. | in progress), January 2021. | |||
| [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | |||
| Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | |||
| DOI 10.17487/RFC7540, May 2015, | DOI 10.17487/RFC7540, May 2015, | |||
| <https://www.rfc-editor.org/info/rfc7540>. | <https://www.rfc-editor.org/info/rfc7540>. | |||
| 6.3. URIs | ||||
| [1] https://mailarchive.ietf.org/arch/search/?email_list=quic | ||||
| [2] https://github.com/quicwg | ||||
| [3] https://github.com/quicwg/base-drafts/labels/-qcram | ||||
| Acknowledgments | ||||
| This draft draws heavily on the text of [RFC7541]. The indirect | ||||
| input of those authors is gratefully acknowledged, as well as ideas | ||||
| from: | ||||
| o Ryan Hamilton | ||||
| o Patrick McManus | ||||
| o Kazuho Oku | ||||
| o Biren Roy | ||||
| o Ian Swett | ||||
| o Dmitri Tikhonov | ||||
| Authors' Addresses | Authors' Addresses | |||
| Charles 'Buck' Krasic | Charles 'Buck' Krasic | |||
| Google, Inc | Google, Inc | |||
| Email: ckrasic@google.com | Email: ckrasic@google.com | |||
| Mike Bishop | Mike Bishop | |||
| Akamai Technologies | Akamai Technologies | |||
| End of changes. 44 change blocks. | ||||
| 141 lines changed or deleted | 103 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/ | ||||