Кратко

  • В README Barry ::/0 задан как стандартный IPv6-ресурс якоря доверия, тогда как задача 7 сообщает об отказе этой записи в полях ресурсов сертификата и ROA.
  • В зафиксированном коде двоеточия и косая черта допустимы внутри уже начатой строки без кавычек. Но начать её могут только буква или цифра, $ либо . Поэтому 0::/0 становится токеном, а ::/0 останавливается до IP-парсера.
  • RFC 4291 допускает ::/0 как корректный IPv6-префикс, а RFC 5952 делает его каноническим представлением. 0::/0 имеет то же значение, но не является максимально сжатым выводом.
  • Источники не подтверждают создание некорректного объекта, решение relying party, влияние на рабочие системы LACNIC или маршрутизацию. Нужна версионная таблица соответствия от лексера до DER с точной стадией завершения.

Ноль меняет вход, а не сеть

Вся разница умещается в одном знаке:

::/0
0::/0

Обе строки означают 128-битный нулевой адрес IPv6 с длиной префикса ноль и охватывают всё пространство IPv6. Тем не менее задача 7 в репозитории LACNIC/barry описывает разные пути в программе: каноническая форма приводит к сообщению о неожиданном символе, а форма с первой цифрой служит обходным вариантом.

Эта граница существенна для генератора материалов RPKI, особенно когда он создаёт намеренно неправильные объекты для проверки валидаторов. Отрицательный тест начинается лишь после того, как корректный исходный текст превратился в однозначное значение, а затем в идентифицируемые байты. Если язык дескриптора не сформировал даже токен, результат нельзя приписывать сертификату, ROA или relying party. Объекта, о котором они могли бы вынести решение, нет.

Наиболее сильная трактовка в пользу организации требует сдержанности. Метаданные репозитория описывают небольшой генератор, а не производственный сервис. README на исследованном коммите дважды называет проект или спецификацию Repository Descriptor незавершённой и предупреждает о несовместимых изменениях до версии 1.0. Списки релизов и тегов на момент фиксации пусты. Открытая задача с малым примером — нормальная прозрачность прототипа, а не признак аварии.

Пример и вставленная трассировка не совпадают побайтно

Задача открыта 28 августа 2026 года. На дату отсечения 6 сентября она оставалась открытой, без меток, комментариев и последующих обновлений. GitHub указывает отношение автора сообщения к репозиторию как NONE. Ответа сопровождающего с подтверждением, диагнозом или исправлением нет.

В сообщении ::/0 помещена в два места: расширение IP-ресурсов сертификата CA и ipAddrBlocks в ROA. Там же 0::/0 предложена как текущий обход. Но внутри свидетельства есть важное расхождение. Показанный дескриптор содержит ::/0 в обоих полях; вставленная трассировка сначала печатает уже изменённое значение 0::/0, а затем останавливается на первом : другого поля с Unexpected character: : (0x3a).

Расхождение не отменяет задачу, но ограничивает вывод. Трассировка непосредственно показывает отказ при двоеточии в начале одного пути. Автор утверждает, что каноническая запись не работает в обоих полях. Публичный материал не демонстрирует независимо два побайтно одинаковых отказа в одном запуске. Именно поэтому квитанция соответствия должна сохранять точные байты входа и их хеш: перенос обходной записи в одно поле способен незаметно изменить опыт.

Трассировка также не показывает испорченный сертификат или ROA, опубликованный репозиторий либо итог валидатора. Она не подтверждает изменение маршрута или участие производственного RPKI LACNIC. Все эти события находятся ниже наблюдаемой границы.

Асимметрию объясняет правило первого символа

Код зафиксирован на коммите 994a598321336baf1767f0fbfb460ed96c29fe4f от 1 сентября. Его тема — реализация authorityCertIssuer в AKI; он не заявлен как исправление задачи 7. Список последних коммитов задаёт момент наблюдения, но не доказывает, когда появилось это поведение.

В src/rpki_tree.c функция next_token начинает строку без кавычек только тогда, когда первый символ является буквой или цифрой, $ либо . Двоеточия в перечне нет. Управление переходит к try_emoji, после чего обычный : признаётся неожиданным.

После начала строки правило шире. Двоеточия и косая черта внутри неё разрешены: продолжение исключает прежде всего пробелы и структурные разделители. Ноль в начале 0::/0 не заставляет IPv6-библиотеку принять иную сеть. Он лишь выполняет условие запуска, после чего остаток остаётся внутри открытого токена.

README делает границу особенно заметной. В нём есть сжатый адрес 2001:db8::/64, который начинается с шестнадцатеричной цифры и проходит входную проверку. Там же ::/0 указан как стандартный IPv6-ресурс якоря доверия. Поэтому общее утверждение «сжатый IPv6 поддерживается» неточно: сжатие после цифры и сжатие с первого символа идут по разным ветвям лексера.

Компонент, понимающий значение префикса, расположен дальше. В src/field.c parse_ip_node разделяет текст по /, определяет IPv6 по двоеточию, вызывает inet_pton, затем читает длину. Отвергнутая форма до этой функции не доходит. Нельзя называть наблюдение ошибкой inet_pton, длины префикса или связывания поля.

Каноническая форма должна идти обычным путём

RFC 4291 разрешает :: для сжатия последовательных нулевых групп и обозначает им полностью нулевой IPv6-адрес. Запись префикса соединяет любую корректную форму адреса, / и длину. Следовательно, ::/0 — допустимый вход IPv6.

RFC 5952 разделяет приём и выдачу. Реализация должна принимать допустимые формы RFC 4291, а при генерации текста использовать каноническую запись и максимальное сжатие. 0::/0 сохраняет ту же семью, значение и длину, однако оставляет нулевую группу, которую канонический вывод убирает.

Ограниченная локальная проверка через Ruby IPAddr нормализовала ::/0, 0::/0, 0000::/0 и полностью записанный нулевой адрес в один и тот же диапазон. Это не запуск Barry и не нормативный источник. Проверка лишь поддерживает выбор правильного предмета: лексическая граница, а не вымышленное различие сетей.

На уровне объекта RFC 3779 кодирует IP-ресурсы как BIT STRING в DER. Блок всех адресов с нулевой длиной становится 03 01 00; исходное написание дескриптора в сертификате или ROA не сохраняется. Если строка остановилась в лексере, нет DER-значения, которое relying party мог бы принять или отклонить.

Небольшая таблица разделит все решения

Вместо общего обещания совместимости достаточно версионной таблицы. В каждой строке нужны точные байты дескриптора и их хеш, целевое поле, результат токенизации, нормализованные семья/значение/длина, канонический вывод, коммит парсера и генератора, а при успешном построении — хеш объекта.

Конечную стадию следует выбирать из стабильного набора: descriptor-tokenize, prefix-parse, field-bind, object-build, DER-encode или RP-validate. Тогда отказ генератора нельзя будет посчитать сбоем валидатора. Центральный инвариант краток: parse(format(parse(input))) сохраняет ту же тройку. Эквивалентные допустимые формы при успешной генерации должны сходиться к одному DER-значению префикса.

Эта таблица не сертифицирует Barry и не описывает весь IPv6. Она отвечает на локальный проверяемый вопрос: какие байты приняты, какое значение понято, какой объект создан и какой уровень вынес последнее решение. Для генератора отрицательных тестов это полезнее единой отметки «успех» или «сбой».

Источники