3. 系统维护的组播接收状态
3. 系统维护的组播接收状态
3.1. 套接字状态
对于已调用 IPMulticastListen 的每个套接字 (socket), 系统记录该套接字所需的组播接收状态. 该状态在概念上由一组以下形式的记录组成:
(interface, multicast-address, filter-mode, source-list)
套接字状态根据在套接字上每次调用 IPMulticastListen 而演化, 如下所示:
-
如果请求的过滤模式是 INCLUDE 且请求的源列表为空, 则删除与请求的接口和组播地址对应的条目 (如果存在). 如果不存在这样的条目, 则忽略该请求.
-
如果请求的过滤模式是 EXCLUDE 或请求的源列表非空, 则更改与请求的接口和组播地址对应的条目 (如果存在) 以包含请求的过滤模式和源列表. 如果不存在这样的条目, 则使用请求中指定的参数创建新条目.
3.2. 接口状态
除了每个套接字的组播接收状态外, 系统还必须为其每个接口维护或计算组播接收状态. 该状态在概念上由一组以下形式的记录组成:
(multicast-address, filter-mode, source-list)
对于给定接口, 每个组播地址最多存在一条记录. 此每接口状态派生自每套接字状态, 但当不同套接字对同一组播地址和接口具有不同的过滤模式和/或源列表时, 可能与每套接字状态不同. 例如, 假设一个应用程序或进程在套接字 s1 上调用以下操作:
IPMulticastListen ( s1, i, m, INCLUDE, {a, b, c} )
请求在接口 i 上接收发送到组播地址 m 的数据包, 仅当它们来自源 a、b 或 c 时. 假设另一个应用程序或进程在套接字 s2 上调用以下操作:
IPMulticastListen ( s2, i, m, INCLUDE, {b, c, d} )
请求在同一接口 i 上接收发送到同一组播地址 m 的数据包, 仅当它们来自源 b、c 或 d 时. 为了满足两个套接字的接收要求, 接口 i 必须接收从源 a、b、c 或 d 中的任何一个发送到 m 的数据包. 因此, 在此示例中, 接口 i 对于组播地址 m 的接收状态具有过滤模式 INCLUDE 和源列表 {a, b, c, d}.
在 IP 层从接口接受组播数据包之后, 其后续传递到侦听特定套接字的应用程序或进程取决于该套接字的组播接收状态 [并且可能还取决于其他条件, 例如套接字绑定到哪个传输层端口]. 因此, 在上面的示例中, 如果一个数据包到达接口 i, 目的地为组播地址 m, 源地址为 a, 它将在套接字 s1 上传递, 但不在套接字 s2 上. 请注意, IGMP 查询 (Query) 和报告 (Report) 不受源过滤的影响, 必须始终由主机和路由器处理.
基于套接字的组播接收状态过滤数据包是此服务接口的新功能. 以前的服务接口 [RFC1112] 没有描述基于组播加入状态的过滤; 相反, 在套接字上的加入只是导致主机在给定接口上加入一个组, 并且发往该组的数据包可以传递到所有套接字, 无论它们是否已加入.
从每套接字状态派生每接口状态的一般规则如下: 对于出现在任何套接字状态中的每个不同的 (interface, multicast-address) 对, 在该接口上为该组播地址创建一个每接口记录. 考虑包含相同 (interface, multicast-address) 对的所有套接字记录,
- 如果任何此类记录的过滤模式为 EXCLUDE, 则接口记录的过滤模式为 EXCLUDE, 接口记录的源列表是所有处于 EXCLUDE 模式的套接字记录的源列表的交集, 减去出现在任何处于 INCLUDE 模式的套接字记录中的那些源地址. 例如, 如果接口 i 上组播地址 m 的套接字记录是:
来自套接字 s1: ( i, m, EXCLUDE, {a, b, c, d} )
来自套接字 s2: ( i, m, EXCLUDE, {b, c, d, e} )
来自套接字 s3: ( i, m, INCLUDE, {d, e, f} )
则接口 i 上相应的接口记录是:
( m, EXCLUDE, {b, c} )
如果添加第四个套接字, 例如:
来自套接字 s4: ( i, m, EXCLUDE, {} )
则接口记录变为:
( m, EXCLUDE, {} )
- 如果所有此类记录的过滤模式都是 INCLUDE, 则接口记录的过滤模式为 INCLUDE, 接口记录的源列表是所有套接字记录的源列表的并集. 例如, 如果接口 i 上组播地址 m 的套接字记录是:
来自套接字 s1: ( i, m, INCLUDE, {a, b, c} )
来自套接字 s2: ( i, m, INCLUDE, {b, c, d} )
来自套接字 s3: ( i, m, INCLUDE, {e, f} )
则接口 i 上相应的接口记录是:
( m, INCLUDE, {a, b, c, d, e, f} )
当该组的所有套接字都处于 INCLUDE 状态时, 实现不得使用 EXCLUDE 接口记录来表示该组. 如果在计算接口状态源列表时达到系统资源限制, 则必须向请求操作的应用程序返回错误.
每当 IPMulticastListen 调用通过添加、删除或修改每套接字状态记录来修改套接字状态时, 就会 (重新) 评估上述派生接口状态的规则. 请注意, 套接字状态的更改不一定导致接口状态的更改.