"Теоретически канал с адресацией EUI 64 может соединить порядка " запись вида не понятна и отнимает время на попытку ее осмыслить. ее можно заменить например на записи вида 264 или 1,8 * 1019
|
Протокол розыска соседей
Окончательный смысл нового флага в сообщении NA сводится к тому, замещать ли уже существующую полную запись. Поэтому данный флаг мы обозначим как "замещение" (override), сокращенно O. Если в принятом сообщении NA флаг O установлен (O = 1), то сведения из этого сообщения имеют приоритет перед записью в NC. Канальный адрес из сообщения немедленно перемещается в запись. Сама запись становится ДОСТУПНОЙ, если сообщение по вызову (S = 1), или ПРОСРОЧЕННОЙ, если оно добровольное (S = 0). Если же флаг O сброшен (O = 0), то новый канальный адрес в сообщении NA не приводит к немедленному обновлению записи NC. Вместо этого ДОСТУПНАЯ запись просто становится ПРОСРОЧЕННОЙ; в других полных состояниях запись вообще остается без изменений, потому что она уже проходит проверку [§7.2.5 RFC 4861]. После дополнения этими правилами конечный автомат NUD приобретает вид, показанный на рис. 5.9.
Теперь, благодаря флагу O и связанным с ним правилам обновления канального адреса, мы можем отразить в ND еще одну полезную идею ARP. Если у интерфейса данного узла менялся канальный адрес, то узел высылал широковещательный "добровольный ARP", в котором разыскивал собственный сетевой адрес или отвечал о нем сам себе. Это вызывало немедленное обновление существующих записей у его соседей — точнее, у тех из них, до кого добровольный ARP успешно дошел. Почему происходило обновление, мы уже обсудили: по правилам ARP, получатель сообщения первым делом искал сетевой адрес источника в своем кэше и обновлял его канальный адрес [RFC 826]. Хотя этот механизм вполне работал, сейчас давайте позаботимся, чтобы каждый тип сообщения ND делал, по возможности, свое дело. К счастью, узел IPv6 уже вправе выслать объявление NA, когда ему этого захочется. Единственная обязанность узла, когда объявление добровольное, — это сбросить в нем флаг S.
Добровольный запрос ARP служил также и для того, чтобы обнаруживать конфликты адресов IP, но об этой функции мы поговорим в §5.4.1.
Поэтому, когда происходит смена канального адреса, узел IPv6 может выслать добровольное объявление NA о своем новом канальном адресе. Подходящими флагами в этом объявлении будут сброшенный флаг S (S = 0) и установленный флаг O (O = 1), поскольку объявление не по запросу, однако его источник самый авторитетный. А по какому адресу следует выслать такое объявление? Так как данный узел не знает, кто из его соседей хранит в NC запись о нем, объявление придется выслать по групповому адресу "все узлы канала", FF02::1. Чтобы оно наверняка не потерялось, его можно повторить несколько раз ,16 Параметр MAX_NEIGHBOR_ADVERTISEMENT, 3 раза [§10 RFC 4861]. разделив передачи паузами .17 Дважды, то есть всего до 3 вызовов — параметр MAX_MULTICAST_SOLICIT [§10 RFC 4861].
На этом мы исчерпали первую порцию задач, связанных с розыском соседей в IPv6, и можем наконец-то собрать вместе требования к формату сообщений NS и NA.
По нашему плану, центральный элемент сообщения NS — это адрес IPv6 искомого соседа, о котором происходит запрос. Нам уже сейчас нетрудно предвидеть, что сетевой или канальный адрес соседа, о котором идет речь в данном сообщении, будет элементом в формате многих сообщений ND. Поэтому давайте называть его одним термином: адрес цели (target address). В сообщении NS (рис. 5.10) центральное место займет сетевой адрес цели, то есть ее адрес IPv6 [§4.3 RFC 4861].
Флаги в сообщении NS нам не понадобились. Зато выше, на с. 112, мы запланировали, что в целях оптимизации сообщение NS может включать в себя канальный адрес источника (при этом сетевой адрес источника находится в заголовке IPv6). Насколько эта информация необходима в теле NS и есть ли у нее другие применения?
Мы настолько сконцентрировались на поведении узла-искателя, что совсем забыли об искомом узле и упустили из виду вот какую важную деталь: чтобы ответить индивидуальным объявлением NA на вызов NS, необходимо сперва узнать канальный адрес узла-искателя. Очевидно, что применить ND для этой цели нельзя, так как протокол зациклится и возникнет тупиковая ситуация. Поэтому верным решением будет указать канальный адрес узла-искателя, источника NS, непосредственно в самом NS. Конечно, канальный кадр, доставивший вызов NS, должен содержать в себе адрес источника, но с уровня IP доступ к канальному заголовку может быть затруднен ввиду программных ограничений стека. Поэтому вполне оправдано повторить канальный адрес источника в теле вызова NS.
Таким образом, получается, что типичное сообщение NS не только может, но и должно содержать в себе канальный адрес источника. Из этого правила будет всего одно серьезное исключение. Когда мы будем говорить в §5.4 об автоматической настройке адресов, у нас возникнет вызов NS с неопределенного адреса и без канального адреса источника. Уже и сейчас понятно, что такой особенный вызов NS понадобится, чтобы обойти очередную "проблему курицы и яйца" на нашем пути.
Еще есть один случай, когда канальный адрес источника в вызове NS рекомендован, но не обязателен: когда вызов NS индивидуальный [§4.3 RFC 4861]. Ведь такой вызов шлют соседу, когда его запись NC уже существует в заполненном виде, а значит, велик шанс, что у соседа тоже есть запись NC о нашем локальном узле [§7.2.2 RFC 4861]. Сосед должен был создать такую запись по приходу от нас самого первого вызова NS, который был групповым и содержал канальный адрес источника.
В итоге, канальный адрес источника — это не вполне обязательный элемент NS, а значит, нам понадобятся опции в формате ND.
Пусть общий вид опций ND (рис. 5.11) будет основан на уже знакомом нам формате TLV: тип (1 байт), длина (1 байт), а затем переменное количество данных, формат которых зависит от типа [§4.6 RFC 4861]. Длина опции ND измеряется в 8 байтных словах и, разнообразия ради, включает в себя байты типа и длины, так что нулевое значение длины свидетельствует о сбое. Узнать о наличии опций в сообщении ND можно, определив, где находится его конец: если он совпадает с концом фиксированной части формата, то опций нет, а иначе они присутствуют. Как определить границы сообщения ND, мы уже сказали в §4.3; ведь ND — это подмножество ICMPv6.
В уже потребовавшейся нам опции "канальный адрес источника" (Source Link-Layer Address Option, SLLA или SLLAO) роль данных играет канальный адрес, а ее тип равен 1 [§4.6.1 RFC 4861]. Такой формат опции SLLA представлен на рис. 5.13. В частности, на канале Ethernet длина данных будет равна шести байтам, а всей опции — единице (8 байт), как показано на рис. 5.10. Поэтому, к примеру, адрес MAC 02 03 04 05 06 07 будет инкапсулирован в эту опцию так: <0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07>.
Предполагается, что у каждой канальной технологии есть стандарт RFC, где зафиксированы детали работы IPv6 поверх каналов этого типа. Точный формат опций ND "канальный адрес" — одна из таких деталей. Например, см. [§6 RFC 2464] для Ethernet.
В отличие от ARP, ND не указывает явным образом тип канального адреса. Ведь он однозначно следует из типа канала, откуда пришло сообщение ND.
Сообщение NA содержит сведения о соседе, а именно его сетевой и канальный адреса. Согласно нашей терминологии, это адреса цели. Хотя сетевой адрес источника сообщения приведен в заголовке IPv6, он может и не совпадать с сетевым адресом цели, так как сообщение мог послать proxy, а не сам искомый узел. Чтобы proxy не пришлось "подделывать" адрес в заголовке IPv6, мы поместим сетевой адрес цели отдельно, в тело сообщения NA [§4.4 RFC 4861].
Форматы NS и NA могут стать довольно похожими, если мы приложим к этому немного усилий ради упрощения будущих реализаций. Для этого пусть канальный адрес цели разместится в опции, а не в фиксированной части сообщения NA. Когда искомый узел или proxy отвечает на групповой вызов NS, он обязан включить эту опцию в объявление NA, чтобы сообщить канальный адрес цели. В то же время, когда узел отвечает на индивидуальный запрос NS, он вправе предположить, что источник запроса уже располагает правильным канальным адресом цели; в этом случае канальный адрес цели в объявлении NA можно опустить, хотя особой выгоды это не принесет. Соответствующая опция — "канальный адрес цели" (Target Link-Layer Address Option, TLLA или TLLAO) — отличается от опции "канальный адрес источника" только типом, который равен 2. Благодаря этому, формат обеих опций можно представить на одной иллюстрации; их общий формат показан нарис. 5.12, а формат для Ethernet — на рис. 5.13.
Кроме того, в сообщении NA мы запланировали несколько флагов. Помимо уже знакомых нам флагов S и O, мы отведем бит для флага R, необходимость в котором возникнет ниже, в §5.4.2. Окончательный формат NA будет таким, как показано на рис. 5.14.
Прекрасно, теперь наш узел IPv6 может составить сообщение NS или NA, когда потребуется. А в какой сетевой интерфейс он отправит это сообщение, если у него их несколько?
Что касается NS, то это сообщение уходит в интерфейс, подключенный к тому каналу, где проводится розыск соседа. Ведь мы с самого начала отметили, что отношение соседства между узлами определено только на заранее заданном канале. Поэтому розыск соседа проводится не глобально, а только после того, как узел-искатель определился с каналом. В свою очередь, соседа разыскивают, когда для него есть исходящий пакет и уже известен выходной интерфейс. Тогда будет вполне резонно передать и сообщение NS в тот интерфейс, на который указала маршрутизация исходящего пакета. Это обеспечит однозначный выбор канала для проведения розыска соседа, поскольку в архитектуре IP к интерфейсу нельзя одновременно подключить больше одного канала.
Что же касается сообщения NA, то в этом случае выбор интерфейса зависит от того, по запросу ли высылается данное сообщение. Если NA — это ответ на запрос NS (S = 1), то его достаточно передать в тот же сетевой интерфейс, откуда пришел запрос, и тогда оно заведомо попадет в нужный контекст канала. Ну, а если NA не по запросу (S = 0), то контекст канала известен из других соображений. Например, если это объявление о смене канального адреса, то его надо передать именно в тот интерфейс, на котором эта смена произошла.
Вот теперь розыск соседей на самом деле возможен: у нас есть форматы сообщений ND и правила работы с ними. А какую еще информацию извлекает из успешного обмена сообщениями NS и NA локальный узел А, кроме канального адреса искомого соседа Б? Очевидно, он узнаёт, что передача данных по каналу от А к Б и обратно, от Б к А, была возможна хотя бы на момент розыска соседа Б. Таким образом, ND позволяет узлу А убедиться в том, что доступность соседа Б симметричная, а NUD поддерживает актуальность этих сведений. В случае же асимметричной доступности, когда канал однонаправленный, ND просигнализирует полную недоступность узла Б. Иными словами, ND поддерживает только двунаправленные каналы [§3.2 RFC 4861].
Возможно, когда-нибудь в будущем состоится попытка распространить ND и на асимметричные каналы [§3.2 RFC 4861]. Произойдет это, конечно же, когда возникнет спрос на такие каналы в среде IPv6.
На этом мы завершили работу над первой частью протокола розыска соседей, посвященной разрешению индивидуальных адресов IPv6 в канальные адреса. Ниже мы встретим еще несколько задач, решение которых будет удобным и логически обоснованным, если его оформить в рамках того же самого протокола. Поэтому протокол розыска соседей IPv6 (Neighbor Discovery Protocol, NDP) не ограничен одним только разрешением адресов [§3 RFC 4861]. Но, как говорится, всему свое время.
Завершим раздел мы тем, что обратим внимание, как полезные разработки IPv6 постепенно находят себе дорогу обратно в IPv4. Так, в современных версиях Linux18 Klaus Wehrle, Frank Pahlke, Hartmut Ritter, Daniel Muller, Marc Bechler. The Linux Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel. Prentice Hall, 2004. §15.3. и MS Windows19 Description of Address Resolution Protocol (ARP) caching behavior in Windows Vista TCP/IP implementations. Microsoft KB article 949589. http://support.microsoft.com/kb/949589 к модулю ARP фактически приделали конечный автомат ND, который включает в себя обратную связь с вышестоящими протоколами, тонкое управление кэшем соседей с помощью NUD и прочие новшества, которых не хватало в традиционных реализациях ARP.