mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26637 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9f782768ab
commit
d3004ccff3
2 changed files with 82 additions and 33 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
Thu Feb 11 09:49:31 2010 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@tsg.ne.jp>
|
Thu Feb 11 01:45:04 2010 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* vm.c (vm_exec): temporarily revert r26628, which causes SEGV when
|
* vm.c (vm_exec): temporarily revert r26628, which causes SEGV when
|
||||||
|
|
|
@ -520,10 +520,11 @@ class Resolv
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_requester # :nodoc:
|
def make_requester # :nodoc:
|
||||||
if nameserver_port = @config.single?
|
nameserver_port = @config.nameserver_port
|
||||||
Requester::ConnectedUDP.new(*nameserver_port)
|
if nameserver_port.length == 1
|
||||||
|
Requester::ConnectedUDP.new(*nameserver_port[0])
|
||||||
else
|
else
|
||||||
Requester::UnconnectedUDP.new
|
Requester::UnconnectedUDP.new(*nameserver_port)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -609,10 +610,10 @@ class Resolv
|
||||||
}
|
}
|
||||||
end
|
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
|
begin
|
||||||
port = rangerand(1024..65535)
|
port = rangerand(1024..65535)
|
||||||
udpsock.bind(is_ipv6 ? "::" : "", port)
|
udpsock.bind(bind_host, port)
|
||||||
rescue Errno::EADDRINUSE
|
rescue Errno::EADDRINUSE
|
||||||
retry
|
retry
|
||||||
end
|
end
|
||||||
|
@ -621,7 +622,7 @@ class Resolv
|
||||||
class Requester # :nodoc:
|
class Requester # :nodoc:
|
||||||
def initialize
|
def initialize
|
||||||
@senders = {}
|
@senders = {}
|
||||||
@sock = nil
|
@socks = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def request(sender, tout)
|
def request(sender, tout)
|
||||||
|
@ -629,10 +630,11 @@ class Resolv
|
||||||
sender.send
|
sender.send
|
||||||
while (now = Time.now) < timelimit
|
while (now = Time.now) < timelimit
|
||||||
timeout = timelimit - now
|
timeout = timelimit - now
|
||||||
if !IO.select([@sock], nil, nil, timeout)
|
select_result = IO.select(@socks, nil, nil, timeout)
|
||||||
|
if !select_result
|
||||||
raise ResolvTimeout
|
raise ResolvTimeout
|
||||||
end
|
end
|
||||||
reply, from = recv_reply
|
reply, from = recv_reply(select_result[0])
|
||||||
begin
|
begin
|
||||||
msg = Message.decode(reply)
|
msg = Message.decode(reply)
|
||||||
rescue DecodeError
|
rescue DecodeError
|
||||||
|
@ -648,9 +650,11 @@ class Resolv
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
sock = @sock
|
socks = @socks
|
||||||
@sock = nil
|
@socks = nil
|
||||||
sock.close if sock
|
if socks
|
||||||
|
socks.each {|sock| sock.close }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Sender # :nodoc:
|
class Sender # :nodoc:
|
||||||
|
@ -662,16 +666,31 @@ class Resolv
|
||||||
end
|
end
|
||||||
|
|
||||||
class UnconnectedUDP < Requester # :nodoc:
|
class UnconnectedUDP < Requester # :nodoc:
|
||||||
def initialize
|
def initialize(*nameserver_port)
|
||||||
super()
|
super()
|
||||||
@sock = UDPSocket.new
|
@nameserver_port = nameserver_port
|
||||||
@sock.do_not_reverse_lookup = true
|
@socks_hash = {}
|
||||||
@sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
@socks = []
|
||||||
DNS.bind_random_port(@sock)
|
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
|
end
|
||||||
|
|
||||||
def recv_reply
|
def recv_reply(readable_socks)
|
||||||
reply, from = @sock.recvfrom(UDPSize)
|
reply, from = readable_socks[0].recvfrom(UDPSize)
|
||||||
return reply, [from[3],from[1]]
|
return reply, [from[3],from[1]]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -680,8 +699,9 @@ class Resolv
|
||||||
id = DNS.allocate_request_id(host, port)
|
id = DNS.allocate_request_id(host, port)
|
||||||
request = msg.encode
|
request = msg.encode
|
||||||
request[0,2] = [id].pack('n')
|
request[0,2] = [id].pack('n')
|
||||||
|
sock = @socks_hash[host.index(':') ? "::" : "0.0.0.0"]
|
||||||
return @senders[[service, id]] =
|
return @senders[[service, id]] =
|
||||||
Sender.new(request, data, @sock, host, port)
|
Sender.new(request, data, sock, host, port)
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
|
@ -711,15 +731,16 @@ class Resolv
|
||||||
@host = host
|
@host = host
|
||||||
@port = port
|
@port = port
|
||||||
is_ipv6 = host.index(':')
|
is_ipv6 = host.index(':')
|
||||||
@sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
|
sock = UDPSocket.new(is_ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
|
||||||
@sock.do_not_reverse_lookup = true
|
@socks = [sock]
|
||||||
@sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
sock.do_not_reverse_lookup = true
|
||||||
DNS.bind_random_port(@sock, is_ipv6)
|
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
||||||
@sock.connect(host, port)
|
DNS.bind_random_port(sock, is_ipv6 ? "::" : "0.0.0.0")
|
||||||
|
sock.connect(host, port)
|
||||||
end
|
end
|
||||||
|
|
||||||
def recv_reply
|
def recv_reply(readable_socks)
|
||||||
reply = @sock.recv(UDPSize)
|
reply = readable_socks[0].recv(UDPSize)
|
||||||
return reply, nil
|
return reply, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -730,7 +751,7 @@ class Resolv
|
||||||
id = DNS.allocate_request_id(@host, @port)
|
id = DNS.allocate_request_id(@host, @port)
|
||||||
request = msg.encode
|
request = msg.encode
|
||||||
request[0,2] = [id].pack('n')
|
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
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
|
@ -753,14 +774,15 @@ class Resolv
|
||||||
super()
|
super()
|
||||||
@host = host
|
@host = host
|
||||||
@port = port
|
@port = port
|
||||||
@sock = TCPSocket.new(@host, @port)
|
sock = TCPSocket.new(@host, @port)
|
||||||
@sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
@socks = [sock]
|
||||||
|
sock.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined? Fcntl::F_SETFD
|
||||||
@senders = {}
|
@senders = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def recv_reply
|
def recv_reply(readable_socks)
|
||||||
len = @sock.read(2).unpack('n')[0]
|
len = readable_socks[0].read(2).unpack('n')[0]
|
||||||
reply = @sock.read(len)
|
reply = @socks[0].read(len)
|
||||||
return reply, nil
|
return reply, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -771,7 +793,7 @@ class Resolv
|
||||||
id = DNS.allocate_request_id(@host, @port)
|
id = DNS.allocate_request_id(@host, @port)
|
||||||
request = msg.encode
|
request = msg.encode
|
||||||
request[0,2] = [request.length, id].pack('nn')
|
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
|
end
|
||||||
|
|
||||||
class Sender < Requester::Sender # :nodoc:
|
class Sender < Requester::Sender # :nodoc:
|
||||||
|
@ -932,6 +954,10 @@ class Resolv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def nameserver_port
|
||||||
|
@nameserver_port
|
||||||
|
end
|
||||||
|
|
||||||
def generate_candidates(name)
|
def generate_candidates(name)
|
||||||
candidates = nil
|
candidates = nil
|
||||||
name = Name.create(name)
|
name = Name.create(name)
|
||||||
|
|
Loading…
Add table
Reference in a new issue