[getdns-api] An Object Oriented API

Phillip Hallam-Baker hallam
Wed Jan 30 18:25:50 CET 2013


Hello all.

I have been working on a DNS Interface library for .NET because I need one
and there wasn't a good one. Comodo has agreed to make the code open source
under an MIT license and it should start appearing in Sourceforge once I
get to a stable state.


We really need two new APIs, a low level interface to the DNS and a high
level interface to the Internet name service. These are not the same thing.
The low level interface should simply serve up records. The high level
interface should build in understanding of the record semantics like MX and
SRV.

The low level interface is merely a tool to allow us to get to a point
where we can support a call such as:

Stream Connection = Broker.Connect ( "http", "google.com" )

Only with the Connect call doing all the interpretation of DNS data (and
other data sources like cached client side HSTS data) to return the
cleanest, best secure channel to the service.

For applications like SMTP we would have the opposite call to allow the
service to filter incoming connection requests in a sensible fashion.



The implementation of the DNS API is generated using a code synthesizer for
DNS records. I have a file that defines the wire format and presentation
form of every DNS RR ever defined and these are grouped into sets (Current,
Obsolete, Security, Experimental). The generator is also open source so the
developer can generate code to parse only the records they actually need.

It is currently targeting C# but the plan is to add C. Java might be added
but it would be a low priority.

My view is that for a project like this you either work with a modern
object oriented framework like C# or you write in C. but the generator can
be targeted at pretty much anything.


Working in an object oriented approach results in a rather different style
of API.

To set up a DNS client context you create an instance of the DNS class:

            DNS DNS = new DNS(ServerIP);

Since this is C# the API supplies a bunch of convenience constructors that
allow the caller to specify multiple DNS server IP addresses or no address
and default to the system default DNS server etc.

The caller can set the client context to resolve in various ways (Sub,
Recursive, Validate)

The caller can also add in callbacks for tasks such as checking a DNSSEC
Trust anchor, etc. This allows DLV type trust anchors to be used. We can
also add in a caching callback


There is a convenience function to construct a request:
            DNSRequest DNSRequest = new DNSRequest (Domain, QType);

Making the call to the service raises the issue of synchronous vs
asynchronous calling patterns. We need both which is the reason I prefer to
have a separate request structure. If you are writing single threaded code
then you probably don't want the DNS API to block. But when you are writing
code that is already threaded it is actually easier to use a blocking call:

            DNSResponse DNSResponse;
            DNS.Query (DNSRequest, out DNSResponse);

DNSResponse is of course a class that exposes the whole DNS message as .NET
types. There is a DNS class defined for each record with accessors for all
the type data and methods for encoding/decoding the wire and presentation
formats.


Translating this API back into C yields an API that I think is easier to
follow that the one currently on the table and more importantly rather
easier to extend and adapt. There would be a DNSContext structure that is
essentially equivalent to the DNS class and that would be where features
like the retry interval, resolution mode, etc, etc, would be set up.

C types are much closer to DNS wire format than C# classes. But I would
still not want to manipulate the wireline format directly.


My plan for the C incarnation of the API was to have something like the
following:

typedef struct _DNSRecord {
    // header stuff

    short  RType;
    union {
         DNSRecord_A  A;
         DNSRecord_NS NS;
         ....
         } DNSRecord;

There would then be a function DNS_EncodeRecord that would be generated
from the record type definition file.


Again, whether having support for every DNS record ever defined is going to
depend on the application. A dig like tool or a DNS server needs to be able
to handle every record type ever defined and deal with both the wireline
and the presentation format. A client implementation is only going to need
the record types that the caller actually uses and only the decode
accessors.

Using the synthesizer allows both approaches to be supported. The C version
could even include preprocessor flags to allow individual record types or
groups of record types to be enabled or disabled.

-- 
Website: http://hallambaker.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vpnc.org/pipermail/getdns-api/attachments/20130130/86744717/attachment.html>



More information about the spec mailing list