Dual-Stack сокеты для приложений Winsock IPv6
Для поддержки IPv4 и IPv6 в Windows XP с пакетом обновления 1 (SP1) и в Windows Server 2003 приложение должен создать два сокета, один сокет для использования с IPv4 и один сокет для использования с IPv6. Эти два сокета должны обрабатываться отдельно приложением.
Windows Vista и более поздних версий предлагают возможность создать один сокет IPv6, который может обрабатывать трафик IPv6 и IPv4. Например, создается сокет прослушивания TCP для IPv6, помещается в режим двойного стека и привязан к порту 5001. Этот сокет с двойным стеком может принимать подключения от клиентов TCP IPv6, подключающихся к порту 5001 и от клиентов TCP IPv4, подключающихся к порту 5001. Эта функция позволяет значительно упростить проектирование приложения и сократить затраты на ресурсы, необходимые для размещения операций на двух отдельных сокетах.
Создание сокета Dual-Stack
По умолчанию сокет IPv6, созданный в Windows Vista, работает только через протокол IPv6. Чтобы сделать сокет IPv6 в сокет с двумя стеками, функция setockopt должна вызываться с параметром сокета IPV6_V6ONLY, чтобы задать это значение равно нулю, прежде чем сокет привязан к IP-адресу. Если параметр сокета IPV6_V6ONLY имеет значение нулю, то для отправки и получения пакетов из IPv6-адреса или сопоставленного адреса IPv4 можно использовать сокет, созданный для семейства адресов AF_INET6.
IP-адреса с сокетом Dual-Stack
Сокеты с двумя стеками всегда требуют IPv6-адресов. Для взаимодействия с IPv4-адресом требуется использование формата IPv4-сопоставленного IPv6-адреса. Все адреса IPv4 должны быть представлены в формате IPv4-сопоставленного IPv6-адреса, что позволяет приложению IPv6 взаимодействовать только с узлом IPv4. Формат IPv4-сопоставленного IPv6-адреса позволяет представлять IPv4-адрес узла IPv4 в виде IPv6-адреса. IPv4-адрес закодирован в 32-разрядные 32 бита IPv6-адреса, а высокий порядок 96 битов содержит фиксированный префикс 0:0:0:0:0:0:0:FFFF. В RFC 4291 указан формат адресов iPv6, сопоставленный с IPv4. Дополнительные сведения см. в www.ietf.org/rfc/rfc4291.txt. Макрос IN6ADDR_SETV4MAPPED в Mstcpip.h можно использовать для преобразования IPv4-адреса в требуемый формат IPv4-адресов, сопоставленных с IPv6.
Если базовый протокол фактически является IPv4, то IPv4-адрес сопоставляется с форматом IPv4-адресов, сопоставленных с IPv6. То есть поле семейства в структуре SOCKADDR указывает AF_INET6, но ipPv4-сопоставленный IPv6-адрес закодирован в структуре адресов IPv6. Для сокета с двумя стеками в режиме прослушивания это означает, что все принятые подключения IPv4 возвращают ipPv4-адрес, сопоставленный с IPv6. Для сокета с двойным стеком, который подключается к назначению IPv4, структура SOCKADDR, переданная для подключения, должна быть ipPv4-сопоставленным IPv6-адресом. Приложения должны заботиться об обработке этих IPv4-сопоставленных IPv6-адресов соответствующим образом и использовать их только с двумя сокетами стека. Если IP-адрес должен передаваться в обычный сокет IPv4, адрес должен быть обычным IPv4-адресом, а не IPv4-сопоставленным IPv6-адресом.
Потенциальные проблемы с использованием сокета Dual-Stack
Потенциальная ошибка для приложений получает IPv4-сопоставленный IPv6-адрес на сокете с двумя стеками, а затем пытается использовать возвращенный IP-адрес только в другом сокете IPv6. Например, getockname или функции getpeername могут возвращать IPv4-сопоставленный IPv6-адрес при использовании в сокете с двумя стеками. Если возвращенный IPv4-сопоставленный IPv6-адрес затем используется в другом сокете, который не был задан для двойного стека (IPv6 только сокет, который является поведением по умолчанию при создании сокета), любое использование этого сокета IPv6 только с IPv4-сопоставленным IPv6-адресом завершится ошибкой. Формат адресов IPv4, сопоставленный с IPv6, можно использовать только в сокете с двумя стеками.
Если приложению требуется функция LPFN_WSARECVMSG (WSARecvMsg) для возврата сведений о пакете в WSAMSG для диаграмм данных IP_PKTINFO, полученных по протоколу IPv4, необходимо задать значение true в сокете. Если для сокета задано значение true только IPV6_PKTINFO, сведения о пакете будут предоставлены для диаграмм данных, полученных по протоколу IPv6, но могут не предоставляться для диаграмм данных, полученных по протоколу IPv4.
Если приложение пытается задать параметр сокета IP_PKTINFO в сокете с двумя стеками данных и IPv4 отключен в системе, функция setockopt завершится ошибкой, и WSAGetLastError возвращается с ошибкой WSAEINVAL. Эта же ошибка также возвращается функцией setsockopt в результате других ошибок. Если приложение пытается задать параметр сокета уровня IPPROTO_IP на сокете с двумя стеками и завершается сбоем с WSAEINVAL, то приложение должно определить, отключен ли IPv4 на локальном компьютере. Один из методов, который можно использовать для обнаружения включения или отключения IPv4, заключается в вызове функции сокета с параметром af для AF_INET, чтобы попытаться создать сокет IPv4. Если функция сокета завершается ошибкой и WSAGetLastError возвращает ошибку WSAEAFNOSUPPORT, то это означает, что IPv4 не включен. В этом случае сбой функции setockopt при попытке задать параметр сокета IP_PKTINFO можно игнорировать приложением. В противном случае при попытке задать параметр сокета IP_PKTINFO следует рассматривать как непредвиденная ошибка.
Для сокета с двумя стеками при отправке диаграмм данных с помощью функции WSASendMsg и приложение хочет указать конкретный локальный IP-адрес источника, метод обработки этого зависит от целевого IP-адреса. При отправке в адрес назначения IPv4 или ipPv4-сопоставленный адрес назначения IPv6 один из объектов данных управления, передаваемых в структуре WSAMSG, на которую указывает параметр lpMsg, должен содержать структуру in_pktinfo, содержащую локальный исходный адрес IPv4, используемый для отправки. При отправке в целевой адрес IPv6, который не является ipPv4-сопоставленным IPv6-адресом, один из объектов данных управления, передаваемых в структуре WSAMSG, на которую указывает параметр lpMsg, должен содержать in6_pktinfo структуру, содержащую локальный исходный адрес IPv6, используемый для отправки.
Связанные разделы
-
изменение структур данных для IPv6 Winsock Appications
-
проблемы с пользовательским интерфейсом для приложений Winsock IPv6