4. 规范 (Specifications)
4.1. 连接建立
DoQ 连接按 QUIC 传输规范 [RFC9000] 中的描述建立. 在连接建立期间, 通过在加密握手中选择应用层协议协商 (Application-Layer Protocol Negotiation, ALPN) 令牌 "doq" 来指示支持 DoQ.
4.1.1. 端口选择
默认情况下, 支持 DoQ 的 DNS 服务器 MUST 在专用 UDP 端口 853 (第 8 节) 上监听并接受 QUIC 连接, 除非双方同意使用其他端口.
默认情况下, 希望与特定服务器使用 DoQ 的 DNS 客户端 MUST 建立到该服务器 UDP 端口 853 的 QUIC 连接, 除非双方同意使用其他端口.
DoQ 连接 MUST NOT 使用 UDP 端口 53. 不建议 DoQ 使用端口 53 是为了避免 DoQ 与 DNS over UDP [RFC1035] 的使用发生混淆.
4.2. 流映射和使用
DNS 流量到 QUIC 流的映射利用了 [RFC9000] 第 2 节中详述的 QUIC 流特性.
通过 DoQ 连接发送的所有 DNS 消息 (查询和响应) MUST 编码为 2 个八位组的长度字段, 后跟 [RFC1035] 中指定的消息内容.
对于 QUIC 连接上的每个后续查询, 客户端 MUST 选择下一个可用的客户端发起双向流. 客户端 MUST 在所选流上发送 DNS 查询, 并且 MUST 通过 STREAM FIN 机制指示该流上不会再发送更多数据.
服务器 MUST 在同一流上发送响应, 并且 MUST 在最后一个响应之后通过 STREAM FIN 机制指示该流上不会再发送更多数据.
4.2.1. DNS 消息 ID
通过 QUIC 连接发送查询时, DNS Message ID MUST 设置为 0. DoQ 的流映射允许明确关联查询和响应, 因此不需要 Message ID 字段.
4.3. DoQ 错误码
定义以下错误码:
- DOQ_NO_ERROR (0x0): 无错误
- DOQ_INTERNAL_ERROR (0x1): 内部错误
- DOQ_PROTOCOL_ERROR (0x2): 协议错误
- DOQ_REQUEST_CANCELLED (0x3): 请求已取消
- DOQ_EXCESSIVE_LOAD (0x4): 负载过高
- DOQ_UNSPECIFIED_ERROR (0x5): 未指定错误
- DOQ_ERROR_RESERVED (0xd098ea5e): 预留用于测试
4.3.1. 事务取消
如果 DoQ 客户端希望取消未完成请求, 它 MUST 发出 QUIC STOP_SENDING, 并且 SHOULD 使用错误码 DOQ_REQUEST_CANCELLED.
4.3.2. 事务错误
服务器通常通过在事务流上发送 DNS 响应来完成事务. 如果服务器因内部错误无法发送 DNS 响应, 它 SHOULD 发出带有错误码 DOQ_INTERNAL_ERROR 的 QUIC RESET_STREAM 帧.
4.3.3. 协议错误
协议错误包括收到 Message ID 非零的消息、在收到所有预期数据之前收到 STREAM FIN, 或其他协议违规. 如果对等方遇到此类错误, 它 SHOULD 使用 QUIC 的 CONNECTION_CLOSE 机制并带错误码 DOQ_PROTOCOL_ERROR 强制中止连接.
4.3.4. 替代错误码
在非预期上下文中使用错误码或收到未知错误码, MUST 被视为等同于 DOQ_UNSPECIFIED_ERROR.
4.4. 连接管理
实现 DoQ 的客户端和服务器 SHOULD 协商使用空闲超时. 客户端 SHOULD 监控其连接上的空闲时间, 并在接近空闲超时时建立新连接.
4.5. 会话恢复和 0-RTT
如果服务器支持会话恢复和 0-RTT 机制, 客户端 MAY 利用它们. 0-RTT 机制 MUST NOT 用于发送不是"可重放"事务的 DNS 请求. 只有 OPCODE 为 QUERY 或 NOTIFY 的事务才被视为可重放.
4.6. 消息大小
DoQ 查询和响应在 QUIC 流上发送, QUIC 流最多可承载 2^62 字节. 但是, DNS 消息限制为最大 65535 字节. DoQ 实现始终假定最大消息大小为 65535 字节.