第12章 IP多播:IGMP
所属:TCP/IP详解 卷2:实现 来源:TCP/IP详解 卷2:实现
本章描述IP多播和IGMP(Internet组管理协议)的实现,包括IGMP报文格式、组成员管理、多播数据的收发等。
12.1 引言
什么是IP多播
IP多播(IP Multicast):
- 一对多的通信
- 发送一次,多个接收者收到
- 用D类地址标识组
- 节省带宽,提高效率
多播是高效的一对多通信方式。
什么是IGMP
IGMP(Internet Group Management Protocol):
- 主机向路由器报告组成员关系
- 路由器知道哪些组在局域网上有成员
- 用于IP多播的组管理
- IGMPv1和IGMPv2
IGMP是多播的组管理协议。
IGMP的位置
IGMP在协议栈中的位置:
- 在IP层之上,用IP封装
- 协议号:2
- TTL=1,只在本地子网传播
- 属于网络层协议
IGMP只在本地子网有效。
12.2 IGMP报文格式
IGMP报文结构
IGMPv2报文格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 类型 | 最大响应时间 | 检验和 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 组地址 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
字段说明:
- 类型:8位,报文类型
- 最大响应时间:8位,v2才有,v1为0
- 检验和:16位,IGMP报文的检验和
- 组地址:32位,IP多播组地址
IGMP报文封装在IP数据报中。
报文类型
IGMP报文类型:
| 类型 | 名称 | 说明 |
|---|---|---|
| 0x11 | 成员查询(Membership Query) | 路由器查询组成员 |
| 0x12 | 成员报告v1(Membership Report v1) | 主机报告加入 |
| 0x16 | 成员报告v2(Membership Report v2) | 主机报告加入 |
| 0x17 | 离开组(Leave Group) | 主机报告离开 |
v1和v2的区别:
- v2增加了离开组报文
- v2增加了最大响应时间字段
- v2向下兼容v1
IGMPv2比v1功能更丰富。
12.3 组成员状态
多播地址列表
每个接口维护多播地址列表:
- ia_multiaddrs链表
- 每个地址有引用计数
- 多个进程可以加入同一个组
数据结构:
struct in_multi {
struct in_multi *inm_next; /* 下一个 */
struct in_ifaddr *inm_ia; /* 所属接口地址 */
struct in_addr inm_addr; /* 多播地址 */
u_int inm_refcount; /* 引用计数 */
/* ... */
};每个接口的多播地址链表。
加入组
加入多播组的过程:
- 应用程序调用setsockopt(IP_ADD_MEMBERSHIP)
- 内核检查是否已在列表中
- 不在列表中:
- 分配in_multi结构
- 添加到接口的ia_multiaddrs链表
- 引用计数设为1
- 通知网卡加入多播组
- 发送IGMP成员报告
- 已在列表中:
- 引用计数加1
引用计数支持多个进程加入同一组。
离开组
离开多播组的过程:
- 应用程序调用setsockopt(IP_DROP_MEMBERSHIP)
- 引用计数减1
- 计数为0时:
- 从链表移除
- 通知网卡离开多播组
- 发送IGMP离开组报文(v2)
- 计数不为0:
- 什么都不做
最后一个进程离开才真正离开组。
12.4 IGMP工作机制
查询-响应机制
IGMP的基本工作机制:
-
路由器定期查询
- 发送成员查询报文
- 目的地址:224.0.0.1(所有主机)
- 周期:通常60秒
-
主机响应
- 收到查询后,为每个组成员启动定时器
- 定时器是随机的(0-最大响应时间)
- 定时器超时后,发送成员报告
- 收到其他主机的报告,取消自己的定时器
-
路由器维护
- 收到报告,知道该组有成员
- 一段时间没收到报告,认为没有成员
- 停止转发该组的数据
随机延迟避免所有主机同时发送。
为什么用随机延迟
随机延迟的作用:
- 避免所有主机同时发送报告
- 减少网络上的IGMP报文
- 一个组只要有一个主机报告就行
- 其他主机听到报告就不用发了
报告是抑制的,一个组只需要一个报告。
离开组(v2)
IGMPv2的离开机制:
-
主机发送离开组报文
- 最后一个成员离开时发送
- 目的地址:224.0.0.2(所有路由器)
- 告诉路由器可能要离开
-
路由器发送特定组查询
- 收到离开后,发送针对该组的查询
- 确认是否还有成员
-
如果还有成员
- 主机发送报告
- 路由器继续转发
-
如果没有成员
- 一段时间没收到报告
- 路由器停止转发该组
v2可以快速知道组是否还有成员。
12.5 多播数据的接收
多播数据的接收流程
多播数据的接收过程:
-
网卡接收
- 网卡收到多播帧
- 检查目的MAC地址
- 如果在多播地址列表中,接收
-
IP层处理
- 检查IP首部
- 检查目的IP地址
- 验证校验和
-
分用
- 根据协议号分用
- TCP/UDP/ICMP等
-
递送
- 递送给所有加入该组的套接字
- 多播可以被多个套接字接收
多播数据可以被多个接收者同时收到。
多播的过滤
多层过滤:
- 网卡层:MAC地址过滤
- IP层:IP地址过滤
- 传输层:端口过滤
- 应用层:应用自己过滤
多层过滤提高效率。
12.6 多播数据的发送
多播数据的发送流程
多播数据的发送过程:
-
应用发送
- 发送到多播地址
- UDP或原始IP
-
IP层处理
- 确定输出接口
- 设置TTL(默认1)
- 封装IP首部
-
链路层
- 映射到多播MAC地址
- 发送出去
多播发送和单播类似,只是目的地址是多播地址。
输出接口的选择
多播输出接口的确定:
- 默认根据路由表
- 可以用IP_MULTICAST_IF指定
- 可以指定特定的接口
应用可以控制从哪个接口发多播。
TTL的设置
多播的TTL:
- 默认TTL=1,只在本地子网
- 可以用IP_MULTICAST_TTL设置
- TTL决定多播的范围
- TTL越大,传播越远
TTL限制多播的传播范围。
12.7 小结
IGMP概述
-
IGMP的作用
- 组管理协议
- 主机报告组成员
- 路由器维护组成员关系
-
IGMP的位置
- IP协议号2
- TTL=1
- 只在本地子网
IGMP报文
-
报文格式
- 类型、最大响应时间
- 检验和、组地址
-
报文类型
- 成员查询
- 成员报告(v1/v2)
- 离开组(v2)
-
v1和v2的区别
- v2有离开组
- v2有最大响应时间
- v2向下兼容
组成员状态
-
多播地址列表
- 每个接口一个链表
- in_multi结构
- 引用计数
-
加入组
- setsockopt(IP_ADD_MEMBERSHIP)
- 添加到链表
- 发送报告
-
离开组
- setsockopt(IP_DROP_MEMBERSHIP)
- 引用计数减1
- 计数为0才真正离开
IGMP工作机制
-
查询-响应
- 路由器定期查询
- 主机随机延迟响应
- 报告抑制
-
随机延迟
- 避免同时发送
- 减少报文数量
-
离开组(v2)
- 主机发送离开
- 路由器特定查询
- 快速确认
多播数据收发
-
接收
- 网卡过滤
- IP层处理
- 多个套接字可以同时收到
-
发送
- 确定输出接口
- 设置TTL
- 映射MAC地址
关键概念
-
IP多播
- 一对多通信
- D类地址
- 高效
-
IGMP
- 组管理协议
- 查询-响应机制
- v1和v2
-
组成员管理
- 链表管理
- 引用计数
- 加入/离开
-
多播收发
- 接收:多个接收者
- 发送:TTL控制范围