查看文章 |
离开一个多播组(最简单的情况)
2007年01月03日 星期三 下午 10:37
应用程序通过命令字IP_DROP_MEMBERSHIP使一个socket离开一个多播组,IP_DROP_MEMBERSHIP是一个IP层的命令字,其调用使用的参数是结构体struct ip_mreq。该结构体的两个成员分别用于指定所要离开的多播组的组IP地址,和所要离开组的那个本地接口的IP地址。 ip_setsockopt实现了该命令字,它通过调用ip_mc_leave_group使socket离开一个多播组。 表示INET域socket的结构体struct inet_sock的成员mc_list是该socket所加入的所有多播组的一个链表,ip_mc_leave_group从该链表中去匹配所要离开的组(匹配条件是组地址相同,本地网络接口相同),找到一个结构体struct ip_mc_socklist节点。 首先要从该节点中删去源列表,同时把该节点从socket中删除,因为我们现在所关注的IP_DROP_MEMBERSHIP所要离开的组是通过IP_ADD_MEMBERSHIP加入的,没有源过滤机制,只要把节点从socket中删除即可。 然后,还需要从网络接口struct in_device中删掉这个组,以使网络硬件设备以后可以过滤掉发往这个组的数据报。首先从struct in_device的成员mc_list链表中去匹配一个struct ip_mc_list结构体节点(匹配条件是组地址相同即可)。 如果节点的成员loaded不为0,表示硬件过滤机制正接收该组的数据报。则调用ip_mc_filter_del从网络设备接口的结构体struct net_device的成员mc_list链表中删去相应的节点struct dev_mc_list,并通过调用网络设备接口的成员函数set_multicast_list来更新设备的过滤机制。 如果所要离开的组不是IGMP_ALL_HOSTS(224.0.0.1),则首先停止节点本身的定时器(用于IGMPv1和IGMPv2的主动报告),然后把要删除的节点从struct in_device的mc_list链表移到mc_tomb链表上,表示这是将要删除的一个组,在稍后发送状态改变报告时有用。 最后启用定时器struct in_device->mr_ifc_timer(接口状态改变定时器),发送主动成员报告。测试环境中要离开的多播组中是224.0.1.1,发出的IGMPv3报告如下: 数据 含义 22 第3版成员关系报告 00 8bit保留,必须为0 f9 fc 校验和 00 00 16bit保留,必须为0 00 01 组记录的数量,为1 下面为一条组记录: 03 组记录类型为CHANGE_TO_INCLUDE_MODE,改变到INCLUDE模式 00 辅助数据长度 00 00 源地址的数量 e0 00 01 01 组地址224.0.1.1 即:组224.0.1.1的过滤模式从原来的EXCLUDE(过滤的源为空)变到现在的INCLUDE(包含的源为空),也就是离开了多播组224.0.1.1。 |
最近读者: