[bind10-dev] DNS message API: resource data classes
JINMEI Tatuya / 神明達哉
jinmei at isc.org
Sun Aug 16 20:56:06 UTC 2009
This is an initial design proposal for various DNS resource data
classes. I've written a prototype header file and incomplete
implementation with a sample test program as in my previous "name"
class proposal. The header file is attached to this message for
reference. I'll commit all .hh and .cc files to the repository later.
This proposal covers the following concepts:
- RR classes
- RR types
- TTL
- resource record data (RDATA)
- rdataset (a set of RDATA with the corresponding class, type, TTL)
- RRset (name + rdataset)
- RR (name, class, type, TTL + single RDATA)
The API design generally follows the model adopted in BIND9 libdns and
dnspython, but are different in the following points:
- classes/types/TTLs are real objects, not values of basic types (such
as uint32_t for TTL)
- introduce "RR" (like ldns, Net::DNS, dnsruby). architecturally,
this may be redundant, but it will be useful for API uses. for
example, I can imagine application code that examines all RRs in a
DNS message one by one. We can implement it using rdataset, but in
that case we first go through all rdataset's, and examine all RDATA
instances of each rdataset. This is not very handy. our primary
application such as name servers probably won't use RRs for
efficiency reasons, but general purpose applications may rather want
to use RRs.
The following are a summary of the new classes:
- class RdataClass: RR classes
public methods: toText(), toValue(), ==, !=
well-known constant objects: RdataClass::IN, RdataClass::CHAOS, ...
- class RdataType: RR types
public methods: toText(), toValue(), ==, !=
well-known constant objects: RdataType::A, RdataType::AAAA, ...
- class TTL: TTLs
public methods: toText(), toValue(), ==, !=, <=, >=, <, >
(<, >, etc would be based on serial number arithmetic)
- class Rdata: abstract resource record data
public methods: getType(), toText(), fromWire(), toWire()
subclasses: concrete subclasses for specific types
ARdata, AAAARdata: has an additional method "getAddress()"
WireRdata: generic wire representation of Rdata
- class RdataSet: a set of RDATA's
public methods: addRdata(), removeRdata(), toText(), toWire(),
countRdata(), getClass(), getType(), getTTL()
getRdatalist<RdataType>()
- class RRSet: a set of RRs (or name + RdataSet)
public methods: all methods available for RdataSet + getName()
- class RR: a single resource record
public methods: toText(), getName(), getClass(), getType(), getTTL()
Additional design considerations (and open issues):
- ldns doesn't have per RR type structure such as "AAAARdata" above or
dnspython's rdata.Rdata.AAAA. It has a generic interface to
retrieve a specific rdata field (ldns_rr_rdf) and the programmer
generally handles the data RR-type independent manner. We could do
the same thing, but this approach requires the programmer to
understand and use the wire-format rdata representation. I think
it's inconvenient (e.g., to get the "minimum" field of SOA, the
programmer needs to know it's the 7th field) and we should provide a
more intuitive interface. That's why specific subclasses like
ARdata/AAAARdata are introduced.
- dnspython's rdata.from_wire() function constructs a type-specific
subclass object. This approach is simple and would work for us, but
I'm concerned about its performance impact. I'd like our API to
handle wire-format data untouched as long as possible. For example,
when a recursive server receives a response and examines it, it
would be better for the server to do minimal validity check, and
store it in the cache and/or return it to the client without doing
type-specific conversion. The WireRdata subclass is introduced
mainly for this reason.
- The getRdatalist<RdataType> method of RdataSet is a templatized
function:
template <typename T> vector<T> getRdatalist() const;
It returns a list (vector) of Rdata (of specific subclass type) of
the RdataSet. It's intended to be a convenient interface
for examining all RDATA of an rdataset (or RRset) when we have a
generic form of set. For example, if we are given a AAAA rdataset
and want to retrieve all IPv6 addresses of the corresponding RDATA,
we would do:
vector<AAAARdata> datalist = rdataset.getRdatalist<AAAARdata>();
and iterate over the datalist. The general goal is to provide an
easy programming interface for an operation like this while
maintaining RDATA in an rdataset in type-independent manner. There
may be other ways to realize this goal, and the use of templatized
function may not be the best approach. I'm open to other
suggestions.
- The fromWire() method of Rdata (and its subclasses) is not a
constructor. This is partly because if we represent wire-format
data as string we wouldn't be able to differentiate the "fromWire"
constructor from a constructor from textual string (the "name"
object had the same problem). The other reason is that this method
is used to implement the getRdatalist method (above) and it's more
convenient if this function is a normal method for this purpose
(i.e. it's a purely implementation dependent reason).
- We'll probably (definitely?) need more methods. For example, we may
need a "search" and/or "sort" method for rdataset.
- In the initial prototype implementation, RRSet is a subclass of
RdataSet as in dnspython. I found it convenient as I wrote a
prototype implementation, but I'm not sure if this is a natural
inheritance relationship from the data modeling point of view (i.e.,
can we say an RRset "is an" rdataset?). We may want to revisit it
later.
---
JINMEI, Tatuya
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rrset.hh
Type: application/octet-stream
Size: 9514 bytes
Desc: not available
URL: <https://lists.isc.org/pipermail/bind10-dev/attachments/20090816/8ea15bc1/attachment.obj>
More information about the bind10-dev
mailing list