Какова была мотивация для добавления флага IPV6_V6ONLY? - PullRequest
23 голосов
/ 22 апреля 2010

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

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

Ответы [ 7 ]

10 голосов
/ 10 мая 2010

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

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

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

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

4 голосов
/ 09 мая 2010

Чаще всего упоминается причина для случая, когда сервер имеет некоторую форму ACL (Access Control List). Например, представьте сервер с такими правилами:

Allow 192.0.2.4
Deny all

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

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

3 голосов
/ 22 апреля 2010

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

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

2 голосов
/ 28 марта 2013

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

1 голос
/ 25 апреля 2012

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

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

0 голосов
/ 12 октября 2015

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

В некоторых системах 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().

0 голосов
/ 02 мая 2010

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

...