跳到主要内容

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 字节.