Appendix A. Backends in detail

This appendix lists several of the available backends in more detail

A.1. PipeBackend

Table A-1. PipeBackend capabilities

NativeYes
MasterNo
SlaveNo
SuperslaveNo
AutoserialNo
CaseDepends
Module namepipe
Launch namepipe

The PipeBackend allows for easy dynamic resolution based on a 'Coprocess' which can be written in any programming language that can read a question on standard input and answer on standard output.

Note

The Pipe Backend currently does not function under FreeBSD 4.x and 5.x, probably due to unfavorable interactions between its threading implementation and the fork system call.

Interestingly, the Linux PowerDNS binary running under the Linuxulator on FreeBSD does work.

To configure, the following settings are available:

pipe-command

Command to launch as backend. Mandatory.

pipe-timeout

Number of milliseconds to wait for an answer from the backend. If this time is ever exceeded, the backend is declared dead and a new process is spawned. Available since 2.7.

pipe-regex

If set, only questions matching this regular expression are even sent to the backend. This makes sure that most of PowerDNS does not slow down if you you reploy a slow backend. A query for the A record of 'www.powerdns.com' would be presented to the regex as 'www.powerdns.com;A'. A matching regex would be '^www.powerdns.com;.*$'.

To match only ANY and A queries for www.powerdns.com, use '^www.powerdns.com;(A|ANY)$'. Available since 2.8.

pipebackend-abi-version

This is the version of the question format that is sent to the co-process (pipe-command) for the pipe backend.

If not set the default pipebackend-abi-version is 1. When set to 2, the local-ip-address field is added after the remote-ip-address. (the local-ip-address refers to the IP address the question was received on)

A.1.1. PipeBackend protocol

Questions come in over a file descriptor, by default standard input. Answers are sent out over another file descriptor, standard output by default.

A.1.1.1. Handshake

PowerDNS sends out 'HELO\t1', indicating that it wants to speak the protocol as defined in this document, version 1. A PowerDNS CoProcess must then send out a banner, prefixed by 'OK\t', indicating it launched successfully. If it does not support the indicated version, it should respond with FAIL, but not exit. Suggested behaviour is to try and read a further line, and wait to be terminated.

A.1.1.2. Questions

Questions come in three forms and are prefixed by a tag indicating the kind:

Q

Regular queries

AXFR

List requests, which mean that an entire zone should be listed

PING

Check if the coprocess is functioning

The question format: pipebackend-abi-version = 1 [default]
type	qname		qclass	qtype	id	remote-ip-address
pipebackend-abi-version = 2
type	qname		qclass	qtype	id	remote-ip-address	local-ip-address
Fields are tab separated, and terminated with a single \n. The remote-ip-address is the IP address of the nameserver asking the question; the local-ip-address is the IP address on which the question was received. Type is the tag above, qname is the domain the question is about. qclass is always 'IN' currently, denoting an INternet question. qtype is the kind of information desired, the record type, like A, CNAME or AAAA. id can be specified to help your backend find an answer if the id is already known from an earlier query. You can ignore it. remote-ip-address is the ip-address of the nameserver asking the question. local-ip-address is the ip-address that was querried locally.

A.1.1.3. Answers

Each answer starts with a tag, possibly followed by a TAB and more data.

DATA

Indicating a successful line of DATA

END

Indicating the end of an answer - no further data

FAIL

Indicating a lookup failure. Also serves as 'END'. No further data.

LOG

For specifying things that should be logged. Can only be sent after a query and before an END line. After the tab, the message to be logged

So letting it be known that there is no data consists if sending 'END' without anything else. The answer format:
DATA	qname		qclass	qtype	ttl	id	content	
'content' is as specified in Chapter 17. A sample dialogue may look like this:
Q	www.ds9a.nl	IN	CNAME	-1	213.244.168.210
DATA	www.ds9a.nl	IN	CNAME	3600	1 ws1.ds9a.nl
Q	ws1.ds9a.nl	IN	CNAME	-1	213.244.168.210
END
Q	wd1.ds9a.nl	IN	A	-1	213.244.168.210
DATA	ws1.ds9a.nl	IN	A	3600	1	1.2.3.4
DATA	ws1.ds9a.nl	IN	A	3600	1	1.2.3.5
DATA	ws1.ds9a.nl	IN	A	3600	1	1.2.3.6
END
This would correspond to a remote webserver 213.244.168.210 wanting to resolve the IP address of www.ds9a.nl, and PowerDNS traversing the CNAMEs to find the IP addresses of ws1.ds9a.nl Another dialogue might be:
Q	ds9a.nl		IN	SOA	-1	213.244.168.210
DATA	ds9a.nl		IN	SOA	86400	1 ahu.ds9a.nl ...
END
AXFR	1
DATA	ds9a.nl		IN	SOA	86400	1 ahu.ds9a.nl ...
DATA	ds9a.nl		IN	NS	86400	1 ns1.ds9a.nl
DATA	ds9a.nl		IN	NS	86400	1 ns2.ds9a.nl
DATA	ns1.ds9a.nl	IN	A	86400	1 213.244.168.210
DATA	ns2.ds9a.nl	IN	A	86400	1 63.123.33.135
.
.
END
This is a typical zone transfer.

A.1.1.4. Sample perl backend

#!/usr/bin/perl -w
# sample PowerDNS Coprocess backend
#

use strict;


$|=1;					# no buffering

my $line=<>;
chomp($line);

unless($line eq "HELO\t1") {
	print "FAIL\n";
	print STDERR "Recevied '$line'\n";
	<>;
	exit;
}
print "OK	Sample backend firing up\n";	# print our banner

while(<>)
{
	print STDERR "$$ Received: $_";
	chomp();
	my @arr=split(/\t/);
	if(@arr<6) {
		print "LOG	PowerDNS sent unparseable line\n";
		print "FAIL\n";
		next;
	}

	my ($type,$qname,$qclass,$qtype,$id,$ip)=split(/\t/);

	if(($qtype eq "A" || $qtype eq "ANY") && $qname eq "webserver.example.com") {
		print STDERR "$$ Sent A records\n";
		print "DATA	$qname	$qclass	A	3600	-1	1.2.3.4\n";
		print "DATA	$qname	$qclass	A	3600	-1	1.2.3.5\n";
		print "DATA	$qname	$qclass	A	3600	-1	1.2.3.6\n";
	}
	elsif(($qtype eq "CNAME" || $qtype eq "ANY") && $qname eq "www.example.com") {
		print STDERR "$$ Sent CNAME records\n";
		print "DATA	$qname	$qclass	CNAME	3600	-1	webserver.example.com\n";
	}
	elsif($qtype eq "MBOXFW") {
		print STDERR "$$ Sent MBOXFW records\n";
		print "DATA	$qname	$qclass	MBOXFW	3600	-1	powerdns\@example.com\n";
	}


	print STDERR "$$ End of data\n";
	print "END\n";
}