В сетях IPv6 флаг IPV6_V6ONLY используется, чтобы гарантировать, что сокет будет только использовать IPv6, и в особенности что отображение IPv4 к IPv6 не будет использоваться для того сокета. На многих ОС IPV6_V6ONLY не установлен по умолчанию, но на некоторой ОС (например, Windows 7), это установлено по умолчанию.
Мой вопрос: Какова была мотивация для представления этого флага? Есть ли что-то о IPv4 к IPv6, отображающемся, который вызывал проблемы, и таким образом людям был нужен способ отключить его? Мне казалось бы, что, если кто-то не хотел использовать отображение IPv4 к IPv6, они не могли бы просто указать отображенный на IPv4 адрес IPv6. Что я пропускаю здесь?
Я не знаю, почему это будет по умолчанию; но это тот тип флагов, который я бы всегда ставил явным, независимо от того, какой он установлен по умолчанию.
О том, почему он вообще существует, я предполагаю, что он позволяет вам сохранить существующие серверы только для IPv4 и просто запускать новые на том же порту, но только для соединений IPv6. Или, может быть, новый сервер может просто проксировать клиентов к старому, что упрощает и упрощает добавление функциональности IPv6 к старым службам.
Представьте себе протокол, который включает в диалог сетевой адрес, например, канал данных для FTP. При использовании IPv6 вы собираетесь отправить IPv6-адрес, если получатель окажется сопоставленным адресом IPv4, у него не будет возможности подключиться к этому адресу.
Чаще всего упоминается причина, по которой сервер имеет некоторую форму ACL (список управления доступом). Например, представьте сервер с такими правилами, как:
Allow 192.0.2.4
Deny all
Он работает на IPv4. Теперь кто-то запускает его на машине с IPv6, и, в зависимости от некоторых параметров, запросы IPv4 принимаются в сокете IPv6, отображаются как :: 192.0.2.4, а затем больше не соответствуют первому ACL. Внезапно в доступе будет отказано.
Явное указание в вашем приложении (с использованием IPV6_V6ONLY) решило бы проблему, независимо от того, какое значение имеет операционная система по умолчанию.
Не все платформы, поддерживающие IPv6, поддерживают двухстековые сокеты, поэтому возникает вопрос, как приложениям, нуждающимся в максимальной совместимости с IPv6, узнать, что двухстековый сокет поддерживается, или связывать его отдельно, если он не поддерживается? Единственный универсальный ответ - IPV6_V6ONLY.
Приложение, игнорирующее IPV6_V6ONLY или написанное до появления IP-стеков с поддержкой dualstack, может обнаружить, что привязка отдельно к V4 не работает в среде dualstack, поскольку привязка сокетов IPv6 dualstack к IPv4 предотвращает привязку сокетов IPv4. Приложение также может не ожидать IPv4 поверх IPv6 из-за проблем с адресацией на уровне протокола или приложения или контроля доступа к IP.
Эта и подобные ситуации, скорее всего, побудили MS и других разработчиков установить значение по умолчанию 1, несмотря на то, что RFC3493 объявляет 0 значением по умолчанию. Теоретически 1 максимизирует обратную совместимость. В частности, Windows XP/2003 не поддерживает двухстековые сокеты.
Существует также множество приложений, которым, к сожалению, необходимо передавать информацию нижнего уровня для корректной работы, поэтому этот параметр может быть весьма полезен для планирования стратегии совместимости IPv4/IPv6, которая наилучшим образом соответствует требованиям и существующим кодовым базам.