2010-04-22 1 views
22

В сети IPv6 флаг IPV6_V6ONLY используется, чтобы гарантировать, что сокет будет использовать только IPv6, и, в частности, сопоставление IPv4-IPv6 не будет использоваться для этого сокета. На многих ОС IPV6_V6ONLY не установлен по умолчанию, но на некоторых ОС (например, Windows 7) он устанавливается по умолчанию.Какова была мотивация добавления флага IPV6_V6ONLY?

Мой вопрос: Какова была мотивация для введения этого флага? Что-то связано с отображением IPv4-to-IPv6, которое вызывало проблемы, и, следовательно, людям нужен способ его отключения? Мне показалось, что если кто-то не хочет использовать сопоставление IPv4-to-IPv6, они могут просто не указывать IPv6-адрес IPv4-сопоставленного IPv6. Что мне здесь не хватает?

+5

@ Eric Eijkelenboom: нет, это не – Javier

+0

Поскольку это сетевой вопрос, и это не связано с программированием, я предположил, что это так. –

+5

Эти флаги являются параметрами, предоставляемыми системным вызовам для открытия сокета. используется при программировании, а не при настройке или обслуживании. IOW: это разработчик, а не администратор, который его использует. – Javier

ответ

3

Я не знаю, почему это было бы по умолчанию; но это именно те флагов, которые я всегда ставил явным, независимо от того, что такое по умолчанию.

О том, почему он существует в первую очередь, я предполагаю, что он позволяет сохранить существующие серверы только для IPv4 и просто запускать новые в одном и том же порту, но только для соединений IPv6. Или, может быть, новый сервер может просто прокси-клиентов к старому, что делает IPv6-функцию легкой и безболезненной для добавления к старым службам.

0

Представьте протокол, который включает в разговор сетевой адрес, например. канал передачи данных для FTP. При использовании IPv6 вы собираетесь отправить IPv6-адрес, если получатель окажется адресом IPv4, он не сможет подключиться к этому адресу.

4

Причина, по которой чаще всего упоминается, относится к случаю, когда сервер имеет какой-либо вид ACL (список контроля доступа). Например, представьте себе сервер с правилами, такими как:

Allow 192.0.2.4 
Deny all 

Он работает на IPv4. Теперь кто-то запускает его на машине с IPv6 и, в зависимости от некоторых параметров, запросы IPv4 принимаются в сокет IPv6, отображаемые как :: 192.0.2.4, и затем больше не сопоставляются с первым ACL. Внезапно доступ будет отклонен.

Будучи явным в вашем приложении (с использованием IPV6_V6ONLY), вы решите проблему, независимо от того, что по умолчанию имеет операционная система.

+0

Сервер просто не должен использовать сокеты с двойным стеком с сопоставленными адресами, если он не может применять ACL для IPv4 к адресам IPv4 в отображаемой форме. –

10

Не все платформы, поддерживающие IPv6, поддерживают сокеты с двойным стеклом, поэтому возникает вопрос, как приложения, требующие максимизации совместимости с IPv6, знают, что dualstack поддерживается или связывается отдельно, когда его нет? Единственный универсальный ответ - IPV6_V6ONLY.

Приложение, игнорирующее IPV6_V6ONLY или написанное до наличия стеков IP-совместимых стеков, может найти привязку к V4 сбой в среде двойного старта, поскольку сокет с двойным стеклом IPv6 привязан к IPv4, предотвращающий привязку сокета IPv4. Приложение также не может ожидать IPv4 через IPv6 из-за проблем с адресацией на уровне протокола или приложений или элементов управления доступом к IP.

Эта или подобные ситуации, скорее всего, побудили MS et al к стандарту 1, даже если RFC3493 объявляет 0 значением по умолчанию. 1 теоретически максимизирует обратную совместимость. В частности, Windows XP/2003 не поддерживает сокеты dualstack.

Существует также недостаток приложений, которые, к сожалению, должны передавать информацию нижнего уровня для правильной работы, поэтому этот параметр может быть весьма полезен для планирования стратегии совместимости IPv4/IPv6, которая наилучшим образом соответствует требованиям и существующим кодам.

1

Есть правдоподобные способы, с помощью которых (плохо названные) адреса с IPv4-адресами могут использоваться для обхода плохо сконфигурированных систем или плохих стеков или даже в хорошо сконфигурированной системе может потребоваться только обременительное количество ошибок. Разработчик, возможно, пожелает использовать этот флаг, чтобы сделать их приложение более безопасным, не используя эту часть API.

См: http://ipv6samurais.com/ipv6samurais/openbsd-audit/draft-cmetz-v6ops-v4mapped-api-harmful-01.txt

2

Для Linux, при написании сервис, который прослушивает на обоих IPv4 и IPv6 сокетов на сервисный порт же, например порт 2001, вы ДОЛЖНЫ называть setsockopt (s, SOL_IPV6, IPV6_V6ONLY, & one, sizeof (one)); на разъеме IPv6. Если вы этого не сделаете, операция bind() для сокета IPv4 завершится с «Адресом, который уже используется».

0

Существует один очень распространенный пример, когда двойственность поведения является проблемой. Стандарт getaddrinfo() звонок с флагом AI_PASSIVE предлагает возможность передать параметр nodename и возвращает список адресов для прослушивания. Специальное значение в виде строки NULL принимается для nodename и подразумевает прослушивание подстановочных адресов.

В некоторых системах 0.0.0.0 и :: возвращены в этом порядке. Если по умолчанию установлен сокет с двойным стеком, и вы не устанавливаете сокет IPV6_V6ONLY, сервер подключается к 0.0.0.0, а затем не может подключиться к двойному стеку ::, и поэтому (1) работает только с ошибками протокола IPv4 и (2).

Я бы счел порядок неправильным, поскольку ожидается, что IPv6 будет предпочтительнее. Но даже когда вы сначала пытаетесь выполнить двойной стек ::, а затем только IPv4 0.0.0.0, сервер по-прежнему сообщает об ошибке для второго вызова.

Я лично считаю, что вся идея гнезда двойного стека является ошибкой. В моем проекте я предпочел бы всегда явно устанавливать IPV6_V6ONLY, чтобы этого избежать. Некоторые люди, по-видимому, рассматривали это как хорошую идею, но в этом случае я, вероятно, явно отключил бы IPV6_V6ONLY и перевел NULL непосредственно на 0.0.0.0 в обход механизма getaddrinfo().