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

Протокол розыска соседей

Все состояния, в которых запись заполнена (в ней указан не только сетевой, но и канальный адрес), мы будем собирательно называть полными.

ДОСТУПНАЯ запись освежается по сигналу от вышестоящих протоколов, или же дополнительными объявлениями NA с S = 1 — то есть сбрасывается тайм-аут записи. Но допустим, что такую запись давно10 S. Floyd, V. Jacobson, "The Synchronization of Periodic Routing Messages", IEEE/ACM Transactions on Networking, April 1994. http://ee.lbl.gov/papers/sync_94.pdf не освежали. Означает ли это, что сосед Б куда-то пропал? В аналогичных условиях ARP полагал именно так и удалял запись. Но на самом деле это может означать всего лишь, что текущий диалог завершился и соседи решили помолчать, занявшись другими делами. Поэтому узел А не удаляет запись NC о соседе Б, а просто переводит ее в состояние ПРОСРОЧЕННАЯ (STALE).

Так как в ND активная ДОСТУПНАЯ запись постоянно освежается, ее тайм-аут может быть существенно меньше, чем знакомое нам время жизни записи в кэше ARP. Так что не стоит удивляться, что простаивающие ДОСТУПНЫЕ записи NC становятся ПРОСРОЧЕННЫМИ гораздо скорее, нежели предсказывает наш опыт IPv4.

ПРОСРОЧЕННАЯ запись хранит сведения, в которых узел А не уверен. Без проверки пользоваться ими нежелательно, и поэтому запись остается ПРОСРОЧЕННОЙ ровно до тех пор, пока к ней не будет обращений. Но, с другой стороны, и обязательного тайм-аута у ПРОСРОЧЕННОЙ записи нет, потому что она содержит полезные сведения.

Проходит время, и вот узел А опять готов передать новый пакет соседу Б, запись о котором ПРОСРОЧЕННАЯ. Весьма вероятно, что узлы А и Б находятся там же, где они были и раньше. Поэтому узел А шлет пакет по канальному адресу Б, взятому из записи. Он надеется, что вскоре вышестоящий протокол подаст сигнал о доступности соседа Б. Такое событие узел А отмечает, переводя запись в состояние ЗАДЕРЖКА (DELAY) и устанавливая ее таймер. 11 Параметр DELAY_FIRST_PROBE_TIME, 5 с [§10 RFC 4861].

А что если интервал этого таймера истек, а сигнала сверху по-прежнему нет? Даже тогда для записи в состоянии ЗАДЕРЖКА не все потеряно: ведь, возможно, переданный пакет не предполагал никакого отклика, или он потерялся где-то дальше в сети. Чтобы разрешить возникшую неоднозначность, узел А целенаправленно проверяет годность записи NC: он направляет вызов NS по индивидуальному адресу узла Б, используя канальный адрес из записи, и переводит запись в состояние ИСПЫТАНИЕ (PROBE). И, наконец, если даже после нескольких попыток12 Параметр MAX_UNICAST_SOLICIT, 3 раза [§10 RFC 4861]. вызова и ожидания76 сосед Б так и не ответил объявлением NA, то остается только удалить его запись из NC и тем самым начать розыск данного соседа с нуля в надежде обнаружить его новый канальный адрес.

Современные реализации IPv4 тоже освежают записи в кэше ARP по истечении тайм-аута, индивидуально обращаясь к соседям. Например, так поступает ядро Linux13 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. . Этот прием был описан в п. 2 [§2.3.2.1 RFC 1122] под названием индивидуальный опрос (unicast poll).

Окончательная хронология не обновляемой и потому обреченной исчезнуть записи NC показана на рис. 5.4.

Наглядная хронология устаревающей записи NC

Рис. 5.4. Наглядная хронология устаревающей записи NC

Пока запись NC полная, но проходит проверку, в очереди узла А могут возникнуть прикладные пакеты, требующие передачи соседу Б. Должен ли узел А приостановить их отправку до тех пор, пока он не убедится в достоверности записи? На самом деле, пауза здесь не требуется и может быть даже вредна, так что узел А продолжает передавать пакеты соседу Б, используя канальный адрес из записи. Благодаря этому, у вышестоящих протоколов тоже появляется возможность освежить запись. Сигнал вышестоящего протокола переводит полную запись из любого состояния в состояние ДОСТУПНАЯ. Очевидно, что на несуществующие и НЕПОЛНЫЕ записи сигнал не действует, даже если он вдруг поступит, поскольку в таких записях нет информации о канальном адресе соседа.

Хотя начинали мы с простой экономии ресурсов канала и узлов-соседей, в результате у нас получился полнофункциональный механизм наблюдения за состоянием соседей, которым локальный узел передает пакеты. Этот механизм называют выявление недоступности соседей (neighbor unreachability detection), сокращенно NUD [§7.3 RFC 4861]. По сути, механизм NUD — это и есть конечный автомат ND, а информация о доступности соседей — один из основных продуктов его работы. На текущий момент у нас готов упрощенный вариант этого механизма, схематически показанный на рис. 5.5.

Упрощенная диаграмма состояний ND

Рис. 5.5. Упрощенная диаграмма состояний ND

Более полную диаграмму состояний ND можно найти, например, в14 Qing Li, Tatuya Jinmei, Keiichi Shima. IPv6 Core Protocols Implementation. Morgan Kaufmann, 2007. P. 502. , однако эта диаграмма покажется вам заметно доступнее и осмысленнее, если вы сначала завершите вместе с нами работу над текущим разделом.

Ценой определенных усилий мы победили в ND недостатки ARP и теперь можем спокойно взглянуть на плодотворные идеи старого протокола, чтобы не потерять их в ND.

Первая идея состоит в том, что большинство запросов ARP, а теперь и вызовов NS открывает некий сетевой диалог. Иными словами, очень часто узел А проводит розыск соседа Б и передает ему пакет, а вскоре уже узел Б имеет что передать своему соседу А. Если А и Б — хосты, то это естественный стиль работы большинства прикладных протоколов. Если же один из них или оба — маршрутизаторы, то здесь проявляется не только двунаправленная работа прикладных протоколов, но и практическая симметрия маршрутов. Поэтому модуль ARP, получив запрос, предусмотрительно создавал запись о его источнике, если запрос касался локального узла: он предвидел, что скоро роли поменяются и источник запроса станет искомым соседом, получателем пакета IP.

В среде IPv6 намек на предстоящий диалог — это вызов NS. Если формат сообщения NS предусмотрит место для канального адреса источника (А), то получатель NS (Б) сможет сразу же создать о нем полную запись NC. По правилам NUD, эта запись — ненадежная, потому что проверена только односторонняя проходимость канала: А\toБ. Значит, такая запись заслуживает состояния ПРОСРОЧЕННАЯ. Это состояние записи вполне позволит сетевому диалогу начаться без задержки на еще один цикл ND между А и Б, когда узел Б станет разыскивать соседа А. Далее , если все будет в порядке, запись о соседе А перейдет в состояние ДОСТУПНАЯ по стандартной процедуре, не задерживая диалог.

Вторая идея заключается в том, что на розыск соседа не всегда откликается сам владелец искомого сетевого адреса. Искомый узел может находиться вне канала, а ответит за него маршрутизатор, у которого есть сведения о доступности искомого узла, как то маршрут к нему, более точный (specific), чем префикс подсети канала. Поскольку такой маршрутизатор отвечает от имени искомого узла и выступает посредником между искателем и искомым, то его обозначают популярным термином proxy. В частности, в ARP такой маршрутизатор назывался ARP proxy. Задача подобного proxy — привлечь к себе трафик для искомого узла, чтобы затем продвинуть его согласно таблице маршрутов, как показано на рис. 5.6. Поэтому proxy должен ответить, что искомому сетевому адресу отвечает его собственный канальный адрес. Особенность IPv6 здесь только в том, что ND proxy должен вступить в группу искомого узла, отвечающую адресу "Б", чтобы принимать вызовы NS к Б и отвечать на них объявлениями NA от имени Б.

Идея: ND proxy отвечает за другой узел

Рис. 5.6. Идея: ND proxy отвечает за другой узел

Если ND proxy отвечает от имени многих узлов, например, целой подсети, ему может пригодиться режим работы сетевого интерфейса, когда тот принимает все групповые кадры подряд (allmulti). Однако это может вызвать осложнения в коммутируемой ЛВС, использующей сообщения IGMP или MLD (§6.4) для изучения географии групп IP. В такой ЛВС трафик группы просто не дойдет до портов, из которых не поступало уведомления о вступлении в данную группу.

Функция ND proxy должна быть настраиваемой. Как минимум, ей требуется "выключатель", потому что по умолчанию она должна быть выключена.

А как быть, если искомый узел — мобильный и может находиться то по соседству, то вне данного канала, не меняя при этом своего адреса? Сохраним наши обозначения: пусть Б — это искомый узел, тогда как А — наш локальный узел, который хочет передать пакет непосредственно узлу Б, полагая при этом, что Б — его сосед. Этот сценарий представлен на рис. 5.7.

Хотя такая мобильность еще не позволяет узлу Б свободно перемещаться в пределах Internet, она отвечает основному требованию мобильного IP (mobile IP): при перемещении узел Б не меняет своего адреса15Introduction to Mobility in IP. Configuring Proxy Mobile IP. Cisco Aironet 1200 Series Access Point Software Configuration Guide for VxWorks. http://www.cisco.com/en/US/docs/wireless/access_point/1200/vxworks/configuration/guide/bkscgch6.html#wp1032681 . Альтернативный подход — это т.н. кочевой IP (nomadic IP), когда узел меняет свой адрес в зависимости от точки подключения к сети [ibid]. Очевидно, что "кочевой IP" гораздо проще реализовать, так как он опирается только на обычную маршрутизацию, но он не обеспечит долгоживущих прикладных сеансов, способных пережить переезды узла, если только прикладной протокол сам не поддерживает смены адреса на лету.
 Мобильность узла, за которого отвечает ND proxy

Рис. 5.7. Мобильность узла, за которого отвечает ND proxy

Пусть сначала узел Б находится в другой части сети. Узел А начинает розыск узла Б запросом ARP в IPv4 или вызовом NS в IPv6. От имени узла Б отвечает proxy и сообщает свой канальный адрес. Узел А думает, что это ответил его сосед Б, и передает пакет по канальному адресу proxy. Так proxy перехватывает пакеты, предназначенные узлу Б, и поступает с ними согласно своим текущим настройкам. В это время узел Б вообще не видит запросов ARP или вызовов NS, которые посылает узел А, потому что узлы А и Б на самом деле не являются соседями.

Теперь допустим, что узел Б незаметно перемещается на данный канал и действительно становится соседом узла А, как показано на рис. 5.8. В этом случае он уже самостоятельно отвечает на запросы (вызовы) узла А. Но proxy тем временем продолжает отвечать от его имени, потому что ничего не знает о перемещении узла Б. Это значит, что на каждый запрос узла А придет два ответа (объявления), сообщающих разные канальные адреса искомого узла Б! Какой окажется запись об узле Б в кэше узла А, если он успешно получит оба ответа? В ARP все решает ее величество фортуна: окончательный вид записи зависит от порядка, в котором поступят ответы, а он, можно сказать, случайный. "Победит" ответ, пришедший последним: именно его канальный адрес останется в записи. Таким образом, примерно в половине случаев в запись об узле Б попадет канальный адрес proxy, и пакеты пойдут туда, где узла Б в данный момент нет. Проблема налицо, и нам обязательно надо исправить ее в ND, потому что сегодня мобильные узлы получают все большее распространение.

Точнее, в IPv4 один или несколько первых пакетов пойдут по канальному адресу из ответа ARP, пришедшего первым, а затем придет другой ответ, и последующие пакеты пойдут по канальному адресу из него.

Мобильность                     приводит к сбою: трафик уходит не туда

Рис. 5.8. Мобильность приводит к сбою: трафик уходит не туда

К счастью, перед нами всего два уровня в ранжире узлов, "борющихся" за искомый адрес. Первый, с наибольшим приоритетом — это действительный владелец адреса Б. По определению индивидуального адреса, владелец у него ровно один. Второй уровень — это proxy, которых может быть и несколько. Относительный приоритет одних proxy перед другими мы определять не будем, так как в данном случае proxy — это вспомогательный механизм, и его не стоит усложнять сверх меры. Поэтому нам достаточно одного бита в формате NA, который и укажет, пришло ли объявление NA от владельца адреса или от proxy.

Теперь давайте подумаем, как получатель обязан реагировать на то или иное значение этого бита, чтобы получился желаемый результат. Нам необходимо, чтобы в итоге "выигрывал" владелец адреса, независимо от последовательности объявлений:

  • если первым приходит объявление NA от владельца:
    1. по приходу объявления владельца узел А заполняет запись о соседе Б, внося в нее канальный адрес из NA;
    2. последующее объявление liroxy не меняет уже полной записи о Б;
  • когда первым приходит объявление NA от proxy:
    1. по приходу объявления proxy узел А заполняет запись о соседе Б, внося в нее канальный адрес из NA;
    2. объявление владельца изменяет канальный адрес в записи о Б, несмотря на то что она уже полная.

То есть объявление владельца вытесняет данные, полученные от proxy, но не наоборот. Обеспечить это можно было бы, снабдив запись в NC атрибутом: заполнена ли она по объявлению владельца или proxy. Но нельзя ли обойтись без дополнительного атрибута? Если объявление послал владелец, то оно безусловно обновляет запись в кэше, и происхождение этой записи неважно. Если же объявление исходит от proxy, а полная запись с другим канальным адресом уже существует в NC, то достаточно воспользоваться конечным автоматом NUD и просто перевести запись в состояние ПРОСРОЧЕННАЯ, не изменяя других ее полей.

Пожалуйста, не забывайте, что, в отличие от ARP, запись в кэше соседей ND никогда не создают по приходу объявления NA. Объявление NA может повлиять только на уже существующую запись, будь то полную или НЕПОЛНУЮ.

Став ПРОСРОЧЕННОЙ, запись проходит процедуру проверки. Если указанный в ней канальный адрес по-прежнему доступен, то запись просто возвращается в состояние ДОСТУПНАЯ. Так произойдет, если запись указывает на "живого" владельца искомого адреса, или же на "живой" proxy, который предлагает доступ к владельцу искомого адреса. В противном случае запись исчезнет, а узел А повторит процедуру ND с самого начала. Это случится, в частности, когда узел Б снова уйдет с канала и станет доступен только через proxy.

Поскольку все proxy равноправны, в рамках ND нет способа определить, какой именно proxy дает доступ к узлу Б, когда тот вне канала и за него отвечают несколько proxy. Эту проблему придется решать надлежащей настройкой самих proxy.

Обратите внимание: механизм NUD следит только за состоянием подлинных соседей. Так, если запись NC об узле Б указывает на proxy, то ее состояние — это состояние proxy, а не самого узла Б. О доступности узла Б в этом случае NUD информации не предоставляет, потому что он ограничен рамками канала и не рассчитан на слежение за сквозной доступностью. Эту архитектурную особенность стоит иметь в виду, даже если вы не собираетесь применять ND proxy на практике.

Сергей Субботин
Сергей Субботин

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

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

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

 

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

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

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