summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2021-09-17 17:17:20 -0700
committergit <svn-admin@ruby-lang.org>2023-11-25 02:24:43 +0000
commit7276d4b4e87bfdc9b609f481a734e39c499de253 (patch)
tree1669a12e27d1af77f3318d8a3c4987c8efa160fb
parentfb7add495454322ea00efa7549feb957cb1ca538 (diff)
[ruby/resolv] Support a :raise_timeout_errors option to raise timeouts as Resolv::ResolvError
This allows to differentiate a timeout from an NXDOMAIN response. Fixes [Bug #18151] https://github.com/ruby/resolv/commit/c0e5abab76
-rw-r--r--lib/resolv.rb6
-rw-r--r--test/resolv/test_dns.rb24
2 files changed, 30 insertions, 0 deletions
diff --git a/lib/resolv.rb b/lib/resolv.rb
index 8203e5110a..0943edc400 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -312,6 +312,8 @@ class Resolv
# String:: Path to a file using /etc/resolv.conf's format.
# Hash:: Must contain :nameserver, :search and :ndots keys.
# :nameserver_port can be used to specify port number of nameserver address.
+ # :raise_timeout_errors can be used to raise timeout errors
+ # as exceptions instead of treating the same as an NXDOMAIN response.
#
# The value of :nameserver should be an address string or
# an array of address strings.
@@ -1032,6 +1034,7 @@ class Resolv
end
@search = config_hash[:search] if config_hash.include? :search
@ndots = config_hash[:ndots] if config_hash.include? :ndots
+ @raise_timeout_errors = config_hash[:raise_timeout_errors]
if @nameserver_port.empty?
@nameserver_port << ['0.0.0.0', Port]
@@ -1118,6 +1121,7 @@ class Resolv
def resolv(name)
candidates = generate_candidates(name)
timeouts = @timeouts || generate_timeouts
+ timeout_error = false
begin
candidates.each {|candidate|
begin
@@ -1129,11 +1133,13 @@ class Resolv
end
}
}
+ timeout_error = true
raise ResolvError.new("DNS resolv timeout: #{name}")
rescue NXDomain
end
}
rescue ResolvError
+ raise if @raise_timeout_errors && timeout_error
end
end
diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb
index c0400b4bb8..63ab66657c 100644
--- a/test/resolv/test_dns.rb
+++ b/test/resolv/test_dns.rb
@@ -630,4 +630,28 @@ class TestResolvDNS < Test::Unit::TestCase
end
assert_raise(Resolv::ResolvError) { dns.each_name('example.com') }
end
+
+ def test_unreachable_server
+ unreachable_ip = '127.0.0.1'
+ sock = UDPSocket.new
+ sock.connect(unreachable_ip, 53)
+ begin
+ sock.send('1', 0)
+ rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH
+ else
+ omit('cannot test unreachable server, as IP used is reachable')
+ end
+
+ config = {
+ :nameserver => [unreachable_ip],
+ :search => ['lan'],
+ :ndots => 1
+ }
+ r = Resolv.new([Resolv::DNS.new(config)])
+ assert_equal([], r.getaddresses('www.google.com'))
+
+ config[:raise_timeout_errors] = true
+ r = Resolv.new([Resolv::DNS.new(config)])
+ assert_raise(Resolv::ResolvError) { r.getaddresses('www.google.com') }
+ end
end