Опубликован: 30.07.2013 | Уровень: для всех | Доступ: платный
Лекция 5:

IPv6 в стеке протоколов

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >

Далее, как мы уже отметили, говоря о фрагментации и сборке в §3.3.4, извещение "пакет слишком велик" обязано содержать в себе значение MTU выходного канала, куда "не уместился" пакет. Благодаря этой информации, процедура PMTUD сойдется гораздо быстрее.

Извещение "проблема в параметре" подходит для того, чтобы сообщать источнику, помимо прочих проблем в составленном им пакете, о неопознанных опциях и неизвестных значениях "следующий заголовок". Чтобы различать эти проблемы, можно назначить им разные коды [§3.4 RFC 4443]:

  • код 0: недопустимое значение какого-либо поля в заголовке либо неверно сформированный пакет, например, длина фрагмента с M = 1 не кратна восьми;
  • код 1: неопознанное значение "следующий заголовок" — возможно, адресат не поддерживает это расширение или протокол ;
  • код 2: неопознанная опция IPv6 — высылается, только если старшие биты кода опции требуют такого извещения (см. §3.3.2).

Но почему тип 3 называется "время истекло"? Ведь в §3.2 мы приняли решение, что теперь вместо поля "время жизни пакета" будет поле "предельное число шагов". Конечно, это так, но тип 3 охватывает два разных события, и второе из них по-прежнему связано со временем [§3.3 RFC 4443]:

  • код 0: превышено предельное число шагов, то есть пакет предположительно зациклился в сети, отчего значение его поля "предельное число шагов" достигло нуля;
  • код 1: истек тайм-аут сборки, то есть адресат не дождался прихода всех фрагментов пакета.
К сожалению, текст [§3.3 RFC 4443] можно трактовать так, будто маршрутизатор должен проверить поле "предельное число шагов" во входящем пакете, как только он принят из сети. Как мы знаем из §3.2 настоящего курса, на самом деле этому обязательно предшествует вывод, что пакет транзитный и подлежит продвижению, так как иначе поле "предельное число шагов" вообще не проверяется. Видимо, авторы [RFC 4443] руководствовались моделью идеального маршрутизатора, у которого все пакеты — транзитные, но забыли сделать на этом акцент. Увы, в наши дни такие недомолвки чреваты неправильными реализациями.

Дополнительные типы сообщений ICMPv6 возникнут по мере необходимости. Хотя у каждого из них будет свой формат, возможны и общие детали. Одну важную деталь мы сейчас обнаружим в извещениях об ошибках.

Модель управления ошибками IPv6 остается такая же, как и в IPv4: извещение об ошибке высылается только при невозможности обработать принятый пакет IP. То есть за каждым сообщением об ошибке стоит определенный пакет-виновник. А значит, к извещению об ошибке обязательно надо приложить хотя бы начало пакета-виновника, чтобы его источник смог опознать пакет и принять необходимые меры. Это правило касается всех извещений об ошибках ICMPv6. Оно не ново — подобное правило было и в ICMPv4.

По одной из точек зрения, даже минимальный MTU IPv4 был выбран в связи с сигнализацией ошибок таким образом. Ведь в 68 байт как раз умещается внешний заголовок IPv4 (20 байт), заголовок ICMPv4 (8 байт), заголовок IPv4 виновника (20 байт), и остается еще 20 байт для заголовка TCP.

Однако теперь у нас есть шанс устранить одну застарелую проблему. Она была в том, что сообщение ICMPv4 содержало слишком мало байтов из пакета-виновника: стандартом требовались лишь его заголовок IPv4 и 8 байт полезной нагрузки [§3.2.2 RFC 1122]. Когда в сети возникали сложные схемы многоуровневой инкапсуляции, например, с привлечением туннелей, информативные части пакета-виновника просто не помещались в сообщение.

Теперь же мы вправе — и обязаны — потребовать, чтобы всякое сообщение об ошибке ICMPv6 содержало как можно большую часть пакета-виновника [§2.4(c) RFC 4443]. Очевидно, что это должно быть начало пакета [§2.1 RFC 4443], а не середина или конец, потому что именно начало пакета дает ключ к его содержимому.

Подумайте, что можно включить в копию пакета-виновника, когда происходит тайм-аут сборки, а первый фрагмент так и не получен. (Вариант: образец нефрагментируемой части и заголовок фрагмента.)

Насколько велика может быть эта часть? Мы заметили в §3.3.4, что ICMPv6 поможет нам управлять фрагментацией. Но если извещения ICMPv6 сами будут подвержены фрагментации, то наша схема зациклится. Поэтому фрагментировать извещения ICMPv6, вообще говоря, нельзя. Следовательно, ограничением сверху здесь будет минимальный MTU IPv6, 1280 байт. Конечно, в этот MTU должен умещаться весь пакет ICMPv6, включая заголовок IPv6 и возможные заголовки расширения.

Нетрудно убедиться, что вместе эти два условия (как можно больше, но не больше чем) допускают только два случая:

  • извещение содержит пакет-виновник целиком (в том виде как он был доступен извещающему узлу);
  • извещение содержит начало пакета-виновника, а весь пакет ICMPv6 занимает 1280 байт.

В результате извещения ICMPv6 будут иметь единый формат, представленный на рис. 4.8.

              Структура извещения об ошибке ICMPv6

Рис. 4.8. Структура извещения об ошибке ICMPv6

Однако полнота сообщений об ошибках оборачивается другой проблемой. Теперь сообщения об ошибках имеют относительно большой размер, а значит, они смогут расходовать заметную часть ресурсов сети, если частота ошибок будет высокой, например, вследствие атаки. Хуже того, возможны косвенные атаки, когда злоумышленник "бомбардирует" узел А сбойными пакетами от имени источника Б, вызывая шквал ICMPv6 от А к Б. Предотвратить эту проблему можно, если все узлы IPv6 ограничат частоту, с которой они высылают сообщения об ошибках. Пусть это ограничение будет обязательным [§2.4(f) RFC 4443], хотя конкретный алгоритм мы оставим на усмотрение реализаций.

Пример такого алгоритма в общих чертах описан в [§2.4(f) RFC 4443].

Продолжая наш ход мысли, мы приходим к общему вопросу [§2.4(e) RFC 4443]: в каких случаях узел IPv6 обязан воздержаться от уведомления об ошибке? Прежде всего, чтобы избежать бесконечной "игры в пинг-понг", извещение об ошибке ни в коем случае нельзя высылать в ответ на другое извещение об ошибке. Возможно, в будущем у нас возникнут и справочные типы сообщений ICMPv6, которые могут спровоцировать "пинг-понг", так что за этим моментом надо внимательно следить.

Например, в §5.2 нам встретится сообщение типа "переадресовка", которое высылается в ответ на другой пакет, хотя и не является извещением об ошибке.

Также не следует отвечать ошибкой на пакет, адрес источника в котором не индивидуальный. Ведь извещение об ошибке уходит по адресу, который был источником пакета-виновника. Например, если пакет отправлен с группового адреса, то налицо явное нарушение протокола (см. §3.2); если это не результат сбоя, то попытка атаки "отказ в обслуживании". Помимо того, в некоторых вполне законных случаях — с ними мы встретимся ниже, это будут DAD в §5.4.1 и MLD в §6.4 — адрес источника в пакете может быть неопределенным, ::. На такой пакет отвечать ошибкой тоже нельзя, потому что это означало бы указать неопределенный адрес назначения в пакете ICMPv6.

Также не следует в общем случае отвечать на групповые и широковещательные пакеты, поскольку иначе один ошибочный пакет вызовет целую бурю ответов ICMPv6. Чтобы определить, относится ли пакет к групповым или широковещательным, недостаточно проверить адрес источника в заголовке IPv6. Необходимо также убедиться, что пакет не был разослан группе или всем узлам на канальном уровне. К примеру, если пакет получен из канала Ethernet, то надо проверить адрес MAC назначения в заголовке кадра. Таким образом, для данной проверки нужна помощь со стороны канального уровня сетевого стека.

Например, в сетевом стеке BSD Unix канальный уровень помечает принятый кадр как групповой или широковещательный с помощью битовых флагов M_MCAST и M_BCAST[13 Gary R. Wright, W. Richard Stevens. TCP/IP Illustrated, Volume 2: The Implementation. Addison Wesley, 1995. p. 39. ], так что сетевому уровню достаточно проверить эти флаги — ему не нужно изучать заголовок кадра самостоятельно.

Из последнего правила есть всего пара исключений [§2.4(e) RFC 4443]. Во-первых, если код нераспознанной опции IPv6 содержит двоичный префикс 10, то сообщение об ошибке требуется независимо от сетевого и канального адресов назначения пакета (см. §3.3.2). Во-вторых, ошибка "пакет слишком велик" высылается независимо от адресов назначения пакета [§3.2 RFC 4443], чтобы процедуру PMTUD можно было применять и к групповому трафику.

Когда маршрутизатор отвечает извещением ICMPv6, его адрес назначения очевиден: это адрес источника из пакета-виновника. А какой надо выбрать адрес источника для самого извещения? В общем случае это нетривиальный вопрос [§2.2(b) RFC 4443]; ответ на него дает процедура DAS, с которой мы познакомимся в §6.6. Главная сложность здесь в том, чтобы зона адреса источника позволяла коммуникацию с адресом назначения. Этой особенности не было в IPv4, где маршрутизатор просто использовал адрес выходного интерфейса извещения [§4.3.2.4 RFC 1812]. Также сравните это со случаем высылающего ICMPv6 хоста: ему достаточно поменять местами адреса источника и назначения, при условии что пакет-виновник был адресован индивидуально хосту, а не группе [§2.2(a) RFC 4443].

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >
Сергей Субботин
Сергей Субботин

"Теоретически канал с адресацией EUI 64 может соединить порядка 2^63 "

запись вида 2^63  не понятна и отнимает время на попытку ее осмыслить.

ее можно заменить например на записи вида  264  или 1,8 * 1019

 

Павел Афиногенов
Павел Афиногенов

Курс IPv6, в тексте имеются ссылки на параграфы. Разбиения курса на параграфы нет.

Александр Худышкин
Александр Худышкин
Россия
Константин Второв
Константин Второв
Россия, Бокситогорск, ЛГОУ им. А.С.Пушкина, 2003