RFC 3376

1. Introduction

网际组管理协议(IGMP)被用于IPv4系统(主机和路由器)向临近的多播路由器报告他们的IP多播组成员。

多播路由器应当仅管理所在网络的多个IP多播组的组成员,分开管理。

注意一个IP多播路由器可能自己就是一个或多个多播组的成员之一,在这种情况下,它既执行协议的”多播路由部分“(收集它的多播路由协议需要的成员信息),也执行协议的”组成员部分“(通知它自己和其他,临近的多播路由器它的成员身份)。

IGMP也被用于其他的IP多播管理函数,使用非用于组成员报告的消息类型。本文档仅指定组成员报告函数和消息。

本文档指定 IGMP版本3。版本1,在[RFC-1112]中指定,是第一个广泛应用的版本,也是第一个成为互联网标准的版本。版本2,在[RFC-2236]中指定,添加了对"low leave latency"的支持,即,多播路由器知道在关联的网络上,当前在特定组中没有任何成员这一行为花费的时间减少了。版本3添加对”source filtering“支持,即,一个系统报告仅对接收到的来自特定源地址的包(发送到特定的组播地址)感兴趣,以支持源特定多播(Source-Specific Multicast,SSM),或者来自除指定源地址以外的 所有 源地址。版本3 在设计上继承 Version 1 和 2。

Multicast Listener Discovery (MLD) 在IPv6系统中使用的方法类似。MLD 版本1 实现 IGMP 版本2 的功能,MLD 版本2 实现 IGMP 版本3 的功能。

2. The Service Interface for Requesting IP Multicast Reception

在一个IP系统中,有一个(至少在概念上)服务接口被用于上层协议或应用程序来请求IP层启用或禁止发送到指定IP组播地址的数据包的接收。为了充分利用IGMPv3的能力,一个系统的IP服务接口必须支持下列的操作:

IPMulticastListen( socket, interface, multicast-address, filter-mode, source-list )

其中:

  • “socket” 是一个实现指定的参数,用于区分系统中不同的请求实体(e.g. 程序或进程),BSD Unix 系统调用的socket参数是一个特定的例子。
  • ”interface“ 是一个本地网络接口 (network interface) 标识符,在其上启用/关闭特定对发送向特定IP多播地址的包的接收。接口可能是物理的 (e.g., 一个以太网接口) 或虚拟的。一个实现可能允许一个特殊的”未指定“的值作为接口参数被传递,在这种情况下,请求将应用于系统上”primary“或”default“的接口 (或由系统配置建立)。如果相同多播地址的接受需求超过一个接口,IPMulticastListen 将为每个就扣分别触发。
  • ”multicast-address“ 是IP多播地址,或请求相关组。如果在给定接口上有超出一个多播地址的接受被期望,IPMulticastListen 为每个期望的多播地址分别调用。
  • ”filter-mode“ 可以是INCLUDE或EXCLUDE。在INCLUDE模式下,请求仅接受来自在source-list参数中列出的这些IP源地址向指定多播地址发送的数据包。在EXCLUDE模式中,请求接受来自所以IP源地址除了在source-list参数中列出的这些IP源地址向指定多播地址发送的数据包。
  • ”source-list“ 是一个包含0个或多个IP单播地址的无序列表,表明是否接受源自这些源地址上IP多播。一个实现可能会对source-list的长度附加一些限制,但是这个限制不能小于每个列表64个地址。当某个操作造成源地址列表的限制尺寸被超出,那个服务接口必须返回一个错误。

对于一个 socket,interface, 和 multicast address 的给定结合,任意时间点,仅有一个过滤模式和源地址列表生效。然而,无论是过滤模式还是源地址列表,亦或是二者都是,都可能因为随后的 指定了相同的 socket, interface, 和 multicast address 的 IPMulticastListen 请求而被改变。每个随后的请求都会完全取代早期具有相同socket, interface, 和 multicast address的请求。

早期版本的IGMP不支持源过滤,有一个更简单的服务接口,由Join和Leave操作组成,来启用和禁用一个给定接口上的给定多播地址在所有源地址上的接受。

Join 操作等价于

IPMulticastListen (socket, interface, multicast-address, EXCLUDE, {})

Leave 操作等价于

IPMulticastListen (socket, interface, multicast-address, INCLUDE, {}

其中,{} 表示一个空的源列表。

3. Multicast Reception State Maintained by Systemss

3.1 Socket State

对于每个 IPMulticastListen 调用的 socket,系统位该 socket 记录期望的多播接受状态。该状态概念上由一系列下述格式的记录组成:

(interface, multicast-address, filter-mode, source-list)

每次在 socket 上调用 IPMulticastListen 都会导致 socket 状态改变,如下:

  • 如果请求的过滤模式是 INCLUDE,且请求源列表是空,那么对应请求的接口和多播地址的 entry 如果存在则被删除。如果没有这样的entry,请求被忽略。
  • 如果请求得过滤模式是 EXCLUDE 或 请求得得源列表非空,那么对应请求的接口和多播地址的 entry 如果存在,则变为请求得过滤模式和源地址。如果这样得 entry 不存在,则使用请求指定得参数创建一个新得 entry。

无 entry 表示过滤所有源地址,不接受任何来自于该接口该多播地址得多播数据。

3.2 Interface State

除了pre-socket multicast reception 状态,系统还必须维护或计算它的每个接口的多播接受状态。该状态概念上由一组如下格式的记录组成:

(multicast-address, filter-mode, source-list)

对于给定的接口,每个 multicast-address 至多有一条记录。这个 per-interface 状态继承于 per-socket 状态,但可能与 per-socket 状态不同,当不同的socket对相同的多播地址和接口有不同的过滤模式且/或不同源列表。例如,假设一个应用或进程在 socket s2 上调用下述操作:

IPMulticastListen(s1, i, m, INCLUDE, {a, b, c})

以请求接受发送到接口i来自多播地址m,且源地址为 a, b, c 之一的数据包。假设另一个应用或进程在socket s2 上调用下述操作:

IPMulticastListen(s2, i, m, INCLUDE, {b, c, d})

请求接受发送到相同的接口i,来自相同多播地址m的数据包,但是源地址要求为 b,c,d 之一。为了同时满足两个sockets的接受需求,接口必须接收发送向多播地址m的且源地址为 a, b, c, d 之一的所有数据包。因此,在这个例子中,接口的接受状态为

(m, INCLUDE, {a, b, c, d})

在多播数据包在IP层被接口接受之后,它随后被递交到在特定套接字上监听的应用或进程 (递交与否取决于套接字的多播接受状态,还可能有其他情况,比如套接字绑定的传输层端口)。所以,在上述例子中,如果一个包到达了接口i,目的是多播地址m,源地址为a,它将被递交到 socket s1,而非 socket s2。注意,IGMP 查询和报告不受源过滤的影响且总是被主机和路由器处理。

基于socket的多播接受状态的包的过滤是该服务接口的新特性。早期的服务接口[RFC1112]描述了非基于过滤的多播连接状态;然而,套接字上的加入简单的造成主机加入接口上的多播组,目的为该多播组的包将会被递交到所有的套接字,无论该套接字是否加入改组。

递交来自per-socket 状态的 per-interface 状态的为per-socket status求并集,以不影响每个per-socket状态为条件求最小并集。

4. Multicast

4.1 Options

4.1.1 IP_ADD_MEMBERSHIP,IPV6_JOIN_GROUP,MCAST_JOIN_GROUP

在指定本地接口加入不限源的多播组。

struct in_addr { 		// internet address
	in_addr_t s_addr; 	// socket address, uint32_t
};

struct sockaddr_in {
	uint8_t sin_len; 			// length of internet socket
	sa_family_t sin_family;		// AF_INET
	in_port_t sin_port;       	// network byte ordered, 16 bits
	struct in_addr sin_addr;	// network byte ordered, 32 bits
	char sin_zero[8];			// unused
};
struct ip_mreq {
	// IPv4, 使用某个单播地址指定本地接口
	struct in_addr imr_multiaddr;	/*IPv4 class D multicast addr*/
	struct in_addr imr_interface;	/*IPv4 addr of local interface*/
};
// IPv6, 使用某个接口索引指定本地接口
struct ipv6_mreq {
	struct in6_addr ipv6mr_multiaddr; 	/*IPv6 multicast addr*/
	unsigned int 	ipv6mr_interface;	/*interface index, or 0*/
};
// 协议无关, 使用某个接口索引指定本地接口
struct group_req {
    unsigned int			gr_interface;	/*interface index, or 0*/
	struct sockaddr_storage	gr_froup;		/*IPv4 or IPv6 multicast addr*/
}

如果本地接口指定为IPv4的通配地址(INADDR_ANY) 或 IPv6 值为0的索引,那就由内核选择一个本地接口。
一个给定套接字可以多次加入不同/同一多播组(multicast_addr),对于不同多播组,不能以同一多播地址加入,对于同一多播组,不能以相同的multicast address 和 interface 结合加入。

4.1.2 IP_DROP_MEMBERSHIP,IPV6_LEAVE_GROUP和MCAST_LEAVE_GROUP

离开一个本地接口上不限源的多播组。如果未指定本地接口(IPV4接口指定未INADDR_ANY,IPV6接口索引值为0),那么抹除首个匹配的多播组成员关系。
如果一个进程加入某个多播组后从不显式的离开该组,则当套接字关闭时,会自动离开。单个主机上可能有多个套接字加入相同的多播组,任一的套接字离开多播组,不影响主机作为该多播组的成员,直到其上所有的套接字都离开该多播组。

4.1.3 IP_BLOCK_SOURCE 和 MCAST_BLOCK_SOURCE

对于给定的本地接口上的一个不限源的多播组,在本套接字上阻塞接收来自指定源的多播分组。

struct ip_mreq_source {
	struct in_addr imr_multiaddr;	/*IPv4 class D multicast addr*/
	struct in_addr imr_sourceaddr;	/*IPv4 source addr*/
	struct in_addr imr_interface; 	/*IPv4 addr of local interface*/
};

struct group_source_req {
	unsigned int 			gsr_interface; /*interface index. or 0*/
	struct sockaddr_storage	gsr_group; 	   /*IPv4 or IPv6 multicast addr*/
	struct sockaddr_storage gsr_source;	   /*IPv4 or IPv6 source addr*/
};

如果本地接口被指定为IPv4的通配地址(INADDR_ANY)或与协议无关的API的0值索引,那就由内核选择首个匹配的多播成员关系对应的多播组。

4.1.4 IP_UNBLOCK_SOURCE 和 MCAST_UNBLOCK_SOURCE

开通一个先前被阻塞的源。如果未指定本地接口,则开通首个匹配的阻塞源。

4.1.5 IP_ADD_SOURCE_MEMBERSHIP 和 MCAST_JOIN_SOURCE_GROUP

在一个本地接口上加入一个特定于源的多播组。

4.1.6 IP_DROP_SOURCE_MEMBERSHIP 和 MCAST_LEAVE_SOURCE_GROUP

在一个本地接口上离开一个特定于源的多播组。

4.1.7 IP_MULTICAST_IF 和 IPV6_MULTICAST_IF

指定通过本套接字发送的多播数据报的外出接口。如果其值对于IPv4为通配地址(INADDR_ANY),对于IPv6为接口索引值为0,则先前通过本套接字选项指定的任何接口都将被抹除,系统改为每次发送数据都选择外出接口。
注意仔细区分当进程加入多播组时指定的(或由内核选定的)本地接口(到达多播数据报通过该接口接收)以及当进程送出多播数据报时指定的(或由内核选定)本地接口。

4.1.8 IP_MULTICAST_TTL 和 IPV6_MULTICAST_HOPS

给外出多播数据报设置IPv4的TTL或IPv6的跳限。如果不指定,则两个版本都默认为1,从而把多播数据报限制在本地子网。

4.1.9 IP_MULTICAST_LOOP 和 IPV6_MULTICAST_LOOP

开启或关闭多播数据报的本地自环(即回馈)。默认回馈开启,如果一个主机上在某个接口上属于某个多播组,则该主机上的由某个进程发送的目的地为该多播组的每个数据报都会有一个副本回馈,被改主机作为一个收取的数据报处理。

类似广播的是,一个主机上发送的任何广播数据报也被该主机作为收取的数据报处理(对于广播而言,这种回馈无法禁止)。这一点意味着,如果一个进程同时属于所发送数据报的目的多播组,它就会收到自己发送的任何数据报。

上述9个套接字选项中,前6个影响多播数据报的接收,后3个影响多播数据报的发送(外出接口,TTL或跳限及回馈)。多播数据报的发送如果没有任何特使处理,将会使用默认值,外出接口由内核选择,TTL或跳限为1,并由一个副本自环回来。

为了接收目的地址为某个组地址,且目的端口为某个端口的多播数据报,进程必须加入该多播组,并捆绑该端口到某个UDP套接字。这两个操作时截然不同的,不过都是必须的。多播组的加入操作告知所在主机的IP层和数据链路层接收发往该组的多播数据报。端口捆绑操作则是应用进程向UDP指示它想接收发往该端口的数据报。有些应用进程除端口之外还把多播地址绑定到某个套接字,从而防止所在主机IP层为该端口收取的目的地址为其他单播,广播或多播地址的数据报递交到该套接字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值