Как поддерживать соединения IPv4 и IPv6 - PullRequest
52 голосов
/ 24 октября 2009

В настоящее время я работаю над приложением сокета UDP и мне нужно встроить поддержку, чтобы соединения IPV4 и IPV6 могли отправлять пакеты на сервер.

Я надеялся, что кто-нибудь сможет мне помочь и направить меня в правильном направлении; Большая часть документации, которую я нашел, была неполной. Также было бы полезно, если бы вы указали на различия между Winsock и BSD сокетами.

Заранее спасибо!

Ответы [ 4 ]

80 голосов
/ 24 октября 2009

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

Основное различие между системами заключается в том, является ли IPV6_V6ONLY а) доступным и б) включено или выключено по умолчанию. По умолчанию он отключен в Linux (то есть разрешает двойные стек-сокеты без setsockopt) и включен в большинстве других систем.

Кроме того, стек IPv6 в Windows XP не поддерживает эту опцию. В этих случаях вам потребуется создать два отдельных серверных сокета и поместить их в select или в несколько потоков.

7 голосов
/ 11 февраля 2010

API сокетов регулируется RFC IETF и должен быть одинаковым на всех платформах, включая Windows WRT IPv6.

Для приложений IPv4 / IPv6 это ALL о getaddrinfo() и getnameinfo(). getaddrinfo - гений - смотрит на DNS, имена портов и возможности клиента, чтобы решить вечный вопрос «могу ли я использовать IPv4, IPv6 или и то и другое для достижения определенного пункта назначения?» Или, если вы собираетесь использовать двойной стек маршрутизировать и хотеть, чтобы он возвращал IPv4-сопоставленные IPv6-адреса, он тоже это сделает.

Он обеспечивает прямую структуру sockaddr *, которую можно подключить к bind(), recvfrom(), sendto() и семейство адресов для socket() ... Во многих случаях это означает, что не нужно заполнять беспорядочные структуры sockaddr_in(6) и иметь дело.

Для реализаций UDP я бы с осторожностью относился к настройке сокетов с двумя стеками или, в более общем смысле, к привязке ко всем интерфейсам (INADDR_ANY). Классическая проблема заключается в том, что, когда адреса не заблокированы (см. bind()) для определенных интерфейсов, а система имеет несколько запросов интерфейсов, ответы могут передаваться с разных адресов для компьютеров с несколькими адресами на основе прихотей таблицы маршрутизации ОС, путающие прикладные протоколы - особенно любые системы с требованиями аутентификации.

Для реализаций UDP, где это не является проблемой, или TCP, двойные стековые сокеты могут сэкономить много времени при включении IPv * вашей системы. Нужно быть осторожным, чтобы полностью не полагаться на двойной стек, если это не является абсолютно необходимым, поскольку нет недостатка в разумных платформах (Old Linux, BSD, Windows 2003), развернутых со стеками IPv6, не способными к сокетам с двумя стеками.

4 голосов
/ 20 августа 2010

Я играл с этим под Windows, и это действительно кажется проблемой безопасности, если вы привязываетесь к адресу обратной петли, тогда сокет IPv6 правильно привязан к [:: 1], но сопоставленный сокет IPv4 привязан к INADDR_ANY, так что ваше (предположительно) безопасное локальное приложение фактически открыто миру.

3 голосов
/ 18 мая 2010

RFC на самом деле не определяют наличие опции сокета IPV6_V6ONLY, но, если она отсутствует, RFC довольно ясно, что реализация должна быть такой, как если бы эта опция была FALSE.

Если эта опция присутствует, я бы сказал, что она должна иметь значение по умолчанию FALSE, но по причинам, подтверждающим понимание, реализации BSD и Windows по умолчанию имеют значение TRUE. Существует причудливое утверждение, что это проблема безопасности, потому что незнающий программист IPv6 мог связать себя, думая, что он был связан только с IN6ADDR_ANY только для IPv6, и случайно принять соединение IPv4, вызывающее проблему безопасности. Я думаю, что это и надумано, и абсурдно в дополнение к сюрпризу для тех, кто ожидает реализацию в соответствии с RFC.

В случае Windows несоответствие обычно не будет сюрпризом. В случае с BSD это в лучшем случае неудачно.

...