| draft-ietf-quic-transport-15.txt | draft-ietf-quic-transport-16.txt | |||
|---|---|---|---|---|
| QUIC J. Iyengar, Ed. | QUIC J. Iyengar, Ed. | |||
| Internet-Draft Fastly | Internet-Draft Fastly | |||
| Intended status: Standards Track M. Thomson, Ed. | Intended status: Standards Track M. Thomson, Ed. | |||
| Expires: April 6, 2019 Mozilla | Expires: April 26, 2019 Mozilla | |||
| October 03, 2018 | October 23, 2018 | |||
| QUIC: A UDP-Based Multiplexed and Secure Transport | QUIC: A UDP-Based Multiplexed and Secure Transport | |||
| draft-ietf-quic-transport-15 | draft-ietf-quic-transport-16 | |||
| Abstract | Abstract | |||
| This document defines the core of the QUIC transport protocol. This | This document defines the core of the QUIC transport protocol. This | |||
| document describes connection establishment, packet format, | document describes connection establishment, packet format, | |||
| multiplexing, and reliability. Accompanying documents describe the | multiplexing, and reliability. Accompanying documents describe the | |||
| cryptographic handshake and loss detection. | cryptographic handshake and loss detection. | |||
| Note to Readers | Note to Readers | |||
| skipping to change at page 1, line 44 ¶ | skipping to change at page 1, line 44 ¶ | |||
| 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 April 6, 2019. | This Internet-Draft will expire on April 26, 2019. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2018 IETF Trust and the persons identified as the | Copyright (c) 2018 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 . . . . . . . . . . . . . . . . . . . . . . . . 5 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
| 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 6 | 1.1. Document Structure . . . . . . . . . . . . . . . . . . . 6 | |||
| 2.1. Notational Conventions . . . . . . . . . . . . . . . . . 7 | 1.2. Conventions and Definitions . . . . . . . . . . . . . . . 7 | |||
| 3. Versions . . . . . . . . . . . . . . . . . . . . . . . . . . 7 | 1.3. Notational Conventions . . . . . . . . . . . . . . . . . 8 | |||
| 4. Packet Types and Formats . . . . . . . . . . . . . . . . . . 8 | 2. Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 4.1. Long Header . . . . . . . . . . . . . . . . . . . . . . . 8 | 2.1. Stream Identifiers . . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2. Short Header . . . . . . . . . . . . . . . . . . . . . . 11 | 2.2. Stream Concurrency . . . . . . . . . . . . . . . . . . . 10 | |||
| 4.3. Version Negotiation Packet . . . . . . . . . . . . . . . 12 | 2.3. Sending and Receiving Data . . . . . . . . . . . . . . . 11 | |||
| 4.4. Retry Packet . . . . . . . . . . . . . . . . . . . . . . 14 | 2.4. Stream Prioritization . . . . . . . . . . . . . . . . . . 11 | |||
| 4.5. Cryptographic Handshake Packets . . . . . . . . . . . . . 16 | 3. Stream States: Life of a Stream . . . . . . . . . . . . . . . 12 | |||
| 4.6. Initial Packet . . . . . . . . . . . . . . . . . . . . . 17 | 3.1. Send Stream States . . . . . . . . . . . . . . . . . . . 13 | |||
| 4.6.1. Connection IDs . . . . . . . . . . . . . . . . . . . 18 | 3.2. Receive Stream States . . . . . . . . . . . . . . . . . . 15 | |||
| 4.6.2. Tokens . . . . . . . . . . . . . . . . . . . . . . . 19 | 3.3. Permitted Frame Types . . . . . . . . . . . . . . . . . . 18 | |||
| 4.6.3. Starting Packet Numbers . . . . . . . . . . . . . . . 20 | 3.4. Bidirectional Stream States . . . . . . . . . . . . . . . 18 | |||
| 4.6.4. 0-RTT Packet Numbers . . . . . . . . . . . . . . . . 20 | 3.5. Solicited State Transitions . . . . . . . . . . . . . . . 19 | |||
| 4.6.5. Minimum Packet Size . . . . . . . . . . . . . . . . . 21 | 4. Flow Control . . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
| 4.7. Handshake Packet . . . . . . . . . . . . . . . . . . . . 21 | 4.1. Handling of Stream Cancellation . . . . . . . . . . . . . 21 | |||
| 4.8. Protected Packets . . . . . . . . . . . . . . . . . . . . 22 | 4.2. Data Limit Increments . . . . . . . . . . . . . . . . . . 22 | |||
| 4.9. Coalescing Packets . . . . . . . . . . . . . . . . . . . 22 | 4.3. Stream Final Offset . . . . . . . . . . . . . . . . . . . 23 | |||
| 4.10. Connection ID Encoding . . . . . . . . . . . . . . . . . 23 | 4.4. Flow Control for Cryptographic Handshake . . . . . . . . 24 | |||
| 4.11. Packet Numbers . . . . . . . . . . . . . . . . . . . . . 24 | 4.5. Stream Limit Increment . . . . . . . . . . . . . . . . . 24 | |||
| 5. Frames and Frame Types . . . . . . . . . . . . . . . . . . . 27 | 5. Connections . . . . . . . . . . . . . . . . . . . . . . . . . 24 | |||
| 5.1. Extension Frames . . . . . . . . . . . . . . . . . . . . 30 | 5.1. Connection ID . . . . . . . . . . . . . . . . . . . . . . 24 | |||
| 6. Life of a Connection . . . . . . . . . . . . . . . . . . . . 30 | 5.1.1. Issuing Connection IDs . . . . . . . . . . . . . . . 25 | |||
| 6.1. Connection ID . . . . . . . . . . . . . . . . . . . . . . 31 | 5.1.2. Consuming and Retiring Connection IDs . . . . . . . . 26 | |||
| 6.1.1. Issuing Connection IDs . . . . . . . . . . . . . . . 31 | 5.2. Matching Packets to Connections . . . . . . . . . . . . . 27 | |||
| 6.1.2. Consuming and Retiring Connection IDs . . . . . . . . 32 | 5.2.1. Client Packet Handling . . . . . . . . . . . . . . . 27 | |||
| 6.2. Matching Packets to Connections . . . . . . . . . . . . . 32 | 5.2.2. Server Packet Handling . . . . . . . . . . . . . . . 27 | |||
| 6.2.1. Client Packet Handling . . . . . . . . . . . . . . . 33 | 5.3. Life of a QUIC Connection . . . . . . . . . . . . . . . . 28 | |||
| 6.2.2. Server Packet Handling . . . . . . . . . . . . . . . 33 | 6. Version Negotiation . . . . . . . . . . . . . . . . . . . . . 28 | |||
| 6.3. Version Negotiation . . . . . . . . . . . . . . . . . . . 34 | 6.1. Sending Version Negotiation Packets . . . . . . . . . . . 29 | |||
| 6.3.1. Sending Version Negotiation Packets . . . . . . . . . 34 | 6.2. Handling Version Negotiation Packets . . . . . . . . . . 29 | |||
| 6.3.2. Handling Version Negotiation Packets . . . . . . . . 35 | 6.3. Using Reserved Versions . . . . . . . . . . . . . . . . . 30 | |||
| 6.3.3. Using Reserved Versions . . . . . . . . . . . . . . . 35 | 7. Cryptographic and Transport Handshake . . . . . . . . . . . . 31 | |||
| 6.4. Cryptographic and Transport Handshake . . . . . . . . . . 36 | 7.1. Example Handshake Flows . . . . . . . . . . . . . . . . . 32 | |||
| 6.5. Example Handshake Flows . . . . . . . . . . . . . . . . . 37 | 7.2. Negotiating Connection IDs . . . . . . . . . . . . . . . 33 | |||
| 6.6. Transport Parameters . . . . . . . . . . . . . . . . . . 38 | 7.3. Transport Parameters . . . . . . . . . . . . . . . . . . 34 | |||
| 6.6.1. Transport Parameter Definitions . . . . . . . . . . . 41 | 7.3.1. Values of Transport Parameters for 0-RTT . . . . . . 35 | |||
| 6.6.2. Values of Transport Parameters for 0-RTT . . . . . . 43 | 7.3.2. New Transport Parameters . . . . . . . . . . . . . . 36 | |||
| 6.6.3. New Transport Parameters . . . . . . . . . . . . . . 44 | 7.3.3. Version Negotiation Validation . . . . . . . . . . . 36 | |||
| 6.6.4. Version Negotiation Validation . . . . . . . . . . . 45 | 8. Address Validation . . . . . . . . . . . . . . . . . . . . . 37 | |||
| 6.7. Stateless Retries . . . . . . . . . . . . . . . . . . . . 46 | 8.1. Address Validation During Connection Establishment . . . 38 | |||
| 6.8. Using Explicit Congestion Notification . . . . . . . . . 46 | 8.1.1. Address Validation using Retry Packets . . . . . . . 38 | |||
| 6.9. Proof of Source Address Ownership . . . . . . . . . . . . 48 | 8.1.2. Address Validation for Future Connections . . . . . . 39 | |||
| 6.9.1. Client Address Validation Procedure . . . . . . . . . 49 | 8.1.3. Address Validation Token Integrity . . . . . . . . . 41 | |||
| 6.9.2. Address Validation for Future Connections . . . . . . 50 | 8.2. Path Validation . . . . . . . . . . . . . . . . . . . . . 41 | |||
| 6.9.3. Address Validation Token Integrity . . . . . . . . . 50 | 8.3. Initiating Path Validation . . . . . . . . . . . . . . . 42 | |||
| 6.10. Path Validation . . . . . . . . . . . . . . . . . . . . . 51 | 8.4. Path Validation Responses . . . . . . . . . . . . . . . . 42 | |||
| 6.10.1. Initiation . . . . . . . . . . . . . . . . . . . . . 51 | 8.5. Successful Path Validation . . . . . . . . . . . . . . . 42 | |||
| 6.10.2. Response . . . . . . . . . . . . . . . . . . . . . . 52 | 8.6. Failed Path Validation . . . . . . . . . . . . . . . . . 43 | |||
| 6.10.3. Completion . . . . . . . . . . . . . . . . . . . . . 52 | 9. Connection Migration . . . . . . . . . . . . . . . . . . . . 43 | |||
| 6.10.4. Abandonment . . . . . . . . . . . . . . . . . . . . 53 | 9.1. Probing a New Path . . . . . . . . . . . . . . . . . . . 44 | |||
| 6.11. Connection Migration . . . . . . . . . . . . . . . . . . 53 | 9.2. Initiating Connection Migration . . . . . . . . . . . . . 45 | |||
| 6.11.1. Probing a New Path . . . . . . . . . . . . . . . . . 54 | 9.3. Responding to Connection Migration . . . . . . . . . . . 45 | |||
| 6.11.2. Initiating Connection Migration . . . . . . . . . . 54 | 9.3.1. Handling Address Spoofing by a Peer . . . . . . . . . 46 | |||
| 6.11.3. Responding to Connection Migration . . . . . . . . . 55 | 9.3.2. Handling Address Spoofing by an On-path Attacker . . 46 | |||
| 6.11.4. Loss Detection and Congestion Control . . . . . . . 56 | 9.4. Loss Detection and Congestion Control . . . . . . . . . . 47 | |||
| 6.11.5. Privacy Implications of Connection Migration . . . . 57 | 9.5. Privacy Implications of Connection Migration . . . . . . 48 | |||
| 6.12. Server's Preferred Address . . . . . . . . . . . . . . . 58 | 9.6. Server's Preferred Address . . . . . . . . . . . . . . . 49 | |||
| 6.12.1. Communicating A Preferred Address . . . . . . . . . 59 | 9.6.1. Communicating A Preferred Address . . . . . . . . . . 49 | |||
| 6.12.2. Responding to Connection Migration . . . . . . . . . 59 | 9.6.2. Responding to Connection Migration . . . . . . . . . 49 | |||
| 6.12.3. Interaction of Client Migration and Preferred | 9.6.3. Interaction of Client Migration and Preferred Address 50 | |||
| Address . . . . . . . . . . . . . . . . . . . . . . 59 | 10. Connection Termination . . . . . . . . . . . . . . . . . . . 50 | |||
| 6.13. Connection Termination . . . . . . . . . . . . . . . . . 60 | 10.1. Closing and Draining Connection States . . . . . . . . . 51 | |||
| 6.13.1. Closing and Draining Connection States . . . . . . . 60 | 10.2. Idle Timeout . . . . . . . . . . . . . . . . . . . . . . 52 | |||
| 6.13.2. Idle Timeout . . . . . . . . . . . . . . . . . . . . 61 | 10.3. Immediate Close . . . . . . . . . . . . . . . . . . . . 52 | |||
| 6.13.3. Immediate Close . . . . . . . . . . . . . . . . . . 62 | 10.4. Stateless Reset . . . . . . . . . . . . . . . . . . . . 53 | |||
| 6.13.4. Stateless Reset . . . . . . . . . . . . . . . . . . 63 | 10.4.1. Detecting a Stateless Reset . . . . . . . . . . . . 56 | |||
| 7. Frame Types and Formats . . . . . . . . . . . . . . . . . . . 67 | 10.4.2. Calculating a Stateless Reset Token . . . . . . . . 56 | |||
| 7.1. Variable-Length Integer Encoding . . . . . . . . . . . . 67 | 10.4.3. Looping . . . . . . . . . . . . . . . . . . . . . . 57 | |||
| 7.2. PADDING Frame . . . . . . . . . . . . . . . . . . . . . . 68 | 11. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 58 | |||
| 7.3. RST_STREAM Frame . . . . . . . . . . . . . . . . . . . . 68 | 11.1. Connection Errors . . . . . . . . . . . . . . . . . . . 58 | |||
| 7.4. CONNECTION_CLOSE frame . . . . . . . . . . . . . . . . . 69 | 11.2. Stream Errors . . . . . . . . . . . . . . . . . . . . . 59 | |||
| 7.5. APPLICATION_CLOSE frame . . . . . . . . . . . . . . . . . 70 | 12. Packets and Frames . . . . . . . . . . . . . . . . . . . . . 59 | |||
| 7.6. MAX_DATA Frame . . . . . . . . . . . . . . . . . . . . . 71 | 12.1. Protected Packets . . . . . . . . . . . . . . . . . . . 59 | |||
| 7.7. MAX_STREAM_DATA Frame . . . . . . . . . . . . . . . . . . 72 | 12.2. Coalescing Packets . . . . . . . . . . . . . . . . . . . 60 | |||
| 7.8. MAX_STREAM_ID Frame . . . . . . . . . . . . . . . . . . . 73 | 12.3. Packet Numbers . . . . . . . . . . . . . . . . . . . . . 61 | |||
| 7.9. PING Frame . . . . . . . . . . . . . . . . . . . . . . . 73 | 12.4. Frames and Frame Types . . . . . . . . . . . . . . . . . 62 | |||
| 7.10. BLOCKED Frame . . . . . . . . . . . . . . . . . . . . . . 74 | 13. Packetization and Reliability . . . . . . . . . . . . . . . . 65 | |||
| 7.11. STREAM_BLOCKED Frame . . . . . . . . . . . . . . . . . . 74 | 13.1. Packet Processing and Acknowledgment . . . . . . . . . . 66 | |||
| 7.12. STREAM_ID_BLOCKED Frame . . . . . . . . . . . . . . . . . 75 | 13.1.1. Sending ACK Frames . . . . . . . . . . . . . . . . . 66 | |||
| 7.13. NEW_CONNECTION_ID Frame . . . . . . . . . . . . . . . . . 75 | 13.1.2. ACK Frames and Packet Protection . . . . . . . . . . 67 | |||
| 7.14. RETIRE_CONNECTION_ID Frame . . . . . . . . . . . . . . . 77 | 13.2. Retransmission of Information . . . . . . . . . . . . . 67 | |||
| 7.15. STOP_SENDING Frame . . . . . . . . . . . . . . . . . . . 77 | 13.3. Explicit Congestion Notification . . . . . . . . . . . . 69 | |||
| 7.16. ACK Frame . . . . . . . . . . . . . . . . . . . . . . . . 78 | 13.3.1. ECN Counters . . . . . . . . . . . . . . . . . . . . 70 | |||
| 7.16.1. ACK Block Section . . . . . . . . . . . . . . . . . 79 | 13.3.2. ECN Verification . . . . . . . . . . . . . . . . . . 70 | |||
| 7.16.2. ECN section . . . . . . . . . . . . . . . . . . . . 81 | 14. Packet Size . . . . . . . . . . . . . . . . . . . . . . . . . 71 | |||
| 7.16.3. Sending ACK Frames . . . . . . . . . . . . . . . . . 82 | 14.1. Path Maximum Transmission Unit . . . . . . . . . . . . . 72 | |||
| 7.16.4. ACK Frames and Packet Protection . . . . . . . . . . 83 | 14.1.1. IPv4 PMTU Discovery . . . . . . . . . . . . . . . . 73 | |||
| 7.17. PATH_CHALLENGE Frame . . . . . . . . . . . . . . . . . . 83 | 14.2. Special Considerations for Packetization Layer PMTU | |||
| 7.18. PATH_RESPONSE Frame . . . . . . . . . . . . . . . . . . . 84 | Discovery . . . . . . . . . . . . . . . . . . . . . . . 73 | |||
| 7.19. NEW_TOKEN frame . . . . . . . . . . . . . . . . . . . . . 84 | 15. Versions . . . . . . . . . . . . . . . . . . . . . . . . . . 74 | |||
| 7.20. STREAM Frames . . . . . . . . . . . . . . . . . . . . . . 84 | 16. Variable-Length Integer Encoding . . . . . . . . . . . . . . 75 | |||
| 7.21. CRYPTO Frame . . . . . . . . . . . . . . . . . . . . . . 86 | 17. Packet Formats . . . . . . . . . . . . . . . . . . . . . . . 75 | |||
| 8. Packetization and Reliability . . . . . . . . . . . . . . . . 87 | 17.1. Packet Number Encoding and Decoding . . . . . . . . . . 76 | |||
| 8.1. Packet Processing and Acknowledgment . . . . . . . . . . 87 | 17.2. Long Header Packet . . . . . . . . . . . . . . . . . . . 77 | |||
| 8.2. Retransmission of Information . . . . . . . . . . . . . . 88 | 17.3. Short Header Packet . . . . . . . . . . . . . . . . . . 79 | |||
| 8.3. Packet Size . . . . . . . . . . . . . . . . . . . . . . . 90 | 17.4. Version Negotiation Packet . . . . . . . . . . . . . . . 81 | |||
| 8.4. Path Maximum Transmission Unit . . . . . . . . . . . . . 90 | 17.5. Initial Packet . . . . . . . . . . . . . . . . . . . . . 82 | |||
| 8.4.1. IPv4 PMTU Discovery . . . . . . . . . . . . . . . . . 91 | 17.5.1. Starting Packet Numbers . . . . . . . . . . . . . . 84 | |||
| 8.4.2. Special Considerations for Packetization Layer PMTU | 17.5.2. 0-RTT Packet Numbers . . . . . . . . . . . . . . . . 84 | |||
| Discovery . . . . . . . . . . . . . . . . . . . . . . 92 | 17.6. Handshake Packet . . . . . . . . . . . . . . . . . . . . 85 | |||
| 9. Streams: QUIC's Data Structuring Abstraction . . . . . . . . 92 | 17.7. Retry Packet . . . . . . . . . . . . . . . . . . . . . . 85 | |||
| 9.1. Stream Identifiers . . . . . . . . . . . . . . . . . . . 93 | 18. Transport Parameter Encoding . . . . . . . . . . . . . . . . 88 | |||
| 9.2. Stream States . . . . . . . . . . . . . . . . . . . . . . 94 | 18.1. Transport Parameter Definitions . . . . . . . . . . . . 90 | |||
| 9.2.1. Send Stream States . . . . . . . . . . . . . . . . . 95 | 19. Frame Types and Formats . . . . . . . . . . . . . . . . . . . 92 | |||
| 9.2.2. Receive Stream States . . . . . . . . . . . . . . . . 97 | 19.1. PADDING Frame . . . . . . . . . . . . . . . . . . . . . 93 | |||
| 9.2.3. Permitted Frame Types . . . . . . . . . . . . . . . . 99 | 19.2. RST_STREAM Frame . . . . . . . . . . . . . . . . . . . . 93 | |||
| 9.2.4. Bidirectional Stream States . . . . . . . . . . . . . 99 | 19.3. CONNECTION_CLOSE frame . . . . . . . . . . . . . . . . . 94 | |||
| 9.3. Solicited State Transitions . . . . . . . . . . . . . . . 101 | 19.4. APPLICATION_CLOSE frame . . . . . . . . . . . . . . . . 95 | |||
| 9.4. Stream Concurrency . . . . . . . . . . . . . . . . . . . 101 | 19.5. MAX_DATA Frame . . . . . . . . . . . . . . . . . . . . . 95 | |||
| 9.5. Sending and Receiving Data . . . . . . . . . . . . . . . 102 | 19.6. MAX_STREAM_DATA Frame . . . . . . . . . . . . . . . . . 96 | |||
| 9.6. Stream Prioritization . . . . . . . . . . . . . . . . . . 102 | 19.7. MAX_STREAM_ID Frame . . . . . . . . . . . . . . . . . . 97 | |||
| 10. Flow Control . . . . . . . . . . . . . . . . . . . . . . . . 103 | 19.8. PING Frame . . . . . . . . . . . . . . . . . . . . . . . 98 | |||
| 10.1. Edge Cases and Other Considerations . . . . . . . . . . 105 | 19.9. BLOCKED Frame . . . . . . . . . . . . . . . . . . . . . 98 | |||
| 10.1.1. Response to a RST_STREAM . . . . . . . . . . . . . . 105 | 19.10. STREAM_BLOCKED Frame . . . . . . . . . . . . . . . . . . 99 | |||
| 10.1.2. Data Limit Increments . . . . . . . . . . . . . . . 105 | 19.11. STREAM_ID_BLOCKED Frame . . . . . . . . . . . . . . . . 99 | |||
| 10.2. Stream Limit Increment . . . . . . . . . . . . . . . . . 106 | 19.12. NEW_CONNECTION_ID Frame . . . . . . . . . . . . . . . . 100 | |||
| 10.2.1. Blocking on Flow Control . . . . . . . . . . . . . . 106 | 19.13. RETIRE_CONNECTION_ID Frame . . . . . . . . . . . . . . . 101 | |||
| 10.3. Stream Final Offset . . . . . . . . . . . . . . . . . . 107 | 19.14. STOP_SENDING Frame . . . . . . . . . . . . . . . . . . . 102 | |||
| 10.4. Flow Control for Cryptographic Handshake . . . . . . . . 107 | 19.15. ACK Frame . . . . . . . . . . . . . . . . . . . . . . . 102 | |||
| 11. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 107 | 19.15.1. ACK Block Section . . . . . . . . . . . . . . . . . 104 | |||
| 11.1. Connection Errors . . . . . . . . . . . . . . . . . . . 108 | 19.15.2. ECN section . . . . . . . . . . . . . . . . . . . . 105 | |||
| 11.2. Stream Errors . . . . . . . . . . . . . . . . . . . . . 108 | 19.16. PATH_CHALLENGE Frame . . . . . . . . . . . . . . . . . . 106 | |||
| 11.3. Transport Error Codes . . . . . . . . . . . . . . . . . 109 | 19.17. PATH_RESPONSE Frame . . . . . . . . . . . . . . . . . . 107 | |||
| 11.4. Application Protocol Error Codes . . . . . . . . . . . . 110 | 19.18. NEW_TOKEN frame . . . . . . . . . . . . . . . . . . . . 107 | |||
| 12. Security Considerations . . . . . . . . . . . . . . . . . . . 110 | 19.19. STREAM Frames . . . . . . . . . . . . . . . . . . . . . 107 | |||
| 12.1. Handshake Denial of Service . . . . . . . . . . . . . . 110 | 19.20. CRYPTO Frame . . . . . . . . . . . . . . . . . . . . . . 109 | |||
| 12.2. Spoofed ACK Attack . . . . . . . . . . . . . . . . . . . 111 | 19.21. Extension Frames . . . . . . . . . . . . . . . . . . . . 110 | |||
| 12.3. Optimistic ACK Attack . . . . . . . . . . . . . . . . . 112 | 20. Transport Error Codes . . . . . . . . . . . . . . . . . . . . 110 | |||
| 12.4. Slowloris Attacks . . . . . . . . . . . . . . . . . . . 112 | 20.1. Application Protocol Error Codes . . . . . . . . . . . . 111 | |||
| 12.5. Stream Fragmentation and Reassembly Attacks . . . . . . 113 | 21. Security Considerations . . . . . . . . . . . . . . . . . . . 112 | |||
| 12.6. Stream Commitment Attack . . . . . . . . . . . . . . . . 113 | 21.1. Handshake Denial of Service . . . . . . . . . . . . . . 112 | |||
| 12.7. Explicit Congestion Notification Attacks . . . . . . . . 114 | 21.2. Spoofed ACK Attack . . . . . . . . . . . . . . . . . . . 113 | |||
| 12.8. Stateless Reset Oracle . . . . . . . . . . . . . . . . . 114 | 21.3. Optimistic ACK Attack . . . . . . . . . . . . . . . . . 113 | |||
| 13. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 114 | 21.4. Slowloris Attacks . . . . . . . . . . . . . . . . . . . 114 | |||
| 13.1. QUIC Transport Parameter Registry . . . . . . . . . . . 114 | 21.5. Stream Fragmentation and Reassembly Attacks . . . . . . 114 | |||
| 13.2. QUIC Frame Type Registry . . . . . . . . . . . . . . . . 116 | 21.6. Stream Commitment Attack . . . . . . . . . . . . . . . . 114 | |||
| 13.3. QUIC Transport Error Codes Registry . . . . . . . . . . 117 | 21.7. Explicit Congestion Notification Attacks . . . . . . . . 115 | |||
| 14. References . . . . . . . . . . . . . . . . . . . . . . . . . 120 | 21.8. Stateless Reset Oracle . . . . . . . . . . . . . . . . . 115 | |||
| 14.1. Normative References . . . . . . . . . . . . . . . . . . 120 | 22. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 116 | |||
| 14.2. Informative References . . . . . . . . . . . . . . . . . 121 | 22.1. QUIC Transport Parameter Registry . . . . . . . . . . . 116 | |||
| Appendix A. Sample Packet Number Decoding Algorithm . . . . . . 122 | 22.2. QUIC Frame Type Registry . . . . . . . . . . . . . . . . 117 | |||
| Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 123 | 22.3. QUIC Transport Error Codes Registry . . . . . . . . . . 118 | |||
| B.1. Since draft-ietf-quic-transport-14 . . . . . . . . . . . 123 | 23. References . . . . . . . . . . . . . . . . . . . . . . . . . 121 | |||
| B.2. Since draft-ietf-quic-transport-13 . . . . . . . . . . . 124 | 23.1. Normative References . . . . . . . . . . . . . . . . . . 121 | |||
| B.3. Since draft-ietf-quic-transport-12 . . . . . . . . . . . 124 | 23.2. Informative References . . . . . . . . . . . . . . . . . 122 | |||
| B.4. Since draft-ietf-quic-transport-11 . . . . . . . . . . . 125 | Appendix A. Sample Packet Number Decoding Algorithm . . . . . . 123 | |||
| B.5. Since draft-ietf-quic-transport-10 . . . . . . . . . . . 126 | Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 124 | |||
| B.6. Since draft-ietf-quic-transport-09 . . . . . . . . . . . 126 | B.1. Since draft-ietf-quic-transport-15 . . . . . . . . . . . 124 | |||
| B.7. Since draft-ietf-quic-transport-08 . . . . . . . . . . . 127 | B.2. Since draft-ietf-quic-transport-14 . . . . . . . . . . . 124 | |||
| B.8. Since draft-ietf-quic-transport-07 . . . . . . . . . . . 127 | B.3. Since draft-ietf-quic-transport-13 . . . . . . . . . . . 125 | |||
| B.9. Since draft-ietf-quic-transport-06 . . . . . . . . . . . 128 | B.4. Since draft-ietf-quic-transport-12 . . . . . . . . . . . 126 | |||
| B.10. Since draft-ietf-quic-transport-05 . . . . . . . . . . . 129 | B.5. Since draft-ietf-quic-transport-11 . . . . . . . . . . . 126 | |||
| B.11. Since draft-ietf-quic-transport-04 . . . . . . . . . . . 129 | B.6. Since draft-ietf-quic-transport-10 . . . . . . . . . . . 127 | |||
| B.12. Since draft-ietf-quic-transport-03 . . . . . . . . . . . 130 | B.7. Since draft-ietf-quic-transport-09 . . . . . . . . . . . 127 | |||
| B.13. Since draft-ietf-quic-transport-02 . . . . . . . . . . . 130 | B.8. Since draft-ietf-quic-transport-08 . . . . . . . . . . . 128 | |||
| B.14. Since draft-ietf-quic-transport-01 . . . . . . . . . . . 131 | B.9. Since draft-ietf-quic-transport-07 . . . . . . . . . . . 129 | |||
| B.15. Since draft-ietf-quic-transport-00 . . . . . . . . . . . 133 | B.10. Since draft-ietf-quic-transport-06 . . . . . . . . . . . 130 | |||
| B.16. Since draft-hamilton-quic-transport-protocol-01 . . . . . 133 | B.11. Since draft-ietf-quic-transport-05 . . . . . . . . . . . 130 | |||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 133 | B.12. Since draft-ietf-quic-transport-04 . . . . . . . . . . . 130 | |||
| Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 134 | B.13. Since draft-ietf-quic-transport-03 . . . . . . . . . . . 131 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 134 | B.14. Since draft-ietf-quic-transport-02 . . . . . . . . . . . 131 | |||
| B.15. Since draft-ietf-quic-transport-01 . . . . . . . . . . . 132 | ||||
| B.16. Since draft-ietf-quic-transport-00 . . . . . . . . . . . 134 | ||||
| B.17. Since draft-hamilton-quic-transport-protocol-01 . . . . . 134 | ||||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 134 | ||||
| Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 135 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 135 | ||||
| 1. Introduction | 1. Introduction | |||
| QUIC is a multiplexed and secure transport protocol that runs on top | QUIC is a multiplexed and secure transport protocol that runs on top | |||
| of UDP. QUIC aims to provide a flexible set of features that allow | of UDP. QUIC aims to provide a flexible set of features that allow | |||
| it to be a general-purpose secure transport for multiple | it to be a general-purpose secure transport for multiple | |||
| applications. | applications. | |||
| o Version negotiation | o Version negotiation | |||
| skipping to change at page 6, line 4 ¶ | skipping to change at page 6, line 10 ¶ | |||
| 1. Introduction | 1. Introduction | |||
| QUIC is a multiplexed and secure transport protocol that runs on top | QUIC is a multiplexed and secure transport protocol that runs on top | |||
| of UDP. QUIC aims to provide a flexible set of features that allow | of UDP. QUIC aims to provide a flexible set of features that allow | |||
| it to be a general-purpose secure transport for multiple | it to be a general-purpose secure transport for multiple | |||
| applications. | applications. | |||
| o Version negotiation | o Version negotiation | |||
| o Low-latency connection establishment | o Low-latency connection establishment | |||
| o Authenticated and encrypted header and payload | o Authenticated and encrypted header and payload | |||
| o Stream multiplexing | o Stream multiplexing | |||
| o Stream and connection-level flow control | o Stream and connection-level flow control | |||
| o Connection migration and resilience to NAT rebinding | o Connection migration and resilience to NAT rebinding | |||
| QUIC uses UDP as a substrate to avoid requiring changes in legacy | QUIC uses UDP as a substrate to avoid requiring changes in legacy | |||
| client operating systems and middleboxes. QUIC authenticates all of | client operating systems and middleboxes. QUIC authenticates all of | |||
| its headers and encrypts most of the data it exchanges, including its | its headers and encrypts most of the data it exchanges, including its | |||
| signaling. This allows the protocol to evolve without incurring a | signaling. This allows the protocol to evolve without incurring a | |||
| dependency on upgrades to middleboxes. | dependency on upgrades to middleboxes. | |||
| This document describes the core QUIC protocol, including the | 1.1. Document Structure | |||
| conceptual design, wire format, and mechanisms of the QUIC protocol | ||||
| for connection establishment, stream multiplexing, stream and | This document describes the core QUIC protocol, and is structured as | |||
| connection-level flow control, connection migration, and data | follows: | |||
| reliability. | ||||
| o Streams are the basic service abstraction that QUIC provides. | ||||
| * Section 2 describes core concepts related to streams, | ||||
| * Section 3 provides a reference model for stream states, and | ||||
| * Section 4 outlines the operation of flow control. | ||||
| o Connections are the context in which QUIC endpoints communicate. | ||||
| * Section 5 describes core concepts related to connections, | ||||
| * Section 6 describes version negotiation, | ||||
| * Section 7 details the process for establishing connections, | ||||
| * Section 8 specifies critical denial of service mitigation | ||||
| mechanisms, | ||||
| * Section 9 describes how endpoints migrate a connection to use a | ||||
| new network paths, and | ||||
| * Section 10 lists the options for terminating an open | ||||
| connection. | ||||
| o Packets and frames are the basic unit used by QUIC to communicate. | ||||
| * Section 12 describes concepts related to packets and frames, | ||||
| * Section 13 defines models for the transmission, retransmission, | ||||
| and acknowledgement of information, and | ||||
| * Section 14 contains a rules for managing the size of packets. | ||||
| o Details of encoding of QUIC protocol elements is described in: | ||||
| * Section 15 (Versions), | ||||
| * Section 17 (Packet Headers), | ||||
| * Section 18 (Transport Parameters), | ||||
| * Section 19 (Frames), and | ||||
| * Section 20 (Errors). | ||||
| Accompanying documents describe QUIC's loss detection and congestion | Accompanying documents describe QUIC's loss detection and congestion | |||
| control [QUIC-RECOVERY], and the use of TLS 1.3 for key negotiation | control [QUIC-RECOVERY], and the use of TLS 1.3 for key negotiation | |||
| [QUIC-TLS]. | [QUIC-TLS]. | |||
| QUIC version 1 conforms to the protocol invariants in | QUIC version 1 conforms to the protocol invariants in | |||
| [QUIC-INVARIANTS]. | [QUIC-INVARIANTS]. | |||
| 2. Conventions and Definitions | 1.2. 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. | |||
| Definitions of terms that are used in this document: | Definitions of terms that are used in this document: | |||
| Client: The endpoint initiating a QUIC connection. | Client: The endpoint initiating a QUIC connection. | |||
| Server: The endpoint accepting incoming QUIC connections. | Server: The endpoint accepting incoming QUIC connections. | |||
| Endpoint: The client or server end of a connection. | Endpoint: The client or server end of a connection. | |||
| Stream: A logical, bi-directional channel of ordered bytes within a | Stream: A logical unidirectional or bidirectional channel of ordered | |||
| QUIC connection. | bytes within a QUIC connection. | |||
| Connection: A conversation between two QUIC endpoints with a single | Connection: A conversation between two QUIC endpoints with a single | |||
| encryption context that multiplexes streams within it. | encryption context that multiplexes streams within it. | |||
| Connection ID: An opaque identifier that is used to identify a QUIC | Connection ID: An opaque identifier that is used to identify a QUIC | |||
| connection at an endpoint. Each endpoint sets a value that its | connection at an endpoint. Each endpoint sets a value that its | |||
| peer includes in packets. | peer includes in packets. | |||
| QUIC packet: The smallest unit of data that can be exchanged by QUIC | QUIC packet: The smallest unit of data that can be exchanged by QUIC | |||
| endpoints. | endpoints. | |||
| QUIC is a name, not an acronym. | QUIC is a name, not an acronym. | |||
| 2.1. Notational Conventions | 1.3. Notational Conventions | |||
| Packet and frame diagrams use the format described in Section 3.1 of | Packet and frame diagrams use the format described in Section 3.1 of | |||
| [RFC2360], with the following additional conventions: | [RFC2360], with the following additional conventions: | |||
| [x] Indicates that x is optional | [x] Indicates that x is optional | |||
| x (A) Indicates that x is A bits long | x (A) Indicates that x is A bits long | |||
| x (A/B/C) ... Indicates that x is one of A, B, or C bits long | x (A/B/C) ... Indicates that x is one of A, B, or C bits long | |||
| x (i) ... Indicates that x uses the variable-length encoding in | x (i) ... Indicates that x uses the variable-length encoding in | |||
| Section 7.1 | Section 16 | |||
| x (*) ... Indicates that x is variable-length | x (*) ... Indicates that x is variable-length | |||
| 3. Versions | 2. Streams | |||
| QUIC versions are identified using a 32-bit unsigned number. | ||||
| The version 0x00000000 is reserved to represent version negotiation. | ||||
| This version of the specification is identified by the number | ||||
| 0x00000001. | ||||
| Other versions of QUIC might have different properties to this | ||||
| version. The properties of QUIC that are guaranteed to be consistent | ||||
| across all versions of the protocol are described in | ||||
| [QUIC-INVARIANTS]. | ||||
| Version 0x00000001 of QUIC uses TLS as a cryptographic handshake | ||||
| protocol, as described in [QUIC-TLS]. | ||||
| Versions with the most significant 16 bits of the version number | ||||
| cleared are reserved for use in future IETF consensus documents. | ||||
| Versions that follow the pattern 0x?a?a?a?a are reserved for use in | ||||
| forcing version negotiation to be exercised. That is, any version | ||||
| number where the low four bits of all octets is 1010 (in binary). A | ||||
| client or server MAY advertise support for any of these reserved | ||||
| versions. | ||||
| Reserved version numbers will probably never represent a real | ||||
| protocol; a client MAY use one of these version numbers with the | ||||
| expectation that the server will initiate version negotiation; a | ||||
| server MAY advertise support for one of these versions and can expect | ||||
| that clients ignore the value. | ||||
| [[RFC editor: please remove the remainder of this section before | ||||
| publication.]] | ||||
| The version number for the final version of this specification | ||||
| (0x00000001), is reserved for the version of the protocol that is | ||||
| published as an RFC. | ||||
| Version numbers used to identify IETF drafts are created by adding | ||||
| the draft number to 0xff000000. For example, draft-ietf-quic- | ||||
| transport-13 would be identified as 0xff00000D. | ||||
| Implementors are encouraged to register version numbers of QUIC that | ||||
| they are using for private experimentation on the GitHub wiki at | ||||
| <https://github.com/quicwg/base-drafts/wiki/QUIC-Versions>. | ||||
| 4. Packet Types and Formats | ||||
| We first describe QUIC's packet types and their formats, since some | ||||
| are referenced in subsequent mechanisms. | ||||
| All numeric values are encoded in network byte order (that is, big- | ||||
| endian) and all field sizes are in bits. When discussing individual | ||||
| bits of fields, the least significant bit is referred to as bit 0. | ||||
| Hexadecimal notation is used for describing the value of fields. | ||||
| Any QUIC packet has either a long or a short header, as indicated by | ||||
| the Header Form bit. Long headers are expected to be used early in | ||||
| the connection before version negotiation and establishment of 1-RTT | ||||
| keys. Short headers are minimal version-specific headers, which are | ||||
| used after version negotiation and 1-RTT keys are established. | ||||
| 4.1. Long Header | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| Type (7) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Length (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Packet Number (8/16/32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Payload (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 1: Long Header Packet Format | ||||
| Long headers are used for packets that are sent prior to the | ||||
| completion of version negotiation and establishment of 1-RTT keys. | ||||
| Once both conditions are met, a sender switches to sending packets | ||||
| using the short header (Section 4.2). The long form allows for | ||||
| special packets - such as the Version Negotiation packet - to be | ||||
| represented in this uniform fixed-length packet format. Packets that | ||||
| use the long header contain the following fields: | ||||
| Header Form: The most significant bit (0x80) of octet 0 (the first | ||||
| octet) is set to 1 for long headers. | ||||
| Long Packet Type: The remaining seven bits of octet 0 contain the | ||||
| packet type. This field can indicate one of 128 packet types. | ||||
| The types specified for this version are listed in Table 1. | ||||
| Version: The QUIC Version is a 32-bit field that follows the Type. | ||||
| This field indicates which version of QUIC is in use and | ||||
| determines how the rest of the protocol fields are interpreted. | ||||
| DCIL and SCIL: The octet following the version contains the lengths | ||||
| of the two connection ID fields that follow it. These lengths are | ||||
| encoded as two 4-bit unsigned integers. The Destination | ||||
| Connection ID Length (DCIL) field occupies the 4 high bits of the | ||||
| octet and the Source Connection ID Length (SCIL) field occupies | ||||
| the 4 low bits of the octet. An encoded length of 0 indicates | ||||
| that the connection ID is also 0 octets in length. Non-zero | ||||
| encoded lengths are increased by 3 to get the full length of the | ||||
| connection ID, producing a length between 4 and 18 octets | ||||
| inclusive. For example, an octet with the value 0x50 describes an | ||||
| 8-octet Destination Connection ID and a zero-length Source | ||||
| Connection ID. | ||||
| Destination Connection ID: The Destination Connection ID field | ||||
| follows the connection ID lengths and is either 0 octets in length | ||||
| or between 4 and 18 octets. Section 4.10 describes the use of | ||||
| this field in more detail. | ||||
| Source Connection ID: The Source Connection ID field follows the | ||||
| Destination Connection ID and is either 0 octets in length or | ||||
| between 4 and 18 octets. Section 4.10 describes the use of this | ||||
| field in more detail. | ||||
| Length: The length of the remainder of the packet (that is, the | ||||
| Packet Number and Payload fields) in octets, encoded as a | ||||
| variable-length integer (Section 7.1). | ||||
| Packet Number: The packet number field is 1, 2, or 4 octets long. | ||||
| The packet number has confidentiality protection separate from | ||||
| packet protection, as described in Section 5.3 of [QUIC-TLS]. The | ||||
| length of the packet number field is encoded in the plaintext | ||||
| packet number. See Section 4.11 for details. | ||||
| Payload: The payload of the packet. | ||||
| The following packet types are defined: | ||||
| +------+-----------------+-------------+ | ||||
| | Type | Name | Section | | ||||
| +------+-----------------+-------------+ | ||||
| | 0x7F | Initial | Section 4.6 | | ||||
| | | | | | ||||
| | 0x7E | Retry | Section 4.4 | | ||||
| | | | | | ||||
| | 0x7D | Handshake | Section 4.7 | | ||||
| | | | | | ||||
| | 0x7C | 0-RTT Protected | Section 4.8 | | ||||
| +------+-----------------+-------------+ | ||||
| Table 1: Long Header Packet Types | ||||
| The header form, type, connection ID lengths octet, destination and | ||||
| source connection IDs, and version fields of a long header packet are | ||||
| version-independent. The packet number and values for packet types | ||||
| defined in Table 1 are version-specific. See [QUIC-INVARIANTS] for | ||||
| details on how packets from different versions of QUIC are | ||||
| interpreted. | ||||
| The interpretation of the fields and the payload are specific to a | ||||
| version and packet type. Type-specific semantics for this version | ||||
| are described in the following sections. | ||||
| The end of the packet is determined by the Length field. The Length | ||||
| field covers both the Packet Number and Payload fields, both of which | ||||
| are confidentiality protected and initially of unknown length. The | ||||
| size of the Payload field is learned once the packet number | ||||
| protection is removed. | ||||
| Senders can sometimes coalesce multiple packets into one UDP | ||||
| datagram. See Section 4.9 for more details. | ||||
| 4.2. Short Header | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |0|K|1|1|0|R R R| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Packet Number (8/16/32) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Protected Payload (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 2: Short Header Packet Format | ||||
| The short header can be used after the version and 1-RTT keys are | ||||
| negotiated. Packets that use the short header contain the following | ||||
| fields: | ||||
| Header Form: The most significant bit (0x80) of octet 0 is set to 0 | ||||
| for the short header. | ||||
| Key Phase Bit: The second bit (0x40) of octet 0 indicates the key | ||||
| phase, which allows a recipient of a packet to identify the packet | ||||
| protection keys that are used to protect the packet. See | ||||
| [QUIC-TLS] for details. | ||||
| [[Editor's Note: this section should be removed and the bit | ||||
| definitions changed before this draft goes to the IESG.]] | ||||
| Third Bit: The third bit (0x20) of octet 0 is set to 1. | ||||
| [[Editor's Note: this section should be removed and the bit | ||||
| definitions changed before this draft goes to the IESG.]] | ||||
| Fourth Bit: The fourth bit (0x10) of octet 0 is set to 1. | ||||
| [[Editor's Note: this section should be removed and the bit | ||||
| definitions changed before this draft goes to the IESG.]] | ||||
| Google QUIC Demultiplexing Bit: The fifth bit (0x8) of octet 0 is | ||||
| set to 0. This allows implementations of Google QUIC to | ||||
| distinguish Google QUIC packets from short header packets sent by | ||||
| a client because Google QUIC servers expect the connection ID to | ||||
| always be present. The special interpretation of this bit SHOULD | ||||
| be removed from this specification when Google QUIC has finished | ||||
| transitioning to the new header format. | ||||
| Reserved: The sixth, seventh, and eighth bits (0x7) of octet 0 are | ||||
| reserved for experimentation. Endpoints MUST ignore these bits on | ||||
| packets they receive unless they are participating in an | ||||
| experiment that uses these bits. An endpoint not actively using | ||||
| these bits SHOULD set the value randomly on packets they send to | ||||
| protect against unwanted inference about particular values. | ||||
| Destination Connection ID: The Destination Connection ID is a | ||||
| connection ID that is chosen by the intended recipient of the | ||||
| packet. See Section 6.1 for more details. | ||||
| Packet Number: The packet number field is 1, 2, or 4 octets long. | ||||
| The packet number has confidentiality protection separate from | ||||
| packet protection, as described in Section 5.3 of [QUIC-TLS]. The | ||||
| length of the packet number field is encoded in the plaintext | ||||
| packet number. See Section 4.11 for details. | ||||
| Protected Payload: Packets with a short header always include a | ||||
| 1-RTT protected payload. | ||||
| The header form and connection ID field of a short header packet are | ||||
| version-independent. The remaining fields are specific to the | ||||
| selected QUIC version. See [QUIC-INVARIANTS] for details on how | ||||
| packets from different versions of QUIC are interpreted. | ||||
| 4.3. Version Negotiation Packet | ||||
| A Version Negotiation packet is inherently not version-specific, and | ||||
| does not use the long packet header (see Section 4.1. Upon receipt | ||||
| by a client, it will appear to be a packet using the long header, but | ||||
| will be identified as a Version Negotiation packet based on the | ||||
| Version field having a value of 0. | ||||
| The Version Negotiation packet is a response to a client packet that | ||||
| contains a version that is not supported by the server, and is only | ||||
| sent by servers. | ||||
| The layout of a Version Negotiation packet is: | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| Unused (7) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Supported Version 1 (32) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | [Supported Version 2 (32)] ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | [Supported Version N (32)] ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 3: Version Negotiation Packet | ||||
| The value in the Unused field is selected randomly by the server. | ||||
| The Version field of a Version Negotiation packet MUST be set to | ||||
| 0x00000000. | ||||
| The server MUST include the value from the Source Connection ID field | ||||
| of the packet it receives in the Destination Connection ID field. | ||||
| The value for Source Connection ID MUST be copied from the | ||||
| Destination Connection ID of the received packet, which is initially | ||||
| randomly selected by a client. Echoing both connection IDs gives | ||||
| clients some assurance that the server received the packet and that | ||||
| the Version Negotiation packet was not generated by an off-path | ||||
| attacker. | ||||
| The remainder of the Version Negotiation packet is a list of 32-bit | ||||
| versions which the server supports. | ||||
| A Version Negotiation packet cannot be explicitly acknowledged in an | ||||
| ACK frame by a client. Receiving another Initial packet implicitly | ||||
| acknowledges a Version Negotiation packet. | ||||
| The Version Negotiation packet does not include the Packet Number and | ||||
| Length fields present in other packets that use the long header form. | ||||
| Consequently, a Version Negotiation packet consumes an entire UDP | ||||
| datagram. | ||||
| See Section 6.3 for a description of the version negotiation process. | ||||
| 4.4. Retry Packet | ||||
| A Retry packet uses a long packet header with a type value of 0x7E. | ||||
| It carries an address validation token created by the server. It is | ||||
| used by a server that wishes to perform a stateless retry (see | ||||
| Section 6.7). | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| 0x7e | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | ODCIL(8) | Original Destination Connection ID (*) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Retry Token (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 4: Retry Packet | ||||
| A Retry packet (shown in Figure 4) only uses the invariant portion of | ||||
| the long packet header [QUIC-INVARIANTS]; that is, the fields up to | ||||
| and including the Destination and Source Connection ID fields. A | ||||
| Retry packet does not contain any protected fields. Like Version | ||||
| Negotiation, a Retry packet contains the long header including the | ||||
| connection IDs, but omits the Length, Packet Number, and Payload | ||||
| fields. These are replaced with: | ||||
| ODCIL: The length of the Original Destination Connection ID field. | ||||
| The length is encoded in the least significant 4 bits of the | ||||
| octet, using the same encoding as the DCIL and SCIL fields. The | ||||
| most significant 4 bits of this octet are reserved. Unless a use | ||||
| for these bits has been negotiated, endpoints SHOULD send | ||||
| randomized values and MUST ignore any value that it receives. | ||||
| Original Destination Connection ID: The Original Destination | ||||
| Connection ID contains the value of the Destination Connection ID | ||||
| from the Initial packet that this Retry is in response to. The | ||||
| length of this field is given in ODCIL. | ||||
| Retry Token: An opaque token that the server can use to validate the | ||||
| client's address. | ||||
| The server populates the Destination Connection ID with the | Streams in QUIC provide a lightweight, ordered byte-stream | |||
| connection ID that the client included in the Source Connection ID of | abstraction. | |||
| the Initial packet. | ||||
| The server includes a connection ID of its choice in the Source | There are two basic types of stream in QUIC. Unidirectional streams | |||
| Connection ID field. This value MUST not be equal to the Destination | carry data in one direction: from the initiator of the stream to its | |||
| Connection ID field of the packet sent by the client. The client | peer; bidirectional streams allow for data to be sent in both | |||
| MUST use this connection ID in the Destination Connection ID of | directions. Different stream identifiers are used to distinguish | |||
| subsequent packets that it sends. | between unidirectional and bidirectional streams, as well as to | |||
| create a separation between streams that are initiated by the client | ||||
| and server (see Section 2.1). | ||||
| A server MAY send Retry packets in response to Initial and 0-RTT | Either type of stream can be created by either endpoint, can | |||
| packets. A server can either discard or buffer 0-RTT packets that it | concurrently send data interleaved with other streams, and can be | |||
| receives. A server can send multiple Retry packets as it receives | cancelled. | |||
| Initial or 0-RTT packets. | ||||
| A client MUST accept and process at most one Retry packet for each | Streams can be created by sending data. Other processes associated | |||
| connection attempt. After the client has received and processed an | with stream management - ending, cancelling, and managing flow | |||
| Initial or Retry packet from the server, it MUST discard any | control - are all designed to impose minimal overheads. For | |||
| subsequent Retry packets that it receives. | instance, a single STREAM frame (Section 19.19) can open, carry data | |||
| for, and close a stream. Streams can also be long-lived and can last | ||||
| the entire duration of a connection. | ||||
| Clients MUST discard Retry packets that contain an Original | Stream offsets allow for the octets on a stream to be placed in | |||
| Destination Connection ID field that does not match the Destination | order. An endpoint MUST be capable of delivering data received on a | |||
| Connection ID from its Initial packet. This prevents an off-path | stream in order. Implementations MAY choose to offer the ability to | |||
| attacker from injecting a Retry packet. | deliver data out of order. There is no means of ensuring ordering | |||
| between octets on different streams. | ||||
| The client responds to a Retry packet with an Initial packet that | Streams are individually flow controlled, allowing an endpoint to | |||
| includes the provided Retry Token to continue connection | limit memory commitment and to apply back pressure. The creation of | |||
| establishment. | streams is also flow controlled, with each peer declaring the maximum | |||
| stream ID it is willing to accept at a given time. | ||||
| A client sets the Destination Connection ID field of this Initial | An alternative view of QUIC streams is as an elastic "message" | |||
| packet to the value from the Source Connection ID in the Retry | abstraction, similar to the way ephemeral streams are used in SST | |||
| packet. Changing Destination Connection ID also results in a change | [SST], which may be a more appealing description for some | |||
| to the keys used to protect the Initial packet. It also sets the | applications. | |||
| Token field to the token provided in the Retry. The client MUST NOT | ||||
| change the Source Connection ID because the server could include the | ||||
| connection ID as part of its token validation logic (see | ||||
| Section 4.6.2). | ||||
| All subsequent Initial packets from the client MUST use the | 2.1. Stream Identifiers | |||
| connection ID and token values from the Retry packet. Aside from | ||||
| this, the Initial packet sent by the client is subject to the same | ||||
| restrictions as the first Initial packet. A client can either reuse | ||||
| the cryptographic handshake message or construct a new one at its | ||||
| discretion. | ||||
| A client MAY attempt 0-RTT after receiving a Retry packet by sending | Streams are identified by an unsigned 62-bit integer, referred to as | |||
| 0-RTT packets to the connection ID provided by the server. A client | the Stream ID. Stream IDs are encoded as a variable-length integer | |||
| that sends additional 0-RTT packets without constructing a new | (see Section 16). The least significant two bits of the Stream ID | |||
| cryptographic handshake message MUST NOT reset the packet number to 0 | are used to identify the type of stream (unidirectional or | |||
| after a Retry packet, see Section 4.6.4. | bidirectional) and the initiator of the stream. | |||
| A server acknowledges the use of a Retry packet for a connection | The least significant bit (0x1) of the Stream ID identifies the | |||
| using the original_connection_id transport parameter (see | initiator of the stream. Clients initiate even-numbered streams | |||
| Section 6.6.1). If the server sends a Retry packet, it MUST include | (those with the least significant bit set to 0); servers initiate | |||
| the value of the Original Destination Connection ID field of the | odd-numbered streams (with the bit set to 1). Separation of the | |||
| Retry packet (that is, the Destination Connection ID field from the | stream identifiers ensures that client and server are able to open | |||
| client's first Initial packet) in the transport parameter. | streams without the latency imposed by negotiating for an identifier. | |||
| If the client received and processed a Retry packet, it validates | If an endpoint receives a frame for a stream that it expects to | |||
| that the original_connection_id transport parameter is present and | initiate (i.e., odd-numbered for the client or even-numbered for the | |||
| correct; otherwise, it validates that the transport parameter is | server), but which it has not yet opened, it MUST close the | |||
| absent. A client MUST treat a failed validation as a connection | connection with error code STREAM_STATE_ERROR. | |||
| error of type TRANSPORT_PARAMETER_ERROR. | ||||
| A Retry packet does not include a packet number and cannot be | The second least significant bit (0x2) of the Stream ID | |||
| explicitly acknowledged by a client. | differentiates between unidirectional streams and bidirectional | |||
| streams. Unidirectional streams always have this bit set to 1 and | ||||
| bidirectional streams have this bit set to 0. | ||||
| 4.5. Cryptographic Handshake Packets | The two type bits from a Stream ID therefore identify streams as | |||
| summarized in Table 1. | ||||
| Once version negotiation is complete, the cryptographic handshake is | +----------+----------------------------------+ | |||
| used to agree on cryptographic keys. The cryptographic handshake is | | Low Bits | Stream Type | | |||
| carried in Initial (Section 4.6) and Handshake (Section 4.7) packets. | +----------+----------------------------------+ | |||
| | 0x0 | Client-Initiated, Bidirectional | | ||||
| | | | | ||||
| | 0x1 | Server-Initiated, Bidirectional | | ||||
| | | | | ||||
| | 0x2 | Client-Initiated, Unidirectional | | ||||
| | | | | ||||
| | 0x3 | Server-Initiated, Unidirectional | | ||||
| +----------+----------------------------------+ | ||||
| All these packets use the long header and contain the current QUIC | Table 1: Stream ID Types | |||
| version in the version field. | ||||
| In order to prevent tampering by version-unaware middleboxes, Initial | The first bidirectional stream opened by the client is stream 0. | |||
| packets are protected with connection- and version-specific keys | ||||
| (Initial keys) as described in [QUIC-TLS]. This protection does not | ||||
| provide confidentiality or integrity against on-path attackers, but | ||||
| provides some level of protection against off-path attackers. | ||||
| 4.6. Initial Packet | A QUIC endpoint MUST NOT reuse a Stream ID. Streams of each type are | |||
| created in numeric order. Streams that are used out of order result | ||||
| in opening all lower-numbered streams of the same type in the same | ||||
| direction. | ||||
| The Initial packet uses long headers with a type value of 0x7F. It | 2.2. Stream Concurrency | |||
| carries the first CRYPTO frames sent by the client and server to | ||||
| perform key exchange, and carries ACKs in either direction. The | ||||
| Initial packet is protected by Initial keys as described in | ||||
| [QUIC-TLS]. | ||||
| The Initial packet (shown in Figure 5) has two additional header | QUIC allows for an arbitrary number of streams to operate | |||
| fields that are added to the Long Header before the Length field. | concurrently. An endpoint limits the number of concurrently active | |||
| incoming streams by limiting the maximum stream ID (see Section 4.5). | ||||
| +-+-+-+-+-+-+-+-+ | The maximum stream ID is specific to each endpoint and applies only | |||
| |1| 0x7f | | to the peer that receives the setting. That is, clients specify the | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | maximum stream ID the server can initiate, and servers specify the | |||
| | Version (32) | | maximum stream ID the client can initiate. Each endpoint may respond | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | on streams initiated by the other peer, regardless of whether it is | |||
| |DCIL(4)|SCIL(4)| | permitted to initiate new streams. | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Token Length (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Token (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Length (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Packet Number (8/16/32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Payload (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 5: Initial Packet | Endpoints MUST NOT exceed the limit set by their peer. An endpoint | |||
| that receives a STREAM frame with an ID greater than the limit it has | ||||
| sent MUST treat this as a stream error of type STREAM_ID_ERROR | ||||
| (Section 11), unless this is a result of a change in the initial | ||||
| limits (see Section 7.3.1). | ||||
| These fields include the token that was previously provided in a | A receiver cannot renege on an advertisement; that is, once a | |||
| Retry packet or NEW_TOKEN frame: | receiver advertises a stream ID via a MAX_STREAM_ID frame, | |||
| advertising a smaller maximum ID has no effect. A receiver MUST | ||||
| ignore any MAX_STREAM_ID frame that does not increase the maximum | ||||
| stream ID. | ||||
| Token Length: A variable-length integer specifying the length of the | 2.3. Sending and Receiving Data | |||
| Token field, in bytes. This value is zero if no token is present. | ||||
| Initial packets sent by the server MUST set the Token Length field | ||||
| to zero; clients that receive an Initial packet with a non-zero | ||||
| Token Length field MUST either discard the packet or generate a | ||||
| connection error of type PROTOCOL_VIOLATION. | ||||
| Token: The value of the token. | Endpoints uses streams to send and receive data. Endpoints send | |||
| STREAM frames, which encapsulate data for a stream. STREAM frames | ||||
| carry a flag that can be used to signal the end of a stream. | ||||
| The client and server use the Initial packet type for any packet that | Streams are an ordered byte-stream abstraction with no other | |||
| contains an initial cryptographic handshake message. This includes | structure that is visible to QUIC. STREAM frame boundaries are not | |||
| all cases where a new packet containing the initial cryptographic | expected to preserved when data is transmitted, when data is | |||
| message needs to be created, such as the packets sent after receiving | retransmitted after packet loss, or when data is delivered to the | |||
| a Version Negotiation (Section 4.3) or Retry packet (Section 4.4). | application at the receiver. | |||
| A server sends its first Initial packet in response to a client | When new data is to be sent on a stream, a sender MUST set the | |||
| Initial. A server may send multiple Initial packets. The | encapsulating STREAM frame's offset field to the stream offset of the | |||
| cryptographic key exchange could require multiple round trips or | first octet of this new data. The first octet of data on a stream | |||
| retransmissions of this data. | has an offset of 0. An endpoint is expected to send every stream | |||
| octet. The largest offset delivered on a stream MUST be less than | ||||
| 2^62. | ||||
| The payload of an Initial packet includes a CRYPTO frame (or frames) | QUIC makes no specific allowances for partial reliability or delivery | |||
| containing a cryptographic handshake message, ACK frames, or both. | of stream data out of order. Endpoints MUST be able to deliver | |||
| PADDING and CONNECTION_CLOSE frames are also permitted. An endpoint | stream data to an application as an ordered byte-stream. Delivering | |||
| that receives an Initial packet containing other frames can either | an ordered byte-stream requires that an endpoint buffer any data that | |||
| discard the packet as spurious or treat it as a connection error. | is received out of order, up to the advertised flow control limit. | |||
| The first packet sent by a client always includes a CRYPTO frame that | An endpoint could receive the same octets multiple times; octets that | |||
| contains the entirety of the first cryptographic handshake message. | have already been received can be discarded. The value for a given | |||
| This packet, and the cryptographic handshake message, MUST fit in a | octet MUST NOT change if it is sent multiple times; an endpoint MAY | |||
| single UDP datagram (see Section 6.4). The first CRYPTO frame sent | treat receipt of a changed octet as a connection error of type | |||
| always begins at an offset of 0 (see Section 6.4). | PROTOCOL_VIOLATION. | |||
| Note that if the server sends a HelloRetryRequest, the client will | An endpoint MUST NOT send data on any stream without ensuring that it | |||
| send a second Initial packet. This Initial packet will continue the | is within the data limits set by its peer. Flow control is described | |||
| cryptographic handshake and will contain a CRYPTO frame with an | in detail in Section 4. | |||
| offset matching the size of the CRYPTO frame sent in the first | ||||
| Initial packet. Cryptographic handshake messages subsequent to the | ||||
| first do not need to fit within a single UDP datagram. | ||||
| 4.6.1. Connection IDs | 2.4. Stream Prioritization | |||
| When an Initial packet is sent by a client which has not previously | Stream multiplexing has a significant effect on application | |||
| received a Retry packet from the server, it populates the Destination | performance if resources allocated to streams are correctly | |||
| Connection ID field with an unpredictable value. This MUST be at | prioritized. Experience with other multiplexed protocols, such as | |||
| least 8 octets in length. Until a packet is received from the | HTTP/2 [HTTP2], shows that effective prioritization strategies have a | |||
| server, the client MUST use the same value unless it abandons the | significant positive impact on performance. | |||
| connection attempt and starts a new one. The initial Destination | ||||
| Connection ID is used to determine packet protection keys for Initial | ||||
| packets. | ||||
| The client populates the Source Connection ID field with a value of | QUIC does not provide frames for exchanging prioritization | |||
| its choosing and sets the SCIL field to match. | information. Instead it relies on receiving priority information | |||
| from the application that uses QUIC. Protocols that use QUIC are | ||||
| able to define any prioritization scheme that suits their application | ||||
| semantics. A protocol might define explicit messages for signaling | ||||
| priority, such as those defined in HTTP/2; it could define rules that | ||||
| allow an endpoint to determine priority based on context; or it could | ||||
| leave the determination to the application. | ||||
| The Destination Connection ID field in the server's Initial packet | A QUIC implementation SHOULD provide ways in which an application can | |||
| contains a connection ID that is chosen by the recipient of the | indicate the relative priority of streams. When deciding which | |||
| packet (i.e., the client); the Source Connection ID includes the | streams to dedicate resources to, QUIC SHOULD use the information | |||
| connection ID that the sender of the packet wishes to use (see | provided by the application. Failure to account for priority of | |||
| Section 6.1). The server MUST use consistent Source Connection IDs | streams can result in suboptimal performance. | |||
| during the handshake. | ||||
| On first receiving an Initial or Retry packet from the server, the | Stream priority is most relevant when deciding which stream data will | |||
| client uses the Source Connection ID supplied by the server as the | be transmitted. Often, there will be limits on what can be | |||
| Destination Connection ID for subsequent packets. That means that a | transmitted as a result of connection flow control or the current | |||
| client might change the Destination Connection ID twice during | congestion controller state. | |||
| connection establishment. Once a client has received an Initial | ||||
| packet from the server, it MUST discard any packet it receives with a | ||||
| different Source Connection ID. | ||||
| 4.6.2. Tokens | Giving preference to the transmission of its own management frames | |||
| ensures that the protocol functions efficiently. That is, | ||||
| prioritizing frames other than STREAM frames ensures that loss | ||||
| recovery, congestion control, and flow control operate effectively. | ||||
| If the client has a token received in a NEW_TOKEN frame on a previous | CRYPTO frames SHOULD be prioritized over other streams prior to the | |||
| connection to what it believes to be the same server, it can include | completion of the cryptographic handshake. This includes the | |||
| that value in the Token field of its Initial packet. | retransmission of the second flight of client handshake messages, | |||
| that is, the TLS Finished and any client authentication messages. | ||||
| A token allows a server to correlate activity between connections. | STREAM data in frames determined to be lost SHOULD be retransmitted | |||
| Specifically, the connection where the token was issued, and any | before sending new data, unless application priorities indicate | |||
| connection where it is used. Clients that want to break continuity | otherwise. Retransmitting lost stream data can fill in gaps, which | |||
| of identity with a server MAY discard tokens provided using the | allows the peer to consume already received data and free up the flow | |||
| NEW_TOKEN frame. Tokens obtained in Retry packets MUST NOT be | control window. | |||
| discarded. | ||||
| A client SHOULD NOT reuse a token. Reusing a token allows | 3. Stream States: Life of a Stream | |||
| connections to be linked by entities on the network path (see | ||||
| Section 6.11.5). A client MUST NOT reuse a token if it believes that | ||||
| its point of network attachment has changed since the token was last | ||||
| used; that is, if there is a change in its local IP address or | ||||
| network interface. A client needs to start the connection process | ||||
| over if it migrates prior to completing the handshake. | ||||
| When a server receives an Initial packet with an address validation | This section describes the two types of QUIC stream in terms of the | |||
| token, it SHOULD attempt to validate it. If the token is invalid | states of their send or receive components. Two state machines are | |||
| then the server SHOULD proceed as if the client did not have a | described: one for streams on which an endpoint transmits data | |||
| validated address, including potentially sending a Retry. If the | (Section 3.1); another for streams from which an endpoint receives | |||
| validation succeeds, the server SHOULD then allow the handshake to | data (Section 3.2). | |||
| proceed (see Section 6.7). | ||||
| Note: The rationale for treating the client as unvalidated rather | Unidirectional streams use the applicable state machine directly. | |||
| than discarding the packet is that the client might have received | Bidirectional streams use both state machines. For the most part, | |||
| the token in a previous connection using the NEW_TOKEN frame, and | the use of these state machines is the same whether the stream is | |||
| if the server has lost state, it might be unable to validate the | unidirectional or bidirectional. The conditions for opening a stream | |||
| token at all, leading to connection failure if the packet is | are slightly more complex for a bidirectional stream because the | |||
| discarded. A server MAY encode tokens provided with NEW_TOKEN | opening of either send or receive sides causes the stream to open in | |||
| frames and Retry packets differently, and validate the latter more | both directions. | |||
| strictly. | ||||
| In a stateless design, a server can use encrypted and authenticated | An endpoint can open streams up to its maximum stream limit in any | |||
| tokens to pass information to clients that the server can later | order, however endpoints SHOULD open the send side of streams for | |||
| recover and use to validate a client address. Tokens are not | each type in order. | |||
| integrated into the cryptographic handshake and so they are not | ||||
| authenticated. For instance, a client might be able to reuse a | ||||
| token. To avoid attacks that exploit this property, a server can | ||||
| limit its use of tokens to only the information needed validate | ||||
| client addresses. | ||||
| 4.6.3. Starting Packet Numbers | Note: These states are largely informative. This document uses | |||
| stream states to describe rules for when and how different types | ||||
| of frames can be sent and the reactions that are expected when | ||||
| different types of frames are received. Though these state | ||||
| machines are intended to be useful in implementing QUIC, these | ||||
| states aren't intended to constrain implementations. An | ||||
| implementation can define a different state machine as long as its | ||||
| behavior is consistent with an implementation that implements | ||||
| these states. | ||||
| The first Initial packet sent by either endpoint contains a packet | 3.1. Send Stream States | |||
| number of 0. The packet number MUST increase monotonically | ||||
| thereafter. Initial packets are in a different packet number space | ||||
| to other packets (see Section 4.11). | ||||
| 4.6.4. 0-RTT Packet Numbers | Figure 1 shows the states for the part of a stream that sends data to | |||
| a peer. | ||||
| Packet numbers for 0-RTT protected packets use the same space as | o | |||
| 1-RTT protected packets. | | Create Stream (Sending) | |||
| | Create Bidirectional Stream (Receiving) | ||||
| v | ||||
| +-------+ | ||||
| | Ready | Send RST_STREAM | ||||
| | |-----------------------. | ||||
| +-------+ | | ||||
| | | | ||||
| | Send STREAM / | | ||||
| | STREAM_BLOCKED | | ||||
| | | | ||||
| | Create Bidirectional | | ||||
| | Stream (Receiving) | | ||||
| v | | ||||
| +-------+ | | ||||
| | Send | Send RST_STREAM | | ||||
| | |---------------------->| | ||||
| +-------+ | | ||||
| | | | ||||
| | Send STREAM + FIN | | ||||
| v v | ||||
| +-------+ +-------+ | ||||
| | Data | Send RST_STREAM | Reset | | ||||
| | Sent |------------------>| Sent | | ||||
| +-------+ +-------+ | ||||
| | | | ||||
| | Recv All ACKs | Recv ACK | ||||
| v v | ||||
| +-------+ +-------+ | ||||
| | Data | | Reset | | ||||
| | Recvd | | Recvd | | ||||
| +-------+ +-------+ | ||||
| After a client receives a Retry or Version Negotiation packet, 0-RTT | Figure 1: States for Send Streams | |||
| packets are likely to have been lost or discarded by the server. A | ||||
| client MAY attempt to resend data in 0-RTT packets after it sends a | ||||
| new Initial packet. | ||||
| A client MUST NOT reset the packet number it uses for 0-RTT packets. | The sending part of stream that the endpoint initiates (types 0 and 2 | |||
| The keys used to protect 0-RTT packets will not change as a result of | for clients, 1 and 3 for servers) is opened by the application or | |||
| responding to a Retry or Version Negotiation packet unless the client | application protocol. The "Ready" state represents a newly created | |||
| also regenerates the cryptographic handshake message. Sending | stream that is able to accept data from the application. Stream data | |||
| packets with the same packet number in that case is likely to | might be buffered in this state in preparation for sending. | |||
| compromise the packet protection for all 0-RTT packets because the | ||||
| same key and nonce could be used to protect different content. | ||||
| Receiving a Retry or Version Negotiation packet, especially a Retry | Sending the first STREAM or STREAM_BLOCKED frame causes a send stream | |||
| that changes the connection ID used for subsequent packets, indicates | to enter the "Send" state. An implementation might choose to defer | |||
| a strong possibility that 0-RTT packets could be lost. A client only | allocating a Stream ID to a send stream until it sends the first | |||
| receives acknowledgments for its 0-RTT packets once the handshake is | frame and enters this state, which can allow for better stream | |||
| complete. Consequently, a server might expect 0-RTT packets to start | prioritization. | |||
| with a packet number of 0. Therefore, in determining the length of | ||||
| the packet number encoding for 0-RTT packets, a client MUST assume | ||||
| that all packets up to the current packet number are in flight, | ||||
| starting from a packet number of 0. Thus, 0-RTT packets could need | ||||
| to use a longer packet number encoding. | ||||
| A client SHOULD instead generate a fresh cryptographic handshake | The sending part of a bidirectional stream initiated by a peer (type | |||
| message and start packet numbers from 0. This ensures that new 0-RTT | 0 for a server, type 1 for a client) enters the "Ready" state then | |||
| packets will not use the same keys, avoiding any risk of key and | immediately transitions to the "Send" state if the receiving part | |||
| nonce reuse; this also prevents 0-RTT packets from previous handshake | enters the "Recv" state. | |||
| attempts from being accepted as part of the connection. | ||||
| 4.6.5. Minimum Packet Size | In the "Send" state, an endpoint transmits - and retransmits as | |||
| necessary - data in STREAM frames. The endpoint respects the flow | ||||
| control limits of its peer, accepting MAX_STREAM_DATA frames. An | ||||
| endpoint in the "Send" state generates STREAM_BLOCKED frames if it | ||||
| encounters flow control limits. | ||||
| The payload of a UDP datagram carrying the Initial packet MUST be | After the application indicates that stream data is complete and a | |||
| expanded to at least 1200 octets (see Section 8), by adding PADDING | STREAM frame containing the FIN bit is sent, the send stream enters | |||
| frames to the Initial packet and/or by combining the Initial packet | the "Data Sent" state. From this state, the endpoint only | |||
| with a 0-RTT packet (see Section 4.9). | retransmits stream data as necessary. The endpoint no longer needs | |||
| to track flow control limits or send STREAM_BLOCKED frames for a send | ||||
| stream in this state. The endpoint can ignore any MAX_STREAM_DATA | ||||
| frames it receives from its peer in this state; MAX_STREAM_DATA | ||||
| frames might be received until the peer receives the final stream | ||||
| offset. | ||||
| 4.7. Handshake Packet | Once all stream data has been successfully acknowledged, the send | |||
| stream enters the "Data Recvd" state, which is a terminal state. | ||||
| A Handshake packet uses long headers with a type value of 0x7D. It | From any of the "Ready", "Send", or "Data Sent" states, an | |||
| is used to carry acknowledgments and cryptographic handshake messages | application can signal that it wishes to abandon transmission of | |||
| from the server and client. | stream data. Similarly, the endpoint might receive a STOP_SENDING | |||
| frame from its peer. In either case, the endpoint sends a RST_STREAM | ||||
| frame, which causes the stream to enter the "Reset Sent" state. | ||||
| A server sends its cryptographic handshake in one or more Handshake | An endpoint MAY send a RST_STREAM as the first frame on a send | |||
| packets in response to an Initial packet if it does not send a Retry | stream; this causes the send stream to open and then immediately | |||
| packet. Once a client has received a Handshake packet from a server, | transition to the "Reset Sent" state. | |||
| it uses Handshake packets to send subsequent cryptographic handshake | ||||
| messages and acknowledgments to the server. | ||||
| The Destination Connection ID field in a Handshake packet contains a | Once a packet containing a RST_STREAM has been acknowledged, the send | |||
| connection ID that is chosen by the recipient of the packet; the | stream enters the "Reset Recvd" state, which is a terminal state. | |||
| Source Connection ID includes the connection ID that the sender of | ||||
| the packet wishes to use (see Section 4.10). | ||||
| The first Handshake packet sent by a server contains a packet number | 3.2. Receive Stream States | |||
| of 0. Handshake packets are their own packet number space. Packet | ||||
| numbers are incremented normally for other Handshake packets. | ||||
| Servers MUST NOT send more than three times as many bytes as the | Figure 2 shows the states for the part of a stream that receives data | |||
| number of bytes received prior to verifying the client's address. | from a peer. The states for a receive stream mirror only some of the | |||
| Source addresses can be verified through an address validation token | states of the send stream at the peer. A receive stream doesn't | |||
| (delivered via a Retry packet or a NEW_TOKEN frame) or by processing | track states on the send stream that cannot be observed, such as the | |||
| any message from the client encrypted using the Handshake keys. This | "Ready" state; instead, receive streams track the delivery of data to | |||
| limit exists to mitigate amplification attacks. | the application or application protocol some of which cannot be | |||
| observed by the sender. | ||||
| In order to prevent this limit causing a handshake deadlock, the | o | |||
| client SHOULD always send a packet upon a handshake timeout, as | | Recv STREAM / STREAM_BLOCKED / RST_STREAM | |||
| described in [QUIC-RECOVERY]. If the client has no data to | | Create Bidirectional Stream (Sending) | |||
| retransmit and does not have Handshake keys, it SHOULD send an | | Recv MAX_STREAM_DATA | |||
| Initial packet in a UDP datagram of at least 1200 octets. If the | | Create Higher-Numbered Stream | |||
| client has Handshake keys, it SHOULD send a Handshake packet. | v | |||
| +-------+ | ||||
| | Recv | Recv RST_STREAM | ||||
| | |-----------------------. | ||||
| +-------+ | | ||||
| | | | ||||
| | Recv STREAM + FIN | | ||||
| v | | ||||
| +-------+ | | ||||
| | Size | Recv RST_STREAM | | ||||
| | Known |---------------------->| | ||||
| +-------+ | | ||||
| | | | ||||
| | Recv All Data | | ||||
| v v | ||||
| +-------+ Recv RST_STREAM +-------+ | ||||
| | Data |--- (optional) --->| Reset | | ||||
| | Recvd | Recv All Data | Recvd | | ||||
| +-------+<-- (optional) ----+-------+ | ||||
| | | | ||||
| | App Read All Data | App Read RST | ||||
| v v | ||||
| +-------+ +-------+ | ||||
| | Data | | Reset | | ||||
| | Read | | Read | | ||||
| +-------+ +-------+ | ||||
| The payload of this packet contains CRYPTO frames and could contain | Figure 2: States for Receive Streams | |||
| PADDING, or ACK frames. Handshake packets MAY contain | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE frames. Endpoints MUST treat | ||||
| receipt of Handshake packets with other frames as a connection error. | ||||
| 4.8. Protected Packets | The receiving part of a stream initiated by a peer (types 1 and 3 for | |||
| a client, or 0 and 2 for a server) are created when the first STREAM, | ||||
| STREAM_BLOCKED, RST_STREAM, or MAX_STREAM_DATA (bidirectional only, | ||||
| see below) is received for that stream. The initial state for a | ||||
| receive stream is "Recv". Receiving a RST_STREAM frame causes the | ||||
| receive stream to immediately transition to the "Reset Recvd". | ||||
| All QUIC packets use packet protection. Packets that are protected | The receive stream enters the "Recv" state when the sending part of a | |||
| with the static handshake keys or the 0-RTT keys are sent with long | bidirectional stream initiated by the endpoint (type 0 for a client, | |||
| headers; all packets protected with 1-RTT keys are sent with short | type 1 for a server) enters the "Ready" state. | |||
| headers. The different packet types explicitly indicate the | ||||
| encryption level and therefore the keys that are used to remove | ||||
| packet protection. 0-RTT and 1-RTT protected packets share a single | ||||
| packet number space. | ||||
| Packets protected with handshake keys only use packet protection to | A bidirectional stream also opens when a MAX_STREAM_DATA frame is | |||
| ensure that the sender of the packet is on the network path. This | received. Receiving a MAX_STREAM_DATA frame implies that the remote | |||
| packet protection is not effective confidentiality protection; any | peer has opened the stream and is providing flow control credit. A | |||
| entity that receives the Initial packet from a client can recover the | MAX_STREAM_DATA frame might arrive before a STREAM or STREAM_BLOCKED | |||
| keys necessary to remove packet protection or to generate packets | frame if packets are lost or reordered. | |||
| that will be successfully authenticated. | ||||
| Packets protected with 0-RTT and 1-RTT keys are expected to have | Before creating a stream, all lower-numbered streams of the same type | |||
| confidentiality and data origin authentication; the cryptographic | MUST be created. That means that receipt of a frame that would open | |||
| handshake ensures that only the communicating endpoints receive the | a stream causes all lower-numbered streams of the same type to be | |||
| corresponding keys. | opened in numeric order. This ensures that the creation order for | |||
| streams is consistent on both endpoints. | ||||
| Packets protected with 0-RTT keys use a type value of 0x7C. The | In the "Recv" state, the endpoint receives STREAM and STREAM_BLOCKED | |||
| connection ID fields for a 0-RTT packet MUST match the values used in | frames. Incoming data is buffered and can be reassembled into the | |||
| the Initial packet (Section 4.6). | correct order for delivery to the application. As data is consumed | |||
| by the application and buffer space becomes available, the endpoint | ||||
| sends MAX_STREAM_DATA frames to allow the peer to send more data. | ||||
| The version field for protected packets is the current QUIC version. | When a STREAM frame with a FIN bit is received, the final offset (see | |||
| Section 4.3) is known. The receive stream enters the "Size Known" | ||||
| state. In this state, the endpoint no longer needs to send | ||||
| MAX_STREAM_DATA frames, it only receives any retransmissions of | ||||
| stream data. | ||||
| The packet number field contains a packet number, which has | Once all data for the stream has been received, the receive stream | |||
| additional confidentiality protection that is applied after packet | enters the "Data Recvd" state. This might happen as a result of | |||
| protection is applied (see [QUIC-TLS] for details). The underlying | receiving the same STREAM frame that causes the transition to "Size | |||
| packet number increases with each packet sent, see Section 4.11 for | Known". In this state, the endpoint has all stream data. Any STREAM | |||
| details. | or STREAM_BLOCKED frames it receives for the stream can be discarded. | |||
| The payload is protected using authenticated encryption. [QUIC-TLS] | The "Data Recvd" state persists until stream data has been delivered | |||
| describes packet protection in detail. After decryption, the | to the application or application protocol. Once stream data has | |||
| plaintext consists of a sequence of frames, as described in | been delivered, the stream enters the "Data Read" state, which is a | |||
| Section 5. | terminal state. | |||
| 4.9. Coalescing Packets | Receiving a RST_STREAM frame in the "Recv" or "Size Known" states | |||
| causes the stream to enter the "Reset Recvd" state. This might cause | ||||
| the delivery of stream data to the application to be interrupted. | ||||
| A sender can coalesce multiple QUIC packets (typically a | It is possible that all stream data is received when a RST_STREAM is | |||
| Cryptographic Handshake packet and a Protected packet) into one UDP | received (that is, from the "Data Recvd" state). Similarly, it is | |||
| datagram. This can reduce the number of UDP datagrams needed to send | possible for remaining stream data to arrive after receiving a | |||
| application data during the handshake and immediately afterwards. It | RST_STREAM frame (the "Reset Recvd" state). An implementation is | |||
| is not necessary for senders to coalesce packets, though failing to | able to manage this situation as they choose. Sending RST_STREAM | |||
| do so will require sending a significantly larger number of datagrams | means that an endpoint cannot guarantee delivery of stream data; | |||
| during the handshake. Receivers MUST be able to process coalesced | however there is no requirement that stream data not be delivered if | |||
| packets. | a RST_STREAM is received. An implementation MAY interrupt delivery | |||
| of stream data, discard any data that was not consumed, and signal | ||||
| the existence of the RST_STREAM immediately. Alternatively, the | ||||
| RST_STREAM signal might be suppressed or withheld if stream data is | ||||
| completely received. In the latter case, the receive stream | ||||
| effectively transitions to "Data Recvd" from "Reset Recvd". | ||||
| Coalescing packets in order of increasing encryption levels (Initial, | Once the application has been delivered the signal indicating that | |||
| 0-RTT, Handshake, 1-RTT) makes it more likely the receiver will be | the receive stream was reset, the receive stream transitions to the | |||
| able to process all the packets in a single pass. A packet with a | "Reset Read" state, which is a terminal state. | |||
| short header does not include a length, so it will always be the last | ||||
| packet included in a UDP datagram. | ||||
| Senders MUST NOT coalesce QUIC packets with different Destination | 3.3. Permitted Frame Types | |||
| Connection IDs into a single UDP datagram. Receivers SHOULD ignore | ||||
| any subsequent packets with a different Destination Connection ID | ||||
| than the first packet in the datagram. | ||||
| Every QUIC packet that is coalesced into a single UDP datagram is | The sender of a stream sends just three frame types that affect the | |||
| separate and complete. Though the values of some fields in the | state of a stream at either sender or receiver: STREAM | |||
| packet header might be redundant, no fields are omitted. The | (Section 19.19), STREAM_BLOCKED (Section 19.10), and RST_STREAM | |||
| receiver of coalesced QUIC packets MUST individually process each | (Section 19.2). | |||
| QUIC packet and separately acknowledge them, as if they were received | ||||
| as the payload of different UDP datagrams. If one or more packets in | ||||
| a datagram cannot be processed yet (because the keys are not yet | ||||
| available) or processing fails (decryption failure, unknown type, | ||||
| etc.), the receiver MUST still attempt to process the remaining | ||||
| packets. The skipped packets MAY either be discarded or buffered for | ||||
| later processing, just as if the packets were received out-of-order | ||||
| in separate datagrams. | ||||
| Retry (Section 4.4) and Version Negotiation (Section 4.3) packets | A sender MUST NOT send any of these frames from a terminal state | |||
| cannot be coalesced. | ("Data Recvd" or "Reset Recvd"). A sender MUST NOT send STREAM or | |||
| STREAM_BLOCKED after sending a RST_STREAM; that is, in the "Reset | ||||
| Sent" state in addition to the terminal states. A receiver could | ||||
| receive any of these frames in any state, but only due to the | ||||
| possibility of delayed delivery of packets carrying them. | ||||
| 4.10. Connection ID Encoding | The receiver of a stream sends MAX_STREAM_DATA (Section 19.6) and | |||
| STOP_SENDING frames (Section 19.14). | ||||
| A connection ID is used to ensure consistent routing of packets, as | The receiver only sends MAX_STREAM_DATA in the "Recv" state. A | |||
| described in Section 6.1. The long header contains two connection | receiver can send STOP_SENDING in any state where it has not received | |||
| IDs: the Destination Connection ID is chosen by the recipient of the | a RST_STREAM frame; that is states other than "Reset Recvd" or "Reset | |||
| packet and is used to provide consistent routing; the Source | Read". However there is little value in sending a STOP_SENDING frame | |||
| Connection ID is used to set the Destination Connection ID used by | after all stream data has been received in the "Data Recvd" state. A | |||
| the peer. | sender could receive these frames in any state as a result of delayed | |||
| delivery of packets. | ||||
| During the handshake, packets with the long header are used to | 3.4. Bidirectional Stream States | |||
| establish the connection ID that each endpoint uses. Each endpoint | ||||
| uses the Source Connection ID field to specify the connection ID that | ||||
| is used in the Destination Connection ID field of packets being sent | ||||
| to them. Upon receiving a packet, each endpoint sets the Destination | ||||
| Connection ID it sends to match the value of the Source Connection ID | ||||
| that they receive. | ||||
| During the handshake, a client can receive both a Retry and an | A bidirectional stream is composed of a send stream and a receive | |||
| Initial packet, and thus be given two opportunities to update the | stream. Implementations may represent states of the bidirectional | |||
| Destination Connection ID it sends. A client MUST only change the | stream as composites of send and receive stream states. The simplest | |||
| value it sends in the Destination Connection ID in response to the | model presents the stream as "open" when either send or receive | |||
| first packet of each type it receives from the server (Retry or | stream is in a non-terminal state and "closed" when both send and | |||
| Initial); a server MUST set its value based on the Initial packet. | receive streams are in a terminal state. | |||
| Any additional changes are not permitted; if subsequent packets of | ||||
| those types include a different Source Connection ID, they MUST be | ||||
| discarded. This avoids problems that might arise from stateless | ||||
| processing of multiple Initial packets producing different connection | ||||
| IDs. | ||||
| Short headers only include the Destination Connection ID and omit the | Table 2 shows a more complex mapping of bidirectional stream states | |||
| explicit length. The length of the Destination Connection ID field | that loosely correspond to the stream states in HTTP/2 [HTTP2]. This | |||
| is expected to be known to endpoints. | shows that multiple states on send or receive streams are mapped to | |||
| the same composite state. Note that this is just one possibility for | ||||
| such a mapping; this mapping requires that data is acknowledged | ||||
| before the transition to a "closed" or "half-closed" state. | ||||
| Endpoints using a connection-ID based load balancer could agree with | +-----------------------+---------------------+---------------------+ | |||
| the load balancer on a fixed or minimum length and on an encoding for | | Send Stream | Receive Stream | Composite State | | |||
| connection IDs. This fixed portion could encode an explicit length, | +-----------------------+---------------------+---------------------+ | |||
| which allows the entire connection ID to vary in length and still be | | No Stream/Ready | No Stream/Recv *1 | idle | | |||
| used by the load balancer. | | | | | | |||
| | Ready/Send/Data Sent | Recv/Size Known | open | | ||||
| | | | | | ||||
| | Ready/Send/Data Sent | Data Recvd/Data | half-closed | | ||||
| | | Read | (remote) | | ||||
| | | | | | ||||
| | Ready/Send/Data Sent | Reset Recvd/Reset | half-closed | | ||||
| | | Read | (remote) | | ||||
| | | | | | ||||
| | Data Recvd | Recv/Size Known | half-closed (local) | | ||||
| | | | | | ||||
| | Reset Sent/Reset | Recv/Size Known | half-closed (local) | | ||||
| | Recvd | | | | ||||
| | | | | | ||||
| | Data Recvd | Recv/Size Known | half-closed (local) | | ||||
| | | | | | ||||
| | Reset Sent/Reset | Data Recvd/Data | closed | | ||||
| | Recvd | Read | | | ||||
| | | | | | ||||
| | Reset Sent/Reset | Reset Recvd/Reset | closed | | ||||
| | Recvd | Read | | | ||||
| | | | | | ||||
| | Data Recvd | Data Recvd/Data | closed | | ||||
| | | Read | | | ||||
| | | | | | ||||
| | Data Recvd | Reset Recvd/Reset | closed | | ||||
| | | Read | | | ||||
| +-----------------------+---------------------+---------------------+ | ||||
| The very first packet sent by a client includes a random value for | Table 2: Possible Mapping of Stream States to HTTP/2 | |||
| Destination Connection ID. The same value MUST be used for all 0-RTT | ||||
| packets sent on that connection (Section 4.8). This randomized value | ||||
| is used to determine the packet protection keys for Initial packets | ||||
| (see Section 5.2 of [QUIC-TLS]). | ||||
| A Version Negotiation (Section 4.3) packet MUST use both connection | Note (*1): A stream is considered "idle" if it has not yet been | |||
| IDs selected by the client, swapped to ensure correct routing toward | created, or if the receive stream is in the "Recv" state without | |||
| the client. | yet having received any frames. | |||
| The connection ID can change over the lifetime of a connection, | 3.5. Solicited State Transitions | |||
| especially in response to connection migration (Section 6.11). | ||||
| NEW_CONNECTION_ID frames (Section 7.13) are used to provide new | ||||
| connection ID values. | ||||
| 4.11. Packet Numbers | If an endpoint is no longer interested in the data it is receiving on | |||
| a stream, it MAY send a STOP_SENDING frame identifying that stream to | ||||
| prompt closure of the stream in the opposite direction. This | ||||
| typically indicates that the receiving application is no longer | ||||
| reading data it receives from the stream, but is not a guarantee that | ||||
| incoming data will be ignored. | ||||
| The packet number is an integer in the range 0 to 2^62-1. The value | STREAM frames received after sending STOP_SENDING are still counted | |||
| is used in determining the cryptographic nonce for packet protection. | toward the connection and stream flow-control windows, even though | |||
| Each endpoint maintains a separate packet number for sending and | these frames will be discarded upon receipt. This avoids potential | |||
| receiving. | ambiguity about which STREAM frames count toward flow control. | |||
| Packet numbers are divided into 3 spaces in QUIC: | A STOP_SENDING frame requests that the receiving endpoint send a | |||
| RST_STREAM frame. An endpoint that receives a STOP_SENDING frame | ||||
| MUST send a RST_STREAM frame for that stream, and can use an error | ||||
| code of STOPPING. If the STOP_SENDING frame is received on a send | ||||
| stream that is already in the "Data Sent" state, a RST_STREAM frame | ||||
| MAY still be sent in order to cancel retransmission of previously- | ||||
| sent STREAM frames. | ||||
| o Initial space: All Initial packets Section 4.6 are in this space. | STOP_SENDING SHOULD only be sent for a receive stream that has not | |||
| been reset. STOP_SENDING is most useful for streams in the "Recv" or | ||||
| "Size Known" states. | ||||
| o Handshake space: All Handshake packets Section 4.7 are in this | An endpoint is expected to send another STOP_SENDING frame if a | |||
| space. | packet containing a previous STOP_SENDING is lost. However, once | |||
| either all stream data or a RST_STREAM frame has been received for | ||||
| the stream - that is, the stream is in any state other than "Recv" or | ||||
| "Size Known" - sending a STOP_SENDING frame is unnecessary. | ||||
| o Application data space: All 0-RTT and 1-RTT encrypted packets | 4. Flow Control | |||
| Section 4.8 are in this space. | ||||
| As described in [QUIC-TLS], each packet type uses different | It is necessary to limit the amount of data that a sender may have | |||
| protection keys. | outstanding at any time, so as to prevent a fast sender from | |||
| overwhelming a slow receiver, or to prevent a malicious sender from | ||||
| consuming significant resources at a receiver. To this end, QUIC | ||||
| employs a credit-based flow-control scheme similar to that in HTTP/2 | ||||
| [HTTP2]. A receiver advertises the number of octets it is prepared | ||||
| to receive on a given stream and for the entire connection. This | ||||
| leads to two levels of flow control in QUIC: | ||||
| Conceptually, a packet number space is the context in which a packet | o Stream flow control, which prevents a single stream from consuming | |||
| can be processed and acknowledged. Initial packets can only be sent | the entire receive buffer for a connection. | |||
| with Initial packet protection keys and acknowledged in packets which | ||||
| are also Initial packets. Similarly, Handshake packets are sent at | ||||
| the Handshake encryption level and can only be acknowledged in | ||||
| Handshake packets. | ||||
| This enforces cryptographic separation between the data sent in the | o Connection flow control, which prevents senders from exceeding a | |||
| different packet sequence number spaces. Each packet number space | receiver's buffer capacity for the connection, and | |||
| starts at packet number 0. Subsequent packets sent in the same | ||||
| packet number space MUST increase the packet number by at least one. | ||||
| 0-RTT and 1-RTT data exist in the same packet number space to make | A data receiver sets initial credits for all streams by sending | |||
| loss recovery algorithms easier to implement between the two packet | transport parameters during the handshake (Section 7.3). | |||
| types. | ||||
| A QUIC endpoint MUST NOT reuse a packet number within the same packet | A data receiver sends MAX_STREAM_DATA or MAX_DATA frames to the | |||
| number space in one connection (that is, under the same cryptographic | sender to advertise additional credit. MAX_STREAM_DATA frames send | |||
| keys). If the packet number for sending reaches 2^62 - 1, the sender | the maximum absolute byte offset of a stream, while MAX_DATA frames | |||
| MUST close the connection without sending a CONNECTION_CLOSE frame or | send the maximum of the sum of the absolute byte offsets of all | |||
| any further packets; an endpoint MAY send a Stateless Reset | streams. | |||
| (Section 6.13.4) in response to further packets that it receives. | ||||
| In the QUIC long and short packet headers, the number of bits | A receiver advertises credit for a stream by sending a | |||
| required to represent the packet number is reduced by including only | MAX_STREAM_DATA frame with the Stream ID set appropriately. A | |||
| a variable number of the least significant bits of the packet number. | receiver could use the current offset of data consumed to determine | |||
| One or two of the most significant bits of the first octet determine | the flow control offset to be advertised. A receiver MAY send | |||
| how many bits of the packet number are provided, as shown in Table 2. | MAX_STREAM_DATA frames in multiple packets in order to make sure that | |||
| the sender receives an update before running out of flow control | ||||
| credit, even if one of the packets is lost. | ||||
| +---------------------+----------------+--------------+ | Connection flow control is a limit to the total bytes of stream data | |||
| | First octet pattern | Encoded Length | Bits Present | | sent in STREAM frames on all streams. A receiver advertises credit | |||
| +---------------------+----------------+--------------+ | for a connection by sending a MAX_DATA frame. A receiver maintains a | |||
| | 0b0xxxxxxx | 1 octet | 7 | | cumulative sum of bytes received on all contributing streams, which | |||
| | | | | | are used to check for flow control violations. A receiver might use | |||
| | 0b10xxxxxx | 2 | 14 | | a sum of bytes consumed on all streams to determine the maximum data | |||
| | | | | | limit to be advertised. | |||
| | 0b11xxxxxx | 4 | 30 | | ||||
| +---------------------+----------------+--------------+ | ||||
| Table 2: Packet Number Encodings for Packet Headers | A receiver MAY advertise a larger offset at any point by sending | |||
| MAX_STREAM_DATA or MAX_DATA frames. A receiver cannot renege on an | ||||
| advertisement; that is, once a receiver advertises an offset, | ||||
| advertising a smaller offset has no effect. A sender MUST therefore | ||||
| ignore any MAX_STREAM_DATA or MAX_DATA frames that do not increase | ||||
| flow control limits. | ||||
| Note that these encodings are similar to those in Section 7.1, but | A receiver MUST close the connection with a FLOW_CONTROL_ERROR error | |||
| use different values. | (Section 11) if the peer violates the advertised connection or stream | |||
| data limits. | ||||
| The encoded packet number is protected as described in Section 5.3 | A sender SHOULD send STREAM_BLOCKED or BLOCKED frames to indicate it | |||
| [QUIC-TLS]. Protection of the packet number is removed prior to | has data to write but is blocked by flow control limits. These | |||
| recovering the full packet number. The full packet number is | frames are expected to be sent infrequently in common cases, but they | |||
| reconstructed at the receiver based on the number of significant bits | are considered useful for debugging and monitoring purposes. | |||
| present, the value of those bits, and the largest packet number | ||||
| received on a successfully authenticated packet. Recovering the full | ||||
| packet number is necessary to successfully remove packet protection. | ||||
| Once packet number protection is removed, the packet number is | A similar method is used to control the number of open streams (see | |||
| decoded by finding the packet number value that is closest to the | Section 4.5 for details). | |||
| next expected packet. The next expected packet is the highest | ||||
| received packet number plus one. For example, if the highest | ||||
| successfully authenticated packet had a packet number of 0xaa82f30e, | ||||
| then a packet containing a 14-bit value of 0x9b3 will be decoded as | ||||
| 0xaa8309b3. Example pseudo-code for packet number decoding can be | ||||
| found in Appendix A. | ||||
| The sender MUST use a packet number size able to represent more than | 4.1. Handling of Stream Cancellation | |||
| twice as large a range than the difference between the largest | ||||
| acknowledged packet and packet number being sent. A peer receiving | ||||
| the packet will then correctly decode the packet number, unless the | ||||
| packet is delayed in transit such that it arrives after many higher- | ||||
| numbered packets have been received. An endpoint SHOULD use a large | ||||
| enough packet number encoding to allow the packet number to be | ||||
| recovered even if the packet arrives after packets that are sent | ||||
| afterwards. | ||||
| As a result, the size of the packet number encoding is at least one | There are some edge cases which must be considered when dealing with | |||
| more than the base 2 logarithm of the number of contiguous | stream and connection level flow control. Given enough time, both | |||
| unacknowledged packet numbers, including the new packet. | endpoints must agree on flow control state. If one end believes it | |||
| can send more than the other end is willing to receive, the | ||||
| connection will be torn down when too much data arrives. Conversely | ||||
| if a sender believes it is blocked, while endpoint B expects more | ||||
| data can be received, then the connection can be in a deadlock, with | ||||
| the sender waiting for a MAX_STREAM_DATA or MAX_DATA frame which will | ||||
| never come. | ||||
| For example, if an endpoint has received an acknowledgment for packet | On receipt of a RST_STREAM frame, an endpoint will tear down state | |||
| 0x6afa2f, sending a packet with a number of 0x6b2d79 requires a | for the matching stream and ignore further data arriving on that | |||
| packet number encoding with 14 bits or more; whereas the 30-bit | stream. This could result in the endpoints getting out of sync, | |||
| packet number encoding is needed to send a packet with a number of | since the RST_STREAM frame may have arrived out of order and there | |||
| 0x6bc107. | may be further bytes in flight. The data sender would have counted | |||
| the data against its connection level flow control budget, but a | ||||
| receiver that has not received these bytes would not know to include | ||||
| them as well. The receiver must learn the number of bytes that were | ||||
| sent on the stream to make the same adjustment in its connection flow | ||||
| controller. | ||||
| A receiver MUST discard a newly unprotected packet unless it is | To ensure that endpoints maintain a consistent connection-level flow | |||
| certain that it has not processed another packet with the same packet | control state, the RST_STREAM frame (Section 19.2) includes the | |||
| number from the same packet number space. Duplicate suppression MUST | largest offset of data sent on the stream. On receiving a RST_STREAM | |||
| happen after removing packet protection for the reasons described in | frame, a receiver definitively knows how many bytes were sent on that | |||
| Section 9.3 of [QUIC-TLS]. An efficient algorithm for duplicate | stream before the RST_STREAM frame, and the receiver MUST use the | |||
| suppression can be found in Section 3.4.3 of [RFC2406]. | final offset to account for all bytes sent on the stream in its | |||
| connection level flow controller. | ||||
| A Version Negotiation packet (Section 4.3) does not include a packet | RST_STREAM terminates one direction of a stream abruptly. Whether | |||
| number. The Retry packet (Section 4.4) has special rules for | any action or response can or should be taken on the data already | |||
| populating the packet number field. | received is application specific. | |||
| 5. Frames and Frame Types | For a bidirectional stream, RST_STREAM has no effect on data flow in | |||
| the opposite direction. The RST_STREAM sender can send a | ||||
| STOP_SENDING frame to encourage prompt termination. Both endpoints | ||||
| MUST maintain state for the stream in the unterminated direction | ||||
| until that direction enters a terminal state, or either side sends | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE. | ||||
| The payload of all packets, after removing packet protection, | 4.2. Data Limit Increments | |||
| consists of a sequence of frames, as shown in Figure 6. Version | ||||
| Negotiation and Stateless Reset do not contain frames. | ||||
| 0 1 2 3 | This document leaves when and how many bytes to advertise in a | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | MAX_DATA or MAX_STREAM_DATA to implementations, but offers a few | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | considerations. These frames contribute to connection overhead. | |||
| | Frame 1 (*) ... | Therefore frequently sending frames with small changes is | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | undesirable. At the same time, larger increments to limits are | |||
| | Frame 2 (*) ... | necessary to avoid blocking if updates are less frequent, requiring | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | larger resource commitments at the receiver. Thus there is a trade- | |||
| ... | off between resource commitment and overhead when determining how | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | large a limit is advertised. | |||
| | Frame N (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 6: QUIC Payload | A receiver MAY use an autotuning mechanism to tune the frequency and | |||
| amount that it increases data limits based on a round-trip time | ||||
| estimate and the rate at which the receiving application consumes | ||||
| data, similar to common TCP implementations. | ||||
| QUIC payloads MUST contain at least one frame, and MAY contain | If a sender runs out of flow control credit, it will be unable to | |||
| multiple frames and multiple frame types. | send new data. That is, the sender is blocked. A blocked sender | |||
| SHOULD send a STREAM_BLOCKED or BLOCKED frame. A receiver uses these | ||||
| frames for debugging purposes. A receiver MUST NOT wait for a | ||||
| STREAM_BLOCKED or BLOCKED frame before sending MAX_STREAM_DATA or | ||||
| MAX_DATA, since doing so will mean that a sender will be blocked for | ||||
| an entire round trip and the peer may never send a STREAM_BLOCKED or | ||||
| BLOCKED frame. | ||||
| Frames MUST fit within a single QUIC packet and MUST NOT span a QUIC | It is generally considered best to not let the sender go into | |||
| packet boundary. Each frame begins with a Frame Type, indicating its | quiescence if avoidable. To avoid blocking a sender, and to | |||
| type, followed by additional type-dependent fields: | reasonably account for the possibility of loss, a receiver should | |||
| send a MAX_DATA or MAX_STREAM_DATA frame at least two round trips | ||||
| before it expects the sender to get blocked. | ||||
| 0 1 2 3 | A sender sends a single BLOCKED or STREAM_BLOCKED frame only once | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | when it reaches a data limit. A sender SHOULD NOT send multiple | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | BLOCKED or STREAM_BLOCKED frames for the same data limit, unless the | |||
| | Frame Type (i) ... | original frame is determined to be lost. Another BLOCKED or | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | STREAM_BLOCKED frame can be sent after the data limit is increased. | |||
| | Type-Dependent Fields (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 7: Generic Frame Layout | 4.3. Stream Final Offset | |||
| The frame types defined in this specification are listed in Table 3. | The final offset is the count of the number of octets that are | |||
| The Frame Type in STREAM frames is used to carry other frame-specific | transmitted on a stream. For a stream that is reset, the final | |||
| flags. For all other frames, the Frame Type field simply identifies | offset is carried explicitly in a RST_STREAM frame. Otherwise, the | |||
| the frame. These frames are explained in more detail as they are | final offset is the offset of the end of the data carried in a STREAM | |||
| referenced later in the document. | frame marked with a FIN flag, or 0 in the case of incoming | |||
| unidirectional streams. | ||||
| +-------------+----------------------+--------------+ | An endpoint will know the final offset for a stream when the receive | |||
| | Type Value | Frame Type Name | Definition | | stream enters the "Size Known" or "Reset Recvd" state. | |||
| +-------------+----------------------+--------------+ | ||||
| | 0x00 | PADDING | Section 7.2 | | ||||
| | | | | | ||||
| | 0x01 | RST_STREAM | Section 7.3 | | ||||
| | | | | | ||||
| | 0x02 | CONNECTION_CLOSE | Section 7.4 | | ||||
| | | | | | ||||
| | 0x03 | APPLICATION_CLOSE | Section 7.5 | | ||||
| | | | | | ||||
| | 0x04 | MAX_DATA | Section 7.6 | | ||||
| | | | | | ||||
| | 0x05 | MAX_STREAM_DATA | Section 7.7 | | ||||
| | | | | | ||||
| | 0x06 | MAX_STREAM_ID | Section 7.8 | | ||||
| | | | | | ||||
| | 0x07 | PING | Section 7.9 | | ||||
| | | | | | ||||
| | 0x08 | BLOCKED | Section 7.10 | | ||||
| | | | | | ||||
| | 0x09 | STREAM_BLOCKED | Section 7.11 | | ||||
| | | | | | ||||
| | 0x0a | STREAM_ID_BLOCKED | Section 7.12 | | ||||
| | | | | | ||||
| | 0x0b | NEW_CONNECTION_ID | Section 7.13 | | ||||
| | | | | | ||||
| | 0x0c | STOP_SENDING | Section 7.15 | | ||||
| | | | | | ||||
| | 0x0d | RETIRE_CONNECTION_ID | Section 7.14 | | ||||
| | | | | | ||||
| | 0x0e | PATH_CHALLENGE | Section 7.17 | | ||||
| | | | | | ||||
| | 0x0f | PATH_RESPONSE | Section 7.18 | | ||||
| | | | | | ||||
| | 0x10 - 0x17 | STREAM | Section 7.20 | | ||||
| | | | | | ||||
| | 0x18 | CRYPTO | Section 7.21 | | ||||
| | | | | | ||||
| | 0x19 | NEW_TOKEN | Section 7.19 | | ||||
| | | | | | ||||
| | 0x1a - 0x1b | ACK | Section 7.16 | | ||||
| +-------------+----------------------+--------------+ | ||||
| Table 3: Frame Types | An endpoint MUST NOT send data on a stream at or beyond the final | |||
| offset. | ||||
| All QUIC frames are idempotent. That is, a valid frame does not | Once a final offset for a stream is known, it cannot change. If a | |||
| cause undesirable side effects or errors when received more than | RST_STREAM or STREAM frame causes the final offset to change for a | |||
| once. | stream, an endpoint SHOULD respond with a FINAL_OFFSET_ERROR error | |||
| (see Section 11). A receiver SHOULD treat receipt of data at or | ||||
| beyond the final offset as a FINAL_OFFSET_ERROR error, even after a | ||||
| stream is closed. Generating these errors is not mandatory, but only | ||||
| because requiring that an endpoint generate these errors also means | ||||
| that the endpoint needs to maintain the final offset state for closed | ||||
| streams, which could mean a significant state commitment. | ||||
| The Frame Type field uses a variable length integer encoding (see | 4.4. Flow Control for Cryptographic Handshake | |||
| Section 7.1) with one exception. To ensure simple and efficient | ||||
| implementations of frame parsing, a frame type MUST use the shortest | ||||
| possible encoding. Though a two-, four- or eight-octet encoding of | ||||
| the frame types defined in this document is possible, the Frame Type | ||||
| field for these frames is encoded on a single octet. For instance, | ||||
| though 0x4007 is a legitimate two-octet encoding for a variable- | ||||
| length integer with a value of 7, PING frames are always encoded as a | ||||
| single octet with the value 0x07. An endpoint MUST treat the receipt | ||||
| of a frame type that uses a longer encoding than necessary as a | ||||
| connection error of type PROTOCOL_VIOLATION. | ||||
| 5.1. Extension Frames | Data sent in CRYPTO frames is not flow controlled in the same way as | |||
| STREAM frames. QUIC relies on the cryptographic protocol | ||||
| implementation to avoid excessive buffering of data, see [QUIC-TLS]. | ||||
| The implementation SHOULD provide an interface to QUIC to tell it | ||||
| about its buffering limits so that there is not excessive buffering | ||||
| at multiple layers. | ||||
| QUIC frames do not use a self-describing encoding. An endpoint | 4.5. Stream Limit Increment | |||
| therefore needs to understand the syntax of all frames before it can | ||||
| successfully process a packet. This allows for efficient encoding of | ||||
| frames, but it means that an endpoint cannot send a frame of a type | ||||
| that is unknown to its peer. | ||||
| An extension to QUIC that wishes to use a new type of frame MUST | An endpoint limits the number of concurrently active incoming streams | |||
| first ensure that a peer is able to understand the frame. An | by limiting the maximum stream ID. An initial value is set in the | |||
| endpoint can use a transport parameter to signal its willingness to | transport parameters (see Section 18.1) and is subsequently increased | |||
| receive one or more extension frame types with the one transport | by MAX_STREAM_ID frames (see Section 19.7). | |||
| parameter. | ||||
| Extension frames MUST be congestion controlled and MUST cause an ACK | As with stream and connection flow control, this document leaves when | |||
| frame to be sent. The exception is extension frames that replace or | and how many streams to make available to a peer via MAX_STREAM_ID to | |||
| supplement the ACK frame. Extension frames are not included in flow | implementations, but offers a few considerations. MAX_STREAM_ID | |||
| control unless specified in the extension. | frames constitute minimal overhead, while withholding MAX_STREAM_ID | |||
| frames can prevent the peer from using the available parallelism. | ||||
| An IANA registry is used to manage the assignment of frame types, see | The STREAM_ID_BLOCKED frame (Section 19.11) can be used to signal a | |||
| Section 13.2. | shortage of available streams. Implementations will likely want to | |||
| increase the maximum stream ID as peer-initiated streams close. | ||||
| 6. Life of a Connection | 5. Connections | |||
| A QUIC connection is a single conversation between two QUIC | A QUIC connection is a single conversation between two QUIC | |||
| endpoints. QUIC's connection establishment intertwines version | endpoints. QUIC's connection establishment combines version | |||
| negotiation with the cryptographic and transport handshakes to reduce | negotiation with the cryptographic and transport handshakes to reduce | |||
| connection establishment latency, as described in Section 6.4. Once | connection establishment latency, as described in Section 7. Once | |||
| established, a connection may migrate to a different IP or port at | established, a connection may migrate to a different IP or port at | |||
| either endpoint, due to NAT rebinding or mobility, as described in | either endpoint as described in Section 9. Finally, a connection may | |||
| Section 6.11. Finally, a connection may be terminated by either | be terminated by either endpoint, as described in Section 10. | |||
| endpoint, as described in Section 6.13. | ||||
| 6.1. Connection ID | 5.1. Connection ID | |||
| Each connection possesses a set of identifiers, any of which could be | Each connection possesses a set of connection identifiers, or | |||
| used to distinguish it from other connections. Connection IDs are | connection IDs, each of which can be identify the connection. | |||
| selected independently in each direction. Each Connection ID has an | Connection IDs are independently selected by endpoints; each endpoint | |||
| associated sequence number to assist in deduplicating messages. | selects the connection IDs that its peer uses. | |||
| The primary function of a connection ID is to ensure that changes in | The primary function of a connection ID is to ensure that changes in | |||
| addressing at lower protocol layers (UDP, IP, and below) don't cause | addressing at lower protocol layers (UDP, IP, and below) don't cause | |||
| packets for a QUIC connection to be delivered to the wrong endpoint. | packets for a QUIC connection to be delivered to the wrong endpoint. | |||
| Each endpoint selects connection IDs using an implementation-specific | Each endpoint selects connection IDs using an implementation-specific | |||
| (and perhaps deployment-specific) method which will allow packets | (and perhaps deployment-specific) method which will allow packets | |||
| with that connection ID to be routed back to the endpoint and | with that connection ID to be routed back to the endpoint and | |||
| identified by the endpoint upon receipt. | identified by the endpoint upon receipt. | |||
| Connection IDs MUST NOT contain any information that can be used to | Connection IDs MUST NOT contain any information that can be used to | |||
| correlate them with other connection IDs for the same connection. As | correlate them with other connection IDs for the same connection. As | |||
| a trivial example, this means the same connection ID MUST NOT be | a trivial example, this means the same connection ID MUST NOT be | |||
| issued more than once on the same connection. | issued more than once on the same connection. | |||
| Packets with long headers include Source Connection ID and | ||||
| Destination Connection ID fields. These fields are used to set the | ||||
| connection IDs for new connections, see Section 7.2 for details. | ||||
| Packets with short headers (Section 17.3) only include the | ||||
| Destination Connection ID and omit the explicit length. The length | ||||
| of the Destination Connection ID field is expected to be known to | ||||
| endpoints. Endpoints using a load balancer that routes based on | ||||
| connection ID could agree with the load balancer on a fixed length | ||||
| for connection IDs, or agree on an encoding scheme. A fixed portion | ||||
| could encode an explicit length, which allows the entire connection | ||||
| ID to vary in length and still be used by the load balancer. | ||||
| A Version Negotiation (Section 17.4) packet echoes the connection IDs | ||||
| selected by the client, both to ensure correct routing toward the | ||||
| client and to allow the client to validate that the packet is in | ||||
| response to an Initial packet. | ||||
| A zero-length connection ID MAY be used when the connection ID is not | A zero-length connection ID MAY be used when the connection ID is not | |||
| needed for routing and the address/port tuple of packets is | needed for routing and the address/port tuple of packets is | |||
| sufficient to identify a connection. An endpoint whose peer has | sufficient to identify a connection. An endpoint whose peer has | |||
| selected a zero-length connection ID MUST continue to use a zero- | selected a zero-length connection ID MUST continue to use a zero- | |||
| length connection ID for the lifetime of the connection and MUST NOT | length connection ID for the lifetime of the connection and MUST NOT | |||
| send packets from any other local address. | send packets from any other local address. | |||
| When an endpoint has requested a non-zero-length connection ID, it | When an endpoint has requested a non-zero-length connection ID, it | |||
| needs to ensure that the peer has a supply of connection IDs from | needs to ensure that the peer has a supply of connection IDs from | |||
| which to choose for packets sent to the endpoint. These connection | which to choose for packets sent to the endpoint. These connection | |||
| IDs are supplied by the endpoint using the NEW_CONNECTION_ID frame | IDs are supplied by the endpoint using the NEW_CONNECTION_ID frame | |||
| (Section 7.13). | (Section 19.12). | |||
| 6.1.1. Issuing Connection IDs | 5.1.1. Issuing Connection IDs | |||
| The initial connection ID issued by an endpoint is the Source | Each Connection ID has an associated sequence number to assist in | |||
| Connection ID during the handshake. The sequence number of the | deduplicating messages. The initial connection ID issued by an | |||
| initial connection ID is 0. If the preferred_address transport | endpoint is sent in the Source Connection ID field of the long packet | |||
| header (Section 17.2) during the handshake. The sequence number of | ||||
| the initial connection ID is 0. If the preferred_address transport | ||||
| parameter is sent, the sequence number of the supplied connection ID | parameter is sent, the sequence number of the supplied connection ID | |||
| is 1. Subsequent connection IDs are communicated to the peer using | is 1. | |||
| NEW_CONNECTION_ID frames (Section 7.13), and the sequence number on | ||||
| Additional connection IDs are communicated to the peer using | ||||
| NEW_CONNECTION_ID frames (Section 19.12). The sequence number on | ||||
| each newly-issued connection ID MUST increase by 1. The connection | each newly-issued connection ID MUST increase by 1. The connection | |||
| ID randomly selected by the client in the Initial packet and any | ID randomly selected by the client in the Initial packet and any | |||
| connection ID provided by a Reset packet are not assigned sequence | connection ID provided by a Reset packet are not assigned sequence | |||
| numbers unless a server opts to retain them as its initial connection | numbers unless a server opts to retain them as its initial connection | |||
| ID. | ID. | |||
| When an endpoint issues a connection ID, it MUST accept packets that | When an endpoint issues a connection ID, it MUST accept packets that | |||
| carry this connection ID for the duration of the connection or until | carry this connection ID for the duration of the connection or until | |||
| its peer invalidates the connection ID via a RETIRE_CONNECTION_ID | its peer invalidates the connection ID via a RETIRE_CONNECTION_ID | |||
| frame (Section 7.14). | frame (Section 19.13). | |||
| An endpoint SHOULD ensure that its peer has a sufficient number of | An endpoint SHOULD ensure that its peer has a sufficient number of | |||
| available and unused connection IDs. While each endpoint | available and unused connection IDs. While each endpoint | |||
| independently chooses how many connection IDs to issue, endpoints | independently chooses how many connection IDs to issue, endpoints | |||
| SHOULD provide and maintain at least eight connection IDs. The | SHOULD provide and maintain at least eight connection IDs. The | |||
| endpoint can do this by always supplying a new connection ID when a | endpoint can do this by always supplying a new connection ID when a | |||
| connection ID is retired by its peer or when the endpoint receives a | connection ID is retired by its peer or when the endpoint receives a | |||
| packet with a previously unused connection ID. Endpoints that | packet with a previously unused connection ID. Endpoints that | |||
| initiate migration and require non-zero-length connection IDs SHOULD | initiate migration and require non-zero-length connection IDs SHOULD | |||
| provide their peers with new connection IDs before migration, or risk | provide their peers with new connection IDs before migration, or risk | |||
| the peer closing the connection. | the peer closing the connection. | |||
| 6.1.2. Consuming and Retiring Connection IDs | 5.1.2. Consuming and Retiring Connection IDs | |||
| An endpoint can change the connection ID it uses for a peer to | An endpoint can change the connection ID it uses for a peer to | |||
| another available one at any time during the connection. An endpoint | another available one at any time during the connection. An endpoint | |||
| consumes connection IDs in response to a migrating peer, see | consumes connection IDs in response to a migrating peer, see | |||
| Section 6.11.5 for more. | Section 9.5 for more. | |||
| An endpoint maintains a set of connection IDs received from its peer, | An endpoint maintains a set of connection IDs received from its peer, | |||
| any of which it can use when sending packets. When the endpoint | any of which it can use when sending packets. When the endpoint | |||
| wishes to remove a connection ID from use, it sends a | wishes to remove a connection ID from use, it sends a | |||
| RETIRE_CONNECTION_ID frame to its peer, indicating that the peer | RETIRE_CONNECTION_ID frame to its peer, indicating that the peer | |||
| might bring a new connection ID into circulation using the | might bring a new connection ID into circulation using the | |||
| NEW_CONNECTION_ID frame. | NEW_CONNECTION_ID frame. | |||
| An endpoint that retires a connection ID can retain knowledge of that | An endpoint that retires a connection ID can retain knowledge of that | |||
| connection ID for a period of time after sending the | connection ID for a period of time after sending the | |||
| RETIRE_CONNECTION_ID frame, or until that frame is acknowledged. | RETIRE_CONNECTION_ID frame, or until that frame is acknowledged. | |||
| As discussed in Section 6.11.5, each connection ID MUST be used on | As discussed in Section 9.5, each connection ID MUST be used on | |||
| packets sent from only one local address. An endpoint that migrates | packets sent from only one local address. An endpoint that migrates | |||
| away from a local address SHOULD retire all connection IDs used on | away from a local address SHOULD retire all connection IDs used on | |||
| that address once it no longer plans to use that address. | that address once it no longer plans to use that address. | |||
| 6.2. Matching Packets to Connections | 5.2. Matching Packets to Connections | |||
| Incoming packets are classified on receipt. Packets can either be | Incoming packets are classified on receipt. Packets can either be | |||
| associated with an existing connection, or - for servers - | associated with an existing connection, or - for servers - | |||
| potentially create a new connection. | potentially create a new connection. | |||
| Hosts try to associate a packet with an existing connection. If the | Hosts try to associate a packet with an existing connection. If the | |||
| packet has a Destination Connection ID corresponding to an existing | packet has a Destination Connection ID corresponding to an existing | |||
| connection, QUIC processes that packet accordingly. Note that more | connection, QUIC processes that packet accordingly. Note that more | |||
| than one connection ID can be associated with a connection; see | than one connection ID can be associated with a connection; see | |||
| Section 6.1. | Section 5.1. | |||
| If the Destination Connection ID is zero length and the packet | If the Destination Connection ID is zero length and the packet | |||
| matches the address/port tuple of a connection where the host did not | matches the address/port tuple of a connection where the host did not | |||
| require connection IDs, QUIC processes the packet as part of that | require connection IDs, QUIC processes the packet as part of that | |||
| connection. Endpoints MUST drop packets with zero-length Destination | connection. Endpoints MUST drop packets with zero-length Destination | |||
| Connection ID fields if they do not correspond to a single | Connection ID fields if they do not correspond to a single | |||
| connection. | connection. | |||
| Endpoints SHOULD send a Stateless Reset (Section 6.13.4) for any | Endpoints SHOULD send a Stateless Reset (Section 10.4) for any | |||
| packets that cannot be attributed to an existing connection. | packets that cannot be attributed to an existing connection. | |||
| 6.2.1. Client Packet Handling | Packets that are matched to an existing connection, but for which the | |||
| endpoint cannot remove packet protection, are discarded. | ||||
| 5.2.1. Client Packet Handling | ||||
| Valid packets sent to clients always include a Destination Connection | Valid packets sent to clients always include a Destination Connection | |||
| ID that matches the value the client selects. Clients that choose to | ID that matches a value the client selects. Clients that choose to | |||
| receive zero-length connection IDs can use the address/port tuple to | receive zero-length connection IDs can use the address/port tuple to | |||
| identify a connection. Packets that don't match an existing | identify a connection. Packets that don't match an existing | |||
| connection are discarded. | connection are discarded. | |||
| Due to packet reordering or loss, clients might receive packets for a | Due to packet reordering or loss, clients might receive packets for a | |||
| connection that are encrypted with a key it has not yet computed. | connection that are encrypted with a key it has not yet computed. | |||
| Clients MAY drop these packets, or MAY buffer them in anticipation of | Clients MAY drop these packets, or MAY buffer them in anticipation of | |||
| later packets that allow it to compute the key. | later packets that allow it to compute the key. | |||
| If a client receives a packet that has an unsupported version, it | If a client receives a packet that has an unsupported version, it | |||
| MUST discard that packet. | MUST discard that packet. | |||
| 6.2.2. Server Packet Handling | 5.2.2. Server Packet Handling | |||
| If a server receives a packet that has an unsupported version, but | If a server receives a packet that has an unsupported version, but | |||
| the packet is sufficiently large to initiate a new connection for any | the packet is sufficiently large to initiate a new connection for any | |||
| version supported by the server, it SHOULD send a Version Negotiation | version supported by the server, it SHOULD send a Version Negotiation | |||
| packet as described in Section 6.3.1. Servers MAY rate control these | packet as described in Section 6.1. Servers MAY rate control these | |||
| packets to avoid storms of Version Negotiation packets. | packets to avoid storms of Version Negotiation packets. | |||
| The first packet for an unsupported version can use different | The first packet for an unsupported version can use different | |||
| semantics and encodings for any version-specific field. In | semantics and encodings for any version-specific field. In | |||
| particular, different packet protection keys might be used for | particular, different packet protection keys might be used for | |||
| different versions. Servers that do not support a particular version | different versions. Servers that do not support a particular version | |||
| are unlikely to be able to decrypt the payload of the packet. | are unlikely to be able to decrypt the payload of the packet. | |||
| Servers SHOULD NOT attempt to decode or decrypt a packet from an | Servers SHOULD NOT attempt to decode or decrypt a packet from an | |||
| unknown version, but instead send a Version Negotiation packet, | unknown version, but instead send a Version Negotiation packet, | |||
| provided that the packet is sufficiently long. | provided that the packet is sufficiently long. | |||
| Servers MUST drop other packets that contain unsupported versions. | Servers MUST drop other packets that contain unsupported versions. | |||
| Packets with a supported version, or no version field, are matched to | Packets with a supported version, or no version field, are matched to | |||
| a connection as described in Section 6.2. If not matched, the server | a connection using the connection ID or - for packets with zero- | |||
| continues below. | length connection IDs - the address tuple. If the packet doesn't | |||
| match an existing connection, the server continues below. | ||||
| If the packet is an Initial packet fully conforming with the | If the packet is an Initial packet fully conforming with the | |||
| specification, the server proceeds with the handshake (Section 6.4). | specification, the server proceeds with the handshake (Section 7). | |||
| This commits the server to the version that the client selected. | This commits the server to the version that the client selected. | |||
| If a server isn't currently accepting any new connections, it SHOULD | If a server isn't currently accepting any new connections, it SHOULD | |||
| send an Initial packet containing a CONNECTION_CLOSE frame with error | send an Initial packet containing a CONNECTION_CLOSE frame with error | |||
| code SERVER_BUSY. | code SERVER_BUSY. | |||
| If the packet is a 0-RTT packet, the server MAY buffer a limited | If the packet is a 0-RTT packet, the server MAY buffer a limited | |||
| number of these packets in anticipation of a late-arriving Initial | number of these packets in anticipation of a late-arriving Initial | |||
| Packet. Clients are forbidden from sending Handshake packets prior | Packet. Clients are forbidden from sending Handshake packets prior | |||
| to receiving a server response, so servers SHOULD ignore any such | to receiving a server response, so servers SHOULD ignore any such | |||
| packets. | packets. | |||
| Servers MUST drop incoming packets under all other circumstances. | Servers MUST drop incoming packets under all other circumstances. | |||
| 6.3. Version Negotiation | 5.3. Life of a QUIC Connection | |||
| TBD. | ||||
| 6. Version Negotiation | ||||
| Version negotiation ensures that client and server agree to a QUIC | Version negotiation ensures that client and server agree to a QUIC | |||
| version that is mutually supported. A server sends a Version | version that is mutually supported. A server sends a Version | |||
| Negotiation packet in response to each packet that might initiate a | Negotiation packet in response to each packet that might initiate a | |||
| new connection, see Section 6.2 for details. | new connection, see Section 5.2 for details. | |||
| The first few messages of an exchange between a client attempting to | ||||
| create a new connection with server is shown in Figure 3. After | ||||
| version negotiation completes, connection establishment can proceed, | ||||
| for example as shown in Section 7.1. | ||||
| Client Server | ||||
| Packet (v=X) -> | ||||
| <- Version Negotiation (supported=Y,Z) | ||||
| Packet (v=Y) -> | ||||
| <- Packet(s) (v=Y) | ||||
| Figure 3: Example Version Negotiation Exchange | ||||
| The size of the first packet sent by a client will determine whether | The size of the first packet sent by a client will determine whether | |||
| a server sends a Version Negotiation packet. Clients that support | a server sends a Version Negotiation packet. Clients that support | |||
| multiple QUIC versions SHOULD pad the first packet they send to the | multiple QUIC versions SHOULD pad the first packet they send to the | |||
| largest of the minimum packet sizes across all versions they support. | largest of the minimum packet sizes across all versions they support. | |||
| This ensures that the server responds if there is a mutually | This ensures that the server responds if there is a mutually | |||
| supported version. | supported version. | |||
| 6.3.1. Sending Version Negotiation Packets | 6.1. Sending Version Negotiation Packets | |||
| If the version selected by the client is not acceptable to the | If the version selected by the client is not acceptable to the | |||
| server, the server responds with a Version Negotiation packet (see | server, the server responds with a Version Negotiation packet (see | |||
| Section 4.3). This includes a list of versions that the server will | Section 17.4). This includes a list of versions that the server will | |||
| accept. | accept. | |||
| This system allows a server to process packets with unsupported | This system allows a server to process packets with unsupported | |||
| versions without retaining state. Though either the Initial packet | versions without retaining state. Though either the Initial packet | |||
| or the Version Negotiation packet that is sent in response could be | or the Version Negotiation packet that is sent in response could be | |||
| lost, the client will send new packets until it successfully receives | lost, the client will send new packets until it successfully receives | |||
| a response or it abandons the connection attempt. | a response or it abandons the connection attempt. | |||
| 6.3.2. Handling Version Negotiation Packets | A server MAY limit the number of Version Negotiation packets it | |||
| sends. For instance, a server that is able to recognize packets as | ||||
| 0-RTT might choose not to send Version Negotiation packets in | ||||
| response to 0-RTT packets with the expectation that it will | ||||
| eventually receive an Initial packet. | ||||
| 6.2. Handling Version Negotiation Packets | ||||
| When the client receives a Version Negotiation packet, it first | When the client receives a Version Negotiation packet, it first | |||
| checks that the Destination and Source Connection ID fields match the | checks that the Destination and Source Connection ID fields match the | |||
| Source and Destination Connection ID fields in a packet that the | Source and Destination Connection ID fields in a packet that the | |||
| client sent. If this check fails, the packet MUST be discarded. | client sent. If this check fails, the packet MUST be discarded. | |||
| Once the Version Negotiation packet is determined to be valid, the | Once the Version Negotiation packet is determined to be valid, the | |||
| client then selects an acceptable protocol version from the list | client then selects an acceptable protocol version from the list | |||
| provided by the server. The client then attempts to create a | provided by the server. The client then attempts to create a | |||
| connection using that version. Though the content of the Initial | connection using that version. Though the content of the Initial | |||
| packet the client sends might not change in response to version | packet the client sends might not change in response to version | |||
| negotiation, a client MUST increase the packet number it uses on | negotiation, a client MUST increase the packet number it uses on | |||
| every packet it sends. Packets MUST continue to use long headers and | every packet it sends. Packets MUST continue to use long headers | |||
| MUST include the new negotiated protocol version. | (Section 17.2) and MUST include the new negotiated protocol version. | |||
| The client MUST use the long header format and include its selected | The client MUST use the long header format and include its selected | |||
| version on all packets until it has 1-RTT keys and it has received a | version on all packets until it has 1-RTT keys and it has received a | |||
| packet from the server which is not a Version Negotiation packet. | packet from the server which is not a Version Negotiation packet. | |||
| A client MUST NOT change the version it uses unless it is in response | A client MUST NOT change the version it uses unless it is in response | |||
| to a Version Negotiation packet from the server. Once a client | to a Version Negotiation packet from the server. Once a client | |||
| receives a packet from the server which is not a Version Negotiation | receives a packet from the server which is not a Version Negotiation | |||
| packet, it MUST discard other Version Negotiation packets on the same | packet, it MUST discard other Version Negotiation packets on the same | |||
| connection. Similarly, a client MUST ignore a Version Negotiation | connection. Similarly, a client MUST ignore a Version Negotiation | |||
| packet if it has already received and acted on a Version Negotiation | packet if it has already received and acted on a Version Negotiation | |||
| packet. | packet. | |||
| A client MUST ignore a Version Negotiation packet that lists the | A client MUST ignore a Version Negotiation packet that lists the | |||
| client's chosen version. | client's chosen version. | |||
| A client MAY attempt 0-RTT after receiving a Version Negotiation | A client MAY attempt 0-RTT after receiving a Version Negotiation | |||
| packet. A client that sends additional 0-RTT packets MUST NOT reset | packet. A client that sends additional 0-RTT packets MUST NOT reset | |||
| the packet number to 0 as a result, see Section 4.6.4. | the packet number to 0 as a result, see Section 17.5.2. | |||
| Version negotiation packets have no cryptographic protection. The | Version negotiation packets have no cryptographic protection. The | |||
| result of the negotiation MUST be revalidated as part of the | result of the negotiation MUST be revalidated as part of the | |||
| cryptographic handshake (see Section 6.6.4). | cryptographic handshake (see Section 7.3.3). | |||
| 6.3.3. Using Reserved Versions | 6.3. Using Reserved Versions | |||
| For a server to use a new version in the future, clients must | For a server to use a new version in the future, clients must | |||
| correctly handle unsupported versions. To help ensure this, a server | correctly handle unsupported versions. To help ensure this, a server | |||
| SHOULD include a reserved version (see Section 3) while generating a | SHOULD include a reserved version (see Section 15) while generating a | |||
| Version Negotiation packet. | Version Negotiation packet. | |||
| The design of version negotiation permits a server to avoid | The design of version negotiation permits a server to avoid | |||
| maintaining state for packets that it rejects in this fashion. The | maintaining state for packets that it rejects in this fashion. The | |||
| validation of version negotiation (see Section 6.6.4) only validates | validation of version negotiation (see Section 7.3.3) only validates | |||
| the result of version negotiation, which is the same no matter which | the result of version negotiation, which is the same no matter which | |||
| reserved version was sent. A server MAY therefore send different | reserved version was sent. A server MAY therefore send different | |||
| reserved version numbers in the Version Negotiation Packet and in its | reserved version numbers in the Version Negotiation Packet and in its | |||
| transport parameters. | transport parameters. | |||
| A client MAY send a packet using a reserved version number. This can | A client MAY send a packet using a reserved version number. This can | |||
| be used to solicit a list of supported versions from a server. | be used to solicit a list of supported versions from a server. | |||
| 6.4. Cryptographic and Transport Handshake | 7. Cryptographic and Transport Handshake | |||
| QUIC relies on a combined cryptographic and transport handshake to | QUIC relies on a combined cryptographic and transport handshake to | |||
| minimize connection establishment latency. QUIC uses the CRYPTO | minimize connection establishment latency. QUIC uses the CRYPTO | |||
| frame Section 7.21 to transmit the cryptographic handshake. Version | frame Section 19.20 to transmit the cryptographic handshake. Version | |||
| 0x00000001 of QUIC uses TLS 1.3 as described in [QUIC-TLS]; a | 0x00000001 of QUIC uses TLS 1.3 as described in [QUIC-TLS]; a | |||
| different QUIC version number could indicate that a different | different QUIC version number could indicate that a different | |||
| cryptographic handshake protocol is in use. | cryptographic handshake protocol is in use. | |||
| QUIC provides reliable, ordered delivery of the cryptographic | QUIC provides reliable, ordered delivery of the cryptographic | |||
| handshake data. QUIC packet protection ensures confidentiality and | handshake data. QUIC packet protection ensures confidentiality and | |||
| integrity protection that meets the requirements of the cryptographic | integrity protection that meets the requirements of the cryptographic | |||
| handshake protocol: | handshake protocol: | |||
| o authenticated key exchange, where | o authenticated key exchange, where | |||
| skipping to change at page 36, line 41 ¶ | skipping to change at page 31, line 33 ¶ | |||
| * a client is optionally authenticated, | * a client is optionally authenticated, | |||
| * every connection produces distinct and unrelated keys, | * every connection produces distinct and unrelated keys, | |||
| * keying material is usable for packet protection for both 0-RTT | * keying material is usable for packet protection for both 0-RTT | |||
| and 1-RTT packets, and | and 1-RTT packets, and | |||
| * 1-RTT keys have forward secrecy | * 1-RTT keys have forward secrecy | |||
| o authenticated values for the transport parameters of the peer (see | o authenticated values for the transport parameters of the peer (see | |||
| Section 6.6) | Section 7.3) | |||
| o authenticated confirmation of version negotiation (see | o authenticated confirmation of version negotiation (see | |||
| Section 6.6.4) | Section 7.3.3) | |||
| o authenticated negotiation of an application protocol (TLS uses | o authenticated negotiation of an application protocol (TLS uses | |||
| ALPN [RFC7301] for this purpose) | ALPN [RFC7301] for this purpose) | |||
| o for the server, the ability to carry data that provides assurance | The first CRYPTO frame from a client MUST be sent in a single packet. | |||
| that the client can receive packets that are addressed with the | Any second attempt that is triggered by address validation (see | |||
| transport address that is claimed by the client (see Section 6.9) | Section 8.1) MUST also be sent within a single packet. This avoids | |||
| having to reassemble a message from multiple packets. | ||||
| The first CRYPTO frame MUST be sent in a single packet. Any second | ||||
| attempt that is triggered by address validation MUST also be sent | ||||
| within a single packet. This avoids having to reassemble a message | ||||
| from multiple packets. | ||||
| The first client packet of the cryptographic handshake protocol MUST | The first client packet of the cryptographic handshake protocol MUST | |||
| fit within a 1232 octet QUIC packet payload. This includes overheads | fit within a 1232 octet QUIC packet payload. This includes overheads | |||
| that reduce the space available to the cryptographic handshake | that reduce the space available to the cryptographic handshake | |||
| protocol. | protocol. | |||
| The CRYPTO frame can be sent in different packet number spaces. | The CRYPTO frame can be sent in different packet number spaces. The | |||
| CRYPTO frames in each packet number space carry a separate sequence | sequence numbers used by CRYPTO frames to ensure ordered delivery of | |||
| of handshake data starting from an offset of 0. | cryptographic handshake data start from zero in each packet number | |||
| space. | ||||
| 6.5. Example Handshake Flows | 7.1. Example Handshake Flows | |||
| Details of how TLS is integrated with QUIC are provided in | Details of how TLS is integrated with QUIC are provided in | |||
| [QUIC-TLS], but some examples are provided here. | [QUIC-TLS], but some examples are provided here. An extension of | |||
| this exchange to support client address validation is shown in | ||||
| Section 8.1.1. | ||||
| Figure 8 provides an overview of the 1-RTT handshake. Each line | Once any version negotiation and address validation exchanges are | |||
| complete, the cryptographic handshake is used to agree on | ||||
| cryptographic keys. The cryptographic handshake is carried in | ||||
| Initial (Section 17.5) and Handshake (Section 17.6) packets. | ||||
| Figure 4 provides an overview of the 1-RTT handshake. Each line | ||||
| shows a QUIC packet with the packet type and packet number shown | shows a QUIC packet with the packet type and packet number shown | |||
| first, followed by the frames that are typically contained in those | first, followed by the frames that are typically contained in those | |||
| packets. So, for instance the first packet is of type Initial, with | packets. So, for instance the first packet is of type Initial, with | |||
| packet number 0, and contains a CRYPTO frame carrying the | packet number 0, and contains a CRYPTO frame carrying the | |||
| ClientHello. | ClientHello. | |||
| Note that multiple QUIC packets - even of different encryption levels | Note that multiple QUIC packets - even of different encryption levels | |||
| - may be coalesced into a single UDP datagram (see Section 4.9), and | - may be coalesced into a single UDP datagram (see Section 12.2), and | |||
| so this handshake may consist of as few as 4 UDP datagrams, or any | so this handshake may consist of as few as 4 UDP datagrams, or any | |||
| number more. For instance, the server's first flight contains | number more. For instance, the server's first flight contains | |||
| packets from the Initial encryption level (obfuscation), the | packets from the Initial encryption level (obfuscation), the | |||
| Handshake level, and "0.5-RTT data" from the server at the 1-RTT | Handshake level, and "0.5-RTT data" from the server at the 1-RTT | |||
| encryption level. | encryption level. | |||
| Client Server | Client Server | |||
| Initial[0]: CRYPTO[CH] -> | Initial[0]: CRYPTO[CH] -> | |||
| skipping to change at page 38, line 20 ¶ | skipping to change at page 32, line 49 ¶ | |||
| Handshake[0]: CRYPTO[EE, CERT, CV, FIN] | Handshake[0]: CRYPTO[EE, CERT, CV, FIN] | |||
| <- 1-RTT[0]: STREAM[1, "..."] | <- 1-RTT[0]: STREAM[1, "..."] | |||
| Initial[1]: ACK[0] | Initial[1]: ACK[0] | |||
| Handshake[0]: CRYPTO[FIN], ACK[0] | Handshake[0]: CRYPTO[FIN], ACK[0] | |||
| 1-RTT[0]: STREAM[0, "..."], ACK[0] -> | 1-RTT[0]: STREAM[0, "..."], ACK[0] -> | |||
| 1-RTT[1]: STREAM[55, "..."], ACK[0] | 1-RTT[1]: STREAM[55, "..."], ACK[0] | |||
| <- Handshake[1]: ACK[0] | <- Handshake[1]: ACK[0] | |||
| Figure 8: Example 1-RTT Handshake | Figure 4: Example 1-RTT Handshake | |||
| Figure 9 shows an example of a connection with a 0-RTT handshake and | Figure 5 shows an example of a connection with a 0-RTT handshake and | |||
| a single packet of 0-RTT data. Note that as described in | a single packet of 0-RTT data. Note that as described in | |||
| Section 4.11, the server ACKs the 0-RTT data at the 1-RTT encryption | Section 12.3, the server acknowledges 0-RTT data at the 1-RTT | |||
| level, and the client's sequence numbers at the 1-RTT encryption | encryption level, and the client sends 1-RTT packets in the same | |||
| level continue to increment from its 0-RTT packets. | packet number space. | |||
| Client Server | Client Server | |||
| Initial[0]: CRYPTO[CH] | Initial[0]: CRYPTO[CH] | |||
| 0-RTT[0]: STREAM[0, "..."] -> | 0-RTT[0]: STREAM[0, "..."] -> | |||
| Initial[0]: CRYPTO[SH] ACK[0] | Initial[0]: CRYPTO[SH] ACK[0] | |||
| Handshake[0] CRYPTO[EE, CERT, CV, FIN] | Handshake[0] CRYPTO[EE, CERT, CV, FIN] | |||
| <- 1-RTT[0]: STREAM[1, "..."] ACK[0] | <- 1-RTT[0]: STREAM[1, "..."] ACK[0] | |||
| Initial[1]: ACK[0] | Initial[1]: ACK[0] | |||
| 0-RTT[1]: CRYPTO[EOED] | ||||
| Handshake[0]: CRYPTO[FIN], ACK[0] | Handshake[0]: CRYPTO[FIN], ACK[0] | |||
| 1-RTT[2]: STREAM[0, "..."] ACK[0] -> | 1-RTT[2]: STREAM[0, "..."] ACK[0] -> | |||
| 1-RTT[1]: STREAM[55, "..."], ACK[1,2] | 1-RTT[1]: STREAM[55, "..."], ACK[1,2] | |||
| <- Handshake[1]: ACK[0] | <- Handshake[1]: ACK[0] | |||
| Figure 9: Example 0-RTT Handshake | Figure 5: Example 0-RTT Handshake | |||
| 6.6. Transport Parameters | 7.2. Negotiating Connection IDs | |||
| During connection establishment, both endpoints make authenticated | A connection ID is used to ensure consistent routing of packets, as | |||
| declarations of their transport parameters. These declarations are | described in Section 5.1. The long header contains two connection | |||
| made unilaterally by each endpoint. Endpoints are required to comply | IDs: the Destination Connection ID is chosen by the recipient of the | |||
| with the restrictions implied by these parameters; the description of | packet and is used to provide consistent routing; the Source | |||
| each parameter includes rules for its handling. | Connection ID is used to set the Destination Connection ID used by | |||
| the peer. | ||||
| The format of the transport parameters is the TransportParameters | During the handshake, packets with the long header (Section 17.2) are | |||
| struct from Figure 10. This is described using the presentation | used to establish the connection ID that each endpoint uses. Each | |||
| language from Section 3 of [TLS13]. | endpoint uses the Source Connection ID field to specify the | |||
| connection ID that is used in the Destination Connection ID field of | ||||
| packets being sent to them. Upon receiving a packet, each endpoint | ||||
| sets the Destination Connection ID it sends to match the value of the | ||||
| Source Connection ID that they receive. | ||||
| uint32 QuicVersion; | When an Initial packet is sent by a client which has not previously | |||
| received a Retry packet from the server, it populates the Destination | ||||
| Connection ID field with an unpredictable value. This MUST be at | ||||
| least 8 octets in length. Until a packet is received from the | ||||
| server, the client MUST use the same value unless it abandons the | ||||
| connection attempt and starts a new one. The initial Destination | ||||
| Connection ID is used to determine packet protection keys for Initial | ||||
| packets. | ||||
| enum { | The client populates the Source Connection ID field with a value of | |||
| initial_max_stream_data_bidi_local(0), | its choosing and sets the SCIL field to match. | |||
| initial_max_data(1), | ||||
| initial_max_bidi_streams(2), | ||||
| idle_timeout(3), | ||||
| preferred_address(4), | ||||
| max_packet_size(5), | ||||
| stateless_reset_token(6), | ||||
| ack_delay_exponent(7), | ||||
| initial_max_uni_streams(8), | ||||
| disable_migration(9), | ||||
| initial_max_stream_data_bidi_remote(10), | ||||
| initial_max_stream_data_uni(11), | ||||
| max_ack_delay(12), | ||||
| original_connection_id(13), | ||||
| (65535) | ||||
| } TransportParameterId; | ||||
| struct { | The Destination Connection ID field in the server's Initial packet | |||
| TransportParameterId parameter; | contains a connection ID that is chosen by the recipient of the | |||
| opaque value<0..2^16-1>; | packet (i.e., the client); the Source Connection ID includes the | |||
| } TransportParameter; | connection ID that the sender of the packet wishes to use (see | |||
| Section 5.1). The server MUST use consistent Source Connection IDs | ||||
| during the handshake. | ||||
| struct { | On first receiving an Initial or Retry packet from the server, the | |||
| select (Handshake.msg_type) { | client uses the Source Connection ID supplied by the server as the | |||
| case client_hello: | Destination Connection ID for subsequent packets. That means that a | |||
| QuicVersion initial_version; | client might change the Destination Connection ID twice during | |||
| connection establishment. Once a client has received an Initial | ||||
| packet from the server, it MUST discard any packet it receives with a | ||||
| different Source Connection ID. | ||||
| case encrypted_extensions: | A client MUST only change the value it sends in the Destination | |||
| QuicVersion negotiated_version; | Connection ID in response to the first packet of each type it | |||
| QuicVersion supported_versions<4..2^8-4>; | receives from the server (Retry or Initial); a server MUST set its | |||
| }; | value based on the Initial packet. Any additional changes are not | |||
| TransportParameter parameters<22..2^16-1>; | permitted; if subsequent packets of those types include a different | |||
| } TransportParameters; | Source Connection ID, they MUST be discarded. This avoids problems | |||
| that might arise from stateless processing of multiple Initial | ||||
| packets producing different connection IDs. | ||||
| struct { | The connection ID can change over the lifetime of a connection, | |||
| enum { IPv4(4), IPv6(6), (15) } ipVersion; | especially in response to connection migration (Section 9), see | |||
| opaque ipAddress<4..2^8-1>; | Section 5.1.1 for details. | |||
| uint16 port; | ||||
| opaque connectionId<0..18>; | ||||
| opaque statelessResetToken[16]; | ||||
| } PreferredAddress; | ||||
| Figure 10: Definition of TransportParameters | 7.3. Transport Parameters | |||
| The "extension_data" field of the quic_transport_parameters extension | During connection establishment, both endpoints make authenticated | |||
| defined in [QUIC-TLS] contains a TransportParameters value. TLS | declarations of their transport parameters. These declarations are | |||
| encoding rules are therefore used to encode the transport parameters. | made unilaterally by each endpoint. Endpoints are required to comply | |||
| with the restrictions implied by these parameters; the description of | ||||
| each parameter includes rules for its handling. | ||||
| QUIC encodes transport parameters into a sequence of octets, which | The encoding of the transport parameters is detailed in Section 18. | |||
| are then included in the cryptographic handshake. Once the handshake | ||||
| completes, the transport parameters declared by the peer are | QUIC includes the encoded transport parameters in the cryptographic | |||
| available. Each endpoint validates the value provided by its peer. | handshake. Once the handshake completes, the transport parameters | |||
| In particular, version negotiation MUST be validated (see | declared by the peer are available. Each endpoint validates the | |||
| Section 6.6.4) before the connection establishment is considered | value provided by its peer. In particular, version negotiation MUST | |||
| properly complete. | be validated (see Section 7.3.3) before the connection establishment | |||
| is considered properly complete. | ||||
| Definitions for each of the defined transport parameters are included | Definitions for each of the defined transport parameters are included | |||
| in Section 6.6.1. Any given parameter MUST appear at most once in a | in Section 18.1. Any given parameter MUST appear at most once in a | |||
| given transport parameters extension. An endpoint MUST treat receipt | given transport parameters extension. An endpoint MUST treat receipt | |||
| of duplicate transport parameters as a connection error of type | of duplicate transport parameters as a connection error of type | |||
| TRANSPORT_PARAMETER_ERROR. | TRANSPORT_PARAMETER_ERROR. | |||
| 6.6.1. Transport Parameter Definitions | ||||
| An endpoint MAY use the following transport parameters: | ||||
| initial_max_data (0x0001): The initial maximum data parameter | ||||
| contains the initial value for the maximum amount of data that can | ||||
| be sent on the connection. This parameter is encoded as an | ||||
| unsigned 32-bit integer in units of octets. This is equivalent to | ||||
| sending a MAX_DATA (Section 7.6) for the connection immediately | ||||
| after completing the handshake. If the transport parameter is | ||||
| absent, the connection starts with a flow control limit of 0. | ||||
| initial_max_bidi_streams (0x0002): The initial maximum bidirectional | ||||
| streams parameter contains the initial maximum number of | ||||
| bidirectional streams the peer may initiate, encoded as an | ||||
| unsigned 16-bit integer. If this parameter is absent or zero, | ||||
| bidirectional streams cannot be created until a MAX_STREAM_ID | ||||
| frame is sent. Setting this parameter is equivalent to sending a | ||||
| MAX_STREAM_ID (Section 7.8) immediately after completing the | ||||
| handshake containing the corresponding Stream ID. For example, a | ||||
| value of 0x05 would be equivalent to receiving a MAX_STREAM_ID | ||||
| containing 16 when received by a client or 17 when received by a | ||||
| server. | ||||
| initial_max_uni_streams (0x0008): The initial maximum unidirectional | ||||
| streams parameter contains the initial maximum number of | ||||
| unidirectional streams the peer may initiate, encoded as an | ||||
| unsigned 16-bit integer. If this parameter is absent or zero, | ||||
| unidirectional streams cannot be created until a MAX_STREAM_ID | ||||
| frame is sent. Setting this parameter is equivalent to sending a | ||||
| MAX_STREAM_ID (Section 7.8) immediately after completing the | ||||
| handshake containing the corresponding Stream ID. For example, a | ||||
| value of 0x05 would be equivalent to receiving a MAX_STREAM_ID | ||||
| containing 18 when received by a client or 19 when received by a | ||||
| server. | ||||
| idle_timeout (0x0003): The idle timeout is a value in seconds that | ||||
| is encoded as an unsigned 16-bit integer. If this parameter is | ||||
| absent or zero then the idle timeout is disabled. | ||||
| max_packet_size (0x0005): The maximum packet size parameter places a | ||||
| limit on the size of packets that the endpoint is willing to | ||||
| receive, encoded as an unsigned 16-bit integer. This indicates | ||||
| that packets larger than this limit will be dropped. The default | ||||
| for this parameter is the maximum permitted UDP payload of 65527. | ||||
| Values below 1200 are invalid. This limit only applies to | ||||
| protected packets (Section 4.8). | ||||
| ack_delay_exponent (0x0007): An 8-bit unsigned integer value | ||||
| indicating an exponent used to decode the ACK Delay field in the | ||||
| ACK frame, see Section 7.16. If this value is absent, a default | ||||
| value of 3 is assumed (indicating a multiplier of 8). The default | ||||
| value is also used for ACK frames that are sent in Initial and | ||||
| Handshake packets. Values above 20 are invalid. | ||||
| disable_migration (0x0009): The endpoint does not support connection | ||||
| migration (Section 6.11). Peers MUST NOT send any packets, | ||||
| including probing packets (Section 6.11.1), from a local address | ||||
| other than that used to perform the handshake. This parameter is | ||||
| a zero-length value. | ||||
| max_ack_delay (0x000c): An 8 bit unsigned integer value indicating | ||||
| the maximum amount of time in milliseconds by which it will delay | ||||
| sending of acknowledgments. If this value is absent, a default of | ||||
| 25 milliseconds is assumed. | ||||
| Either peer MAY advertise an initial value for the flow control on | ||||
| each type of stream on which they might receive data. Each of the | ||||
| following transport parameters is encoded as an unsigned 32-bit | ||||
| integer in units of octets: | ||||
| initial_max_stream_data_bidi_local (0x0000): The initial stream | ||||
| maximum data for bidirectional, locally-initiated streams | ||||
| parameter contains the initial flow control limit for newly | ||||
| created bidirectional streams opened by the endpoint that sets the | ||||
| transport parameter. In client transport parameters, this applies | ||||
| to streams with an identifier ending in 0x0; in server transport | ||||
| parameters, this applies to streams ending in 0x1. | ||||
| initial_max_stream_data_bidi_remote (0x000a): The initial stream | ||||
| maximum data for bidirectional, peer-initiated streams parameter | ||||
| contains the initial flow control limit for newly created | ||||
| bidirectional streams opened by the endpoint that receives the | ||||
| transport parameter. In client transport parameters, this applies | ||||
| to streams with an identifier ending in 0x1; in server transport | ||||
| parameters, this applies to streams ending in 0x0. | ||||
| initial_max_stream_data_uni (0x000b): The initial stream maximum | ||||
| data for unidirectional streams parameter contains the initial | ||||
| flow control limit for newly created unidirectional streams opened | ||||
| by the endpoint that receives the transport parameter. In client | ||||
| transport parameters, this applies to streams with an identifier | ||||
| ending in 0x3; in server transport parameters, this applies to | ||||
| streams ending in 0x2. | ||||
| If present, transport parameters that set initial stream flow control | ||||
| limits are equivalent to sending a MAX_STREAM_DATA frame | ||||
| (Section 7.7) on every stream of the corresponding type immediately | ||||
| after opening. If the transport parameter is absent, streams of that | ||||
| type start with a flow control limit of 0. | ||||
| A server MUST include the original_connection_id transport parameter | A server MUST include the original_connection_id transport parameter | |||
| if it sent a Retry packet: | (Section 18.1) if it sent a Retry packet. | |||
| original_connection_id (0x000d): The value of the Destination | ||||
| Connection ID field from the first Initial packet sent by the | ||||
| client. This transport parameter is only sent by the server. | ||||
| A server MAY include the following transport parameters: | ||||
| stateless_reset_token (0x0006): The Stateless Reset Token is used in | ||||
| verifying a stateless reset, see Section 6.13.4. This parameter | ||||
| is a sequence of 16 octets. | ||||
| preferred_address (0x0004): The server's Preferred Address is used | ||||
| to effect a change in server address at the end of the handshake, | ||||
| as described in Section 6.12. | ||||
| A client MUST NOT include a stateless reset token or a preferred | ||||
| address. A server MUST treat receipt of either transport parameter | ||||
| as a connection error of type TRANSPORT_PARAMETER_ERROR. | ||||
| 6.6.2. Values of Transport Parameters for 0-RTT | 7.3.1. Values of Transport Parameters for 0-RTT | |||
| A client that attempts to send 0-RTT data MUST remember the transport | A client that attempts to send 0-RTT data MUST remember the transport | |||
| parameters used by the server. The transport parameters that the | parameters used by the server. The transport parameters that the | |||
| server advertises during connection establishment apply to all | server advertises during connection establishment apply to all | |||
| connections that are resumed using the keying material established | connections that are resumed using the keying material established | |||
| during that handshake. Remembered transport parameters apply to the | during that handshake. Remembered transport parameters apply to the | |||
| new connection until the handshake completes and new transport | new connection until the handshake completes and new transport | |||
| parameters from the server can be provided. | parameters from the server can be provided. | |||
| A server can remember the transport parameters that it advertised, or | A server can remember the transport parameters that it advertised, or | |||
| store an integrity-protected copy of the values in the ticket and | store an integrity-protected copy of the values in the ticket and | |||
| recover the information when accepting 0-RTT data. A server uses the | recover the information when accepting 0-RTT data. A server uses the | |||
| transport parameters in determining whether to accept 0-RTT data. | transport parameters in determining whether to accept 0-RTT data. | |||
| A server MAY accept 0-RTT and subsequently provide different values | A server MAY accept 0-RTT and subsequently provide different values | |||
| for transport parameters for use in the new connection. If 0-RTT | for transport parameters for use in the new connection. If 0-RTT | |||
| data is accepted by the server, the server MUST NOT reduce any limits | data is accepted by the server, the server MUST NOT reduce any limits | |||
| or alter any values that might be violated by the client with its | or alter any values that might be violated by the client with its | |||
| 0-RTT data. In particular, a server that accepts 0-RTT data MUST NOT | 0-RTT data. In particular, a server that accepts 0-RTT data MUST NOT | |||
| set values for initial_max_data, initial_max_stream_data_bidi_local, | set values for initial_max_data, initial_max_stream_data_bidi_local, | |||
| initial_max_stream_data_bidi_remote, and initial_max_stream_data_uni | initial_max_stream_data_bidi_remote, initial_max_stream_data_uni, | |||
| initial_max_bidi_streams, or initial_max_uni_streams (Section 18.1) | ||||
| that are smaller than the remembered value of those parameters. | that are smaller than the remembered value of those parameters. | |||
| Similarly, a server MUST NOT reduce the value of | ||||
| initial_max_bidi_streams or initial_max_uni_streams. | ||||
| Omitting or setting a zero value for certain transport parameters can | Omitting or setting a zero value for certain transport parameters can | |||
| result in 0-RTT data being enabled, but not usable. The applicable | result in 0-RTT data being enabled, but not usable. The applicable | |||
| subset of transport parameters that permit sending of application | subset of transport parameters that permit sending of application | |||
| data SHOULD be set to non-zero values for 0-RTT. This includes | data SHOULD be set to non-zero values for 0-RTT. This includes | |||
| initial_max_data and either initial_max_bidi_streams and | initial_max_data and either initial_max_bidi_streams and | |||
| initial_max_stream_data_bidi_remote, or initial_max_uni_streams and | initial_max_stream_data_bidi_remote, or initial_max_uni_streams and | |||
| initial_max_stream_data_uni. | initial_max_stream_data_uni. | |||
| The value of the server's previous preferred_address MUST NOT be used | The value of the server's previous preferred_address MUST NOT be used | |||
| when establishing a new connection; rather, the client should wait to | when establishing a new connection; rather, the client should wait to | |||
| observe the server's new preferred_address value in the handshake. | observe the server's new preferred_address value in the handshake. | |||
| A server MUST reject 0-RTT data or even abort a handshake if the | A server MUST reject 0-RTT data or even abort a handshake if the | |||
| implied values for transport parameters cannot be supported. | implied values for transport parameters cannot be supported. | |||
| 6.6.3. New Transport Parameters | 7.3.2. New Transport Parameters | |||
| New transport parameters can be used to negotiate new protocol | New transport parameters can be used to negotiate new protocol | |||
| behavior. An endpoint MUST ignore transport parameters that it does | behavior. An endpoint MUST ignore transport parameters that it does | |||
| not support. Absence of a transport parameter therefore disables any | not support. Absence of a transport parameter therefore disables any | |||
| optional protocol feature that is negotiated using the parameter. | optional protocol feature that is negotiated using the parameter. | |||
| New transport parameters can be registered according to the rules in | New transport parameters can be registered according to the rules in | |||
| Section 13.1. | Section 22.1. | |||
| 6.6.4. Version Negotiation Validation | 7.3.3. Version Negotiation Validation | |||
| Though the cryptographic handshake has integrity protection, two | Though the cryptographic handshake has integrity protection, two | |||
| forms of QUIC version downgrade are possible. In the first, an | forms of QUIC version downgrade are possible. In the first, an | |||
| attacker replaces the QUIC version in the Initial packet. In the | attacker replaces the QUIC version in the Initial packet. In the | |||
| second, a fake Version Negotiation packet is sent by an attacker. To | second, a fake Version Negotiation packet is sent by an attacker. To | |||
| protect against these attacks, the transport parameters include three | protect against these attacks, the transport parameters include three | |||
| fields that encode version information. These parameters are used to | fields that encode version information. These parameters are used to | |||
| retroactively authenticate the choice of version (see Section 6.3). | retroactively authenticate the choice of version (see Section 6). | |||
| The cryptographic handshake provides integrity protection for the | The cryptographic handshake provides integrity protection for the | |||
| negotiated version as part of the transport parameters (see | negotiated version as part of the transport parameters (see | |||
| Section 6.6). As a result, attacks on version negotiation by an | Section 18.1). As a result, attacks on version negotiation by an | |||
| attacker can be detected. | attacker can be detected. | |||
| The client includes the initial_version field in its transport | The client includes the initial_version field in its transport | |||
| parameters. The initial_version is the version that the client | parameters. The initial_version is the version that the client | |||
| initially attempted to use. If the server did not send a Version | initially attempted to use. If the server did not send a Version | |||
| Negotiation packet Section 4.3, this will be identical to the | Negotiation packet Section 17.4, this will be identical to the | |||
| negotiated_version field in the server transport parameters. | negotiated_version field in the server transport parameters. | |||
| A server that processes all packets in a stateful fashion can | A server that processes all packets in a stateful fashion can | |||
| remember how version negotiation was performed and validate the | remember how version negotiation was performed and validate the | |||
| initial_version value. | initial_version value. | |||
| A server that does not maintain state for every packet it receives | A server that does not maintain state for every packet it receives | |||
| (i.e., a stateless server) uses a different process. If the | (i.e., a stateless server) uses a different process. If the | |||
| initial_version matches the version of QUIC that is in use, a | initial_version matches the version of QUIC that is in use, a | |||
| stateless server can accept the value. | stateless server can accept the value. | |||
| If the initial_version is different from the version of QUIC that is | If the initial_version is different from the version of QUIC that is | |||
| in use, a stateless server MUST check that it would have sent a | in use, a stateless server MUST check that it would have sent a | |||
| Version Negotiation packet if it had received a packet with the | Version Negotiation packet if it had received a packet with the | |||
| indicated initial_version. If a server would have accepted the | indicated initial_version. If a server would have accepted the | |||
| version included in the initial_version and the value differs from | version included in the initial_version and the value differs from | |||
| the QUIC version that is in use, the server MUST terminate the | the QUIC version that is in use, the server MUST terminate the | |||
| connection with a VERSION_NEGOTIATION_ERROR error. | connection with a VERSION_NEGOTIATION_ERROR error. | |||
| The server includes both the version of QUIC that is in use and a | The server includes both the version of QUIC that is in use and a | |||
| list of the QUIC versions that the server supports. | list of the QUIC versions that the server supports (see | |||
| Section 18.1). | ||||
| The negotiated_version field is the version that is in use. This | The negotiated_version field is the version that is in use. This | |||
| MUST be set by the server to the value that is on the Initial packet | MUST be set by the server to the value that is on the Initial packet | |||
| that it accepts (not an Initial packet that triggers a Retry or | that it accepts (not an Initial packet that triggers a Retry or | |||
| Version Negotiation packet). A client that receives a | Version Negotiation packet). A client that receives a | |||
| negotiated_version that does not match the version of QUIC that is in | negotiated_version that does not match the version of QUIC that is in | |||
| use MUST terminate the connection with a VERSION_NEGOTIATION_ERROR | use MUST terminate the connection with a VERSION_NEGOTIATION_ERROR | |||
| error code. | error code. | |||
| The server includes a list of versions that it would send in any | The server includes a list of versions that it would send in any | |||
| version negotiation packet (Section 4.3) in the supported_versions | version negotiation packet (Section 17.4) in the supported_versions | |||
| field. The server populates this field even if it did not send a | field. The server populates this field even if it did not send a | |||
| version negotiation packet. | version negotiation packet. | |||
| The client validates that the negotiated_version is included in the | The client validates that the negotiated_version is included in the | |||
| supported_versions list and - if version negotiation was performed - | supported_versions list and - if version negotiation was performed - | |||
| that it would have selected the negotiated version. A client MUST | that it would have selected the negotiated version. A client MUST | |||
| terminate the connection with a VERSION_NEGOTIATION_ERROR error code | terminate the connection with a VERSION_NEGOTIATION_ERROR error code | |||
| if the current QUIC version is not listed in the supported_versions | if the current QUIC version is not listed in the supported_versions | |||
| list. A client MUST terminate with a VERSION_NEGOTIATION_ERROR error | list. A client MUST terminate with a VERSION_NEGOTIATION_ERROR error | |||
| code if version negotiation occurred but it would have selected a | code if version negotiation occurred but it would have selected a | |||
| skipping to change at page 46, line 29 ¶ | skipping to change at page 37, line 43 ¶ | |||
| When an endpoint accepts multiple QUIC versions, it can potentially | When an endpoint accepts multiple QUIC versions, it can potentially | |||
| interpret transport parameters as they are defined by any of the QUIC | interpret transport parameters as they are defined by any of the QUIC | |||
| versions it supports. The version field in the QUIC packet header is | versions it supports. The version field in the QUIC packet header is | |||
| authenticated using transport parameters. The position and the | authenticated using transport parameters. The position and the | |||
| format of the version fields in transport parameters MUST either be | format of the version fields in transport parameters MUST either be | |||
| identical across different QUIC versions, or be unambiguously | identical across different QUIC versions, or be unambiguously | |||
| different to ensure no confusion about their interpretation. One way | different to ensure no confusion about their interpretation. One way | |||
| that a new format could be introduced is to define a TLS extension | that a new format could be introduced is to define a TLS extension | |||
| with a different codepoint. | with a different codepoint. | |||
| 6.7. Stateless Retries | 8. Address Validation | |||
| A server can process an Initial packet from a client without | ||||
| committing any state. This allows a server to perform address | ||||
| validation (Section 6.9), or to defer connection establishment costs. | ||||
| A server that generates a response to an Initial packet without | ||||
| retaining connection state MUST use the Retry packet (Section 4.4). | ||||
| This packet causes a client to restart the connection attempt and | ||||
| includes the token in the new Initial packet (Section 4.6) to prove | ||||
| source address ownership. | ||||
| 6.8. Using Explicit Congestion Notification | ||||
| QUIC endpoints use Explicit Congestion Notification (ECN) [RFC3168] | ||||
| to detect and respond to network congestion. ECN allows a network | ||||
| node to indicate congestion in the network by setting a codepoint in | ||||
| the IP header of a packet instead of dropping it. Endpoints react to | ||||
| congestion by reducing their sending rate in response, as described | ||||
| in [QUIC-RECOVERY]. | ||||
| To use ECN, QUIC endpoints first determine whether a path supports | ||||
| ECN marking and the peer is able to access the ECN codepoint in the | ||||
| IP header. A network path does not support ECN if ECN marked packets | ||||
| get dropped or ECN markings are rewritten on the path. An endpoint | ||||
| verifies the path, both during connection establishment and when | ||||
| migrating to a new path (see Section 6.11). | ||||
| Each endpoint independently verifies and enables use of ECN by | ||||
| setting the IP header ECN codepoint to ECN Capable Transport (ECT) | ||||
| for the path from it to the other peer. Even if ECN is not used on | ||||
| the path to the peer, the endpoint MUST provide feedback about ECN | ||||
| markings received (if accessible). | ||||
| To verify both that a path supports ECN and the peer can provide ECN | ||||
| feedback, an endpoint MUST set the ECT(0) codepoint in the IP header | ||||
| of all outgoing packets [RFC8311]. | ||||
| If an ECT codepoint set in the IP header is not corrupted by a | ||||
| network device, then a received packet contains either the codepoint | ||||
| sent by the peer or the Congestion Experienced (CE) codepoint set by | ||||
| a network device that is experiencing congestion. | ||||
| On receiving a packet with an ECT or CE codepoint, an endpoint that | ||||
| can access the IP ECN codepoints increases the corresponding ECT(0), | ||||
| ECT(1), or CE count, and includes these counters in subsequent (see | ||||
| Section 8.1) ACK frames (see Section 7.16). | ||||
| A packet detected by a receiver as a duplicate does not affect the | ||||
| receiver's local ECN codepoint counts; see (Section 12.7) for | ||||
| relevant security concerns. | ||||
| If an endpoint receives a packet without an ECT or CE codepoint, it | ||||
| responds per Section 8.1 with an ACK frame. | ||||
| If an endpoint does not have access to received ECN codepoints, it | ||||
| acknowledges received packets per Section 8.1 with an ACK frame. | ||||
| If a packet sent with an ECT codepoint is newly acknowledged by the | ||||
| peer in an ACK frame, the endpoint stops setting ECT codepoints in | ||||
| subsequent packets, with the expectation that either the network or | ||||
| the peer no longer supports ECN. | ||||
| To protect the connection from arbitrary corruption of ECN codepoints | ||||
| by the network, an endpoint verifies the following when an ACK frame | ||||
| is received: | ||||
| o The increase in ECT(0) and ECT(1) counters MUST be at least the | ||||
| number of packets newly acknowledged that were sent with the | ||||
| corresponding codepoint. | ||||
| o The total increase in ECT(0), ECT(1), and CE counters reported in | Address validation is used by QUIC to avoid being used for a traffic | |||
| the ACK frame MUST be at least the total number of packets newly | amplification attack. In such an attack, a packet is sent to a | |||
| acknowledged in this ACK frame. | server with spoofed source address information that identifies a | |||
| victim. If a server generates more or larger packets in response to | ||||
| that packet, the attacker can use the server to send more data toward | ||||
| the victim than it would be able to send on its own. | ||||
| An endpoint could miss acknowledgements for a packet when ACK frames | The primary defense against amplification attack is verifying that an | |||
| are lost. It is therefore possible for the total increase in ECT(0), | endpoint is able to receive packets at the transport address that it | |||
| ECT(1), and CE counters to be greater than the number of packets | claims. Address validation is performed both during connection | |||
| acknowledged in an ACK frame. When this happens, the local reference | establishment (see Section 8.1) and during connection migration (see | |||
| counts MUST be increased to match the counters in the ACK frame. | Section 8.2). | |||
| Upon successful verification, an endpoint continues to set ECT | 8.1. Address Validation During Connection Establishment | |||
| codepoints in subsequent packets with the expectation that the path | ||||
| is ECN-capable. | ||||
| If verification fails, then the endpoint ceases setting ECT | Connection establishment implicitly provides address validation for | |||
| codepoints in subsequent packets with the expectation that either the | both endpoints. In particular, receipt of a packet protected with | |||
| network or the peer does not support ECN. | Handshake keys confirms that the client received the Initial packet | |||
| from the server. Once the server has successfully processed a | ||||
| Handshake packet from the client, it can consider the client address | ||||
| to have been validated. | ||||
| If an endpoint sets ECT codepoints on outgoing packets and encounters | Prior to validating the client address, servers MUST NOT send more | |||
| a retransmission timeout due to the absence of acknowledgments from | than three times as many bytes as the number of bytes they have | |||
| the peer (see [QUIC-RECOVERY]), or if an endpoint has reason to | received. This limits the magnitude of any amplification attack that | |||
| believe that a network element might be corrupting ECN codepoints, | can be mounted using spoofed source addresses. | |||
| the endpoint MAY cease setting ECT codepoints in subsequent packets. | ||||
| Doing so allows the connection to traverse network elements that drop | ||||
| or corrupt ECN codepoints in the IP header. | ||||
| 6.9. Proof of Source Address Ownership | To ensure that the server is not overly constrained by this | |||
| restriction, clients MUST send UDP datagrams with at least 1200 | ||||
| octets of payload until the server has completed address validation, | ||||
| see Section 14. | ||||
| Transport protocols commonly spend a round trip checking that a | In order to prevent a handshake deadlock as a result of the server | |||
| client owns the transport address (IP and port) that it claims. | being unable to send, clients SHOULD send a packet upon a handshake | |||
| Verifying that a client can receive packets sent to its claimed | timeout, as described in [QUIC-RECOVERY]. If the client has no data | |||
| transport address protects against spoofing of this information by | to retransmit and does not have Handshake keys, it SHOULD send an | |||
| malicious clients. | Initial packet in a UDP datagram of at least 1200 octets. If the | |||
| client has Handshake keys, it SHOULD send a Handshake packet. | ||||
| This technique is used primarily to avoid QUIC from being used for | A server might wish to validate the client address before starting | |||
| traffic amplification attack. In such an attack, a packet is sent to | the cryptographic handshake. Client addresses can be verified using | |||
| a server with spoofed source address information that identifies a | an address validation token. This token is delivered during | |||
| victim. If a server generates more or larger packets in response to | connection establishment with a Retry packet (see Section 8.1.1) or | |||
| that packet, the attacker can use the server to send more data toward | in a previous connection using the NEW_TOKEN frame (see | |||
| the victim than it would be able to send on its own. | Section 8.1.2). | |||
| Several methods are used in QUIC to mitigate this attack. Firstly, | 8.1.1. Address Validation using Retry Packets | |||
| the initial handshake packet is sent in a UDP datagram that contains | ||||
| at least 1200 octets of UDP payload. This allows a server to send a | ||||
| similar amount of data without risking causing an amplification | ||||
| attack toward an unproven remote address. | ||||
| A server eventually confirms that a client has received its messages | QUIC uses token-based address validation during connection | |||
| when the first Handshake-level message is received. This might be | establishment. Any time the server wishes to validate a client | |||
| insufficient, either because the server wishes to avoid the | address, it provides the client with a token. As long as it is not | |||
| computational cost of completing the handshake, or it might be that | possible for an attacker to generate a valid token for its own | |||
| the size of the packets that are sent during the handshake is too | address (see Section 8.1.3) and the client is able to return that | |||
| large. This is especially important for 0-RTT, where the server | token, it proves to the server that it received the token. | |||
| might wish to provide application data traffic - such as a response | ||||
| to a request - in response to the data carried in the early data from | ||||
| the client. | ||||
| To send additional data prior to completing the cryptographic | Upon receiving the client's Initial packet, the server can request | |||
| handshake, the server then needs to validate that the client owns the | address validation by sending a Retry packet (Section 17.7) | |||
| address that it claims. | containing a token. This token is repeated by the client in an | |||
| Initial packet after it receives the Retry packet. In response to | ||||
| receiving a token in an Initial packet, a server can either abort the | ||||
| connection or permit it to proceed. | ||||
| Source address validation is therefore performed by the core | A server can also use a Retry packet to defer the state and | |||
| transport protocol during the establishment of a connection. | processing costs of connection establishment. By giving the client a | |||
| different connection ID to use, a server can cause the connection to | ||||
| be routed to a server instance with more resources available for new | ||||
| connections. | ||||
| A different type of source address validation is performed after a | A flow showing the use of a Retry packet is shown in Figure 6. | |||
| connection migration, see Section 6.10. | ||||
| 6.9.1. Client Address Validation Procedure | Client Server | |||
| QUIC uses token-based address validation. Any time the server wishes | Initial[0]: CRYPTO[CH] -> | |||
| to validate a client address, it provides the client with a token. | ||||
| As long as the token's authenticity can be checked (see | ||||
| Section 6.9.3) and the client is able to return that token, it proves | ||||
| to the server that it received the token. | ||||
| Upon receiving the client's Initial packet, the server can request | <- Retry+Token | |||
| address validation by sending a Retry packet containing a token. | ||||
| This token is repeated in the client's next Initial packet. Because | ||||
| the token is consumed by the server that generates it, there is no | ||||
| need for a single well-defined format. A token could include | ||||
| information about the claimed client address (IP and port), a | ||||
| timestamp, and any other supplementary information the server will | ||||
| need to validate the token in the future. | ||||
| The Retry packet is sent to the client and a legitimate client will | Initial+Token[0]: CRYPTO[CH] -> | |||
| respond with an Initial packet containing the token from the Retry | ||||
| packet when it continues the handshake. In response to receiving the | ||||
| token, a server can either abort the connection or permit it to | ||||
| proceed. | ||||
| A connection MAY be accepted without address validation - or with | Initial[0]: CRYPTO[SH] ACK[0] | |||
| only limited validation - but a server SHOULD limit the data it sends | Handshake[0]: CRYPTO[EE, CERT, CV, FIN] | |||
| toward an unvalidated address. Successful completion of the | <- 1-RTT[0]: STREAM[1, "..."] | |||
| cryptographic handshake implicitly provides proof that the client has | ||||
| received packets from the server. | ||||
| The client should allow for additional Retry packets being sent in | Figure 6: Example Handshake with Retry | |||
| response to Initial packets sent containing a token. There are | ||||
| several situations in which the server might not be able to use the | ||||
| previously generated token to validate the client's address and must | ||||
| send a new Retry. A reasonable limit to the number of tries the | ||||
| client allows for, before giving up, is 3. That is, the client MUST | ||||
| echo the address validation token from a new Retry packet up to 3 | ||||
| times. After that, it MAY give up on the connection attempt. | ||||
| 6.9.2. Address Validation for Future Connections | 8.1.2. Address Validation for Future Connections | |||
| A server MAY provide clients with an address validation token during | A server MAY provide clients with an address validation token during | |||
| one connection that can be used on a subsequent connection. Address | one connection that can be used on a subsequent connection. Address | |||
| validation is especially important with 0-RTT because a server | validation is especially important with 0-RTT because a server | |||
| potentially sends a significant amount of data to a client in | potentially sends a significant amount of data to a client in | |||
| response to 0-RTT data. | response to 0-RTT data. | |||
| The server uses the NEW_TOKEN frame Section 7.19 to provide the | The server uses the NEW_TOKEN frame Section 19.18 to provide the | |||
| client with an address validation token that can be used to validate | client with an address validation token that can be used to validate | |||
| future connections. The client may then use this token to validate | future connections. The client may then use this token to validate | |||
| future connections by including it in the Initial packet's header. | future connections by including it in the Initial packet's header. | |||
| The client MUST NOT use the token provided in a Retry for future | The client MUST NOT use the token provided in a Retry for future | |||
| connections. | connections. | |||
| Unlike the token that is created for a Retry packet, there might be | Unlike the token that is created for a Retry packet, there might be | |||
| some time between when the token is created and when the token is | some time between when the token is created and when the token is | |||
| subsequently used. Thus, a resumption token SHOULD include an | subsequently used. Thus, a resumption token SHOULD include an | |||
| expiration time. The server MAY include either an explicit | expiration time. The server MAY include either an explicit | |||
| expiration time or an issued timestamp and dynamically calculate the | expiration time or an issued timestamp and dynamically calculate the | |||
| expiration time. It is also unlikely that the client port number is | expiration time. It is also unlikely that the client port number is | |||
| the same on two different connections; validating the port is | the same on two different connections; validating the port is | |||
| therefore unlikely to be successful. | therefore unlikely to be successful. | |||
| 6.9.3. Address Validation Token Integrity | A resumption token SHOULD be constructed to be easily distinguishable | |||
| from tokens that are sent in Retry packets as they are carried in the | ||||
| same field. | ||||
| If the client has a token received in a NEW_TOKEN frame on a previous | ||||
| connection to what it believes to be the same server, it can include | ||||
| that value in the Token field of its Initial packet. | ||||
| A token allows a server to correlate activity between the connection | ||||
| where the token was issued and any connection where it is used. | ||||
| Clients that want to break continuity of identity with a server MAY | ||||
| discard tokens provided using the NEW_TOKEN frame. Tokens obtained | ||||
| in Retry packets MUST NOT be discarded. | ||||
| A client SHOULD NOT reuse a token. Reusing a token allows | ||||
| connections to be linked by entities on the network path (see | ||||
| Section 9.5). A client MUST NOT reuse a token if it believes that | ||||
| its point of network attachment has changed since the token was last | ||||
| used; that is, if there is a change in its local IP address or | ||||
| network interface. A client needs to start the connection process | ||||
| over if it migrates prior to completing the handshake. | ||||
| When a server receives an Initial packet with an address validation | ||||
| token, it SHOULD attempt to validate it. If the token is invalid | ||||
| then the server SHOULD proceed as if the client did not have a | ||||
| validated address, including potentially sending a Retry. If the | ||||
| validation succeeds, the server SHOULD then allow the handshake to | ||||
| proceed. | ||||
| Note: The rationale for treating the client as unvalidated rather | ||||
| than discarding the packet is that the client might have received | ||||
| the token in a previous connection using the NEW_TOKEN frame, and | ||||
| if the server has lost state, it might be unable to validate the | ||||
| token at all, leading to connection failure if the packet is | ||||
| discarded. A server MAY encode tokens provided with NEW_TOKEN | ||||
| frames and Retry packets differently, and validate the latter more | ||||
| strictly. | ||||
| In a stateless design, a server can use encrypted and authenticated | ||||
| tokens to pass information to clients that the server can later | ||||
| recover and use to validate a client address. Tokens are not | ||||
| integrated into the cryptographic handshake and so they are not | ||||
| authenticated. For instance, a client might be able to reuse a | ||||
| token. To avoid attacks that exploit this property, a server can | ||||
| limit its use of tokens to only the information needed validate | ||||
| client addresses. | ||||
| 8.1.3. Address Validation Token Integrity | ||||
| An address validation token MUST be difficult to guess. Including a | An address validation token MUST be difficult to guess. Including a | |||
| large enough random value in the token would be sufficient, but this | large enough random value in the token would be sufficient, but this | |||
| depends on the server remembering the value it sends to clients. | depends on the server remembering the value it sends to clients. | |||
| A token-based scheme allows the server to offload any state | A token-based scheme allows the server to offload any state | |||
| associated with validation to the client. For this design to work, | associated with validation to the client. For this design to work, | |||
| the token MUST be covered by integrity protection against | the token MUST be covered by integrity protection against | |||
| modification or falsification by clients. Without integrity | modification or falsification by clients. Without integrity | |||
| protection, malicious clients could generate or guess values for | protection, malicious clients could generate or guess values for | |||
| tokens that would be accepted by the server. Only the server | tokens that would be accepted by the server. Only the server | |||
| requires access to the integrity protection key for tokens. | requires access to the integrity protection key for tokens. | |||
| 6.10. Path Validation | There is no need for a single well-defined format for the token | |||
| because the server that generates the token also consumes it. A | ||||
| token could include information about the claimed client address (IP | ||||
| and port), a timestamp, and any other supplementary information the | ||||
| server will need to validate the token in the future. | ||||
| Path validation is used by an endpoint to verify reachability of a | 8.2. Path Validation | |||
| peer over a specific path. That is, it tests reachability between a | ||||
| specific local address and a specific peer address, where an address | ||||
| is the two-tuple of IP address and port. Path validation tests that | ||||
| packets can be both sent to and received from a peer. | ||||
| Path validation is used during connection migration (see Section 6.11 | Path validation is used during connection migration (see Section 9 | |||
| and Section 6.12) by the migrating endpoint to verify reachability of | and Section 9.6) by the migrating endpoint to verify reachability of | |||
| a peer from a new local address. Path validation is also used by the | a peer from a new local address. In path validation, endpoints test | |||
| peer to verify that the migrating endpoint is able to receive packets | reachability between a specific local address and a specific peer | |||
| sent to the its new address. That is, that the packets received from | address, where an address is the two-tuple of IP address and port. | |||
| the migrating endpoint do not carry a spoofed source address. | ||||
| Path validation tests that packets can be both sent to and received | ||||
| from a peer on the path. Importantly, it validates that the packets | ||||
| received from the migrating endpoint do not carry a spoofed source | ||||
| address. | ||||
| Path validation can be used at any time by either endpoint. For | Path validation can be used at any time by either endpoint. For | |||
| instance, an endpoint might check that a peer is still in possession | instance, an endpoint might check that a peer is still in possession | |||
| of its address after a period of quiescence. | of its address after a period of quiescence. | |||
| Path validation is not designed as a NAT traversal mechanism. Though | Path validation is not designed as a NAT traversal mechanism. Though | |||
| the mechanism described here might be effective for the creation of | the mechanism described here might be effective for the creation of | |||
| NAT bindings that support NAT traversal, the expectation is that one | NAT bindings that support NAT traversal, the expectation is that one | |||
| or other peer is able to receive packets without first having sent a | or other peer is able to receive packets without first having sent a | |||
| packet on that path. Effective NAT traversal needs additional | packet on that path. Effective NAT traversal needs additional | |||
| synchronization mechanisms that are not provided here. | synchronization mechanisms that are not provided here. | |||
| An endpoint MAY bundle PATH_CHALLENGE and PATH_RESPONSE frames that | An endpoint MAY bundle PATH_CHALLENGE and PATH_RESPONSE frames that | |||
| are used for path validation with other frames. For instance, an | are used for path validation with other frames. In particular, an | |||
| endpoint may pad a packet carrying a PATH_CHALLENGE for PMTU | endpoint may pad a packet carrying a PATH_CHALLENGE for PMTU | |||
| discovery, or an endpoint may bundle a PATH_RESPONSE with its own | discovery, or an endpoint may bundle a PATH_RESPONSE with its own | |||
| PATH_CHALLENGE. | PATH_CHALLENGE. | |||
| When probing a new path, an endpoint might want to ensure that its | When probing a new path, an endpoint might want to ensure that its | |||
| peer has an unused connection ID available for responses. The | peer has an unused connection ID available for responses. The | |||
| endpoint can send NEW_CONNECTION_ID and PATH_CHALLENGE frames in the | endpoint can send NEW_CONNECTION_ID and PATH_CHALLENGE frames in the | |||
| same packet. This ensures that an unused connection ID will be | same packet. This ensures that an unused connection ID will be | |||
| available to the peer when sending a response. | available to the peer when sending a response. | |||
| 6.10.1. Initiation | 8.3. Initiating Path Validation | |||
| To initiate path validation, an endpoint sends a PATH_CHALLENGE frame | To initiate path validation, an endpoint sends a PATH_CHALLENGE frame | |||
| containing a random payload on the path to be validated. | containing a random payload on the path to be validated. | |||
| An endpoint MAY send additional PATH_CHALLENGE frames to handle | An endpoint MAY send multiple PATH_CHALLENGE frames to guard against | |||
| packet loss. An endpoint SHOULD NOT send a PATH_CHALLENGE more | packet loss. An endpoint SHOULD NOT send a PATH_CHALLENGE more | |||
| frequently than it would an Initial packet, ensuring that connection | frequently than it would an Initial packet, ensuring that connection | |||
| migration is no more load on a new path than establishing a new | migration is no more load on a new path than establishing a new | |||
| connection. | connection. | |||
| The endpoint MUST use fresh random data in every PATH_CHALLENGE frame | The endpoint MUST use fresh random data in every PATH_CHALLENGE frame | |||
| so that it can associate the peer's response with the causative | so that it can associate the peer's response with the causative | |||
| PATH_CHALLENGE. | PATH_CHALLENGE. | |||
| 6.10.2. Response | 8.4. Path Validation Responses | |||
| On receiving a PATH_CHALLENGE frame, an endpoint MUST respond | On receiving a PATH_CHALLENGE frame, an endpoint MUST respond | |||
| immediately by echoing the data contained in the PATH_CHALLENGE frame | immediately by echoing the data contained in the PATH_CHALLENGE frame | |||
| in a PATH_RESPONSE frame, with the following stipulation. Since a | in a PATH_RESPONSE frame. However, because a PATH_CHALLENGE might be | |||
| PATH_CHALLENGE might be sent from a spoofed address, an endpoint MAY | sent from a spoofed address, an endpoint MUST limit the rate at which | |||
| limit the rate at which it sends PATH_RESPONSE frames and MAY | it sends PATH_RESPONSE frames and MAY silently discard PATH_CHALLENGE | |||
| silently discard PATH_CHALLENGE frames that would cause it to respond | frames that would cause it to respond at a higher rate. | |||
| at a higher rate. | ||||
| To ensure that packets can be both sent to and received from the | To ensure that packets can be both sent to and received from the | |||
| peer, the PATH_RESPONSE MUST be sent on the same path as the | peer, the PATH_RESPONSE MUST be sent on the same path as the | |||
| triggering PATH_CHALLENGE: from the same local address on which the | triggering PATH_CHALLENGE. That is, from the same local address on | |||
| PATH_CHALLENGE was received, to the same remote address from which | which the PATH_CHALLENGE was received, to the same remote address | |||
| the PATH_CHALLENGE was received. | from which the PATH_CHALLENGE was received. | |||
| 6.10.3. Completion | 8.5. Successful Path Validation | |||
| A new address is considered valid when a PATH_RESPONSE frame is | A new address is considered valid when a PATH_RESPONSE frame is | |||
| received containing data that was sent in a previous PATH_CHALLENGE. | received containing data that was sent in a previous PATH_CHALLENGE. | |||
| Receipt of an acknowledgment for a packet containing a PATH_CHALLENGE | Receipt of an acknowledgment for a packet containing a PATH_CHALLENGE | |||
| frame is not adequate validation, since the acknowledgment can be | frame is not adequate validation, since the acknowledgment can be | |||
| spoofed by a malicious peer. | spoofed by a malicious peer. | |||
| For path validation to be successful, a PATH_RESPONSE frame MUST be | For path validation to be successful, a PATH_RESPONSE frame MUST be | |||
| received from the same remote address to which the corresponding | received from the same remote address to which the corresponding | |||
| PATH_CHALLENGE was sent. If a PATH_RESPONSE frame is received from a | PATH_CHALLENGE was sent. If a PATH_RESPONSE frame is received from a | |||
| skipping to change at page 53, line 5 ¶ | skipping to change at page 43, line 23 ¶ | |||
| Additionally, the PATH_RESPONSE frame MUST be received on the same | Additionally, the PATH_RESPONSE frame MUST be received on the same | |||
| local address from which the corresponding PATH_CHALLENGE was sent. | local address from which the corresponding PATH_CHALLENGE was sent. | |||
| If a PATH_RESPONSE frame is received on a different local address | If a PATH_RESPONSE frame is received on a different local address | |||
| than the one from which the PATH_CHALLENGE was sent, path validation | than the one from which the PATH_CHALLENGE was sent, path validation | |||
| is considered to have failed, even if the data matches that sent in | is considered to have failed, even if the data matches that sent in | |||
| the PATH_CHALLENGE. Thus, the endpoint considers the path to be | the PATH_CHALLENGE. Thus, the endpoint considers the path to be | |||
| valid when a PATH_RESPONSE frame is received on the same path with | valid when a PATH_RESPONSE frame is received on the same path with | |||
| the same payload as the PATH_CHALLENGE frame. | the same payload as the PATH_CHALLENGE frame. | |||
| 6.10.4. Abandonment | 8.6. Failed Path Validation | |||
| An endpoint SHOULD abandon path validation after sending some number | Path validation only fails when the endpoint attempting to validate | |||
| of PATH_CHALLENGE frames or after some time has passed. When setting | the path abandons its attempt to validate the path. | |||
| this timer, implementations are cautioned that the new path could | ||||
| have a longer round-trip time than the original. | Endpoints SHOULD abandon path validation based on a timer. When | |||
| setting this timer, implementations are cautioned that the new path | ||||
| could have a longer round-trip time than the original. | ||||
| Note that the endpoint might receive packets containing other frames | Note that the endpoint might receive packets containing other frames | |||
| on the new path, but a PATH_RESPONSE frame with appropriate data is | on the new path, but a PATH_RESPONSE frame with appropriate data is | |||
| required for path validation to succeed. | required for path validation to succeed. | |||
| If path validation fails, the path is deemed unusable. This does not | When an endpoint abandons path validation, it determines that the | |||
| necessarily imply a failure of the connection - endpoints can | path is unusable. This does not necessarily imply a failure of the | |||
| continue sending packets over other paths as appropriate. If no | connection - endpoints can continue sending packets over other paths | |||
| paths are available, an endpoint can wait for a new path to become | as appropriate. If no paths are available, an endpoint can wait for | |||
| available or close the connection. | a new path to become available or close the connection. | |||
| A path validation might be abandoned for other reasons besides | A path validation might be abandoned for other reasons besides | |||
| failure. Primarily, this happens if a connection migration to a new | failure. Primarily, this happens if a connection migration to a new | |||
| path is initiated while a path validation on the old path is in | path is initiated while a path validation on the old path is in | |||
| progress. | progress. | |||
| 6.11. Connection Migration | 9. Connection Migration | |||
| QUIC allows connections to survive changes to endpoint addresses | The use of a connection ID allows connections to survive changes to | |||
| (that is, IP address and/or port), such as those caused by an | endpoint addresses (that is, IP address and/or port), such as those | |||
| endpoint migrating to a new network. This section describes the | caused by an endpoint migrating to a new network. This section | |||
| process by which an endpoint migrates to a new address. | describes the process by which an endpoint migrates to a new address. | |||
| An endpoint MUST NOT initiate connection migration before the | An endpoint MUST NOT initiate connection migration before the | |||
| handshake is finished and the endpoint has 1-RTT keys. The design of | handshake is finished and the endpoint has 1-RTT keys. The design of | |||
| QUIC relies on endpoints retaining a stable address for the duration | QUIC relies on endpoints retaining a stable address for the duration | |||
| of the handshake. | of the handshake. | |||
| An endpoint also MUST NOT initiate connection migration if the peer | An endpoint also MUST NOT initiate connection migration if the peer | |||
| sent the "disable_migration" transport parameter during the | sent the "disable_migration" transport parameter during the | |||
| handshake. An endpoint which has sent this transport parameter, but | handshake. An endpoint which has sent this transport parameter, but | |||
| detects that a peer has nonetheless migrated to a different network | detects that a peer has nonetheless migrated to a different network | |||
| MAY treat this as a connection error of type INVALID_MIGRATION. | MAY treat this as a connection error of type INVALID_MIGRATION. | |||
| Not all changes of peer address are intentional migrations. The peer | Not all changes of peer address are intentional migrations. The peer | |||
| could experience NAT rebinding: a change of address due to a | could experience NAT rebinding: a change of address due to a | |||
| middlebox, usually a NAT, allocating a new outgoing port or even a | middlebox, usually a NAT, allocating a new outgoing port or even a | |||
| new outgoing IP address for a flow. Endpoints SHOULD perform path | new outgoing IP address for a flow. NAT rebinding is not connection | |||
| validation (Section 6.10) if a NAT rebinding does not cause the | migration as defined in this section, though an endpoint SHOULD | |||
| connection to fail. | perform path validation (Section 8.2) if it detects a change in the | |||
| IP address of its peer. | ||||
| This document limits migration of connections to new client | This document limits migration of connections to new client | |||
| addresses, except as described in Section 6.12. Clients are | addresses, except as described in Section 9.6. Clients are | |||
| responsible for initiating all migrations. Servers do not send non- | responsible for initiating all migrations. Servers do not send non- | |||
| probing packets (see Section 6.11.1) toward a client address until | probing packets (see Section 9.1) toward a client address until they | |||
| they see a non-probing packet from that address. If a client | see a non-probing packet from that address. If a client receives | |||
| receives packets from an unknown server address, the client MAY | packets from an unknown server address, the client MAY discard these | |||
| discard these packets. | packets. | |||
| 6.11.1. Probing a New Path | 9.1. Probing a New Path | |||
| An endpoint MAY probe for peer reachability from a new local address | An endpoint MAY probe for peer reachability from a new local address | |||
| using path validation Section 6.10 prior to migrating the connection | using path validation Section 8.2 prior to migrating the connection | |||
| to the new local address. Failure of path validation simply means | to the new local address. Failure of path validation simply means | |||
| that the new path is not usable for this connection. Failure to | that the new path is not usable for this connection. Failure to | |||
| validate a path does not cause the connection to end unless there are | validate a path does not cause the connection to end unless there are | |||
| no valid alternative paths available. | no valid alternative paths available. | |||
| An endpoint uses a new connection ID for probes sent from a new local | An endpoint uses a new connection ID for probes sent from a new local | |||
| address, see Section 6.11.5 for further discussion. An endpoint that | address, see Section 9.5 for further discussion. An endpoint that | |||
| uses a new local address needs to ensure that at least one new | uses a new local address needs to ensure that at least one new | |||
| connection ID is available at the peer. That can be achieved by | connection ID is available at the peer. That can be achieved by | |||
| including a NEW_CONNECTION_ID frame in the probe. | including a NEW_CONNECTION_ID frame in the probe. | |||
| Receiving a PATH_CHALLENGE frame from a peer indicates that the peer | Receiving a PATH_CHALLENGE frame from a peer indicates that the peer | |||
| is probing for reachability on a path. An endpoint sends a | is probing for reachability on a path. An endpoint sends a | |||
| PATH_RESPONSE in response as per Section 6.10. | PATH_RESPONSE in response as per Section 8.2. | |||
| PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, and PADDING frames | PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, and PADDING frames | |||
| are "probing frames", and all other frames are "non-probing frames". | are "probing frames", and all other frames are "non-probing frames". | |||
| A packet containing only probing frames is a "probing packet", and a | A packet containing only probing frames is a "probing packet", and a | |||
| packet containing any other frame is a "non-probing packet". | packet containing any other frame is a "non-probing packet". | |||
| 6.11.2. Initiating Connection Migration | 9.2. Initiating Connection Migration | |||
| An endpoint can migrate a connection to a new local address by | An endpoint can migrate a connection to a new local address by | |||
| sending packets containing frames other than probing frames from that | sending packets containing non-probing frames from that address. | |||
| address. | ||||
| Each endpoint validates its peer's address during connection | Each endpoint validates its peer's address during connection | |||
| establishment. Therefore, a migrating endpoint can send to its peer | establishment. Therefore, a migrating endpoint can send to its peer | |||
| knowing that the peer is willing to receive at the peer's current | knowing that the peer is willing to receive at the peer's current | |||
| address. Thus an endpoint can migrate to a new local address without | address. Thus an endpoint can migrate to a new local address without | |||
| first validating the peer's address. | first validating the peer's address. | |||
| When migrating, the new path might not support the endpoint's current | When migrating, the new path might not support the endpoint's current | |||
| sending rate. Therefore, the endpoint resets its congestion | sending rate. Therefore, the endpoint resets its congestion | |||
| controller, as described in Section 6.11.4. | controller, as described in Section 9.4. | |||
| The new path might not have the same ECN capability. Therefore, the | The new path might not have the same ECN capability. Therefore, the | |||
| endpoint verifies ECN capability as described in Section 6.8. | endpoint verifies ECN capability as described in Section 13.3. | |||
| Receiving acknowledgments for data sent on the new path serves as | Receiving acknowledgments for data sent on the new path serves as | |||
| proof of the peer's reachability from the new address. Note that | proof of the peer's reachability from the new address. Note that | |||
| since acknowledgments may be received on any path, return | since acknowledgments may be received on any path, return | |||
| reachability on the new path is not established. To establish return | reachability on the new path is not established. To establish return | |||
| reachability on the new path, an endpoint MAY concurrently initiate | reachability on the new path, an endpoint MAY concurrently initiate | |||
| path validation Section 6.10 on the new path. | path validation Section 8.2 on the new path. | |||
| 6.11.3. Responding to Connection Migration | 9.3. Responding to Connection Migration | |||
| Receiving a packet from a new peer address containing a non-probing | Receiving a packet from a new peer address containing a non-probing | |||
| frame indicates that the peer has migrated to that address. | frame indicates that the peer has migrated to that address. | |||
| In response to such a packet, an endpoint MUST start sending | In response to such a packet, an endpoint MUST start sending | |||
| subsequent packets to the new peer address and MUST initiate path | subsequent packets to the new peer address and MUST initiate path | |||
| validation (Section 6.10) to verify the peer's ownership of the | validation (Section 8.2) to verify the peer's ownership of the | |||
| unvalidated address. | unvalidated address. | |||
| An endpoint MAY send data to an unvalidated peer address, but it MUST | An endpoint MAY send data to an unvalidated peer address, but it MUST | |||
| protect against potential attacks as described in Section 6.11.3.1 | protect against potential attacks as described in Section 9.3.1 and | |||
| and Section 6.11.3.2. An endpoint MAY skip validation of a peer | Section 9.3.2. An endpoint MAY skip validation of a peer address if | |||
| address if that address has been seen recently. | that address has been seen recently. | |||
| An endpoint only changes the address that it sends packets to in | An endpoint only changes the address that it sends packets to in | |||
| response to the highest-numbered non-probing packet. This ensures | response to the highest-numbered non-probing packet. This ensures | |||
| that an endpoint does not send packets to an old peer address in the | that an endpoint does not send packets to an old peer address in the | |||
| case that it receives reordered packets. | case that it receives reordered packets. | |||
| After changing the address to which it sends non-probing packets, an | After changing the address to which it sends non-probing packets, an | |||
| endpoint could abandon any path validation for other addresses. | endpoint could abandon any path validation for other addresses. | |||
| Receiving a packet from a new peer address might be the result of a | Receiving a packet from a new peer address might be the result of a | |||
| NAT rebinding at the peer. | NAT rebinding at the peer. | |||
| After verifying a new client address, the server SHOULD send new | After verifying a new client address, the server SHOULD send new | |||
| address validation tokens (Section 6.9) to the client. | address validation tokens (Section 8) to the client. | |||
| 6.11.3.1. Handling Address Spoofing by a Peer | 9.3.1. Handling Address Spoofing by a Peer | |||
| It is possible that a peer is spoofing its source address to cause an | It is possible that a peer is spoofing its source address to cause an | |||
| endpoint to send excessive amounts of data to an unwilling host. If | endpoint to send excessive amounts of data to an unwilling host. If | |||
| the endpoint sends significantly more data than the spoofing peer, | the endpoint sends significantly more data than the spoofing peer, | |||
| connection migration might be used to amplify the volume of data that | connection migration might be used to amplify the volume of data that | |||
| an attacker can generate toward a victim. | an attacker can generate toward a victim. | |||
| As described in Section 6.11.3, an endpoint is required to validate a | As described in Section 9.3, an endpoint is required to validate a | |||
| peer's new address to confirm the peer's possession of the new | peer's new address to confirm the peer's possession of the new | |||
| address. Until a peer's address is deemed valid, an endpoint MUST | address. Until a peer's address is deemed valid, an endpoint MUST | |||
| limit the rate at which it sends data to this address. The endpoint | limit the rate at which it sends data to this address. The endpoint | |||
| MUST NOT send more than a minimum congestion window's worth of data | MUST NOT send more than a minimum congestion window's worth of data | |||
| per estimated round-trip time (kMinimumWindow, as defined in | per estimated round-trip time (kMinimumWindow, as defined in | |||
| [QUIC-RECOVERY]). In the absence of this limit, an endpoint risks | [QUIC-RECOVERY]). In the absence of this limit, an endpoint risks | |||
| being used for a denial of service attack against an unsuspecting | being used for a denial of service attack against an unsuspecting | |||
| victim. Note that since the endpoint will not have any round-trip | victim. Note that since the endpoint will not have any round-trip | |||
| time measurements to this address, the estimate SHOULD be the default | time measurements to this address, the estimate SHOULD be the default | |||
| initial value (see [QUIC-RECOVERY]). | initial value (see [QUIC-RECOVERY]). | |||
| If an endpoint skips validation of a peer address as described in | If an endpoint skips validation of a peer address as described in | |||
| Section 6.11.3, it does not need to limit its sending rate. | Section 9.3, it does not need to limit its sending rate. | |||
| 6.11.3.2. Handling Address Spoofing by an On-path Attacker | 9.3.2. Handling Address Spoofing by an On-path Attacker | |||
| An on-path attacker could cause a spurious connection migration by | An on-path attacker could cause a spurious connection migration by | |||
| copying and forwarding a packet with a spoofed address such that it | copying and forwarding a packet with a spoofed address such that it | |||
| arrives before the original packet. The packet with the spoofed | arrives before the original packet. The packet with the spoofed | |||
| address will be seen to come from a migrating connection, and the | address will be seen to come from a migrating connection, and the | |||
| original packet will be seen as a duplicate and dropped. After a | original packet will be seen as a duplicate and dropped. After a | |||
| spurious migration, validation of the source address will fail | spurious migration, validation of the source address will fail | |||
| because the entity at the source address does not have the necessary | because the entity at the source address does not have the necessary | |||
| cryptographic keys to read or respond to the PATH_CHALLENGE frame | cryptographic keys to read or respond to the PATH_CHALLENGE frame | |||
| that is sent to it even if it wanted to. | that is sent to it even if it wanted to. | |||
| skipping to change at page 56, line 47 ¶ | skipping to change at page 47, line 20 ¶ | |||
| MUST close the connection silently by discarding all connection | MUST close the connection silently by discarding all connection | |||
| state. This results in new packets on the connection being handled | state. This results in new packets on the connection being handled | |||
| generically. For instance, an endpoint MAY send a stateless reset in | generically. For instance, an endpoint MAY send a stateless reset in | |||
| response to any further incoming packets. | response to any further incoming packets. | |||
| Note that receipt of packets with higher packet numbers from the | Note that receipt of packets with higher packet numbers from the | |||
| legitimate peer address will trigger another connection migration. | legitimate peer address will trigger another connection migration. | |||
| This will cause the validation of the address of the spurious | This will cause the validation of the address of the spurious | |||
| migration to be abandoned. | migration to be abandoned. | |||
| 6.11.4. Loss Detection and Congestion Control | 9.4. Loss Detection and Congestion Control | |||
| The capacity available on the new path might not be the same as the | The capacity available on the new path might not be the same as the | |||
| old path. Packets sent on the old path SHOULD NOT contribute to | old path. Packets sent on the old path SHOULD NOT contribute to | |||
| congestion control or RTT estimation for the new path. | congestion control or RTT estimation for the new path. | |||
| On confirming a peer's ownership of its new address, an endpoint | On confirming a peer's ownership of its new address, an endpoint | |||
| SHOULD immediately reset the congestion controller and round-trip | SHOULD immediately reset the congestion controller and round-trip | |||
| time estimator for the new path. | time estimator for the new path. | |||
| An endpoint MUST NOT return to the send rate used for the previous | An endpoint MUST NOT return to the send rate used for the previous | |||
| skipping to change at page 57, line 36 ¶ | skipping to change at page 48, line 8 ¶ | |||
| single congestion control context and a single loss recovery context | single congestion control context and a single loss recovery context | |||
| (as described in [QUIC-RECOVERY]) may be adequate. A sender can make | (as described in [QUIC-RECOVERY]) may be adequate. A sender can make | |||
| exceptions for probe packets so that their loss detection is | exceptions for probe packets so that their loss detection is | |||
| independent and does not unduly cause the congestion controller to | independent and does not unduly cause the congestion controller to | |||
| reduce its sending rate. An endpoint might set a separate timer when | reduce its sending rate. An endpoint might set a separate timer when | |||
| a PATH_CHALLENGE is sent, which is cancelled when the corresponding | a PATH_CHALLENGE is sent, which is cancelled when the corresponding | |||
| PATH_RESPONSE is received. If the timer fires before the | PATH_RESPONSE is received. If the timer fires before the | |||
| PATH_RESPONSE is received, the endpoint might send a new | PATH_RESPONSE is received, the endpoint might send a new | |||
| PATH_CHALLENGE, and restart the timer for a longer period of time. | PATH_CHALLENGE, and restart the timer for a longer period of time. | |||
| 6.11.5. Privacy Implications of Connection Migration | 9.5. Privacy Implications of Connection Migration | |||
| Using a stable connection ID on multiple network paths allows a | Using a stable connection ID on multiple network paths allows a | |||
| passive observer to correlate activity between those paths. An | passive observer to correlate activity between those paths. An | |||
| endpoint that moves between networks might not wish to have their | endpoint that moves between networks might not wish to have their | |||
| activity correlated by any entity other than their peer, so different | activity correlated by any entity other than their peer, so different | |||
| connection IDs are used when sending from different local addresses, | connection IDs are used when sending from different local addresses, | |||
| as discussed in Section 6.1. For this to be effective endpoints need | as discussed in Section 5.1. For this to be effective endpoints need | |||
| to ensure that connections IDs they provide cannot be linked by any | to ensure that connections IDs they provide cannot be linked by any | |||
| other entity. | other entity. | |||
| This eliminates the use of the connection ID for linking activity | This eliminates the use of the connection ID for linking activity | |||
| from the same connection on different networks. Protection of packet | from the same connection on different networks. Protection of packet | |||
| numbers ensures that packet numbers cannot be used to correlate | numbers ensures that packet numbers cannot be used to correlate | |||
| activity. This does not prevent other properties of packets, such as | activity. This does not prevent other properties of packets, such as | |||
| timing and size, from being used to correlate activity. | timing and size, from being used to correlate activity. | |||
| Clients MAY move to a new connection ID at any time based on | Clients MAY move to a new connection ID at any time based on | |||
| skipping to change at page 58, line 17 ¶ | skipping to change at page 48, line 37 ¶ | |||
| network inactivity NAT rebinding might occur when the client begins | network inactivity NAT rebinding might occur when the client begins | |||
| sending data again. | sending data again. | |||
| A client might wish to reduce linkability by employing a new | A client might wish to reduce linkability by employing a new | |||
| connection ID and source UDP port when sending traffic after a period | connection ID and source UDP port when sending traffic after a period | |||
| of inactivity. Changing the UDP port from which it sends packets at | of inactivity. Changing the UDP port from which it sends packets at | |||
| the same time might cause the packet to appear as a connection | the same time might cause the packet to appear as a connection | |||
| migration. This ensures that the mechanisms that support migration | migration. This ensures that the mechanisms that support migration | |||
| are exercised even for clients that don't experience NAT rebindings | are exercised even for clients that don't experience NAT rebindings | |||
| or genuine migrations. Changing port number can cause a peer to | or genuine migrations. Changing port number can cause a peer to | |||
| reset its congestion state (see Section 6.11.4), so the port SHOULD | reset its congestion state (see Section 9.4), so the port SHOULD only | |||
| only be changed infrequently. | be changed infrequently. | |||
| Endpoints that use connection IDs with length greater than zero could | Endpoints that use connection IDs with length greater than zero could | |||
| have their activity correlated if their peers keep using the same | have their activity correlated if their peers keep using the same | |||
| destination connection ID after migration. Endpoints that receive | destination connection ID after migration. Endpoints that receive | |||
| packets with a previously unused Destination Connection ID SHOULD | packets with a previously unused Destination Connection ID SHOULD | |||
| change to sending packets with a connection ID that has not been used | change to sending packets with a connection ID that has not been used | |||
| on any other network path. The goal here is to ensure that packets | on any other network path. The goal here is to ensure that packets | |||
| sent on different paths cannot be correlated. To fulfill this | sent on different paths cannot be correlated. To fulfill this | |||
| privacy requirement, endpoints that initiate migration and use | privacy requirement, endpoints that initiate migration and use | |||
| connection IDs with length greater than zero SHOULD provide their | connection IDs with length greater than zero SHOULD provide their | |||
| peers with new connection IDs before migration. | peers with new connection IDs before migration. | |||
| Caution: If both endpoints change connection ID in response to | Caution: If both endpoints change connection ID in response to | |||
| seeing a change in connection ID from their peer, then this can | seeing a change in connection ID from their peer, then this can | |||
| trigger an infinite sequence of changes. | trigger an infinite sequence of changes. | |||
| 6.12. Server's Preferred Address | 9.6. Server's Preferred Address | |||
| QUIC allows servers to accept connections on one IP address and | QUIC allows servers to accept connections on one IP address and | |||
| attempt to transfer these connections to a more preferred address | attempt to transfer these connections to a more preferred address | |||
| shortly after the handshake. This is particularly useful when | shortly after the handshake. This is particularly useful when | |||
| clients initially connect to an address shared by multiple servers | clients initially connect to an address shared by multiple servers | |||
| but would prefer to use a unicast address to ensure connection | but would prefer to use a unicast address to ensure connection | |||
| stability. This section describes the protocol for migrating a | stability. This section describes the protocol for migrating a | |||
| connection to a preferred server address. | connection to a preferred server address. | |||
| Migrating a connection to a new server address mid-connection is left | Migrating a connection to a new server address mid-connection is left | |||
| for future work. If a client receives packets from a new server | for future work. If a client receives packets from a new server | |||
| address not indicated by the preferred_address transport parameter, | address not indicated by the preferred_address transport parameter, | |||
| the client SHOULD discard these packets. | the client SHOULD discard these packets. | |||
| 6.12.1. Communicating A Preferred Address | 9.6.1. Communicating A Preferred Address | |||
| A server conveys a preferred address by including the | A server conveys a preferred address by including the | |||
| preferred_address transport parameter in the TLS handshake. | preferred_address transport parameter in the TLS handshake. | |||
| Once the handshake is finished, the client SHOULD initiate path | Once the handshake is finished, the client SHOULD initiate path | |||
| validation (see Section 6.10) of the server's preferred address using | validation (see Section 8.2) of the server's preferred address using | |||
| the connection ID provided in the preferred_address transport | the connection ID provided in the preferred_address transport | |||
| parameter. | parameter. | |||
| If path validation succeeds, the client SHOULD immediately begin | If path validation succeeds, the client SHOULD immediately begin | |||
| sending all future packets to the new server address using the new | sending all future packets to the new server address using the new | |||
| connection ID and discontinue use of the old server address. If path | connection ID and discontinue use of the old server address. If path | |||
| validation fails, the client MUST continue sending all future packets | validation fails, the client MUST continue sending all future packets | |||
| to the server's original IP address. | to the server's original IP address. | |||
| 6.12.2. Responding to Connection Migration | 9.6.2. Responding to Connection Migration | |||
| A server might receive a packet addressed to its preferred IP address | A server might receive a packet addressed to its preferred IP address | |||
| at any time after the handshake is completed. If this packet | at any time after it accepts a connection. If this packet contains a | |||
| contains a PATH_CHALLENGE frame, the server sends a PATH_RESPONSE | PATH_CHALLENGE frame, the server sends a PATH_RESPONSE frame as per | |||
| frame as per Section 6.10, but the server MUST continue sending all | Section 8.2. The server MAY send other non-probing frames from its | |||
| other packets from its original IP address. | preferred address, but MUST continue sending all probing packets from | |||
| its original IP address. | ||||
| The server SHOULD also initiate path validation of the client using | The server SHOULD also initiate path validation of the client using | |||
| its preferred address and the address from which it received the | its preferred address and the address from which it received the | |||
| client probe. This helps to guard against spurious migration | client probe. This helps to guard against spurious migration | |||
| initiated by an attacker. | initiated by an attacker. | |||
| Once the server has completed its path validation and has received a | Once the server has completed its path validation and has received a | |||
| non-probing packet with a new largest packet number on its preferred | non-probing packet with a new largest packet number on its preferred | |||
| address, the server begins sending to the client exclusively from its | address, the server begins sending non-probing packets to the client | |||
| preferred IP address. It SHOULD drop packets for this connection | exclusively from its preferred IP address. It SHOULD drop packets | |||
| received on the old IP address, but MAY continue to process delayed | for this connection received on the old IP address, but MAY continue | |||
| packets. | to process delayed packets. | |||
| 6.12.3. Interaction of Client Migration and Preferred Address | 9.6.3. Interaction of Client Migration and Preferred Address | |||
| A client might need to perform a connection migration before it has | A client might need to perform a connection migration before it has | |||
| migrated to the server's preferred address. In this case, the client | migrated to the server's preferred address. In this case, the client | |||
| SHOULD perform path validation to both the original and preferred | SHOULD perform path validation to both the original and preferred | |||
| server address from the client's new address concurrently. | server address from the client's new address concurrently. | |||
| If path validation of the server's preferred address succeeds, the | If path validation of the server's preferred address succeeds, the | |||
| client MUST abandon validation of the original address and migrate to | client MUST abandon validation of the original address and migrate to | |||
| using the server's preferred address. If path validation of the | using the server's preferred address. If path validation of the | |||
| server's preferred address fails, but validation of the server's | server's preferred address fails but validation of the server's | |||
| original address succeeds, the client MAY migrate to using the | original address succeeds, the client MAY migrate to its new address | |||
| original address from the client's new address. | and continue sending to the server's original address. | |||
| If the connection to the server's preferred address is not from the | If the connection to the server's preferred address is not from the | |||
| same client address, the server MUST protect against potential | same client address, the server MUST protect against potential | |||
| attacks as described in Section 6.11.3.1 and Section 6.11.3.2. In | attacks as described in Section 9.3.1 and Section 9.3.2. In addition | |||
| addition to intentional simultaneous migration, this might also occur | to intentional simultaneous migration, this might also occur because | |||
| because the client's access network used a different NAT binding for | the client's access network used a different NAT binding for the | |||
| the server's preferred address. | server's preferred address. | |||
| Servers SHOULD initiate path validation to the client's new address | Servers SHOULD initiate path validation to the client's new address | |||
| upon receiving a probe packet from a different address. Servers MUST | upon receiving a probe packet from a different address. Servers MUST | |||
| NOT send more than a minimum congestion window's worth of non-probing | NOT send more than a minimum congestion window's worth of non-probing | |||
| packets to the new address before path validation is complete. | packets to the new address before path validation is complete. | |||
| 6.13. Connection Termination | 10. Connection Termination | |||
| Connections should remain open until they become idle for a pre- | Connections should remain open until they become idle for a pre- | |||
| negotiated period of time. A QUIC connection, once established, can | negotiated period of time. A QUIC connection, once established, can | |||
| be terminated in one of three ways: | be terminated in one of three ways: | |||
| o idle timeout (Section 6.13.2) | o idle timeout (Section 10.2) | |||
| o immediate close (Section 6.13.3) | o immediate close (Section 10.3) | |||
| o stateless reset (Section 6.13.4) | o stateless reset (Section 10.4) | |||
| 6.13.1. Closing and Draining Connection States | 10.1. Closing and Draining Connection States | |||
| The closing and draining connection states exist to ensure that | The closing and draining connection states exist to ensure that | |||
| connections close cleanly and that delayed or reordered packets are | connections close cleanly and that delayed or reordered packets are | |||
| properly discarded. These states SHOULD persist for three times the | properly discarded. These states SHOULD persist for three times the | |||
| current Retransmission Timeout (RTO) interval as defined in | current Retransmission Timeout (RTO) interval as defined in | |||
| [QUIC-RECOVERY]. | [QUIC-RECOVERY]. | |||
| An endpoint enters a closing period after initiating an immediate | An endpoint enters a closing period after initiating an immediate | |||
| close (Section 6.13.3). While closing, an endpoint MUST NOT send | close (Section 10.3). While closing, an endpoint MUST NOT send | |||
| packets unless they contain a CONNECTION_CLOSE or APPLICATION_CLOSE | packets unless they contain a CONNECTION_CLOSE or APPLICATION_CLOSE | |||
| frame (see Section 6.13.3 for details). | frame (see Section 10.3 for details). An endpoint retains only | |||
| enough information to generate a packet containing a closing frame | ||||
| In the closing state, only a packet containing a closing frame can be | and to identify packets as belonging to the connection. The | |||
| sent. An endpoint retains only enough information to generate a | connection ID and QUIC version is sufficient information to identify | |||
| packet containing a closing frame and to identify packets as | packets for a closing connection; an endpoint can discard all other | |||
| belonging to the connection. The connection ID and QUIC version is | connection state. An endpoint MAY retain packet protection keys for | |||
| sufficient information to identify packets for a closing connection; | incoming packets to allow it to read and process a closing frame. | |||
| an endpoint can discard all other connection state. An endpoint MAY | ||||
| retain packet protection keys for incoming packets to allow it to | ||||
| read and process a closing frame. | ||||
| The draining state is entered once an endpoint receives a signal that | The draining state is entered once an endpoint receives a signal that | |||
| its peer is closing or draining. While otherwise identical to the | its peer is closing or draining. While otherwise identical to the | |||
| closing state, an endpoint in the draining state MUST NOT send any | closing state, an endpoint in the draining state MUST NOT send any | |||
| packets. Retaining packet protection keys is unnecessary once a | packets. Retaining packet protection keys is unnecessary once a | |||
| connection is in the draining state. | connection is in the draining state. | |||
| An endpoint MAY transition from the closing period to the draining | An endpoint MAY transition from the closing period to the draining | |||
| period if it can confirm that its peer is also closing or draining. | period if it can confirm that its peer is also closing or draining. | |||
| Receiving a closing frame is sufficient confirmation, as is receiving | Receiving a closing frame is sufficient confirmation, as is receiving | |||
| skipping to change at page 61, line 33 ¶ | skipping to change at page 51, line 52 ¶ | |||
| an abbreviated draining period which can allow for faster resource | an abbreviated draining period which can allow for faster resource | |||
| recovery. Servers that retain an open socket for accepting new | recovery. Servers that retain an open socket for accepting new | |||
| connections SHOULD NOT exit the closing or draining period early. | connections SHOULD NOT exit the closing or draining period early. | |||
| Once the closing or draining period has ended, an endpoint SHOULD | Once the closing or draining period has ended, an endpoint SHOULD | |||
| discard all connection state. This results in new packets on the | discard all connection state. This results in new packets on the | |||
| connection being handled generically. For instance, an endpoint MAY | connection being handled generically. For instance, an endpoint MAY | |||
| send a stateless reset in response to any further incoming packets. | send a stateless reset in response to any further incoming packets. | |||
| The draining and closing periods do not apply when a stateless reset | The draining and closing periods do not apply when a stateless reset | |||
| (Section 6.13.4) is sent. | (Section 10.4) is sent. | |||
| An endpoint is not expected to handle key updates when it is closing | An endpoint is not expected to handle key updates when it is closing | |||
| or draining. A key update might prevent the endpoint from moving | or draining. A key update might prevent the endpoint from moving | |||
| from the closing state to draining, but it otherwise has no impact. | from the closing state to draining, but it otherwise has no impact. | |||
| An endpoint could receive packets from a new source address, | An endpoint could receive packets from a new source address, | |||
| indicating a client connection migration (Section 6.11), while in the | indicating a client connection migration (Section 9), while in the | |||
| closing period. An endpoint in the closing state MUST strictly limit | closing period. An endpoint in the closing state MUST strictly limit | |||
| the number of packets it sends to this new address until the address | the number of packets it sends to this new address until the address | |||
| is validated (see Section 6.10). A server in the closing state MAY | is validated (see Section 8.2). A server in the closing state MAY | |||
| instead choose to discard packets received from a new source address. | instead choose to discard packets received from a new source address. | |||
| 6.13.2. Idle Timeout | 10.2. Idle Timeout | |||
| If the idle timeout is enabled, a connection that remains idle for | If the idle timeout is enabled, a connection that remains idle for | |||
| longer than the advertised idle timeout (see Section 6.6.1) is | longer than the advertised idle timeout (see Section 18.1) is closed. | |||
| closed. A connection enters the draining state when the idle timeout | A connection enters the draining state when the idle timeout expires. | |||
| expires. | ||||
| Each endpoint advertises their own idle timeout to their peer. The | Each endpoint advertises its own idle timeout to its peer. The idle | |||
| idle timeout starts from the last packet received. In order to | timeout starts from the last packet received. In order to ensure | |||
| ensure that initiating new activity postpones an idle timeout, an | that initiating new activity postpones an idle timeout, an endpoint | |||
| endpoint restarts this timer when sending a packet. An endpoint does | restarts this timer when sending a packet. An endpoint does not | |||
| not postpone the idle timeout if another packet has been sent | postpone the idle timeout if another packet has been sent containing | |||
| containing frames other than ACK or PADDING, and that other packet | frames other than ACK or PADDING, and that other packet has not been | |||
| has not been acknowledged or declared lost. Packets that contain | acknowledged or declared lost. Packets that contain only ACK or | |||
| only ACK or PADDING frames are not acknowledged until an endpoint has | PADDING frames are not acknowledged until an endpoint has other | |||
| other frames to send, so they could prevent the timeout from being | frames to send, so they could prevent the timeout from being | |||
| refreshed. | refreshed. | |||
| The value for an idle timeout can be asymmetric. The value | The value for an idle timeout can be asymmetric. The value | |||
| advertised by an endpoint is only used to determine whether the | advertised by an endpoint is only used to determine whether the | |||
| connection is live at that endpoint. An endpoint that sends packets | connection is live at that endpoint. An endpoint that sends packets | |||
| near the end of the idle timeout period of a peer risks having those | near the end of the idle timeout period of a peer risks having those | |||
| packets discarded if its peer enters the draining state before the | packets discarded if its peer enters the draining state before the | |||
| packets arrive. If a peer could timeout within an RTO (see | packets arrive. If a peer could timeout within an RTO (see | |||
| Section 4.3.3 of [QUIC-RECOVERY]), it is advisable to test for | Section 4.3.3 of [QUIC-RECOVERY]), it is advisable to test for | |||
| liveness before sending any data that cannot be retried safely. | liveness before sending any data that cannot be retried safely. | |||
| 6.13.3. Immediate Close | 10.3. Immediate Close | |||
| An endpoint sends a closing frame (CONNECTION_CLOSE or | An endpoint sends a closing frame (CONNECTION_CLOSE or | |||
| APPLICATION_CLOSE) to terminate the connection immediately. Any | APPLICATION_CLOSE) to terminate the connection immediately. Any | |||
| closing frame causes all streams to immediately become closed; open | closing frame causes all streams to immediately become closed; open | |||
| streams can be assumed to be implicitly reset. | streams can be assumed to be implicitly reset. | |||
| After sending a closing frame, endpoints immediately enter the | After sending a closing frame, endpoints immediately enter the | |||
| closing state. During the closing period, an endpoint that sends a | closing state. During the closing period, an endpoint that sends a | |||
| closing frame SHOULD respond to any packet that it receives with | closing frame SHOULD respond to any packet that it receives with | |||
| another packet containing a closing frame. To minimize the state | another packet containing a closing frame. To minimize the state | |||
| skipping to change at page 63, line 18 ¶ | skipping to change at page 53, line 35 ¶ | |||
| An immediate close can be used after an application protocol has | An immediate close can be used after an application protocol has | |||
| arranged to close a connection. This might be after the application | arranged to close a connection. This might be after the application | |||
| protocols negotiates a graceful shutdown. The application protocol | protocols negotiates a graceful shutdown. The application protocol | |||
| exchanges whatever messages that are needed to cause both endpoints | exchanges whatever messages that are needed to cause both endpoints | |||
| to agree to close the connection, after which the application | to agree to close the connection, after which the application | |||
| requests that the connection be closed. The application protocol can | requests that the connection be closed. The application protocol can | |||
| use an APPLICATION_CLOSE message with an appropriate error code to | use an APPLICATION_CLOSE message with an appropriate error code to | |||
| signal closure. | signal closure. | |||
| 6.13.4. Stateless Reset | If the connection has been successfully established, endpoints MUST | |||
| send any closing frames in a 1-RTT packet. Prior to connection | ||||
| establishment a peer might not have 1-RTT keys, so endpoints SHOULD | ||||
| send closing frames in a Handshake packet. If the endpoint does not | ||||
| have Handshake keys, or it is not certain that the peer has Handshake | ||||
| keys, it MAY send closing frames in an Initial packet. If multiple | ||||
| packets are sent, they can be coalesced (see Section 12.2) to | ||||
| facilitate retransmission. | ||||
| 10.4. Stateless Reset | ||||
| A stateless reset is provided as an option of last resort for an | A stateless reset is provided as an option of last resort for an | |||
| endpoint that does not have access to the state of a connection. A | endpoint that does not have access to the state of a connection. A | |||
| crash or outage might result in peers continuing to send data to an | crash or outage might result in peers continuing to send data to an | |||
| endpoint that is unable to properly continue the connection. An | endpoint that is unable to properly continue the connection. An | |||
| endpoint that wishes to communicate a fatal connection error MUST use | endpoint that wishes to communicate a fatal connection error MUST use | |||
| a closing frame if it has sufficient state to do so. | a closing frame if it has sufficient state to do so. | |||
| To support this process, a token is sent by endpoints. The token is | To support this process, a token is sent by endpoints. The token is | |||
| carried in the NEW_CONNECTION_ID frame sent by either peer, and | carried in the NEW_CONNECTION_ID frame sent by either peer, and | |||
| servers can specify the stateless_reset_token transport parameter | servers can specify the stateless_reset_token transport parameter | |||
| during the handshake (clients cannot because their transport | during the handshake (clients cannot because their transport | |||
| parameters don't have confidentiality protection). This value is | parameters don't have confidentiality protection). This value is | |||
| protected by encryption, so only client and server know this value. | protected by encryption, so only client and server know this value. | |||
| Tokens sent via NEW_CONNECTION_ID frames are invalidated when their | Tokens sent via NEW_CONNECTION_ID frames are invalidated when their | |||
| associated connection ID is retired via a RETIRE_CONNECTION_ID frame | associated connection ID is retired via a RETIRE_CONNECTION_ID frame | |||
| (Section 7.14). | (Section 19.13). | |||
| An endpoint that receives packets that it cannot process sends a | An endpoint that receives packets that it cannot process sends a | |||
| packet in the following layout: | packet in the following layout: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+ | |||
| |0|K|1|1|0|0|0|0| | |0|K|1|1|0|0|0|0| | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Random Octets (160..) ... | | Random Octets (160..) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | | | | | | |||
| + + | + + | |||
| | | | | | | |||
| + Stateless Reset Token (128) + | + Stateless Reset Token (128) + | |||
| | | | | | | |||
| + + | + + | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 11: Stateless Reset Packet | Figure 7: Stateless Reset Packet | |||
| This design ensures that a stateless reset packet is - to the extent | This design ensures that a stateless reset packet is - to the extent | |||
| possible - indistinguishable from a regular packet with a short | possible - indistinguishable from a regular packet with a short | |||
| header. | header. | |||
| The message consists of a header octet, followed by an arbitrary | The message consists of a header octet, followed by an arbitrary | |||
| number of random octets, followed by a Stateless Reset Token. | number of random octets, followed by a Stateless Reset Token. | |||
| A stateless reset will be interpreted by a recipient as a packet with | A stateless reset will be interpreted by a recipient as a packet with | |||
| a short header. For the packet to appear as valid, the Random Octets | a short header. For the packet to appear as valid, the Random Octets | |||
| skipping to change at page 65, line 11 ¶ | skipping to change at page 55, line 25 ¶ | |||
| Because the stateless reset token is not available until connection | Because the stateless reset token is not available until connection | |||
| establishment is complete or near completion, ignoring an unknown | establishment is complete or near completion, ignoring an unknown | |||
| packet with a long header might be more effective. | packet with a long header might be more effective. | |||
| An endpoint cannot determine the Source Connection ID from a packet | An endpoint cannot determine the Source Connection ID from a packet | |||
| with a short header, therefore it cannot set the Destination | with a short header, therefore it cannot set the Destination | |||
| Connection ID in the stateless reset packet. The Destination | Connection ID in the stateless reset packet. The Destination | |||
| Connection ID will therefore differ from the value used in previous | Connection ID will therefore differ from the value used in previous | |||
| packets. A random Destination Connection ID makes the connection ID | packets. A random Destination Connection ID makes the connection ID | |||
| appear to be the result of moving to a new connection ID that was | appear to be the result of moving to a new connection ID that was | |||
| provided using a NEW_CONNECTION_ID frame (Section 7.13). | provided using a NEW_CONNECTION_ID frame (Section 19.12). | |||
| Using a randomized connection ID results in two problems: | Using a randomized connection ID results in two problems: | |||
| o The packet might not reach the peer. If the Destination | o The packet might not reach the peer. If the Destination | |||
| Connection ID is critical for routing toward the peer, then this | Connection ID is critical for routing toward the peer, then this | |||
| packet could be incorrectly routed. This might also trigger | packet could be incorrectly routed. This might also trigger | |||
| another Stateless Reset in response, see Section 6.13.4.3. A | another Stateless Reset in response, see Section 10.4.3. A | |||
| Stateless Reset that is not correctly routed is ineffective in | Stateless Reset that is not correctly routed is ineffective in | |||
| causing errors to be quickly detected and recovered. In this | causing errors to be quickly detected and recovered. In this | |||
| case, endpoints will need to rely on other methods - such as | case, endpoints will need to rely on other methods - such as | |||
| timers - to detect that the connection has failed. | timers - to detect that the connection has failed. | |||
| o The randomly generated connection ID can be used by entities other | o The randomly generated connection ID can be used by entities other | |||
| than the peer to identify this as a potential stateless reset. An | than the peer to identify this as a potential stateless reset. An | |||
| endpoint that occasionally uses different connection IDs might | endpoint that occasionally uses different connection IDs might | |||
| introduce some uncertainty about this. | introduce some uncertainty about this. | |||
| skipping to change at page 65, line 45 ¶ | skipping to change at page 56, line 10 ¶ | |||
| sufficient state to do so. | sufficient state to do so. | |||
| This stateless reset design is specific to QUIC version 1. An | This stateless reset design is specific to QUIC version 1. An | |||
| endpoint that supports multiple versions of QUIC needs to generate a | endpoint that supports multiple versions of QUIC needs to generate a | |||
| stateless reset that will be accepted by peers that support any | stateless reset that will be accepted by peers that support any | |||
| version that the endpoint might support (or might have supported | version that the endpoint might support (or might have supported | |||
| prior to losing state). Designers of new versions of QUIC need to be | prior to losing state). Designers of new versions of QUIC need to be | |||
| aware of this and either reuse this design, or use a portion of the | aware of this and either reuse this design, or use a portion of the | |||
| packet other than the last 16 octets for carrying data. | packet other than the last 16 octets for carrying data. | |||
| 6.13.4.1. Detecting a Stateless Reset | 10.4.1. Detecting a Stateless Reset | |||
| An endpoint detects a potential stateless reset when a packet with a | An endpoint detects a potential stateless reset when a packet with a | |||
| short header either cannot be decrypted or is marked as a duplicate | short header either cannot be decrypted or is marked as a duplicate | |||
| packet. The endpoint then compares the last 16 octets of the packet | packet. The endpoint then compares the last 16 octets of the packet | |||
| with the Stateless Reset Token provided by its peer, either in a | with the Stateless Reset Token provided by its peer, either in a | |||
| NEW_CONNECTION_ID frame or the server's transport parameters. If | NEW_CONNECTION_ID frame or the server's transport parameters. If | |||
| these values are identical, the endpoint MUST enter the draining | these values are identical, the endpoint MUST enter the draining | |||
| period and not send any further packets on this connection. If the | period and not send any further packets on this connection. If the | |||
| comparison fails, the packet can be discarded. | comparison fails, the packet can be discarded. | |||
| 6.13.4.2. Calculating a Stateless Reset Token | 10.4.2. Calculating a Stateless Reset Token | |||
| The stateless reset token MUST be difficult to guess. In order to | The stateless reset token MUST be difficult to guess. In order to | |||
| create a Stateless Reset Token, an endpoint could randomly generate | create a Stateless Reset Token, an endpoint could randomly generate | |||
| [RFC4086] a secret for every connection that it creates. However, | [RFC4086] a secret for every connection that it creates. However, | |||
| this presents a coordination problem when there are multiple | this presents a coordination problem when there are multiple | |||
| instances in a cluster or a storage problem for an endpoint that | instances in a cluster or a storage problem for an endpoint that | |||
| might lose state. Stateless reset specifically exists to handle the | might lose state. Stateless reset specifically exists to handle the | |||
| case where state is lost, so this approach is suboptimal. | case where state is lost, so this approach is suboptimal. | |||
| A single static key can be used across all connections to the same | A single static key can be used across all connections to the same | |||
| endpoint by generating the proof using a second iteration of a | endpoint by generating the proof using a second iteration of a | |||
| preimage-resistant function that takes a static key and the | preimage-resistant function that takes a static key and the | |||
| connection ID chosen by the endpoint (see Section 6.1) as input. An | connection ID chosen by the endpoint (see Section 5.1) as input. An | |||
| endpoint could use HMAC [RFC2104] (for example, HMAC(static_key, | endpoint could use HMAC [RFC2104] (for example, HMAC(static_key, | |||
| connection_id)) or HKDF [RFC5869] (for example, using the static key | connection_id)) or HKDF [RFC5869] (for example, using the static key | |||
| as input keying material, with the connection ID as salt). The | as input keying material, with the connection ID as salt). The | |||
| output of this function is truncated to 16 octets to produce the | output of this function is truncated to 16 octets to produce the | |||
| Stateless Reset Token for that connection. | Stateless Reset Token for that connection. | |||
| An endpoint that loses state can use the same method to generate a | An endpoint that loses state can use the same method to generate a | |||
| valid Stateless Reset Token. The connection ID comes from the packet | valid Stateless Reset Token. The connection ID comes from the packet | |||
| that the endpoint receives. | that the endpoint receives. | |||
| This design relies on the peer always sending a connection ID in its | This design relies on the peer always sending a connection ID in its | |||
| packets so that the endpoint can use the connection ID from a packet | packets so that the endpoint can use the connection ID from a packet | |||
| to reset the connection. An endpoint that uses this design MUST | to reset the connection. An endpoint that uses this design MUST | |||
| either use the same connection ID length for all connections or | either use the same connection ID length for all connections or | |||
| encode the length of the connection ID such that it can be recovered | encode the length of the connection ID such that it can be recovered | |||
| without state. In addition, it MUST NOT provide a zero-length | without state. In addition, it cannot provide a zero-length | |||
| connection ID. | connection ID. | |||
| Revealing the Stateless Reset Token allows any entity to terminate | Revealing the Stateless Reset Token allows any entity to terminate | |||
| the connection, so a value can only be used once. This method for | the connection, so a value can only be used once. This method for | |||
| choosing the Stateless Reset Token means that the combination of | choosing the Stateless Reset Token means that the combination of | |||
| connection ID and static key cannot occur for another connection. A | connection ID and static key cannot occur for another connection. A | |||
| denial of service attack is possible if the same connection ID is | denial of service attack is possible if the same connection ID is | |||
| used by instances that share a static key, or if an attacker can | used by instances that share a static key, or if an attacker can | |||
| cause a packet to be routed to an instance that has no state but the | cause a packet to be routed to an instance that has no state but the | |||
| same static key (see Section 12.8). A connection ID from a | same static key (see Section 21.8). A connection ID from a | |||
| connection that is reset by revealing the Stateless Reset Token | connection that is reset by revealing the Stateless Reset Token | |||
| cannot be reused for new connections at nodes that share a static | cannot be reused for new connections at nodes that share a static | |||
| key. | key. | |||
| Note that Stateless Reset packets do not have any cryptographic | Note that Stateless Reset packets do not have any cryptographic | |||
| protection. | protection. | |||
| 6.13.4.3. Looping | 10.4.3. Looping | |||
| The design of a Stateless Reset is such that it is indistinguishable | The design of a Stateless Reset is such that it is indistinguishable | |||
| from a valid packet. This means that a Stateless Reset might trigger | from a valid packet. This means that a Stateless Reset might trigger | |||
| the sending of a Stateless Reset in response, which could lead to | the sending of a Stateless Reset in response, which could lead to | |||
| infinite exchanges. | infinite exchanges. | |||
| An endpoint MUST ensure that every Stateless Reset that it sends is | An endpoint MUST ensure that every Stateless Reset that it sends is | |||
| smaller than the packet which triggered it, unless it maintains state | smaller than the packet which triggered it, unless it maintains state | |||
| sufficient to prevent looping. In the event of a loop, this results | sufficient to prevent looping. In the event of a loop, this results | |||
| in packets eventually being too small to trigger a response. | in packets eventually being too small to trigger a response. | |||
| skipping to change at page 67, line 39 ¶ | skipping to change at page 58, line 5 ¶ | |||
| observer that it is a Stateless Reset. Conversely, refusing to send | observer that it is a Stateless Reset. Conversely, refusing to send | |||
| a Stateless Reset in response to a small packet might result in | a Stateless Reset in response to a small packet might result in | |||
| Stateless Reset not being useful in detecting cases of broken | Stateless Reset not being useful in detecting cases of broken | |||
| connections where only very small packets are sent; such failures | connections where only very small packets are sent; such failures | |||
| might only be detected by other means, such as timers. | might only be detected by other means, such as timers. | |||
| An endpoint can increase the odds that a packet will trigger a | An endpoint can increase the odds that a packet will trigger a | |||
| Stateless Reset if it cannot be processed by padding it to at least | Stateless Reset if it cannot be processed by padding it to at least | |||
| 38 octets. | 38 octets. | |||
| 7. Frame Types and Formats | 11. Error Handling | |||
| As described in Section 5, packets contain one or more frames. This | An endpoint that detects an error SHOULD signal the existence of that | |||
| section describes the format and semantics of the core QUIC frame | error to its peer. Both transport-level and application-level errors | |||
| can affect an entire connection (see Section 11.1), while only | ||||
| application-level errors can be isolated to a single stream (see | ||||
| Section 11.2). | ||||
| The most appropriate error code (Section 20) SHOULD be included in | ||||
| the frame that signals the error. Where this specification | ||||
| identifies error conditions, it also identifies the error code that | ||||
| is used. | ||||
| A stateless reset (Section 10.4) is not suitable for any error that | ||||
| can be signaled with a CONNECTION_CLOSE, APPLICATION_CLOSE, or | ||||
| RST_STREAM frame. A stateless reset MUST NOT be used by an endpoint | ||||
| that has the state necessary to send a frame on the connection. | ||||
| 11.1. Connection Errors | ||||
| Errors that result in the connection being unusable, such as an | ||||
| obvious violation of protocol semantics or corruption of state that | ||||
| affects an entire connection, MUST be signaled using a | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE frame (Section 19.3, | ||||
| Section 19.4). An endpoint MAY close the connection in this manner | ||||
| even if the error only affects a single stream. | ||||
| Application protocols can signal application-specific protocol errors | ||||
| using the APPLICATION_CLOSE frame. Errors that are specific to the | ||||
| transport, including all those described in this document, are | ||||
| carried in a CONNECTION_CLOSE frame. Other than the type of error | ||||
| code they carry, these frames are identical in format and semantics. | ||||
| A CONNECTION_CLOSE or APPLICATION_CLOSE frame could be sent in a | ||||
| packet that is lost. An endpoint SHOULD be prepared to retransmit a | ||||
| packet containing either frame type if it receives more packets on a | ||||
| terminated connection. Limiting the number of retransmissions and | ||||
| the time over which this final packet is sent limits the effort | ||||
| expended on terminated connections. | ||||
| An endpoint that chooses not to retransmit packets containing | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE risks a peer missing the first | ||||
| such packet. The only mechanism available to an endpoint that | ||||
| continues to receive data for a terminated connection is to use the | ||||
| stateless reset process (Section 10.4). | ||||
| An endpoint that receives an invalid CONNECTION_CLOSE or | ||||
| APPLICATION_CLOSE frame MUST NOT signal the existence of the error to | ||||
| its peer. | ||||
| 11.2. Stream Errors | ||||
| If an application-level error affects a single stream, but otherwise | ||||
| leaves the connection in a recoverable state, the endpoint can send a | ||||
| RST_STREAM frame (Section 19.2) with an appropriate error code to | ||||
| terminate just the affected stream. | ||||
| Other than STOPPING (Section 3.5), RST_STREAM MUST be instigated by | ||||
| the application and MUST carry an application error code. Resetting | ||||
| a stream without knowledge of the application protocol could cause | ||||
| the protocol to enter an unrecoverable state. Application protocols | ||||
| might require certain streams to be reliably delivered in order to | ||||
| guarantee consistent state between endpoints. | ||||
| 12. Packets and Frames | ||||
| QUIC endpoints communicate by exchanging packets. Packets are | ||||
| carried in UDP datagrams (see Section 12.2) and have confidentiality | ||||
| and integrity protection (see Section 12.1). | ||||
| This version of QUIC uses the long packet header (see Section 17.2) | ||||
| during connection establishment and the short header (see | ||||
| Section 17.3) once 1-RTT keys have been established. | ||||
| Packets that carry the long header are Initial Section 17.5, Retry | ||||
| Section 17.7, Handshake Section 17.6, and 0-RTT Protected packets | ||||
| Section 12.1. | ||||
| Packets with the short header are designed for minimal overhead and | ||||
| are used after a connection is established. | ||||
| Version negotiation uses a packet with a special format (see | ||||
| Section 17.4). | ||||
| 12.1. Protected Packets | ||||
| All QUIC packets except Version Negotiation and Retry packets use | ||||
| authenticated encryption with additional data (AEAD) [RFC5119] to | ||||
| provide confidentiality and integrity protection. Details of packet | ||||
| protection are found in [QUIC-TLS]; this section includes an overview | ||||
| of the process. | ||||
| Initial packets are protected using keys that are statically derived. | ||||
| This packet protection is not effective confidentiality protection, | ||||
| it only exists to ensure that the sender of the packet is on the | ||||
| network path. Any entity that receives the Initial packet from a | ||||
| client can recover the keys necessary to remove packet protection or | ||||
| to generate packets that will be successfully authenticated. | ||||
| All other packets are protected with keys derived from the | ||||
| cryptographic handshake. The type of the packet from the long header | ||||
| or key phase from the short header are used to identify which | ||||
| encryption level - and therefore the keys - that are used. Packets | ||||
| protected with 0-RTT and 1-RTT keys are expected to have | ||||
| confidentiality and data origin authentication; the cryptographic | ||||
| handshake ensures that only the communicating endpoints receive the | ||||
| corresponding keys. | ||||
| The packet number field contains a packet number, which has | ||||
| additional confidentiality protection that is applied after packet | ||||
| protection is applied (see [QUIC-TLS] for details). The underlying | ||||
| packet number increases with each packet sent, see Section 12.3 for | ||||
| details. | ||||
| 12.2. Coalescing Packets | ||||
| A sender can coalesce multiple QUIC packets into one UDP datagram. | ||||
| This can reduce the number of UDP datagrams needed to complete the | ||||
| cryptographic handshake and starting sending data. Receivers MUST be | ||||
| able to process coalesced packets. | ||||
| Coalescing packets in order of increasing encryption levels (Initial, | ||||
| 0-RTT, Handshake, 1-RTT) makes it more likely the receiver will be | ||||
| able to process all the packets in a single pass. A packet with a | ||||
| short header does not include a length, so it will always be the last | ||||
| packet included in a UDP datagram. | ||||
| Senders MUST NOT coalesce QUIC packets for different connections into | ||||
| a single UDP datagram. Receivers SHOULD ignore any subsequent | ||||
| packets with a different Destination Connection ID than the first | ||||
| packet in the datagram. | ||||
| Every QUIC packet that is coalesced into a single UDP datagram is | ||||
| separate and complete. Though the values of some fields in the | ||||
| packet header might be redundant, no fields are omitted. The | ||||
| receiver of coalesced QUIC packets MUST individually process each | ||||
| QUIC packet and separately acknowledge them, as if they were received | ||||
| as the payload of different UDP datagrams. For example, if | ||||
| decryption fails (because the keys are not available or any other | ||||
| reason) or the packet is of an unknown type, the receiver MAY either | ||||
| discard or buffer the packet for later processing and MUST attempt to | ||||
| process the remaining packets. | ||||
| Retry packets (Section 17.7), Version Negotiation packets | ||||
| (Section 17.4), and packets with a short header cannot be followed by | ||||
| other packets in the same UDP datagram. | ||||
| 12.3. Packet Numbers | ||||
| The packet number is an integer in the range 0 to 2^62-1. Where | ||||
| present, packet numbers are encoded as a variable-length integer (see | ||||
| Section 16). This number is used in determining the cryptographic | ||||
| nonce for packet protection. Each endpoint maintains a separate | ||||
| packet number for sending and receiving. | ||||
| Version Negotiation (Section 17.4) and Retry Section 17.7 packets do | ||||
| not include a packet number. | ||||
| Packet numbers are divided into 3 spaces in QUIC: | ||||
| o Initial space: All Initial packets Section 17.5 are in this space. | ||||
| o Handshake space: All Handshake packets Section 17.6 are in this | ||||
| space. | ||||
| o Application data space: All 0-RTT and 1-RTT encrypted packets | ||||
| Section 12.1 are in this space. | ||||
| As described in [QUIC-TLS], each packet type uses different | ||||
| protection keys. | ||||
| Conceptually, a packet number space is the context in which a packet | ||||
| can be processed and acknowledged. Initial packets can only be sent | ||||
| with Initial packet protection keys and acknowledged in packets which | ||||
| are also Initial packets. Similarly, Handshake packets are sent at | ||||
| the Handshake encryption level and can only be acknowledged in | ||||
| Handshake packets. | ||||
| This enforces cryptographic separation between the data sent in the | ||||
| different packet sequence number spaces. Each packet number space | ||||
| starts at packet number 0. Subsequent packets sent in the same | ||||
| packet number space MUST increase the packet number by at least one. | ||||
| 0-RTT and 1-RTT data exist in the same packet number space to make | ||||
| loss recovery algorithms easier to implement between the two packet | ||||
| types. | types. | |||
| 7.1. Variable-Length Integer Encoding | A QUIC endpoint MUST NOT reuse a packet number within the same packet | |||
| number space in one connection (that is, under the same cryptographic | ||||
| keys). If the packet number for sending reaches 2^62 - 1, the sender | ||||
| MUST close the connection without sending a CONNECTION_CLOSE frame or | ||||
| any further packets; an endpoint MAY send a Stateless Reset | ||||
| (Section 10.4) in response to further packets that it receives. | ||||
| QUIC frames commonly use a variable-length encoding for non-negative | A receiver MUST discard a newly unprotected packet unless it is | |||
| integer values. This encoding ensures that smaller integer values | certain that it has not processed another packet with the same packet | |||
| need fewer octets to encode. | number from the same packet number space. Duplicate suppression MUST | |||
| happen after removing packet protection for the reasons described in | ||||
| Section 9.3 of [QUIC-TLS]. An efficient algorithm for duplicate | ||||
| suppression can be found in Section 3.4.3 of [RFC2406]. | ||||
| Packet number encoding at a sender and decoding at a receiver are | ||||
| described in Section 17.1. | ||||
| 12.4. Frames and Frame Types | ||||
| The payload of QUIC packets, after removing packet protection, | ||||
| commonly consists of a sequence of frames, as shown in Figure 8. | ||||
| Version Negotiation, Stateless Reset, and Retry packets do not | ||||
| contain frames. | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Frame 1 (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Frame 2 (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Frame N (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 8: QUIC Payload | ||||
| QUIC payloads MUST contain at least one frame, and MAY contain | ||||
| multiple frames and multiple frame types. | ||||
| Frames MUST fit within a single QUIC packet and MUST NOT span a QUIC | ||||
| packet boundary. Each frame begins with a Frame Type, indicating its | ||||
| type, followed by additional type-dependent fields: | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Frame Type (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Type-Dependent Fields (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 9: Generic Frame Layout | ||||
| The frame types defined in this specification are listed in Table 3. | ||||
| The Frame Type in STREAM frames is used to carry other frame-specific | ||||
| flags. For all other frames, the Frame Type field simply identifies | ||||
| the frame. These frames are explained in more detail in Section 19. | ||||
| +-------------+----------------------+---------------+ | ||||
| | Type Value | Frame Type Name | Definition | | ||||
| +-------------+----------------------+---------------+ | ||||
| | 0x00 | PADDING | Section 19.1 | | ||||
| | | | | | ||||
| | 0x01 | RST_STREAM | Section 19.2 | | ||||
| | | | | | ||||
| | 0x02 | CONNECTION_CLOSE | Section 19.3 | | ||||
| | | | | | ||||
| | 0x03 | APPLICATION_CLOSE | Section 19.4 | | ||||
| | | | | | ||||
| | 0x04 | MAX_DATA | Section 19.5 | | ||||
| | | | | | ||||
| | 0x05 | MAX_STREAM_DATA | Section 19.6 | | ||||
| | | | | | ||||
| | 0x06 | MAX_STREAM_ID | Section 19.7 | | ||||
| | | | | | ||||
| | 0x07 | PING | Section 19.8 | | ||||
| | | | | | ||||
| | 0x08 | BLOCKED | Section 19.9 | | ||||
| | | | | | ||||
| | 0x09 | STREAM_BLOCKED | Section 19.10 | | ||||
| | | | | | ||||
| | 0x0a | STREAM_ID_BLOCKED | Section 19.11 | | ||||
| | | | | | ||||
| | 0x0b | NEW_CONNECTION_ID | Section 19.12 | | ||||
| | | | | | ||||
| | 0x0c | STOP_SENDING | Section 19.14 | | ||||
| | | | | | ||||
| | 0x0d | RETIRE_CONNECTION_ID | Section 19.13 | | ||||
| | | | | | ||||
| | 0x0e | PATH_CHALLENGE | Section 19.16 | | ||||
| | | | | | ||||
| | 0x0f | PATH_RESPONSE | Section 19.17 | | ||||
| | | | | | ||||
| | 0x10 - 0x17 | STREAM | Section 19.19 | | ||||
| | | | | | ||||
| | 0x18 | CRYPTO | Section 19.20 | | ||||
| | | | | | ||||
| | 0x19 | NEW_TOKEN | Section 19.18 | | ||||
| | | | | | ||||
| | 0x1a - 0x1b | ACK | Section 19.15 | | ||||
| +-------------+----------------------+---------------+ | ||||
| Table 3: Frame Types | ||||
| All QUIC frames are idempotent. That is, a valid frame does not | ||||
| cause undesirable side effects or errors when received more than | ||||
| once. | ||||
| The Frame Type field uses a variable length integer encoding (see | ||||
| Section 16) with one exception. To ensure simple and efficient | ||||
| implementations of frame parsing, a frame type MUST use the shortest | ||||
| possible encoding. Though a two-, four- or eight-octet encoding of | ||||
| the frame types defined in this document is possible, the Frame Type | ||||
| field for these frames is encoded on a single octet. For instance, | ||||
| though 0x4007 is a legitimate two-octet encoding for a variable- | ||||
| length integer with a value of 7, PING frames are always encoded as a | ||||
| single octet with the value 0x07. An endpoint MUST treat the receipt | ||||
| of a frame type that uses a longer encoding than necessary as a | ||||
| connection error of type PROTOCOL_VIOLATION. | ||||
| 13. Packetization and Reliability | ||||
| A sender bundles one or more frames in a QUIC packet (see | ||||
| Section 12.4). | ||||
| A sender can minimize per-packet bandwidth and computational costs by | ||||
| bundling as many frames as possible within a QUIC packet. A sender | ||||
| MAY wait for a short period of time to bundle multiple frames before | ||||
| sending a packet that is not maximally packed, to avoid sending out | ||||
| large numbers of small packets. An implementation may use knowledge | ||||
| about application sending behavior or heuristics to determine whether | ||||
| and for how long to wait. This waiting period is an implementation | ||||
| decision, and an implementation should be careful to delay | ||||
| conservatively, since any delay is likely to increase application- | ||||
| visible latency. | ||||
| Stream multiplexing is achieved by interleaving STREAM frames from | ||||
| multiple streams into one or more QUIC packets. A single QUIC packet | ||||
| can include multiple STREAM frames from one or more streams. | ||||
| One of the benefits of QUIC is avoidance of head-of-line blocking | ||||
| across multiple streams. When a packet loss occurs, only streams | ||||
| with data in that packet are blocked waiting for a retransmission to | ||||
| be received, while other streams can continue making progress. Note | ||||
| that when data from multiple streams is bundled into a single QUIC | ||||
| packet, loss of that packet blocks all those streams from making | ||||
| progress. Implementations are advised to bundle as few streams as | ||||
| necessary in outgoing packets without losing transmission efficiency | ||||
| to underfilled packets. | ||||
| 13.1. Packet Processing and Acknowledgment | ||||
| A packet MUST NOT be acknowledged until packet protection has been | ||||
| successfully removed and all frames contained in the packet have been | ||||
| processed. For STREAM frames, this means the data has been enqueued | ||||
| in preparation to be received by the application protocol, but it | ||||
| does not require that data is delivered and consumed. | ||||
| Once the packet has been fully processed, a receiver acknowledges | ||||
| receipt by sending one or more ACK frames containing the packet | ||||
| number of the received packet. | ||||
| 13.1.1. Sending ACK Frames | ||||
| To avoid creating an indefinite feedback loop, an endpoint MUST NOT | ||||
| send an ACK frame in response to a packet containing only ACK or | ||||
| PADDING frames, even if there are packet gaps which precede the | ||||
| received packet. The endpoint MUST however acknowledge packets | ||||
| containing only ACK or PADDING frames when sending ACK frames in | ||||
| response to other packets. | ||||
| While PADDING frames do not elicit an ACK frame from a receiver, they | ||||
| are considered to be in flight for congestion control purposes | ||||
| [QUIC-RECOVERY]. Sending only PADDING frames might cause the sender | ||||
| to become limited by the congestion controller (as described in | ||||
| [QUIC-RECOVERY]) with no acknowledgments forthcoming from the | ||||
| receiver. Therefore, a sender should ensure that other frames are | ||||
| sent in addition to PADDING frames to elicit acknowledgments from the | ||||
| receiver. | ||||
| An endpoint MUST NOT send more than one packet containing only an ACK | ||||
| frame per received packet that contains frames other than ACK and | ||||
| PADDING frames. | ||||
| The receiver's delayed acknowledgment timer SHOULD NOT exceed the | ||||
| current RTT estimate or the value it indicates in the "max_ack_delay" | ||||
| transport parameter. This ensures an acknowledgment is sent at least | ||||
| once per RTT when packets needing acknowledgement are received. The | ||||
| sender can use the receiver's "max_ack_delay" value in determining | ||||
| timeouts for timer-based retransmission. | ||||
| Strategies and implications of the frequency of generating | ||||
| acknowledgments are discussed in more detail in [QUIC-RECOVERY]. | ||||
| To limit ACK Blocks to those that have not yet been received by the | ||||
| sender, the receiver SHOULD track which ACK frames have been | ||||
| acknowledged by its peer. Once an ACK frame has been acknowledged, | ||||
| the packets it acknowledges SHOULD NOT be acknowledged again. | ||||
| Because ACK frames are not sent in response to ACK-only packets, a | ||||
| receiver that is only sending ACK frames will only receive | ||||
| acknowledgements for its packets if the sender includes them in | ||||
| packets with non-ACK frames. A sender SHOULD bundle ACK frames with | ||||
| other frames when possible. | ||||
| To limit receiver state or the size of ACK frames, a receiver MAY | ||||
| limit the number of ACK Blocks it sends. A receiver can do this even | ||||
| without receiving acknowledgment of its ACK frames, with the | ||||
| knowledge this could cause the sender to unnecessarily retransmit | ||||
| some data. Standard QUIC [QUIC-RECOVERY] algorithms declare packets | ||||
| lost after sufficiently newer packets are acknowledged. Therefore, | ||||
| the receiver SHOULD repeatedly acknowledge newly received packets in | ||||
| preference to packets received in the past. | ||||
| 13.1.2. ACK Frames and Packet Protection | ||||
| ACK frames MUST only be carried in a packet that has the same packet | ||||
| number space as the packet being ACKed (see Section 12.1). For | ||||
| instance, packets that are protected with 1-RTT keys MUST be | ||||
| acknowledged in packets that are also protected with 1-RTT keys. | ||||
| Packets that a client sends with 0-RTT packet protection MUST be | ||||
| acknowledged by the server in packets protected by 1-RTT keys. This | ||||
| can mean that the client is unable to use these acknowledgments if | ||||
| the server cryptographic handshake messages are delayed or lost. | ||||
| Note that the same limitation applies to other data sent by the | ||||
| server protected by the 1-RTT keys. | ||||
| Endpoints SHOULD send acknowledgments for packets containing CRYPTO | ||||
| frames with a reduced delay; see Section 4.3.1 of [QUIC-RECOVERY]. | ||||
| 13.2. Retransmission of Information | ||||
| QUIC packets that are determined to be lost are not retransmitted | ||||
| whole. The same applies to the frames that are contained within lost | ||||
| packets. Instead, the information that might be carried in frames is | ||||
| sent again in new frames as needed. | ||||
| New frames and packets are used to carry information that is | ||||
| determined to have been lost. In general, information is sent again | ||||
| when a packet containing that information is determined to be lost | ||||
| and sending ceases when a packet containing that information is | ||||
| acknowledged. | ||||
| o Data sent in CRYPTO frames is retransmitted according to the rules | ||||
| in [QUIC-RECOVERY], until all data has been acknowledged. | ||||
| o Application data sent in STREAM frames is retransmitted in new | ||||
| STREAM frames unless the endpoint has sent a RST_STREAM for that | ||||
| stream. Once an endpoint sends a RST_STREAM frame, no further | ||||
| STREAM frames are needed. | ||||
| o The most recent set of acknowledgments are sent in ACK frames. An | ||||
| ACK frame SHOULD contain all unacknowledged acknowledgments, as | ||||
| described in Section 13.1.1. | ||||
| o Cancellation of stream transmission, as carried in a RST_STREAM | ||||
| frame, is sent until acknowledged or until all stream data is | ||||
| acknowledged by the peer (that is, either the "Reset Recvd" or | ||||
| "Data Recvd" state is reached on the send stream). The content of | ||||
| a RST_STREAM frame MUST NOT change when it is sent again. | ||||
| o Similarly, a request to cancel stream transmission, as encoded in | ||||
| a STOP_SENDING frame, is sent until the receive stream enters | ||||
| either a "Data Recvd" or "Reset Recvd" state, see Section 3.5. | ||||
| o Connection close signals, including those that use | ||||
| CONNECTION_CLOSE and APPLICATION_CLOSE frames, are not sent again | ||||
| when packet loss is detected, but as described in Section 10. | ||||
| o The current connection maximum data is sent in MAX_DATA frames. | ||||
| An updated value is sent in a MAX_DATA frame if the packet | ||||
| containing the most recently sent MAX_DATA frame is declared lost, | ||||
| or when the endpoint decides to update the limit. Care is | ||||
| necessary to avoid sending this frame too often as the limit can | ||||
| increase frequently and cause an unnecessarily large number of | ||||
| MAX_DATA frames to be sent. | ||||
| o The current maximum stream data offset is sent in MAX_STREAM_DATA | ||||
| frames. Like MAX_DATA, an updated value is sent when the packet | ||||
| containing the most recent MAX_STREAM_DATA frame for a stream is | ||||
| lost or when the limit is updated, with care taken to prevent the | ||||
| frame from being sent too often. An endpoint SHOULD stop sending | ||||
| MAX_STREAM_DATA frames when the receive stream enters a "Size | ||||
| Known" state. | ||||
| o The maximum stream ID for a stream of a given type is sent in | ||||
| MAX_STREAM_ID frames. Like MAX_DATA, an updated value is sent | ||||
| when a packet containing the most recent MAX_STREAM_ID for a | ||||
| stream type frame is declared lost or when the limit is updated, | ||||
| with care taken to prevent the frame from being sent too often. | ||||
| o Blocked signals are carried in BLOCKED, STREAM_BLOCKED, and | ||||
| STREAM_ID_BLOCKED frames. BLOCKED streams have connection scope, | ||||
| STREAM_BLOCKED frames have stream scope, and STREAM_ID_BLOCKED | ||||
| frames are scoped to a specific stream type. New frames are sent | ||||
| if packets containing the most recent frame for a scope is lost, | ||||
| but only while the endpoint is blocked on the corresponding limit. | ||||
| These frames always include the limit that is causing blocking at | ||||
| the time that they are transmitted. | ||||
| o A liveness or path validation check using PATH_CHALLENGE frames is | ||||
| sent periodically until a matching PATH_RESPONSE frame is received | ||||
| or until there is no remaining need for liveness or path | ||||
| validation checking. PATH_CHALLENGE frames include a different | ||||
| payload each time they are sent. | ||||
| o Responses to path validation using PATH_RESPONSE frames are sent | ||||
| just once. A new PATH_CHALLENGE frame will be sent if another | ||||
| PATH_RESPONSE frame is needed. | ||||
| o New connection IDs are sent in NEW_CONNECTION_ID frames and | ||||
| retransmitted if the packet containing them is lost. | ||||
| Retransmissions of this frame carry the same sequence number | ||||
| value. Likewise, retired connection IDs are sent in | ||||
| RETIRE_CONNECTION_ID frames and retransmitted if the packet | ||||
| containing them is lost. | ||||
| o PADDING frames contain no information, so lost PADDING frames do | ||||
| not require repair. | ||||
| Upon detecting losses, a sender MUST take appropriate congestion | ||||
| control action. The details of loss detection and congestion control | ||||
| are described in [QUIC-RECOVERY]. | ||||
| 13.3. Explicit Congestion Notification | ||||
| QUIC endpoints use Explicit Congestion Notification (ECN) [RFC3168] | ||||
| to detect and respond to network congestion. ECN allows a network | ||||
| node to indicate congestion in the network by setting a codepoint in | ||||
| the IP header of a packet instead of dropping it. Endpoints react to | ||||
| congestion by reducing their sending rate in response, as described | ||||
| in [QUIC-RECOVERY]. | ||||
| To use ECN, QUIC endpoints first determine whether a path supports | ||||
| ECN marking and the peer is able to access the ECN codepoint in the | ||||
| IP header. A network path does not support ECN if ECN marked packets | ||||
| get dropped or ECN markings are rewritten on the path. An endpoint | ||||
| verifies the path, both during connection establishment and when | ||||
| migrating to a new path (see Section 9). | ||||
| 13.3.1. ECN Counters | ||||
| On receiving a packet with an ECT or CE codepoint, an endpoint that | ||||
| can access the IP ECN codepoints increases the corresponding ECT(0), | ||||
| ECT(1), or CE count, and includes these counters in subsequent (see | ||||
| Section 13.1) ACK frames (see Section 19.15). | ||||
| A packet detected by a receiver as a duplicate does not affect the | ||||
| receiver's local ECN codepoint counts; see (Section 21.7) for | ||||
| relevant security concerns. | ||||
| If an endpoint receives a packet without an ECT or CE codepoint, it | ||||
| responds per Section 13.1 with an ACK frame. If an endpoint does not | ||||
| have access to received ECN codepoints, it acknowledges received | ||||
| packets per Section 13.1 with an ACK frame. | ||||
| 13.3.2. ECN Verification | ||||
| Each endpoint independently verifies and enables use of ECN by | ||||
| setting the IP header ECN codepoint to ECN Capable Transport (ECT) | ||||
| for the path from it to the other peer. Even if ECN is not used on | ||||
| the path to the peer, the endpoint MUST provide feedback about ECN | ||||
| markings received (if accessible). | ||||
| To verify both that a path supports ECN and the peer can provide ECN | ||||
| feedback, an endpoint MUST set the ECT(0) codepoint in the IP header | ||||
| of all outgoing packets [RFC8311]. | ||||
| If an ECT codepoint set in the IP header is not corrupted by a | ||||
| network device, then a received packet contains either the codepoint | ||||
| sent by the peer or the Congestion Experienced (CE) codepoint set by | ||||
| a network device that is experiencing congestion. | ||||
| If a packet sent with an ECT codepoint is newly acknowledged by the | ||||
| peer in an ACK frame without ECN feedback, the endpoint stops setting | ||||
| ECT codepoints in subsequent packets, with the expectation that | ||||
| either the network or the peer no longer supports ECN. | ||||
| To protect the connection from arbitrary corruption of ECN codepoints | ||||
| by the network, an endpoint verifies the following when an ACK frame | ||||
| is received: | ||||
| o The increase in ECT(0) and ECT(1) counters MUST be at least the | ||||
| number of packets newly acknowledged that were sent with the | ||||
| corresponding codepoint. | ||||
| o The total increase in ECT(0), ECT(1), and CE counters reported in | ||||
| the ACK frame MUST be at least the total number of packets newly | ||||
| acknowledged in this ACK frame. | ||||
| An endpoint could miss acknowledgements for a packet when ACK frames | ||||
| are lost. It is therefore possible for the total increase in ECT(0), | ||||
| ECT(1), and CE counters to be greater than the number of packets | ||||
| acknowledged in an ACK frame. When this happens, the local reference | ||||
| counts MUST be increased to match the counters in the ACK frame. | ||||
| Upon successful verification, an endpoint continues to set ECT | ||||
| codepoints in subsequent packets with the expectation that the path | ||||
| is ECN-capable. | ||||
| If verification fails, then the endpoint ceases setting ECT | ||||
| codepoints in subsequent packets with the expectation that either the | ||||
| network or the peer does not support ECN. | ||||
| If an endpoint sets ECT codepoints on outgoing packets and encounters | ||||
| a retransmission timeout due to the absence of acknowledgments from | ||||
| the peer (see [QUIC-RECOVERY]), or if an endpoint has reason to | ||||
| believe that a network element might be corrupting ECN codepoints, | ||||
| the endpoint MAY cease setting ECT codepoints in subsequent packets. | ||||
| Doing so allows the connection to traverse network elements that drop | ||||
| or corrupt ECN codepoints in the IP header. | ||||
| 14. Packet Size | ||||
| The QUIC packet size includes the QUIC header and integrity check, | ||||
| but not the UDP or IP header. | ||||
| Clients MUST ensure that the first Initial packet they send is sent | ||||
| in a UDP datagram that is at least 1200 octets. Padding the Initial | ||||
| packet or including a 0-RTT packet in the same datagram are ways to | ||||
| meet this requirement. Sending a UDP datagram of this size ensures | ||||
| that the network path supports a reasonable Maximum Transmission Unit | ||||
| (MTU), and helps reduce the amplitude of amplification attacks caused | ||||
| by server responses toward an unverified client address, see | ||||
| Section 8. | ||||
| The payload of a UDP datagram carrying the Initial packet MUST be | ||||
| expanded to at least 1200 octets, by adding PADDING frames to the | ||||
| Initial packet and/or by combining the Initial packet with a 0-RTT | ||||
| packet (see Section 12.2). | ||||
| The datagram containing the first Initial packet from a client MAY | ||||
| exceed 1200 octets if the client believes that the Path Maximum | ||||
| Transmission Unit (PMTU) supports the size that it chooses. | ||||
| A server MAY send a CONNECTION_CLOSE frame with error code | ||||
| PROTOCOL_VIOLATION in response to the first Initial packet it | ||||
| receives from a client if the UDP datagram is smaller than 1200 | ||||
| octets. It MUST NOT send any other frame type in response, or | ||||
| otherwise behave as if any part of the offending packet was processed | ||||
| as valid. | ||||
| The server MUST also limit the number of bytes it sends before | ||||
| validating the address of the client, see Section 8. | ||||
| 14.1. Path Maximum Transmission Unit | ||||
| The Path Maximum Transmission Unit (PMTU) is the maximum size of the | ||||
| entire IP header, UDP header, and UDP payload. The UDP payload | ||||
| includes the QUIC packet header, protected payload, and any | ||||
| authentication fields. | ||||
| All QUIC packets SHOULD be sized to fit within the estimated PMTU to | ||||
| avoid IP fragmentation or packet drops. To optimize bandwidth | ||||
| efficiency, endpoints SHOULD use Packetization Layer PMTU Discovery | ||||
| ([PLPMTUD]). Endpoints MAY use PMTU Discovery ([PMTUDv4], [PMTUDv6]) | ||||
| for detecting the PMTU, setting the PMTU appropriately, and storing | ||||
| the result of previous PMTU determinations. | ||||
| In the absence of these mechanisms, QUIC endpoints SHOULD NOT send IP | ||||
| packets larger than 1280 octets. Assuming the minimum IP header | ||||
| size, this results in a QUIC packet size of 1232 octets for IPv6 and | ||||
| 1252 octets for IPv4. Some QUIC implementations MAY be more | ||||
| conservative in computing allowed QUIC packet size given unknown | ||||
| tunneling overheads or IP header options. | ||||
| QUIC endpoints that implement any kind of PMTU discovery SHOULD | ||||
| maintain an estimate for each combination of local and remote IP | ||||
| addresses. Each pairing of local and remote addresses could have a | ||||
| different maximum MTU in the path. | ||||
| QUIC depends on the network path supporting an MTU of at least 1280 | ||||
| octets. This is the IPv6 minimum MTU and therefore also supported by | ||||
| most modern IPv4 networks. An endpoint MUST NOT reduce its MTU below | ||||
| this number, even if it receives signals that indicate a smaller | ||||
| limit might exist. | ||||
| If a QUIC endpoint determines that the PMTU between any pair of local | ||||
| and remote IP addresses has fallen below 1280 octets, it MUST | ||||
| immediately cease sending QUIC packets on the affected path. This | ||||
| could result in termination of the connection if an alternative path | ||||
| cannot be found. | ||||
| 14.1.1. IPv4 PMTU Discovery | ||||
| Traditional ICMP-based path MTU discovery in IPv4 [PMTUDv4] is | ||||
| potentially vulnerable to off-path attacks that successfully guess | ||||
| the IP/port 4-tuple and reduce the MTU to a bandwidth-inefficient | ||||
| value. TCP connections mitigate this risk by using the (at minimum) | ||||
| 8 bytes of transport header echoed in the ICMP message to validate | ||||
| the TCP sequence number as valid for the current connection. | ||||
| However, as QUIC operates over UDP, in IPv4 the echoed information | ||||
| could consist only of the IP and UDP headers, which usually has | ||||
| insufficient entropy to mitigate off-path attacks. | ||||
| As a result, endpoints that implement PMTUD in IPv4 SHOULD take steps | ||||
| to mitigate this risk. For instance, an application could: | ||||
| o Set the IPv4 Don't Fragment (DF) bit on a small proportion of | ||||
| packets, so that most invalid ICMP messages arrive when there are | ||||
| no DF packets outstanding, and can therefore be identified as | ||||
| spurious. | ||||
| o Store additional information from the IP or UDP headers from DF | ||||
| packets (for example, the IP ID or UDP checksum) to further | ||||
| authenticate incoming Datagram Too Big messages. | ||||
| o Any reduction in PMTU due to a report contained in an ICMP packet | ||||
| is provisional until QUIC's loss detection algorithm determines | ||||
| that the packet is actually lost. | ||||
| 14.2. Special Considerations for Packetization Layer PMTU Discovery | ||||
| The PADDING frame provides a useful option for PMTU probe packets. | ||||
| PADDING frames generate acknowledgements, but they need not be | ||||
| delivered reliably. As a result, the loss of PADDING frames in probe | ||||
| packets does not require delay-inducing retransmission. However, | ||||
| PADDING frames do consume congestion window, which may delay the | ||||
| transmission of subsequent application data. | ||||
| When implementing the algorithm in Section 7.2 of [PLPMTUD], the | ||||
| initial value of search_low SHOULD be consistent with the IPv6 | ||||
| minimum packet size. Paths that do not support this size cannot | ||||
| deliver Initial packets, and therefore are not QUIC-compliant. | ||||
| Section 7.3 of [PLPMTUD] discusses trade-offs between small and large | ||||
| increases in the size of probe packets. As QUIC probe packets need | ||||
| not contain application data, aggressive increases in probe size | ||||
| carry fewer consequences. | ||||
| 15. Versions | ||||
| QUIC versions are identified using a 32-bit unsigned number. | ||||
| The version 0x00000000 is reserved to represent version negotiation. | ||||
| This version of the specification is identified by the number | ||||
| 0x00000001. | ||||
| Other versions of QUIC might have different properties to this | ||||
| version. The properties of QUIC that are guaranteed to be consistent | ||||
| across all versions of the protocol are described in | ||||
| [QUIC-INVARIANTS]. | ||||
| Version 0x00000001 of QUIC uses TLS as a cryptographic handshake | ||||
| protocol, as described in [QUIC-TLS]. | ||||
| Versions with the most significant 16 bits of the version number | ||||
| cleared are reserved for use in future IETF consensus documents. | ||||
| Versions that follow the pattern 0x?a?a?a?a are reserved for use in | ||||
| forcing version negotiation to be exercised. That is, any version | ||||
| number where the low four bits of all octets is 1010 (in binary). A | ||||
| client or server MAY advertise support for any of these reserved | ||||
| versions. | ||||
| Reserved version numbers will probably never represent a real | ||||
| protocol; a client MAY use one of these version numbers with the | ||||
| expectation that the server will initiate version negotiation; a | ||||
| server MAY advertise support for one of these versions and can expect | ||||
| that clients ignore the value. | ||||
| [[RFC editor: please remove the remainder of this section before | ||||
| publication.]] | ||||
| The version number for the final version of this specification | ||||
| (0x00000001), is reserved for the version of the protocol that is | ||||
| published as an RFC. | ||||
| Version numbers used to identify IETF drafts are created by adding | ||||
| the draft number to 0xff000000. For example, draft-ietf-quic- | ||||
| transport-13 would be identified as 0xff00000D. | ||||
| Implementors are encouraged to register version numbers of QUIC that | ||||
| they are using for private experimentation on the GitHub wiki at | ||||
| <https://github.com/quicwg/base-drafts/wiki/QUIC-Versions>. | ||||
| 16. Variable-Length Integer Encoding | ||||
| QUIC packets and frames commonly use a variable-length encoding for | ||||
| non-negative integer values. This encoding ensures that smaller | ||||
| integer values need fewer octets to encode. | ||||
| The QUIC variable-length integer encoding reserves the two most | The QUIC variable-length integer encoding reserves the two most | |||
| significant bits of the first octet to encode the base 2 logarithm of | significant bits of the first octet to encode the base 2 logarithm of | |||
| the integer encoding length in octets. The integer value is encoded | the integer encoding length in octets. The integer value is encoded | |||
| on the remaining bits, in network byte order. | on the remaining bits, in network byte order. | |||
| This means that integers are encoded on 1, 2, 4, or 8 octets and can | This means that integers are encoded on 1, 2, 4, or 8 octets and can | |||
| encode 6, 14, 30, or 62 bit values respectively. Table 4 summarizes | encode 6, 14, 30, or 62 bit values respectively. Table 4 summarizes | |||
| the encoding properties. | the encoding properties. | |||
| skipping to change at page 68, line 31 ¶ | skipping to change at page 75, line 40 ¶ | |||
| +------+--------+-------------+-----------------------+ | +------+--------+-------------+-----------------------+ | |||
| Table 4: Summary of Integer Encodings | Table 4: Summary of Integer Encodings | |||
| For example, the eight octet sequence c2 19 7c 5e ff 14 e8 8c (in | For example, the eight octet sequence c2 19 7c 5e ff 14 e8 8c (in | |||
| hexadecimal) decodes to the decimal value 151288809941952652; the | hexadecimal) decodes to the decimal value 151288809941952652; the | |||
| four octet sequence 9d 7f 3e 7d decodes to 494878333; the two octet | four octet sequence 9d 7f 3e 7d decodes to 494878333; the two octet | |||
| sequence 7b bd decodes to 15293; and the single octet 25 decodes to | sequence 7b bd decodes to 15293; and the single octet 25 decodes to | |||
| 37 (as does the two octet sequence 40 25). | 37 (as does the two octet sequence 40 25). | |||
| Error codes (Section 11.3) are described using integers, but do not | Error codes (Section 20) and versions Section 15 are described using | |||
| use this encoding. | integers, but do not use this encoding. | |||
| 7.2. PADDING Frame | 17. Packet Formats | |||
| All numeric values are encoded in network byte order (that is, big- | ||||
| endian) and all field sizes are in bits. Hexadecimal notation is | ||||
| used for describing the value of fields. | ||||
| 17.1. Packet Number Encoding and Decoding | ||||
| Packet numbers in long and short packet headers are encoded as | ||||
| follows. The number of bits required to represent the packet number | ||||
| is first reduced by including only a variable number of the least | ||||
| significant bits of the packet number. One or two of the most | ||||
| significant bits of the first octet are then used to represent how | ||||
| many bits of the packet number are provided, as shown in Table 5. | ||||
| +---------------------+----------------+--------------+ | ||||
| | First octet pattern | Encoded Length | Bits Present | | ||||
| +---------------------+----------------+--------------+ | ||||
| | 0b0xxxxxxx | 1 octet | 7 | | ||||
| | | | | | ||||
| | 0b10xxxxxx | 2 | 14 | | ||||
| | | | | | ||||
| | 0b11xxxxxx | 4 | 30 | | ||||
| +---------------------+----------------+--------------+ | ||||
| Table 5: Packet Number Encodings for Packet Headers | ||||
| Note that these encodings are similar to those in Section 16, but use | ||||
| different values. | ||||
| Finally, the encoded packet number is protected as described in | ||||
| Section 5.3 of [QUIC-TLS]. | ||||
| The sender MUST use a packet number size able to represent more than | ||||
| twice as large a range than the difference between the largest | ||||
| acknowledged packet and packet number being sent. A peer receiving | ||||
| the packet will then correctly decode the packet number, unless the | ||||
| packet is delayed in transit such that it arrives after many higher- | ||||
| numbered packets have been received. An endpoint SHOULD use a large | ||||
| enough packet number encoding to allow the packet number to be | ||||
| recovered even if the packet arrives after packets that are sent | ||||
| afterwards. | ||||
| As a result, the size of the packet number encoding is at least one | ||||
| more than the base 2 logarithm of the number of contiguous | ||||
| unacknowledged packet numbers, including the new packet. | ||||
| For example, if an endpoint has received an acknowledgment for packet | ||||
| 0x6afa2f, sending a packet with a number of 0x6b2d79 requires a | ||||
| packet number encoding with 14 bits or more; whereas the 30-bit | ||||
| packet number encoding is needed to send a packet with a number of | ||||
| 0x6bc107. | ||||
| At a receiver, protection of the packet number is removed prior to | ||||
| recovering the full packet number. The full packet number is then | ||||
| reconstructed based on the number of significant bits present, the | ||||
| value of those bits, and the largest packet number received on a | ||||
| successfully authenticated packet. Recovering the full packet number | ||||
| is necessary to successfully remove packet protection. | ||||
| Once packet number protection is removed, the packet number is | ||||
| decoded by finding the packet number value that is closest to the | ||||
| next expected packet. The next expected packet is the highest | ||||
| received packet number plus one. For example, if the highest | ||||
| successfully authenticated packet had a packet number of 0xaa82f30e, | ||||
| then a packet containing a 14-bit value of 0x9b3 will be decoded as | ||||
| 0xaa8309b3. Example pseudo-code for packet number decoding can be | ||||
| found in Appendix A. | ||||
| 17.2. Long Header Packet | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| Type (7) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Length (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Packet Number (8/16/32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Payload (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 10: Long Header Packet Format | ||||
| Long headers are used for packets that are sent prior to the | ||||
| completion of version negotiation and establishment of 1-RTT keys. | ||||
| Once both conditions are met, a sender switches to sending packets | ||||
| using the short header (Section 17.3). The long form allows for | ||||
| special packets - such as the Version Negotiation packet - to be | ||||
| represented in this uniform fixed-length packet format. Packets that | ||||
| use the long header contain the following fields: | ||||
| Header Form: The most significant bit (0x80) of octet 0 (the first | ||||
| octet) is set to 1 for long headers. | ||||
| Long Packet Type: The remaining seven bits of octet 0 contain the | ||||
| packet type. This field can indicate one of 128 packet types. | ||||
| The types specified for this version are listed in Table 6. | ||||
| Version: The QUIC Version is a 32-bit field that follows the Type. | ||||
| This field indicates which version of QUIC is in use and | ||||
| determines how the rest of the protocol fields are interpreted. | ||||
| DCIL and SCIL: The octet following the version contains the lengths | ||||
| of the two connection ID fields that follow it. These lengths are | ||||
| encoded as two 4-bit unsigned integers. The Destination | ||||
| Connection ID Length (DCIL) field occupies the 4 high bits of the | ||||
| octet and the Source Connection ID Length (SCIL) field occupies | ||||
| the 4 low bits of the octet. An encoded length of 0 indicates | ||||
| that the connection ID is also 0 octets in length. Non-zero | ||||
| encoded lengths are increased by 3 to get the full length of the | ||||
| connection ID, producing a length between 4 and 18 octets | ||||
| inclusive. For example, an octet with the value 0x50 describes an | ||||
| 8-octet Destination Connection ID and a zero-length Source | ||||
| Connection ID. | ||||
| Destination Connection ID: The Destination Connection ID field | ||||
| follows the connection ID lengths and is either 0 octets in length | ||||
| or between 4 and 18 octets. Section 7.2 describes the use of this | ||||
| field in more detail. | ||||
| Source Connection ID: The Source Connection ID field follows the | ||||
| Destination Connection ID and is either 0 octets in length or | ||||
| between 4 and 18 octets. Section 7.2 describes the use of this | ||||
| field in more detail. | ||||
| Length: The length of the remainder of the packet (that is, the | ||||
| Packet Number and Payload fields) in octets, encoded as a | ||||
| variable-length integer (Section 16). | ||||
| Packet Number: The packet number field is 1, 2, or 4 octets long. | ||||
| The packet number has confidentiality protection separate from | ||||
| packet protection, as described in Section 5.3 of [QUIC-TLS]. The | ||||
| length of the packet number field is encoded in the plaintext | ||||
| packet number. See Section 17.1 for details. | ||||
| Payload: The payload of the packet. | ||||
| The following packet types are defined: | ||||
| +------+-----------------+--------------+ | ||||
| | Type | Name | Section | | ||||
| +------+-----------------+--------------+ | ||||
| | 0x7F | Initial | Section 17.5 | | ||||
| | | | | | ||||
| | 0x7E | Retry | Section 17.7 | | ||||
| | | | | | ||||
| | 0x7D | Handshake | Section 17.6 | | ||||
| | | | | | ||||
| | 0x7C | 0-RTT Protected | Section 12.1 | | ||||
| +------+-----------------+--------------+ | ||||
| Table 6: Long Header Packet Types | ||||
| The header form, type, connection ID lengths octet, destination and | ||||
| source connection IDs, and version fields of a long header packet are | ||||
| version-independent. The packet number and values for packet types | ||||
| defined in Table 6 are version-specific. See [QUIC-INVARIANTS] for | ||||
| details on how packets from different versions of QUIC are | ||||
| interpreted. | ||||
| The interpretation of the fields and the payload are specific to a | ||||
| version and packet type. Type-specific semantics for this version | ||||
| are described in the following sections. | ||||
| The end of the packet is determined by the Length field. The Length | ||||
| field covers both the Packet Number and Payload fields, both of which | ||||
| are confidentiality protected and initially of unknown length. The | ||||
| size of the Payload field is learned once the packet number | ||||
| protection is removed. The Length field enables packet coalescing | ||||
| (Section 12.2). | ||||
| 17.3. Short Header Packet | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |0|K|1|1|0|R R R| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Packet Number (8/16/32) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Protected Payload (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 11: Short Header Packet Format | ||||
| The short header can be used after the version and 1-RTT keys are | ||||
| negotiated. Packets that use the short header contain the following | ||||
| fields: | ||||
| Header Form: The most significant bit (0x80) of octet 0 is set to 0 | ||||
| for the short header. | ||||
| Key Phase Bit: The second bit (0x40) of octet 0 indicates the key | ||||
| phase, which allows a recipient of a packet to identify the packet | ||||
| protection keys that are used to protect the packet. See | ||||
| [QUIC-TLS] for details. | ||||
| [[Editor's Note: this section should be removed and the bit | ||||
| definitions changed before this draft goes to the IESG.]] | ||||
| Third Bit: The third bit (0x20) of octet 0 is set to 1. | ||||
| [[Editor's Note: this section should be removed and the bit | ||||
| definitions changed before this draft goes to the IESG.]] | ||||
| Fourth Bit: The fourth bit (0x10) of octet 0 is set to 1. | ||||
| [[Editor's Note: this section should be removed and the bit | ||||
| definitions changed before this draft goes to the IESG.]] | ||||
| Google QUIC Demultiplexing Bit: The fifth bit (0x8) of octet 0 is | ||||
| set to 0. This allows implementations of Google QUIC to | ||||
| distinguish Google QUIC packets from short header packets sent by | ||||
| a client because Google QUIC servers expect the connection ID to | ||||
| always be present. The special interpretation of this bit SHOULD | ||||
| be removed from this specification when Google QUIC has finished | ||||
| transitioning to the new header format. | ||||
| Reserved: The sixth, seventh, and eighth bits (0x7) of octet 0 are | ||||
| reserved for experimentation. Endpoints MUST ignore these bits on | ||||
| packets they receive unless they are participating in an | ||||
| experiment that uses these bits. An endpoint not actively using | ||||
| these bits SHOULD set the value randomly on packets they send to | ||||
| protect against unwanted inference about particular values. | ||||
| Destination Connection ID: The Destination Connection ID is a | ||||
| connection ID that is chosen by the intended recipient of the | ||||
| packet. See Section 5.1 for more details. | ||||
| Packet Number: The packet number field is 1, 2, or 4 octets long. | ||||
| The packet number has confidentiality protection separate from | ||||
| packet protection, as described in Section 5.3 of [QUIC-TLS]. The | ||||
| length of the packet number field is encoded in the plaintext | ||||
| packet number. See Section 17.1 for details. | ||||
| Protected Payload: Packets with a short header always include a | ||||
| 1-RTT protected payload. | ||||
| The header form and connection ID field of a short header packet are | ||||
| version-independent. The remaining fields are specific to the | ||||
| selected QUIC version. See [QUIC-INVARIANTS] for details on how | ||||
| packets from different versions of QUIC are interpreted. | ||||
| 17.4. Version Negotiation Packet | ||||
| A Version Negotiation packet is inherently not version-specific, and | ||||
| does not use the long packet header (see Section 17.2). Upon receipt | ||||
| by a client, it will appear to be a packet using the long header, but | ||||
| will be identified as a Version Negotiation packet based on the | ||||
| Version field having a value of 0. | ||||
| The Version Negotiation packet is a response to a client packet that | ||||
| contains a version that is not supported by the server, and is only | ||||
| sent by servers. | ||||
| The layout of a Version Negotiation packet is: | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| Unused (7) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Supported Version 1 (32) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | [Supported Version 2 (32)] ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | [Supported Version N (32)] ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 12: Version Negotiation Packet | ||||
| The value in the Unused field is selected randomly by the server. | ||||
| The Version field of a Version Negotiation packet MUST be set to | ||||
| 0x00000000. | ||||
| The server MUST include the value from the Source Connection ID field | ||||
| of the packet it receives in the Destination Connection ID field. | ||||
| The value for Source Connection ID MUST be copied from the | ||||
| Destination Connection ID of the received packet, which is initially | ||||
| randomly selected by a client. Echoing both connection IDs gives | ||||
| clients some assurance that the server received the packet and that | ||||
| the Version Negotiation packet was not generated by an off-path | ||||
| attacker. | ||||
| The remainder of the Version Negotiation packet is a list of 32-bit | ||||
| versions which the server supports. | ||||
| A Version Negotiation packet cannot be explicitly acknowledged in an | ||||
| ACK frame by a client. Receiving another Initial packet implicitly | ||||
| acknowledges a Version Negotiation packet. | ||||
| The Version Negotiation packet does not include the Packet Number and | ||||
| Length fields present in other packets that use the long header form. | ||||
| Consequently, a Version Negotiation packet consumes an entire UDP | ||||
| datagram. | ||||
| See Section 6 for a description of the version negotiation process. | ||||
| 17.5. Initial Packet | ||||
| An Initial packet uses long headers with a type value of 0x7F. It | ||||
| carries the first CRYPTO frames sent by the client and server to | ||||
| perform key exchange, and carries ACKs in either direction. | ||||
| In order to prevent tampering by version-unaware middleboxes, Initial | ||||
| packets are protected with connection- and version-specific keys | ||||
| (Initial keys) as described in [QUIC-TLS]. This protection does not | ||||
| provide confidentiality or integrity against on-path attackers, but | ||||
| provides some level of protection against off-path attackers. | ||||
| An Initial packet (shown in Figure 13) has two additional header | ||||
| fields that are added to the Long Header before the Length field. | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| 0x7f | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Token Length (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Token (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Length (i) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Packet Number (8/16/32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Payload (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 13: Initial Packet | ||||
| These fields include the token that was previously provided in a | ||||
| Retry packet or NEW_TOKEN frame: | ||||
| Token Length: A variable-length integer specifying the length of the | ||||
| Token field, in bytes. This value is zero if no token is present. | ||||
| Initial packets sent by the server MUST set the Token Length field | ||||
| to zero; clients that receive an Initial packet with a non-zero | ||||
| Token Length field MUST either discard the packet or generate a | ||||
| connection error of type PROTOCOL_VIOLATION. | ||||
| Token: The value of the token. | ||||
| The client and server use the Initial packet type for any packet that | ||||
| contains an initial cryptographic handshake message. This includes | ||||
| all cases where a new packet containing the initial cryptographic | ||||
| message needs to be created, such as the packets sent after receiving | ||||
| a Version Negotiation (Section 17.4) or Retry packet (Section 17.7). | ||||
| A server sends its first Initial packet in response to a client | ||||
| Initial. A server may send multiple Initial packets. The | ||||
| cryptographic key exchange could require multiple round trips or | ||||
| retransmissions of this data. | ||||
| The payload of an Initial packet includes a CRYPTO frame (or frames) | ||||
| containing a cryptographic handshake message, ACK frames, or both. | ||||
| PADDING and CONNECTION_CLOSE frames are also permitted. An endpoint | ||||
| that receives an Initial packet containing other frames can either | ||||
| discard the packet as spurious or treat it as a connection error. | ||||
| The first packet sent by a client always includes a CRYPTO frame that | ||||
| contains the entirety of the first cryptographic handshake message. | ||||
| This packet, and the cryptographic handshake message, MUST fit in a | ||||
| single UDP datagram (see Section 7). The first CRYPTO frame sent | ||||
| always begins at an offset of 0 (see Section 7). | ||||
| Note that if the server sends a HelloRetryRequest, the client will | ||||
| send a second Initial packet. This Initial packet will continue the | ||||
| cryptographic handshake and will contain a CRYPTO frame with an | ||||
| offset matching the size of the CRYPTO frame sent in the first | ||||
| Initial packet. Cryptographic handshake messages subsequent to the | ||||
| first do not need to fit within a single UDP datagram. | ||||
| 17.5.1. Starting Packet Numbers | ||||
| The first Initial packet sent by either endpoint contains a packet | ||||
| number of 0. The packet number MUST increase monotonically | ||||
| thereafter. Initial packets are in a different packet number space | ||||
| to other packets (see Section 12.3). | ||||
| 17.5.2. 0-RTT Packet Numbers | ||||
| Packet numbers for 0-RTT protected packets use the same space as | ||||
| 1-RTT protected packets. | ||||
| After a client receives a Retry or Version Negotiation packet, 0-RTT | ||||
| packets are likely to have been lost or discarded by the server. A | ||||
| client MAY attempt to resend data in 0-RTT packets after it sends a | ||||
| new Initial packet. | ||||
| A client MUST NOT reset the packet number it uses for 0-RTT packets. | ||||
| The keys used to protect 0-RTT packets will not change as a result of | ||||
| responding to a Retry or Version Negotiation packet unless the client | ||||
| also regenerates the cryptographic handshake message. Sending | ||||
| packets with the same packet number in that case is likely to | ||||
| compromise the packet protection for all 0-RTT packets because the | ||||
| same key and nonce could be used to protect different content. | ||||
| Receiving a Retry or Version Negotiation packet, especially a Retry | ||||
| that changes the connection ID used for subsequent packets, indicates | ||||
| a strong possibility that 0-RTT packets could be lost. A client only | ||||
| receives acknowledgments for its 0-RTT packets once the handshake is | ||||
| complete. Consequently, a server might expect 0-RTT packets to start | ||||
| with a packet number of 0. Therefore, in determining the length of | ||||
| the packet number encoding for 0-RTT packets, a client MUST assume | ||||
| that all packets up to the current packet number are in flight, | ||||
| starting from a packet number of 0. Thus, 0-RTT packets could need | ||||
| to use a longer packet number encoding. | ||||
| A client SHOULD instead generate a fresh cryptographic handshake | ||||
| message and start packet numbers from 0. This ensures that new 0-RTT | ||||
| packets will not use the same keys, avoiding any risk of key and | ||||
| nonce reuse; this also prevents 0-RTT packets from previous handshake | ||||
| attempts from being accepted as part of the connection. | ||||
| 17.6. Handshake Packet | ||||
| A Handshake packet uses long headers with a type value of 0x7D. It | ||||
| is used to carry acknowledgments and cryptographic handshake messages | ||||
| from the server and client. | ||||
| Once a client has received a Handshake packet from a server, it uses | ||||
| Handshake packets to send subsequent cryptographic handshake messages | ||||
| and acknowledgments to the server. | ||||
| The Destination Connection ID field in a Handshake packet contains a | ||||
| connection ID that is chosen by the recipient of the packet; the | ||||
| Source Connection ID includes the connection ID that the sender of | ||||
| the packet wishes to use (see Section 7.2). | ||||
| The first Handshake packet sent by a server contains a packet number | ||||
| of 0. Handshake packets are their own packet number space. Packet | ||||
| numbers are incremented normally for other Handshake packets. | ||||
| The payload of this packet contains CRYPTO frames and could contain | ||||
| PADDING, or ACK frames. Handshake packets MAY contain | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE frames. Endpoints MUST treat | ||||
| receipt of Handshake packets with other frames as a connection error. | ||||
| 17.7. Retry Packet | ||||
| A Retry packet uses a long packet header with a type value of 0x7E. | ||||
| It carries an address validation token created by the server. It is | ||||
| used by a server that wishes to perform a stateless retry (see | ||||
| Section 8.1). | ||||
| 0 1 2 3 | ||||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||||
| +-+-+-+-+-+-+-+-+ | ||||
| |1| 0x7e | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Version (32) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| |DCIL(4)|SCIL(4)| | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Destination Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Source Connection ID (0/32..144) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | ODCIL(8) | Original Destination Connection ID (*) | | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| | Retry Token (*) ... | ||||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| Figure 14: Retry Packet | ||||
| A Retry packet (shown in Figure 14) only uses the invariant portion | ||||
| of the long packet header [QUIC-INVARIANTS]; that is, the fields up | ||||
| to and including the Destination and Source Connection ID fields. A | ||||
| Retry packet does not contain any protected fields. Like Version | ||||
| Negotiation, a Retry packet contains the long header including the | ||||
| connection IDs, but omits the Length, Packet Number, and Payload | ||||
| fields. These are replaced with: | ||||
| ODCIL: The length of the Original Destination Connection ID field. | ||||
| The length is encoded in the least significant 4 bits of the | ||||
| octet, using the same encoding as the DCIL and SCIL fields. The | ||||
| most significant 4 bits of this octet are reserved. Unless a use | ||||
| for these bits has been negotiated, endpoints SHOULD send | ||||
| randomized values and MUST ignore any value that it receives. | ||||
| Original Destination Connection ID: The Original Destination | ||||
| Connection ID contains the value of the Destination Connection ID | ||||
| from the Initial packet that this Retry is in response to. The | ||||
| length of this field is given in ODCIL. | ||||
| Retry Token: An opaque token that the server can use to validate the | ||||
| client's address. | ||||
| The server populates the Destination Connection ID with the | ||||
| connection ID that the client included in the Source Connection ID of | ||||
| the Initial packet. | ||||
| The server includes a connection ID of its choice in the Source | ||||
| Connection ID field. This value MUST not be equal to the Destination | ||||
| Connection ID field of the packet sent by the client. The client | ||||
| MUST use this connection ID in the Destination Connection ID of | ||||
| subsequent packets that it sends. | ||||
| A server MAY send Retry packets in response to Initial and 0-RTT | ||||
| packets. A server can either discard or buffer 0-RTT packets that it | ||||
| receives. A server can send multiple Retry packets as it receives | ||||
| Initial or 0-RTT packets. | ||||
| A client MUST accept and process at most one Retry packet for each | ||||
| connection attempt. After the client has received and processed an | ||||
| Initial or Retry packet from the server, it MUST discard any | ||||
| subsequent Retry packets that it receives. | ||||
| Clients MUST discard Retry packets that contain an Original | ||||
| Destination Connection ID field that does not match the Destination | ||||
| Connection ID from its Initial packet. This prevents an off-path | ||||
| attacker from injecting a Retry packet. | ||||
| The client responds to a Retry packet with an Initial packet that | ||||
| includes the provided Retry Token to continue connection | ||||
| establishment. | ||||
| A client sets the Destination Connection ID field of this Initial | ||||
| packet to the value from the Source Connection ID in the Retry | ||||
| packet. Changing Destination Connection ID also results in a change | ||||
| to the keys used to protect the Initial packet. It also sets the | ||||
| Token field to the token provided in the Retry. The client MUST NOT | ||||
| change the Source Connection ID because the server could include the | ||||
| connection ID as part of its token validation logic (see | ||||
| Section 8.1.2). | ||||
| All subsequent Initial packets from the client MUST use the | ||||
| connection ID and token values from the Retry packet. Aside from | ||||
| this, the Initial packet sent by the client is subject to the same | ||||
| restrictions as the first Initial packet. A client can either reuse | ||||
| the cryptographic handshake message or construct a new one at its | ||||
| discretion. | ||||
| A client MAY attempt 0-RTT after receiving a Retry packet by sending | ||||
| 0-RTT packets to the connection ID provided by the server. A client | ||||
| that sends additional 0-RTT packets without constructing a new | ||||
| cryptographic handshake message MUST NOT reset the packet number to 0 | ||||
| after a Retry packet, see Section 17.5.2. | ||||
| A server acknowledges the use of a Retry packet for a connection | ||||
| using the original_connection_id transport parameter (see | ||||
| Section 18.1). If the server sends a Retry packet, it MUST include | ||||
| the value of the Original Destination Connection ID field of the | ||||
| Retry packet (that is, the Destination Connection ID field from the | ||||
| client's first Initial packet) in the transport parameter. | ||||
| If the client received and processed a Retry packet, it validates | ||||
| that the original_connection_id transport parameter is present and | ||||
| correct; otherwise, it validates that the transport parameter is | ||||
| absent. A client MUST treat a failed validation as a connection | ||||
| error of type TRANSPORT_PARAMETER_ERROR. | ||||
| A Retry packet does not include a packet number and cannot be | ||||
| explicitly acknowledged by a client. | ||||
| 18. Transport Parameter Encoding | ||||
| The format of the transport parameters is the TransportParameters | ||||
| struct from Figure 15. This is described using the presentation | ||||
| language from Section 3 of [TLS13]. | ||||
| uint32 QuicVersion; | ||||
| enum { | ||||
| initial_max_stream_data_bidi_local(0), | ||||
| initial_max_data(1), | ||||
| initial_max_bidi_streams(2), | ||||
| idle_timeout(3), | ||||
| preferred_address(4), | ||||
| max_packet_size(5), | ||||
| stateless_reset_token(6), | ||||
| ack_delay_exponent(7), | ||||
| initial_max_uni_streams(8), | ||||
| disable_migration(9), | ||||
| initial_max_stream_data_bidi_remote(10), | ||||
| initial_max_stream_data_uni(11), | ||||
| max_ack_delay(12), | ||||
| original_connection_id(13), | ||||
| (65535) | ||||
| } TransportParameterId; | ||||
| struct { | ||||
| TransportParameterId parameter; | ||||
| opaque value<0..2^16-1>; | ||||
| } TransportParameter; | ||||
| struct { | ||||
| select (Handshake.msg_type) { | ||||
| case client_hello: | ||||
| QuicVersion initial_version; | ||||
| case encrypted_extensions: | ||||
| QuicVersion negotiated_version; | ||||
| QuicVersion supported_versions<4..2^8-4>; | ||||
| }; | ||||
| TransportParameter parameters<0..2^16-1>; | ||||
| } TransportParameters; | ||||
| struct { | ||||
| enum { IPv4(4), IPv6(6), (15) } ipVersion; | ||||
| opaque ipAddress<4..2^8-1>; | ||||
| uint16 port; | ||||
| opaque connectionId<0..18>; | ||||
| opaque statelessResetToken[16]; | ||||
| } PreferredAddress; | ||||
| Figure 15: Definition of TransportParameters | ||||
| The "extension_data" field of the quic_transport_parameters extension | ||||
| defined in [QUIC-TLS] contains a TransportParameters value. TLS | ||||
| encoding rules are therefore used to describe the encoding of | ||||
| transport parameters. | ||||
| QUIC encodes transport parameters into a sequence of octets, which | ||||
| are then included in the cryptographic handshake. | ||||
| 18.1. Transport Parameter Definitions | ||||
| An endpoint MAY use the following transport parameters: | ||||
| idle_timeout (0x0003): The idle timeout is a value in seconds that | ||||
| is encoded as an unsigned 16-bit integer. If this parameter is | ||||
| absent or zero then the idle timeout is disabled. | ||||
| max_packet_size (0x0005): The maximum packet size parameter places a | ||||
| limit on the size of packets that the endpoint is willing to | ||||
| receive, encoded as an unsigned 16-bit integer. This indicates | ||||
| that packets larger than this limit will be dropped. The default | ||||
| for this parameter is the maximum permitted UDP payload of 65527. | ||||
| Values below 1200 are invalid. This limit only applies to | ||||
| protected packets (Section 12.1). | ||||
| ack_delay_exponent (0x0007): An 8-bit unsigned integer value | ||||
| indicating an exponent used to decode the ACK Delay field in the | ||||
| ACK frame, see Section 19.15. If this value is absent, a default | ||||
| value of 3 is assumed (indicating a multiplier of 8). The default | ||||
| value is also used for ACK frames that are sent in Initial and | ||||
| Handshake packets. Values above 20 are invalid. | ||||
| disable_migration (0x0009): The endpoint does not support connection | ||||
| migration (Section 9). Peers MUST NOT send any packets, including | ||||
| probing packets (Section 9.1), from a local address other than | ||||
| that used to perform the handshake. This parameter is a zero- | ||||
| length value. | ||||
| max_ack_delay (0x000c): An 8 bit unsigned integer value indicating | ||||
| the maximum amount of time in milliseconds by which the endpoint | ||||
| will delay sending acknowledgments. If this value is absent, a | ||||
| default of 25 milliseconds is assumed. | ||||
| Either peer MAY advertise an initial value for flow control of each | ||||
| type of stream on which they might receive data. Each of the | ||||
| following transport parameters is encoded as an unsigned 32-bit | ||||
| integer in units of octets: | ||||
| initial_max_stream_data_bidi_local (0x0000): The initial stream | ||||
| maximum data for bidirectional, locally-initiated streams | ||||
| parameter contains the initial flow control limit for newly | ||||
| created bidirectional streams opened by the endpoint that sets the | ||||
| transport parameter. In client transport parameters, this applies | ||||
| to streams with an identifier ending in 0x0; in server transport | ||||
| parameters, this applies to streams ending in 0x1. | ||||
| initial_max_stream_data_bidi_remote (0x000a): The initial stream | ||||
| maximum data for bidirectional, peer-initiated streams parameter | ||||
| contains the initial flow control limit for newly created | ||||
| bidirectional streams opened by the endpoint that receives the | ||||
| transport parameter. In client transport parameters, this applies | ||||
| to streams with an identifier ending in 0x1; in server transport | ||||
| parameters, this applies to streams ending in 0x0. | ||||
| initial_max_stream_data_uni (0x000b): The initial stream maximum | ||||
| data for unidirectional streams parameter contains the initial | ||||
| flow control limit for newly created unidirectional streams opened | ||||
| by the endpoint that receives the transport parameter. In client | ||||
| transport parameters, this applies to streams with an identifier | ||||
| ending in 0x3; in server transport parameters, this applies to | ||||
| streams ending in 0x2. | ||||
| If present, transport parameters that set initial flow control limits | ||||
| (initial_max_stream_data_bidi_local, | ||||
| initial_max_stream_data_bidi_remote, and initial_max_stream_data_uni) | ||||
| are equivalent to sending a MAX_STREAM_DATA frame (Section 19.6) on | ||||
| every stream of the corresponding type immediately after opening. If | ||||
| the transport parameter is absent, streams of that type start with a | ||||
| flow control limit of 0. | ||||
| initial_max_data (0x0001): The initial maximum data parameter | ||||
| contains the initial value for the maximum amount of data that can | ||||
| be sent on the connection. This parameter is encoded as an | ||||
| unsigned 32-bit integer in units of octets. This is equivalent to | ||||
| sending a MAX_DATA (Section 19.5) for the connection immediately | ||||
| after completing the handshake. If the transport parameter is | ||||
| absent, the connection starts with a flow control limit of 0. | ||||
| initial_max_bidi_streams (0x0002): The initial maximum bidirectional | ||||
| streams parameter contains the initial maximum number of | ||||
| bidirectional streams the peer may initiate, encoded as an | ||||
| unsigned 16-bit integer. If this parameter is absent or zero, | ||||
| bidirectional streams cannot be created until a MAX_STREAM_ID | ||||
| frame is sent. Setting this parameter is equivalent to sending a | ||||
| MAX_STREAM_ID (Section 19.7) immediately after completing the | ||||
| handshake containing the corresponding Stream ID. For example, a | ||||
| value of 0x05 would be equivalent to receiving a MAX_STREAM_ID | ||||
| containing 16 when received by a client or 17 when received by a | ||||
| server. | ||||
| initial_max_uni_streams (0x0008): The initial maximum unidirectional | ||||
| streams parameter contains the initial maximum number of | ||||
| unidirectional streams the peer may initiate, encoded as an | ||||
| unsigned 16-bit integer. If this parameter is absent or zero, | ||||
| unidirectional streams cannot be created until a MAX_STREAM_ID | ||||
| frame is sent. Setting this parameter is equivalent to sending a | ||||
| MAX_STREAM_ID (Section 19.7) immediately after completing the | ||||
| handshake containing the corresponding Stream ID. For example, a | ||||
| value of 0x05 would be equivalent to receiving a MAX_STREAM_ID | ||||
| containing 18 when received by a client or 19 when received by a | ||||
| server. | ||||
| A server MUST include the following transport parameter if it sent a | ||||
| Retry packet: | ||||
| original_connection_id (0x000d): The value of the Destination | ||||
| Connection ID field from the first Initial packet sent by the | ||||
| client. This transport parameter is only sent by the server. | ||||
| A server MAY include the following transport parameters: | ||||
| stateless_reset_token (0x0006): The Stateless Reset Token is used in | ||||
| verifying a stateless reset, see Section 10.4. This parameter is | ||||
| a sequence of 16 octets. | ||||
| preferred_address (0x0004): The server's Preferred Address is used | ||||
| to effect a change in server address at the end of the handshake, | ||||
| as described in Section 9.6. | ||||
| A client MUST NOT include an original connection ID, a stateless | ||||
| reset token, or a preferred address. A server MUST treat receipt of | ||||
| any of these transport parameters as a connection error of type | ||||
| TRANSPORT_PARAMETER_ERROR. | ||||
| 19. Frame Types and Formats | ||||
| As described in Section 12.4, packets contain one or more frames. | ||||
| This section describes the format and semantics of the core QUIC | ||||
| frame types. | ||||
| 19.1. PADDING Frame | ||||
| The PADDING frame (type=0x00) has no semantic value. PADDING frames | The PADDING frame (type=0x00) has no semantic value. PADDING frames | |||
| can be used to increase the size of a packet. Padding can be used to | can be used to increase the size of a packet. Padding can be used to | |||
| increase an initial client packet to the minimum required size, or to | increase an initial client packet to the minimum required size, or to | |||
| provide protection against traffic analysis for protected packets. | provide protection against traffic analysis for protected packets. | |||
| A PADDING frame has no content. That is, a PADDING frame consists of | A PADDING frame has no content. That is, a PADDING frame consists of | |||
| the single octet that identifies the frame as a PADDING frame. | the single octet that identifies the frame as a PADDING frame. | |||
| 7.3. RST_STREAM Frame | 19.2. RST_STREAM Frame | |||
| An endpoint may use a RST_STREAM frame (type=0x01) to abruptly | An endpoint may use a RST_STREAM frame (type=0x01) to abruptly | |||
| terminate a stream. | terminate a stream. | |||
| After sending a RST_STREAM, an endpoint ceases transmission and | After sending a RST_STREAM, an endpoint ceases transmission and | |||
| retransmission of STREAM frames on the identified stream. A receiver | retransmission of STREAM frames on the identified stream. A receiver | |||
| of RST_STREAM can discard any data that it already received on that | of RST_STREAM can discard any data that it already received on that | |||
| stream. | stream. | |||
| An endpoint that receives a RST_STREAM frame for a send-only stream | An endpoint that receives a RST_STREAM frame for a send-only stream | |||
| skipping to change at page 69, line 28 ¶ | skipping to change at page 93, line 46 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Final Offset (i) ... | | Final Offset (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields are: | The fields are: | |||
| Stream ID: A variable-length integer encoding of the Stream ID of | Stream ID: A variable-length integer encoding of the Stream ID of | |||
| the stream being terminated. | the stream being terminated. | |||
| Application Protocol Error Code: A 16-bit application protocol error | Application Protocol Error Code: A 16-bit application protocol error | |||
| code (see Section 11.4) which indicates why the stream is being | code (see Section 20.1) which indicates why the stream is being | |||
| closed. | closed. | |||
| Final Offset: A variable-length integer indicating the absolute byte | Final Offset: A variable-length integer indicating the absolute byte | |||
| offset of the end of data written on this stream by the RST_STREAM | offset of the end of data written on this stream by the RST_STREAM | |||
| sender. | sender. | |||
| 7.4. CONNECTION_CLOSE frame | 19.3. CONNECTION_CLOSE frame | |||
| An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its | An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its | |||
| peer that the connection is being closed. CONNECTION_CLOSE is used | peer that the connection is being closed. CONNECTION_CLOSE is used | |||
| to signal errors at the QUIC layer, or the absence of errors (with | to signal errors at the QUIC layer, or the absence of errors (with | |||
| the NO_ERROR code). | the NO_ERROR code). | |||
| If there are open streams that haven't been explicitly closed, they | If there are open streams that haven't been explicitly closed, they | |||
| are implicitly closed when the connection is closed. | are implicitly closed when the connection is closed. | |||
| The CONNECTION_CLOSE frame is as follows: | The CONNECTION_CLOSE frame is as follows: | |||
| skipping to change at page 70, line 21 ¶ | skipping to change at page 94, line 33 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Reason Phrase Length (i) ... | | Reason Phrase Length (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Reason Phrase (*) ... | | Reason Phrase (*) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields of a CONNECTION_CLOSE frame are as follows: | The fields of a CONNECTION_CLOSE frame are as follows: | |||
| Error Code: A 16-bit error code which indicates the reason for | Error Code: A 16-bit error code which indicates the reason for | |||
| closing this connection. CONNECTION_CLOSE uses codes from the | closing this connection. CONNECTION_CLOSE uses codes from the | |||
| space defined in Section 11.3. | space defined in Section 20. | |||
| Frame Type: A variable-length integer encoding the type of frame | Frame Type: A variable-length integer encoding the type of frame | |||
| that triggered the error. A value of 0 (equivalent to the mention | that triggered the error. A value of 0 (equivalent to the mention | |||
| of the PADDING frame) is used when the frame type is unknown. | of the PADDING frame) is used when the frame type is unknown. | |||
| Reason Phrase Length: A variable-length integer specifying the | Reason Phrase Length: A variable-length integer specifying the | |||
| length of the reason phrase in bytes. Note that a | length of the reason phrase in bytes. Note that a | |||
| CONNECTION_CLOSE frame cannot be split between packets, so in | CONNECTION_CLOSE frame cannot be split between packets, so in | |||
| practice any limits on packet size will also limit the space | practice any limits on packet size will also limit the space | |||
| available for a reason phrase. | available for a reason phrase. | |||
| Reason Phrase: A human-readable explanation for why the connection | Reason Phrase: A human-readable explanation for why the connection | |||
| was closed. This can be zero length if the sender chooses to not | was closed. This can be zero length if the sender chooses to not | |||
| give details beyond the Error Code. This SHOULD be a UTF-8 | give details beyond the Error Code. This SHOULD be a UTF-8 | |||
| encoded string [RFC3629]. | encoded string [RFC3629]. | |||
| 7.5. APPLICATION_CLOSE frame | 19.4. APPLICATION_CLOSE frame | |||
| An APPLICATION_CLOSE frame (type=0x03) is used to signal an error | An APPLICATION_CLOSE frame (type=0x03) is used to signal an error | |||
| with the protocol that uses QUIC. | with the protocol that uses QUIC. | |||
| The APPLICATION_CLOSE frame is as follows: | The APPLICATION_CLOSE frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Error Code (16) | | | Error Code (16) | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Reason Phrase Length (i) ... | | Reason Phrase Length (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Reason Phrase (*) ... | | Reason Phrase (*) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields of an APPLICATION_CLOSE frame are as follows: | The fields of an APPLICATION_CLOSE frame are as follows: | |||
| Error Code: A 16-bit error code which indicates the reason for | Error Code: A 16-bit error code which indicates the reason for | |||
| closing this connection. APPLICATION_CLOSE uses codes from the | closing this connection. APPLICATION_CLOSE uses codes from the | |||
| application protocol error code space, see Section 11.4. | application protocol error code space, see Section 20.1. | |||
| Reason Phrase Length: This field is identical in format and | Reason Phrase Length: This field is identical in format and | |||
| semantics to the Reason Phrase Length field from CONNECTION_CLOSE. | semantics to the Reason Phrase Length field from CONNECTION_CLOSE. | |||
| Reason Phrase: This field is identical in format and semantics to | Reason Phrase: This field is identical in format and semantics to | |||
| the Reason Phrase field from CONNECTION_CLOSE. | the Reason Phrase field from CONNECTION_CLOSE. | |||
| APPLICATION_CLOSE has similar format and semantics to the | APPLICATION_CLOSE has similar format and semantics to the | |||
| CONNECTION_CLOSE frame (Section 7.4). Aside from the semantics of | CONNECTION_CLOSE frame (Section 19.3). Aside from the semantics of | |||
| the Error Code field and the omission of the Frame Type field, both | the Error Code field and the omission of the Frame Type field, both | |||
| frames are used to close the connection. | frames are used to close the connection. | |||
| 7.6. MAX_DATA Frame | 19.5. MAX_DATA Frame | |||
| The MAX_DATA frame (type=0x04) is used in flow control to inform the | The MAX_DATA frame (type=0x04) is used in flow control to inform the | |||
| peer of the maximum amount of data that can be sent on the connection | peer of the maximum amount of data that can be sent on the connection | |||
| as a whole. | as a whole. | |||
| The frame is as follows: | The frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| skipping to change at page 71, line 45 ¶ | skipping to change at page 96, line 4 ¶ | |||
| peer of the maximum amount of data that can be sent on the connection | peer of the maximum amount of data that can be sent on the connection | |||
| as a whole. | as a whole. | |||
| The frame is as follows: | The frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Maximum Data (i) ... | | Maximum Data (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields in the MAX_DATA frame are as follows: | The fields in the MAX_DATA frame are as follows: | |||
| Maximum Data: A variable-length integer indicating the maximum | Maximum Data: A variable-length integer indicating the maximum | |||
| amount of data that can be sent on the entire connection, in units | amount of data that can be sent on the entire connection, in units | |||
| of octets. | of octets. | |||
| All data sent in STREAM frames counts toward this limit. The sum of | All data sent in STREAM frames counts toward this limit. The sum of | |||
| the largest received offsets on all streams - including streams in | the largest received offsets on all streams - including streams in | |||
| terminal states - MUST NOT exceed the value advertised by a receiver. | terminal states - MUST NOT exceed the value advertised by a receiver. | |||
| An endpoint MUST terminate a connection with a FLOW_CONTROL_ERROR | An endpoint MUST terminate a connection with a FLOW_CONTROL_ERROR | |||
| error if it receives more data than the maximum data value that it | error if it receives more data than the maximum data value that it | |||
| has sent, unless this is a result of a change in the initial limits | has sent, unless this is a result of a change in the initial limits | |||
| (see Section 6.6.2). | (see Section 7.3.1). | |||
| 7.7. MAX_STREAM_DATA Frame | 19.6. MAX_STREAM_DATA Frame | |||
| The MAX_STREAM_DATA frame (type=0x05) is used in flow control to | The MAX_STREAM_DATA frame (type=0x05) is used in flow control to | |||
| inform a peer of the maximum amount of data that can be sent on a | inform a peer of the maximum amount of data that can be sent on a | |||
| stream. | stream. | |||
| An endpoint that receives a MAX_STREAM_DATA frame for a receive-only | An endpoint that receives a MAX_STREAM_DATA frame for a receive-only | |||
| stream MUST terminate the connection with error PROTOCOL_VIOLATION. | stream MUST terminate the connection with error PROTOCOL_VIOLATION. | |||
| An endpoint that receives a MAX_STREAM_DATA frame for a send-only | An endpoint that receives a MAX_STREAM_DATA frame for a send-only | |||
| stream it has not opened MUST terminate the connection with error | stream it has not opened MUST terminate the connection with error | |||
| skipping to change at page 73, line 12 ¶ | skipping to change at page 97, line 17 ¶ | |||
| stream. Loss or reordering can mean that the largest received offset | stream. Loss or reordering can mean that the largest received offset | |||
| on a stream can be greater than the total size of data received on | on a stream can be greater than the total size of data received on | |||
| that stream. Receiving STREAM frames might not increase the largest | that stream. Receiving STREAM frames might not increase the largest | |||
| received offset. | received offset. | |||
| The data sent on a stream MUST NOT exceed the largest maximum stream | The data sent on a stream MUST NOT exceed the largest maximum stream | |||
| data value advertised by the receiver. An endpoint MUST terminate a | data value advertised by the receiver. An endpoint MUST terminate a | |||
| connection with a FLOW_CONTROL_ERROR error if it receives more data | connection with a FLOW_CONTROL_ERROR error if it receives more data | |||
| than the largest maximum stream data that it has sent for the | than the largest maximum stream data that it has sent for the | |||
| affected stream, unless this is a result of a change in the initial | affected stream, unless this is a result of a change in the initial | |||
| limits (see Section 6.6.2). | limits (see Section 7.3.1). | |||
| 7.8. MAX_STREAM_ID Frame | 19.7. MAX_STREAM_ID Frame | |||
| The MAX_STREAM_ID frame (type=0x06) informs the peer of the maximum | The MAX_STREAM_ID frame (type=0x06) informs the peer of the maximum | |||
| stream ID that they are permitted to open. | stream ID that they are permitted to open. | |||
| The frame is as follows: | The frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Maximum Stream ID (i) ... | | Maximum Stream ID (i) ... | |||
| skipping to change at page 73, line 45 ¶ | skipping to change at page 97, line 50 ¶ | |||
| Loss or reordering can mean that a MAX_STREAM_ID frame can be | Loss or reordering can mean that a MAX_STREAM_ID frame can be | |||
| received which states a lower stream limit than the client has | received which states a lower stream limit than the client has | |||
| previously received. MAX_STREAM_ID frames which do not increase the | previously received. MAX_STREAM_ID frames which do not increase the | |||
| maximum stream ID MUST be ignored. | maximum stream ID MUST be ignored. | |||
| A peer MUST NOT initiate a stream with a higher stream ID than the | A peer MUST NOT initiate a stream with a higher stream ID than the | |||
| greatest maximum stream ID it has received. An endpoint MUST | greatest maximum stream ID it has received. An endpoint MUST | |||
| terminate a connection with a STREAM_ID_ERROR error if a peer | terminate a connection with a STREAM_ID_ERROR error if a peer | |||
| initiates a stream with a higher stream ID than it has sent, unless | initiates a stream with a higher stream ID than it has sent, unless | |||
| this is a result of a change in the initial limits (see | this is a result of a change in the initial limits (see | |||
| Section 6.6.2). | Section 7.3.1). | |||
| 7.9. PING Frame | 19.8. PING Frame | |||
| Endpoints can use PING frames (type=0x07) to verify that their peers | Endpoints can use PING frames (type=0x07) to verify that their peers | |||
| are still alive or to check reachability to the peer. The PING frame | are still alive or to check reachability to the peer. The PING frame | |||
| contains no additional fields. | contains no additional fields. | |||
| The receiver of a PING frame simply needs to acknowledge the packet | The receiver of a PING frame simply needs to acknowledge the packet | |||
| containing this frame. | containing this frame. | |||
| The PING frame can be used to keep a connection alive when an | The PING frame can be used to keep a connection alive when an | |||
| application or application protocol wishes to prevent the connection | application or application protocol wishes to prevent the connection | |||
| from timing out. An application protocol SHOULD provide guidance | from timing out. An application protocol SHOULD provide guidance | |||
| about the conditions under which generating a PING is recommended. | about the conditions under which generating a PING is recommended. | |||
| This guidance SHOULD indicate whether it is the client or the server | This guidance SHOULD indicate whether it is the client or the server | |||
| that is expected to send the PING. Having both endpoints send PING | that is expected to send the PING. Having both endpoints send PING | |||
| frames without coordination can produce an excessive number of | frames without coordination can produce an excessive number of | |||
| packets and poor performance. | packets and poor performance. | |||
| A connection will time out if no packets are sent or received for a | A connection will time out if no packets are sent or received for a | |||
| period longer than the time specified in the idle_timeout transport | period longer than the time specified in the idle_timeout transport | |||
| parameter (see Section 6.13). However, state in middleboxes might | parameter (see Section 10). However, state in middleboxes might time | |||
| time out earlier than that. Though REQ-5 in [RFC4787] recommends a 2 | out earlier than that. Though REQ-5 in [RFC4787] recommends a 2 | |||
| minute timeout interval, experience shows that sending packets every | minute timeout interval, experience shows that sending packets every | |||
| 15 to 30 seconds is necessary to prevent the majority of middleboxes | 15 to 30 seconds is necessary to prevent the majority of middleboxes | |||
| from losing state for UDP flows. | from losing state for UDP flows. | |||
| 7.10. BLOCKED Frame | 19.9. BLOCKED Frame | |||
| A sender SHOULD send a BLOCKED frame (type=0x08) when it wishes to | A sender SHOULD send a BLOCKED frame (type=0x08) when it wishes to | |||
| send data, but is unable to due to connection-level flow control (see | send data, but is unable to due to connection-level flow control (see | |||
| Section 10.2.1). BLOCKED frames can be used as input to tuning of | Section 4). BLOCKED frames can be used as input to tuning of flow | |||
| flow control algorithms (see Section 10.1.2). | control algorithms (see Section 4.2). | |||
| The BLOCKED frame is as follows: | The BLOCKED frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Offset (i) ... | | Offset (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The BLOCKED frame contains a single field. | The BLOCKED frame contains a single field. | |||
| Offset: A variable-length integer indicating the connection-level | Offset: A variable-length integer indicating the connection-level | |||
| offset at which the blocking occurred. | offset at which the blocking occurred. | |||
| 7.11. STREAM_BLOCKED Frame | 19.10. STREAM_BLOCKED Frame | |||
| A sender SHOULD send a STREAM_BLOCKED frame (type=0x09) when it | A sender SHOULD send a STREAM_BLOCKED frame (type=0x09) when it | |||
| wishes to send data, but is unable to due to stream-level flow | wishes to send data, but is unable to due to stream-level flow | |||
| control. This frame is analogous to BLOCKED (Section 7.10). | control. This frame is analogous to BLOCKED (Section 19.9). | |||
| An endpoint that receives a STREAM_BLOCKED frame for a send-only | An endpoint that receives a STREAM_BLOCKED frame for a send-only | |||
| stream MUST terminate the connection with error PROTOCOL_VIOLATION. | stream MUST terminate the connection with error PROTOCOL_VIOLATION. | |||
| The STREAM_BLOCKED frame is as follows: | The STREAM_BLOCKED frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Stream ID (i) ... | | Stream ID (i) ... | |||
| skipping to change at page 75, line 23 ¶ | skipping to change at page 99, line 32 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The STREAM_BLOCKED frame contains two fields: | The STREAM_BLOCKED frame contains two fields: | |||
| Stream ID: A variable-length integer indicating the stream which is | Stream ID: A variable-length integer indicating the stream which is | |||
| flow control blocked. | flow control blocked. | |||
| Offset: A variable-length integer indicating the offset of the | Offset: A variable-length integer indicating the offset of the | |||
| stream at which the blocking occurred. | stream at which the blocking occurred. | |||
| 7.12. STREAM_ID_BLOCKED Frame | 19.11. STREAM_ID_BLOCKED Frame | |||
| A sender MAY send a STREAM_ID_BLOCKED frame (type=0x0a) when it | A sender SHOULD send a STREAM_ID_BLOCKED frame (type=0x0a) when it | |||
| wishes to open a stream, but is unable to due to the maximum stream | wishes to open a stream, but is unable to due to the maximum stream | |||
| ID limit set by its peer (see Section 7.8). This does not open the | ID limit set by its peer (see Section 19.7). This does not open the | |||
| stream, but informs the peer that a new stream was needed, but the | stream, but informs the peer that a new stream was needed, but the | |||
| stream limit prevented the creation of the stream. | stream limit prevented the creation of the stream. | |||
| The STREAM_ID_BLOCKED frame is as follows: | The STREAM_ID_BLOCKED frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Stream ID (i) ... | | Stream ID (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The STREAM_ID_BLOCKED frame contains a single field. | The STREAM_ID_BLOCKED frame contains a single field. | |||
| Stream ID: A variable-length integer indicating the highest stream | Stream ID: A variable-length integer indicating the highest stream | |||
| ID that the sender was permitted to open. | ID that the sender was permitted to open. | |||
| 7.13. NEW_CONNECTION_ID Frame | 19.12. NEW_CONNECTION_ID Frame | |||
| An endpoint sends a NEW_CONNECTION_ID frame (type=0x0b) to provide | An endpoint sends a NEW_CONNECTION_ID frame (type=0x0b) to provide | |||
| its peer with alternative connection IDs that can be used to break | its peer with alternative connection IDs that can be used to break | |||
| linkability when migrating connections (see Section 6.11.5). | linkability when migrating connections (see Section 9.5). | |||
| The NEW_CONNECTION_ID frame is as follows: | The NEW_CONNECTION_ID frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Length (8) | Sequence Number (i) ... | | Length (8) | Sequence Number (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Connection ID (32..144) ... | | Connection ID (32..144) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| skipping to change at page 76, line 29 ¶ | skipping to change at page 100, line 37 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields are: | The fields are: | |||
| Length: An 8-bit unsigned integer containing the length of the | Length: An 8-bit unsigned integer containing the length of the | |||
| connection ID. Values less than 4 and greater than 18 are invalid | connection ID. Values less than 4 and greater than 18 are invalid | |||
| and MUST be treated as a connection error of type | and MUST be treated as a connection error of type | |||
| PROTOCOL_VIOLATION. | PROTOCOL_VIOLATION. | |||
| Sequence Number: The sequence number assigned to the connection ID | Sequence Number: The sequence number assigned to the connection ID | |||
| by the sender. See Section 6.1.1. | by the sender. See Section 5.1.1. | |||
| Connection ID: A connection ID of the specified length. | Connection ID: A connection ID of the specified length. | |||
| Stateless Reset Token: A 128-bit value that will be used for a | Stateless Reset Token: A 128-bit value that will be used for a | |||
| stateless reset when the associated connection ID is used (see | stateless reset when the associated connection ID is used (see | |||
| Section 6.13.4). | Section 10.4). | |||
| An endpoint MUST NOT send this frame if it currently requires that | An endpoint MUST NOT send this frame if it currently requires that | |||
| its peer send packets with a zero-length Destination Connection ID. | its peer send packets with a zero-length Destination Connection ID. | |||
| Changing the length of a connection ID to or from zero-length makes | Changing the length of a connection ID to or from zero-length makes | |||
| it difficult to identify when the value of the connection ID changed. | it difficult to identify when the value of the connection ID changed. | |||
| An endpoint that is sending packets with a zero-length Destination | An endpoint that is sending packets with a zero-length Destination | |||
| Connection ID MUST treat receipt of a NEW_CONNECTION_ID frame as a | Connection ID MUST treat receipt of a NEW_CONNECTION_ID frame as a | |||
| connection error of type PROTOCOL_VIOLATION. | connection error of type PROTOCOL_VIOLATION. | |||
| Transmission errors, timeouts and retransmissions might cause the | Transmission errors, timeouts and retransmissions might cause the | |||
| same NEW_CONNECTION_ID frame to be received multiple times. Receipt | same NEW_CONNECTION_ID frame to be received multiple times. Receipt | |||
| of the same frame multiple times MUST NOT be treated as a connection | of the same frame multiple times MUST NOT be treated as a connection | |||
| error. A receiver can use the sequence number supplied in the | error. A receiver can use the sequence number supplied in the | |||
| NEW_CONNECTION_ID frame to identify new connection IDs from old ones. | NEW_CONNECTION_ID frame to identify new connection IDs from old ones. | |||
| If an endpoint receives a NEW_CONNECTION_ID frame that repeats a | If an endpoint receives a NEW_CONNECTION_ID frame that repeats a | |||
| previously issued connection ID with a different Stateless Reset | previously issued connection ID with a different Stateless Reset | |||
| Token or a different sequence number, the endpoint MAY treat that | Token or a different sequence number, the endpoint MAY treat that | |||
| receipt as a connection error of type PROTOCOL_VIOLATION. | receipt as a connection error of type PROTOCOL_VIOLATION. | |||
| 7.14. RETIRE_CONNECTION_ID Frame | 19.13. RETIRE_CONNECTION_ID Frame | |||
| An endpoint sends a RETIRE_CONNECTION_ID frame (type=0x1b) to | An endpoint sends a RETIRE_CONNECTION_ID frame (type=0x1b) to | |||
| indicate that it will no longer use a connection ID that was issued | indicate that it will no longer use a connection ID that was issued | |||
| by its peer. This may include the connection ID provided during the | by its peer. This may include the connection ID provided during the | |||
| handshake. Sending a RETIRE_CONNECTION_ID frame also serves as a | handshake. Sending a RETIRE_CONNECTION_ID frame also serves as a | |||
| request to the peer to send additional connection IDs for future use | request to the peer to send additional connection IDs for future use | |||
| (see Section 6.1). New connection IDs can be delivered to a peer | (see Section 5.1). New connection IDs can be delivered to a peer | |||
| using the NEW_CONNECTION_ID frame (Section 7.13). | using the NEW_CONNECTION_ID frame (Section 19.12). | |||
| Retiring a connection ID invalidates the stateless reset token | Retiring a connection ID invalidates the stateless reset token | |||
| associated with that connection ID. | associated with that connection ID. | |||
| The RETIRE_CONNECTION_ID frame is as follows: | The RETIRE_CONNECTION_ID frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Sequence Number (i) ... | | Sequence Number (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields are: | The fields are: | |||
| Sequence Number: The sequence number of the connection ID being | Sequence Number: The sequence number of the connection ID being | |||
| retired. See Section 6.1.2. | retired. See Section 5.1.2. | |||
| Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number | Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number | |||
| greater than any previously sent to the peer MAY be treated as a | greater than any previously sent to the peer MAY be treated as a | |||
| connection error of type PROTOCOL_VIOLATION. | connection error of type PROTOCOL_VIOLATION. | |||
| An endpoint cannot send this frame if it was provided with a zero- | An endpoint cannot send this frame if it was provided with a zero- | |||
| length connection ID by its peer. An endpoint that provides a zero- | length connection ID by its peer. An endpoint that provides a zero- | |||
| length connection ID MUST treat receipt of a RETIRE_CONNECTION_ID | length connection ID MUST treat receipt of a RETIRE_CONNECTION_ID | |||
| frame as a connection error of type PROTOCOL_VIOLATION. | frame as a connection error of type PROTOCOL_VIOLATION. | |||
| 7.15. STOP_SENDING Frame | 19.14. STOP_SENDING Frame | |||
| An endpoint may use a STOP_SENDING frame (type=0x0c) to communicate | An endpoint may use a STOP_SENDING frame (type=0x0c) to communicate | |||
| that incoming data is being discarded on receipt at application | that incoming data is being discarded on receipt at application | |||
| request. This signals a peer to abruptly terminate transmission on a | request. This signals a peer to abruptly terminate transmission on a | |||
| stream. | stream. | |||
| Receipt of a STOP_SENDING frame is only valid for a send stream that | Receipt of a STOP_SENDING frame is only valid for a send stream that | |||
| exists and is not in the "Ready" state (see Section 9.2.1). | exists and is not in the "Ready" state (see Section 3.1). Receiving | |||
| Receiving a STOP_SENDING frame for a send stream that is "Ready" or | a STOP_SENDING frame for a send stream that is "Ready" or non- | |||
| non-existent MUST be treated as a connection error of type | existent MUST be treated as a connection error of type | |||
| PROTOCOL_VIOLATION. An endpoint that receives a STOP_SENDING frame | PROTOCOL_VIOLATION. An endpoint that receives a STOP_SENDING frame | |||
| for a receive-only stream MUST terminate the connection with error | for a receive-only stream MUST terminate the connection with error | |||
| PROTOCOL_VIOLATION. | PROTOCOL_VIOLATION. | |||
| The STOP_SENDING frame is as follows: | The STOP_SENDING frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Stream ID (i) ... | | Stream ID (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Application Error Code (16) | | | Application Error Code (16) | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields are: | The fields are: | |||
| Stream ID: A variable-length integer carrying the Stream ID of the | Stream ID: A variable-length integer carrying the Stream ID of the | |||
| stream being ignored. | stream being ignored. | |||
| Application Error Code: A 16-bit, application-specified reason the | Application Error Code: A 16-bit, application-specified reason the | |||
| sender is ignoring the stream (see Section 11.4). | sender is ignoring the stream (see Section 20.1). | |||
| 7.16. ACK Frame | 19.15. ACK Frame | |||
| Receivers send ACK frames (types 0x1a and 0x1b) to inform senders of | Receivers send ACK frames (types 0x1a and 0x1b) to inform senders of | |||
| packets they have received and processed. The ACK frame contains one | packets they have received and processed. The ACK frame contains one | |||
| or more ACK Blocks. ACK Blocks are ranges of acknowledged packets. | or more ACK Blocks. ACK Blocks are ranges of acknowledged packets. | |||
| If the frame type is 0x1b, ACK frames also contain the sum of ECN | If the frame type is 0x1b, ACK frames also contain the sum of ECN | |||
| marks received on the connection up until this point. | marks received on the connection up until this point. | |||
| QUIC acknowledgements are irrevocable. Once acknowledged, a packet | QUIC acknowledgements are irrevocable. Once acknowledged, a packet | |||
| remains acknowledged, even if it does not appear in a future ACK | remains acknowledged, even if it does not appear in a future ACK | |||
| frame. This is unlike TCP SACKs ([RFC2018]). | frame. This is unlike TCP SACKs ([RFC2018]). | |||
| skipping to change at page 79, line 19 ¶ | skipping to change at page 103, line 28 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ACK Delay (i) ... | | ACK Delay (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ACK Block Count (i) ... | | ACK Block Count (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ACK Blocks (*) ... | | ACK Blocks (*) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | [ECN Section] ... | | [ECN Section] ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 12: ACK Frame Format | Figure 16: ACK Frame Format | |||
| The fields in the ACK frame are as follows: | The fields in the ACK frame are as follows: | |||
| Largest Acknowledged: A variable-length integer representing the | Largest Acknowledged: A variable-length integer representing the | |||
| largest packet number the peer is acknowledging; this is usually | largest packet number the peer is acknowledging; this is usually | |||
| the largest packet number that the peer has received prior to | the largest packet number that the peer has received prior to | |||
| generating the ACK frame. Unlike the packet number in the QUIC | generating the ACK frame. Unlike the packet number in the QUIC | |||
| long or short header, the value in an ACK frame is not truncated. | long or short header, the value in an ACK frame is not truncated. | |||
| ACK Delay: A variable-length integer including the time in | ACK Delay: A variable-length integer including the time in | |||
| microseconds that the largest acknowledged packet, as indicated in | microseconds that the largest acknowledged packet, as indicated in | |||
| the Largest Acknowledged field, was received by this peer to when | the Largest Acknowledged field, was received by this peer to when | |||
| this ACK was sent. The value of the ACK Delay field is scaled by | this ACK was sent. The value of the ACK Delay field is scaled by | |||
| multiplying the encoded value by 2 to the power of the value of | multiplying the encoded value by 2 to the power of the value of | |||
| the "ack_delay_exponent" transport parameter set by the sender of | the "ack_delay_exponent" transport parameter set by the sender of | |||
| the ACK frame. The "ack_delay_exponent" defaults to 3, or a | the ACK frame. The "ack_delay_exponent" defaults to 3, or a | |||
| multiplier of 8 (see Section 6.6.1). Scaling in this fashion | multiplier of 8 (see Section 18.1). Scaling in this fashion | |||
| allows for a larger range of values with a shorter encoding at the | allows for a larger range of values with a shorter encoding at the | |||
| cost of lower resolution. | cost of lower resolution. | |||
| ACK Block Count: A variable-length integer specifying the number of | ACK Block Count: A variable-length integer specifying the number of | |||
| Additional ACK Block (and Gap) fields after the First ACK Block. | Additional ACK Block (and Gap) fields after the First ACK Block. | |||
| ACK Blocks: Contains one or more blocks of packet numbers which have | ACK Blocks: Contains one or more blocks of packet numbers which have | |||
| been successfully received, see Section 7.16.1. | been successfully received, see Section 19.15.1. | |||
| 7.16.1. ACK Block Section | 19.15.1. ACK Block Section | |||
| The ACK Block Section consists of alternating Gap and ACK Block | The ACK Block Section consists of alternating Gap and ACK Block | |||
| fields in descending packet number order. A First Ack Block field is | fields in descending packet number order. A First Ack Block field is | |||
| followed by a variable number of alternating Gap and Additional ACK | followed by a variable number of alternating Gap and Additional ACK | |||
| Blocks. The number of Gap and Additional ACK Block fields is | Blocks. The number of Gap and Additional ACK Block fields is | |||
| determined by the ACK Block Count field. | determined by the ACK Block Count field. | |||
| Gap and ACK Block fields use a relative integer encoding for | Gap and ACK Block fields use a relative integer encoding for | |||
| efficiency. Though each encoded value is positive, the values are | efficiency. Though each encoded value is positive, the values are | |||
| subtracted, so that each ACK Block describes progressively lower- | subtracted, so that each ACK Block describes progressively lower- | |||
| skipping to change at page 80, line 36 ¶ | skipping to change at page 104, line 47 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Additional ACK Block (i) ... | | Additional ACK Block (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| ... | ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Gap (i) ... | | Gap (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Additional ACK Block (i) ... | | Additional ACK Block (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 13: ACK Block Section | Figure 17: ACK Block Section | |||
| Each ACK Block acknowledges a contiguous range of packets by | Each ACK Block acknowledges a contiguous range of packets by | |||
| indicating the number of acknowledged packets that precede the | indicating the number of acknowledged packets that precede the | |||
| largest packet number in that block. A value of zero indicates that | largest packet number in that block. A value of zero indicates that | |||
| only the largest packet number is acknowledged. Larger ACK Block | only the largest packet number is acknowledged. Larger ACK Block | |||
| values indicate a larger range, with corresponding lower values for | values indicate a larger range, with corresponding lower values for | |||
| the smallest packet number in the range. Thus, given a largest | the smallest packet number in the range. Thus, given a largest | |||
| packet number for the ACK, the smallest value is determined by the | packet number for the ACK, the smallest value is determined by the | |||
| formula: | formula: | |||
| skipping to change at page 81, line 38 ¶ | skipping to change at page 105, line 47 ¶ | |||
| being acknowledged. | being acknowledged. | |||
| Gap (repeated): A variable-length integer indicating the number of | Gap (repeated): A variable-length integer indicating the number of | |||
| contiguous unacknowledged packets preceding the packet number one | contiguous unacknowledged packets preceding the packet number one | |||
| lower than the smallest in the preceding ACK Block. | lower than the smallest in the preceding ACK Block. | |||
| Additional ACK Block (repeated): A variable-length integer | Additional ACK Block (repeated): A variable-length integer | |||
| indicating the number of contiguous acknowledged packets preceding | indicating the number of contiguous acknowledged packets preceding | |||
| the largest packet number, as determined by the preceding Gap. | the largest packet number, as determined by the preceding Gap. | |||
| 7.16.2. ECN section | 19.15.2. ECN section | |||
| The ECN section should only be parsed when the ACK frame type byte is | The ECN section should only be parsed when the ACK frame type byte is | |||
| 0x1b. The ECN section consists of 3 ECN counters as shown below. | 0x1b. The ECN section consists of 3 ECN counters as shown below. | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ECT(0) Count (i) ... | | ECT(0) Count (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ECT(1) Count (i) ... | | ECT(1) Count (i) ... | |||
| skipping to change at page 82, line 4 ¶ | skipping to change at page 106, line 14 ¶ | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ECT(0) Count (i) ... | | ECT(0) Count (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ECT(1) Count (i) ... | | ECT(1) Count (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | ECN-CE Count (i) ... | | ECN-CE Count (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| ECT(0) Count: A variable-length integer representing the total | ECT(0) Count: A variable-length integer representing the total | |||
| number packets received with the ECT(0) codepoint. | number packets received with the ECT(0) codepoint. | |||
| ECT(1) Count: A variable-length integer representing the total | ECT(1) Count: A variable-length integer representing the total | |||
| number packets received with the ECT(1) codepoint. | number packets received with the ECT(1) codepoint. | |||
| CE Count: A variable-length integer representing the total number | CE Count: A variable-length integer representing the total number | |||
| packets received with the CE codepoint. | packets received with the CE codepoint. | |||
| 7.16.3. Sending ACK Frames | 19.16. PATH_CHALLENGE Frame | |||
| Implementations MUST NOT generate packets that only contain ACK | ||||
| frames in response to packets which only contain ACK and PADDING | ||||
| frames. However, they MUST acknowledge packets containing only ACK | ||||
| and PADDING frames when sending ACK frames in response to other | ||||
| packets. Implementations MUST NOT send more than one packet | ||||
| containing only an ACK frame per received packet that contains frames | ||||
| other than ACK and PADDING frames. Packets containing frames besides | ||||
| ACK and PADDING MUST be acknowledged immediately or when a delayed | ||||
| ack timer expires. | ||||
| The receiver's delayed acknowledgment timer SHOULD NOT exceed the | ||||
| current RTT estimate or the value it indicates in the "max_ack_delay" | ||||
| transport parameter. This ensures an acknowledgment is sent at least | ||||
| once per RTT when packets needing acknowledgement are received. The | ||||
| sender can use the receiver's "max_ack_delay" value in determining | ||||
| timeouts for timer-based retransmission. | ||||
| An acknowledgment SHOULD be sent immediately after receiving 2 | ||||
| packets that require acknowledgement, unless multiple packets are | ||||
| received together. | ||||
| To limit ACK Blocks to those that have not yet been received by the | ||||
| sender, the receiver SHOULD track which ACK frames have been | ||||
| acknowledged by its peer. Once an ACK frame has been acknowledged, | ||||
| the packets it acknowledges SHOULD NOT be acknowledged again. | ||||
| Because ACK frames are not sent in response to ACK-only packets, a | ||||
| receiver that is only sending ACK frames will only receive | ||||
| acknowledgements for its packets if the sender includes them in | ||||
| packets with non-ACK frames. A sender SHOULD bundle ACK frames with | ||||
| other frames when possible. | ||||
| Endpoints can only acknowledge packets sent in a particular packet | ||||
| number space by sending ACK frames in packets from the same packet | ||||
| number space. | ||||
| To limit receiver state or the size of ACK frames, a receiver MAY | ||||
| limit the number of ACK Blocks it sends. A receiver can do this even | ||||
| without receiving acknowledgment of its ACK frames, with the | ||||
| knowledge this could cause the sender to unnecessarily retransmit | ||||
| some data. Standard QUIC [QUIC-RECOVERY] algorithms declare packets | ||||
| lost after sufficiently newer packets are acknowledged. Therefore, | ||||
| the receiver SHOULD repeatedly acknowledge newly received packets in | ||||
| preference to packets received in the past. | ||||
| 7.16.4. ACK Frames and Packet Protection | ||||
| ACK frames MUST only be carried in a packet that has the same packet | ||||
| number space as the packet being ACKed (see Section 4.8). For | ||||
| instance, packets that are protected with 1-RTT keys MUST be | ||||
| acknowledged in packets that are also protected with 1-RTT keys. | ||||
| Packets that a client sends with 0-RTT packet protection MUST be | ||||
| acknowledged by the server in packets protected by 1-RTT keys. This | ||||
| can mean that the client is unable to use these acknowledgments if | ||||
| the server cryptographic handshake messages are delayed or lost. | ||||
| Note that the same limitation applies to other data sent by the | ||||
| server protected by the 1-RTT keys. | ||||
| Endpoints SHOULD send acknowledgments for packets containing CRYPTO | ||||
| frames with a reduced delay; see Section 4.3.1 of [QUIC-RECOVERY]. | ||||
| 7.17. PATH_CHALLENGE Frame | ||||
| Endpoints can use PATH_CHALLENGE frames (type=0x0e) to check | Endpoints can use PATH_CHALLENGE frames (type=0x0e) to check | |||
| reachability to the peer and for path validation during connection | reachability to the peer and for path validation during connection | |||
| migration. | migration. | |||
| PATH_CHALLENGE frames contain an 8-byte payload. | PATH_CHALLENGE frames contain an 8-byte payload. | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| skipping to change at page 84, line 6 ¶ | skipping to change at page 106, line 47 ¶ | |||
| | | | | | | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Data: This 8-byte field contains arbitrary data. | Data: This 8-byte field contains arbitrary data. | |||
| A PATH_CHALLENGE frame containing 8 octets that are hard to guess is | A PATH_CHALLENGE frame containing 8 octets that are hard to guess is | |||
| sufficient to ensure that it is easier to receive the packet than it | sufficient to ensure that it is easier to receive the packet than it | |||
| is to guess the value correctly. | is to guess the value correctly. | |||
| The recipient of this frame MUST generate a PATH_RESPONSE frame | The recipient of this frame MUST generate a PATH_RESPONSE frame | |||
| (Section 7.18) containing the same Data. | (Section 19.17) containing the same Data. | |||
| 7.18. PATH_RESPONSE Frame | 19.17. PATH_RESPONSE Frame | |||
| The PATH_RESPONSE frame (type=0x0f) is sent in response to a | The PATH_RESPONSE frame (type=0x0f) is sent in response to a | |||
| PATH_CHALLENGE frame. Its format is identical to the PATH_CHALLENGE | PATH_CHALLENGE frame. Its format is identical to the PATH_CHALLENGE | |||
| frame (Section 7.17). | frame (Section 19.16). | |||
| If the content of a PATH_RESPONSE frame does not match the content of | If the content of a PATH_RESPONSE frame does not match the content of | |||
| a PATH_CHALLENGE frame previously sent by the endpoint, the endpoint | a PATH_CHALLENGE frame previously sent by the endpoint, the endpoint | |||
| MAY generate a connection error of type PROTOCOL_VIOLATION. | MAY generate a connection error of type PROTOCOL_VIOLATION. | |||
| 7.19. NEW_TOKEN frame | 19.18. NEW_TOKEN frame | |||
| A server sends a NEW_TOKEN frame (type=0x19) to provide the client a | A server sends a NEW_TOKEN frame (type=0x19) to provide the client a | |||
| token to send in the header of an Initial packet for a future | token to send in the header of an Initial packet for a future | |||
| connection. | connection. | |||
| The NEW_TOKEN frame is as follows: | The NEW_TOKEN frame is as follows: | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| skipping to change at page 84, line 42 ¶ | skipping to change at page 107, line 39 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| The fields of a NEW_TOKEN frame are as follows: | The fields of a NEW_TOKEN frame are as follows: | |||
| Token Length: A variable-length integer specifying the length of the | Token Length: A variable-length integer specifying the length of the | |||
| token in bytes. | token in bytes. | |||
| Token: An opaque blob that the client may use with a future Initial | Token: An opaque blob that the client may use with a future Initial | |||
| packet. | packet. | |||
| 7.20. STREAM Frames | 19.19. STREAM Frames | |||
| STREAM frames implicitly create a stream and carry stream data. The | STREAM frames implicitly create a stream and carry stream data. The | |||
| STREAM frame takes the form 0b00010XXX (or the set of values from | STREAM frame takes the form 0b00010XXX (or the set of values from | |||
| 0x10 to 0x17). The value of the three low-order bits of the frame | 0x10 to 0x17). The value of the three low-order bits of the frame | |||
| type determine the fields that are present in the frame. | type determine the fields that are present in the frame. | |||
| o The OFF bit (0x04) in the frame type is set to indicate that there | o The OFF bit (0x04) in the frame type is set to indicate that there | |||
| is an Offset field present. When set to 1, the Offset field is | is an Offset field present. When set to 1, the Offset field is | |||
| present; when set to 0, the Offset field is absent and the Stream | present; when set to 0, the Offset field is absent and the Stream | |||
| Data starts at an offset of 0 (that is, the frame contains the | Data starts at an offset of 0 (that is, the frame contains the | |||
| skipping to change at page 85, line 33 ¶ | skipping to change at page 108, line 31 ¶ | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Stream ID (i) ... | | Stream ID (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | [Offset (i)] ... | | [Offset (i)] ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | [Length (i)] ... | | [Length (i)] ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Stream Data (*) ... | | Stream Data (*) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 14: STREAM Frame Format | Figure 18: STREAM Frame Format | |||
| The STREAM frame contains the following fields: | The STREAM frame contains the following fields: | |||
| Stream ID: A variable-length integer indicating the stream ID of the | Stream ID: A variable-length integer indicating the stream ID of the | |||
| stream (see Section 9.1). | stream (see Section 2.1). | |||
| Offset: A variable-length integer specifying the byte offset in the | Offset: A variable-length integer specifying the byte offset in the | |||
| stream for the data in this STREAM frame. This field is present | stream for the data in this STREAM frame. This field is present | |||
| when the OFF bit is set to 1. When the Offset field is absent, | when the OFF bit is set to 1. When the Offset field is absent, | |||
| the offset is 0. | the offset is 0. | |||
| Length: A variable-length integer specifying the length of the | Length: A variable-length integer specifying the length of the | |||
| Stream Data field in this STREAM frame. This field is present | Stream Data field in this STREAM frame. This field is present | |||
| when the LEN bit is set to 1. When the LEN bit is set to 0, the | when the LEN bit is set to 1. When the LEN bit is set to 0, the | |||
| Stream Data field consumes all the remaining octets in the packet. | Stream Data field consumes all the remaining octets in the packet. | |||
| Stream Data: The bytes from the designated stream to be delivered. | Stream Data: The bytes from the designated stream to be delivered. | |||
| When a Stream Data field has a length of 0, the offset in the STREAM | When a Stream Data field has a length of 0, the offset in the STREAM | |||
| frame is the offset of the next byte that would be sent. | frame is the offset of the next byte that would be sent. | |||
| The first byte in the stream has an offset of 0. The largest offset | The first byte in the stream has an offset of 0. The largest offset | |||
| delivered on a stream - the sum of the re-constructed offset and data | delivered on a stream - the sum of the re-constructed offset and data | |||
| length - MUST be less than 2^62. | length - MUST be less than 2^62. | |||
| Stream multiplexing is achieved by interleaving STREAM frames from | 19.20. CRYPTO Frame | |||
| multiple streams into one or more QUIC packets. A single QUIC packet | ||||
| can include multiple STREAM frames from one or more streams. | ||||
| Implementation note: One of the benefits of QUIC is avoidance of | ||||
| head-of-line blocking across multiple streams. When a packet loss | ||||
| occurs, only streams with data in that packet are blocked waiting for | ||||
| a retransmission to be received, while other streams can continue | ||||
| making progress. Note that when data from multiple streams is | ||||
| bundled into a single QUIC packet, loss of that packet blocks all | ||||
| those streams from making progress. An implementation is therefore | ||||
| advised to bundle as few streams as necessary in outgoing packets | ||||
| without losing transmission efficiency to underfilled packets. | ||||
| 7.21. CRYPTO Frame | ||||
| The CRYPTO frame (type=0x18) is used to transmit cryptographic | The CRYPTO frame (type=0x18) is used to transmit cryptographic | |||
| handshake messages. It can be sent in all packet types. The CRYPTO | handshake messages. It can be sent in all packet types. The CRYPTO | |||
| frame offers the cryptographic protocol an in-order stream of bytes. | frame offers the cryptographic protocol an in-order stream of bytes. | |||
| CRYPTO frames are functionally identical to STREAM frames, except | CRYPTO frames are functionally identical to STREAM frames, except | |||
| that they do not bear a stream identifier; they are not flow | that they do not bear a stream identifier; they are not flow | |||
| controlled; and they do not carry markers for optional offset, | controlled; and they do not carry markers for optional offset, | |||
| optional length, and the end of the stream. | optional length, and the end of the stream. | |||
| A CRYPTO frame is shown below. | A CRYPTO frame is shown below. | |||
| skipping to change at page 86, line 48 ¶ | skipping to change at page 109, line 31 ¶ | |||
| 0 1 2 3 | 0 1 2 3 | |||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Offset (i) ... | | Offset (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Length (i) ... | | Length (i) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| | Crypto Data (*) ... | | Crypto Data (*) ... | |||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |||
| Figure 15: CRYPTO Frame Format | Figure 19: CRYPTO Frame Format | |||
| The CRYPTO frame contains the following fields: | The CRYPTO frame contains the following fields: | |||
| Offset: A variable-length integer specifying the byte offset in the | Offset: A variable-length integer specifying the byte offset in the | |||
| stream for the data in this CRYPTO frame. | stream for the data in this CRYPTO frame. | |||
| Length: A variable-length integer specifying the length of the | Length: A variable-length integer specifying the length of the | |||
| Crypto Data field in this CRYPTO frame. | Crypto Data field in this CRYPTO frame. | |||
| Crypto Data: The cryptographic message data. | Crypto Data: The cryptographic message data. | |||
| skipping to change at page 87, line 23 ¶ | skipping to change at page 110, line 5 ¶ | |||
| There is a separate flow of cryptographic handshake data in each | There is a separate flow of cryptographic handshake data in each | |||
| encryption level, each of which starts at an offset of 0. This | encryption level, each of which starts at an offset of 0. This | |||
| implies that each encryption level is treated as a separate CRYPTO | implies that each encryption level is treated as a separate CRYPTO | |||
| stream of data. | stream of data. | |||
| Unlike STREAM frames, which include a Stream ID indicating to which | Unlike STREAM frames, which include a Stream ID indicating to which | |||
| stream the data belongs, the CRYPTO frame carries data for a single | stream the data belongs, the CRYPTO frame carries data for a single | |||
| stream per encryption level. The stream does not have an explicit | stream per encryption level. The stream does not have an explicit | |||
| end, so CRYPTO frames do not have a FIN bit. | end, so CRYPTO frames do not have a FIN bit. | |||
| 8. Packetization and Reliability | 19.21. Extension Frames | |||
| A sender bundles one or more frames in a QUIC packet (see Section 5). | ||||
| A sender SHOULD minimize per-packet bandwidth and computational costs | ||||
| by bundling as many frames as possible within a QUIC packet. A | ||||
| sender MAY wait for a short period of time to bundle multiple frames | ||||
| before sending a packet that is not maximally packed, to avoid | ||||
| sending out large numbers of small packets. An implementation may | ||||
| use knowledge about application sending behavior or heuristics to | ||||
| determine whether and for how long to wait. This waiting period is | ||||
| an implementation decision, and an implementation should be careful | ||||
| to delay conservatively, since any delay is likely to increase | ||||
| application-visible latency. | ||||
| 8.1. Packet Processing and Acknowledgment | ||||
| A packet MUST NOT be acknowledged until packet protection has been | ||||
| successfully removed and all frames contained in the packet have been | ||||
| processed. For STREAM frames, this means the data has been enqueued | ||||
| in preparation to be received by the application protocol, but it | ||||
| does not require that data is delivered and consumed. | ||||
| Once the packet has been fully processed, a receiver acknowledges | ||||
| receipt by sending one or more ACK frames containing the packet | ||||
| number of the received packet. To avoid creating an indefinite | ||||
| feedback loop, an endpoint MUST NOT send an ACK frame in response to | ||||
| a packet containing only ACK or PADDING frames, even if there are | ||||
| packet gaps which precede the received packet. The endpoint MUST | ||||
| acknowledge packets containing only ACK or PADDING frames in the next | ||||
| ACK frame that it sends. | ||||
| While PADDING frames do not elicit an ACK frame from a receiver, they | ||||
| are considered to be in flight for congestion control purposes | ||||
| [QUIC-RECOVERY]. Sending only PADDING frames might cause the sender | ||||
| to become limited by the congestion controller (as described in | ||||
| [QUIC-RECOVERY]) with no acknowledgments forthcoming from the | ||||
| receiver. Therefore, a sender should ensure that other frames are | ||||
| sent in addition to PADDING frames to elicit acknowledgments from the | ||||
| receiver. | ||||
| Strategies and implications of the frequency of generating | ||||
| acknowledgments are discussed in more detail in [QUIC-RECOVERY]. | ||||
| 8.2. Retransmission of Information | ||||
| QUIC packets that are determined to be lost are not retransmitted | ||||
| whole. The same applies to the frames that are contained within lost | ||||
| packets. Instead, the information that might be carried in frames is | ||||
| sent again in new frames as needed. | ||||
| New frames and packets are used to carry information that is | ||||
| determined to have been lost. In general, information is sent again | ||||
| when a packet containing that information is determined to be lost | ||||
| and sending ceases when a packet containing that information is | ||||
| acknowledged. | ||||
| o Data sent in CRYPTO frames is retransmitted according to the rules | ||||
| in [QUIC-RECOVERY], until either all data has been acknowledged or | ||||
| the crypto state machine implicitly knows that the peer received | ||||
| the data. | ||||
| o Application data sent in STREAM frames is retransmitted in new | ||||
| STREAM frames unless the endpoint has sent a RST_STREAM for that | ||||
| stream. Once an endpoint sends a RST_STREAM frame, no further | ||||
| STREAM frames are needed. | ||||
| o The most recent set of acknowledgments are sent in ACK frames. An | ||||
| ACK frame SHOULD contain all unacknowledged acknowledgments, as | ||||
| described in Section 7.16.3. | ||||
| o Cancellation of stream transmission, as carried in a RST_STREAM | ||||
| frame, is sent until acknowledged or until all stream data is | ||||
| acknowledged by the peer (that is, either the "Reset Recvd" or | ||||
| "Data Recvd" state is reached on the send stream). The content of | ||||
| a RST_STREAM frame MUST NOT change when it is sent again. | ||||
| o Similarly, a request to cancel stream transmission, as encoded in | ||||
| a STOP_SENDING frame, is sent until the receive stream enters | ||||
| either a "Data Recvd" or "Reset Recvd" state, see Section 9.3. | ||||
| o Connection close signals, including those that use | ||||
| CONNECTION_CLOSE and APPLICATION_CLOSE frames, are not sent again | ||||
| when packet loss is detected, but as described in Section 6.13. | ||||
| o The current connection maximum data is sent in MAX_DATA frames. | ||||
| An updated value is sent in a MAX_DATA frame if the packet | ||||
| containing the most recently sent MAX_DATA frame is declared lost, | ||||
| or when the endpoint decides to update the limit. Care is | ||||
| necessary to avoid sending this frame too often as the limit can | ||||
| increase frequently and cause an unnecessarily large number of | ||||
| MAX_DATA frames to be sent. | ||||
| o The current maximum stream data offset is sent in MAX_STREAM_DATA | ||||
| frames. Like MAX_DATA, an updated value is sent when the packet | ||||
| containing the most recent MAX_STREAM_DATA frame for a stream is | ||||
| lost or when the limit is updated, with care taken to prevent the | ||||
| frame from being sent too often. An endpoint SHOULD stop sending | ||||
| MAX_STREAM_DATA frames when the receive stream enters a "Size | ||||
| Known" state. | ||||
| o The maximum stream ID for a stream of a given type is sent in | ||||
| MAX_STREAM_ID frames. Like MAX_DATA, an updated value is sent | ||||
| when a packet containing the most recent MAX_STREAM_ID for a | ||||
| stream type frame is declared lost or when the limit is updated, | ||||
| with care taken to prevent the frame from being sent too often. | ||||
| o Blocked signals are carried in BLOCKED, STREAM_BLOCKED, and | ||||
| STREAM_ID_BLOCKED frames. BLOCKED streams have connection scope, | ||||
| STREAM_BLOCKED frames have stream scope, and STREAM_ID_BLOCKED | ||||
| frames are scoped to a specific stream type. New frames are sent | ||||
| if packets containing the most recent frame for a scope is lost, | ||||
| but only while the endpoint is blocked on the corresponding limit. | ||||
| These frames always include the limit that is causing blocking at | ||||
| the time that they are transmitted. | ||||
| o A liveness or path validation check using PATH_CHALLENGE frames is | ||||
| sent periodically until a matching PATH_RESPONSE frame is received | ||||
| or until there is no remaining need for liveness or path | ||||
| validation checking. PATH_CHALLENGE frames include a different | ||||
| payload each time they are sent. | ||||
| o Responses to path validation using PATH_RESPONSE frames are sent | ||||
| just once. A new PATH_CHALLENGE frame will be sent if another | ||||
| PATH_RESPONSE frame is needed. | ||||
| o New connection IDs are sent in NEW_CONNECTION_ID frames and | ||||
| retransmitted if the packet containing them is lost. | ||||
| Retransmissions of this frame carry the same sequence number | ||||
| value. Likewise, retired connection IDs are sent in | ||||
| RETIRE_CONNECTION_ID frames and retransmitted if the packet | ||||
| containing them is lost. | ||||
| o PADDING frames contain no information, so lost PADDING frames do | ||||
| not require repair. | ||||
| Upon detecting losses, a sender MUST take appropriate congestion | ||||
| control action. The details of loss detection and congestion control | ||||
| are described in [QUIC-RECOVERY]. | ||||
| 8.3. Packet Size | ||||
| The QUIC packet size includes the QUIC header and integrity check, | ||||
| but not the UDP or IP header. | ||||
| Clients MUST ensure that the first Initial packet they send is sent | ||||
| in a UDP datagram that is at least 1200 octets. Padding the Initial | ||||
| packet or including a 0-RTT packet in the same datagram are ways to | ||||
| meet this requirement. Sending a UDP datagram of this size ensures | ||||
| that the network path supports a reasonable Maximum Transmission Unit | ||||
| (MTU), and helps reduce the amplitude of amplification attacks caused | ||||
| by server responses toward an unverified client address. | ||||
| The datagram containing the first Initial packet from a client MAY | ||||
| exceed 1200 octets if the client believes that the Path Maximum | ||||
| Transmission Unit (PMTU) supports the size that it chooses. | ||||
| A server MAY send a CONNECTION_CLOSE frame with error code | ||||
| PROTOCOL_VIOLATION in response to the first Initial packet it | ||||
| receives from a client if the UDP datagram is smaller than 1200 | ||||
| octets. It MUST NOT send any other frame type in response, or | ||||
| otherwise behave as if any part of the offending packet was processed | ||||
| as valid. | ||||
| 8.4. Path Maximum Transmission Unit | ||||
| The Path Maximum Transmission Unit (PMTU) is the maximum size of the | ||||
| entire IP header, UDP header, and UDP payload. The UDP payload | ||||
| includes the QUIC packet header, protected payload, and any | ||||
| authentication fields. | ||||
| All QUIC packets SHOULD be sized to fit within the estimated PMTU to | ||||
| avoid IP fragmentation or packet drops. To optimize bandwidth | ||||
| efficiency, endpoints SHOULD use Packetization Layer PMTU Discovery | ||||
| ([PLPMTUD]). Endpoints MAY use PMTU Discovery ([PMTUDv4], [PMTUDv6]) | ||||
| for detecting the PMTU, setting the PMTU appropriately, and storing | ||||
| the result of previous PMTU determinations. | ||||
| In the absence of these mechanisms, QUIC endpoints SHOULD NOT send IP | ||||
| packets larger than 1280 octets. Assuming the minimum IP header | ||||
| size, this results in a QUIC packet size of 1232 octets for IPv6 and | ||||
| 1252 octets for IPv4. Some QUIC implementations MAY be more | ||||
| conservative in computing allowed QUIC packet size given unknown | ||||
| tunneling overheads or IP header options. | ||||
| QUIC endpoints that implement any kind of PMTU discovery SHOULD | ||||
| maintain an estimate for each combination of local and remote IP | ||||
| addresses. Each pairing of local and remote addresses could have a | ||||
| different maximum MTU in the path. | ||||
| QUIC depends on the network path supporting an MTU of at least 1280 | ||||
| octets. This is the IPv6 minimum MTU and therefore also supported by | ||||
| most modern IPv4 networks. An endpoint MUST NOT reduce its MTU below | ||||
| this number, even if it receives signals that indicate a smaller | ||||
| limit might exist. | ||||
| If a QUIC endpoint determines that the PMTU between any pair of local | ||||
| and remote IP addresses has fallen below 1280 octets, it MUST | ||||
| immediately cease sending QUIC packets on the affected path. This | ||||
| could result in termination of the connection if an alternative path | ||||
| cannot be found. | ||||
| 8.4.1. IPv4 PMTU Discovery | ||||
| Traditional ICMP-based path MTU discovery in IPv4 [PMTUDv4] is | ||||
| potentially vulnerable to off-path attacks that successfully guess | ||||
| the IP/port 4-tuple and reduce the MTU to a bandwidth-inefficient | ||||
| value. TCP connections mitigate this risk by using the (at minimum) | ||||
| 8 bytes of transport header echoed in the ICMP message to validate | ||||
| the TCP sequence number as valid for the current connection. | ||||
| However, as QUIC operates over UDP, in IPv4 the echoed information | ||||
| could consist only of the IP and UDP headers, which usually has | ||||
| insufficient entropy to mitigate off-path attacks. | ||||
| As a result, endpoints that implement PMTUD in IPv4 SHOULD take steps | ||||
| to mitigate this risk. For instance, an application could: | ||||
| o Set the IPv4 Don't Fragment (DF) bit on a small proportion of | ||||
| packets, so that most invalid ICMP messages arrive when there are | ||||
| no DF packets outstanding, and can therefore be identified as | ||||
| spurious. | ||||
| o Store additional information from the IP or UDP headers from DF | ||||
| packets (for example, the IP ID or UDP checksum) to further | ||||
| authenticate incoming Datagram Too Big messages. | ||||
| o Any reduction in PMTU due to a report contained in an ICMP packet | ||||
| is provisional until QUIC's loss detection algorithm determines | ||||
| that the packet is actually lost. | ||||
| 8.4.2. Special Considerations for Packetization Layer PMTU Discovery | ||||
| The PADDING frame provides a useful option for PMTU probe packets. | ||||
| PADDING frames generate acknowledgements, but they need not be | ||||
| delivered reliably. As a result, the loss of PADDING frames in probe | ||||
| packets does not require delay-inducing retransmission. However, | ||||
| PADDING frames do consume congestion window, which may delay the | ||||
| transmission of subsequent application data. | ||||
| When implementing the algorithm in Section 7.2 of [PLPMTUD], the | ||||
| initial value of search_low SHOULD be consistent with the IPv6 | ||||
| minimum packet size. Paths that do not support this size cannot | ||||
| deliver Initial packets, and therefore are not QUIC-compliant. | ||||
| Section 7.3 of [PLPMTUD] discusses trade-offs between small and large | ||||
| increases in the size of probe packets. As QUIC probe packets need | ||||
| not contain application data, aggressive increases in probe size | ||||
| carry fewer consequences. | ||||
| 9. Streams: QUIC's Data Structuring Abstraction | ||||
| Streams in QUIC provide a lightweight, ordered byte-stream | ||||
| abstraction. | ||||
| There are two basic types of stream in QUIC. Unidirectional streams | ||||
| carry data in one direction: from the initiator of the stream to its | ||||
| peer; bidirectional streams allow for data to be sent in both | ||||
| directions. Different stream identifiers are used to distinguish | ||||
| between unidirectional and bidirectional streams, as well as to | ||||
| create a separation between streams that are initiated by the client | ||||
| and server (see Section 9.1). | ||||
| Either type of stream can be created by either endpoint, can | ||||
| concurrently send data interleaved with other streams, and can be | ||||
| cancelled. | ||||
| Stream offsets allow for the octets on a stream to be placed in | ||||
| order. An endpoint MUST be capable of delivering data received on a | ||||
| stream in order. Implementations MAY choose to offer the ability to | ||||
| deliver data out of order. There is no means of ensuring ordering | ||||
| between octets on different streams. | ||||
| The creation and destruction of streams are expected to have minimal | ||||
| bandwidth and computational cost. A single STREAM frame may create, | ||||
| carry data for, and terminate a stream, or a stream may last the | ||||
| entire duration of a connection. | ||||
| Streams are individually flow controlled, allowing an endpoint to | ||||
| limit memory commitment and to apply back pressure. The creation of | ||||
| streams is also flow controlled, with each peer declaring the maximum | ||||
| stream ID it is willing to accept at a given time. | ||||
| An alternative view of QUIC streams is as an elastic "message" | ||||
| abstraction, similar to the way ephemeral streams are used in SST | ||||
| [SST], which may be a more appealing description for some | ||||
| applications. | ||||
| 9.1. Stream Identifiers | ||||
| Streams are identified by an unsigned 62-bit integer, referred to as | ||||
| the Stream ID. The least significant two bits of the Stream ID are | ||||
| used to identify the type of stream (unidirectional or bidirectional) | ||||
| and the initiator of the stream. | ||||
| The least significant bit (0x1) of the Stream ID identifies the | ||||
| initiator of the stream. Clients initiate even-numbered streams | ||||
| (those with the least significant bit set to 0); servers initiate | ||||
| odd-numbered streams (with the bit set to 1). Separation of the | ||||
| stream identifiers ensures that client and server are able to open | ||||
| streams without the latency imposed by negotiating for an identifier. | ||||
| If an endpoint receives a frame for a stream that it expects to | ||||
| initiate (i.e., odd-numbered for the client or even-numbered for the | ||||
| server), but which it has not yet opened, it MUST close the | ||||
| connection with error code STREAM_STATE_ERROR. | ||||
| The second least significant bit (0x2) of the Stream ID | ||||
| differentiates between unidirectional streams and bidirectional | ||||
| streams. Unidirectional streams always have this bit set to 1 and | ||||
| bidirectional streams have this bit set to 0. | ||||
| The two type bits from a Stream ID therefore identify streams as | ||||
| summarized in Table 5. | ||||
| +----------+----------------------------------+ | ||||
| | Low Bits | Stream Type | | ||||
| +----------+----------------------------------+ | ||||
| | 0x0 | Client-Initiated, Bidirectional | | ||||
| | | | | ||||
| | 0x1 | Server-Initiated, Bidirectional | | ||||
| | | | | ||||
| | 0x2 | Client-Initiated, Unidirectional | | ||||
| | | | | ||||
| | 0x3 | Server-Initiated, Unidirectional | | ||||
| +----------+----------------------------------+ | ||||
| Table 5: Stream ID Types | ||||
| The first bi-directional stream opened by the client is stream 0. | ||||
| A QUIC endpoint MUST NOT reuse a Stream ID. Streams of each type are | ||||
| created in numeric order. Streams that are used out of order result | ||||
| in opening all lower-numbered streams of the same type in the same | ||||
| direction. | ||||
| Stream IDs are encoded as a variable-length integer (see | ||||
| Section 7.1). | ||||
| 9.2. Stream States | ||||
| This section describes the two types of QUIC stream in terms of the | ||||
| states of their send or receive components. Two state machines are | ||||
| described: one for streams on which an endpoint transmits data | ||||
| (Section 9.2.1); another for streams from which an endpoint receives | ||||
| data (Section 9.2.2). | ||||
| Unidirectional streams use the applicable state machine directly. | ||||
| Bidirectional streams use both state machines. For the most part, | ||||
| the use of these state machines is the same whether the stream is | ||||
| unidirectional or bidirectional. The conditions for opening a stream | ||||
| are slightly more complex for a bidirectional stream because the | ||||
| opening of either send or receive sides causes the stream to open in | ||||
| both directions. | ||||
| An endpoint can open streams up to its maximum stream limit in any | ||||
| order, however endpoints SHOULD open the send side of streams for | ||||
| each type in order. | ||||
| Note: These states are largely informative. This document uses | ||||
| stream states to describe rules for when and how different types | ||||
| of frames can be sent and the reactions that are expected when | ||||
| different types of frames are received. Though these state | ||||
| machines are intended to be useful in implementing QUIC, these | ||||
| states aren't intended to constrain implementations. An | ||||
| implementation can define a different state machine as long as its | ||||
| behavior is consistent with an implementation that implements | ||||
| these states. | ||||
| 9.2.1. Send Stream States | ||||
| Figure 16 shows the states for the part of a stream that sends data | ||||
| to a peer. | ||||
| o | ||||
| | Create Stream (Sending) | ||||
| | Create Bidirectional Stream (Receiving) | ||||
| v | ||||
| +-------+ | ||||
| | Ready | Send RST_STREAM | ||||
| | |-----------------------. | ||||
| +-------+ | | ||||
| | | | ||||
| | Send STREAM / | | ||||
| | STREAM_BLOCKED | | ||||
| | | | ||||
| | Create Bidirectional | | ||||
| | Stream (Receiving) | | ||||
| v | | ||||
| +-------+ | | ||||
| | Send | Send RST_STREAM | | ||||
| | |---------------------->| | ||||
| +-------+ | | ||||
| | | | ||||
| | Send STREAM + FIN | | ||||
| v v | ||||
| +-------+ +-------+ | ||||
| | Data | Send RST_STREAM | Reset | | ||||
| | Sent |------------------>| Sent | | ||||
| +-------+ +-------+ | ||||
| | | | ||||
| | Recv All ACKs | Recv ACK | ||||
| v v | ||||
| +-------+ +-------+ | ||||
| | Data | | Reset | | ||||
| | Recvd | | Recvd | | ||||
| +-------+ +-------+ | ||||
| Figure 16: States for Send Streams | ||||
| The sending part of stream that the endpoint initiates (types 0 and 2 | ||||
| for clients, 1 and 3 for servers) is opened by the application or | ||||
| application protocol. The "Ready" state represents a newly created | ||||
| stream that is able to accept data from the application. Stream data | ||||
| might be buffered in this state in preparation for sending. | ||||
| Sending the first STREAM or STREAM_BLOCKED frame causes a send stream | ||||
| to enter the "Send" state. An implementation might choose to defer | ||||
| allocating a Stream ID to a send stream until it sends the first | ||||
| frame and enters this state, which can allow for better stream | ||||
| prioritization. | ||||
| The sending part of a bidirectional stream initiated by a peer (type | ||||
| 0 for a server, type 1 for a client) enters the "Ready" state then | ||||
| immediately transitions to the "Send" state if the receiving part | ||||
| enters the "Recv" state. | ||||
| In the "Send" state, an endpoint transmits - and retransmits as | ||||
| necessary - data in STREAM frames. The endpoint respects the flow | ||||
| control limits of its peer, accepting MAX_STREAM_DATA frames. An | ||||
| endpoint in the "Send" state generates STREAM_BLOCKED frames if it | ||||
| encounters flow control limits. | ||||
| After the application indicates that stream data is complete and a | ||||
| STREAM frame containing the FIN bit is sent, the send stream enters | ||||
| the "Data Sent" state. From this state, the endpoint only | ||||
| retransmits stream data as necessary. The endpoint no longer needs | ||||
| to track flow control limits or send STREAM_BLOCKED frames for a send | ||||
| stream in this state. The endpoint can ignore any MAX_STREAM_DATA | ||||
| frames it receives from its peer in this state; MAX_STREAM_DATA | ||||
| frames might be received until the peer receives the final stream | ||||
| offset. | ||||
| Once all stream data has been successfully acknowledged, the send | ||||
| stream enters the "Data Recvd" state, which is a terminal state. | ||||
| From any of the "Ready", "Send", or "Data Sent" states, an | ||||
| application can signal that it wishes to abandon transmission of | ||||
| stream data. Similarly, the endpoint might receive a STOP_SENDING | ||||
| frame from its peer. In either case, the endpoint sends a RST_STREAM | ||||
| frame, which causes the stream to enter the "Reset Sent" state. | ||||
| An endpoint MAY send a RST_STREAM as the first frame on a send | ||||
| stream; this causes the send stream to open and then immediately | ||||
| transition to the "Reset Sent" state. | ||||
| Once a packet containing a RST_STREAM has been acknowledged, the send | ||||
| stream enters the "Reset Recvd" state, which is a terminal state. | ||||
| 9.2.2. Receive Stream States | ||||
| Figure 17 shows the states for the part of a stream that receives | ||||
| data from a peer. The states for a receive stream mirror only some | ||||
| of the states of the send stream at the peer. A receive stream | ||||
| doesn't track states on the send stream that cannot be observed, such | ||||
| as the "Ready" state; instead, receive streams track the delivery of | ||||
| data to the application or application protocol some of which cannot | ||||
| be observed by the sender. | ||||
| o | ||||
| | Recv STREAM / STREAM_BLOCKED / RST_STREAM | ||||
| | Create Bidirectional Stream (Sending) | ||||
| | Recv MAX_STREAM_DATA | ||||
| | Create Higher-Numbered Stream | ||||
| v | ||||
| +-------+ | ||||
| | Recv | Recv RST_STREAM | ||||
| | |-----------------------. | ||||
| +-------+ | | ||||
| | | | ||||
| | Recv STREAM + FIN | | ||||
| v | | ||||
| +-------+ | | ||||
| | Size | Recv RST_STREAM | | ||||
| | Known |---------------------->| | ||||
| +-------+ | | ||||
| | | | ||||
| | Recv All Data | | ||||
| v v | ||||
| +-------+ Recv RST_STREAM +-------+ | ||||
| | Data |--- (optional) --->| Reset | | ||||
| | Recvd | Recv All Data | Recvd | | ||||
| +-------+<-- (optional) ----+-------+ | ||||
| | | | ||||
| | App Read All Data | App Read RST | ||||
| v v | ||||
| +-------+ +-------+ | ||||
| | Data | | Reset | | ||||
| | Read | | Read | | ||||
| +-------+ +-------+ | ||||
| Figure 17: States for Receive Streams | ||||
| The receiving part of a stream initiated by a peer (types 1 and 3 for | ||||
| a client, or 0 and 2 for a server) are created when the first STREAM, | ||||
| STREAM_BLOCKED, RST_STREAM, or MAX_STREAM_DATA (bidirectional only, | ||||
| see below) is received for that stream. The initial state for a | ||||
| receive stream is "Recv". Receiving a RST_STREAM frame causes the | ||||
| receive stream to immediately transition to the "Reset Recvd". | ||||
| The receive stream enters the "Recv" state when the sending part of a | ||||
| bidirectional stream initiated by the endpoint (type 0 for a client, | ||||
| type 1 for a server) enters the "Ready" state. | ||||
| A bidirectional stream also opens when a MAX_STREAM_DATA frame is | ||||
| received. Receiving a MAX_STREAM_DATA frame implies that the remote | ||||
| peer has opened the stream and is providing flow control credit. A | ||||
| MAX_STREAM_DATA frame might arrive before a STREAM or STREAM_BLOCKED | ||||
| frame if packets are lost or reordered. | ||||
| Before creating a stream, all lower-numbered streams of the same type | ||||
| MUST be created. That means that receipt of a frame that would open | ||||
| a stream causes all lower-numbered streams of the same type to be | ||||
| opened in numeric order. This ensures that the creation order for | ||||
| streams is consistent on both endpoints. | ||||
| In the "Recv" state, the endpoint receives STREAM and STREAM_BLOCKED | ||||
| frames. Incoming data is buffered and can be reassembled into the | ||||
| correct order for delivery to the application. As data is consumed | ||||
| by the application and buffer space becomes available, the endpoint | ||||
| sends MAX_STREAM_DATA frames to allow the peer to send more data. | ||||
| When a STREAM frame with a FIN bit is received, the final offset (see | ||||
| Section 10.3) is known. The receive stream enters the "Size Known" | ||||
| state. In this state, the endpoint no longer needs to send | ||||
| MAX_STREAM_DATA frames, it only receives any retransmissions of | ||||
| stream data. | ||||
| Once all data for the stream has been received, the receive stream | ||||
| enters the "Data Recvd" state. This might happen as a result of | ||||
| receiving the same STREAM frame that causes the transition to "Size | ||||
| Known". In this state, the endpoint has all stream data. Any STREAM | ||||
| or STREAM_BLOCKED frames it receives for the stream can be discarded. | ||||
| The "Data Recvd" state persists until stream data has been delivered | ||||
| to the application or application protocol. Once stream data has | ||||
| been delivered, the stream enters the "Data Read" state, which is a | ||||
| terminal state. | ||||
| Receiving a RST_STREAM frame in the "Recv" or "Size Known" states | ||||
| causes the stream to enter the "Reset Recvd" state. This might cause | ||||
| the delivery of stream data to the application to be interrupted. | ||||
| It is possible that all stream data is received when a RST_STREAM is | ||||
| received (that is, from the "Data Recvd" state). Similarly, it is | ||||
| possible for remaining stream data to arrive after receiving a | ||||
| RST_STREAM frame (the "Reset Recvd" state). An implementation is | ||||
| able to manage this situation as they choose. Sending RST_STREAM | ||||
| means that an endpoint cannot guarantee delivery of stream data; | ||||
| however there is no requirement that stream data not be delivered if | ||||
| a RST_STREAM is received. An implementation MAY interrupt delivery | ||||
| of stream data, discard any data that was not consumed, and signal | ||||
| the existence of the RST_STREAM immediately. Alternatively, the | ||||
| RST_STREAM signal might be suppressed or withheld if stream data is | ||||
| completely received. In the latter case, the receive stream | ||||
| effectively transitions to "Data Recvd" from "Reset Recvd". | ||||
| Once the application has been delivered the signal indicating that | ||||
| the receive stream was reset, the receive stream transitions to the | ||||
| "Reset Read" state, which is a terminal state. | ||||
| 9.2.3. Permitted Frame Types | ||||
| The sender of a stream sends just three frame types that affect the | ||||
| state of a stream at either sender or receiver: STREAM | ||||
| (Section 7.20), STREAM_BLOCKED (Section 7.11), and RST_STREAM | ||||
| (Section 7.3). | ||||
| A sender MUST NOT send any of these frames from a terminal state | ||||
| ("Data Recvd" or "Reset Recvd"). A sender MUST NOT send STREAM or | ||||
| STREAM_BLOCKED after sending a RST_STREAM; that is, in the "Reset | ||||
| Sent" state in addition to the terminal states. A receiver could | ||||
| receive any of these frames in any state, but only due to the | ||||
| possibility of delayed delivery of packets carrying them. | ||||
| The receiver of a stream sends MAX_STREAM_DATA (Section 7.7) and | ||||
| STOP_SENDING frames (Section 7.15). | ||||
| The receiver only sends MAX_STREAM_DATA in the "Recv" state. A | ||||
| receiver can send STOP_SENDING in any state where it has not received | ||||
| a RST_STREAM frame; that is states other than "Reset Recvd" or "Reset | ||||
| Read". However there is little value in sending a STOP_SENDING frame | ||||
| after all stream data has been received in the "Data Recvd" state. A | ||||
| sender could receive these frames in any state as a result of delayed | ||||
| delivery of packets. | ||||
| 9.2.4. Bidirectional Stream States | ||||
| A bidirectional stream is composed of a send stream and a receive | ||||
| stream. Implementations may represent states of the bidirectional | ||||
| stream as composites of send and receive stream states. The simplest | ||||
| model presents the stream as "open" when either send or receive | ||||
| stream is in a non-terminal state and "closed" when both send and | ||||
| receive streams are in a terminal state. | ||||
| Table 6 shows a more complex mapping of bidirectional stream states | ||||
| that loosely correspond to the stream states in HTTP/2 [HTTP2]. This | ||||
| shows that multiple states on send or receive streams are mapped to | ||||
| the same composite state. Note that this is just one possibility for | ||||
| such a mapping; this mapping requires that data is acknowledged | ||||
| before the transition to a "closed" or "half-closed" state. | ||||
| +-----------------------+---------------------+---------------------+ | ||||
| | Send Stream | Receive Stream | Composite State | | ||||
| +-----------------------+---------------------+---------------------+ | ||||
| | No Stream/Ready | No Stream/Recv *1 | idle | | ||||
| | | | | | ||||
| | Ready/Send/Data Sent | Recv/Size Known | open | | ||||
| | | | | | ||||
| | Ready/Send/Data Sent | Data Recvd/Data | half-closed | | ||||
| | | Read | (remote) | | ||||
| | | | | | ||||
| | Ready/Send/Data Sent | Reset Recvd/Reset | half-closed | | ||||
| | | Read | (remote) | | ||||
| | | | | | ||||
| | Data Recvd | Recv/Size Known | half-closed (local) | | ||||
| | | | | | ||||
| | Reset Sent/Reset | Recv/Size Known | half-closed (local) | | ||||
| | Recvd | | | | ||||
| | | | | | ||||
| | Data Recvd | Recv/Size Known | half-closed (local) | | ||||
| | | | | | ||||
| | Reset Sent/Reset | Data Recvd/Data | closed | | ||||
| | Recvd | Read | | | ||||
| | | | | | ||||
| | Reset Sent/Reset | Reset Recvd/Reset | closed | | ||||
| | Recvd | Read | | | ||||
| | | | | | ||||
| | Data Recvd | Data Recvd/Data | closed | | ||||
| | | Read | | | ||||
| | | | | | ||||
| | Data Recvd | Reset Recvd/Reset | closed | | ||||
| | | Read | | | ||||
| +-----------------------+---------------------+---------------------+ | ||||
| Table 6: Possible Mapping of Stream States to HTTP/2 | ||||
| Note (*1): A stream is considered "idle" if it has not yet been | ||||
| created, or if the receive stream is in the "Recv" state without | ||||
| yet having received any frames. | ||||
| 9.3. Solicited State Transitions | ||||
| If an endpoint is no longer interested in the data it is receiving on | ||||
| a stream, it MAY send a STOP_SENDING frame identifying that stream to | ||||
| prompt closure of the stream in the opposite direction. This | ||||
| typically indicates that the receiving application is no longer | ||||
| reading data it receives from the stream, but is not a guarantee that | ||||
| incoming data will be ignored. | ||||
| STREAM frames received after sending STOP_SENDING are still counted | ||||
| toward the connection and stream flow-control windows, even though | ||||
| these frames will be discarded upon receipt. This avoids potential | ||||
| ambiguity about which STREAM frames count toward flow control. | ||||
| A STOP_SENDING frame requests that the receiving endpoint send a | ||||
| RST_STREAM frame. An endpoint that receives a STOP_SENDING frame | ||||
| MUST send a RST_STREAM frame for that stream, and can use an error | ||||
| code of STOPPING. If the STOP_SENDING frame is received on a send | ||||
| stream that is already in the "Data Sent" state, a RST_STREAM frame | ||||
| MAY still be sent in order to cancel retransmission of previously- | ||||
| sent STREAM frames. | ||||
| STOP_SENDING SHOULD only be sent for a receive stream that has not | ||||
| been reset. STOP_SENDING is most useful for streams in the "Recv" or | ||||
| "Size Known" states. | ||||
| An endpoint is expected to send another STOP_SENDING frame if a | ||||
| packet containing a previous STOP_SENDING is lost. However, once | ||||
| either all stream data or a RST_STREAM frame has been received for | ||||
| the stream - that is, the stream is in any state other than "Recv" or | ||||
| "Size Known" - sending a STOP_SENDING frame is unnecessary. | ||||
| 9.4. Stream Concurrency | ||||
| An endpoint limits the number of concurrently active incoming streams | ||||
| by adjusting the maximum stream ID. An initial value is set in the | ||||
| transport parameters (see Section 6.6.1) and is subsequently | ||||
| increased by MAX_STREAM_ID frames (see Section 7.8). | ||||
| The maximum stream ID is specific to each endpoint and applies only | ||||
| to the peer that receives the setting. That is, clients specify the | ||||
| maximum stream ID the server can initiate, and servers specify the | ||||
| maximum stream ID the client can initiate. Each endpoint may respond | ||||
| on streams initiated by the other peer, regardless of whether it is | ||||
| permitted to initiate new streams. | ||||
| Endpoints MUST NOT exceed the limit set by their peer. An endpoint | ||||
| that receives a STREAM frame with an ID greater than the limit it has | ||||
| sent MUST treat this as a stream error of type STREAM_ID_ERROR | ||||
| (Section 11), unless this is a result of a change in the initial | ||||
| limits (see Section 6.6.2). | ||||
| A receiver cannot renege on an advertisement; that is, once a | ||||
| receiver advertises a stream ID via a MAX_STREAM_ID frame, | ||||
| advertising a smaller maximum ID has no effect. A sender MUST ignore | ||||
| any MAX_STREAM_ID frame that does not increase the maximum stream ID. | ||||
| 9.5. Sending and Receiving Data | ||||
| Once a stream is created, endpoints may use the stream to send and | ||||
| receive data. Each endpoint may send a series of STREAM frames | ||||
| encapsulating data on a stream until the stream is terminated in that | ||||
| direction. Streams are an ordered byte-stream abstraction, and they | ||||
| have no other structure within them. STREAM frame boundaries are not | ||||
| expected to be preserved in retransmissions from the sender or during | ||||
| delivery to the application at the receiver. | ||||
| When new data is to be sent on a stream, a sender MUST set the | ||||
| encapsulating STREAM frame's offset field to the stream offset of the | ||||
| first byte of this new data. The first octet of data on a stream has | ||||
| an offset of 0. An endpoint is expected to send every stream octet. | ||||
| The largest offset delivered on a stream MUST be less than 2^62. | ||||
| QUIC makes no specific allowances for partial reliability or delivery | ||||
| of stream data out of order. Endpoints MUST be able to deliver | ||||
| stream data to an application as an ordered byte-stream. Delivering | ||||
| an ordered byte-stream requires that an endpoint buffer any data that | ||||
| is received out of order, up to the advertised flow control limit. | ||||
| An endpoint could receive the same octets multiple times; octets that | ||||
| have already been received can be discarded. The value for a given | ||||
| octet MUST NOT change if it is sent multiple times; an endpoint MAY | ||||
| treat receipt of a changed octet as a connection error of type | ||||
| PROTOCOL_VIOLATION. | ||||
| An endpoint MUST NOT send data on any stream without ensuring that it | ||||
| is within the data limits set by its peer. | ||||
| Flow control is described in detail in Section 10, and congestion | ||||
| control is described in the companion document [QUIC-RECOVERY]. | ||||
| 9.6. Stream Prioritization | ||||
| Stream multiplexing has a significant effect on application | ||||
| performance if resources allocated to streams are correctly | ||||
| prioritized. Experience with other multiplexed protocols, such as | ||||
| HTTP/2 [HTTP2], shows that effective prioritization strategies have a | ||||
| significant positive impact on performance. | ||||
| QUIC does not provide frames for exchanging prioritization | ||||
| information. Instead it relies on receiving priority information | ||||
| from the application that uses QUIC. Protocols that use QUIC are | ||||
| able to define any prioritization scheme that suits their application | ||||
| semantics. A protocol might define explicit messages for signaling | ||||
| priority, such as those defined in HTTP/2; it could define rules that | ||||
| allow an endpoint to determine priority based on context; or it could | ||||
| leave the determination to the application. | ||||
| A QUIC implementation SHOULD provide ways in which an application can | ||||
| indicate the relative priority of streams. When deciding which | ||||
| streams to dedicate resources to, QUIC SHOULD use the information | ||||
| provided by the application. Failure to account for priority of | ||||
| streams can result in suboptimal performance. | ||||
| Stream priority is most relevant when deciding which stream data will | ||||
| be transmitted. Often, there will be limits on what can be | ||||
| transmitted as a result of connection flow control or the current | ||||
| congestion controller state. | ||||
| Giving preference to the transmission of its own management frames | ||||
| ensures that the protocol functions efficiently. That is, | ||||
| prioritizing frames other than STREAM frames ensures that loss | ||||
| recovery, congestion control, and flow control operate effectively. | ||||
| CRYPTO frames SHOULD be prioritized over other streams prior to the | ||||
| completion of the cryptographic handshake. This includes the | ||||
| retransmission of the second flight of client handshake messages, | ||||
| that is, the TLS Finished and any client authentication messages. | ||||
| STREAM data in frames determined to be lost SHOULD be retransmitted | ||||
| before sending new data, unless application priorities indicate | ||||
| otherwise. Retransmitting lost stream data can fill in gaps, which | ||||
| allows the peer to consume already received data and free up the flow | ||||
| control window. | ||||
| 10. Flow Control | ||||
| It is necessary to limit the amount of data that a sender may have | ||||
| outstanding at any time, so as to prevent a fast sender from | ||||
| overwhelming a slow receiver, or to prevent a malicious sender from | ||||
| consuming significant resources at a receiver. This section | ||||
| describes QUIC's flow-control mechanisms. | ||||
| QUIC employs a credit-based flow-control scheme similar to HTTP/2's | ||||
| flow control [HTTP2]. A receiver advertises the number of octets it | ||||
| is prepared to receive on a given stream and for the entire | ||||
| connection. This leads to two levels of flow control in QUIC: (i) | ||||
| Connection flow control, which prevents senders from exceeding a | ||||
| receiver's buffer capacity for the connection, and (ii) Stream flow | ||||
| control, which prevents a single stream from consuming the entire | ||||
| receive buffer for a connection. | ||||
| A data receiver sends MAX_STREAM_DATA or MAX_DATA frames to the | ||||
| sender to advertise additional credit. MAX_STREAM_DATA frames send | ||||
| the maximum absolute byte offset of a stream, while MAX_DATA sends | ||||
| the maximum of the sum of the absolute byte offsets of all streams. | ||||
| A receiver MAY advertise a larger offset at any point by sending | ||||
| MAX_DATA or MAX_STREAM_DATA frames. A receiver cannot renege on an | ||||
| advertisement; that is, once a receiver advertises an offset, | ||||
| advertising a smaller offset has no effect. A sender MUST therefore | ||||
| ignore any MAX_DATA or MAX_STREAM_DATA frames that do not increase | ||||
| flow control limits. | ||||
| A receiver MUST close the connection with a FLOW_CONTROL_ERROR error | ||||
| (Section 11) if the peer violates the advertised connection or stream | ||||
| data limits. | ||||
| A sender SHOULD send BLOCKED or STREAM_BLOCKED frames to indicate it | ||||
| has data to write but is blocked by flow control limits. These | ||||
| frames are expected to be sent infrequently in common cases, but they | ||||
| are considered useful for debugging and monitoring purposes. | ||||
| A receiver advertises credit for a stream by sending a | ||||
| MAX_STREAM_DATA frame with the Stream ID set appropriately. A | ||||
| receiver could use the current offset of data consumed to determine | ||||
| the flow control offset to be advertised. A receiver MAY send | ||||
| MAX_STREAM_DATA frames in multiple packets in order to make sure that | ||||
| the sender receives an update before running out of flow control | ||||
| credit, even if one of the packets is lost. | ||||
| Connection flow control is a limit to the total bytes of stream data | ||||
| sent in STREAM frames on all streams. A receiver advertises credit | ||||
| for a connection by sending a MAX_DATA frame. A receiver maintains a | ||||
| cumulative sum of bytes received on all contributing streams, which | ||||
| are used to check for flow control violations. A receiver might use | ||||
| a sum of bytes consumed on all contributing streams to determine the | ||||
| maximum data limit to be advertised. | ||||
| 10.1. Edge Cases and Other Considerations | ||||
| There are some edge cases which must be considered when dealing with | ||||
| stream and connection level flow control. Given enough time, both | ||||
| endpoints must agree on flow control state. If one end believes it | ||||
| can send more than the other end is willing to receive, the | ||||
| connection will be torn down when too much data arrives. | ||||
| Conversely if a sender believes it is blocked, while endpoint B | ||||
| expects more data can be received, then the connection can be in a | ||||
| deadlock, with the sender waiting for a MAX_DATA or MAX_STREAM_DATA | ||||
| frame which will never come. | ||||
| On receipt of a RST_STREAM frame, an endpoint will tear down state | ||||
| for the matching stream and ignore further data arriving on that | ||||
| stream. This could result in the endpoints getting out of sync, | ||||
| since the RST_STREAM frame may have arrived out of order and there | ||||
| may be further bytes in flight. The data sender would have counted | ||||
| the data against its connection level flow control budget, but a | ||||
| receiver that has not received these bytes would not know to include | ||||
| them as well. The receiver must learn the number of bytes that were | ||||
| sent on the stream to make the same adjustment in its connection flow | ||||
| controller. | ||||
| To avoid this de-synchronization, a RST_STREAM sender MUST include | ||||
| the final byte offset sent on the stream in the RST_STREAM frame. On | ||||
| receiving a RST_STREAM frame, a receiver definitively knows how many | ||||
| bytes were sent on that stream before the RST_STREAM frame, and the | ||||
| receiver MUST use the final offset to account for all bytes sent on | ||||
| the stream in its connection level flow controller. | ||||
| 10.1.1. Response to a RST_STREAM | ||||
| RST_STREAM terminates one direction of a stream abruptly. Whether | ||||
| any action or response can or should be taken on the data already | ||||
| received is an application-specific issue, but it will often be the | ||||
| case that upon receipt of a RST_STREAM an endpoint will choose to | ||||
| stop sending data in its own direction. If the sender of a | ||||
| RST_STREAM wishes to explicitly state that no future data will be | ||||
| processed, that endpoint MAY send a STOP_SENDING frame at the same | ||||
| time. | ||||
| 10.1.2. Data Limit Increments | ||||
| This document leaves when and how many bytes to advertise in a | ||||
| MAX_DATA or MAX_STREAM_DATA to implementations, but offers a few | ||||
| considerations. These frames contribute to connection overhead. | ||||
| Therefore frequently sending frames with small changes is | ||||
| undesirable. At the same time, infrequent updates require larger | ||||
| increments to limits if blocking is to be avoided. Thus, larger | ||||
| updates require a receiver to commit to larger resource commitments. | ||||
| Thus there is a trade-off between resource commitment and overhead | ||||
| when determining how large a limit is advertised. | ||||
| A receiver MAY use an autotuning mechanism to tune the frequency and | ||||
| amount that it increases data limits based on a round-trip time | ||||
| estimate and the rate at which the receiving application consumes | ||||
| data, similar to common TCP implementations. | ||||
| 10.2. Stream Limit Increment | ||||
| As with flow control, this document leaves when and how many streams | ||||
| to make available to a peer via MAX_STREAM_ID to implementations, but | ||||
| offers a few considerations. MAX_STREAM_ID frames constitute minimal | ||||
| overhead, while withholding MAX_STREAM_ID frames can prevent the peer | ||||
| from using the available parallelism. | ||||
| Implementations will likely want to increase the maximum stream ID as | ||||
| peer-initiated streams close. A receiver MAY also advance the | ||||
| maximum stream ID based on current activity, system conditions, and | ||||
| other environmental factors. | ||||
| 10.2.1. Blocking on Flow Control | ||||
| If a sender does not receive a MAX_DATA or MAX_STREAM_DATA frame when | ||||
| it has run out of flow control credit, the sender will be blocked and | ||||
| SHOULD send a BLOCKED or STREAM_BLOCKED frame. These frames are | ||||
| expected to be useful for debugging at the receiver; they do not | ||||
| require any other action. A receiver SHOULD NOT wait for a BLOCKED | ||||
| or STREAM_BLOCKED frame before sending MAX_DATA or MAX_STREAM_DATA, | ||||
| since doing so will mean that a sender is unable to send for an | ||||
| entire round trip. | ||||
| For smooth operation of the congestion controller, it is generally | ||||
| considered best to not let the sender go into quiescence if | ||||
| avoidable. To avoid blocking a sender, and to reasonably account for | ||||
| the possibility of loss, a receiver should send a MAX_DATA or | ||||
| MAX_STREAM_DATA frame at least two round trips before it expects the | ||||
| sender to get blocked. | ||||
| A sender sends a single BLOCKED or STREAM_BLOCKED frame only once | ||||
| when it reaches a data limit. A sender SHOULD NOT send multiple | ||||
| BLOCKED or STREAM_BLOCKED frames for the same data limit, unless the | ||||
| original frame is determined to be lost. Another BLOCKED or | ||||
| STREAM_BLOCKED frame can be sent after the data limit is increased. | ||||
| 10.3. Stream Final Offset | ||||
| The final offset is the count of the number of octets that are | ||||
| transmitted on a stream. For a stream that is reset, the final | ||||
| offset is carried explicitly in a RST_STREAM frame. Otherwise, the | ||||
| final offset is the offset of the end of the data carried in a STREAM | ||||
| frame marked with a FIN flag, or 0 in the case of incoming | ||||
| unidirectional streams. | ||||
| An endpoint will know the final offset for a stream when the receive | ||||
| stream enters the "Size Known" or "Reset Recvd" state. | ||||
| An endpoint MUST NOT send data on a stream at or beyond the final | ||||
| offset. | ||||
| Once a final offset for a stream is known, it cannot change. If a | ||||
| RST_STREAM or STREAM frame causes the final offset to change for a | ||||
| stream, an endpoint SHOULD respond with a FINAL_OFFSET_ERROR error | ||||
| (see Section 11). A receiver SHOULD treat receipt of data at or | ||||
| beyond the final offset as a FINAL_OFFSET_ERROR error, even after a | ||||
| stream is closed. Generating these errors is not mandatory, but only | ||||
| because requiring that an endpoint generate these errors also means | ||||
| that the endpoint needs to maintain the final offset state for closed | ||||
| streams, which could mean a significant state commitment. | ||||
| 10.4. Flow Control for Cryptographic Handshake | ||||
| Data sent in CRYPTO frames is not flow controlled in the same way as | ||||
| STREAM frames. QUIC relies on the cryptographic protocol | ||||
| implementation to avoid excessive buffering of data, see [QUIC-TLS]. | ||||
| The implementation SHOULD provide an interface to QUIC to tell it | ||||
| about its buffering limits so that there is not excessive buffering | ||||
| at multiple layers. | ||||
| 11. Error Handling | ||||
| An endpoint that detects an error SHOULD signal the existence of that | ||||
| error to its peer. Both transport-level and application-level errors | ||||
| can affect an entire connection (see Section 11.1), while only | ||||
| application-level errors can be isolated to a single stream (see | ||||
| Section 11.2). | ||||
| The most appropriate error code (Section 11.3) SHOULD be included in | ||||
| the frame that signals the error. Where this specification | ||||
| identifies error conditions, it also identifies the error code that | ||||
| is used. | ||||
| A stateless reset (Section 6.13.4) is not suitable for any error that | ||||
| can be signaled with a CONNECTION_CLOSE, APPLICATION_CLOSE, or | ||||
| RST_STREAM frame. A stateless reset MUST NOT be used by an endpoint | ||||
| that has the state necessary to send a frame on the connection. | ||||
| 11.1. Connection Errors | ||||
| Errors that result in the connection being unusable, such as an | ||||
| obvious violation of protocol semantics or corruption of state that | ||||
| affects an entire connection, MUST be signaled using a | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE frame (Section 7.4, | ||||
| Section 7.5). An endpoint MAY close the connection in this manner | ||||
| even if the error only affects a single stream. | ||||
| Application protocols can signal application-specific protocol errors | ||||
| using the APPLICATION_CLOSE frame. Errors that are specific to the | ||||
| transport, including all those described in this document, are | ||||
| carried in a CONNECTION_CLOSE frame. Other than the type of error | ||||
| code they carry, these frames are identical in format and semantics. | ||||
| A CONNECTION_CLOSE or APPLICATION_CLOSE frame could be sent in a | ||||
| packet that is lost. An endpoint SHOULD be prepared to retransmit a | ||||
| packet containing either frame type if it receives more packets on a | ||||
| terminated connection. Limiting the number of retransmissions and | ||||
| the time over which this final packet is sent limits the effort | ||||
| expended on terminated connections. | ||||
| An endpoint that chooses not to retransmit packets containing | ||||
| CONNECTION_CLOSE or APPLICATION_CLOSE risks a peer missing the first | ||||
| such packet. The only mechanism available to an endpoint that | ||||
| continues to receive data for a terminated connection is to use the | ||||
| stateless reset process (Section 6.13.4). | ||||
| An endpoint that receives an invalid CONNECTION_CLOSE or | QUIC frames do not use a self-describing encoding. An endpoint | |||
| APPLICATION_CLOSE frame MUST NOT signal the existence of the error to | therefore needs to understand the syntax of all frames before it can | |||
| its peer. | successfully process a packet. This allows for efficient encoding of | |||
| frames, but it means that an endpoint cannot send a frame of a type | ||||
| that is unknown to its peer. | ||||
| 11.2. Stream Errors | An extension to QUIC that wishes to use a new type of frame MUST | |||
| first ensure that a peer is able to understand the frame. An | ||||
| endpoint can use a transport parameter to signal its willingness to | ||||
| receive one or more extension frame types with the one transport | ||||
| parameter. | ||||
| If an application-level error affects a single stream, but otherwise | Extension frames MUST be congestion controlled and MUST cause an ACK | |||
| leaves the connection in a recoverable state, the endpoint can send a | frame to be sent. The exception is extension frames that replace or | |||
| RST_STREAM frame (Section 7.3) with an appropriate error code to | supplement the ACK frame. Extension frames are not included in flow | |||
| terminate just the affected stream. | control unless specified in the extension. | |||
| Other than STOPPING (Section 9.3), RST_STREAM MUST be instigated by | An IANA registry is used to manage the assignment of frame types, see | |||
| the application and MUST carry an application error code. Resetting | Section 22.2. | |||
| a stream without knowledge of the application protocol could cause | ||||
| the protocol to enter an unrecoverable state. Application protocols | ||||
| might require certain streams to be reliably delivered in order to | ||||
| guarantee consistent state between endpoints. | ||||
| 11.3. Transport Error Codes | 20. Transport Error Codes | |||
| QUIC error codes are 16-bit unsigned integers. | QUIC error codes are 16-bit unsigned integers. | |||
| This section lists the defined QUIC transport error codes that may be | This section lists the defined QUIC transport error codes that may be | |||
| used in a CONNECTION_CLOSE frame. These errors apply to the entire | used in a CONNECTION_CLOSE frame. These errors apply to the entire | |||
| connection. | connection. | |||
| NO_ERROR (0x0): An endpoint uses this with CONNECTION_CLOSE to | NO_ERROR (0x0): An endpoint uses this with CONNECTION_CLOSE to | |||
| signal that the connection is being closed abruptly in the absence | signal that the connection is being closed abruptly in the absence | |||
| of any error. | of any error. | |||
| INTERNAL_ERROR (0x1): The endpoint encountered an internal error and | INTERNAL_ERROR (0x1): The endpoint encountered an internal error and | |||
| cannot continue with the connection. | cannot continue with the connection. | |||
| SERVER_BUSY (0x2): The server is currently busy and does not accept | SERVER_BUSY (0x2): The server is currently busy and does not accept | |||
| any new connections. | any new connections. | |||
| FLOW_CONTROL_ERROR (0x3): An endpoint received more data than it | FLOW_CONTROL_ERROR (0x3): An endpoint received more data than it | |||
| permitted in its advertised data limits (see Section 10). | permitted in its advertised data limits (see Section 4). | |||
| STREAM_ID_ERROR (0x4): An endpoint received a frame for a stream | STREAM_ID_ERROR (0x4): An endpoint received a frame for a stream | |||
| identifier that exceeded its advertised maximum stream ID. | identifier that exceeded its advertised maximum stream ID. | |||
| STREAM_STATE_ERROR (0x5): An endpoint received a frame for a stream | STREAM_STATE_ERROR (0x5): An endpoint received a frame for a stream | |||
| that was not in a state that permitted that frame (see | that was not in a state that permitted that frame (see Section 3). | |||
| Section 9.2). | ||||
| FINAL_OFFSET_ERROR (0x6): An endpoint received a STREAM frame | FINAL_OFFSET_ERROR (0x6): An endpoint received a STREAM frame | |||
| containing data that exceeded the previously established final | containing data that exceeded the previously established final | |||
| offset. Or an endpoint received a RST_STREAM frame containing a | offset. Or an endpoint received a RST_STREAM frame containing a | |||
| final offset that was lower than the maximum offset of data that | final offset that was lower than the maximum offset of data that | |||
| was already received. Or an endpoint received a RST_STREAM frame | was already received. Or an endpoint received a RST_STREAM frame | |||
| containing a different final offset to the one already | containing a different final offset to the one already | |||
| established. | established. | |||
| FRAME_ENCODING_ERROR (0x7): An endpoint received a frame that was | FRAME_ENCODING_ERROR (0x7): An endpoint received a frame that was | |||
| skipping to change at page 110, line 23 ¶ | skipping to change at page 111, line 41 ¶ | |||
| INVALID_MIGRATION (0xC): A peer has migrated to a different network | INVALID_MIGRATION (0xC): A peer has migrated to a different network | |||
| when the endpoint had disabled migration. | when the endpoint had disabled migration. | |||
| CRYPTO_ERROR (0x1XX): The cryptographic handshake failed. A range | CRYPTO_ERROR (0x1XX): The cryptographic handshake failed. A range | |||
| of 256 values is reserved for carrying error codes specific to the | of 256 values is reserved for carrying error codes specific to the | |||
| cryptographic handshake that is used. Codes for errors occurring | cryptographic handshake that is used. Codes for errors occurring | |||
| when TLS is used for the crypto handshake are described in | when TLS is used for the crypto handshake are described in | |||
| Section 4.8 of [QUIC-TLS]. | Section 4.8 of [QUIC-TLS]. | |||
| See Section 13.3 for details of registering new error codes. | See Section 22.3 for details of registering new error codes. | |||
| 11.4. Application Protocol Error Codes | 20.1. Application Protocol Error Codes | |||
| Application protocol error codes are 16-bit unsigned integers, but | Application protocol error codes are 16-bit unsigned integers, but | |||
| the management of application error codes are left to application | the management of application error codes are left to application | |||
| protocols. Application protocol error codes are used for the | protocols. Application protocol error codes are used for the | |||
| RST_STREAM (Section 7.3) and APPLICATION_CLOSE (Section 7.5) frames. | RST_STREAM (Section 19.2) and APPLICATION_CLOSE (Section 19.4) | |||
| frames. | ||||
| There is no restriction on the use of the 16-bit error code space for | There is no restriction on the use of the 16-bit error code space for | |||
| application protocols. However, QUIC reserves the error code with a | application protocols. However, QUIC reserves the error code with a | |||
| value of 0 to mean STOPPING. The application error code of STOPPING | value of 0 to mean STOPPING. The application error code of STOPPING | |||
| (0) is used by the transport to cancel a stream in response to | (0) is used by the transport to cancel a stream in response to | |||
| receipt of a STOP_SENDING frame. | receipt of a STOP_SENDING frame. | |||
| 12. Security Considerations | 21. Security Considerations | |||
| 12.1. Handshake Denial of Service | 21.1. Handshake Denial of Service | |||
| As an encrypted and authenticated transport QUIC provides a range of | As an encrypted and authenticated transport QUIC provides a range of | |||
| protections against denial of service. Once the cryptographic | protections against denial of service. Once the cryptographic | |||
| handshake is complete, QUIC endpoints discard most packets that are | handshake is complete, QUIC endpoints discard most packets that are | |||
| not authenticated, greatly limiting the ability of an attacker to | not authenticated, greatly limiting the ability of an attacker to | |||
| interfere with existing connections. | interfere with existing connections. | |||
| Once a connection is established QUIC endpoints might accept some | Once a connection is established QUIC endpoints might accept some | |||
| unauthenticated ICMP packets (see Section 8.4.1), but the use of | unauthenticated ICMP packets (see Section 14.1.1), but the use of | |||
| these packets is extremely limited. The only other type of packet | these packets is extremely limited. The only other type of packet | |||
| that an endpoint might accept is a stateless reset (Section 6.13.4) | that an endpoint might accept is a stateless reset (Section 10.4) | |||
| which relies on the token being kept secret until it is used. | which relies on the token being kept secret until it is used. | |||
| During the creation of a connection, QUIC only provides protection | During the creation of a connection, QUIC only provides protection | |||
| against attack from off the network path. All QUIC packets contain | against attack from off the network path. All QUIC packets contain | |||
| proof that the recipient saw a preceding packet from its peer. | proof that the recipient saw a preceding packet from its peer. | |||
| The first mechanism used is the source and destination connection | The first mechanism used is the source and destination connection | |||
| IDs, which are required to match those set by a peer. Except for an | IDs, which are required to match those set by a peer. Except for an | |||
| Initial and stateless reset packets, an endpoint only accepts packets | Initial and stateless reset packets, an endpoint only accepts packets | |||
| that include a destination connection that matches a connection ID | that include a destination connection that matches a connection ID | |||
| skipping to change at page 111, line 36 ¶ | skipping to change at page 113, line 7 ¶ | |||
| These protections are not intended to be effective against an | These protections are not intended to be effective against an | |||
| attacker that is able to receive QUIC packets prior to the connection | attacker that is able to receive QUIC packets prior to the connection | |||
| being established. Such an attacker can potentially send packets | being established. Such an attacker can potentially send packets | |||
| that will be accepted by QUIC endpoints. This version of QUIC | that will be accepted by QUIC endpoints. This version of QUIC | |||
| attempts to detect this sort of attack, but it expects that endpoints | attempts to detect this sort of attack, but it expects that endpoints | |||
| will fail to establish a connection rather than recovering. For the | will fail to establish a connection rather than recovering. For the | |||
| most part, the cryptographic handshake protocol [QUIC-TLS] is | most part, the cryptographic handshake protocol [QUIC-TLS] is | |||
| responsible for detecting tampering during the handshake, though | responsible for detecting tampering during the handshake, though | |||
| additional validation is required for version negotiation (see | additional validation is required for version negotiation (see | |||
| Section 6.6.4). | Section 7.3.3). | |||
| Endpoints are permitted to use other methods to detect and attempt to | Endpoints are permitted to use other methods to detect and attempt to | |||
| recover from interference with the handshake. Invalid packets may be | recover from interference with the handshake. Invalid packets may be | |||
| identified and discarded using other methods, but no specific method | identified and discarded using other methods, but no specific method | |||
| is mandated in this document. | is mandated in this document. | |||
| 12.2. Spoofed ACK Attack | 21.2. Spoofed ACK Attack | |||
| An attacker might be able to receive an address validation token | An attacker might be able to receive an address validation token | |||
| (Section 6.9) from the server and then release the IP address it used | (Section 8) from the server and then release the IP address it used | |||
| to acquire that token. The attacker may, in the future, spoof this | to acquire that token. The attacker may, in the future, spoof this | |||
| same address (which now presumably addresses a different endpoint), | same address (which now presumably addresses a different endpoint), | |||
| and initiate a 0-RTT connection with a server on the victim's behalf. | and initiate a 0-RTT connection with a server on the victim's behalf. | |||
| The attacker can then spoof ACK frames to the server which cause the | The attacker can then spoof ACK frames to the server which cause the | |||
| server to send excessive amounts of data toward the new owner of the | server to send excessive amounts of data toward the new owner of the | |||
| IP address. | IP address. | |||
| There are two possible mitigations to this attack. The simplest one | There are two possible mitigations to this attack. The simplest one | |||
| is that a server can unilaterally create a gap in packet-number | is that a server can unilaterally create a gap in packet-number | |||
| space. In the non-attack scenario, the client will send an ACK frame | space. In the non-attack scenario, the client will send an ACK frame | |||
| skipping to change at page 112, line 23 ¶ | skipping to change at page 113, line 43 ¶ | |||
| The second mitigation is that the server can require that | The second mitigation is that the server can require that | |||
| acknowledgments for sent packets match the encryption level of the | acknowledgments for sent packets match the encryption level of the | |||
| sent packet. This mitigation is useful if the connection has an | sent packet. This mitigation is useful if the connection has an | |||
| ephemeral forward-secure key that is generated and used for every new | ephemeral forward-secure key that is generated and used for every new | |||
| connection. If a packet sent is protected with a forward-secure key, | connection. If a packet sent is protected with a forward-secure key, | |||
| then any acknowledgments that are received for them MUST also be | then any acknowledgments that are received for them MUST also be | |||
| forward-secure protected. Since the attacker will not have the | forward-secure protected. Since the attacker will not have the | |||
| forward-secure key, the attacker will not be able to generate | forward-secure key, the attacker will not be able to generate | |||
| forward-secure protected packets with ACK frames. | forward-secure protected packets with ACK frames. | |||
| 12.3. Optimistic ACK Attack | 21.3. Optimistic ACK Attack | |||
| An endpoint that acknowledges packets it has not received might cause | An endpoint that acknowledges packets it has not received might cause | |||
| a congestion controller to permit sending at rates beyond what the | a congestion controller to permit sending at rates beyond what the | |||
| network supports. An endpoint MAY skip packet numbers when sending | network supports. An endpoint MAY skip packet numbers when sending | |||
| packets to detect this behavior. An endpoint can then immediately | packets to detect this behavior. An endpoint can then immediately | |||
| close the connection with a connection error of type | close the connection with a connection error of type | |||
| PROTOCOL_VIOLATION (see Section 6.13.3). | PROTOCOL_VIOLATION (see Section 10.3). | |||
| 12.4. Slowloris Attacks | 21.4. Slowloris Attacks | |||
| The attacks commonly known as Slowloris [SLOWLORIS] try to keep many | The attacks commonly known as Slowloris [SLOWLORIS] try to keep many | |||
| connections to the target endpoint open and hold them open as long as | connections to the target endpoint open and hold them open as long as | |||
| possible. These attacks can be executed against a QUIC endpoint by | possible. These attacks can be executed against a QUIC endpoint by | |||
| generating the minimum amount of activity necessary to avoid being | generating the minimum amount of activity necessary to avoid being | |||
| closed for inactivity. This might involve sending small amounts of | closed for inactivity. This might involve sending small amounts of | |||
| data, gradually opening flow control windows in order to control the | data, gradually opening flow control windows in order to control the | |||
| sender rate, or manufacturing ACK frames that simulate a high loss | sender rate, or manufacturing ACK frames that simulate a high loss | |||
| rate. | rate. | |||
| QUIC deployments SHOULD provide mitigations for the Slowloris | QUIC deployments SHOULD provide mitigations for the Slowloris | |||
| attacks, such as increasing the maximum number of clients the server | attacks, such as increasing the maximum number of clients the server | |||
| will allow, limiting the number of connections a single IP address is | will allow, limiting the number of connections a single IP address is | |||
| allowed to make, imposing restrictions on the minimum transfer speed | allowed to make, imposing restrictions on the minimum transfer speed | |||
| a connection is allowed to have, and restricting the length of time | a connection is allowed to have, and restricting the length of time | |||
| an endpoint is allowed to stay connected. | an endpoint is allowed to stay connected. | |||
| 12.5. Stream Fragmentation and Reassembly Attacks | 21.5. Stream Fragmentation and Reassembly Attacks | |||
| An adversarial sender might intentionally send fragments of stream | An adversarial sender might intentionally send fragments of stream | |||
| data in order to cause disproportionate receive buffer memory | data in order to cause disproportionate receive buffer memory | |||
| commitment and/or creation of a large and inefficient data structure. | commitment and/or creation of a large and inefficient data structure. | |||
| An adversarial receiver might intentionally not acknowledge packets | An adversarial receiver might intentionally not acknowledge packets | |||
| containing stream data in order to force the sender to store the | containing stream data in order to force the sender to store the | |||
| unacknowledged stream data for retransmission. | unacknowledged stream data for retransmission. | |||
| The attack on receivers is mitigated if flow control windows | The attack on receivers is mitigated if flow control windows | |||
| skipping to change at page 113, line 28 ¶ | skipping to change at page 114, line 46 ¶ | |||
| that exceed actual available memory. The over-commitment strategy | that exceed actual available memory. The over-commitment strategy | |||
| can lead to better performance when endpoints are well behaved, but | can lead to better performance when endpoints are well behaved, but | |||
| renders endpoints vulnerable to the stream fragmentation attack. | renders endpoints vulnerable to the stream fragmentation attack. | |||
| QUIC deployments SHOULD provide mitigations against stream | QUIC deployments SHOULD provide mitigations against stream | |||
| fragmentation attacks. Mitigations could consist of avoiding over- | fragmentation attacks. Mitigations could consist of avoiding over- | |||
| committing memory, limiting the size of tracking data structures, | committing memory, limiting the size of tracking data structures, | |||
| delaying reassembly of STREAM frames, implementing heuristics based | delaying reassembly of STREAM frames, implementing heuristics based | |||
| on the age and duration of reassembly holes, or some combination. | on the age and duration of reassembly holes, or some combination. | |||
| 12.6. Stream Commitment Attack | 21.6. Stream Commitment Attack | |||
| An adversarial endpoint can open lots of streams, exhausting state on | An adversarial endpoint can open lots of streams, exhausting state on | |||
| an endpoint. The adversarial endpoint could repeat the process on a | an endpoint. The adversarial endpoint could repeat the process on a | |||
| large number of connections, in a manner similar to SYN flooding | large number of connections, in a manner similar to SYN flooding | |||
| attacks in TCP. | attacks in TCP. | |||
| Normally, clients will open streams sequentially, as explained in | Normally, clients will open streams sequentially, as explained in | |||
| Section 9.1. However, when several streams are initiated at short | Section 2.1. However, when several streams are initiated at short | |||
| intervals, transmission error may cause STREAM DATA frames opening | intervals, transmission error may cause STREAM DATA frames opening | |||
| streams to be received out of sequence. A receiver is obligated to | streams to be received out of sequence. A receiver is obligated to | |||
| open intervening streams if a higher-numbered stream ID is received. | open intervening streams if a higher-numbered stream ID is received. | |||
| Thus, on a new connection, opening stream 2000001 opens 1 million | Thus, on a new connection, opening stream 2000001 opens 1 million | |||
| streams, as required by the specification. | streams, as required by the specification. | |||
| The number of active streams is limited by the concurrent stream | The number of active streams is limited by the concurrent stream | |||
| limit transport parameter, as explained in Section 9.4. If chosen | limit transport parameter, as explained in Section 2.2. If chosen | |||
| judiciously, this limit mitigates the effect of the stream commitment | judiciously, this limit mitigates the effect of the stream commitment | |||
| attack. However, setting the limit too low could affect performance | attack. However, setting the limit too low could affect performance | |||
| when applications expect to open large number of streams. | when applications expect to open large number of streams. | |||
| 12.7. Explicit Congestion Notification Attacks | 21.7. Explicit Congestion Notification Attacks | |||
| An on-path attacker could manipulate the value of ECN codepoints in | An on-path attacker could manipulate the value of ECN codepoints in | |||
| the IP header to influence the sender's rate. [RFC3168] discusses | the IP header to influence the sender's rate. [RFC3168] discusses | |||
| manipulations and their effects in more detail. | manipulations and their effects in more detail. | |||
| An on-the-side attacker can duplicate and send packets with modified | An on-the-side attacker can duplicate and send packets with modified | |||
| ECN codepoints to affect the sender's rate. If duplicate packets are | ECN codepoints to affect the sender's rate. If duplicate packets are | |||
| discarded by a receiver, an off-path attacker will need to race the | discarded by a receiver, an off-path attacker will need to race the | |||
| duplicate packet against the original to be successful in this | duplicate packet against the original to be successful in this | |||
| attack. Therefore, QUIC receivers ignore ECN codepoints set in | attack. Therefore, QUIC receivers ignore ECN codepoints set in | |||
| duplicate packets (see Section 6.8). | duplicate packets (see Section 13.3). | |||
| 12.8. Stateless Reset Oracle | 21.8. Stateless Reset Oracle | |||
| Stateless resets create a possible denial of service attack analogous | Stateless resets create a possible denial of service attack analogous | |||
| to a TCP reset injection. This attack is possible if an attacker is | to a TCP reset injection. This attack is possible if an attacker is | |||
| able to cause a stateless reset token to be generated for a | able to cause a stateless reset token to be generated for a | |||
| connection with a selected connection ID. An attacker that can cause | connection with a selected connection ID. An attacker that can cause | |||
| this token to be generated can reset an active connection with the | this token to be generated can reset an active connection with the | |||
| same connection ID. | same connection ID. | |||
| If a packet can be routed to different instances that share a static | If a packet can be routed to different instances that share a static | |||
| key, for example by changing an IP address or port, then an attacker | key, for example by changing an IP address or port, then an attacker | |||
| can cause the server to send a stateless reset. To defend against | can cause the server to send a stateless reset. To defend against | |||
| this style of denial service, endpoints that share a static key for | this style of denial service, endpoints that share a static key for | |||
| stateless reset (see Section 6.13.4.2) MUST be arranged so that | stateless reset (see Section 10.4.2) MUST be arranged so that packets | |||
| packets with a given connection ID always arrive at an instance that | with a given connection ID always arrive at an instance that has | |||
| has connection state, unless that connection is no longer active. | connection state, unless that connection is no longer active. | |||
| In the case of a cluster that uses dynamic load balancing, it's | In the case of a cluster that uses dynamic load balancing, it's | |||
| possible that a change in load balancer configuration could happen | possible that a change in load balancer configuration could happen | |||
| while an active instance retains connection state; even if an | while an active instance retains connection state; even if an | |||
| instance retains connection state, the change in routing and | instance retains connection state, the change in routing and | |||
| resulting stateless reset will result in the connection being | resulting stateless reset will result in the connection being | |||
| terminated. If there is no chance in the packet being routed to the | terminated. If there is no chance in the packet being routed to the | |||
| correct instance, it is better to send a stateless reset than wait | correct instance, it is better to send a stateless reset than wait | |||
| for connections to time out. However, this is acceptable only if the | for connections to time out. However, this is acceptable only if the | |||
| routing cannot be influenced by an attacker. | routing cannot be influenced by an attacker. | |||
| 13. IANA Considerations | 22. IANA Considerations | |||
| 13.1. QUIC Transport Parameter Registry | 22.1. QUIC Transport Parameter Registry | |||
| IANA [SHALL add/has added] a registry for "QUIC Transport Parameters" | IANA [SHALL add/has added] a registry for "QUIC Transport Parameters" | |||
| under a "QUIC Protocol" heading. | under a "QUIC Protocol" heading. | |||
| The "QUIC Transport Parameters" registry governs a 16-bit space. | The "QUIC Transport Parameters" registry governs a 16-bit space. | |||
| This space is split into two spaces that are governed by different | This space is split into two spaces that are governed by different | |||
| policies. Values with the first byte in the range 0x00 to 0xfe (in | policies. Values with the first byte in the range 0x00 to 0xfe (in | |||
| hexadecimal) are assigned via the Specification Required policy | hexadecimal) are assigned via the Specification Required policy | |||
| [RFC8126]. Values with the first byte 0xff are reserved for Private | [RFC8126]. Values with the first byte 0xff are reserved for Private | |||
| Use [RFC8126]. | Use [RFC8126]. | |||
| skipping to change at page 116, line 8 ¶ | skipping to change at page 117, line 8 ¶ | |||
| readily accessible. Expert(s) are encouraged to be biased towards | readily accessible. Expert(s) are encouraged to be biased towards | |||
| approving registrations unless they are abusive, frivolous, or | approving registrations unless they are abusive, frivolous, or | |||
| actively harmful (not merely aesthetically displeasing, or | actively harmful (not merely aesthetically displeasing, or | |||
| architecturally dubious). | architecturally dubious). | |||
| The initial contents of this registry are shown in Table 7. | The initial contents of this registry are shown in Table 7. | |||
| +--------+-------------------------------------+---------------+ | +--------+-------------------------------------+---------------+ | |||
| | Value | Parameter Name | Specification | | | Value | Parameter Name | Specification | | |||
| +--------+-------------------------------------+---------------+ | +--------+-------------------------------------+---------------+ | |||
| | 0x0000 | initial_max_stream_data_bidi_local | Section 6.6.1 | | | 0x0000 | initial_max_stream_data_bidi_local | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0001 | initial_max_data | Section 6.6.1 | | | 0x0001 | initial_max_data | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0002 | initial_max_bidi_streams | Section 6.6.1 | | | 0x0002 | initial_max_bidi_streams | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0003 | idle_timeout | Section 6.6.1 | | | 0x0003 | idle_timeout | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0004 | preferred_address | Section 6.6.1 | | | 0x0004 | preferred_address | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0005 | max_packet_size | Section 6.6.1 | | | 0x0005 | max_packet_size | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0006 | stateless_reset_token | Section 6.6.1 | | | 0x0006 | stateless_reset_token | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0007 | ack_delay_exponent | Section 6.6.1 | | | 0x0007 | ack_delay_exponent | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0008 | initial_max_uni_streams | Section 6.6.1 | | | 0x0008 | initial_max_uni_streams | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x0009 | disable_migration | Section 6.6.1 | | | 0x0009 | disable_migration | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x000a | initial_max_stream_data_bidi_remote | Section 6.6.1 | | | 0x000a | initial_max_stream_data_bidi_remote | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x000b | initial_max_stream_data_uni | Section 6.6.1 | | | 0x000b | initial_max_stream_data_uni | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x000c | max_ack_delay | Section 6.6.1 | | | 0x000c | max_ack_delay | Section 18.1 | | |||
| | | | | | | | | | | |||
| | 0x000d | original_connection_id | Section 6.6.1 | | | 0x000d | original_connection_id | Section 18.1 | | |||
| +--------+-------------------------------------+---------------+ | +--------+-------------------------------------+---------------+ | |||
| Table 7: Initial QUIC Transport Parameters Entries | Table 7: Initial QUIC Transport Parameters Entries | |||
| 13.2. QUIC Frame Type Registry | 22.2. QUIC Frame Type Registry | |||
| IANA [SHALL add/has added] a registry for "QUIC Frame Types" under a | IANA [SHALL add/has added] a registry for "QUIC Frame Types" under a | |||
| "QUIC Protocol" heading. | "QUIC Protocol" heading. | |||
| The "QUIC Frame Types" registry governs a 62-bit space. This space | The "QUIC Frame Types" registry governs a 62-bit space. This space | |||
| is split into three spaces that are governed by different policies. | is split into three spaces that are governed by different policies. | |||
| Values between 0x00 and 0x3f (in hexadecimal) are assigned via the | Values between 0x00 and 0x3f (in hexadecimal) are assigned via the | |||
| Standards Action or IESG Review policies [RFC8126]. Values from 0x40 | Standards Action or IESG Review policies [RFC8126]. Values from 0x40 | |||
| to 0x3fff operate on the Specification Required policy [RFC8126]. | to 0x3fff operate on the Specification Required policy [RFC8126]. | |||
| All other values are assigned to Private Use [RFC8126]. | All other values are assigned to Private Use [RFC8126]. | |||
| skipping to change at page 117, line 17 ¶ | skipping to change at page 118, line 17 ¶ | |||
| Frame Name: A short mnemonic for the frame type. | Frame Name: A short mnemonic for the frame type. | |||
| Specification: A reference to a publicly available specification for | Specification: A reference to a publicly available specification for | |||
| the value. | the value. | |||
| The nominated expert(s) verify that a specification exists and is | The nominated expert(s) verify that a specification exists and is | |||
| readily accessible. Specifications for new registrations need to | readily accessible. Specifications for new registrations need to | |||
| describe the means by which an endpoint might determine that it can | describe the means by which an endpoint might determine that it can | |||
| send the identified type of frame. An accompanying transport | send the identified type of frame. An accompanying transport | |||
| parameter registration (see Section 13.1) is expected for most | parameter registration (see Section 22.1) is expected for most | |||
| registrations. The specification needs to describe the format and | registrations. The specification needs to describe the format and | |||
| assigned semantics of any fields in the frame. | assigned semantics of any fields in the frame. | |||
| Expert(s) are encouraged to be biased towards approving registrations | Expert(s) are encouraged to be biased towards approving registrations | |||
| unless they are abusive, frivolous, or actively harmful (not merely | unless they are abusive, frivolous, or actively harmful (not merely | |||
| aesthetically displeasing, or architecturally dubious). | aesthetically displeasing, or architecturally dubious). | |||
| The initial contents of this registry are tabulated in Table 3. | The initial contents of this registry are tabulated in Table 3. | |||
| 13.3. QUIC Transport Error Codes Registry | 22.3. QUIC Transport Error Codes Registry | |||
| IANA [SHALL add/has added] a registry for "QUIC Transport Error | IANA [SHALL add/has added] a registry for "QUIC Transport Error | |||
| Codes" under a "QUIC Protocol" heading. | Codes" under a "QUIC Protocol" heading. | |||
| The "QUIC Transport Error Codes" registry governs a 16-bit space. | The "QUIC Transport Error Codes" registry governs a 16-bit space. | |||
| This space is split into two spaces that are governed by different | This space is split into two spaces that are governed by different | |||
| policies. Values with the first byte in the range 0x00 to 0xfe (in | policies. Values with the first byte in the range 0x00 to 0xfe (in | |||
| hexadecimal) are assigned via the Specification Required policy | hexadecimal) are assigned via the Specification Required policy | |||
| [RFC8126]. Values with the first byte 0xff are reserved for Private | [RFC8126]. Values with the first byte 0xff are reserved for Private | |||
| Use [RFC8126]. | Use [RFC8126]. | |||
| skipping to change at page 119, line 9 ¶ | skipping to change at page 120, line 9 ¶ | |||
| Specification: A reference to a publicly available specification for | Specification: A reference to a publicly available specification for | |||
| the value. | the value. | |||
| The initial contents of this registry are shown in Table 8. Values | The initial contents of this registry are shown in Table 8. Values | |||
| from 0xFF00 to 0xFFFF are reserved for Private Use [RFC8126]. | from 0xFF00 to 0xFFFF are reserved for Private Use [RFC8126]. | |||
| +------+---------------------------+----------------+---------------+ | +------+---------------------------+----------------+---------------+ | |||
| | Valu | Error | Description | Specification | | | Valu | Error | Description | Specification | | |||
| | e | | | | | | e | | | | | |||
| +------+---------------------------+----------------+---------------+ | +------+---------------------------+----------------+---------------+ | |||
| | 0x0 | NO_ERROR | No error | Section 11.3 | | | 0x0 | NO_ERROR | No error | Section 20 | | |||
| | | | | | | | | | | | | |||
| | 0x1 | INTERNAL_ERROR | Implementation | Section 11.3 | | | 0x1 | INTERNAL_ERROR | Implementation | Section 20 | | |||
| | | | error | | | | | | error | | | |||
| | | | | | | | | | | | | |||
| | 0x2 | SERVER_BUSY | Server | Section 11.3 | | | 0x2 | SERVER_BUSY | Server | Section 20 | | |||
| | | | currently busy | | | | | | currently busy | | | |||
| | | | | | | | | | | | | |||
| | 0x3 | FLOW_CONTROL_ERROR | Flow control | Section 11.3 | | | 0x3 | FLOW_CONTROL_ERROR | Flow control | Section 20 | | |||
| | | | error | | | | | | error | | | |||
| | | | | | | | | | | | | |||
| | 0x4 | STREAM_ID_ERROR | Invalid stream | Section 11.3 | | | 0x4 | STREAM_ID_ERROR | Invalid stream | Section 20 | | |||
| | | | ID | | | | | | ID | | | |||
| | | | | | | | | | | | | |||
| | 0x5 | STREAM_STATE_ERROR | Frame received | Section 11.3 | | | 0x5 | STREAM_STATE_ERROR | Frame received | Section 20 | | |||
| | | | in invalid | | | | | | in invalid | | | |||
| | | | stream state | | | | | | stream state | | | |||
| | | | | | | | | | | | | |||
| | 0x6 | FINAL_OFFSET_ERROR | Change to | Section 11.3 | | | 0x6 | FINAL_OFFSET_ERROR | Change to | Section 20 | | |||
| | | | final stream | | | | | | final stream | | | |||
| | | | offset | | | | | | offset | | | |||
| | | | | | | | | | | | | |||
| | 0x7 | FRAME_ENCODING_ERROR | Frame encoding | Section 11.3 | | | 0x7 | FRAME_ENCODING_ERROR | Frame encoding | Section 20 | | |||
| | | | error | | | | | | error | | | |||
| | | | | | | | | | | | | |||
| | 0x8 | TRANSPORT_PARAMETER_ERROR | Error in | Section 11.3 | | | 0x8 | TRANSPORT_PARAMETER_ERROR | Error in | Section 20 | | |||
| | | | transport | | | | | | transport | | | |||
| | | | parameters | | | | | | parameters | | | |||
| | | | | | | | | | | | | |||
| | 0x9 | VERSION_NEGOTIATION_ERROR | Version | Section 11.3 | | | 0x9 | VERSION_NEGOTIATION_ERROR | Version | Section 20 | | |||
| | | | negotiation | | | | | | negotiation | | | |||
| | | | failure | | | | | | failure | | | |||
| | | | | | | | | | | | | |||
| | 0xA | PROTOCOL_VIOLATION | Generic | Section 11.3 | | | 0xA | PROTOCOL_VIOLATION | Generic | Section 20 | | |||
| | | | protocol | | | | | | protocol | | | |||
| | | | violation | | | | | | violation | | | |||
| | | | | | | | | | | | | |||
| | 0xC | INVALID_MIGRATION | Violated | Section 11.3 | | | 0xC | INVALID_MIGRATION | Violated | Section 20 | | |||
| | | | disabled | | | | | | disabled | | | |||
| | | | migration | | | | | | migration | | | |||
| +------+---------------------------+----------------+---------------+ | +------+---------------------------+----------------+---------------+ | |||
| Table 8: Initial QUIC Transport Error Codes Entries | Table 8: Initial QUIC Transport Error Codes Entries | |||
| 14. References | 23. References | |||
| 14.1. Normative References | 23.1. Normative References | |||
| [PLPMTUD] Mathis, M. and J. Heffner, "Packetization Layer Path MTU | [PLPMTUD] Mathis, M. and J. Heffner, "Packetization Layer Path MTU | |||
| Discovery", RFC 4821, DOI 10.17487/RFC4821, March 2007, | Discovery", RFC 4821, DOI 10.17487/RFC4821, March 2007, | |||
| <https://www.rfc-editor.org/info/rfc4821>. | <https://www.rfc-editor.org/info/rfc4821>. | |||
| [PMTUDv4] Mogul, J. and S. Deering, "Path MTU discovery", RFC 1191, | [PMTUDv4] Mogul, J. and S. Deering, "Path MTU discovery", RFC 1191, | |||
| DOI 10.17487/RFC1191, November 1990, | DOI 10.17487/RFC1191, November 1990, | |||
| <https://www.rfc-editor.org/info/rfc1191>. | <https://www.rfc-editor.org/info/rfc1191>. | |||
| [PMTUDv6] McCann, J., Deering, S., Mogul, J., and R. Hinden, Ed., | [PMTUDv6] McCann, J., Deering, S., Mogul, J., and R. Hinden, Ed., | |||
| "Path MTU Discovery for IP version 6", STD 87, RFC 8201, | "Path MTU Discovery for IP version 6", STD 87, RFC 8201, | |||
| DOI 10.17487/RFC8201, July 2017, | DOI 10.17487/RFC8201, July 2017, | |||
| <https://www.rfc-editor.org/info/rfc8201>. | <https://www.rfc-editor.org/info/rfc8201>. | |||
| [QUIC-RECOVERY] | [QUIC-RECOVERY] | |||
| Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection | Iyengar, J., Ed. and I. Swett, Ed., "QUIC Loss Detection | |||
| and Congestion Control", draft-ietf-quic-recovery-15 (work | and Congestion Control", draft-ietf-quic-recovery-16 (work | |||
| in progress), October 2018. | in progress), October 2018. | |||
| [QUIC-TLS] | [QUIC-TLS] | |||
| Thomson, M., Ed. and S. Turner, Ed., "Using Transport | Thomson, M., Ed. and S. Turner, Ed., "Using Transport | |||
| Layer Security (TLS) to Secure QUIC", draft-ietf-quic- | Layer Security (TLS) to Secure QUIC", draft-ietf-quic- | |||
| tls-15 (work in progress), October 2018. | tls-16 (work in progress), October 2018. | |||
| [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/info/rfc2119>. | |||
| [RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition | [RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition | |||
| of Explicit Congestion Notification (ECN) to IP", | of Explicit Congestion Notification (ECN) to IP", | |||
| RFC 3168, DOI 10.17487/RFC3168, September 2001, | RFC 3168, DOI 10.17487/RFC3168, September 2001, | |||
| <https://www.rfc-editor.org/info/rfc3168>. | <https://www.rfc-editor.org/info/rfc3168>. | |||
| [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO | [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO | |||
| 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November | 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November | |||
| 2003, <https://www.rfc-editor.org/info/rfc3629>. | 2003, <https://www.rfc-editor.org/info/rfc3629>. | |||
| [RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker, | [RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker, | |||
| "Randomness Requirements for Security", BCP 106, RFC 4086, | "Randomness Requirements for Security", BCP 106, RFC 4086, | |||
| DOI 10.17487/RFC4086, June 2005, | DOI 10.17487/RFC4086, June 2005, | |||
| <https://www.rfc-editor.org/info/rfc4086>. | <https://www.rfc-editor.org/info/rfc4086>. | |||
| [RFC5119] Edwards, T., "A Uniform Resource Name (URN) Namespace for | ||||
| the Society of Motion Picture and Television Engineers | ||||
| (SMPTE)", RFC 5119, DOI 10.17487/RFC5119, February 2008, | ||||
| <https://www.rfc-editor.org/info/rfc5119>. | ||||
| [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for | [RFC8126] 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/info/rfc8126>. | |||
| [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/info/rfc8174>. | |||
| [RFC8311] Black, D., "Relaxing Restrictions on Explicit Congestion | [RFC8311] Black, D., "Relaxing Restrictions on Explicit Congestion | |||
| Notification (ECN) Experimentation", RFC 8311, | Notification (ECN) Experimentation", RFC 8311, | |||
| DOI 10.17487/RFC8311, January 2018, | DOI 10.17487/RFC8311, January 2018, | |||
| <https://www.rfc-editor.org/info/rfc8311>. | <https://www.rfc-editor.org/info/rfc8311>. | |||
| [TLS13] Rescorla, E., "The Transport Layer Security (TLS) Protocol | [TLS13] Rescorla, E., "The Transport Layer Security (TLS) Protocol | |||
| Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | |||
| <https://www.rfc-editor.org/info/rfc8446>. | <https://www.rfc-editor.org/info/rfc8446>. | |||
| 14.2. Informative References | 23.2. Informative References | |||
| [EARLY-DESIGN] | [EARLY-DESIGN] | |||
| Roskind, J., "QUIC: Multiplexed Transport Over UDP", | Roskind, J., "QUIC: Multiplexed Transport Over UDP", | |||
| December 2013, <https://goo.gl/dMVtFi>. | December 2013, <https://goo.gl/dMVtFi>. | |||
| [HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | [HTTP2] 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>. | |||
| skipping to change at page 123, line 37 ¶ | skipping to change at page 124, line 37 ¶ | |||
| return candidate_pn - pn_win | return candidate_pn - pn_win | |||
| return candidate_pn | return candidate_pn | |||
| Appendix B. Change Log | Appendix B. Change Log | |||
| *RFC Editor's Note:* Please remove this section prior to | *RFC Editor's Note:* Please remove this section prior to | |||
| publication of a final version of this document. | publication of a final version of this document. | |||
| Issue and pull request numbers are listed with a leading octothorp. | Issue and pull request numbers are listed with a leading octothorp. | |||
| B.1. Since draft-ietf-quic-transport-14 | B.1. Since draft-ietf-quic-transport-15 | |||
| Substantial editorial reorganization; no technical changes. | ||||
| B.2. Since draft-ietf-quic-transport-14 | ||||
| o Merge ACK and ACK_ECN (#1778, #1801) | o Merge ACK and ACK_ECN (#1778, #1801) | |||
| o Explicitly communicate max_ack_delay (#981, #1781) | o Explicitly communicate max_ack_delay (#981, #1781) | |||
| o Validate original connection ID after Retry packets (#1710, #1486, | o Validate original connection ID after Retry packets (#1710, #1486, | |||
| #1793) | #1793) | |||
| o Idle timeout is optional and has no specified maximum (#1520, | o Idle timeout is optional and has no specified maximum (#1765) | |||
| #1521) | ||||
| o Update connection ID handling; add RETIRE_CONNECTION_ID type | o Update connection ID handling; add RETIRE_CONNECTION_ID type | |||
| (#1464, #1468, #1483, #1484, #1486, #1495, #1729, #1742, #1799, | (#1464, #1468, #1483, #1484, #1486, #1495, #1729, #1742, #1799, | |||
| #1821) | #1821) | |||
| o Include a Token in all Initial packets (#1649, #1794) | o Include a Token in all Initial packets (#1649, #1794) | |||
| o Prevent handshake deadlock (#1764, #1824) | o Prevent handshake deadlock (#1764, #1824) | |||
| B.2. Since draft-ietf-quic-transport-13 | B.3. Since draft-ietf-quic-transport-13 | |||
| o Streams open when higher-numbered streams of the same type open | o Streams open when higher-numbered streams of the same type open | |||
| (#1342, #1549) | (#1342, #1549) | |||
| o Split initial stream flow control limit into 3 transport | o Split initial stream flow control limit into 3 transport | |||
| parameters (#1016, #1542) | parameters (#1016, #1542) | |||
| o All flow control transport parameters are optional (#1610) | o All flow control transport parameters are optional (#1610) | |||
| o Removed UNSOLICITED_PATH_RESPONSE error code (#1265, #1539) | o Removed UNSOLICITED_PATH_RESPONSE error code (#1265, #1539) | |||
| skipping to change at page 124, line 47 ¶ | skipping to change at page 126, line 5 ¶ | |||
| o Permit 0-RTT after receiving Version Negotiation or Retry (#1507, | o Permit 0-RTT after receiving Version Negotiation or Retry (#1507, | |||
| #1514, #1621) | #1514, #1621) | |||
| o Permit Retry in response to 0-RTT (#1547, #1552) | o Permit Retry in response to 0-RTT (#1547, #1552) | |||
| o Looser verification of ECN counters to account for ACK loss | o Looser verification of ECN counters to account for ACK loss | |||
| (#1555, #1481, #1565) | (#1555, #1481, #1565) | |||
| o Remove frame type field from APPLICATION_CLOSE (#1508, #1528) | o Remove frame type field from APPLICATION_CLOSE (#1508, #1528) | |||
| B.3. Since draft-ietf-quic-transport-12 | B.4. Since draft-ietf-quic-transport-12 | |||
| o Changes to integration of the TLS handshake (#829, #1018, #1094, | o Changes to integration of the TLS handshake (#829, #1018, #1094, | |||
| #1165, #1190, #1233, #1242, #1252, #1450, #1458) | #1165, #1190, #1233, #1242, #1252, #1450, #1458) | |||
| * The cryptographic handshake uses CRYPTO frames, not stream 0 | * The cryptographic handshake uses CRYPTO frames, not stream 0 | |||
| * QUIC packet protection is used in place of TLS record | * QUIC packet protection is used in place of TLS record | |||
| protection | protection | |||
| * Separate QUIC packet number spaces are used for the handshake | * Separate QUIC packet number spaces are used for the handshake | |||
| * Changed Retry to be independent of the cryptographic handshake | * Changed Retry to be independent of the cryptographic handshake | |||
| * Added NEW_TOKEN frame and Token fields to Initial packet | * Added NEW_TOKEN frame and Token fields to Initial packet | |||
| * Limit the use of HelloRetryRequest to address TLS needs (like | * Limit the use of HelloRetryRequest to address TLS needs (like | |||
| skipping to change at page 125, line 40 ¶ | skipping to change at page 126, line 48 ¶ | |||
| o Fixed sampling method for packet number encryption; the length | o Fixed sampling method for packet number encryption; the length | |||
| field in long headers includes the packet number field in addition | field in long headers includes the packet number field in addition | |||
| to the packet payload (#1387, #1389) | to the packet payload (#1387, #1389) | |||
| o Stateless Reset is now symmetric and subject to size constraints | o Stateless Reset is now symmetric and subject to size constraints | |||
| (#466, #1346) | (#466, #1346) | |||
| o Added frame type extension mechanism (#58, #1473) | o Added frame type extension mechanism (#58, #1473) | |||
| B.4. Since draft-ietf-quic-transport-11 | B.5. Since draft-ietf-quic-transport-11 | |||
| o Enable server to transition connections to a preferred address | o Enable server to transition connections to a preferred address | |||
| (#560, #1251) | (#560, #1251) | |||
| o Packet numbers are encrypted (#1174, #1043, #1048, #1034, #850, | o Packet numbers are encrypted (#1174, #1043, #1048, #1034, #850, | |||
| #990, #734, #1317, #1267, #1079) | #990, #734, #1317, #1267, #1079) | |||
| o Packet numbers use a variable-length encoding (#989, #1334) | o Packet numbers use a variable-length encoding (#989, #1334) | |||
| o STREAM frames can now be empty (#1350) | o STREAM frames can now be empty (#1350) | |||
| B.5. Since draft-ietf-quic-transport-10 | B.6. Since draft-ietf-quic-transport-10 | |||
| o Swap payload length and packed number fields in long header | o Swap payload length and packed number fields in long header | |||
| (#1294) | (#1294) | |||
| o Clarified that CONNECTION_CLOSE is allowed in Handshake packet | o Clarified that CONNECTION_CLOSE is allowed in Handshake packet | |||
| (#1274) | (#1274) | |||
| o Spin bit reserved (#1283) | o Spin bit reserved (#1283) | |||
| o Coalescing multiple QUIC packets in a UDP datagram (#1262, #1285) | o Coalescing multiple QUIC packets in a UDP datagram (#1262, #1285) | |||
| skipping to change at page 126, line 41 ¶ | skipping to change at page 127, line 48 ¶ | |||
| o STOP_SENDING is now prohibited before streams are used (#1050) | o STOP_SENDING is now prohibited before streams are used (#1050) | |||
| o Recommend including ACK in Retry packets and allow PADDING (#1067, | o Recommend including ACK in Retry packets and allow PADDING (#1067, | |||
| #882) | #882) | |||
| o Endpoints now become closing after an idle timeout (#1178, #1179) | o Endpoints now become closing after an idle timeout (#1178, #1179) | |||
| o Remove implication that Version Negotiation is sent when a packet | o Remove implication that Version Negotiation is sent when a packet | |||
| of the wrong version is received (#1197) | of the wrong version is received (#1197) | |||
| B.6. Since draft-ietf-quic-transport-09 | B.7. Since draft-ietf-quic-transport-09 | |||
| o Added PATH_CHALLENGE and PATH_RESPONSE frames to replace PING with | o Added PATH_CHALLENGE and PATH_RESPONSE frames to replace PING with | |||
| Data and PONG frame. Changed ACK frame type from 0x0e to 0x0d. | Data and PONG frame. Changed ACK frame type from 0x0e to 0x0d. | |||
| (#1091, #725, #1086) | (#1091, #725, #1086) | |||
| o A server can now only send 3 packets without validating the client | o A server can now only send 3 packets without validating the client | |||
| address (#38, #1090) | address (#38, #1090) | |||
| o Delivery order of stream data is no longer strongly specified | o Delivery order of stream data is no longer strongly specified | |||
| (#252, #1070) | (#252, #1070) | |||
| skipping to change at page 127, line 20 ¶ | skipping to change at page 128, line 26 ¶ | |||
| o Improved retransmission rules for all frame types: information is | o Improved retransmission rules for all frame types: information is | |||
| retransmitted, not packets or frames (#463, #765, #1095, #1053) | retransmitted, not packets or frames (#463, #765, #1095, #1053) | |||
| o Added an error code for server busy signals (#1137) | o Added an error code for server busy signals (#1137) | |||
| o Endpoints now set the connection ID that their peer uses. | o Endpoints now set the connection ID that their peer uses. | |||
| Connection IDs are variable length. Removed the | Connection IDs are variable length. Removed the | |||
| omit_connection_id transport parameter and the corresponding short | omit_connection_id transport parameter and the corresponding short | |||
| header flag. (#1089, #1052, #1146, #821, #745, #821, #1166, #1151) | header flag. (#1089, #1052, #1146, #821, #745, #821, #1166, #1151) | |||
| B.7. Since draft-ietf-quic-transport-08 | B.8. Since draft-ietf-quic-transport-08 | |||
| o Clarified requirements for BLOCKED usage (#65, #924) | o Clarified requirements for BLOCKED usage (#65, #924) | |||
| o BLOCKED frame now includes reason for blocking (#452, #924, #927, | o BLOCKED frame now includes reason for blocking (#452, #924, #927, | |||
| #928) | #928) | |||
| o GAP limitation in ACK Frame (#613) | o GAP limitation in ACK Frame (#613) | |||
| o Improved PMTUD description (#614, #1036) | o Improved PMTUD description (#614, #1036) | |||
| skipping to change at page 127, line 48 ¶ | skipping to change at page 129, line 5 ¶ | |||
| o Stateless reset clarified as version-specific (#930, #986) | o Stateless reset clarified as version-specific (#930, #986) | |||
| o initial_max_stream_id_x transport parameters are optional (#970, | o initial_max_stream_id_x transport parameters are optional (#970, | |||
| #971) | #971) | |||
| o Ack Delay assumes a default value during the handshake (#1007, | o Ack Delay assumes a default value during the handshake (#1007, | |||
| #1009) | #1009) | |||
| o Removed transport parameters from NewSessionTicket (#1015) | o Removed transport parameters from NewSessionTicket (#1015) | |||
| B.8. Since draft-ietf-quic-transport-07 | B.9. Since draft-ietf-quic-transport-07 | |||
| o The long header now has version before packet number (#926, #939) | o The long header now has version before packet number (#926, #939) | |||
| o Rename and consolidate packet types (#846, #822, #847) | o Rename and consolidate packet types (#846, #822, #847) | |||
| o Packet types are assigned new codepoints and the Connection ID | o Packet types are assigned new codepoints and the Connection ID | |||
| Flag is inverted (#426, #956) | Flag is inverted (#426, #956) | |||
| o Removed type for Version Negotiation and use Version 0 (#963, | o Removed type for Version Negotiation and use Version 0 (#963, | |||
| #968) | #968) | |||
| o Streams are split into unidirectional and bidirectional (#643, | o Streams are split into unidirectional and bidirectional (#643, | |||
| #656, #720, #872, #175, #885) | #656, #720, #872, #175, #885) | |||
| * Stream limits now have separate uni- and bi-directional | * Stream limits now have separate uni- and bi-directional | |||
| skipping to change at page 128, line 42 ¶ | skipping to change at page 130, line 5 ¶ | |||
| o Address validation for connection migration (#161, #732, #878) | o Address validation for connection migration (#161, #732, #878) | |||
| o Clearly defined retransmission rules for BLOCKED (#452, #65, #924) | o Clearly defined retransmission rules for BLOCKED (#452, #65, #924) | |||
| o negotiated_version is sent in server transport parameters (#710, | o negotiated_version is sent in server transport parameters (#710, | |||
| #959) | #959) | |||
| o Increased the range over which packet numbers are randomized | o Increased the range over which packet numbers are randomized | |||
| (#864, #850, #964) | (#864, #850, #964) | |||
| B.9. Since draft-ietf-quic-transport-06 | B.10. Since draft-ietf-quic-transport-06 | |||
| o Replaced FNV-1a with AES-GCM for all "Cleartext" packets (#554) | o Replaced FNV-1a with AES-GCM for all "Cleartext" packets (#554) | |||
| o Split error code space between application and transport (#485) | o Split error code space between application and transport (#485) | |||
| o Stateless reset token moved to end (#820) | o Stateless reset token moved to end (#820) | |||
| o 1-RTT-protected long header types removed (#848) | o 1-RTT-protected long header types removed (#848) | |||
| o No acknowledgments during draining period (#852) | o No acknowledgments during draining period (#852) | |||
| o Remove "application close" as a separate close type (#854) | o Remove "application close" as a separate close type (#854) | |||
| o Remove timestamps from the ACK frame (#841) | o Remove timestamps from the ACK frame (#841) | |||
| o Require transport parameters to only appear once (#792) | o Require transport parameters to only appear once (#792) | |||
| B.10. Since draft-ietf-quic-transport-05 | B.11. Since draft-ietf-quic-transport-05 | |||
| o Stateless token is server-only (#726) | o Stateless token is server-only (#726) | |||
| o Refactor section on connection termination (#733, #748, #328, | o Refactor section on connection termination (#733, #748, #328, | |||
| #177) | #177) | |||
| o Limit size of Version Negotiation packet (#585) | o Limit size of Version Negotiation packet (#585) | |||
| o Clarify when and what to ack (#736) | o Clarify when and what to ack (#736) | |||
| o Renamed STREAM_ID_NEEDED to STREAM_ID_BLOCKED | o Renamed STREAM_ID_NEEDED to STREAM_ID_BLOCKED | |||
| o Clarify Keep-alive requirements (#729) | o Clarify Keep-alive requirements (#729) | |||
| B.11. Since draft-ietf-quic-transport-04 | B.12. Since draft-ietf-quic-transport-04 | |||
| o Introduce STOP_SENDING frame, RST_STREAM only resets in one | o Introduce STOP_SENDING frame, RST_STREAM only resets in one | |||
| direction (#165) | direction (#165) | |||
| o Removed GOAWAY; application protocols are responsible for graceful | o Removed GOAWAY; application protocols are responsible for graceful | |||
| shutdown (#696) | shutdown (#696) | |||
| o Reduced the number of error codes (#96, #177, #184, #211) | o Reduced the number of error codes (#96, #177, #184, #211) | |||
| o Version validation fields can't move or change (#121) | o Version validation fields can't move or change (#121) | |||
| skipping to change at page 130, line 4 ¶ | skipping to change at page 131, line 13 ¶ | |||
| NewSessionTicket message (#547) | NewSessionTicket message (#547) | |||
| o Clarify the meaning of "bytes in flight" (#550) | o Clarify the meaning of "bytes in flight" (#550) | |||
| o Public reset is now stateless reset and not visible to the path | o Public reset is now stateless reset and not visible to the path | |||
| (#215) | (#215) | |||
| o Reordered bits and fields in STREAM frame (#620) | o Reordered bits and fields in STREAM frame (#620) | |||
| o Clarifications to the stream state machine (#572, #571) | o Clarifications to the stream state machine (#572, #571) | |||
| o Increased the maximum length of the Largest Acknowledged field in | o Increased the maximum length of the Largest Acknowledged field in | |||
| ACK frames to 64 bits (#629) | ACK frames to 64 bits (#629) | |||
| o truncate_connection_id is renamed to omit_connection_id (#659) | o truncate_connection_id is renamed to omit_connection_id (#659) | |||
| o CONNECTION_CLOSE terminates the connection like TCP RST (#330, | o CONNECTION_CLOSE terminates the connection like TCP RST (#330, | |||
| #328) | #328) | |||
| o Update labels used in HKDF-Expand-Label to match TLS 1.3 (#642) | o Update labels used in HKDF-Expand-Label to match TLS 1.3 (#642) | |||
| B.12. Since draft-ietf-quic-transport-03 | B.13. Since draft-ietf-quic-transport-03 | |||
| o Change STREAM and RST_STREAM layout | o Change STREAM and RST_STREAM layout | |||
| o Add MAX_STREAM_ID settings | o Add MAX_STREAM_ID settings | |||
| B.13. Since draft-ietf-quic-transport-02 | B.14. Since draft-ietf-quic-transport-02 | |||
| o The size of the initial packet payload has a fixed minimum (#267, | o The size of the initial packet payload has a fixed minimum (#267, | |||
| #472) | #472) | |||
| o Define when Version Negotiation packets are ignored (#284, #294, | o Define when Version Negotiation packets are ignored (#284, #294, | |||
| #241, #143, #474) | #241, #143, #474) | |||
| o The 64-bit FNV-1a algorithm is used for integrity protection of | o The 64-bit FNV-1a algorithm is used for integrity protection of | |||
| unprotected packets (#167, #480, #481, #517) | unprotected packets (#167, #480, #481, #517) | |||
| skipping to change at page 131, line 4 ¶ | skipping to change at page 132, line 13 ¶ | |||
| different handshake protocol (#516) | different handshake protocol (#516) | |||
| o STREAM frames have a reduced number of offset lengths (#543, #430) | o STREAM frames have a reduced number of offset lengths (#543, #430) | |||
| o Split some frames into separate connection- and stream- level | o Split some frames into separate connection- and stream- level | |||
| frames (#443) | frames (#443) | |||
| * WINDOW_UPDATE split into MAX_DATA and MAX_STREAM_DATA (#450) | * WINDOW_UPDATE split into MAX_DATA and MAX_STREAM_DATA (#450) | |||
| * BLOCKED split to match WINDOW_UPDATE split (#454) | * BLOCKED split to match WINDOW_UPDATE split (#454) | |||
| * Define STREAM_ID_NEEDED frame (#455) | * Define STREAM_ID_NEEDED frame (#455) | |||
| o A NEW_CONNECTION_ID frame supports connection migration without | o A NEW_CONNECTION_ID frame supports connection migration without | |||
| linkability (#232, #491, #496) | linkability (#232, #491, #496) | |||
| o Transport parameters for 0-RTT are retained from a previous | o Transport parameters for 0-RTT are retained from a previous | |||
| connection (#405, #513, #512) | connection (#405, #513, #512) | |||
| * A client in 0-RTT no longer required to reset excess streams | * A client in 0-RTT no longer required to reset excess streams | |||
| (#425, #479) | (#425, #479) | |||
| o Expanded security considerations (#440, #444, #445, #448) | o Expanded security considerations (#440, #444, #445, #448) | |||
| B.14. Since draft-ietf-quic-transport-01 | B.15. Since draft-ietf-quic-transport-01 | |||
| o Defined short and long packet headers (#40, #148, #361) | o Defined short and long packet headers (#40, #148, #361) | |||
| o Defined a versioning scheme and stable fields (#51, #361) | o Defined a versioning scheme and stable fields (#51, #361) | |||
| o Define reserved version values for "greasing" negotiation (#112, | o Define reserved version values for "greasing" negotiation (#112, | |||
| #278) | #278) | |||
| o The initial packet number is randomized (#35, #283) | o The initial packet number is randomized (#35, #283) | |||
| skipping to change at page 133, line 17 ¶ | skipping to change at page 134, line 25 ¶ | |||
| o Remove error code and reason phrase from GOAWAY (#352, #355) | o Remove error code and reason phrase from GOAWAY (#352, #355) | |||
| o GOAWAY includes a final stream number for both directions (#347) | o GOAWAY includes a final stream number for both directions (#347) | |||
| o Error codes for RST_STREAM and CONNECTION_CLOSE are now at a | o Error codes for RST_STREAM and CONNECTION_CLOSE are now at a | |||
| consistent offset (#249) | consistent offset (#249) | |||
| o Defined priority as the responsibility of the application protocol | o Defined priority as the responsibility of the application protocol | |||
| (#104, #303) | (#104, #303) | |||
| B.15. Since draft-ietf-quic-transport-00 | B.16. Since draft-ietf-quic-transport-00 | |||
| o Replaced DIVERSIFICATION_NONCE flag with KEY_PHASE flag | o Replaced DIVERSIFICATION_NONCE flag with KEY_PHASE flag | |||
| o Defined versioning | o Defined versioning | |||
| o Reworked description of packet and frame layout | o Reworked description of packet and frame layout | |||
| o Error code space is divided into regions for each component | o Error code space is divided into regions for each component | |||
| o Use big endian for all numeric values | o Use big endian for all numeric values | |||
| B.16. Since draft-hamilton-quic-transport-protocol-01 | B.17. Since draft-hamilton-quic-transport-protocol-01 | |||
| o Adopted as base for draft-ietf-quic-tls | o Adopted as base for draft-ietf-quic-tls | |||
| o Updated authors/editors list | o Updated authors/editors list | |||
| o Added IANA Considerations section | o Added IANA Considerations section | |||
| o Moved Contributors and Acknowledgments to appendices | o Moved Contributors and Acknowledgments to appendices | |||
| Acknowledgments | Acknowledgments | |||
| End of changes. 450 change blocks. | ||||
| 2922 lines changed or deleted | 3012 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||