ruby-changes:14776
From: akr <ko1@a...>
Date: Thu, 11 Feb 2010 10:29:57 +0900 (JST)
Subject: [ruby-changes:14776] Ruby:r26637 (ruby_1_8, trunk): * lib/resolv.rb: fix .
akr 2010-02-11 10:29:38 +0900 (Thu, 11 Feb 2010) New Revision: 26637 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26637 Log: * lib/resolv.rb: fix [ruby-core:28144]. (Resolv::DNS#make_requester): pass nameserver_port to UnconnectedUDP.new. (Resolv::DNS.bind_random_port): change the is_ipv6 argument to bind_host. (Resolv::DNS::Requester#initialize): change instance variable to store multiple sockets. (Resolv::DNS::Requester#request): pass readable sockets to recv_reply. (Resolv::DNS::Requester#close): close all sockets. (Resolv::DNS::Requester::UnconnectedUDP#initialize): allocate a socket for each address family of name servers. (Resolv::DNS::Requester::UnconnectedUDP#recv_reply): read from the passwd readable socket. (Resolv::DNS::Requester::UnconnectedUDP#sender): use appropriate socket for the target nameserver. (Resolv::DNS::Requester::ConnectedUDP): follow the instance variable change. (Resolv::DNS::Requester::TCP#sender): ditto. (Resolv::DNS::Config#nameserver_port): new method. Modified files: branches/ruby_1_8/ChangeLog branches/ruby_1_8/lib/resolv.rb trunk/ChangeLog trunk/lib/resolv.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 26636) +++ ChangeLog (revision 26637) @@ -1,3 +1,26 @@ +Thu Feb 11 09:49:31 2010 Tanaka Akira <akr@f...> + + * lib/resolv.rb: fix [ruby-core:28144]. + (Resolv::DNS#make_requester): pass nameserver_port to + UnconnectedUDP.new. + (Resolv::DNS.bind_random_port): change the is_ipv6 argument to + bind_host. + (Resolv::DNS::Requester#initialize): change instance variable to + store multiple sockets. + (Resolv::DNS::Requester#request): pass readable sockets to + recv_reply. + (Resolv::DNS::Requester#close): close all sockets. + (Resolv::DNS::Requester::UnconnectedUDP#initialize): allocate + a socket for each address family of name servers. + (Resolv::DNS::Requester::UnconnectedUDP#recv_reply): read from the + passwd readable socket. + (Resolv::DNS::Requester::UnconnectedUDP#sender): use appropriate + socket for the target nameserver. + (Resolv::DNS::Requester::ConnectedUDP): follow the instance variable + change. + (Resolv::DNS::Requester::TCP#sender): ditto. + (Resolv::DNS::Config#nameserver_port): new method. + Thu Feb 11 01:45:04 2010 Yusuke Endoh <mame@t...> * vm.c (vm_exec): temporarily revert r26628, which causes SEGV when Index: lib/resolv.rb =================================================================== --- lib/resolv.rb (revision 26636) +++ lib/resolv.rb (revision 26637) @@ -520,10 +520,11 @@ end def make_requester # :nodoc: - if nameserver_port = @config.single? - Requester::ConnectedUDP.new(*nameserver_port) + nameserver_port = @config.nameserver_port + if nameserver_port.length == 1 + Requester::ConnectedUDP.new(*nameserver_port[0]) else - Requester::UnconnectedUDP.new + Requester::UnconnectedUDP.new(*nameserver_port) end end @@ -609,10 +610,10 @@ } end - def self.bind_random_port(udpsock, is_ipv6=false) # :nodoc: + def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc: begin port = rangerand(1024..65535) - udpsock.bind(is_ipv6 ? "::" : "", port) + udpsock.bind(bind_host, port) rescue Errno::EADDRINUSE retry end @@ -621,7 +622,7 @@ class Requester # :nodoc: def initialize @senders = {} - @sock = nil + @socks = nil end def request(sender, tout) @@ -629,10 +630,11 @@ sender.send while (now = Time.now) < timelimit timeout = timelimit - now - if !IO.select([@sock], nil, nil, timeout) + select_result = IO.select(@socks, nil, nil, timeout) + if !select_result raise ResolvTimeout end - reply, from = recv_reply + reply, from = recv_reply(select_result[0]) begin msg = Message.decode(reply) rescue DecodeError @@ -648,9 +650,11 @@ end def close - sock = @sock - @sock = nil - sock.close if sock + socks = @socks + @socks = nil + if socks + socks.each {|sock| sock.close } + end end class Sender # :nodoc: @@ -662,16 +666,31 @@ end class UnconnectedUDP < Requester # :nodoc: - def initialize + def initialize(*nameserver_port) super() - @sock = UDPSocket.new - @sock.do_not_reverse_lookup = true - @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD - DNS.bind_random_port(@sock) + @nameserver_port = nameserver_port + @socks_hash = {} + @socks = [] + nameserver_port.each {|host, port| + if host.index(':') + bind_host = "::" + af = Socket::AF_INET6 + else + bind_host = "0.0.0.0" + af = Socket::AF_INET + end + next if @socks_hash[bind_host] + sock = UDPSocket.new(af) + sock.do_not_reverse_lookup = true + sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + DNS.bind_random_port(sock, bind_host) + @socks << sock + @socks_hash[bind_host] = sock + } end - def recv_reply - reply, from = @sock.recvfrom(UDPSize) + def recv_reply(readable_socks) + reply, from = readable_socks[0].recvfrom(UDPSize) return reply, [from[3],from[1]] end @@ -680,8 +699,9 @@ id = DNS.allocate_request_id(host, port) request = msg.encode request[0,2] = [id].pack('n') + sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"] return @senders[[service, id]] = - Sender.new(request, data, @sock, host, port) + Sender.new(request, data, sock, host, port) end def close @@ -711,15 +731,16 @@ @host = host @port = port is_ipv6 = host.index(':') - @sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET) - @sock.do_not_reverse_lookup = true - @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD - DNS.bind_random_port(@sock, is_ipv6) - @sock.connect(host, port) + sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET) + @socks = [sock] + sock.do_not_reverse_lookup = true + sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0") + sock.connect(host, port) end - def recv_reply - reply = @sock.recv(UDPSize) + def recv_reply(readable_socks) + reply = readable_socks[0].recv(UDPSize) return reply, nil end @@ -730,7 +751,7 @@ id = DNS.allocate_request_id(@host, @port) request = msg.encode request[0,2] = [id].pack('n') - return @senders[[nil,id]] = Sender.new(request, data, @sock) + return @senders[[nil,id]] = Sender.new(request, data, @socks[0]) end def close @@ -753,14 +774,15 @@ super() @host = host @port = port - @sock = TCPSocket.new(@host, @port) - @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + sock = TCPSocket.new(@host, @port) + @socks = [sock] + sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD @senders = {} end - def recv_reply - len = @sock.read(2).unpack('n')[0] - reply = @sock.read(len) + def recv_reply(readable_socks) + len = readable_socks[0].read(2).unpack('n')[0] + reply = @socks[0].read(len) return reply, nil end @@ -771,7 +793,7 @@ id = DNS.allocate_request_id(@host, @port) request = msg.encode request[0,2] = [request.length, id].pack('nn') - return @senders[[nil,id]] = Sender.new(request, data, @sock) + return @senders[[nil,id]] = Sender.new(request, data, @socks[0]) end class Sender < Requester::Sender # :nodoc: @@ -932,6 +954,10 @@ end end + def nameserver_port + @nameserver_port + end + def generate_candidates(name) candidates = nil name = Name.create(name) Index: ruby_1_8/ChangeLog =================================================================== --- ruby_1_8/ChangeLog (revision 26636) +++ ruby_1_8/ChangeLog (revision 26637) @@ -1,3 +1,26 @@ +Thu Feb 11 09:49:31 2010 Tanaka Akira <akr@f...> + + * lib/resolv.rb: fix [ruby-core:28144]. + (Resolv::DNS#make_requester): pass nameserver_port to + UnconnectedUDP.new. + (Resolv::DNS.bind_random_port): change the is_ipv6 argument to + bind_host. + (Resolv::DNS::Requester#initialize): change instance variable to + store multiple sockets. + (Resolv::DNS::Requester#request): pass readable sockets to + recv_reply. + (Resolv::DNS::Requester#close): close all sockets. + (Resolv::DNS::Requester::UnconnectedUDP#initialize): allocate + a socket for each address family of name servers. + (Resolv::DNS::Requester::UnconnectedUDP#recv_reply): read from the + passwd readable socket. + (Resolv::DNS::Requester::UnconnectedUDP#sender): use appropriate + socket for the target nameserver. + (Resolv::DNS::Requester::ConnectedUDP): follow the instance variable + change. + (Resolv::DNS::Requester::TCP#sender): ditto. + (Resolv::DNS::Config#nameserver_port): new method. + Thu Feb 11 09:37:01 2010 Tanaka Akira <akr@f...> * lib/resolv.rb: support :nameserver_port option. backport r26230 Index: ruby_1_8/lib/resolv.rb =================================================================== --- ruby_1_8/lib/resolv.rb (revision 26636) +++ ruby_1_8/lib/resolv.rb (revision 26637) @@ -513,10 +513,11 @@ end def make_requester # :nodoc: - if nameserver_port = @config.single? - Requester::ConnectedUDP.new(*nameserver_port) + nameserver_port = @config.nameserver_port + if nameserver_port.length == 1 + Requester::ConnectedUDP.new(*nameserver_port[0]) else - Requester::UnconnectedUDP.new + Requester::UnconnectedUDP.new(*nameserver_port) end end @@ -602,10 +603,10 @@ } end - def self.bind_random_port(udpsock, is_ipv6=false) # :nodoc: + def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc: begin port = rangerand(1024..65535) - udpsock.bind(is_ipv6 ? "::" : "", port) + udpsock.bind(bind_host, port) rescue Errno::EADDRINUSE retry end @@ -614,7 +615,7 @@ class Requester # :nodoc: def initialize @senders = {} - @sock = nil + @socks = nil end def request(sender, tout) @@ -622,10 +623,11 @@ sender.send while (now = Time.now) < timelimit timeout = timelimit - now - if !IO.select([@sock], nil, nil, timeout) + select_result = IO.select(@socks, nil, nil, timeout) + if !select_result raise ResolvTimeout end - reply, from = recv_reply + reply, from = recv_reply(select_result[0]) begin msg = Message.decode(reply) rescue DecodeError @@ -641,9 +643,11 @@ end def close - sock = @sock - @sock = nil - sock.close if sock + socks = @socks + @socks = nil + if socks + socks.each {|sock| sock.close } + end end class Sender # :nodoc: @@ -655,15 +659,30 @@ end class UnconnectedUDP < Requester # :nodoc: - def initialize + def initialize(*nameserver_port) super() - @sock = UDPSocket.new - @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD - DNS.bind_random_port(@sock) + @nameserver_port = nameserver_port + @socks_hash = {} + @socks = [] + nameserver_port.each {|host, port| + if host.index(':') + bind_host = "::" + af = Socket::AF_INET6 + else + bind_host = "0.0.0.0" + af = Socket::AF_INET + end + next if @socks_hash[bind_host] + sock = UDPSocket.new(af) + sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + DNS.bind_random_port(sock, bind_host) + @socks << sock + @socks_hash[bind_host] = sock + } end - def recv_reply - reply, from = @sock.recvfrom(UDPSize) + def recv_reply(readable_socks) + reply, from = readable_socks[0].recvfrom(UDPSize) return reply, [from[3],from[1]] end @@ -672,8 +691,9 @@ id = DNS.allocate_request_id(host, port) request = msg.encode request[0,2] = [id].pack('n') + sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"] return @senders[[service, id]] = - Sender.new(request, data, @sock, host, port) + Sender.new(request, data, sock, host, port) end def close @@ -703,14 +723,15 @@ @host = host @port = port is_ipv6 = host.index(':') - @sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET) - DNS.bind_random_port(@sock, is_ipv6) - @sock.connect(host, port) - @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET) + @socks = [sock] + sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0") + sock.connect(host, port) end - def recv_reply - reply = @sock.recv(UDPSize) + def recv_reply(readable_socks) + reply = readable_socks[0].recv(UDPSize) return reply, nil end @@ -721,7 +742,7 @@ id = DNS.allocate_request_id(@host, @port) request = msg.encode request[0,2] = [id].pack('n') - return @senders[[nil,id]] = Sender.new(request, data, @sock) + return @senders[[nil,id]] = Sender.new(request, data, @socks[0]) end def close @@ -744,14 +765,15 @@ super() @host = host @port = port - @sock = TCPSocket.new(@host, @port) - @sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD + sock = TCPSocket.new(@host, @port) + @socks = [sock] + sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD @senders = {} end - def recv_reply - len = @sock.read(2).unpack('n')[0] - reply = @sock.read(len) + def recv_reply(readable_socks) + len = readable_socks[0].read(2).unpack('n')[0] + reply = @socks[0].read(len) return reply, nil end @@ -762,7 +784,7 @@ id = DNS.allocate_request_id(@host, @port) request = msg.encode request[0,2] = [request.length, id].pack('nn') - return @senders[[nil,id]] = Sender.new(request, data, @sock) + return @senders[[nil,id]] = Sender.new(request, data, @socks[0]) end class Sender < Requester::Sender # :nodoc: @@ -923,6 +945,10 @@ end end + def nameserver_port + @nameserver_port + end + def generate_candidates(name) candidates = nil name = Name.create(name) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/