From 2bb96458e7da360b82519745e607bfa89ae00dc4 Mon Sep 17 00:00:00 2001 From: akr Date: Fri, 29 Oct 2010 21:01:53 +0000 Subject: * 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 --- lib/resolv.rb | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'lib/resolv.rb') 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) -- cgit v1.2.3