# Теория IGMP

Как же именно работает IGMP?\
Пожалуй, начать нужно с того, что версий у протокола сейчас три: IGMPv1, IGMPv2, IGMPv3. Наиболее используемая — вторая, первая уже практически забыта, поэтому про неё говорить не будем, третья очень похожа на вторую.

Акцентируемся пока на второй, как на самой показательной, и рассмотрим все события от подключения клиента к группе до его выхода из неё.\
Клиент будет также запрашивать группу 224.2.2.4 через проигрыватель VLC.

Роль IGMP очень проста: если клиентов нет — передавать мультикастовый трафик в сегмент не надо. Если появился клиент, он уведомляет маршрутизаторы с помощью IGMP о том, что хочет получать трафик.

Для того, чтобы понять, как всё происходит, возьмём такую сеть:

![Multicast](http://img-fotki.yandex.ru/get/9753/83739833.37/0_da2ef_f0bc8d45_XL.png)

Предположим, что маршрутизатор уже настроен на получение и обработку мультикастового трафика.

![](http://img-fotki.yandex.ru/get/6729/83739833.39/0_da9ff_770594e6_M.png)\
**1.** Как только мы запустили приложение на клиенте и задали группу 224.2.2.4, в сеть будет отправлен пакет **IGMP Membership Report** — узел «рапортует» о том, что хочет получать трафик этой группы.

![IGMP Report](http://img-fotki.yandex.ru/get/6729/83739833.37/0_da2f0_e4ee7c67_XXXL.png)

В IGMPv2 Report отправляется на адрес желаемой группы, и параллельно он же указывается в самом пакете. Данные сообщения должны жить только в пределах своего сегмента и не пересылаться никуда маршрутизаторами, поэтому и TTL у них 1.

> Часто в литературе вы можете встретить упоминание о **IGMP Join**. Не пугайтесь — это альтернативное название для IGMP Membership Report.

![](http://img-fotki.yandex.ru/get/6729/83739833.39/0_da9ff_770594e6_M.png)\
**2.** Маршрутизатор получает IGMP-Report и, понимая, что за данным интерфейсом теперь есть клиенты, заносит информацию в свои таблицы

![show ip igmp group](http://img-fotki.yandex.ru/get/9763/83739833.37/0_da2f1_e0f2b4_XL.png)

Это вывод информации по IGMP. Первая группа запрошена клиентом. Третья и четвёртая — это служебные группы протокола [SSDP](http://lookmeup.linkmeup.ru/#term158), встроенного в Windows. Вторая — специальная группа, которая всегда присутствует на маршрутизаторах Cisco — она используется для протокола [Auto-RP](http://lookmeup.linkmeup.ru/#term306), который по умолчанию активирован на маршрутизаторах.\
Интерфейс FE0/0 становится нисходящим для трафика группы 224.2.2.4 — в него нужно будет отправлять полученный трафик.

Наряду с обычной юникастовой таблицей маршрутизации существует ещё и мультикастовая:

![show ip mroute](http://img-fotki.yandex.ru/get/9932/83739833.37/0_da2f2_7a90f656_XL.png)

О наличии клиентов говорит первая запись **(\*, 224.2.2.4)**. А запись **(172.16.0.5, 224.2.2.4)** означает, что маршрутизатор знает об источнике мультикастового потока для этой группы.\
Из вывода видно, что трафик для группы 224.2.2.4 приходит через FE0/1, а передавать его надо на порт FE0/0.\
Интерфейсы, в которые нужно передавать трафик, входят в список нисходящих интерфейсов — **OIL — Outbound Interface List**.\
Более подробно вывод команды **show ip mroute** мы разберём позже.

Выше на дампе вы видите, что как только клиент отправил IGMP-Report, сразу после него полетели UDP — это видеопоток.

![](http://img-fotki.yandex.ru/get/6729/83739833.39/0_da9ff_770594e6_M.png)\
**3.** Клиент начал получать трафик. Теперь маршрутизатор должен иногда проверять, что получатели до сих пор у него есть, чтобы зазря не вещать, если вдруг клиентов не осталось. Для этого он периодически отправляет во все свои нисходящие интерфейсы запрос **IGMP Query**.\
\&#xNAN;*Дамп отфильтрован по IGMP*.\
![IGMP General Query](http://img-fotki.yandex.ru/get/9169/83739833.37/0_da2f3_1f65170e_XXL.png)

По умолчанию это происходит каждые 60 секунд. TTL таких пакетов тоже равен 1. Они отправляются на адрес 224.0.0.1 — все узлы в этом сегменте — без указания конкретной группы. Такие сообщений Query называются **General Query** — общие. Таким образом маршрутизатор спрашивает: «Ребят, а кто и что ещё хочет получать?».

Получив IGMP General Query, любой хост, который слушает любую группу, должен отправить IGMP Report, как он это делал при подключении. В Report, естественно, должен быть указан адрес интересующей его группы.\
\&#xNAN;*Дамп отфильтрован по IGMP*.\
![IGMP Membership report](http://img-fotki.yandex.ru/get/9491/83739833.37/0_da2f4_7d385a82_XXL.png)

Если в ответ на Query на маршрутизатор пришёл хотя бы один Report для группы, значит есть ещё клиенты, он продолжает вещать в тот интерфейс, откуда пришёл этот Report, трафик этой самой группы.\
Если на 3 подряд Query не было с интерфейса ответа для какой-то группы, маршрутизатор удаляет этот интерфейс из своей таблицы мультикастовой маршрутизации для данной группы — перестаёт туда посылать трафик.

По своей инициативе клиент обычно посылает Report только при подключении, потом — просто отвечает на Query от маршрутизатора.

> Интересная деталь в поведении клиента: получив Query, он не торопится сразу же ответить Report'ом. Узел берёт тайм-аут длиной от 0 до **Max Response Time**, который указан в пришедшем Query:\
> \
> ![Max Response Time](http://img-fotki.yandex.ru/get/9497/83739833.37/0_da2f5_348d9ad8_XXL.png)\
> \
> При отладке или в дампе, кстати, можно видеть, что между получением различных Report может пройти несколько секунд.\
> Сделано это для того, чтобы сотни клиентов все скопом не наводнили сеть своими пакетам Report, получив General Query. Более того, только один клиент обычно отправляет Report.\
> Дело в том, что Report отсылается на адрес группы, а следовательно доходит и до всех клиентов. Получив Report от другого клиента для этой же группы, узел не будет отправлять свой. Логика простая: маршрутизатор и так уже получил этот самый Report и знает, что клиенты есть, больше ему не надо.\
> Этот механизм называется **Report Suppression**.\
> \
> **Далее в статье мы расскажем о том, почему этот механизм на деле очень редко реально работает**.

![](http://img-fotki.yandex.ru/get/6729/83739833.39/0_da9ff_770594e6_M.png)\
**4.** Так продолжается веками, пока клиент не захочет выйти из группы (например, выключит плеер/телевизор). В этом случае он отправляет **IGMP Leave** на адрес группы.

![IGMP Leave](http://img-fotki.yandex.ru/get/6710/83739833.37/0_da2f6_4cec4c3a_XXXL.png)

Маршрутизатор получает его и по идее должен отключить. Но он ведь не может отключить одного конкретного клиента — маршрутизатор их не различает — у него просто есть нисходящий интерфейс. А за интерфейсом может быть несколько клиентов. То есть, если маршрутизатор удалит этот интерфейс из своего списка OIL (Outgoing Interface List) для этой группы, видео выключится у всех.\
Но и не удалять его совсем тоже нельзя — вдруг это был последний клиент — зачем тогда впустую вещать?

Если вы посмотрите в дамп, то увидите, что после получения Leave маршрутизатор ещё некоторое время продолжает слать поток. Дело в том, что маршрутизатор в ответ на Leave высылает IGMP Query на адрес группы, для которой этот Leave пришёл в тот интерфейс, откуда он пришёл. Такой пакет называется **Group Specific Query**. На него отвечают **только** те клиенты, которые подключены к данной конкретной группе.

![IGMP Group Specific Query](http://img-fotki.yandex.ru/get/9169/83739833.37/0_da2f7_eb322104_XXXL.png)

Если маршрутизатор получил ответный Report для группы, он продолжает вещать в интерфейс, если не получил — удаляет по истечении таймера.

Всего после получения Leave отправляется два Group Specific Query — один обязательный, второй контрольный.

*Дамп отфильтрован по IGMP*.\
![Отключение мультикастового клиента](http://img-fotki.yandex.ru/get/9806/83739833.37/0_da2f8_5c37f4c9_XXL.png)

Далее маршрутизатор останавливает поток.
