summaryrefslogtreecommitdiff
path: root/lib/resolv.rb
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-10-29 21:01:53 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-10-29 21:01:53 +0000
commit2bb96458e7da360b82519745e607bfa89ae00dc4 (patch)
treedadc12ed90886587ba94a7dfa60080e8e0c87ecc /lib/resolv.rb
parent340bb04efe438e10a972c3d159451636b69ead1e (diff)
* lib/resolv.rb: retry via TCP if UDP reply is truncated.
fixed by Julian Mehnle. [ruby-core:32407] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/resolv.rb')
-rw-r--r--lib/resolv.rb23
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/resolv.rb b/lib/resolv.rb
index 590a26bcf5..f706d7037d 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -492,7 +492,7 @@ class Resolv
def each_resource(name, typeclass, &proc)
lazy_initialize
- requester = make_requester
+ requester = make_udp_requester
senders = {}
begin
@config.resolv(name) {|candidate, tout, nameserver, port|
@@ -506,7 +506,19 @@ class Resolv
reply, reply_name = requester.request(sender, tout)
case reply.rcode
when RCode::NoError
- extract_resources(reply, reply_name, typeclass, &proc)
+ if reply.tc == 1 and not Requester::TCP === requester
+ requester.close
+ # Retry via TCP:
+ requester = make_tcp_requester
+ senders = {}
+ # This will use TCP for all remaining candidates (assuming the
+ # current candidate does not already respond successfully via
+ # TCP). This makes sense because we already know the full
+ # response will not fit in an untruncated UDP packet.
+ redo
+ else
+ extract_resources(reply, reply_name, typeclass, &proc)
+ end
return
when RCode::NXDomain
raise Config::NXDomain.new(reply_name.to_s)
@@ -519,7 +531,7 @@ class Resolv
end
end
- def make_requester # :nodoc:
+ def make_udp_requester # :nodoc:
nameserver_port = @config.nameserver_port
if nameserver_port.length == 1
Requester::ConnectedUDP.new(*nameserver_port[0])
@@ -528,6 +540,11 @@ class Resolv
end
end
+ def make_tcp_requester # :nodoc:
+ nameserver_port = @config.nameserver_port
+ return Requester::TCP.new(*nameserver_port[0])
+ end
+
def extract_resources(msg, name, typeclass) # :nodoc:
if typeclass < Resource::ANY
n0 = Name.create(name)