AF_INET6 アドレス・ファミリーの使用

AF_INET6 ソケットは、 インターネット・プロトコル バージョン 6 (IPv6) の 128 ビット (16 バイト) アドレス構造をサポートします。 プログラマーは AF_INET6 アドレス・ファミリーを使用してアプリケーションを作成し、IPv4 ノードまたは IPv6 ノードのどちらかから、 あるいは IPv6 ノードのみから、クライアント要求を受け入れることができます。

AF_INET ソケットと同様に、AF_INET6 ソケットにも、 コネクション型 (タイプ SOCK_STREAM) とコネクションレス型 (タイプ SOCK_DGRAM) があります。コネクション型 AF_INET6 ソケットは、TCP をトランスポート・プロトコルとして使用します。 コネクションレス型 AF_INET6 ソケットは、トランスポート・プロトコルとしてユーザー・データグラム・プロトコル (UDP) を使用します。AF_INET6 ドメイン・ソケットの作成時に、 ソケット・プログラムのアドレス・ファミリーに AF_INET6 を指定します。 AF_INET6 ソケットもタイプ SOCK_RAW を使用することができます。 このタイプを設定すると、アプリケーションは IP 層に直接接続し、TCP または UDP トランスポートのいずれも使用しません。

IPv6 アプリケーションと IPv4 アプリケーションの互換性

AF_INET6 アドレス・ファミリーを使ってソケット・アプリケーションを作成すれば、 インターネット・プロトコル バージョン 6 (IPv6) アプリケーションは、 インターネット・プロトコル バージョン 4 (IPv4) アプリケーション (AF_INET アドレス・ファミリーを使用するアプリケーション) と一緒に機能できるようになります。 この機能により、 ソケット・プログラマーは IPv4 マップ IPv6 アドレス形式を使用できます。 このアドレス形式は、IPv4 ノードの IPv4 アドレスを IPv6 アドレスとして表します。 IPv4 アドレスは IPv6 アドレスの下位 32 ビットにエンコードされ、 高位 96 ビットは 0:0:0:0:0:FFFF という接頭部で固定されます。 IPv4 マップ・アドレスの一例を挙げます。

 ::FFFF:192.1.1.1

指定されたホストが IPv4 アドレスしか持っていない場合、getaddrinfo() API でこのようなアドレスを自動的に生成できます。

AF_INET6 ソケットを使用して IPv4 ノードへの TCP 接続をオープンするアプリケーションを作成することができます。 そのためには、宛先の IPv4 アドレスを IPv4 マップ IPv6 アドレスにエンコードし、connect() または sendto() 呼び出しの中で、そのアドレスを sockaddr_in6 構造に渡すことができます。アプリケーションが AF_INET6 ソケットを使用して、IPv4 ノードからの TCP 接続を受け入れたり、IPv4 ノードから UDP パケットを受信したりする場合、 システムは同様の方法でエンコードされた sockaddr_in6 構造を使用し、 相手システムのアドレスを、accept()recvfrom()、 または getpeername() 呼び出しによってアプリケーションに戻します。

アプリケーションは、bind() API によって、UDP パケットや TCP 接続の送信元の IP アドレスを選択することができますが、 システムに送信元アドレスを選択してもらいたい場合もあります。 そのような場合、IPv4 であれば INADDR_ANY マクロを使用しますが、 それと同様の方法でアプリケーションは in6addr_any を使用できます。 この方法のバインドに追加された機能は、AF_INET6 ソケットが、IPv4 ノードと IPv6 ノードの両方と通信できるようになったということです。 例えば、in6addr_any にバインドされた listen 中のソケット上で accept() を発行するアプリケーションは、IPv4 または IPv6 ノードのどちらか一方からの接続を受け入れることができます。 この動作は、IPPROTO_IPV6 レベルのソケット・オプション IPV6_V6ONLY を使用して変更が可能です。 相互運用しているノードのタイプを知る必要のあるアプリケーションはほとんどありませんが、 それを知る必要のあるアプリケーションのために、<netinet/in.h> で定義されている IN6_IS_ADDR_V4MAPPED() マクロが提供されています。