The patch is for ruby-1.7.2.2002.07.15:
- it fixes the TCP Requester, even if not directly used by the DNS class,
  some programs may want to use it (for example to perform tests on a DNS
  server)
- add fields 'aa' (authoritative anwser), 'ttl', and 'rec' (recursive) to
  the Resource class, so that people using Resolv::DNS#getresources
  can easily access (without redefining several internal methods) the context
  in which the Resource is to be used (for example a program may want to
  consider differently the address of a host, if the anwser was emitted
  from an authoritative server or not). But these 3 fields are more 
  informative and are not taken into account for Resource comparison.
  
can someone commit this patch, if everybody agree of course.


--- /usr/local/lib/ruby/1.7/resolv.rb   Fri Jul 19 19:37:07 2002
+++ resolv.rb   Mon Jul 22 00:17:58 2002
@@ -651,35 +651,44 @@
           super()
           @host = host
           @port = port
-          @sock = TCPSocket.new
-          @sock.connect(host, port)
-          @sock.fcntl(Fcntl::F_SETFD, 1)
           @id = -1
           @senders = {}
-          @thread = Thread.new {
-           DNSThreadGroup.add Thread.current
-            loop {
-              len = @sock.read(2).unpack('n')
-              reply = @sock.read(len)
-              msg = begin
-                Message.decode(reply)
-              rescue DecodeError
-                STDERR.print("DNS message decoding error: #{reply.inspect}")
-                next
-              end
-              if s = @senders[msg.id]
-                s.push msg
-              else
-                #STDERR.print("non-handled DNS message: #{msg.inspect}")
-              end
-            }
-          }
-        end
+         @sock = nil
+         @mutex = Mutex.new
+       end
+
+       def lazy_initialize
+         @mutex.synchronize {
+           if @sock.nil?
+             @sock = TCPSocket.new(@host, @port)
+             @sock.fcntl(Fcntl::F_SETFD, 1)
+             @thread = Thread.new {
+               DNSThreadGroup.add Thread.current
+               loop {
+                 len = @sock.read(2).unpack('n')[0]
+                 reply = @sock.read(len)
+                 msg = begin
+                   Message.decode(reply)
+                 rescue DecodeError
+                   STDERR.print("DNS message decoding error: #{reply.inspect}")
+                   next
+                 end
+                 if s = @senders[msg.id]
+                   s.recv msg
+                 else
+                   #STDERR.print("non-handled DNS message: #{msg.inspect}")
+                 end
+               }
+             }
+           end
+         }
+       end
 
         def sender(msg, data, queue, host=@host, port=@port)
           unless host == @host && port == @port
             raise RequestError.new("host/port don't match: #{host}:#{port}")
           end
+         lazy_initialize
           id = Thread.exclusive { @id = (@id + 1) & 0xffff }
           request = msg.encode
           request[0,2] = [request.length, id].pack('nn')
@@ -688,7 +697,7 @@
 
         class Sender < Requester::Sender
           def send
-            @sock.print(@msg)
+            @sock.write(@msg)
             @sock.flush
           end
         end
@@ -978,6 +987,8 @@
       end
 
       def add_answer(name, ttl, data)
+       data.aa  = @aa != 0 ? true : false
+       data.rec = @ra != 0 ? true : false
         @answer << [Name.create(name), ttl, data]
       end
 
@@ -988,6 +999,8 @@
       end
 
       def add_authority(name, ttl, data)
+       data.aa  = @aa != 0 ? true : false
+       data.rec = @ra != 0 ? true : false
         @authority << [Name.create(name), ttl, data]
       end
 
@@ -998,6 +1011,8 @@
       end
 
       def add_additional(name, ttl, data)
+       data.aa  = @aa != 0 ? true : false
+       data.rec = @ra != 0 ? true : false
         @additional << [Name.create(name), ttl, data]
       end
 
@@ -1232,7 +1247,9 @@
           name = self.get_name
           type, klass, ttl = self.get_unpack('nnN')
           typeclass = Resource.get_class(type, klass)
-          return name, ttl, self.get_length16 {typeclass.decode_rdata(self)}
+         data = self.get_length16 {typeclass.decode_rdata(self)}
+         data.ttl = ttl
+          return name, ttl, data
         end
       end
     end
@@ -1250,6 +1267,9 @@
     class Resource < Query
       ClassHash = {}
 
+      attr_reader :ttl, :aa, :rec
+      attr_writer :ttl, :aa, :rec
+
       def encode_rdata(msg)
         raise NotImplementedError.new
       end
@@ -1259,10 +1279,23 @@
       end
 
       def ==(other)
-        return self.type == other.type &&
-          self.instance_variables == other.instance_variables &&
-          self.instance_variables.collect {|name| self.instance_eval name} ==
-            other.instance_variables.collect {|name| other.instance_eval name}
+       return false unless self.type == other.type
+       siv = self.instance_variables.delete_if {|n| 
+         case n
+         when "ttl", "aa", "rec" then true
+         else false
+         end 
+       }
+       oiv = other.instance_variables.delete_if {|n| 
+         case n
+         when "ttl", "aa", "rec" then true
+         else false
+         end 
+       }
+       
+       return siv == oiv &&
+         siv.collect {|name| self.instance_eval name} ==
+         oiv.collect {|name| other.instance_eval name}
       end
 
       def eql?(other)