[bind10-dev] DNS packet API: the name object

JINMEI Tatuya / 神明達哉 jinmei at isc.org
Thu Aug 6 21:58:46 UTC 2009


This is an initial design proposal for the (DNS) "name" object (class)
as part of the "DNS packet API".  I've also written some incomplete
prototype implementation of the API as a proof of concept.  I'm
attaching the header file for those who are rather interested in code
than textual description.  I also plan to commit .cc files to the svn
repository for reference once I get an access to it.

I've done some research into existing libraries/tools: BIND9's libdns,
NLnet Lab's ldns, perl Net::DNS, and dnspython.  The design of libdns
and dnspython are quite similar (not so surprisingly, as the author of
dnspython was involved in the original BIND9 development).  Net::DNS
doesn't support a notion of "names" explicitly.  ldns handles DNS
names as part of a generic data structure (ldns_struct_rdf) and
doesn't support so many operations on names (like counting labels,
concatenating two names, etc) as far as I can see.

The general API design of libdns and dnspython seems reasonable to me,
so I basically followed the design in this initial proposal.
Furthermore, libdns's implementation is (unlike other part of BIND9)
rather straightforward, so I think we could reuse its implementation
as a backend of the new API.  In fact, I've quickly implemented some
of the new APIs by porting libdns's name.c to C++ and found it
workable.

Here is a summary of the new "Name" class:
- constructed from a string (e.g. "www.example.com")
- supported methods:
  + conversion: to_string()
  + transformation: split(), concatenate()
  + properties: is_wildcard(), is_absolute(), countlabels()
  + comparison: fullcompare(), ==, !=, <=, >=, <, >

Other design choices:
- for conversion and transformation, it generally returns a new
  object.  For example, to_string() returns a new (std::)string object
  representing the name as string.  This will be convenient for the
  API user (unlike BIND9's libdns) in that the caller doesn't have to
  prepare the new object beforehand.  Also, since all dynamically
  allocated data is encapsulated, we don't have to worry about
  resource leak (too much).
- one possible concern with this approach is that it may tend to
  require data copy more frequently than other approaches (such as
  pointer/reference-based design) and may cause non-negligible
  performance penalty.  This may be a non-issue in practice, however,
  if the underlying containers are carefully designed/implemented
  (e.g., multiple instances of std::string can share the actual data,
  making copies cheaper).  In any case, we'll eventually need to do
  benchmark.
- the fullcompare() method is similar to libdns's
  dns_name_fullcompare(), but returns an abstract "result" object,
  encapsulating the comparison result, ordering as an integer, and the
  number of common labels.  dns_name_fullcompare() took pointers to
  integers as arguments for the latter two, but I believe returning a
  single result is more intuitive for the API user.
- in general, error cases trigger C++ exceptions, rather than an error
  code as a return value.  I know this is a controversial design
  decision and I'm not sticking to this approach.  I'm open to other
  suggestions on this.

The following is a sample test code using this API:

int
main()
{
	Name n("www.jinmei.org");
	Name ncap("WWW.JINMEI.ORG");
	Name n2("www.isc.org");

	cout << n << endl;	// should be "www.jinmei.org"
	cout << (n == ncap) << endl; // should be 1
	cout << (n != n2) << endl;   // should be 1

	try {
		Name invalidlabel("012345678901234567890123456789"
				  "0123456789012345678901234567890123456789");
		cout << invalidlabel << endl; // shouldn't reach here
	} catch (const DNSLabelTooLong &e) {
		cout << "caught label-too-long exception" << endl;
	}

	return (0);
}

The output of this program is as follows:
% ./dnsname-test
www.jinmei.org
1
1
caught label-too-long exception

---
JINMEI, Tatuya
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dnsname.hh
Type: application/octet-stream
Size: 3115 bytes
Desc: not available
URL: <https://lists.isc.org/pipermail/bind10-dev/attachments/20090806/e744a991/attachment.obj>


More information about the bind10-dev mailing list