Issue #7100 has been reported by sho-h (Sho Hashimoto). ---------------------------------------- Bug #7100: WEBrick::HTTPServer.new で BindAddress を指定しない場合に必ず警告が記録される https://bugs.ruby-lang.org/issues/7100 Author: sho-h (Sho Hashimoto) Status: Open Priority: Low Assignee: Category: Target version: ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] =begin 以下のようにすると必ず警告が記録されるようです。 $ ruby -v -r webrick -e 'WEBrick::HTTPServer.new(Port: 3000)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [2012-09-04 19:20:48] INFO WEBrick 1.3.1 [2012-09-04 19:20:48] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux] [2012-09-04 19:20:48] WARN TCPServer Error: Address already in use - bind(2) 1.8 では記録されませんでした。1.9.1 以降は記録されました。 lib/webrick/utils.rb の WEBrick::Utils#create_listeners が以下のようになっており、 res = Socket::getaddrinfo(address, port, Socket::AF_UNSPEC, # address family Socket::SOCK_STREAM, # socket type 0, # protocol Socket::AI_PASSIVE) # flag last_error = nil sockets = [] res.each{|ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger sock = TCPServer.new(ai[3], port) ... Socket.getaddrinfo が 1.9 から複数値を返すからのようです。1.8.7 だと 0.0.0.0 の方だけでした。 $ ruby -v -r pp -r socket -e 'pp Socket::getaddrinfo(nil, 3000, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [["AF_INET", 3000, "0.0.0.0", "0.0.0.0", 2, 1, 6], ["AF_INET6", 3000, "::", "::", 10, 1, 6]] WEBrick::Utils#create_listeners のコメントとマッチしなくなるデメリットがあるのですが、config[:BindAddress] のデフォルト値を 0.0.0.0 か :: のどちらかにしてしまうのはいかがでしょう。 =end
on 2012-10-02 10:22
on 2012-10-12 17:08
Issue #7100 has been updated by ChultOch5 (Sho Morita). =begin 私のところでも同様の症状が出ています。そういった警告が出る場合、WEBrick サーバーに IPv6 でアクセスできなくなってしまいます。また、環境によっては http://localhost:3000/ のように localhost を指定してもアクセス不能になってしまいます。(:BindAddress を明示的に指定すれば問題ないのですけれども…) WEBrick のドキュメントには :BindAddress に関して デフォルトの nil や "0.0.0.0", "::" などを指定した場合は使用可能なすべてのネットワークインターフェースに対して listen を開始します。 と書いてあるものの、実際には * nil を指定すると使用可能なすべての IPv4 および IPv6 ネットワークインターフェースに対して listen する。 * "0.0.0.0" を指定すると使用可能なすべての IPv4 ネットワークインターフェースに対してのみ listen する。 * "::" を指定すると使用可能なすべての IPv6 ネットワークインターフェースに対してのみ listen する。(一部システムでは nil と指定したのと同様に、すべての IPv4 と IPv6 ネットワークインターフェースに対して listen する) となります。 一部のシステム(Linuxなど)では、IPv6 ワイルドカードアドレスである :: を bind すると、IPv6 ネットワークインターフェースだけではなく、IPv4 ネットワークインターフェースも bind されます。0.0.0.0 と :: を両方 bind しようとすると、後から bind した方が Address already in use(EADDRINUSE) エラーとなり失敗するため、IPv6 でのアクセスが行えなくなってしまいます。 * http://www.a-k-r.org/pub/socket-rubykaigi2009.pdf * http://codezine.jp/article/detail/5395 * NEWS-1.9.2 などによると、Ruby 1.9.2 で Socket にたくさん機能が追加され、IPv6 問題がだいぶ改善されたようです。そこで追加された Socket#ipv6only! を呼び出すと IPV6_V6ONLY ソケットオプションが有効になり、0.0.0.0 と :: の両方を bind する事ができるようになります。 しかし、現在 WEBrick が使用している TCPServer は従来からある API で、IPV6_V6ONLY ソケットオプションをセットしません。新しい API である Socket.tcp_server_sockets などは、必要に応じて Socket#ipv6only! を呼び出してくれます。 ですので、TCPServer.new ではなく Socket.tcp_server_sockets を使うようにするのが良いかと思ったのですが、TCPServer.new のオブジェクトと Socket.tcp_server_sockets のオブジェクトは一部互換性の無い部分があり、置き換えてしまうと WEBrick を利用する既存のソフトウェアで互換性問題が起こるのではないか心配です。 そこで、互換性の問題が起こらないように TCPServer を使うのを維持しつつ問題を修正しようとすると、 * :BindAddress == nil である場合に、:: を先に bind し、0.0.0.0 を後から bind (その際 EADDRINUSE が起きても無視)する。 というようにすれば良いのではないかと思います。一応パッチを作ってみました。 Index: lib/webrick/utils.rb =================================================================== --- lib/webrick/utils.rb (revision 37168) +++ lib/webrick/utils.rb (working copy) @@ -79,6 +79,15 @@ Socket::AI_PASSIVE) # flag last_error = nil sockets = [] + # If address == nil, Socket.getaddrinfo returns 2 entries, the + # IPv4 wildcard address "0.0.0.0" and the IPv6 wildcard address "::". + # On some systems, if you try to bind for both "0.0.0.0" and "::", + # the later one will fails. + # To workaround such behaviour, try bind for "::" first, then + # bind "0.0.0.0" and ignore EADDRINUSE error. + if address.nil? + res = res.sort_by{|i| i[4]}.reverse + end res.each{|ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger @@ -87,7 +96,9 @@ Utils::set_close_on_exec(sock) sockets << sock rescue => ex - logger.warn("TCPServer Error: #{ex}") if logger + logger.warn("TCPServer Error: #{ex}") if logger and !(address.nil? and + ai[4] == Socket::AF_INET and + Errno::EADDRINUSE === ex) last_error = ex end } ちなみに、根本的な解決にはなりませんが、 # sysctl net.ipv6.bindv6only=1 とすると、IPV6_V6ONLY ソケットオプションがデフォルトで有効になり、:BindAddress が nil でも警告は出なくなります。 =end ---------------------------------------- Bug #7100: WEBrick::HTTPServer.new で BindAddress を指定しない場合に必ず警告が記録される https://bugs.ruby-lang.org/issues/7100#change-30447 Author: sho-h (Sho Hashimoto) Status: Open Priority: Low Assignee: Category: Target version: ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] =begin 以下のようにすると必ず警告が記録されるようです。 $ ruby -v -r webrick -e 'WEBrick::HTTPServer.new(Port: 3000)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [2012-09-04 19:20:48] INFO WEBrick 1.3.1 [2012-09-04 19:20:48] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux] [2012-09-04 19:20:48] WARN TCPServer Error: Address already in use - bind(2) 1.8 では記録されませんでした。1.9.1 以降は記録されました。 lib/webrick/utils.rb の WEBrick::Utils#create_listeners が以下のようになっており、 res = Socket::getaddrinfo(address, port, Socket::AF_UNSPEC, # address family Socket::SOCK_STREAM, # socket type 0, # protocol Socket::AI_PASSIVE) # flag last_error = nil sockets = [] res.each{|ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger sock = TCPServer.new(ai[3], port) ... Socket.getaddrinfo が 1.9 から複数値を返すからのようです。1.8.7 だと 0.0.0.0 の方だけでした。 $ ruby -v -r pp -r socket -e 'pp Socket::getaddrinfo(nil, 3000, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [["AF_INET", 3000, "0.0.0.0", "0.0.0.0", 2, 1, 6], ["AF_INET6", 3000, "::", "::", 10, 1, 6]] WEBrick::Utils#create_listeners のコメントとマッチしなくなるデメリットがあるのですが、config[:BindAddress] のデフォルト値を 0.0.0.0 か :: のどちらかにしてしまうのはいかがでしょう。 =end
on 2012-11-05 13:37
Issue #7100 has been updated by mame (Yusuke Endoh). Status changed from Open to Assigned Assignee set to akr (Akira Tanaka) Target version set to 2.0.0 akr さん、どう思われますか? -- Yusuke Endoh <mame@tsg.ne.jp> ---------------------------------------- Bug #7100: WEBrick::HTTPServer.new で BindAddress を指定しない場合に必ず警告が記録される https://bugs.ruby-lang.org/issues/7100#change-32403 Author: sho-h (Sho Hashimoto) Status: Assigned Priority: Low Assignee: akr (Akira Tanaka) Category: Target version: 2.0.0 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] =begin 以下のようにすると必ず警告が記録されるようです。 $ ruby -v -r webrick -e 'WEBrick::HTTPServer.new(Port: 3000)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [2012-09-04 19:20:48] INFO WEBrick 1.3.1 [2012-09-04 19:20:48] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux] [2012-09-04 19:20:48] WARN TCPServer Error: Address already in use - bind(2) 1.8 では記録されませんでした。1.9.1 以降は記録されました。 lib/webrick/utils.rb の WEBrick::Utils#create_listeners が以下のようになっており、 res = Socket::getaddrinfo(address, port, Socket::AF_UNSPEC, # address family Socket::SOCK_STREAM, # socket type 0, # protocol Socket::AI_PASSIVE) # flag last_error = nil sockets = [] res.each{|ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger sock = TCPServer.new(ai[3], port) ... Socket.getaddrinfo が 1.9 から複数値を返すからのようです。1.8.7 だと 0.0.0.0 の方だけでした。 $ ruby -v -r pp -r socket -e 'pp Socket::getaddrinfo(nil, 3000, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [["AF_INET", 3000, "0.0.0.0", "0.0.0.0", 2, 1, 6], ["AF_INET6", 3000, "::", "::", 10, 1, 6]] WEBrick::Utils#create_listeners のコメントとマッチしなくなるデメリットがあるのですが、config[:BindAddress] のデフォルト値を 0.0.0.0 か :: のどちらかにしてしまうのはいかがでしょう。 =end
on 2012-11-06 10:34
2012/11/5 mame (Yusuke Endoh) <mame@tsg.ne.jp>: > > akr $B$5$s!"$I$&;W$o$l$^$9$+!)(B IPv4-mapped IPv6 address $B$O%W%i%C%H%U%)!<%`$K$h$C$FMxMQ$G$-$?$j$G$-$J$+$C$?$j$9$k$N$G!"(B $B$I$N%W%i%C%H%U%)!<%`$G$bMxMQ$7$J$$$GF0:n$9$k$h$&$K$9$k$N$,F0:n$,0l4S$7$F$h$$$H;W$$$^$9!#(B $B;d$O!"D94|E*$K$O!"(BTCPServer $B$H$+$r;H$&$N$O$d$a$F!"(B Socket $B$K0\9T$7$FM_$7$$$H;W$C$F$$$^$9$,!"(B $B8_49@-$NLdBj$rL5;k$9$k$3$H$b$G$-$^$;$s$h$M!#(B $B$H$$$&$U$?$D$NE@$r9M$($k$H!"(BSocket.tcp_server_sockets $B$G%=%1%C%H$r:n$C$F!"(B $B$=$3$+$i(B TCPServer.for_fd $B$G(B TCPServer $B$N%$%s%9%?%s%9$r:n$k$"$?$j$+$J$!!"$H(B $B;W$$$^$9!#(B
on 2012-11-07 11:21
Issue #7100 has been updated by akr (Akira Tanaka). File webrick-dont-use-ipv4-mapped-ipv6-address.patch added webrick-dont-use-ipv4-mapped-ipv6-address.patch みたいなかんじかなぁ。 ---------------------------------------- Bug #7100: WEBrick::HTTPServer.new で BindAddress を指定しない場合に必ず警告が記録される https://bugs.ruby-lang.org/issues/7100#change-32549 Author: sho-h (Sho Hashimoto) Status: Assigned Priority: Low Assignee: akr (Akira Tanaka) Category: Target version: 2.0.0 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] =begin 以下のようにすると必ず警告が記録されるようです。 $ ruby -v -r webrick -e 'WEBrick::HTTPServer.new(Port: 3000)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [2012-09-04 19:20:48] INFO WEBrick 1.3.1 [2012-09-04 19:20:48] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux] [2012-09-04 19:20:48] WARN TCPServer Error: Address already in use - bind(2) 1.8 では記録されませんでした。1.9.1 以降は記録されました。 lib/webrick/utils.rb の WEBrick::Utils#create_listeners が以下のようになっており、 res = Socket::getaddrinfo(address, port, Socket::AF_UNSPEC, # address family Socket::SOCK_STREAM, # socket type 0, # protocol Socket::AI_PASSIVE) # flag last_error = nil sockets = [] res.each{|ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger sock = TCPServer.new(ai[3], port) ... Socket.getaddrinfo が 1.9 から複数値を返すからのようです。1.8.7 だと 0.0.0.0 の方だけでした。 $ ruby -v -r pp -r socket -e 'pp Socket::getaddrinfo(nil, 3000, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [["AF_INET", 3000, "0.0.0.0", "0.0.0.0", 2, 1, 6], ["AF_INET6", 3000, "::", "::", 10, 1, 6]] WEBrick::Utils#create_listeners のコメントとマッチしなくなるデメリットがあるのですが、config[:BindAddress] のデフォルト値を 0.0.0.0 か :: のどちらかにしてしまうのはいかがでしょう。 =end
on 2013-02-18 15:55
Issue #7100 has been updated by mame (Yusuke Endoh). Target version changed from 2.0.0 to next minor ちょっと今からだと怖すぎるのと、BindAddress を指定するという workaround があるようなので、 すみませんが一旦 next minor に。 2.0.0-pXXX で直すかどうかは nagachika さんにお任せします。 -- Yusuke Endoh <mame@tsg.ne.jp> ---------------------------------------- Bug #7100: WEBrick::HTTPServer.new で BindAddress を指定しない場合に必ず警告が記録される https://bugs.ruby-lang.org/issues/7100#change-36535 Author: sho-h (Sho Hashimoto) Status: Assigned Priority: Low Assignee: akr (Akira Tanaka) Category: Target version: next minor ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] =begin 以下のようにすると必ず警告が記録されるようです。 $ ruby -v -r webrick -e 'WEBrick::HTTPServer.new(Port: 3000)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [2012-09-04 19:20:48] INFO WEBrick 1.3.1 [2012-09-04 19:20:48] INFO ruby 1.9.3 (2012-04-20) [x86_64-linux] [2012-09-04 19:20:48] WARN TCPServer Error: Address already in use - bind(2) 1.8 では記録されませんでした。1.9.1 以降は記録されました。 lib/webrick/utils.rb の WEBrick::Utils#create_listeners が以下のようになっており、 res = Socket::getaddrinfo(address, port, Socket::AF_UNSPEC, # address family Socket::SOCK_STREAM, # socket type 0, # protocol Socket::AI_PASSIVE) # flag last_error = nil sockets = [] res.each{|ai| begin logger.debug("TCPServer.new(#{ai[3]}, #{port})") if logger sock = TCPServer.new(ai[3], port) ... Socket.getaddrinfo が 1.9 から複数値を返すからのようです。1.8.7 だと 0.0.0.0 の方だけでした。 $ ruby -v -r pp -r socket -e 'pp Socket::getaddrinfo(nil, 3000, Socket::AF_UNSPEC, Socket::SOCK_STREAM, 0, Socket::AI_PASSIVE)' ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux] [["AF_INET", 3000, "0.0.0.0", "0.0.0.0", 2, 1, 6], ["AF_INET6", 3000, "::", "::", 10, 1, 6]] WEBrick::Utils#create_listeners のコメントとマッチしなくなるデメリットがあるのですが、config[:BindAddress] のデフォルト値を 0.0.0.0 か :: のどちらかにしてしまうのはいかがでしょう。 =end
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.