摘要

  • RFC 9952 把两个字节 0x63 0x6f(即 co)登记为 CoAP over DTLS 的 ALPN 标识,也允许 SVCB 用它做服务发现。但文档同时说明:RFC 7252 没有定义 DTLS 握手中的 ALPN 用法,而 RFC 9952 并未像 RFC 8323 那样补上一套规则。
  • 注册表证明共同词汇,DNS 证明某个发现声明;只有 ClientHello 的完整 offer 与 ServerHello 的 selection 或失败,才能证明一次实际协商。对端身份、CoAP 授权与应用结果仍是后续独立事实。

CoAP over TLS 已经使用四字节的 coap。RFC 9952 没有把它直接搬到 DTLS,而是另外注册两字节的 co。不同传输层不应共用同一 ALPN 名称;短两字节还可能降低受限链路上的握手大小,避免在临界点多出一个 6LoWPAN 分片。

这是一项合理的最小公共规范:所有参与者不再各造私有名称。但注册完成之后,权力并没有自动向上扩张。

文档中最重要的是“不建立规则”

IANA 表格回答的是:若某个实现或 profile 要用 ALPN 表示 CoAP over DTLS,应发送哪些字节。它不回答二进制是否包含功能、配置是否开启、客户端是否发送、服务器是否选择。

RFC 9952 特意指出,RFC 7252 原本没有定义 DTLS 连接握手中的 ALPN 扩展;新文档不改变这种行为,也不建立 RFC 8323 第 8.2 节那样的规则。因而“支持 RFC 9952 标识”与“每条连接必须协商 co”是两种完全不同的声明。

测试报告若声称合规,必须先指出依据的具体 profile。若本地 profile 把 co 设为强制项,测试就要保留配置和线上握手证据。若 profile 只是允许它,一条没有 ALPN 的连接不能仅凭 RFC 9952 被判违规。

DNS 广告只是候选输入

SVCB 的 alpn=co 可以帮助客户端发现服务。此时需要保留发布者、名称、RRset、验证状态、TTL、缓存年龄、别名处理、候选目标和本地选择策略。即使 DNSSEC 验证成功,它也只保护 DNS 回答的来源与完整性,不能证明目标进程已加载同一代配置。

发布与服务器升级可能不同步,缓存也可能保留旧视图。客户端还可能忽略 SVCB,走另一条发现路径。这些都不必然意味着某方撒谎;真正的问题是把 DNS、配置与握手合并成一个“ALPN 已部署”的绿灯。

握手回执有精确语法

RFC 7301 要求客户端在 ClientHello 中发送有序的 ProtocolNameList。服务器若选择协议,只能从列表中选一个并放入 ServerHello;若理解 ALPN 却不支持任何 offer,规范定义了致命的 no_application_protocol 告警。

一次可审计协商至少要记录连接标识、端点、DTLS 版本、完整 offer、selection 或失败、时间与采集位置。重试与 fallback 必须另有连接身份,否则第二次成功的 CoAP 应答很容易被错误归给第一次失败的握手。

两字节优势仍需现场测量

co 比 coap 少两字节,这是确定事实;是否少一个链路分片则不是。ClientHello 还包含密码套件、key share、签名算法、cookie、证书相关信息与其他扩展。DTLS 记录分片和 6LoWPAN 链路分片也不是同一层。

真正的效率结论需要同一命名配置下的前后数据:握手字节、链路分片数、重传、完成时间与失败率。注册表解释了设计动机,却不能替任何网络出具性能证明。

selection 之后还有身份和业务

即使抓包确认服务器选择了 co,也只证明该连接完成了这一小步。证书或原始公钥是否绑定预期服务、信任锚与有效期是否满足政策,仍需独立判断。随后还要激活正确的 CoAP 解析器、关联请求响应、执行方法与资源授权,最后才是应用是否允许产生状态变化。

完整证据链是:注册词汇、DNS 广告、客户端候选、ClientHello offer、ServerHello selection 或告警、对端身份、CoAP 交换、资源授权、应用效果、现场结果。前一步成功不能借走后一步的权力。

Lu Heng 的最小初始规范原则恰好解释这篇短 RFC 的价值:公共层只需要足够互操作的名称,未来部署决定留给承担后果的端点。现实层纪律阻止注册表替代数据包,也阻止数据包替代授权。运行代码优先要求检查实际加载的二进制、配置和交换,而不是制度性符号。

RFC 9952 没有因为篇幅短而不重要。它用最少规则解决命名问题,并拒绝把命名伪装成执行。成熟运营也应如此克制。

例外清单不是部署报告的附录

真实迁移几乎不会让整个设备群在同一时刻从“没有 co”跳到“已经使用 co”。有些传感器仍运行旧固件,有些网关查询另一组递归解析器,有些 SVCB 记录停留在缓存中,有些静态配置客户端根本不做 DNS 服务发现。它们决定了进程是否有机会看到广告、是否加载了支持能力、是否会把值写进 ClientHello。把这些路径压进一个“部署率 95%”的数字,恰好会抹掉事故解释所需的信息。

例外账本至少应写明负责人、设备或连接群、原因、软件与配置代次、截止日期和 fallback 行为。日期到了并不等于例外关闭;只有观测到最后一个相关 endpoint 离开旧路径,才算完成。只要替代路径仍然存在,每次连接就必须保留独立身份,每个 CoAP 效果也必须能归因到产生它的连接。第二次尝试成功,不能反向把第一次握手失败改写成成功。

一次发布的证据应连接四类工件。第一,含有支持代码的二进制或固件及其可验证摘要;第二,真正启用能力的配置与加载回执;第三,客户端当时看见的 DNS/SVCB 代次;第四,显示完整 offer、selection 或失败的连接 trace。它们彼此不能替代。新程序可能读取旧配置,新 DNS 可能指向旧 listener,一个 canary 成功也不能代表其他网络视图下的全部设备。

这种拆分同时暴露组织边界。DNS 团队能证明广告正确,却不能证明客户端发出了 ClientHello。平台团队能证明开关开启,却不能证明服务器选择了 co。安全团队能证明对端身份,却不能替资源策略授权。应用团队能看到状态变化,却可能不知道是哪次重试产生。上线报告必须先保留这些独立判定,再用连接标识、时间、端点与配置代次把它们连接起来。

从发布窗口走到可复核结论

灰度期间可以选择三个相互独立的观察群。控制群保持原有发现与握手行为;能力群加载支持但不发布 SVCB;发布群同时具备 DNS 广告与 endpoint 支持。这样的分组不是为了制造实验室式确定性,而是为了区分代码加载、发现输入和握手选择各自带来的变化。如果只比较“发布前后”,缓存更新、设备重启和无线损耗很容易被误写成 ALPN 效果。

每个群都应在固定时间窗内记录分母。看到广告的客户端数、实际 offer co 的连接数、服务器选择数、身份验证成功数、CoAP 操作完成数和业务效果数是六个不同分母。它们逐层减少并不必然是故障,却必须能够解释。只有这样,领导层看到的漏斗才是证据链,而不是把不相干的成功率拼成一条漂亮曲线。

回滚也需要相同精度。撤掉 SVCB 广告不会立即清除缓存,关闭服务器能力也不能保证客户端不再 offer,客户端停止 offer 更不代表旧连接已经结束。回滚计划应分别给出 DNS、客户端、服务器与连接存续期的完成条件,并明确哪些进行中的 CoAP 操作可以安全结束,哪些必须撤销或人工核对。可逆性来自这些边界,而不是来自一句“支持回滚”。

来源