0%

quicrfc

quic协议和翻译: QUIC: A UDP-Based Multiplexed and Secure Transport

1
2
3
4
5
6
Internet Engineering Task Force (IETF)                   J. Iyengar, Ed.
Request for Comments: 9000 Fastly
Category: Standards Track M. Thomson, Ed.
ISSN: 2070-1721 Mozilla
May 2021

       QUIC: A UDP-Based Multiplexed and Secure Transport  

Abstract

This document defines the core of the QUIC transport protocol. QUIC
provides applications with flow-controlled streams for structured
communication, low-latency connection establishment, and network path
migration. QUIC includes security measures that ensure
confidentiality, integrity, and availability in a range of deployment
circumstances. Accompanying documents describe the integration of
TLS for key negotiation, loss detection, and an exemplary congestion
control algorithm.
本文档定义了 QUIC 传输协议的核心。
QUIC 为应用程序提供流控流,用于结构化通信、低延迟连接建立和网络路径迁移。
QUIC 包括在一系列部署环境中确保机密性、完整性和可用性的安全措施。
随附的文件描述了用于密钥协商、丢失检测和示例性拥塞控制算法的 TLS 集成。

Status of This Memo

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force
(IETF). It represents the consensus of the IETF community. It has
received public review and has been approved for publication by the
Internet Engineering Steering Group (IESG). Further information on
Internet Standards is available in Section 2 of RFC 7841.

Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
https://www.rfc-editor.org/info/rfc9000.

Copyright (c) 2021 IETF Trust and the persons identified as the
document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust’s Legal
Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.

Table of Contents

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
1.  Overview
1.1. Document Structure
1.2. Terms and Definitions
1.3. Notational Conventions
2. Streams
2.1. Stream Types and Identifiers
2.2. Sending and Receiving Data
2.3. Stream Prioritization
2.4. Operations on Streams
3. Stream States
3.1. Sending Stream States
3.2. Receiving Stream States
3.3. Permitted Frame Types
3.4. Bidirectional Stream States
3.5. Solicited State Transitions
4. Flow Control
4.1. Data Flow Control
4.2. Increasing Flow Control Limits
4.3. Flow Control Performance
4.4. Handling Stream Cancellation
4.5. Stream Final Size
4.6. Controlling Concurrency
5. Connections
5.1. Connection ID
5.1.1. Issuing Connection IDs
5.1.2. Consuming and Retiring Connection IDs
5.2. Matching Packets to Connections
5.2.1. Client Packet Handling
5.2.2. Server Packet Handling
5.2.3. Considerations for Simple Load Balancers
5.3. Operations on Connections
6. Version Negotiation
6.1. Sending Version Negotiation Packets
6.2. Handling Version Negotiation Packets
6.3. Using Reserved Versions
7. Cryptographic and Transport Handshake
7.1. Example Handshake Flows
7.2. Negotiating Connection IDs
7.3. Authenticating Connection IDs
7.4. Transport Parameters
7.4.1. Values of Transport Parameters for 0-RTT
7.4.2. New Transport Parameters
7.5. Cryptographic Message Buffering
8. Address Validation
8.1. Address Validation during Connection Establishment
8.1.1. Token Construction
8.1.2. Address Validation Using Retry Packets
8.1.3. Address Validation for Future Connections
8.1.4. Address Validation Token Integrity
8.2. Path Validation
8.2.1. Initiating Path Validation
8.2.2. Path Validation Responses
8.2.3. Successful Path Validation
8.2.4. Failed Path Validation
9. Connection Migration
9.1. Probing a New Path
9.2. Initiating Connection Migration
9.3. Responding to Connection Migration
9.3.1. Peer Address Spoofing
9.3.2. On-Path Address Spoofing
9.3.3. Off-Path Packet Forwarding
9.4. Loss Detection and Congestion Control
9.5. Privacy Implications of Connection Migration
9.6. Server's Preferred Address
9.6.1. Communicating a Preferred Address
9.6.2. Migration to a Preferred Address
9.6.3. Interaction of Client Migration and Preferred Address
9.7. Use of IPv6 Flow Label and Migration
10. Connection Termination
10.1. Idle Timeout
10.1.1. Liveness Testing
10.1.2. Deferring Idle Timeout
10.2. Immediate Close
10.2.1. Closing Connection State
10.2.2. Draining Connection State
10.2.3. Immediate Close during the Handshake
10.3. Stateless Reset
10.3.1. Detecting a Stateless Reset
10.3.2. Calculating a Stateless Reset Token
10.3.3. Looping
11. Error Handling
11.1. Connection Errors
11.2. Stream Errors
12. Packets and Frames
12.1. Protected Packets
12.2. Coalescing Packets
12.3. Packet Numbers
12.4. Frames and Frame Types
12.5. Frames and Number Spaces
13. Packetization and Reliability
13.1. Packet Processing
13.2. Generating Acknowledgments
13.2.1. Sending ACK Frames
13.2.2. Acknowledgment Frequency
13.2.3. Managing ACK Ranges
13.2.4. Limiting Ranges by Tracking ACK Frames
13.2.5. Measuring and Reporting Host Delay
13.2.6. ACK Frames and Packet Protection
13.2.7. PADDING Frames Consume Congestion Window
13.3. Retransmission of Information
13.4. Explicit Congestion Notification
13.4.1. Reporting ECN Counts
13.4.2. ECN Validation
14. Datagram Size
14.1. Initial Datagram Size
14.2. Path Maximum Transmission Unit
14.2.1. Handling of ICMP Messages by PMTUD
14.3. Datagram Packetization Layer PMTU Discovery
14.3.1. DPLPMTUD and Initial Connectivity
14.3.2. Validating the Network Path with DPLPMTUD
14.3.3. Handling of ICMP Messages by DPLPMTUD
14.4. Sending QUIC PMTU Probes
14.4.1. PMTU Probes Containing Source Connection ID
15. Versions
16. Variable-Length Integer Encoding
17. Packet Formats
17.1. Packet Number Encoding and Decoding
17.2. Long Header Packets
17.2.1. Version Negotiation Packet
17.2.2. Initial Packet
17.2.3. 0-RTT
17.2.4. Handshake Packet
17.2.5. Retry Packet
17.3. Short Header Packets
17.3.1. 1-RTT Packet
17.4. Latency Spin Bit
18. Transport Parameter Encoding
18.1. Reserved Transport Parameters
18.2. Transport Parameter Definitions
19. Frame Types and Formats
19.1. PADDING Frames
19.2. PING Frames
19.3. ACK Frames
19.3.1. ACK Ranges
19.3.2. ECN Counts
19.4. RESET_STREAM Frames
19.5. STOP_SENDING Frames
19.6. CRYPTO Frames
19.7. NEW_TOKEN Frames
19.8. STREAM Frames
19.9. MAX_DATA Frames
19.10. MAX_STREAM_DATA Frames
19.11. MAX_STREAMS Frames
19.12. DATA_BLOCKED Frames
19.13. STREAM_DATA_BLOCKED Frames
19.14. STREAMS_BLOCKED Frames
19.15. NEW_CONNECTION_ID Frames
19.16. RETIRE_CONNECTION_ID Frames
19.17. PATH_CHALLENGE Frames
19.18. PATH_RESPONSE Frames
19.19. CONNECTION_CLOSE Frames
19.20. HANDSHAKE_DONE Frames
19.21. Extension Frames
20. Error Codes
20.1. Transport Error Codes
20.2. Application Protocol Error Codes
21. Security Considerations
21.1. Overview of Security Properties
21.1.1. Handshake
21.1.2. Protected Packets
21.1.3. Connection Migration
21.2. Handshake Denial of Service
21.3. Amplification Attack
21.4. Optimistic ACK Attack
21.5. Request Forgery Attacks
21.5.1. Control Options for Endpoints
21.5.2. Request Forgery with Client Initial Packets
21.5.3. Request Forgery with Preferred Addresses
21.5.4. Request Forgery with Spoofed Migration
21.5.5. Request Forgery with Version Negotiation
21.5.6. Generic Request Forgery Countermeasures
21.6. Slowloris Attacks
21.7. Stream Fragmentation and Reassembly Attacks
21.8. Stream Commitment Attack
21.9. Peer Denial of Service
21.10. Explicit Congestion Notification Attacks
21.11. Stateless Reset Oracle
21.12. Version Downgrade
21.13. Targeted Attacks by Routing
21.14. Traffic Analysis
22. IANA Considerations
22.1. Registration Policies for QUIC Registries
22.1.1. Provisional Registrations
22.1.2. Selecting Codepoints
22.1.3. Reclaiming Provisional Codepoints
22.1.4. Permanent Registrations
22.2. QUIC Versions Registry
22.3. QUIC Transport Parameters Registry
22.4. QUIC Frame Types Registry
22.5. QUIC Transport Error Codes Registry
23. References
23.1. Normative References
23.2. Informative References
Appendix A. Pseudocode
A.1. Sample Variable-Length Integer Decoding
A.2. Sample Packet Number Encoding Algorithm
A.3. Sample Packet Number Decoding Algorithm
A.4. Sample ECN Validation Algorithm
Contributors
Authors' Addresses

1. Overview

QUIC is a secure general-purpose transport protocol. This document
defines version 1 of QUIC, which conforms to the version-independent
properties of QUIC defined in [QUIC-INVARIANTS].

QUIC is a connection-oriented protocol that creates a stateful
interaction between a client and server.

The QUIC handshake combines negotiation of cryptographic and
transport parameters. QUIC integrates the TLS handshake [TLS13],
although using a customized framing for protecting packets. The
integration of TLS and QUIC is described in more detail in
[QUIC-TLS]. The handshake is structured to permit the exchange of
application data as soon as possible. This includes an option for
clients to send data immediately (0-RTT), which requires some form of
prior communication or configuration to enable.

Endpoints communicate in QUIC by exchanging QUIC packets. Most
packets contain frames, which carry control information and
application data between endpoints. QUIC authenticates the entirety
of each packet and encrypts as much of each packet as is practical.
QUIC packets are carried in UDP datagrams [UDP] to better facilitate
deployment in existing systems and networks.

Application protocols exchange information over a QUIC connection via
streams, which are ordered sequences of bytes. Two types of streams
can be created: bidirectional streams, which allow both endpoints to
send data; and unidirectional streams, which allow a single endpoint
to send data. A credit-based scheme is used to limit stream creation
and to bound the amount of data that can be sent.

QUIC provides the necessary feedback to implement reliable delivery
and congestion control. An algorithm for detecting and recovering
from loss of data is described in Section 6 of [QUIC-RECOVERY]. QUIC
depends on congestion control to avoid network congestion. An
exemplary congestion control algorithm is described in Section 7 of
[QUIC-RECOVERY].

QUIC connections are not strictly bound to a single network path.
Connection migration uses connection identifiers to allow connections
to transfer to a new network path. Only clients are able to migrate
in this version of QUIC. This design also allows connections to
continue after changes in network topology or address mappings, such
as might be caused by NAT rebinding.

Once established, multiple options are provided for connection
termination. Applications can manage a graceful shutdown, endpoints
can negotiate a timeout period, errors can cause immediate connection
teardown, and a stateless mechanism provides for termination of
connections after one endpoint has lost state.

QUIC 是一种安全的通用传输协议。
本文档定义了 QUIC 的版本 1,它符合 [QUIC-INVARIANTS] 中定义的 QUIC 的版本无关属性。

QUIC 是一种面向连接的协议,它在客户端和服务器之间创建有状态的交互。

QUIC 握手结合了加密和传输参数的协商。
QUIC 集成了 TLS 握手 [TLS13],尽管使用定制的帧来保护数据包。
TLS 和 QUIC 的集成在 [QUIC-TLS] 中有更详细的描述。
握手的结构允许尽快交换应用程序数据。
这包括客户端立即发送数据的选项 (0-RTT),这需要某种形式的事先通信或配置才能启用。

端点通过交换 QUIC 数据包在 QUIC 中进行通信。
大多数数据包都包含帧,这些帧在端点之间携带控制信息和应用程序数据。
QUIC 对每个数据包的整体进行身份验证,并尽可能多地加密每个数据包。
QUIC 数据包在 UDP 数据报 [UDP] 中携带,以更好地促进在现有系统和网络中的部署。

应用程序协议通过 QUIC 连接通过流交换信息,流是有序的字节序列。
可以创建两种类型的流:双向流,允许两个端点发送数据;和单向流,允许单个端点发送数据。
基于信用的方案用于限制流创建并限制可以发送的数据量。

QUIC 提供必要的反馈来实现可靠的交付和拥塞控制。
[QUIC-RECOVERY] 的第 6 节描述了一种用于检测和恢复数据丢失的算法。
QUIC依靠拥塞控制来避免网络拥塞。
[QUIC-RECOVERY] 的第 7 节描述了示例性拥塞控制算法。

QUIC 连接并不严格绑定到单个网络路径。
连接迁移使用连接标识符来允许连接转移到新的网络路径。
只有客户端才能在此版本的 QUIC 中迁移。
这种设计还允许在网络拓扑或地址映射发生变化后继续连接,例如可能由 NAT 重新绑定引起的。

一旦建立,就会为连接终止提供多个选项。
应用程序可以管理正常关闭,端点可以协商超时期限,错误可以导致立即连接断开,并且无状态机制提供在一个端点丢失状态后终止连接。

1.1. Document Structure

This document describes the core QUIC protocol and is structured as
follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
*  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.

* 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 describes address validation and critical denial-of-
service mitigations,

- Section 9 describes how endpoints migrate a connection to a new
network path,

- Section 10 lists the options for terminating an open
connection, and

- Section 11 provides guidance for stream and connection error
handling.

* 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 acknowledgment of data, and

- Section 14 specifies rules for managing the size of datagrams
carrying QUIC packets.

* Finally, encoding details of QUIC protocol elements are described
in:

- Section 15 (versions),

- Section 16 (integer encoding),

- Section 17 (packet headers),

- Section 18 (transport parameters),

- Section 19 (frames), and

- Section 20 (errors).

Accompanying documents describe QUIC’s loss detection and congestion
control [QUIC-RECOVERY], and the use of TLS and other cryptographic
mechanisms [QUIC-TLS].

This document defines QUIC version 1, which conforms to the protocol
invariants in [QUIC-INVARIANTS].

To refer to QUIC version 1, cite this document. References to the
limited set of version-independent properties of QUIC can cite
[QUIC-INVARIANTS].

1.2. Terms and Definitions

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and
“OPTIONAL” in this document are to be interpreted as described in BCP
14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.

Commonly used terms in this document are described below.

QUIC: The transport protocol described by this document. QUIC is a
name, not an acronym.

Endpoint: An entity that can participate in a QUIC connection by
generating, receiving, and processing QUIC packets. There are
only two types of endpoints in QUIC: client and server.

Client: The endpoint that initiates a QUIC connection.

Server: The endpoint that accepts a QUIC connection.

QUIC packet: A complete processable unit of QUIC that can be
encapsulated in a UDP datagram. One or more QUIC packets can be
encapsulated in a single UDP datagram.

Ack-eliciting packet: A QUIC packet that contains frames other than
ACK, PADDING, and CONNECTION_CLOSE. These cause a recipient to
send an acknowledgment; see Section 13.2.1.
Ack-eliciting packet:一个 QUIC 数据包,包含除 ACK、PADDING 和 CONNECTION_CLOSE 之外的帧。
这些会导致收件人发送确认; 见第 13.2.1 节。
Frame: A unit of structured protocol information. There are
multiple frame types, each of which carries different information.
Frames are contained in QUIC packets.

Address: When used without qualification, the tuple of IP version,
IP address, and UDP port number that represents one end of a
network path.

Connection ID: An identifier that is used to identify a QUIC
connection at an endpoint. Each endpoint selects one or more
connection IDs for its peer to include in packets sent towards the
endpoint. This value is opaque to the peer.

Stream: A unidirectional or bidirectional channel of ordered bytes
within a QUIC connection. A QUIC connection can carry multiple
simultaneous streams.

Application: An entity that uses QUIC to send and receive data.

This document uses the terms “QUIC packets”, “UDP datagrams”, and “IP
packets” to refer to the units of the respective protocols. That is,
one or more QUIC packets can be encapsulated in a UDP datagram, which
is in turn encapsulated in an IP packet.

1.3. Notational Conventions

Packet and frame diagrams in this document use a custom format. The
purpose of this format is to summarize, not define, protocol
elements. Prose defines the complete semantics and details of
structures.

Complex fields are named and then followed by a list of fields
surrounded by a pair of matching braces. Each field in this list is
separated by commas.

Individual fields include length information, plus indications about
fixed value, optionality, or repetitions. Individual fields use the
following notational conventions, with all lengths in bits:
本文档中的数据包和帧图使用自定义格式。 这
这种格式的目的是总结,而不是定义,协议
元素。 散文定义了完整的语义和细节
结构。

复杂字段被命名,然后是字段列表
被一对匹配的大括号包围。 此列表中的每个字段都是
被逗号隔开。

各个字段包括长度信息,以及关于
固定值、可选性或重复性。 个别字段使用
遵循符号约定,所有长度均以位为单位:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
x (A):  Indicates that x is A bits long
x (i): Indicates that x holds an integer value using the variable-
length encoding described in Section 16
x (A..B): Indicates that x can be any length from A to B; A can be
omitted to indicate a minimum of zero bits, and B can be omitted
to indicate no set upper limit; values in this format always end
on a byte boundary

x (L) = C: Indicates that x has a fixed value of C; the length of x
is described by L, which can use any of the length forms above
x (L) = C..D: Indicates that x has a value in the range from C to D,
inclusive, with the length described by L, as above
[x (L)]: Indicates that x is optional and has a length of L
x (L) ...: Indicates that x is repeated zero or more times and that
each instance has a length of L

大端,网络序
This document uses network byte order (that is, big endian) values.
Fields are placed starting from the high-order bits of each byte.

By convention, individual fields reference a complex field by using
the name of the complex field.

Figure 1 provides an example:

Example Structure {
One-bit Field (1),
7-bit Field with Fixed Value (7) = 61,
Field with Variable-Length Integer (i),
Arbitrary-Length Field (..),
Variable-Length Field (8..24),
Field With Minimum Length (16..),
Field With Maximum Length (..128),
[Optional Field (64)],
Repeated Field (8) ...,
}
                      Figure 1: Example Format

When a single-bit field is referenced in prose, the position of that
field can be clarified by using the value of the byte that carries
the field with the field’s value set. For example, the value 0x80
could be used to refer to the single-bit field in the most
significant bit of the byte, such as One-bit Field in Figure 1.
在散文中引用单个位字段时,该字段的位置
可以通过使用携带的字节的值来澄清字段
设置了字段值的字段。 例如,值 0x80
可以用来指代最多的单比特字段
字节的有效位,例如图 1 中的一位字段。

2 Stream:
  1. 流是什么:有序的字节流,即由类似seqnum来指定顺序。每个流有自己的seqnum空间。分单向流和双向流。

  2. 流的操作和管理:打开、携带和关闭流,允许一个连接上同时有多个流进行。
    3)流标识和类型:
    流ID: 流 ID 是一个 62 位整数(0 到 2^62-1),对于连接上的所有流都是唯一的。流 ID 被编码为变长整数;见第 16 节。QUIC 端点不得在连接中重用流 ID。
    流 ID 的最低有效位 (0x01) 标识流的发起者。
    客户端发起的流具有偶数的流 ID(位设置为 0),服务器发起的流具有奇数的流 ID(位设置为 1)。
    流 ID 的第二个最低有效位 (0x02) 区分双向流(位设置为 0)和单向流(位设置为 1)。
    因此,流 ID 中的两个最低有效位将流标识为四种类型之一,如表 1 所示。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    +======+==================================+
    | Bits | Stream Type |
    +======+==================================+
    | 0x00 | Client-Initiated, Bidirectional |
    +------+----------------------------------+
    | 0x01 | Server-Initiated, Bidirectional |
    +------+----------------------------------+
    | 0x02 | Client-Initiated, Unidirectional |
    +------+----------------------------------+
    | 0x03 | Server-Initiated, Unidirectional |
    +------+----------------------------------+

    Table 1: Stream ID Types
  3. 通过流发送和接收数据:
    (1) STREAM frames 封装了app的数据,然后结点在STREAM frames中插入Stream ID和Offset 来标识是哪条流的数据,并按顺序放置数据。节点必须能将流数据作为有序字节流传递给一个app. 传递有序的字节流要求节点缓存无序的数据,直到指定的流控限制;
    quic没有具体的允许传递无序流数据的情况。然而,实现可能选择提供传递无序数据的能力给到一个正在接收的app
    (2) 节点可以以相同的流偏移量接收流的数据多次。已经接收的数据可以被丢弃。数据被给定的offset不能改变,如果它被发送多次;
    一个节点可能会将在一个流中相同offset接收到不同数据认为是一个connection error,错误类型为PROTOCOL_VIOLATION.
    (3)流是有序的字节流抽象,没有其他QUIC 可见的结构。当数据被传输时,STREAM frame boundaries不会被预期的保留,在包loss后重传,或者作为receiver传递到app层
    (4)节点不得在任何流上发送数据而不确保它处于其对等体设置的流量控制限制范围内。流量控制是在第 4 节中详细描述。

  4. 流的优先级:
    (1) 多路流传输可以对应用程序的性能产生重大影响,如果分配给流的资源优先级排序正确。
    QUIC 不提供交换优先级信息的机制。相反,它依赖于从应用程序接收优先级信息。
    (2) QUIC 实现应该提供应用程序可以指示流的相对优先级。一个实现使用应用程序提供的信息以确定如何分配active流的资源。

  5. 流的操作:
    这个文档没有定义一个API给QUIC; 它反而定义了应用程序协议可以依赖的流上的一组函数。应用协议可以假设 QUIC 实现
    提供了一个接口,其中包括在此描述的操作部分。设计用于特定的实现应用程序协议可能只提供那些该协议使用。
    在流的发送部分,应用程序协议可以:

    • 写入数据,了解何时流控信用(第 4.1 节)已成功保留以发送写入的数据;
    • 结束流(干净终止),产生一个设置了 FIN 位的 STREAM 帧(第 19.8 节); 和
    • 重置流(突然终止),如果流尚未处于终端状态,则导致 RESET_STREAM 帧(第 19.4 节)。

    在流的接收部分,应用协议可以:

    • 读取数据; 和
    • 中止读取流并请求关闭,可能导致 STOP_SENDING 帧(第 19.5 节)。

    应用程序协议还可以请求被通知流的状态变化,包括对等方何时打开或重置流、何时中止对流的读取、何时有新数据可用以及何时由于流量控制,可以或不可以写入数据到流。

3 Stream States:sending stream states & recving stream states;

基本介绍:接收和发送模块,都各自维护了一个状态机来处理发送,接收 的状态;
对单向的流来说,可能使用发送或接收状态机,取决于流的类型和节点角色;而对于双向的流来说,则两个节点,都有两个状态机,发送和接收;
对于双向流,打开流稍微复杂一些因为无论是发送方还是接收方的打开都会导致流向两个方向打开。

本文档使用流状态来描述何时以及如何发送不同类型的帧的规则,
以及在接收不同类型的帧时预期的反应。
虽然这些状态机旨在用于实现QUIC,但这些状态并不旨在约束实现。
一个实现可以定义不同的状态机,只要其行为与实现这些状态的实现一致。
|注意:在某些情况下,单个事件或操作可能会导致通过多个状态的转换。例如,
具有FIN位设置的发送流可能会导致发送流的两种状态转换:
从“就绪”状态到“发送”状态,以及从“发送”状态到“数据发送”状态。

(1) 发送流的状态:

      o
      | Create Stream (Sending)
      | Peer Creates Bidirectional Stream
      v
  +-------+
  | Ready | Send RESET_STREAM
  |       |-----------------------.
  +-------+                       |
      |                           |
      | Send STREAM /             |
      |      STREAM_DATA_BLOCKED  |
      v                           |
  +-------+                       |
  | Send  | Send RESET_STREAM     |
  |       |---------------------->|
  +-------+                       |
      |                           |
      | Send STREAM + FIN         |
      v                           v
  +-------+                   +-------+
  | Data  | Send RESET_STREAM | Reset |
  | Sent  |------------------>| Sent  |
  +-------+                   +-------+
      |                           |
      | Recv All ACKs             | Recv ACK
      v                           v
  +-------+                   +-------+
  | Data  |                   | Reset |
  | Recvd |                   | Recvd |
  +-------+                   +-------+

Figure 2: States for Sending Parts of Streams

Ready状态:
节点发起的流的发送部分是应用打开的;((types 0 and 2 for clients, 1 and 3 for servers).
Ready状态表示一个新的被创建的流,可以从应用接受数据。在这个状态,流数据可能会被缓存,准备发送;

进入Send状态:
发送第一个STREAM 或 STREAM_DATA_BLOCKED frame会导致一个流的发送部分进入到Send状态。
一种实现会选择去推迟生成流的streamID,
直到它发送第一个STREAM frame并且进入到这个状态,这样可能更有利于帧的优先排序;

双向流:
对端发起一个双向流,此时我方也会被迫作为发送方(接收+发送):
client-> server => server->client 此时对端是0-client;for a server
server-> client => client->server 此时对端是1-server;for a client
对双向流的发送部分,由对端(type 0 for a server, type 1 for a client) 发起,
启动并进入Ready 状态,当接收模块被创建。

Send状态下:
在Send状态,一个节点发送,重传如果必要,流数据在STREAM frames.
节点会遵守流控限制(由对端设置)并持续接收和处理MAX_STREAM_DATA frames.
一个节点在Send状态时可能会生成STREAM_DATA_BLOCKED frames,若它被流控限制阻塞时。

进入Data Sent状态:
当应用指示所有流数据都被发送且一个STREAM frame包含了FIN bit 被发送时,
流发送部分进入到Data Sent状态。
进入这个状态后,节点只重传必要的数据。
节点不需要检查流控限制或发送STREAM_DATA_BLOCKED frames for a stream in this state。
MAX_STREAM_DATA frames 可能会被接收直到对端接收到最后的stream offset.
在这个状态,节点能安全的忽略任何接收到的对端的流的MAX_STREAM_DATA frames。

进入Data Recvd状态:
一旦所有的流数据被成功的ack,则发送部分进入到Data Recvd状态。是一个终止的状态。

Reset Sent状态:
从任何状态,如Ready,Send,Data Sent,一个应用能通知它想放弃传输数据。
可选的,一个节点可能从它的对端接收到STOP_SENDING frame。
在任意情况下,节点发送一个RESET_STREAM frame,能导致流进入到Reset Sent状态。

一个节点可能发送RESET_STREAM作为stream中的第一个帧;
这个会导致发送模块打开并且立即转换到Reset Sent状态。
一旦一个包含了RESET_STREAM的包被ack了,则发送部分会进入到Reset Recvd状态。即终止状态。

(2) 接收流的状态: Receiving Stream States

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    o
| Recv STREAM / STREAM_DATA_BLOCKED / RESET_STREAM
| Create Bidirectional Stream (Sending)
| Recv MAX_STREAM_DATA / STOP_SENDING (Bidirectional)
| Create Higher-Numbered Stream
v
+-------+
| Recv | Recv RESET_STREAM
| |-----------------------.
+-------+ |
| |
| Recv STREAM + FIN |
v |
+-------+ |
| Size | Recv RESET_STREAM |
| Known |---------------------->|
+-------+ |
| |
| Recv All Data |
v v
+-------+ Recv RESET_STREAM +-------+
| Data |--- (optional) --->| Reset |
| Recvd | Recv All Data | Recvd |
+-------+<-- (optional) ----+-------+
| |
| App Read All Data | App Read Reset
v v
+-------+ +-------+
| Data | | Reset |
| Read | | Read |
+-------+ +-------+
          Figure 3: States for Receiving Parts of Streams

图展示了从对端接收流数据的本端状态情况。
接收部分的流状态只是镜像了部分发送端的流状态。(并不是一一对应)
接收部分并不跟踪发送部分的无法观察到的状态,比如Ready状态。
然而,接收部分的状态是跟踪了传输数据到应用,这些确无法被发送方得知。

一个流的接收部分的被对端((type 0 for a client, type 1 for a server) 初始化,
当收到流的第一个STREAM,STREAM_DATA_BLOCKED,或RESET_STREAM 帧时被创建。

For bidirectional streams initiated by a peer, receipt of a
MAX_STREAM_DATA or STOP_SENDING frame for the sending part of the
stream also creates the receiving part.

For a bidirectional stream, the receiving part enters the “Recv”
state when the sending part initiated by the endpoint (type 0 for a
client, type 1 for a server) enters the “Ready” state.
An endpoint opens a bidirectional stream when a MAX_STREAM_DATA or
STOP_SENDING frame is received from the peer for that stream.
Receiving a MAX_STREAM_DATA frame for an unopened stream indicates
that the remote peer has opened the stream and is providing flow
control credit. Receiving a STOP_SENDING frame for an unopened
stream indicates that the remote peer no longer wishes to receive
data on this stream. Either frame might arrive before a STREAM or
STREAM_DATA_BLOCKED frame if packets are lost or reordered.

在一个流被创建之前,所有有更低数值的StreamID的同类型的流必须被创建。这个确保流的创建顺序是连续的,在双方节点来看。
在Recv状态,节点接收STREAM和STRAM_DATA_BLOCKED frames.到达的数据被缓存,然后能重组成正确的顺序,之后传递给app.
数据被app消费后,buffer空间变得有效,节点发送MAX_STREAM_DATA frames来允许对端发送更多数据。

当一个STREAM frame带FIN bit被接收,流的最后长度被知晓; 流的接收部分,进入到Size Known的状态。 这个状态下,节点不再需要
发送MAX_STREAM_DATA frames. 它只接收任何的流数据重传。

一旦所有的流数据被接收,接收部分进入到Data Recvd状态,这个可能是接收到相同的STRAM frame导致转换到Size Known状态的一个结果。在所有数据被接收,任何这个流的STREAM或STREAM_DATA_BLOCKED frames 被丢弃

Data Recvd状态持续直到流数据被传递到app.一旦流数据被传递,则流进入到Data Read 状态,这是一个终止状态。
接收到一个RESET_STREAM frame在Recv或Size Known状态下,导致流进入到ResetRecvd状态。这个可能导致传递到app的数据被中断。

存在一个特殊场景,在Data Recvd状态下接收到RESET_STREAM,或者在Reset Recvd状态下接收完剩下的数据。这个由实现来处理这种场景,比如前者进入到Reset Recvd,后者进入Data Recvd

发送一个RESET_STREAM 意味着一个节点不能保证传输流数据。然而,没有要求帧数据不能被传输,若收到一个RESET_STREAM.
一个实现可能会中断传输流数据,丢弃任何没被app consumed的数据 ,并通知收到了RESET_STREAM. 一个RESET_STREM的信号可能被抑制或隐瞒,若流数据完全被接收,且buffer被app读完。若RESET_STREAM被抑制,则流的接收部分保持在DataRecvd状态

一旦app收到信号按时流被重置了,则流的接收部分进入到Reset Read状态,是一个终止状态。

(3) 允许的(合法的)帧类型:
流的发送方只发送三种能影响发送方或接收方流状态的帧类型:
STREAM,STREAM_DATA_BLOCKED和RESET_STREAM.

一个发送方不能在一个终止状态(“Data Recvd” or “Reset Recvd”)发送任意这些帧。
A sender MUST NOT send a STREAM or STREAM_DATA_BLOCKED frame for a stream in the “Reset Sent” state or any terminal state – that is, after sending a RESET_STREAM frame
但是一个接收方,却可能接收到任何这些帧在任意状态,因为可能包传递有延迟。(网络阻塞)

一个流的接收方发送sends MAX_STREAM_DATA frames (Section 19.10) and STOP_SENDING frames (Section 19.5).

接收方只能在Recv State发送MAX_STREAM_DATA frames。
一个接收方可能在任意没收到一个RESET_STREM的状态下发送一个STOP_SENDING frame. 即,非Reset Recvd或Reset Read状态。
然而,会有一些小的值,在发送一个STOP_SENDING frame ,在Data Recvd状态,当所有的流已经被接收。
一个发送方可能接收可以接收这两个中的任何一个由于延迟传输而导致的任何状态的帧类型数据包。

(4) 双向流状态:Bidirectional Stream States
双向stream states;
一个双向流由发送和接收部分组成。
实现上能表示双向流的状态也是由接收和发送流状态组成。
最简单的模型:
表示打开,即当sending或receiving 部分在非 terminal状态。
表示关闭,当发送和接收流在terminal状态。

表 2 显示了更复杂的双向流状态映射松散地对应于 HTTP/2 中定义的流状态[HTTP2]。
这表明流的发送或接收部分的多个状态被映射到相同的复合状态。
注意这只是这种映射的一种可能性;这个映射要求在转换“关闭”或“半关闭”状态之前数据已被确认。

  +===================+=======================+=================+
  | Sending Part      | Receiving Part        | Composite State |
  +===================+=======================+=================+
  | No Stream / Ready | No Stream / Recv (*1) | idle            |
  +-------------------+-----------------------+-----------------+
  | Ready / Send /    | Recv / Size Known     | open            |
  | Data Sent         |                       |                 |
  +-------------------+-----------------------+-----------------+
  | Ready / Send /    | Data Recvd / Data     | half-closed     |
  | Data Sent         | Read                  | (remote)        |
  +-------------------+-----------------------+-----------------+
  | Ready / Send /    | Reset Recvd / Reset   | half-closed     |
  | Data Sent         | Read                  | (remote)        |
  +-------------------+-----------------------+-----------------+
  | Data Recvd        | Recv / Size Known     | half-closed     |
  |                   |                       | (local)         |
  +-------------------+-----------------------+-----------------+
  | Reset Sent /      | Recv / Size Known     | half-closed     |
  | Reset Recvd       |                       | (local)         |
  +-------------------+-----------------------+-----------------+
  | Reset Sent /      | Data Recvd / Data     | closed          |
  | Reset Recvd       | Read                  |                 |
  +-------------------+-----------------------+-----------------+
  | Reset Sent /      | Reset Recvd / Reset   | closed          |
  | Reset Recvd       | Read                  |                 |
  +-------------------+-----------------------+-----------------+
  | Data Recvd        | Data Recvd / Data     | closed          |
  |                   | Read                  |                 |
  +-------------------+-----------------------+-----------------+
  | Data Recvd        | Reset Recvd / Reset   | closed          |
  |                   | Read                  |                 |
  +-------------------+-----------------------+-----------------+

        Table 2: 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 receiving part of the stream is in the "Recv"
  |  state without yet having received any frames.

(5) 请求的状态转换:Solicited State Transitions
若一个app不再对接收的流数据感兴趣时,他可以停止读取流,并指示一个应用错误码。

如果流处于“Recv ”或“Size Known”状态,传输应该通过发送 STOP_SENDING 帧来提示关闭在相反方向的流。
这通常表明接收应用程序不再读取它接收的数据来自流,但不能保证传入的数据将忽略。

发送 STOP_SENDING 帧后收到的 STREAM 帧仍然是计入连接和流控制,即使这些帧可以在收到时丢弃.
一个 STOP_SENDING 帧请求接收端点发送一个RESET_STREAM 帧。接收 STOP_SENDING 帧的端点
如果流处于“Ready”状态或“Send”状态,则必须发送 RESET_STREAM 帧。如果流处于“Data Sent”状态,则端点可以推迟发送 RESET_STREAM 帧,直到数据包包含未完成的数据被确认或宣布丢失。如果任何未完成的数据被声明为丢失,端点应该发送一个
RESET_STREAM 帧而不是重新传输数据。

一个节点可能从STOP_SENDING帧拷贝错误码到RESET_FRAME然后发送,但它能使用 任意应用错误码。发送 STOP_SENDING 帧的节点可以忽略
随后收到的该流任何 RESET_STREAM 帧中的错误代码。

STOP_SENDING 可能只在未被对端reset的流 被发送。 STOP_SENDING是最有用的在流的Recv或SizeKnown状态。

一个节点备期待发送另一个STOP_SENDING frame若一个包含了之前的STOP_SENDING 的包丢失。然而,一旦所有的流数据或一个RESET_STREAM frame 被接收,即,这个流在任意非Recv或Size Known状态。发送一个STOP_SENDING frame是不太必要的。

一个节点,希望停止一个双向流的两个方向流,可以终止一个方向通过发送一个RESET_STRAEM frame,且它能通过发送一个STOP_SENDING frame来鼓励驱动另一个方向的终止。

4 流量控制:Flow Control

背景:
接收者需要限制他们需要的数据量缓冲区,以防止快速发件人压倒他们或恶意发件人消耗大量内存。
为了使能一个接收方在连接上限制内存限制,Stream是被单独流控制和跨连接作为一个整体;
一个QUIC 接收方控制发送方在任何时候一个流以及所有流可以发送的最大数据量。

  相似的,为了限制一个连接内的并发,一个QUIC 节点控制它对端能初始化的流的最大的累计数量。
  加密frame的发送,并不和stream data一样的流控方式。 QUIC依赖加密协议实现,来防止过多的数据缓存;see [QUIC-TLS].
  
  为了防止在多层级上的buffer溢出,QUIC实现应该提供一个接口来为加密协议的实现去做缓存限制的交流协商;
4.1 Data Flow Control

数据流控基本规则:
QUIC 采用基于限制的流量控制方案,其中接收器通告它准备接收的总字节数限制给定的流或整个连接。这个将会引导出QUIC的两个阶段的数据流控:
1) stream flow control: 用来通过限制每个流能发送的数据总数防止一个单独的流对整个连接的接收缓存的消耗。
2) Connection flow control: 通过限制发送在所有stream上发送的STREAM frames的字节总数来防止发送者 发送超过一个接收者在连接上的缓存容量。
发送方在这些任意限制上 不能发送数据

1)一个接收方通过在握手阶段传输参数来设置所有流的初始限制,随后,一个接收方发送MAX_STREAM_DATA frames或MAX_DATA frames,到发送方来通告更大的限制;

2)一个接收方能通告一个流的更大的限制,通过发送一个MAX_STREAM_DATA frame,携带上关联的stream ID; 一个MAX_STREAM_DATA frame暗示一个流的最大绝对字节偏移。 一个接收方能决定流控
偏移通告,基于该流当前的数据消耗偏移。

3)一个接收方能通过一个流的更大限制,通过发送一个MAX_DATA frame,来指示所有流的字节偏移总数最大值。 一个接收方维护一个所有接收到的流的累计字节总数,用来去检查是否违反了通告的连接或流数据 限制。一个接收方能决定最大数据限制为基于所有流上消耗的字节总数,并进行通告;

  1. 一旦接收者通告连接或流的限制,它宣传较小的限制不是错误,而是较小的限制没有效果
  2. 接收者必须关闭带有类型错误的连接FLOW_CONTROL_ERROR 如果发件人违反了通告的连接或流数据限制;有关错误处理的详细信息,请参阅第 11 节。
  3. 一个发送方必须忽略任何不增加流控限制的MAX_STREAM_DATA 或 MAX_DATA frames.
  4. 若一个发送方已经发送了超过限制的数据,则它将不能发送新数据,而是被阻塞。一个发送方应该发送一个STREAM_DATA_BLOCKED 或 DATA_BLOCKED frame来提示接收方它有数据要写,但是被阻塞了因为流控。若发送方被阻塞了一个周期,超过了idle timeout,则接收方可能关闭了连接,即使当发送方有数据是有效的要发送。 为了保持连接关闭,流量控制受限的发送方应该定期发送 STREAM_DATA_BLOCKED 或 DATA_BLOCKED 帧当它在传输中没有收到 ack数据包。ack-eliciting引发确认。
4.2 增加流控限制 Increasing Flow Control Limits

1)实现决定了什么时候和多少值在MAX_STREAM_DATA和MAX_DATA frames来通告,当这个小节也提供了一些考虑;
2)为了避免阻塞发送方,一个接收方可能发送一个MAX_STREAM_DATA或MAX_DATA frame多次,在一个round trip或更早的发送来允许足够时间丢失和后续恢复。
3)控制帧贡献了连接开销。 因此频繁发送MAX_STREAM_DATA 和 MAX_DATA frame 但是带了小的改变是不值得的。 另一方面,若更新是更小的频率时,更大的增长限制对避免发送方阻塞是必要的,接收方要请求更大的资源。在资源分配和确定一个多大的流控限制通告,这两者之间是一个 trade-off(平衡权衡)的
4)一个接收方可以使用一个自动调节的机制去调节频率和通告的额外增加的credit总数,基于rtt测量和接收方app消耗数据的速率,类似tcp的实现。 作为一个优化项,一个节点能发送和flow control关联的frame, 只是当有其他frame要发送,确保流控不会引起额外包的发送。
5) 一个被阻塞的发送方并不被要求一定要发送STREAM_DATA_BLOCKED或DATA_BLOCKED frames。 因此,接收方不用等待一个STREAM_DATA_BLOCKED或 DATA_BLOCKED frame才发送一个MAX_STREAM_DATA 或MAX_DATA frame; 这样做的话可以导致在剩下的连接上,发送端保持blocked. 即使发送方发送这些帧,等待他们将导致发送方阻塞至少一个完整的round trip;(rtt)
6)当一个发送方在阻塞之后接收到credit (即类似MAX_STREAM_DATA或MAX_DATA 携带更大flowcontrol限制值),他可能能发送更大量的数据回复,导致在短时间内拥塞;see Section 7.7 of [QUIC-RECOVERY] for a discussion of how a sender can avoid this congestion

4.3 流控的性能:Flow Control Performance
  1. 和throughput: 如果一个节点不能确保它的对端总是有有效的flow control credit 比对端在这个连接上的带宽延迟统计上大,它的接收吞吐量将会被flow control限制。
  2. 丢包会导致接收缓存的gap(差距), 防止app 从缓存中消费数据和释放缓存。
  3. 及时发送流量控制限制的更新可以改善性能表现。发送包若只携带flow control更新会增加网络负担,对性能产生不利影响。可以在如ACK frames,等类型的frame ,同时携带flow control update信息,来减少网络消耗。
4.4 处理流的取消:Handling Stream Cancellation

节点需要最终就流量控制的每个流上被消耗的credit 数量达成一样,从而能统计下连接维度的流控的所有字节。
一旦节点接收到RESET_STREAM frame,节点将拆除匹配的流的状态,并忽略未来接收到的该流的数据。
RESET_STREAM 会突然中止一个方向的流 。对双向流来说,RESET_STREAM 对另一个方向的流没有影响。 两个节点必须为流的未中止的方向维持流控状态直到该方向进入中止状态。

4.5 流的final size (流的最终大小) Stream Final Size

1)the final size 是一个流消耗的flow control credit.假设流上的每个连续字节都是发送一次,最终大小为发送的字节数。更多的,通常,这是一个比该流上发送的最大偏移更大的字节偏移,或者是0若没有字节被发送。
2)发送方总是可靠的将流的最终大小传达给接收方,不管流是如何终止的。the final size 是 STREAM 帧的 Offset 和 Length 字段的总和带有 FIN 标志,注意这些字段可能是隐式的。可选的,RESET_STREAM 帧的最终大小字段携带这个值。这样保证了双方节点在这条流上发送方消耗了多少flow control credit 达成一致。
3)一个节点将知道一个流的the final size 当接收到部分流,并进入到‘Size Known’或’Reset Recvd’状态。 接收方必须使用the final size of the stream.来统计连接维度上的flow controller上在这个流上发送的所有字节数。
4)一个节点不能在一个流上发送超过final size的数据。
5) 一旦流的final size被知道了,则它不能改变。若一个RESET_STREAM 或 STREAM frame被接收以指示流的final size变化了,则节点应该回复一个错误类型为FINAL_SIZE_ERROR的错误。
一个接收方应该将超过final size 作为一个错误类型为FINAL_SIZE_ERROR的错误,即使在流被关闭后。生成这些错误不是强制的,因为要求让节点产生这些错误也意味着节点需要去为已经关闭的流维护the final size 状态, 意味着需要额外的一个状态维护。

4.6. Controlling Concurrency

1)一个节点限制一个对端可以打开的到达流的累计数量。只有携带的stream ID 小于”(max_streams * 4 + first_stream_id_of_type)” 才能被打开。
初始化限制被设置到传输参数中; 后续的限制在MAX_STREAMS frame中被告知; 单向和双向的流是分开限制的。
2)若一个max_streams 传输参数或一个MAX_STREAMS frame是被接收携带一个大于2^60的值,则这个可能允许一个不能表示最大的stream ID作为一个可变长度的interger;
若在接收到的帧中,传输参数为非法值或类型为FRAME_ENCODING_ERROR的异常,则必须立即关闭连接,用一个连接错误类型为TRANSPORT_PARAMETER_ERROR。
3) 节点不能超过对端设置的限制。 一个节点若接收一个帧,携带的stream ID超过了限制,它被发送了,则被对待为一个连接错误,类型为STREM_LIMIT_ERROR.
4) 一旦一个接收方用MAX_STREAMS frame通告一个流的限制,通告一个更小的限制没有影响。没增加限制的MAX_STREAMS frame会被忽略。
5) 作为流和连接的流控,这个文档遗留给实现去决定何时和多少流应该被通告给对端通过MAX_STREAMS. 实现可能选择在流关闭时去增加限制,以保持可用流的数量对对端是大致一致的。
6) 一个节点当因为对端的限制不能打开一个新流时,应该发送一个STREAMS_BLOCKED frame. 这个信号是被认为是对调试有用的。 一个节点不能等待去接收这个信号,在通告额外的限制值(credit)之前。因为这样做将意味着对端将阻塞至少一个完整的rtt, 和潜在的未定义行为若对端选择不发STREAM_BLOCKED frames时。

5. Connections

A QUIC connection is shared state between a client and a server.

Each connection starts with a handshake phase, during which the two
endpoints establish a shared secret using the cryptographic handshake
protocol [QUIC-TLS] and negotiate交涉 the application protocol. The
handshake (Section 7) confirms that both endpoints are willing to
communicate (Section 8.1) and establishes parameters for the
connection (Section 7.4).

An application protocol can use the connection during the handshake
phase with some limitations. 0-RTT allows application data to be
sent by a client before receiving a response from the server.
However, 0-RTT provides no protection against replay attacks; see
Section 9.2 of [QUIC-TLS]. A server can also send application data
to a client before it receives the final cryptographic handshake
messages that allow it to confirm the identity and liveness of the
client. These capabilities allow an application protocol to offer
the option of trading some security guarantees for reduced latency.

The use of connection IDs (Section 5.1) allows connections to migrate
to a new network path, both as a direct choice of an endpoint and
when forced by a change in a middlebox. Section 9 describes
mitigations for the security and privacy issues associated with
migration.

For connections that are no longer needed or desired, there are
several ways for a client and server to terminate a connection, as
described in Section 10.

connection
概述:
1)一个QUIC的连接在client和server之间是共享状态的。
2)每个连接起始于一次握手,在握手期间两个节点会使用加密握手协议(QUIC-TLS)建立一个共享的秘钥并且协商app协议。这次握手也确定了双方节点将愿意交互和建立连接的的参数。
3)一个app协议能在握手期间使用连接,但是有一些限制。0-RTT允许app数据在client端被发送,在收到server的响应之前。然而,0-RTT 无法防止重放攻击;
4)一个服务也能发送app数据到client,在他收到最后的加密握手信息之前,从而允许它确认客户端的身份和活跃度的消息。这些能力允许应用程序协议提供
交易一些安全保证以减少延迟的选项。
5) connection IDs的使用允许连接进行迁移到一个新的网络路径,既可以作为终点的直接选择,也可以作为当因中间件的变化而被迫时。第 9 节描述
与迁移相关的安全和隐私问题的缓解措施。
6) 对不再需要的连接,有几种方式对client和server去终止一个连接。

5.1. Connection ID

Each connection possesses持有 a set of connection identifiers, or
connection IDs, each of which can identify the connection.
Connection IDs are independently selected by endpoints; each endpoint
selects the connection IDs that its peer uses.

The primary function of a connection ID is to ensure that changes in
addressing at lower protocol layers (UDP, IP) do not cause packets
for a QUIC connection to be delivered to the wrong endpoint. Each
endpoint selects connection IDs using an implementation-specific (and
perhaps deployment-specific) method that will allow packets with that
connection ID to be routed back to the endpoint and to be identified
by the endpoint upon receipt.

Multiple connection IDs are used so that endpoints can send packets
that cannot be identified by an observer as being for the same
connection without cooperation from an endpoint; see Section 9.5.

Connection IDs MUST NOT contain any information that can be used by
an external observer (that is, one that does not cooperate with the
issuer) to correlate them with other connection IDs for the same
connection. As a trivial example, this means the same connection ID
MUST NOT be 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.2.1) packet echoes回显 the connection
IDs selected by the client, both to ensure correct routing toward the
client and to demonstrate证明 that the packet is in response to a packet
sent by the client.

A zero-length connection ID can be used when a connection ID is not
needed to route to the correct endpoint. However, multiplexing
connections on the same local IP address and port while using zero-
length connection IDs will cause failures in the presence of peer
connection migration, NAT rebinding, and client port reuse. An
endpoint MUST NOT use the same IP address and port for multiple
concurrent connections with zero-length connection IDs, unless it is
certain that those protocol features are not in use.

When an endpoint uses a non-zero-length connection ID, it needs to
ensure that the peer has a supply of connection IDs from which to
choose for packets sent to the endpoint. These connection IDs are
supplied by the endpoint using the NEW_CONNECTION_ID frame
(Section 19.15).

连接ID

  1. 每个连接拥有一个连接标记集合,或连接IDs, 每个都能标记连接。连接IDs是被节点独立选择的;每个节点选择其对端使用的连接IDs 。
  2. 连接IDs的主要功能是确保底层协议如UDP,IP的地址变化不会导致一个QUIC的连接被传送到错误的节点;
    每个节点使用一个具体的实现(和也许是deployment-specific) 方式,来允许携带连接ID的包能被路由到节点,并被节点识别和接受。
  3. 使用多个连接 ID,以便端点可以发送观察者无法识别为同一连接的数据包,而无需端点的合作;见第 9.5 节。
    4)连接 ID 不得包含任何可被外部观察者(即不与发布者合作的观察者)用于将它们与同一连接的其他连接 ID 相关联的信息。
    作为一个简单的例子,这意味着相同的连接 ID不得在同一连接上多次发出。

5)带有长标头的数据包包括源连接 ID 和目标连接 ID 字段。这些字段用于设置新连接的连接 ID;有关详细信息,请参阅第 7.2 节。
6) 带短头(Section 17.3)的包,只包含了目的连接ID和省略显示的长度。 目的连接ID域的长度要被节点知道。使用基于连接 ID 路由的负载均衡器的端点可以与负载均衡器就连接 ID 的固定长度达成一致,或者就编码方案达成一致。
固定部分可以编码显式长度,这允许整个连接 ID 的长度不同,并且仍然由负载平衡器使用。
7) 版本协商(第 17.2.1 节)数据包回显客户端选择的连接 ID,以确保正确路由到客户端并证明数据包是对客户端发送的数据包的响应。
8) 一个零长的连接ID,在一个连接ID不需要被路由到正确的节点时,被使用。 然而,当使用了零长连接ID在相同的本地IP地址和端口上多路复用连接时,在节点连接迁移的场景下,NAT重新绑定,和客户端端口重用下,将会失败。
一个节点不能用零长的连接ID来进行相同的IP和端口进行多路复用连接,除非它是确定这些协议特性不会使用。
9) 当端点使用非零长度的连接 ID 时,它需要确保对等方有一个连接 ID 的供应,可以从中选择发送到端点的数据包。这些连接 ID 由端点使用 NEW_CONNECTION_ID 帧提供

5.1.1. Issuing Connection IDs

Each connection ID has an associated sequence number to assist in
detecting when NEW_CONNECTION_ID or RETIRE_CONNECTION_ID frames refer
to the same value. The initial connection ID issued by an 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
is 1.

Additional connection IDs are communicated to the peer using
NEW_CONNECTION_ID frames (Section 19.15). The sequence number on
each newly issued connection ID MUST increase by 1. The connection
ID that a client selects for the first Destination Connection ID
field it sends and any connection ID provided by a Retry packet are
not assigned sequence numbers.

When an endpoint issues a connection ID, it MUST accept packets that
carry this connection ID for the duration of the connection or until
its peer invalidates the connection ID via a RETIRE_CONNECTION_ID
frame (Section 19.16). Connection IDs that are issued and not
retired are considered active; any active connection ID is valid for
use with the current connection at any time, in any packet type.
This includes the connection ID issued by the server via the
preferred_address transport parameter.

An endpoint SHOULD ensure that its peer has a sufficient number of
available and unused connection IDs. Endpoints advertise the number
of active connection IDs they are willing to maintain using the
active_connection_id_limit transport parameter. An endpoint MUST NOT
provide more connection IDs than the peer’s limit. An endpoint MAY
send connection IDs that temporarily exceed a peer’s limit if the
NEW_CONNECTION_ID frame also requires the retirement of any excess,
by including a sufficiently large value in the Retire Prior To field.

A NEW_CONNECTION_ID frame might cause an endpoint to add some active
connection IDs and retire others based on the value of the Retire
Prior To field. After processing a NEW_CONNECTION_ID frame and
adding and retiring active connection IDs, if the number of active
connection IDs exceeds the value advertised in its
active_connection_id_limit transport parameter, an endpoint MUST
close the connection with an error of type CONNECTION_ID_LIMIT_ERROR.

An endpoint SHOULD supply a new connection ID when the peer retires a
connection ID. If an endpoint provided fewer connection IDs than the
peer’s active_connection_id_limit, it MAY supply a new connection ID
when it receives a packet with a previously unused connection ID. An
endpoint MAY limit the total number of connection IDs issued for each
connection to avoid the risk of running out of connection IDs; see
Section 10.3.2. An endpoint MAY also limit the issuance of
connection IDs to reduce the amount of per-path state it maintains,
such as path validation status, as its peer might interact with it
over as many paths as there are issued connection IDs.

An endpoint that initiates migration and requires non-zero-length
connection IDs SHOULD ensure that the pool of connection IDs
available to its peer allows the peer to use a new connection ID on
migration, as the peer will be unable to respond if the pool is
exhausted.

An endpoint that selects a zero-length connection ID during the
handshake cannot issue a new connection ID. A zero-length
Destination Connection ID field is used in all packets sent toward
such an endpoint over any network path.
5.1.1 发行连接IDs

  1. 每个连接ID有一个关联的seq num,用来协助检测 ,当NEW_CONNECTION_ID or RETIRE_CONNECTION_ID frames refer to the same value.
    在握手期间,端点发出的初始连接 ID 在长数据包头(第 17.2 节)的源连接 ID 字段中发送。初始化的seqnum是0。 若preferred_address 传输参数被发送,则提供的seqnum是1
    2)添加的连接IDs是使用NEW_CONNECTION_ID帧来和对端协商的。 每个新的发布的连接ID必须递增1. 客户端为其发送的第一个目标连接 ID 字段选择的 connectionID 和重传数据包提供的任何连接 ID 都没有分配序列号。
    3)当一个节点发行了一个连接ID,它必须接受携带这个连接ID的包,在这个连接的过程中,或者直到它的对端通过发送一个RETIRE_CONNECTION_ID帧来无效化这个连接ID。被发行但未被retire的连接IDs是被认为活跃的。
    任何活跃的连接ID是可以被当前连接在任何时候,任何包类型有效使用的。这也包括了被服务器携带preffered_address传输参数发行的连接ID.
  2. 一个节点应该确定他的对端有足够的有效且未被使用的连接IDs. 节点广播它们将会维持使用的活跃连接ID数,通过使用active_connection_id_limit传输参数。 一个节点不能提供超过对端限制的连接IDs数量。 一个节点
    也可以发送连接IDs临时超过对端的限制,如果NEW_CONNECTION_ID帧也请求任何多余的退休,通过包含一个足够大的值,在Retire Prior To 字段。
    5)一个NEW_CONNECTION_ID帧可能引起一个节点去增加一些活跃的连接IDs和退休其他基于Retire Prior To字段。 在处理一个NEW_CONNECTION_ID帧和添加,退休连接IDs后,若活跃连接IDs的数量还是超过在它的
    active_connection_id_limit传输参数中携带的值时,一个节点必须关闭连接,携带一个错误码为CONNECTION_ID_LIMIT_ERROR类型的错误。
    6)一个节点应该补充一个新的连接ID当对端退休一个连接ID。若一个节点提供的连接ID比对端的active_connection_id_limi少,则它可能会补充一个新的连接ID当它收到一个携带以前未使用的连接ID的包时。
    一个节点会对每个连接限制发行的连接IDs总数来避免超过连接IDs的风险。见secion10.3.2 . 一个节点也会限制发行连接IDs来减少它维持每个路径状态的数量,例如路径有效状态,因为对端可能会在和发行的连接ID数量一样多的
    路径上和它交互。
    7)一个开始迁移的节点并且要求非0长的连接IDs应该确保连接IDs池子的有效性,以允许对端使用一个新的连接ID来迁移。因为如果池子枯竭,对端将不能响应。
    8)一个选择非0长连接ID的节点在握手期间不能发行一个新连接ID。 在通过任何网络路径向此类端点发送的所有数据包中都使用零长度的目标连接 ID 字段。
5.1.2. Consuming and Retiring Connection IDs

An endpoint can change the connection ID it uses for a peer to
another available one at any time during the connection. An endpoint
consumes connection IDs in response to a migrating peer; see
Section 9.5 for more details.

An endpoint maintains a set of connection IDs received from its peer,
any of which it can use when sending packets. When the endpoint
wishes to remove a connection ID from use, it sends a
RETIRE_CONNECTION_ID frame to its peer. Sending a
RETIRE_CONNECTION_ID frame indicates that the connection ID will not
be used again and requests that the peer replace it with a new
connection ID using a NEW_CONNECTION_ID frame.

As discussed in Section 9.5, endpoints limit the use of a connection
ID to packets sent from a single local address to a single
destination address. Endpoints SHOULD retire connection IDs when
they are no longer actively using either the local or destination
address for which the connection ID was used.

An endpoint might need to stop accepting previously issued connection
IDs in certain circumstances. Such an endpoint can cause its peer to
retire connection IDs by sending a NEW_CONNECTION_ID frame with an
increased Retire Prior To field. The endpoint SHOULD continue to
accept the previously issued connection IDs until they are retired by
the peer. If the endpoint can no longer process the indicated
connection IDs, it MAY close the connection.

Upon receipt of an increased Retire Prior To field, the peer MUST
stop using the corresponding connection IDs and retire them with
RETIRE_CONNECTION_ID frames before adding the newly provided
connection ID to the set of active connection IDs. This ordering
allows an endpoint to replace all active connection IDs without the
possibility of a peer having no available connection IDs and without
exceeding the limit the peer sets in the active_connection_id_limit
transport parameter; see Section 18.2. Failure to cease using the
connection IDs when requested can result in connection failures, as
the issuing endpoint might be unable to continue using the connection
IDs with the active connection.

An endpoint SHOULD limit the number of connection IDs it has retired
locally for which RETIRE_CONNECTION_ID frames have not yet been
acknowledged. An endpoint SHOULD allow for sending and tracking a
number of RETIRE_CONNECTION_ID frames of at least twice the value of
the active_connection_id_limit transport parameter. An endpoint MUST
NOT forget a connection ID without retiring it, though it MAY choose
to treat having connection IDs in need of retirement that exceed this
limit as a connection error of type CONNECTION_ID_LIMIT_ERROR.

Endpoints SHOULD NOT issue updates of the Retire Prior To field
before receiving RETIRE_CONNECTION_ID frames that retire all
connection IDs indicated by the previous Retire Prior To value.
5.1.2. Consuming and Retiring Connection IDs
终端可以在连接期间任何时候将其与对端交互的连接ID更改为另一个可用的连接ID。在对端进行迁移连接时,终端会消耗连接ID,更多详见第9.5章。

终端维护一个接收自对端的连接ID集合,其中每个ID均可用于发送数据包。当终端想要停止使用一个连接ID,其可以发送一个撤销连接ID帧给对端。发送一个撤销连接ID帧意味着将不会再次使用该连接ID,同时请求对端通过新连接ID帧换一个新的连接ID。

如第9.5章所述,终端限制使用一个连接ID从一个单一本地地址向一个单一目标地址发送数据包。当使用连接ID的本地或目标地址不再活跃的时候,终端应该撤销这些连接ID。

在特定场合,终端可能需要停止接收先前发布的连接ID。这种终端会通过发送带有值已增加的“撤销前”字段的新连接ID帧使对端停用这些连接ID。终端应该继续接收先前发布的连接ID直到它们被对端撤销。如果终端不能再处理指定的连接ID,其可以关闭连接。

一旦收到一个值增加的“撤销前”字段,对端必须停止使用相关连接ID,并在添加新提供的连接ID到活跃连接ID集合之前,通过撤销连接ID帧停用这些连接ID。这么安排使得终端能够替换全部活跃连接ID,而不会出现对端没有可用连接ID的情况,也不会使活跃连接ID数超过对端传输参数active_connection_id_limit设下的限制,详见第18.2章。无法停止使用连接ID可能导致连接错误,因为发布端可能不能在当前连接上继续使用这些连接ID。

如果撤销连接ID帧尚未被确认,那么终端应该限制本地已撤销连接ID的数量。终端应该允许发送中及可追踪的撤销连接ID帧数量至少是传输参数active_connection_id_limit值的两倍。终端必须不在没有撤销一个连接ID前忘记它,尽管其可以选择将仍然使用达到该限制而需要被撤销的连接ID的情况视为一个CONNECTION_ID_LIMIT_ERROR类型的连接错误。

在收到撤销由先前的“撤销前”字段指定的全部连接ID的撤销连接ID帧前,终端不应该发布更新“撤销前”字段。

5.2. Matching Packets to Connections

Incoming packets are classified on receipt. Packets can either be
associated with an existing connection or – for servers –
potentially create a new connection.

Endpoints try to associate a packet with an existing connection. If
the packet has a non-zero-length Destination Connection ID
corresponding to an existing connection, QUIC processes that packet
accordingly. Note that more than one connection ID can be associated
with a connection; see Section 5.1.

If the Destination Connection ID is zero length and the addressing
information in the packet matches the addressing information the
endpoint uses to identify a connection with a zero-length connection
ID, QUIC processes the packet as part of that connection. An
endpoint can use just destination IP and port or both source and
destination addresses for identification, though this makes
connections fragile as described in Section 5.1.

Endpoints can send a Stateless Reset (Section 10.3) for any packets
that cannot be attributed to an existing connection. A Stateless
Reset allows a peer to more quickly identify when a connection
becomes unusable.

Packets that are matched to an existing connection are discarded if
the packets are inconsistent with the state of that connection. For
example, packets are discarded if they indicate a different protocol
version than that of the connection or if the removal of packet
protection is unsuccessful once the expected keys are available.

Invalid packets that lack strong integrity protection, such as
Initial, Retry, or Version Negotiation, MAY be discarded. An
endpoint MUST generate a connection error if processing the contents
of these packets prior to discovering an error, or fully revert any
changes made during that processing.
Matching Packets to Connections
入包在接收时进行分类。数据包可能被关联到一个已存在的连接,也可能(在服务端)创建一个新连接。

终端尝试将数据包与现有连接关联起来。如果数据包有关联到一个已存在的连接的非零目标连接ID,QUIC将在相应连接上处理该数据包。注意一条连接可以对应不止一个连接ID,详见第5.1章。

如果一个数据包的目标连接ID是零长度的,而且其地址信息与终端用来标识零长度连接ID的连接匹配,则QUIC将该数据包作为该连接的一部分处理。终端可以只使用目标IP和端口,也可以同时使用源地址和目标地址作为标识,尽管这样会使连接像第5.1章描述的那样变得脆弱。

对任何不属于已存在连接的数据包,终端都可以发送一个无状态重置(第10.3章)。无状态重置使对端能更快地识别连接变得不可用的情况。

初始化、重试或版本协商这种缺乏强完整性保护的无效包可以被丢弃。如果终端在发生错误前处理了这些包的内容,终端必须产生一个连接错误,或完全恢复处理期间所做的所有变更。

5.2.1. Client Packet Handling

Valid packets sent to clients always include a Destination Connection
ID that matches a value the client selects. Clients that choose to
receive zero-length connection IDs can use the local address and port
to identify a connection. Packets that do not match an existing
connection – based on Destination Connection ID or, if this value is
zero length, local IP address and port – are discarded.

Due to packet reordering or loss, a client might receive packets for
a connection that are encrypted with a key it has not yet computed.
The client MAY drop these packets, or it MAY buffer them in
anticipation of later packets that allow it to compute the key.

If a client receives a packet that uses a different version than it
initially selected, it MUST discard that packet.

5.2.1 客户端数据包处理
发往客户端的有效数据包往往包含一个与客户端选择的值匹配的目标连接ID。选择接收零长度连接ID的客户端可以使用本地地址和端口识别一个连接。不能与已存在连接匹配的数据包——基于目标连接ID或目标连接ID为零长度时基于本地IP地址和端口——将被丢弃。

由于数据包乱序或丢失,客户端可能收到使用尚未算出的密钥加密的数据包。客户端可以丢弃这些包,也可以缓存起来以备后续数据包使其可以计算出密钥。

如果客户端收到一个包使用了与初始化阶段选择不同的QUIC版本,其必须丢弃该包。

5.2.2. Server Packet Handling

If a server receives a packet that indicates an unsupported version
and if the packet is large enough to initiate a new connection for
any supported version, the server SHOULD send a Version Negotiation
packet as described in Section 6.1. A server MAY limit the number of
packets to which it responds with a Version Negotiation packet.
Servers MUST drop smaller packets that specify unsupported versions.

The first packet for an unsupported version can use different
semantics and encodings for any version-specific field. In
particular, different packet protection keys might be used for
different versions. Servers that do not support a particular version
are unlikely to be able to decrypt the payload of the packet or
properly interpret the result. Servers SHOULD respond with a Version
Negotiation packet, provided that the datagram is sufficiently long.

Packets with a supported version, or no Version field, are matched to
a connection using the connection ID or – for packets with zero-
length connection IDs – the local address and port. These packets
are processed using the selected connection; otherwise, the server
continues as described below.

If the packet is an Initial packet fully conforming with the
specification, the server proceeds with the handshake (Section 7).
This commits the server to the version that the client selected.

If a server refuses to accept a new connection, it SHOULD send an
Initial packet containing a CONNECTION_CLOSE frame with error code
CONNECTION_REFUSED.

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
packet. Clients are not able to send Handshake packets prior to
receiving a server response, so servers SHOULD ignore any such
packets.

Servers MUST drop incoming packets under all other circumstances.

5.2.2 服务端数据包处理
如果服务端收到一个来自不支持版本的数据包而其又足够初始化某个支持版本的新连接,服务端应该发送一个版本协商包,详见第6.1章。服务端可以限制其回复的版本协商包的数量。服务端必须丢弃属于不支持版本的小包。

一个不支持版本的第一个包可以对任何与具体版本有关的字段使用不同语义和编码。尤其是不同的版本可能使用不同的数据包保护密钥。不支持一个特定版本的服务端不太可能解密数据包的有效负载或正确解释其内容。当数据报文足够长时,服务端应该回复一个版本协商包。

有一个支持版本或没有版本字段的数据包通过连接ID或——对于零长度连接ID的数据包——本地地址和端口与一个连接匹配,这些包在该连接上处理;否则,服务端继续做如下处理。

如果数据包是完全符合规范的初始化包,则服务端继续进行握手(第7章)。服务端会指派为客户端选择的版本。

如果服务端拒绝接收一个新连接,它应该发送一个带连接关闭帧的初始化包给客户端,其中连接关闭帧的错误码设置为CONNECTION_REFUSED(连接拒绝)。

如果数据包是一个0-RTT包,服务端可以进行有限数量的缓存,因为后续预期会收到初始化包。由于客户端不可能先于收到服务端回复发送握手包,所以服务端应该忽略任何这样的包。

服务端必须丢弃任何其他场合收到的数据包。

5.2.3. Considerations for Simple Load Balancers

A server deployment could load-balance among servers using only
source and destination IP addresses and ports. Changes to the
client’s IP address or port could result in packets being forwarded
to the wrong server. Such a server deployment could use one of the
following methods for connection continuity when a client’s address
changes.

  • Servers could use an out-of-band mechanism to forward packets to
    the correct server based on connection ID.

  • If servers can use a dedicated server IP address or port, other
    than the one that the client initially connects to, they could use
    the preferred_address transport parameter to request that clients
    move connections to that dedicated address. Note that clients
    could choose not to use the preferred address.

A server in a deployment that does not implement a solution to
maintain connection continuity when the client address changes SHOULD
indicate that migration is not supported by using the
disable_active_migration transport parameter. The
disable_active_migration transport parameter does not prohibit
connection migration after a client has acted on a preferred_address
transport parameter.

Server deployments that use this simple form of load balancing MUST
avoid the creation of a stateless reset oracle; see Section 21.11.

5.3. Operations on Connections

This document does not define an API for QUIC; it instead defines a
set of functions for QUIC connections that application protocols can
rely upon. An application protocol can assume that an implementation
of QUIC provides an interface that includes the operations described
in this section. An implementation designed for use with a specific
application protocol might provide only those operations that are
used by that protocol.

When implementing the client role, an application protocol can:

  • open a connection, which begins the exchange described in
    Section 7;

  • enable Early Data when available; and

  • be informed when Early Data has been accepted or rejected by a
    server.

When implementing the server role, an application protocol can:

  • listen for incoming connections, which prepares for the exchange
    described in Section 7;

  • if Early Data is supported, embed application-controlled data in
    the TLS resumption ticket sent to the client; and

  • if Early Data is supported, retrieve application-controlled data
    from the client’s resumption ticket and accept or reject Early
    Data based on that information.

In either role, an application protocol can:

  • configure minimum values for the initial number of permitted
    streams of each type, as communicated in the transport parameters
    (Section 7.4);

  • control resource allocation for receive buffers by setting flow
    control limits both for streams and for the connection;

  • identify whether the handshake has completed successfully or is
    still ongoing;

  • keep a connection from silently closing, by either generating PING
    frames (Section 19.2) or requesting that the transport send
    additional frames before the idle timeout expires (Section 10.1);
    and

  • immediately close (Section 10.2) the connection.

5.2.3 关于简单负载均衡
服务端部署可以仅仅使用源与目的IP地址和端口在服务器之间进行负载均衡。改变客户端IP地址或端口可能导致数据包被转发到错误的服务器上。这种服务端部署可以从如下方法中选择一个用于在客户端地址变换时维持连接。

服务端可以使用带外机制,根据连接ID将数据包转发到正确的服务器;
如果服务器可以使用固定的IP地址或端口,且不同于客户端初始建联时访问的那个,它们可以使用传输参数preferred_address(推荐地址)请求客户端迁移到那个固定的地址上。 注意客户端可以选择不使用推荐地址。
服务端的一台服务器如果不支持在客户端改变地址时维持连接,其应该通过传输参数disable_active_migration(关闭活动迁移)告知对端当前不支持连接迁移。在客户端预先拿到preferred_address参数后,传输参数disable_active_migration将不能阻止客户端进行连接迁移。

应用本简单形式负载均衡进行部署后,服务端必须避免创建无状态重置指示,详见第21.11章。
Operations on Connections
本文没有定义QUIC的API,而是定义了一系列有关QUIC连接的函数,用于应用层协议进行依赖。应用层协议可以假设一个QUIC的实现提供了一个包括本章所述操作的接口。针对一个特定应用层协议而设计的实现可能只提供该协议用到的那些操作。

当实现用户端时,应用层协议可以:

创建一个连接,开始进行第7章描述的交互过程;
如果支持,启用早期数据功能;
当早期数据被服务端接受或拒绝时,收到通知。
当实现服务端时,应用层协议可以:

监听传入的连接,准备进行第7章描述的交互过程;
如果支持早期数据,在发送给客户端的TLS恢复ticket中嵌入应用层控制数据;
如果支持早期数据,从接收自客户端的恢复ticket中恢复应用层控制数据,并根据该信息接受或拒绝早期数据。
当同时实现客户端及服务端时,应用层协议可以:

如传输参数(第7.4章)所述,为每种类型允许的流的配置最小的初始数量;
通过设置流级别及连接级别的流量控制限制,限制接收缓存区资源分配;
识别握手已经成功结束抑或仍在进行中;
保持连接不被默认关闭,即通过PING帧(第19.2章)或其他请求使得传输层在空闲超时(第10.1章)前发送额外的帧;以及
立即关闭连接(第10.2章)。

6. Version Negotiation

Version negotiation allows a server to indicate that it does not
support the version the client used. A server sends a Version
Negotiation packet in response to each packet that might initiate a
new connection; see Section 5.2 for details.

The size of the first packet sent by a client will determine whether
a server sends a Version Negotiation packet. Clients that support
multiple QUIC versions SHOULD ensure that the first UDP datagram they
send is sized to the largest of the minimum datagram sizes from all
versions they support, using PADDING frames (Section 19.1) as
necessary. This ensures that the server responds if there is a
mutually supported version. A server might not send a Version
Negotiation packet if the datagram it receives is smaller than the
minimum size specified in a different version; see Section 14.1.
Version Negotiation 版本协商。
版本协商使得服务端可以表明其不支持客户端使用的版本。服务端发送一个版本协商包用于回复任何可能导致创建新连接的数据包,更多细节详见第5.2章。

客户端发送的第一个包的大小决定服务端是否发送版本协商包。支持多个QUIC版本的客户端应该确保其发出的第一个UDP报文的大小合乎其支持的所有版本的最小数据报文大小中的最大值,必要时可以用填充帧补齐(第19.1章)。这确保如果有相互支持的版本,服务端能够响应。如果收到的报文小于一个不同版本的最小数据包大小,服务端可能不会发出版本协商包。

6.1. Sending Version Negotiation Packets

If the version selected by the client is not acceptable to the
server, the server responds with a Version Negotiation packet; see
Section 17.2.1. This includes a list of versions that the server
will accept. An endpoint MUST NOT send a Version Negotiation packet
in response to receiving a Version Negotiation packet.

This system allows a server to process packets with unsupported
versions without retaining state. Though either the Initial packet
or the Version Negotiation packet that is sent in response could be
lost, the client will send new packets until it successfully receives
a response or it abandons the connection attempt.

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.
发送版本协商包
如果客户端选择的版本服务端不接受,服务端会响应一个版本协商包,详见第17.2.1章。版本协商包包含一个服务端支持的版本的列表。终端必须不能给一个版本协商包回应一个版本协商包。

这个系统允许服务端处理不支持的数据包而不保持状态。即使作为响应发出的初始包或版本协商包都可能丢失,客户端也会发新的包直到收到回复或放弃建连尝试。

服务端可以限制其发送版本协商包的数量。例如,能识别0-RTT包的服务端可能会选择不发送版本协商包来响应0-RTT包,而是期望最终能收到初始包。

6.2. Handling Version Negotiation Packets

Version Negotiation packets are designed to allow for functionality
to be defined in the future that allows QUIC to negotiate the version
of QUIC to use for a connection. Future Standards Track
specifications might change how implementations that support multiple
versions of QUIC react to Version Negotiation packets received in
response to an attempt to establish a connection using this version.

A client that supports only this version of QUIC MUST abandon the
current connection attempt if it receives a Version Negotiation
packet, with the following two exceptions. A client MUST discard any
Version Negotiation packet if it has received and successfully
processed any other packet, including an earlier Version Negotiation
packet. A client MUST discard a Version Negotiation packet that
lists the QUIC version selected by the client.

How to perform version negotiation is left as future work defined by
future Standards Track specifications. In particular, that future
work will ensure robustness against version downgrade attacks; see
Section 21.12.
处理版本协商包
设计版本协商包的目的是为了让QUIC能够给未来定义的功能协商QUIC版本用于连接。未来标准追踪规范可能改变支持多版本QUIC对于收到的用于回复给试图使用这个版本建立连接的版本协商包进行应对的实现方式。

仅仅支持这个版本的客户端如果收到一个版本协商包,其必须放弃当前建联尝试,除非是下述两种例外:如果已经收到且成功处理任何其他类型的包,客户端必须忽略任何版本协商包;客户端必须忽略包含其选择的QUIC版本的版本协商包。

如何执行版本协商留作由未来标准追踪规范定义的未来工作。特别是,未来工作将确保在抵御版本降级攻击时具有健壮性,详见第21.12章。

6.3. Using Reserved Versions

For a server to use a new version in the future, clients need to
correctly handle unsupported versions. Some version numbers
(0x?a?a?a?a, as defined in Section 15) are reserved for inclusion in
fields that contain version numbers.

Endpoints MAY add reserved versions to any field where unknown or
unsupported versions are ignored to test that a peer correctly
ignores the value. For instance, an endpoint could include a
reserved version in a Version Negotiation packet; see Section 17.2.1.
Endpoints MAY send packets with a reserved version to test that a
peer correctly discards the packet.

使用预留的版本
对于将来使用新版本QUIC的服务端,客户端需要正确处理不支持的版本。一些版本号(如0x?a?a?a?a,见第15章)保留作包含版本号的字段。

终端可以添加保留版本到任意未知或不支持版本中会被忽略的字段,用以测试对端是否正确地忽略了该值。例如,终端可以发版本协商包中包含一个保留版本,详见第17.2.1章)。终端可以发送一个保留版本的数据包来测试对端是否会正确丢弃该包。

7. Cryptographic and Transport Handshake

QUIC relies on a combined cryptographic and transport handshake to
minimize connection establishment latency. QUIC uses the CRYPTO
frame (Section 19.6) to transmit the cryptographic handshake. The
version of QUIC defined in this document is identified as 0x00000001
and uses TLS as described in [QUIC-TLS]; a different QUIC version
could indicate that a different cryptographic handshake protocol is
in use.

QUIC provides reliable, ordered delivery of the cryptographic
handshake data. QUIC packet protection is used to encrypt as much of
the handshake protocol as possible. The cryptographic handshake MUST
provide the following properties:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*  authenticated key exchange, where

- a server is always authenticated,

- a client is optionally authenticated,

- every connection produces distinct and unrelated keys, and

- keying material is usable for packet protection for both 0-RTT
and 1-RTT packets.

* authenticated exchange of values for transport parameters of both
endpoints, and confidentiality protection for server transport
parameters (see Section 7.4).

* authenticated negotiation of an application protocol (TLS uses
Application-Layer Protocol Negotiation (ALPN) [ALPN] for this
purpose).

The CRYPTO frame can be sent in different packet number spaces
(Section 12.3). The offsets used by CRYPTO frames to ensure ordered
delivery of cryptographic handshake data start from zero in each
packet number space.

Figure 4 shows a simplified handshake and the exchange of packets and
frames that are used to advance the handshake. Exchange of
application data during the handshake is enabled where possible,
shown with an asterisk (“*”). Once the handshake is complete,
endpoints are able to exchange application data freely.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Client                                               Server

Initial (CRYPTO)
0-RTT (*) ---------->
Initial (CRYPTO)
Handshake (CRYPTO)
<---------- 1-RTT (*)
Handshake (CRYPTO)
1-RTT (*) ---------->
<---------- 1-RTT (HANDSHAKE_DONE)

1-RTT <=========> 1-RTT

Figure 4: Simplified QUIC Handshake

Endpoints can use packets sent during the handshake to test for
Explicit Congestion Notification (ECN) support; see Section 13.4. An
endpoint validates support for ECN by observing whether the ACK
frames acknowledging the first packets it sends carry ECN counts, as
described in Section 13.4.2.

Endpoints MUST explicitly negotiate an application protocol. This
avoids situations where there is a disagreement about the protocol
that is in use.

  1. Cryptographic and Transport Handshake

QUIC relies on a combined cryptographic and transport handshake to minimize connection establishment latency.
QUIC uses the CRYPTO frame (Section 19.6) to transmit the cryptographic handshake.
The version of QUIC defined in this document is identified as 0x00000001 and uses TLS as described in [QUIC-TLS]; a different QUIC version could indicate that a different cryptographic handshake protocol is in use.
QUIC 依靠组合的加密和传输握手来最小化连接建立延迟。
QUIC 使用 CRYPTO 帧(第 19.6 节)来传输加密握手。
本文档中定义的 QUIC 版本标识为 0x00000001,并使用 [QUIC-TLS] 中描述的 TLS;不同的 QUIC 版本可能表明正在使用不同的加密握手协议。
QUIC provides reliable, ordered delivery of the cryptographic handshake data.
QUIC packet protection is used to encrypt as much of the handshake protocol as possible.
The cryptographic handshake MUST provide the following properties:

  • authenticated key exchange, where
    • a server is always authenticated,
    • a client is optionally authenticated,
    • every connection produces distinct and unrelated keys, and
    • keying material is usable for packet protection for both 0-RTT and 1-RTT packets.
      QUIC 提供可靠、有序的加密握手数据交付。
      QUIC 数据包保护用于尽可能多地加密握手协议。
      加密握手必须提供以下属性:

*经过身份验证的密钥交换,其中
- 服务器始终经过身份验证,
- 客户端可选地进行身份验证,
- 每个连接都会产生不同且不相关的键,并且
- 密钥材料可用于 0-RTT 和 1-RTT 数据包的数据包保护。

  • authenticated exchange of values for transport parameters of both endpoints, and confidentiality protection for server transport parameters (see Section 7.4).

  • authenticated negotiation of an application protocol (TLS uses Application-Layer Protocol Negotiation (ALPN) [ALPN] for this purpose).

  • 两个端点的传输参数值的认证交换,以及服务器传输参数的机密性保护(参见第 7.4 节)。

    • 应用协议的经过身份验证的协商(TLS 使用应用层协议协商 (ALPN) [ALPN] 为此目的)。
      The CRYPTO frame can be sent in different packet number spaces (Section 12.3).
      The offsets used by CRYPTO frames to ensure ordered delivery of cryptographic handshake data start from zero in each packet number space.

    Figure 4 shows a simplified handshake and the exchange of packets and frames that are used to advance the handshake.
    Exchange of application data during the handshake is enabled where possible, shown with an asterisk (“*”).
    Once the handshake is complete, endpoints are able to exchange application data freely.

CRYPTO 帧可以在不同的包号空间中发送(第 12.3 节)。
CRYPTO 帧使用的偏移量以确保加密握手数据的有序传递在每个数据包编号空间中从零开始。

图 4 显示了简化的握手以及用于推进握手的数据包和帧的交换。
在可能的情况下启用握手期间的应用程序数据交换,用星号 (“*”) 显示。
一旦握手完成,端点就可以自由地交换应用程序数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Client                                               Server

Initial (CRYPTO)
0-RTT (*) ---------->
Initial (CRYPTO)
Handshake (CRYPTO)
<---------- 1-RTT (*)
Handshake (CRYPTO)
1-RTT (*) ---------->
<---------- 1-RTT (HANDSHAKE_DONE)

1-RTT <=========> 1-RTT

Figure 4: Simplified QUIC Handshake

Endpoints can use packets sent during the handshake to test for Explicit Congestion Notification (ECN) support; see Section 13.4.
An endpoint validates support for ECN by observing whether the ACK frames acknowledging the first packets it sends carry ECN counts, as described in Section 13.4.2.

Endpoints MUST explicitly negotiate an application protocol.
This avoids situations where there is a disagreement about the protocol that is in use.
端点可以使用握手期间发送的数据包来测试显式拥塞通知 (ECN) 支持; 见第 13.4 节。
端点通过观察确认它发送的第一个数据包的 ACK 帧是否携带 ECN 计数来验证对 ECN 的支持,如第 13.4.2 节所述。

端点必须明确协商应用协议。

这避免了对正在使用的协议存在分歧的情况。

7.1. Example Handshake Flows

Details of how TLS is integrated with QUIC are provided in [QUIC-TLS], but some examples are provided here.
An extension of this exchange to support client address validation is shown in Section 8.1.2.
[QUIC-TLS] 中提供了 TLS 如何与 QUIC 集成的详细信息,但此处提供了一些示例。
此交换的扩展以支持客户端地址验证显示在第 8.1.2 节中。
Once any address validation exchanges are complete, the cryptographic handshake is used to agree on cryptographic keys.
The cryptographic handshake is carried in Initial (Section 17.2.2) and Handshake (Section 17.2.4) packets.
一旦任何地址验证交换完成,加密握手将用于就加密密钥达成一致。
加密握手在初始(第 17.2.2 节)和握手(第 17.2.4 节)数据包中携带。
Figure 5 provides an overview of the 1-RTT handshake.
Each line shows a QUIC packet with the packet type and packet number shown first, followed by the frames that are typically contained in those packets.
For instance, the first packet is of type Initial, with packet number 0, and contains a CRYPTO frame carrying the ClientHello.
图 5 提供了 1-RTT 握手的概述。
每行显示一个 QUIC 数据包,首先显示数据包类型和数据包编号,然后是通常包含在这些数据包中的帧。
例如,第一个数据包的类型为 Initial,数据包编号为 0,并包含一个携带 ClientHello 的 CRYPTO 帧。
Multiple QUIC packets – even of different packet types – can be coalesced into a single UDP datagram; see Section 12.2.
As a result, this handshake could consist of as few as four UDP datagrams, or any number more (subject to limits inherent to the protocol, such as congestion control and anti-amplification).
For instance, the server’s first flight contains Initial packets, Handshake packets, and “0.5-RTT data” in 1-RTT packets.
多个 QUIC 数据包——即使是不同类型的数据包——可以合并为一个 UDP 数据报;见第 12.2 节。
因此,此握手可能包含少至四个 UDP 数据报,或者更多(受协议固有的限制,例如拥塞控制和反放大)。
例如,服务器的第一次飞行包含初始数据包、握手数据包和 1-RTT 数据包中的“0.5-RTT 数据”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Client                                                  Server

Initial[0]: CRYPTO[CH] ->

Initial[0]: CRYPTO[SH] ACK[0]
Handshake[0]: CRYPTO[EE, CERT, CV, FIN]
<- 1-RTT[0]: STREAM[1, "..."]

Initial[1]: ACK[0]
Handshake[0]: CRYPTO[FIN], ACK[0]
1-RTT[0]: STREAM[0, "..."], ACK[0] ->

Handshake[1]: ACK[0]
<- 1-RTT[1]: HANDSHAKE_DONE, STREAM[3, "..."], ACK[0]

Figure 5: Example 1-RTT Handshake

Figure 6 shows an example of a connection with a 0-RTT handshake and
a single packet of 0-RTT data. Note that as described in
Section 12.3, the server acknowledges 0-RTT data in 1-RTT packets,
and the client sends 1-RTT packets in the same packet number space.
图 6 显示了一个使用 0-RTT 握手和连接的示例
一个 0-RTT 数据包。 请注意,如中所述
第 12.3 节,服务器在 1-RTT 数据包中确认 0-RTT 数据,
客户端在相同的包号空间发送 1-RTT 包。 之所以说是0-RTT,是因为最开始的Initial包就包含了STREAM实际数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Client                                                  Server

Initial[0]: CRYPTO[CH]
0-RTT[0]: STREAM[0, "..."] ->

Initial[0]: CRYPTO[SH] ACK[0]
Handshake[0] CRYPTO[EE, FIN]
<- 1-RTT[0]: STREAM[1, "..."] ACK[0]

Initial[1]: ACK[0]
Handshake[0]: CRYPTO[FIN], ACK[0]
1-RTT[1]: STREAM[0, "..."] ACK[0] ->

Handshake[1]: ACK[0]
<- 1-RTT[1]: HANDSHAKE_DONE, STREAM[3, "..."], ACK[1]

Figure 6: Example 0-RTT Handshake
7.2. Negotiating Connection IDs 协商连接 ID

A connection ID is used to ensure consistent routing of packets, as described in Section 5.1.
The long header contains two connection IDs: the Destination Connection ID is chosen by the recipient of the packet and is used to provide consistent routing; the Source Connection ID is used to set the Destination Connection ID used by the peer.
如第 5.1 节所述,连接 ID 用于确保数据包的一致路由。
长头包含两个连接 ID:目标连接 ID 由数据包的接收者选择,用于提供一致的路由; Source Connection ID 用于设置对端使用的 Destination Connection ID。
During the handshake, packets with the long header (Section 17.2) are used to establish the connection IDs used by both endpoints.
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.
After processing the first Initial packet, each endpoint sets the Destination Connection ID field in subsequent packets it sends to the value of the Source Connection ID field that it received.
在握手期间,带有长报头(第 17.2 节)的数据包用于建立两个端点使用的连接 ID。
每个端点使用源连接 ID 字段来指定在发送给它们的数据包的目标连接 ID 字段中使用的连接 ID。
处理完第一个初始数据包后,每个端点将其发送的后续数据包中的目标连接 ID 字段设置为它收到的源连接 ID 字段的值。
When an Initial packet is sent by a client that has not previously received an Initial or Retry packet from the server, the client populates the Destination Connection ID field with an unpredictable value.
This Destination Connection ID MUST be at least 8 bytes in length.
Until a packet is received from the server, the client MUST use the same Destination Connection ID value on all packets in this connection.
当一个初始包由一个以前没有从服务器接收到一个初始包或重试包的客户端发送时,客户端用一个不可预知的值填充目标连接 ID 字段。
此目标连接 ID 的长度必须至少为 8 个字节。
在从服务器接收到数据包之前,客户端必须在此连接中的所有数据包上使用相同的目标连接 ID 值。
The Destination Connection ID field from the first Initial packet sent by a client is used to determine packet protection keys for Initial packets.
These keys change after receiving a Retry packet; see Section 5.2 of [QUIC-TLS].
客户端发送的第一个初始数据包的目标连接 ID 字段用于确定初始数据包的数据包保护密钥。
这些密钥在收到重试数据包后发生变化;请参阅 [QUIC-TLS] 的第 5.2 节。
The client populates the Source Connection ID field with a value of its choosing and sets the Source Connection ID Length field to indicate the length.
客户端使用其选择的值填充源连接 ID 字段,并设置源连接 ID 长度字段以指示长度。
0-RTT packets in the first flight use the same Destination Connection
ID and Source Connection ID values as the client’s first Initial packet.
第一次飞行中的 0-RTT 数据包使用相同的目标连接
ID 和源连接 ID 值作为客户端的第一个初始数据包。
Upon first receiving an Initial or Retry packet from the server, the client uses the Source Connection ID supplied by the server as the Destination Connection ID for subsequent packets, including any 0-RTT packets.
This means that a client might have to change the connection ID it sets in the Destination Connection ID field twice during connection establishment: once in response to a Retry packet and once in response to an Initial packet from the server.
Once a client has received a valid Initial packet from the server, it MUST discard any subsequent packet it receives on that connection with a different Source Connection ID.
在第一次从服务器接收到初始或重试数据包时,客户端使用服务器提供的源连接 ID 作为后续数据包的目标连接 ID,包括任何 0-RTT 数据包。
这意味着客户端可能必须在连接建立期间两次更改其在目标连接 ID 字段中设置的连接 ID:一次是响应重试数据包,一次是响应来自服务器的初始数据包。
一旦客户端从服务器接收到有效的初始数据包,它必须丢弃它在该连接上接收到的具有不同源连接 ID 的任何后续数据包。
A client MUST change the Destination Connection ID it uses for sending packets in response to only the first received Initial or Retry packet.
A server MUST set the Destination Connection ID it uses for sending packets based on the first received Initial packet.
Any further changes to the Destination Connection ID are only permitted if the values are taken from NEW_CONNECTION_ID frames; if subsequent Initial packets include a different Source Connection ID, they MUST be discarded.
This avoids unpredictable outcomes that might otherwise result from stateless processing of multiple Initial packets with different Source Connection IDs.
客户端必须更改它用于发送数据包的目标连接 ID,以仅响应第一个接收到的初始或重试数据包。
服务器必须根据第一个收到的初始数据包设置它用于发送数据包的目标连接 ID。
只有当值取自 NEW_CONNECTION_ID 帧时,才允许对目标连接 ID 进行任何进一步的更改;如果后续的初始数据包包含不同的源连接 ID,则必须丢弃它们。
这避免了由于对具有不同源连接 ID 的多个初始数据包进行无状态处理而可能导致的不可预测的结果。
The Destination Connection ID that an endpoint sends can change over the lifetime of a connection, especially in response to connection migration (Section 9); see Section 5.1.1 for details.
端点发送的目标连接 ID 可以在连接的生命周期内发生变化,尤其是在响应连接迁移时(第 9 节);有关详细信息,请参见第 5.1.1 节。

7.3. Authenticating Connection IDs

验证连接 ID
The choice each endpoint makes about connection IDs during the handshake is authenticated by including all values in transport parameters; see Section 7.4.
This ensures that all connection IDs used for the handshake are also authenticated by the cryptographic handshake.
通过在传输参数中包含所有值来验证每个端点在握手期间对连接 ID 所做的选择;见第 7.4 节。
这可确保用于握手的所有连接 ID 也通过加密握手进行身份验证。
Each endpoint includes the value of the Source Connection ID field from the first Initial packet it sent in the initial_source_connection_id transport parameter; see Section 18.2.
A server includes the Destination Connection ID field from the first Initial packet it received from the client in the original_destination_connection_id transport parameter; if the server sent a Retry packet, this refers to the first Initial packet received before sending the Retry packet.
If it sends a Retry packet, a server also includes the Source Connection ID field from the Retry packet in the retry_source_connection_id transport parameter.
每个端点都包含来自它在 initial_source_connection_id 传输参数中发送的第一个初始数据包的源连接 ID 字段的值;见第 18.2 节。
服务器在 original_destination_connection_id 传输参数中包含来自它从客户端接收到的第一个初始数据包的目标连接 ID 字段;如果服务器发送了重试包,这是指在发送重试包之前收到的第一个初始包。
如果它发送重试数据包,服务器还会在 retry_source_connection_id 传输参数中包含来自重试数据包的源连接 ID 字段。

The values provided by a peer for these transport parameters MUST match the values that an endpoint used in the Destination and Source Connection ID fields of Initial packets that it sent (and received, for servers).
Endpoints MUST validate that received transport parameters match received connection ID values.
Including connection ID values in transport parameters and verifying them ensures that an attacker cannot influence the choice of connection ID for a successful connection by injecting packets carrying attacker-chosen connection IDs during the handshake.
对等体为这些传输参数提供的值必须与端点在它发送(和接收,对于服务器)的初始数据包的目标和源连接 ID 字段中使用的值匹配。
端点必须验证接收到的传输参数是否与接收到的连接 ID 值匹配。
在传输参数中包含连接 ID 值并对其进行验证,可确保攻击者无法通过在握手期间注入携带攻击者选择的连接 ID 的数据包来影响连接 ID 的选择以实现成功连接。

An endpoint MUST treat the absence of the initial_source_connection_id transport parameter from either endpoint or the absence of the original_destination_connection_id transport parameter from the server as a connection error of type TRANSPORT_PARAMETER_ERROR.
端点必须将任一端点缺少 initial_source_connection_id 传输参数或服务器缺少 original_destination_connection_id 传输参数视为 TRANSPORT_PARAMETER_ERROR 类型的连接错误。
An endpoint MUST treat the following as a connection error of type TRANSPORT_PARAMETER_ERROR or PROTOCOL_VIOLATION:

  • absence of the retry_source_connection_id transport parameter from the server after receiving a Retry packet,
  • presence of the retry_source_connection_id transport parameter when no Retry packet was received, or
  • a mismatch between values received from a peer in these transport parameters and the value sent in the corresponding Destination or Source Connection ID fields of Initial packets.
    端点必须将以下内容视为 TRANSPORT_PARAMETER_ERROR 或 PROTOCOL_VIOLATION 类型的连接错误:
  • 收到重试数据包后,服务器缺少 retry_source_connection_id 传输参数,
  • 当没有接收到重试数据包时存在 retry_source_connection_id 传输参数,或者
  • 在这些传输参数中从对等方接收的值与在初始数据包的相应目标或源连接 ID 字段中发送的值之间不匹配。

If a zero-length connection ID is selected, the corresponding transport parameter is included with a zero-length value.

Figure 7 shows the connection IDs (with DCID=Destination Connection ID, SCID=Source Connection ID) that are used in a complete handshake.
The exchange of Initial packets is shown, plus the later exchange of 1-RTT packets that includes the connection ID established during the
handshake.
如果选择了零长度连接 ID,则相应的传输参数包含一个零长度值。

图 7 显示了在完整握手中使用的连接 ID(DCID=Destination Connection ID,SCID=Source Connection ID)。
显示了初始数据包的交换,以及随后的 1-RTT 数据包交换,其中包括在握手期间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Client                                                  Server

Initial: DCID=S1, SCID=C1 ->
<- Initial: DCID=C1, SCID=S3
...
1-RTT: DCID=S3 ->
<- 1-RTT: DCID=C1

Figure 7: Use of Connection IDs in a Handshake

Figure 8 shows a similar handshake that includes a Retry packet.

Client Server

Initial: DCID=S1, SCID=C1 ->
<- Retry: DCID=C1, SCID=S2
Initial: DCID=S2, SCID=C1 ->
<- Initial: DCID=C1, SCID=S3
...
1-RTT: DCID=S3 ->
<- 1-RTT: DCID=C1

Figure 8: Use of Connection IDs in a Handshake with Retry

In both cases (Figures 7 and 8), the client sets the value of the initial_source_connection_id transport parameter to “C1”.
在这两种情况下(图 7 和图 8),客户端都将 initial_source_connection_id 传输参数的值设置为“C1”。
When the handshake does not include a Retry (Figure 7), the server sets original_destination_connection_id to “S1” (note that this value is chosen by the client) and initial_source_connection_id to “S3”.
In this case, the server does not include a retry_source_connection_id transport parameter.
当握手不包括重试时(图 7),服务器将 original_destination_connection_id 设置为“S1”(注意该值由客户端选择)并将 initial_source_connection_id 设置为“S3”。
在这种情况下,服务器不包含 retry_source_connection_id 传输参数。
When the handshake includes a Retry (Figure 8), the server sets original_destination_connection_id to “S1”, retry_source_connection_id to “S2”, and initial_source_connection_id to “S3”.
当握手包括重试时(图 8),服务器将 original_destination_connection_id 设置为“S1”,retry_source_connection_id 设置为“S2”,并将 initial_source_connection_id 设置为“S3”。
In both cases (Figures 7 and 8), the client sets the value of the initial_source_connection_id transport parameter to “C1”.
在这两种情况下(图 7 和图 8),客户端都将 initial_source_connection_id 传输参数的值设置为“C1”。
When the handshake does not include a Retry (Figure 7), the server sets original_destination_connection_id to “S1” (note that this value is chosen by the client) and initial_source_connection_id to “S3”.
In this case, the server does not include a retry_source_connection_id transport parameter.
当握手不包括重试时(图 7),服务器将 original_destination_connection_id 设置为“S1”(注意该值由客户端选择)并将 initial_source_connection_id 设置为“S3”。
在这种情况下,服务器不包含 retry_source_connection_id 传输参数。
When the handshake includes a Retry (Figure 8), the server sets original_destination_connection_id to “S1”, retry_source_connection_id to “S2”, and initial_source_connection_id to “S3”.
当握手包括重试时(图 8),服务器将 original_destination_connection_id 设置为“S1”,retry_source_connection_id 设置为“S2”,并将 initial_source_connection_id 设置为“S3”。

7.4. Transport Parameters

During connection establishment, both endpoints make authenticated declarations of their transport parameters.
Endpoints are required to comply with the restrictions that each parameter defines; the description of each parameter includes rules for its handling.
在连接建立期间,两个端点都对其传输参数进行经过身份验证的声明。
端点必须遵守每个参数定义的限制;每个参数的描述包括其处理规则。
Transport parameters are declarations that are made unilaterally by each endpoint.
Each endpoint can choose values for transport parameters independent of the values chosen by its peer.
传输参数是每个端点单方面做出的声明。
每个端点都可以选择独立于其对等点选择的值的传输参数值。
The encoding of the transport parameters is detailed in Section 18.
传输参数的编码详见第 18 节。
QUIC includes the encoded transport parameters in the cryptographic handshake.
Once the handshake completes, the transport parameters declared by the peer are available.
Each endpoint validates the values provided by its peer.
QUIC 在加密握手中包含编码的传输参数。
握手完成后,对等方声明的传输参数可用。
每个端点验证其对等方提供的值。
Definitions for each of the defined transport parameters are included in Section 18.2.
每个已定义的传输参数的定义都包含在第 18.2 节中。
An endpoint MUST treat receipt of a transport parameter with an invalid value as a connection error of type TRANSPORT_PARAMETER_ERROR.
端点必须将接收到具有无效值的传输参数视为 TRANSPORT_PARAMETER_ERROR 类型的连接错误。
An endpoint MUST NOT send a parameter more than once in a given transport parameters extension.
An endpoint SHOULD treat receipt of duplicate transport parameters as a connection error of type TRANSPORT_PARAMETER_ERROR.
端点不能在给定的传输参数扩展中多次发送参数。
端点应该将接收到重复的传输参数视为 TRANSPORT_PARAMETER_ERROR 类型的连接错误。
Endpoints use transport parameters to authenticate the negotiation of connection IDs during the handshake; see Section 7.3.
端点在握手期间使用传输参数来验证连接 ID 的协商;见第 7.3 节。
ALPN (see [ALPN]) allows clients to offer multiple application protocols during connection establishment.
The transport parameters that a client includes during the handshake apply to all application protocols that the client offers.
Application protocols can recommend values for transport parameters, such as the initial flow control limits.
However, application protocols that set constraints on values for transport parameters could make it impossible for a client to offer multiple application protocols if these constraints conflict.
ALPN(参见 [ALPN])允许客户端在连接建立期间提供多种应用协议。
客户端在握手期间包含的传输参数适用于客户端提供的所有应用程序协议。
应用程序协议可以推荐传输参数的值,例如初始流量控制限制。
但是,如果应用程序协议对传输参数的值设置了约束,则如果这些约束冲突,客户端可能无法提供多个应用程序协议。

7.4.1. Values of Transport Parameters for 0-RTT

Using 0-RTT depends on both client and server using protocol parameters that were negotiated from a previous connection.
To enable 0-RTT, endpoints store the values of the server transport parameters with any session tickets it receives on the connection.
Endpoints also store any information required by the application protocol or cryptographic handshake; see Section 4.6 of [QUIC-TLS].
The values of stored transport parameters are used when attempting 0-RTT using the session tickets.
使用 0-RTT 取决于客户端和服务器都使用从先前连接协商的协议参数。
为了启用 0-RTT,端点将服务器传输参数的值与它在连接上收到的任何会话票证一起存储。
端点还存储应用协议或加密握手所需的任何信息;请参阅 [QUIC-TLS] 的第 4.6 节。
使用会话票证尝试 0-RTT 时使用存储的传输参数的值。

Remembered transport parameters apply to the new connection until the handshake completes and the client starts sending 1-RTT packets.
Once the handshake completes, the client uses the transport parameters established in the handshake.
Not all transport parameters are remembered, as some do not apply to future connections or they have no effect on the use of 0-RTT.
记住的传输参数适用于新连接,直到握手完成并且客户端开始发送 1-RTT 数据包。
握手完成后,客户端使用握手中建立的传输参数。
并非所有传输参数都会被记住,因为有些参数不适用于未来的连接,或者它们对 0-RTT 的使用没有影响。
The definition of a new transport parameter (Section 7.4.2) MUST specify whether storing the transport parameter for 0-RTT is mandatory, optional, or prohibited.
A client need not store a transport parameter it cannot process.
新传输参数的定义(第 7.4.2 节)必须指定存储 0-RTT 的传输参数是强制的、可选的还是禁止的。
客户端不需要存储它无法处理的传输参数。
A client MUST NOT use remembered values for the following parameters: ack_delay_exponent, max_ack_delay, initial_source_connection_id, original_destination_connection_id, preferred_address, retry_source_connection_id, and stateless_reset_token.
The client MUST use the server’s new values in the handshake instead; if the server does not provide new values, the default values are used.
客户端不得为以下参数使用记忆值:ack_delay_exponent、max_ack_delay、initial_source_connection_id、original_destination_connection_id、preferred_address、retry_source_connection_id 和 stateless_reset_token。
客户端必须在握手中使用服务器的新值;如果服务器不提供新值,则使用默认值。
A client that attempts to send 0-RTT data MUST remember all other transport parameters used by the server that it is able to process.
The server can remember these transport parameters or can store an integrity-protected copy of the values in the ticket and recover the information when accepting 0-RTT data.
A server uses the transport parameters in determining whether to accept 0-RTT data.
尝试发送 0-RTT 数据的客户端必须记住它能够处理的服务器使用的所有其他传输参数。
服务器可以记住这些传输参数,或者可以在票证中存储受完整性保护的值副本,并在接受 0-RTT 数据时恢复信息。
服务器使用传输参数来确定是否接受 0-RTT 数据。
If 0-RTT 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 0-RTT data.
In particular, a server that accepts 0-RTT data MUST NOT set values for the following parameters (Section 18.2) that are smaller than the remembered values of the parameters.
如果服务器接受 0-RTT 数据,则服务器不得减少任何限制或更改客户端可能使用其 0-RTT 数据违反的任何值。
特别是,接受 0-RTT 数据的服务器不得为以下参数(第 18.2 节)设置小于参数的记忆值的值。

1
2
3
4
5
6
7
*  active_connection_id_limit
* initial_max_data
* initial_max_stream_data_bidi_local
* initial_max_stream_data_bidi_remote
* initial_max_stream_data_uni
* initial_max_streams_bidi
* initial_max_streams_uni

Omitting or setting a zero value for certain transport parameters can result in 0-RTT data being enabled but not usable.
The applicable subset of transport parameters that permit the sending of application data SHOULD be set to non-zero values for 0-RTT.
This includes initial_max_data and either (1) initial_max_streams_bidi and initial_max_stream_data_bidi_remote or (2) initial_max_streams_uni and initial_max_stream_data_uni.
为某些传输参数省略或设置零值会导致 0-RTT 数据被启用但不可用。
对于 0-RTT,允许发送应用数据的传输参数的适用子集应该设置为非零值。
这包括 initial_max_data 和 (1) initial_max_streams_bidi 和 initial_max_stream_data_bidi_remote 或 (2) initial_max_streams_uni 和 initial_max_stream_data_uni。

A server might provide larger initial stream flow control limits for streams than the remembered values that a client applies when sending 0-RTT. Once the handshake completes, the client updates the flow
control limits on all sending streams using the updated values of initial_max_stream_data_bidi_remote and initial_max_stream_data_uni.
服务器可能会为流提供比客户端在发送 0-RTT 时应用的记住值更大的初始流流控制限制。握手完成后,客户端更新流程
使用 initial_max_stream_data_bidi_remote 和 initial_max_stream_data_uni 的更新值控制所有发送流的限制。
A server MAY store and recover the previously sent values of the max_idle_timeout, max_udp_payload_size, and disable_active_migration parameters and reject 0-RTT if it selects smaller values.
Lowering the values of these parameters while also accepting 0-RTT data could degrade the performance of the connection.
Specifically, lowering the max_udp_payload_size could result in dropped packets, leading to worse performance compared to rejecting 0-RTT data outright.
服务器可以存储和恢复先前发送的 max_idle_timeout、max_udp_payload_size 和 disable_active_migration 参数的值,如果选择较小的值,则拒绝 0-RTT。
在接受 0-RTT 数据的同时降低这些参数的值可能会降低连接的性能。
具体来说,降低 max_udp_payload_size 可能会导致丢包,与直接拒绝 0-RTT 数据相比,会导致更差的性能。
A server MUST reject 0-RTT data if the restored values for transport parameters cannot be supported.
如果不能支持传输参数的恢复值,服务器必须拒绝 0-RTT 数据。
When sending frames in 0-RTT packets, a client MUST only use remembered transport parameters; importantly, it MUST NOT use updated values that it learns from the server’s updated transport parameters or from frames received in 1-RTT packets.
Updated values of transport parameters from the handshake apply only to 1-RTT packets.
For instance, flow control limits from remembered transport parameters apply to all 0-RTT packets even if those values are increased by the handshake or by frames sent in 1-RTT packets.
A server MAY treat the use of updated transport parameters in 0-RTT as a connection error of type PROTOCOL_VIOLATION.
在 0-RTT 包中发送帧时,客户端必须只使用记住的传输参数;重要的是,它绝不能使用从服务器更新的传输参数或从 1-RTT 数据包中接收的帧中学习到的更新值。
握手中传输参数的更新值仅适用于 1-RTT 数据包。
例如,来自记住传输参数的流量控制限制适用于所有 0-RTT 数据包,即使这些值因握手或 1-RTT 数据包中发送的帧而增加。
服务器可以将 0-RTT 中更新的传输参数的使用视为 PROTOCOL_VIOLATION 类型的连接错误。

7.4.2. New Transport Parameters

New transport parameters can be used to negotiate new protocol behavior.
An endpoint MUST ignore transport parameters that it does not support.
The absence of a transport parameter therefore disables any optional protocol feature that is negotiated using the parameter.
As described in Section 18.1, some identifiers are reserved in order to exercise this requirement.
新的传输参数可用于协商新的协议行为。
端点必须忽略它不支持的传输参数。
因此,缺少传输参数会禁用使用该参数协商的任何可选协议功能。
如第 18.1 节所述,保留一些标识符以执行此要求。
A client that does not understand a transport parameter can discard it and attempt 0-RTT on subsequent connections.
However, if the client adds support for a discarded transport parameter, it risks violating the constraints that the transport parameter establishes if it attempts 0-RTT.
New transport parameters can avoid this problem by setting a default of the most conservative value.
Clients can avoid this problem by remembering all parameters, even those not currently supported.
不理解传输参数的客户端可以丢弃它并在后续连接上尝试 0-RTT。
但是,如果客户端添加对丢弃的传输参数的支持,则它可能会违反传输参数在尝试 0-RTT 时建立的约束。
新的传输参数可以通过设置一个最保守的默认值来避免这个问题。
客户可以通过记住所有参数来避免这个问题,即使是那些当前不支持的参数。
New transport parameters can be registered according to the rules in Section 22.3.

7.5. Cryptographic Message Buffering

Implementations need to maintain a buffer of CRYPTO data received out of order.
Because there is no flow control of CRYPTO frames, an endpoint could potentially force its peer to buffer an unbounded amount of data.
实现需要维护一个无序接收的 CRYPTO 数据的缓冲区。
因为没有 CRYPTO 帧的流量控制,端点可能会强制其对等方缓冲无限量的数据。
Implementations MUST support buffering at least 4096 bytes of data received in out-of-order CRYPTO frames.
Endpoints MAY choose to allow more data to be buffered during the handshake.
A larger limit during the handshake could allow for larger keys or credentials to be exchanged.
An endpoint’s buffer size does not need to remain constant during the life of the connection.
实现必须支持缓冲在乱序 CRYPTO 帧中接收到的至少 4096 字节的数据。
端点可以选择允许在握手期间缓冲更多数据。
握手期间的较大限制可能允许交换较大的密钥或凭据。
端点的缓冲区大小不需要在连接的生命周期内保持不变。
Being unable to buffer CRYPTO frames during the handshake can lead to a connection failure.
If an endpoint’s buffer is exceeded during the handshake, it can expand its buffer temporarily to complete the handshake.
If an endpoint does not expand its buffer, it MUST close the connection with a CRYPTO_BUFFER_EXCEEDED error code.
在握手期间无法缓冲 CRYPTO 帧可能会导致连接失败。
如果在握手过程中超出了端点的缓冲区,它可以临时扩展其缓冲区以完成握手。
如果端点不扩展其缓冲区,它必须关闭连接并使用 CRYPTO_BUFFER_EXCEEDED 错误代码。
Once the handshake completes, if an endpoint is unable to buffer all data in a CRYPTO frame, it MAY discard that CRYPTO frame and all CRYPTO frames received in the future, or it MAY close the connection with a CRYPTO_BUFFER_EXCEEDED error code.
Packets containing discarded CRYPTO frames MUST be acknowledged because the packet has been received and processed by the transport even though the CRYPTO frame was discarded.
一旦握手完成,如果端点无法缓冲 CRYPTO 帧中的所有数据,它可能会丢弃该 CRYPTO 帧和将来收到的所有 CRYPTO 帧,或者它可能会关闭连接并返回 CRYPTO_BUFFER_EXCEEDED 错误代码。
必须确认包含丢弃的 CRYPTO 帧的数据包,因为即使 CRYPTO 帧已被丢弃,传输也已接收并处理了该数据包。

8. Address Validation 验证

Address validation ensures that an endpoint cannot be used for a traffic amplification attack.
In such an attack, a packet is sent to a 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.
地址验证确保端点不能用于流量放大攻击。
在这种攻击中,数据包被发送到服务器,其中包含识别受害者的欺骗源地址信息。
如果服务器生成更多或更大的数据包以响应该数据包,则攻击者可以使用服务器向受害者发送比它自己能够发送的数据更多的数据。
The primary defense against amplification attacks is verifying that a peer is able to receive packets at the transport address that it claims.
Therefore, after receiving packets from an address that is not yet validated, an endpoint MUST limit the amount of data it sends to the unvalidated address to three times the amount of data received from that address.
This limit on the size of responses is known as the anti-amplification limit.
针对放大攻击的主要防御措施是验证对等方是否能够在其声称的传输地址处接收数据包。
因此,在从尚未验证的地址接收数据包后,端点必须将其发送到未验证地址的数据量限制为从该地址接收的数据量的三倍。
这种对响应大小的限制称为抗放大限制。
Address validation is performed both during connection establishment (see Section 8.1) and during connection migration (see Section 8.2).
地址验证在连接建立期间(参见第 8.1 节)和连接迁移期间(参见第 8.2 节)执行。

8.1. Address Validation during Connection Establishment

Connection establishment implicitly provides address validation for both endpoints.
In particular, receipt of a packet protected with Handshake keys confirms that the peer successfully processed an Initial packet.
Once an endpoint has successfully processed a Handshake packet from the peer, it can consider the peer address to have been validated.
连接建立隐含地为两个端点提供地址验证。
特别是,收到受握手密钥保护的数据包确认对等方成功处理了初始数据包。
一旦端点成功处理了来自对等方的握手数据包,它就可以认为对等方地址已经过验证。
Additionally, an endpoint MAY consider the peer address validated if the peer uses a connection ID chosen by the endpoint and the connection ID contains at least 64 bits of entropy.
此外,如果对等点使用端点选择的连接 ID 并且连接 ID 包含至少 64 位熵,则端点可以认为对等点地址已验证。
For the client, the value of the Destination Connection ID field in its first Initial packet allows it to validate the server address as a part of successfully processing any packet.
Initial packets from the server are protected with keys that are derived from this value (see Section 5.2 of [QUIC-TLS]).
Alternatively, the value is echoed by the server in Version Negotiation packets (Section 6) or included in the Integrity Tag in Retry packets (Section 5.8 of [QUIC-TLS]).
对于客户端,它的第一个初始数据包中的目标连接 ID 字段的值允许它验证服务器地址,作为成功处理任何数据包的一部分。
来自服务器的初始数据包使用从该值派生的密钥进行保护(参见 [QUIC-TLS] 的第 5.2 节)。
或者,该值由服务器在版本协商数据包(第 6 节)中回显,或包含在重试数据包中的完整性标签中([QUIC-TLS] 的第 5.8 节)。

Prior to validating the client address, servers MUST NOT send more than three times as many bytes as the number of bytes they have received.
This limits the magnitude of any amplification attack that can be mounted using spoofed source addresses.
For the purposes of avoiding amplification prior to address validation, servers MUST count all of the payload bytes received in datagrams that are uniquely attributed to a single connection.
This includes datagrams that contain packets that are successfully processed and datagrams that contain packets that are all discarded.
在验证客户端地址之前,服务器发送的字节数不得超过它们收到的字节数的三倍。
这限制了可以使用欺骗源地址安装的任何放大攻击的幅度。
为了在地址验证之前避免放大,服务器必须计算在唯一归属于单个连接的数据报中接收的所有有效负载字节。
这包括包含成功处理的数据包的数据报和包含全部丢弃的数据包的数据报。

Clients MUST ensure that UDP datagrams containing Initial packets have UDP payloads of at least 1200 bytes, adding PADDING frames as necessary.
A client that sends padded datagrams allows the server to send more data prior to completing address validation.
客户端必须确保包含初始数据包的 UDP 数据报具有至少 1200 字节的 UDP 有效负载,并根据需要添加 PADDING 帧。
发送填充数据报的客户端允许服务器在完成地址验证之前发送更多数据。
Loss of an Initial or Handshake packet from the server can cause a deadlock if the client does not send additional Initial or Handshake packets.
A deadlock could occur when the server reaches its anti- amplification limit and the client has received acknowledgments for all the data it has sent.
In this case, when the client has no reason to send additional packets, the server will be unable to send more data because it has not validated the client’s address.
To prevent this deadlock, clients MUST send a packet on a Probe Timeout (PTO); see Section 6.2 of [QUIC-RECOVERY].
Specifically, the client MUST send an Initial packet in a UDP datagram that contains at least 1200 bytes if it does not have Handshake keys, and otherwise send a
Handshake packet.
如果客户端不发送额外的 Initial 或 Handshake 数据包,服务器丢失 Initial 或 Handshake 数据包可能会导致死锁。
当服务器达到其抗放大限制并且客户端已收到其发送的所有数据的确认时,可能会发生死锁。
在这种情况下,当客户端没有理由发送额外的数据包时,服务器将无法发送更多数据,因为它没有验证客户端的地址。
为了防止这种死锁,客户端必须在探测超时(PTO)上发送一个数据包;请参阅 [QUIC-RECOVERY] 的第 6.2 节。
具体来说,如果客户端没有握手密钥,则客户端必须在包含至少 1200 字节的 UDP 数据报中发送初始数据包,否则发送
握手包。
A server might wish to validate the client address before starting the cryptographic handshake.
QUIC uses a token in the Initial packet to provide address validation prior to completing the handshake.
This token is delivered to the client during connection establishment with a Retry packet (see Section 8.1.2) or in a previous connection using the NEW_TOKEN frame (see Section 8.1.3).
服务器可能希望在开始加密握手之前验证客户端地址。
QUIC 使用初始数据包中的令牌在完成握手之前提供地址验证。
此令牌在使用重试数据包建立连接期间(参见第 8.1.2 节)或在使用 NEW_TOKEN 帧(参见第 8.1.3 节)的先前连接中传递给客户端。
In addition to sending limits imposed prior to address validation, servers are also constrained in what they can send by the limits set by the congestion controller.
Clients are only constrained by the congestion controller.
除了在地址验证之前施加的发送限制之外,服务器还受到拥塞控制器设置的限制的限制。
客户端仅受拥塞控制器的约束。

8.1.1. Token Construction

A token sent in a NEW_TOKEN frame or a Retry packet MUST be constructed in a way that allows the server to identify how it was provided to a client.
These tokens are carried in the same field but require different handling from servers.
在 NEW_TOKEN 帧或重试数据包中发送的令牌必须以允许服务器识别它是如何提供给客户端的方式构造。
这些令牌在同一个字段中携带,但需要与服务器不同的处理。

8.1.2. Address Validation Using Retry Packets

Upon receiving the client’s Initial packet, the server can request address validation by sending a Retry packet (Section 17.2.5) containing a token.
This token MUST be repeated by the client in all Initial packets it sends for that connection after it receives the Retry packet.
在接收到客户端的初始数据包后,服务器可以通过发送包含令牌的重试数据包(第 17.2.5 节)来请求地址验证。
客户端在收到重试数据包后为该连接发送的所有初始数据包中都必须重复此令牌。
In response to processing an Initial packet containing a token that was provided in a Retry packet, a server cannot send another Retry packet; it can only refuse the connection or permit it to proceed.
响应处理包含重试数据包中提供的令牌的初始数据包,服务器无法发送另一个重试数据包;它只能拒绝连接或允许连接继续。
As long as it is not possible for an attacker to generate a valid token for its own address (see Section 8.1.4) and the client is able to return that token, it proves to the server that it received the token.
只要攻击者不可能为自己的地址生成一个有效的令牌(参见第 8.1.4 节)并且客户端能够返回该令牌,它就向服务器证明它收到了该令牌。
A server can also use a Retry packet to defer the state and processing costs of connection establishment.
Requiring the server to provide a different connection ID, along with the original_destination_connection_id transport parameter defined in Section 18.2, forces the server to demonstrate that it, or an entity it cooperates with, received the original Initial packet from the client.
Providing a different connection ID also grants a server some control over how subsequent packets are routed.
This can be used to direct connections to a different server instance.
服务器还可以使用重试数据包来延迟连接建立的状态和处理成本。
要求服务器提供不同的连接 ID,以及 18.2 节中定义的 original_destination_connection_id 传输参数,强制服务器证明它或与之合作的实体从客户端接收到原始初始数据包。
提供不同的连接 ID 还允许服务器对后续数据包的路由方式进行一些控制。
这可用于将连接定向到不同的服务器实例。
If a server receives a client Initial that contains an invalid Retry token but is otherwise valid, it knows the client will not accept another Retry token.
The server can discard such a packet and allow the client to time out to detect handshake failure, but that could impose a significant latency penalty on the client.
Instead, the server SHOULD immediately close (Section 10.2) the connection with an INVALID_TOKEN error.
Note that a server has not established any state for the connection at this point and so does not enter the closing period.
如果服务器接收到包含无效重试令牌但在其他方面有效的客户端初始值,则它知道客户端不会接受另一个重试令牌。
服务器可以丢弃这样的数据包并允许客户端超时以检测握手失败,但这可能会对客户端造成严重的延迟损失。
相反,服务器应该立即关闭(第 10.2 节)带有 INVALID_TOKEN 错误的连接。
请注意,此时服务器尚未为连接建立任何状态,因此不会进入关闭期。
A flow showing the use of a Retry packet is shown in Figure 9.

1
2
3
4
5
6
7
8
9
10
11
12
13
Client                                                  Server

Initial[0]: CRYPTO[CH] ->

<- Retry+Token

Initial+Token[1]: CRYPTO[CH] ->

Initial[0]: CRYPTO[SH] ACK[1]
Handshake[0]: CRYPTO[EE, CERT, CV, FIN]
<- 1-RTT[0]: STREAM[1, "..."]

Figure 9: Example Handshake with Retry
8.1.3. Address Validation for Future Connections

A server MAY provide clients with an address validation token during one connection that can be used on a subsequent connection.
Address validation is especially important with 0-RTT because a server potentially sends a significant amount of data to a client in response to 0-RTT data.
服务器可以在一个连接期间为客户端提供一个地址验证令牌,该令牌可用于后续连接。
地址验证对于 0-RTT 尤其重要,因为服务器可能会向客户端发送大量数据以响应 0-RTT 数据。
The server uses the NEW_TOKEN frame (Section 19.7) to provide the client with an address validation token that can be used to validate future connections.
In a future connection, the client includes this token in Initial packets to provide address validation.
The client MUST include the token in all Initial packets it sends, unless a Retry replaces the token with a newer one.
The client MUST NOT use the token provided in a Retry for future connections.
Servers MAY discard any Initial packet that does not carry the expected token.
服务器使用 NEW_TOKEN 帧(第 19.7 节)为客户端提供地址验证令牌,该令牌可用于验证未来的连接。
在未来的连接中,客户端在初始数据包中包含此令牌以提供地址验证。
客户端必须在它发送的所有初始数据包中包含令牌,除非重试用更新的令牌替换令牌。
客户端不得将重试中提供的令牌用于将来的连接。
服务器可以丢弃任何不携带预期令牌的初始数据包。

Unlike the token that is created for a Retry packet, which is used immediately, the token sent in the NEW_TOKEN frame can be used after some period of time has passed.
Thus, a token SHOULD have an expiration time, which could be either an explicit expiration time or an issued timestamp that can be used to dynamically calculate the expiration time.
A server can store the expiration time or include it in an encrypted form in the token.
与为重试数据包创建的令牌立即使用不同,在 NEW_TOKEN 帧中发送的令牌可以在经过一段时间后使用。
因此,一个令牌应该有一个过期时间,它可以是一个明确的过期时间,也可以是一个发布的时间戳,可以用来动态计算过期时间。
服务器可以存储过期时间或将其以加密形式包含在令牌中。
A token issued with NEW_TOKEN MUST NOT include information that would allow values to be linked by an observer to the connection on which it was issued.
For example, it cannot include the previous connection ID or addressing information, unless the values are encrypted.
A server MUST ensure that every NEW_TOKEN frame it sends is unique across all clients, with the exception of those sent to repair losses of previously sent NEW_TOKEN frames.
Information that allows the server to distinguish between tokens from Retry and NEW_TOKEN MAY be accessible to entities other than the server.
使用 NEW_TOKEN 发出的令牌不得包含允许观察者将值链接到发出它的连接的信息。
例如,它不能包含先前的连接 ID 或地址信息,除非这些值是加密的。
服务器必须确保它发送的每个 NEW_TOKEN 帧在所有客户端中都是唯一的,除了那些为修复先前发送的 NEW_TOKEN 帧丢失而发送的帧。
允许服务器区分来自 Retry 和 NEW_TOKEN 的令牌的信息可以被服务器以外的实体访问。
It is unlikely that the client port number is the same on two different connections; validating the port is therefore unlikely to be successful.
两个不同连接上的客户端端口号不太可能相同;因此,验证端口不太可能成功。
A token received in a NEW_TOKEN frame is applicable to any server that the connection is considered authoritative for (e.g., server names included in the certificate).
When connecting to a server for which the client retains an applicable and unused token, it SHOULD include that token in the Token field of its Initial packet.
Including a token might allow the server to validate the client address without an additional round trip.
A client MUST NOT include a token that is not applicable to the server that it is connecting to, unless the client has the knowledge that the server that issued the token and the server the client is connecting to are jointly managing the tokens.
A client MAY use a token from any previous connection to that server.
在 NEW_TOKEN 帧中接收到的令牌适用于连接被认为具有权威性的任何服务器(例如,证书中包含的服务器名称)。
当连接到客户端保留了适用和未使用令牌的服务器时,它应该在其初始数据包的令牌字段中包含该令牌。
包含令牌可能允许服务器验证客户端地址而无需额外的往返。
客户端不得包含不适用于它所连接的服务器的令牌,除非客户端知道发布令牌的服务器和客户端连接的服务器共同管理令牌。
客户端可以使用任何先前连接到该服务器的令牌。
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 can discard tokens provided using the NEW_TOKEN frame.
In comparison, a token obtained in a Retry packet MUST be used immediately during the connection attempt and cannot be used in subsequent connection attempts.
令牌允许服务器将发出令牌的连接与使用它的任何连接之间的活动关联起来。
想要中断与服务器身份连续性的客户端可以丢弃使用 NEW_TOKEN 帧提供的令牌。
相比之下,在重试数据包中获得的令牌必须在连接尝试期间立即使用,并且不能在后续连接尝试中使用。
A client SHOULD NOT reuse a token from a NEW_TOKEN frame for different connection attempts.
Reusing a token allows connections to be linked by entities on the network path; see Section 9.5.
客户端不应该为不同的连接尝试重用 NEW_TOKEN 帧中的令牌。
重用令牌允许连接由网络路径上的实体链接;见第 9.5 节。
Clients might receive multiple tokens on a single connection.
Aside from preventing linkability, any token can be used in any connection attempt.
Servers can send additional tokens to either enable address validation for multiple connection attempts or replace older tokens that might become invalid.
For a client, this ambiguity means that sending the most recent unused token is most likely to be effective.
Though saving and using older tokens have no negative consequences, clients can regard older tokens as being less likely to be useful to the server for address validation.
客户端可能会在单个连接上收到多个令牌。
除了防止可链接性之外,任何令牌都可以用于任何连接尝试。
服务器可以发送额外的令牌来启用多次连接尝试的地址验证或替换可能变得无效的旧令牌。
对于客户端而言,这种模糊性意味着发送最近未使用的令牌最有可能是有效的。
尽管保存和使用旧令牌没有负面影响,但客户端可以认为旧令牌不太可能对服务器进行地址验证有用。
When a server receives an Initial packet with an address validation token, it MUST attempt to validate the token, unless it has already completed address validation.
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 packet.
Tokens provided with NEW_TOKEN frames and Retry packets can be distinguished by servers (see Section 8.1.1), and the latter can be validated more strictly.
If the validation succeeds, the server SHOULD then allow the handshake to proceed.
当服务器接收到带有地址验证令牌的初始数据包时,它必须尝试验证令牌,除非它已经完成了地址验证。
如果令牌无效,那么服务器应该继续处理,就好像客户端没有经过验证的地址一样,包括可能发送重试数据包。
NEW_TOKEN 帧和 Retry 数据包提供的令牌可以被服务器区分(参见第 8.1.1 节),并且可以更严格地验证后者。
如果验证成功,服务器应该允许握手继续进行。
| 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.
|注意:将客户视为未经验证的理由 |而不是丢弃数据包是客户端可能有|在以前的连接中使用 NEW_TOKEN | 收到令牌框架,如果服务器已经丢失状态,它可能无法 |完全验证令牌,如果 |数据包被丢弃。
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 to validate client addresses.
在无状态设计中,服务器可以使用加密和经过身份验证的令牌将信息传递给客户端,服务器稍后可以恢复并使用这些信息来验证客户端地址。
令牌没有集成到加密握手中,因此它们没有经过身份验证。
例如,客户端可能能够重用令牌。
为了避免利用此属性的攻击,服务器可以将其对令牌的使用限制为仅用于验证客户端地址所需的信息。
Clients MAY use tokens obtained on one connection for any connection attempt using the same version.
When selecting a token to use, clients do not need to consider other properties of the connection that is being attempted, including the choice of possible application protocols, session tickets, or other connection properties.
客户端可以将在一个连接上获得的令牌用于任何使用相同版本的连接尝试。
在选择要使用的令牌时,客户端不需要考虑正在尝试的连接的其他属性,包括选择可能的应用程序协议、会话票证或其他连接属性。

8.1.4. Address Validation Token Integrity 地址验证令牌完整性

An address validation token MUST be difficult to guess.
Including a random value with at least 128 bits of entropy in the token would be sufficient, but this depends on the server remembering the value it sends to clients.
地址验证令牌必须难以猜测。
在令牌中包含至少 128 位熵的随机值就足够了,但这取决于服务器是否记住它发送给客户端的值。
A token-based scheme allows the server to offload any state associated with validation to the client.
For this design to work, the token MUST be covered by integrity protection against modification or falsification by clients.
Without integrity protection, malicious clients could generate or guess values for tokens that would be accepted by the server.
Only the server requires access to the integrity protection key for tokens.
基于令牌的方案允许服务器将与验证相关的任何状态卸载给客户端。
为了使这种设计工作,令牌必须由完整性保护覆盖,以防止客户端修改或伪造。
如果没有完整性保护,恶意客户端可能会为服务器接受的令牌生成或猜测值。
只有服务器需要访问令牌的完整性保护密钥。
There is no need for a single well-defined format for the token because the server that generates the token also consumes it.
Tokens sent in Retry packets SHOULD include information that allows the server to verify that the source IP address and port in client packets remain constant.
令牌不需要单一的明确定义的格式,因为生成令牌的服务器也会使用它。
在重试数据包中发送的令牌应该包含允许服务器验证客户端数据包中的源 IP 地址和端口保持不变的信息。
Tokens sent in NEW_TOKEN frames MUST include information that allows the server to verify that the client IP address has not changed from when the token was issued.
Servers can use tokens from NEW_TOKEN frames in deciding not to send a Retry packet, even if the client address has changed.
If the client IP address has changed, the server MUST adhere to the anti-amplification limit; see Section 8.
Note that in the presence of NAT, this requirement might be insufficient to protect other hosts that share the NAT from amplification attacks.
在 NEW_TOKEN 帧中发送的令牌必须包含允许服务器验证客户端 IP 地址从发出令牌时起没有更改的信息。
服务器可以使用 NEW_TOKEN 帧中的令牌来决定不发送重试数据包,即使客户端地址已更改。
如果客户端 IP 地址发生变化,服务器必须遵守反放大限制;见第 8 节。
请注意,在存在 NAT 的情况下,此要求可能不足以保护共享 NAT 的其他主机免受放大攻击。
Attackers could replay tokens to use servers as amplifiers in DDoS attacks.
To protect against such attacks, servers MUST ensure that replay of tokens is prevented or limited.
Servers SHOULD ensure that tokens sent in Retry packets are only accepted for a short time, as they are returned immediately by clients.
Tokens that are provided in NEW_TOKEN frames (Section 19.7) need to be valid for longer but SHOULD NOT be accepted multiple times.
Servers are encouraged to allow tokens to be used only once, if possible; tokens MAY include additional information about clients to further narrow applicability or reuse.
攻击者可以重放令牌以在 DDoS 攻击中使用服务器作为放大器。
为了防止此类攻击,服务器必须确保阻止或限制令牌的重放。
服务器应该确保在重试数据包中发送的令牌只在短时间内被接受,因为它们会立即被客户端返回。
NEW_TOKEN 帧(第 19.7 节)中提供的令牌需要更长时间有效,但不应多次接受。
如果可能,鼓励服务器只允许使用一次令牌;令牌可能包含有关客户端的附加信息,以进一步缩小适用性或重用性。

8.2. Path Validation

Path validation is used by both peers during connection migration (see Section 9) to verify reachability after a change of address.
In path validation, endpoints test reachability between a specific local address and a specific peer address, where an address is the 2-tuple of IP address and port.
在连接迁移期间(见第 9 节),双方都使用路径验证来验证地址更改后的可达性。
在路径验证中,端点测试特定本地地址和特定对等地址之间的可达性,其中地址是 IP 地址和端口的 2 元组。
Path validation tests that packets sent on a path to a peer are received by that peer.
Path validation is used to ensure that packets received from a migrating peer do not carry a spoofed source address.
路径验证测试在路径上发送到对等点的数据包是否被该对等点接收。
路径验证用于确保从迁移对等方接收到的数据包不携带伪造的源地址。
Path validation does not validate that a peer can send in the return direction.
Acknowledgments cannot be used for return path validation because they contain insufficient entropy and might be spoofed.
Endpoints independently determine reachability on each direction of a path, and therefore return reachability can only be established by the peer.
路径验证不验证对等方是否可以在返回方向发送。
确认不能用于返回路径验证,因为它们包含的熵不足并且可能被欺骗。
端点独立确定路径每个方向的可达性,因此返回可达性只能由对等方建立。
Path validation can be used at any time by either endpoint.
For instance, an endpoint might check that a peer is still in possession of its address after a period of quiescence.
任一端点都可以随时使用路径验证。
例如,一个端点可能会检查一个对等点在一段静止期后是否仍然拥有它的地址。
Path validation is not designed as a NAT traversal mechanism.
Though the mechanism described here might be effective for the creation of NAT bindings that support NAT traversal, the expectation is that one endpoint is able to receive packets without first having sent a packet on that path.
Effective NAT traversal needs additional synchronization mechanisms that are not provided here.
路径验证并非设计为 NAT 穿越机制。
尽管这里描述的机制对于创建支持 NAT 遍历的 NAT 绑定可能是有效的,但期望一个端点能够在没有先在该路径上发送数据包的情况下接收数据包。
有效的 NAT 穿越需要额外的同步机制,这里没有提供。
An endpoint MAY include other frames with the PATH_CHALLENGE and PATH_RESPONSE frames used for path validation.
In particular, an endpoint can include PADDING frames with a PATH_CHALLENGE frame for Path Maximum Transmission Unit Discovery (PMTUD); see Section 14.2.1.
An endpoint can also include its own PATH_CHALLENGE frame when sending a PATH_RESPONSE frame.
端点可以包含其他帧,其中 PATH_CHALLENGE 和 PATH_RESPONSE 帧用于路径验证。
特别地,端点可以包括带有 PATH_CHALLENGE 帧的 PADDING 帧,用于路径最大传输单元发现 (PMTUD);见第 14.2.1 节。
端点在发送 PATH_RESPONSE 帧时也可以包含它自己的 PATH_CHALLENGE 帧。
An endpoint uses a new connection ID for probes sent from a new local address; see Section 9.5.
When probing a new path, an endpoint can ensure that its peer has an unused connection ID available for responses.
Sending NEW_CONNECTION_ID and PATH_CHALLENGE frames in the same packet, if the peer’s active_connection_id_limit permits, ensures that an unused connection ID will be available to the peer when sending a response.
端点对从新本地地址发送的探测使用新的连接 ID;见第 9.5 节。
在探测新路径时,端点可以确保其对等方具有可用于响应的未使用连接 ID。
如果对等方的 active_connection_id_limit 允许,在同一数据包中发送 NEW_CONNECTION_ID 和 PATH_CHALLENGE 帧,可确保在发送响应时对等方可以使用未使用的连接 ID。
An endpoint can choose to simultaneously probe multiple paths.
The number of simultaneous paths used for probes is limited by the number of extra connection IDs its peer has previously supplied, since each new local address used for a probe requires a previously unused connection ID.
一个端点可以选择同时探测多条路径。
用于探测的同时路径的数量受到其对等方先前提供的额外连接 ID 的数量的限制,因为用于探测的每个新本地地址都需要一个以前未使用的连接 ID。

8.2.1. Initiating Path Validation

To initiate path validation, an endpoint sends a PATH_CHALLENGE frame containing an unpredictable payload on the path to be validated.
为了启动路径验证,端点会在要验证的路径上发送一个 PATH_CHALLENGE 帧,其中包含不可预测的有效载荷。
An endpoint MAY send multiple PATH_CHALLENGE frames to guard against packet loss.
However, an endpoint SHOULD NOT send multiple PATH_CHALLENGE frames in a single packet.
一个端点可以发送多个 PATH_CHALLENGE 帧来防止丢包。
但是,端点不应在单个数据包中发送多个 PATH_CHALLENGE 帧。
An endpoint SHOULD NOT probe a new path with packets containing a PATH_CHALLENGE frame more frequently than it would send an Initial packet.
This ensures that connection migration is no more load on a new path than establishing a new connection.
端点不应该比发送初始数据包更频繁地使用包含 PATH_CHALLENGE 帧的数据包探测新路径。
这确保了连接迁移在新路径上的负载不会比建立新连接更多。
The endpoint MUST use unpredictable data in every PATH_CHALLENGE frame so that it can associate the peer’s response with the corresponding PATH_CHALLENGE.
端点必须在每个 PATH_CHALLENGE 帧中使用不可预测的数据,以便它可以将对等方的响应与相应的 PATH_CHALLENGE 相关联。
An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame to at least the smallest allowed maximum datagram size of 1200 bytes, unless the anti-amplification limit for the path does not permit sending a datagram of this size.
Sending UDP datagrams of this size ensures that the network path from the endpoint to the peer can be used for QUIC; see Section 14.
端点必须将包含 PATH_CHALLENGE 帧的数据报扩展至至少允许的最小最大数据报大小 1200 字节,除非路径的反放大限制不允许发送此大小的数据报。
发送这种大小的 UDP 数据报可确保从端点到对等方的网络路径可用于 QUIC;见第 14 节。
When an endpoint is unable to expand the datagram size to 1200 bytes due to the anti-amplification limit, the path MTU will not be validated.
To ensure that the path MTU is large enough, the endpoint MUST perform a second path validation by sending a PATH_CHALLENGE frame in a datagram of at least 1200 bytes.
This additional validation can be performed after a PATH_RESPONSE is successfully received or when enough bytes have been received on the path that sending the larger datagram will not result in exceeding the anti- amplification limit.
当端点由于抗放大限制而无法将数据报大小扩展到 1200 字节时,将不会验证路径 MTU。
为了确保路径 MTU 足够大,端点必须通过在至少 1200 字节的数据报中发送 PATH_CHALLENGE 帧来执行第二次路径验证。
在成功接收到 PATH_RESPONSE 或在路径上接收到足够的字节以致发送更大的数据报不会导致超过抗放大限制时,可以执行此附加验证。
Unlike other cases where datagrams are expanded, endpoints MUST NOT discard datagrams that appear to be too small when they contain PATH_CHALLENGE or PATH_RESPONSE.
与扩展数据报的其他情况不同,端点不得丢弃包含 PATH_CHALLENGE 或 PATH_RESPONSE 时看起来太小的数据报。

8.2.2. Path Validation Responses

On receiving a PATH_CHALLENGE frame, an endpoint MUST respond by echoing the data contained in the PATH_CHALLENGE frame in a PATH_RESPONSE frame.
An endpoint MUST NOT delay transmission of a packet containing a PATH_RESPONSE frame unless constrained by congestion control.
在接收到 PATH_CHALLENGE 帧时,端点必须通过在 PATH_RESPONSE 帧中回显 PATH_CHALLENGE 帧中包含的数据来响应。
端点不得延迟包含 PATH_RESPONSE 帧的数据包的传输,除非受到拥塞控制的限制。
A PATH_RESPONSE frame MUST be sent on the network path where the PATH_CHALLENGE frame was received.
This ensures that path validation by a peer only succeeds if the path is functional in both directions.
This requirement MUST NOT be enforced by the endpoint that initiates path validation, as that would enable an attack on migration; see Section 9.3.3.
PATH_RESPONSE 帧必须在接收到 PATH_CHALLENGE 帧的网络路径上发送。
这确保了只有当路径在两个方向上都有效时,对等方的路径验证才会成功。
启动路径验证的端点不得强制执行此要求,因为这会导致对迁移的攻击;见第 9.3.3 节。
An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame to at least the smallest allowed maximum datagram size of 1200 bytes.
This verifies that the path is able to carry datagrams of this size in both directions.
However, an endpoint MUST NOT expand the datagram containing the PATH_RESPONSE if the resulting data exceeds the anti-amplification limit.
This is expected to only occur if the received PATH_CHALLENGE was not sent in an expanded datagram.
端点必须将包含 PATH_RESPONSE 帧的数据报扩展到至少允许的最小最大数据报大小 1200 字节。
这验证了路径能够在两个方向上携带这种大小的数据报。
但是,如果结果数据超过反放大限制,端点不得扩展包含 PATH_RESPONSE 的数据报。
仅当接收到的 PATH_CHALLENGE 未在扩展数据报中发送时,才会发生这种情况。
An endpoint MUST NOT send more than one PATH_RESPONSE frame in response to one PATH_CHALLENGE frame; see Section 13.3.
The peer is expected to send more PATH_CHALLENGE frames as necessary to evoke additional PATH_RESPONSE frames.
端点不得发送超过一个 PATH_RESPONSE 帧来响应一个 PATH_CHALLENGE 帧;见第 13.3 节。
对等方应根据需要发送更多 PATH_CHALLENGE 帧以唤起额外的 PATH_RESPONSE 帧。

8.2.3. Successful Path Validation

Path validation succeeds when a PATH_RESPONSE frame is received that contains the data that was sent in a previous PATH_CHALLENGE frame.
A PATH_RESPONSE frame received on any network path validates the path on which the PATH_CHALLENGE was sent.
当接收到包含先前 PATH_CHALLENGE 帧中发送的数据的 PATH_RESPONSE 帧时,路径验证成功。
在任何网络路径上接收到的 PATH_RESPONSE 帧都会验证发送 PATH_CHALLENGE 的路径。
If an endpoint sends a PATH_CHALLENGE frame in a datagram that is not expanded to at least 1200 bytes and if the response to it validates the peer address, the path is validated but not the path MTU.
As a result, the endpoint can now send more than three times the amount of data that has been received.
However, the endpoint MUST initiate another path validation with an expanded datagram to verify that the path supports the required MTU.
如果端点在未扩展至至少 1200 字节的数据报中发送 PATH_CHALLENGE 帧,并且如果对它的响应验证对等地址,则验证路径但不验证路径 MTU。
因此,端点现在可以发送超过已接收数据量的三倍。
但是,端点必须使用扩展数据报启动另一个路径验证,以验证该路径是否支持所需的 MTU。
Receipt of an acknowledgment for a packet containing a PATH_CHALLENGE frame is not adequate validation, since the acknowledgment can be spoofed by a malicious peer.
接收到包含 PATH_CHALLENGE 帧的数据包的确认不是充分的验证,因为该确认可能被恶意对等方欺骗。

8.2.4. Failed Path Validation

Path validation only fails when the endpoint attempting to validate the path abandons its attempt to validate the path.
仅当尝试验证路径的端点放弃验证路径的尝试时,路径验证才会失败。
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.
A value of three times the larger of the current PTO or the PTO for the new path (using kInitialRtt, as defined in [QUIC-RECOVERY]) is RECOMMENDED.
端点应该放弃基于计时器的路径验证。
设置此计时器时,请注意新路径的往返时间可能比原始路径更长。
建议使用当前 PTO 或新路径的 PTO(使用 [QUIC-RECOVERY] 中定义的 kInitialRtt)中的较大值的三倍。
This timeout allows for multiple PTOs to expire prior to failing path validation, so that loss of a single PATH_CHALLENGE or PATH_RESPONSE frame does not cause path validation failure.
此超时允许多个 PTO 在路径验证失败之前到期,因此单个 PATH_CHALLENGE 或 PATH_RESPONSE 帧的丢失不会导致路径验证失败。
Note that the endpoint might receive packets containing other frames on the new path, but a PATH_RESPONSE frame with appropriate data is required for path validation to succeed.
请注意,端点可能会在新路径上接收包含其他帧的数据包,但路径验证成功需要包含适当数据的 PATH_RESPONSE 帧。
When an endpoint abandons path validation, it determines that the path is unusable.
This does not necessarily imply a failure of the connection – endpoints can continue sending packets over other paths as appropriate.
If no paths are available, an endpoint can wait for a new path to become available or close the connection.
An endpoint that has no valid network path to its peer MAY signal this using the NO_VIABLE_PATH connection error, noting that this is only possible if the network path exists but does not support the required MTU (Section 14).
当端点放弃路径验证时,它确定该路径不可用。
这并不一定意味着连接失败——端点可以根据需要继续通过其他路径发送数据包。
如果没有可用的路径,端点可以等待新路径可用或关闭连接。
没有有效网络路径到其对等点的端点可以使用 NO_VIABLE_PATH 连接错误发出信号,注意这只有在网络路径存在但不支持所需的 MTU 时才有可能(第 14 节)。
A path validation might be abandoned for other reasons besides failure.
Primarily, this happens if a connection migration to a new path is initiated while a path validation on the old path is in progress.
除了失败之外,路径验证可能会因为其他原因而被放弃。
首先,如果在旧路径上的路径验证正在进行时启动到新路径的连接迁移,则会发生这种情况。

9. Connection Migration 连接迁移

The use of a connection ID allows connections to survive changes to endpoint addresses (IP address and port), such as those caused by an endpoint migrating to a new network.
This section describes the process by which an endpoint migrates to a new address.
连接 ID 的使用允许连接在端点地址(IP 地址和端口)的更改中保留下来,例如由端点迁移到新网络引起的更改。
本节介绍端点迁移到新地址的过程。
The design of QUIC relies on endpoints retaining a stable address for the duration of the handshake.
An endpoint MUST NOT initiate connection migration before the handshake is confirmed, as defined in Section 4.1.2 of [QUIC-TLS].
QUIC 的设计依赖于端点在握手期间保持稳定的地址。
如 [QUIC-TLS] 的第 4.1.2 节所定义的,端点不能在确认握手之前启动连接迁移。
If the peer sent the disable_active_migration transport parameter, an endpoint also MUST NOT send packets (including probing packets; see Section 9.1) from a different local address to the address the peer used during the handshake, unless the endpoint has acted on a preferred_address transport parameter from the peer.
If the peer violates this requirement, the endpoint MUST either drop the incoming packets on that path without generating a Stateless Reset or proceed with path validation and allow the peer to migrate.
Generating a Stateless Reset or closing the connection would allow third parties in the network to cause connections to close by spoofing or otherwise manipulating observed traffic.
如果对等方发送了 disable_active_migration 传输参数,端点也不得从不同的本地地址向对等方在握手期间使用的地址发送数据包(包括探测数据包;参见第 9.1 节),除非端点对首选地址传输参数采取了行动来自同行。
如果对等体违反此要求,端点必须要么丢弃该路径上的传入数据包而不生成无状态重置,要么继续进行路径验证并允许对等体迁移。
生成无状态重置或关闭连接将允许网络中的第三方通过欺骗或以其他方式操纵观察到的流量来导致连接关闭。
Not all changes of peer address are intentional, or active, migrations.
The peer could experience NAT rebinding: a change of address due to a middlebox, usually a NAT, allocating a new outgoing port or even a new outgoing IP address for a flow.
An endpoint MUST perform path validation (Section 8.2) if it detects any change to a peer’s address, unless it has previously validated that address.
并非所有对等地址的更改都是有意或主动的迁移。
对等方可能会遇到 NAT 重新绑定:由于中间盒(通常是 NAT)而导致地址更改,为流分配新的传出端口甚至新的传出 IP 地址。
如果端点检测到对等地址的任何更改,则端点必须执行路径验证(第 8.2 节),除非它先前已验证该地址。
When an endpoint has no validated path on which to send packets, it MAY discard connection state.
An endpoint capable of connection migration MAY wait for a new path to become available before discarding connection state.
当端点没有经过验证的发送数据包的路径时,它可以丢弃连接状态。
能够进行连接迁移的端点可以在丢弃连接状态之前等待新路径可用。
This document limits migration of connections to new client addresses, except as described in Section 9.6.
Clients are responsible for initiating all migrations.
Servers do not send non- probing packets (see Section 9.1) toward a client address until they see a non-probing packet from that address.
If a client receives packets from an unknown server address, the client MUST discard these packets.
本文档限制连接迁移到新的客户端地址,除非第 9.6 节中描述。
客户端负责启动所有迁移。
服务器不会向客户端地址发送非探测数据包(参见第 9.1 节),直到它们看到来自该地址的非探测数据包。
如果客户端接收到来自未知服务器地址的数据包,客户端必须丢弃这些数据包。

9.1. Probing a New Path

An endpoint MAY probe for peer reachability from a new local address using path validation (Section 8.2) prior to migrating the connection to the new local address.
Failure of path validation simply means 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 no valid alternative paths available.
在将连接迁移到新的本地地址之前,端点可以使用路径验证(第 8.2 节)从新的本地地址探测对等方的可达性。
路径验证失败仅仅意味着新路径不适用于此连接。
验证路径失败不会导致连接结束,除非没有可用的有效替代路径。
PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, and PADDING frames are “probing frames”, and all other frames are “non-probing frames”.
A packet containing only probing frames is a “probing packet”, and a packet containing any other frame is a “non-probing packet”.
PATH_CHALLENGE、PATH_RESPONSE、NEW_CONNECTION_ID 和 PADDING 帧是“探测帧”,所有其他帧都是“非探测帧”。
仅包含探测帧的数据包是“探测数据包”,包含任何其他帧的数据包是“非探测数据包”。

9.2. Initiating Connection Migration

An endpoint can migrate a connection to a new local address by sending packets containing non-probing frames from that address.
端点可以通过从该地址发送包含非探测帧的数据包来将连接迁移到新的本地地址。
Each endpoint validates its peer’s address during connection establishment.
Therefore, a migrating endpoint can send to its peer 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 first validating the peer’s address.
每个端点在连接建立期间验证其对等方的地址。
因此,迁移端点可以向其对等方发送消息,知道对等方愿意在对等方的当前地址接收。
因此,端点可以迁移到新的本地地址,而无需首先验证对等方的地址。
To establish reachability on the new path, an endpoint initiates path validation (Section 8.2) on the new path.
An endpoint MAY defer path validation until after a peer sends the next non-probing frame to its new address.
为了在新路径上建立可达性,端点在新路径上启动路径验证(第 8.2 节)。
端点可以推迟路径验证,直到对等方将下一个非探测帧发送到其新地址。
When migrating, the new path might not support the endpoint’s current sending rate.
Therefore, the endpoint resets its congestion controller and RTT estimate, as described in Section 9.4.

The new path might not have the same ECN capability.
Therefore, the endpoint validates ECN capability as described in Section 13.4.
迁移时,新路径可能不支持端点当前的发送速率。
因此,端点重置其拥塞控制器和 RTT 估计,如第 9.4 节所述。

新路径可能没有相同的 ECN 功能。
因此,端点验证 ECN 能力,如第 13.4 节所述。

9.3. Responding to Connection Migration

Receiving a packet from a new peer address containing a non-probing frame indicates that the peer has migrated to that address.
从包含非探测帧的新对等地址接收到数据包表明对等方已迁移到该地址。
If the recipient permits the migration, it MUST send subsequent packets to the new peer address and MUST initiate path validation (Section 8.2) to verify the peer’s ownership of the address if validation is not already underway.
If the recipient has no unused connection IDs from the peer, it will not be able to send anything on the new path until the peer provides one; see Section 9.5.
如果接收方允许迁移,它必须将后续数据包发送到新的对等地址,并且必须启动路径验证(第 8.2 节)以验证对等方对地址的所有权(如果验证尚未进行)。
如果接收方没有来自对等方的未使用连接 ID,则在对等方提供之前,它将无法在新路径上发送任何内容;见第 9.5 节。
An endpoint only changes the address to which it sends packets in response to the highest-numbered non-probing packet.
This ensures that an endpoint does not send packets to an old peer address in the case that it receives reordered packets.
端点仅更改其发送数据包的地址以响应编号最高的非探测数据包。
这可确保端点在收到重新排序的数据包时不会将数据包发送到旧的对等地址。
An endpoint MAY send data to an unvalidated peer address, but it MUST protect against potential attacks as described in Sections 9.3.1 and 9.3.2. An endpoint MAY skip validation of a peer address if that
address has been seen recently.
In particular, if an endpoint returns to a previously validated path after detecting some form of spurious migration, skipping address validation and restoring loss detection and congestion state can reduce the performance impact of the attack.
端点可以将数据发送到未经验证的对等地址,但它必须防止潜在的攻击,如第 9.3.1 和 9.3.2 节所述。如果最近看到了对等地址,端点可以跳过对等地址的验证。
特别是,如果端点在检测到某种形式的虚假迁移后返回到先前验证的路径,则跳过地址验证并恢复丢失检测和拥塞状态可以减少攻击对性能的影响。
After changing the address to which it sends non-probing packets, an endpoint can abandon any path validation for other addresses.

Receiving a packet from a new peer address could be the result of a NAT rebinding at the peer.

After verifying a new client address, the server SHOULD send new address validation tokens (Section 8) to the client.
在更改发送非探测数据包的地址后,端点可以放弃对其他地址的任何路径验证。

从新的对等地址接收数据包可能是对等点的 NAT 重新绑定的结果。

在验证了一个新的客户端地址之后,服务器应该向客户端发送新的地址验证令牌(第 8 节)。

9.3.1. Peer Address Spoofing 对等地址欺骗

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 the endpoint sends significantly more data than the spoofing peer, connection migration might be used to amplify the volume of data that an attacker can generate toward a victim.
对等点可能会欺骗其源地址,以导致端点向不情愿的主机发送过多的数据。
如果端点发送的数据明显多于欺骗对等方,则连接迁移可能会用于放大攻击者可以向受害者生成的数据量。
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 address.
Until a peer’s address is deemed valid, an endpoint limits the amount of data it sends to that address; see Section 8.
In the absence of this limit, an endpoint risks being used for a denial-of- service attack against an unsuspecting victim.
如第 9.3 节所述,端点需要验证对等点的新地址,以确认对等点拥有新地址。
在对等点的地址被视为有效之前,端点会限制它发送到该地址的数据量; 见第 8 节。
如果没有此限制,端点就有可能被用于针对毫无戒心的受害者的拒绝服务攻击。
If an endpoint skips validation of a peer address as described above, it does not need to limit its sending rate.
如果端点如上所述跳过对等地址的验证,则不需要限制其发送速率。

9.3.2. On-Path Address Spoofing 路径地址欺骗

An on-path attacker could cause a spurious connection migration by copying and forwarding a packet with a spoofed address such that it arrives before the original packet.
The packet with the spoofed address will be seen to come from a migrating connection, and the original packet will be seen as a duplicate and dropped.
After a spurious migration, validation of the source address will fail because the entity at the source address does not have the necessary cryptographic keys to read or respond to the PATH_CHALLENGE frame that is sent to it even if it wanted to.
路径上的攻击者可以通过复制和转发具有欺骗性地址的数据包,使其在原始数据包之前到达,从而导致虚假连接迁移。
带有欺骗地址的数据包将被视为来自迁移连接,而原始数据包将被视为重复并被丢弃。
在虚假迁移之后,源地址的验证将失败,因为源地址处的实体没有必要的加密密钥来读取或响应发送给它的 PATH_CHALLENGE 帧,即使它想要。
To protect the connection from failing due to such a spurious migration, an endpoint MUST revert to using the last validated peer address when validation of a new peer address fails.
Additionally, receipt of packets with higher packet numbers from the legitimate peer address will trigger another connection migration.
This will cause the validation of the address of the spurious migration to be abandoned, thus containing migrations initiated by the attacker injecting a single packet.
为了防止连接由于这种虚假迁移而失败,端点必须在新对等地址的验证失败时恢复使用最后验证的对等地址。
此外,从合法对等地址接收到具有更高数据包编号的数据包将触发另一个连接迁移。
这将导致对虚假迁移地址的验证被放弃,从而包含由注入单个数据包的攻击者发起的迁移。
If an endpoint has no state about the last validated peer address, it MUST close the connection silently by discarding all connection state.
This results in new packets on the connection being handled generically.
For instance, an endpoint MAY send a Stateless Reset in response to any further incoming packets.
如果端点没有关于最后验证的对等地址的状态,它必须通过丢弃所有连接状态来静默关闭连接。
这导致连接上的新数据包被一般处理。
例如,端点可以发送无状态重置以响应任何进一步的传入数据包。

9.3.3. Off-Path Packet Forwarding

路径外数据包转发
An off-path attacker that can observe packets might forward copies of genuine packets to endpoints.
If the copied packet arrives before the genuine packet, this will appear as a NAT rebinding.
Any genuine packet will be discarded as a duplicate.
If the attacker is able to continue forwarding packets, it might be able to cause migration to a path via the attacker.
This places the attacker on-path, giving it the ability to observe or drop all subsequent packets.
可以观察数据包的路径外攻击者可能会将真实数据包的副本转发到端点。
如果复制的数据包在真正的数据包之前到达,这将显示为 NAT 重新绑定。
任何真正的数据包都将作为副本被丢弃。
如果攻击者能够继续转发数据包,它可能会导致通过攻击者迁移到路径。
这将攻击者置于路径上,使其能够观察或丢弃所有后续数据包。
This style of attack relies on the attacker using a path that has approximately the same characteristics as the direct path between endpoints.
The attack is more reliable if relatively few packets are sent or if packet loss coincides with the attempted attack.
这种攻击方式依赖于攻击者使用与端点之间的直接路径具有大致相同特征的路径。
如果发送的数据包相对较少或数据包丢失与尝试的攻击同时发生,则攻击更可靠。
A non-probing packet received on the original path that increases the maximum received packet number will cause the endpoint to move back to that path.
Eliciting packets on this path increases the likelihood that the attack is unsuccessful.
Therefore, mitigation of this attack relies on triggering the exchange of packets.
在原始路径上接收到的增加最大接收数据包数的非探测数据包将导致端点移回该路径。
在此路径上引出数据包会增加攻击失败的可能性。
因此,缓解这种攻击依赖于触发数据包的交换。
In response to an apparent migration, endpoints MUST validate the previously active path using a PATH_CHALLENGE frame.
This induces the sending of new packets on that path.
If the path is no longer viable, the validation attempt will time out and fail; if the path is viable but no longer desired, the validation will succeed but only results in probing packets being sent on the path.
为了响应明显的迁移,端点必须使用 PATH_CHALLENGE 帧验证先前的活动路径。
这会导致在该路径上发送新数据包。
如果路径不再可行,验证尝试将超时并失败;如果路径可行但不再需要,则验证将成功,但只会导致在路径上发送探测数据包。
An endpoint that receives a PATH_CHALLENGE on an active path SHOULD send a non-probing packet in response.
If the non-probing packet arrives before any copy made by an attacker, this results in the connection being migrated back to the original path.
Any subsequent migration to another path restarts this entire process.
在活动路径上接收到 PATH_CHALLENGE 的端点应该发送一个非探测包作为响应。
如果非探测数据包在攻击者复制任何副本之前到达,这将导致连接迁移回原始路径。
任何后续迁移到另一条路径都会重新启动整个过程。
This defense is imperfect, but this is not considered a serious problem.
If the path via the attack is reliably faster than the original path despite multiple attempts to use that original path, it is not possible to distinguish between an attack and an improvement in routing.
这种防御是不完善的,但这不被认为是一个严重的问题。
如果尽管多次尝试使用原始路径,通过攻击的路径确实比原始路径快,则无法区分攻击和路由改进。
An endpoint could also use heuristics to improve detection of this style of attack.
For instance, NAT rebinding is improbable if packets were recently received on the old path; similarly, rebinding is rare on IPv6 paths.
Endpoints can also look for duplicated packets.
Conversely, a change in connection ID is more likely to indicate an intentional migration rather than an attack.
端点还可以使用启发式方法来改进对这种攻击方式的检测。
例如,如果最近在旧路径上接收到数据包,则 NAT 重新绑定是不可能的;同样,重新绑定在 IPv6 路径上很少见。
端点还可以查找重复的数据包。
相反,连接 ID 的更改更有可能表示有意迁移而不是攻击。

9.4. Loss Detection and Congestion Control

The capacity available on the new path might not be the same as the old path.
Packets sent on the old path MUST NOT contribute to congestion control or RTT estimation for the new path.
新路径上的可用容量可能与旧路径不同。
在旧路径上发送的数据包不得有助于新路径的拥塞控制或 RTT 估计。
On confirming a peer’s ownership of its new address, an endpoint MUST immediately reset the congestion controller and round-trip time estimator for the new path to initial values (see Appendices A.3 and B.3 of [QUIC-RECOVERY]) unless the only change in the peer’s address is its port number.
Because port-only changes are commonly the result of NAT rebinding or other middlebox activity, the endpoint MAY instead retain its congestion control state and round-trip estimate in those cases instead of reverting to initial values.
In cases where congestion control state retained from an old path is used on a new path with substantially different characteristics, a sender could transmit too aggressively until the congestion controller and the RTT estimator have adapted.
Generally, implementations are advised to be cautious when using previous values on a new path.
在确认对等点对其新地址的所有权后,端点必须立即将新路径的拥塞控制器和往返时间估计器重置为初始值(参见 [QUIC-RECOVERY] 的附录 A.3 和 B.3),除非对等方地址的唯一变化是其端口号。
因为仅端口更改通常是 NAT 重新绑定或其他中间盒活动的结果,所以端点可以在这些情况下保留其拥塞控制状态和往返估计,而不是恢复到初始值。
在从旧路径保留的拥塞控制状态用于具有显着不同特征的新路径的情况下,发送方可能过于激进地传输,直到拥塞控制器和RTT估计器已经适应。
通常,在新路径上使用以前的值时,建议实现要谨慎。
There could be apparent reordering at the receiver when an endpoint sends data and probes from/to multiple addresses during the migration period, since the two resulting paths could have different round-trip times.
A receiver of packets on multiple paths will still send ACK frames covering all received packets.
当端点在迁移期间从/向多个地址发送数据和探测时,接收器可能会出现明显的重新排序,因为两条生成的路径可能具有不同的往返时间。
多个路径上的数据包接收器仍将发送覆盖所有接收数据包的 ACK 帧。
While multiple paths might be used during connection migration, a single congestion control context and a single loss recovery context (as described in [QUIC-RECOVERY]) could be adequate.
For instance, an endpoint might delay switching to a new congestion control context until it is confirmed that an old path is no longer needed (such as the case described in Section 9.3.3).
虽然在连接迁移期间可能会使用多条路径,但单个拥塞控制上下文和单个丢失恢复上下文(如 [QUIC-RECOVERY] 中所述)可能就足够了。
例如,端点可能会延迟切换到新的拥塞控制上下文,直到确认不再需要旧路径(例如第 9.3.3 节中描述的情况)。
A sender can make exceptions for probe packets so that their loss detection is independent and does not unduly cause the congestion controller to reduce its sending rate.
An endpoint might set a separate timer when a PATH_CHALLENGE is sent, which is canceled if the corresponding PATH_RESPONSE is received.
If the timer fires before the PATH_RESPONSE is received, the endpoint might send a new PATH_CHALLENGE and restart the timer for a longer period of time.
This timer SHOULD be set as described in Section 6.2.1 of [QUIC-RECOVERY] and MUST NOT be more aggressive.
发送者可以对探测包进行例外处理,以便它们的丢失检测是独立的,并且不会过度地导致拥塞控制器降低其发送速率。
发送 PATH_CHALLENGE 时,端点可能会设置一个单独的计时器,如果收到相应的 PATH_RESPONSE,则会取消该计时器。
如果计时器在收到 PATH_RESPONSE 之前触发,端点可能会发送一个新的 PATH_CHALLENGE 并重新启动计时器更长的时间。

9.5. Privacy Implications of Connection Migration 连接迁移的隐私影响

Using a stable connection ID on multiple network paths would allow a passive observer to correlate activity between those paths.
An endpoint that moves between networks might not wish to have their activity correlated by any entity other than their peer, so different connection IDs are used when sending from different local addresses, as discussed in Section 5.1.
For this to be effective, endpoints need to ensure that connection IDs they provide cannot be linked by any other entity.
在多个网络路径上使用稳定的连接 ID 将允许被动观察者关联这些路径之间的活动。
在网络之间移动的端点可能不希望它们的活动与它们的对等方以外的任何实体相关联,因此在从不同的本地地址发送时使用不同的连接 ID,如第 5.1 节所述。
为此,端点需要确保它们提供的连接 ID 不能被任何其他实体链接。
At any time, endpoints MAY change the Destination Connection ID they transmit with to a value that has not been used on another path.
在任何时候,端点都可以将它们传输的目标连接 ID 更改为尚未在另一条路径上使用的值。
An endpoint MUST NOT reuse a connection ID when sending from more than one local address – for example, when initiating connection migration as described in Section 9.2 or when probing a new network path as described in Section 9.1.
当从多个本地地址发送时,端点不得重用连接 ID——例如,当启动连接迁移时,如第 9.2 节所述,或在探测新网络路径时,如第 9.1 节所述。
Similarly, an endpoint MUST NOT reuse a connection ID when sending to more than one destination address.
Due to network changes outside the control of its peer, an endpoint might receive packets from a new source address with the same Destination Connection ID field value, in which case it MAY continue to use the current connection ID with the new remote address while still sending from the same local address.
类似地,端点在发送到多个目标地址时不得重用连接 ID。
由于其对等点无法控制的网络变化,端点可能会从具有相同目标连接 ID 字段值的新源地址接收数据包,在这种情况下,它可以继续使用具有新远程地址的当前连接 ID,同时仍然发送来自同一个本地地址。
These requirements regarding connection ID reuse apply only to the sending of packets, as unintentional changes in path without a change in connection ID are possible.
For example, after a period of network inactivity, NAT rebinding might cause packets to be sent on a new path when the client resumes sending.
An endpoint responds to such an event as described in Section 9.3.
这些关于连接 ID 重用的要求仅适用于数据包的发送,因为可能会在不改变连接 ID 的情况下无意更改路径。
例如,在一段时间的网络不活动之后,当客户端恢复发送时,NAT 重新绑定可能会导致数据包在新路径上发送。
端点响应第 9.3 节中描述的此类事件。
Using different connection IDs for packets sent in both directions on each new network path eliminates the use of the connection ID for linking packets from the same connection across different network paths.
Header protection ensures that packet numbers cannot be used to correlate activity.
This does not prevent other properties of packets, such as timing and size, from being used to correlate activity.
对在每个新网络路径上双向发送的数据包使用不同的连接 ID 消除了使用连接 ID 来链接来自不同网络路径的同一连接的数据包。
标头保护确保数据包编号不能用于关联活动。
这并不妨碍使用数据包的其他属性(例如时间和大小)来关联活动。
An endpoint SHOULD NOT initiate migration with a peer that has requested a zero-length connection ID, because traffic over the new path might be trivially linkable to traffic over the old one.
If the server is able to associate packets with a zero-length connection ID to the right connection, it means that the server is using other information to demultiplex packets.
For example, a server might provide a unique address to every client – for instance, using HTTP alternative services [ALTSVC].
Information that might allow correct routing of packets across multiple network paths will also allow activity on those paths to be linked by entities other than the peer.
端点不应该向已请求零长度连接 ID 的对等方发起迁移,因为新路径上的流量可能很容易链接到旧路径上的流量。
如果服务器能够将具有零长度连接 ID 的数据包关联到正确的连接,则意味着服务器正在使用其他信息来解复用数据包。
例如,服务器可能会为每个客户端提供唯一的地址——例如,使用 HTTP 替代服务 [ALTSVC]。
可能允许跨多个网络路径正确路由数据包的信息也将允许这些路径上的活动由对等实体以外的实体链接。
A client might wish to reduce linkability by switching to a new connection ID, source UDP port, or IP address (see [RFC8981]) when sending traffic after a period of inactivity.
Changing the address from which it sends packets at the same time might cause the server to detect a connection migration.
This ensures that the mechanisms that support migration are exercised even for clients that do not experience NAT rebindings or genuine migrations.
Changing address can cause a peer to reset its congestion control state (see Section 9.4), so addresses SHOULD only be changed infrequently.
在一段时间不活动后发送流量时,客户端可能希望通过切换到新的连接 ID、源 UDP 端口或 IP 地址(参见 [RFC8981])来降低可链接性。
同时更改它发送数据包的地址可能会导致服务器检测到连接迁移。
这确保即使对于没有经历 NAT 重新绑定或真正迁移的客户端,也可以使用支持迁移的机制。
更改地址可能会导致对等方重置其拥塞控制状态(参见第 9.4 节),因此地址应该只偶尔更改。
An endpoint that exhausts available connection IDs cannot probe new paths or initiate migration, nor can it respond to probes or attempts by its peer to migrate.
To ensure that migration is possible and packets sent on different paths cannot be correlated, endpoints SHOULD provide new connection IDs before peers migrate; see Section 5.1.1.
If a peer might have exhausted available connection IDs, a migrating endpoint could include a NEW_CONNECTION_ID frame in all packets sent on a new network path.
耗尽可用连接 ID 的端点无法探测新路径或启动迁移,也无法响应其对等方的探测或迁移尝试。
为了确保迁移是可能的并且在不同路径上发送的数据包不能相互关联,端点应该在对等方迁移之前提供新的连接 ID;见第 5.1.1 节。
如果对等点可能已经用尽了可用的连接 ID,则迁移端点可以在新网络路径上发送的所有数据包中包含 NEW_CONNECTION_ID 帧。

9.6. Server’s Preferred Address

QUIC allows servers to accept connections on one IP address and attempt to transfer these connections to a more preferred address shortly after the handshake.
This is particularly useful when clients initially connect to an address shared by multiple servers but would prefer to use a unicast address to ensure connection stability.
This section describes the protocol for migrating a connection to a preferred server address.
QUIC 允许服务器接受一个 IP 地址上的连接,并在握手后不久尝试将这些连接转移到更首选的地址。
当客户端最初连接到由多个服务器共享的地址但更愿意使用单播地址以确保连接稳定性时,这特别有用。
本节介绍将连接迁移到首选服务器地址的协议。
Migrating a connection to a new server address mid-connection is not supported by the version of QUIC specified in this document.
If a client receives packets from a new server address when the client has not initiated a migration to that address, the client SHOULD discard these packets.
本文档中指定的 QUIC 版本不支持将连接迁移到中间连接的新服务器地址。
如果客户端从新的服务器地址接收到数据包,而客户端尚未启动到该地址的迁移,则客户端应该丢弃这些数据包。

9.6.1. Communicating a Preferred Address

A server conveys a preferred address by including the preferred_address transport parameter in the TLS handshake.
服务器通过在 TLS 握手中包含 preferred_address 传输参数来传达首选地址。
Servers MAY communicate a preferred address of each address family (IPv4 and IPv6) to allow clients to pick the one most suited to their network attachment.
服务器可以传达每个地址族(IPv4 和 IPv6)的首选地址,以允许客户端选择最适合其网络连接的地址。
Once the handshake is confirmed, the client SHOULD select one of the two addresses provided by the server and initiate path validation (see Section 8.2).
A client constructs packets using any previously unused active connection ID, taken from either the preferred_address transport parameter or a NEW_CONNECTION_ID frame.
一旦握手被确认,客户端应该选择服务器提供的两个地址之一并启动路径验证(见第 8.2 节)。
客户端使用任何以前未使用的活动连接 ID 构造数据包,该 ID 取自首选地址传输参数或 NEW_CONNECTION_ID 帧。
As soon as path validation succeeds, the client SHOULD begin sending all future packets to the new server address using the new connection ID and discontinue use of the old server address.
If path validation fails, the client MUST continue sending all future packets to the server’s original IP address.
一旦路径验证成功,客户端应该开始使用新的连接 ID 将所有未来的数据包发送到新的服务器地址,并停止使用旧的服务器地址。
如果路径验证失败,客户端必须继续将所有未来的数据包发送到服务器的原始 IP 地址。

9.6.2. Migration to a Preferred Address

A client that migrates to a preferred address MUST validate the address it chooses before migrating; see Section 21.5.3.
迁移到首选地址的客户端必须在迁移之前验证它选择的地址;见第 21.5.3 节。
A server might receive a packet addressed to its preferred IP address at any time after it accepts a connection.
If this packet contains a PATH_CHALLENGE frame, the server sends a packet containing a PATH_RESPONSE frame as per Section 8.2.
The server MUST send non- probing packets from its original address until it receives a non- probing packet from the client at its preferred address and until the server has validated the new path.
服务器可能会在接受连接后的任何时间收到发往其首选 IP 地址的数据包。
如果此数据包包含 PATH_CHALLENGE 帧,则服务器根据第 8.2 节发送包含 PATH_RESPONSE 帧的数据包。
服务器必须从其原始地址发送非探测数据包,直到它在其首选地址接收到来自客户端的非探测数据包,并且直到服务器验证了新路径。
The server MUST probe on the path toward the client from its preferred address.
This helps to guard against spurious migration initiated by an attacker.
服务器必须探测从其首选地址到客户端的路径。
这有助于防止攻击者发起的虚假迁移。
Once the server has completed its path validation and has received a non-probing packet with a new largest packet number on its preferred address, the server begins sending non-probing packets to the client exclusively from its preferred IP address.
The server SHOULD drop newer packets for this connection that are received on the old IP address.
The server MAY continue to process delayed packets that are received on the old IP address.
一旦服务器完成其路径验证并在其首选地址上接收到具有新的最大数据包编号的非探测数据包,服务器就会开始专门从其首选 IP 地址向客户端发送非探测数据包。
服务器应该丢弃在旧 IP 地址上收到的此连接的新数据包。
服务器可以继续处理在旧 IP 地址上接收到的延迟数据包。
The addresses that a server provides in the preferred_address transport parameter are only valid for the connection in which they are provided.
A client MUST NOT use these for other connections, including connections that are resumed from the current connection.
服务器在首选地址传输参数中提供的地址仅对提供它们的连接有效。
客户端不得将这些用于其他连接,包括从当前连接恢复的连接。

9.6.3. Interaction of Client Migration and Preferred Address

客户迁移与首选地址的交互
A client might need to perform a connection migration before it has migrated to the server’s preferred address.
In this case, the client SHOULD perform path validation to both the original and preferred server address from the client’s new address concurrently.
客户端可能需要在迁移到服务器的首选地址之前执行连接迁移。
在这种情况下,客户端应该同时执行从客户端的新地址到原始和首选服务器地址的路径验证。
If path validation of the server’s preferred address succeeds, the client MUST abandon validation of the original address and migrate to using the server’s preferred address.
If path validation of the server’s preferred address fails but validation of the server’s original address succeeds, the client MAY migrate to its new address and continue sending to the server’s original address.
如果服务器首选地址的路径验证成功,客户端必须放弃对原始地址的验证并迁移到使用服务器的首选地址。
如果服务器首选地址的路径验证失败但服务器原始地址的验证成功,客户端可以迁移到它的新地址并继续发送到服务器的原始地址。
If packets received at the server’s preferred address have a different source address than observed from the client during the handshake, the server MUST protect against potential attacks as described in Sections 9.3.1 and 9.3.2.
In addition to intentional simultaneous migration, this might also occur because the client’s access network used a different NAT binding for the server’s preferred address.
如果在服务器的首选地址接收到的数据包的源地址与在握手期间从客户端观察到的不同,则服务器必须防止潜在的攻击,如第 9.3.1 和 9.3.2 节所述。
除了有意的同时迁移之外,这也可能是因为客户端的访问网络对服务器的首选地址使用了不同的 NAT 绑定。
Servers SHOULD initiate path validation to the client’s new address upon receiving a probe packet from a different address; see Section 8.
服务器应该在接收到来自不同地址的探测包时启动对客户端新地址的路径验证;见第 8 节。
A client that migrates to a new address SHOULD use a preferred address from the same address family for the server.
迁移到新地址的客户端应该为服务器使用来自同一地址族的首选地址。
The connection ID provided in the preferred_address transport parameter is not specific to the addresses that are provided.
This connection ID is provided to ensure that the client has a connection ID available for migration, but the client MAY use this connection ID on any path.
在 preferred_address 传输参数中提供的连接 ID 并不特定于所提供的地址。
提供此连接 ID 是为了确保客户端具有可用于迁移的连接 ID,但客户端可以在任何路径上使用此连接 ID。

9.7. Use of IPv6 Flow Label and Migration

Endpoints that send data using IPv6 SHOULD apply an IPv6 flow label in compliance with [RFC6437], unless the local API does not allow setting IPv6 flow labels.
使用 IPv6 发送数据的端点应该应用符合 [RFC6437] 的 IPv6 流标签,除非本地 API 不允许设置 IPv6 流标签。
The flow label generation MUST be designed to minimize the chances of linkability with a previously used flow label, as a stable flow label would enable correlating activity on multiple paths; see Section 9.5.
流标签生成必须设计为尽量减少与先前使用的流标签的可链接性,因为稳定的流标签将能够关联多条路径上的活动; 见第 9.5 节。
[RFC6437] suggests deriving values using a pseudorandom function to generate flow labels.
Including the Destination Connection ID field in addition to source and destination addresses when generating flow labels ensures that changes are synchronized with changes in other observable identifiers.
A cryptographic hash function that combines these inputs with a local secret is one way this might be implemented.
[RFC6437] 建议使用伪随机函数导出值以生成流标签。
在生成流标签时,除了源地址和目标地址之外,还包括目标连接 ID 字段可确保更改与其他可观察标识符的更改同步。
将这些输入与本地机密相结合的加密哈希函数是可能实现的一种方式。

10. Connection Termination

1
2
3
4
5
An established QUIC connection can be terminated in one of three   ways:
* idle timeout (Section 10.1)
* immediate close (Section 10.2)
* stateless reset (Section 10.3)
An endpoint MAY discard connection state if it does not have a validated path on which it can send packets; see Section 8.2.
10.1. Idle Timeout

If a max_idle_timeout is specified by either endpoint in its transport parameters (Section 18.2), the connection is silently closed and its state is discarded when it remains idle for longer than the minimum of the max_idle_timeout value advertised by both endpoints.
如果 max_idle_timeout 由任一端点在其传输参数中指定(第 18.2 节),则连接将静默关闭,并且当它保持空闲的时间超过两个端点通告的 max_idle_timeout 值的最小值时,将丢弃其状态。
Each endpoint advertises a max_idle_timeout, but the effective value at an endpoint is computed as the minimum of the two advertised values (or the sole advertised value, if only one endpoint advertises a non-zero value).
By announcing a max_idle_timeout, an endpoint commits to initiating an immediate close (Section 10.2) if it abandons the connection prior to the effective value.
每个端点都通告一个 max_idle_timeout,但端点处的有效值被计算为两个通告值中的最小值(或唯一通告值,如果只有一个端点通告非零值)。
通过宣布 max_idle_timeout,如果端点在有效值之前放弃连接,则端点承诺启动立即关闭(第 10.2 节)。
An endpoint restarts its idle timer when a packet from its peer is received and processed successfully.
An endpoint also restarts its idle timer when sending an ack-eliciting packet if no other ack- eliciting packets have been sent since last receiving and processing a packet.
Restarting this timer when sending a packet ensures that connections are not closed after new activity is initiated.
当成功接收并处理来自其对等方的数据包时,端点重新启动其空闲计时器。
如果自上次接收和处理数据包后没有发送其他确认数据包,端点也会在发送确认数据包时重新启动其空闲计时器。
在发送数据包时重新启动此计时器可确保在启动新活动后连接不会关闭。
To avoid excessively small idle timeout periods, endpoints MUST increase the idle timeout period to be at least three times the current Probe Timeout (PTO).
This allows for multiple PTOs to expire, and therefore multiple probes to be sent and lost, prior to idle timeout.
为了避免过小的空闲超时时间,端点必须将空闲超时时间增加到至少是当前探测超时(PTO)的三倍。
这允许多个 PTO 过期,因此在空闲超时之前发送和丢失多个探测。

10.1.1. Liveness Testing

An endpoint that sends packets close to the effective timeout risks having them be discarded at the peer, since the idle timeout period might have expired at the peer before these packets arrive.
发送接近有效超时的数据包的端点有可能在对等方丢弃它们,因为空闲超时期限可能在这些数据包到达之前在对等方已到期。
An endpoint can send a PING or another ack-eliciting frame to test the connection for liveness if the peer could time out soon, such as within a PTO; see Section 6.2 of [QUIC-RECOVERY].
This is especially useful if any available application data cannot be safely retried.
Note that the application determines what data is safe to retry.
如果对等方可能很快超时,例如在 PTO 内,端点可以发送 PING 或另一个确认帧来测试连接的活跃性; 请参阅 [QUIC-RECOVERY] 的第 6.2 节。
如果无法安全地重试任何可用的应用程序数据,这将特别有用。
请注意,应用程序确定哪些数据可以安全重试。

10.1.2. Deferring Idle Timeout 推迟

An endpoint might need to send ack-eliciting packets to avoid an idle timeout if it is expecting response data but does not have or is unable to send application data.
如果端点期待响应数据但没有或无法发送应用程序数据,它可能需要发送 ack-eliciting 数据包以避免空闲超时。
An implementation of QUIC might provide applications with an option to defer an idle timeout.
This facility could be used when the application wishes to avoid losing state that has been associated with an open connection but does not expect to exchange application data for some time.
With this option, an endpoint could send a PING frame (Section 19.2) periodically, which will cause the peer to restart its idle timeout period.
Sending a packet containing a PING frame restarts the idle timeout for this endpoint also if this is the first ack-eliciting packet sent since receiving a packet.
Sending a PING frame causes the peer to respond with an acknowledgment, which also restarts the idle timeout for the endpoint.
QUIC 的实现可能会为应用程序提供延迟空闲超时的选项。
当应用程序希望避免丢失与打开的连接相关的状态但不希望在一段时间内交换应用程序数据时,可以使用此工具。
使用此选项,端点可以定期发送 PING 帧(第 19.2 节),这将导致对等方重新启动其空闲超时周期。
发送包含 PING 帧的数据包会重新启动此端点的空闲超时,如果这是自接收数据包后发送的第一个确认请求数据包。
发送 PING 帧会导致对等方以确认响应,这也会重新启动端点的空闲超时。
Application protocols that use QUIC SHOULD provide guidance on when deferring an idle timeout is appropriate.
Unnecessary sending of PING frames could have a detrimental effect on performance.
使用 QUIC 的应用程序协议应该就何时推迟空闲超时提供指导。
不必要地发送 PING 帧可能会对性能产生不利影响。
A connection will time out if no packets are sent or received for a period longer than the time negotiated using the max_idle_timeout transport parameter; see Section 10.
However, state in middleboxes might time out earlier than that.
Though REQ-5 in [RFC4787] recommends a 2-minute timeout interval, experience shows that sending packets every 30 seconds is necessary to prevent the majority of middleboxes from losing state for UDP flows [GATEWAY].
如果在超过使用 max_idle_timeout 传输参数协商的时间的时间内没有发送或接收数据包,则连接将超时;见第 10 节。
但是,中间盒中的状态可能会比这更早超时。
尽管 [RFC4787] 中的 REQ-5 建议 2 分钟的超时间隔,但经验表明,每 30 秒发送一次数据包对于防止大多数中间盒丢失 UDP 流 [GATEWAY] 状态是必要的。

10.2. Immediate Close

An endpoint sends a CONNECTION_CLOSE frame (Section 19.19) to terminate the connection immediately.
A CONNECTION_CLOSE frame causes all streams to immediately become closed; open streams can be assumed to be implicitly reset.
端点发送一个 CONNECTION_CLOSE 帧(第 19.19 节)以立即终止连接。
CONNECTION_CLOSE 帧会导致所有流立即关闭;可以假设打开的流被隐式重置。
After sending a CONNECTION_CLOSE frame, an endpoint immediately enters the closing state; see Section 10.2.1.
After receiving a CONNECTION_CLOSE frame, endpoints enter the draining state; see Section 10.2.2.
发送一个CONNECTION_CLOSE帧后,端点立即进入关闭状态;见第 10.2.1 节。
端点收到CONNECTION_CLOSE帧后,进入draining状态;见第 10.2.2 节。
Violations of the protocol lead to an immediate close.
违反协议会导致立即关闭。
An immediate close can be used after an application protocol has arranged to close a connection.
This might be after the application protocol negotiates a graceful shutdown.
The application protocol can exchange messages that are needed for both application endpoints to agree that the connection can be closed, after which the application requests that QUIC close the connection.
When QUIC consequently closes the connection, a CONNECTION_CLOSE frame with an application-supplied error code will be used to signal closure to the peer.
在应用程序协议安排关闭连接后,可以使用立即关闭。
这可能是在应用程序协议协商正常关闭之后。
应用程序协议可以交换两个应用程序端点所需的消息,以同意可以关闭连接,之后应用程序请求 QUIC 关闭连接。
当 QUIC 因此关闭连接时,将使用带有应用程序提供的错误代码的 CONNECTION_CLOSE 帧向对等方发出关闭信号。
The closing and draining connection states exist to ensure that connections close cleanly and that delayed or reordered packets are properly discarded.
These states SHOULD persist for at least three times the current PTO interval as defined in [QUIC-RECOVERY].
存在关闭和耗尽连接状态以确保连接干净地关闭并且延迟或重新排序的数据包被正确丢弃。
这些状态应该持续至少三倍于 [QUIC-RECOVERY] 中定义的当前 PTO 间隔。
Disposing of connection state prior to exiting the closing or draining state could result in an endpoint generating a Stateless Reset unnecessarily when it receives a late-arriving packet.
Endpoints that have some alternative means to ensure that late- arriving packets do not induce a response, such as those that are able to close the UDP socket, MAY end these states earlier to allow for faster resource recovery.
Servers that retain an open socket for accepting new connections SHOULD NOT end the closing or draining state early.
在退出关闭或耗尽状态之前处理连接状态可能会导致端点在收到迟到的数据包时产生不必要的无状态重置。
有一些替代方法来确保迟到的数据包不会引起响应的端点,例如能够关闭 UDP 套接字的端点,可以提前结束这些状态以允许更快的资源恢复。
保留打开套接字以接受新连接的服务器不应提前结束关闭或耗尽状态。
Once its closing or draining state ends, an endpoint SHOULD discard all connection state.
The endpoint MAY send a Stateless Reset in response to any further incoming packets belonging to this connection.
一旦其关闭或耗尽状态结束,端点应该丢弃所有连接状态。
端点可以发送一个无状态复位来响应属于这个连接的任何进一步的传入数据包。

10.2.1. Closing Connection State

An endpoint enters the closing state after initiating an immediate close.
端点在发起立即关闭后进入关闭状态
In the closing state, an endpoint retains only enough information to generate a packet containing a CONNECTION_CLOSE frame and to identify packets as belonging to the connection.
An endpoint in the closing state sends a packet containing a CONNECTION_CLOSE frame in response to any incoming packet that it attributes to the connection.
在关闭状态下,端点只保留足够的信息来生成包含 CONNECTION_CLOSE 帧的数据包并将数据包标识为属于该连接。
处于关闭状态的端点发送一个包含 CONNECTION_CLOSE 帧的数据包,以响应它归属于连接的任何传入数据包。
An endpoint SHOULD limit the rate at which it generates packets in the closing state.
For instance, an endpoint could wait for a progressively increasing number of received packets or amount of time before responding to received packets.
端点应该限制它在关闭状态下生成数据包的速率。
例如,端点可以在响应接收到的数据包之前等待逐渐增加的接收数据包数量或时间量。
An endpoint’s selected connection ID and the QUIC version are sufficient information to identify packets for a closing connection; the endpoint MAY discard all other connection state.
An endpoint that is closing is not required to process any received frame.
An endpoint MAY retain packet protection keys for incoming packets to allow it to read and process a CONNECTION_CLOSE frame.
端点选择的连接 ID 和 QUIC 版本足以识别用于关闭连接的数据包;端点可以丢弃所有其他连接状态。
正在关闭的端点不需要处理任何接收到的帧。
端点可以保留传入数据包的数据包保护密钥,以允许它读取和处理 CONNECTION_CLOSE 帧。
An endpoint MAY drop packet protection keys when entering the closing state and send a packet containing a CONNECTION_CLOSE frame in response to any UDP datagram that is received.
However, an endpoint that discards packet protection keys cannot identify and discard invalid packets.
To avoid being used for an amplification attack, such endpoints MUST limit the cumulative size of packets it sends to three times the cumulative size of the packets that are received and attributed to the connection.
To minimize the state that an endpoint maintains for a closing connection, endpoints MAY send the exact same packet in response to any received packet.
端点可以在进入关闭状态时丢弃数据包保护密钥,并发送包含 CONNECTION_CLOSE 帧的数据包以响应接收到的任何 UDP 数据报。
但是,丢弃数据包保护密钥的端点无法识别和丢弃无效数据包。
为避免被用于放大攻击,此类端点必须将其发送的数据包的累积大小限制为接收并归因于连接的数据包的累积大小的三倍。
为了最小化端点为关闭连接而保持的状态,端点可以发送完全相同的数据包以响应任何接收到的数据包。
| Note: Allowing retransmission of a closing packet is an | exception to the requirement that a new packet number be used | for each packet; see Section 12.3.
Sending new packet numbers | is primarily of advantage to loss recovery and congestion | control, which are not expected to be relevant for a closed | connection.
Retransmitting the final packet requires less | state.
|注意:允许重新传输关闭数据包是 |要求使用新数据包编号的例外情况|对于每个数据包;见第 12.3 节。
发送新的数据包号码 |主要有利于损失恢复和拥塞|控制,预计与关闭的 | 无关联系。
重传最终数据包需要更少 |状态。
While in the closing state, an endpoint could receive packets from a new source address, possibly indicating a connection migration; see Section 9.
An endpoint in the closing state MUST either discard packets received from an unvalidated address or limit the cumulative size of packets it sends to an unvalidated address to three times the size of packets it receives from that address.
当处于关闭状态时,端点可以接收来自新源地址的数据包,这可能表明连接迁移;见第 9 节。
处于关闭状态的端点必须要么丢弃从未经验证的地址接收的数据包,要么将其发送到未经验证的地址的数据包的累积大小限制为从该地址接收的数据包大小的三倍。
An endpoint is not expected to handle key updates when it is closing (Section 6 of [QUIC-TLS]).
A key update might prevent the endpoint from moving from the closing state to the draining state, as the endpoint will not be able to process subsequently received packets, but it otherwise has no impact.
端点在关闭时不应处理密钥更新([QUIC-TLS] 的第 6 节)。
密钥更新可能会阻止端点从关闭状态移动到耗尽状态,因为端点将无法处理随后收到的数据包,但它不会产生任何影响。

10.2.2. Draining Connection State

The draining state is entered once an endpoint receives a CONNECTION_CLOSE frame, which indicates that its peer is closing or draining.
While otherwise identical to the closing state, an endpoint in the draining state MUST NOT send any packets.
Retaining packet protection keys is unnecessary once a connection is in the draining state.

An endpoint that receives a CONNECTION_CLOSE frame MAY send a single packet containing a CONNECTION_CLOSE frame before entering the draining state, using a NO_ERROR code if appropriate.
An endpoint MUST NOT send further packets.
Doing so could result in a constant exchange of CONNECTION_CLOSE frames until one of the endpoints exits the closing state.

An endpoint MAY enter the draining state from the closing state if it receives a CONNECTION_CLOSE frame, which indicates that the peer is also closing or draining.
In this case, the draining state ends when the closing state would have ended.
In other words, the endpoint uses the same end time but ceases transmission of any packets on this connection.

10.2.3. Immediate Close during the Handshake

When sending a CONNECTION_CLOSE frame, the goal is to ensure that the peer will process the frame.
Generally, this means sending the frame in a packet with the highest level of packet protection to avoid the packet being discarded.
After the handshake is confirmed (see Section 4.1.2 of [QUIC-TLS]), an endpoint MUST send any CONNECTION_CLOSE frames in a 1-RTT packet.
However, prior to confirming the handshake, it is possible that more advanced packet protection keys are not available to the peer, so another CONNECTION_CLOSE frame MAY be sent in a packet that uses a lower packet protection level.
More specifically:
发送 CONNECTION_CLOSE 帧时,目标是确保对等方将处理该帧。
通常,这意味着在具有最高数据包保护级别的数据包中发送帧,以避免数据包被丢弃。
在握手被确认后(参见 [QUIC-TLS] 的第 4.1.2 节),端点必须在 1-RTT 数据包中发送任何 CONNECTION_CLOSE 帧。
但是,在确认握手之前,可能对等方无法使用更高级的数据包保护密钥,因此可以在使用较低数据包保护级别的数据包中发送另一个 CONNECTION_CLOSE 帧。
进一步来说:

  • A client will always know whether the server has Handshake keys (see Section 17.2.2.1), but it is possible that a server does not know whether the client has Handshake keys.
    Under these circumstances, a server SHOULD send a CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure that at least one of them is processable by the client.

  • 客户端将始终知道服务器是否有握手密钥(参见第 17.2.2.1 节),但服务器可能不知道客户端是否有握手密钥。
    在这些情况下,服务器应该在握手和初始数据包中发送一个 CONNECTION_CLOSE 帧,以确保其中至少一个可以被客户端处理。

    • A client that sends a CONNECTION_CLOSE frame in a 0-RTT packet cannot be assured that the server has accepted 0-RTT.
      Sending a CONNECTION_CLOSE frame in an Initial packet makes it more likely that the server can receive the close signal, even if the application error code might not be received.
  • 在 0-RTT 数据包中发送 CONNECTION_CLOSE 帧的客户端不能保证服务器已接受 0-RTT。
    在初始数据包中发送 CONNECTION_CLOSE 帧使服务器更有可能接收到关闭信号,即使可能没有收到应用程序错误代码。

    • Prior to confirming the handshake, a peer might be unable to process 1-RTT packets, so an endpoint SHOULD send a CONNECTION_CLOSE frame in both Handshake and 1-RTT packets.
      A server SHOULD also send a CONNECTION_CLOSE frame in an Initial packet.
  • 在确认握手之前,对等点可能无法处理 1-RTT 数据包,因此端点应该在握手和 1-RTT 数据包中发送一个 CONNECTION_CLOSE 帧。
    服务器也应该在初始数据包中发送一个 CONNECTION_CLOSE 帧。
    Sending a CONNECTION_CLOSE of type 0x1d in an Initial or Handshake packet could expose application state or be used to alter application state.
    A CONNECTION_CLOSE of type 0x1d MUST be replaced by a CONNECTION_CLOSE of type 0x1c when sending the frame in Initial or Handshake packets.
    Otherwise, information about the application state might be revealed.
    Endpoints MUST clear the value of the Reason Phrase field and SHOULD use the APPLICATION_ERROR code when converting to a CONNECTION_CLOSE of type 0x1c.
    在 Initial 或 Handshake 数据包中发送 0x1d 类型的 CONNECTION_CLOSE 可能会暴露应用程序状态或用于更改应用程序状态。
    在 Initial 或 Handshake 数据包中发送帧时,类型 0x1d 的 CONNECTION_CLOSE 必须替换为类型 0x1c 的 CONNECTION_CLOSE。
    否则,可能会泄露有关应用程序状态的信息。
    端点必须清除原因短语字段的值,并且在转换为 0x1c 类型的 CONNECTION_CLOSE 时应该使用 APPLICATION_ERROR 代码。
    CONNECTION_CLOSE frames sent in multiple packet types can be coalesced into a single UDP datagram; see Section 12.2.
    以多种数据包类型发送的 CONNECTION_CLOSE 帧可以合并为单个 UDP 数据报;见第 12.2 节。
    An endpoint can send a CONNECTION_CLOSE frame in an Initial packet.
    This might be in response to unauthenticated information received in Initial or Handshake packets.
    Such an immediate close might expose legitimate connections to a denial of service.
    QUIC does not include defensive measures for on-path attacks during the handshake; see Section 21.2.
    However, at the cost of reducing feedback about errors for legitimate peers, some forms of denial of service can be made more difficult for an attacker if endpoints discard illegal packets rather than terminating a connection with CONNECTION_CLOSE.
    For this reason, endpoints MAY discard packets rather than immediately close if errors are detected in packets that lack authentication.

    An endpoint that has not established state, such as a server that detects an error in an Initial packet, does not enter the closing state.
    An endpoint that has no state for the connection does not enter a closing or draining period on sending a CONNECTION_CLOSE frame.

端点可以在初始数据包中发送 CONNECTION_CLOSE 帧。
这可能是对在 Initial 或 Handshake 数据包中收到的未经身份验证的信息的响应。
这种立即关闭可能会将合法连接暴露给拒绝服务。
QUIC 不包括握手期间的路径攻击防御措施;见第 21.2 节。
但是,如果端点丢弃非法数据包而不是使用 CONNECTION_CLOSE 终止连接,则以减少对合法对等方错误的反馈为代价,某些形式的拒绝服务可能会使攻击者更加困难。
因此,如果在缺少身份验证的数据包中检测到错误,端点可以丢弃数据包而不是立即关闭。

尚未建立状态的端点,例如在初始数据包中检测到错误的服务器,不会进入关闭状态。
没有连接状态的端点在发送 CONNECTION_CLOSE 帧时不会进入关闭或耗尽期。

10.3. Stateless Reset

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 crash or outage might result in peers continuing to send data to an endpoint that is unable to properly continue the connection.
An endpoint MAY send a Stateless Reset in response to receiving a packet that it cannot associate with an active connection.
对于无法访问连接状态的端点,提供无状态重置作为最后手段的选项。
崩溃或中断可能会导致对等方继续向无法正确继续连接的端点发送数据。
端点可以发送无状态重置以响应接收到它无法与活动连接关联的数据包。
A stateless reset is not appropriate for indicating errors in active connections.
An endpoint that wishes to communicate a fatal connection error MUST use a CONNECTION_CLOSE frame if it is able.
无状态重置不适用于指示活动连接中的错误。
如果可以的话,希望传达致命连接错误的端点必须使用 CONNECTION_CLOSE 帧。
To support this process, an endpoint issues a stateless reset token, which is a 16-byte value that is hard to guess.
If the peer subsequently receives a Stateless Reset, which is a UDP datagram that ends in that stateless reset token, the peer will immediately end the connection.
为了支持这个过程,端点发出一个无状态的重置令牌,它是一个难以猜测的 16 字节值。
如果对等方随后收到无状态重置,这是一个以该无状态重置令牌结尾的 UDP 数据报,对等方将立即结束连接。
A stateless reset token is specific to a connection ID.
An endpoint issues a stateless reset token by including the value in the Stateless Reset Token field of a NEW_CONNECTION_ID frame.
Servers can also issue a stateless_reset_token transport parameter during the handshake that applies to the connection ID that it selected during the handshake.
These exchanges are protected by encryption, so only client and server know their value.
Note that clients cannot use the stateless_reset_token transport parameter because their transport parameters do not have confidentiality protection.
无状态重置令牌特定于连接 ID。
端点通过将值包含在 NEW_CONNECTION_ID 帧的无状态重置令牌字段中来发出无状态重置令牌。
服务器还可以在握手期间发出 stateless_reset_token 传输参数,该参数应用于它在握手期间选择的连接 ID。
这些交换受到加密保护,因此只有客户端和服务器知道它们的价值。
请注意,客户端不能使用 stateless_reset_token 传输参数,因为它们的传输参数没有机密性保护。
Tokens are invalidated when their associated connection ID is retired via a RETIRE_CONNECTION_ID frame (Section 19.16).
当关联的连接 ID 通过 RETIRE_CONNECTION_ID 帧(第 19.16 节)停用时,令牌将失效。
An endpoint that receives packets that it cannot process sends a packet in the following layout (see Section 1.3):
Stateless Reset { Fixed Bits (2) = 1, Unpredictable Bits (38..), Stateless Reset Token (128), }
Figure 10: Stateless Reset
接收到无法处理的数据包的端点以以下布局发送数据包(参见第 1.3 节):
无状态复位 { 固定位 (2) = 1,不可预测位 (38..),无状态复位令牌 (128),}
图 10:无状态复位
This design ensures that a Stateless Reset is – to the extent possible – indistinguishable from a regular packet with a short header.
这种设计可确保无状态复位在可能的范围内与具有短标头的常规数据包无法区分。
A Stateless Reset uses an entire UDP datagram, starting with the first two bits of the packet header.
The remainder of the first byte and an arbitrary number of bytes following it are set to values that SHOULD be indistinguishable from random.
The last 16 bytes of the datagram contain a stateless reset token.
无状态重置使用整个 UDP 数据报,从数据包头的前两位开始。
第一个字节的其余部分和它后面的任意数量的字节被设置为应该与随机无法区分的值。
数据报的最后 16 个字节包含一个无状态复位令牌。
To entities other than its intended recipient, a Stateless Reset will appear to be a packet with a short header.
For the Stateless Reset to appear as a valid QUIC packet, the Unpredictable Bits field needs to include at least 38 bits of data (or 5 bytes, less the two fixed bits).
对于其预期接收者以外的实体,无状态重置似乎是一个带有短标头的数据包。
要使无状态复位显示为有效的 QUIC 数据包,不可预测位字段需要包含至少 38 位数据(或 5 个字节,减去两个固定位)。
The resulting minimum size of 21 bytes does not guarantee that a Stateless Reset is difficult to distinguish from other packets if the recipient requires the use of a connection ID.
To achieve that end, the endpoint SHOULD ensure that all packets it sends are at least 22 bytes longer than the minimum connection ID length that it requests the peer to include in its packets, adding PADDING frames as necessary.
This ensures that any Stateless Reset sent by the peer is indistinguishable from a valid packet sent to the endpoint.
An endpoint that sends a Stateless Reset in response to a packet that is 43 bytes or shorter SHOULD send a Stateless Reset that is one byte
shorter than the packet it responds to.
如果接收方要求使用连接 ID,则生成的 21 字节的最小大小并不能保证无状态重置很难与其他数据包区分开来。
为了达到这个目的,端点应该确保它发送的所有数据包至少比它请求对等方包含在其数据包中的最小连接 ID 长度长 22 个字节,并在必要时添加 PADDING 帧。
这确保了对等方发送的任何无状态重置与发送到端点的有效数据包无法区分。
发送无状态重置以响应 43 字节或更短的数据包的端点应该发送比它响应的数据包短一个字节的无状态重置。
These values assume that the stateless reset token is the same length as the minimum expansion of the packet protection AEAD.
Additional unpredictable bytes are necessary if the endpoint could have negotiated a packet protection scheme with a larger minimum expansion.
这些值假定无状态重置令牌与数据包保护 AEAD 的最小扩展长度相同。
如果端点可以协商具有更大最小扩展的数据包保护方案,则需要额外的不可预测的字节。
An endpoint MUST NOT send a Stateless Reset that is three times or more larger than the packet it receives to avoid being used for amplification.
Section 10.3.3 describes additional limits on Stateless Reset size.
端点不得发送比它接收到的数据包大三倍或更多的无状态重置,以避免被用于放大。
第 10.3.3 节描述了对无状态重置大小的附加限制。
Endpoints MUST discard packets that are too small to be valid QUIC packets.
To give an example, with the set of AEAD functions defined in [QUIC-TLS], short header packets that are smaller than 21 bytes are never valid.
端点必须丢弃太小而不能成为有效 QUIC 数据包的数据包。
举个例子,使用 [QUIC-TLS] 中定义的 AEAD 函数集,小于 21 字节的短头数据包永远不会有效。
Endpoints MUST send Stateless Resets formatted as a packet with a short header.
However, endpoints MUST treat any packet ending in a valid stateless reset token as a Stateless Reset, as other QUIC versions might allow the use of a long header.
端点必须发送格式化为具有短标头的数据包的无状态重置。
但是,端点必须将任何以有效无状态重置令牌结尾的数据包视为无状态重置,因为其他 QUIC 版本可能允许使用长标头。
An endpoint MAY send a Stateless Reset in response to a packet with a long header.
Sending a Stateless Reset is not effective prior to the stateless reset token being available to a peer.
In this QUIC version, packets with a long header are only used during connection establishment.
Because the stateless reset token is not available until connection establishment is complete or near completion, ignoring an unknown packet with a long header might be as effective as sending a Stateless Reset.
一个端点可以发送一个无状态复位来响应一个带有长头的数据包。
在无状态重置令牌可供对等方使用之前,发送无状态重置无效。
在这个 QUIC 版本中,具有长标头的数据包仅在连接建立期间使用。
由于无状态重置令牌在连接建立完成或接近完成之前不可用,因此忽略具有长标头的未知数据包可能与发送无状态重置一样有效。
An endpoint cannot determine the Source Connection ID from a packet with a short header; therefore, it cannot set the Destination Connection ID in the Stateless Reset.
The Destination Connection ID will therefore differ from the value used in previous packets.
A random Destination Connection ID makes the connection ID appear to be the result of moving to a new connection ID that was provided using a NEW_CONNECTION_ID frame; see Section 19.15.
端点无法从具有短标头的数据包中确定源连接 ID;因此,它无法在 Stateless Reset 中设置 Destination Connection ID。
因此,目标连接 ID 将不同于先前数据包中使用的值。
随机目标连接 ID 使连接 ID 看起来是移动到使用 NEW_CONNECTION_ID 帧提供的新连接 ID 的结果;见第 19.15 节。
Using a randomized connection ID results in two problems:

  • The packet might not reach the peer.
    If the Destination Connection ID is critical for routing toward the peer, then this packet could be incorrectly routed.
    This might also trigger another Stateless Reset in response; see Section 10.3.3.
    A Stateless Reset that is not correctly routed is an ineffective error detection and recovery mechanism.
    In this case, endpoints will need to rely on other methods – such as timers – to detect that the connection has failed.
    使用随机连接 ID 会导致两个问题:
  • 数据包可能无法到达对等方。
    如果目标连接 ID 对于向对等方路由至关重要,则此数据包可能被错误地路由。
    这也可能触发另一个无状态重置作为响应;见第 10.3.3 节。
    未正确路由的无状态复位是一种无效的错误检测和恢复机制。
    在这种情况下,端点将需要依赖其他方法(例如计时器)来检测连接是否失败。
  • The randomly generated connection ID can be used by entities other than the peer to identify this as a potential Stateless Reset.
    An endpoint that occasionally uses different connection IDs might introduce some uncertainty about this.
  • 随机生成的连接 ID 可由对等方以外的实体使用,以将其识别为潜在的无状态重置。
    偶尔使用不同连接 ID 的端点可能会对此带来一些不确定性。
    This stateless reset design is specific to QUIC version 1.
    An endpoint that supports multiple versions of QUIC needs to generate a Stateless Reset that will be accepted by peers that support any version that the endpoint might support (or might have supported prior to losing state).
    Designers of new versions of QUIC need to be aware of this and either (1) reuse this design or (2) use a portion of the packet other than the last 16 bytes for carrying data.
    这种无状态复位设计特定于 QUIC 版本 1。
    支持多个版本的 QUIC 的端点需要生成一个无状态重置,该无状态重置将被支持该端点可能支持的任何版本(或在丢失状态之前可能已经支持)的对等方接受。
    新版本 QUIC 的设计者需要意识到这一点,或者 (1) 重用这个设计,或者 (2) 使用数据包的一部分而不是最后 16 个字节来承载数据。
    10.3.1. Detecting a Stateless Reset
    An endpoint detects a potential Stateless Reset using the trailing 16 bytes of the UDP datagram.
    An endpoint remembers all stateless reset tokens associated with the connection IDs and remote addresses for datagrams it has recently sent.
    This includes Stateless Reset Token field values from NEW_CONNECTION_ID frames and the server’s transport parameters but excludes stateless reset tokens associated with connection IDs that are either unused or retired.
    The endpoint identifies a received datagram as a Stateless Reset by comparing the last 16 bytes of the datagram with all stateless reset tokens associated with the remote address on which the datagram was received.

端点使用 UDP 数据报的尾随 16 个字节检测潜在的无状态复位。
端点会记住与其最近发送的数据报的连接 ID 和远程地址相关的所有无状态重置令牌。
这包括来自 NEW_CONNECTION_ID 帧的无状态重置令牌字段值和服务器的传输参数,但不包括与未使用或已停用的连接 ID 关联的无状态重置令牌。
端点通过将数据报的最后 16 个字节与与接收数据报的远程地址相关联的所有无状态重置令牌进行比较,将接收到的数据报识别为无状态重置。
This comparison can be performed for every inbound datagram.
Endpoints MAY skip this check if any packet from a datagram is successfully processed.
However, the comparison MUST be performed when the first packet in an incoming datagram either cannot be associated with a connection or cannot be decrypted.
可以对每个入站数据报执行此比较。
如果数据报中的任何数据包被成功处理,端点可以跳过此检查。
但是,当传入数据报中的第一个数据包不能与连接关联或不能解密时,必须执行比较。
An endpoint MUST NOT check for any stateless reset tokens associated with connection IDs it has not used or for connection IDs that have been retired.
端点不得检查与它未使用的连接 ID 相关联的任何无状态重置令牌或已停用的连接 ID。
When comparing a datagram to stateless reset token values, endpoints MUST perform the comparison without leaking information about the value of the token.
For example, performing this comparison in constant time protects the value of individual stateless reset tokens from information leakage through timing side channels.
Another approach would be to store and compare the transformed values of stateless reset tokens instead of the raw token values, where the transformation is defined as a cryptographically secure pseudorandom function using a secret key (e.g.
, block cipher, Hashed Message Authentication Code (HMAC) [RFC2104]).
An endpoint is not expected to protect information about whether a packet was successfully decrypted or the number of valid stateless reset tokens.
在将数据报与无状态重置令牌值进行比较时,端点必须执行比较而不泄露有关令牌值的信息。
例如,在恒定时间内执行此比较可保护各个无状态重置令牌的值免受通过时序侧通道的信息泄漏。
另一种方法是存储和比较无状态重置令牌的转换值而不是原始令牌值,其中转换定义为使用密钥的加密安全伪随机函数(例如
、分组密码、散列消息验证码 (HMAC) [RFC2104])。
端点不应保护有关数据包是否成功解密或有效无状态重置令牌数量的信息。
If the last 16 bytes of the datagram are identical in value to a stateless reset token, the endpoint MUST enter the draining period and not send any further packets on this connection.
如果数据报的最后 16 个字节的值与无状态重置令牌的值相同,则端点必须进入耗尽期并且不再在此连接上发送任何数据包。

10.3.2. Calculating a Stateless Reset Token

The stateless reset token MUST be difficult to guess.
In order to create a stateless reset token, an endpoint could randomly generate [RANDOM] a secret for every connection that it creates.
However, this presents a coordination problem when there are multiple instances in a cluster or a storage problem for an endpoint that might lose state.
Stateless reset specifically exists to handle the case where state is lost, so this approach is suboptimal.
无状态重置令牌必须难以猜测。
为了创建无状态重置令牌,端点可以为它创建的每个连接随机生成 [RANDOM] 秘密。
但是,当集群中有多个实例或可能丢失状态的端点的存储问题时,这会出现协调问题。
无状态重置专门用于处理状态丢失的情况,因此这种方法不是最理想的。
A single static key can be used across all connections to the same endpoint by generating the proof using a pseudorandom function that takes a static key and the connection ID chosen by the endpoint (see Section 5.1) as input.
An endpoint could use HMAC [RFC2104] (for example, HMAC(static_key, connection_id)) or the HMAC-based Key Derivation Function (HKDF) [RFC5869] (for example, using the static key as input keying material, with the connection ID as salt).
The output of this function is truncated to 16 bytes to produce the stateless reset token for that connection.
通过使用伪随机函数生成证明,可以在到同一端点的所有连接中使用单个静态密钥,该函数将静态密钥和端点选择的连接 ID(参见第 5.1 节)作为输入。
端点可以使用 HMAC [RFC2104](例如,HMAC(static_key, connection_id))或基于 HMAC 的密钥派生函数 (HKDF) [RFC5869](例如,使用静态密钥作为输入密钥材料,带有连接 ID作为盐)。
此函数的输出被截断为 16 个字节,以生成该连接的无状态重置令牌。
An endpoint that loses state can use the same method to generate a valid stateless reset token.
The connection ID comes from the packet that the endpoint receives.
丢失状态的端点可以使用相同的方法来生成有效的无状态重置令牌。
连接 ID 来自端点接收的数据包。
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 to reset the connection.
An endpoint that uses this design MUST either use the same connection ID length for all connections or encode the length of the connection ID such that it can be recovered without state.
In addition, it cannot provide a zero-length connection ID.
这种设计依赖于对等方始终在其数据包中发送连接 ID,以便端点可以使用数据包中的连接 ID 来重置连接。
使用这种设计的端点必须要么对所有连接使用相同的连接 ID 长度,要么对连接 ID 的长度进行编码,以便可以在没有状态的情况下恢复它。
此外,它不能提供零长度的连接 ID。
Revealing the stateless reset token allows any entity to terminate the connection, so a value can only be used once.
This method for choosing the stateless reset token means that the combination of connection ID and static key MUST NOT be used for another connection.
A 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 cause a packet to be routed to an instance that has no state but the same static key; see Section 21.11.
A connection ID from a connection that is reset by revealing the stateless reset token MUST NOT be reused for new connections at nodes that share a static key.
显示无状态重置令牌允许任何实体终止连接,因此一个值只能使用一次。
这种选择无状态重置令牌的方法意味着连接 ID 和静态密钥的组合不得用于另一个连接。
如果共享静态密钥的实例使用相同的连接 ID,或者如果攻击者可以将数据包路由到没有状态但具有相同静态密钥的实例,则可能发生拒绝服务攻击;见第 21.11 节。
通过显示无状态重置令牌重置的连接中的连接 ID 不得用于共享静态密钥的节点上的新连接。
The same stateless reset token MUST NOT be used for multiple connection IDs.
Endpoints are not required to compare new values against all previous values, but a duplicate value MAY be treated as a connection error of type PROTOCOL_VIOLATION.

Note that Stateless Resets do not have any cryptographic protection.
同一个无状态重置令牌不得用于多个连接 ID。
端点不需要将新值与所有以前的值进行比较,但重复值可以被视为 PROTOCOL_VIOLATION 类型的连接错误。

请注意,无状态重置没有任何加密保护。

10.3.3. Looping 死锁?死循环

The design of a Stateless Reset is such that without knowing the stateless reset token it is indistinguishable from a valid packet.
For instance, if a server sends a Stateless Reset to another server, it might receive another Stateless Reset in response, which could lead to an infinite exchange.
无状态重置的设计使得在不知道无状态重置令牌的情况下无法将其与有效数据包区分开来。
例如,如果服务器向另一台服务器发送无状态重置,它可能会收到另一个无状态重置作为响应,这可能导致无限交换。
An endpoint MUST ensure that every Stateless Reset that it sends is smaller than the packet that triggered it, unless it maintains state sufficient to prevent looping.
In the event of a loop, this results in packets eventually being too small to trigger a response.
端点必须确保它发送的每个无状态重置都小于触发它的数据包,除非它保持足以防止循环的状态。
如果发生循环,这将导致数据包最终太小而无法触发响应。
An endpoint can remember the number of Stateless Resets that it has sent and stop generating new Stateless Resets once a limit is reached.
Using separate limits for different remote addresses will ensure that Stateless Resets can be used to close connections when other peers or connections have exhausted limits.
端点可以记住它已发送的无状态重置的数量,并在达到限制后停止生成新的无状态重置。
对不同的远程地址使用单独的限制将确保无状态重置可用于在其他对等方或连接已用尽限制时关闭连接。
A Stateless Reset that is smaller than 41 bytes might be identifiable as a Stateless Reset by an observer, depending upon the length of the peer’s connection IDs.
Conversely, not sending a Stateless Reset in response to a small packet might result in Stateless Resets not being useful in detecting cases of broken connections where only very small packets are sent; such failures might only be detected by other means, such as timers.
小于 41 字节的无状态重置可能会被观察者识别为无状态重置,具体取决于对等方的连接 ID 的长度。
相反,不发送无状态重置以响应小数据包可能会导致无状态重置无法用于检测仅发送非常小的数据包的断开连接的情况;此类故障可能只能通过其他方式(例如计时器)检测到。

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.
Only application- level errors can be isolated to a single stream; see Section 11.2.
检测到错误的端点应该向其对等方发送该错误的存在信号。
传输级和应用级错误都会影响整个连接;见第 11.1 节。
只有应用程序级别的错误可以隔离到单个流中;见第 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; though these are worded as requirements, different implementation strategies might lead to different errors being reported.
In particular, an endpoint MAY use any applicable error code when it detects an error condition; a generic error code (such as PROTOCOL_VIOLATION or INTERNAL_ERROR) can always be used in place of specific error codes.
最合适的错误代码(第 20 节)应该包含在发出错误信号的帧中。
在本规范标识错误条件的地方,它也标识了所使用的错误代码;尽管这些被表述为要求,但不同的实施策略可能会导致报告不同的错误。
特别是,端点在检测到错误条件时可以使用任何适用的错误代码;通用错误代码(例如 PROTOCOL_VIOLATION 或 INTERNAL_ERROR)始终可以用来代替特定错误代码。
A stateless reset (Section 10.3) is not suitable for any error that can be signaled with a CONNECTION_CLOSE or RESET_STREAM frame.
A stateless reset MUST NOT be used by an endpoint that has the state necessary to send a frame on the connection.
无状态重置(第 10.3 节)不适用于可以通过 CONNECTION_CLOSE 或 RESET_STREAM 帧发出信号的任何错误。
具有在连接上发送帧所必需的状态的端点不得使用无状态重置。

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 frame (Section 19.19).
导致连接不可用的错误,例如明显违反协议语义或影响整个连接的状态损坏,必须使用 CONNECTION_CLOSE 帧(第 19.19 节)发出信号。
Application-specific protocol errors are signaled using the CONNECTION_CLOSE frame with a frame type of 0x1d.
Errors that are specific to the transport, including all those described in this document, are carried in the CONNECTION_CLOSE frame with a frame type of 0x1c.
应用程序特定的协议错误使用帧类型为 0x1d 的 CONNECTION_CLOSE 帧发出信号。
特定于传输的错误,包括本文档中描述的所有错误,都在帧类型为 0x1c 的 CONNECTION_CLOSE 帧中携带。
A CONNECTION_CLOSE frame could be sent in a packet that is lost.
An endpoint SHOULD be prepared to retransmit a packet containing a CONNECTION_CLOSE frame 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.
CONNECTION_CLOSE 帧可以在丢失的数据包中发送。
如果端点在终止的连接上接收到更多数据包,则应该准备重新传输包含 CONNECTION_CLOSE 帧的数据包。
限制重传次数和发送此最终数据包的时间限制了终止连接所花费的努力。
An endpoint that chooses not to retransmit packets containing a CONNECTION_CLOSE frame 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 attempt the stateless reset process (Section 10.3).
选择不重新传输包含 CONNECTION_CLOSE 帧的数据包的端点有可能导致对等方丢失第一个这样的数据包。
继续接收终止连接的数据的端点唯一可用的机制是尝试无状态重置过程(第 10.3 节)。
As the AEAD for Initial packets does not provide strong authentication, an endpoint MAY discard an invalid Initial packet.
Discarding an Initial packet is permitted even where this specification otherwise mandates a connection error.
An endpoint can only discard a packet if it does not process the frames in the packet or reverts the effects of any processing.
Discarding invalid Initial packets might be used to reduce exposure to denial of service; see Section 21.2.
由于初始数据包的 AEAD 不提供强认证,端点可以丢弃无效的初始数据包。
即使本规范要求连接错误,也允许丢弃初始数据包。
如果端点不处理数据包中的帧或恢复任何处理的效果,则端点只能丢弃数据包。
丢弃无效的初始数据包可用于减少拒绝服务的风险;见第 21.2 节。

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 RESET_STREAM frame (Section 19.4) with an appropriate error code to terminate just the affected stream.
如果应用程序级错误影响单个流,但使连接处于可恢复状态,则端点可以发送带有适当错误代码的 RESET_STREAM 帧(第 19.4 节)以仅终止受影响的流。
Resetting a stream without the involvement of the application protocol could cause the application protocol to enter an unrecoverable state.
RESET_STREAM MUST only be instigated by the application protocol that uses QUIC.
在不涉及应用程序协议的情况下重置流可能会导致应用程序协议进入不可恢复状态。
RESET_STREAM 只能由使用 QUIC 的应用程序协议发起。
The semantics of the application error code carried in RESET_STREAM are defined by the application protocol.
Only the application protocol is able to cause a stream to be terminated.
A local instance of the application protocol uses a direct API call, and a remote instance uses the STOP_SENDING frame, which triggers an automatic RESET_STREAM.
RESET_STREAM 中携带的应用程序错误代码的语义由应用程序协议定义。
只有应用程序协议能够导致流终止。
应用程序协议的本地实例使用直接 API 调用,远程实例使用 STOP_SENDING 帧,这会触发自动 RESET_STREAM。
Application protocols SHOULD define rules for handling streams that are prematurely canceled by either endpoint.
应用程序协议应该定义规则来处理被任一端点提前取消的流。

12. Packets and Frames

packets and Frames
QUIC endpoints communicate by exchanging packets. Packets have
confidentiality and integrity protection; see Section 12.1. Packets
are carried in UDP datagrams; see Section 12.2.
QUIC通过包交流信息。包被保密性和完整性保护。包放在udp数据报中。

This version of QUIC uses the long packet header during connection
establishment; see Section 17.2. Packets with the long header are
Initial (Section 17.2.2), 0-RTT (Section 17.2.3), Handshake
(Section 17.2.4), and Retry (Section 17.2.5). Version negotiation
uses a version-independent packet with a long header; see
Section 17.2.1.
这个版本的QUIC使用长的包头在连接建立的时候。见。。
具有长包头的包有:Init,0-RTT,Handshake,和Retry. version negatiation 使用一个独立的version的包带long header.

Packets with the short header are designed for minimal overhead and
are used after a connection is established and 1-RTT keys are
available; see Section 17.3.
带有短标头的数据包设计用于最小的开销和
在建立连接并使用 1-RTT 密钥后使用
可用的;见第 17.3 节。

12.1. Protected Packets

QUIC packets have different levels of cryptographic protection based
on the type of packet. Details of packet protection are found in
[QUIC-TLS]; this section includes an overview of the protections that
are provided.

Version Negotiation packets have no cryptographic protection; see
[QUIC-INVARIANTS].

Retry packets use an AEAD function [AEAD] to protect against
accidental modification.

Initial packets use an AEAD function, the keys for which are derived
using a value that is visible on the wire. Initial packets therefore
do not have effective confidentiality protection. Initial protection
exists to ensure that the sender of the packet is on the network
path. Any entity that receives an Initial packet from a client can
recover the keys that will allow them to both read the contents of
the packet and generate Initial packets that will be successfully
authenticated at either endpoint. The AEAD also protects Initial
packets against accidental modification.

All other packets are protected with keys derived from the
cryptographic handshake. The cryptographic handshake ensures that
only the communicating endpoints receive the corresponding keys for
Handshake, 0-RTT, and 1-RTT packets. Packets protected with 0-RTT
and 1-RTT keys have strong confidentiality and integrity protection.

The Packet Number field that appears in some packet types has
alternative confidentiality protection that is applied as part of
header protection; see Section 5.4 of [QUIC-TLS] for details. The
underlying packet number increases with each packet sent in a given
packet number space; see Section 12.3 for details.

protected packets
不同的包类别,加密情况不同,加密的细节见QUIC_TLS.
几种包的加密情况:
1) Version Negotiation packets have no cryptographic protection; see
[QUIC-INVARIANTS].
2)Retry packets use an AEAD function [AEAD] to protect against
accidental modification.
3) Initial packets use an AEAD function, the keys for which are derived
using a value that is visible on the wire. 更多见协议
4) All other packets are protected with keys derived from the
cryptographic handshake.
PS: The Packet Number field that appears in some packet types has
alternative confidentiality protection that is applied as part of
header protection;

12.2. Coalescing Packets

Initial (Section 17.2.2), 0-RTT (Section 17.2.3), and Handshake
(Section 17.2.4) packets contain a Length field that determines the
end of the packet. The length includes both the Packet Number and
Payload fields, both of which are confidentiality protected and
initially of unknown length. The length of the Payload field is
learned once header protection is removed.

Using the Length field, 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 start sending
data. This can also be used to construct Path Maximum Transmission
Unit (PMTU) probes; see Section 14.4.1. Receivers MUST be able to
process coalesced packets.

Coalescing packets in order of increasing encryption levels (Initial,
0-RTT, Handshake, 1-RTT; see Section 4.1.4 of [QUIC-TLS]) makes it
more likely that 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 can only be the last packet included in a UDP datagram.
An endpoint SHOULD include multiple frames in a single packet if they
are to be sent at the same encryption level, instead of coalescing
multiple packets at the same encryption level.

Receivers MAY route based on the information in the first packet
contained in a UDP datagram. Senders MUST NOT coalesce QUIC packets
with different 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
separate and complete. 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 for any other reason), the receiver MAY either
discard or buffer the packet for later processing and MUST attempt to
process the remaining packets.

Retry packets (Section 17.2.5), Version Negotiation packets
(Section 17.2.1), and packets with a short header (Section 17.3) do
not contain a Length field and so cannot be followed by other packets
in the same UDP datagram. Note also that there is no situation where
a Retry or Version Negotiation packet is coalesced with another
packet.

联合(合并)的包:Coalescing Packets
联合包: 因为类似Init,0-RTT和握手包,包含一个Length field来决定包的结尾。 The Length包含了包括packet number和payload fields. 两者均受加密保护,且最初长度未知。 The length of the Payload field is
learned once header protection is removed.

基于此,使用Length field,发送方可以把多个QUIC packet打包到一个UDP 数据报中。 可以减少UDP数据报的数量。
This can reduce the number of UDP datagrams needed to complete the cryptographic handshake and start sending data. This can also be used to construct Path Maximum Transmission
Unit (PMTU) probes; see Section 14.4.1. Receivers MUST be able to process coalesced packets.

合并包要按加密级别从高到低排序,这样使得接收方在一次性处理所有的包更便利。 比如,一个短的header的packet是没有length 域的,这样它要被放在UDP数据报 的最后才行。
一个端点应该在一个数据包中包含多个帧,如果它们将以相同的加密级别发送,而不是合并同一加密级别的多个数据包。

此外,接收方是基于udp数据报的第一个packet来路由包的(即往上派发处理),这样,发送方不应该把不同的ConnectionID的quicpacket合并到同一个UDP datagrame中。 接收方如果遇到这种情况,就忽略udp datagrame中和第一个packet 的connection ID不同的packet

被合并到udp datagram中的不同的quic packet是独立和完整的。接收方应该逐个处理每个quic包和分别ack 他们,就好像他们在不同的udp datagrampe中一样。例如,如果解密失败(因为密钥是
不可用或出于任何其他原因),接收方可以丢弃或缓冲数据包以供以后处理,并且必须尝试处理udp datagrame剩余的packet.

                哪些包不能合并?
               Retry packets (Section 17.2.5), Version Negotiation packets (Section 17.2.1), and packets with a short header (Section 17.3) do not contain a Length field and so cannot be followed by other packets
               in the same UDP datagram.    因为是短的header不包含 length field.
              Note also that there is no situation where   a Retry or Version Negotiation packet is coalesced with another  packet. 没有情况是一个重传包和version  Negotiation packet是合并到另一个packet的。
12.3. Packet Numbers

The packet number is an integer in the range 0 to 2^62-1. This
number is used in determining the cryptographic nonce for packet
protection. Each endpoint maintains a separate packet number for
sending and receiving.

Packet numbers are limited to this range because they need to be
representable in whole in the Largest Acknowledged field of an ACK
frame (Section 19.3). When present in a long or short header,
however, packet numbers are reduced and encoded in 1 to 4 bytes; see
Section 17.1.

Version Negotiation (Section 17.2.1) and Retry (Section 17.2.5)
packets do not include a packet number.

Packet numbers are divided into three spaces in QUIC:

Initial space: All Initial packets (Section 17.2.2) are in this
space.

Handshake space: All Handshake packets (Section 17.2.4) are in this
space.

Application data space: All 0-RTT (Section 17.2.3) and 1-RTT
(Section 17.3.1) packets 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 that
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 number spaces. Packet numbers in each space start
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.

A QUIC endpoint MUST NOT reuse a packet number within the same packet
number space in one connection. 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.3) in response to further packets that
it receives.

A receiver MUST discard a newly unprotected packet unless it is
certain that it has not processed another packet with the same packet
number from the same packet number space. Duplicate suppression MUST
happen after removing packet protection for the reasons described in
Section 9.5 of [QUIC-TLS].

Endpoints that track all individual packets for the purposes of
detecting duplicates are at risk of accumulating excessive state.
The data required for detecting duplicates can be limited by
maintaining a minimum packet number below which all packets are
immediately dropped. Any minimum needs to account for large
variations in round-trip time, which includes the possibility that a
peer might probe network paths with much larger round-trip times; see
Section 9.

Packet number encoding at a sender and decoding at a receiver are
described in Section 17.1.
包的编号 packet numbers
The packet number is an integer in the range 0 to 2^62-1. This
number is used in determining the cryptographic nonce for packet
protection. Each endpoint maintains a separate packet number for
sending and receiving.
数据包编号是 0 到 2~62-1 范围内的整数。这
number 用于确定数据包的加密随机数
保护。每个端点维护一个单独的数据包编号
发送和接收。

packet num被限制在这个范围因为他们需要被可表示在ACK frame中的ack field中。Packet numbers are limited to this range because they need to be representable in whole in the Largest Acknowledged field of an ACK frame (Section 19.3). When present in a long or short header,
however, packet numbers are reduced and encoded in 1 to 4 bytes; see Section 17.1.

哪些包没有packet num: Version Negotiation (Section 17.2.1) and Retry (Section 17.2.5)
packets do not include a packet number.

packet numbers被分为三个数据集合空间在QUIC:
Initial space: All Initial packets (Section 17.2.2) are in this space.

Handshake space: All Handshake packets (Section 17.2.4) are in this space.

Application data space: All 0-RTT (Section 17.2.3) and 1-RTT
(Section 17.3.1) packets are in this space.
如QUIC-TLS描述的,每个packet type使用不同的 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 that
are also Initial packets. Similarly, Handshake packets are sent at
the Handshake encryption level and can only be acknowledged in
Handshake packets.

这样就强制了在不同的packet number spaces ,加密密码不同。 packet num在不同的空间起始于0,且在相同的空间,后续的数据packet必须至少
递增1.
0-RTT and 1-RTT data exist in the same packet number space to make丢失恢复算法更容易在两个数据包类型之间实现

packet num的重用情况,以及耗尽的处理:
A QUIC endpoint MUST NOT reuse a packet number within the same packet
number space in one connection. 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.3) in response to further packets that
it receives.

重复包序号的处理:Endpoints that track all individual packets for the purposes of
detecting duplicates are at risk of accumulating excessive state.
The data required for detecting duplicates can be limited by
maintaining a minimum packet number below which all packets are
immediately dropped. Any minimum needs to account for large
variations in round-trip time, which includes the possibility that a
peer might probe network paths with much larger round-trip times; see
Section 9.

packet的编解码: 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,
consists of a sequence of complete frames, as shown in Figure 11.
Version Negotiation, Stateless Reset, and Retry packets do not
contain frames.

1
2
3
Packet Payload {
Frame (8..) ...,
}
                      Figure 11: QUIC Payload

The payload of a packet that contains frames MUST contain at least
one frame, and MAY contain multiple frames and multiple frame types.一个packet中至少有一帧,可以有多个帧和多个类型的帧。

An endpoint MUST treat receipt of a packet containing no frames as a
connection error of type PROTOCOL_VIOLATION. Frames always fit
within a single QUIC packet and cannot span multiple packets. 如果应该包含frame的packet没包含,就认为是一个连接错误。帧总是在单独的包里面,不能跨包。

Each frame begins with a Frame Type, indicating its type, followed by
additional type-dependent fields: 每个帧起始一个帧类型,提示类型,接着跟额外的独立类型的域。

                  Figure 12: Generic Frame Layout

Table 3 lists and summarizes information about each frame type that
is defined in this specification. A description of this summary is
included after the table.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
+============+======================+===============+======+======+
| Type Value | Frame Type Name | Definition | Pkts | Spec |
+============+======================+===============+======+======+
| 0x00 | PADDING | Section 19.1 | IH01 | NP |
+------------+----------------------+---------------+------+------+
| 0x01 | PING | Section 19.2 | IH01 | |
+------------+----------------------+---------------+------+------+
| 0x02-0x03 | ACK | Section 19.3 | IH_1 | NC |
+------------+----------------------+---------------+------+------+
| 0x04 | RESET_STREAM | Section 19.4 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x05 | STOP_SENDING | Section 19.5 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x06 | CRYPTO | Section 19.6 | IH_1 | |
+------------+----------------------+---------------+------+------+
| 0x07 | NEW_TOKEN | Section 19.7 | ___1 | |
+------------+----------------------+---------------+------+------+
| 0x08-0x0f | STREAM | Section 19.8 | __01 | F |
+------------+----------------------+---------------+------+------+
| 0x10 | MAX_DATA | Section 19.9 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x11 | MAX_STREAM_DATA | Section 19.10 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x12-0x13 | MAX_STREAMS | Section 19.11 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x14 | DATA_BLOCKED | Section 19.12 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x15 | STREAM_DATA_BLOCKED | Section 19.13 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x16-0x17 | STREAMS_BLOCKED | Section 19.14 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x18 | NEW_CONNECTION_ID | Section 19.15 | __01 | P |
+------------+----------------------+---------------+------+------+
| 0x19 | RETIRE_CONNECTION_ID | Section 19.16 | __01 | |
+------------+----------------------+---------------+------+------+
| 0x1a | PATH_CHALLENGE | Section 19.17 | __01 | P |
+------------+----------------------+---------------+------+------+
| 0x1b | PATH_RESPONSE | Section 19.18 | ___1 | P |
+------------+----------------------+---------------+------+------+
| 0x1c-0x1d | CONNECTION_CLOSE | Section 19.19 | ih01 | N |
+------------+----------------------+---------------+------+------+
| 0x1e | HANDSHAKE_DONE | Section 19.20 | ___1 | |
+------------+----------------------+---------------+------+------+

Table 3: Frame Types

每个帧类型的格式和语法在section19. .剩下的内容解释表格等。
这几个类型被使用去携带帧具体标记:The Frame Type in ACK, STREAM, MAX_STREAMS, STREAMS_BLOCKED, and
CONNECTION_CLOSE frames is used to carry other frame-specific flags.
For all other frames, the Frame Type field simply identifies the frame.

关于pkts列:

1
2
3
4
5
6
7
8
9
10
11
12
13
The "Pkts" column in Table 3 lists the types of packets that each
frame type could appear in, indicated by the following characters:即该帧类型可以出现再哪种包里面:

I: Initial (Section 17.2.2) 可以出现再Initial包

H: Handshake (Section 17.2.4) ...

0: 0-RTT (Section 17.2.3)

1: 1-RTT (Section 17.3.1)

ih: Only a CONNECTION_CLOSE frame of type 0x1c can appear in Initial
or Handshake packets.

For more details about these restrictions, see Section 12.5. Note
that all frames can appear in 1-RTT packets. An endpoint MUST treat
receipt of a frame in a packet type that is not permitted as a
connection error of type PROTOCOL_VIOLATION.
更多见12.5,不过注意所有的帧可以出现再1-RTT包中,一个节点当收到不允许帧在该类包中时,错误类型为 PROTOCOL_VIOLATION.

               关于spec列:

The “Spec” column in Table 3 summarizes any special rules governing
the processing or generation of the frame type, as indicated by the
following characters: 总结了任何特殊规则
下所示的帧类型的处理或产生

1
2
3
4
5
6
7
8
9
10
11
下字符:
N: Packets containing only frames with this marking are not ack-
eliciting; see Section 13.2. 包中的帧仅包含此标记时不用ack?
C: Packets containing only frames with this marking do not count
toward bytes in flight for congestion control purposes; see
[QUIC-RECOVERY].不需要包含在在传播中的字节数,用于拥塞控制的。
P: Packets containing only frames with this marking can be used to
probe new network paths during connection migration; see
Section 9.1.能被用于探测新的网络路径在链接迁移的过程中。
F: The contents of frames with this marking are flow controlled;
see Section 4.这个mark的帧用于流控。

The “Pkts” and “Spec” columns in Table 3 do not form part of the IANA
registry; see Section 22.4.

An endpoint MUST treat the receipt of a frame of unknown type as a
connection error of type FRAME_ENCODING_ERROR.结点收到不认识的帧类型时,应该返回错误。
All frames are idempotent in this version of QUIC. 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. For frame types defined in this document, this
means a single-byte encoding, even though it is possible to encode
these values as a two-, four-, or eight-byte variable-length integer.
For instance, though 0x4001 is a legitimate two-byte encoding for a
variable-length integer with a value of 1, PING frames are always
encoded as a single byte with the value 0x01. This rule applies to
all current and future QUIC frame types. An endpoint MAY treat the
receipt of a frame type that uses a longer encoding than necessary as
a connection error of type PROTOCOL_VIOLATION.
Frame type域使用一个可变长的整数编码,一个例外。为了确保简单和有效的帧解析的实现
,一个帧类型必须使用最短可能的编码。对帧类型定义在这个文档,这意味着一个单字节的编码,即使可以编码这些值为一个2,4,8字节的变长整数。
例如,尽管0x4001是一个合法的两个字节的编码对一个可变长的整数1来说,但PING帧总是编码为1个单字节的值为1.
这个规则适用于所有当前和未来的quic 帧类型。 一个结点可能对待接收到的使用一个比必要的更长编码帧类型为一个连接错误类型: PROTOCOL_VIOLATION

frames and number spaces: 帧和数字空间

12.5. Frames and Number Spaces

Some frames are prohibited in different packet number spaces. The
rules here generalize those of TLS, in that frames associated with
establishing the connection can usually appear in packets in any
packet number space, whereas those associated with transferring data
can only appear in the application data packet number space:
某些帧在不同的包号空间中被禁止。这个规则概述了那些TLS的,在关联建立连接的帧所在的包通常能出现任何包数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
*  PADDING, PING, and CRYPTO frames MAY appear in any packet number
space.

* CONNECTION_CLOSE frames signaling errors at the QUIC layer (type
0x1c) MAY appear in any packet number space. CONNECTION_CLOSE
frames signaling application errors (type 0x1d) MUST only appear
in the application data packet number space.

* ACK frames MAY appear in any packet number space but can only
acknowledge packets that appeared in that packet number space.
However, as noted below, 0-RTT packets cannot contain ACK frames.

* All other frame types MUST only be sent in the application data
packet number space.

Note that it is not possible to send the following frames in 0-RTT
packets for various reasons: ACK, CRYPTO, HANDSHAKE_DONE, NEW_TOKEN,
PATH_RESPONSE, and RETIRE_CONNECTION_ID. 注意不能发送以下的帧类型,在0-RTT包中有多种原因. ACK,…

A server MAY treat receipt
of these frames in 0-RTT packets as a connection error of type
PROTOCOL_VIOLATION.

打包和可靠性:Packetization and Reliability
数据包处理:Packet Processing

13. Packetization and Reliability

A sender sends one or more frames in a QUIC packet; see Section 12.4.

A sender can minimize per-packet bandwidth and computational costs by
including as many frames as possible in each QUIC packet. A sender
MAY wait for a short period of time to collect 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.
一个发送方可以最小化每个包的带宽和计算损耗通过包含尽可能多的帧在一个QUIC包中。
一个发送方可能会等待一个短的周期时间来收集多个帧,在发送一个不是最大化打包的包之前,去避免发送大量小包。
一个实现可能使用应用发送行为或启发相关知识来决定是否和等待多久。 这个等待周期是一个实现决定的,和一个实现应该小心保守的延迟,
因为任何延迟都可能增加应用的可见延迟。
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.
多路复用流被实现,通过交错STREAM帧,将多个流塞在一个或多个QUIC包中。一个单独的QUIC包能包含来自一个或多个流的STREAM帧。

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 included in a single QUIC
packet, loss of that packet blocks all those streams from making
progress. Implementations are advised to include as few streams as
necessary in outgoing packets without losing transmission efficiency
to underfilled packets.
QUIC 的好处之一是避免了跨多个流的行头阻塞。当一个packet发生丢失,只有在那个packet的流数据会被阻塞等待一个重传被接收,
而此时其他流却能继续处理不被影响。注意到当从一个packet包含了多个流时,该packet的丢失会阻塞该包的所有流处理进程。
实现上建议包含尽可能少的流在一个输出包,避免对为满的包丢失传输效率

13.1. Packet Processing

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 be delivered and consumed.一个packet不能被ack(接收方回ack),直到包被成功解密且包中所有的帧都被成功处理。
对STREAM帧,这个以为着数据被塞入准备给到应用接收队列中,但没有要求数据必须被传递和消费掉。

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.
一旦packet被完全处理,一个接收方确认回执通过发送一个或多个ack frame包含接收的包的包number。
An endpoint SHOULD treat receipt of an acknowledgment for a packet it
did not send as a connection error of type PROTOCOL_VIOLATION, if it
is able to detect the condition. For further discussion of how this
might be achieved, see Section 21.4.
若果能检测条件,一个结点应该处理该对一个包的回执确认为一个连接错误PROTOCOL_VIOLATION. 对更多信息见21.4

ack帧也有额外的开销和负载。下面的指导指在建议这方面的内容。
生成ack

13.2. Generating Acknowledgments 生成ack

如果packet的荷载里,不包括ACK, PADDING, and CONNECTION_CLOSE这种三种类型的帧,那么这个packet则被定义为ack-eliciting,
意味着对端必须对这种packet生成相应的ack通知发送方,以确保数据没有丢失。
Endpoints acknowledge all packets they receive and process. However,
only ack-eliciting packets cause an ACK frame to be sent within the
maximum ack delay. Packets that are not ack-eliciting are only
acknowledged when an ACK frame is sent for other reasons.结点确认所有包他们接收和处理的,然而只有ack-eliciting的包才会
引发一个ACK帧在最大ack延迟内被发送。 packets不是ack-eliciting的只有在ACK frame因其他原因被发送才被确认。

When sending a packet for any reason, an endpoint SHOULD attempt to
include an ACK frame if one has not been sent recently. Doing so
helps with timely loss detection at the peer.当出于任何原因发送一个包时,一个结点应该尝试包含一个ack frame,如果最近没发送过ack
这样做帮助对端及时的丢包检测处理。

In general, frequent feedback from a receiver improves loss and
congestion response, but this has to be balanced against excessive
load generated by a receiver that sends an ACK frame in response to
every ack-eliciting packet. The guidance offered below seeks to
strike this balance.一般来说,来自接收方的频繁反馈提高了丢失和拥塞的响应,但这个也对每个ack-eliciting 包做发送

13.2.1 发送ACK frames;

Every packet SHOULD be acknowledged at least once, and ack-eliciting
packets MUST be acknowledged at least once within the maximum delay
an endpoint communicated using the max_ack_delay transport parameter;
see Section 18.2. max_ack_delay declares an explicit contract: an
endpoint promises to never intentionally delay acknowledgments of an
ack-eliciting packet by more than the indicated value. If it does,
any excess accrues to the RTT estimate and could result in spurious
or delayed retransmissions from the peer. A sender uses the
receiver’s max_ack_delay value in determining timeouts for timer-
based retransmission, as detailed in Section 6.2 of [QUIC-RECOVERY].
每个包都应该被ack至少一次,并且需要ack的包必须在最大的delay中至少ack一次,如果一个节点交流使用max_ack_delay传输参数。 见18.2;
max_ack_delay声明一个确定的合约:一个节点承诺从不故意比声明的delay值更大的延迟ack, 对一个需要ack的包。 如果它做了,任何超出预期,RTT 估计会超出部分,并可能导致虚假
或来自对等方的延迟重传。一个发送方使用接收方的max_ack_delay值来决定超时重传中的超时。as detailed in Section 6.2 of [QUIC-RECOVERY].

An endpoint MUST acknowledge all ack-eliciting Initial and Handshake
packets immediately and all ack-eliciting 0-RTT and 1-RTT packets
within its advertised max_ack_delay, with the following exception.
Prior to handshake confirmation, an endpoint might not have packet
protection keys for decrypting Handshake, 0-RTT, or 1-RTT packets
when they are received. It might therefore buffer them and
acknowledge them when the requisite keys become available.
一个节点必须立即ack所有的ack所有需要ack的初始化和握手包,并且在它声明的max_ack_delay范围内ack所有需要ack的0-RTT和1-RTT包,除了以下情况。
在握手确认之前,端点可能没有数据包用于解密握手、0-RTT 或 1-RTT 数据包的保护密钥当他们收到。因此需要缓存它们并等到有可用的秘钥时再ack它们。

Since packets containing only ACK frames are not congestion
controlled, an endpoint MUST NOT send more than one such packet in
response to receiving an ack-eliciting packet.
由于只包含ack 帧的包不受拥塞控制,所以一个节点不能发送一个或多个这样的包来回复一个需要ack的包。

An endpoint MUST NOT send a non-ack-eliciting packet in response to a
non-ack-eliciting packet, even if there are packet gaps that precede
the received packet. This avoids an infinite feedback loop of
acknowledgments, which could prevent the connection from ever
becoming idle. Non-ack-eliciting packets are eventually acknowledged
when the endpoint sends an ACK frame in response to other events.
节点不能以别的非ack的包做回复,不然可能导致无限feedback循环ack,。不需要ack的包可以通过其他事件驱动ack回复。

An endpoint that is only sending ACK frames will not receive
acknowledgments from its peer unless those acknowledgments are
included in packets with ack-eliciting frames. An endpoint SHOULD
send an ACK frame with other frames when there are new ack-eliciting
packets to acknowledge. When only non-ack-eliciting packets need to
be acknowledged, an endpoint MAY choose not to send an ACK frame with
outgoing frames until an ack-eliciting packet has been received.
一个节点只是发送ack帧时将不会收到ack回复除非那个包包含了其他需要ack的帧。 一个节点应该发送一个ack帧包含其他frames当有新的需要回复的包要确认时。
当只有非需要ack的包需要ack时,一个节点可能选择不发送ack帧携带输出帧。等到一个需要ack的包被收到。这里指偏向接收方;。

An endpoint that is only sending non-ack-eliciting packets might
choose to occasionally add an ack-eliciting frame to those packets to
ensure that it receives an acknowledgment; see Section 13.2.4. In
that case, an endpoint MUST NOT send an ack-eliciting frame in all
packets that would otherwise be non-ack-eliciting, to avoid an
infinite feedback loop of acknowledgments.
—–这段不太懂。。。。

In order to assist loss detection at the sender, an endpoint SHOULD
generate and send an ACK frame without delay when it receives an ack-
eliciting packet either: 为了协助丢包检测在发送端,一个节点应该生成和发送一个ack帧不用延迟当他收到一个需要ack的包当:

  • when the received packet has a packet number less than another
    ack-eliciting packet that has been received, or 当收到的包有一个packet number小于已经收到的另一个需要ack的包。或

  • when the packet has a packet number larger than the highest-
    numbered ack-eliciting packet that has been received and there are
    missing packets between that packet and this packet. 当该包有一个比最大的已收到的需要ack的包的packet number还大时,并且在这两个包中间存在丢失包时。

Similarly, packets marked with the ECN Congestion Experienced (CE)
codepoint in the IP header SHOULD be acknowledged immediately, to
reduce the peer’s response time to congestion events. 类似的,包被打上ecn 拥塞出现时,在IPheader中 应该立刻被ack。 去减少对端对拥塞时间的响应时间。

The algorithms in [QUIC-RECOVERY] are expected to be resilient弹性 to
receivers that do not follow the guidance offered above. However, an
implementation should only deviate from these requirements after
careful consideration of the performance implications of a change,
for connections made by the endpoint and for other users of the
network.

13.2.2. Acknowledgment Frequency

A receiver determines how frequently to send acknowledgments in
response to ack-eliciting packets. This determination involves a
trade-off. 接收者决定多频繁去发送ack来回复需要ack的包。这个决定涉及一个平衡。

Endpoints rely on timely acknowledgment to detect loss; see Section 6
of [QUIC-RECOVERY]. Window-based congestion controllers, such as the
one described in Section 7 of [QUIC-RECOVERY], rely on
acknowledgments to manage their congestion window. In both cases,
delaying acknowledgments can adversely affect performance.
节点依赖周期的ack去检测丢包。见section6 of。。 基于窗口的拥塞控制器,例如之前描述的,依赖ack去管理他们的拥塞窗口。在这两种case下,延迟ack会对性能产生不利影响。

On the other hand, reducing the frequency of packets that carry only
acknowledgments reduces packet transmission and processing cost at
both endpoints. It can improve connection throughput on severely
asymmetric links and reduce the volume of acknowledgment traffic
using return path capacity; see Section 3 of [RFC3449].
另一方面,减少只携带ack的包的频率可以减少两个端点的包传输和处理成本。 它能在严格的不对称链路下提高连接 的吞吐并减少对返回路径流量容量的使用。

A receiver SHOULD send an ACK frame after receiving at least two ack-
eliciting packets. This recommendation is general in nature and
consistent with recommendations for TCP endpoint behavior [RFC5681].
Knowledge of network conditions, knowledge of the peer’s congestion
controller, or further research and experimentation might suggest
alternative acknowledgment strategies with better performance
characteristics.
一个接收方应该发送一个ack frame在接收到至少两个需要ack包后。 这个建议是一般性质,且和tcp节点行为建议一致。
对网络条件的认知,对对端拥塞控制的认知和未来的研究,实验可能建议选择ack策略基于更好的表现特性。

A receiver MAY process multiple available packets before determining
whether to send an ACK frame in response.
接收方可能处理多种有效的包在决定是否发送ack帧回复之前。

13.2.3. Managing ACK Ranges

When an ACK frame is sent, one or more ranges of acknowledged packets
are included. Including acknowledgments for older packets reduces
the chance of spurious retransmissions caused by losing previously
sent ACK frames, at the cost of larger ACK frames.
当一个ACK frame被发送,一个或多个范围的ack包被包含。包含老的包的ack 减少了因为丢失了之前发送的ack帧导致的假重传的机会,虽然是以更大的ack帧为代价。、
ACK frames SHOULD always acknowledge the most recently received
packets, and the more out of order the packets are, the more
important it is to send an updated ACK frame quickly, to prevent the
peer from declaring a packet as lost and spuriously retransmitting
the frames it contains. An ACK frame is expected to fit within a
single QUIC packet. If it does not, then older ranges (those with
the smallest packet numbers) are omitted
ack帧应该总是ack最近收到的包,并且包越乱序,去快速发送更新ACK 帧就越重要,为了防止对端声明一个包被丢失和伪重传它包含的帧。

A receiver limits the number of ACK Ranges (Section 19.3.1) it
remembers and sends in ACK frames, both to limit the size of ACK
frames and to avoid resource exhaustion. After receiving
acknowledgments for an ACK frame, the receiver SHOULD stop tracking
those acknowledged ACK Ranges. Senders can expect acknowledgments
for most packets, but QUIC does not guarantee receipt of an
acknowledgment for every packet that the receiver processes.
一个接收方限制它记住和发送在ACK帧中的ack范围数量,包括限制ack帧的大小和避免资源耗尽。 在接收到ack的确认后,接收方应该停止跟踪那些ack范围。发送方能期待大部分包的ack,但quic不保证收到接收方处理的每个数据包的确认。

It is possible that retaining many ACK Ranges could cause an ACK
frame to become too large. A receiver can discard unacknowledged ACK
Ranges to limit ACK frame size, at the cost of increased
retransmissions from the sender. This is necessary if an ACK frame
would be too large to fit in a packet. Receivers MAY also limit ACK
frame size further to preserve space for other frames or to limit the
capacity that acknowledgments consume. 保留很多ack 范围可能会导致一个ack的帧很大。一个接收方可能因为要限制ack帧的大小所以丢弃,不ack它们,代价就是会增加发送方的重传。
这个是必要的如果一个ack 帧太大不合适放到一个包中。接收方可能也会限制ack帧的大小以为其他帧未来预留空间或限制ack损耗总量。

A receiver MUST retain an ACK Range unless it can ensure that it will
not subsequently accept packets with numbers in that range.
Maintaining a minimum packet number that increases as ranges are
discarded is one way to achieve this with minimal state.
一个接收方必须保留 一个ack范围,除非它能确认未来不会再接收该范围的包。 维持一个最小包号,在范围增加时丢弃是一种实现最小状态的方式。

Receivers can discard all ACK Ranges, but they MUST retain the
largest packet number that has been successfully processed, as that
is used to recover packet numbers from subsequent packets; see
Section 17.1. 接收方能丢弃所有的ack范围,但他们必须保留已经成功处理的最大的包号,因为那被用来从连串的包中恢复包号。

A receiver SHOULD include an ACK Range containing the largest
received packet number in every ACK frame. The Largest Acknowledged
field is used in ECN validation at a sender, and including a lower
value than what was included in a previous ACK frame could cause ECN
to be unnecessarily disabled; see Section 13.4.2.

Section 13.2.4 describes an exemplary approach for determining what
packets to acknowledge in each ACK frame. Though the goal of this
algorithm is to generate an acknowledgment for every packet that is
processed, it is still possible for acknowledgments to be lost. //在13。2.4有一个例子来说明。

13.2.4. Limiting Ranges by Tracking ACK Frames //限制跟踪的ack frame的范围。

When a packet containing an ACK frame is sent, the Largest
Acknowledged field in that frame can be saved. When a packet
containing an ACK frame is acknowledged, the receiver can stop
acknowledging packets less than or equal to the Largest Acknowledged
field in the sent ACK frame.

A receiver that sends only non-ack-eliciting packets, such as ACK
frames, might not receive an acknowledgment for a long period of
time. This could cause the receiver to maintain state for a large
number of ACK frames for a long period of time, and ACK frames it
sends could be unnecessarily large. In such a case, a receiver could
send a PING or other small ack-eliciting frame occasionally, such as
once per round trip, to elicit an ACK from the peer. 如果接收方只发送了不需要ack的包如ack 帧。可能在长时间内不会收到一个ack。这个可能导致接收方维持状态来在一个长时间内有很多ack帧,而且一个ack帧
被发送可能没必要很大。在这种情况下,一个接收方可以发送PING或其他小的需要ack的帧偶尔的,例如一个rtt一次,来触发对端的一个ack过来。

In cases without ACK frame loss, this algorithm allows for a minimum
of 1 RTT of reordering. In cases with ACK frame loss and reordering,
this approach does not guarantee that every acknowledgment is seen by
the sender before it is no longer included in the ACK frame. Packets
could be received out of order, and all subsequent ACK frames
containing them could be lost. In this case, the loss recovery
algorithm could cause spurious retransmissions, but the sender will
continue making forward progress. 在没有ack帧丢失情况下,算法允许在一个最小的rtt内重新排序。在ack帧丢失和重排序下,这个不保证每个ack能被发送方看到,在它不再包含在ack帧之前。
包可能接收失序了,并且所有的后续ack帧可能丢失。在这种情况下,丢失恢复算法可能导致很多虚假的重传,但发送方将继续处理前进。

13.2.5. Measuring and Reporting Host Delay 测量和上报主机延迟: 一个包的延迟可能在os kernel或其他地方,在ACK帧的ACK Delay field填入这个delay值,可以让接受方做调整。
 如果发现值比max_ack_delay,及时上报。

An endpoint measures the delays intentionally introduced between the
time the packet with the largest packet number is received and the
time an acknowledgment is sent. The endpoint encodes this
acknowledgment delay in the ACK Delay field of an ACK frame; see
Section 19.3. This allows the receiver of the ACK frame to adjust
for any intentional delays, which is important for getting a better
estimate of the path RTT when acknowledgments are delayed.

A packet might be held in the OS kernel or elsewhere on the host
before being processed. An endpoint MUST NOT include delays that it
does not control when populating the ACK Delay field in an ACK frame.
However, endpoints SHOULD include buffering delays caused by
unavailability of decryption keys, since these delays can be large
and are likely to be non-repeating.

When the measured acknowledgment delay is larger than its
max_ack_delay, an endpoint SHOULD report the measured delay. This
information is especially useful during the handshake when delays
might be large; see Section 13.2.1.

13.2.6. 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 acknowledged; 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.

13.2.7. PADDING Frames Consume Congestion Window

Packets containing PADDING frames are considered to be in flight for
congestion control purposes [QUIC-RECOVERY]. Packets containing only
PADDING frames therefore consume congestion window but do not
generate acknowledgments that will open the congestion window. To
avoid a deadlock, a sender SHOULD ensure that other frames are sent
periodically in addition to PADDING frames to elicit acknowledgments
from the receiver.

信息重新传递:即某些包确定丢了,那需要重新传递信息?
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. 那些被判定为已丢失的quic 包 没有全部都重传。 这同样适用于那些包含在丢失的包里的帧。相反,帧中可能携带的信息是根据需要在新帧中再次发送。

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. 新帧和包被用于携带被判定已经丢失的信息。 一般来说,信息被再次发送,当一个包包含了被判定为丢失的信息,以及发送
停止,当一个包包含已经被ack的信息。
以下为几类帧的重传要求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
*  Data sent in CRYPTO frames is retransmitted according to the rules
in [QUIC-RECOVERY], until all data has been acknowledged. Data in
CRYPTO frames for Initial and Handshake packets is discarded when
keys for the corresponding packet number space are discarded.

* Application data sent in STREAM frames is retransmitted in new
STREAM frames unless the endpoint has sent a RESET_STREAM for that
stream. Once an endpoint sends a RESET_STREAM frame, no further
STREAM frames are needed.

* ACK frames carry the most recent set of acknowledgments and the
acknowledgment delay from the largest acknowledged packet, as
described in Section 13.2.1. Delaying the transmission of packets
containing ACK frames or resending old ACK frames can cause the
peer to generate an inflated RTT sample or unnecessarily disable
ECN.

* Cancellation of stream transmission, as carried in a RESET_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 sending part of the stream).
The content of a RESET_STREAM frame MUST NOT change when it is
sent again.

* Similarly, a request to cancel stream transmission, as encoded in
a STOP_SENDING frame, is sent until the receiving part of the
stream enters either a "Data Recvd" or "Reset Recvd" state; see
Section 3.5.

* Connection close signals, including packets that contain
CONNECTION_CLOSE frames, are not sent again when packet loss is
detected. Resending these signals is described in Section 10.

* 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; see Section 4.2.

* 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 receiving part of the stream
enters a "Size Known" or "Reset Recvd" state.

* The limit on streams of a given type is sent in MAX_STREAMS
frames. Like MAX_DATA, an updated value is sent when a packet
containing the most recent MAX_STREAMS 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.

* Blocked signals are carried in DATA_BLOCKED, STREAM_DATA_BLOCKED,
and STREAMS_BLOCKED frames. DATA_BLOCKED frames have connection
scope, STREAM_DATA_BLOCKED frames have stream scope, and
STREAMS_BLOCKED frames are scoped to a specific stream type. A
new frame is sent if a packet 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.

* 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.

* Responses to path validation using PATH_RESPONSE frames are sent
just once. The peer is expected to send more PATH_CHALLENGE
frames as necessary to evoke additional PATH_RESPONSE frames.

* 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.

* NEW_TOKEN frames are retransmitted if the packet containing them
is lost. No special support is made for detecting reordered and
duplicated NEW_TOKEN frames other than a direct comparison of the
frame contents.

* PING and PADDING frames contain no information, so lost PING or
PADDING frames do not require repair.

* The HANDSHAKE_DONE frame MUST be retransmitted until it is
acknowledged.
Endpoints SHOULD prioritize retransmission of data over sending new
data, unless priorities specified by the application indicate
otherwise; see Section 2.3.节点应该优先重传数据而不是新的数据。除非应用层暗示了具体的优先级,否则。

Even though a sender is encouraged to assemble frames containing up-
to-date information every time it sends a packet, it is not forbidden
to retransmit copies of frames from lost packets. A sender that
retransmits copies of frames needs to handle decreases in available
payload size due to changes in packet number length, connection ID
length, and path MTU. A receiver MUST accept packets containing an
outdated frame, such as a MAX_DATA frame carrying a smaller maximum
data value than one found in an older packet.

A sender SHOULD avoid retransmitting information from packets once
they are acknowledged. This includes packets that are acknowledged
after being declared lost, which can happen in the presence of
network reordering. Doing so requires senders to retain information
about packets after they are declared lost. A sender can discard
this information after a period of time elapses that adequately
allows for reordering, such as a PTO (Section 6.2 of
[QUIC-RECOVERY]), or based on other events, such as reaching a memory
limit.

Upon detecting losses, a sender MUST take appropriate congestion
control action. The details of loss detection and congestion control
are described in [QUIC-RECOVERY].

显示拥塞控制:Explicit Congestion Notification 和ECN相关,依赖于路由器。

数据报长度:Datagram Size

14. Datagram Size

A UDP datagram can include one or more QUIC packets. The datagram
size refers to the total UDP payload size of a single UDP datagram
carrying QUIC packets. The datagram size includes one or more QUIC
packet headers and protected payloads, but not the UDP or IP headers.
一个UDP数据报能包含一个或多个QUIC包。 该数据报的大小参考一个单个UDP数据报携带QUIC包的载荷总大小。
该数据报包含一个或多个QUIC包头(分长头和短头)和保护的载荷,但不包含udp或ip头大小。

The maximum datagram size is defined as the largest size of UDP
payload that can be sent across a network path using a single UDP
datagram. QUIC MUST NOT be used if the network path cannot support a
maximum datagram size of at least 1200 bytes.

QUIC assumes a minimum IP packet size of at least 1280 bytes. This
is the IPv6 minimum size [IPv6] and is also supported by most modern
IPv4 networks. quic 假定最小的IP包大小至少为1280,这个是IPv6支持的最小尺寸和也支持大部分的现代IPv4.
Assuming the minimum IP header size of 40 bytes for
IPv6 and 20 bytes for IPv4 and a UDP header size of 8 bytes, this
results in a maximum datagram size of 1232 bytes for IPv6 and 1252
bytes for IPv4. 假定最小的IP头是40字节对IPv6和20字节对IPv4,UDP头是8字节,则,QUIC 的maxnum datagrames是:IPV6:1232,IPV4:1252
Thus, modern IPv4 and all IPv6 network paths are
expected to be able to support QUIC.

最大数据报大小定义为可以使用单个 UDP 数据报通过网络路径发送的最大 UDP 有效负载大小。 如果网络路径不能支持至少 1200 字节的最大数据报大小,则不得使用 QUIC。

QUIC 假定最小 IP 数据包大小至少为 1280 字节。 这是 IPv6 的最小大小 [IPv6],大多数现代 IPv4 网络也支持。 假设 IPv6 的最小 IP 报头大小为 40 字节,IPv4 为 20 字节,UDP 报头大小为 8 字节,这导致 IPv6 的最大数据报大小为 1232 字节,IPv4 为 1252 字节。 因此,现代 IPv4 和所有 IPv6 网络路径都有望支持 QUIC。
  |  Note: This requirement to support a UDP payload of 1200 bytes
  |  limits the space available for IPv6 extension headers to 32
  |  bytes or IPv4 options to 52 bytes if the path only supports the
  |  IPv6 minimum MTU of 1280 bytes.  This affects Initial packets
  |  and path validation.

Any maximum datagram size larger than 1200 bytes can be discovered using Path Maximum Transmission Unit Discovery (PMTUD) (see Section 14.2.1) or Datagram Packetization Layer PMTU Discovery (DPLPMTUD) (see Section 14.3).
任何大于 1200 字节的最大数据报大小都可以使用路径最大传输单元发现 (PMTUD)(参见第 14.2.1 节)或数据报分组化层 PMTU 发现(DPLPMTUD)(参见第 14.3 节)来发现。

max_udp_payload_size :即quic的的最大长度
Enforcement of the max_udp_payload_size transport parameter
(Section 18.2) might act as an additional limit on the maximum
datagram size. A sender can avoid exceeding this limit, once the
value is known. However, prior to learning the value of the
transport parameter, endpoints risk datagrams being lost if they send
datagrams larger than the smallest allowed maximum datagram size of
1200 bytes. 强制设置 max_udp_payload_size 传输参数可能会带来额外的限制最大的数据报大小。发送端
能避免超出这个限制,一旦这个值被获得。然而在从传输参数获取这个值之前,节点有丢失超出这个限制的数据的风险。

UDP datagrams MUST NOT be fragmented at the IP layer. In IPv4
[IPv4], the Don’t Fragment (DF) bit MUST be set if possible, to
prevent fragmentation on the path. udp数据报应避免分片,来防止链路的碎片。

QUIC sometimes requires datagrams to be no smaller than a certain

size; see Section 8.1 as an example. However, the size of a datagram
is not authenticated. That is, if an endpoint receives a datagram of
a certain size, it cannot know that the sender sent the datagram at
the same size. Therefore, an endpoint MUST NOT close a connection
when it receives a datagram that does not meet size constraints; the
endpoint MAY discard such datagrams. quic有时会要求数据报不要小于一个确定的大小。
然而,数据报的大小不是被认证的。即若节点收到一个数据报是一个确定的大小,它不能知道发送方
发送数据报在相同的大小。因此一个节点不能断开连接当收到一个数据报不满足特定尺寸,但节点可能会丢弃这个数据报。

14.1. Initial Datagram Size

A client MUST expand the payload of all UDP datagrams carrying
Initial packets to at least the smallest allowed maximum datagram
size of 1200 bytes by adding PADDING frames to the Initial packet or
by coalescing the Initial packet; see Section 12.2. Initial packets
can even be coalesced with invalid packets, which a receiver will
discard. Similarly, a server MUST expand the payload of all UDP
datagrams carrying ack-eliciting Initial packets to at least the
smallest allowed maximum datagram size of 1200 bytes.客户端要扩展udp载荷到满足允许的最小大小如1200字节,当传输Initial packet
可以通过添加padding frames或合并Initial packet。 Initpacket甚至可以合并无效packets,接收方会丢弃。
类似的,服务端必须扩展payload,当携带所有要ack的Initial packet ,至少1200bytes

Sending UDP datagrams of this size ensures that the network path
supports a reasonable Path Maximum Transmission Unit (PMTU), in both
directions. Additionally, a client that expands Initial packets
helps reduce the amplitude of amplification attacks caused by server
responses toward an unverified client address; see Section 8.
使得PMTU更合适,增加攻击的幅度,增加攻击难度。

 Datagrams containing Initial packets MAY exceed 1200 bytes if the

sender believes that the network path and peer both support the size
that it chooses. 可能超过1200bytes,若发送方相信网络链路支持。

A server MUST discard an Initial packet that is carried in a UDP
datagram with a payload that is smaller than the smallest allowed
maximum datagram size of 1200 bytes. A server MAY also immediately
close the connection by sending a CONNECTION_CLOSE frame with an
error code of PROTOCOL_VIOLATION; see Section 10.2.3.
服务端可能丢弃udp报,当载荷大小小于最小值。服务端可能会立刻关闭连接。

The server MUST also limit the number of bytes it sends before
validating the address of the client; see Section 8.
服务端也必须限制它发送的字节数,在它拿到客户端有效地址时。

14.2. Path Maximum Transmission Unit 路径最大传输单元。

The PMTU is the maximum size of the entire IP packet, including the
IP header, UDP header, and UDP payload. The UDP payload includes one
or more QUIC packet headers and protected payloads. The PMTU can
depend on path characteristics and can therefore change over time.
The largest UDP payload an endpoint sends at any given time is
referred to as the endpoint’s maximum datagram size.
PMTU是整个IP包的最大值,包括IP头,UDP头和UDP载荷。UDP载荷包含一个或多个QUIC包头和保护的载荷。
PMTU能依赖于链路特性和能因此随时间改变。 一个节点在任何给定时间发送的最大的UDP载荷是参考节点的最大报文大小。

An endpoint SHOULD use DPLPMTUD (Section 14.3) or PMTUD
(Section 14.2.1) to determine whether the path to a destination will
support a desired maximum datagram size without fragmentation. In
the absence of these mechanisms, QUIC endpoints SHOULD NOT send
datagrams larger than the smallest allowed maximum datagram size.
一个节点应该使用DPLPMTUD 或PMTUD 来决定是否到一个目的地的路径将支持一个想要的最大不分片的报文大小。
在缺失这些机制下,QUIC节点不应该发送数据报比最小允许的 最大报文长度还大。

Both DPLPMTUD and PMTUD send datagrams that are larger than the
current maximum datagram size, referred to as PMTU probes. All QUIC
packets that are not sent in a PMTU probe SHOULD be sized to fit
within the maximum datagram size to avoid the datagram being
fragmented or dropped [RFC8085].

If a QUIC endpoint determines that the PMTU between any pair of local
and remote IP addresses cannot support the smallest allowed maximum
datagram size of 1200 bytes, it MUST immediately cease sending QUIC
packets, except for those in PMTU probes or those containing
CONNECTION_CLOSE frames, on the affected path. An endpoint MAY
terminate the connection if an alternative path cannot be found.

Each pair of local and remote addresses could have a different PMTU.
QUIC implementations that implement any kind of PMTU discovery
therefore SHOULD maintain a maximum datagram size for each
combination of local and remote IP addresses.

A QUIC implementation MAY be more conservative in computing the
maximum datagram size to allow for unknown tunnel overheads or IP
header options/extensions.

14.2.1. Handling of ICMP Messages by PMTUD QUIC如何处理ICMP包.

PMTUD [RFC1191] [RFC8201] relies on reception of ICMP messages (that
is, IPv6 Packet Too Big (PTB) messages) that indicate when an IP
packet is dropped because it is larger than the local router MTU.
DPLPMTUD can also optionally use these messages. This use of ICMP
messages is potentially vulnerable to attacks by entities that cannot
observe packets but might successfully guess the addresses used on
the path. These attacks could reduce the PMTU to a bandwidth-
inefficient value. PMTUD依赖于收取的ICMP包。。。

An endpoint MUST ignore an ICMP message that claims the PMTU has
decreased below QUIC’s smallest allowed maximum datagram size.

The requirements for generating ICMP [RFC1812] [RFC4443] state that
the quoted packet should contain as much of the original packet as
possible without exceeding the minimum MTU for the IP version. The
size of the quoted packet can actually be smaller, or the information
unintelligible, as described in Section 1.1 of [DPLPMTUD].

QUIC endpoints using PMTUD SHOULD validate ICMP messages to protect
from packet injection as specified in [RFC8201] and Section 5.2 of
[RFC8085]. This validation SHOULD use the quoted packet supplied in
the payload of an ICMP message to associate the message with a
corresponding transport connection (see Section 4.6.1 of [DPLPMTUD]).
ICMP message validation MUST include matching IP addresses and UDP
ports [RFC8085] and, when possible, connection IDs to an active QUIC
session. The endpoint SHOULD ignore all ICMP messages that fail
validation.

An endpoint MUST NOT increase the PMTU based on ICMP messages; see
Item 6 in Section 3 of [DPLPMTUD]. Any reduction in QUIC’s maximum
datagram size in response to ICMP messages MAY be provisional until
QUIC’s loss detection algorithm determines that the quoted packet has
actually been lost.

QUIC的PMTU 发送。
14.3. Datagram Packetization Layer PMTU Discovery

DPLPMTUD [DPLPMTUD] relies on tracking loss or acknowledgment of QUIC
packets that are carried in PMTU probes. PMTU probes for DPLPMTUD
that use the PADDING frame implement “Probing using padding data”, as
defined in Section 4.1 of [DPLPMTUD].

Endpoints SHOULD set the initial value of BASE_PLPMTU (Section 5.1 of
[DPLPMTUD]) to be consistent with QUIC’s smallest allowed maximum
datagram size. The MIN_PLPMTU is the same as the BASE_PLPMTU.

QUIC endpoints implementing DPLPMTUD maintain a DPLPMTUD Maximum
Packet Size (MPS) (Section 4.4 of [DPLPMTUD]) for each combination of
local and remote IP addresses. This corresponds to the maximum
datagram size.

14.3.1. DPLPMTUD and Initial Connectivity

From the perspective of DPLPMTUD, QUIC is an acknowledged
Packetization Layer (PL). A QUIC sender can therefore enter the
DPLPMTUD BASE state (Section 5.2 of [DPLPMTUD]) when the QUIC
connection handshake has been completed.

14.3.2. Validating the Network Path with DPLPMTUD

QUIC is an acknowledged PL; therefore, a QUIC sender does not
implement a DPLPMTUD CONFIRMATION_TIMER while in the SEARCH_COMPLETE
state; see Section 5.2 of [DPLPMTUD].

14.3.3. Handling of ICMP Messages by DPLPMTUD

An endpoint using DPLPMTUD requires the validation of any received
ICMP PTB message before using the PTB information, as defined in
Section 4.6 of [DPLPMTUD]. In addition to UDP port validation, QUIC
validates an ICMP message by using other PL information (e.g.,
validation of connection IDs in the quoted packet of any received
ICMP message).

The considerations for processing ICMP messages described in
Section 14.2.1 also apply if these messages are used by DPLPMTUD.

14.4. Sending QUIC PMTU Probes

PMTU probes are ack-eliciting packets.

Endpoints could limit the content of PMTU probes to PING and PADDING
frames, since packets that are larger than the current maximum
datagram size are more likely to be dropped by the network. Loss of
a QUIC packet that is carried in a PMTU probe is therefore not a
reliable indication of congestion and SHOULD NOT trigger a congestion
control reaction; see Item 7 in Section 3 of [DPLPMTUD]. However,
PMTU probes consume congestion window, which could delay subsequent
transmission by an application.

14.4.1. PMTU Probes Containing Source Connection ID

Endpoints that rely on the Destination Connection ID field for
routing incoming QUIC packets are likely to require that the
connection ID be included in PMTU probes to route any resulting ICMP
messages (Section 14.2.1) back to the correct endpoint. However,
only long header packets (Section 17.2) contain the Source Connection
ID field, and long header packets are not decrypted or acknowledged
by the peer once the handshake is complete.

One way to construct a PMTU probe is to coalesce (see Section 12.2) a
packet with a long header, such as a Handshake or 0-RTT packet
(Section 17.2), with a short header packet in a single UDP datagram.
If the resulting PMTU probe reaches the endpoint, the packet with the
long header will be ignored, but the short header packet will be
acknowledged. If the PMTU probe causes an ICMP message to be sent,
the first part of the probe will be quoted in that message. If the
Source Connection ID field is within the quoted portion of the probe,
that could be used for routing or validation of the ICMP message.

  |  Note: The purpose of using a packet with a long header is only
  |  to ensure that the quoted packet contained in the ICMP message
  |  contains a Source Connection ID field.  This packet does not
  |  need to be a valid packet, and it can be sent even if there is
  |  no current use for packets of that type.

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 from 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 bytes is 1010 (in binary). A
client or server MAY advertise support for any of these reserved
versions.

Reserved version numbers will 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.

  1. 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 bytes to encode.
QUIC 包和帧都使用可变长度编码,非负整数。 这个编码确保越小整数值需要更小的字节编码。

The QUIC variable-length integer encoding reserves the two most
significant bits of the first byte to encode the base-2 logarithm of
the integer encoding length in bytes. The integer value is encoded
on the remaining bits, in network byte order.
quic可变长整数编码保留两个最多符号未去编码基于2的对数的整数。整数值被编码到剩余的位,用网络字节序。
This means that integers are encoded on 1, 2, 4, or 8 bytes and can
encode 6-, 14-, 30-, or 62-bit values, respectively. Table 4
summarizes the encoding properties.
这意味着整数被编码为1,2,4或8字节和能编码为6-, 14-, 30-, or 62-bit values,分别的。
如下表:

1
2
3
4
5
6
7
8
9
10
11
12
13
+======+========+=============+=======================+
| 2MSB | Length | Usable Bits | Range |
+======+========+=============+=======================+
| 00 | 1(Byte)| 6 | 0-63 |
+------+--------+-------------+-----------------------+
| 01 | 2 | 14 | 0-16383 |
+------+--------+-------------+-----------------------+
| 10 | 4 | 30 | 0-1073741823 |
+------+--------+-------------+-----------------------+
| 11 | 8 | 62 | 0-4611686018427387903 |
+------+--------+-------------+-----------------------+

Table 4: Summary of Integer Encodings

An example of a decoding algorithm and sample encodings are shown in
Appendix A.1. 例子?

Values do not need to be encoded on the minimum number of bytes
necessary, with the sole exception of the Frame Type field; see
Section 12.4.

Versions (Section 15), packet numbers sent in the header
(Section 17.1), and the length of connection IDs in long header
packets (Section 17.2) are described using integers but do not use
this encoding.

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.
所有数值型值被编码为网络字节序即大端。并且所有域的长度是位计算的。 十六进制表示法用于描述字段的值。

包number如何编码和解码。TODO

17.1. Packet Number Encoding and Decoding

Packet numbers are integers in the range 0 to 2^62-1 (Section 12.3).
When present in long or short packet headers, they are encoded in 1
to 4 bytes. The number of bits required to represent the packet
number is reduced by including only the least significant bits of the
packet number. 包number是整数类型,范围在0-2^62-1. 当被填充到long 或 short
packet headers,他们被编码为1-4字节。这个数值的损失只在符号位。

The encoded packet number is protected as described in Section 5.4 of
[QUIC-TLS].

Prior to receiving an acknowledgment for a packet number space, the
full packet number MUST be included; it is not to be truncated, as
described below.
在接收到数据包编号空间的确认之前,
必须包括完整的包号;它不能被截断,因为
如下面所描述的。

After an acknowledgment is received for a packet number space, the
sender MUST use a packet number size able to represent more than
twice as large a range as the difference between the largest
acknowledged packet number and the 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 bit more than the base-2 logarithm of the number of contiguous unacknowledged packet numbers, including the new packet.
Pseudocode and an example for packet number encoding can be found in Appendix A.2.
结果,数据包编号编码的大小至少比包括新数据包在内的连续未确认数据包编号的以 2 为底的对数多一位。
伪代码和包号编码示例见附录 A.2。

  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 in a successfully authenticated packet.
Recovering the full packet number is necessary to successfully complete the removal of packet protection.
在接收方,在恢复完整的包号之前,删除了对包号的保护。
然后根据存在的有效位的数量、这些位的值以及在成功验证的数据包中接收到的最大数据包编号来重构完整的数据包编号。
恢复完整的数据包编号对于成功完成数据包保护的删除是必要的。

Once header 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.
Pseudocode and an example for packet number decoding can be found in Appendix A.
一旦去除了报头保护,就会通过查找最接近下一个预期数据包的数据包编号值来解码数据包编号。
下一个预期数据包是接收到的最高数据包编号加一。
伪代码和包号解码示例见附录 A。

17.2. Long Header Packets

【先简单回顾下规范:
1.3. Notational Conventions

Packet and frame diagrams in this document use a custom format. The
purpose of this format is to summarize, not define, protocol
elements. Prose defines the complete semantics and details of
structures.

Complex fields are named and then followed by a list of fields
surrounded by a pair of matching braces. Each field in this list is
separated by commas.

Individual fields include length information, plus indications about
fixed value, optionality, or repetitions. Individual fields use the
following notational conventions, with all lengths in bits:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
x (A):  Indicates that x is A bits long

x (i): Indicates that x holds an integer value using the variable-
length encoding described in Section 16

x (A..B): Indicates that x can be any length from A to B; A can be
omitted to indicate a minimum of zero bits, and B can be omitted
to indicate no set upper limit; values in this format always end
on a byte boundary

x (L) = C: Indicates that x has a fixed value of C; the length of x
is described by L, which can use any of the length forms above

x (L) = C..D: Indicates that x has a value in the range from C to D,
inclusive, with the length described by L, as above

[x (L)]: Indicates that x is optional and has a length of L

x (L) ...: Indicates that x is repeated zero or more times and that
each instance has a length of L

This document uses network byte order (that is, big endian) values.
Fields are placed starting from the high-order bits of each byte.

By convention, individual fields reference a complex field by using
the name of the complex field.

Figure 1 provides an example:

Example Structure {
One-bit Field (1),
7-bit Field with Fixed Value (7) = 61,
Field with Variable-Length Integer (i),
Arbitrary-Length Field (..),
Variable-Length Field (8..24),
Field With Minimum Length (16..),
Field With Maximum Length (..128),
[Optional Field (64)],
Repeated Field (8) ...,
}
                      Figure 1: Example Format

When a single-bit field is referenced in prose, the position of that
field can be clarified by using the value of the byte that carries
the field with the field’s value set. For example, the value 0x80
could be used to refer to the single-bit field in the most
significant bit of the byte, such as One-bit Field in Figure 1.

1
2
3
4
5
6
7
8
9
10
11
12
Long Header Packet {
Header Form (1) = 1, 1bit,值为1,表示是长header,短header则为0
Fixed Bit (1) = 1, 版本协商数据包为0,否则为1,其他情况0时丢弃
Long Packet Type (2), 长头包类型 Initial/0-RTT/handshake/retry
Type-Specific Bits (4), 和具体包有关。。
Version (32), 版本号
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Type-Specific Payload (..),
}
                Figure 13: Long Header Packet Format

Long headers are used for packets that are sent prior to the establishment of 1-RTT keys.
Once 1-RTT keys are available, 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 byte 0 (the first byte) is set to 1 for long headers.
长标头用于在建立 1-RTT 密钥之前发送的数据包。
一旦 1-RTT 密钥可用,发送方就会切换到使用短报头发送数据包(第 17.3 节)。
长格式允许特殊的数据包——例如版本协商数据包——以这种统一的固定长度数据包格式表示。
使用长头的数据包包含以下字段:
Header Form:字节 0(第一个字节)的最高有效位(0x80)设置为 1,用于长报头。

Fixed Bit: The next bit (0x40) of byte 0 is set to 1, unless the packet is a Version Negotiation packet.
Packets containing a zero value for this bit are not valid packets in this version and MUST be discarded.
A value of 1 for this bit allows QUIC to coexist with other protocols; see [RFC7983].
固定位:字节 0 的下一位 (0x40) 设置为 1,除非数据包是版本协商数据包。
该位包含零值的数据包在此版本中不是有效的数据包,必须被丢弃。
该位的值为 1 允许 QUIC 与其他协议共存;参见 [RFC7983]。 ngtcp2测试除了第一个包Initial,其他包都是0

Long Packet Type: The next two bits (those with a mask of 0x30) of byte 0 contain a packet type.
Packet types are listed in Table 5.
长数据包类型:字节 0 的下两位(掩码为 0x30)包含数据包类型。
数据包类型在表 5 中列出。
In this version of QUIC, the following packet types with the long header are defined:

1
2
3
4
5
6
7
8
9
10
11
12
13
+======+===========+================+
| Type | Name | Section |
+======+===========+================+
| 0x00 | Initial | Section 17.2.2 |
+------+-----------+----------------+
| 0x01 | 0-RTT | Section 17.2.3 |
+------+-----------+----------------+
| 0x02 | Handshake | Section 17.2.4 |
+------+-----------+----------------+
| 0x03 | Retry | Section 17.2.5 |
+------+-----------+----------------+

Table 5: Long Header Packet Types

Type-Specific Bits: The semantics of the lower four bits (those with a mask of 0x0f) of byte 0 are determined by the packet type.
类型特定位:字节 0 的低四位(掩码为 0x0f)的语义由数据包类型决定。 目前看ngtcp2,wireshark解析为reserve+packet number lenght

Version: The QUIC Version is a 32-bit field that follows the first byte.
This field indicates the version of QUIC that is in use and determines how the rest of the protocol fields are interpreted.
版本:QUIC 版本是跟在第一个字节之后的 32 位字段。
此字段指示正在使用的 QUIC 版本,并确定其余协议字段的解释方式。

Destination Connection ID Length: The byte following the version contains the length in bytes of the Destination Connection ID field that follows it.
This length is encoded as an 8-bit unsigned integer.
In QUIC version 1, this value MUST NOT exceed 20 bytes. Endpoints that receive a version 1 long header with a value larger than 20 MUST drop the packet.
In order to properly form a Version Negotiation packet, servers SHOULD be able to read longer connection IDs from other QUIC versions.
目标连接 ID 长度:版本后面的字节包含其后面的目标连接 ID 字段的字节长度。
此长度编码为 8 位无符号整数。
在 QUIC 版本 1 中,此值不得超过 20 个字节。接收到值大于 20 的版本 1 长标头的端点必须丢弃该数据包。
为了正确形成版本协商包,服务器应该能够从其他 QUIC 版本中读取更长的连接 ID。

Destination Connection ID: The Destination Connection ID field follows the Destination Connection ID Length field, which indicates the length of this field.
Section 7.2 describes the use of this field in more detail.
Destination Connection ID:Destination Connection ID 字段跟在 Destination Connection ID Length 字段之后,表示该字段的长度。
第 7.2 节更详细地描述了该字段的使用。

Source Connection ID Length: The byte following the Destination Connection ID contains the length in bytes of the Source Connection ID field that follows it.
This length is encoded as an 8-bit unsigned integer. In QUIC version 1, this value MUST NOT exceed 20 bytes.
Endpoints that receive a version 1 long header with a value larger than 20 MUST drop the packet.
In order to properly form a Version Negotiation packet, servers SHOULD be able to read longer connection IDs from other QUIC versions.
源连接 ID 长度:目标连接 ID 后面的字节包含其后面的源连接 ID 字段的长度(以字节为单位)。
此长度编码为 8 位无符号整数。在 QUIC 版本 1 中,此值不得超过 20 个字节。
接收到值大于 20 的版本 1 长标头的端点必须丢弃该数据包。
为了正确形成版本协商包,服务器应该能够从其他 QUIC 版本中读取更长的连接 ID。

Source Connection ID: The Source Connection ID field follows the Source Connection ID Length field, which indicates the length of this field.
Section 7.2 describes the use of this field in more detail.
Source Connection ID:Source Connection ID 字段跟在 Source Connection ID Length 字段之后,表示该字段的长度。
第 7.2 节更详细地描述了该字段的使用。

Type-Specific Payload: The remainder of the packet, if any, is type specific.
特定于类型的有效负载:数据包的其余部分(如果有)是特定于类型的。

The header form bit, Destination and Source Connection ID lengths, Destination and Source Connection ID fields, and Version fields of a long header packet are version independent.
The other fields in the first byte are version specific.
See [QUIC-INVARIANTS] for details on how packets from different versions of QUIC are interpreted.
长报头数据包的报头形式位、目的和源连接 ID 长度、目的和源连接 ID 字段以及版本字段与版本无关。
第一个字节中的其他字段是特定于版本的。
有关如何解释来自不同版本 QUIC 的数据包的详细信息,请参阅 [QUIC-INVARIANTS]。

The interpretation of the fields and the payload are specific to a version and packet type.
While type-specific semantics for this version are described in the following sections, several long header packets in this version of QUIC contain these additional fields:
Reserved Bits: Two bits (those with a mask of 0x0c) of byte 0 are reserved across multiple packet types.
These bits are protected using header protection; see Section 5.4 of [QUIC-TLS].
The value included prior to protection MUST be set to 0.
An endpoint MUST treat receipt of a packet that has a non-zero value for these bits after removing both packet and header protection as a connection error of type PROTOCOL_VIOLATION.
Discarding such a packet after only removing header protection can expose the endpoint to attacks; see Section 9.5 of [QUIC-TLS].
字段和有效负载的解释特定于版本和数据包类型。
虽然此版本的特定于类型的语义在以下部分中描述,但此版本 QUIC 中的几个长头数据包包含以下附加字段:
保留位:字节 0 的两个位(掩码为 0x0c)在多种数据包类型中保留。
这些位使用标头保护进行保护;请参阅 [QUIC-TLS] 的第 5.4 节。
包含在保护之前的值必须设置为 0。
在删除数据包和报头保护之后,端点必须将接收到这些位具有非零值的数据包视为 PROTOCOL_VIOLATION 类型的连接错误。
仅删除标头保护后丢弃此类数据包会使端点受到攻击;请参阅 [QUIC-TLS] 的第 9.5 节。

type-specific payload:可能由下构成
Packet Number Length: In packet types that contain a Packet Number field, the least significant two bits (those with a mask of 0x03) of byte 0 contain the length of the Packet Number field, encoded as an unsigned two-bit integer that is one less than the length of the Packet Number field in bytes.
That is, the length of the Packet Number field is the value of this field plus one.
These bits are protected using header protection; see Section 5.4 of [QUIC-TLS].
数据包编号长度:在包含数据包编号字段的数据包类型中,字节 0 的最低有效两位(掩码为 0x03)包含数据包编号字段的长度,编码为无符号两位整数,即 1小于 Packet Number 字段的长度(以字节为单位)。
即 Packet Number 字段的长度是该字段的值加一。
这些位使用标头保护进行保护;请参阅 [QUIC-TLS] 的第 5.4 节。

Length: This is the length of the remainder of the packet (that is, the Packet Number and Payload fields) in bytes, encoded as a variable-length integer (Section 16).
长度:这是数据包剩余部分(即数据包编号和有效负载字段)的长度,以字节为单位,编码为可变长度整数(第 16 节)。

Packet Number: This field is 1 to 4 bytes long. 和wireshark 解析有点出入,是token length
The packet number is protected using header protection; see Section 5.4 of [QUIC-TLS].
The length of the Packet Number field is encoded in the Packet Number Length bits of byte 0; see above.
数据包编号:该字段的长度为 1 到 4 个字节。
数据包编号使用标头保护进行保护;请参阅 [QUIC-TLS] 的第 5.4 节。
Packet Number 字段的长度编码在字节 0 的 Packet Number Length 位中;往上看。

Packet Payload: This is the payload of the packet – containing a sequence of frames – that is protected using packet protection.
数据包有效负载:这是数据包的有效负载 - 包含一系列帧 - 使用数据包保护进行保护。

17.2.1. Version Negotiation Packet

A Version Negotiation packet is inherently not version specific.
Upon receipt by a client, it 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.
It is only sent by servers.
The layout of a Version Negotiation packet is:
重要!!!!它由服务器发,仅在服务器不支持客户端指定的版本的回复。
版本协商数据包本质上不是特定于版本的。
客户端收到后,将根据版本字段值为 0 将其识别为版本协商包。
版本协商数据包是对包含服务器不支持的版本的客户端数据包的响应。
它仅由服务器发送。
版本协商包的布局是:

1
2
3
4
5
6
7
8
9
10
Version Negotiation Packet {
Header Form (1) = 1,
Unused (7),
Version (32) = 0,
Destination Connection ID Length (8),
Destination Connection ID (0..2040),
Source Connection ID Length (8),
Source Connection ID (0..2040),
Supported Version (32) ...,
}
               Figure 14: Version Negotiation Packet

The value in the Unused field is set to an arbitrary value by the server.
Clients MUST ignore the value of this field.
Where QUIC might be multiplexed with other protocols (see [RFC7983]), servers SHOULD set the most significant bit of this field (0x40) to 1 so that Version Negotiation packets appear to have the Fixed Bit field.
Note that other versions of QUIC might not make a similar recommendation.
未使用字段中的值由服务器设置为任意值。
客户端必须忽略该字段的值。
在 QUIC 可能与其他协议复用的情况下(参见 [RFC7983]),服务器应该将此字段的最高有效位(0x40)设置为 1,以便版本协商数据包看起来具有固定位字段。
请注意,其他版本的 QUIC 可能不会提出类似的建议。

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 entity that did not observe the Initial packet.
服务器必须在目标连接 ID 字段中包含它接收到的数据包的源连接 ID 字段的值。
源连接 ID 的值必须从接收到的数据包的目标连接 ID 中复制,该数据包最初是由客户端随机选择的。
回显两个连接 ID 可以让客户端确信服务器收到了数据包,并且版本协商数据包不是由没有观察初始数据包的实体生成的。

Future versions of QUIC could have different requirements for the lengths of connection IDs.
In particular, connection IDs might have a smaller minimum length or a greater maximum length.
Version- specific rules for the connection ID therefore MUST NOT influence a decision about whether to send a Version Negotiation packet.
QUIC 的未来版本可能对连接 ID 的长度有不同的要求。
特别是,连接 ID 可能具有较小的最小长度或较大的最大长度。
因此,连接 ID 的版本特定规则不得影响是否发送版本协商包的决定。

The remainder of the Version Negotiation packet is a list of 32-bit versions that the server supports.
版本协商数据包的其余部分是服务器支持的 32 位版本列表。
A Version Negotiation packet is not acknowledged.版本协商包不需要ack回复
It is only sent in response to a packet that indicates an unsupported version; see Section 5.2.2.
它仅在响应表明版本不受支持的数据包时发送; 见第 5.2.2 节。
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.
版本协商数据包不包括使用长报头形式的其他数据包中存在的 数据包编号和长度字段。
因此,版本协商数据包会消耗整个 UDP 数据报。
A server MUST NOT send more than one Version Negotiation packet in response to a single UDP datagram.
See Section 6 for a description of the version negotiation process.
服务器不得发送多个版本协商包以响应单个 UDP 数据报。
有关版本协商过程的描述,请参见第 6 节。

17.2.2. Initial Packet

An Initial packet uses long headers with a type value of 0x00.
It carries the first CRYPTO frames sent by the client and server to perform key exchange, and it carries ACK frames in either direction.
初始数据包使用类型值为 0x00 的长标头。
它携带客户端和服务器发送的第一个 CRYPTO 帧以执行密钥交换,并在任一方向携带 ACK 帧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Initial Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 0,
Reserved Bits (2),
Packet Number Length (2), //到此1B
Version (32), //4B
Destination Connection ID Length (8),//1B
Destination Connection ID (0..160),//20B
Source Connection ID Length (8),//1B
Source Connection ID (0..160),//20B
Token Length (i), //可变长
Token (..),
Length (i),//可变长
Packet Number (8..32),1B-4B
Packet Payload (8..),
}
                     Figure 15: Initial Packet

The Initial packet contains a long header as well as the Length and Packet Number fields; see Section 17.2.
The first byte contains the Reserved and Packet Number Length bits; see also Section 17.2.
Between the Source Connection ID and Length fields, there are two additional fields specific to the Initial packet.
初始数据包包含一个长标头以及长度和数据包编号字段; 见第 17.2 节。
第一个字节包含保留位和包号长度位; 另见第 17.2 节。
在源连接 ID 和长度字段之间,还有两个特定于初始数据包的附加字段。

Token Length: A variable-length integer specifying the length of the Token field, in bytes.
This value is 0 if no token is present.
Initial packets sent by the server MUST set the Token Length field to 0; 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长度:一个可变长度整数,指定令牌字段的长度,以字节为单位。
如果不存在令牌,则此值为 0。
服务器发送的初始数据包必须将令牌长度字段设置为 0; 接收到具有非零令牌长度字段的初始数据包的客户端必须丢弃该数据包或生成 PROTOCOL_VIOLATION 类型的连接错误。

Token: The value of the token that was previously provided in a Retry packet or NEW_TOKEN frame; see Section 8.1.
Token:之前在 Retry 包或 NEW_TOKEN 帧中提供的 token 的值; 见第 8.1 节。
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 attackers that can observe packets, but it does prevent attackers that cannot observe packets from spoofing Initial packets.
为了防止不知道版本的中间盒篡改,初始数据包使用 [QUIC-TLS] 中所述的连接和版本特定密钥(初始密钥)进行保护。
这种保护不会为可以观察数据包的攻击者提供机密性或完整性,但它确实可以防止无法观察数据包的攻击者欺骗初始数据包。

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 Retry packet; see Section 17.2.5.
客户端和服务器对任何包含初始加密握手消息的数据包都使用初始数据包类型。
这包括所有需要创建包含初始加密消息的新数据包的情况,例如接收到 Retry 数据包后发送的数据包; 见第 17.2.5 节。

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.
服务器发送其第一个 Initial 数据包以响应客户端 Initial。
服务器可以发送多个初始数据包。
加密密钥交换可能需要多次往返或重新传输此数据。

The payload of an Initial packet includes a CRYPTO frame (or frames) containing a cryptographic handshake message, ACK frames, or both.
PING, PADDING, and CONNECTION_CLOSE frames of type 0x1c 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.
初始数据包的有效载荷包括一个 CRYPTO 帧(或多个帧),其中包含加密握手消息、ACK 帧或两者。
也允许使用 0x1c 类型的 PING、PADDING 和 CONNECTION_CLOSE 帧。
接收到包含其他帧的初始数据包的端点可以将该数据包作为虚假数据包丢弃或将其视为连接错误。

The first packet sent by a client always includes a CRYPTO frame that contains the start or all of the first cryptographic handshake message.
The first CRYPTO frame sent always begins at an offset of 0; see Section 7.
客户端发送的第一个数据包总是包含一个 CRYPTO 帧,该帧包含第一个加密握手消息的开始或全部。
发送的第一个 CRYPTO 帧总是从偏移量 0 开始; 见第 7 节。

Note that if the server sends a TLS HelloRetryRequest (see Section 4.7 of [QUIC-TLS]), the client will send another series of Initial packets.
These Initial packets will continue the cryptographic handshake and will contain CRYPTO frames starting at an offset matching the size of the CRYPTO frames sent in the first flight of Initial packets.
请注意,如果服务器发送一个 TLS HelloRetryRequest(参见 [QUIC-TLS] 的第 4.7 节),客户端将发送另一系列初始数据包。
这些 Initial 数据包将继续加密握手,并将包含 CRYPTO 帧,其偏移量与在 Initial 数据包的第一次飞行中发送的 CRYPTO 帧的大小相匹配。
所以初始化和握手的一般流程:
client—-Initial packet(packet type 0: CRYPTO Frame+可选PADDING Frame) —> server client发送Initial 包给到服务器
client<—-Initial packet(packet type 0: ACK Frame+CRYPTO Frame) + handshake packet(CRYPTO Frame)–server 服务器发送Initial packet和握手包

17.2.2.1. Abandoning Initial Packets

A client stops both sending and processing Initial packets when it sends its first Handshake packet.
A server stops sending and processing Initial packets when it receives its first Handshake packet.
Though packets might still be in flight or awaiting acknowledgment, no further Initial packets need to be exchanged beyond this point.
Initial packet protection keys are discarded (see Section 4.9.1 of [QUIC-TLS]) along with any loss recovery and congestion control state; see Section 6.4 of [QUIC-RECOVERY].
Any data in CRYPTO frames is discarded – and no longer retransmitted – when Initial keys are discarded.
客户端在发送其第一个握手数据包时停止发送和处理初始数据包。
服务器在收到第一个握手包时停止发送和处理初始包。
尽管数据包可能仍在传输中或等待确认,但在此之后不再需要交换初始数据包。
初始数据包保护密钥与任何丢失恢复和拥塞控制状态一起被丢弃(参见 [QUIC-TLS] 的第 4.9.1 节); 请参阅 [QUIC-RECOVERY] 的第 6.4 节。
当初始密钥被丢弃时,CRYPTO 帧中的任何数据都将被丢弃 - 并且不再重新传输。

17.2.3. 0-RTT

A 0-RTT packet uses long headers with a type value of 0x01, followed by the Length and Packet Number fields; see Section 17.2.
The first byte contains the Reserved and Packet Number Length bits; see Section 17.2.
A 0-RTT packet is used to carry “early” data from the client to the server as part of the first flight, prior to handshake completion.
As part of the TLS handshake, the server can accept or reject this early data.
0-RTT 数据包使用类型值为 0x01 的长标头,后跟长度和数据包编号字段; 见第 17.2 节。
第一个字节包含保留位和包号长度位; 见第 17.2 节。
在握手完成之前,作为第一次传输的一部分,0-RTT 数据包用于将“早期”数据从客户端传送到服务器。
作为 TLS 握手的一部分,服务器可以接受或拒绝此早期数据。
See Section 2.3 of [TLS13] for a discussion of 0-RTT data and its limitations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0-RTT Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 1,
Reserved Bits (2),
Packet Number Length (2),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Length (i),
Packet Number (8..32),
Packet Payload (8..),
}
                      Figure 16: 0-RTT Packet

Packet numbers for 0-RTT protected packets use the same space as 1-RTT protected packets.
0-RTT 保护数据包的数据包编号使用与 1-RTT 保护数据包相同的空间。
After a client receives a Retry packet, 0-RTT packets are likely to have been lost or discarded by the server.
A client SHOULD attempt to resend data in 0-RTT packets after it sends a new Initial packet.
New packet numbers MUST be used for any new packets that are sent; as described in Section 17.2.5.3, reusing packet numbers could compromise packet protection.
客户端收到 Retry 报文后,0-RTT 报文很可能已经丢失或被服务器丢弃。
客户端应该在发送新的初始数据包后尝试重新发送 0-RTT 数据包中的数据。
新的数据包编号必须用于发送的任何新数据包; 如第 17.2.5.3 节所述,重复使用数据包编号可能会危及数据包保护。

A client only receives acknowledgments for its 0-RTT packets once the handshake is complete, as defined in Section 4.1.1 of [QUIC-TLS].
握手完成后,客户端仅接收其 0-RTT 数据包的确认,如 [QUIC-TLS] 的第 4.1.1 节中所定义。
A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.
This means that 0-RTT packets cannot contain any response to frames from 1-RTT packets.
For instance, a client cannot send an ACK frame in a 0-RTT packet, because that can only acknowledge a 1-RTT packet.
An acknowledgment for a 1-RTT packet MUST be carried in a 1-RTT packet.
客户端一旦开始处理来自服务器的 1-RTT 数据包,就不能发送 0-RTT 数据包。
这意味着 0-RTT 数据包不能包含对来自 1-RTT 数据包的帧的任何响应。
例如,客户端不能在 0-RTT 数据包中发送 ACK 帧,因为它只能确认 1-RTT 数据包。
1-RTT 数据包的确认必须在 1-RTT 数据包中携带。

A server SHOULD treat a violation of remembered limits (Section 7.4.1) as a connection error of an appropriate type (for instance, a FLOW_CONTROL_ERROR for exceeding stream data limits).
服务器应该将违反记忆限制(第 7.4.1 节)视为适当类型的连接错误(例如,超出流数据限制的 FLOW_CONTROL_ERROR)。

17.2.4. Handshake Packet

A Handshake packet uses long headers with a type value of 0x02, followed by the Length and Packet Number fields; see Section 17.2.
The first byte contains the Reserved and Packet Number Length bits; see Section 17.2.
It is used to carry cryptographic handshake messages and acknowledgments from the server and client.
Handshake 数据包使用类型值为 0x02 的长标头,后跟 Length 和 Packet Number 字段; 见第 17.2 节。
第一个字节包含保留位和包号长度位; 见第 17.2 节。
它用于携带来自服务器和客户端的加密握手消息和确认。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Handshake Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 2,
Reserved Bits (2),
Packet Number Length (2),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Length (i),
Packet Number (8..32),
Packet Payload (8..),
}
               Figure 17: Handshake Protected Packet
 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.
一旦客户端从服务器接收到握手包,它就会使用握手包向服务器发送后续的加密握手消息和确认。
Handshake 数据包中的 Destination Connection ID 字段包含一个由数据包的接收者选择的连接 ID; 源连接 ID 包括数据包的发送者希望使用的连接 ID; 见第 7.2 节。
Handshake packets have their own packet number space, and thus the first Handshake packet sent by a server contains a packet number of 0.
握手包有自己的包号空间,因此服务器发送的第一个握手包包含的包号为0。而之后客户端发送的handshake packet的packet number为1
The payload of this packet contains CRYPTO frames and could contain PING, PADDING, or ACK frames.
Handshake packets MAY contain CONNECTION_CLOSE frames of type 0x1c.
Endpoints MUST treat receipt of Handshake packets with other frames as a connection error of type PROTOCOL_VIOLATION.
此数据包的有效负载包含 CRYPTO 帧,并且可能包含 PING、PADDING 或 ACK 帧。
握手包可以包含 0x1c 类型的 CONNECTION_CLOSE 帧。
端点必须将收到与其他帧的握手包视为 PROTOCOL_VIOLATION 类型的连接错误。
Like Initial packets (see Section 17.2.2.1), data in CRYPTO frames for Handshake packets is discarded – and no longer retransmitted – when Handshake protection keys are discarded.
与初始数据包(参见第 17.2.2.1 节)一样,当握手保护密钥被丢弃时,握手数据包的 CRYPTO 帧中的数据将被丢弃 - 并且不再重新传输。

17.2.5. Retry Packet

As shown in Figure 18, a Retry packet uses a long packet header with a type value of 0x03.
It carries an address validation token created by the server.
It is used by a server that wishes to perform a retry; see Section 8.1.
如图 18 所示,Retry 包使用类型值为 0x03 的长包头。
它带有一个由服务器创建的地址验证令牌。
它被希望执行重试的服务器使用; 见第 8.1 节。

1
2
3
4
5
6
7
8
9
10
11
12
13
 Retry Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 3,
Unused (4),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Retry Token (..),
Retry Integrity Tag (128),
}
                      Figure 18: Retry Packet
A Retry packet does not contain any protected fields.

The value in the Unused field is set to an arbitrary value by the server; a client MUST ignore these bits.
In addition to the fields from the long header, it contains these additional fields:
Retry Token: An opaque token that the server can use to validate the client’s address.
重试数据包不包含任何受保护的字段。
未使用字段中的值由服务器设置为任意值; 客户端必须忽略这些位。
除了长标头中的字段外,它还包含以下附加字段:
重试令牌:服务器可以用来验证客户端地址的不透明令牌。

Retry Integrity Tag: Defined in Section 5.8 (“Retry Packet Integrity”) of [QUIC-TLS].
重试完整性标签:在 [QUIC-TLS] 的第 5.8 节(“重试数据包完整性”)中定义。

17.2.5.1. Sending a Retry Packet 由服务器发送?

The server populates the Destination Connection ID with the connection ID that the client included in the Source Connection ID of the Initial packet.
服务器使用客户端包含在初始数据包的源连接 ID 中的连接 ID 填充目标连接 ID。
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.
A client MUST discard a Retry packet that contains a Source Connection ID field that is identical to the Destination Connection ID field of its Initial packet.
The client MUST use the value from the Source Connection ID field of the Retry packet in the Destination Connection ID field of subsequent packets that it sends.
服务器在 Source Connection ID 字段中包含其选择的连接 ID。
此值不得等于客户端发送的数据包的目标连接 ID 字段。
客户端必须丢弃包含与其初始数据包的目标连接 ID 字段相同的源连接 ID 字段的重试数据包。
客户端必须在其发送的后续数据包的目标连接 ID 字段中使用重试数据包的源连接 ID 字段中的值。

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 server MUST NOT send more than one Retry packet in response to a single UDP datagram.
服务器可以发送 Retry 数据包以响应 Initial 和 0-RTT 数据包。
服务器可以丢弃或缓冲它接收到的 0-RTT 数据包。
服务器可以在接收到 Initial 或 0-RTT 数据包时发送多个 Retry 数据包。
服务器不得发送多个 Retry 数据包以响应单个 UDP 数据报。

17.2.5.2. Handling a Retry Packet

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 have a Retry Integrity Tag that cannot be validated; see Section 5.8 of [QUIC-TLS].
This diminishes an attacker’s ability to inject a Retry packet and protects against accidental corruption of Retry packets.
A client MUST discard a Retry packet with a zero-length Retry Token field.
客户端必须丢弃具有无法验证的重试完整性标签的重试数据包; 请参阅 [QUIC-TLS] 的第 5.8 节。
这会降低攻击者注入重试数据包的能力,并防止意外损坏重试数据包。
客户端必须丢弃具有零长度重试令牌字段的重试数据包。

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 field in the Retry packet.
Changing the Destination Connection ID field 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 packet.
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.4.
客户端将此初始数据包的目标连接 ID 字段设置为重试数据包中源连接 ID 字段的值。
更改目标连接 ID 字段也会导致更改用于保护初始数据包的密钥。
它还将令牌字段设置为重试数据包中提供的令牌。
客户端不得更改源连接 ID,因为服务器可以将连接 ID 作为其令牌验证逻辑的一部分; 见第 8.1.4 节。

A Retry packet does not include a packet number and cannot be explicitly acknowledged by a client.
重试数据包不包含数据包编号,并且无法由客户端显式确认。

17.2.5.3. Continuing a Handshake after Retry

Subsequent Initial packets from the client include the connection ID and token values from the Retry packet.
The client copies the Source Connection ID field from the Retry packet to the Destination Connection ID field and uses this value until an Initial packet with an updated value is received; see Section 7.2.
The value of the Token field is copied to all subsequent Initial packets; see Section 8.1.2.
来自客户端的后续初始数据包包括来自重试数据包的连接 ID 和令牌值。
客户端将 Retry 数据包中的 Source Connection ID 字段复制到 Destination Connection ID 字段并使用该值,直到收到具有更新值的 Initial 数据包; 见第 7.2 节。
Token 字段的值被复制到所有后续的 Initial packet; 见第 8.1.2 节。

Other than updating the Destination Connection ID and Token fields, the Initial packet sent by the client is subject to the same restrictions as the first Initial packet.
A client MUST use the same cryptographic handshake message it included in this packet.
A server MAY treat a packet that contains a different cryptographic handshake message as a connection error or discard it.
Note that including a Token field reduces the available space for the cryptographic handshake message, which might result in the client needing to send multiple Initial packets.
除了更新 Destination Connection ID 和 Token 字段外,客户端发送的 Initial packet 与第一个 Initial packet 的限制相同。
客户端必须使用它包含在此数据包中的相同加密握手消息。
服务器可以将包含不同加密握手消息的数据包视为连接错误或丢弃它。
请注意,包含 Token 字段会减少加密握手消息的可用空间,这可能导致客户端需要发送多个 Initial 数据包。

A client MAY attempt 0-RTT after receiving a Retry packet by sending 0-RTT packets to the connection ID provided by the server.
客户端可以在收到重试包后尝试 0-RTT,方法是向服务器提供的连接 ID 发送 0-RTT 包。

A client MUST NOT reset the packet number for any packet number space after processing a Retry packet.
In particular, 0-RTT packets contain confidential information that will most likely be retransmitted on receiving a Retry packet.
The keys used to protect these new 0-RTT packets will not change as a result of responding to a Retry packet.
However, the data sent in these packets could be different than what was sent earlier.
Sending these new packets with the same packet number is likely to compromise the packet protection for those packets because the same key and nonce could be used to protect different content.
A server MAY abort the connection if it detects that the client reset the packet number.
在处理重试数据包后,客户端不得重置任何数据包编号空间的数据包编号。
特别是,0-RTT 数据包包含机密信息,这些信息很可能在接收到重试数据包时被重新传输。
用于保护这些新的 0-RTT 数据包的密钥不会因为响应重试数据包而改变。
但是,这些数据包中发送的数据可能与之前发送的数据不同。
发送这些具有相同数据包编号的新数据包可能会危及这些数据包的数据包保护,因为相同的密钥和随机数可用于保护不同的内容。
如果服务器检测到客户端重置了数据包编号,它可能会中止连接。

The connection IDs used in Initial and Retry packets exchanged between client and server are copied to the transport parameters and validated as described in Section 7.3.
在客户端和服务器之间交换的初始和重试数据包中使用的连接 ID 被复制到传输参数并按照第 7.3 节所述进行验证。

17.3. Short Header Packets

This version of QUIC defines a single packet type that uses the short packet header.

17.3.1. 1-RTT Packet
1
2
3
4
5
6
7
8
9
10
11
12
13
 A 1-RTT packet uses a short packet header.
It is used after the version and 1-RTT keys are negotiated.
1-RTT Packet {
Header Form (1) = 0,
Fixed Bit (1) = 1,
Spin Bit (1),
Reserved Bits (2),
Key Phase (1),
Packet Number Length (2),
Destination Connection ID (0..160),
Packet Number (8..32),
Packet Payload (8..),
}
                      Figure 19: 1-RTT Packet

1-RTT packets contain the following fields:

Header Form: The most significant bit (0x80) of byte 0 is set to 0 for the short header.

Fixed Bit: The next bit (0x40) of byte 0 is set to 1.
Packets containing a zero value for this bit are not valid packets in this version and MUST be discarded.
A value of 1 for this bit allows QUIC to coexist with other protocols; see [RFC7983].

Spin Bit: The third most significant bit (0x20) of byte 0 is the latency spin bit, set as described in Section 17.4.

Reserved Bits: The next two bits (those with a mask of 0x18) of byte 0 are reserved. These bits are protected using header protection;
see Section 5.4 of [QUIC-TLS].

The value included prior to protection MUST be set to 0.
An endpoint MUST treat receipt of a packet that has a non-zero value for these bits, after removing both packet and header protection, as a connection error of type PROTOCOL_VIOLATION.
Discarding such a packet after only removing header protection can expose the endpoint to attacks; see Section 9.5 of [QUIC-TLS].
包含在保护之前的值必须设置为 0。
端点必须在删除数据包和报头保护后,将接收到这些位具有非零值的数据包视为 PROTOCOL_VIOLATION 类型的连接错误。
仅删除标头保护后丢弃此类数据包会使端点受到攻击; 请参阅 [QUIC-TLS] 的第 9.5 节。

Key Phase: The next bit (0x04) of byte 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.
This bit is protected using header protection; see Section 5.4 of [QUIC-TLS].

Packet Number Length: The least significant two bits (those with a mask of 0x03) of byte 0 contain the length of the Packet Number field, encoded as an unsigned two-bit integer that is one less than the length of the Packet Number field in bytes.
That is, the length of the Packet Number field is the value of this field plus one.
These bits are protected using header protection; see Section 5.4 of [QUIC-TLS].

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 to 4 bytes long.
The packet number is protected using header protection; see Section 5.4 of [QUIC-TLS].
The length of the Packet Number field is encoded in Packet Number Length field.
See Section 17.1 for details.

Packet Payload: 1-RTT packets always include a 1-RTT protected payload.

The header form bit and the Destination 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. Latency Spin Bit 这个位干啥的?

The latency spin bit, which is defined for 1-RTT packets (Section 17.3.1), enables passive latency monitoring from observation points on the network path throughout the duration of a connection.
The server reflects the spin value received, while the client “spins” it after one RTT.
On-path observers can measure the time between two spin bit toggle events to estimate the end-to-end RTT of a connection.
为 1-RTT 数据包(第 17.3.1 节)定义的延迟自旋位允许在整个连接期间从网络路径上的观察点进行被动延迟监控。
服务器反映收到的旋转值,而客户端在一个 RTT 后“旋转”它。
路径上的观察者可以测量两个自旋位切换事件之间的时间,以估计连接的端到端 RTT。

The spin bit is only present in 1-RTT packets, since it is possible to measure the initial RTT of a connection by observing the handshake.
Therefore, the spin bit is available after version negotiation and connection establishment are completed.
On-path measurement and use of the latency spin bit are further discussed in [QUIC-MANAGEABILITY].
自旋位仅存在于 1-RTT 数据包中,因为可以通过观察握手来测量连接的初始 RTT。
因此,在版本协商和连接建立完成后,spin bit 可用。
在 [QUIC-MANAGEABILITY] 中进一步讨论了路径上的测量和延迟自旋位的使用。

The spin bit is an OPTIONAL feature of this version of QUIC.
An endpoint that does not support this feature MUST disable it, as defined below.
自旋位是这个版本的 QUIC 的一个可选特性。
不支持此功能的端点必须禁用它,定义如下。

Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection.
Implementations MUST allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis.
Even when the spin bit is not disabled by the administrator, endpoints MUST disable their use of the spin bit for a random selection of at least one in every 16 network paths, or for one in every 16 connection IDs, in order to ensure that QUIC connections that disable the spin bit are commonly observed on the network.
As each endpoint disables the spin bit independently, this ensures that the spin bit signal is disabled on approximately one in eight network paths.
每个端点单方面决定是否为连接启用或禁用自旋位。
实现必须允许客户端和服务器的管理员全局或基于每个连接禁用旋转位。
即使管理员没有禁用自旋位,端点也必须禁用自旋位以随机选择每 16 个网络路径中的至少一个,或每 16 个连接 ID 中的一个,以确保 QUIC 禁用旋转位的连接通常在网络上观察到。
由于每个端点独立禁用自旋位,这确保了自旋位信号在大约八分之一的网络路径上被禁用。

When the spin bit is disabled, endpoints MAY set the spin bit to any value and MUST ignore any incoming value.
It is RECOMMENDED that endpoints set the spin bit to a random value either chosen independently for each packet or chosen independently for each connection ID.
当自旋位被禁用时,端点可以将自旋位设置为任何值,并且必须忽略任何传入的值。
建议端点将自旋位设置为随机值,或者为每个数据包独立选择,或者为每个连接 ID 独立选择。

If the spin bit is enabled for the connection, the endpoint maintains a spin value for each network path and sets the spin bit in the packet header to the currently stored value when a 1-RTT packet is sent on that path.
The spin value is initialized to 0 in the endpoint for each network path.
Each endpoint also remembers the highest packet number seen from its peer on each path.
如果为连接启用了自旋位,则端点为每个网络路径维护一个自旋值,并在该路径上发送 1-RTT 数据包时将数据包标头中的自旋位设置为当前存储的值。
在每个网络路径的端点中,自旋值被初始化为 0。
每个端点还记得在每条路径上从其对等点看到的最高数据包编号。

When a server receives a 1-RTT packet that increases the highest packet number seen by the server from the client on a given network path, it sets the spin value for that path to be equal to the spin bit in the received packet.
When a client receives a 1-RTT packet that increases the highest packet number seen by the client from the server on a given network path, it sets the spin value for that path to the inverse of the spin bit in the received packet.
An endpoint resets the spin value for a network path to 0 when changing the connection ID being used on that network path.
当服务器收到一个 1-RTT 数据包,该数据包增加了服务器在给定网络路径上从客户端看到的最高数据包编号,它将该路径的自旋值设置为等于接收到的数据包中的自旋位。
当客户端在给定的网络路径上接收到增加客户端从服务器看到的最高数据包编号的 1-RTT 数据包时,它将该路径的自旋值设置为接收到的数据包中自旋位的倒数。
当更改网络路径上使用的连接 ID 时,端点会将网络路径的自旋值重置为 0。

18. Transport Parameter Encoding

The extension_data field of the quic_transport_parameters extension
defined in [QUIC-TLS] contains the QUIC transport parameters. They
are encoded as a sequence of transport parameters, as shown in
Figure 20:

1
2
3
 Transport Parameters {
Transport Parameter (..) ...,
}
            Figure 20: Sequence of Transport Parameters

Each transport parameter is encoded as an (identifier, length, value)
tuple, as shown in Figure 21:

1
2
3
4
5
Transport Parameter {
Transport Parameter ID (i),
Transport Parameter Length (i),
Transport Parameter Value (..),
}
              Figure 21: Transport Parameter Encoding

The Transport Parameter Length field contains the length of the Transport Parameter Value field in bytes.
QUIC encodes transport parameters into a sequence of bytes, which is then included in the cryptographic handshake.
传输参数长度字段包含传输参数值字段的字节长度。
QUIC 将传输参数编码为字节序列,然后将其包含在加密握手中。

18.1. Reserved Transport Parameters

Transport parameters with an identifier of the form “31 * N + 27” for integer values of N are reserved to exercise the requirement that unknown transport parameters be ignored.
These transport parameters have no semantics and can carry arbitrary values.
对于 N 的整数值,具有“31 * N + 27”形式的标识符的传输参数被保留以执行忽略未知传输参数的要求。
这些传输参数没有语义,可以携带任意值。

18.2. Transport Parameter Definitions

This section details the transport parameters defined in this document.
本节详细介绍了本文档中定义的传输参数。

Many transport parameters listed here have integer values.
Those transport parameters that are identified as integers use a variable- length integer encoding; see Section 16.
Transport parameters have a default value of 0 if the transport parameter is absent, unless otherwise stated.
此处列出的许多传输参数具有整数值。
那些被标识为整数的传输参数使用可变长度整数编码; 见第 16 节。
如果传输参数不存在,则传输参数的默认值为 0,除非另有说明。

The following transport parameters are defined:定义了以下传输参数:

original_destination_connection_id (0x00): This parameter is the value of the Destination Connection ID field from the first Initial packet sent by the client; see Section 7.3.
This transport parameter is only sent by a server.
original_destination_connection_id (0x00):该参数是客户端发送的第一个Initial包中Destination Connection ID字段的值; 见第 7.3 节。
此传输参数仅由服务器发送。

max_idle_timeout (0x01): The maximum idle timeout is a value in milliseconds that is encoded as an integer; see (Section 10.1).
Idle timeout is disabled when both endpoints omit this transport parameter or specify a value of 0.
max_idle_timeout (0x01):最大空闲超时是一个以毫秒为单位的值,编码为整数; 见(第 10.1 节)。
当两个端点都省略此传输参数或指定值为 0 时,将禁用空闲超时。

stateless_reset_token (0x02): A stateless reset token is used in verifying a stateless reset; see Section 10.3.
This parameter is a sequence of 16 bytes.
This transport parameter MUST NOT be sent by a client but MAY be sent by a server.
A server that does not send this transport parameter cannot use stateless reset (Section 10.3) for the connection ID negotiated during the handshake.
stateless_reset_token (0x02):无状态重置令牌用于验证无状态重置; 见第 10.3 节。
该参数是一个 16 字节的序列。
这个传输参数不能由客户端发送,但可以由服务器发送。
不发送此传输参数的服务器不能对握手期间协商的连接 ID 使用无状态重置(第 10.3 节)。

max_udp_payload_size (0x03): The maximum UDP payload size parameter is an integer value that limits the size of UDP payloads that the endpoint is willing to receive.
UDP datagrams with payloads larger than this limit are not likely to be processed by the receiver.
max_udp_payload_size (0x03):最大 UDP 有效负载大小参数是一个整数值,用于限制端点愿意接收的 UDP 有效负载的大小。
有效负载大于此限制的 UDP 数据报不太可能被接收方处理。
The default for this parameter is the maximum permitted UDP payload of 65527.
Values below 1200 are invalid.此参数的默认值是允许的最大 UDP 有效负载 65527。
低于 1200 的值无效。
This limit does act as an additional constraint on datagram size in the same way as the path MTU, but it is a property of the endpoint and not the path; see Section 14.
It is expected that this is the space an endpoint dedicates to holding incoming packets.
这个限制确实像路径 MTU 一样作为对数据报大小的附加约束,但它是端点的属性,而不是路径的属性; 见第 14 节。
预计这是端点专用于保存传入数据包的空间。

initial_max_data (0x04): The initial maximum data parameter is an integer value that contains the initial value for the maximum amount of data that can be sent on the connection.
This is equivalent to sending a MAX_DATA (Section 19.9) for the connection immediately after completing the handshake.
initial_max_data (0x04):初始最大数据参数是一个整数值,包含可以在连接上发送的最大数据量的初始值。
这相当于在完成握手后立即为连接发送一个 MAX_DATA(第 19.9 节)。

initial_max_stream_data_bidi_local (0x05): This parameter is an integer value specifying the initial flow control limit for locally initiated bidirectional streams.
This limit applies to newly created bidirectional streams opened by the endpoint that sends the transport parameter.
In client transport parameters, this applies to streams with an identifier with the least significant two bits set to 0x00; in server transport parameters, this applies to streams with the least significant two bits set to 0x01.
initial_max_stream_data_bidi_local (0x05):此参数是一个整数值,指定本地发起的双向流的初始流量控制限制。
此限制适用于由发送传输参数的端点打开的新创建的双向流。
在客户端传输参数中,这适用于标识符的最低有效两位设置为 0x00 的流; 在服务器传输参数中,这适用于最低有效两位设置为 0x01 的流。

initial_max_stream_data_bidi_remote (0x06): This parameter is an integer value specifying the initial flow control limit for peer- initiated bidirectional streams.
This limit applies to newly created bidirectional streams opened by the endpoint that receives the transport parameter.
In client transport parameters, this applies to streams with an identifier with the least significant two bits set to 0x01; in server transport parameters, this applies to streams with the least significant two bits set to 0x00.
initial_max_stream_data_bidi_remote (0x06):此参数是一个整数值,指定对等发起的双向流的初始流量控制限制。
此限制适用于由接收传输参数的端点打开的新创建的双向流。
在客户端传输参数中,这适用于标识符的最低有效两位设置为 0x01 的流; 在服务器传输参数中,这适用于最低有效两位设置为 0x00 的流。

initial_max_stream_data_uni (0x07): This parameter is an integer value specifying the initial flow control limit for unidirectional streams.
This limit applies to newly created unidirectional streams opened by the endpoint that receives the transport parameter.
In client transport parameters, this applies to streams with an identifier with the least significant two bits set to 0x03; in server transport parameters, this applies to streams with the least significant two bits set to 0x02.
initial_max_stream_data_uni (0x07):此参数是一个整数值,指定单向流的初始流量控制限制。
此限制适用于由接收传输参数的端点打开的新创建的单向流。
在客户端传输参数中,这适用于标识符的最低有效两位设置为 0x03 的流; 在服务器传输参数中,这适用于最低有效两位设置为 0x02 的流。

initial_max_streams_bidi (0x08): The initial maximum bidirectional streams parameter is an integer value that contains the initial maximum number of bidirectional streams the endpoint that receives this transport parameter is permitted to initiate.
If this parameter is absent or zero, the peer cannot open bidirectional streams until a MAX_STREAMS frame is sent.
Setting this parameter is equivalent to sending a MAX_STREAMS (Section 19.11) of the corresponding type with the same value.
initial_max_streams_bidi (0x08):初始最大双向流参数是一个整数值,包含允许接收此传输参数的端点发起的双向流的初始最大数量。
如果此参数不存在或为零,则对等方无法打开双向流,直到发送 MAX_STREAMS 帧。
设置此参数相当于发送一个具有相同值的对应类型的 MAX_STREAMS(第 19.11 节)。

initial_max_streams_uni (0x09): The initial maximum unidirectional streams parameter is an integer value that contains the initial maximum number of unidirectional streams the endpoint that receives this transport parameter is permitted to initiate.
If this parameter is absent or zero, the peer cannot open unidirectional streams until a MAX_STREAMS frame is sent.
Setting this parameter is equivalent to sending a MAX_STREAMS (Section 19.11) of the corresponding type with the same value.
initial_max_streams_uni (0x09):初始最大单向流参数是一个整数值,包含允许接收此传输参数的端点发起的单向流的初始最大数量。
如果此参数不存在或为零,则对等方无法打开单向流,直到发送 MAX_STREAMS 帧。
设置此参数相当于发送一个具有相同值的对应类型的 MAX_STREAMS(第 19.11 节)。

ack_delay_exponent (0x0a): The acknowledgment delay exponent is an integer value indicating an exponent used to decode the ACK Delay field in the ACK frame (Section 19.3).
If this value is absent, a default value of 3 is assumed (indicating a multiplier of 8).
Values above 20 are invalid.
ack_delay_exponent (0x0a):确认延迟指数是一个整数值,指示用于解码 ACK 帧(第 19.3 节)中的 ACK 延迟字段的指数。
如果此值不存在,则假定默认值为 3(表示乘数为 8)。
大于 20 的值无效。

max_ack_delay (0x0b): The maximum acknowledgment delay is an integer value indicating the maximum amount of time in milliseconds by which the endpoint will delay sending acknowledgments.
This value SHOULD include the receiver’s expected delays in alarms firing.
For example, if a receiver sets a timer for 5ms and alarms commonly fire up to 1ms late, then it should send a max_ack_delay of 6ms.
If this value is absent, a default of 25 milliseconds is assumed.
Values of 2^14 or greater are invalid.
max_ack_delay (0x0b):最大确认延迟是一个整数值,表示端点将延迟发送确认的最大时间量(以毫秒为单位)。
这个值应该包括接收器在警报触发中的预期延迟。
例如,如果接收器将定时器设置为 5 毫秒,而警报通常延迟到 1 毫秒,那么它应该发送 6 毫秒的 max_ack_delay。
如果不存在此值,则假定默认值为 25 毫秒。
2^14 或更大的值无效。

disable_active_migration (0x0c): The disable active migration transport parameter is included if the endpoint does not support active connection migration (Section 9) on the address being used during the handshake.
An endpoint that receives this transport parameter MUST NOT use a new local address when sending to the address that the peer used during the handshake.
This transport parameter does not prohibit connection migration after a client has acted on a preferred_address transport parameter.
This parameter is a zero-length value.
disable_active_migration (0x0c):如果端点不支持在握手期间使用的地址上的主动连接迁移(第 9 节),则包括禁用主动迁移传输参数。
接收此传输参数的端点在向对等方在握手期间使用的地址发送时不得使用新的本地地址。
在客户端对首选地址传输参数执行操作后,此传输参数不会禁止连接迁移。
此参数是一个零长度值。

preferred_address (0x0d): 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.
This transport parameter is only sent by a server.
Servers MAY choose to only send a preferred address of one address family by sending an all-zero address and port (0.0.0.0:0 or [::]:0) for the other family.
IP addresses are encoded in network byte order.
preferred_address (0x0d):服务器的首选地址用于在握手结束时更改服务器地址,如第 9.6 节所述。
此传输参数仅由服务器发送。
服务器可以选择只发送一个地址系列的首选地址,方法是为另一个系列发送全零地址和端口(0.0.0.0:0 或 [::]:0)。
IP 地址以网络字节顺序编码。

  The preferred_address transport parameter contains an address and      port for both IPv4 and IPv6.

The four-byte IPv4 Address field is followed by the associated two-byte IPv4 Port field.
This is followed by a 16-byte IPv6 Address field and two-byte IPv6 Port field.
After address and port pairs, a Connection ID Length field describes the length of the following Connection ID field.
Finally, a 16-byte Stateless Reset Token field includes the stateless reset token associated with the connection ID.
The format of this transport parameter is shown in Figure 22 below.
preferred_address 传输参数包含 IPv4 和 IPv6 的地址和端口。
四字节 IPv4 地址字段后跟相关的两字节 IPv4 端口字段。
接下来是一个 16 字节的 IPv6 地址字段和两个字节的 IPv6 端口字段。
在地址和端口对之后,Connection ID Length 字段描述了后面的 Connection ID 字段的长度。
最后,一个 16 字节的无状态重置令牌字段包括与连接 ID 关联的无状态重置令牌。
该传输参数的格式如下图 22 所示。

  The Connection ID field and the Stateless Reset Token field      contain an alternative connection ID that has a sequence number of      1; see Section 5.1.1.  Having these values sent alongside the
  preferred address ensures that there will be at least one unused      active connection ID when the client initiates migration to the      preferred address.

Connection ID 字段和 Stateless Reset Token 字段包含一个序列号为 1 的替代连接 ID; 见第 5.1.1 节。 将这些值与
首选地址确保当客户端启动迁移到首选地址时,至少有一个未使用的活动连接 ID。

  The Connection ID and Stateless Reset Token fields of a preferred      address are identical in syntax and semantics to the corresponding      fields of a NEW_CONNECTION_ID frame (Section 19.15).

A server that chooses a zero-length connection ID MUST NOT provide a preferred address.
Similarly, a server MUST NOT include a zero- length connection ID in this transport parameter.
A client MUST treat a violation of these requirements as a connection error of type TRANSPORT_PARAMETER_ERROR.
首选地址的连接 ID 和无状态重置令牌字段在语法和语义上与 NEW_CONNECTION_ID 帧(第 19.15 节)的相应字段相同。
选择零长度连接 ID 的服务器不得提供首选地址。
类似地,服务器不得在此传输参数中包含长度为零的连接 ID。
客户端必须将违反这些要求视为 TRANSPORT_PARAMETER_ERROR 类型的连接错误。

1
2
3
4
5
6
7
8
9
  Preferred Address {
IPv4 Address (32),
IPv4 Port (16),
IPv6 Address (128),
IPv6 Port (16),
Connection ID Length (8),
Connection ID (..),
Stateless Reset Token (128),
}
                Figure 22: Preferred Address Format

active_connection_id_limit (0x0e): This is an integer value specifying the maximum number of connection IDs from the peer that an endpoint is willing to store.
This value includes the connection ID received during the handshake, that received in the preferred_address transport parameter, and those received in NEW_CONNECTION_ID frames.
The value of the active_connection_id_limit parameter MUST be at least 2.
An endpoint that receives a value less than 2 MUST close the connection with an error of type TRANSPORT_PARAMETER_ERROR.
If this transport parameter is absent, a default of 2 is assumed.
If an endpoint issues a zero-length connection ID, it will never send a NEW_CONNECTION_ID frame and therefore ignores the active_connection_id_limit value received from its peer.
active_connection_id_limit (0x0e):这是一个整数值,指定端点愿意存储的来自对等方的连接 ID 的最大数量。
此值包括在握手期间收到的连接 ID、在 preferred_address 传输参数中收到的连接 ID,以及在 NEW_CONNECTION_ID 帧中收到的连接 ID。
active_connection_id_limit 参数的值必须至少为 2。
接收到小于 2 的值的端点必须以 TRANSPORT_PARAMETER_ERROR 类型的错误关闭连接。
如果此传输参数不存在,则假定默认值为 2。
如果端点发出零长度的连接 ID,它将永远不会发送 NEW_CONNECTION_ID 帧,因此会忽略从其对等方接收到的 active_connection_id_limit 值。

initial_source_connection_id (0x0f): This is the value that the endpoint included in the Source Connection ID field of the first Initial packet it sends for the connection; see Section 7.3.
initial_source_connection_id (0x0f):这是端点包含在它为连接发送的第一个初始数据包的源连接 ID 字段中的值; 见第 7.3 节。

retry_source_connection_id (0x10): This is the value that the server included in the Source Connection ID field of a Retry packet; see Section 7.3.
This transport parameter is only sent by a server.
retry_source_connection_id (0x10):这是服务器包含在重试数据包的源连接 ID 字段中的值; 见第 7.3 节。
此传输参数仅由服务器发送。

If present, transport parameters that set initial per-stream 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.10) 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_stream_data_bidi_local、initial_max_stream_data_bidi_remote 和 initial_max_stream_data_uni)等效于在打开后立即在相应类型的每个流上发送 MAX_STREAM_DATA 帧(第 19.10 节)。
如果传输参数不存在,则该类型的流以流量控制限制 0 开始。
A client MUST NOT include any server-only transport parameter: original_destination_connection_id, preferred_address, retry_source_connection_id, or stateless_reset_token.
A server MUST treat receipt of any of these transport parameters as a connection error of type TRANSPORT_PARAMETER_ERROR.
客户端不得包含任何服务器专用传输参数:original_destination_connection_id、preferred_address、retry_source_connection_id 或 stateless_reset_token。
服务器必须将接收到这些传输参数中的任何一个视为 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.
如第 12.4 节所述,数据包包含一个或多个帧。
本节描述核心 QUIC 帧类型的格式和语义。

19.1. PADDING Frames

A 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 increase an Initial packet to the minimum required size or to provide protection against traffic analysis for protected packets.

PADDING frames are formatted as shown in Figure 23, which shows that PADDING frames have no content.
That is, a PADDING frame consists of the single byte that identifies the frame as a PADDING frame.
PADDING 帧(类型=0x00)没有语义值。
PADDING 帧可用于增加数据包的大小。
填充可用于将初始数据包增加到所需的最小大小或为受保护的数据包提供流量分析保护。

PADDING 帧的格式如图 23 所示,这表明 PADDING 帧没有内容。

也就是说,一个填充帧由一个字节组成,该字节将该帧标识为一个填充帧。

1
2
3
 PADDING Frame {
Type (i) = 0x00,
}
                  Figure 23: PADDING Frame Format
19.2. PING Frames

Endpoints can use PING frames (type=0x01) to verify that their peers are still alive or to check reachability to the peer.
端点可以使用 PING 帧 (type=0x01) 来验证其对等方是否仍然存在或检查对等方的可达性。
PING frames are formatted as shown in Figure 24, which shows that PING frames have no content.
PING 帧的格式如图 24 所示,这表明 PING 帧没有内容。

1
2
3
PING Frame {
Type (i) = 0x01,
}
                    Figure 24: PING Frame Format

The receiver of a PING frame simply needs to acknowledge the packet containing this frame.
PING 帧的接收者只需要确认包含该帧的数据包。
The PING frame can be used to keep a connection alive when an application or application protocol wishes to prevent the connection from timing out; see Section 10.1.2.
当应用程序或应用程序协议希望防止连接超时时,可以使用 PING 帧来保持连接处于活动状态; 见第 10.1.2 节。

19.3. ACK Frames

Receivers send ACK frames (types 0x02 and 0x03) to inform senders of packets they have received and processed.
The ACK frame contains one or more ACK Ranges.
ACK Ranges identify acknowledged packets.
If the frame type is 0x03, ACK frames also contain the cumulative count of QUIC packets with associated ECN marks received on the connection up until this point.
QUIC implementations MUST properly handle both types, and, if they have enabled ECN for packets they send, they SHOULD use the information in the ECN section to manage their congestion state.
接收方发送 ACK 帧(类型 0x02 和 0x03)以通知发送方他们已接收和处理的数据包。
ACK 帧包含一个或多个 ACK Ranges。
ACK 范围识别确认的数据包。
如果帧类型为 0x03,则 ACK 帧还包含 QUIC 数据包的累积计数,该数据包具有在此之前在连接上接收到的相关 ECN 标记。
QUIC 实现必须正确处理这两种类型,并且,如果他们为发送的数据包启用了 ECN,他们应该使用 ECN 部分中的信息来管理他们的拥塞状态。

QUIC acknowledgments are irrevocable.
Once acknowledged, a packet remains acknowledged, even if it does not appear in a future ACK frame.
This is unlike reneging for TCP Selective Acknowledgments (SACKs) [RFC2018].
QUIC 确认是不可撤销的。
一旦被确认,一个数据包仍然被确认,即使它没有出现在未来的 ACK 帧中。
这与对 TCP 选择性确认 (SACK) [RFC2018] 的违约不同。

Packets from different packet number spaces can be identified using the same numeric value.
An acknowledgment for a packet needs to indicate both a packet number and a packet number space.
This is accomplished by having each ACK frame only acknowledge packet numbers in the same space as the packet in which the ACK frame is contained.
可以使用相同的数值来识别来自不同包号空间的包。
一个包的确认需要同时指明一个包号和一个包号空间。
这是通过让每个 ACK 帧仅确认与包含 ACK 帧的数据包相同的空间中的数据包编号来实现的。

Version Negotiation and Retry packets cannot be acknowledged because they do not contain a packet number.
Rather than relying on ACK frames, these packets are implicitly acknowledged by the next Initial packet sent by the client.
版本协商和重试数据包无法确认,因为它们不包含数据包编号。
这些数据包不依赖于 ACK 帧,而是由客户端发送的下一个初始数据包隐式确认。

1
2
3
4
5
6
7
8
9
10
ACK frames are formatted as shown in Figure 25.
ACK Frame {
Type (i) = 0x02..0x03,
Largest Acknowledged (i),
ACK Delay (i),
ACK Range Count (i),
First ACK Range (i),
ACK Range (..) ...,
[ECN Counts (..)],
}
                    Figure 25: ACK Frame Format

ACK frames contain the following fields:
Largest Acknowledged: A variable-length integer representing the largest packet number the peer is acknowledging; this is usually the largest packet number that the peer has received prior to generating the ACK frame.
Unlike the packet number in the QUIC long or short header, the value in an ACK frame is not truncated.
ACK 帧包含以下字段:
Largest Acknowledged:一个可变长度整数,表示对等方正在确认的最大数据包号; 这通常是对等方在生成 ACK 帧之前收到的最大数据包编号。
与 QUIC 长或短标头中的数据包编号不同,ACK 帧中的值不会被截断。

ACK Delay: A variable-length integer encoding the acknowledgment delay in microseconds; see Section 13.2.5.
It is decoded by multiplying the value in the field by 2 to the power of the ack_delay_exponent transport parameter sent by the sender of the ACK frame; see Section 18.2.
Compared to simply expressing the delay as an integer, this encoding allows for a larger range of values within the same number of bytes, at the cost of lower resolution.
ACK Delay:一个可变长度整数,以微秒为单位编码确认延迟; 见第 13.2.5 节。
它是通过将字段中的值乘以 2 乘以 ACK 帧的发送方发送的 ack_delay_exponent 传输参数的幂来解码的; 见第 18.2 节。
与简单地将延迟表示为整数相比,这种编码允许在相同字节数内有更大范围的值,但代价是分辨率较低。

ACK Range Count: A variable-length integer specifying the number of ACK Range fields in the frame.
ACK Range Count:一个可变长度整数,指定帧中 ACK Range 字段的数量。

First ACK Range: A variable-length integer indicating the number of contiguous packets preceding the Largest Acknowledged that are being acknowledged.
That is, the smallest packet acknowledged in the range is determined by subtracting the First ACK Range value from the Largest Acknowledged field.
第一个 ACK 范围:一个可变长度整数,指示正在确认的最大确认之前的连续数据包的数量。
也就是说,在该范围内确认的最小数据包是通过从最大确认字段中减去 First ACK Range 值来确定的。

ACK Ranges: Contains additional ranges of packets that are alternately not acknowledged (Gap) and acknowledged (ACK Range); see Section 19.3.1.
ACK Ranges:包含交替未确认(Gap)和确认(ACK Range)的数据包的附加范围; 见第 19.3.1 节。

ECN Counts: The three ECN counts; see Section 19.3.2.
ECN Counts:三个 ECN 计数; 见第 19.3.2 节。

19.3.1. ACK Ranges

Each ACK Range consists of alternating Gap and ACK Range Length values in descending packet number order.
ACK Ranges can be repeated.
The number of Gap and ACK Range Length values is determined by the ACK Range Count field; one of each value is present for each value in the ACK Range Count field.
每个 ACK Range 由交替的 Gap 和 ACK Range Length 值组成,按数据包编号降序排列。
ACK 范围可以重复。
Gap 和 ACK Range Length 值的数量由 ACK Range Count 字段确定; ACK Range Count 字段中的每个值都存在每个值之一。

1
2
3
4
5
ACK Ranges are structured as shown in Figure 26.
ACK Range {
Gap (i),
ACK Range Length (i),
}
                       Figure 26: ACK Ranges

The fields that form each ACK Range are:
Gap: A variable-length integer indicating the number of contiguous unacknowledged packets preceding the packet number one lower than the smallest in the preceding ACK Range.
构成每个 ACK 范围的字段是:
Gap:一个可变长度整数,指示在比前一个 ACK 范围中的最小值低一号的数据包之前的连续未确认数据包的数量。
ACK Range Length: A variable-length integer indicating the number of contiguous acknowledged packets preceding the largest packet number, as determined by the preceding Gap.
ACK Range Length:一个可变长度整数,指示在最大数据包编号之前的连续确认数据包的数量,由前面的 Gap 确定。
Gap and ACK Range Length values use a relative integer encoding for efficiency.
Though each encoded value is positive, the values are subtracted, so that each ACK Range describes progressively lower- numbered packets.
Gap 和 ACK Range Length 值使用相对整数编码来提高效率。
尽管每个编码值都是正数,但会减去这些值,以便每个 ACK 范围描述逐渐降低编号的数据包。

Each ACK Range acknowledges a contiguous range of packets by indicating the number of acknowledged packets that precede the largest packet number in that range.
A value of 0 indicates that only the largest packet number is acknowledged.
Larger ACK Range values indicate a larger range, with corresponding lower values for the smallest packet number in the range.
Thus, given a largest packet number for the range, the smallest value is determined by the following formula:
smallest = largest - ack_range
An ACK Range acknowledges all packets between the smallest packet number and the largest, inclusive.
每个 ACK 范围通过指示在该范围内最大数据包编号之前的已确认数据包的数量来确认连续的数据包范围。
值 0 表示仅确认最大的数据包编号。
较大的 ACK Range 值表示较大的范围,相应的较低值表示该范围内的最小数据包编号。
因此,给定范围的最大数据包编号,最小值由以下公式确定:
最小 = 最大 - ack_range
一个 ACK Range 确认最小包号和最大包号之间的所有包。

The largest value for an ACK Range is determined by cumulatively subtracting the size of all preceding ACK Range Lengths and Gaps.
ACK 范围的最大值是通过累积减去所有前面的 ACK 范围长度和间隙的大小来确定的。

Each Gap indicates a range of packets that are not being acknowledged.
The number of packets in the gap is one higher than the encoded value of the Gap field.
每个 Gap 表示未确认的数据包范围。
间隙中的数据包数量比 Gap 字段的编码值高 1。

The value of the Gap field establishes the largest packet number value for the subsequent ACK Range using the following formula:
largest = previous_smallest - gap - 2
If any computed packet number is negative, an endpoint MUST generate a connection error of type FRAME_ENCODING_ERROR.
Gap 字段的值使用以下公式确定后续 ACK Range 的最大数据包编号值:
最大 = previous_smallest - 差距 - 2
如果任何计算的数据包编号为负,端点必须生成 FRAME_ENCODING_ERROR 类型的连接错误。

19.3.2. ECN Counts

The ACK frame uses the least significant bit of the type value (that is, type 0x03) to indicate ECN feedback and report receipt of QUIC packets with associated ECN codepoints of ECT(0), ECT(1), or ECN-CE in the packet’s IP header.
ECN counts are only present when the ACK frame type is 0x03.
ACK 帧使用类型值的最低有效位(即类型 0x03)来指示 ECN 反馈,并报告接收到的 QUIC 数据包的相关 ECN 代码点为 ECT(0)、ECT(1) 或 ECN-CE。 数据包的IP头。
ECN 计数仅在 ACK 帧类型为 0x03 时出现。

1
2
3
4
5
6
When present, there are three ECN counts, as shown in Figure 27.
ECN Counts {
ECT0 Count (i),
ECT1 Count (i),
ECN-CE Count (i),
}
                    Figure 27: ECN Count Format

The ECN count fields are:
ECT0 Count: A variable-length integer representing the total number of packets received with the ECT(0) codepoint in the packet number space of the ACK frame.
ECT1 Count: A variable-length integer representing the total number of packets received with the ECT(1) codepoint in the packet number space of the ACK frame.
ECN-CE Count: A variable-length integer representing the total number of packets received with the ECN-CE codepoint in the packet number space of the ACK frame.
ECN counts are maintained separately for each packet number space.
ECN 计数字段为:
ECT0 计数:一个可变长度整数,表示在 ACK 帧的数据包编号空间中使用 ECT(0) 代码点接收到的数据包总数。
ECT1 计数:一个可变长度整数,表示在 ACK 帧的数据包编号空间中使用 ECT(1) 代码点接收到的数据包总数。
ECN-CE 计数:一个可变长度整数,表示在 ACK 帧的数据包编号空间中使用 ECN-CE 代码点接收到的数据包总数。
ECN 计数为每个数据包编号空间单独维护。

19.4. RESET_STREAM Frames

An endpoint uses a RESET_STREAM frame (type=0x04) to abruptly terminate the sending part of a stream.
端点使用 RESET_STREAM 帧(类型=0x04)突然终止流的发送部分。
After sending a RESET_STREAM, an endpoint ceases transmission and retransmission of STREAM frames on the identified stream.
A receiver of RESET_STREAM can discard any data that it already received on that stream.
发送 RESET_STREAM 后,端点停止在识别的流上传输和重传 STREAM 帧。
RESET_STREAM 的接收者可以丢弃它已经在该流上接收到的任何数据。

An endpoint that receives a RESET_STREAM frame for a send-only stream MUST terminate the connection with error STREAM_STATE_ERROR.
为只发送流接收 RESET_STREAM 帧的端点必须以错误 STREAM_STATE_ERROR 终止连接。

1
2
3
4
5
6
7
RESET_STREAM frames are formatted as shown in Figure 28.
RESET_STREAM Frame {
Type (i) = 0x04,
Stream ID (i),
Application Protocol Error Code (i),
Final Size (i),
}
                Figure 28: RESET_STREAM Frame Format

RESET_STREAM frames contain the following fields:
Stream ID: A variable-length integer encoding of the stream ID of the stream being terminated.
Application Protocol Error Code: A variable-length integer containing the application protocol error code (see Section 20.2) that indicates why the stream is being closed.
Final Size: A variable-length integer indicating the final size of the stream by the RESET_STREAM sender, in units of bytes; see Section 4.5.
RESET_STREAM 帧包含以下字段:
流 ID:被终止流的流 ID 的可变长度整数编码。
应用程序协议错误代码:一个可变长度整数,包含应用程序协议错误代码(参见第 20.2 节),指示关闭流的原因。
Final Size:一个变长整数,表示RESET_STREAM发送方流的最终大小,以字节为单位; 见第 4.5 节。

19.5. STOP_SENDING Frames

An endpoint uses a STOP_SENDING frame (type=0x05) to communicate that incoming data is being discarded on receipt per application request.
STOP_SENDING requests that a peer cease transmission on a stream.
端点使用 STOP_SENDING 帧(类型 = 0x05)来传达传入数据在收到每个应用程序请求时被丢弃。
STOP_SENDING 请求对等端停止流上的传输。

A STOP_SENDING frame can be sent for streams in the “Recv” or “Size Known” states; see Section 3.2.
Receiving a STOP_SENDING frame for a locally initiated stream that has not yet been created MUST be treated as a connection error of type STREAM_STATE_ERROR.
An endpoint that receives a STOP_SENDING frame for a receive-only stream MUST terminate the connection with error STREAM_STATE_ERROR.
可以为“Recv”或“Size Known”状态的流发送 STOP_SENDING 帧; 见第 3.2 节。
接收到尚未创建的本地启动流的 STOP_SENDING 帧必须被视为 STREAM_STATE_ERROR 类型的连接错误。
为只接收流接收 STOP_SENDING 帧的端点必须以错误 STREAM_STATE_ERROR 终止连接。

1
2
3
4
5
6
STOP_SENDING frames are formatted as shown in Figure 29.
STOP_SENDING Frame {
Type (i) = 0x05,
Stream ID (i),
Application Protocol Error Code (i),
}
                Figure 29: STOP_SENDING Frame Format

STOP_SENDING frames contain the following fields:
Stream ID: A variable-length integer carrying the stream ID of the stream being ignored.
STOP_SENDING 帧包含以下字段:
流 ID:一个可变长度整数,携带被忽略的流的流 ID。
Application Protocol Error Code: A variable-length integer containing the application-specified reason the sender is ignoring the stream; see Section 20.2.
应用程序协议错误代码:一个可变长度整数,包含应用程序指定的发送方忽略流的原因; 见第 20.2 节。

19.6. CRYPTO Frames

A CRYPTO frame (type=0x06) is used to transmit cryptographic handshake messages.
It can be sent in all packet types except 0-RTT.
The CRYPTO frame offers the cryptographic protocol an in-order stream of bytes.
CRYPTO frames are functionally identical to STREAM frames, except that they do not bear a stream identifier; they are not flow controlled; and they do not carry markers for optional offset, optional length, and the end of the stream.
CRYPTO 帧(类型=0x06)用于传输加密握手消息。
它可以在除 0-RTT 之外的所有数据包类型中发送。
CRYPTO 帧为加密协议提供了一个有序的字节流。
CRYPTO 帧在功能上与 STREAM 帧相同,只是它们不带有流标识符; 它们不受流量控制; 并且它们不携带可选偏移量、可选长度和流结尾的标记。
CRYPTO frames are formatted as shown in Figure 30.

1
2
3
4
5
6
 CRYPTO Frame {
Type (i) = 0x06,
Offset (i),
Length (i),
Crypto Data (..),
}
                   Figure 30: CRYPTO Frame Format

CRYPTO frames contain the following fields:
Offset: A variable-length integer specifying the byte offset in the stream for the data in this CRYPTO frame.
CRYPTO 帧包含以下字段:
偏移量:一个可变长度整数,指定此 CRYPTO 帧中的数据在流中的字节偏移量。

Length: A variable-length integer specifying the length of the Crypto Data field in this CRYPTO frame.
长度:一个可变长度整数,指定此 CRYPTO 帧中加密数据字段的长度。
Crypto Data: The cryptographic message data.

There is a separate flow of cryptographic handshake data in each encryption level, each of which starts at an offset of 0.
This implies that each encryption level is treated as a separate CRYPTO stream of data.
每个加密级别都有单独的加密握手数据流,每个加密握手数据都从偏移量 0 开始。
这意味着每个加密级别都被视为单独的 CRYPTO 数据流。
The largest offset delivered on a stream – the sum of the offset and data length – cannot exceed 2^62-1.
Receipt of a frame that exceeds this limit MUST be treated as a connection error of type FRAME_ENCODING_ERROR or CRYPTO_BUFFER_EXCEEDED.
流上传递的最大偏移量——偏移量和数据长度之和——不能超过 2^62-1。
接收超过此限制的帧必须被视为 FRAME_ENCODING_ERROR 或 CRYPTO_BUFFER_EXCEEDED 类型的连接错误。
Unlike STREAM frames, which include a stream ID indicating to which stream the data belongs, the CRYPTO frame carries data for a single stream per encryption level.
The stream does not have an explicit end, so CRYPTO frames do not have a FIN bit.
与包含指示数据属于哪个流的流 ID 的 STREAM 帧不同,CRYPTO 帧携带每个加密级别的单个流的数据。
流没有明确的结束,因此 CRYPTO 帧没有 FIN 位。

19.7. NEW_TOKEN Frames

A server sends a NEW_TOKEN frame (type=0x07) to provide the client with a token to send in the header of an Initial packet for a future connection.
服务器发送 NEW_TOKEN 帧 (type=0x07) 以向客户端提供令牌,以便在初始数据包的标头中发送以用于将来的连接。
NEW_TOKEN frames are formatted as shown in Figure 31.

1
2
3
4
5
6
NEW_TOKEN Frame {
Type (i) = 0x07,
Token Length (i),
Token (..),
}
Figure 31: NEW_TOKEN Frame Format

NEW_TOKEN frames contain the following fields:
Token Length: A variable-length integer specifying the length of the token in bytes.

Token: An opaque blob that the client can use with a future Initial packet.
The token MUST NOT be empty.
A client MUST treat receipt of a NEW_TOKEN frame with an empty Token field as a connection error of type FRAME_ENCODING_ERROR.
客户端必须将接收到带有空 Token 字段的 NEW_TOKEN 帧视为 FRAME_ENCODING_ERROR 类型的连接错误。
A client might receive multiple NEW_TOKEN frames that contain the same token value if packets containing the frame are incorrectly determined to be lost.
Clients are responsible for discarding duplicate values, which might be used to link connection attempts; see Section 8.1.3.
如果包含帧的数据包被错误地确定为丢失,则客户端可能会收到多个包含相同令牌值的 NEW_TOKEN 帧。
客户端负责丢弃可能用于链接连接尝试的重复值; 见第 8.1.3 节。
Clients MUST NOT send NEW_TOKEN frames.
A server MUST treat receipt of a NEW_TOKEN frame as a connection error of type PROTOCOL_VIOLATION.
客户端不得发送 NEW_TOKEN 帧。
服务器必须将接收到 NEW_TOKEN 帧视为 PROTOCOL_VIOLATION 类型的连接错误。

19.8. STREAM Frames

STREAM frames implicitly create a stream and carry stream data.
The Type field in the STREAM frame takes the form 0b00001XXX (or the set of values from 0x08 to 0x0f).
The three low-order bits of the frame type determine the fields that are present in the frame:
STREAM 帧隐式创建流并携带流数据。
STREAM 帧中的类型字段采用 0b00001XXX 的形式(或从 0x08 到 0x0f 的一组值)。
帧类型的三个低位确定帧中存在的字段:

  • 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 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 first bytes of the stream, or the end of a stream that includes no data).

  • 帧类型中的 OFF 位 (0x04) 设置为指示存在偏移字段。
    设置为 1 时,存在偏移字段。
    当设置为 0 时,偏移字段不存在并且流数据从偏移量 0 开始(即,帧包含流的第一个字节,或不包含数据的流的结尾)。

    • The LEN bit (0x02) in the frame type is set to indicate that there is a Length field present.
      If this bit is set to 0, the Length field is absent and the Stream Data field extends to the end of the packet.
      If this bit is set to 1, the Length field is present.
  • 帧类型中的 LEN 位 (0x02) 设置为指示存在长度字段。
    如果该位设置为 0,则长度字段不存在,流数据字段延伸到数据包的末尾。
    如果该位设置为 1,则存在长度字段。

    • The FIN bit (0x01) indicates that the frame marks the end of the stream.
      The final size of the stream is the sum of the offset and the length of this frame.
  • FIN 位(0x01)表示该帧标志着流的结束。
    流的最终大小是偏移量和该帧长度的总和。

    An endpoint MUST terminate the connection with error STREAM_STATE_ERROR if it receives a STREAM frame for a locally initiated stream that has not yet been created, or for a send-only stream.

如果端点接收到一个尚未创建的本地启动流或仅发送流的 STREAM 帧,则端点必须以错误 STREAM_STATE_ERROR 终止连接。
STREAM frames are formatted as shown in Figure 32.

1
2
3
4
5
6
7
STREAM Frame {
Type (i) = 0x08..0x0f,
Stream ID (i),
[Offset (i)],
[Length (i)],
Stream Data (..),
}

Figure 32: STREAM Frame Format
STREAM frames contain the following fields:
Stream ID: A variable-length integer indicating the stream ID of the stream; see Section 2.1.

Offset: A variable-length integer specifying the byte offset in the 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, the offset is 0.
偏移量:一个可变长度整数,指定此 STREAM 帧中的数据在流中的字节偏移量。
该字段在 OFF 位设置为 1 时出现。
当 Offset 字段不存在时,偏移量为 0。

Length: A variable-length integer specifying the length of the 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 Stream Data field consumes all the remaining bytes in the packet.
长度:一个可变长度整数,指定此 STREAM 帧中流数据字段的长度。
当 LEN 位设置为 1 时,该字段出现。
当 LEN 位设置为 0 时,流数据字段会消耗数据包中的所有剩余字节。

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 frame is the offset of the next byte that would be sent.
当流数据字段的长度为 0 时,STREAM 帧中的偏移量就是将要发送的下一个字节的偏移量。
The first byte in the stream has an offset of 0.
The largest offset delivered on a stream – the sum of the offset and data length – cannot exceed 2^62-1, as it is not possible to provide flow control credit for that data.
Receipt of a frame that exceeds this limit MUST be treated as a connection error of type FRAME_ENCODING_ERROR or FLOW_CONTROL_ERROR.
流中的第一个字节的偏移量为 0。
流上传递的最大偏移量(偏移量和数据长度之和)不能超过 2^62-1,因为无法为该数据提供流控制信用。
收到超过此限制的帧必须被视为 FRAME_ENCODING_ERROR 或 FLOW_CONTROL_ERROR 类型的连接错误。

19.9. MAX_DATA Frames

A MAX_DATA frame (type=0x10) is used in flow control to inform the peer of the maximum amount of data that can be sent on the connection as a whole.
MAX_DATA 帧(类型=0x10)用于流控制,以通知对等方可以在整个连接上发送的最大数据量。
MAX_DATA frames are formatted as shown in Figure 33.

1
2
3
4
MAX_DATA Frame {
Type (i) = 0x10,
Maximum Data (i),
}
                  Figure 33: MAX_DATA Frame Format

MAX_DATA frames contain the following field:
Maximum Data: A variable-length integer indicating the maximum amount of data that can be sent on the entire connection, in units of bytes.
MAX_DATA 帧包含以下字段:
最大数据:一个可变长度整数,表示在整个连接上可以发送的最大数据量,以字节为单位。
All data sent in STREAM frames counts toward this limit.
The sum of the final sizes on all streams – including streams in terminal states – MUST NOT exceed the value advertised by a receiver.
An endpoint MUST terminate a connection with an error of type FLOW_CONTROL_ERROR if it receives more data than the maximum data value that it has sent.
This includes violations of remembered limits in Early Data; see Section 7.4.1.
在 STREAM 帧中发送的所有数据都计入此限制。
所有流的最终大小的总和——包括终端状态的流——不得超过接收者通告的值。
如果端点接收到的数据多于它已发送的最大数据值,则端点必须以 FLOW_CONTROL_ERROR 类型的错误终止连接。
这包括违反早期数据中记住的限制; 请参见第 7.4.1 节。

19.10. MAX_STREAM_DATA Frames

A MAX_STREAM_DATA frame (type=0x11) is used in flow control to inform a peer of the maximum amount of data that can be sent on a stream.
MAX_STREAM_DATA 帧(类型=0x11)用于流控制,以通知对等方可以在流上发送的最大数据量。

A MAX_STREAM_DATA frame can be sent for streams in the “Recv” state; see Section 3.2.
Receiving a MAX_STREAM_DATA frame for a locally initiated stream that has not yet been created MUST be treated as a connection error of type STREAM_STATE_ERROR.
An endpoint that receives a MAX_STREAM_DATA frame for a receive-only stream MUST terminate the connection with error STREAM_STATE_ERROR.
可以为“Recv”状态的流发送 MAX_STREAM_DATA 帧; 见第 3.2 节。
为尚未创建的本地启动流接收 MAX_STREAM_DATA 帧必须被视为 STREAM_STATE_ERROR 类型的连接错误。
为只接收流接收 MAX_STREAM_DATA 帧的端点必须以错误 STREAM_STATE_ERROR 终止连接。

1
2
3
4
5
6
  MAX_STREAM_DATA frames are formatted as shown in Figure 34.
MAX_STREAM_DATA Frame {
Type (i) = 0x11,
Stream ID (i),
Maximum Stream Data (i),
}
              Figure 34: MAX_STREAM_DATA Frame Format

MAX_STREAM_DATA frames contain the following fields:
Stream ID: The stream ID of the affected stream, encoded as a variable-length integer.
MAX_STREAM_DATA 帧包含以下字段:
流 ID:受影响流的流 ID,编码为变长整数。
Maximum Stream Data: A variable-length integer indicating the maximum amount of data that can be sent on the identified stream, in units of bytes.
最大流数据:一个可变长度整数,指示可以在识别的流上发送的最大数据量,以字节为单位。
When counting data toward this limit, an endpoint accounts for the largest received offset of data that is sent or received on the 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 that stream.
Receiving STREAM frames might not increase the largest received offset.
当向此限制计数数据时,端点会考虑在流上发送或接收的数据的最大接收偏移量。
丢失或重新排序可能意味着流上接收到的最大偏移量可能大于该流上接收到的数据的总大小。
接收 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 connection with an error of type FLOW_CONTROL_ERROR if it receives more data than the largest maximum stream data that it has sent for the affected stream.
This includes violations of remembered limits in Early Data; see Section 7.4.1.
在流上发送的数据不得超过接收方通告的最大最大流数据值。
如果端点接收到的数据多于它为受影响的流发送的最大最大流数据,则端点必须以 FLOW_CONTROL_ERROR 类型的错误终止连接。
这包括违反早期数据中记住的限制; 请参见第 7.4.1 节。

19.11. MAX_STREAMS Frames

A MAX_STREAMS frame (type=0x12 or 0x13) informs the peer of the cumulative number of streams of a given type it is permitted to open.
A MAX_STREAMS frame with a type of 0x12 applies to bidirectional streams, and a MAX_STREAMS frame with a type of 0x13 applies to unidirectional streams.
MAX_STREAMS 帧(类型=0x12 或 0x13)通知对等方允许打开的给定类型的流的累积数量。
类型为 0x12 的 MAX_STREAMS 帧适用于双向流,类型为 0x13 的 MAX_STREAMS 帧适用于单向流。
MAX_STREAMS frames are formatted as shown in Figure 35.

1
2
3
4
MAX_STREAMS Frame {
Type (i) = 0x12..0x13,
Maximum Streams (i),
}
                Figure 35: MAX_STREAMS Frame Format

MAX_STREAMS frames contain the following field:
Maximum Streams: A count of the cumulative number of streams of the corresponding type that can be opened over the lifetime of the connection.
This value cannot exceed 2^60, as it is not possible to encode stream IDs larger than 2^62-1.
Receipt of a frame that permits opening of a stream larger than this limit MUST be treated as a connection error of type FRAME_ENCODING_ERROR.
MAX_STREAMS 帧包含以下字段:
最大流数:在连接的生命周期内可以打开的相应类型的流的累积数量。
此值不能超过 2^60,因为无法对大于 2^62-1 的流 ID 进行编码。
接收到允许打开大于此限制的流的帧必须被视为 FRAME_ENCODING_ERROR 类型的连接错误。

Loss or reordering can cause an endpoint to receive a MAX_STREAMS frame with a lower stream limit than was previously received.
MAX_STREAMS frames that do not increase the stream limit MUST be ignored.
丢失或重新排序可能会导致端点接收到 MAX_STREAMS 帧,其流限制比以前接收的要低。
必须忽略不增加流限制的 MAX_STREAMS 帧。
An endpoint MUST NOT open more streams than permitted by the current stream limit set by its peer.
For instance, a server that receives a unidirectional stream limit of 3 is permitted to open streams 3, 7, and 11, but not stream 15.
An endpoint MUST terminate a connection with an error of type STREAM_LIMIT_ERROR if a peer opens more streams than was permitted.
This includes violations of remembered limits in Early Data; see Section 7.4.1.
端点不能打开比其对等点设置的当前流限制所允许的更多的流。
例如,接收到单向流限制 3 的服务器被允许打开流 3、7 和 11,但不能打开流 15。
如果对等点打开的流比允许的多,端点必须终止连接并返回类型为 STREAM_LIMIT_ERROR 的错误。
这包括违反早期数据中记住的限制; 请参见第 7.4.1 节。
Note that these frames (and the corresponding transport parameters) do not describe the number of streams that can be opened concurrently.
The limit includes streams that have been closed as well as those that are open.
请注意,这些帧(以及相应的传输参数)并未描述可以同时打开的流的数量。
该限制包括已关闭的流和打开的流。

19.12. DATA_BLOCKED Frames

A sender SHOULD send a DATA_BLOCKED frame (type=0x14) when it wishes to send data but is unable to do so due to connection-level flow control; see Section 4.
DATA_BLOCKED frames can be used as input to tuning of flow control algorithms; see Section 4.2.
当发送者希望发送数据但由于连接级别的流量控制而无法发送时,发送者应该发送一个 DATA_BLOCKED 帧(类型=0x14); 见第 4 节。
DATA_BLOCKED 帧可用作流控制算法调整的输入; 见第 4.2 节。

DATA_BLOCKED frames are formatted as shown in Figure 36.

1
2
3
4
5
  
DATA_BLOCKED Frame {
Type (i) = 0x14,
Maximum Data (i),
}
                Figure 36: DATA_BLOCKED Frame Format

DATA_BLOCKED frames contain the following field:
Maximum Data: A variable-length integer indicating the connection- level limit at which blocking occurred.
DATA_BLOCKED 帧包含以下字段:
最大数据:一个可变长度整数,指示发生阻塞的连接级别限制。

19.13. STREAM_DATA_BLOCKED Frames

A sender SHOULD send a STREAM_DATA_BLOCKED frame (type=0x15) when it wishes to send data but is unable to do so due to stream-level flow control.
This frame is analogous to DATA_BLOCKED (Section 19.12).
当发送者希望发送数据但由于流级流量控制而无法发送时,它应该发送一个 STREAM_DATA_BLOCKED 帧(类型=0x15)。
此帧类似于 DATA_BLOCKED(第 19.12 节)。
An endpoint that receives a STREAM_DATA_BLOCKED frame for a send-only stream MUST terminate the connection with error STREAM_STATE_ERROR.
对只发送流的,却接收 STREAM_DATA_BLOCKED 帧的端点必须终止连接并返回错误 STREAM_STATE_ERROR。
STREAM_DATA_BLOCKED frames are formatted as shown in Figure 37.

1
2
3
4
5
  STREAM_DATA_BLOCKED Frame {
Type (i) = 0x15,
Stream ID (i),
Maximum Stream Data (i),
}
            Figure 37: STREAM_DATA_BLOCKED Frame Format

STREAM_DATA_BLOCKED frames contain the following fields:
Stream ID: A variable-length integer indicating the stream that is blocked due to flow control.

Maximum Stream Data: A variable-length integer indicating the offset of the stream at which the blocking occurred.
最大流数据:一个可变长度整数,指示发生阻塞的流的偏移量。

19.14. STREAMS_BLOCKED Frames

A sender SHOULD send a STREAMS_BLOCKED frame (type=0x16 or 0x17) when it wishes to open a stream but is unable to do so due to the maximum stream limit set by its peer; see Section 19.11.
A STREAMS_BLOCKED frame of type 0x16 is used to indicate reaching the bidirectional stream limit, and a STREAMS_BLOCKED frame of type 0x17 is used to indicate reaching the unidirectional stream limit.
当发送者希望打开一个流但由于其对等方设置的最大流限制而无法这样做时,它应该发送一个 STREAMS_BLOCKED 帧(类型=0x16 或 0x17); 见第 19.11 节。
类型为 0x16 的 STREAMS_BLOCKED 帧用于指示达到双向流限制,类型为 0x17 的 STREAMS_BLOCKED 帧用于指示达到单向流限制。
A STREAMS_BLOCKED frame does not open the stream, but informs the peer that a new stream was needed and the stream limit prevented the creation of the stream.
STREAMS_BLOCKED 帧不会打开流,但会通知对等方需要新流并且流限制阻止了流的创建。
STREAMS_BLOCKED frames are formatted as shown in Figure 38.

1
2
3
4
STREAMS_BLOCKED Frame {
Type (i) = 0x16..0x17,
Maximum Streams (i),
}
              Figure 38: STREAMS_BLOCKED Frame Format

STREAMS_BLOCKED frames contain the following field:
Maximum Streams: A variable-length integer indicating the maximum number of streams allowed at the time the frame was sent.
This value cannot exceed 2^60, as it is not possible to encode stream IDs larger than 2^62-1.
Receipt of a frame that encodes a larger stream ID MUST be treated as a connection error of type STREAM_LIMIT_ERROR or FRAME_ENCODING_ERROR.
STREAMS_BLOCKED 帧包含以下字段:
最大流数:一个可变长度整数,指示发送帧时允许的最大流数。
此值不能超过 2^60,因为无法对大于 2^62-1 的流 ID 进行编码。
接收到编码较大流 ID 的帧必须被视为 STREAM_LIMIT_ERROR 或 FRAME_ENCODING_ERROR 类型的连接错误。

19.15. NEW_CONNECTION_ID Frames

An endpoint sends a NEW_CONNECTION_ID frame (type=0x18) to provide its peer with alternative connection IDs that can be used to break linkability when migrating connections; see Section 9.5.
端点发送 NEW_CONNECTION_ID 帧 (type=0x18) 为其对等方提供可用于在迁移连接时破坏可链接性的替代连接 ID; 见第 9.5 节。
NEW_CONNECTION_ID frames are formatted as shown in Figure 39.

1
2
3
4
5
6
7
8
NEW_CONNECTION_ID Frame {
Type (i) = 0x18,
Sequence Number (i),
Retire Prior To (i),
Length (8),
Connection ID (8..160),
Stateless Reset Token (128),
}
             Figure 39: NEW_CONNECTION_ID Frame Format

NEW_CONNECTION_ID frames contain the following fields:
Sequence Number: The sequence number assigned to the connection ID by the sender, encoded as a variable-length integer; see Section 5.1.1.
NEW_CONNECTION_ID 帧包含以下字段:
序号:发送方分配给连接ID的序号,编码为变长整数; 见第 5.1.1 节。
Retire Prior To: A variable-length integer indicating which connection IDs should be retired; see Section 5.1.2.
Length: An 8-bit unsigned integer containing the length of the connection ID.
Values less than 1 and greater than 20 are invalid and MUST be treated as a connection error of type FRAME_ENCODING_ERROR.
Retire Prior To:一个可变长度的整数,指示哪些连接 ID 应该被淘汰; 见第 5.1.2 节。
长度:一个 8 位无符号整数,包含连接 ID 的长度。
小于 1 和大于 20 的值是无效的,必须被视为 FRAME_ENCODING_ERROR 类型的连接错误。

Connection ID: A connection ID of the specified length.

Stateless Reset Token: A 128-bit value that will be used for a stateless reset when the associated connection ID is used; see Section 10.3.

An endpoint MUST NOT send this frame if it currently requires that its peer send packets with a zero-length Destination Connection ID.
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.
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 error of type PROTOCOL_VIOLATION.
如果端点当前要求其对等方发送具有零长度目标连接 ID 的数据包,则端点不得发送此帧。
将连接 ID 的长度更改为零长度或从零长度更改使得很难识别连接 ID 的值何时更改。
发送具有零长度目标连接 ID 的数据包的端点必须将接收到 NEW_CONNECTION_ID 帧视为 PROTOCOL_VIOLATION 类型的连接错误。

Transmission errors, timeouts, and retransmissions might cause the same NEW_CONNECTION_ID frame to be received multiple times.
Receipt of the same frame multiple times MUST NOT be treated as a connection error.
A receiver can use the sequence number supplied in the NEW_CONNECTION_ID frame to handle receiving the same NEW_CONNECTION_ID frame multiple times.
传输错误、超时和重传可能会导致多次接收相同的 NEW_CONNECTION_ID 帧。
多次接收到同一帧不能被视为连接错误。
接收者可以使用 NEW_CONNECTION_ID 帧中提供的序列号来处理多次接收相同的 NEW_CONNECTION_ID 帧。

If an endpoint receives a NEW_CONNECTION_ID frame that repeats a previously issued connection ID with a different Stateless Reset Token field value or a different Sequence Number field value, or if a sequence number is used for different connection IDs, the endpoint MAY treat that receipt as a connection error of type PROTOCOL_VIOLATION.
如果端点接收到 NEW_CONNECTION_ID 帧,该帧重复先前发出的具有不同无状态重置令牌字段值或不同序列号字段值的连接 ID,或者如果序列号用于不同的连接 ID,则端点可以将该接收视为 PROTOCOL_VIOLATION 类型的连接错误。

The Retire Prior To field applies to connection IDs established during connection setup and the preferred_address transport parameter; see Section 5.1.2.
The value in the Retire Prior To field MUST be less than or equal to the value in the Sequence Number field.
Receiving a value in the Retire Prior To field that is greater than that in the Sequence Number field MUST be treated as a connection error of type FRAME_ENCODING_ERROR.
Retire Prior To 字段适用于在连接建立期间建立的连接 ID 和 preferred_address 传输参数; 见第 5.1.2 节。
Retire Prior To 字段中的值必须小于或等于 Sequence Number 字段中的值。
在 Retire Prior To 字段中接收到大于 Sequence Number 字段中的值必须被视为 FRAME_ENCODING_ERROR 类型的连接错误。

Once a sender indicates a Retire Prior To value, smaller values sent in subsequent NEW_CONNECTION_ID frames have no effect.
A receiver MUST ignore any Retire Prior To fields that do not increase the largest received Retire Prior To value.
一旦发送者指示 Retire Prior To 值,在后续 NEW_CONNECTION_ID 帧中发送的较小值将无效。
接收者必须忽略任何不增加最大接收到的 Retire Prior To 值的 Retire Prior To 字段。

An endpoint that receives a NEW_CONNECTION_ID frame with a sequence number smaller than the Retire Prior To field of a previously received NEW_CONNECTION_ID frame MUST send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID, unless it has already done so for that sequence number.
接收到序列号小于先前接收到的 NEW_CONNECTION_ID 帧的 Retire Prior To 字段的 NEW_CONNECTION_ID 帧的端点必须发送相应的 RETIRE_CONNECTION_ID 帧以使新接收的连接 ID 失效,除非它已经为该序列号这样做。

19.16. RETIRE_CONNECTION_ID Frames

An endpoint sends a RETIRE_CONNECTION_ID frame (type=0x19) to indicate that it will no longer use a connection ID that was issued by its peer.
This includes the connection ID provided during the handshake.
Sending a RETIRE_CONNECTION_ID frame also serves as a request to the peer to send additional connection IDs for future use; see Section 5.1.
New connection IDs can be delivered to a peer using the NEW_CONNECTION_ID frame (Section 19.15).
端点发送一个 RETIRE_CONNECTION_ID 帧(类型=0x19)以表明它将不再使用由其对等方发布的连接 ID。
这包括握手期间提供的连接 ID。
发送一个 RETIRE_CONNECTION_ID 帧也可以作为对端发送额外连接 ID 以供将来使用的请求; 见第 5.1 节。
可以使用 NEW_CONNECTION_ID 帧(第 19.15 节)将新的连接 ID 传递给对等方。

Retiring a connection ID invalidates the stateless reset token associated with that connection ID.
停用连接 ID 会使与该连接 ID 关联的无状态重置令牌失效。
RETIRE_CONNECTION_ID frames are formatted as shown in Figure 40.

1
2
3
4
RETIRE_CONNECTION_ID Frame {
Type (i) = 0x19,
Sequence Number (i),
}
            Figure 40: RETIRE_CONNECTION_ID Frame Format

RETIRE_CONNECTION_ID frames contain the following field:
Sequence Number: The sequence number of the connection ID being retired; see Section 5.1.2.

Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number greater than any previously sent to the peer MUST be treated as a connection error of type PROTOCOL_VIOLATION.
接收到包含序列号的 RETIRE_CONNECTION_ID 帧,该序列号大于之前发送给对等方的任何序列号,必须将其视为 PROTOCOL_VIOLATION 类型的连接错误。
The sequence number specified in a RETIRE_CONNECTION_ID frame MUST NOT refer to the Destination Connection ID field of the packet in which the frame is contained.
The peer MAY treat this as a connection error of type PROTOCOL_VIOLATION.
在 RETIRE_CONNECTION_ID 帧中指定的序列号不得引用包含该帧的数据包的目标连接 ID 字段。
对等方可以将此视为 PROTOCOL_VIOLATION 类型的连接错误。
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 MUST treat receipt of a RETIRE_CONNECTION_ID frame as a connection error of type PROTOCOL_VIOLATION.
如果端点提供了一个长度为零的连接 ID,则端点不能发送此帧。
提供零长度连接 ID 的端点必须将接收到 RETIRE_CONNECTION_ID 帧视为 PROTOCOL_VIOLATION 类型的连接错误。

19.17. PATH_CHALLENGE Frames

Endpoints can use PATH_CHALLENGE frames (type=0x1a) to check reachability to the peer and for path validation during connection migration.
端点可以使用 PATH_CHALLENGE 帧(类型=0x1a)来检查对等方的可达性并在连接迁移期间进行路径验证。
PATH_CHALLENGE frames are formatted as shown in Figure 41.

1
2
3
4
  PATH_CHALLENGE Frame {
Type (i) = 0x1a,
Data (64),
}
               Figure 41: PATH_CHALLENGE Frame Format

PATH_CHALLENGE frames contain the following field:
Data: This 8-byte field contains arbitrary data.

Including 64 bits of entropy in a PATH_CHALLENGE frame ensures that it is easier to receive the packet than it is to guess the value correctly.
在 PATH_CHALLENGE 帧中包含 64 位熵确保接收数据包比正确猜测值更容易。
The recipient of this frame MUST generate a PATH_RESPONSE frame (Section 19.18) containing the same Data value.
该帧的接收者必须生成一个包含相同数据值的 PATH_RESPONSE 帧(第 19.18 节)。

19.18. PATH_RESPONSE Frames

A PATH_RESPONSE frame (type=0x1b) is sent in response to a PATH_CHALLENGE frame.

PATH_RESPONSE frames are formatted as shown in Figure 42.
The format of a PATH_RESPONSE frame is identical to that of the PATH_CHALLENGE frame; see Section 19.17.

1
2
3
4
 PATH_RESPONSE Frame {
Type (i) = 0x1b,
Data (64),
}
               Figure 42: PATH_RESPONSE Frame Format

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 MAY generate a connection error of type PROTOCOL_VIOLATION.
如果 PATH_RESPONSE 帧的内容与端点先前发送的 PATH_CHALLENGE 帧的内容不匹配,则端点可能会生成 PROTOCOL_VIOLATION 类型的连接错误。

19.19. CONNECTION_CLOSE Frames

An endpoint sends a CONNECTION_CLOSE frame (type=0x1c or 0x1d) to notify its peer that the connection is being closed.
The CONNECTION_CLOSE frame with a type of 0x1c is used to signal errors at only the QUIC layer, or the absence of errors (with the NO_ERROR code).
The CONNECTION_CLOSE frame with a type of 0x1d is used to signal an error with the application that uses QUIC.
端点发送一个 CONNECTION_CLOSE 帧(类型=0x1c 或 0x1d)以通知其对等方连接正在关闭。
类型为 0x1c 的 CONNECTION_CLOSE 帧仅用于指示 QUIC 层的错误,或不存在错误(使用 NO_ERROR 代码)。
类型为 0x1d 的 CONNECTION_CLOSE 帧用于向使用 QUIC 的应用程序发出错误信号。

If there are open streams that have not been explicitly closed, they are implicitly closed when the connection is closed.
如果有未显式关闭的打开流,则在关闭连接时将它们隐式关闭。
CONNECTION_CLOSE frames are formatted as shown in Figure 43.

1
2
3
4
5
6
7
CONNECTION_CLOSE Frame {
Type (i) = 0x1c..0x1d,
Error Code (i),
[Frame Type (i)],
Reason Phrase Length (i),
Reason Phrase (..),
}
              Figure 43: CONNECTION_CLOSE Frame Format

CONNECTION_CLOSE frames contain the following fields:
Error Code: A variable-length integer that indicates the reason for closing this connection.
A CONNECTION_CLOSE frame of type 0x1c uses codes from the space defined in Section 20.1.
A CONNECTION_CLOSE frame of type 0x1d uses codes defined by the application protocol; see Section 20.2.
CONNECTION_CLOSE 帧包含以下字段:
错误代码:一个可变长度整数,指示关闭此连接的原因。
类型为 0x1c 的 CONNECTION_CLOSE 帧使用第 20.1 节中定义的空间中的代码。
类型为 0x1d 的 CONNECTION_CLOSE 帧使用应用协议定义的代码; 见第 20.2 节。

Frame Type: A variable-length integer encoding the type of frame that triggered the error.
A value of 0 (equivalent to the mention of the PADDING frame) is used when the frame type is unknown.
The application-specific variant of CONNECTION_CLOSE (type 0x1d) does not include this field.
帧类型:一个可变长度整数,编码触发错误的帧类型。
当帧类型未知时,使用值 0(相当于提到了 PADDING 帧)。
CONNECTION_CLOSE(类型 0x1d)的特定于应用程序的变体不包括此字段。

Reason Phrase Length: A variable-length integer specifying the length of the reason phrase in bytes.
Because a CONNECTION_CLOSE frame cannot be split between packets, any limits on packet size will also limit the space available for a reason phrase.
原因短语长度:一个可变长度整数,指定原因短语的长度(以字节为单位)。
因为 CONNECTION_CLOSE 帧不能在数据包之间拆分,所以对数据包大小的任何限制也会限制原因短语的可用空间。

Reason Phrase: Additional diagnostic information for the closure.
This can be zero length if the sender chooses not to give details beyond the Error Code value.
This SHOULD be a UTF-8 encoded string [RFC3629], though the frame does not carry information, such as language tags, that would aid comprehension by any entity other than the one that created the text.
原因短语:关闭的附加诊断信息。
如果发件人选择不提供超出错误代码值的详细信息,则该长度可以为零。
这应该是一个 UTF-8 编码字符串 [RFC3629],尽管框架不携带信息,例如语言标签,这将有助于除创建文本的实体之外的任何实体的理解。

The application-specific variant of CONNECTION_CLOSE (type 0x1d) can only be sent using 0-RTT or 1-RTT packets; see Section 12.5.
When an application wishes to abandon a connection during the handshake, an endpoint can send a CONNECTION_CLOSE frame (type 0x1c) with an error code of APPLICATION_ERROR in an Initial or Handshake packet.
CONNECTION_CLOSE(类型 0x1d)的应用程序特定变体只能使用 0-RTT 或 1-RTT 数据包发送; 见第 12.5 节。
当应用程序希望在握手期间放弃连接时,端点可以在初始或握手数据包中发送带有错误代码 APPLICATION_ERROR 的 CONNECTION_CLOSE 帧(类型 0x1c)。

19.20. HANDSHAKE_DONE Frames

The server uses a HANDSHAKE_DONE frame (type=0x1e) to signal confirmation of the handshake to the client.
服务器使用 HANDSHAKE_DONE 帧(类型=0x1e)向客户端发出握手确认信号。
HANDSHAKE_DONE frames are formatted as shown in Figure 44, which shows that HANDSHAKE_DONE frames have no content.

1
2
3
  HANDSHAKE_DONE Frame {
Type (i) = 0x1e,
}
               Figure 44: HANDSHAKE_DONE Frame Format

A HANDSHAKE_DONE frame can only be sent by the server.
Servers MUST NOT send a HANDSHAKE_DONE frame before completing the handshake.
A server MUST treat receipt of a HANDSHAKE_DONE frame as a connection error of type PROTOCOL_VIOLATION.
HANDSHAKE_DONE 帧只能由服务器发送。
服务器在完成握手之前不得发送 HANDSHAKE_DONE 帧。
服务器必须将收到 HANDSHAKE_DONE 帧视为 PROTOCOL_VIOLATION 类型的连接错误。

19.21. Extension Frames

QUIC frames do not use a self-describing encoding.
An endpoint 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.
QUIC 帧不使用自描述编码。
因此,端点在成功处理数据包之前需要了解所有帧的语法。
这允许对帧进行有效编码,但这意味着端点不能发送对其对等方未知类型的帧。

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 extension frame types.
One transport parameter can indicate support for one or more extension frame types.
希望使用新型帧的 QUIC 扩展必须首先确保对等方能够理解该帧。
端点可以使用传输参数来表示其接收扩展帧类型的意愿。
一个传输参数可以指示对一种或多种扩展帧类型的支持。

Extensions that modify or replace core protocol functionality (including frame types) will be difficult to combine with other extensions that modify or replace the same functionality unless the behavior of the combination is explicitly defined.
Such extensions SHOULD define their interaction with previously defined extensions modifying the same protocol components.
修改或替换核心协议功能(包括帧类型)的扩展将难以与修改或替换相同功能的其他扩展组合,除非明确定义组合的行为。
这样的扩展应该定义它们与先前定义的修改相同协议组件的扩展的交互。

Extension frames MUST be congestion controlled and MUST cause an ACK frame to be sent.
The exception is extension frames that replace or supplement the ACK frame.
Extension frames are not included in flow control unless specified in the extension.
扩展帧必须是拥塞控制的,并且必须导致发送一个 ACK 帧。
例外是替换或补充 ACK 帧的扩展帧。
除非在扩展中指定,否则扩展帧不包含在流量控制中。

An IANA registry is used to manage the assignment of frame types; see Section 22.4.
IANA 注册用于管理帧类型的分配; 见第 22.4 节。

20. Error Codes

QUIC transport error codes and application error codes are 62-bit unsigned integers.

20.1. Transport Error Codes

This section lists the defined QUIC transport error codes that can be used in a CONNECTION_CLOSE frame with a type of 0x1c.
These errors apply to the entire connection.

NO_ERROR (0x00): An endpoint uses this with CONNECTION_CLOSE to signal that the connection is being closed abruptly in the absence of any error.

INTERNAL_ERROR (0x01): The endpoint encountered an internal error and cannot continue with the connection.

CONNECTION_REFUSED (0x02): The server refused to accept a new connection.

FLOW_CONTROL_ERROR (0x03): An endpoint received more data than it permitted in its advertised data limits; see Section 4.

STREAM_LIMIT_ERROR (0x04): An endpoint received a frame for a stream identifier that exceeded its advertised stream limit for the corresponding stream type.

STREAM_STATE_ERROR (0x05): An endpoint received a frame for a stream that was not in a state that permitted that frame; see Section 3.

FINAL_SIZE_ERROR (0x06): (1) An endpoint received a STREAM frame containing data that exceeded the previously established final size, (2) an endpoint received a STREAM frame or a RESET_STREAM frame containing a final size that was lower than the size of stream data that was already received, or (3) an endpoint received a STREAM frame or a RESET_STREAM frame containing a different final size to the one already established.

FRAME_ENCODING_ERROR (0x07): An endpoint received a frame that was badly formatted – for instance, a frame of an unknown type or an ACK frame that has more acknowledgment ranges than the remainder of the packet could carry.

TRANSPORT_PARAMETER_ERROR (0x08): An endpoint received transport parameters that were badly formatted, included an invalid value, omitted a mandatory transport parameter, included a forbidden transport parameter, or were otherwise in error.

CONNECTION_ID_LIMIT_ERROR (0x09): The number of connection IDs provided by the peer exceeds the advertised active_connection_id_limit.

PROTOCOL_VIOLATION (0x0a): An endpoint detected an error with protocol compliance that was not covered by more specific error codes.

INVALID_TOKEN (0x0b): A server received a client Initial that contained an invalid Token field.

APPLICATION_ERROR (0x0c): The application or application protocol caused the connection to be closed.

CRYPTO_BUFFER_EXCEEDED (0x0d): An endpoint has received more data in CRYPTO frames than it can buffer.

KEY_UPDATE_ERROR (0x0e): An endpoint detected errors in performing key updates; see Section 6 of [QUIC-TLS].

AEAD_LIMIT_REACHED (0x0f): An endpoint has reached the confidentiality or integrity limit for the AEAD algorithm used by the given connection.

NO_VIABLE_PATH (0x10): An endpoint has determined that the network path is incapable of supporting QUIC.
An endpoint is unlikely to receive a CONNECTION_CLOSE frame carrying this code except when the path does not support a large enough MTU.

CRYPTO_ERROR (0x0100-0x01ff): The cryptographic handshake failed.
A range of 256 values is reserved for carrying error codes specific to the cryptographic handshake that is used.
Codes for errors occurring when TLS is used for the cryptographic handshake are described in Section 4.8 of [QUIC-TLS].

See Section 22.5 for details on registering new error codes.

In defining these error codes, several principles are applied.
Error conditions that might require specific action on the part of a recipient are given unique codes.
Errors that represent common conditions are given specific codes.
Absent either of these conditions, error codes are used to identify a general function of the stack, like flow control or transport parameter handling.
Finally, generic errors are provided for conditions where implementations are unable or unwilling to use more specific codes.

本节列出了可在类型为 0x1c 的 CONNECTION_CLOSE 帧中使用的已定义 QUIC 传输错误代码。
这些错误适用于整个连接。

NO_ERROR (0x00):端点将其与 CONNECTION_CLOSE 一起使用,以表示在没有任何错误的情况下突然关闭连接。

INTERNAL_ERROR (0x01):端点遇到内部错误,无法继续连接。

CONNECTION_REFUSED (0x02):服务器拒绝接受新连接。

FLOW_CONTROL_ERROR (0x03):端点接收到的数据超出了其告知的数据限制所允许的数量;见第 4 节。

STREAM_LIMIT_ERROR (0x04):端点接收到一个流标识符的帧,该帧超过了相应流类型的告知的流限制。

STREAM_STATE_ERROR (0x05):端点接收到的流的帧不在允许该帧的状态;见第 3 节。

FINAL_SIZE_ERROR (0x06):(1) 端点接收到包含超过先前确定的最终大小的数据的 STREAM 帧,(2) 端点接收到包含最终大小低于流数据大小的 STREAM 帧或 RESET_STREAM 帧已经收到,或者 (3) 端点收到了一个 STREAM 帧或一个 RESET_STREAM 帧,其中包含与已经建立的不同的最终大小。

FRAME_ENCODING_ERROR (0x07):端点接收到格式错误的帧 - 例如,未知类型的帧或确认范围超过数据包其余部分可以携带的 ACK 帧。

TRANSPORT_PARAMETER_ERROR (0x08):端点接收到格式错误、包含无效值、省略强制传输参数、包含禁止传输参数或其他错误的传输参数。

CONNECTION_ID_LIMIT_ERROR (0x09):对等体提供的连接 ID 数量超过了通告的 active_connection_id_limit。

PROTOCOL_VIOLATION (0x0a):端点检测到协议合规性错误,该错误未包含在更具体的错误代码中。

INVALID_TOKEN (0x0b):服务器收到包含无效令牌字段的客户端初始值。

APPLICATION_ERROR (0x0c):应用程序或应用程序协议导致连接关闭。

CRYPTO_BUFFER_EXCEEDED (0x0d):端点在 CRYPTO 帧中接收到的数据多于它可以缓冲的数据。

KEY_UPDATE_ERROR (0x0e):端点在执行密钥更新时检测到错误;参见 [QUIC-TLS] 的第 6 节。

AEAD_LIMIT_REACHED (0x0f):端点已达到给定连接使用的 AEAD 算法的机密性或完整性限制。

NO_VIABLE_PATH (0x10):端点已确定网络路径无法支持 QUIC。
端点不太可能接收到携带此代码的 CONNECTION_CLOSE 帧,除非路径不支持足够大的 MTU。

CRYPTO_ERROR (0x0100-0x01ff):加密握手失败。
保留 256 个值的范围,用于携带特定于所使用的加密握手的错误代码。
[QUIC-TLS] 的第 4.8 节描述了当 TLS 用于加密握手时发生的错误代码。

有关注册新错误代码的详细信息,请参见第 22.5 节。

在定义这些错误代码时,应用了几个原则。
可能需要收件人采取特定措施的错误条件被赋予唯一的代码。
代表常见情况的错误被赋予特定代码。
如果没有这些条件中的任何一个,错误代码将用于识别堆栈的一般功能,例如流控制或传输参数处理。
最后,为实现无法或不愿使用更具体代码的情况提供通用错误。
20.2. Application Protocol Error Codes

The management of application error codes is left to application protocols.
Application protocol error codes are used for the RESET_STREAM frame (Section 19.4), the STOP_SENDING frame (Section 19.5), and the CONNECTION_CLOSE frame with a type of 0x1d (Section 19.19).
应用程序错误代码的管理留给应用程序协议。
应用程序协议错误代码用于 RESET_STREAM 帧(第 19.4 节)、STOP_SENDING 帧(第 19.5 节)和类型为 0x1d 的 CONNECTION_CLOSE 帧(第 19.19 节)。

21. Security Considerations

The goal of QUIC is to provide a secure transport connection.
Section 21.1 provides an overview of those properties; subsequent sections discuss constraints and caveats regarding these properties, including descriptions of known attacks and countermeasures.
QUIC 的目标是提供安全的传输连接。
第 21.1 节概述了这些属性; 随后的部分讨论了有关这些属性的限制和注意事项,包括对已知攻击和对策的描述。

21.1. Overview of Security Properties

A complete security analysis of QUIC is outside the scope of this document.
This section provides an informal description of the desired security properties as an aid to implementers and to help guide protocol analysis.

QUIC assumes the threat model described in [SEC-CONS] and provides protections against many of the attacks that arise from that model.

For this purpose, attacks are divided into passive and active attacks.
Passive attackers have the ability to read packets from the network, while active attackers also have the ability to write packets into the network.
However, a passive attack could involve an attacker with the ability to cause a routing change or other modification in the path taken by packets that comprise a connection.

Attackers are additionally categorized as either on-path attackers or off-path attackers.
An on-path attacker can read, modify, or remove any packet it observes such that the packet no longer reaches its destination, while an off-path attacker observes the packets but cannot prevent the original packet from reaching its intended destination.
Both types of attackers can also transmit arbitrary packets.
This definition differs from that of Section 3.5 of [SEC-CONS] in that an off-path attacker is able to observe packets.

Properties of the handshake, protected packets, and connection migration are considered separately.
QUIC 的完整安全分析超出了本文档的范围。
本节提供对所需安全属性的非正式描述,以帮助实施者并帮助指导协议分析。

QUIC 采用 [SEC-CONS] 中描述的威胁模型,并针对该模型产生的许多攻击提供保护。

为此,攻击分为被动攻击和主动攻击。
被动攻击者有能力从网络中读取数据包,而主动攻击者也有能力将数据包写入网络。
但是,被动攻击可能涉及攻击者,该攻击者能够在构成连接的数据包所采用的路径中引起路由更改或其他修改。

攻击者还被分类为路径上的攻击者或路径外的攻击者。
路径上的攻击者可以读取、修改或删除它观察到的任何数据包,从而使数据包不再到达其目的地,而路径外的攻击者可以观察到数据包,但无法阻止原始数据包到达其预期目的地。
这两种类型的攻击者也可以传输任意数据包。
这个定义与 [SEC-CONS] 的第 3.5 节的不同之处在于,偏离路径的攻击者能够观察数据包。

握手的属性、受保护的数据包和连接迁移是分开考虑的。

21.1.1. Handshake

The QUIC handshake incorporates the TLS 1.3 handshake and inherits the cryptographic properties described in Appendix E.1 of [TLS13].
Many of the security properties of QUIC depend on the TLS handshake providing these properties.
Any attack on the TLS handshake could affect QUIC.

Any attack on the TLS handshake that compromises the secrecy or uniqueness of session keys, or the authentication of the participating peers, affects other security guarantees provided by QUIC that depend on those keys.
For instance, migration (Section 9) depends on the efficacy of confidentiality protections, both for the negotiation of keys using the TLS handshake and for QUIC packet protection, to avoid linkability across network paths.

An attack on the integrity of the TLS handshake might allow an attacker to affect the selection of application protocol or QUIC version.

In addition to the properties provided by TLS, the QUIC handshake provides some defense against DoS attacks on the handshake.
QUIC 握手结合了 TLS 1.3 握手并继承了 [TLS13] 的附录 E.1 中描述的加密属性。
QUIC 的许多安全属性取决于提供这些属性的 TLS 握手。
对 TLS 握手的任何攻击都可能影响 QUIC。

对 TLS 握手的任何攻击都会损害会话密钥的保密性或唯一性,或参与对等方的身份验证,都会影响 QUIC 提供的依赖于这些密钥的其他安全保证。
例如,迁移(第 9 节)取决于机密性保护的有效性,无论是使用 TLS 握手协商密钥还是 QUIC 数据包保护,以避免跨网络路径的可链接性。

对 TLS 握手完整性的攻击可能允许攻击者影响应用程序协议或 QUIC 版本的选择。

除了 TLS 提供的属性之外,QUIC 握手还提供了一些针对握手的 DoS 攻击的防御。

  • 21.1.1.1. Anti-Amplification

    Address validation (Section 8) is used to verify that an entity that claims a given address is able to receive packets at that address.
    Address validation limits amplification attack targets to addresses for which an attacker can observe packets.

    Prior to address validation, endpoints are limited in what they are able to send.
    Endpoints cannot send data toward an unvalidated address in excess of three times the data received from that address.

    |  Note: The anti-amplification limit only applies when an      |  endpoint responds to packets received from an unvalidated      |  address.
    

    The anti-amplification limit does not apply to | clients when establishing a new connection or when initiating | connection migration.

地址验证(第 8 节)用于验证声明给定地址的实体是否能够在该地址接收数据包。
地址验证将放大攻击目标限制为攻击者可以观察数据包的地址。

在地址验证之前,端点能够发送的内容受到限制。

端点向未经验证的地址发送的数据不能超过从该地址接收的数据的三倍。

   | 注意:抗放大限制仅适用于 | 端点响应从未经验证的 | 接收到的数据包 地址。

抗放大限制不适用于 | 客户端在建立新连接或启动时 | 连接迁移。

  • 21.1.1.2. Server-Side DoS

    Computing the server’s first flight for a full handshake is potentially expensive, requiring both a signature and a key exchange computation.
    In order to prevent computational DoS attacks, the Retry packet provides a cheap token exchange mechanism that allows servers to validate a client’s IP address prior to doing any expensive computations at the cost of a single round trip.
    After a successful handshake, servers can issue new tokens to a client, which will allow new connection establishment without incurring this cost.

为完整握手计算服务器的第一次传输可能很昂贵,需要签名和密钥交换计算。
为了防止计算 DoS 攻击,重试数据包提供了一种廉价的令牌交换机制,允许服务器在以单次往返为代价进行任何昂贵的计算之前验证客户端的 IP 地址。
成功握手后,服务器可以向客户端颁发新令牌token,这将允许建立新的连接而不会产生此成本。

  • 21.1.1.3. On-Path Handshake Termination

    An on-path or off-path attacker can force a handshake to fail by replacing or racing Initial packets.
    Once valid Initial packets have been exchanged, subsequent Handshake packets are protected with the Handshake keys, and an on-path attacker cannot force handshake failure other than by dropping packets to cause endpoints to abandon the attempt.

    An on-path attacker can also replace the addresses of packets on either side and therefore cause the client or server to have an incorrect view of the remote addresses.
    Such an attack is indistinguishable from the functions performed by a NAT.

路径上或路径外的攻击者可以通过替换或竞争初始数据包来强制握手失败。
一旦交换了有效的初始数据包,后续的握手数据包就会受到握手密钥的保护,并且路径上的攻击者只能通过丢弃数据包以导致端点放弃尝试来强制握手失败。

路径上的攻击者还可以替换任一端数据包的地址,从而导致客户端或服务器对远程地址的看法不正确。

这种攻击与 NAT 执行的功能无法区分。

  • 21.1.1.4. Parameter Negotiation

    The entire handshake is cryptographically protected, with the Initial packets being encrypted with per-version keys and the Handshake and later packets being encrypted with keys derived from the TLS key exchange.
    Further, parameter negotiation is folded into the TLS transcript and thus provides the same integrity guarantees as ordinary TLS negotiation.
    An attacker can observe the client’s transport parameters (as long as it knows the version-specific salt) but cannot observe the server’s transport parameters and cannot influence parameter negotiation.

    Connection IDs are unencrypted but integrity protected in all packets.

    This version of QUIC does not incorporate a version negotiation mechanism; implementations of incompatible versions will simply fail to establish a connection.

整个握手过程都受到加密保护,初始数据包使用每个版本的密钥加密,握手和后续数据包使用从 TLS 密钥交换派生的密钥进行加密。
此外,参数协商被折叠到 TLS 记录中,因此提供与普通 TLS 协商相同的完整性保证。
攻击者可以观察客户端的传输参数(只要它知道特定于版本的盐),但无法观察服务器的传输参数,也无法影响参数协商。

连接 ID 未加密,但在所有数据包中都受到完整性保护。

此版本的 QUIC 不包含版本协商机制; 不兼容版本的实现将无法建立连接。
21.1.2. Protected Packets

Packet protection (Section 12.1) applies authenticated encryption to all packets except Version Negotiation packets, though Initial and Retry packets have limited protection due to the use of version- specific keying material; see [QUIC-TLS] for more details.
This section considers passive and active attacks against protected packets.

Both on-path and off-path attackers can mount a passive attack in which they save observed packets for an offline attack against packet protection at a future time; this is true for any observer of any packet on any network.

An attacker that injects packets without being able to observe valid packets for a connection is unlikely to be successful, since packet protection ensures that valid packets are only generated by endpoints that possess the key material established during the handshake; see Sections 7 and 21.1.1.
Similarly, any active attacker that observes packets and attempts to insert new data or modify existing data in those packets should not be able to generate packets deemed valid by the receiving endpoint, other than Initial packets.

A spoofing attack, in which an active attacker rewrites unprotected parts of a packet that it forwards or injects, such as the source or destination address, is only effective if the attacker can forward packets to the original endpoint.
Packet protection ensures that the packet payloads can only be processed by the endpoints that completed the handshake, and invalid packets are ignored by those endpoints.

An attacker can also modify the boundaries between packets and UDP datagrams, causing multiple packets to be coalesced into a single datagram or splitting coalesced packets into multiple datagrams.
Aside from datagrams containing Initial packets, which require padding, modification of how packets are arranged in datagrams has no functional effect on a connection, although it might change some performance characteristics.
数据包保护(第 12.1 节)对除版本协商数据包之外的所有数据包应用经过验证的加密,但由于使用了特定于版本的密钥材料,初始和重试数据包的保护有限;有关详细信息,请参阅 [QUIC-TLS]。
本节考虑对受保护数据包的被动和主动攻击。

路径上和路径外的攻击者都可以发起被动攻击,在这种攻击中他们保存观察到的数据包,以便在未来对数据包保护进行离线攻击;对于任何网络上任何数据包的任何观察者来说都是如此。

注入数据包而无法观察连接的有效数据包的攻击者不太可能成功,因为数据包保护确保有效数据包仅由拥有握手期间建立的密钥材料的端点生成;请参见第 7 节和第 21.1.1 节。
类似地,任何观察数据包并尝试在这些数据包中插入新数据或修改现有数据的主动攻击者都不应生成接收端点认为有效的数据包,除了初始数据包。

只有当攻击者可以将数据包转发到原始端点时,主动攻击者才会重写其转发或注入的数据包中未受保护的部分(例如源地址或目标地址)的欺骗攻击。
数据包保护确保数据包有效负载只能由完成握手的端点处理,并且这些端点会忽略无效数据包。

攻击者还可以修改数据包和 UDP 数据报之间的边界,导致多个数据包合并为一个数据报或将合并的数据包拆分为多个数据报。
除了包含需要填充的初始数据包的数据报之外,修改数据报中数据包的排列方式对连接没有功能影响,尽管它可能会改变一些性能特征。

21.1.3. Connection Migration

Connection migration (Section 9) provides endpoints with the ability to transition between IP addresses and ports on multiple paths, using one path at a time for transmission and receipt of non-probing frames.
提供了一种在多路径的ip,端口转换的能力,在一个传输和接收非探测帧的时间段使用一个路径。
Path validation (Section 8.2) establishes that a peer is both willing and able to receive packets sent on a particular path.
This helps reduce the effects of address spoofing地址欺骗 by limiting the number of packets sent to a spoofed伪造的 address.

This section describes the intended security properties of connection migration under various types of DoS attacks.本节描述了在各种类型的 DoS 攻击下连接迁移的预期安全属性。

  • 21.1.3.1. On-Path Active Attacks

    An attacker that can cause a packet it observes to no longer reach its intended destination is considered an on-path attacker.什么是on-path attacker
    When an attacker is present between a client and server, endpoints are required to send packets through the attacker to establish connectivity on a given path.

    An on-path attacker can:

    • Inspect检查查阅 packets
    • Modify IP and UDP packet headers
    • Inject new packets
    • Delay packets
    • Reorder packets
    • Drop packets
    • Split and merge datagrams along packet boundaries

    An on-path attacker cannot:

    • Modify an authenticated portion部分 of a packet and cause the recipient to accept that packet 接收者接受该数据包
      An on-path attacker has the opportunity to modify the packets that it observes; however, any modifications to an authenticated portion of a packet will cause it to be dropped by the receiving endpoint as invalid,
      as packet payloads are both authenticated and encrypted.能修改包,但因认证失败会被丢弃

    QUIC aims to constrain约束 the capabilities of an on-path attacker as follows: 下面是攻击者的能力和方式:

    1. An on-path attacker can prevent the use of a path for a
      connection, causing the connection to fail if it cannot use a different path that does not contain the attacker.能阻止使用一个路径来连接,如果它不能使用一个不包含攻击者的不同路径,则会导致连接失败。
      This can be achieved by dropping all packets, modifying them so that they fail to decrypt, or other methods.这个可以通过丢弃所有包,修改来导致解密失败或其他方式来完成。

    2. An on-path attacker can prevent migration to a new path for which
      the attacker is also on-path by causing path validation to fail on the new path.阻止连接迁移

    3. An on-path attacker cannot prevent a client from migrating to a
      path for which the attacker is not on-path.不能阻止 攻击者不在路径上的client的连接迁移

    4. An on-path attacker can reduce the throughput of a connection by
      delaying packets or dropping them. 减少吞吐量通过延迟和丢弃

    5. An on-path attacker cannot cause an endpoint to accept a packet
      for which it has modified an authenticated portion of that packet.不能让节点去接受修改了认证部分的包。

  • 21.1.3.2. Off-Path Active Attacks

    An off-path attacker is not directly on the path between a client and server but could be able to obtain copies of some or all packets sent between the client and the server.非中间人攻击(在client->server路径上的攻击者)
    而是一个能拿到副本包的off-path attacker
    It is also able to send copies of those packets to either endpoint.

    An off-path attacker can:

    • Inspect packets
    • Inject new packets
    • Reorder injected packets
      An off-path attacker cannot:
    • Modify packets sent by endpoints
    • Delay packets
    • Drop packets
    • Reorder original packets
      An off-path attacker can create modified copies of packets that it has observed and inject those copies into the network, potentially with spoofed虚假的 source and destination addresses.

    For the purposes of this discussion, it is assumed that an off-path attacker has the ability to inject a modified copy of a packet into the network that will reach the destination endpoint prior to(之前) the arrival of
    the original packet observed by the attacker.有什么能力呢?将修改的副本包发到网络上,将在原始包到达目的节点之前
    In other words, an attacker has the ability to consistently “win” a race with the legitimate合法的 packets between the endpoints, potentially causing the original packet to be ignored by the recipient.
    比合法包早到达,这样合法包会被接收方忽略。

    It is also assumed that an attacker has the resources necessary to affect NAT state.有必要的资源能影响NAT状态
    In particular, an attacker can cause an endpoint to lose its NAT binding and then obtain the same port for use with its own traffic.特别是,攻击者可以导致端点丢失其 NAT 绑定,然后获取相同的端口以用于其自己的流量。

    QUIC aims to constrain the capabilities of an off-path attacker as follows:

    1. An off-path attacker can race packets and attempt to become a
      “limited” on-path attacker.

    2. An off-path attacker can cause path validation to succeed for
      forwarded packets with the source address listed as the off-path attacker as long as it can provide improved改善 connectivity between the client and the server.

    3. An off-path attacker cannot cause a connection to close once the
      handshake has completed.

    4. An off-path attacker cannot cause migration to a new path to fail
      if it cannot observe the new path.

    5. An off-path attacker can become a limited on-path attacker during
      migration to a new path for which it is also an off-path attacker.

    6. An off-path attacker can become a limited on-path attacker by
      affecting shared NAT state such that it sends packets to the server from the same IP address and port that the client originally used.

  • 21.1.3.3. Limited On-Path Active Attacks
    什么是Limited On-Path Active Attacks:和前面的off-path类似,但是这个不修改
    A limited on-path attacker is an off-path attacker that has offered improved routing of packets by duplicating and forwarding original packets between the server and the client, causing those packets to
    arrive before the original copies such that the original packets are dropped by the destination endpoint.

    A limited on-path attacker differs from an on-path attacker in that it is not on the original path between endpoints, and therefore the original packets sent by an endpoint are still reaching their destination.
    This means that a future failure to route copied packets to the destination faster than their original path will not prevent the original packets from reaching the destination.

    A limited on-path attacker can:

    • Inspect packets
    • Inject new packets
    • Modify unencrypted packet headers
    • Reorder packets
      A limited on-path attacker cannot:
    • Delay packets so that they arrive later than packets sent on the original path
    • Drop packets
    • Modify the authenticated and encrypted portion of a packet and cause the recipient to accept that packet
      A limited on-path attacker can only delay packets up to the point that the original packets arrive before the duplicate packets, meaning that it cannot offer routing with worse latency than the original path.
      If a limited on-path attacker drops packets, the original copy will still arrive at the destination endpoint.

    QUIC aims to constrain the capabilities of a limited off-path attacker as follows:

    1. A limited on-path attacker cannot cause a connection to close
      once the handshake has completed.

    2. A limited on-path attacker cannot cause an idle connection to
      close if the client is first to resume activity.

    3. A limited on-path attacker can cause an idle connection to be
      deemed lost if the server is the first to resume activity.

    Note that these guarantees are the same guarantees provided for any NAT, for the same reasons.

21.2. Handshake Denial of Service

As an encrypted and authenticated transport, QUIC provides a range of protections against denial of service.QUIC 提供一系列针对拒绝服务的保护
Once the cryptographic handshake is complete, QUIC endpoints discard most packets that are not authenticated, greatly limiting the ability of an attacker to interfere干扰 with existing connections.
握手完成,丢弃未认证的包

Once a connection is established, QUIC endpoints might accept some unauthenticated ICMP packets (see Section 14.2.1), but the use of these packets is extremely limited.
The only other type of packet that an endpoint might accept is a stateless reset (Section 10.3), which relies on the token being kept secret until it is used.连接建立后,限制非认证包的接收

During the creation of a connection, QUIC only provides protection against attacks from off the network path.
All QUIC packets contain proof that the recipient saw a preceding packet from its peer.

Addresses cannot change during the handshake, so endpoints can discard packets that are received on a different network path.

The Source and Destination Connection ID fields are the primary means of protection against an off-path attack during the handshake; see Section 8.1.
These are required to match those set by a peer.
Except for Initial and Stateless Resets, an endpoint only accepts packets that include a Destination Connection ID field that matches a value the endpoint previously chose.
This is the only protection offered for Version Negotiation packets.

The Destination Connection ID field in an Initial packet is selected by a client to be unpredictable, which serves an additional purpose.
The packets that carry the cryptographic handshake are protected with a key that is derived from this connection ID and a salt specific to the QUIC version.
This allows endpoints to use the same process for authenticating packets that they receive as they use after the cryptographic handshake completes.
Packets that cannot be authenticated are discarded.
Protecting packets in this fashion provides a strong assurance that the sender of the packet saw the Initial packet and understood it.

These protections are not intended to be effective against an attacker that is able to receive QUIC packets prior to the connection being established.
Such an attacker can potentially send packets that will be accepted by QUIC endpoints.
This version of QUIC attempts to detect this sort of attack, but it expects that endpoints will fail to establish a connection rather than recovering.
For the most part, the cryptographic handshake protocol [QUIC-TLS] is responsible for detecting tampering during the handshake.

Endpoints are permitted to use other methods to detect and attempt to recover from interference with the handshake.
Invalid packets can be identified and discarded using other methods, but no specific method is mandated in this document.

21.3. Amplification Attack

An attacker might be able to receive an address validation token (Section 8) from a server and then release the IP address it used to acquire that token.
At a later time, the attacker can initiate a 0-RTT connection with a server by spoofing this same address, which might now address a different (victim) endpoint.
The attacker can thus potentially cause the server to send an initial congestion window’s worth of data towards the victim.

Servers SHOULD provide mitigations for this attack by limiting the usage and lifetime of address validation tokens; see Section 8.1.3.

21.4. Optimistic ACK Attack

An endpoint that acknowledges packets it has not received might cause a congestion controller to permit sending at rates beyond what the network supports.
An endpoint MAY skip packet numbers when sending packets to detect this behavior.
An endpoint can then immediately close the connection with a connection error of type PROTOCOL_VIOLATION; see Section 10.2.

21.5. Request Forgery Attacks

A request forgery attack occurs where an endpoint causes its peer to issue a request towards a victim, with the request controlled by the endpoint.
Request forgery attacks aim to provide an attacker with access to capabilities of its peer that might otherwise be unavailable to the attacker.
For a networking protocol, a request forgery attack is often used to exploit any implicit authorization conferred on the peer by the victim due to the peer’s location in the network.

For request forgery to be effective, an attacker needs to be able to influence what packets the peer sends and where these packets are sent.
If an attacker can target a vulnerable service with a controlled payload, that service might perform actions that are attributed to the attacker’s peer but are decided by the attacker.

For example, cross-site request forgery [CSRF] exploits on the Web cause a client to issue requests that include authorization cookies [COOKIE], allowing one site access to information and actions that are intended to be restricted to a different site.

As QUIC runs over UDP, the primary attack modality of concern is one where an attacker can select the address to which its peer sends UDP datagrams and can control some of the unprotected content of those packets.
As much of the data sent by QUIC endpoints is protected, this includes control over ciphertext.
An attack is successful if an attacker can cause a peer to send a UDP datagram to a host that will perform some action based on content in the datagram.

This section discusses ways in which QUIC might be used for request forgery attacks.

This section also describes limited countermeasures that can be implemented by QUIC endpoints.
These mitigations can be employed unilaterally by a QUIC implementation or deployment, without potential targets for request forgery attacks taking action.
However, these countermeasures could be insufficient if UDP-based services do not properly authorize requests.

Because the migration attack described in Section 21.5.4 is quite powerful and does not have adequate countermeasures, QUIC server implementations should assume that attackers can cause them to generate arbitrary UDP payloads to arbitrary destinations.
QUIC servers SHOULD NOT be deployed in networks that do not deploy ingress filtering [BCP38] and also have inadequately secured UDP endpoints.

Although it is not generally possible to ensure that clients are not co-located with vulnerable endpoints, this version of QUIC does not allow servers to migrate, thus preventing spoofed migration attacks on clients.
Any future extension that allows server migration MUST also define countermeasures for forgery attacks.

21.5.1. Control Options for Endpoints

QUIC offers some opportunities for an attacker to influence or control where its peer sends UDP datagrams:

  • initial connection establishment (Section 7), where a server is able to choose where a client sends datagrams – for example, by populating DNS records;
  • preferred addresses (Section 9.6), where a server is able to choose where a client sends datagrams;
  • spoofed connection migrations (Section 9.3.1), where a client is able to use source address spoofing to select where a server sends subsequent datagrams; and
  • spoofed packets that cause a server to send a Version Negotiation packet (Section 21.5.5).

In all cases, the attacker can cause its peer to send datagrams to a victim that might not understand QUIC.
That is, these packets are sent by the peer prior to address validation; see Section 8.

Outside of the encrypted portion of packets, QUIC offers an endpoint several options for controlling the content of UDP datagrams that its peer sends.
The Destination Connection ID field offers direct control over bytes that appear early in packets sent by the peer; see Section 5.1.
The Token field in Initial packets offers a server control over other bytes of Initial packets; see Section 17.2.2.

There are no measures in this version of QUIC to prevent indirect control over the encrypted portions of packets.
It is necessary to assume that endpoints are able to control the contents of frames that a peer sends, especially those frames that convey application data, such as STREAM frames.
Though this depends to some degree on details of the application protocol, some control is possible in many protocol usage contexts.
As the attacker has access to packet protection keys, they are likely to be capable of predicting how a peer will encrypt future packets.
Successful control over datagram content then only requires that the attacker be able to predict the packet number and placement of frames in packets with some amount of reliability.

This section assumes that limiting control over datagram content is not feasible.
The focus of the mitigations in subsequent sections is on limiting the ways in which datagrams that are sent prior to address validation can be used for request forgery.

21.5.2. Request Forgery with Client Initial Packets

An attacker acting as a server can choose the IP address and port on which it advertises its availability, so Initial packets from clients are assumed to be available for use in this sort of attack.
The address validation implicit in the handshake ensures that – for a new connection – a client will not send other types of packets to a destination that does not understand QUIC or is not willing to accept a QUIC connection.

Initial packet protection (Section 5.2 of [QUIC-TLS]) makes it difficult for servers to control the content of Initial packets sent by clients.
A client choosing an unpredictable Destination Connection ID ensures that servers are unable to control any of the encrypted portion of Initial packets from clients.

However, the Token field is open to server control and does allow a server to use clients to mount request forgery attacks.
The use of tokens provided with the NEW_TOKEN frame (Section 8.1.3) offers the only option for request forgery during connection establishment.

Clients, however, are not obligated to use the NEW_TOKEN frame.
Request forgery attacks that rely on the Token field can be avoided if clients send an empty Token field when the server address has changed from when the NEW_TOKEN frame was received.

Clients could avoid using NEW_TOKEN if the server address changes.
However, not including a Token field could adversely affect performance.
Servers could rely on NEW_TOKEN to enable the sending of data in excess of the three-times limit on sending data; see Section 8.1.
In particular, this affects cases where clients use 0-RTT to request data from servers.

Sending a Retry packet (Section 17.2.5) offers a server the option to change the Token field.
After sending a Retry, the server can also control the Destination Connection ID field of subsequent Initial packets from the client.
This also might allow indirect control over the encrypted content of Initial packets.
However, the exchange of a Retry packet validates the server’s address, thereby preventing the use of subsequent Initial packets for request forgery.

21.5.3. Request Forgery with Preferred Addresses

Servers can specify a preferred address, which clients then migrate to after confirming the handshake; see Section 9.6.
The Destination Connection ID field of packets that the client sends to a preferred address can be used for request forgery.

A client MUST NOT send non-probing frames to a preferred address prior to validating that address; see Section 8.
This greatly reduces the options that a server has to control the encrypted portion of datagrams.

This document does not offer any additional countermeasures that are specific to the use of preferred addresses and can be implemented by endpoints.
The generic measures described in Section 21.5.6 could be used as further mitigation.

21.5.4. Request Forgery with Spoofed Migration

Clients are able to present a spoofed source address as part of an apparent connection migration to cause a server to send datagrams to that address.

The Destination Connection ID field in any packets that a server subsequently sends to this spoofed address can be used for request forgery.
A client might also be able to influence the ciphertext.

A server that only sends probing packets (Section 9.1) to an address prior to address validation provides an attacker with only limited control over the encrypted portion of datagrams.
However, particularly for NAT rebinding, this can adversely affect performance.
If the server sends frames carrying application data, an attacker might be able to control most of the content of datagrams.

This document does not offer specific countermeasures that can be implemented by endpoints, aside from the generic measures described in Section 21.5.6.
However, countermeasures for address spoofing at the network level – in particular, ingress filtering [BCP38] – are especially effective against attacks that use spoofing and originate from an external network.

21.5.5. Request Forgery with Version Negotiation

Clients that are able to present a spoofed source address on a packet can cause a server to send a Version Negotiation packet (Section 17.2.1) to that address.

The absence of size restrictions on the connection ID fields for packets of an unknown version increases the amount of data that the client controls from the resulting datagram.
The first byte of this packet is not under client control and the next four bytes are zero, but the client is able to control up to 512 bytes starting from the fifth byte.

No specific countermeasures are provided for this attack, though generic protections (Section 21.5.6) could apply.
In this case, ingress filtering [BCP38] is also effective.

21.5.6. Generic Request Forgery Countermeasures

The most effective defense against request forgery attacks is to modify vulnerable services to use strong authentication.
However, this is not always something that is within the control of a QUIC deployment.
This section outlines some other steps that QUIC endpoints could take unilaterally.
These additional steps are all discretionary because, depending on circumstances, they could interfere with or prevent legitimate uses.

Services offered over loopback interfaces often lack proper authentication.
Endpoints MAY prevent connection attempts or migration to a loopback address.
Endpoints SHOULD NOT allow connections or migration to a loopback address if the same service was previously available at a different interface or if the address was provided by a service at a non-loopback address.
Endpoints that depend on these capabilities could offer an option to disable these protections.

Similarly, endpoints could regard a change in address to a link-local address [RFC4291] or an address in a private-use range [RFC1918] from a global, unique-local [RFC4193], or non-private address as a potential attempt at request forgery.
Endpoints could refuse to use these addresses entirely, but that carries a significant risk of interfering with legitimate uses.
Endpoints SHOULD NOT refuse to use an address unless they have specific knowledge about the network indicating that sending datagrams to unvalidated addresses in a given range is not safe.

Endpoints MAY choose to reduce the risk of request forgery by not including values from NEW_TOKEN frames in Initial packets or by only sending probing frames in packets prior to completing address validation.
Note that this does not prevent an attacker from using the Destination Connection ID field for an attack.

Endpoints are not expected to have specific information about the location of servers that could be vulnerable targets of a request forgery attack.
However, it might be possible over time to identify specific UDP ports that are common targets of attacks or particular patterns in datagrams that are used for attacks.
Endpoints MAY choose to avoid sending datagrams to these ports or not send datagrams that match these patterns prior to validating the destination address.
Endpoints MAY retire connection IDs containing patterns known to be problematic without using them.

  |  Note: Modifying endpoints to apply these protections is more      |  efficient than deploying network-based protections, as      |  endpoints do not need to perform any additional processing when      |  sending to an address that has been validated.
21.6. Slowloris Attacks

The attacks commonly known as Slowloris [SLOWLORIS] try to keep many connections to the target endpoint open and hold them open as long as possible.
These attacks can be executed against a QUIC endpoint by generating the minimum amount of activity necessary to avoid being closed for inactivity.
This might involve sending small amounts of data, gradually opening flow control windows in order to control the sender rate, or manufacturing ACK frames that simulate a high loss rate.

QUIC deployments SHOULD provide mitigations for the Slowloris attacks, such as increasing the maximum number of clients the server will allow, limiting the number of connections a single IP address is allowed to make, imposing restrictions on the minimum transfer speed a connection is allowed to have, and restricting the length of time an endpoint is allowed to stay connected.

21.7. Stream Fragmentation and Reassembly Attacks

An adversarial sender might intentionally not send portions of the stream data, causing the receiver to commit resources for the unsent data.
This could cause a disproportionate receive buffer memory commitment and/or the creation of a large and inefficient data structure at the receiver.

An adversarial receiver might intentionally not acknowledge packets containing stream data in an attempt to force the sender to store the unacknowledged stream data for retransmission.

The attack on receivers is mitigated if flow control windows correspond to available memory.
However, some receivers will overcommit memory and advertise flow control offsets in the aggregate that exceed actual available memory.
The overcommitment strategy can lead to better performance when endpoints are well behaved, but renders endpoints vulnerable to the stream fragmentation attack.

QUIC deployments SHOULD provide mitigations for stream fragmentation attacks.
Mitigations could consist of avoiding overcommitting memory, limiting the size of tracking data structures, delaying reassembly of STREAM frames, implementing heuristics based on the age and duration of reassembly holes, or some combination of these.

21.8. Stream Commitment Attack

An adversarial endpoint can open a large number of streams, exhausting state on an endpoint.
The adversarial endpoint could repeat the process on a large number of connections, in a manner similar to SYN flooding attacks in TCP.

Normally, clients will open streams sequentially, as explained in Section 2.1.
However, when several streams are initiated at short intervals, loss or reordering can cause STREAM frames that open streams to be received out of sequence.
On receiving a higher- numbered stream ID, a receiver is required to open all intervening streams of the same type; see Section 3.2.
Thus, on a new connection, opening stream 4000000 opens 1 million and 1 client- initiated bidirectional streams.

The number of active streams is limited by the initial_max_streams_bidi and initial_max_streams_uni transport parameters as updated by any received MAX_STREAMS frames, as explained in Section 4.6.
If chosen judiciously, these limits mitigate the effect of the stream commitment attack.
However, setting the limit too low could affect performance when applications expect to open a large number of streams.

21.9. Peer Denial of Service

QUIC and TLS both contain frames or messages that have legitimate uses in some contexts, but these frames or messages can be abused to cause a peer to expend processing resources without having any observable impact on the state of the connection.

Messages can also be used to change and revert state in small or inconsequential ways, such as by sending small increments to flow control limits.

If processing costs are disproportionately large in comparison to bandwidth consumption or effect on state, then this could allow a malicious peer to exhaust processing capacity.

While there are legitimate uses for all messages, implementations SHOULD track cost of processing relative to progress and treat excessive quantities of any non-productive packets as indicative of an attack.
Endpoints MAY respond to this condition with a connection error or by dropping packets.

21.10. Explicit Congestion Notification Attacks

An on-path attacker could manipulate the value of ECN fields in the IP header to influence the sender’s rate.
[RFC3168] discusses manipulations and their effects in more detail.

A limited on-path attacker can duplicate and send packets with modified ECN fields to affect the sender’s rate.
If duplicate packets are discarded by a receiver, an attacker will need to race the duplicate packet against the original to be successful in this attack.
Therefore, QUIC endpoints ignore the ECN field in an IP packet unless at least one QUIC packet in that IP packet is successfully processed; see Section 13.4.

21.11. Stateless Reset Oracle

Stateless resets create a possible denial-of-service attack analogous 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 connection with a selected connection ID.
An attacker that can cause this token to be generated can reset an active connection with the same connection ID.

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 can cause the server to send a stateless reset.
To defend against this style of denial of service, endpoints that share a static key for stateless resets (see Section 10.3.2) MUST be arranged so that packets with a given connection ID always arrive at an instance that has connection state, unless that connection is no longer active.

More generally, servers MUST NOT generate a stateless reset if a connection with the corresponding connection ID could be active on any endpoint using the same static key.

In the case of a cluster that uses dynamic load balancing, it is possible that a change in load-balancer configuration could occur while an active instance retains connection state.
Even if an instance retains connection state, the change in routing and resulting stateless reset will result in the connection being terminated.
If there is no chance of the packet being routed to the correct instance, it is better to send a stateless reset than wait for the connection to time out.
However, this is acceptable only if the routing cannot be influenced by an attacker.

21.12. Version Downgrade

This document defines QUIC Version Negotiation packets (Section 6), which can be used to negotiate the QUIC version used between two endpoints.
However, this document does not specify how this negotiation will be performed between this version and subsequent future versions.
In particular, Version Negotiation packets do not contain any mechanism to prevent version downgrade attacks.
Future versions of QUIC that use Version Negotiation packets MUST define a mechanism that is robust against version downgrade attacks.

21.13. Targeted Attacks by Routing

Deployments should limit the ability of an attacker to target a new connection to a particular server instance.
Ideally, routing decisions are made independently of client-selected values, including addresses.
Once an instance is selected, a connection ID can be selected so that later packets are routed to the same instance.

21.14. Traffic Analysis

The length of QUIC packets can reveal information about the length of the content of those packets.
The PADDING frame is provided so that endpoints have some ability to obscure the length of packet content; see Section 19.1.

Defeating traffic analysis is challenging and the subject of active research.
Length is not the only way that information might leak.
Endpoints might also reveal sensitive information through other side channels, such as the timing of packets.