にし@おかやまです。

[ruby-list:35713]から引っ越しました。

TCPSocketでIPv4/IPv6の選択ができないのが不便に感じたので,
TCPSocket#newおよびTCPServer#newをそれぞれ

TCPSocket#new(host, service [,ai_family=Socket::PF_UNSPEC])
TCPServer#new([host=localhost,] service [,ai_family=Socket::PF_UNSPEC])

と拡張してみました。

ruby 1.6.7 (2002-03-01) のext/socket/socket.cに対するパッチを
http://www.koka-in.org/%7Ezophos/lib/ruby-1.6.7-ipsocket_select_ai_family.patch
に置いておきます。

当初はIPSocket#lookup_order_table= を新設することも考えましたが,それに
ついては[ruby-dev:9904]で否定的結論が出ているようなので,
hint->ai_family=PF_UNSPEC時の挙動を規定するのではなく,hint->ai_family自
体を接続時に決めてしまおうと言うアプローチにしています。

この方法のメリットは
 * 既存のRubyコードに影響をあたえない
 * インスタンス毎にIPv4/IPv6/UNSPECを切り替えられる
ということでしょうか。

デメリットは
 * TCPServerの引数のパースがややこしくなる
 * Linux(USAGI)ではCONFIG_IPV6_DOUBLE_BINDが有効なカーネルであり,
   かつソケットオプションでIPV6_V6ONLYを設定しない限り,TCPServerで
   ai_familyを設定しても意味が無い
などが考えられます。

よろしければ,手法の妥当性を含めて検討してみてください。

-- 
NISHI Takao   D add ninth Co.,Ltd.  http://www.Dadd9.com/
   1-2-24 Toyonari, Okayama, 700-0942, Japan               @@@@
   Phone:+81-86-801-4216  Facsimile:+81-86-801-4217        OO/
   PGP:1466 BB16 3186 CC11 1A06 713C 5518 3A2A A122 118A  -|/