Alterando estruturas de dados para aplicativos IPv6 Winsock

Ao adicionar suporte para IPv6, você deve garantir que seu aplicativo defina estruturas de dados com o tamanho adequado. O tamanho de um endereço IPv6 é muito maior do que de um IPv4. Estruturas rigidamente codificadas para lidar com o tamanho de um endereço IPv4 ao armazenar um endereço IP causarão problemas em seu aplicativo e devem ser modificadas.

Melhor Prática

A melhor abordagem para garantir que suas estruturas sejam dimensionadas corretamente é usar a estrutura SOCKADDR_STORAGE . A estrutura SOCKADDR_STORAGE é agnóstica à versão do endereço IP. Quando a estrutura SOCKADDR_STORAGE é usada para armazenar endereços IP, os endereços IPv4 e IPv6 podem ser tratados adequadamente com uma base de código.

O exemplo a seguir, que é um trecho retirado do arquivo Server.c encontrado no Apêndice B, identifica um uso apropriado da estrutura SOCKADDR_STORAGE. Observe que a estrutura, usada corretamente, como mostra este exemplo, lida normalmente com um endereço IPv4 ou IPv6.

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

#define BUFFER_SIZE 512
#define DEFAULT_PORT "27015"

int main(int argc, char **argv)
{
    char Buffer[BUFFER_SIZE] = {0};
    char *Hostname;
    int Family = AF_UNSPEC;
    int SocketType = SOCK_STREAM;
    char *Port = DEFAULT_PORT;
    char *Address = NULL;
    int i = 0;
    DWORD dwRetval = 0;
    int iResult = 0;
    int FromLen = 0;
    int AmountRead = 0;

    SOCKADDR_STORAGE From;

    WSADATA wsaData;

    ADDRINFO *AddrInfo = NULL;
    ADDRINFO *AI = NULL;

    // Parse arguments
    if (argc >= 1) {
        Hostname = argv[1];
    }    

   // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %d\n", iResult);
        return 1;
    }

    From.ss_family = (ADDRESS_FAMILY) Family;
    
    //...
        
        return 0;
}

Observação

A estrutura SOCKADDR_STORAGE é nova para o Windows XP.

 

Código a ser evitado.

Normalmente, muitos aplicativos usavam a estrutura sockaddr para armazenar endereços independentes de protocolo ou a estrutura sockaddr_in para endereços IP. Nem a estrutura sockaddr nem a sockaddr_in são grandes o suficiente para conter endereços IPv6 e, portanto, são insuficientes para que seu aplicativo seja compatível com IPv6.

Tarefa de codificação

Para modificar sua base de código existente de IPv4 para interoperabilidade IPv4 e IPv6

  1. Adquira o utilitário Checkv4.exe. Esses utilitários estão incluídos no kit de desenvolvimento de software (SDK) do Microsoft Windows.
  2. Execute o utilitário Checkv4.exe em seu código. Saiba mais sobre como executar o utilitário Checkv4.exe em seus arquivos na seção Como usar o Utilitário Checkv4.exe.
  3. O utilitário alerta sobre o uso de estruturas sockaddr ou sockaddr_in e fornece recomendações sobre como substituir qualquer uma delas por uma estrutura compatível com IPv6 SOCKADDR_STORAGE.
  4. Substitua quaisquer instâncias e o código associado, como apropriado, para usar a estrutura SOCKADDR_STORAGE.

Como alternativa, você pode pesquisar em sua base de código instâncias das estruturas sockaddr e sockaddr_in e alterar todo o uso (e outro código associado, como apropriado) para a estrutura SOCKADDR_STORAGE.

Observação

As estruturas addrinfo e SOCKADDR_STORAGE incluem membros da família de protocolo e endereço (ai_family e ss_family), respectivamente. O RFC 2553 especifica o membro ai_family de addrinfo como um int, enquanto ss_family é especificado como um short; como tal, uma cópia direta entre esses membros resulta em um erro do compilador.

 

Guia do IPv6 para aplicativos Windows Sockets

Soquetes de pilha dupla para aplicativos Winsock IPv6

Chamadas de função para aplicativos Winsock IPv6

Uso de endereços IPv4 codificados

Problemas de interface do usuário em aplicativos Winsock IPv6

Protocolos subjacentes para aplicativos Winsock IPv6