.@ Tony Finch – blog


tl;dr - you can use my program adns-masterfile to pre-heat a DNS cache as part of a planned failover process.

adns

One of my favourite DNS tools is GNU adns, an easy-to-use asynchronous stub resolver library.

I started using adns in 1999 when it was still very new. At that time I was working on web servers at Demon Internet. We had a daily log processing job which translated IP addresses in web access logs to host names, and this was getting close to taking more than a day to process a day of logs. I fixed this problem very nicely with adns, and my code is included as an example adns client program.

Usually when I want to do some bulk DNS queries, I end up doing a clone-and-hack of adnslogres. Although adns comes with a very capable general-purpose program called adnshost, it doesn't have any backpressure to control the number of outstanding queries. So if you try to use it for bulk queries, you will overwhelm the server with traffic and most of the queries will time out and fail. So, although my normal approach would be to massage the data with an ad-hoc Perl script so I can pipe it into a general-purpose program, with adns I usually end up writing special-purpose C programs which have their own concurrency control.

cache preheating

In our DNS server setup we use keepalived to do automatic failover of the recursive server IP addresses. I wrote about our keepalived configuration last year, explaining how we can control which servers are live, which are standby, and which are not part of the failover pool.

The basic process for config changes, patches, upgrades, etc., is to take a stanby machine out of the pool, apply the changes, test them, then shuffle the pool so the next machine can be patched. Patching all of the servers requires one blip of a few seconds for each live service address.

However, after moving a service address, the new server has a cold cache, so (from the point of view of the user) a planned failover looks like a sudden drop in DNS server performance.

It would be nice if we could pre-heat a server's cache before making it live, to minimize the impact of planned maintenance.

rndc dumpdb

BIND can be told to dump its cache, which it does in almost-standard textual DNS master file format. This is ideal source data for cache preheating: we could get one of the live servers to dump its cache, then use the dump to make lots of DNS queries against a standby server to warm it up.

The named_dump.db file uses a number of slightly awkward master file features: it omits owner names and other repeated fields when it can, and it uses () to split records across multiple lines. So it needs a bit more intelligence to parse than just extracting a field from a web log line!

lex

I hadn't used lex for years and years before last month. I had almost forgotten how handy it is, although it does have some very weird features. (Its treatment of leading whitespace is almost as special as tab characters in make files.)

But, if you have a problem whose solution involves regular expressions and a C library, it's hard to do better than lex. It makes C feel almost like a scripting language!

(According to the Jargon File, Perl was described as a "Swiss-Army chainsaw" because it is so much more powerful than Lex, which had been described as the Swiss-Army knife of Unix. I can see why!)

adns-masterfile

So last month, I used adns and lex to write a program called adns-masterfile which parses a DNS master file (in BIND named_dump.db flavour) and makes queries for all the records it can. It's a reasonably handy way for pre-heating a cache as part of a planned server swap.

I used it yesterday when I was patching and rebooting everything to deal with the glibc CVE-2015-7547 vulnerability.

performance

Our servers produce a named_dump.db file of about 5.3 million lines (175 MB). From this adns-masterfile makes about 2.6 million queries, which takes about 10 minutes with a concurrency limit of 5000.