Dual-Stack sockets para aplicaciones winsock IPv6
Para admitir IPv4 e IPv6 en Windows XP con Service Pack 1 (SP1) y en Windows Server 2003, una aplicación tiene que crear dos sockets, un socket para su uso con IPv4 y un socket para su uso con IPv6. La aplicación debe controlar estos dos sockets por separado.
Windows Vista y versiones posteriores ofrecen la capacidad de crear un único socket IPv6 que pueda controlar el tráfico IPv6 e IPv4. Por ejemplo, se crea un socket de escucha TCP para IPv6, se coloca en modo de pila dual y se enlaza al puerto 5001. Este socket de doble pila puede aceptar conexiones de clientes TCP IPv6 que se conectan al puerto 5001 y desde clientes TCP IPv4 que se conectan al puerto 5001. Esta característica permite un diseño de aplicaciones muy simplificado y reduce la sobrecarga de recursos necesaria para contabilizar operaciones en dos sockets independientes.
Creación de un socket Dual-Stack
De forma predeterminada, un socket IPv6 creado en Windows Vista y versiones posteriores solo funciona a través del protocolo IPv6. Para convertir un socket IPv6 en un socket de doble pila, se debe llamar a la función setsockopt con la opción de socket IPV6_V6ONLY para establecer este valor en cero antes de que el socket esté enlazado a una dirección IP. Cuando la opción de socket de IPV6_V6ONLY está establecida en cero, se puede usar un socket creado para la familia de direcciones AF_INET6 para enviar y recibir paquetes hacia y desde una dirección IPv6 o una dirección asignada IPv4.
Direcciones IP con un socket Dual-Stack
Los sockets de doble pila siempre requieren direcciones IPv6. La capacidad de interactuar con una dirección IPv4 requiere el uso del formato de dirección IPv4 asignado a IPv6. Todas las direcciones IPv4 deben representarse en el formato de dirección IPv4 asignado a IPv6, lo que permite que una aplicación IPv6 solo se comunique con un nodo IPv4. El formato de dirección IPv4 asignado a IPv6 permite representar la dirección IPv4 de un nodo IPv4 como una dirección IPv6. La dirección IPv4 se codifica en los 32 bits de orden bajo de la dirección IPv6 y los 96 bits de orden superior contienen el prefijo fijo 0:0:0:0:0:0:0:FFFF. El formato de dirección IPv4 asignado a IPv6 se especifica en RFC 4291. Para obtener más información, vea www.ietf.org/rfc/rfc4291.txt. La macro IN6ADDR_SETV4MAPPED de Mstcpip.h se puede usar para convertir una dirección IPv4 al formato de dirección IPv4 asignado a IPv4 necesario.
Si el protocolo subyacente es realmente IPv4, la dirección IPv4 se asigna a un formato de dirección IPv4 asignado a IPv6. Es decir, el campo de familia del SOCKADDR estructura indica AF_INET6, pero una dirección IPv4 asignada por IPv6 se codifica en la estructura de direcciones IPv6. Para un socket de doble pila en modo de escucha, esto significa que las conexiones IPv4 aceptadas devolverán una dirección IPv6 asignada por IPv4. Para un socket de doble pila que se conecta a un destino IPv4, la estructura SOCKADDR pasada a la conexión debe ser una dirección IPv4 asignada a IPv6. Las aplicaciones deben tener cuidado para controlar estas direcciones IPv4 asignadas a IPv6 de forma adecuada y solo usarlas con sockets de pila dual. Si se va a pasar una dirección IP a un socket IPv4 normal, la dirección debe ser una dirección IPv4 normal no una dirección IPv6 asignada por IPv4.
Posibles problemas con un socket de Dual-Stack
Un posible problema para las aplicaciones es obtener una dirección IPv4 asignada por IPv6 en un socket de doble pila y, a continuación, intentar usar la dirección IP devuelta en un socket IPv6 único diferente. Por ejemplo, las funciones de getockname o getpeername pueden devolver una dirección IPv4 asignada por IPv6 cuando se usa en un socket de doble pila. Si la dirección IPv4 asignada a IPv4 devuelta se usa posteriormente en un socket diferente que no se estableció en la pila doble (un socket IPv6 solo que es el comportamiento predeterminado cuando se crea un socket), cualquier uso de este socket IPv6 solo con una dirección IPv6 asignada por IPv4 producirá un error. El formato de dirección IPv4 asignado a IPv6 solo se puede usar en un socket de doble pila.
En un socket de datagrama de doble pila, si una aplicación requiere el LPFN_WSARECVMSG (WSARecvMsg) función para devolver información de paquetes en un estructura de WSAMSG para datagramas recibidos a través de IPv4, IP_PKTINFO opción de socket debe establecerse en true en el socket. Si solo la opción IPV6_PKTINFO se establece en true en el socket, se proporcionará información de paquetes para datagramas recibidos a través de IPv6, pero no se puede proporcionar para datagramas recibidos a través de IPv4.
Si una aplicación intenta establecer la opción de socket IP_PKTINFO en un socket de datagrama de doble pila e IPv4 está deshabilitada en el sistema, se producirá un error en la funciónsetsockopty WSAGetLastError devolverá un error de WSAEINVAL. Este mismo error también lo devuelve el setockopt función como resultado de otros errores. Si una aplicación intenta establecer una opción de socket de nivel de IPPROTO_IP en un socket de doble pila y se produce un error con WSAEINVAL, la aplicación debe determinar si IPv4 está deshabilitado en el equipo local. Un método que se puede usar para detectar si IPv4 está habilitado o deshabilitado es llamar a la función socket con el parámetro af establecido en AF_INET para intentar crear un socket IPv4. Si se produce un error en la función de socket y WSAGetLastError devuelve un error de WSAEAFNOSUPPORT, significa que IPv4 no está habilitado. En este caso, la aplicación puede omitir un error de función de setsockopt al intentar establecer la opción de socket IP_PKTINFO. De lo contrario, se debe tratar un error al intentar establecer la opción de socket IP_PKTINFO como un error inesperado.
Para un socket de doble pila al enviar datagramas con la función WSASendMsgdey una aplicación quiere especificar una dirección de origen IP local específica que se va a usar, el método para controlar esto depende de la dirección IP de destino. Al enviar a una dirección de destino IPv4 o a una dirección de destino IPv4 asignada por IPv4, uno de los objetos de datos de control pasados en la estructura WSAMSG apuntada por el parámetro lpMsg debe contener una estructura de in_pktinfo que contiene la dirección de origen IPv4 local que se va a usar para el envío. Al enviar a una dirección de destino IPv6 que no es una dirección IPv4 asignada a IPv6, uno de los objetos de datos de control pasados en la estructura WSAMSG apuntada por el parámetro lpMsg debe contener una estructura de in6_pktinfo que contiene la dirección de origen IPv6 local que se va a usar para el envío.
Temas relacionados
-
cambiar las estructuras de datos para las de aplicaciones de Winsock de IPv6
-
problemas de la interfaz de usuario de para aplicaciones IPv6 Winsock