摘要

  • RFC 3678 为保留源代码与二进制兼容性,没有改写旧的组播成员调用,而是在其旁边增加了源过滤选项与函数。
  • 增量操作改变当前过滤器中的一个来源;完整状态操作则同时替换模式和来源列表。RFC 3678 指出,不离开组就切换 INCLUDE/EXCLUDE 模式需要后一种方式;列表较大时,它也能让整次改动以一个原子操作完成。

旧调用不能随意扩宽

第一道约束不是路由器,而是已经依赖套接字接口的程序。源过滤出现之前,组播接收端可以加入一个组,必要时再选定本地接口;但它不能进一步说明自己愿意接收哪些发送源。直接改动原有调用来塞进这些信息,会危及二进制兼容性。RFC 3678 明确指出:要保住既有程序,就不能改写旧接口。

因此,这份备忘录选择在旁边增加新能力。新 API 既要保持源代码兼容——旧源码仍可编译并运行——也要保持二进制兼容——已编译的程序在支持扩展的系统上仍可继续运行。文档还要求尽量少改,并让应用能够发现新 API 不可用后妥善处理。这是一份信息性 API 设计说明,不是所有操作系统都实现了相同调用的证据。RFC 3678

一次改一个来源

增量接口逐步修改过滤状态。对任意源组播成员,接收端起初通常接受各种来源,再用阻止或解除阻止的操作改变某个发送源的待遇。对特定源组播,则把某个来源加入或移出想接收的集合。调用前的状态很重要:文档区分了不合法的成员/选项组合,也区分“来源已被阻止”或“从未加入该来源”等错误情形。

当应用只要做一个小改动时,这套语法较为省事。它可以说“阻止这个源”或“加入这个源”,不用重发整张列表。不过,这条命令的含义取决于当前成员关系和过滤模式;它只描述一个增量,并不完整声明调用结束后过滤器应该是什么样子。RFC 3678 同时规定了 IPv4 专用选项(如 IP_ADD_SOURCE_MEMBERSHIP)和与地址族无关的选项(如 MCAST_JOIN_SOURCE_GROUP)。RFC 3678

或一次替换全部状态

完整状态 API 解决的是另一类问题。应用交出过滤模式——MCAST_INCLUDE 或 MCAST_EXCLUDE——以及要包含或排除的整个来源列表;这次调用替换旧过滤器,而不是在旧状态上增删一项。

RFC 3678 点出两种特别需要这种表达的情形。应用若要在不离开组的情况下从 INCLUDE 切换为 EXCLUDE,必须使用完整状态 API。来源列表较大时,也建议这样做,因为整张列表可以在一次操作中原子替换。一串增量操作或许最终能得到同一集合,但中间会经过若干逐步变化的状态。

读取完整状态也有自己的约定:调用方可以先估计缓冲区大小,返回值会告知来源总数;若缓冲区偏小,应用可以再读一次。如果某个实现对列表长度设有上限,超过上限的设置可能返回 ENOBUFS。所以“整体替换”是状态管理方式,不是无限容量承诺。RFC 3678

一个组,两个地址族

文档保留了 IPv4 专用结构和选项,目的是减少现有 IPv4 程序为支持源过滤所需的改动;与此同时,它也定义了地址族无关的形式。后者用能够容纳不同地址族的套接字结构携带组地址和来源地址,再用接口索引单独标识本地网络接口。RFC 3493 已提供不少 IPv6 套接字基础,但没有提供地址族无关的组播加入与离开操作;RFC 3678 补上了这一段。RFC 3493

读函数签名时很容易把三件事混在一起:组地址标识组播目的地,源地址标识发送者,接口索引则把操作限制在本机的一个连接点。后来验证通过的技术勘误 2524 修正了第 5.2.2 节对 getsourcefilter 参数的描述:原文“接口的本地 IP 地址”应为“接口索引”,与前一节的设置函数保持一致。另一项已验证的编辑性勘误,修正了指向不存在错误码小节的交叉引用。这些勘误没有改变过滤模型,却厘清了参数本身的含义。RFC 3678 勘误

本机过滤不等于网络各处过滤

即使路由器不支持 IGMPv3 或 MLDv2,操作系统仍可能在本机执行源过滤。因此,应用可能获得主机侧效果,却不能据此证明不想要的数据包不再穿过本地链路。相关协议会把过滤信息传向路由器;那是与套接字调用不同的网络机制,有自己的状态与路径。RFC 3376、RFC 3810 和 RFC 4604 描述了这条网络侧机制的部分行为。RFC 3376 RFC 3810 RFC 4604

过滤器也不会认证发送者。RFC 3678 提醒,若攻击者把来源地址伪造成获准的来源,仅靠源过滤无法阻止该数据包;反向路径检查在某些路由安排中有帮助,却不构成保证。一次套接字调用成功,只能证明 API 操作被接受,不能单独证明路由器状态、带宽下降、流量真实、数据包抵达或应用处理成功。RFC 3678

RFC 3678 属于 Informational 文档,并明确表示它不是互联网标准;它也将读者引向正式的套接字规范。它的历史贡献更具体:既有成员调用得到保护,改单个发送源的成本较低,而当状态切换或列表规模需要时,完整过滤器仍可一次换掉。Lu Heng 后来写下的 Note 64 与 Note 65,在这里仅作为观察兼容性与本地采纳的分析视角;它们不是 RFC 的作者、背书者或 2004 年设计的成因。RFC 3678 状态页 Note 64 Note 65

来源