Кратко

  • Успех IPV6_ADDR_PREFERENCES подтверждает согласованное пожелание приложения, но не наличие и не выбор адреса с нужным свойством.
  • Если свойство обязательно, адрес надо выбрать, прочитать и проверить до продолжения; отправка, путь, принятие удалённой стороной и итог приложения остаются отдельными фактами.

В отчёте пожелание приложения превращается в факт сети: «временный адрес использован». Между этими фразами должна находиться работа стека, но её следов в отчёте нет.

RFC 5014 решал ограниченную задачу API. Точный адрес уже можно было задать через bind() или IPV6_PKTINFO, но тогда приложение само отвечало за его пригодность для назначения, интерфейса и области действия. Новый механизм меняет отдельные предпочтения, оставляя остальной алгоритм хосту.

Определены три пары: home/care-of, temporary/public и CGA/non-CGA. Свойства из разных пар совместимы. Две стороны одной пары противоречат друг другу: socket возвращает EINVAL, расширение getaddrinfo()EAI_BADEXTFLAGS. Отсутствие противоречия ещё не означает наличие подходящего кандидата.

Стандарт намеренно описывает предпочтение, а не жёсткое требование. Если временного адреса нет, вместо него может быть выбран публичный. Если часть комбинации недоступна, доступная часть влияет на выбор, а остальное решает системная политика. Неподдерживаемый флаг следует молча игнорировать. Успешный вызов не раскрывает, был ли запрос выполнен или произошла подмена по умолчанию.

Есть и контур разрешения имён. Предполагаемый источник может изменить порядок адресов назначения. Поэтому getaddrinfo() и socket должны получить семантически одинаковые флаги. При расхождении поведение не определено. Запись только о socket теряет решение, которое могло заранее переставить назначения.

Явная команда сильнее предпочтения. Источник, заданный через bind() или IPV6_PKTINFO, имеет приоритет. Флаг остаётся в конфигурации, хотя уже не управляет выбором.

Для строгого условия RFC прямо говорит: предпочтения не гарантируют выполнение требования приложения. Программа задаёт одинаковые флаги разрешителю и socket, заставляет стек выбрать адрес, читает его через getsockname(), проверяет свойства функцией inet6_is_srcaddr() и прекращает связь при несоответствии.

Даже выбор может иметь сетевой эффект. В TCP connect() способен отправить SYN до проверки. bind2addrsel() связывает тот адрес, который был бы выбран для назначения, не начиная соединение. В UDP connect() может сделать локальный выбор без отправки datagram. Выбранный адрес ещё не равен отправленному.

Проверка возвращает 1, 0 или -1: локальный адрес удовлетворяет всем флагам, не удовлетворяет им либо адрес/вход недопустим. Единица не доказывает удалённый путь. Свойство home может быть истинным на хосте без Mobile IPv6 или у мобильного узла дома; это не физическая геолокация.

Остальные слова тоже имеют узкий смысл. RFC 8981 сокращает окно простой корреляции активности по одному временному адресу, но не обещает анонимность других уровней. RFC 3972 связывает CGA с материалом открытого ключа, однако CGA не является удостоверенной личностью. Предпочтение CGA — не проверка подписи и не авторизация.

Исторические значения по умолчанию изменились. RFC 5014 опирался на RFC 3484, предпочитавший публичный источник. RFC 6724 заменил его и предпочёл временный адрес в соответствующем правиле. Реальный аудит обязан сохранить кандидатов и версию политики конкретного хоста.

Надёжная квитанция содержит приложение и socket, запрошенные и предыдущие флаги, флаги разрешителя и порядок назначений, проигнорированные возможности, набор кандидатов, версию политики, явный источник, способ выбора и риск ранней отправки, результат getsockname(), вход и трёхзначный итог проверки, решение продолжить или остановиться, а затем отдельно исходящий пакет, ответ и итог приложения.

Это операционная рекомендация, а не скрытое требование RFC. Она следует дисциплине слоёв реальности Heng Lu: намерение программы, выбор хоста, локальное свойство, сетевой путь и деловой вывод нельзя соединять без доказуемых переходов.

Источники