摘要

  • RFC 2013 为整个 UDP 实现定义四个只读 Counter32:交给 UDP 用户的数据报、目标端口没有应用的数据报、其他输入交付错误,以及从该实体发出的数据报。
  • udpTable 的每行只用本地 IPv4 地址和端口索引。它证明管理代理当时表示一个本地监听坐标存在,却不包含远端、进程、socket 实例或单个数据报身份。
  • RFC 4113 后来加入本地与远端地址类型、地址、端口、实例判别和进程标识,把端点身份变得更明确;这些字段仍不能替代应用处理、回复送达或服务结果的证据。

先问计数器在数什么

RFC 2013 的 UDP 组小得近乎克制。udpInDatagrams 统计“交付给 UDP 用户”的数据报;udpNoPorts 统计目标端口没有应用的接收数据报;udpInErrors 统计因其他原因无法交付的接收数据报;udpOutDatagrams 统计从该实体发出的数据报。四个对象都是只读 Counter32。

这四个口径可以回答有价值的问题。它们把进入 UDP 用户边界、撞上空端口、遇到其他输入错误和离开本实体的数量分开,不应被贬成毫无意义的数字。但它们的对象单位是整个 UDP 引擎,不是端点,不是进程,也不是一次对话。计数器没有远端地址、端口、消息 ID、时间戳或请求与回复的配对字段。

同时代的 RFC 1902 还为 Counter32 划了一条更基础的界线:数值单调增加到 2^32−1 后回绕;计数器没有规定的初始值;单独读取一次通常没有信息内容;管理系统重启等事件会造成不连续。因此,解释变化至少要有两个采样点和连续性证据。即使差值完全可信,它也只证明某个口径在区间内增加,不能自行回答是哪一个端口、哪个远端或哪个程序造成的。

本地坐标不等于通信双方

udpTable 把观察从全机总量推进到当前监听者。RFC 2013 说,表里记录的是本地应用正在接受数据报的 UDP 端点。每行的索引只有 udpLocalAddress 和 udpLocalPort。绑定所有本地接口时,地址写作 0.0.0.0;端口范围为 0 到 65535。

因此,一行表项能可靠表达的命题是:在采样时刻,管理代理把这个本地 IPv4 地址与端口表示为当前监听坐标。它没有远端地址或端口,没有进程号,没有 socket 实例判别,没有每行收发计数,也没有创建时间。

“正在接受数据报”很容易被读成应用故事。可是表项不告诉我们是哪一个进程持有端口,不告诉我们某个数据报来自谁,也不告诉我们进程是否从缓冲区读走、解析、授权并执行了请求。它更不会记录应用是否生成回复、回复是否到达对端、用户是否得到预期服务。端口在,最多说明门牌和门口存在;访客、接待人和办成的事情仍要另找收据。

“已交给 UDP 用户”不是“应用已经办完”

四个计数器中,最需要精确阅读的是 udpInDatagrams。规范的措辞并非“网卡看见”,而是“交付给 UDP 用户”。这已经跨过了一个真实的协议边界。写作时不能把它含糊成任意报文出现。

但 UDP 层的交付也不是应用结果。计数器不证明程序已经读取缓冲区、接受内容、写入状态或完成事务。udpNoPorts 证明被统计的数据报没有目标应用,却不保留发送者和原始内容。udpInErrors 把“并非缺少应用”的其他交付失败合并到一个总量里。udpOutDatagrams 证明实体侧执行了发送统计,不证明网络另一端收到,更不证明远端应用处理成功。

如果把四个总数和端口表直接拼成一次请求—回复链条,就等于在数据库之外发明了关联。正确做法不是否定这些对象,而是承认它们各自只覆盖一层现实。

RFC 4113 把“是哪一个端点”重新设计了一遍

2005 年的 RFC 4113 取代 RFC 2013 时,保留四个基础计数器,却弃用了旧 udpTable。它给出两个互不相同的理由:旧表只支持 IPv4;旧表不能描述“connected” UDP 端点。前一个问题属于地址族可见性史,已经由 RFC 2011 文章负责;后一个问题正好揭示本篇的身份缺口。

新的 udpEndpointTable 可表示通配监听,也可表示限定到具体远端的端点。索引包含本地地址类型、地址与端口,远端地址类型、地址与端口,以及 udpEndpointInstance。最后这个实例值用于区分复用同一端点元组的多个进程,包括 SO_REUSEADDR 和 SO_REUSEPORT 场景。行内还增加 udpEndpointProcess,报告关联的操作系统进程 ID;没有时为零,并可与 Host Resources MIB 或 SYSAPPL-MIB 对照。

这不是把无连接传输伪装成可靠会话,而是承认管理身份需要更多坐标。运维者终于可以区分“任何远端”和“指定远端”,区分同一元组上的不同实例,并把端点尝试连到一个本机进程。RFC 4113 也因此提醒:端点索引会泄露开放端口,读取本身可能敏感。

然而,新的索引仍不是应用事务。进程 ID 可以为零、可以复用,也只在特定系统上下文内有效。指定远端描述 socket 的约束,不证明某枚数据报确实到达。实例号不会告诉你负载是否通过业务校验,进程号不会告诉你回复是否抵达客户。

记录应该描述现实,而不是替现实下结论

RFC 2013 没有承诺成为完整的对话账本,因此不应因为它保持简洁而被定罪。真正的风险来自后来的解释者:把一个本地监听行当作通信双方,把实体级差值当作某服务的流量,把“sent”写成“delivered”,把 UDP 用户边界写成业务完成。

较诚实的表述会带上限制:在连续性相容的两个采样点之间,某个实体级计数器增加;在某个采样时刻,本地端口由代理表示为监听状态。要进一步归因,需要把报文或事件身份与端点状态相连;要声称应用处理,需要应用收据;要声称远端送达,需要另一端证据;要声称服务成功,则必须在服务层定义并观察结果。

这段历史最终留下三个不同单位:端口是坐标,计数器是口径,对话是经过归因的一串事件。RFC 4113 扩大了端点问责面,但没有替应用签署结果。

来源

证据边界

这些来源可以证明文档沿革、对象定义、计数器语义与后继模型;不能证明厂商实现、部署率、当前默认设置、产品缺陷、现实事故、SLA、实测流量或应用事务已经完成。