idnits 2.17.1 draft-bishop-quic-http-and-qpack-05.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([RFC7540], [RFC7541], [I-D.ietf-quic-transport]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document seems to lack the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. (The document does seem to have the reference to RFC 2119 which the ID-Checklist requires). -- The document date (September 26, 2017) is 2403 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Outdated reference: A later version (-34) exists of draft-ietf-quic-http-06 == Outdated reference: A later version (-34) exists of draft-ietf-quic-transport-06 ** Obsolete normative reference: RFC 7540 (Obsoleted by RFC 9113) Summary: 2 errors (**), 0 flaws (~~), 4 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 QUIC Working Group M. Bishop 3 Internet-Draft Microsoft 4 Intended status: Standards Track September 26, 2017 5 Expires: March 30, 2018 7 Header Compression for HTTP/QUIC 8 draft-bishop-quic-http-and-qpack-05 10 Abstract 12 HTTP/2 [RFC7540] uses HPACK [RFC7541] for header compression. 13 However, HPACK relies on the in-order message-based semantics of the 14 HTTP/2 framing layer in order to function. Messages can only be 15 successfully decoded if processed by the decoder in the same order as 16 generated by the encoder. This draft refines HPACK to loosen the 17 ordering requirements for use over QUIC [I-D.ietf-quic-transport]. 19 Status of This Memo 21 This Internet-Draft is submitted in full conformance with the 22 provisions of BCP 78 and BCP 79. 24 Internet-Drafts are working documents of the Internet Engineering 25 Task Force (IETF). Note that other groups may also distribute 26 working documents as Internet-Drafts. The list of current Internet- 27 Drafts is at http://datatracker.ietf.org/drafts/current/. 29 Internet-Drafts are draft documents valid for a maximum of six months 30 and may be updated, replaced, or obsoleted by other documents at any 31 time. It is inappropriate to use Internet-Drafts as reference 32 material or to cite them other than as "work in progress." 34 This Internet-Draft will expire on March 30, 2018. 36 Copyright Notice 38 Copyright (c) 2017 IETF Trust and the persons identified as the 39 document authors. All rights reserved. 41 This document is subject to BCP 78 and the IETF Trust's Legal 42 Provisions Relating to IETF Documents 43 (http://trustee.ietf.org/license-info) in effect on the date of 44 publication of this document. Please review these documents 45 carefully, as they describe your rights and restrictions with respect 46 to this document. Code Components extracted from this document must 47 include Simplified BSD License text as described in Section 4.e of 48 the Trust Legal Provisions and are provided without warranty as 49 described in the Simplified BSD License. 51 Table of Contents 53 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 54 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3 55 2. QPACK . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 56 2.1. Basic model . . . . . . . . . . . . . . . . . . . . . . . 3 57 2.2. Changes to Static and Dynamic Tables . . . . . . . . . . 4 58 2.2.1. Changes to Header Table Size . . . . . . . . . . . . 4 59 2.2.2. Dynamic Table State Synchronization . . . . . . . . . 5 60 2.3. Header Management Streams . . . . . . . . . . . . . . . . 6 61 2.3.1. Insert . . . . . . . . . . . . . . . . . . . . . . . 6 62 2.3.2. Delete . . . . . . . . . . . . . . . . . . . . . . . 7 63 2.3.3. Delete-Ack . . . . . . . . . . . . . . . . . . . . . 10 64 2.4. Format of Encoded Headers on Message Streams . . . . . . 10 65 2.4.1. Indexed Header Field Representation . . . . . . . . . 10 66 2.4.2. Literal Header Field Representation . . . . . . . . . 11 67 3. Use in HTTP/QUIC . . . . . . . . . . . . . . . . . . . . . . 12 68 4. Implementation trade-offs . . . . . . . . . . . . . . . . . . 12 69 4.1. Compression Efficiency versus Blocking Avoidance . . . . 13 70 4.2. Timely Delete Completion versus State Commitment . . . . 13 71 5. Security Considerations . . . . . . . . . . . . . . . . . . . 14 72 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 73 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 14 74 8. Normative References . . . . . . . . . . . . . . . . . . . . 15 75 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 15 77 1. Introduction 79 HPACK has a number of features that were intended to provide 80 performance advantages to HTTP/2, but which don't live well in an 81 out-of-order environment such as that provided by QUIC. 83 The largest challenge is the fact that elements are referenced by a 84 very fluid index. Not only is the index implicit when an item is 85 added to the header table, the index will change without notice as 86 other items are added to the header table. Static entries occupy the 87 first 61 values, followed by dynamic entries. A newly-added dynamic 88 entry would cause older dynamic entries to be evicted, and the 89 retained items are then renumbered beginning with 62. This means 90 that, without processing all preceding header sets, no index into the 91 dynamic table can be interpreted, and the index of a given entry 92 cannot be predicted. 94 Any solution to the above will almost certainly fall afoul of the 95 memory constraints the decompressor imposes. The automatic eviction 96 of entries is done based on the compressor's declared dynamic table 97 size, which MUST be less than the maximum permitted by the 98 decompressor (and relayed using an HTTP/2 SETTINGS value). 100 Further, streams in QUIC are lossy in the presence of stream resets. 101 While HTTP/2 (via TCP) guarantees the delivery of all previously-sent 102 data on a stream even if that stream is reset, QUIC does not 103 retransmit lost frames if a stream has been reset, and may discard 104 data which has not yet been delivered to the application. 106 Previous versions of QPACK were small deltas of HPACK to introduce 107 order-resiliency. This version departs from HPACK more substantially 108 to add resilience against reset message streams. 110 In the following sections, this document proposes a new version of 111 HPACK which makes different trade-offs, enabling partial out-of-order 112 interpretation and bounded memory consumption with minimal head-of- 113 line blocking. None of the proposed improvements to HPACK (strongly- 114 typed fields, binary compression of common header syntax) are 115 currently included, but certainly could be. 117 1.1. Terminology 119 In this document, the key words "MUST", "MUST NOT", "REQUIRED", 120 "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 121 and "OPTIONAL" are to be interpreted as described in BCP 14, 122 [RFC2119] and indicate requirement levels for compliant 123 implementations. 125 2. QPACK 127 2.1. Basic model 129 HPACK combines header table modification and message header emission 130 in a single sequence of coded bytes. QPACK bifurcates these into two 131 channels: 133 o Connection-wide sets of table update instructions sent on non- 134 request streams 136 o Non-modifying instructions which use the current header table 137 state to encode message headers on request streams 139 Because the per-message instructions introduce no changes to the 140 header table state, no state is lost if these instructions are 141 discarded due to a stream reset. Because the updates to the header 142 table supply their own order controls (the delete logic), they can be 143 processed in any order and therefore delivered as messages using 144 unidirectional QUIC streams. 146 2.2. Changes to Static and Dynamic Tables 148 QPACK uses two tables for associating header fields to indexes. The 149 static table is unchanged from [RFC7541]. Unlike in [RFC7541], the 150 tables are not concatenated, but are referenced separately. 152 The dynamic table is a map from index to header field. Indices are 153 arbitrary numbers between 1 and 2^27. Each insert instruction will 154 specify the index being modified. While any index MAY be chosen for 155 a new entry, smaller numbers will yield better compression 156 performance. 158 The dynamic table is still constrained to the size specified by the 159 decoder. An attempt to add a header to the dynamic table which 160 causes it to exceed the maximum size MUST be treated as an error by a 161 decoder. To enable encoders to reclaim space, encoders can delete 162 entries in the dynamic table, but can only reuse the index or the 163 space after receiving confirmation of a successful deletion. 165 Because it is possible for QPACK frames to arrive which reference 166 indices which have not yet been defined, such frames MUST wait until 167 another frame has arrived and defined the index. In order to guard 168 against malicious peers, implementations SHOULD impose a time limit 169 and treat expiration of the timer as a decoding error. 171 2.2.1. Changes to Header Table Size 173 HTTP/QUIC prohibits mid-stream changes of settings. As a result, 174 only one table size change is possible: From the value a client 175 assumes during the 0-RTT flight to the actual value included in the 176 server's SETTINGS frame. The assumed value is required to be either 177 a server's previous value or zero. A server whose configuration has 178 recently changed MAY overlook inadvertent violations of its maximum 179 table size during the first round-trip. 181 In the case that the value has increased, either from zero to a non- 182 zero value or from the cached value to a higher value, no action is 183 required by the client. The encoder can simply begin using the 184 additional space. In the case that the value has decreased, the 185 encoder MUST immediately emit delete instructions which, upon 186 completion, would bring the table within the required size. 188 Regardless of changes to header table size, the encoder MUST NOT add 189 entries to the table which would result in a size greater than the 190 maximum permitted. This can imply that no additions are permitted 191 while waiting for these delete instructions to complete. 193 2.2.2. Dynamic Table State Synchronization 195 In order to ensure table consistency, all modifications of the header 196 table occur as separate messages rather than on request streams. 197 Request streams contain only indexed and literal header entries. 199 No entries are automatically evicted from the dynamic table. Size 200 management is purely the responsibility of the encoder, which MUST 201 NOT exceed the declared memory size of the decoder. 203 The encoder SHOULD track the following information about each entry 204 in the table: 206 o The list of recently-active streams which reference the entry in a 207 trailer block, if any 209 o The list of recently-active streams which reference the entry in a 210 non-trailer block, if any 212 "Recently-active" streams are those which are still open or were 213 closed less than a reasonable number of RTTs ago. An implementation 214 MAY vary its definition of "recent" to trade off memory consumption 215 and timely completion of deletes, and tracking no information is a 216 functional (though potentially less performant) choice in this space. 218 The encoder MUST consider memory as committed beginning when the 219 indexed entry is assigned. 221 When the encoder wishes to delete an inserted value, it flows through 222 the following set of states: 224 1. *Delete requested.* The encoder emits a delete instruction 225 indicating which streams might have referenced the entry. The 226 encoder MUST NOT reference the entry in any subsequent frame 227 until this state machine has completed and MUST continue to 228 include the entry in its calculation of consumed memory. 230 2. *Delete pending.* The decoder receives the delete instruction and 231 checks the current state of its incoming streams (see 232 Section 2.3.2.2). If more references might arrive, it stores the 233 streams still needed and waits for them to complete. 235 3. *Delete acknowledged.* The decoder has received all QPACK frames 236 which reference the deleted value, and can safely delete the 237 entry. The decoder SHOULD promptly emit a Delete-Ack instruction 238 on a header management stream. 240 4. *Delete completed.* When the encoder receives a Delete-Ack 241 instruction acknowledging the delete, it no longer counts the 242 size of the deleted entry against the table size and MAY emit 243 insert instructions for the field with a new value. 245 2.3. Header Management Streams 247 Header management streams are unidirectional streams in either 248 direction which contain a series of QPACK instructions with no 249 message boundaries. Data on these streams SHOULD be processed as 250 soon as it arrives. 252 This section describes the instructions which are possible on header 253 management streams. 255 2.3.1. Insert 257 An addition to the header table starts with the '1' one-bit pattern, 258 followed by the new index of the header represented as an integer 259 with a 7-bit prefix. This value is always greater than the number of 260 entries in the static table. 262 If the header field name matches the header field name of an entry 263 stored in the static table or the dynamic table, the header field 264 name can be represented using the index of that entry. In this case, 265 the "S" bit indicates whether the reference is to the static (S=1) or 266 dynamic (S=0) table and the index of the entry is represented as an 267 integer with an 7-bit prefix (see Section 5.1 of [RFC7541]). This 268 value is always non-zero. 270 0 1 2 3 4 5 6 7 271 +---+---+---+---+---+---+---+---+ 272 | 1 | New Index (7+) | 273 +---+---+-----------------------+ 274 | S | Name Index (7+) | 275 +---+---------------------------+ 276 | H | Value Length (7+) | 277 +---+---------------------------+ 278 | Value String (Length octets) | 279 +-------------------------------+ 281 Insert Header Field -- Indexed Name 283 Otherwise, the header field name is represented as a string literal 284 (see Section 5.2 of [RFC7541]). A value 0 is used in place of the 285 table reference, followed by the header field name. 287 0 1 2 3 4 5 6 7 288 +---+---+---+---+---+---+---+---+ 289 | 1 | New Index (7+) | 290 +---+---+-----------------------+ 291 | 0 | 292 +---+---+-----------------------+ 293 | H | Name Length (7+) | 294 +---+---------------------------+ 295 | Name String (Length octets) | 296 +---+---------------------------+ 297 | H | Value Length (7+) | 298 +---+---------------------------+ 299 | Value String (Length octets) | 300 +-------------------------------+ 302 Insert Header Field -- New Name 304 Either form of header field name representation is followed by the 305 header field value represented as a string literal (see Section 5.2 306 of [RFC7541]). 308 An encoder MUST NOT attempt to place a value at an index not known to 309 be vacant. A decoder MUST treat the attempt to insert into an 310 occupied slot as a fatal error. 312 2.3.2. Delete 314 A deletion from the header table starts with the '00' two bit 315 pattern, followed by the index of the affected entry in the dynamic 316 table represented as an integer with a 6-bit prefix. 318 A delete instruction then encodes a series of stream IDs which might 319 have contained references to the entry in question. 321 0 1 2 3 4 5 6 7 322 +---+---+---+---+---+---+---+---+ 323 | 0 | 0 | Index (6+) | 324 +---+---+-----------------------+ 325 | Non-Trailer List (*) ... 326 +-------------------------------+ 327 | Trailer List (*) ... 328 +-------------------------------+ 330 Delete Instruction 332 Both the Non-Trailer List and Trailer List are Stream ID Lists (see 333 below) encoding a list of streams which might have referenced the 334 entry either in non-trailer or trailer blocks. 336 2.3.2.1. Stream ID List 338 A Stream ID List encodes a sequence of stream IDs in two parts: 339 First, a Horizon value indicates the first non-occurrence about which 340 data is maintained. If data is maintained from the beginning of the 341 connection, the Horizon is zero. This allows senders to succinctly 342 express both old state which has been discarded and large regions 343 where many or all streams contain references. 345 Following the horizon, a sequence of deltas indicates all streams 346 since the Horizon on which a value has been used. 348 This structure permits either side to adjust the amount of tracking 349 complexity it is willing to devote to ensure timely deletions. In 350 the simplest case, a Stream ID List might be a horizon value followed 351 by one zero byte. This indicates an absolute cut-off after which the 352 entry is guaranteed not to be referenced, and requires the receiver 353 to wait until all prior requests have been completed. Similarly, the 354 receiver can create equivalent-but-less-complex forms of a Stream ID 355 list by increasing the Horizon value and discarding all explicit 356 stream entries less than the new value. 358 0 1 2 3 4 5 6 7 359 +-------------------------------+ 360 | Horizon (8+) | 361 +-------------------------------+ 362 | NumEntries (8+) | 363 +-------------------------------+ 364 | [Delta1 (8+)] | 365 +-------------------------------+ 366 | [Delta2 (8+)] | 367 +-------------------------------+ 368 ... 369 +-------------------------------+ 370 | [DeltaN (8+)] | 371 +-------------------------------+ 373 Stream ID List 375 The field are as follows: 377 Horizon: The ID of the first stream for which the sender retains 378 state which does not reference the deleted entry in the indicated 379 block 381 NumEntries: The number of streams greater than the Horizon which 382 might reference the entry and are listed in the remainder of the 383 instruction 385 Delta1..N: A sequence of streams greater than the Horizon which 386 might reference the entry, encoded as the difference in stream 387 number from the previously-listed stream. This field is repeated 388 NumEntries times. 390 2.3.2.2. Delete Validation 392 In order to safely delete an entry, a decoder MUST ensure that all 393 outstanding references have arrived and been processed. Because no 394 data is available about stream IDs less than the Horizon, a decoder 395 MUST assume that any earlier stream ID might have contained a 396 reference to the value in question. 398 A decoder can ensure all outstanding references have been processed 399 by verifying that the following statements are true: 401 o In the Non-Trailer Block, all streams less than the Horizon and 402 all streams explicitly listed are in one of two states: 404 * closed 406 * headers completely processed 408 o In the Trailer Block, all streams less than the Horizon and all 409 streams explicitly listed are in one of three states: 411 * closed 413 * headers completely processed AND no trailers are expected 415 * trailers completely processed 417 An implementation MAY omit the "trailers completely processed" case, 418 since the stream is expected to close immediately after receipt of 419 the trailers block. 421 If these conditions are not met upon receipt of a Delete instruction, 422 a decoder MUST wait to emit a Delete-Ack instruction until the 423 outstanding streams have reached an appropriate state. 425 Note that a decoder MAY condense the list of specified streams by 426 increasing the Horizon value and discarding those explicitly-listed 427 stream IDs which are less than the new Horizon it has chosen. This 428 delays delete completion, but reduces the amount of state to be 429 tracked by the decoder without changing the correctness of the 430 requirements above. 432 2.3.3. Delete-Ack 434 Confirmation that a delete has completed is expressed by an 435 instruction which starts with the '01' two-bit pattern, followed by 436 the index of the affected dynamic table entry represented as an 437 integer with a 6-bit prefix. 439 Note that unlike all other instructions, this instruction refers to 440 the receiver's dynamic table, not the sender's. 442 0 1 2 3 4 5 6 7 443 +---+---+---+---+---+---+---+---+ 444 | 0 | 1 | Index (6+) | 445 +---+---+-----------------------+ 447 Delete-Ack Instruction 449 This instruction MUST NOT be sent before the conditions described in 450 Section 2.3.2.2 have been satisfied, and SHOULD be sent as soon as 451 possible once they are. 453 2.4. Format of Encoded Headers on Message Streams 455 Frames which carry HTTP message headers encode them using the 456 following instructions: 458 2.4.1. Indexed Header Field Representation 460 An indexed header field representation identifies an entry in either 461 the static table or the dynamic table and causes that header field to 462 be added to the decoded header list, as described in Section 3.2 of 463 [RFC7541]. 465 0 1 2 3 4 5 6 7 466 +---+---+---+---+---+---+---+---+ 467 | 1 | S | Index (6+) | 468 +---+---------------------------+ 470 Indexed Header Field 472 An indexed header field starts with the '1' 1-bit pattern, followed 473 by the "S" bit indicating whether the reference is into the static 474 (S=1) or dynamic (S=0) table. Finally, the index of the matching 475 header field is represented as an integer with a 6-bit prefix (see 476 Section 5.1 of [RFC7541]). 478 The index value of 0 is not used. It MUST be treated as a decoding 479 error if found in an indexed header field representation. 481 2.4.2. Literal Header Field Representation 483 A literal header field representation starts with the '0' 1-bit 484 pattern and causes a header field to be added the decoded header 485 list. 487 The second bit, 'N', indicates whether an intermediary is permitted 488 to add this header to the dynamic header table on subsequent hops. 489 When the 'N' bit is set, the encoded header MUST always be encoded 490 with this specific literal representation. In particular, when a 491 peer sends a header field that it received represented as a literal 492 header field with the 'N' bit set, it MUST use the same 493 representation to forward this header field. This bit is intended 494 for protecting header field values that are not to be put at risk by 495 compressing them (see Section 7.1 of [RFC7541] for more details). 497 If the header field name matches the header field name of an entry 498 stored in the static table or the dynamic table, the header field 499 name can be represented using the index of that entry. In this case, 500 the "S" bit indicates whether the reference is to the static (S=1) or 501 dynamic (S=0) table and the index of the entry is represented as an 502 integer with an 5-bit prefix (see Section 5.1 of [RFC7541]). This 503 value is always non-zero. 505 0 1 2 3 4 5 6 7 506 +---+---+---+---+---+---+---+---+ 507 | 0 | N | S | Name Index (5+) | 508 +---+---+-----------------------+ 509 | H | Value Length (7+) | 510 +---+---------------------------+ 511 | Value String (Length octets) | 512 +-------------------------------+ 514 Literal Header Field -- Indexed Name 516 Otherwise, the header field name is represented as a string literal 517 (see Section 5.2 of [RFC7541]). A value 0 is used in place of the 518 6-bit index, followed by the header field name. 520 0 1 2 3 4 5 6 7 521 +---+---+---+---+---+---+---+---+ 522 | 0 | N | 0 | 523 +---+---+-----------------------+ 524 | H | Name Length (7+) | 525 +---+---------------------------+ 526 | Name String (Length octets) | 527 +---+---------------------------+ 528 | H | Value Length (7+) | 529 +---+---------------------------+ 530 | Value String (Length octets) | 531 +-------------------------------+ 533 Literal Header Field -- Literal Name 535 Either form of header field name representation is followed by the 536 header field value represented as a string literal (see Section 5.2 537 of [RFC7541]). 539 3. Use in HTTP/QUIC 541 HTTP/QUIC [I-D.ietf-quic-http] currently retains the HPACK encoder/ 542 decoder from HTTP/2, using a Sequence number to enforce ordering. 543 Using QPACK instead would entail the following changes: 545 o The Sequence field is removed from HEADERS frames (Section 5.2.2) 546 and PUSH_PROMISE frames (Section 5.2.6). 548 o Header Block Fragments consist of QPACK data instead of HPACK 549 data. 551 o Just as unidirectional push streams have a stream header 552 identifying their type and Push ID, a header will need to be added 553 to differentiate header table update streams from requests and 554 pushes. 556 A HEADERS or PUSH_PROMISE frame MAY contain an arbitrary number of 557 QPACK instructions, but QPACK instructions SHOULD NOT cross a 558 boundary between successive HEADERS frames. A partial HEADERS or 559 PUSH_PROMISE frame MAY be processed upon arrival and the resulting 560 partial header set emitted or buffered according to implementation 561 requirements. 563 4. Implementation trade-offs 565 This document specifies a means for the encoder to express the 566 choices it made while encoding, but intentionally does not mandate 567 what those choices should be. In this section, potential areas for 568 implementation tuning are explored. 570 4.1. Compression Efficiency versus Blocking Avoidance 572 References to indexed entries will block if the frame containing the 573 entry definition is lost or delayed. Encoders MAY choose to trade 574 off compression efficiency and avoid blocking by using literal 575 instructions rather than referencing the dynamic table until the 576 insertion is believed to be complete. 578 The most efficient compression algorithm will reference a table entry 579 whenever it exists in the table, but risks blocking when subject to 580 packet loss or reordering. The most conservative algorithm will 581 always emit literals to guarantee that no blocking will ever occur. 582 Most implementations will choose a balance between these two 583 extremes. 585 Better efficiency while being similarly conservative can be achieved 586 by permitting references to table entries only once these entries are 587 confirmed to be present in the table. More optimization can be 588 achieved when the reference is known to be in the same packet as the 589 definition. 591 Increases in efficiency can be achieved by assuming greater risk of 592 blocking - implementations might choose a particular balance, or 593 adjust their aggressiveness based on observed network 594 characteristics. 596 Since it is possible to insert header values without emitting them on 597 a stream, an encoder MAY also proactively insert header values which 598 it believes will be needed on future requests, at the cost of reduced 599 compression efficiency for incorrect predictions. 601 The ability to split updates to the header table into discrete 602 messages reduces the possibility for head-of-line blocking within the 603 table update streams. Implementations SHOULD limit the size of table 604 update messages to avoid head-of-line blocking within these messages. 606 4.2. Timely Delete Completion versus State Commitment 608 Anything which prevent deletes from completing can prevent the 609 encoder from adding any new entries due to the maximum table size. 610 This does not block the encoder from continuing to make requests, but 611 could sharply limit compression performance. Encoders would be well- 612 served to delete entries in advance of encountering the table 613 maximum. Decoders SHOULD be prompt about emitting Delete-Ack 614 instructions to enable the encoder to recover the table space. 616 The encoder can enable deletes to complete more quickly by 617 maintaining a complete history of which streams have referenced any 618 given table entry and providing this list as part of the delete 619 instruction. The encoder can also choose to maintain less state by 620 advancing the Horizon value (see Section 2.3.2.1). This value 621 indicates the starting point of the provided history, and can be 622 advanced arbitrarily far to discard history. This comes at the 623 potential cost of a decoder taking longer to acknowledge that entries 624 have been removed, but this cost is zero if all previous requests are 625 known to have completed. Therefore, this history can be pruned 626 without performance impact by removing entries where all data is 627 known to have been successfully delivered and interpreted, if some 628 transport coordination is employed. 630 An encoder which chooses to maintain no history would simply supply a 631 Horizon value of a stream which has not yet been used, meaning that 632 deletes cannot complete until all currently-active requests have 633 completed. 635 A decoder can perform the same trade-off in the event the encoder's 636 supplied history is more state than it wishes to track. 638 5. Security Considerations 640 A malicious encoder might attempt to consume a large amount of space 641 on the decoder by opening the maximum number of streams, adding 642 entries to the table, then sending delete instructions enumerating 643 many streams in a Stream ID List. 645 To guard against such attacks, a decoder SHOULD bound its state 646 tracking by generalizing the list of streams to be tracked. This is 647 most easily achieved by advancing the Horizon to a later value and 648 discarding explicit Stream IDs to track, but can also be accomplished 649 by eliding explicit streams in ranges. This does not cause any loss 650 of consistency for deletes, but could delay completion and reduce 651 performance if done aggressively. 653 6. IANA Considerations 655 This document currently makes no request of IANA, and might not need 656 to. 658 7. Acknowledgements 660 This draft draws heavily on the text of [RFC7541]. The indirect 661 input of those authors is gratefully acknowledged, as well as ideas 662 gleefully stolen from: 664 o Jana Iyengar 666 o Patrick McManus 668 o Martin Thomson 670 o Charles 'Buck' Krasic 672 o Kyle Rose 674 8. Normative References 676 [I-D.ietf-quic-http] 677 Bishop, M., "Hypertext Transfer Protocol (HTTP) over 678 QUIC", draft-ietf-quic-http-06 (work in progress), 679 September 2017. 681 [I-D.ietf-quic-transport] 682 Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed 683 and Secure Transport", draft-ietf-quic-transport-06 (work 684 in progress), September 2017. 686 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 687 Requirement Levels", BCP 14, RFC 2119, 688 DOI 10.17487/RFC2119, March 1997, . 691 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 692 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 693 DOI 10.17487/RFC7540, May 2015, . 696 [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for 697 HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, 698 . 700 Author's Address 702 Mike Bishop 703 Microsoft 705 Email: michael.bishop@microsoft.com