NAME

Config::TinyDNS - Manipulate tinydns' data file

SYNOPSIS

use Config::TinyDNS qw/filter_tdns_data/;

my $data = File::Slurp::read_file(...);
$data = filter_tdns_data $data, qw/include vars lresolv/;

DESCRIPTION

Tinydns, the DNS server in Dan Bernstein's djbdns package, uses a simple line-based format instead of a zone file. The format was designed to be easy for machines to parse, so it sometimes requires rather a lot of repetition. This module provides functions for manipulating these files, however it is primarily intended as the backend for tinydns-filter(1).

The general principle of operation is that the file is split into records and fields, these records are passed through a series of filters, and the results joined back up into a config file. The basic file format is line-based, with each line consisting of a single-character operator followed by a number of colon-separated arguments. For more details on the format, see tinydns-data(8).

FUNCTIONS

split_tdns_data STRING

Breaks the provided string up into a list of arrayrefs. Each arrayref represents a line of the input; each line is broken into the initial single-character operator and the subsequent colon-separated fields. Trailing blank fields are removed. Blank lines are removed. Comments are not broken up into fields.

For example, an input of

+foo.com:1.2.3.4:
Idynamic/bar.org
# some:comment

would produce a data structure like

["+", "foo.com", "1.2.3.4"],
["I", "dynamic/bar.org"],
["#", " some:comment"],

join_tdns_data LIST

Join the result of "split_tdns_data" back up into a single string. Undef fields are silently rendered as blanks. Trailing empty fields are removed.

filter_tdns_data STRING, FILTERS

Break STRING up using "split_tdns_data", pass it through a series of filters, and join it up again with "join_tdns_data". FILTERS should be a list of the following:

  • a CODE ref

    The coderef will be called once for each line of input. C$_> will be set to the initial single character and the arguments in @_ will be the remaining fields. The return value should be a list of arrayrefs as from "split_tdns_data". A simple filter that changes nothing looks like

    sub { return [$_, @_] }
  • a plain string

    This requests a filter registered with "register_tdns_filter". See "FILTERS" below for a list of the predefined filters.

  • an ARRAY ref

    The first argument will be looked up as a registered filter. If this is a generator-type filter (see below), the generator will be called with the rest of the contents of the arrayref as arguments.

register_tdns_filters LIST

Register filters to be called by name later. LIST should be a list of key => value pairs, where each value is either

  • a CODE ref

    The coderef will be called as though it had been supplied to filter_tdns_data directly. Any arguments passed (using an arrayref) will be ignored.

  • a ref to a CODE ref

    For example

    record => \sub {
        my %vars;
        sub {
            /\$/ or return [$_, @_];
            $vars{$_[0]} = $_[1];
        };
    },

    The coderef will be called once when filter_tdns_data is called, and the return value will be used as the filter sub. Any arguments supplied will be passed to the generator sub.

FILTERS

Many of these filters introduce ordering constraints on the lines of the file. Be careful about re-ordering files written for them.

null

Pass all lines through unchanged. Note that blank lines and trailing blank fields will still be removed.

vars

Input lines of the form

$name:value

are treated as variable definitions and removed from the output. Variables may have any name, but only those matching \w+ are useful. Expressions looking like /\$\w+/ will be substituted across all fields, including in variable definitions. This allows a form of symref, use of which should be discouraged. Variables must be defined before they are used; nonexistent variables will be silently replaced with the empty string. Dollars can be escaped by doubling them.

$foo:foo.com
=$foo:1.2.3.4
+www.$foo:1.2.3.4
"txt.$foo:this $$ is a dollar

translates to

=foo.com:1.2.3.4
+www.foo.com:1.2.3.4
"txt.foo.com:this $ is a dollar

include

This interprets lines of the form

Isome/file

as a request to include the contents of some/file at this point. The included lines are scanned for further includes but are not passed through any other filters (though this may change at some point).

lresolv

Resolve hostnames in IP-address slots in the configuration using the information in this file. Names must be defined before they will be translated. Currently only the + = . & @ lines used by tinydns-data(1) are recognised. If you want to run both lresolv and "rresolv", you need to run lresolv first or local hostnames will already have been replaced.

For example

=foo.com:1.2.3.4
+www.foo.com:foo.com

would translate to

=foo.com:1.2.3.4
+www.foo.com:1.2.3.4

rresolv

Resolve hostnames in IP-address slots in the configuration by looking them up in the current DNS. This assumes anything which doesn't match /[0-9.]*/ is a hostname, and any hostname that doesn't resolve is replaced with 0.0.0.0. Currently this only recognises the standard +=.&@ lines.

site SITES

This adds an extra field to % lines, so they look like

%lo:ipprefix:site

If site is in the list of SITES provided, the site field will be removed and the line left in the output. Otherwise, the line will be removed entirely. This makes it possible to build data files for several different views on the DNS from one master file.

SEE ALSO

tinydns-filter(1), tinydns-data(8).

AUTHOR

Ben Morrow <ben@morrow.me.uk>

COPYRIGHT

Copyright 2010 Ben Morrow.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BEN MORROW BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.