Кратко

  • RFC 3678 сохранил существующие вызовы multicast-членства ради совместимости исходного кода и двоичных файлов, дополнив их параметрами и функциями фильтрации источников.
  • Вызов-дельта меняет один источник в текущем фильтре. Вызов полного состояния вместе заменяет режим и список; RFC считает такой способ необходимым для смены режима без выхода из группы и полезным для атомарной замены большого списка.

Старый вызов нельзя было просто расширить

Первое ограничение задавал не маршрутизатор, а уже работающая программа, использующая сокет. До появления фильтрации по источникам получатель multicast мог вступить в группу и при необходимости выбрать локальный интерфейс. Членство задавалось, но приложение не могло указать, каких отправителей оно хочет принимать. Изменять устоявшийся вызов ради новых сведений было небезопасно: RFC 3678 прямо говорит, что интерфейс нельзя менять без нарушения двоичной совместимости.

Поэтому документ выбрал добавление новых возможностей. Новые API должны были сохранить совместимость исходного кода — старый код по-прежнему компилируется и работает — и двоичную совместимость: существующая программа продолжает запускаться в системе, поддерживающей расширение. RFC также предлагал ограничить объём изменений и дать приложениям возможность обнаружить отсутствие новых параметров, чтобы корректно на это реагировать. Это информационная записка о проектировании API, а не свидетельство того, что одинаковые вызовы появились во всех операционных системах. RFC 3678

По одному источнику за раз

Интерфейс-дельта меняет фильтр постепенно. При членстве, принимающем любые источники, получатель изначально принимает источники в целом, а операция блокировки или разблокировки меняет обработку одного отправителя. В режиме Source-Specific Multicast приложение добавляет конкретный источник в нужное множество или удаляет его. Важен исходный режим: RFC считает некоторые сочетания параметра и членства недопустимыми; уже заблокированный или не добавленный в группу источник может приводить к другой ошибке.

Для небольшого изменения такой синтаксис экономен. Можно запросить «заблокировать этот источник» или «добавить этот источник», не передавая остальной список заново. Но смысл операции зависит от текущих фильтра и членства. Дельта — это не полное описание состояния, которое должно получиться после вызова. API включает специфичные для IPv4 параметры вроде IP_ADD_SOURCE_MEMBERSHIP и независимые от протокола параметры вроде MCAST_JOIN_SOURCE_GROUP. RFC 3678

Или заменить всё состояние целиком

У API полного состояния другая задача. Приложение передаёт режим фильтра — MCAST_INCLUDE или MCAST_EXCLUDE — и весь список источников, которые нужно включить или исключить. Вызов заменяет прежний фильтр, а не вносит в него одно изменение членства.

RFC 3678 указывает два случая, когда это различие существенно. Чтобы перейти между INCLUDE и EXCLUDE, не выходя из группы, приложение должно использовать API полного состояния. Оно также подходит для больших списков источников: весь список меняется атомарно за один вызов. Последовательность дельт может привести к тому же набору, но это уже несколько промежуточных изменений, а не одна замена.

Для чтения состояния предусмотрен отдельный контракт: приложение может оценить размер буфера, получить общее число источников и повторить вызов, если буфер оказался мал. Если реализация ограничивает длину списка, превышение может завершиться ошибкой ENOBUFS. Поэтому «заменить всё» — способ управлять состоянием, а не обещание неограниченной вместимости. RFC 3678

Одна группа — два семейства адресов

Для приложений, которым важны минимальные изменения IPv4-кода, записка сохранила структуры и параметры, специфичные для IPv4. Кроме того, она определила формы, не привязанные к протоколу: группа и источник передаются в сокетных структурах с поддержкой разных семейств адресов, а локальный интерфейс задаётся отдельно индексом интерфейса. RFC 3493 предоставил значительную часть словаря IPv6-сокетов, но не независимые от протокола операции вступления в multicast-группу и выхода из неё; этот пробел закрыл RFC 3678. RFC 3493

В сигнатуре функции это разделение легко упустить: адрес группы обозначает multicast-направление, адрес источника — отправителя, а индекс интерфейса ограничивает операцию локальным подключением. Проверенная техническая поправка erratum 2524 позднее исправила описание аргумента getsourcefilter в разделе 5.2.2: это индекс интерфейса, а не «локальный IP-адрес», как и у описанного в предыдущем разделе вызова установки. Ещё одна подтверждённая редакционная поправка исправила ошибочную ссылку на раздел кодов ошибок. Ни одна из них не меняет модель фильтра; обе помогают точно понять аргументы. Errata RFC 3678

Фильтрация на хосте не означает фильтрацию повсюду

Фильтр может действовать на самом хосте, даже если маршрутизаторы не поддерживают IGMPv3 или MLDv2. Приложение тогда получает локальную фильтрацию, но это не доказывает, что нежелательные пакеты перестали проходить по локальному каналу. Эти протоколы передают сведения о фильтре маршрутизатору; это отдельный от вызова сокета механизм со своим состоянием и сетевым путём. RFC 3376, RFC 3810 и RFC 4604 описывают части этого поведения на сетевой стороне. RFC 3376 RFC 3810 RFC 4604

Фильтр источников также не удостоверяет отправителя. RFC 3678 предупреждает: одной фильтрации недостаточно, если злоумышленник подставил в пакет адрес источника, совпадающий с разрешённым. Проверка обратного маршрута может помочь при некоторых схемах маршрутизации, но гарантии не даёт. Успешный вызов сокета подтверждает выполнение операции API, а не состояние маршрутизатора, снижение трафика, подлинность пакета, его получение или успех приложения. RFC 3678

У документа статус Informational; он прямо говорит, что не является стандартом Интернета, и отсылает к официальной спецификации сокетов. Его исторический вклад уже и потому точнее: старые вызовы членства были защищены, изменение одного источника оставалось простым, а для смены режима или большой таблицы можно было заменить фильтр целиком. Более поздние заметки Лу Хэна № 64 и № 65 здесь служат аналитическими оптиками для разговора о совместимости и локальном внедрении, а не утверждением об авторстве, одобрении или влиянии на записку 2004 года. Статус RFC 3678 Заметка 64 Заметка 65

Источники