web-dev-qa-db-ja.com

IPv4接続とIPv6接続の両方をサポートする方法

現在、UDPソケットアプリケーションに取り組んでおり、IPV4およびIPV6接続がサーバーにパケットを送信できるようにサポートを組み込む必要があります。

誰かが私を助けて正しい方向に向けてくれることを望んでいた。私が見つけたドキュメントの大半は完全ではありませんでした。また、WinsockとBSDソケットの違いを指摘できると助かります。

前もって感謝します!

52
Charles

最良のアプローチは、IPv4接続も受け入れることができるIPv6サーバーソケットを作成することです。そのためには、通常のIPv6ソケットを作成し、ソケットオプションIPV6_V6ONLY、それを「任意の」アドレスにバインドし、受信を開始します。 IPv4アドレスは、IPv6アドレスとして IPv4-mapped 形式で表示されます。

システム間の主な違いは、IPV6_V6ONLYは、a)利用可能、b)デフォルトでオンまたはオフになります。 Linuxではデフォルトでオフになっています(つまり、setsockoptなしでデュアルスタックソケットを許可します)。他のほとんどのシステムではオンになっています。

さらに、Windows上のIPv6スタックXPはそのオプションをサポートしません。これらの場合、2つの別個のサーバーソケットを作成し、選択または複数のスレッドに配置する必要があります。

80

ソケットAPIはIETF RFCによって管理されており、Windows WRT IPv6を含むすべてのプラットフォームで同じである必要があります。

IPv4/IPv6アプリケーションの場合、[〜#〜] all [〜#〜]getaddrinfo()およびgetnameinfo()についてです。 getaddrinfoは天才です。DNS、ポート名、クライアントの機能を見て、「特定の宛先に到達するためにIPv4、IPv6、またはその両方を使用できますか?」という永遠の疑問を解決します。または、デュアルスタックルートを使用していて、IPv4にマップされたIPv6アドレスを返すようにしたい場合は、それも行います。

bind()recvfrom()sendto()、およびsocket()のアドレスファミリにプラグインできる直接_sockaddr *_構造を提供します...多くの場合これは、面倒なsockaddr_in(6)構造に記入して対処する必要がないことを意味します。

UDP実装の場合、デュアルスタックソケットの設定、またはより一般的にはすべてのインターフェイス(_INADDR_ANY_)へのバインドに注意します。古典的な問題は、アドレスが特定のインターフェイスにロックダウンされていない場合(bind()を参照)、システムに複数のインターフェイスリクエストがある場合、OSの気まぐれに基づいて複数のアドレスを持つコンピューターの異なるアドレスから応答が送信される可能性があることですルーティングテーブル、アプリケーションプロトコルの混乱-特に認証要件のあるシステム。

これが問題ではないUDP実装、またはTCPの場合、デュアルスタックソケットは、システムをIPv *対応にするときに多くの時間を節約できます。デュアルスタックソケットに対応していないIPv6スタックで展開された合理的なプラットフォーム(Old Linux、BSD、Windows 2003)が不足していないため、絶対に必要ではないデュアルスタックに完全に依存しないように注意する必要があります。

7
Einstein

私はこれをWindowsで遊んでいますが、実際にはそこにセキュリティの問題があるようです。ループバックアドレスにバインドすると、IPv6ソケットは[:: 1]に正しくバインドされますが、マッピングされたIPv4ソケットはINADDR_ANYにバインドされます、したがって、(おそらく)安全なローカル専用アプリは実際に世界に公開されます。

4
Dave

RFCは実際にはIPV6_V6ONLYソケットオプションの存在を指定していませんが、存在しない場合、RFCはそのオプションがFALSEであるかのように実装する必要があることを明確にしています。

このオプションが存在する場合、デフォルトはFALSEであると主張しますが、理解を得るために、BSDおよびWindowsの実装はデフォルトでTRUEになります。知らないIPv6プログラマーは、IPv6のみに対してIN6ADDR_ANYにのみバインドしていると考え、誤ってIPv4接続を受け入れてセキュリティ問題を引き起こすため、これはセキュリティ上の懸念であるという奇妙な主張があります。これは、RFC準拠の実装を期待している人にとって驚きであることに加えて、これは非常に難解で不条理だと思います。

Windowsの場合、通常、非コンプライアンスは驚くことではありません。 BSDの場合、これは良くても残念です。

3
Owen DeLong