Поработав над розыском соседей, мы можем пересмотреть типы вещания в IPv6. Прежде всего, что произошло с широковещанием? До сих пор мы старательно избегали этой темы. Однако теперь мы убедились, что необходимость в широковещании полностью отпала благодаря обязательной поддержке группового вещания. Широковещание IPv4 опиралось на широковещание канального уровня, а с ним мы активно боремся, чтобы не расходовать впустую ресурсы сети. Обратиться же ко всем узлам IPv6 в определенной зоне всегда можно с помощью общепринятой группы "все узлы" (FF0x::1). Итак, в IPv6 нет широковещания; его функции выполняет групповое вещание.
А когда нет широковещания, то не нужны и особые широковещательные адреса. В частности, идентификатор интерфейса FFFF:FFFF:FFFF:FFFF (все биты установлены) никоим образом не зарезервирован.
Групповое вещание полезно для протоколов не только служебных, но и прикладных. Оно выручает в тех случаях, когда один пакет надо с минимальными затратами разослать нескольким узлам. Например, сервер NTP может передавать "сигналы точного времени" сразу группе клиентов; клиент DHCP может обратиться одним запросом к группе серверов и получить несколько предложений, а затем выбрать среди них наиболее подходящее.
Однако возникают похожие задачи, которые групповое вещание решить не может. К примеру, нет смысла создавать в организации группу серверов DNS хотя бы потому, что протокол DNS рассчитан на индивидуальное вещание и клиенту не будет никакой выгоды от нескольких ответов.
Также групповое вещание совершенно бессильно в протоколах, работающих поверх TCP. Тем не менее, сама концепция сетевой группы, когда за одним адресом стоят несколько узлов (точнее, интерфейсов), сохраняет свое значение и в этом случае. Скажем, в крупной организации можно было бы назначить всем серверам DNS или SMTP один "волшебный" адрес X, так чтобы клиент, независимо от местоположения в сети и не меняя настроек, всегда обращался бы к ближайшему серверу (см. рис. 6.1). С точки зрения источника пакета, это будет вещание наугад ((рис 6.1) Идея anycast для DNS
Тем не менее, роль случайности в этом типе вещания не так велика, как кажется источнику. Для простых протоколов, где весь сеанс состоит из обмена парой пакетов UDP по схеме "запрос-ответ", действительно неважно, в какой именно узел anycast попадет запрос. Между тем, TCP не играет в кости: для его работы надо, чтобы пакеты данного соединения попадали в один и тот же узел anycast хотя бы при условии постоянной конфигурации сети. Получается оксюморон: вещание наугад должно быть воспроизводимым (см. рис. 6.2).
(рис 6.2) Anycast должен быть воспроизводимым
Примером простого протокола "запрос-ответ" мог бы служить DNS поверх UDP, если бы его стороны вообще не поддерживали транспорт "виртуальная цепь" при поддержке TCP [RFC 5966]. Но, как мы помним, поддержка этого транспорта важна для передачи длинных сообщений DNS. Так что даже DNS требует от вещания наугад воспроизводимости.
И даже простейший протокол вида "запрос-ответ" потребует воспроизводимого вещания наугад, если длина его полностью сформированного пакета может превышать минимальное значение MTU. Дело здесь, конечно же, во фрагментации и сборке. Ведь после фрагментации каждый фрагмент представляет собой отдельный пакет и проходит путь к адресату независимо от других фрагментов, а встретиться они должны на одном и том же узле назначения, чтобы сборка прошла успешно.
Как нам выполнить это противоречивое условие? Давайте попробуем свести задачу к двум крайним случаям. В первом из них источник и узлы anycast будут разбросаны по сети, так что они не окажутся соседями друг друга. Во втором же случае источник и все узлы anycast будут соседями по каналу.
В первом случае задачу можно решить обычной настройкой маршрутов в сети. Для простоты положим, что источник — это хост, у которого есть только маршрутизатор по умолчанию. По условию задачи, источник — не сосед ни одному из узлов anycast, а значит, первым шагом пакет попадет на маршрутизатор по умолчанию. Если у того будет маршрут для адреса anycast X в сторону ближайшего узла anycast N, то следующим шагом пакет достигнет его или хотя бы приблизится к нему и т.д. То есть достаточно выстроить на маршрутизаторах цепочку маршрутов, которая приведет пакет к ближайшему узлу anycast, как показано на рис. 6.3. Принципиально это ничем не отличается от процесса маршрутизации в сложной сети, где к данному адресату можно проложить более одного пути и потому пакеты от разных источников ходят к нему через совершенно разные участки сети. Следовательно, и осуществить такую схему можно теми же инструментами: статическими маршрутами или протоколом динамической маршрутизации.
(рис 6.3) Трасса к адресу anycast
Тогда вопрос для нас представляет только финал, когда последний маршрутизатор в цепочке передает пакет непосредственно узлу anycast. Здесь возможны два очевидных подхода.
Согласно первому из них, маршрутизатор должен полагать, что адрес X — "на канале". Как сообщить эту информацию маршрутизатору, зависит от реализации. К примеру, можно назначить каналу между маршрутизатором и узлом anycast префикс X/64. Так или иначе, маршрутизатор проведет розыск адреса X, а узел anycast откликнется и получит пакет.
Второй подход состоит в том, чтобы каждому узлу anycast J назначить, помимо адреса X, обычный индивидуальный адрес $$A_J$$. Тогда в таблице маршрутов последнего маршрутизатора достаточно будет создать маршрут $$X\to A_N$$, и по нему пакет достигнет узла anycast N. В этой схеме адрес $$A_J$$ вполне может быть внутриканальным, а хотя бы один такой адрес — это обязательный атрибут всякого интерфейса IPv6 (см. §2.5); так что назначать дополнительные адреса только ради работы anycast не придется. Сам же адрес $$X $$ можно назначить любому сетевому интерфейсу узла, включая "петлю", как это показано на рис. 6.4.
(рис 6.4) Последний шаг к адресу anycast
Когда же источник переместится в другую часть сети, как показано на рис. 6.5, там у него будет новый маршрутизатор по умолчанию, с которого начнется иная цепочка маршрутов к ближайшему узлу anycast K. Так как цепочка маршрутов зависит только от точки подключения источника, вещание наугад будет воспроизводимым, пока источник находится на одном месте, а это нас вполне устраивает.
(рис 6.5) Сеть выбирает узел anycast в зависимости от точки подключения хоста
Перейдем теперь ко второму случаю, когда источник и все узлы anycast — соседи по какому-то каналу. В этом случае трудно сказать, какой из узлов anycast ближе к источнику, так что пусть это будет настоящее вещание наугад, когда первичный выбор узла anycast происходит случайно. Тем не менее, после случайного выбора должен идти воспроизводимый этап передачи пакетов. Решим ли мы и эту задачу уже доступными нам средствами?
Допустим, что источник по-прежнему не подозревает об особенностях адреса X и работает с ним, как с обычным индивидуальным адресом. По условию задачи, адрес X — "на канале". Поэтому источник первым делом проведет розыск соседа X, направив вызов NS группе искомого узла Г(X), как мы обсудили в §5.1. Если наши узлы anycast заранее вступят в эту группу, то все они, в идеале, получат NS и ответят на него объявлениями NA. В результате источник получит несколько объявлений NA об одном и том же сетевом адресе цели X, но все они будут с разными канальными адресами, как показано на рис. 6.6.
(рис 6.6) Anycast в пределах канала
Потенциально эти объявления могут состязаться за запись в кэше NC источника, меняя ее непредсказуемым образом. Поэтому нам надо позаботиться, чтобы узлы anycast не воевали между собой. Гарантией мира будет сброшенный флаг O ( O = 0) в их объявлениях NA насчет адреса цели X. Тогда в кэше NC закрепится канальный адрес из объявления, пришедшего самым первым. Последующие объявления станут переводить запись в состояние ПРОСРОЧЕННАЯ, но она будет возвращаться в состояние ДОСТУПНАЯ, не меняя канального адреса, благодаря процедуре NUD. Таким образом, вещание наугад будет воспроизводимым и в этом случае.
Если на канале будет много источников вещания наугад и все они обратятся по адресу X, то их обращения распределятся между узлами anycast случайным образом. Так вещание наугад можно использовать для распределения нагрузки на узлы.
Пока что в нашей схеме узлы anycast отвечают на каждый вызов NS "хором", а это приведет к пикам нагрузки на канал. Чтобы сгладить эти
пики, пусть каждый узел anycast задерживает объявление NA на случайное время, от 0 до заданного
По-хорошему, параметр MAX_ANYCAST_DELAY_TIME должен быть меньше параметра RETRANS_TIMER, чтобы оставить немного времени на передачу по каналу, но в §10 RFC 4861 их значения совпадают.
С другой стороны, если бы узлы anycast отвечали на вызов NS без искусственной задержки, это позволило бы источнику выбрать ближайший или наименее загруженный узел, так как выигрывает ответ NA, пришедший первым.
А что произойдет, если выбранный узел anycast через какое-то время станет недоступен, скажем, его просто выключат? Тогда источник вычистит запись об адресе X из NC благодаря NUD, и цикл розыска повторится с начала. В результате источник переключится на другой, доступный узел anycast. Так оказывается, что вещание наугад в рамках одного канала открывает путь не только к распределению нагрузки, но и к резервированию.
Итак, мы рассмотрели два независимых сценария с вещанием наугад. Можно ли их объединить, чтобы охватить все возможные случаи? Конечно! Если мы поместим между источником и каналом с узлами anycast маршрутизатор, как показано на рис. 6.7, то выбирать узел anycast придется маршрутизатору, но он с этой задачей вполне справится. Ведь выбор узла anycast по адресу ничем не отличается от обычного розыска соседа. Однако у гибридного сценария есть важное отличие от сценария "все на одном канале": если несколько источников станут обращаться по адресу anycast через один и тот же маршрутизатор, то все обращения пойдут на один и тот же узел anycast. В этом случае распределения нагрузки не произойдет.
(рис 6.7) Anycast на канале через маршрутизатор
Остался последний вопрос касательно вещания наугад: какова структура "волшебного" адреса anycast? Возникнет ли у нас новый тип адреса IPv6? Нет, не возникнет. "Построенная" нами схема вещания наугад в IPv6 явно требует, чтобы адрес anycast ничем не отличался от индивидуального адреса. Только при этом условии вещание наугад можно вести на основе уже доступных механизмов, маршрутизации и ND. Узнать, что данный адрес — anycast, можно только из настроек узла, которому он назначен, и только такой узел работает с адресом anycast чуть иначе.
"Разрабатывая" вещание наугад, мы почти не ограничивали себя деталями IPv6. Поэтому вещать наугад по той же схеме можно и в среде IPv4, с точностью до замены ND на ARP [RFC 1546]. Вещание наугад уже пробовали использовать в DNS [RFC 3258].
О назначении общепринятых адресов anycast в IPv6 см. §6.1 и [RFC 2526].
Некоторые реализации не поддерживают передачу пакетов с адресом источника
Можно подвести итоги раздела. В IPv6 исчезло широковещание, но зато появилось вещание наугад. Индивидуальный и групповой режимы вещания продолжают играть свои роли, причем групповое вещание IPv6 также выполняет те важные функции, которые традиционно были свойственны широковещанию.
Как показывает практика, реализации группового вещания на канальном уровне зачастую менее отлажены, чем остальной код, и потому они далеко не всегда надежны. Не стоит сомневаться, что "глюки" канального группового вещания неизбежно выливаются в труднодиагностируемые проблемы на уровне IPv6. Поэтому производителям канального оборудования придется хорошенько потрудиться над тем, чтобы их продукция стала действительно пригодна к работе в эпоху IPv6.
Давным-давно существовал протокол IPX, в чем-то похожий на IPv6
Если адаптер позволяет программировать свой адрес MAC, то можно было бы сохранить старый адрес, однако это означало бы переход к самостоятельному управлению адресами MAC и — прощай, простота IPX! В действительности, реализации даже позволяли выбирать адрес IPX на свой вкус, но это вызывало программную смену связанного с ним адреса MAC.
Конечно, еще одно очевидное ограничение IPX состояло в том, что он мог работать только поверх каналов с адресацией MAC 48 или совместимой.
К счастью, ограничения на идентификатор интерфейса IPv6 гораздо мягче, чем это было в IPX. Единственное условие, на котором мы
настаиваем, — это чтобы идентификатор интерфейса в индивидуальном адресе
Чаще всего серверу достаточно постоянного имени, которое зарегистрировано в DNS. Тем не менее, в некоторых случаях нужен именно постоянный адрес IP, который будет зафиксирован в настройках клиентов. Например, это касается серверов DNS. Ведь узнать из DNS адрес сервера DNS — это все равно, что вытащить себя из болота за собственные волосы.
Между тем, технология TCP/IP находит применение не только в традиционных вычислительных сетях. Не исключено, что скоро все интеллектуальные бытовые приборы и личные электронные устройства будут общаться друг с другом по IPv6, и движение в эту сторону заметно уже сегодня. Управление такими сетями требует нетрадиционного подхода, потому что у рядового пользователя не будет ни желания, ни навыков, чтобы вручную назначить адрес IPv6 каждому из окружающих его "маленьких цифровых друзей". Но даже в традиционных сетях далеко не все узлы требуют адресов, назначенных вручную. Например, такие адреса не нужны большинству рабочих станций и терминалов. Для них, равно как и для персональных электронных устройств, будет достаточно предсказуемой автоматической настройки адресов.
Предсказуемость здесь нужна, чтобы облегчить отладку сети, если уж до этого дойдет дело.
Итак, мы видим, что нам пора заняться процедурой автоматической настройки индивидуальных адресов в IPv6. На какие части можно разбить ее? Прежде всего, узел должен найти для каждого из активных сетевых интерфейсов один или несколько адресов IPv6. Чтобы составить хотя бы один адрес IPv6, узел должен откуда-то узнать значения его фундаментальных частей — префикса подсети и идентификатора интерфейса. Посмотрим на эти части по отдельности, начав с последней.
Если у интерфейса, подлежащего настройке, есть уникальный канальный адрес, такой как MAC 48 или EUI 64, то это отличный кандидат на роль идентификатора интерфейса. Все, что требуется в этом случае — преобразовать канальный адрес к формату "модифицированный EUI 64" по общепринятой методике, которую мы "разработали" в §2.7. Эта часть задачи не представляет трудности.
Строго говоря, методику преобразования канального адреса в идентификатор интерфейса должен приводить документ, посвященный передаче IPv6 в данной канальной среде. Например, для Ethernet это [RFC 2464]. Тем не менее, случаи EUI 64 и MAC 48 также рассмотрены в центральном документе "Адресная архитектура IPv6" потому что эти виды идентификаторов популярны и применяются в самых разных технологиях канального уровня [Приложение A, RFC 4291]. Там же приводятся рекомендации, что делать, если у интерфейса нет уникального канального адреса.
Мы уже встретили пример, когда, не имея готовых адресов, канальный протокол согласует уникальные идентификаторы интерфейса для IPv6. Это, конечно же, IPV6CP в рамках PPP — см. §4.1.2.
Как выбрать префикс подсети, зависит от области адреса. Если надо составить внутриканальный адрес, то искомый префикс заранее известен: FE80::/64. Благодаря этому, узел может самостоятельно выбрать внутриканальные адреса для своих активных интерфейсов, не пользуясь никакими дополнительными сведениями.
Хотя для внутриканальных адресов был зарезервирован префикс FE80::/10, на интерфейсах мы встречаем только FE80::/64 в согласии с тем правилом, что длина префикса подсети IPv6 составляет 64 бита. Но, строго говоря, внутриканальный префикс подсети может зависеть от типа канала и уточняется соответствующим документом о канальной инкапсуляции IPv6.
Если же область адреса больше, чем канал, то префикс подсети выбирает и сообщает узлу администратор сети. Здесь наш путь снова раздваивается: или администратор вручную заносит префикс подсети в настройки узла, или же префикс настраивается централизованно, а узел узнает его автоматически, следуя некому протоколу. Такой протокол вполне сможет работать поверх IPv6, так как узел уже выбрал себе внутриканальные адреса.
Искушенный читатель спросит, почему бы не выбрать этим протоколом DHCP (точнее, его вариант для IPv6 — DHCPv6). Сейчас мы убедимся, что в NDP уже заложено достаточно возможностей, чтобы обойтись без еще одного протокола, по крайней мере, для распространения самых необходимых настроек.
Мы посвятим §5.4.2 вопросу о точном механизме автоматической настройки префикса подсети, а сейчас давайте переключимся на следующую проблему. Предположим, что узел уже автоматически составил адрес IPv6. Например, это может быть внутриканальный адрес, префикс которого известен заранее: FE80::/64. В отличие от IPX, где идентификатор интерфейса обязан совпадать с его адресом MAC, в IPv6 такого требования нет. Поэтому нельзя исключить ситуацию, когда автоматически выбранный идентификатор интерфейса уже занят другим узлом-соседом.
Скажем, узел собирается назначить внутриканальный адрес интерфейсу Ethernet, адрес MAC которого 00-01-02-03-04-05. Согласно правилам "модифицированного EUI 64", ему отвечает идентификатор интерфейса 02-01-02-FF-FE-03-04-05. Сцепляя его с внутриканальным префиксом, узел получает адрес FE80::0201:02FF:FE03:0405. Несмотря на уникальность исходного адреса MAC, тот же самый адрес IPv6 уже может быть назначен другому соседу, например, вручную. Таким образом, было бы опрометчиво назначить автоматически составленный адрес IPv6, не проверив его на уникальность в пределах канала.
Строго говоря, рассмотренный в примере конфликт адресов возникает из-за нарушения формата "модифицированный EUI 64": администратор не должен назначать "с потолка" идентификаторы интерфейсов, у которых установлен бит U/L. Тем не менее, на практике случается всякое. Даже производители сетевых адаптеров не застрахованы от ошибок, и у разных адаптеров могут совпасть адреса MAC. Подобные проблемы желательно выявлять до того, как они навредят работе сети.
Непроверенный адрес мы обозначим как пробный ( tentative). Требуется ли новый протокол, чтобы проверить такой адрес на уникальность? На самом деле, нет — мы можем обойтись протоколом ND из §5.1, слегка доработав его. В общих чертах схема ясна: узел посылает запрос NS касательно пробного адреса и ожидает, не ответит ли кто-то из соседей объявлением NA; если такой ответ поступит, то пробный адрес, очевидно, уже занят. Однако этот случай применения ND обладает рядом отличительных особенностей, которые выделяют его в под-протокол с названием DAD ( duplicate address detection, выявление дубликатных адресов) [§5.4 RFC 4862].
Как мы знаем, в IPv4 для той же цели служил добровольный запрос ARP. Хотя практика IPv4 уже давно держит этот механизм в своем арсенале, формальная процедура была опубликована относительно недавно под названием " обнаружение конфликтов адресов IPv4" (IPv4 Address Conflict Detection, ACD) [RFC 5227].
Первое затруднение состоит в том, что участие в ND, каким мы его знаем, требует уже назначенного индивидуального адреса. Ведь у пакета ND должен быть определенный адрес источника, не так ли? В то же время, узел не может назначить себе адрес, не проверив его по DAD. Это рождает "проблему курицы и яйца", для решения которой DAD должен работать, даже когда узел-инициатор вообще не обладает индивидуальными адресами. Пусть узел, выполняющий DAD, всегда посылает запрос NS с неопределенным адресом источника IPv6 :: [§5.4.2 RFC 4862] и без опции "канальный адрес источника" [§4.3 RFC 4861]. Тогда неопределенный адрес источника выделит NS для DAD среди обычных вызовов NS, передаваемых с целью разрешения адреса или NUD.
Но как узел-инициатор получит возможный ответ NA? Ведь пакет IPv6 нельзя направить по неопределенному адресу! Чтобы обойти и эту преграду, пусть отвечающий узел направляет ответ NA по групповому адресу "все узлы канала", FF02::1, если вызов NS пришел с неопределенного адреса. Следовательно, узел-инициатор должен вступить в эту группу перед началом DAD [§5.4.2 RFC 4862].
Как следствие, протокол управления группами IPv6 MLD должен работать, когда на интерфейсе еще нет индивидуальных адресов. Возьмем себе это на заметку, чтобы вспомнить позже, когда дело дойдет до MLD (§6.4).
Благодаря тому, что запрос NS в рамках DAD не использует опцию "канальный адрес источника" и ответ на него подлинно групповой, механизм DAD устойчив к конфликтам канальных адресов. Если бы мы "оптимизировали" DAD так, чтобы ответ NA шел по индивидуальному адресу MAC, коммутируемая локальная сеть направила бы его одному случайному владельцу этого адреса MAC, и DAD с большой вероятностью дал бы сбой. А ведь конфликт канальных адресов приведет и к конфликту адресов IPv6, составленных на их основе посредством "модифицированного EUI 64".
Отвечающий узел шлет объявление NA в ответ на запрос NS, однако в случае DAD это объявление направляется всем узлам канала, а не только узлу-инициатору DAD. Такое объявление NA получат и те узлы, которые о нем не просили. Поэтому, отвечая на вызов DAD, то есть вызов NS с неопределенного адреса, узел должен сбросить флаг S (S = 0). Вот еще одна особенность применения ND для DAD.
Дополнительное затруднение возникает, когда два узла одновременно пытаются проверить один и тот же незанятый адрес. Если следовать простейшей схеме, то ни один из узлов не получит объявления NA, и оба узла решат, что пробным адресом можно пользоваться. В результате возникнет конфликт адресов. Чтобы избежать такого исхода, узел-инициатор должен обращать внимание не только на объявления NA, но и на вызовы NS. Если узел получит чужой вызов NS касательно пробного адреса, исходящий с неопределенного адреса, то значит, еще один узел пытается проверить тот же адрес с помощью DAD, и назревает конфликт адресов [§5.4.3 RFC 4862]. Если же чужой вызов NS касательно пробного адреса поступит с определенного адреса, то это обычный розыск соседа, и его следует игнорировать, потому что право нашего узла на пробный адрес еще не доказано. В свою очередь, чтобы принимать интересующие его вызовы NS, узел-инициатор DAD должен заранее вступить в группу искомого узла, отвечающую пробному адресу [§5.4.2 RFC 4862].
Вообще говоря, узел может получать и свои собственные групповые сообщения. Так как в данном случае адрес источника IPv6 неопределенный, источник вызова DAD надо идентифицировать, если это возможно, по его канальному адресу [Приложение A RFC 4862]. Альтернативный подход, если локальный уровень IPv6 уверен, что получает собственные вызовы DAD, — это подсчитать разность между числом посланных и принятых сообщений [там же]; очевидно, в отсутствие конфликта она должна оставаться нулевой. В любом случае, верная обработка этой ситуации зависит от точных свойств канала и интерфейса в него.
Интересная идея, подсказанная нам редактором, состоит вот в чем: узел мог бы отличать собственные групповые вызовы NS от чужих, если бы он включал в свои вызовы особую опцию ND, содержащую достоверный "отпечаток пальцев" узла, например, подпись HMAC.
Узел-владелец пробного адреса, отвечая на вызов DAD, мог бы послать объявление NA более узкой группе искомого
узла, а не группе "все узлы канала". Ведь узел-инициатор DAD все равно обязан состоять в
обеих группах. Мы не видим препятствий для такого подхода, однако стандарты о нем не говорят. По-видимому, мысль разработчиков
IPv6 шла по тому же пути, что и наша: сначала они решали проблему доставки объявления NA инициатору DAD, а только потом
озаботились проблемой одновременных сеансов DAD. Затем надо было соотнести полученные решения между собой и оптимизировать
первое из них в свете второго, но до этого, видимо, просто не дошли руки
Соберем воедино все наши замечания и оформим их как процедуру DAD, в ходе которой узел А проверяет пробный адрес П на интерфейсе И:
узел А вступает на интерфейсе И в следующие группы:
а)"все узлы канала", FF02::1;
б)группа искомого узла, отвечающая адресу П (группа Г);
чужой вызов NS с неопределенного адреса касательно адреса П;
б)объявление NA об адресе П;
DAD дает отрицательный результат, если истекает тайм-аут
Поскольку сообщения ND могут теряться, а именно отсутствие сообщений означает отрицательный результат, процедуру DAD следует повторить
несколько раз
По умолчанию параметр DupAddrDetectTransmits равен единице [§5.1 RFC 4862], и повтора нет.
Вооружившись такой процедурой DAD, мы можем проверять любые индивидуальные адреса IPv6, а не только составленные автоматически. Поэтому пусть узел IPv6 выполняет DAD перед назначением каждого индивидуального адреса независимо от того, настроен ли он вручную или получен автоматически [§5.4 RFC 4862]. Так DAD поможет выявлять ошибки в настройке сети и минимизировать ущерб от них.
Тем не менее, администратор узла может избирательно заблокировать DAD на интерфейсе, установив параметр DupAddrDetectTransmits в ноль [§5.4 RFC 4862].
Обратите внимание: проверка DAD — только для индивидуальных адресов. В частности, DAD никогда не применяют к адресам anycast, потому что те по определению не уникальны [§5.4 RFC 4862]. Между тем, DAD вполне способен обнаружить и предотвратить случай, когда узел назначает своему интерфейсу некий адрес А как индивидуальный, хотя тот уже назначен другим интерфейсам канала как anycast. Ведь, как мы обсудили в §5.3, принадлежность внешне индивидуального адреса IPv6 к anycast — это локальное знание обладающего им узла. В случае назревающего конфликта узел, который назначает себе индивидуальный адрес, просто получит объявления NA с O = 0, а не 1. Условие надежной работы этого механизма таково: MAX_ANYCAST_DELAY_TIME RetransTimer. Обратная ситуация, когда адрес А уже назначен узлу Y как индивидуальный, а сосед X пытается назначить его себе как anycast, приведет к тому, что назначение anycast завершится успешно, но все пакеты от соседей в адрес А пойдут исключительно узлу Y. Самостоятельно обсудите, можно ли обнаружить эту ситуацию автоматически. (Указание: не забудьте о возможном присутствии на канале ND proxy.)
Процедура DAD универсальна по отношению не только к адресам, но и к каналам. Ведь она основана на протоколе ND, а тот поддерживает все каналы с групповым вещанием, а не только широковещательные каналы, подобные Ethernet. Как следствие, и процедура DAD применима ко всем каналам этого типа без исключения. Это как раз тот случай, когда ND полезен даже на каналах "точка-точка".
С другой стороны, на канале NBMA процедура DAD полноценно работать не сможет, потому что нет возможности обратиться ко всем узлам такого канала сразу. Это ограничивает применимость к NBMA протоколов, которые зависят от работоспособности DAD. Такие протоколы автоматически выбирают идентификатор интерфейса и потому вдвойне обязаны проверить его на возможный конфликт. К этой категории относятся SLAAC (§5.4.2), расширения для конфиденциальности (§6.2), CGA (§6.3) и HBA (§6.8). Мы познакомимся с ними ниже, а сейчас просто запомним эту особенность: если адрес составляет сам узел, то ему необходим работоспособный механизм DAD.
Пожалуй, единственный случай, в котором требование DAD можно ослабить, — это когда уникальность адресов обеспечивает другой протокол. Уже известный нам пример — это внутриканальные адреса на канале PPP. Они содержат заведомо уникальные идентификаторы интерфейсов, согласованные с помощью IPV6CP (§4.1.2), и поэтому применение к ним DAD избыточно [§5 RFC 5072]. Тем не менее, прочим индивидуальным адресам даже на интерфейсах PPP может потребоваться проверка DAD [там же].
Располагая DAD, узел IPv6 уже способен сам назначить внутриканальные адреса своим сетевым интерфейсам. Так узел может самостоятельно, без вмешательства оператора, выполнить то требование §2.5, что у каждого сетевого интерфейса IPv6 должен быть внутриканальный адрес [§2.1 RFC 4291]. Это важный шаг на пути к автоматической настройке адресов большей области, так как после него узел может свободно общаться со своими соседями.
Кроме того, внутриканальных адресов уже достаточно, чтобы смогла работать простейшая сеть без маршрутизаторов, такая как была показана на 2.2. То есть мы походя "создали" для IPv6 механизм, аналогичный динамической настройке адресов 169.254.0.0/16 в IPv4 [RFC 3927].
Теперь пришло время сделать то, что мы уже давно внесли в наш план, а именно обеспечить централизованное управление конфигурацией хостов IPv6 в пределах канала.
Первым шагом в этом направлении давайте поручим какому-то из узлов-соседей распространение информации о префиксах подсети, назначенных данному каналу. Этой информацией в любом случае должны располагать маршрутизаторы канала, поэтому они и будут идеальными кандидатами на роль ее распространителей, а дополнительные источники этой информации, такие как серверы DHCP, нам сейчас не понадобятся.
Как мы уже упоминали в §5.4.1, вариант DHCP для IPv6 известен под именем DHCPv6 [RFC 3315].
Рассмотрим простейший случай, когда на канале есть всего один выделенный маршрутизатор, а остальные узлы (хосты) получают от него сведения о префиксах и выбирают его маршрутизатором по умолчанию. Благодаря ND мы уже решили несколько важных задач, так что пусть распространение информации о префиксах будет очередным подмножеством ND [§6 RFC 4861]. Оформить его можно следующим образом:
Если принять во внимание нашу текущую задачу, то главная информация, которую мы хотим видеть в объявлении RA, — это список префиксов, доступных узлам канала для автоматической настройки адресов. Подобный список вполне может быть частью объявления RA. А какие еще сведения мы хотели бы видеть в объявлении RA?
В §5.2 мы запланировали, что список маршрутизаторов по умолчанию и список префиксов в хостах IPv6 тоже можно будет настраивать автоматически. Однако, пока еще не принято окончательных решений касательно протокола, нам следует осознать, что "самореклама" маршрутизаторов, объявление префиксов и автоматическая настройка адресов — это взаимосвязанные, но все же разные механизмы, основанные на протоколе ND. Поэтому нам не следует объединять их в один монолитный блок. Рассмотрим сейчас каждый механизм по отдельности.
Розыск маршрутизаторов (router discovery) — это интересная возможность, которая существовала, но так и не
получила распространения в IPv4 [RFC 1256]. На практике есть два способа сообщить хосту IPv4 адрес маршрутизатора по умолчанию:
или он указывается в административном порядке
Для IPv6 мы уже "создали" механизм на основе NUD, с помощью которого хост IPv6 может выбрать "живой" маршрутизатор из списка, не прибегая к другим протоколам кроме ND; это произошло в §5.2. Поэтому хост IPv6 вполне готов работать со списком маршрутизаторов по умолчанию вместо единственного адреса, как это было в IPv4.
Мы имеем в виду именно список разных индивидуальных адресов, а не один адрес anycast, за которым стоят несколько маршрутизаторов.
Оборотная сторона такого списка — это расход усилий на его настройку и поддержку. Почему бы хосту IPv6 не вести этот список самостоятельно, используя сведения из объявлений RA? В принципе, уже сам факт, что узел рассылает соседям объявления RA, может говорить о его готовности работать маршрутизатором по умолчанию. Но, чтобы жестко не связывать между собой сообщения RA и функцию маршрутизатора по умолчанию, мы чуть позже выделим в формате RA поле со смыслом "я — маршрутизатор по умолчанию". Пока что просто отметим его необходимость. Благодаря такой дифференциации, узел сможет распространять среди соседей полезные сведения, не становясь автоматически их маршрутизатором по умолчанию.
Перейдем к следующему из намеченных нами механизмов, а именно к розыску префиксов (prefix discovery). Есть ли у него другие применения, кроме автоматической настройки адресов? Иными словами, какие еще префиксы могут быть интересны хосту? Конечно же, это префиксы "на канале". Ведь, как мы обсудили в §5.2, префикс подсети IPv6 не всегда автоматически находится "на канале", и наоборот, вполне возможны префиксы "на канале", не совпадающие с префиксом подсети. Мы даже отметили себе на будущее, что эти сведения могли бы распространять маршрутизаторы, если бы у нас был походящий механизм.
Сейчас мы как раз над ним работаем, и возможность сообщать узлам префиксы "на канале" возникает у нас естественным образом. Для этого будет достаточно, чтобы в объявлении RA каждый префикс сопровождали его атрибуты. В частности, префикс может обладать такими свойствами:
То есть (а) и (б) — это независимые свойства префикса, и потому каждое из них заслуживает отдельного флага длиной один бит. Обозначим флаг автоматической настройки как A, а флаг "на канале" как L.
Случай, когда оба флага сброшены (A = 0 и L = 0), сейчас не имеет смысла, но он может пригодиться для расширения протокола, когда у префикса появятся новые свойства.
Как и прочая информация в сообщениях RA, сведения о префиксах "на канале" вполне могут исходить от нескольких маршрутизаторов. Рассмотрим это на примере сценария, где канал обслуживают два маршрутизатора, и каждый из них отвечает за свой префикс "на канале", как показано на рис. 6.8. Теперь сведения о префиксах "на канале" полностью рассредоточены, так что маршрутизатор М больше не играет роль единственного координатора и не может выслать переадресовку, когда хост А вручает ему очередной пакет для хоста Б. Ведь информация, что (рис 6.8) Два маршрутизатора на канале, и у каждого своя подсеть
Допустим теперь, что маршрутизаторы М и Н рассылают объявления RA. Они адресованы группе "все узлы канала", так что хост А будет получать объявления не только от М, но и от Н. Поэтому маршрутизатор Н сможет оптимизировать направление трафика, объявив, что префикс 2001:DB8:777::/64 — "на канале" (L = 1). Тогда хост А зафиксирует 2001:DB8:777::/64 в своем списке префиксов, и трафик от А к Б пойдет по кратчайшему пути. Точно так же хост Б получит объявление RA от маршрутизатора М, поместит 2001:DB8:33::/64 в свой список префиксов, и обратный трафик от Б к А тоже пойдет напрямую.
Обратите внимание: в отличие от хостов, маршрутизаторы никогда не используют чужие сообщения RA как источник сведений о канале. Тем не менее, как мы увидим ниже, маршрутизатору следует пассивно наблюдать за чужими сообщениями RA и извещать администратора сети о замеченных разногласиях.
Прекрасно, теперь хост IPv6 может в автоматическом режиме получать собственные адреса, адреса маршрутизаторов по умолчанию и префиксы "на канале". А как быть, если какие-то из этих параметров изменят свои значения в ходе работы сети? Ведь маршрутизаторы и префиксы вполне могут возникать и исчезать по желанию сетевого администратора. Очевидно, что в этом случае вся сеть должна подстраиваться к новым условиям, чтобы администратору не пришлось вручную вычищать старые параметры из конфигурации хостов. В противном случае ценность механизмов автоматической настройки IPv6 будет равна одному ломаному грошу, да и то в базарный день.
Решить эту задачу можно, если параметры хоста не будут вечными. Вот возможная схема [§6.3.5 RFC 4861, §5.5.3 и §5.5.4 RFC 4862]:
хост удаляет параметр из своих настроек, если:
oего время жизни истекает по таймеру, или
oобъявление RA сообщает, что новое время жизни параметра нулевое.
Здесь под параметром мы понимаем автоматически настроенный адрес, или элемент в списке маршрутизаторов по умолчанию, или префикс "на канале". Конечно, автоматически настроенный адрес наследует свое время жизни у префикса с установленным флагом A, из которого он образован.
Добавление нового параметра проблем не вызывает. Автоматически составив пробный адрес из нового префикса с A = 1, хост должен всего лишь убедиться в его уникальности с помощью DAD, прежде чем назначит его интерфейсу (см. §5.4.1). Адрес нового маршрутизатора достаточно внести в список маршрутизаторов по умолчанию, чтобы можно было им воспользоваться, когда NUD обнаружит сбой текущего маршрутизатора (см. §5.2). Новым префиксом "на канале" (L = 1) можно пользоваться немедленно, как только он будет внесен в список префиксов (см. §5.2).
Напомним себе, что все структуры данных эталонного хоста IPv6 привязаны к определенному интерфейсу, как было показано на рис. 6.8. Поэтому объявление RA влияет только на структуры того интерфейса, через который оно было получено.
Будет ли так же проста процедура удаления этих параметров? Два последних вида параметров, маршрутизаторы по умолчанию и префиксы "на канале", определяют только мгновенное решение хоста, как маршрутизировать исходящий пакет, — они явным образом не влияют на долговременное состояние хоста. Более того, исчезновение маршрутизатора или префикса "на канале" — это внешнее событие, на которое хост повлиять неспособен. Поэтому параметры этих двух видов можно и нужно удалить, как только истечет время их жизни по таймеру или объявлению RA.
В то же время, у локального адреса IP свойства особенные. Во-первых, к нему привязаны протяженные во времени сеансы вышестоящих протоколов, а безусловное удаление адреса вызовет их обрыв. Во-вторых, хост все-таки сам управляет своими адресами, пусть даже на основании внешних сведений, таких как административная конфигурация или объявления RA. Благодаря этому перед хостом открывается возможность провести удаление просроченного адреса по более сложной, но менее болезненной процедуре.
Чтобы "прощание" прошло гладко, пусть хост расстается с просроченным адресом в два этапа [§1 и §5.5.4 RFC 4862].
Здесь не работает пословица: долгие проводы — лишние слезы.
Пока время жизни адреса еще не истекло, он доступен как для создания новых сеансов
В качестве исключения, с устаревшего адреса можно устанавливать новые сеансы, если у хоста нет подходящего предпочтительного адреса, например, когда все его адреса в требуемой зоне устарели [§5.5.4 RFC 4862]. Также приложение может явно запросить определенный локальный адрес посредством API, даже если он устаревший.
Все это касается только исходящих сеансов; входящие сеансы на устаревшие адреса по умолчанию разрешены, так как удаленный хост ничего не знает о состоянии адреса, по которому он обращается.
Какое-то время спустя устаревший адрес превращается в недействительный (invalid), полностью исчезая с интерфейса; теперь незавершенные сеансы разрываются в аварийном порядке. В противоположность недействительному адресу, мы назовем адрес действительным (valid), пока он назначен интерфейсу. Предпочтительные и устаревшие адреса — действительные.
Осуществить подобную схему можно, связав с каждым адресом хоста два таймера, первый из которых отсчитывает предпочтительное время жизни адреса (preferred lifetime), а второй — действительное (valid lifetime). Предпочтительное время жизни не может превышать действительное, потому что недействительный адрес не может оставаться предпочтительным.
Состояние адреса "пробный" из §5.4.1 можно рассматривать наряду с состояниями "предпочтительный" и "устаревший". Пробный адрес назначается интерфейсу "не до конца": в этом состоянии его нельзя использовать для обмена данными, и хост не отвечает на обычные вызовы NS касательно пробного адреса. Затем проходит DAD, и по его результатам адрес превращается в предпочтительный или помечается как дубликат. В этом случае времена жизни можно назначить пробному адресу еще до проведения DAD. Небольшая сложность заключается в том, что один или оба таймера могут сработать до завершения DAD.
Самостоятельно разберите оптимизацию механизма DAD, известную как "оптимистический DAD" [RFC 4429], и дайте ей оценку.
Чтобы реализациям IPv6 не пришлось делать большого различия между адресами, назначенными вручную и настроенными автоматически, пусть особое значение времени жизни означает бесконечность. Так как в объявлении RA время жизни будет представлено в виде двоичного беззнакового поля, пусть бесконечность обозначает максимальное значение этого поля, "все единицы". Тогда действительное и предпочтительное времена жизни смогут быть атрибутами всякого локального адреса, но некоторые адреса устаревать или исчезать никогда не будут.
Но даже адресам с конечным временем жизни не обязательно исчезать, пока их префикс анонсируется маршрутизатором. Как мы только что сказали, объявление RA вызывает перезапуск таймеров на соответствующих параметрах. Поэтому, например, если адресу оставалось жить 5 секунд, но пришло объявление RA, в котором время жизни соответствующего префикса 1 час, то таймер будет перезапущен с интервалом 1 час, и адрес в ближайшее время не исчезнет с интерфейса. Благодаря этому, объявления RA могут сколь угодно долго регенерировать автоматически назначенные адреса.
В результате жизненный цикл индивидуального адреса IPv6 выглядит, как показано на рис 6.9(рис 6.9) Жизненный цикл индивидуального адреса IPv6
Наконец-то мы можем составить форматы сообщений RS и RA. Сообщение RS [§4.1 RFC 4861] — это просто вызов, так что главную информацию несет сам факт отправки и приема этого сообщения. Тем не менее, мы учтем полученный в §5.1 опыт с форматом NS и позволим сообщению RS содержать опцию ND "канальный адрес источника" (SLLA), как показано на рис. 6.10. Действительно, раз хост занялся розыском маршрутизаторов, то он наверняка собирается начать сетевой диалог. Поэтому маршрутизаторы смогут поступить предупредительно и заранее создать для этого хоста запись NC в состоянии ПРОСРОЧЕННАЯ, чтобы позднее не тратить времени на его розыск. А вдобавок, на такой вызов RS можно будет ответить индивидуальным, а не групповым объявлением RA, чтобы не тревожить понапрасну другие узлы канала.
Конечно, у опции "канальный адрес источника" есть смысл, только если адрес источника IPv6 определенный, потому как вносить в NC неопределенный адрес было бы эксцентричным поступком. По стандарту, RS допустимо слать с неопределенного адреса источника, (рис 6.10) Вызов маршрутизатора — RS
Формат RA более богат [§4.2 RFC 4861]. Прежде всего, мы решили, что в нем должно быть поле "время жизни маршрутизатора". Пусть нулевое значение этого поля означает, что данный маршрутизатор не хочет, чтобы хосты вносили его в свои списки маршрутизаторов по умолчанию; а если данный маршрутизатор уже в списке, то его следует оттуда удалить.
В данном протоколе все маршрутизаторы эквивалентны. Однако существует расширение ND [RFC 4191], которое позволяет назначить маршрутизаторам разные приоритеты, а также распространить более точные маршруты на некоторые префиксы. У хостов, поддерживающих это расширение, может появиться еще одна структура данных, а именно явная таблица маршрутов.
Еще механизм розыска маршрутизаторов поможет централизованно настраивать параметры ND и даже всего IPv6, если в сообщении RA будут соответствующие поля. Выбор этих полей мы подробно обсуждать не будем, а приведем только их список:
период повтора — параметр RetransTimer (§5.1): пауза между повторными вызовами NS, пока на них нет ответа NA.
Если маршрутизатор не настаивает на определенном значении какого-то из параметров, то пусть он помещает в это поле ноль.
По-видимому, выбор пал на BaseReachableTime и RetransTimer, потому что именно эти параметры мы бы стали подстраивать, если бы, к примеру, нам пришлось оптимизировать работу канала на несколько тысяч хостов. В таком канале накладные расходы на NUD можно понизить, подняв BaseReachableTime, а задержку отклика на сообщения NS, вызванную их высокой частотой, можно компенсировать, увеличив RetransTimer.
В принципе, эти поля можно было вынести в опции ND, как мы поступим с полем "MTU канала".
Если у хоста несколько интерфейсов, то данные параметры относятся к тому интерфейсу, через который было получено объявление RA [§6.3.2 RFC 4861].
Еще в объявлении RA есть два флага, (рис 6.11) Объявление маршрутизатора — RA
Это была фиксированная часть RA, постоянной длины, — показана на рис. 6.11. Но мы, вообще-то, начинали с того, что хотели распространять список префиксов. Длина этого списка, очевидно, переменная, так что давайте поместим этот список среди опций ND.
Можно поступить еще проще: пускай одна опция содержит один префикс, как показано на рис. 6.12. Она так и называется: (рис 6.12) Опция сведений о префиксе — PIO
По нашему плану, атрибутами каждого префикса будут его длина, действительное и предпочтительное времена жизни, а также флаги A и L, говорящие, в каких целях хостам можно использовать данный префикс: для автоматической настройки адресов, для ведения списка префиксов "на канале".
А если маршрутизатор заодно сообщит свой канальный адрес в опции "канальный адрес источника" (SLLA), то хостам не придется дополнительно разрешать его сетевой адрес — они сразу же смогут создать запись NC, хотя бы в состоянии ПРОСРОЧЕННАЯ. Так маршрутизатор "убьет нескольких зайцев" одним объявлением RA.
Еще одна опция ND, специфичная для сообщения RA — это "MTU канала" [§4.6.4 RFC 4861]. Она призвана помочь работе IPv6 поверх каналов с переменным значением MTU. Формат этой опции показан на рис 6.13(рис 6.13) Опция "MTU канала"
Пример такого канала можно найти даже в современной технологии Ethernet. Представьте себе два коммутатора, А и Б, первый с поддержкой сверхбольших кадров ("кадр-слон", jumbo frame), а второй без нее. Если их соединить между собой, то получится ЛВС, в которой PMTU пары портов зависит от того, на каких коммутаторах выбраны эти порты. Между всеми портами А значение PMTU будет 9000 байт, между портами А и Б — 1500 байт, между портами Б тоже 1500 байт. Допустим, что все интерфейсы, подключенные к А, получили значение MTU 9000 байт, а все интерфейсы, подключенные к Б, — 1500 байт. Механизмы TCP MSS и PMTUD не смогут преодолеть такую асимметрию, потому что извещения ICMP "пакет слишком большой" слать будет некому и большие кадры от А к Б будут просто теряться. (Последняя надежда на детектор "черной дыры PMTUD".) Зато если все хосты, подключенные к А и Б, получат одно и то же значение MTU 1500 байт, то канал сможет беспрепятственно работать, несмотря на особенности его реализации.
С какого адреса источника маршрутизатор должен вести рассылку RA? Ведь именно этот адрес хосты сохранят в своих списках маршрутизаторов по умолчанию, если "время жизни маршрутизатора" в объявлении RA больше нуля. Логично было бы использовать тот адрес, вероятность смены которого минимальна. Этим свойством обладает внутриканальный адрес, так как он не зависит от адресного плана сети, текущего провайдера Internet и проч. Поэтому маршрутизатор обязан рассылать RA с внутриканального адреса [§4.2 RFC 4861].
Конечно, это не произвольный внутриканальный адрес, а назначенный тому интерфейсу, через который ведется рассылка.
Такое же правило в §5.2 мы сформулировали для переадресовок [§4.5 RFC 4861].
Обратите внимание, как работает зонная архитектура адресов IPv6 в случае обмена RS и RA. Хост вправе отправить вызов RS с любого из своих адресов на данном интерфейсе [§4.1 RFC 4861], а маршрутизатор может ответить индивидуальным объявлением RA по этому адресу [§6.2.6 RFC 4861]. Таким образом, вполне возможно, что адреса источника и назначения RA будут из зон разной величины. То есть адрес источник RA всегда будет внутриканальным, а вот адрес назначение может быть, например, глобальным. Тем не менее, такой пакет не покинет пределов данного канала и потому не нарушит принципа изоляции зон (§2.4).
Те же соображения применимы и к переадресовке (§5.2). Ее адрес назначения совпадает с адресом источника пакета-виновника, а тот с большой вероятностью принадлежит области больше внутриканальной, так как пакет был направлен через маршрутизатор. В то же время, адрес источника переадресовки — заведомо внутриканальный.
Распространение параметров IPv6 и ND в сообщениях RA влечет за собой еще одну проблему. Если канал обслуживают несколько маршрутизаторов, то вполне может оказаться, что по недосмотру они объявляют разные значения параметров. В этом случае объявления RA от разных маршрутизаторов будут непрерывно менять соответствующие настройки хостов, а флуктуации настроек чреваты нестабильностью в работе протоколов. По этой причине необходимо, чтобы все маршрутизаторы канала объявляли согласованные наборы параметров. В первую очередь, это касается численных параметров в фиксированной части RA, а также опции "MTU канала": их значения обязаны совпадать.
Разные маршрутизаторы вполне могут объявлять разные списки префиксов, но и здесь необходимо определенное единообразие. А именно времена жизни одного и того же префикса, объявляемого разными маршрутизаторами, должны совпадать, чтобы не было нежелательных флуктуаций в настройках хостов. В то же время, флаги префиксов вполне могут отличаться, потому что их можно объединить операцией "побитовое ИЛИ". К примеру, если префикс 2001:DB8:0:123::/64 объявлен одним маршрутизатором как доступный для автоматической настройки адресов (A = 1), а другим — как расположенный "на канале" (L = 1), то хосты вправе как внести его в свои списки префиксов, так и назначить себе адреса на его основе.
Интересный вопрос состоит в том, как именно удалить префикс "на канале" с помощью RA [§6.3.4 RFC 4861]. Сброс флага L в объявлении не даст желаемого результата, потому что L = 0 значит "нет информации", а не "вне канала". Поэтому верным решением будет объявить префикс с L = 1 и нулевым временем жизни. Из двух времен жизни префикса, атрибут "на канале" использует действительное время жизни [§4.6.2 RFC 4861]. Если тот же префикс доступен для автоматической настройки адресов (A = 1), мгновенная установка его действительного времени жизни в ноль не приведет к потере уже настроенных адресов благодаря защитному правилу "2 часа", которое мы обсудим в конце раздела. Но еще надежнее будет объявить один и тот же префикс в двух опциях PIO, из которых одна имеет L = 1 и нулевое время жизни, а другая — A = 1 и ненулевое время жизни.
Чтобы помочь администратору в согласовании параметров, каждому маршрутизатору рекомендовано следить за объявлениями соседей, сравнивать их со своими и сообщать в системном журнале о найденных противоречиях [§6.2.7 RFC 4861].
А как должен поступить хост, если разные маршрутизаторы объявляют разную длину одного и того же префикса? Здесь мы сами себе поставили небольшую ловушку, как хитрый экзаменатор студенту. На самом деле, длина префикса — это его неотъемлемая часть, так что один и тот же префикс не может иметь разные длины: это будут разные цепочки битов, разные префиксы.
Между тем, один префикс может включать в себя другой. Например, двоичный префикс 01 содержится в префиксе 0100, а префикс IPv6 2001:DB8::/32 — в префиксе 2001:DB8::/48. При этом префикс большей длины точнее, так как ему отвечает меньшее множество адресов. Когда такие префиксы находятся на одном канале, это тривиальный случай: множество адресов короткого префикса полностью содержит в себе множество адресов длинного префикса. Тем не менее, это разные префиксы, у каждого из которых свой набор флагов и свое время жизни. Например, префикс "на канале" 2001:DB8::/32 может устареть раньше, чем 2001:DB8::/48, и тогда адреса, составляющие разность этих множеств, окажутся "вне канала".
Затруднение могло бы возникнуть, если бы такие префиксы разной длины были доступны для авто-настройки адресов IPv6. Однако здесь нас спасает правило, что длина префикса подсети IPv6 всегда равна 64.
Когда канал обслуживают несколько маршрутизаторов, то их немедленный ответ на вызов RS приведет к пику нагрузки на канал. Это может даже открыть дверь атаке типа "отказ в обслуживании", когда злоумышленник подключился к каналу или захватил уже подключенный хост и теперь бомбардирует его маршрутизаторы вызовами RS, чтобы спровоцировать усиленный в несколько раз поток ответов RA.
От засылки извне канала пакеты RS и RA защищены при помощи GTSM: поле "предельное число шагов" в них обязано равняться 255 — см. §5.1.
Маршрутизатору не возбраняется всегда направлять объявления RA по адресу "все узлы канала" независимо от того, шлет ли он это объявление по таймеру или по вызову [§6.2.6 RFC 4861, §5.5.1 RFC 4862]. Так злоумышленник или даже просто сбойный хост сможет вызвать целую бурю группового трафика. Чтобы этого не произошло, каждый маршрутизатор обязан ограничить частоту своих объявлений
Тем не менее, проблема нежелательной синхронизации RA остается. С ней надо бороться, сделав время отправки RA случайным. Если RA по вызову, то надо внести случайную задержку, а если по таймеру, то достаточно сделать его интервал случайным [§6.2.4 и §6.2.6 RFC 4861]. Последний штрих состоит в том, чтобы вообще не слать RA по вызову, если задержка помещает его на оси времени после ближайшего RA по таймеру. Благодаря этим предосторожностям, групповая рассылка объявлений RA не повредит каналу даже при возникновении сбойных или злонамеренных хостов.
Интересно, что разные периодические события в сети неожиданно проявляют склонность к самопроизвольной синхронизации во
Последний вопрос, связанный с розыском маршрутизаторов, заключается в том, может ли узел IPv6 впоследствии отказаться от роли маршрутизатора. Согласно общепринятой модели [§6.2.1 RFC 4861], маршрутизатор IPv6 — это функция узла, которую можно избирательно включить или выключить на каждом из его сетевых интерфейсов, при условии что узел вообще способен быть маршрутизатором. Из соображений устойчивости и безопасности, по умолчанию эта функция выключена.
Но допустим теперь, что на данном интерфейсе некого узла М эта функция была когда-то явным образом включена и узел какое-то время исполнял все обязанности маршрутизатора: продвигал транзитный трафик, высылал переадресовки, рассылал объявления RA с информацией о настройках сети. Чтобы теперь корректно уйти со сцены и превратиться в скромный хост, узел М должен аннулировать всю информацию, которую он явно или неявно сообщил хостам.
С явной информацией все довольно просто: достаточно разослать несколько раз объявление RA, в котором список параметров все тот же, но время их жизни нулевое. Так узел М заставит хосты удалить информацию о префиксах и исключить себя из списка маршрутизаторов по умолчанию.
Однако в памяти хостов все еще остаются записи DC, которые указывают на узел М. Подобные записи могли возникнуть, даже если М не был маршрутизатором по умолчанию, а значит, их нельзя убрать объявлением RA. Например, эти записи могли быть созданы по переадресовке другого маршрутизатора Н. В результате окажется, что хосты продолжают слать транзитный трафик через узел М, хотя тот его просто игнорирует. Если бы узел М вообще исчез, то сработал бы механизм NUD, и хосты бы вычистили устаревшие записи DC, связанные с недоступным соседом. Но в нашем случае узел М будет по-прежнему доступен, и образуется "черная дыра".
Чтобы разрешить это затруднение, нам пригодится флаг R в объявлении NA, который мы предварительно зарезервировали. Пусть узел устанавливает этот флаг в своих сообщениях NA, когда он маршрутизатор на данном интерфейсе, и сбрасывает, когда он просто хост. Тогда хосты-соседи смогут более надежно узнать об отказе узла М продвигать транзитный трафик. Как только флаг R в его сообщениях NA обнулится, полагается вычистить все записи DC, указывающие на узел М, потому что он добровольно сложил с себя полномочия маршрутизатора [§7.2.5 RFC 4861].
Таким образом, оказывается, что хост IPv6 должен следить не только за доступностью соседей, но и за их состоянием "хост/маршрутизатор". Этой цели служит булево поле IsRouter в эталонной записи NC [§5.1 RFC 4861].
Определить, что сосед — маршрутизатор, хост может по прямым или косвенным признакам [Приложение D RFC 4861]. Прямой признак один, это флаг R в объявлении NA, тогда как косвенных признаков несколько. Скажем, получение объявления RA от соседа говорит о том, что он — маршрутизатор. На то же самое указывает переадресовка на соседа, если это переадресовка на маршрутизатор (адрес цели не совпадает с адресом назначения). (Переадресовку от соседа хост может получить, только если он уже использует его как маршрутизатор.) Косвенные признаки, в отличие от прямого, не могут подтвердить обратное, а именно что сосед — это хост, а не маршрутизатор.
На этом мы закончили с розыском маршрутизаторов, и пришло время ответить на вопрос о более подробном алгоритме автоматической настройки адресов. Чтобы освежить нашу память, вернемся к моменту, когда хост провел первичную инициализацию стека IPv6 и активировал сетевой интерфейс. Вот что хост делает дальше:
преобразует канальный адрес интерфейса в идентификатор интерфейса IPv6 длины N;
по мере получения объявлений RA сканирует опции PIO [§5.5.3 RFC 4862]:
а)игнорирует опцию, если в ней сброшен флаг A;
Опция PIO с A = 0 может пригодиться для заполнения списка префиксов "на канале", если у нее L = 1; но мы сейчас говорим только об автоматическом назначении адресов сетевому интерфейсу.
игнорирует опцию, если префикс внутриканальный;
в)игнорирует опцию, если действительное время жизни префикса меньше предпочтительного;
г)если префикс еще не назначен:
i)игнорирует префикс, если сумма длин префикса и идентификатора интерфейса не равна длине адреса IPv6, 128 бит;
ii)игнорирует префикс, если его действительное время жизни равно нулю;
iii)создает пробный адрес, сцепляя префикс из RA и идентификатор интерфейса из шага №1;
iv)проверяет пробный адрес на уникальность с помощью DAD;
v)если адрес уникальный, то назначает его интерфейсу и устанавливает для него времена жизни согласно принятой опции RA;
д)иначе, если префикс уже назначен в составе ранее созданного адреса:
i)устанавливает предпочтительное время жизни адреса согласно опции;
ii)устанавливает действительное время жизни на основании опции (см. примечание).
Хотя вопрос о безопасности ND мы еще не обсуждали, уже сейчас понятно, что без дополнительных механизмов защиты сообщения ND уязвимы к обычной подделке. Подделка RA, помимо прочего, позволяет провести очень простую атаку типа "отказ в обслуживании", когда хост получает RA, в котором действительное время жизни его текущих префиксов очень короткое. В результате хост сбрасывает свои адреса и некоторое время остается полностью недоступен. Обратите внимание, что хост не нужно "бомбардировать" — достаточно единственного фальшивого RA. Чтобы блокировать этот вектор атаки, стоит ограничить возможность RA сокращать действительное время жизни адресов [§5.5.3 RFC 4862]. Суть этого ограничения довольно проста, ее иллюстрирует рис. 6.14. Прежде всего, RA может беспрепятственно удлинять время жизни адреса. Например, если к приходу RA адресу оставалось жить 5 минут, а новое время жизни 10 минут, то таймер адреса будет установлен на 10 минут. Если же RA на самом деле пытается сократить время жизни адреса, то оно может укоротить его только до 2 часов. К примеру, если адресу оставалось жить 1 час, а новое время жизни 10 минут, то адрес проживет целый час. Если адресу оставалось жить 3 часа, а новое время жизни 45 минут, то адрес проживет 2 часа. И только если новое время жизни больше 2 часов, оно вступит в силу как есть. Когда у нас появится надежная защита сообщений RA от подделки, это ограничение можно будет снять. Иными словами, ограничение действует только на те сообщения RA, подлинность которых никак не подтверждена. Кроме того, оно действует только на действительное время жизни как наиболее уязвимый параметр, тогда как предпочтительным временем жизни адресов можно управлять без ограничений.
(рис 6.14) Защита от атаки на время жизни адреса Хост выполняет шаг 6 в фоне, пока интерфейс активен, так как периодические объявления RA сообщают текущую конфигурацию данного канала, а она может изменяться по желанию администратора сети. Маршрутизатор может сам назначить своим интерфейсам внутриканальные адреса, выполнив шаги 1–4; шаги 5 и далее — только для хостов [§4 RFC 4862].
У такого механизма автоматической настройки адресов есть одна любопытная особенность: ни маршрутизатор, ни хост не фиксируют назначение адреса в долговременной памяти. Когда хост включают, он проводит процедуру автоматической настройки с самого начала и, как нетрудно убедиться, получает тот же самый набор адресов, пока постоянны его канальный адрес и конфигурация маршрутизаторов. Можно сказать, что у такого механизма нет внутреннего состояния. Поэтому полностью его называют так: автоматическая настройка адресов без внутреннего состояния, сокращенно SLAAC (stateless address autoconfiguration) [RFC 4862].
В качестве безвредной оптимизации, [§5.7 RFC 4862] разрешает хосту хранить текущие настройки SLAAC в долговременной памяти (ППЗУ, диск) в пределах времени их жизни.
Важное условие работы SLAAC — чтобы канал поддерживал групповое вещание на сетевом уровне. Если это не так, то и SLAAC на таком канале работать не сможет.
Это не значит, что для SLAAC нужно настоящее групповое вещание на канальном уровне, например, каким мы его знаем в Ethernet. Требуется групповое вещание именно на сетевом уровне, а канальный уровень может его эмулировать. Так, например, в канале "точка-точка" групповое вещание сводится к передаче пакетов удаленному узлу. А если канал многоадресный и широковещательный, но без группового вещания, то групповые пакеты можно передавать всем узлам в широковещательных кадрах, полагаясь на отбор нужных пакетов сетевым уровнем. Пример этого подхода мы находим в ARCNET [§4.3 RFC 1201, §7 RFC 2497].
Как и всякий сложный автоматический механизм, SLAAC должен быть, в идеале, полностью управляемым, а по меньшей мере — отключаемым. У оператора узла должна быть возможность блокировать работу SLAAC на сетевом интерфейсе, если она нежелательна по тем или иным соображениям. Это касается как хостов, так и маршрутизаторов. Хост должен быть готов работать с ручными настройками, игнорируя объявления RA. Что же касается маршрутизатора, то рассылка RA может повлиять на конфигурацию многих хостов, и поэтому ее надо вообще отключить по
Это вовсе не противоречит обязательному статусу поддержки элементов SLAAC узлами IPv6. Одно дело, когда функцию можно избирательно отключить, а совсем другое, когда она вообще недоступна. То же касается DAD [§5.4 RFC 4862] и ND в целом.
Интересное применение возможностей SLAAC — это перенумерация сети IPv6, например, при переходе от одного провайдера к другому [§4.1 RFC 4862]. Ввиду постоянной длины префикса подсети, все идентификаторы интерфейсов могут остаться теми же, и тогда задача сводится к перенумерации префиксов подсетей. Гладко провести эту операцию можно, применяя в переходный период два префикса с установленным флагом A. Тогда каждый хост назначит своему интерфейсу два адреса, старый и новый. Далее, управляя предпочтительным временем жизни старого адреса, можно добиться, чтобы он больше не выступал источником новых сеансов. Завершить операцию можно, полностью упразднив старый адрес с помощью его действительного времени жизни. При этом достаточно менять настройки маршрутизаторов, а хосты сами их подхватят из объявлений RA. Подробно безболезненная процедура перенумерации разобрана в [RFC 4192].
Поработав над розыском соседей, мы можем пересмотреть типы вещания в IPv6. Прежде всего, что произошло с широковещанием? До сих пор мы старательно избегали этой темы. Однако теперь мы убедились, что необходимость в широковещании полностью отпала благодаря обязательной поддержке группового вещания. Широковещание IPv4 опиралось на широковещание канального уровня, а с ним мы активно боремся, чтобы не расходовать впустую ресурсы сети. Обратиться же ко всем узлам IPv6 в определенной зоне всегда можно с помощью общепринятой группы "все узлы" (FF0x::1). Итак, в IPv6 нет широковещания; его функции выполняет групповое вещание.
А когда нет широковещания, то не нужны и особые широковещательные адреса. В частности, идентификатор интерфейса FFFF:FFFF:FFFF:FFFF (все биты установлены) никоим образом не зарезервирован.
Групповое вещание полезно для протоколов не только служебных, но и прикладных. Оно выручает в тех случаях, когда один пакет надо с минимальными затратами разослать нескольким узлам. Например, сервер NTP может передавать "сигналы точного времени" сразу группе клиентов; клиент DHCP может обратиться одним запросом к группе серверов и получить несколько предложений, а затем выбрать среди них наиболее подходящее.
Однако возникают похожие задачи, которые групповое вещание решить не может. К примеру, нет смысла создавать в организации группу серверов DNS хотя бы потому, что протокол DNS рассчитан на индивидуальное вещание и клиенту не будет никакой выгоды от нескольких ответов.
Также групповое вещание совершенно бессильно в протоколах, работающих поверх TCP. Тем не менее, сама концепция сетевой группы, когда за одним адресом стоят несколько узлов (точнее, интерфейсов), сохраняет свое значение и в этом случае. Скажем, в крупной организации можно было бы назначить всем серверам DNS или SMTP один "волшебный" адрес X, так чтобы клиент, независимо от местоположения в сети и не меняя настроек, всегда обращался бы к ближайшему серверу (см. рис. 6.1). С точки зрения источника пакета, это будет вещание наугад ((рис 6.1) Идея anycast для DNS
Тем не менее, роль случайности в этом типе вещания не так велика, как кажется источнику. Для простых протоколов, где весь сеанс состоит из обмена парой пакетов UDP по схеме "запрос-ответ", действительно неважно, в какой именно узел anycast попадет запрос. Между тем, TCP не играет в кости: для его работы надо, чтобы пакеты данного соединения попадали в один и тот же узел anycast хотя бы при условии постоянной конфигурации сети. Получается оксюморон: вещание наугад должно быть воспроизводимым (см. рис. 6.2).
(рис 6.2) Anycast должен быть воспроизводимым
Примером простого протокола "запрос-ответ" мог бы служить DNS поверх UDP, если бы его стороны вообще не поддерживали транспорт "виртуальная цепь" при поддержке TCP [RFC 5966]. Но, как мы помним, поддержка этого транспорта важна для передачи длинных сообщений DNS. Так что даже DNS требует от вещания наугад воспроизводимости.
И даже простейший протокол вида "запрос-ответ" потребует воспроизводимого вещания наугад, если длина его полностью сформированного пакета может превышать минимальное значение MTU. Дело здесь, конечно же, во фрагментации и сборке. Ведь после фрагментации каждый фрагмент представляет собой отдельный пакет и проходит путь к адресату независимо от других фрагментов, а встретиться они должны на одном и том же узле назначения, чтобы сборка прошла успешно.
Как нам выполнить это противоречивое условие? Давайте попробуем свести задачу к двум крайним случаям. В первом из них источник и узлы anycast будут разбросаны по сети, так что они не окажутся соседями друг друга. Во втором же случае источник и все узлы anycast будут соседями по каналу.
В первом случае задачу можно решить обычной настройкой маршрутов в сети. Для простоты положим, что источник — это хост, у которого есть только маршрутизатор по умолчанию. По условию задачи, источник — не сосед ни одному из узлов anycast, а значит, первым шагом пакет попадет на маршрутизатор по умолчанию. Если у того будет маршрут для адреса anycast X в сторону ближайшего узла anycast N, то следующим шагом пакет достигнет его или хотя бы приблизится к нему и т.д. То есть достаточно выстроить на маршрутизаторах цепочку маршрутов, которая приведет пакет к ближайшему узлу anycast, как показано на рис. 6.3. Принципиально это ничем не отличается от процесса маршрутизации в сложной сети, где к данному адресату можно проложить более одного пути и потому пакеты от разных источников ходят к нему через совершенно разные участки сети. Следовательно, и осуществить такую схему можно теми же инструментами: статическими маршрутами или протоколом динамической маршрутизации.
(рис 6.3) Трасса к адресу anycast
Тогда вопрос для нас представляет только финал, когда последний маршрутизатор в цепочке передает пакет непосредственно узлу anycast. Здесь возможны два очевидных подхода.
Согласно первому из них, маршрутизатор должен полагать, что адрес X — "на канале". Как сообщить эту информацию маршрутизатору, зависит от реализации. К примеру, можно назначить каналу между маршрутизатором и узлом anycast префикс X/64. Так или иначе, маршрутизатор проведет розыск адреса X, а узел anycast откликнется и получит пакет.
Второй подход состоит в том, чтобы каждому узлу anycast J назначить, помимо адреса X, обычный индивидуальный адрес $$A_J$$. Тогда в таблице маршрутов последнего маршрутизатора достаточно будет создать маршрут $$X\to A_N$$, и по нему пакет достигнет узла anycast N. В этой схеме адрес $$A_J$$ вполне может быть внутриканальным, а хотя бы один такой адрес — это обязательный атрибут всякого интерфейса IPv6 (см. §2.5); так что назначать дополнительные адреса только ради работы anycast не придется. Сам же адрес $$X $$ можно назначить любому сетевому интерфейсу узла, включая "петлю", как это показано на рис. 6.4.
(рис 6.4) Последний шаг к адресу anycast
Когда же источник переместится в другую часть сети, как показано на рис. 6.5, там у него будет новый маршрутизатор по умолчанию, с которого начнется иная цепочка маршрутов к ближайшему узлу anycast K. Так как цепочка маршрутов зависит только от точки подключения источника, вещание наугад будет воспроизводимым, пока источник находится на одном месте, а это нас вполне устраивает.
(рис 6.5) Сеть выбирает узел anycast в зависимости от точки подключения хоста
Перейдем теперь ко второму случаю, когда источник и все узлы anycast — соседи по какому-то каналу. В этом случае трудно сказать, какой из узлов anycast ближе к источнику, так что пусть это будет настоящее вещание наугад, когда первичный выбор узла anycast происходит случайно. Тем не менее, после случайного выбора должен идти воспроизводимый этап передачи пакетов. Решим ли мы и эту задачу уже доступными нам средствами?
Допустим, что источник по-прежнему не подозревает об особенностях адреса X и работает с ним, как с обычным индивидуальным адресом. По условию задачи, адрес X — "на канале". Поэтому источник первым делом проведет розыск соседа X, направив вызов NS группе искомого узла Г(X), как мы обсудили в §5.1. Если наши узлы anycast заранее вступят в эту группу, то все они, в идеале, получат NS и ответят на него объявлениями NA. В результате источник получит несколько объявлений NA об одном и том же сетевом адресе цели X, но все они будут с разными канальными адресами, как показано на рис. 6.6.
(рис 6.6) Anycast в пределах канала
Потенциально эти объявления могут состязаться за запись в кэше NC источника, меняя ее непредсказуемым образом. Поэтому нам надо позаботиться, чтобы узлы anycast не воевали между собой. Гарантией мира будет сброшенный флаг O ( O = 0) в их объявлениях NA насчет адреса цели X. Тогда в кэше NC закрепится канальный адрес из объявления, пришедшего самым первым. Последующие объявления станут переводить запись в состояние ПРОСРОЧЕННАЯ, но она будет возвращаться в состояние ДОСТУПНАЯ, не меняя канального адреса, благодаря процедуре NUD. Таким образом, вещание наугад будет воспроизводимым и в этом случае.
Если на канале будет много источников вещания наугад и все они обратятся по адресу X, то их обращения распределятся между узлами anycast случайным образом. Так вещание наугад можно использовать для распределения нагрузки на узлы.
Пока что в нашей схеме узлы anycast отвечают на каждый вызов NS "хором", а это приведет к пикам нагрузки на канал. Чтобы сгладить эти
пики, пусть каждый узел anycast задерживает объявление NA на случайное время, от 0 до заданного
По-хорошему, параметр MAX_ANYCAST_DELAY_TIME должен быть меньше параметра RETRANS_TIMER, чтобы оставить немного времени на передачу по каналу, но в §10 RFC 4861 их значения совпадают.
С другой стороны, если бы узлы anycast отвечали на вызов NS без искусственной задержки, это позволило бы источнику выбрать ближайший или наименее загруженный узел, так как выигрывает ответ NA, пришедший первым.
А что произойдет, если выбранный узел anycast через какое-то время станет недоступен, скажем, его просто выключат? Тогда источник вычистит запись об адресе X из NC благодаря NUD, и цикл розыска повторится с начала. В результате источник переключится на другой, доступный узел anycast. Так оказывается, что вещание наугад в рамках одного канала открывает путь не только к распределению нагрузки, но и к резервированию.
Итак, мы рассмотрели два независимых сценария с вещанием наугад. Можно ли их объединить, чтобы охватить все возможные случаи? Конечно! Если мы поместим между источником и каналом с узлами anycast маршрутизатор, как показано на рис. 6.7, то выбирать узел anycast придется маршрутизатору, но он с этой задачей вполне справится. Ведь выбор узла anycast по адресу ничем не отличается от обычного розыска соседа. Однако у гибридного сценария есть важное отличие от сценария "все на одном канале": если несколько источников станут обращаться по адресу anycast через один и тот же маршрутизатор, то все обращения пойдут на один и тот же узел anycast. В этом случае распределения нагрузки не произойдет.
(рис 6.7) Anycast на канале через маршрутизатор
Остался последний вопрос касательно вещания наугад: какова структура "волшебного" адреса anycast? Возникнет ли у нас новый тип адреса IPv6? Нет, не возникнет. "Построенная" нами схема вещания наугад в IPv6 явно требует, чтобы адрес anycast ничем не отличался от индивидуального адреса. Только при этом условии вещание наугад можно вести на основе уже доступных механизмов, маршрутизации и ND. Узнать, что данный адрес — anycast, можно только из настроек узла, которому он назначен, и только такой узел работает с адресом anycast чуть иначе.
"Разрабатывая" вещание наугад, мы почти не ограничивали себя деталями IPv6. Поэтому вещать наугад по той же схеме можно и в среде IPv4, с точностью до замены ND на ARP [RFC 1546]. Вещание наугад уже пробовали использовать в DNS [RFC 3258].
О назначении общепринятых адресов anycast в IPv6 см. §6.1 и [RFC 2526].
Некоторые реализации не поддерживают передачу пакетов с адресом источника
Можно подвести итоги раздела. В IPv6 исчезло широковещание, но зато появилось вещание наугад. Индивидуальный и групповой режимы вещания продолжают играть свои роли, причем групповое вещание IPv6 также выполняет те важные функции, которые традиционно были свойственны широковещанию.
Как показывает практика, реализации группового вещания на канальном уровне зачастую менее отлажены, чем остальной код, и потому они далеко не всегда надежны. Не стоит сомневаться, что "глюки" канального группового вещания неизбежно выливаются в труднодиагностируемые проблемы на уровне IPv6. Поэтому производителям канального оборудования придется хорошенько потрудиться над тем, чтобы их продукция стала действительно пригодна к работе в эпоху IPv6.
Давным-давно существовал протокол IPX, в чем-то похожий на IPv6
Если адаптер позволяет программировать свой адрес MAC, то можно было бы сохранить старый адрес, однако это означало бы переход к самостоятельному управлению адресами MAC и — прощай, простота IPX! В действительности, реализации даже позволяли выбирать адрес IPX на свой вкус, но это вызывало программную смену связанного с ним адреса MAC.
Конечно, еще одно очевидное ограничение IPX состояло в том, что он мог работать только поверх каналов с адресацией MAC 48 или совместимой.
К счастью, ограничения на идентификатор интерфейса IPv6 гораздо мягче, чем это было в IPX. Единственное условие, на котором мы
настаиваем, — это чтобы идентификатор интерфейса в индивидуальном адресе
Чаще всего серверу достаточно постоянного имени, которое зарегистрировано в DNS. Тем не менее, в некоторых случаях нужен именно постоянный адрес IP, который будет зафиксирован в настройках клиентов. Например, это касается серверов DNS. Ведь узнать из DNS адрес сервера DNS — это все равно, что вытащить себя из болота за собственные волосы.
Между тем, технология TCP/IP находит применение не только в традиционных вычислительных сетях. Не исключено, что скоро все интеллектуальные бытовые приборы и личные электронные устройства будут общаться друг с другом по IPv6, и движение в эту сторону заметно уже сегодня. Управление такими сетями требует нетрадиционного подхода, потому что у рядового пользователя не будет ни желания, ни навыков, чтобы вручную назначить адрес IPv6 каждому из окружающих его "маленьких цифровых друзей". Но даже в традиционных сетях далеко не все узлы требуют адресов, назначенных вручную. Например, такие адреса не нужны большинству рабочих станций и терминалов. Для них, равно как и для персональных электронных устройств, будет достаточно предсказуемой автоматической настройки адресов.
Предсказуемость здесь нужна, чтобы облегчить отладку сети, если уж до этого дойдет дело.
Итак, мы видим, что нам пора заняться процедурой автоматической настройки индивидуальных адресов в IPv6. На какие части можно разбить ее? Прежде всего, узел должен найти для каждого из активных сетевых интерфейсов один или несколько адресов IPv6. Чтобы составить хотя бы один адрес IPv6, узел должен откуда-то узнать значения его фундаментальных частей — префикса подсети и идентификатора интерфейса. Посмотрим на эти части по отдельности, начав с последней.
Если у интерфейса, подлежащего настройке, есть уникальный канальный адрес, такой как MAC 48 или EUI 64, то это отличный кандидат на роль идентификатора интерфейса. Все, что требуется в этом случае — преобразовать канальный адрес к формату "модифицированный EUI 64" по общепринятой методике, которую мы "разработали" в §2.7. Эта часть задачи не представляет трудности.
Строго говоря, методику преобразования канального адреса в идентификатор интерфейса должен приводить документ, посвященный передаче IPv6 в данной канальной среде. Например, для Ethernet это [RFC 2464]. Тем не менее, случаи EUI 64 и MAC 48 также рассмотрены в центральном документе "Адресная архитектура IPv6" потому что эти виды идентификаторов популярны и применяются в самых разных технологиях канального уровня [Приложение A, RFC 4291]. Там же приводятся рекомендации, что делать, если у интерфейса нет уникального канального адреса.
Мы уже встретили пример, когда, не имея готовых адресов, канальный протокол согласует уникальные идентификаторы интерфейса для IPv6. Это, конечно же, IPV6CP в рамках PPP — см. §4.1.2.
Как выбрать префикс подсети, зависит от области адреса. Если надо составить внутриканальный адрес, то искомый префикс заранее известен: FE80::/64. Благодаря этому, узел может самостоятельно выбрать внутриканальные адреса для своих активных интерфейсов, не пользуясь никакими дополнительными сведениями.
Хотя для внутриканальных адресов был зарезервирован префикс FE80::/10, на интерфейсах мы встречаем только FE80::/64 в согласии с тем правилом, что длина префикса подсети IPv6 составляет 64 бита. Но, строго говоря, внутриканальный префикс подсети может зависеть от типа канала и уточняется соответствующим документом о канальной инкапсуляции IPv6.
Если же область адреса больше, чем канал, то префикс подсети выбирает и сообщает узлу администратор сети. Здесь наш путь снова раздваивается: или администратор вручную заносит префикс подсети в настройки узла, или же префикс настраивается централизованно, а узел узнает его автоматически, следуя некому протоколу. Такой протокол вполне сможет работать поверх IPv6, так как узел уже выбрал себе внутриканальные адреса.
Искушенный читатель спросит, почему бы не выбрать этим протоколом DHCP (точнее, его вариант для IPv6 — DHCPv6). Сейчас мы убедимся, что в NDP уже заложено достаточно возможностей, чтобы обойтись без еще одного протокола, по крайней мере, для распространения самых необходимых настроек.
Мы посвятим §5.4.2 вопросу о точном механизме автоматической настройки префикса подсети, а сейчас давайте переключимся на следующую проблему. Предположим, что узел уже автоматически составил адрес IPv6. Например, это может быть внутриканальный адрес, префикс которого известен заранее: FE80::/64. В отличие от IPX, где идентификатор интерфейса обязан совпадать с его адресом MAC, в IPv6 такого требования нет. Поэтому нельзя исключить ситуацию, когда автоматически выбранный идентификатор интерфейса уже занят другим узлом-соседом.
Скажем, узел собирается назначить внутриканальный адрес интерфейсу Ethernet, адрес MAC которого 00-01-02-03-04-05. Согласно правилам "модифицированного EUI 64", ему отвечает идентификатор интерфейса 02-01-02-FF-FE-03-04-05. Сцепляя его с внутриканальным префиксом, узел получает адрес FE80::0201:02FF:FE03:0405. Несмотря на уникальность исходного адреса MAC, тот же самый адрес IPv6 уже может быть назначен другому соседу, например, вручную. Таким образом, было бы опрометчиво назначить автоматически составленный адрес IPv6, не проверив его на уникальность в пределах канала.
Строго говоря, рассмотренный в примере конфликт адресов возникает из-за нарушения формата "модифицированный EUI 64": администратор не должен назначать "с потолка" идентификаторы интерфейсов, у которых установлен бит U/L. Тем не менее, на практике случается всякое. Даже производители сетевых адаптеров не застрахованы от ошибок, и у разных адаптеров могут совпасть адреса MAC. Подобные проблемы желательно выявлять до того, как они навредят работе сети.
Непроверенный адрес мы обозначим как пробный ( tentative). Требуется ли новый протокол, чтобы проверить такой адрес на уникальность? На самом деле, нет — мы можем обойтись протоколом ND из §5.1, слегка доработав его. В общих чертах схема ясна: узел посылает запрос NS касательно пробного адреса и ожидает, не ответит ли кто-то из соседей объявлением NA; если такой ответ поступит, то пробный адрес, очевидно, уже занят. Однако этот случай применения ND обладает рядом отличительных особенностей, которые выделяют его в под-протокол с названием DAD ( duplicate address detection, выявление дубликатных адресов) [§5.4 RFC 4862].
Как мы знаем, в IPv4 для той же цели служил добровольный запрос ARP. Хотя практика IPv4 уже давно держит этот механизм в своем арсенале, формальная процедура была опубликована относительно недавно под названием " обнаружение конфликтов адресов IPv4" (IPv4 Address Conflict Detection, ACD) [RFC 5227].
Первое затруднение состоит в том, что участие в ND, каким мы его знаем, требует уже назначенного индивидуального адреса. Ведь у пакета ND должен быть определенный адрес источника, не так ли? В то же время, узел не может назначить себе адрес, не проверив его по DAD. Это рождает "проблему курицы и яйца", для решения которой DAD должен работать, даже когда узел-инициатор вообще не обладает индивидуальными адресами. Пусть узел, выполняющий DAD, всегда посылает запрос NS с неопределенным адресом источника IPv6 :: [§5.4.2 RFC 4862] и без опции "канальный адрес источника" [§4.3 RFC 4861]. Тогда неопределенный адрес источника выделит NS для DAD среди обычных вызовов NS, передаваемых с целью разрешения адреса или NUD.
Но как узел-инициатор получит возможный ответ NA? Ведь пакет IPv6 нельзя направить по неопределенному адресу! Чтобы обойти и эту преграду, пусть отвечающий узел направляет ответ NA по групповому адресу "все узлы канала", FF02::1, если вызов NS пришел с неопределенного адреса. Следовательно, узел-инициатор должен вступить в эту группу перед началом DAD [§5.4.2 RFC 4862].
Как следствие, протокол управления группами IPv6 MLD должен работать, когда на интерфейсе еще нет индивидуальных адресов. Возьмем себе это на заметку, чтобы вспомнить позже, когда дело дойдет до MLD (§6.4).
Благодаря тому, что запрос NS в рамках DAD не использует опцию "канальный адрес источника" и ответ на него подлинно групповой, механизм DAD устойчив к конфликтам канальных адресов. Если бы мы "оптимизировали" DAD так, чтобы ответ NA шел по индивидуальному адресу MAC, коммутируемая локальная сеть направила бы его одному случайному владельцу этого адреса MAC, и DAD с большой вероятностью дал бы сбой. А ведь конфликт канальных адресов приведет и к конфликту адресов IPv6, составленных на их основе посредством "модифицированного EUI 64".
Отвечающий узел шлет объявление NA в ответ на запрос NS, однако в случае DAD это объявление направляется всем узлам канала, а не только узлу-инициатору DAD. Такое объявление NA получат и те узлы, которые о нем не просили. Поэтому, отвечая на вызов DAD, то есть вызов NS с неопределенного адреса, узел должен сбросить флаг S (S = 0). Вот еще одна особенность применения ND для DAD.
Дополнительное затруднение возникает, когда два узла одновременно пытаются проверить один и тот же незанятый адрес. Если следовать простейшей схеме, то ни один из узлов не получит объявления NA, и оба узла решат, что пробным адресом можно пользоваться. В результате возникнет конфликт адресов. Чтобы избежать такого исхода, узел-инициатор должен обращать внимание не только на объявления NA, но и на вызовы NS. Если узел получит чужой вызов NS касательно пробного адреса, исходящий с неопределенного адреса, то значит, еще один узел пытается проверить тот же адрес с помощью DAD, и назревает конфликт адресов [§5.4.3 RFC 4862]. Если же чужой вызов NS касательно пробного адреса поступит с определенного адреса, то это обычный розыск соседа, и его следует игнорировать, потому что право нашего узла на пробный адрес еще не доказано. В свою очередь, чтобы принимать интересующие его вызовы NS, узел-инициатор DAD должен заранее вступить в группу искомого узла, отвечающую пробному адресу [§5.4.2 RFC 4862].
Вообще говоря, узел может получать и свои собственные групповые сообщения. Так как в данном случае адрес источника IPv6 неопределенный, источник вызова DAD надо идентифицировать, если это возможно, по его канальному адресу [Приложение A RFC 4862]. Альтернативный подход, если локальный уровень IPv6 уверен, что получает собственные вызовы DAD, — это подсчитать разность между числом посланных и принятых сообщений [там же]; очевидно, в отсутствие конфликта она должна оставаться нулевой. В любом случае, верная обработка этой ситуации зависит от точных свойств канала и интерфейса в него.
Интересная идея, подсказанная нам редактором, состоит вот в чем: узел мог бы отличать собственные групповые вызовы NS от чужих, если бы он включал в свои вызовы особую опцию ND, содержащую достоверный "отпечаток пальцев" узла, например, подпись HMAC.
Узел-владелец пробного адреса, отвечая на вызов DAD, мог бы послать объявление NA более узкой группе искомого
узла, а не группе "все узлы канала". Ведь узел-инициатор DAD все равно обязан состоять в
обеих группах. Мы не видим препятствий для такого подхода, однако стандарты о нем не говорят. По-видимому, мысль разработчиков
IPv6 шла по тому же пути, что и наша: сначала они решали проблему доставки объявления NA инициатору DAD, а только потом
озаботились проблемой одновременных сеансов DAD. Затем надо было соотнести полученные решения между собой и оптимизировать
первое из них в свете второго, но до этого, видимо, просто не дошли руки
Соберем воедино все наши замечания и оформим их как процедуру DAD, в ходе которой узел А проверяет пробный адрес П на интерфейсе И:
узел А вступает на интерфейсе И в следующие группы:
а)"все узлы канала", FF02::1;
б)группа искомого узла, отвечающая адресу П (группа Г);
чужой вызов NS с неопределенного адреса касательно адреса П;
б)объявление NA об адресе П;
DAD дает отрицательный результат, если истекает тайм-аут
Поскольку сообщения ND могут теряться, а именно отсутствие сообщений означает отрицательный результат, процедуру DAD следует повторить
несколько раз
По умолчанию параметр DupAddrDetectTransmits равен единице [§5.1 RFC 4862], и повтора нет.
Вооружившись такой процедурой DAD, мы можем проверять любые индивидуальные адреса IPv6, а не только составленные автоматически. Поэтому пусть узел IPv6 выполняет DAD перед назначением каждого индивидуального адреса независимо от того, настроен ли он вручную или получен автоматически [§5.4 RFC 4862]. Так DAD поможет выявлять ошибки в настройке сети и минимизировать ущерб от них.
Тем не менее, администратор узла может избирательно заблокировать DAD на интерфейсе, установив параметр DupAddrDetectTransmits в ноль [§5.4 RFC 4862].
Обратите внимание: проверка DAD — только для индивидуальных адресов. В частности, DAD никогда не применяют к адресам anycast, потому что те по определению не уникальны [§5.4 RFC 4862]. Между тем, DAD вполне способен обнаружить и предотвратить случай, когда узел назначает своему интерфейсу некий адрес А как индивидуальный, хотя тот уже назначен другим интерфейсам канала как anycast. Ведь, как мы обсудили в §5.3, принадлежность внешне индивидуального адреса IPv6 к anycast — это локальное знание обладающего им узла. В случае назревающего конфликта узел, который назначает себе индивидуальный адрес, просто получит объявления NA с O = 0, а не 1. Условие надежной работы этого механизма таково: MAX_ANYCAST_DELAY_TIME RetransTimer. Обратная ситуация, когда адрес А уже назначен узлу Y как индивидуальный, а сосед X пытается назначить его себе как anycast, приведет к тому, что назначение anycast завершится успешно, но все пакеты от соседей в адрес А пойдут исключительно узлу Y. Самостоятельно обсудите, можно ли обнаружить эту ситуацию автоматически. (Указание: не забудьте о возможном присутствии на канале ND proxy.)
Процедура DAD универсальна по отношению не только к адресам, но и к каналам. Ведь она основана на протоколе ND, а тот поддерживает все каналы с групповым вещанием, а не только широковещательные каналы, подобные Ethernet. Как следствие, и процедура DAD применима ко всем каналам этого типа без исключения. Это как раз тот случай, когда ND полезен даже на каналах "точка-точка".
С другой стороны, на канале NBMA процедура DAD полноценно работать не сможет, потому что нет возможности обратиться ко всем узлам такого канала сразу. Это ограничивает применимость к NBMA протоколов, которые зависят от работоспособности DAD. Такие протоколы автоматически выбирают идентификатор интерфейса и потому вдвойне обязаны проверить его на возможный конфликт. К этой категории относятся SLAAC (§5.4.2), расширения для конфиденциальности (§6.2), CGA (§6.3) и HBA (§6.8). Мы познакомимся с ними ниже, а сейчас просто запомним эту особенность: если адрес составляет сам узел, то ему необходим работоспособный механизм DAD.
Пожалуй, единственный случай, в котором требование DAD можно ослабить, — это когда уникальность адресов обеспечивает другой протокол. Уже известный нам пример — это внутриканальные адреса на канале PPP. Они содержат заведомо уникальные идентификаторы интерфейсов, согласованные с помощью IPV6CP (§4.1.2), и поэтому применение к ним DAD избыточно [§5 RFC 5072]. Тем не менее, прочим индивидуальным адресам даже на интерфейсах PPP может потребоваться проверка DAD [там же].
Располагая DAD, узел IPv6 уже способен сам назначить внутриканальные адреса своим сетевым интерфейсам. Так узел может самостоятельно, без вмешательства оператора, выполнить то требование §2.5, что у каждого сетевого интерфейса IPv6 должен быть внутриканальный адрес [§2.1 RFC 4291]. Это важный шаг на пути к автоматической настройке адресов большей области, так как после него узел может свободно общаться со своими соседями.
Кроме того, внутриканальных адресов уже достаточно, чтобы смогла работать простейшая сеть без маршрутизаторов, такая как была показана на 2.2. То есть мы походя "создали" для IPv6 механизм, аналогичный динамической настройке адресов 169.254.0.0/16 в IPv4 [RFC 3927].
Теперь пришло время сделать то, что мы уже давно внесли в наш план, а именно обеспечить централизованное управление конфигурацией хостов IPv6 в пределах канала.
Первым шагом в этом направлении давайте поручим какому-то из узлов-соседей распространение информации о префиксах подсети, назначенных данному каналу. Этой информацией в любом случае должны располагать маршрутизаторы канала, поэтому они и будут идеальными кандидатами на роль ее распространителей, а дополнительные источники этой информации, такие как серверы DHCP, нам сейчас не понадобятся.
Как мы уже упоминали в §5.4.1, вариант DHCP для IPv6 известен под именем DHCPv6 [RFC 3315].
Рассмотрим простейший случай, когда на канале есть всего один выделенный маршрутизатор, а остальные узлы (хосты) получают от него сведения о префиксах и выбирают его маршрутизатором по умолчанию. Благодаря ND мы уже решили несколько важных задач, так что пусть распространение информации о префиксах будет очередным подмножеством ND [§6 RFC 4861]. Оформить его можно следующим образом:
Если принять во внимание нашу текущую задачу, то главная информация, которую мы хотим видеть в объявлении RA, — это список префиксов, доступных узлам канала для автоматической настройки адресов. Подобный список вполне может быть частью объявления RA. А какие еще сведения мы хотели бы видеть в объявлении RA?
В §5.2 мы запланировали, что список маршрутизаторов по умолчанию и список префиксов в хостах IPv6 тоже можно будет настраивать автоматически. Однако, пока еще не принято окончательных решений касательно протокола, нам следует осознать, что "самореклама" маршрутизаторов, объявление префиксов и автоматическая настройка адресов — это взаимосвязанные, но все же разные механизмы, основанные на протоколе ND. Поэтому нам не следует объединять их в один монолитный блок. Рассмотрим сейчас каждый механизм по отдельности.
Розыск маршрутизаторов (router discovery) — это интересная возможность, которая существовала, но так и не
получила распространения в IPv4 [RFC 1256]. На практике есть два способа сообщить хосту IPv4 адрес маршрутизатора по умолчанию:
или он указывается в административном порядке
Для IPv6 мы уже "создали" механизм на основе NUD, с помощью которого хост IPv6 может выбрать "живой" маршрутизатор из списка, не прибегая к другим протоколам кроме ND; это произошло в §5.2. Поэтому хост IPv6 вполне готов работать со списком маршрутизаторов по умолчанию вместо единственного адреса, как это было в IPv4.
Мы имеем в виду именно список разных индивидуальных адресов, а не один адрес anycast, за которым стоят несколько маршрутизаторов.
Оборотная сторона такого списка — это расход усилий на его настройку и поддержку. Почему бы хосту IPv6 не вести этот список самостоятельно, используя сведения из объявлений RA? В принципе, уже сам факт, что узел рассылает соседям объявления RA, может говорить о его готовности работать маршрутизатором по умолчанию. Но, чтобы жестко не связывать между собой сообщения RA и функцию маршрутизатора по умолчанию, мы чуть позже выделим в формате RA поле со смыслом "я — маршрутизатор по умолчанию". Пока что просто отметим его необходимость. Благодаря такой дифференциации, узел сможет распространять среди соседей полезные сведения, не становясь автоматически их маршрутизатором по умолчанию.
Перейдем к следующему из намеченных нами механизмов, а именно к розыску префиксов (prefix discovery). Есть ли у него другие применения, кроме автоматической настройки адресов? Иными словами, какие еще префиксы могут быть интересны хосту? Конечно же, это префиксы "на канале". Ведь, как мы обсудили в §5.2, префикс подсети IPv6 не всегда автоматически находится "на канале", и наоборот, вполне возможны префиксы "на канале", не совпадающие с префиксом подсети. Мы даже отметили себе на будущее, что эти сведения могли бы распространять маршрутизаторы, если бы у нас был походящий механизм.
Сейчас мы как раз над ним работаем, и возможность сообщать узлам префиксы "на канале" возникает у нас естественным образом. Для этого будет достаточно, чтобы в объявлении RA каждый префикс сопровождали его атрибуты. В частности, префикс может обладать такими свойствами:
То есть (а) и (б) — это независимые свойства префикса, и потому каждое из них заслуживает отдельного флага длиной один бит. Обозначим флаг автоматической настройки как A, а флаг "на канале" как L.
Случай, когда оба флага сброшены (A = 0 и L = 0), сейчас не имеет смысла, но он может пригодиться для расширения протокола, когда у префикса появятся новые свойства.
Как и прочая информация в сообщениях RA, сведения о префиксах "на канале" вполне могут исходить от нескольких маршрутизаторов. Рассмотрим это на примере сценария, где канал обслуживают два маршрутизатора, и каждый из них отвечает за свой префикс "на канале", как показано на рис. 6.8. Теперь сведения о префиксах "на канале" полностью рассредоточены, так что маршрутизатор М больше не играет роль единственного координатора и не может выслать переадресовку, когда хост А вручает ему очередной пакет для хоста Б. Ведь информация, что (рис 6.8) Два маршрутизатора на канале, и у каждого своя подсеть
Допустим теперь, что маршрутизаторы М и Н рассылают объявления RA. Они адресованы группе "все узлы канала", так что хост А будет получать объявления не только от М, но и от Н. Поэтому маршрутизатор Н сможет оптимизировать направление трафика, объявив, что префикс 2001:DB8:777::/64 — "на канале" (L = 1). Тогда хост А зафиксирует 2001:DB8:777::/64 в своем списке префиксов, и трафик от А к Б пойдет по кратчайшему пути. Точно так же хост Б получит объявление RA от маршрутизатора М, поместит 2001:DB8:33::/64 в свой список префиксов, и обратный трафик от Б к А тоже пойдет напрямую.
Обратите внимание: в отличие от хостов, маршрутизаторы никогда не используют чужие сообщения RA как источник сведений о канале. Тем не менее, как мы увидим ниже, маршрутизатору следует пассивно наблюдать за чужими сообщениями RA и извещать администратора сети о замеченных разногласиях.
Прекрасно, теперь хост IPv6 может в автоматическом режиме получать собственные адреса, адреса маршрутизаторов по умолчанию и префиксы "на канале". А как быть, если какие-то из этих параметров изменят свои значения в ходе работы сети? Ведь маршрутизаторы и префиксы вполне могут возникать и исчезать по желанию сетевого администратора. Очевидно, что в этом случае вся сеть должна подстраиваться к новым условиям, чтобы администратору не пришлось вручную вычищать старые параметры из конфигурации хостов. В противном случае ценность механизмов автоматической настройки IPv6 будет равна одному ломаному грошу, да и то в базарный день.
Решить эту задачу можно, если параметры хоста не будут вечными. Вот возможная схема [§6.3.5 RFC 4861, §5.5.3 и §5.5.4 RFC 4862]:
хост удаляет параметр из своих настроек, если:
oего время жизни истекает по таймеру, или
oобъявление RA сообщает, что новое время жизни параметра нулевое.
Здесь под параметром мы понимаем автоматически настроенный адрес, или элемент в списке маршрутизаторов по умолчанию, или префикс "на канале". Конечно, автоматически настроенный адрес наследует свое время жизни у префикса с установленным флагом A, из которого он образован.
Добавление нового параметра проблем не вызывает. Автоматически составив пробный адрес из нового префикса с A = 1, хост должен всего лишь убедиться в его уникальности с помощью DAD, прежде чем назначит его интерфейсу (см. §5.4.1). Адрес нового маршрутизатора достаточно внести в список маршрутизаторов по умолчанию, чтобы можно было им воспользоваться, когда NUD обнаружит сбой текущего маршрутизатора (см. §5.2). Новым префиксом "на канале" (L = 1) можно пользоваться немедленно, как только он будет внесен в список префиксов (см. §5.2).
Напомним себе, что все структуры данных эталонного хоста IPv6 привязаны к определенному интерфейсу, как было показано на рис. 6.8. Поэтому объявление RA влияет только на структуры того интерфейса, через который оно было получено.
Будет ли так же проста процедура удаления этих параметров? Два последних вида параметров, маршрутизаторы по умолчанию и префиксы "на канале", определяют только мгновенное решение хоста, как маршрутизировать исходящий пакет, — они явным образом не влияют на долговременное состояние хоста. Более того, исчезновение маршрутизатора или префикса "на канале" — это внешнее событие, на которое хост повлиять неспособен. Поэтому параметры этих двух видов можно и нужно удалить, как только истечет время их жизни по таймеру или объявлению RA.
В то же время, у локального адреса IP свойства особенные. Во-первых, к нему привязаны протяженные во времени сеансы вышестоящих протоколов, а безусловное удаление адреса вызовет их обрыв. Во-вторых, хост все-таки сам управляет своими адресами, пусть даже на основании внешних сведений, таких как административная конфигурация или объявления RA. Благодаря этому перед хостом открывается возможность провести удаление просроченного адреса по более сложной, но менее болезненной процедуре.
Чтобы "прощание" прошло гладко, пусть хост расстается с просроченным адресом в два этапа [§1 и §5.5.4 RFC 4862].
Здесь не работает пословица: долгие проводы — лишние слезы.
Пока время жизни адреса еще не истекло, он доступен как для создания новых сеансов
В качестве исключения, с устаревшего адреса можно устанавливать новые сеансы, если у хоста нет подходящего предпочтительного адреса, например, когда все его адреса в требуемой зоне устарели [§5.5.4 RFC 4862]. Также приложение может явно запросить определенный локальный адрес посредством API, даже если он устаревший.
Все это касается только исходящих сеансов; входящие сеансы на устаревшие адреса по умолчанию разрешены, так как удаленный хост ничего не знает о состоянии адреса, по которому он обращается.
Какое-то время спустя устаревший адрес превращается в недействительный (invalid), полностью исчезая с интерфейса; теперь незавершенные сеансы разрываются в аварийном порядке. В противоположность недействительному адресу, мы назовем адрес действительным (valid), пока он назначен интерфейсу. Предпочтительные и устаревшие адреса — действительные.
Осуществить подобную схему можно, связав с каждым адресом хоста два таймера, первый из которых отсчитывает предпочтительное время жизни адреса (preferred lifetime), а второй — действительное (valid lifetime). Предпочтительное время жизни не может превышать действительное, потому что недействительный адрес не может оставаться предпочтительным.
Состояние адреса "пробный" из §5.4.1 можно рассматривать наряду с состояниями "предпочтительный" и "устаревший". Пробный адрес назначается интерфейсу "не до конца": в этом состоянии его нельзя использовать для обмена данными, и хост не отвечает на обычные вызовы NS касательно пробного адреса. Затем проходит DAD, и по его результатам адрес превращается в предпочтительный или помечается как дубликат. В этом случае времена жизни можно назначить пробному адресу еще до проведения DAD. Небольшая сложность заключается в том, что один или оба таймера могут сработать до завершения DAD.
Самостоятельно разберите оптимизацию механизма DAD, известную как "оптимистический DAD" [RFC 4429], и дайте ей оценку.
Чтобы реализациям IPv6 не пришлось делать большого различия между адресами, назначенными вручную и настроенными автоматически, пусть особое значение времени жизни означает бесконечность. Так как в объявлении RA время жизни будет представлено в виде двоичного беззнакового поля, пусть бесконечность обозначает максимальное значение этого поля, "все единицы". Тогда действительное и предпочтительное времена жизни смогут быть атрибутами всякого локального адреса, но некоторые адреса устаревать или исчезать никогда не будут.
Но даже адресам с конечным временем жизни не обязательно исчезать, пока их префикс анонсируется маршрутизатором. Как мы только что сказали, объявление RA вызывает перезапуск таймеров на соответствующих параметрах. Поэтому, например, если адресу оставалось жить 5 секунд, но пришло объявление RA, в котором время жизни соответствующего префикса 1 час, то таймер будет перезапущен с интервалом 1 час, и адрес в ближайшее время не исчезнет с интерфейса. Благодаря этому, объявления RA могут сколь угодно долго регенерировать автоматически назначенные адреса.
В результате жизненный цикл индивидуального адреса IPv6 выглядит, как показано на рис 6.9(рис 6.9) Жизненный цикл индивидуального адреса IPv6
Наконец-то мы можем составить форматы сообщений RS и RA. Сообщение RS [§4.1 RFC 4861] — это просто вызов, так что главную информацию несет сам факт отправки и приема этого сообщения. Тем не менее, мы учтем полученный в §5.1 опыт с форматом NS и позволим сообщению RS содержать опцию ND "канальный адрес источника" (SLLA), как показано на рис. 6.10. Действительно, раз хост занялся розыском маршрутизаторов, то он наверняка собирается начать сетевой диалог. Поэтому маршрутизаторы смогут поступить предупредительно и заранее создать для этого хоста запись NC в состоянии ПРОСРОЧЕННАЯ, чтобы позднее не тратить времени на его розыск. А вдобавок, на такой вызов RS можно будет ответить индивидуальным, а не групповым объявлением RA, чтобы не тревожить понапрасну другие узлы канала.
Конечно, у опции "канальный адрес источника" есть смысл, только если адрес источника IPv6 определенный, потому как вносить в NC неопределенный адрес было бы эксцентричным поступком. По стандарту, RS допустимо слать с неопределенного адреса источника, (рис 6.10) Вызов маршрутизатора — RS
Формат RA более богат [§4.2 RFC 4861]. Прежде всего, мы решили, что в нем должно быть поле "время жизни маршрутизатора". Пусть нулевое значение этого поля означает, что данный маршрутизатор не хочет, чтобы хосты вносили его в свои списки маршрутизаторов по умолчанию; а если данный маршрутизатор уже в списке, то его следует оттуда удалить.
В данном протоколе все маршрутизаторы эквивалентны. Однако существует расширение ND [RFC 4191], которое позволяет назначить маршрутизаторам разные приоритеты, а также распространить более точные маршруты на некоторые префиксы. У хостов, поддерживающих это расширение, может появиться еще одна структура данных, а именно явная таблица маршрутов.
Еще механизм розыска маршрутизаторов поможет централизованно настраивать параметры ND и даже всего IPv6, если в сообщении RA будут соответствующие поля. Выбор этих полей мы подробно обсуждать не будем, а приведем только их список:
период повтора — параметр RetransTimer (§5.1): пауза между повторными вызовами NS, пока на них нет ответа NA.
Если маршрутизатор не настаивает на определенном значении какого-то из параметров, то пусть он помещает в это поле ноль.
По-видимому, выбор пал на BaseReachableTime и RetransTimer, потому что именно эти параметры мы бы стали подстраивать, если бы, к примеру, нам пришлось оптимизировать работу канала на несколько тысяч хостов. В таком канале накладные расходы на NUD можно понизить, подняв BaseReachableTime, а задержку отклика на сообщения NS, вызванную их высокой частотой, можно компенсировать, увеличив RetransTimer.
В принципе, эти поля можно было вынести в опции ND, как мы поступим с полем "MTU канала".
Если у хоста несколько интерфейсов, то данные параметры относятся к тому интерфейсу, через который было получено объявление RA [§6.3.2 RFC 4861].
Еще в объявлении RA есть два флага, (рис 6.11) Объявление маршрутизатора — RA
Это была фиксированная часть RA, постоянной длины, — показана на рис. 6.11. Но мы, вообще-то, начинали с того, что хотели распространять список префиксов. Длина этого списка, очевидно, переменная, так что давайте поместим этот список среди опций ND.
Можно поступить еще проще: пускай одна опция содержит один префикс, как показано на рис. 6.12. Она так и называется: (рис 6.12) Опция сведений о префиксе — PIO
По нашему плану, атрибутами каждого префикса будут его длина, действительное и предпочтительное времена жизни, а также флаги A и L, говорящие, в каких целях хостам можно использовать данный префикс: для автоматической настройки адресов, для ведения списка префиксов "на канале".
А если маршрутизатор заодно сообщит свой канальный адрес в опции "канальный адрес источника" (SLLA), то хостам не придется дополнительно разрешать его сетевой адрес — они сразу же смогут создать запись NC, хотя бы в состоянии ПРОСРОЧЕННАЯ. Так маршрутизатор "убьет нескольких зайцев" одним объявлением RA.
Еще одна опция ND, специфичная для сообщения RA — это "MTU канала" [§4.6.4 RFC 4861]. Она призвана помочь работе IPv6 поверх каналов с переменным значением MTU. Формат этой опции показан на рис 6.13(рис 6.13) Опция "MTU канала"
Пример такого канала можно найти даже в современной технологии Ethernet. Представьте себе два коммутатора, А и Б, первый с поддержкой сверхбольших кадров ("кадр-слон", jumbo frame), а второй без нее. Если их соединить между собой, то получится ЛВС, в которой PMTU пары портов зависит от того, на каких коммутаторах выбраны эти порты. Между всеми портами А значение PMTU будет 9000 байт, между портами А и Б — 1500 байт, между портами Б тоже 1500 байт. Допустим, что все интерфейсы, подключенные к А, получили значение MTU 9000 байт, а все интерфейсы, подключенные к Б, — 1500 байт. Механизмы TCP MSS и PMTUD не смогут преодолеть такую асимметрию, потому что извещения ICMP "пакет слишком большой" слать будет некому и большие кадры от А к Б будут просто теряться. (Последняя надежда на детектор "черной дыры PMTUD".) Зато если все хосты, подключенные к А и Б, получат одно и то же значение MTU 1500 байт, то канал сможет беспрепятственно работать, несмотря на особенности его реализации.
С какого адреса источника маршрутизатор должен вести рассылку RA? Ведь именно этот адрес хосты сохранят в своих списках маршрутизаторов по умолчанию, если "время жизни маршрутизатора" в объявлении RA больше нуля. Логично было бы использовать тот адрес, вероятность смены которого минимальна. Этим свойством обладает внутриканальный адрес, так как он не зависит от адресного плана сети, текущего провайдера Internet и проч. Поэтому маршрутизатор обязан рассылать RA с внутриканального адреса [§4.2 RFC 4861].
Конечно, это не произвольный внутриканальный адрес, а назначенный тому интерфейсу, через который ведется рассылка.
Такое же правило в §5.2 мы сформулировали для переадресовок [§4.5 RFC 4861].
Обратите внимание, как работает зонная архитектура адресов IPv6 в случае обмена RS и RA. Хост вправе отправить вызов RS с любого из своих адресов на данном интерфейсе [§4.1 RFC 4861], а маршрутизатор может ответить индивидуальным объявлением RA по этому адресу [§6.2.6 RFC 4861]. Таким образом, вполне возможно, что адреса источника и назначения RA будут из зон разной величины. То есть адрес источник RA всегда будет внутриканальным, а вот адрес назначение может быть, например, глобальным. Тем не менее, такой пакет не покинет пределов данного канала и потому не нарушит принципа изоляции зон (§2.4).
Те же соображения применимы и к переадресовке (§5.2). Ее адрес назначения совпадает с адресом источника пакета-виновника, а тот с большой вероятностью принадлежит области больше внутриканальной, так как пакет был направлен через маршрутизатор. В то же время, адрес источника переадресовки — заведомо внутриканальный.
Распространение параметров IPv6 и ND в сообщениях RA влечет за собой еще одну проблему. Если канал обслуживают несколько маршрутизаторов, то вполне может оказаться, что по недосмотру они объявляют разные значения параметров. В этом случае объявления RA от разных маршрутизаторов будут непрерывно менять соответствующие настройки хостов, а флуктуации настроек чреваты нестабильностью в работе протоколов. По этой причине необходимо, чтобы все маршрутизаторы канала объявляли согласованные наборы параметров. В первую очередь, это касается численных параметров в фиксированной части RA, а также опции "MTU канала": их значения обязаны совпадать.
Разные маршрутизаторы вполне могут объявлять разные списки префиксов, но и здесь необходимо определенное единообразие. А именно времена жизни одного и того же префикса, объявляемого разными маршрутизаторами, должны совпадать, чтобы не было нежелательных флуктуаций в настройках хостов. В то же время, флаги префиксов вполне могут отличаться, потому что их можно объединить операцией "побитовое ИЛИ". К примеру, если префикс 2001:DB8:0:123::/64 объявлен одним маршрутизатором как доступный для автоматической настройки адресов (A = 1), а другим — как расположенный "на канале" (L = 1), то хосты вправе как внести его в свои списки префиксов, так и назначить себе адреса на его основе.
Интересный вопрос состоит в том, как именно удалить префикс "на канале" с помощью RA [§6.3.4 RFC 4861]. Сброс флага L в объявлении не даст желаемого результата, потому что L = 0 значит "нет информации", а не "вне канала". Поэтому верным решением будет объявить префикс с L = 1 и нулевым временем жизни. Из двух времен жизни префикса, атрибут "на канале" использует действительное время жизни [§4.6.2 RFC 4861]. Если тот же префикс доступен для автоматической настройки адресов (A = 1), мгновенная установка его действительного времени жизни в ноль не приведет к потере уже настроенных адресов благодаря защитному правилу "2 часа", которое мы обсудим в конце раздела. Но еще надежнее будет объявить один и тот же префикс в двух опциях PIO, из которых одна имеет L = 1 и нулевое время жизни, а другая — A = 1 и ненулевое время жизни.
Чтобы помочь администратору в согласовании параметров, каждому маршрутизатору рекомендовано следить за объявлениями соседей, сравнивать их со своими и сообщать в системном журнале о найденных противоречиях [§6.2.7 RFC 4861].
А как должен поступить хост, если разные маршрутизаторы объявляют разную длину одного и того же префикса? Здесь мы сами себе поставили небольшую ловушку, как хитрый экзаменатор студенту. На самом деле, длина префикса — это его неотъемлемая часть, так что один и тот же префикс не может иметь разные длины: это будут разные цепочки битов, разные префиксы.
Между тем, один префикс может включать в себя другой. Например, двоичный префикс 01 содержится в префиксе 0100, а префикс IPv6 2001:DB8::/32 — в префиксе 2001:DB8::/48. При этом префикс большей длины точнее, так как ему отвечает меньшее множество адресов. Когда такие префиксы находятся на одном канале, это тривиальный случай: множество адресов короткого префикса полностью содержит в себе множество адресов длинного префикса. Тем не менее, это разные префиксы, у каждого из которых свой набор флагов и свое время жизни. Например, префикс "на канале" 2001:DB8::/32 может устареть раньше, чем 2001:DB8::/48, и тогда адреса, составляющие разность этих множеств, окажутся "вне канала".
Затруднение могло бы возникнуть, если бы такие префиксы разной длины были доступны для авто-настройки адресов IPv6. Однако здесь нас спасает правило, что длина префикса подсети IPv6 всегда равна 64.
Когда канал обслуживают несколько маршрутизаторов, то их немедленный ответ на вызов RS приведет к пику нагрузки на канал. Это может даже открыть дверь атаке типа "отказ в обслуживании", когда злоумышленник подключился к каналу или захватил уже подключенный хост и теперь бомбардирует его маршрутизаторы вызовами RS, чтобы спровоцировать усиленный в несколько раз поток ответов RA.
От засылки извне канала пакеты RS и RA защищены при помощи GTSM: поле "предельное число шагов" в них обязано равняться 255 — см. §5.1.
Маршрутизатору не возбраняется всегда направлять объявления RA по адресу "все узлы канала" независимо от того, шлет ли он это объявление по таймеру или по вызову [§6.2.6 RFC 4861, §5.5.1 RFC 4862]. Так злоумышленник или даже просто сбойный хост сможет вызвать целую бурю группового трафика. Чтобы этого не произошло, каждый маршрутизатор обязан ограничить частоту своих объявлений
Тем не менее, проблема нежелательной синхронизации RA остается. С ней надо бороться, сделав время отправки RA случайным. Если RA по вызову, то надо внести случайную задержку, а если по таймеру, то достаточно сделать его интервал случайным [§6.2.4 и §6.2.6 RFC 4861]. Последний штрих состоит в том, чтобы вообще не слать RA по вызову, если задержка помещает его на оси времени после ближайшего RA по таймеру. Благодаря этим предосторожностям, групповая рассылка объявлений RA не повредит каналу даже при возникновении сбойных или злонамеренных хостов.
Интересно, что разные периодические события в сети неожиданно проявляют склонность к самопроизвольной синхронизации во
Последний вопрос, связанный с розыском маршрутизаторов, заключается в том, может ли узел IPv6 впоследствии отказаться от роли маршрутизатора. Согласно общепринятой модели [§6.2.1 RFC 4861], маршрутизатор IPv6 — это функция узла, которую можно избирательно включить или выключить на каждом из его сетевых интерфейсов, при условии что узел вообще способен быть маршрутизатором. Из соображений устойчивости и безопасности, по умолчанию эта функция выключена.
Но допустим теперь, что на данном интерфейсе некого узла М эта функция была когда-то явным образом включена и узел какое-то время исполнял все обязанности маршрутизатора: продвигал транзитный трафик, высылал переадресовки, рассылал объявления RA с информацией о настройках сети. Чтобы теперь корректно уйти со сцены и превратиться в скромный хост, узел М должен аннулировать всю информацию, которую он явно или неявно сообщил хостам.
С явной информацией все довольно просто: достаточно разослать несколько раз объявление RA, в котором список параметров все тот же, но время их жизни нулевое. Так узел М заставит хосты удалить информацию о префиксах и исключить себя из списка маршрутизаторов по умолчанию.
Однако в памяти хостов все еще остаются записи DC, которые указывают на узел М. Подобные записи могли возникнуть, даже если М не был маршрутизатором по умолчанию, а значит, их нельзя убрать объявлением RA. Например, эти записи могли быть созданы по переадресовке другого маршрутизатора Н. В результате окажется, что хосты продолжают слать транзитный трафик через узел М, хотя тот его просто игнорирует. Если бы узел М вообще исчез, то сработал бы механизм NUD, и хосты бы вычистили устаревшие записи DC, связанные с недоступным соседом. Но в нашем случае узел М будет по-прежнему доступен, и образуется "черная дыра".
Чтобы разрешить это затруднение, нам пригодится флаг R в объявлении NA, который мы предварительно зарезервировали. Пусть узел устанавливает этот флаг в своих сообщениях NA, когда он маршрутизатор на данном интерфейсе, и сбрасывает, когда он просто хост. Тогда хосты-соседи смогут более надежно узнать об отказе узла М продвигать транзитный трафик. Как только флаг R в его сообщениях NA обнулится, полагается вычистить все записи DC, указывающие на узел М, потому что он добровольно сложил с себя полномочия маршрутизатора [§7.2.5 RFC 4861].
Таким образом, оказывается, что хост IPv6 должен следить не только за доступностью соседей, но и за их состоянием "хост/маршрутизатор". Этой цели служит булево поле IsRouter в эталонной записи NC [§5.1 RFC 4861].
Определить, что сосед — маршрутизатор, хост может по прямым или косвенным признакам [Приложение D RFC 4861]. Прямой признак один, это флаг R в объявлении NA, тогда как косвенных признаков несколько. Скажем, получение объявления RA от соседа говорит о том, что он — маршрутизатор. На то же самое указывает переадресовка на соседа, если это переадресовка на маршрутизатор (адрес цели не совпадает с адресом назначения). (Переадресовку от соседа хост может получить, только если он уже использует его как маршрутизатор.) Косвенные признаки, в отличие от прямого, не могут подтвердить обратное, а именно что сосед — это хост, а не маршрутизатор.
На этом мы закончили с розыском маршрутизаторов, и пришло время ответить на вопрос о более подробном алгоритме автоматической настройки адресов. Чтобы освежить нашу память, вернемся к моменту, когда хост провел первичную инициализацию стека IPv6 и активировал сетевой интерфейс. Вот что хост делает дальше:
преобразует канальный адрес интерфейса в идентификатор интерфейса IPv6 длины N;
по мере получения объявлений RA сканирует опции PIO [§5.5.3 RFC 4862]:
а)игнорирует опцию, если в ней сброшен флаг A;
Опция PIO с A = 0 может пригодиться для заполнения списка префиксов "на канале", если у нее L = 1; но мы сейчас говорим только об автоматическом назначении адресов сетевому интерфейсу.
игнорирует опцию, если префикс внутриканальный;
в)игнорирует опцию, если действительное время жизни префикса меньше предпочтительного;
г)если префикс еще не назначен:
i)игнорирует префикс, если сумма длин префикса и идентификатора интерфейса не равна длине адреса IPv6, 128 бит;
ii)игнорирует префикс, если его действительное время жизни равно нулю;
iii)создает пробный адрес, сцепляя префикс из RA и идентификатор интерфейса из шага №1;
iv)проверяет пробный адрес на уникальность с помощью DAD;
v)если адрес уникальный, то назначает его интерфейсу и устанавливает для него времена жизни согласно принятой опции RA;
д)иначе, если префикс уже назначен в составе ранее созданного адреса:
i)устанавливает предпочтительное время жизни адреса согласно опции;
ii)устанавливает действительное время жизни на основании опции (см. примечание).
Хотя вопрос о безопасности ND мы еще не обсуждали, уже сейчас понятно, что без дополнительных механизмов защиты сообщения ND уязвимы к обычной подделке. Подделка RA, помимо прочего, позволяет провести очень простую атаку типа "отказ в обслуживании", когда хост получает RA, в котором действительное время жизни его текущих префиксов очень короткое. В результате хост сбрасывает свои адреса и некоторое время остается полностью недоступен. Обратите внимание, что хост не нужно "бомбардировать" — достаточно единственного фальшивого RA. Чтобы блокировать этот вектор атаки, стоит ограничить возможность RA сокращать действительное время жизни адресов [§5.5.3 RFC 4862]. Суть этого ограничения довольно проста, ее иллюстрирует рис. 6.14. Прежде всего, RA может беспрепятственно удлинять время жизни адреса. Например, если к приходу RA адресу оставалось жить 5 минут, а новое время жизни 10 минут, то таймер адреса будет установлен на 10 минут. Если же RA на самом деле пытается сократить время жизни адреса, то оно может укоротить его только до 2 часов. К примеру, если адресу оставалось жить 1 час, а новое время жизни 10 минут, то адрес проживет целый час. Если адресу оставалось жить 3 часа, а новое время жизни 45 минут, то адрес проживет 2 часа. И только если новое время жизни больше 2 часов, оно вступит в силу как есть. Когда у нас появится надежная защита сообщений RA от подделки, это ограничение можно будет снять. Иными словами, ограничение действует только на те сообщения RA, подлинность которых никак не подтверждена. Кроме того, оно действует только на действительное время жизни как наиболее уязвимый параметр, тогда как предпочтительным временем жизни адресов можно управлять без ограничений.
(рис 6.14) Защита от атаки на время жизни адреса Хост выполняет шаг 6 в фоне, пока интерфейс активен, так как периодические объявления RA сообщают текущую конфигурацию данного канала, а она может изменяться по желанию администратора сети. Маршрутизатор может сам назначить своим интерфейсам внутриканальные адреса, выполнив шаги 1–4; шаги 5 и далее — только для хостов [§4 RFC 4862].
У такого механизма автоматической настройки адресов есть одна любопытная особенность: ни маршрутизатор, ни хост не фиксируют назначение адреса в долговременной памяти. Когда хост включают, он проводит процедуру автоматической настройки с самого начала и, как нетрудно убедиться, получает тот же самый набор адресов, пока постоянны его канальный адрес и конфигурация маршрутизаторов. Можно сказать, что у такого механизма нет внутреннего состояния. Поэтому полностью его называют так: автоматическая настройка адресов без внутреннего состояния, сокращенно SLAAC (stateless address autoconfiguration) [RFC 4862].
В качестве безвредной оптимизации, [§5.7 RFC 4862] разрешает хосту хранить текущие настройки SLAAC в долговременной памяти (ППЗУ, диск) в пределах времени их жизни.
Важное условие работы SLAAC — чтобы канал поддерживал групповое вещание на сетевом уровне. Если это не так, то и SLAAC на таком канале работать не сможет.
Это не значит, что для SLAAC нужно настоящее групповое вещание на канальном уровне, например, каким мы его знаем в Ethernet. Требуется групповое вещание именно на сетевом уровне, а канальный уровень может его эмулировать. Так, например, в канале "точка-точка" групповое вещание сводится к передаче пакетов удаленному узлу. А если канал многоадресный и широковещательный, но без группового вещания, то групповые пакеты можно передавать всем узлам в широковещательных кадрах, полагаясь на отбор нужных пакетов сетевым уровнем. Пример этого подхода мы находим в ARCNET [§4.3 RFC 1201, §7 RFC 2497].
Как и всякий сложный автоматический механизм, SLAAC должен быть, в идеале, полностью управляемым, а по меньшей мере — отключаемым. У оператора узла должна быть возможность блокировать работу SLAAC на сетевом интерфейсе, если она нежелательна по тем или иным соображениям. Это касается как хостов, так и маршрутизаторов. Хост должен быть готов работать с ручными настройками, игнорируя объявления RA. Что же касается маршрутизатора, то рассылка RA может повлиять на конфигурацию многих хостов, и поэтому ее надо вообще отключить по
Это вовсе не противоречит обязательному статусу поддержки элементов SLAAC узлами IPv6. Одно дело, когда функцию можно избирательно отключить, а совсем другое, когда она вообще недоступна. То же касается DAD [§5.4 RFC 4862] и ND в целом.
Интересное применение возможностей SLAAC — это перенумерация сети IPv6, например, при переходе от одного провайдера к другому [§4.1 RFC 4862]. Ввиду постоянной длины префикса подсети, все идентификаторы интерфейсов могут остаться теми же, и тогда задача сводится к перенумерации префиксов подсетей. Гладко провести эту операцию можно, применяя в переходный период два префикса с установленным флагом A. Тогда каждый хост назначит своему интерфейсу два адреса, старый и новый. Далее, управляя предпочтительным временем жизни старого адреса, можно добиться, чтобы он больше не выступал источником новых сеансов. Завершить операцию можно, полностью упразднив старый адрес с помощью его действительного времени жизни. При этом достаточно менять настройки маршрутизаторов, а хосты сами их подхватят из объявлений RA. Подробно безболезненная процедура перенумерации разобрана в [RFC 4192].
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.