IPv4接続とIPv6接続の両方をサポートする方法
質問
現在、UDPソケットアプリケーションに取り組んでおり、IPV4およびIPV6接続がサーバーにパケットを送信できるようにサポートを組み込む必要があります。
誰かが私を助けて正しい方向に向けてくれることを望んでいた。私が見つけたドキュメントの大半は完全ではありませんでした。また、WinsockとBSDソケットの違いを指摘できると助かります。
事前に感謝します!
解決
最良のアプローチは、IPv4接続も受け入れることができるIPv6サーバーソケットを作成することです。これを行うには、通常のIPv6ソケットを作成し、ソケットオプション IPV6_V6ONLY
を off して、「any」にバインドします。アドレスし、受信を開始します。 IPv4アドレスは、 IPv4-mapped 形式でIPv6アドレスとして表示されます。
システム間の主な違いは、 IPV6_V6ONLY
がa)利用可能か、b)デフォルトでオンまたはオフになっているかです。 Linuxではデフォルトでオフになっています(つまり、setsockoptなしでデュアルスタックソケットを許可します)。他のほとんどのシステムではオンになっています。
さらに、Windows XPのIPv6スタックはそのオプションをサポートしていません。これらの場合、2つの別個のサーバーソケットを作成し、それらをselectまたは複数のスレッドに配置する必要があります。
他のヒント
ソケットAPIはIETF RFCによって管理されており、Windows WRT IPv6を含むすべてのプラットフォームで同じである必要があります。
IPv4 / IPv6アプリケーションの場合、 getaddrinfo()
および getnameinfo()
については ALL です。 getaddrinfo
は天才です。DNS、ポート名、クライアントの機能を調べて、特定の宛先に到達するためにIPv4、IPv6、またはその両方を使用できますか?&#8221 ;または、デュアルスタックルートを使用していて、IPv4にマップされたIPv6アドレスを返すようにしたい場合は、それも行います。
bind()
、 recvfrom()
、 sendto()にプラグインできる直接の
および sockaddr *
構造を提供します socket()
…のアドレスファミリ多くの場合、これは、記入して処理する面倒な sockaddr_in(6)
構造がないことを意味します。
UDP実装では、デュアルスタックソケットの設定、またはより一般的にはすべてのインターフェイスへのバインド( INADDR_ANY
)に注意します。古典的な問題は、アドレスが特定のインターフェースにロックダウンされていない場合( bind()
を参照)、システムに複数のインターフェース要求がある場合、応答は、 OSルーティングテーブルの気まぐれ、アプリケーションプロトコル、特に認証要件のあるシステムを混乱させます。
これが問題にならないUDP実装、またはTCPの場合、デュアルスタックソケットは、システムでIPv *を有効にするときに多くの時間を節約できます。デュアルスタックソケットに対応していないIPv6スタックで展開された合理的なプラットフォーム(Old Linux、BSD、Windows 2003)が不足していないため、絶対に必要ではないデュアルスタックに完全に依存しないように注意する必要があります。
私はこれをWindowsで遊んでいますが、実際にはセキュリティ上の問題のようです。ループバックアドレスにバインドすると、IPv6ソケットは[:: 1]に正しくバインドされますが、マッピングされたIPv4ソケットはINADDR_ANYにバインドされているため、(おそらく)安全なローカル専用アプリは実際に世界に公開されます。
RFCは実際にはIPV6_V6ONLYソケットオプションの存在を指定していませんが、存在しない場合、RFCはそのオプションがFALSEであるかのように実装する必要があることを明確にしています。
このオプションが存在する場合、デフォルトはFALSEであると主張しますが、理解を得るために、BSDおよびWindowsの実装はデフォルトでTRUEになります。知らないIPv6プログラマーは、IPv6のIN6ADDR_ANYのみにバインドしていると考えてバインドし、誤ってIPv4接続を受け入れてセキュリティ上の問題を引き起こす可能性があるため、これはセキュリティ上の懸念であるという奇妙な主張があります。これは、RFC準拠の実装を期待している人にとって驚きに加えて、これは非常に手ごわくて馬鹿げていると思います。
Windowsの場合、通常、非準拠は驚くことではありません。 BSDの場合、これは良くても残念です。