api level docs?

Aaron Aston aaston at gotwisted.com
Mon Jun 7 17:33:23 UTC 2004


> >
> >One of my requirements is that we maintain only a single dns
> >'database'.  
> >
> I'm not exactly sure what the requirement *means*, but it sounds pretty 
> unreasonable to me. After all, no matter how you implement it, by 
> definition split DNS means that the "database" that is visible to the 
> outside is going to be different from the "database" that is visible to 
> the inside, so right there you have more than one "database" right? What 
> *exactly* is your requirement? 

We have one nameserver with a set of configuration and zone files that
we consider to be our master.  We would like to maintain those files
*only*, without having to hand edit files on other servers.  At the
end of this game I'd like to have a script/program that will parse our
master set of config/zone files and produce all other sets that are
required (at present, one set, namely the 'external' view of the
data).
 
> >In particular, I need to strip out resource records which are
> >'internal'.
> >
> How do you know that a record is "internal"? Is there something about 
> that name that makes it obvious? If so, why don't you go the next step 
> and create a separate subzone just for internal entries, e.g. 
> internal.example.com.

I know a record is internal/external based on the IP of the associated
resource -- most of the time.  I don't want to create a separate
subzone for internal entries because it's error prone.  Some DNS admin
(me?) is going to put the resource in the wrong zone file and it won't
be published correctly as a result.

> 
> By the way, how do you propose to handle the in-zone references to your 
> own nameservers? Are those entries considered "internal"? If you strip 
> them out, then you end up with a zone with no NS records, or 
> unresolvable NS records. That won't work. Or, do your external 
> nameservers respond on the same IP addresses as your internal 
> nameservers? If that's the case, I can't see how you're going to make 
> split DNS work in the absence of views. Or, are you going to have 
> *different* nameserver references in your internal and external DNS? If 
> that's the case, you've violated your own "single DNS database" 
> requirement. I'm not sure you've thought this through...
> 
er ... I can't make sense of that yet, I think you may have hit on
something but I can't see it yet.


> >The concensus seems to be that the best way to parse BIND zone files
> >is to use the BIND C-libaries.  This makes a certain amount of sense
> >-- BIND knows how to parse it's one files, so use BIND to parse BIND
> >files :).
> >
> I don't quite catch your drift here. Are you saying you want to hack the 
> BIND 9 source to read zone files in a "special" way? If so, then it 
> doesn't really matter whether parsing routine(s) are in a "C-library" or 
> not; they could just as easily be in the core code. Or, did you intend 
> to write a standalone utility that (to paraphrase what you said above) 
> "... strip[s] out resource records which are 'internal'", and writes out 
> the stripped version of the zonefile for the "external" instance to read 
> in normally? Doesn't that violate your "one zonefile per zone" 
> requirement? In any case, rather than write a standalone utility, why 
> not just use Perl, or sed, or awk, or some other text-processing utility 
> to do this, as other posters have suggested?

I'm just writing a utility that parses existing zone files and
generates new zone files with resource records removed.  Yes this
gives me multiple 'databases', but only one source database which is
considered master.  If you update DNS, you update the master and then
re-run the utility to produce the external views.

I'm not using perl/sed/awk/whatsit because then I have to work out all
of the details for parsing BIND zone files -- BIND already knows how
to do it, so I'll just use those same libraries.

> 
> FYI, the main BIND 9 routine that parses zone files, is the "load()" 
> routine in lib/dns/master.c. It doesn't really lend itself to standalone 
> operation, as far as I can see, since it calls a whole bunch of other 
> BIND 9 routines to do its work.

I'm calling dns_db_load(), then I'm using iterators to iterate over
node, rdataset, and rdata structures.  This code is all present in the
contributed code that uploads zone files to a PGSQL database.  After
removing the PGSQL stuff, I have a utility that walks though any BIND
zone file that I ask it to, without having to write parsing code. 
Assuming the BIND interfaces do not change, I will never have to know
details about how to parse a BIND zone file.

> Why did you hack zonetodb.c? You realize, hopefully, that this is not 
> part of the BIND 9 "C-library", but rather a utility to suck in a 
> zonefile and populate a PostgreSQL table with the data? It's part of the 
> overall PostgreSQL "sdb" driver which allows you to use PostgreSQL as a 
> database backend to BIND 9. I don't see that this is what you want at 
> all. The output of "zonetodb" is a PostgreSQL database, not BIND 9's 
> internal structures. How does this get you closer to your goal?

zonetodb.c is essentially 'client' code -- it is a client for BIND
database (zone) files.  As I said, I ripped out the PGSQL stuff, and
am now just using the code that iterates over a zone file.

> 
> >My problem is this:  I don't really understand the source.  Where can
> >I find documentation on BIND data structures and functions?  From what
> >I have read so far, the documentation is all "in the source" ... I
> >just don't know where to start.  In particular I'd really like to know
> >what the default 'database' looks like in memory.  eg: what is a
> >'dns_rdataset' and what's in it?
> >
> I *really* don't think you want to be getting into the business of 
> translating zonefile data directly into BIND 9 internal structures. It's 
> extremely complicated stuff, and you'd basically be reinventing the 
> "load()" routine I mentioned above. If you *insist* on hacking the code 
> (and I'm trying to talk you out of that), I'd concentrate on the load() 
> routine. It's never going to be more than an ugly hack, however, unless 
> you somehow "parameterize" this filtering function through a "zone" 
> definition in named.conf and/or provide a way for the admin to call an 
> external function (e.g. Perl/sed/awk as mentioned above) to do the 
> filtering inline with the zone load. That would be quite a lot of work, 
> however...

I'm almost there ... it's not that hard.  All I need to figure out now
is how to remove a resource definition while I'm iterating.  There is
a handy library function called 'dns_db_dump()' that will let me write
the filtered db back out to disk.

To reiterate:  I'm not hacking BIND 9 source, I'm writing my own
client code using the compiled BIND libraries.  BIND is creating the
internal structures corresponding to input zone files -- I'm just
trying to iterate over the results.

This stuff should be easy, especially for a product with a lengthy
history like BIND.  I'm amazed that it's not routine.


More information about the bind-users mailing list