Кратко

  • RFC 3208 устранил ACK от каждого получателя: пропуск в последовательности вызывал NAK, а маршрутизаторы подавляли дубликаты и запоминали интерфейсы, которым требовалось исправление.
  • NAK Confirmation доказывал лишь обработку отрицательного запроса на данном переходе. Он не доказывал наличие RDATA, её прохождение, получение, декодирование или успех неизвестных членов группы.

Подтверждение кажется однозначным, пока в разговоре участвуют две стороны. Отправитель передал данные, получатель ответил, ожидание можно завершить. В multicast-дереве та же привычка заставила бы тысячи получателей отвечать на каждый пакет и направила бы встречный поток к одному источнику.

Pragmatic General Multicast решал именно проблему ACK implosion. С ростом группы служебный трафик не должен был расти быстрее самой рассылки. Иначе свидетельства успеха разрушили бы систему, успех которой они призваны фиксировать.

PGM сделал молчание нормальным состоянием. Источник рассылал Original Data, ODATA, с номерами последовательности. Каждый получатель следил за собственной картиной и только при обнаружении разрыва отправлял выборочный negative acknowledgement — NAK.

Отказ от ACK был не просто экономией заголовка. У PGM не было модели членства в группе. Получатели могли присоединяться и уходить, а источник не знал их списка и числа. Протокол не предназначался для подтверждённой доставки известному составу и не обещал общего порядка между несколькими источниками.

Надёжность формулировалась со стороны получателя. В пределах применимого окна передачи он получал исходные или исправляющие пакеты либо мог обнаружить невосстановимую потерю. Это не давало источнику права объявлять общий результат для неучтённой аудитории.

Увидев пропуск, получатель посылал NAK по unicast последнему PGM-элементу на входящей ветви. Запрос повторялся, пока на соответствующем интерфейсе не появлялся NAK Confirmation, или NCF.

Сетевой элемент выпускал NCF вниз и пересылал NAK следующему PGM-соседу в сторону источника. Следующий узел делал то же самое, пока запрос не доходил до источника. Подтверждение относилось к одному переходу; маршрутизаторы не превращали его в сквозную квитанцию.

Доказательное содержание NCF было намеренно узким: этот отрицательный запрос услышан и обработан здесь. В подтверждении нет потерянного пакета. Оно не говорит, что источник ещё хранит нужную последовательность, локальный ремонтный узел ответил, RDATA прошла нужную ветвь или получатель сумел её применить.

При получении NAK маршрутизатор создавал repair state. Ключ связывал транспортный сеанс с потерянной последовательностью, а список отмечал нижестоящие интерфейсы, откуда пришло свидетельство потери. После подтверждения сам NAK можно было удалить; обязательство сохранялось в состоянии.

Когда возвращалась Repair Data, RDATA, маршрутизатор пересылал её только через зарегистрированные интерфейсы. Исправление шло в поддерево, запросившее помощь, а не затопляло группу повторно. При отсутствии подходящего состояния RDATA по умолчанию отбрасывалась.

Правильный исправляющий пакет и право этого пакета на проход были разными фактами. Источник мог выпустить корректную RDATA, но ветвь без установленного состояния её не получала. NCF на первом переходе не доказывал ни завершение пути запроса вверх, ни готовность пути исправления вниз.

Source Path Messages, SPM, строили обратное направление. Источник вставлял их между данными, а каждый PGM-элемент обновлял адрес верхнего соседа. Получатели и маршрутизаторы узнавали, куда передавать NAK, следуя обратному маршруту исходной рассылки.

SPM также объявляли границы transmit window. Задняя граница показывала самый старый ещё исправимый номер. Если получатель замечал разрыв после выхода пакета из окна, даже безупречно подтверждённый запрос не мог восстановить уже удалённую копию. Допустимым исходом оставалось обнаружение потери без её устранения.

Поскольку NAK был единственным пусковым сигналом исправления, его путь требовал устойчивости. SPM заставляли повторно проверять разрывы даже при отсутствии недавней ODATA. Получатель вёл отдельные таймеры ожидания NCF и RDATA; услышанное подтверждение не завершало ожидание предмета ремонта.

Одна потеря могла затронуть множество участников. Чтобы не заменить взрыв ACK взрывом NAK, каждый получатель выдерживал случайный back-off. Если за это время он слышал совпадающий NAK или NCF, то подавлял собственную отправку и считал чужой запрос представителем той же потери.

Маршрутизаторы также удаляли дубликаты. Если repair state для сеанса и последовательности уже существовало, новый нижестоящий интерфейс можно было добавить в список без ещё одного NAK вверх. В удачном случае источник видел один запрос, хотя пакет потеряли многие.

Именно это сжатие давало масштабируемость и одновременно уничтожало численность. NAK у источника не сообщал, сколько получателей промолчали из-за подавления. NCF в ветви не перечислял ожидающих членов. Один интерфейс в состоянии не раскрывал число хостов за ним и их текущее участие.

Физическим отправителем RDATA не обязательно был исходный источник. Designated Local Repairer, DLR, мог хранить пакеты и отвечать ближе к получателям. Его исправление сохраняло исходный Transport Session Identifier, чтобы занять правильное место в последовательности. Непрерывность сеанса не доказывала происхождение байтов от первоначального источника.

Объявление DLR, его выбор и перенаправление NAK были отдельными событиями. Объявленная доступность не доказывала, что нужная последовательность всё ещё хранится. Перенаправление не доказывало получение запроса или ответ, а правильный TSI не доказывал принятие результата получателем.

Окно передачи воплощало и эксплуатационную политику. При продвижении по данным NAK возле задней границы мог задержать окно и сохранить шанс полноты ценой латентности. При продвижении по времени окно двигалось несмотря на незавершённые запросы, защищая своевременность ценой окончательных потерь.

При обеих политиках NCF выглядел одинаково. Подсчёт подтверждений не показывал, сколько источник будет хранить последовательность и чему отдан приоритет — полноте или темпу. Движение окна нуждалось в отдельной доказательной записи.

Forward Error Correction менял материал исправления, но не границы утверждения. RDATA могла содержать копию либо данные чётности для реконструкции. NCF для FEC подтверждал запрошенное количество; получателю всё ещё требовалось реально получить достаточно фрагментов и успешно декодировать их.

Статус Experimental ограничивал историческую силу RFC 3208. В разделе применимости контроль перегрузки, помощь маршрутизаторов, локальная повторная передача и программный интерфейс назывались опытными областями. RFC 2357 задавал критерии оценки надёжного multicast, а RFC 3208 предлагал конкретный механизм для эксперимента, не доказательство внедрения или производительности.

Анализ безопасности следовал за представлениями, создающими состояние. Поддельный SPM мог перенаправить запросы. Ложный NAK мог расходовать память. Ложный NCF мог остановить пересылку до источника. Ложная RDATA могла снять законное состояние и заблокировать последующее настоящее исправление.

Злоумышленнику не требовалось подделывать содержимое приложения. Достаточно было изменить, кто выглядит верхним соседом, какой интерфейс считается пострадавшим, жив ли запрос и какое исправление закрывает состояние. Полная аутентификация источников, получателей, DLR и сетевых элементов выходила за пределы простой базовой схемы.

Исторический урок состоит не в бесполезности NCF. Подтверждение было необходимо, чтобы единственный путь запроса не исчезал молча. Его сила заключалась в точной области действия: NAK услышан в этом месте. Переименование этой фразы в «исправление доставлено» превратило бы дисциплину масштабирования PGM в вымышленный журнал доставки.