IPv6 Winsock アプリケーションのデータ構造の変更

IPv6 のサポートを追加するときは、アプリケーションで適切なサイズのデータ構造が定義されていることを確認する必要があります。 IPv6 アドレスのサイズは、IPv4 アドレスよりもはるかに大きくなります。 IP アドレスを格納するときに IPv4 アドレスのサイズを処理するようにハードコードされた構造は、アプリケーションで問題を引き起こすため、変更する必要があります。

ベスト プラクティス

構造のサイズを適切に設定するには、SOCKADDR_STORAGE 構造体を使用することをお勧めします。 SOCKADDR_STORAGE 構造体は、IP アドレスのバージョンに依存しません。 SOCKADDR_STORAGE 構造体を使用して IP アドレスを格納すると、1 つのコード ベースで IPv4 アドレスと IPv6 アドレスを適切に処理できます。

次の例は、付録 B にある Server.c ファイルからの抜粋であり、SOCKADDR_STORAGE 構造体の適切な使用方法を示しています。 この例で示されているように、この構造体は適切に使用されると、IPv4 または 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;
}

Note

SOCKADDR_STORAGE 構造体は、Windows XP の新機能です。

 

回避するコード

通常、多くのアプリケーションは、プロトコルに依存しないアドレスを格納するために sockaddr 構造体を使用し、IP アドレスの格納には sockaddr_in 構造体を使用します。 sockaddr 構造体も sockaddr_in 構造体も IPv6 アドレスを保持するのに十分な大きさがないため、アプリケーションを IPv6 互換にするにはどちらも不十分です。

コーディング タスク

既存のコード ベースを IPv4 から IPv4 と IPv6 の相互運用性に変更するには

  1. Checkv4.exe ユーティリティを取得します。 このユーティリティは、Microsoft Windows ソフトウェア開発キット (SDK) に含まれています。
  2. コードに対して Checkv4.exe ユーティリティを実行します。 ファイルに対して Checkv4.exe ユーティリティを実行する方法の詳細については、「Checkv4.exe ユーティリティの使用」のセクションを参照してください。
  3. このユーティリティは、sockaddr 構造体または sockaddr_in 構造体の使用を警告し、IPv6 互換構造体である SOCKADDR_STORAGE に置き換える方法について推奨事項を提供します。
  4. SOCKADDR_STORAGE 構造体を使用するには、このようなインスタンス、および必要な場合には関連するコードを置き換えます。

あるいは、コード ベースで sockaddr 構造体および sockaddr_in 構造体のインスタンスを検索し、そのような使用法 (および必要な場合にはその他の関連コード) をすべて SOCKADDR_STORAGE 構造体に変更することもできます。

Note

addrinfo 構造体および SOCKADDR_STORAGE 構造体には、プロトコルおよびアドレス ファミリ メンバー (ai_family および ss_family) がそれぞれ含まれます。 RFC 2553 では、addrinfoai_family メンバーは int として指定されていますが、ss_family は short として指定されています。そのため、これらのメンバー間で直接コピーすると、コンパイラ エラーが発生します。

 

Windows ソケット アプリケーションの IPv6 ガイド

IPv6 Winsock アプリケーション用のデュアル スタック ソケット

IPv6 Winsock アプリケーションの関数呼び出し

ハードコードされた IPv4 アドレスの使用

IPv6 Winsock アプリケーションのユーザー インターフェイスに関する問題

IPv6 Winsock アプリケーションの基になるプロトコル