Patch - for resolv.rb to support mDNS "cache flush" bit

mDNS uses the high-bit of the CLASS of a resource record to store a
"cache flush" bit.

This is DNS-incompatible, of course, but note only 2 bits of the 16
CLASS bits are used so far, and classes other than "1" (internet) are
rarely seen. It is unlikely that DNS will be needing the next thousands
of values anytime soon.

Functional requirements for mDNS are:

1 - have the cache flush bit not be considered when choosing a Class to
    decode the rdata

2 - be able to retrieve the saved cache flush bit later

A way of doing this with a small set of changes to resolv.rb is:

Index: resolv.rb

···

===================================================================
RCS file: /src/ruby/lib/resolv.rb,v
retrieving revision 1.17.2.9
diff -u -r1.17.2.9 resolv.rb
--- resolv.rb 5 Feb 2005 18:31:20 -0000 1.17.2.9
+++ resolv.rb 6 Feb 2005 22:32:59 -0000
@@ -1322,8 +1322,10 @@
         def get_rr
           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)}
+ typeclass = Resource.get_class(type, klass % 0x8000)
+ data = self.get_length16 {typeclass.decode_rdata(self)}
+ data.instance_variable_set(:@cacheflush, true) if (klass >> 15) == 1
+ return name, ttl, data
         end
       end
     end

Another way would be to add

   class Resource
     attr_accessor :cacheflush
     ...

and use the attribute rather than #instance_variable_set. This is less
"weird", but instance_variable_set is more backwards compatible (i.e.,
if the bit isn't set (DNS' case) then no extra attributes exist in the
resource data class).

Thoughts please?

Thank you,
Sam

Example packet:

require 'resolv.rb'
require 'pp'

class Resolv
  class DNS
    class Name

    # NOTE - could #inspect be added to Name? An array of labels every
    # time I do a 'pp' is making output much harder to read than
    # necessary.
      def inspect
        to_s + (absolute? ? '.' : '')
      end
    end
  end
end

data1 = "\000\000\204\000\000\000\000\002\000\000\000\001\010ensemble\005_http\004_tcp\005local\000\000!\200\001\000\000\000<\000\021\000\000\000\000\000P\010ensemble\300 \300\f\000\020\200\001\000\000\000<\000\001\000\3007\000\001\200\001\000\000\000<\000\004\300\250{\232"

msg = Resolv::DNS::Message.decode(data1)

pp msg