Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top