Soquetes Dual-Stack para aplicativos Winsock IPv6
Para dar suporte a IPv4 e IPv6 no Windows XP com Service Pack 1 (SP1) e no Windows Server 2003, um aplicativo precisa criar dois soquetes, um soquete para uso com IPv4 e um soquete para uso com IPv6. Esses dois soquetes devem ser tratados separadamente pelo aplicativo.
O Windows Vista e posterior oferecem a capacidade de criar um único soquete IPv6 que pode lidar com o tráfego IPv6 e IPv4. Por exemplo, um soquete de escuta TCP para IPv6 é criado, colocado no modo de pilha dupla e associado à porta 5001. Esse soquete de pilha dupla pode aceitar conexões de clientes TCP IPv6 que se conectam à porta 5001 e de clientes TCP IPv4 que se conectam à porta 5001. Esse recurso permite um design de aplicativo muito simplificado e reduz a sobrecarga de recursos necessária para operações de postagem em dois soquetes separados.
Criando um soquete Dual-Stack
Por padrão, um soquete IPv6 criado no Windows Vista e posterior só opera pelo protocolo IPv6. Para transformar um soquete IPv6 em um soquete de pilha dupla, a função setsockopt deve ser chamada com a opção de soquete IPV6_V6ONLY para definir esse valor como zero antes que o soquete seja associado a um endereço IP. Quando a opção IPV6_V6ONLY soquete é definida como zero, um soquete criado para a família de endereços AF_INET6 pode ser usado para enviar e receber pacotes de e para um endereço IPv6 ou um endereço mapeado IPv4.
Endereços IP com um soquete Dual-Stack
Soquetes de pilha dupla sempre exigem endereços IPv6. A capacidade de interagir com um endereço IPv4 requer o uso do formato de endereço IPv6 mapeado para IPv4. Todos os endereços IPv4 devem ser representados no formato de endereço IPv6 mapeado por IPv4, que permite que um aplicativo IPv6 somente se comunique com um nó IPv4. O formato de endereço IPv6 mapeado para IPv4 permite que o endereço IPv4 de um nó IPv4 seja representado como um endereço IPv6. O endereço IPv4 é codificado nos 32 bits de ordem baixa do endereço IPv6 e os 96 bits de ordem alta contêm o prefixo fixo 0:0:0:0:0:FFFF. O formato de endereço IPv6 mapeado por IPv4 é especificado no RFC 4291. Para obter mais informações, consulte www.ietf.org/rfc/rfc4291.txt. A macro IN6ADDR_SETV4MAPPED em Mstcpip.h pode ser usada para converter um endereço IPv4 no formato de endereço IPv6 mapeado IPv4 necessário.
Se o protocolo subjacente for, na verdade, IPv4, o endereço IPv4 será mapeado para um formato de endereço IPv6 mapeado para IPv4. Esse é o campo da família na estrutura de SOCKADDR indica AF_INET6, mas um endereço IPv6 mapeado por IPv4 é codificado na estrutura de endereçoS IPv6. Para um soquete de pilha dupla no modo de escuta, isso significa que todas as conexões IPv4 aceitas retornarão um endereço IPv6 mapeado por IPv4. Para um soquete de pilha dupla que está se conectando a um destino IPv4, a estrutura SOCKADDR passada para se conectar deve ser um endereço IPv6 mapeado por IPv4. Os aplicativos devem ter cuidado para lidar com esses endereços IPv6 mapeados por IPv4 adequadamente e usá-los apenas com soquetes de pilha dupla. Se um endereço IP deve ser passado para um soquete IPv4 regular, o endereço deve ser um endereço IPv4 normal e não um endereço IPv4 mapeado IPv6.
Possíveis problemas usando um soquete Dual-Stack
Uma possível armadilha para aplicativos é obter um endereço IPv6 mapeado por IPv4 em um soquete de pilha dupla e, em seguida, tentar usar o endereço IP retornado em um soquete IPv6 diferente. Por exemplo, as funções getockname ou getpeername podem retornar um endereço IPv6 mapeado por IPv4 quando usado em um soquete de pilha dupla. Se o endereço IPv6 mapeado IPv4 retornado for usado posteriormente em um soquete diferente que não foi definido como pilha dupla (um soquete IPv6 somente que é o comportamento padrão quando um soquete é criado), qualquer uso desse soquete IPv6 somente com um endereço IPv6 mapeado IPv4 falhará. O formato de endereço IPv6 mapeado por IPv4 só pode ser usado em um soquete de pilha dupla.
Em um soquete de datagram de pilha dupla, se um aplicativo exigir a função LPFN_WSARECVMSG (WSARecvMsg) para retornar informações de pacote em uma estrutura deWSAMSGpara datagramas recebidos por IPv4, IP_PKTINFO opção de soquete deverá ser definida como true no soquete. Se apenas a opção IPV6_PKTINFO for definida como true no soquete, as informações do pacote serão fornecidas para datagramas recebidos por IPv6, mas podem não ser fornecidas para datagramas recebidos por IPv4.
Se um aplicativo tentar definir a opção de soquete IP_PKTINFO em um soquete de datagram de pilha dupla e o IPv4 estiver desabilitado no sistema, a função setsockopt falhará e WSAGetLastError retornará com um erro de WSAEINVAL. Esse mesmo erro também é retornado pela função setsockopt como resultado de outros erros. Se um aplicativo tentar definir uma opção de soquete de nível IPPROTO_IP em um soquete de pilha dupla e falhar com WSAEINVAL, o aplicativo deverá determinar se o IPv4 está desabilitado no computador local. Um método que pode ser usado para detectar se o IPv4 está habilitado ou desabilitado é chamar a funçãodo soquetecom o parâmetro af definido como AF_INET para tentar criar um soquete IPv4. Se a função do soquete falhar e WSAGetLastError retornará um erro de WSAEAFNOSUPPORT, isso significa que o IPv4 não está habilitado. Nesse caso, uma falha de função de setsockopt ao tentar definir a opção de soquete IP_PKTINFO pode ser ignorada pelo aplicativo. Caso contrário, uma falha ao tentar definir a opção de soquete IP_PKTINFO deve ser tratada como um erro inesperado.
Para um soquete de pilha dupla ao enviar datagrams com a função WSASendMsg e um aplicativo deseja especificar um endereço de origem IP local específico a ser usado, o método para lidar com isso depende do endereço IP de destino. Ao enviar para um endereço de destino IPv4 ou um endereço de destino IPv6 mapeado por IPv4, um dos objetos de dados de controle passados na estrutura deWSAMSGapontado pelo parâmetro lpMsg deve conter uma estrutura in_pktinfo que contém o endereço de origem IPv4 local a ser usado para envio. Ao enviar para um endereço de destino IPv6 que não é um endereço IPv6 mapeado para IPv4, um dos objetos de dados de controle passados no estrutura de WSAMSG apontado pelo parâmetro lpMsg deve conter uma estrutura in6_pktinfo que contém o endereço de origem IPv6 local a ser usado para envio.
Tópicos relacionados