跳到主要内容

1. 引言

本文档规定一种用于管理有状态 DNS 连接的机制. DNS 最常见的是在 UDP 传输上运行, 但也可以在流式传输上运行. 原始 DNS RFC 规定了 DNS-over-TCP [RFC1035], 并且已经规定了 DNS-over-TLS [RFC7858] 的配置文件. 这些传输可以提供持久的长期会话, 因而在使用它们传输 DNS 消息时, 拥有一种可建立与这些会话相关参数 (例如超时) 的机制会很有益. 在这类情况下, 支持服务器发起的消息 (例如 DNS Push Notifications [Push]) 也很有价值.

现有的 Extension Mechanism for DNS (EDNS(0)) [RFC6891] 明确定义为只具有 "per-message" 语义. 虽然 EDNS(0) 已被用于信令至少一个与会话相关的参数 (edns-tcp-keepalive EDNS(0) Option [RFC7828]), 但由于 EDNS(0) 语义施加的限制以及缺少服务器发起信令, 其结果并不理想. 例如, 服务器不能任意指示客户端关闭连接, 因为服务器只能在对包含 EDNS(0) 选项的查询的响应中发送 EDNS(0) 选项.

本文档为 DNS Stateful Operations (DSO) 定义一个新的 DNS OPCODE, 其值为 6. DSO 消息用于在持久有状态会话内传达操作, 这些操作使用 Type Length Value (TLV) 语法表示. 本文档定义了初始的三个 TLV 集合, 用于管理会话超时, 终止和加密填充.

这里定义的三个 TLV 对所有 DSO 实现都是强制性的. 后续规范可以定义更多 TLV.

DSO 消息可以被确认, 也可以不被确认. 某个 DSO 消息是否需要确认 (DSO 请求消息) 或不需要确认 (DSO 单向消息), 由该特定 DSO 消息类型的定义规定. 对于 DSO 请求消息, MESSAGE ID 非零. 对于 DSO 单向消息, MESSAGE ID 为零. 消息采用流水线方式处理, 当多个请求并发处理时, 响应可能乱序出现.

DSO 消息格式 (第 5.4 节) 与用于标准查询和响应的传统 DNS 消息格式略有不同. 它使用标准的十二字节头部, 但四个计数字段 (QDCOUNT, ANCOUNT, NSCOUNT, ARCOUNT) 都设置为零, 因而对应的各节不存在.

与 DNS Stateful Operations 有关的实际数据 (以 TLV 语法表示) 追加在 DNS 消息头部末尾. 与传统 DNS-over-TCP [RFC1035] [RFC7766] 一样, 承载 DSO 消息 (它们只是另一种 DNS 消息) 的流协议通过在开头放置 16 位消息长度来成帧. 因此, DSO 消息长度由该长度确定, 而不是由任何 DNS 头部计数字段确定.

使用尚未更新以识别 DSO 格式的数据包分析工具显示时, 这会导致 DSO 数据显示为 DNS 消息末尾之后的未知额外数据.

这种新格式相比基于 RR 的格式具有明显优势, 因为它更明确也更紧凑. 每个 TLV 定义都特定于其用例, 因而不包含冗余字段或重载字段. 更重要的是, 它完全避免以任何方式将 DNS Stateful Operations 与普通 DNS 操作或现有基于 EDNS(0) 的功能混同起来. 该方法的一个目标是避免 EDNS(0) 遭遇过的运行问题, 尤其是与中间盒行为相关的问题 (见近期描述 DNS 故障原因的工作 [Fail] 中讨论 EDNS(0) 以及防火墙和负载均衡器造成问题的章节).

使用 EDNS(0) 时, 多个选项可以打包到单个 OPT 伪 RR 中, 并且没有通用机制让客户端能够判断服务器是否已处理或以其他方式作用于组合 OPT 伪 RR 中的每个单独选项. 每个单独选项的规范需要定义必要时应如何确认各个不同选项.

与 EDNS(0) 相比, DSO 没有强烈动机为了效率把多个操作打包到单个消息中, 因为 DSO 总是使用面向连接的传输协议运行. 每个 DSO 操作都在自己的单独 DNS 消息中传达, 如果合适, 传输协议可以负责将若干 DNS 消息打包进单个 IP 数据包. 例如, TCP 可以把多个小 DNS 消息打包到一个 TCP 段中. 这种简化带来了更清晰的语义. 每个 DSO 请求消息只传达一个主要操作, 对应响应消息中的 RCODE 指示该操作成功或失败.