[Ruby 1.8-Bug#4230][Open] PlatformSDKのヘッダでビルドするとSocket::getaddrinfoで例外

Bug #4230: PlatformSDKのヘッダでビルドするとSocket::getaddrinfoで例外
http://redmine.ruby-lang.org/issues/show/4230

起票者: Masahiro Kitajima
ステータス: Open, 優先度: Normal
ruby -v: ruby -v:ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mswin32]

以前からVC++6.0対応の最後の Platform SDK である「Microsoft Platform SDK February
2003」を使ってビルドしていました。
ruby-1.8.7-p330から ext/socket/extconf.rb
が変わった事で、getaddrinfo()、getnameinfo()
に、エミュレーション・コード(getaddrinfo.c、getnameinfo.c)の代わりに Windows API
が使われるようになりました。
これにより、以下のコードの address に nil や “localhost” を与えた時に例外が上がるようになりました。

---- ここから ----
require ‘socket’
port = 80
address = “localhost”
p Socket::getaddrinfo(address, port,
Socket::AF_UNSPEC, # address family
Socket::SOCK_STREAM, # socket type
0, # protocol
Socket::AI_PASSIVE) # flag
#=>
test.rb:4:in `getaddrinfo’: getnameinfo: 呼び出しでポインタ引数を使用するときに、無効なポインタ
アドレスを検出しました。 (SocketError)
from test.rb:4

ruby-1.8.7-p302 =>

[[“AF_INET”, 80, “localhost”, “127.0.0.1”, 2, 1, 6]]
---- ここまで ----

このテスト・コードは WEBrick::Utils#create_listeners に書かれているものです。WEBrick
利用のアプリケーション(gem server など)が動かなくなって気付きました。
なお、VC++6.0 のヘッダでビルドした時は getaddrinfo.c、getnameinfo.c が使われるため、上記現象は起きません。

ext/socket/extconf.rb を以下のようにすると、Platform SDK のヘッダでビルドした時の
getnameinfo() API 呼び出しの矛盾がなくなり、上記現象が解消します。また結果として IPv6 対応になります。
また VC++6.0 のヘッダでビルドした時は、従来どおり getaddrinfo.c、getnameinfo.c が使われます。

---- ここから ----
extconf.rb.org Wed Nov 24 18:37:06 2010
+++ extconf.rb Tue Jan 04 20:27:24 2011
@@ -43,4 +43,5 @@
if checking_for(“ipv6”) {try_link(<<EOF)}
-#include <sys/types.h>
-#include <sys/socket.h>
+#{(RUBY_PLATFORM =~ /mswin32/) ?

  • #include <winsock2.h>\n#include <ws2tcpip.h>” :
  • #include <sys/types.h>\n#include <sys/socket.h>”}
    int
    @@ -48,2 +49,3 @@
    {
  • struct in6_addr dummy;
    socket(AF_INET6, SOCK_STREAM, 0);
    ---- ここまで ----

チケット #4230 が更新されました。 (by Usaku NAKAMURA)

ステータス OpenからClosedに変更
進捗 % 0から100に変更

This issue was solved with changeset r30457.
Masahiro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.