Wednesday, February 3, 2016

Enhanced getdns data access

getdns is a modern, improved DNS API which provides ease of access to advanced DNS features, including flexible transport options, roadblock (firewall and NAT) avoidance, one-step DNSSEC validation, and a host of other features either not available elsewhere or available through a complicated programming interface that often requires detailed knowledge of DNS internals.  The API was originally specified by Paul Hoffman and is being implemented by a team from NLNet Labs, Verisign Labs, Sinodun Internet Technologies, and No Mountain software.  In addition to the C API, language bindings are also available for Python, PHP, and Node.js.

While the query interface is extremely easy-to-use for the programmer, up until the newest release the returned data could be onerous to process, with the data being represented as dictionaries, lists, and (often) bindatas, none of which are native to C, and which can require a lot of repetitive code to drill down into deeply-nested data structures.  Because of this, we've specified and implemented a new interface in which data elements can be accessed directly using a syntax similar to JSON pointers and to Unix filesystem pathnames.

For example, rather than getting individual answer records by pulling out replies_tree then looping through each reply in the list and for each of those pull out the answer and then go through that list to pull out answer data, getting the answer data is now as simple as 
getdns_dict_get_int(response, "/replies_tree/0/answer/0/type", &type);  

(to retrieve the record type).  The reduction in programmer effort and code size becomes particularly apparent when looping through lists, which you'd do by getting the list length and using snprintf to format the string containing the element to retrieve:

   (void)getdns_list_get_length(replies_tree, &nanswers);  
   for ( i = 0 ; i < (int)nanswers ; i++ ) {  
     snprintf(element, MAXELEM, "/replies_tree/%d/answer/0/type", i);  
     (void)getdns_dict_get_int(response, element, &type);  
          /* do something with the data */  
   }  
I've put up a demo program with complete code on Github, here.

By the way, another extremely handy new feature is pretty-printers for both getdns dicts and getdns lists.  If you ever find yourself scratching your head over the structure of getdns returned data, using these functions to dump the contents to your screen or to a file can be a terrific time-saver.  the functions are getdns_pretty_print_dict() and getdns_pretty_print_list().  For example, I sometimes like to use it as follows:

 printf("%s\n", getdns_pretty_print_dict(response));  

which will print a well-formatted and easy-to-read representation of the data to my screen.

We've added a number of other features not in the original specification.  Some of these provide improvements to the API itself, while others implement new DNS features and transport options.  All of these contribute to the API's appeal to those who need or want access to advanced DNS services to implement application features or as a platform for other DNS-related services.  I'll be posting more about those in the coming weeks.

No comments:

Post a Comment