[bind10-dev] DNS message API: the message class

JINMEI Tatuya / 神明達哉 jinmei at isc.org
Thu Oct 8 07:46:24 UTC 2009


At Wed, 07 Oct 2009 14:24:59 +0200,
Jelte Jansen <jelte at isc.org> wrote:

> - - the Rdata classes had me quite confused at first; these seemed
> to be containing RRs rather than rdata fields. However reading your
> description it does in fact contain all rdata fields for one
> resource record within the RRset, right?

That's right.  Here I've followed the data model adopted by BIND9 and
dnspython.  The main reason for defining "rdata" as a separate class
is because we'd like to use an "RRset" (as defined in RFC2181) as a
minimal unit of various operations, including manipulation of a DNS
message or getting access to a "data source" (which is a BIND10
terminology and is normally called a "database").  Since an RRset
consists of one ore more RRs for the same class/type/TTL, it would be
more reasonable to define a notion of "rdata" and let an RRset contain
a list of one ore more "rdata"s.

(In the experimental code I also defined the "RdataSet" class as in
BIND9 and dnspython, but I'm currently feeling it may not be a good
abstraction and thinking about removing it.  So, please forget it at
this moment.)

An alternative approach is to define an "RR" class as a minimal unit.
ldns, dnsruby, and the Net::DNS perl module adopt this model.  IMO
this is not necessarily a bad idea, and is actually more
intuitive/convenient to use for DNS-related application programmers
because an RR is indeed a minimal unit of a DNS message.  But if we
use RRs as a primary data structure, we'd have to converting a set of
RRs into an RRset in many cases (we'll need a notion of RRset anyway
if we want to support DNSSEC), making sure that they have the same
TTL.  Having multiple RRs as an RRset will also be a waste of memory
because class/type/TTL are the same (although we may be able to
mitigate this problem if we can have them as shared instances).

Note: even though the current prototype version adopts the
RRset-centric approach, I'm not intending to consider it a fixed
decision.  I'm certainly biased in the design comparison (because I'm
so familiarized with the BIND9 implementation), so I'm happy to hear
other opinions.

> Am i correct in assuming that we will be writing (possibly static)
> functions for the specific rdata fields (like an int32 rdata field,
> or a domainname rdata field), which will then be reused by all Rdata
> classes that need them?

I'd first like to note that this is a common question whether we use
"Rdata" or "RR".

Second, this is actually an open issue.  I'd personally prefer
providing per RR-type accessors, that is,

- if rdata is an instance of "A Rdata" class, rdata.get_address()
  returns an IPv4 address.
- if rdata is an instance of "AAAA Rdata" class, rdata.get_address()
  returns an IPv6 address.
- if rdata is an instance of "NS Rdata" class, rdata.get_nsname()
  returns (probably a reference to) an instance of DNS name, which
  represents the name server's name.
- if rdata is an instance of "SOA Rdata" class, rdata.get_serial()
  returns a 32-bit integer representing the SOA's serial number.
etc...

Of course, in theory this approach has a scalability issue because we
can have up to 65536 RR types, some of which may contain multiple
fields.  In practice, however, the number of standard types is much
smaller than the maximum, and will still be relatively small
throughout the lifetime of BIND10 (am I optimistic?).

I guess what you indicated above is something like this:

We have a common "get_uint32()" member function for all subclasses of
"Rdata", and if (e.g.) rdata is an instance of "SOA Rdata" class and
we want to get its "serial" field, we'd do:

  rdata.get_uint32(3); // returning the 3rd field of the rdata as 32bit int
  (get_uint32() is redefined in the SOA Rdata class so that it can
  identify the position of the specified field)

Am I understanding you correctly?  If so, this would be more scalable
than the first approach.  But, IMO, this is not a user/programmer
friendly in that the user needs to know more details of the rdata
format.

BIND9/dnspython/dnsruby/Net::DNS all adopt the first approach; ldns
takes the second approach.  Considering pros and cons of both ways,
I'm currently preferring the first way, but I'm open to other
suggestions.

(Another technical issue of the first approach: since C++ is a
stricter-typed language the implementation of the first approach would
be tricker than in python or ruby).

> Still, RdataClass and RdataType could be named better imo
> 
> - - personal opinion, ignore; our naming convenctions make the Rdata class names
> ugly (ARdata, AAAARdata) :p

Naming things is one of many fields where I'm not good:-)  If you have
specific suggestions I'm happy to hear that.  In particular I don't
like xxxRdata either.  Regarding this one, since we should
differentiate class-specific types in some way, we might use
namespaces as part of class name:

class ISC::DNS::RDATA::IN::A;
class ISC::DNS::RDATA::CH::A;
class ISC::DNS::RDATA::IN::AAAA;
class ISC::DNS::RDATA::ANY::NS;
class ISC::DNS::RDATA::ANY::DNSKEY;
etc.

Are these better?  (An obvious downside is these look lengthy)

---
JINMEI, Tatuya



More information about the bind10-dev mailing list