<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<book>
  <bookinfo>
    <title>PowerDNS manual</title>
    <author>
      <affiliation>
        <orgname>PowerDNS BV</orgname>
        <address>
          <email>pdns.bd@powerdns.com</email>
        </address>
      </affiliation>
    </author>
    
    <PubDate>v2.9.19 $Date: 2007-04-21 11:55:54 +0200 (Sat, 21 Apr 2007) $</PubDate>
    
    <Abstract>
	<para>	
	<blockquote>
	  <LITERALLAYOUT>
	    It is a book about a Spanish guy called Manual. You should read it.
	       -- Dilbert
	  </LITERALLAYOUT>

	</blockquote>
      </para>
    </Abstract>

    
  </BookInfo>
  
  <Chapter id="powerdns">
    <Title>The PowerDNS dynamic nameserver</Title>

    <Para>
      The PowerDNS daemon is a versatile nameserver which supports a large number
      of backends. These backends can either be <link linkend="bindbackend">plain zonefiles</link> or be 
      <link linkend="pipebackend">more dynamic</link> in nature. 
    </Para>
    <Para>
      Prime examples of backends include relational databases, but also
      loadbalancing and failover algorithms. 
    </Para>
    <para>
      The company is called PowerDNS BV, the nameserver daemon is called PDNS.
    </para>

    <sect1 id="function-design"><title>Function &amp; design of PDNS</title>
      <para>
	PDNS is an authoritative only nameserver. It will answer questions about domains it knows about, 
	but will not go out on the net to resolve queries about other domains. However, it can use a 
	<link linkend="recursion">recursing backend</link> to provide that functionality. Depending 
	on your needs, this backend can either be the PowerDNS recursor or an external one.
      </para>
      <para>
	When PDNS answers a question, it comes out of the database, and can be trusted as being authoritative. There is
	no way to pollute the cache or to confuse the daemon. 
      </para>
      <para>
	PDNS has been designed to serve both the needs of small installations by being easy to setup, as well as 
	for serving very large query volumes on large numbers of domains.
      </para>
      <para>
	Another prime goal is <link linkend="security">security</link>. By the use of language features, the PDNS source code 
	is very small (in the order of  10.000 lines) which makes auditing easy. In the same way, library features have been used 
	to mitigate the risks of buffer overflows.
      </para>
      <para>
	Finally, PDNS is able to give a lot of <link linkend="monitoring">statistics</link> on its operation which is both helpful in 
	determining the scalability of an installation as well as for spotting problems.
      </para>
    </sect1>
    <sect1 id="about"><title>About this document</title>
      <para>
	If you are reading this document from disk, you may want to check <ulink url="http://doc.powerdns.com">http://doc.powerdns.com</ulink>
	for updates. The PDF version is available on <ulink url="http://doc.powerdns.com/pdf">http://doc.powerdns.com/pdf</ulink>, a text file is
	on <ulink url="http://doc.powerdns.com/txt">http://doc.powerdns.com/txt/</ulink>. 
      </para>
    </sect1>
    <sect1 id="changelog">
      <title>Release notes</title>
      <para>
	Before proceeding, it is advised to check the release notes for your PDNS version, as specified in the name of the distribution
	file.
      </para>
      <sect2 id="changelog-2-9-21"><title>PowerDNS Authoritative Server version 2.9.21</title>
	<para>
	  Released the 21st of April 2007.
	</para>
	<para>
	  This is the first release the PowerDNS Authoritative Server since the Recursor was split off to a separate product, and also marks the transfer
	  of the new technology developed specifically for the recursor, back to the authoritative server.
	</para>
	<para>
	  This move has reduced the amount of code of the Authoritative server by over 2000 lines, while improving the quality
	  of the program enormously.
	</para>
	<para>
	  However, since so much has been changed, care should be taken when deploying 2.9.21.
	</para>
	<para>
	  To signify the magnitude of the underlying improvements, the next release of the PowerDNS Authoritative Server will be called 3.0.
	</para>
	<para>
	  This release would not have been possible without large amounts of help and support from the PowerDNS Community. We specifically want to thank
	  Massimo Bandinelli of Italy's <ulink url="http://register.it">Register.it</ulink>, <ulink url="http://aaldering-ict.nl">Dave Aaldering of Aaldering ICT</ulink>, 
	  <ulink url="http://true.nl">True BV</ulink>, <ulink url="http://www.xs4all.nl">XS4ALL</ulink>, Daniel Bilik of <ulink url="http://www.neosystem.cz">Neosystem</ulink>,
	  <ulink url="http://www.easydns.com">EasyDNS</ulink>, <ulink url="http://www.siemens.com">Heinrich Ruthensteiner</ulink> of Siemens, 
	  <ulink url="http://schwer.us">Augie Schwer</ulink>, <ulink url="http://www.wikipedia.org">Mark Bergsma</ulink>, <ulink url="http://www.forfun.net">Marco Davids</ulink>,
	  <ulink url="http://www.opensuse.org">Marcus Rueckert of OpenSUSE</ulink>, Andre Muraro of <ulink url="http://www.locaweb.com.br">Locaweb</ulink>, 
	  Antony Lesuisse, <ulink url="http://www.linuxnetworks.de">Norbert Sendetzky</ulink>, <ulink url="http://www.aruba.it">Marco Chiavacci</ulink>, Christoph Haas,
	  Ralf van der Enden and Ruben Kerkhof.
	</para>
	<para>
	  Security issues:
	  <itemizedlist>
	    <listitem>
	      <para>
		The previous packet parsing and generating code contained no known bugs, but was however very lengthy and overly complex, and might have had
		security problems. The new code is 'inherently safe' because it relies on bounds-checking C++ constructs. Therefore, a move to 2.9.21 is highly
		recommended.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Pre-2.9.21, communication between master and server nameservers was not checked as rigidly as possible, possibly allowing third parties to disrupt
		but not modify such communications.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  <warning>
	    <para>
	      The 'bind1' legacy version of our BIND backend has been dropped! There should be no need to rely on this old version anymore, as the main BIND backend
	      has been very well tested recently.
	    </para>
	  </warning>
	<para>
	  Bugs:
	  <itemizedlist>
	    <listitem>
	      <para>
		Multi-part TXT records weren't supported. This has been fixed, and regression tests have been added. Code in commits C1016, C996, C994.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Email addresses with embedded dots in SOA records were not parsed correctly, nor were other embedded dots. Noted by 'Bastiaan', fixed in c1026.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		BIND backend treated the 'm' TTL modifier as 'months' and not 'minutes'. Closes Debian bug 406462. Addressed in c1026.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Our snapshots were built against a static version of PosgreSQL that was incompatible with many Linux distributions, leading to instant
		crashes on startup. Fixed in C1022 and C1023.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		CNAME referrals to child zones gave improper responses. Noted by Augie Schwer in t123, fixed in c992.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When passing a port number with the <command>recursor</command> setting, this would sometimes generate errors during additional processing. Switched off
		overly helpful additional processing for recursive queries to remove this problem. Implemented in c1031, spotted by Ralf van der Enden.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		NS to a nameserver with the name of the zone itself generated problems. Spotted by Augie Schwer, fixed in c947.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Multi-line records in the BIND backend were not always parsed correctly. Fixed in c1014.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The LOC-record had problems operating outside of the eastern hemisphere of the northern part of the world! Fixed in c1011.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Backends were compiled without multithreading preprocessor flags. As far as we can determine, this would only cause problems for the BIND backend, 
		but we cannot rule out this caused instability in other backends. Fixed in c1001.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The BIND backend was highly unstable under reloads, and leaked memory and file descriptors. 
		Thanks to Mark Bergsma and Massimo Bandinelli for respectively pointing this out to us and testing
		large amounts of patches to fix the problem. The fixes have resulted in better performance, less code, and a remarkable simplification 
		of this backend. Commits C1039, C1034, C1035, C1006, C999, C905 and previous.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		BIND backend gave convincing NXDOMAINS on unloaded zones in some cases. Spotted and fixed by Daniel Bilik in c984.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SOA records in zone transfers sometimes contained the wrong SOA TTL. Spotted by Christian Kuehn, fixed in c902.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS could get confused by very high SOA serial numbers. Spotted and fixed by Dan Billik, fixed in c626.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some versions of FreeBSD perform very strict checks on socket address sizes passed to 'connect', which could lead to problems retrieving zones over AXFR.
		Fixed in c891.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some versions of FreeBSD perform very strict checks on IPv6 socket addresses, leading to problems. Discovered by Sten Spans, fixed in c885 and c886.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IXFR requests were not logged properly. Noted by Ralf van der Enden, fixed in c990.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some NAPTR records needed an additional space character to encode correctly. Spotted by Heinrich Ruthensteiner, fixed in c1029.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Many bugs in the TCP nameserver, leading to a PowerDNS process that did not respond to TCP queries over time. Many fixes provided by
		Dan Bilik, other problems were fixed by rewriting our TCP handling code. Commits C982 and C980, C950, C924, C889, C874, C869, C685, C684.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fix crashes on the ARM processor due to alignment errors. Thanks to Sjoerd Simons. Closes Debian bug 397031. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Missing data in generic SQL backends would sometimes lead to faked SOA serial data. Spotted by Leander Lakkas from True. Fix in c866.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When receiving two quick notifications in succession, the packet cache would sometimes "process" the second one, leading PowerDNS to ignore it. Spotted by 
		Dan Bilik, fixed in c686.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Geobackend (by Mark Bergsma) did not properly override the getSOA method, breaking non-overlay operation of this fine backend. The geobackend now also
		skips '.hidden' configuration files, and now properly disregards empty configuration files. Additionally, the overlapping abilities were improved. Details
		available in c876, by Mark.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Thanks to <ulink url="http://www.easydns.com">EasyDNS</ulink>, PowerDNS now supports multiple masters per domain. For configuration
		details, see <xref linkend="slave">. Implemented in c1018, c1017.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Thanks to <ulink url="http://www.easydns.com">EasyDNS</ulink>, PowerDNS now supports the KEY record type, as well the SPF record. In c976.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added support for CERT, SSHFP, DNSKEY, DS, NSEC, RRSIG record types, as part of the move to the new DNS parsing/generating code.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Support for the AFSDB record type, as requested by 'Bastian'. Implemented in c978, closing t129.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Support for the MR record type. Implemented in c941 and c1019.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Gsqlite3 backend was added by Antony Lesuisse in c942;
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added the ability to send out light-weight root-referrals that save bandwidth yet still placate mediocre resolver implementations. Implemented in c912, 
		enable with 'root-referral=lean'.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Miscellaneous OpenDBX and LDAP backend improvements by Norbert Sendetzky. Applied in c977 and c1040.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SGML source of the documentation was cleaned up by Ruben Kerkhof in c936.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Speedups in core DNS label processing code. Implemented in c928, c654, c1020.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When communicating with master servers and encountering errors, more useful details are logged. Reported by Stefan Arentz in t137, closed by c1015.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Database errors are now logged with more details. Addressed in c1004.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_control problems are now logged more verbosely. Change in c910.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Erroneous address configuration was logged unclearly. Spotted by River Tarnell, fixed in c888.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Example configuration shipped with PowerDNS was very old. Noted by Leen Besselink, fixed in c946.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS neglected to chdir to the root when chrooted. This closes t110, fixed in c944.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Microsoft resolver had problems with responses we generated for CNAMEs pointing out of our bailiwick. Fixed in c983 and expedited by Locaweb.com.br.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Built-in webserver logs errors more verbosely. Closes t82, gixed in c991.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Queries containing '@' no longer flood the logs. Addressed in c1014.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The build process now looks for PostgreSQL in more places. Implemented in c998, closes t90.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Speedups in the BIND backend now mean large installations enjoy startup times up to 30 times faster than with the original BIND nameserver. Many thanks
		to Massimo Bandinelli.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		BIND backend now offers full support for query logging, implemented in c1026, c1029.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		BIND backend named.conf parsing is now fully case-insensitive for domain names. This closes Debian bug 406461, fixed in c1027.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IPv6 and IPv4 address parsing routines have been replaced, which should result in prettier output in some cases. c962, c1012 and others.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		5 new regression tests have been added to insure old bugs do not return.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fix small issues with very modern compilers and BOOST snapshots. Noted by Marcus Rueckert, addressed in c954, c964 c965, c1003.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-recursor-3-1-4"><title>Recursor version 3.1.4</title>
	<para>
	  Released the 13th of November 2006.
	</para>
	<para>
	  This release contains almost no new features, but consists mostly of minor and major bug fixes. It also addresses two major security issues, which makes 
	  this release a highly recommended upgrade.
	</para>
	<para>
	  Security issues:
	  <itemizedlist>
	    <listitem>
	      <para>
		Large TCP questions followed by garbage could cause the recursor to crash. This critical security issue has been assigned CVE-2006-4251, and is fixed in 
		c915. More information can be found in <xref linkend="powerdns-advisory-2006-01">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		CNAME loops with zero second TTLs could cause crashes in some conditions. These loops could be constructed by malicious parties, 
		making this issue a potential denial of service attack. This security issue has been assigned CVE-2006-4252 and is fixed by c919. 
		More information can be found in <xref linkend="powerdns-advisory-2006-02">. Many thanks to David Gavarret for helping pin down this problem.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs:
	  <itemizedlist>
	    <listitem>
	      <para>
		On certain error conditions, PowerDNS would neglect to close a socket, which might therefore eventually run out. Spotted by Stefan Schmidt, fixed in commits C892, C897, C899.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some nameservers (including PowerDNS in rare circumstances) emit a SOA record in the authority section. The recursor mistakenly interpreted this as an 
		authoritative "NXRRSET". Spotted by Bryan Seitz, fixed in c893.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		In some circumstances, PowerDNS could end up with a useless (not working, or no longer working) set of nameserver records for a domain. This release contains logic
		to invalidate such broken NSSETs, without overloading authoritative servers. This problem had previously been spotted by Bryan Seitz, 'Cerb' and Darren Gamble. 
		Invalidations of NSSETs can be plotted using the "nsset-invalidations" metric, available through <command>rec_control get</command>.
		Implemented in c896 and c901.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS could crash while dumping the cache using <command>rec_control dump-cache</command>. Reported by Wouter of WideXS and Stefan Schmidt and many others, fixed in c900.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Under rare circumstances (depleted TCP buffers), PowerDNS might send out incomplete questions to remote servers. Additionally, on big-endian systems (non-Intel and non-AMD 
		generally), sending out large TCP answers questions would not work at all, and possibly crash. Brought to our attention by David Gavarret, fixed in c903.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The recursor contained the potential for a dead-lock processing an invalid domain name. It is not known how this might be triggered, 
		but it has been observed by 'Cerb' on #powerdns. Several dead-locks where PowerDNS consumed all CPU, but did not answer questions, 
		have been reported in the past few months. These might be fixed by c904.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IPv6 'allow-from' matching had problems with the least significant bits, sometimes allowing disallowed addresses, but mostly disallowing allowed addresses. Spotted by Wouter
		from WideXS, fixed in c916.
	      </para>
	    </listitem>

	  </itemizedlist>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		PowerDNS has support to drop answers from so called 'delegation only' zones. A statistic ("dlg-only-drops") is now available to plot how often this happens. Implemented in c890.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Hint-file parameter was mistakenly named "hints-file" in the documentation. Spotted by my Marco Davids, fixed in c898.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>rec_control quit</command> should be near instantaneous now, as it no longer meticulously cleans up memory before exiting. Problem spotted by Darren Gamble, fixed in 
		c914, closing t84.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		init.d script no longer refers to the Recursor as the Authoritative Server. Spotted by Wouter of WideXS, fixed in c913.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A potentially serious warning for users of the GNU C Library version 2.5 was fixed. Spotted by Marcus Rueckert, fixed in c920.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

      <sect2 id="changelog-recursor-3-1-3"><title>Recursor version 3.1.3</title>
	<para>
	  Released the 12th of September 2006.
	</para>
	<para>
	  Compared to 3.1.2, this release again consists of a number of mostly minor bug fixes, and some slight improvements. 
	</para>
	<para>
	  Many thanks are again due to Darren Gamble who together with his team has discovered many misconfigured domains that do work 
	  with some other name servers. DNS has long been tolerant of misconfigurations, PowerDNS intends to uphold that tradition. Almost all of
	  the domains found by Darren now work as well in PowerDNS as in other name server implementations.
	</para>
	<para>
	  Thanks to some recent migrations, this release, or something very close to it, is powering over 40 million internet connections that
	  we know of. We appreciate hearing about succesful as well as unsuccesful migrations, please feel free to notify pdns.bd@powerdns.com of your 
	  experiences, good or bad.
	</para>
	<para>
	  Bug-fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		The MThread default stack size was too small, which led to problems, mostly on 64-bit platforms. This stack size is now configurable
		using the <command>stack-size</command> setting should our estimate be off. Discovered by Darren Gamble, Sten Spans and a number of others. 
		Fixed in c868.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Plug a small memory leak discovered by Kai and Darren Gamble, fixed in c870.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Switch from the excellent nedmalloc to dlmalloc, based on advice by the nedmalloc author. Nedmalloc is optimised for multithreaded
		operation, whereas the PowerDNS recursor is single threaded. The version of nedmalloc shipped contained a number of possible bugs,
		which are probably resolved by moving to dlmalloc. Some reported crashes on hitting 2G of allocated memory on 64 bit systems might 
		be solved by this switch, which should also increase performance. See c873 for details.
	      </para>
	    </listitem>
	  </itemizedlist>
        </para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		The cache is now explicitly aware of the difference between authoritative and unauthoritative data, allowing it to deal
		with some domains that have different data in the parent zone than in the authoritative zone. Patch in c867.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		No longer try to parse DNS updates as if they were queries. Discovered and fixed by Jan Gyselinck, fix in c871.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Rebalance logging priorities for less log cluttering and add IP address to a remote server error message. 
		Noticed and fixed by Jan Gyselinck (c877).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Add <command>logging-facility</command> setting, allowing syslog to send PowerDNS logging to a separate file. Added in c871.
	      </para>
	    </listitem>
	  </itemizedlist>
        </para>
      </sect2>
      <sect2 id="changelog-recursor-3-1-2"><title>Recursor version 3.1.2</title>
	<para>
	  Released Monday 26th of June 2006.
	</para>
	<para>
	  Compared to 3.1.1, this release consists almost exclusively of bug-fixes and speedups. A quick update is recommended, as some of the bugs
	  impact operators of authoritative zones on the internet. This version has been tested by some of the largest internet providers on the planet,
	  and is expected to perform well for everybody.
	</para>
	<para>
	  Many thanks are due to Darren Gamble, Stefan Schmidt and Bryan Seitz who all provided excellent feedback based on their large-scale
	  tests of the recursor.
	</para>
	<para>
	  Bug-fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		Internal authoritative server did not differentiate between 'NXDOMAIN' and 'NXRRSET', in other words, it would answer
		'no such host' when an AAAA query came in for a domain that did exist, but did not have an AAAA record. This only affects
		users with <command>auth-zones</command> configured. Discovered by Bryan Seitz, fixed in c848.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		ANY queries for hosts where nothing was present in the cache would not work. This did not cause real problems as ANY queries are 
		not reliable (by design) for anything other than debugging, but did slow down the nameserver and cause unnecessary load on remote
		nameservers. Fixed in c854.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When exceeding the configured maximum amount of TCP sessions, TCP support would break and the nameserver would waste CPU trying to accept TCP
		connections on UDP ports. Noted by Bryan Seitz, fixed in c849.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		DNS queries come in two flavours: recursion desired and non-recursion desired. The latter is not very useful for a recursor, but is 
		sometimes (erroneously) used by monitoring software or loadbalancers to detect nameserver availability. A non-rd query would not only not recurse,
		but also not query authoritative zones, which is confusing. Fixed in c847.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Non-standard DNS TCP queries, that did occur however, could drive the recursor to 100% CPU usage for extended periods of time. This did not disrupt service
		immediately, but does waste a lot of CPU, possibly exhausting resources. Discovered by Bryan Seitz, fixed in c858, which is post-3.1.2-rc1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The PowerDNS recursor did not honour the rare but standardised 'ANY' query class (normally 'ANY' refers to the query type, not class), upsetting the Wildfire
		Jabber server. Discovered and debugged by Daniel Nauck, fixed in c859, which is post-3.1.2-rc1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Everybody's favorite, when starting up under high load, a bogus line of statistics was sometimes logged. Fixed in c851.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Remove some spurious debugging output on dropping a packet by an unauthorized host. Discovered by Kai. Fixed in c854.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Misconfigured domains, with a broken nameserver in the parent zone, should now work better. Changes motivated and suggested by
		Darren Gamble. This makes PowerDNS more compliant with RFC 2181 by making it prefer authoritative data over non-authoritative data.
		Implemented in c856.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can now listen on multiple ports, using the <command>local-address</command> setting. Added in c845.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A number of speedups which should have a noticeable impact, implemented in commits C850, C852, C853, C855
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The recursor now works around an issue with the Linux kernel 2.6.8, as shipped by Debian. Fixed by Christof Meerwald in c860, which is post 3.1.2-rc1.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-recursor-3-1-1"><title>Recursor version 3.1.1</title>
	<para>
	  <warning>
	    <para> 
	      3.1.1 is identical to 3.1 except for a bug in the packet chaining code which would mainly manifest itself for IPv6 enabled Konqueror 
	      users with very fast connections to their PowerDNS installation. However, all 3.1 users are urged to upgrade to 3.1.1.
	      Many thanks to Alessandro Bono for his quick aid in solving this problem.
	    </para>
	  </warning>
	</para>
	<para>
	  Released on the 23rd of May 2006. Many thanks are due to the operators of some of the largest internet access providers in the world,
	  each having many millions of customers, who have tested the various 3.1 pre-releases for suitability. They have uncovered and helped 
	  fix bugs that could impact us all, but are only (quickly) noticeable with such vast amounts of DNS traffic.
	</para>
	<para>
	  After version 3.0.1 has proved to hold up very well under tremendous loads, 3.1 adds important new features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Ability to serve authoritative data from 'BIND' style zone files (using <command>auth-zones</command> statement).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Ability to forward domains so configured to external servers (using <command>forward-zones</command>).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Possibility of 'serving' the contents of <filename>/etc/hosts</filename> over DNS, which is very well 
		suited to simple domestic router/DNS setups. Enabled using <command>export-etc-hosts</command>.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		As recommended by recent standards documents, the PowerDNS recursor is now authoritative for RFC-1918 private IP space
		zones by default (suggested by Paul Vixie).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Full outgoing IPv6 support (off by default) with IPv6 servers getting equal treatment with IPv4, nameserver 
		addresses are chosen based on average response speed, irrespective of protocol.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Initial Windows support, including running as a service ('NET START "POWERDNS RECURSOR"'). <command>rec_channel</command> is still missing,
		the rest should work. Performance appears to be below that of the UNIX versions, this situation is expected to improve.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bug fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		No longer send out SRV and MX record priorities as zero on big-endian platforms (UltraSPARC). Discovered by Eric Sproul, fixed in c773.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SRV records need additional processing, especially in an Active Directory setting. Reported by Kenneth Marshall, fixed in c774.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The root-records were not being refreshed, which could lead to problems under inconceivable conditions. Fixed in c780.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fix resolving domain names for nameservers with multiple IP addresses, with one of these addresses being lame. Other nameserver implementations
		were also unable to resolve these domains, so not a big bug. Fixed in c780.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		For a period of 5 minutes after expiring a negative cache entry, the domain would not be re-cached negatively, leading to a lot of duplicate
		outgoing queries for this short period. This fix has raised the average cache hit rate of the recursor by a few percent. Fixed in c783.
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		Query throttling was not aggressive enough and not all sorts of queries were throttled. Implemented in c786.
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		Fix possible crash during startup when parsing empty configuration lines (c807).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fix possible crash when the first query after wiping a cache entry was for the just deleted entry. Rare in production servers. Fixed in c820.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor would send out differing TTLs when receiving a misconfigured, standards violating, RRSET with different TTLs. Implement fix as mandated by
		RFC 2181, paragraph 5.2. Reported by Stephen Harker (c819).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The <command>top-remotes</command> would list remotes duplicately, once per source port. Discovered by Jorn Ekkelenkamp, fixed in c827, which is post 3.1-pre1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Default <command>allow-from</command> allowed queries from fe80::/16, corrected to fe80::/10. Spotted by Niels Bakker, fixed in c829, which is post 3.1-pre1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		While PowerDNS blocks failing queries quickly, multiple packets could briefly be in flight for the same domain and nameserver. This situation is now
		explicitly detected and queries are chained to identical queries already in flight. Fixed in c833 and c834, post 3.1-pre1.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		ANY queries are now implemented as in other nameserver implementations, leading to a decrease in outgoing queries. The RFCs are not very 
		clear on desired behaviour, what is implemented now saves bandwidth and CPU and brings us in line with existing practice. Previously
		ANY queries were not cached by the PowerDNS recursor. Implemented in c784.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>rec_control</command> was very sparse in its error reporting, and user unfriendly as well. Reported by Erik Bos, fixed in c818 and c820.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IPv6 addresses were printed in a non-standard way, fixed in c788.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		TTLs of records are now capped at two weeks, c820.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
	      <command>allow-from</command> IPv4 netmasks now automatically work for IP4-to-IPv6 mapper IPv4 addresses, which appear when running on the wildcard 
	      <command>::</command> IPv6 address. Lack of feature noted by Marcus 'darix' Rueckert. Fixed in c826, which is post 3.1-pre1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
	      Errors before daemonizing are now also sent to syslog. Suggested by Marcus 'darix' Rueckert. Fixed in c825, which is post 3.1-pre1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When launching without any form of configured network connectivity, all root-servers would be cached as 'down' for some time. Detect this special case
		and treat it as a resource-constraint, which is not accounted against specific nameservers. Spotted by Seth Arnold, fixed in c835, which is post 3.1-pre1.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The recursor now does not allow authoritative servers to keep supplying its own NS records into perpetuity, which causes problems
		when a domain is redelegated but the old authorative servers are not updated to this effect. Noticed and explained at length by Darren 
		Gamble of Shaw Communications, addressed by c837, which is post 3.1-pre2.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some operators may want to follow RFC 2181 paragraph 5.2 and 5.4. This harms performance and does not solve any real problem,
		but does make PowerDNS more compliant. If you want this, enable <command>auth-can-lower-ttl</command>. Implemented in c838, which is
		post 3.1-pre2.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-recursor-3-0-1"><title>Recursor version 3.0.1</title>
	<para>
	  Released 25th of April 2006, <ulink url="http://www.powerdns.com/en/downloads.aspx">download</ulink>.
	</para>
	<para>
	  This release consists of nothing but tiny fixes to 3.0, including one with security implications. An upgrade is highly recommended.
	</para>
	<para>
	<itemizedlist>
	  <listitem>
	    <para>
	      Compilation used both <filename>cc</filename> and <filename>gcc</filename>, leading to the possibility of compiling with different compiler versions (c766).
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      <command>rec_control</command> would leave files named <filename>lsockXXXXXX</filename> around in the configured socket-dir. Operators
	      may wish to remove these files from  their socket-dir (often <filename>/var/run</filename>), quite a few might have accumulated already (c767).
	    </para>
	  </listitem>

	  <listitem>
	    <para>
	      Certain malformed packets could crash the recursor. As far as we can determine these packets could only lead to a crash, 
	      but as always, there are no guarantees. A quick upgrade is highly recommended (commits C760, C761). Reported by David Gavarret.
	    </para>
	  </listitem>

	  <listitem>
	    <para>
	      Recursor would not distinguish between NXDOMAIN and NXRRSET (c756). Reported and debugged by Jorn Ekkelenkamp.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Some error messages and trace logging statements were improved (commits C756, C758, C759).
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      stderr was closed during daemonizing, but not dupped to /dev/null, leading to slight chance of odd behaviour on reporting errors (c757)
	    </para>
	  </listitem>
	</itemizedlist>
	Operating system specific fixes:
	<itemizedlist>
	  <listitem>
	    <para>
	      The stock Debian sarge Linux kernel, 2.6.8, claims to support epoll but fails at runtime. The epoll self-testing code has been improved,
	      and PowerDNS will fall back to a select based multiplexer if needed (c758) Reported by Michiel van Es.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Solaris 8 compilation and runtime issues were addressed. See the README for details (c765). Reported by Juergen Georgi and Kenneth Marshall.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Solaris 10 x86_64 compilation issues were addressed (c755). Reported and debugged by Eric Sproul.
	    </para>
	  </listitem>
	</itemizedlist>
      </para>
      </sect2>
      <sect2 id="changelog-recursor-3-0"><title>Recursor version 3.0</title>
	<para>
	  Released 20th of April 2006, <ulink url="http://www.powerdns.com/en/downloads.aspx">download</ulink>.
	</para>
	<para>
	  This is the first separate release of the PowerDNS Recursor. There are many reasons for this, one of the most important ones is that 
	  previously we could only do a release when both the recursor and the authoritative nameserver were fully tested and in good shape. The split
	  allows us to release new versions when each part is ready.
	</para>
	<para>
	  Now for the real news. This version of the PowerDNS recursor powers the network access of over two million internet connections. Two large
	  access providers have been running pre-releases of 3.0 for the past few weeks and results are good. Furthermore, the various pre-releases
	  have been tested nearly non-stop with DNS traffic replayed at 3000 queries/second.
	</para>
	<para>
	  As expected, the 2 million househoulds shook out some very rare bugs. But even a rare bug happens once in a while when there are this many users.
	</para>
	<para>
	  We consider this version of the PowerDNS recursor to be the most advanced resolver publicly available. Given current levels of spam, phishing 
	  and other forms of internet crime we think no recursor should offer less than the best in spoofing protection. We urge all 
	  operators of resolvers without proper spoofing countermeasures to consider PowerDNS, as it is a Better Internet Nameserver Daemon.
	</para>
	<para>
	  A good article on DNS spoofing can be found <ulink url="http://www.securesphere.net/download/papers/dnsspoof.htm">here</ulink>. Some 
	  more information, based on a previous version of PowerDNS, can be found on the 
	  <ulink url="http://blog.netherlabs.nl/articles/2006/04/14/holy-cow-1-3-million-additional-ip-addresses-served-by-powerdns">PowerDNS development blog</ulink>.
	</para>
	<para>
	  <warning>
	    <para>
	      Because of recent DNS based denial of service attacks, running an open recursor has become a security risk. Therefore, unless configured otherwise
	      this version of PowerDNS will only listen on localhost, which means it does not resolve for hosts on your network.
	      To fix, configure the <command>local-address</command> setting with all addresses you want to listen on. Additionally, by default
	      service is restricted to RFC 1918 private IP addresses. Use <command>allow-from</command> to selectively open up the recursor
	      for your own network. See <xref linkend="recursor-settings"> for details.
	    </para>
	  </warning>
	</para>
	<para>
	  Important new features of the PowerDNS recursor 3.0:
	  <itemizedlist>
	    <listitem>
	      <para>
		Best spoofing protection and detection we know of. Not only is spoofing made harder by using a new network address for each query,
		PowerDNS detects when an attempt is made to spoof it, and temporarily ignores the data. For details, see <xref linkend="anti-spoofing">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		First nameserver to benefit from epoll/kqueue/Solaris completion ports event reporting framework, for stellar performance.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Best statistics of any recursing nameserver we know of, see <xref linkend="recursor-stats">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Last-recently-used based cache cleanup algorithm, keeping the 'best' records in memory
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		First class Solaris support, built on a 'try and buy' Sun CoolThreads T&nbsp;2000.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Full IPv6 support, implemented natively.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Access filtering, both for IPv4 and IPv6.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Experimental SMP support for nearly double performance. See <xref linkend="recursor-performance">.
	      </para>
	  </itemizedlist>
	</para>
	<para>
	  Many people helped package and test this release. Jorn Ekkelenkamp of ISP-Services helped find the '8000 SOAs' bug and spotted
	  many other oddities and <ulink url="http://www.xs4all.nl">XS4ALL</ulink> internet funded a lot of the recent development. 
	  Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz of the boost::multi_index_container was again of great help. 
	</para>
      </sect2>
      <sect2 id="changelog-2-9-20"><title>Version 2.9.20</title>
	<para>
	  Released the 15th of March 2006
	</para>
	<para>
	  Besides adding OpenDBX, this release is mostly about fixing problems and speeding up the recursor. This release has been made possible by 
	  <ulink url="http://www.xs4all.nl">XS4ALL</ulink> and <ulink url="http://true.nl">True</ulink>. Thanks!
	</para>
	<para>
	  Furthermore, we are very grateful for the help of Andrew Pinski, who hacks on gcc, and of Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz, the 
	  author of <ulink url="http://www.boost.org/libs/multi_index/doc/index.html">boost::multi_index_container</ulink>. Without their
	  near-realtime help this release would've been delayed a lot. Thanks!
	</para>
	<para>
	  Bugs fixed in the recursor:
	  <itemizedlist>
	    <listitem>
	      <para>
		Possible stability issues in the recursor on encountering errors (c532, c533) 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Memory leaks in recursor fixed (c534, c572). In a test 800 million real life DNS packets have been sent to the
		recursor, representing several days of traffic from a major ISP, memory use was high (500MB), but stable.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Prune all data in PowerDNS - previously per-nameserver and per-query performance 
		statistics were kept around forever (c535)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IPv6 additional processing was broken. Reported by Lionel Elie Mamane, who also provided a fix. The problem
		was fixed differently in the end. c562.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor did not shuffle answers since 2.9.19, leading to problems sending mail to the Hotmail servers.
		Reported in t54, fixed in c567.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		If a single nameserver had multiple IP addresses listed, PowerDNS would only use one of them. Noted by 
		Mark Martin, fixed in c570, who depends on a domain with 4 nameserver IP addresses of which 2 are broken.
	      </para>
	    </listitem>



	  </itemizedlist>
	  
	  Improvements to the recursor:
	  <itemizedlist>
	    <listitem>
	      <para>
		Commits C535, C540, C541, C542, C543, C544, C545, C547 and C548, C574 all speed up the recursor by a large factor, 
		without altering the DNS algorithm.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Move recursor to the incredible boost::multi_index_container (c580). This brings a huge improvement
		in cache pruning times.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		c549 and c550 work around gcc bug <ulink url="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24704">24704</ulink>
		if requested, which speeds up the recursor a lot, but involves a dirty hack. Enable with 
		<command>./configure --enable-gcc-skip-locking</command>. No guarantees!
	      </para>
	    </listitem>
	  </itemizedlist>
	      
	  Bugs fixed in the authoritative nameserver:
	  <itemizedlist>
	    <listitem>
	      <para>
		PowerDNS would no longer allow a '/' in domain names, fixed by c537, reported in t48.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Parameters to <command>pdns_control notify-host</command> were not checked, leading to
		possible crashes. Reported in t24, fixed in c565.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		On some compilers, processing of NAPTR records could cause the server to crash. Reported by Bernd Froemel 
		in t29, fixed in c538.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Backend errors could make the whole nameserver exit under some circumstances, notably using the LDAP backend. Fixed in c583, reported in
		t62.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Referrals were subtly broken by recent CNAME/Wildcard improvements, fixed in c539. Fix and other
		improvements sponsored by <ulink url="http://true.nl">True</ulink>. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS would try to insert records it has no knowledge about in slave zones, which did not work. Reported
		in t60, fixed in c566. A superior fix would be to implement the relevant unknown record standard.
	      </para>
	    </listitem>
	  </itemizedlist>
	  Improvements to the authoritative nameserver:
	  <itemizedlist>
	    <listitem>
	      <para>
		Pipebackend did not properly propagate the ABI version to its children, fixed in c546, reported by 
		kickdaddy@gmail.com in t45.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<ulink url="http://www.linuxnetworks.de/pdnsodbx/index.html">OpenDBX</ulink> backend added 
		(c559, c560, c561) by Norbert Sendetzky. From the website:
		<quote>
		  The OpenDBX backend enables it to fetch DNS information from every DBMS supported by the OpenDBX library 
		  and combines the power of one of the best DNS server implementations with the flexibility of the OpenDBX 
		  library.
		</quote>
		OpenDBX adds some other features like database failover. Thanks Norbert!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP fixes as reported in t37, fixed in c558, which maked <command>pdns_control notify</command>
		work.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Arjo Hooimeijer added support for soa-refresh-default, soa-retry-default, 
		soa-expire-default, which were previously hardcoded. c563 and fallout in c573 (thanks to Wolfram Schlich).
	      </para>
	    </listitem>
	  </itemizedlist>
	  Miscellaneous:
	  <itemizedlist>
	    <listitem>
	      <para>
		Fixes for g++ 4.1. Compiling with 4.1 realizes notable speedups. c568, c569.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS now reports if it is running in 32 or 64 bit mode, useful for bi-arch users that need
		to know if they are benefitting from <ulink url="http://www.amd.com">their great processor</ulink>. c571.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>dnsscope</command> compiles again, c551, c564 (FreeBSD 64-bit time_t). 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>dnsreplay_mindex</command> compiles again, fixed by c572. Its performance, and the performance of the recursor
		was improved by c559.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Build scripts were added, mostly for internal use but we know some PowerDNS users build their
		own packages too. c553, c554, c555, c556, c557.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<filename>bootstrap</filename> script was not included in release. Thanks to Stefan Arentz for noticing. Fixed in c574.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-19"><title>Version 2.9.19</title>
	<para>
	  Released 29th of October 2005.
	</para>
	<para>
	  As with other recent releases, the usage of PowerDNS appears to have skyrocketed. Informal, though strict, measurements show
	  that PowerDNS now powers around 50% of all German domains, and somewhere in the order of 10-15% of the rest of the world. Furthermore,
	  DNS is set to take a central role in connecting Voice over IP providers, with PowerDNS offering a very good feature set for these ENUM
	  deployments. PowerDNS is already powering the E164.info ENUM zone and also acts as the backend for a major VoIP provisioning platform.
	</para>
	<para>
	  Included in this release is the now complete packet parsing/generating, record parsing/generating infrastructure. Furthermore,
	  this framework is used by the recursor, hopefully making it very fast, memory efficient and robust. Many records are now processed
	  using a single line of code. This has made the recursor a lot stricter in packet parsing, you will see some error messages
	  which did not appear before. Rest assured however that these only happen for queries which have no valid answer in any case.
	</para>
	<para> 
	  Furthermore, support for DNSSEC records is available in the new infrastructure, although is should be emphasised that there is more
	  to DNSSEC than parsing records. There is no real support for DNSSEC (yet).
	</para>
	<para>
	  Additionally, the BIND Backend has been replaced by what was up to now known as the 'Bind2Backend'. Initial benchmarking appears
	  to show that this backend is faster, uses less memory and has shorter startup times. The code is also shorter.
	</para>
	<para>
	  This release fixes a number of embarassing bugs and is a recommended upgrade. 
	</para>
	<para>
	  Thanks are due to <ulink url="http://www.xs4all.nl">XS4ALL</ulink> who are supporting continuing development of PowerDNS, 
	  the fruits of which can be found in this release already. Furthermore, a remarkable number of people have helped report bugs,
	  validate solutions or have submitted entire patches. Many thanks!
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		dnsreplay now has a help message and has received further massive updates, making the code substantially faster. It turns out that dnsreplay
		is often 'heavier' than the PowerDNS process being benchmarked. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS recursor no longer prints out its queries by default as most recursor deployments have too much traffic
		for this to be useful. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS recursor is now able to read its root-hints from disk, which is useful to operate with
		alternate roots, like the <ulink url="http://www.orsn.org">Open Root Server Network</ulink>. See
		<xref linkend="built-in-recursor">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can now send out old-fashioned root-referrals when queried for domains for which it is not authoritative. Wastes some bandwidth
		but may solve incoming query floods if domains are delegated to you for which you are not authoritative, but which are queried by broken
		recursors.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS now prints out a warning when running with legacy LinuxThreads implementation instead of the high performance NPTL
		library, see <xref linkend="nptl">. c455.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A lot of superfluous calls to gettimeofday() have been removed, making PowerDNS and especially the recursor faster. Suggested by Kai.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SPF records are now supported natively. c472, closing t22.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Improved IPv6 'bound to' messages. Thanks to Niels Bakker, Wichert Akkerman and Gerty de Wolf for suggestions.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Separate graphs can now be made of IPv6 queries and answers. c485.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Out of zone additional processing is now on by default to better comply with standards. c487.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Regression tests have been expanded to deal with more record types (SRV, NAPTR, TXT, duplicate SRV).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Improved query-logging in Bindbackend, which can be used for debugging purposes.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Dropped libpcap dependency, making compilation easier
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_control now has a help message.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Add RRSIG, DNSKEY, DS and NSEC records for DNSSEC-bis to new parser infrastructure.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor now honours EDNS0 allowing it to send out larger answers. 
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>

	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Domain name validation has been made a lot stricter - it turns out PostgreSQL was interpreting some (corrupt) domain names
		as unicode. Tested and suggested by Register.com (c451).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP backend did not compile (commits C452, C453) due to partially applied patch (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Incoming zone transfers work reliably again. Fixed in c460 and beyond. And c523 - closing Debian bug 330184. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recent g++ versions exposed a mistake in the PowerDNS recursor cache pruning code, causing random crashes. Fixed in c465. Reported by 
		several Red Hat users.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS recursor, and MTasker in general, did not work on Solaris. Patch by Juergen Ilse, c471. Also moved most of PowerDNS over to
		uint32_t style typedefs, which eases compilation problems on Solaris, c477.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bindbackend2 did not properly search its include path for $INCLUDE statements. Noted by Mark Bergsma, c474.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bindbackend did not notice changed zones, this problem has been fixed by the move to Bind2.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Pipebackend did not clean up, leading to an additional pipe backend per AXFR or pdns_control reload. Discovered by Marc Jauvin, fixed by c525.
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		Bindbackend (both old and current versions) did not honour 'include' statements in <filename>named.conf</filename>
		on <command>pdns_control rediscover</command>. Noted by Marc Jauvin, fixed by c526.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone transfers were sometimes shuffled, which wastes useless time, c478.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		CNAMEs and Wildcards now work as in Bind, fixing many complaints, c487.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		NAPTR records were compressed, which would work, but was in violation of the RFC, commit 493.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		NAPTR records were not always parsed correctly from BIND zonefiles, fixed, commit 494.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Geobackend needed additional include statement to compile on more recent Linux distrbutions, commit 496.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-18"><title>Version 2.9.18</title>
	<para>
	  Released on the 16th of July 2005.
	</para>
	<para> 
	  The '8 million domains' release, which also marks the battle readiness of the PowerDNS Recursor. The latest improvements have been made possible
	  by financial support and contributions by <ulink url="http://register.com">Register.com</ulink> and
	  <ulink url="http://www.xs4all.nl/">XS4ALL</ulink>. Thanks! 
	</para>
	<para>
	  This release brings a number of new features (vastly improved recursor, Generic Oracle Support, DNS analysis and replay tools, and more) 
	  but also has a new build dependency, the <ulink url="http://www.boost.org">Boost library</ulink> (version 1.31 or higher).
	</para>
	<para>
	  Currently several big ISPs are evaluating the PowerDNS recursor for their resolving needs, some of them have switched already.
	  In the course of testing, over 350 million actual queries have been recorded and replayed, the answers turn out to be satisfactorily. 
	</para>
	<para>
	  This testing has verified that the pdns recursor, as shipped in this release, can stand up to heavy duty ISP loads 
	  (over 20000 queries/second) and in fact does so better than major other nameservers, giving more complete answers and being faster to boot.
	</para>
	<para>
	  We invite ISPs who note recursor problems to record their problematic traffic and replay it using the tools described in
	  <xref linkend="analysis"> to discover if PowerDNS does a better job, and to let us know the results.
	</para>
	<para>
	  Additionally, the bind2backend is almost ready to replace the stock bind backend. If you run with Bind zones, you are cordially invited
	  to substitute 'launch=bind2' for 'launch=bind'. This will happen automatically in 2.9.19!
	</para>
	<para>
	  In other news, the entire Wikipedia constellation now runs on PowerDNS using the Geo Backend! Thanks to Mark Bergsma
	  for keeping us updated.
	</para>
	<para>
	  There are two bugs with security implications, which only apply to installations running with the LDAP backend, or installations providing recursion
	  to a limited range of IP addresses. If any of these apply to you, an upgrade is highly advised:
	  <itemizedlist>
	    <listitem>
	      <para>
		The LDAP backend did not properly escape all queries, allowing it to fail and not answer questions. We have not investigated further risks involved,
		but we advise LDAP users to update as quickly as possible (Norbert Sendetzky, Jan de Groot)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Questions from clients denied recursion could blank out answers to clients who are allowed recursion services, temporarily. Reported by Wilco Baan.
		This would've made it possible for outsiders to blank out a domain temporarily to your users. Luckily PowerDNS would send out SERVFAIL or Refused, and
		not a denial of a domain's existence.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  General bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		TCP authoritative server would not relaunch a backend after failure (reported by Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fix backend restarting logic (reported, and fix suggested by Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Launching identical backends multiple times, with different settings, did not work. Reported by Mario Manno.
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		Master/slave queries did not honour the <command>query-local-address</command> setting. Spotted by David Levy of Register.com. 
		The fix also randomises the local port used, slightly improving security. 
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Compilation fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		Fix compile on Solaris, they define 'PC' for some reason. Reported by Eric Yiu.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS recursor would not compile on FreeBSD due to Linux specific defines, as reported in cvstrac ticket 26 (Ralf van der Enden) 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Several 64 bits issues have been fixed, especially in the Logging subsystem.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SSQLite would fail to compile on recent Debian systems (Matthijs Mohlmann)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic MySQL would not compile on 64-bit platforms.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		PowerDNS now reports stray command line arguments, like when running '--local-port 5300' instead of '--local-port=5300'. Reported by Christian Welzel.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		We now warn against erroneous logging-facility specification, ie specifying an unknown facility.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>--version</command> now outputs gcc version used, so we can tell people 2.95 is no longer supported.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Extended regression tests, moved them to the new 'sdig' tool (see below).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bind2backend is now blazingly fast, and highly memory efficient to boot. As a special bonus it can read gzipped zones directly. The '.NET' zone
		is hosted using 401MB of memory, the same size as the zone on disk.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The Pipe Backend has been improved such that it can send out different answers based on the IP address the question was received ON. See
		<xref linkend="pipebackend-protocol"> for how this changed the Pipe Backend protocol. Note that you need to set 
		<command>pipebackend-abi-version</command> to benefit from this change, existing clients are not affected. Change and documentation contributed 
		by Marc Jauvin of Register4Less.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP backend has been updated (Norbert Sendetzky).
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Recursor improvements and fixes.
	  See <xref linkend="recursion"> for details. The changes below mean that all of the caveats listed for the recursor have now been addressed.
	  <itemizedlist>
	    <listitem>
	      <para>
		After half an hour of uptime, the entire cache would be pruned for each packet, which is a tad slow. It now appears 
		the pdns recursor is among the faststest around.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Under high loads, or when unlucky, some query mthreads would get 'stuck', and show up in the statistics as eternally running queries.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Lots of redundant gettimeofday() and time() calls were removed, which has resulted in a measurable speedup. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor can now listen on several addresses simultaneously.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Now supports setuid and setgid operation to allow running as a less privileged user (Bram Vandoren)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Return code of pdns_recursor binary did not make sense (Matthijs Mohlmann and Thomas Hood)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Timeouts and errors are now split out in statistics. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Many people reported broken statistics, it turned out that no statistics were being reported if there had been no questions to base them on. 
		We now log a message to that effect.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Add <command>query-local-address</command> support, which allows the recursor to send questions from a specific IP address. Useful
		for anycast setups.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Add outgoing TCP query support and proper truncated answer support. Needed for Worldnic Denial of Service protection, which
		sends out truncated packets to force clients to connect over TCP, which prevents spoofing. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Properly truncate our own answers.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Improve our TCP answers by using writev, which is slightly friendlier to the network.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		On FreeBSD, TCP errors could cause the recursor to exit suddenly due to a SIGPIPE signal.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Maximum number of simultaneous client TCP connections can now be limited with the <command>max-tcp-clients</command> setting.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Add agressive timeouts for TCP clients to make sure resources are not wasted. Defaults to two seconds, can be
		configured with the <command>client-tcp-timeout</command> setting.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	Backend fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		SQLite backend would not slave properly (Darron Broad)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic MySQL would not compile on 64-bit platforms.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  New technology:
	  <itemizedlist>
	    <listitem>
	      <para>
		Added the new DNS parser logic, called MOADNSParser. Completely modular, every memory access checked. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		'sdig', a simple dig workalike with 'canonical' output, which is used for the regression tests. Based on the new DNS parser logic.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>dnswasher</command>, <command>dnsreplay</command> and <command>dnsscope</command>, all DNS analysis tools. See <xref linkend="analysis">
		for more details.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic Oracle Backend, sponsored by Register.COM. See <xref linkend="goracle">.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

      <sect2 id="changelog-2-9-17"><title>Version 2.9.17</title>
	<para>
	  See <ulink url="http://wiki.powerdns.com/projects/trac/timeline">the new timeline</ulink> for progress reports.
	</para>
	<para>
	  The 'million domains' release - PowerDNS has now firmly established itself as a major player with the 
	  unofficial count (ie, guesswork) now at over two million PowerDNS domains! Also, the GeoBackend has been tested
	  by a big website and may soon see wider deployment. Thanks to Mark Bergsma for spreading the word!
	</para>
	<para>
	  It is also a release with lots of changes and fixes. Take care when deploying!
	</para>
	<para>
	  Security issues:
	  <itemizedlist>
	    <listitem>
	      <para>
		PowerDNS could be temporarily DoSed using a random stream of bytes. Reported cause of this has been fixed.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Reported version can be changed, or removed - see the "version-string" setting. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Duplicate MX records are now no longer considered duplicate if their priorities differ. Some people need this feature for
		spam filtering.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bug fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		NAPTR records can now be slaved, patch by Lorens Kockum.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		GMySQL now works on Solaris
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS could be confused by questions with a %-sign in them - fixing cvstrac ticket #16 (reported by dilinger at voxel.net)
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		An authentication bug in the webserver was possibly fixed, please report if you were suffering from this. Being unable
		to authenticate to the webserver was what you would've noticed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fix for cvstrac ticket #2, PowerDNS could lose sync when sending out a very large number of notifications. Excellent bug report
		by Martin Hoffman, who also improved our original bugfix.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		Fix the oldest PowerDNS bug in existence - under some circumstances, PowerDNS would log to syslog one character at a time. 
		This was cvstrac ticket #4
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		HINFO records can now be slaved, fixing cvstrac ticket #8.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		pdns_recursor could block under some circumstances, especially in case of corrupt UDP packets. Reported by Wichert Akkerman. Fix by 
		Christopher Meer. This was cvstrac ticket #13.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		Large SOA serial numbers would sometimes be logged as a signed integer, leading to negative numbers in the log.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		PowerDNS now fully supports 32 bit SOA serial numbers (thanks to Mark Bergsma), closing cvstrac ticket #5.
	      </para>
	    </listitem>
  	    <listitem>
	      <para>
		pdns_recursor --local-address help text was wrong.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		Very devious bug - PowerDNS did not clear its cache before sending out update notifications, leading slaves
		to conclude there was no update to AXFR. Excellent debugging by mkuchar at wproduction.cz.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		Probably fixed cvstrac ticket #26, which caused pdns_recursor to fail on recent FreeBSD 5.3 systems. Please check, 
		I have no such system to test on.
	      </para>
	    </listitem>
 	    <listitem>
	      <para>
		Geobackend did not get built for Debian. 
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-16"><title>Version 2.9.16</title>
	<para>
	  The 'it must still be Friday somewhere' release. Massive number of fixes, portability improvements and
	  the new Geobackend by Mark Bergsma &amp; friends. 
	</para>
	<para>
	  New:
	  <itemizedlist>
	    <listitem>
	      <para>
		The Geobackend which makes it possible to send different answers to different IP ranges. Initial documentation
		can be found in pdns/modules/geobackend/README.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		qgen query generation tool. Nearly completely undocumented and hard to build too, it requires Boost. But very
		spiffy. Use <command>cd pdns; make qgen</command> to build it.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugfixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		The most reported bug ever was fixed. Zone2sql required the inclusion of unistd.h, except on Debian unstable.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS tried to listen on its control "pipe" which does not work. Probably harmless, but might have caused some 
		oddities.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The Packet Cache did not always set its TTL immediately, causing some packets to be inserted, even when running
		with the cache disabled (Mark Bergsma).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Valgrind found some unitialized reads, causing bogus values in the priority field when it was not needed
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Valgrind found a bug in MTasker where we used delete instead of delete[].
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SOA serials and other parameters are unsigned. 
		This means that very large SOA serial numbers would be messed up (Michel Stol, Stefano Straus)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS left its controlsocket around after exit and reported confusing errors if a socket was
		already in use.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The recursor proxy did not work on big endian systems like SPARC and some MIPS processors (Remco Post)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		We no longer dump core on processing LOC records on UltraSPARC (Andrew Mulholland supplied a testing machine)
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		MySQL can now connect to a specified port again (Chris Anderton)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When running chroot()ed and with master or slave support active, PowerDNS needs to resolve domain names 
		to find slaves. This in turn may require access to certain libraries. Previously, these needed to be available
		in the chroot directory but by forcing an initial lookup, these libraries are now loaded before the chrooting.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor was very slow after having done a larger number of queries because of the checks
		to see if a query should be throttled. This is now done using a set which is a lot faster than the previous
		full sequential scan.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The throttling code may not have throttled as much as was configured.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Yet another big LDAP update. The LDAP backend now loadbalances connections over several hosts (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Updated b.root-servers.net address in the recursor
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

      <sect2 id="changelog-2-9-15"><title>Version 2.9.15</title>
	<para>
	  This release fixes up some of the shortcomings in 2.9.14, and adds some new features too.
	</para>
	<para>
	  Bugfixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		<command>allow-recursion-override</command> was on by default, it was meant to be off.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Logging was still off in daemon mode, fixed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		debian/rules forgot to build an sqllite package 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor accidentally linked in MySQL - this was the result of an experiment with a persistent recursor cache.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The PowerDNS recursor had stability problems. It now sorts nameservers (roughly) by responsiveness. The 'roughly' part
		upset the sorting algorithm used, the speeds being sorted on changed during sorting.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The recursor now outputs the nameserver average response times in trace mode
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP compiles again.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		zone2sql can now accept <filename>-</filename> as a filename which causes it to read stdin. This allows the following 
		to work: <command>dig axfr ds9a.nl | zone2sql --gmysql --zone=- | mysql pdns</command>, which is a nice way to 
		import a zone.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		zone2sql now ignores duplicate SOA records which are identical - which also makes the above possible.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Remove libpqpp dependencies - since we now use the native C API for PostgreSQL
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
	<sect2 id="changelog-2-9-14"><title>Version 2.9.14</title>
	<para>
	  Big release with the fix for the all important 2^30 seconds problem and a lot of other news.
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		errno problems would cause compilation problems when using LDAP (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The Generic SQL backend could cause crashes on PostgreSQL when using pdns_control notify (Georg Bauer)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Debian compatible init.d script (Wichert Akkerman)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		If using the master or slave features, pdns had the notion of eternity ending in 2038, except that due
		to a thinko, eternity ended out to be the 10th of January 2004. This caused a loop to timeout immediately.
		Many thanks to Jasper Spaans for spotting the bug within five minutes.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Parts of the SOA field were not cannonicalized
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The loglevel could in fact cause nothing to be logged (Norbert Sendetzky)
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		The recursor now chooses the fastest nameserver, which causes a big speedup!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP now has different lookup models
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Cleanups, better load distribution, better exception handling, zone2ldap improvements
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The recursor was somewhat chatty about TCP connections
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PostgreSQL now only depends on the C API and not on the deprecated C++ one
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can now fully overrule external zones when doing recursion. See <xref linkend="recursion">.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-13"><title>Version 2.9.13</title>
	<para>
	  Big news! Windows is back! Our great friend Michel Stol found the time to update the PowerDNS code so it works 
	  again under windows. 
	</para>
	<para>
	  Furthermore, big thanks go out to Dell who quickly repaired my trusty <ulink url="http://ds9a.nl/dell-d800">laptop</ulink>.
	</para>
	<para>
	  His changes:
	  <itemizedlist>
	    <listitem>
	      <para>
		Generic SQLite support added
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Removed the ODBC backend, replaced it by the Generic ODBC Backend, which has all the cool configurability
		of the Generic MySQL and PostgreSQL backends.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The PowerDNS Recursor now runs as a Service. It defaults to running on port 5300, PowerDNS itself is configured
		to expect the Recursor on port 5300 now.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The PowerDNS Service is now known as 'PowerDNS' to Windows.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The Installer was redone, this time with <ulink url="http://nsis.sf.net">NSIS2</ulink>. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		General updates and fixes.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Other news:
	</para>
	<para>
	  <note>
	    <para>
	      There appears to be a problem with PowerDNS on Red Hat 7.3 with GCC 2.96 and self-compiled binaries. The symptoms are
	      that PowerDNS works on the foreground but fails as a daemon. We're working on it.
	    </para>
	    <para>
	      If you do note problems, let the list know, if you don't, please do so as well. Tell us if you use the RPM or
	      compiled yourself.
	    </para>
	    <para>
	      It is known that not compiling in MySQL support helps solve the problem, but then you don't have MySQL.
	    </para>
	  </note>
	</para>
	<para>
	  There have been a number of reports on MySQL connections being dropped on FreeBSD 4.x, which sometimes causes PowerDNS to give up and reload itself. 
	  To combat this, MySQL error messages have been improved in some places in hopes of figuring out what is up. The initial indication is 
	  that MySQL itself sometimes terminates the connection and, amazingly, that switching to a Unix domain socket instead of TCP solves
	  the problem.
	</para>
	<para>
	  Bug fixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		<command>allow-axfr-ips</command> did not work for individual IP addresses (bug &amp; fix by Norbert Sendetzky)
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>

	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Opteron support! Thanks to Jeff Davey for providing a shell on an Opteron. The fixes should
		also help PowerDNS on other platforms with a 64 bit userspace.
	      </para>
	      <para>
		Btw, the PowerDNS team has a strong desire for an Opteron :-)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor jumbles answers now. This means that you can do poor man's roundrobin
		by supplying multiple A, MX or AAAA records for a service, and get a random one on top
		each time. Interestingly, this feature appeared out of nowhere, this change was made to the 
		authoritative code but due to the wonders of code-reuse had an effect on pdns_recursor too.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Big LDAP cleanup. Support for TLS was added. Zone2LDAP also gained the ability to
		generate ldif files containing a tree or a list of entries. (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql is now somewhat clearer when reporting malformed line errors - it did not always
		include the name of the file causing a problem, especially for big installations. Problem noted
		by Thom May.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor now survives the expiration of all its root records, most often caused by prolonged
		disconnection from the net.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

    <sect2 id="changelog-2-9-12"><title>Version 2.9.12</title>
	<para> 
	 Release rich in features. Work on Verisign oddities, addition of SQLite backend, pdns_recursor maturity.
      </para>
      <para>
         New features:
      <itemizedlist>
	    <listitem>
	      <para>
		--version command (requested by Mike Benoit)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		delegation-only, a Verisign special. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic <ulink url="http://www.sqlite.org">SQLite</ulink> support, by Michel 'Who da man?' Stol. See <xref linkend="gsqlite">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		init.d script for pdns_recursor
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor now actually purges its cache, saving memory.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Slave configuration now no longer falls over when presented with a NULL master
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bindbackend2 now has supermaster support (Mark Bergsma, untested)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Answers are now shuffled! It turns out a few recursors don't do shuffling (pdns_recursor, djbdns), so we do it now. Requested by Jorn Ekkelenkamp of ISP-Services. This means that if you have
		multiple IP addresses for one host, they will be returned in differing order every once in a while.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		0.0.0.0/0 didn't use to work (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor would try to resolve IP address which to bind to, potentially causing chicken/egg problem
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		gpgsql no longer reports as gmysql (Sherwin Daganoto)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SRV would not be parsed right from disk (Christof Meerwald)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		An AXFR from a zone hosted on the LDAP backend no longer transmits all the reverse entries too (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PostgreSQL backend now does error checking. It would be a bit too trusting before.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements, cleanups:
	  <itemizedlist>
	    <listitem>
	      <para>
		PowerDNS now reports the numerical IP addresses it binds to instead of the, possibly, alphanumeric names the operator passed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Removed only-soa hackery (noticed by Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Debian packaging fixes (Wichert Akkerman)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some parameter descriptions were improved.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Cleanups by Norbert: getAuth moved to chopOff, arguments::contains massive cleanup, more.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      
      <sect2 id="changelog-2-9-11"><title>Version 2.9.11</title>	
      	<para>
	  Yet another iteration, hopefully this will be the last silly release. 
	</para>
	<para>
	  <warning>
	    <para>
	      There has been a change in behaviour whereby <command>disable-axfr</command> does what it means now! From now
	      on, setting <command>allow-axfr-ips</command> automatically disables AXFR from unmentioned subnets.
	    </para>
	  </warning>
	</para>
	<para>
	  This release enables AXFR again, <command>disable-axfr</command> did the opposite of what it claimed. Furthermore, the pdns_recursor now cleans its cache, which should save some memory in the long run. Norbert contributed some small LDAP work which should come in useful in the future.
	</para>
      </sect2>
      <sect2 id="changelog-2-9-10"><title>Version 2.9.10</title>	
	<para>
	  Small bugfixes, LDAP update. Released 3rd of July 2003. Apologies for the long delay, real life keeps interfering.
	</para>
	<para>
	  <warning>
	    <para>
	      Do not use or try to use 2.9.9, it was a botched release!
	    </para>
	  </warning>
	</para>
	<para>
	  <warning>
	    <para>
	      There has been a change in behaviour whereby <command>disable-axfr</command> does what it means now! From now
	      on, setting <command>allow-axfr-ips</command> automatically disables AXFR from unmentioned subnets.
	    </para>
	  </warning>
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		2.9.8 was prone to crash on adding additional records. Thanks to excellent debugging by PowerDNS users worldwide, the bug was found
		quickly and is in fact present in all earlier PowerDNS releases, but for some reason doesn't cause crashes there.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Notifications now jump in front of the queue of domains that need to be checked for changes, giving much greater perceived performance.
		This is needed if you have tens of thousands of slave domains and your master server is on a high latency link. Thanks to Mark Jeftovic
		of EasyDNS for suggesting this change and testing it on their platform.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Dean Mills reported that PowerDNS does confusing logging about changing GIDs and UIDs, fixed. Cosmetic only.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pdns_recursor may have logged empty lines for some users, fixed. Solution suggested by Norbert Sendetzky.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP: DNS TTLs were random values (Norbert Sendetzky, Stefan Pfetzing). New <command>ldap-default-ttl</command>
		option.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP: Now works with OpenLDAP 2.1 (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP: error handling for invalid MX records implemented (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP: better exception handling (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP: code cleanup of lookup() (Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP: added support for scoped searches (Norbert Sendetzky)
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>		
      <sect2 id="changelog-2-9-8"><title>Version 2.9.8</title>	
	<para>
	  Queen's day release! 30th of April 2003.
	</para>
	<para>
	  Added support for AIX, fixed negative SOA caching. Some other cleanups. Not a major release but enough reasons to upgrade.
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Recursor had problems expiring negatively cached entries, which wasted memory and also led to the continued non-existence of 
		hosts that since had come into existence.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The Generic SQL backends did not lowercase the names of records, which led to new records not being found by case sensitive 
		databases (notably PostgreSQL). Found by Volker Goetz.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		NS queries for zones for which we did not carry authority, but only had delegation information, had their NS records in the
		wrong section. Minor detail, but a standards violation on etheless. Spotted by Stephane Bortzmeyer.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Removed crypt.h dependency from powerldap.hh, which was a problem on some platforms (Richard Arends)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can't parse so called binary labels which we now detect and ignore, after printing a warning.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Specifying allow-axfr-ips now automatically disables AXFR for all non-mentioned addresses.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A Solaris ready init.d script is now part of the tar.gz (contributed, but I lost by whom).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added some fixes to PowerDNS can work on AIX (spotted by Markus Heimhilcher).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Norbert Sendetzky contributed <filename>zone2ldap</filename>.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Everybody's favorite compiler warning from <filename>zone2sql.cc</filename> was removed!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor now listens on TCP!
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

      <sect2 id="changelog-2-9-7"><title>Version 2.9.7</title>	
	<para>
	  Released on 2003-03-20.
	</para>
	<para>
	  This is a sweeping release in the sense of cleanup. There are some new features but mostly a lot of cleanup going on. Hiding inside is the 
	  <filename>bind2backend</filename>, the next generation of the bind backend. A work in progress. Those of you with overlapping zones,
	  as mentioned in the changelog of 2.9.6, are invited to check it out by replacing <command>launch=bind</command>
	  by <command>launch=bind2</command> and renaming all <command>bind-</command> parameters to
	  <command>bind2-</command>. Be aware that if you run with many small zones, this backend is faster, but if you run with a few large ones, it is slower. This will improve.
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Mark Bergsma contributed <command>query-local-address</command> which allows the operator to select which source address to 
		use. This is useful on servers with multiple source addresses and the operating system selecting an unintended one, leading to 
		remotes denying access.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can now perform AAAA additional processing optionally, turned on by setting <command>do-ipv6-additional-processing</command>. 
		Thanks to Stephane Bortzmeyer for pointing out the need. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bind2backend, which is almost in compliance with the new IETF AXFR-clarify (some would say 
		'redefinition') draft.
	      </para>
	      <para>
		This backend is not ready for primetime but you may want to try it if you currently have overlapping
		zones and note problems. An overlapping zone would be having "ipv6.powerdns.com" and "powerdns.com" zones
		on one server.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Zone2sql would happily try to read from a directory and not give a useful error about this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS now reports the case where it can't figure out any IP address of slave nameservers for a zone
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Removed <command>receiver-threads</command> setting which was experimental and in fact only made things worse.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		LDAP backend updates from its author Norbert Sendetzky. Reverse lookups should work now too.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		An error message about unparseable packets did not include the originating IP address (fixed by Mark Bergsma)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can now be started via path resolution while running with a guardian. Suggested by Maurice Nonnekes.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<filename>pdns_recursor</filename> moved to <filename>sbin</filename> (reported by Norbert Sendetzky)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Retuned some logger errorlevels, a lot of master/slave chatter was logged as 'Error'. Reported by Willem de Groot.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		<filename>zone2sql</filename> did not remove trailing dots in SOA records.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		ldapbackend did not include <filename>utility.hh</filename> which caused compilation problems on Solaris (reported by Remco Post)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<filename>pdns_control</filename> could leave behind remnants in case PowerDNS was not running (reported by dG)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Incoming AXFR did not work on Solaris and other big-endian systems (Willem de Groot helped debugging this long standing problem).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor could crash on convoluted CNAME loops. Thanks to Dan Faerch for delivering coredumps.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Silly 'wuh' debugging output in zone2sql and bindbackend removed (spotted by Ivo van der Wijk)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor neglected to differentiate between negative cache of NXDOMAIN and NOERROR, leading to problems
		with IPv6 enabled Windows clients. Thanks to Stuart Walsh for reporting this and testing the fix.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS set the 'aa' bit on serving NS records in a zone for which it was authoritative. Most implementations
		drop the 'aa' bit in this case and Stephane Bortzmeyer informed us of this. PowerDNS now also drops the 'aa' 
		bit in this case.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The webserver tended to fail after prolonged operation on FreeBSD, this was due to an uninitialised timeout, other platforms were lucky. Thanks to G.P. de Boer for helping debug this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		getAnswers() in dnspacket.cc could be forced to read bytes beyond the end of the packet, leading to crashes in the
		PowerDNS recursor. This is an ongoing project that needs more work. Reported by Dan Faerch, with a coredump proving the problem.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

      <sect2 id="changelog-2-9-6"><title>Version 2.9.6</title>	
	<para>
	  Two new backends - Generic ODBC (windows only) and LDAP. Furthermore, a few important bugs have been fixed which may have hampered sites seeing a lot of 
	  outgoing zonetransfers. Additionally, the pdns recursor now has 'query throttling' which is pretty cool. In short this makes sure that PowerDNS 
	  does not send out heaps of queries if a nameserver is unable to provide an answer. Many operators of authoritative setups are all too aware of 
	  recursing nameservers that hammer them for zones they don't have, PowerDNS won't do that anymore now, no matter what clients request of it.
	</para>
	<para>
	  <warning>
	    <para>
	      There is an unresolved issue with the BIND backend and 'overlapping' slave zones. So if you have 'example.com' and also have a separate 
	      slave zone called 'external.example.com', things may go wrong badly. Thanks to Christian Laursen for working with us a lot in finding
	      this issue. We hope to resolve it soon.
	    </para>
	  </warning>
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		BIND Backend now honours notifies, code to support this was accidentally left out. Thanks to Christian Laursen for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Massive speedup for those of you using the slightly deprecated MBOXFW records. Thanks to Jorn of <ulink url="http://www.ISP-Services.nl">
		  ISP Services</ulink> for helping and testing this improvement.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		$GENERATE had an off-by-one bug where it would omit the last record to be generated (Christian Laursen)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Simultaneous AXFRs may have been problematic on some backends. Thanks to Jorn of ISP-Services again for helping us resolve this issue.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added LDAP backend by Norbert Sendetzky, see <xref linkend="ldap">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added Generic ODBC backend for Windows by Michel Stol.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Simplified 'out of zone data' detection in incoming AXFR support, hopefully removing a case sensitivity bug there. Thanks again
		to Christian Laursen for reporting this issue.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		$include in-zonefile was broken under some circumstances, losing the last character of a filename. Thanks to Joris Vandalon for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The zoneparser was more case-sensitive than BIND, refusing to accept 'in' as well as 'IN'. Thanks to Joris Vandalon for noticing this.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-5"><title>Version 2.9.5</title>	
	<para>
	  Released on 2002-02-03.
	</para>
	<para>
	  This version is almost entirely about recursion with major changes to both the pdns recursor, which is renamed to 
	  '<filename>pdns_recursor</filename>' and to the main PowerDNS binary to make it interact better with the recursing component.
	</para>
	<para>
	  Sadly, due to <ulink url="http://sources.redhat.com/ml/libc-alpha/2003-01/msg00245.html">technical reasons</ulink>, compiling
	  the pdns recursor and pdns authoritative nameserver into one binary is not immediately possible. During the release of 2.9.4 we
	  stated that the recursing nameserver would be integrated in the next release - this won't happen now.
	</para>
	<para>
	  However, this turns out to not be that bad at all. The recursor can now be restarted without having to restart the rest of the nameserver,
	  for example. Cooperation between the both halves of PDNS is also almost seamless. As a result, 'non-lazy recursion' has been dropped. See
	  <xref linkend="recursion"> for more details.
	</para>
	<para>
	  Furthermore, the recursor only works on Linux, Windows and Solaris (not entirely). FreeBSD does not support the required functions.
	  If you know any important FreeBSD people, plea with them to support set/get/swapcontext! Alternatively, FreeBSD coders could read
	  the solution presented here <ulink url="http://www.eng.uwaterloo.ca/~ejones/software/threading.html">in figure 5</ulink>.
	</para>
	<para>
	  The 'Contributor of the Month' award goes to Mark Bergsma who has responded to our plea for help with the label compressor and contributed
	  a wonderfully simple and right fix that allows PDNS to compress just as well as Other namerervers out there. An honorary mention goes to
	  Ueli Heuer who, despite having no C++ experience, submitted an excellent SRV record implementation.
	</para>
	<para>
	  Excellent work was also performed by Michel Stol, the Windows guy, in fixing all our non-portable stuff again. Christof Meerwald has also done 
	  wonderful work in porting MTasker to Windows, which was then used by Michel to get the recursor functioning on Windows.
	</para>
	<para>
	  Other changes:
	  <itemizedlist>
	    <listitem>
	      <para>
		dnspacket.cc was cleaned up by factoring out common operations
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Heaps of work on the recursing nameserver. Has now achieved *days* of uptime!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursor renamed from syncres to <filename>pdns_recursor</filename>
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS can now serve records it does not know about. To benefit from this slightly undocumented feature, add
		1024 to the numerical type of a record and include the record in binary form in your database. Used internally by the
		recursing nameserver but you can use it too.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PowerDNS now knows about SIG and KEY records *names*. It does not support them yet but can at least report so now.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		HINFO records can now be transferred from a master to PowerDNS (thanks to Ueli Heuer for noticing it didn't work).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Yet more UltraSPARC alignment issues fixed (Chris Andrews).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Dropped non-lazy recursion, nobody was using it. Lazy recursion became even more lazy after Dan Bernstein pointed out that additional
		processing is not vital, so PowerDNS does its best to do additional processing on recursive queries, but does not scream murder if it does
		not succeed. Due to caching, the next identical query will be successfully additionally processed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Label compression was improved so we can now fit all . records in 436 bytes, this used to be 460! (Code &amp; formal 
		proof of correctness by Mark Bergsma).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SRV support (incoming and outgoing), submitted by Ueli Heuer.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic backends do not support SOA serial autocalculation, it appears. Could lead to random SOA serials in case 
		of a serial of 0 in the database. Fixed so that 0 stays zero in that case. Don't set the SOA serial to 0 when using 
		Generic MySQL or Generic PostgreSQL!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		J root-server address was updated to its new location.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SIGUSR1 now forces the recursor to print out statistics to the log.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Meaning of recursor logging was changed a bit - a cache hit is now a question that was answered with 0 outgoing packets needed. Used to 
		be a weighted average of internal cache hits.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		MySQL compilation did not include -lz which causes problems on some platforms. Thanks to James H. Cloos Jr for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		After a suggestion by Daniel Meyer and Florus Both, the built in webserver now reports the configuration name when multiple PowerDNS 
		instances are active.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Brad Knowles noticed that zone2sql had problems with the root.zone, fixed. This also closes some other zone2sql annoyances with converting
		single zones.
	      </para>
	    </listitem>

	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-4"><title>Version 2.9.4</title>	
	<para>
	  Yet another grand release. Big news is the addition of a recursing nameserver which has sprung into existence
	  over the past week. It is in use on several computers already but it is not ready for prime time. Complete integration
	  with PowerDNS is expected around 2.9.5, for now the recursor is a separate program. 
	</para>
	<para>
	  In preliminary tests, the recursor appears to be four times faster than BIND 9 on a naive benchmark starting from a cold cache. BIND 9
	  managed to get through to some slower nameservers however, which were given up on by PowerDNS. We will continue to tune the recursor.
	  See <xref linkend="built-in-recursor"> for further details.
	</para>
	<para>
	  The BIND Backend has also been tested (see the <command>bind-domain-status</command> item below) rather heavily by several parties. After some
	  discussion online, one of the BIND authors ventured that the newsgroup comp.protocols.dns.bind may now in fact be an appropriate venue
	  for discussing PowerDNS. Since this discussion, traffic to the PowerDNS pages has increased sixfold and shows no signs of slowing down.
	</para>
	<para>
	  From this, it is apparent that far more people are interested in PowerDNS than yet know about it. So spread the word!
	</para>
	<para>
	  In other news, we now have a security page at <xref linkend="security-policy">. Furthermore, Maurice Nonnekes contributed an OpenBSD
	  port! See <ulink url="http://www.codeninja.nl/openbsd/powerdns/">his page</ulink> for more details!
	</para>
	<para>
	  New features and improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		All SQL queries in the generic backends are now available for configuration. (Martin Klebermass/bert hubert).
		See <xref linkend="generic-mypgsql-backends">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A recursing nameserver! See <xref linkend="built-in-recursor">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		An incoming AXFR now only starts a backend zone replacement transaction after the first record arrived successfully, thus making 
		sure no work is done when a remote nameserver is unable/unwilling to AXFR a zone to us.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zoneparser error messages were improved slightly (thanks to Stef van Dessel for spotting this shortcoming)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		XS4ALL's Erik Bos checked how PowerDNS reacted to a BIND installation with almost 60.000 domains, some of which
		with >100.000 records, and he discovered the pdns_control <command>bind-domain-status</command> command
		became very slow with larger numbers of domains. Fixed, 60.000 domains are now listed in under one second.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		If a remote nameserver disconnects during an incoming AXFR, the update is now rolled back, unless the AXFR was
		properly terminated.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The migration chapter mentioned the use of deprecated backends.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  A tremendous number of bugs were discovered and fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Zone parser would only accept $include and not $INCLUDE
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone parser had problems with $lines with comments on the end
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Wildcard ANY queries were broken (thanks Colemarcus for spotting this)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A connection failure with the Generic backends would lead to a powerdns reload (cast of many)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic backends had some semantic problems with slave support. Symptoms were oft-repeated notifications
		and transfers (thanks to Mark Bergsma for helping resolve this).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Solaris version compiles again. Thanks to Mohamed Lrhazi for reporting that it didn't.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some UltraSPARC alignment fixes. Thanks to Mohamed Lrhazi for being helpful in spotting these. 
		One problem is still outstanding, Mohamed sent a core dump that tells us where the problem is. Expect the
		fix to be in 2.9.5. Volunteers can grep the source for 'UltraSPARC' to find where the problem is.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Our support of IPv6 on FreeBSD had phase of moon dependent bugs, fixed by Peter van Dijk.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some crashes of and by pdns_control were fixed, thanks to Mark Bergsma for helping resolve these.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Outgoing AXFR in pdns installations with multiple loaded backends was broken (thanks to Stuart Walsh for reporting this).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A failed BIND Backend incoming AXFR would block the zone until it succeeded again.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic PostgreSQL backend wouldn't compile with newer libpq++, fixed by Julien Lemoine/SpeedBlue.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Potential bug (not observed) when listening on multiple interfaces fixed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some typos in manpages fixed (reported by Marco Davids).
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	</sect2>

      <sect2 id="changelog-2-9-3"><title>Version 2.9.3a</title>	
	<para>
	  <note><para>2.9.3a is identical to 2.9.3 except that zone2sql does work</para></note></para>
	<para>
	  Broad range of huge improvements. We now have an all-static .rpm and .deb for Linux users and a link to an OpenBSD port.
	  Major news is that work on the Bind backend has progressed to the point that we've just retired our last Bind server and 
	  replaced it with PowerDNS in Bind mode! This server is operating a number of master and slave setups so it should stress the Bind backend 
	  somewhat.
	</para>
	<para>
	  This version is rapidly approaching the point where it is a better-Bind-than-Bind and nearly a drop-in replacement for authoritative 
	  setups. PowerDNS is now equipped with a powerful 
	  master/slave apparatus that offers a lot of insight and control to the user, even when operating from Bind zonefiles and a 
	  Bind configuration. Observe.
	</para>
	<para>
	  After the SOA of ds9a.nl was raised:
	  <screen>
pdns[17495]: All slave domains are fresh
pdns[17495]: 1 domain for which we are master needs notifications
pdns[17495]: Queued notification of domain 'ds9a.nl' to 195.193.163.3
pdns[17495]: Queued notification of domain 'ds9a.nl' to 213.156.2.1
pdns[17520]: AXFR of domain 'ds9a.nl' initiated by 195.193.163.3
pdns[17520]: AXFR of domain 'ds9a.nl' to 195.193.163.3 finished
pdns[17521]: AXFR of domain 'ds9a.nl' initiated by 213.156.2.1
pdns[17521]: AXFR of domain 'ds9a.nl' to 213.156.2.1 finished
pdns[17495]: Removed from notification list: 'ds9a.nl' to 195.193.163.3 (was acknowledged)
pdns[17495]: Removed from notification list: 'ds9a.nl' to 213.156.2.1 (was acknowledged)
pdns[17495]: No master domains need notifications
	  </screen>
	  If however our slaves would ignore us, as some are prone to do, we can send some additional notifications:
	  <screen>
$ sudo pdns_control notify ds9a.nl         
Added to queue
pdns[17492]: Notification request for domain 'ds9a.nl' received
pdns[17492]: Queued notification of domain 'ds9a.nl' to 195.193.163.3
pdns[17492]: Queued notification of domain 'ds9a.nl' to 213.156.2.1
pdns[17495]: Removed from notification list: 'ds9a.nl' to 195.193.163.3 (was acknowledged)
pdns[17495]: Removed from notification list: 'ds9a.nl' to 213.156.2.1 (was acknowledged)
	    </screen>
	  Conversely, if PowerDNS needs to be reminded to retrieve a zone from a master, a command is provided:
           <screen>
$ sudo pdns_control retrieve forfun.net
Added retrieval request for 'forfun.net' from master 212.187.98.67
pdns[17495]: AXFR started for 'forfun.net', transaction started
pdns[17495]: Zone 'forfun.net' (/var/cache/bind/forfun.net) reloaded 
pdns[17495]: AXFR done for 'forfun.net', zone committed
	  </screen>
	  Also, you can force PowerDNS to reload a zone from disk immediately with <command>pdns_control bind-reload-now</command>.
	  All this happens 'live', per your instructions. Without instructions, the right things also happen, but the operator is in charge.
	</para>
	<para>
	  For more about all this coolness, see <xref linkend="pdnscontrol"> and <xref linkend="bind-control-commands">.
	</para>
	<para>
	  <warning>
	    <para>
	      Again some changes in compilation instructions. The hybrid pgmysql backend has been split up into 'gmysql' and 'gpgsql', sharing
	      a common base within the PowerDNS server itself. This means that you can no longer compile 
	      <command>--with-modules="pgmysql" --enable-mysql --enable-pgsql</command> but that you should now use:
	      <command>--with-modules="gmysql gpgsql"</command>. The old launch-names remain available. 
	    </para>
	    <para>
	      If you launch the Generic PgSQL backend as gpgsql2, all parameters will have gpsql2 as a prefix, for example 
	      <command>pgsql2-dbname</command>. If launched as gpsql, the regular names are in effect.
	    </para>
	  </warning>
	</para>
	<para>
	  <warning>
	    <para>
	      The pdns_control protocol was changed which means that older pdns_controls cannot talk to 2.9.3. The other way around is
	      broken too. This may lead to problems with automatic upgrade scripts, so pay attention if your daemon is truly restarted.
	    </para>
	    <para>
	      Also make sure no old pdns_control command is around to confuse things.
	    </para>
	  </warning>
	</para>
	<para>
	  Improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Bind backend can now deal with missing files and try to find them later.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bind backend is now explicitly master capable and triggers the sending of notifications.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		General robustness improvements in Bind backend - many errors are now non-fatal.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Accessability, Serviceability. New <command>pdns_server</command> commands like <command>bind-list-rejects</command>
		(lists zones that could not be loaded, and the reason why), <command>bind-reload-now</command> (reload a zone from disk NOW),
		<command>rediscover</command> (reread named.conf NOW). More is coming up.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added support for retrieving RP (Responsible Person) records from remote masters. Serving them was already possible.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added support for LOC records, which encode the geographical location of a host, both serving and retrieving (thanks to Marco Davids
		using them on our last Bind server, forcing us to implement this silly record).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Configuration file parser now strips leading spaces too, allowing "chroot= /tmp" to work, as well as "chroot=/tmp" 
		(Thanks to Hub Dohmen for reporting this for months on end).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added <command>bind-domain-status</command> command that shows the status of all domains (when/if they were parsed, any errors
		encountered while parsing them).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added <command>bind-reload-now</command> command that tries to reload a zone from disk NOW, and reports back errors to the operator
		immediatly.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added <command>retrieve</command> command that queues a request to retrieve a zone from its master. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zones retrieved from masters are now stored way smaller on disk because the domain is stripped from records, which is derived
		from the configuration file. Retrieved zones are now prefixed with some information on where they came from.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Changes:
	  <itemizedlist>
	    <listitem>
	      <para>
		gpgsql and gmysql backends split out of the hybrid pgmysqlbackend. This again changed compilation instructions!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>pdns_control</command> now uses the rarely seen SOCK_STREAM Unix Domain socket variety so it can transport
		large amounts of text, which is needed for the <command>bind-domain-status</command> command, for which see
		<xref linkend="bind-control-commands">. This breaks compatability with older pdns_control and pdns_server binaries!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bind backend now ignores 'hint' and 'forward' and other unsupported zone types.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		AXFRs are now logged more heavily by default. An AXFR is a heavy operation anyhow, some more logging does not further 
		increase the load materially. Does help in clearing up what slaves are doing.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A lot of master/slave chatter has been silenced, making output more relevant. No more repetitive 'No master domains need notifications' etc, only changes are reported now.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugfixes:
	  <itemizedlist>
	    <listitem>
	      <para>
		Windows version did not compile without minor changes.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Confusing error reporting on Windows 98 (which does not support PowerDNS) fixed
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Potential crashes with shortened packets addressed. An upgrade is advised!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>notify</command> (which was already there, just badly documented) no longer prints out debugging garbage.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pgmysql backend had problems launching when not compiled in but available as a module. Workaround for 2.9.2 is 'load-modules=pgmysql', 
		but even then gpgsql would not work! gmysql would then, however. These modules are now split out, removing such issues.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9-2"><title>Version 2.9.2</title>	
	<para>
	  Bugfixes galore. Solaris porting created some issues on all platforms. Great news is that PowerDNS is now in Debian 'sid' (unstable). The 2.9.1
	  packages in there currently aren't very good but the 2.9.2 ones will be. Many thanks to Wichert Akkerman, our 'downstream' for making this possible.
	</para>
	<warning>
	  <para>
	    The Generic MySQL backend, part of the Generic MySQL &amp; PostgreSQL backend, is now the DEFAULT! The previous default, the 
	    'mysql' backend (note the lack of 'g') is now DEPRECATED. This was the source of much confusion. The 'mysql' backend
	    does not support MASTER or SLAVE operation. The Generic backends do.
	  </para>
	  <para>
	    To get back the mysql backend, add --with-modules="mysql" or --with-dynmodules="mysql" if you prefer to load your modules at runtime.
	  </para>
	</warning>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Silly debugging output removed from the webserver (found by Paul Wouters)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SEVERE: due to Solaris portability fixes, qtypes&lt;127 were broken. 
		These include NAPTR, ANY and AXFR. The upshot is that powerdns
		wasn't performing outgoing AXFRs nor ANY queries. These were the
		'question for type -1' warnings in the log
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		incoming AXFR could theoretically miss some trailing records (not observed, but could happen)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		incoming AXFR did not support TXT records (spotted by Paul Wouters)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		with some remotes, an incoming AXFR would not terminate until a
		timeout occured (observed by Paul Wouters)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Documentation bug, pgmysql != mypgsql
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Documentation:
	  <itemizedlist>
	    <listitem>
	      <para>
		Documented the 'random backend', see <xref linkend="randombackend">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Wichert Akkerman contributed three manpages.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Building PowerDNS on Unix is now documented somewhat more, see <xref linkend="on-unix">.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		pdns init.d script is now +x by default
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		OpenBSD is on its way of becoming a supported platform! As of 2.9.2, PowerDNS compiles on OpenBSD but swiftly crashes.
		Help is welcome.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		ODBC backend (for Windows only) was missing from the distribution, now added.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		xdb backend added - see <xref linkend="xdbbackend">. Designed for use by root-server operators.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Dynamic modules are back which is good news for distributors who want to make a pdns packages that does not
		depend one every database under the sun. 
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
		

      <sect2 id="changelog-2-9-1"><title>Version 2.9.1</title>	
	<para>
	  Thanks to the great enthusiasm from around the world, powerdns is now available for Solaris and FreeBSD users again! 
	  Furthermore, the Windows build is back. We are very grateful for the help of:
	</para>
	<para>	
	  <itemizedlist>
	    <listitem><para>Michel Stol</para></listitem>
	    <listitem><para>Wichert Akkerman</para></listitem>
	    <listitem><para>Edvard Tuinder</para></listitem>
	    <listitem><para>Koos van den Hout</para></listitem>
	    <listitem><para>Niels Bakker</para></listitem>
	    <listitem><para>Erik Bos</para></listitem>
	    <listitem><para>Alex Bleker</para></listitem>
	    <listitem><para>steven stillaway</para></listitem>
	    <listitem><para>Roel van der Made</para></listitem>
	    <listitem><para>Steven Van Steen</para></listitem>
	  </itemizedlist>
	</para>
	<para>
	  We are happy to have been able to work with the open source community to improve PowerDNS!
	</para>
	<para>
	  Changes:
	  <itemizedlist>
	    <listitem>
	      <para>
		The monitor command <command>set</command> no longer allows the changing of non-existant variables.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IBM Universal Database DB2 backend now included in source distribution (untested!)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Oracle backend now included in source distribution (sligthly tested!)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		configure script now searches for postgresql and mysql includes
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Bind parser now no longer dies on records with a ' in them (Erik Bos)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The pipebackend was accidentally left out of 2.9
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		FreeBSD fixes (with help from Erik Bos, Alex Bleeker, Niels Bakker)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Heap of Solaris work (with help from Edvard Tuinder, Stefan Van Steen, Koos van den Hout, Roel van der Made and 
		especially Mark Bakker).
		Now compiles in 2.7 and 2.8, haven't tried 2.9. May be a bit dysfunctional on 2.7 though - it won't do IPv6 and it won't serve AAAA. Patches
		welcome!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Windows 32 build is back! Michel Stol updated his earlier work to the current version.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		S/Linux (Linux on Sparc) build works now (with help from steven stillaway).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Silly debugging message ('sd.ttl from cache') removed
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		.debs are back, hopefully in 'sid' soon! (Wichert Akkerman)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Removal of bzero and other less portable constructs. Discovered that recent Linux glibc's need -D_GNU_SOURCE (Wichert Akkerman).	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-9"><title>Version 2.9</title>	
	<para>
	Open source release. Do not deploy unless you know what you are
doing. Stability is expected to return with 2.9.1, as are the binary builds.
	</para>
	<para>	
	  <itemizedlist>
	    <listitem>
	      <para>
		License changed to the GNU General Public License version 2.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Cleanups by Erik Bos @ xs4all.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Build improvements by Wichert Akkerman
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Lots of work on the build system, entirely revamped. By PowerDNS.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
	
      <sect2 id="changelog-2-8"><title>Version 2.8</title>	
	<para>
	  From this release onwards, we'll concentrate on stabilising for the 3.0 release. So if you have any must-have features,
	  let us know soonest. The 2.8 release fixes a bunch of small stability issues and add two new features. In the spirit of the move to 
	  stability, this release has already been running 24 hours on our servers before release. 
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		pipe backend gains the ability to restricts its invocation to a limited number of requests. This allows a very busy nameserver
		to still serve packets from a slow perl backend. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pipe backend now honors query-logging, which also documents which queries were blocked by the regex.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pipe backend now has its own backend chapter.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		An incoming AXFR timeout at the wrong moment had the ability to crash the binary, forcing a reload. Thanks to our bug spotting
		champions Mike Benoit and Simon Kirby of NetNation for reporting this.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-7"><title>Version 2.7 and 2.7.1</title>	
	<para>
	  This version fixes some very long standing issues and adds a few new features. If you are still running 2.6, upgrade yesterday. If you
	  were running 2.6.1, an upgrade is still strongly advised.
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		The controlsocket is now readable and writable by the 'setgid' user. This allows for non-root
		access to PDNS which is nice for mrtg or cricket graphs.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		MySQL backend (the non-generic one) gains the ability to read from a different table using the
		<command>mysql-table</command> setting.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		pipe backend now has a configurable timeout using the <command>pipe-timeout</command> setting. Thanks fo Steve Bromwich
		for pointing out the need for this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Experimental backtraces. If PowerDNS crashes, it will log a lot of numbers and sometimes more to the syslog.
		If you see these, please report them to us. Only available under Linux.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs:
	  <itemizedlist>
	    <listitem>
	      <para>
		2.7 briefly broke the mysql backend, so don't use it if you use that. 2.7.1 fixes this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SOA records could sometimes have the wrong TTL. Thanks to Jonas Daugaard for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		An ANY query might lead to duplicate SOA records being returned under exceptional circumstances. 
		Thanks to Jonas Daugaard for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Underlying the above bug, packet compression could sometimes suddenly be turned off, leading to
		overly large responses and non-removal of duplicate records.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The <command>allow-axfr-ips</command> setting did not accept IP ranges (1.2.3.0/24) which the 
		documentation claimed it did (thanks to Florus Both of Ascio technologies for being sufficiently persistent in reporting this).
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Killed backends were not being respawned, leading to suboptimal behaviour on intermittent database errors. Thanks to Steve Bromwich for
		reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Corrupt packets during an incoming AXFR when acting as a slave would cause a PowerDNS reload instead of just failing that AXFR. 
		Thanks to Mike Benoit and Simon Kirby of NetNation for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Label compression in incoming AXFR had problems with large offsets, causing the above mentioned errors. Thanks to Mike Benoit
		and Simon Kirby of NetNation for reporting this.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
	      
      <sect2 id="changelog-2-6-1"><title>Version 2.6.1</title>	
	<para>
	  Quick fix release for a big cache problem. 
	</para>
      </sect2>
      <sect2 id="changelog-2-6"><title>Version 2.6</title>
	<para>
	  Performance release. A lot of work has been done to raise PDNS performance to staggering levels in order to take part
	  in benchmarketing efforts. Together with our as yet unnamed partner, PDNS has been benchmarked at 60.000 mostly cached queries/second
	  on off the shelf PC hardware. Uncached performance was 17.000 uncached DNS queries/second on the .ORG domain.
	</para>
	<para>
	  Performance has been increased by both making PDNS itself quicker but also by lowering the number of backend queries typically needed. Operators
	  will typically see PDNS taking less CPU and the backend seeing less load.
	</para>
	<para>
	  Furthermore, some real bugs were fixed. A couple of undocumented performance switches may appear in --help output but you are advised to stay
	  away from these.
	</para>
	<para>
	  Developers: this version needs the pdns-2.5.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
	    http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
	</para>
	<para>
	  Performance:
	  <itemizedlist>
	    <listitem>
	      <para>
		A big error in latency calculations - cached packets were weighed 50 times less, leading to inflated latency reporting. Latency calculations
		are now correct and way lower - often in the microseconds range.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		It is now possible to run with 0 second cache TTLs. This used to cause very frequent cache cleanups, leading
		to performance degradation.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Many tiny performance improvements, removing duplicate cache key calculations, etc. The cache itself has also been reworked 
		to be more efficient.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		First 'CNAME' backend query replaced by an 'ANY' query, which most of the time returns the actual record,
		preventing the need for a separate CNAME lookup, halving query load.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Much of the same for same-level-NS records on queries needing delegation.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Incidentally, the cache count would show 'unknown' packets, which was harmless but confusing. Thanks to Mike and Simon of
		NetNation for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SOA hostmaster with a . in the local-part would be cached wrongly, leading to a stray backslash
		in case of multiple successively SOA queries. Thanks to Ascio Techologies for spotting this bug.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		zone2sql did not parse Verisign zonefiles correctly as these contained a $TTL statement in mid-record.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Sometimes packets would not be accounted, leading to 'udp-queries' and 'udp-answers' divergence.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		'cricket' command added to init.d scripts that provides unadorned output for parsing by 'Cricket'.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-5-1"><title>Version 2.5.1</title>
	<para>
	  <ulink url="http://www.tuxedo.org/~esr/jargon/html/entry/brown-paper-bag-bug.html">Brown paper bag</ulink> release fixing 
	    a huge memory leak in the new Query Cache.
	</para>
	<para>
	  Developers: this version needs the new pdns-2.5.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
	    http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
	</para>
	<para>
	  And some small changes:
	  <itemizedlist>
	    <listitem>
	      <para>
		Added support for RFC2038 compliant negative-answer caching. This allows remotes to cache the fact that 
		a domain does not exist and will not exist for a while. Thanks to Chris Thompson for <ulink url="http://ops.ietf.org/lists/namedroppers/namedroppers.2002/msg01697.html">pointing out how tiny our minds are</ulink>. This feature may cause a noticeable reduction
		in query load.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Small speedup to non-packet-cached queries, incidentally fixing the huge memory leak.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>pdns_control ccounts</command> command outputs statistics on what is in the cache, which is
		useful to help optimize your caching strategy.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-5"><title>Version 2.5</title>
	<para>
	  An important release which has seen quite a lot of trial and error testing. As a result, PDNS can now run with a huge cache
	  and concurrent invalidations. This is useful when running of a slower database or under high traffic load with a fast database.
	</para>
	<para>
	  Furthermore, the gpgsql2 backend has been validated for use and will soon supplant the gpgsql backend entirely. This also bodes 
	  well for the gmysql backend which is the same code.
	</para>
	<para>
	  Also, a large amount of issues biting large scale slave operators were addressed. Most of these issues would only show up 
	  after prolonged uptime.
	</para>
	<para>
	  New features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Query cache. The old Packet Cache only cached entire questions and their answers. This is very CPU efficient but
		does not lead to maximum hitrate. Two packets both needing to resolve smtp.you.com internally would not benefit 
		from any caching. Furthermore, many different DNS queries lead to the same backend queries, like 'SOA for .COM?'.
	      </para>
	      <para>
		PDNS now also caches backend queries, but only those having no answer (the majority) and those having one answer 
		(almost the rest). 
	      </para>
	      <para>
		In tests, these additional caches appear to halve the database backend load numerically and perhaps even more in terms
		of CPU load. Often, queries with no answer are more expensive than those having one.
	      </para>
	      <para>
		The default <command>ttl</command>s for the query-cache and negquery-cache are set to safe values (20 and 60 seconds
		respectively), you should be seeing an improvement in behaviour without sacrificing a lot in terms of quick updates.
	      </para>
	      <para>
		The webserver also displays the efficiency of the new Query Cache.
	      </para>
	      <para>
		The old Packet Cache is still there (and useful) but see <xref linkend="performance"> for more details.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		There is now the ability to shut off some logging at a very early stage. High performance sites doing thousands of 
		queries/second may in fact spend most of their CPU time on attempting to write out logging, even though it is ignored
		by syslog. The new flag <command>log-dns-details</command>, on by default, allows the operator to kill most 
		informative-only logging before it takes any cpu.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Flags which can be switched 'on' and 'off' can now also be set to 'off' instead of only to 'no' to turn them off.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Packet Cache is now case insensitive, leading to a higher hitrate because identical queries only differing in case
		now both match. Care is taken to restore the proper case in the answer sent out.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Packet Cache stores packets more efficiently now, savings are estimated at 50%. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The Packet Cache is now asynchronous which means that PDNS continues to answer questions while the cache
		is busy being purged or queried. Incidentally this will mean a cache miss where previously the question would
		wait until the cache became available again. 
	      </para>
	      <para>
		The upshot of this is that operators can call <command>pdns_control purge</command> as often as desired without
		fearing performance loss. Especially the full, non-specific, purge was speeded up tremendously. 
	      </para>
	      <para>
		This optimization is of little merit for small sites but is very important when running with a large packetcache, such
		as when using recursion under high load.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		AXFR log messages now all contain the word 'AXFR' to ease grepping.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Linux static version now compiled with gcc 3.2 which is known to output better and faster code than the previously
		used 3.0.4.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Packetcache would sometimes send packets back with slightly modified flags if these differed from the flags
		of the cached copy.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Resolver code did bad things with filedescriptors leading to fd exhaustion after prolonged uptimes and many slave
		SOA currency checks. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Resolver code failed to properly log some errors, leading to operator uncertainty regarding to AXFR problems with
		remote masters.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		After prolonged uptime, slave code would try to use privileged ports for originating queries, leading to bad
		replication efficiency.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Masters sending back answers in differing case from questions would lead to bogus 
		'Master tried to sneak in out-of-zone data' errors and failing AXFRs.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-4"><title>Version 2.4</title>
	<para>
	  Developers: this version is compatible with the pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
	    http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
	</para>
	<para>
	  This version fixes some stability issues with malformed or malcrafted packets. An upgrade is advised. Furthermore, there are interesting new 
	  features.
	</para>
	<para>
	  New features:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		Recursive queries are now also cached, but in a separate namespace so non-recursive queries don't get recursed answers and
		vice versa. This should mean way lower database load for sites running with the current default lazy-recursion. Up to now,
		each and every recursive query would lead to a large amount of SQL queries.
	      </para>
	      <para>
		To prevent the packetcache from becoming huge, a separate <command>recursive-cache-ttl</command> can be specified.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The ability to change parameters at runtime was added. Currently, only the new <command>query-logging</command> flag
		can be changed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added <command>query-logging</command> flag which hints a backend that it should output a textual representation of queries
		it receives. Currently only gmysql and gpgsql2 honor this flag.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Gmysql backend can now also talk to PgSQL, leading to less code. Currently, the old postgresql driver ('gpgsql') is still the default,
		the new driver is available as 'gpgsql2' and has the benefit that it does query logging. In the future, gpgsql2 will become the default
		gpgsql driver.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		DNS recursing proxy is now more verbose in logging odd events which may be caused by buggy recursing backends.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Webserver now displays peak queries/second 1 minute average.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Failure to connect to database in master/slave communicator thread could lead to an unclean reload, fixed.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Documentation: added details for <command>strict-rfc-axfrs</command>. This feature can be used if very old clients need to be able
	  to do zone transfers with PDNS. Very slow.
	</para>
	
      </sect2>
      <sect2 id="changelog-2-3"><title>Version 2.3</title>
	<para>
	  Developers: this version is compatible with the pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
	    http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
	</para>
	<para>
	  This release adds the Generic MySQL backend which allows full master/slave semantics with MySQL and InnoDB tables (or other tables that support
	  transactions). See <xref linkend="generic-mypgsql-backends">.
	</para>
	<para>
	  Other new features:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		Improved error messages in master/slave communicator will help down track problems.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>slave-cycle-interval</command> setting added. Very large sites with thousands of slave domains may need to raise this value
		above the default of 60. Every cycle, domains in undeterminate state are checked for their condition. Depending on the health of the masters,
		this may entail many SOA queries or attempted AXFRs.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		'pdns_control purge <userinput>domain</userinput>' and  'pdns_control purge <userinput>domain$</userinput>' were broken in version 2.2 and 
		did not in fact purge the cache. There is a slight risk that domain-specific purge commands could force a reload in previous version.
		Thanks to Mike Benoit of NetNation for discovering this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Master/slave communicator thread got confused in case of delayed answers from slow masters. While not causing harm, this caused inefficient 
		behaviour when testing large amounts of slave domains because additional 'cycles' had to pass before all domains would have their status
		ascertained. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Backends implementing special SOA semantics (currently only the undocumented 'pdns express backend', or homegrown backends) would 
		under some circumstances not answer the SOA record in case of an ANY query. This should put an end to the last DENIC problems. Thanks to
		DENIC for helping us find the problem.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-2"><title>Version 2.2</title>
	<para>
	  Developers: this version is compatible with the pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
	    http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
	</para>
	<para>
	  Again a big release. PowerDNS is seeing some larger deployments in more demanding environments and these are helping shake out remaining issues,
	  especially with recursing backends.
	</para>
	<para>
	  The big news is that wildcard CNAMEs are now supported, an oft requested feature and nearly the only part in which PDNS differed from BIND in 
	  authoritative capabilities.
	</para>
	<para>
	  If you were seeing signal 6 errors in PDNS causing reloads and intermittent service disruptions, please upgrade to this version.
	</para>
	<para>
	  For operators of PowerDNS Express trying to host .DE domains, the very special <command>soa-serial-offset</command> feature has been added
	  to placate the new DENIC requirement that the SOA serial be at least six digits. PowerDNS Express uses the SOA serial as an actual serial and 
	  not to insert dates and hence often has single digit soa serial numbers, causing big problems with .DE redelegations.
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Malformed or shortened TCP recursion queries would cause a signal 6 and a reload. Same for EOF from the TCP recursing backend.
		Thanks to Simon Kirby and Mike Benoit of NetNation for helping debug this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Timeouts on the TCP recursing backend were far too long, leading to possible exhaustion of TCP resolving threads.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>pdns_control purge domain</command> accidentally cleaned all packets with that name as a prefix. Thanks to Simon Kirby 
		for spotting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Improved exception error logging - in some circumstances PDNS would not properly log the cause of an exception, which hampered problem
		resolution.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>	
	<para>
	  New features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Wildcard CNAMEs now work as expected!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>pdns_control purge</command> can now also purge based on suffix, allowing operators to 
		purge an entire domain from the packet cache instead of only specific records. See also <xref linkend="pdnscontrol">
		Thanks to Mike Benoit for this suggestion. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>soa-serial-offset</command> for installations with small SOA serial numbers wishing to register .DE domains
		with DENIC which demands six-figure SOA serial numbers. See also <xref linkend="all-settings">.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-1"><title>Version 2.1</title>
	<para>
	  This is a somewhat bigger release due to pressing demands from customers. An upgrade is advised for installations using Recursion. 
	  If you are using recursion, it is vital that you are aware of changes in semantics. Basically, local data will now override data in your
	  recursing backend under most circumstances. Old behaviour can be restored by turning <command>lazy-recursion</command> off.
	</para>
	<para>
	  Developers: this version has a new pdns-2.1 development kit, available on <ulink url="http://downloads.powerdns.com/releases/dev">
	    http://downloads.powerdns.com/releases/dev</ulink>. See also <xref linkend="backend-writers-guide">.
	</para>
	<para>
	  <warning>
	    <para>
	      Most users will run a static version of PDNS which has no dependencies on external libraries. However, some may need to run the dynamic version.
	      This warning applies to these users.
	    </para>
	    <para>
	      To run the dynamic version of PDNS, which is needed for backend drivers which are only available in source form, gcc 3.0 is required.
	      RedHat 7.2 comes with gcc 3.0 as an optional component, RedHat 7.3 does not. However, the RedHat 7.2 Update gcc rpms install just fine
	      on RedHat 7.3. For Debian, we suggest running 'woody' and installing the g++-3.0 package. We expect to release a FreeBSD dynamic version
	      shortly.
	    </para>
	  </warning>
	</para>
	      
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		RPM releases sometimes overwrote previous configuration files. Thanks to Jorn Ekkelenkamp of Hubris/ISP Services for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		TCP recursion sent out overly large responses due to a byteorder mistake, confusing some clients.  Thanks to the capable engineers 
		of NetNation for bringing this to our attention.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		TCP recursion in combination with a recursing backend on a non-standard port did not work, leading to a
		non-functioning TCP listener. Thanks to the capable engineers of NetNation for bringing this to our attention.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Unexpected behaviour:
	  <itemizedlist>
	    <listitem>
	      <para>
		Wildcard URL records where not implemented because they are a performance penalty. To turn these on, enable 
		<command>wildcard-url</command> in the configuration.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Unlike other nameservers, local data did not override the internet for recursing queries. This has mostly been brought into conformance
		with user expectations. If a recursive question can be answered entirely from local data, it is. To restore old behaviour, disable
		<command>lazy-recursion</command>. Also see <xref linkend="recursion">.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Oracle support has been tuned, leading to the first public release of the Oracle backend. Zone2sql now outputs better SQL
		and the backend is now fully documented. Furthermore, the queries are compatible with the PowerDNS XML-RPC product, allowing 
		PowerDNS express to run off Oracle. See <xref linkend="oracle">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql now accepts --transactions to wrap zones in a transaction for PostgreSQL and Oracle output. This is a major speedup and also
		makes for better isolation of inserts. See <xref linkend="zone2sql">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>pdns_control</command> now has the ability to purge the PowerDNS cache or parts of it. This enables operators to 
		raise the TTL of the Packet Cache to huge values and only to invalidate the cache when changes are made. See also <xref linkend="performance"> and
		<xref linkend="pdnscontrol">.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-0-1"><title>Version 2.0.1</title>
	<para>
	  Maintenance release, fixing three small issues.
	</para>
	<para>
	  Developers: this version is compatible with 1.99.11 backends.
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		PowerDNS ignored the <command>logging-facility</command> setting unless it was specified on the commandline. 
		Thanks to Karl Obermayer from WebMachine Technologies for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql neglected to preserve 'slaveness' of domains when converting to the slave capable PostgreSQL backend. Thanks
		to Mike Benoit of NetNation for reporting this. Zone2sql now has a <command>--slave</command> option.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SOA Hostmaster addresses with dots in them before the @-sign were mis-encoded on the wire.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-0"><title>Version 2.0</title>
	<para>
	  Two bugfixes, one stability/security related. No new features.
	</para>
	<para>
	  Developers: this version is compatible with 1.99.11 backends.
	</para>
	<para>
	  Bugfixes:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		zone2sql refused to work under some circumstances, taking 100% cpu and not functioning. Thanks to Andrew Clark and Mike Benoit 
		for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fixed a stability issue where malformed packets could force PDNS to reload. Present in all earlier 2.0 versions.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-0-rc2"><title>Version 2.0 Release Candidate 2</title>
	<para>
	  Mostly bugfixes, no really new features.
	</para>
	<para>
	  Developers: this version is compatible with 1.99.11 backends.
	</para>
	<para>
	  Bugs fixed:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		chroot() works again - 2.0rc1 silently refused to chroot. Thanks to Hub Dohmen for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		setuid() and setgid() security features were silently not being performed in 2.0rc1. Thanks to Hub Dohmen for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		MX preferences over 255 now work as intended. Thanks to Jeff Crowe for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IPv6 clients can now also benefit from the recursing backend feature. Thanks to Andy Furnell for proving beyond any doubt that this
		did not work.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Extremely bogus code removed from DNS notification reception code - please test! Thanks to Jakub Jermar for working with us
		in figuring out just how broken this was.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		AXFR code improved to handle more of the myriad different zonetransfer dialects available. Specifically, interoperability 
		with Bind 4 was improved, as well as Bind 8 in 'strict rfc conformance' mode. Thanks again for Jakub Jermar for running many tests for us.
		If your transfers failed with 'Unknown type 14!!' or words to that effect, this was it.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		Win32 version now has a zone2sql tool.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Win32 version now has support for specifying how urgent messages should be before they go to the NT event log.
	      </para>	  
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Remaining issues:
	  <itemizedlist>
	    <listitem>
	      <para>
		One persistent report of the default 'chroot=./' configuration not working.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		One report of disable-axfr and allow-axfr-ips not working as intended.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Support for relative paths in zones and in Bind configuration is not bug-for-bug compatible with bind yet.
	      </para>	  
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-2-0-rc1"><title>Version 2.0 Release Candidate 1</title>
	<para>
	  The MacOS X release! A very experimental OS X 10.2 build has been added. Furthermore, the Windows version is now in line with Unix with 
	  respect to capabilities. The ODBC backend now has the code to function as both a master and a slave.
	</para>
	<para>
	  Developers: this version is compatible with 1.99.11 backends.
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		Implemented native packet response parsing code, allowing Windows to perform AXFR and NS and SOA queries.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		This is the first version for which we have added support for Darwin 6.0, which is part of the forthcoming Mac OS X 10.2. 
		Please note that although this version is marked RC1, that we have not done extensive testing yet. Consider this a technology 
		preview.                                
	      </para>
	      <para>
		<itemizedlist>
		  <listitem><para>
		      The Darwin version has been developed on Mac OS X 10.2 (6C35). Other versions may or may not work. 
		    </para></listitem>
		  <listitem><para>
		      Currently only the random, bind, mysql and pdns backends are included.
		    </para></listitem>

		  <listitem><para>
		      The menu based installer script does not work, you will have to edit         pathconfig by hand as outlined in chapter 2.
		    </para></listitem>

		  <listitem><para>
		      On Mac OS X Client, PDNS will fail to start because a system service         is already bound to port 53. 
		    </para></listitem>
		</itemizedlist>
	      </para>
	      <para>
		This version is distributed as a compressed tar file. You should follow the generic UNIX installation instructions. 
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Zone2sql PostgreSQL mode neglected to lowercase $ORIGIN. Thanks to Maikel Verheijen of Ladot for spotting this.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql PostgreSQL mode neglected to remove a trailing dot from $ORIGIN if present. 
		Thanks to Thanks to Maikel Verheijen of Ladot for spotting this.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Zonefile parser was not compatible with bind when $INCLUDING non-absolute filenames. Thanks to Jeff Miller for working out 
		how this should work. 
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Bind configuration parser was not compatible with bind when including non-absolute filenames. Thanks to Jeff Miller for working out 
		how this should work. 
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Documentation incorrectly listed the Bind backend as 'slave capable'. This is not yet true, now labeled 'experimental'.
	      </para>	  
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Windows changes. We are indebted to Dimitry Andric who educated us in the ways of distributing Windows software.
	  <itemizedlist>
	    <listitem>
	      <para>
		<filename>pdns.conf</filename> is now read if available.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Console version responds to ^c now.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Default pdns.conf added to distribution
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Uninstaller missed several files, leaving remnants behind
	      </para>	  
	    </listitem>

	    <listitem>
	      <para>
		DLLs are now installed locally, with the pdns executable.
	      </para>	  
	    </listitem>

	    <listitem>
	      <para>
		pdns_control is now also available on Windows
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		ODBC backend can now act as master and slave. Experimental.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		The example zone missed indexes and had other faults. 
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		A runtime DLL that is present on most windows systems (but not all!) was missing.
	      </para>	  
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-1-99-12"><title>Version 1.99.12 Prerelease</title>
	<para>
	  The Windows release! See <xref linkend="windows">. Beware, windows support is still very fresh and untested. Feedback is very welcome.
	</para>
	<para>
	  Developers: this version is compatible with 1.99.11 backends.
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		Windows 2000 codebase merge completed. This resulted in quite some changes on the Unix end of things, so this may impact reliability
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		ODBC backend added for Windows. See <xref linkend="odbc">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IBM DB2 Universal Database backend available for Linux. See <xref linkend="db2">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql now understands $INCLUDE. Thanks to Amaze Internet for nagging about this
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The SOA Mininum TTL now has a configurable default (<command>soa-minimum-ttl</command>)value to placate the DENIC requirements.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added a limit on the simultaneous numbers of TCP connections to accept (<command>max-tcp-connections</command>). Defaults to 10. 
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		When operating in virtual hosting mode (See <xref linkend="virtual">), the additional init.d scripts would not function correctly
		and interface with other pdns instances.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		PDNS neglected to conserve case on answers. So a query for WwW.PoWeRdNs.CoM would get an answer listing the address of www.powerdns.com. 
		While this did not confuse resolvers, it is better to conserve case. This has semantical concequences for all backends, which the documentation
		now spells out.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		PostgreSQL backend was case sensitive and returned only answers in case an exact match was found. The Generic PostgreSQL backend is now 
		officially all lower case and zone2sql in PostgreSQL mode enforces this.
		Documentation has been been updated to reflect the case change. Thanks to Maikel Verheijen of Ladot for 
		spotting this!
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		Documentation bug - postgresql create/index statements created a duplicate index. If you've previously copy pasted the commands and
		not noticed the error, execute <command>CREATE INDEX rec_name_index ON records(name)</command> to remedy. Thanks to Jeff Miller for reporting 
		this. This also lead to depressingly slow 'ANY' lookups for those of you doing benchmarks.
	      </para>	  
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		pdns_control (see <xref linkend="pdnscontrol">) now opens the local end of its socket in <filename>/tmp</filename> instead of next to the
		remote socket (by default <filename>/var/run</filename>). This eases the way for allowing non-root access to pdns_control. When running chrooted 
		(see <xref linkend="security">), the local socket again moves back to <filename>/var/run</filename>.
	      </para>	  
	    </listitem>
	    <listitem>
	      <para>
		pdns_control now has a 'version' command. See <xref linkend="pdnscontrol">.
	      </para>	  
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

      <sect2 id="changelog-1-99-11"><title>Version 1.99.11 Prerelease</title>
	<para>
	  This release is important because it is the first release which is accompanied by an Open Source Backend Development Kit, allowing external 
	  developers to write backends for PDNS. Furthermore, a few bugs have been fixed:
	</para>
	<para>
	  <itemizedlist>
	    <listitem>
	      <para>
		Lines with only whitespace in zone files confused PDNS (thanks Henk Wevers)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PDNS did not properly parse TTLs with symbolic sufixes in zone files, ie 2H instead of 7200 (thanks Henk Wevers)
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-1-99-10"><title>Version 1.99.10 Prerelease</title>
	<para>
	  IMPORTANT: there has been a tiny license change involving free public webbased dns hosting, check out the changes before deploying!
	</para>
	<para>
	  PDNS is now feature complete, or very nearly so. Besides adding features, a lot of 'fleshing out' work is done now. There is an important
	  performance bug fix which may have lead to disappointing benchmarks - so if you saw any of that, please try either this version or 1.99.8 which 
	  also does not have the bug.
	</para>
	<para>
	  This version has been very stable for us on multiple hosts, as was 1.99.9.
	</para>
	<para>
	  PostgreSQL users should be aware that while 1.99.10 works with the schema as presented in earlier versions, advanced features
	  such as master or slave support will not work unless you create the new 'domains' table as well.
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Wildcard AAAA queries sometimes received an NXDOMAIN error where they should have gotten an empty NO ERROR. Thanks to Jeroen Massar
		for spotting this on the .TK TLD!
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Do not disable the packetcache for 'recursion desired' packets unless a recursor was configured. Thanks to Greg Schueler for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A failing backend would not be reinstated. Thanks to 'Webspider' for discovering this problem with PostgreSQL connections that die after
		prolonged inactivity.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Fixed loads of IPv6 transport problems. Thanks to Marco Davids and others for testing. Considered ready for production now.
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		<command>Zone2sql</command> printed a debugging statement on range $GENERATE commands. Thanks to Rene van Valkenburg for spotting this.
	      </para>
	  </listitem>
	</itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		PDNS can now act as a master, sending out notifications in case of changes and allowing slaves to AXFR. Big rewording of replication support,
		domains are now either 'native', 'master' or 'slave'. See <xref linkend="replication"> for lots of details.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>Zone2sql</command> in PostgreSQL mode now populates the 'domains' table for easy master, slave or native replication support.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Ability to disable those annoying Windows DNS Dynamic Update messages from appearing in the log. See <function>log-failed-updates</function>
		in <xref linkend="all-settings">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Ability to run on IPv6 transport only
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Logging can now happen under a 'facility' so all PDNS messages appear in their own file. See <xref linkend="syslog">.
	      </para>
	    </listitem>

	    <listitem>
	      <para>
		Different OS releases of PDNS now get different install path defaults. Thanks to Mark Lastdrager for nagging about this and to Nero Imhard and
		Frederique Rijsdijk for suggesting saner defaults.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Infrastructure for 'also-notify' statements added.
	      </para>
	    </listitem>

	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-1-99-9"><title>Version 1.99.9 Early Access Prerelease</title>
	<para>
	  This is again a feature and an infrastructure release. We are nearly feature complete and will soon start
	  work on the backends to make sure that they are all master, slave and 'superslave' capable.
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		PDNS sometimes sent out duplicate replies for packets passed to the recursing backend. Mostly a problem on SMP systems. Thanks to Mike Benoit
		for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Out-of-bailiwick CNAMES (ie, a CNAME to a domain not in PDNS) caused a 'ServFail' packet in 1.99.8, indicating failure, leading to hosts not 
		resolving. Thanks to Martin Gillstrom for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql balked at zones editted under operating sytems terminating files with ^Z (Windows). Thanks Brian Willcott for reporting this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		PostgreSQL backend logged the password used to connect. Now only does so in case of failure to connect. Thanks to 'Webspider' for noticing this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Debian unstable distribution wrongly depended on home compiled PostgreSQL libraries. Thanks to Konrad Wojas for noticing this.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Features:
	  <itemizedlist>
	    <listitem>
	      <para>
		When operating as a slave, AAAA records are now supported in the zone. They were already supported in master zones.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		IPv6 transport support - PDNS can now listen on an IPv6 socket using the <command>local-ipv6</command> setting.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Very silly randombackend added which appears in the documentation as a sample backend. See <xref linkend="backend-writers-guide">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		When transferring a slave zone from a master, out of zone data is now rejected. Malicious operators might try to insert bad records otherwise.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		'Supermaster' support for automatic provisioning from masters. See <xref linkend="supermaster">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Recursing backend can now live on a non-standard (!=53) port. See <xref linkend="recursion">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Slave zone retrieval is now queued instead of immediate, which scales better and is more resilient to temporary failures.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<command>max-queue-length</command> parameter. If this many packets are queued for database attention, consider the situation hopeless and 
		respawn.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Internal:
	  <itemizedlist>
	    <listitem>
	      <para>
		SOA records are now 'special' and each backend can optionally generate them in special ways. PostgreSQL backend does so 
		when operating as a slave.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Writing backends is now a lot easier. See <xref linkend="backend-writers-guide">.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added Bindbackend to internal regression tests, confirming that it is compliant.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>
      <sect2 id="changelog-1-99-8"><title>Version 1.99.8 Early Access Prerelease</title>
	<para>
	  A lot of infrastructure work gearing up to 2.0. Some stability bugs fixed and a lot of new features.
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Bindbackend was overly complex and crashed on some systems on startup. Simplified launch code.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		SOA fields were not always properly filled in, causing default values to go out on the wire
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Obscure bug triggered by malicious packets (we know who you are) in SOA finding code fixed.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Magic serial number calculation contained a double free leading to instability.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Standards violation, questions for domains for which PDNS was unauthoritative now get a SERVFAIL answer. 
		Thanks to the IETF Namedroppers list for helping out with this.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Slowly launching backends were being relaunched at a great rate when queries were coming in while launching backends.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		MySQL-on-unix-domain-socket on SMP systems was overwhelmed by the quick connection rate on launch, inserted a small 50ms delay. 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Some SMP problems appear to be compiler related. Shifted to GCC 3.0.4 for Linux.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Ran ispell on documentation.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Feature enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Recursing backend. See <xref linkend="recursion">. Allows recursive and authoritative DNS on the same IP address.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		<link linkend="naptr">NAPTR support</link>, which is especially useful for the ENUM/E.164 community.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone transfers can now be allowed per <link linkend="allow-axfr-ips">netmask instead of only per IP address</link>.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Preliminary support for slave operation included. Only for the adventurous right now! See <xref linkend="slave"> 
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		All record types now documented, see <xref linkend="types">.
	      </para>
	    </listitem>
          </itemizedlist>
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    Wildcard CNAMES do not work as they do with bind.
	  </para>
	  <para>
	    Recursion sometimes sends out duplicate packets (fixed in 1.99.9 snapshots)
	  </para>
	  <para>
	    Some stability issues which are caught by the guardian
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>
            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend
                </para>
              </listitem>
            </itemizedlist>
            
	  </para>
	</sect3>

      </sect2>
      <sect2 id="changelog-1-99-7"><title>Version 1.99.7 Early Access Prerelease</title>
	<para>
	  Named.conf parsing got a lot of work and many more bind configurations can now be parsed. Furthermore, error reporting was improved.
	  Stability is looking good.
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Bind parser got confused by filenames with underscores and colons.
	      </para
	    </listitem>
	    <listitem>
	      <para>
		Bind parser got confused by spaces in quoted names
	      </para
	    </listitem>
	    <listitem>
	      <para>
		FreeBSD version now stops and starts when instructed to do so.
	      </para
	    </listitem>
	    <listitem>
	      <para>
		Wildcards were off by default, which violates standards. Now on by default.
	      </para
	    </listitem>
	    <listitem>
	      <para>
		--oracle was broken in zone2sql
	      </para
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Feature enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Line number counting goes on as it should when including files in named.conf
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added --no-config to enable users to start the pdns daemon without parsing the configuration file.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		zone2sql now has --bare for unformatted output which can be used to generate insert statements for different database layouts
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		zone2sql now has --gpgsql, which is an alias for --mysql, to output in a format useful for the default Generic PgSQL backend
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		zone2sql is now documented.
	      </para>
	    </listitem>
          </itemizedlist>
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    Wildcard CNAMES do not work as they do with bind.
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>
            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  
	  </para>
	</sect3>

      </sect2>
      <sect2><title>Version 1.99.6 Early Access Prerelease</title>
	<para>
	  This version is now running on dns-eu1.powerdns.net and working very well for us. But please remain cautious before 
	  deploying!
	</para>
	<para>
	  Bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Webserver neglected to show log messages
	      </para
	    </listitem>
	    <listitem>
	      <para>
		TCP question/answer miscounted multiple questions over one socket. Fixed misnaming of counter
	      </para
	    </listitem>
	    <listitem>
	      <para>
		Packetcache now detects clock skew and times out entries
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		named.conf parser now reports errors with line number and offending token
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Filenames in named.conf can now contain :
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Feature enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		The webserver now by default does not print out configuration statements, which might contain database backends. Use 
		<command>webserver-print-arguments</command> to restore the old behaviour.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generic PostgreSQL backend is now included. Still rather beta.
	      </para>
	    </listitem>
          </itemizedlist>
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    FreeBSD version does not stop when requested to do so.
	  </para>
	  <para>
	    Wildcard CNAMES do not work as they do with bind.
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>

            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  
	  </para>
	</sect3>

      </sect2>
      <sect2><title>Version 1.99.5 Early Access Prerelease</title>
	<para>
          The main focus of this release is stability and TCP improvements. This is the first release PowerDNS-the-company actually considers for running
          on its production servers!
	</para>
	<para>
	  Major bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
                Zone2sql received a floating point division by zero error on named.confs with less than 100 domains.
	      </para
	    </listitem>
	    <listitem>
	      <para>
                Huffman encoder failed without specific error on illegal characters in a domain
	      </para
	    </listitem>
	    <listitem>
	      <para>
                Fixed huge memory leaks in TCP code.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
                Removed further file descriptor leaks in guardian respawning code
	      </para>
	    </listitem>
	    <listitem>
	      <para>
                Pipebackend was too chatty.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
                pdns_server neglected to close fds 0, 1 &amp; 2 when daemonizing
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Feature enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
                bindbackend can be instructed not to check the ctime of a zone by specifying <command>bind-check-interval=0</command>,
                which is also the new default.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
                <command>pdns_server --list-modules</command> lists all available modules.
	      </para>
	    </listitem>
          </itemizedlist>
	</para>
	<para>
	  Performance enhancements:
	<itemizedlist>
	    <listitem>
	      <para>
                TCP code now only creates a new database connection for AXFR.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
                TCP connections timeout rather quickly now, leading to less load on the server.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    FreeBSD version does not stop when requested to do so.
	  </para>
	  <para>
	    Wildcard CNAMES do not work as they do with bind.
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>

            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend, gpgsqlbackend
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  
	  </para>
	</sect3>

      </sect2>
      <sect2><title>Version 1.99.4 Early Access Prerelease</title>
	<para>
	  A lot of new named.confs can now be parsed, zone2sql &amp; bindbackend have gained features and stability.
	</para>
	<para>
	  Major bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Label compression was not always enabled, leading to large reply packets sometimes.
	      </para
	    </listitem>
	    <listitem>
	      <para>
		Database errors on TCP server lead to a nameserver reload by the guardian.
	      </para
	    </listitem>
	    <listitem>
	      <para>
		MySQL backend neglected to close its connection properly.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		BindParser miss parsed some IP addresses and netmasks.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Truncated answers were also truncated on the packetcache, leading to truncated TCP answers.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Feature enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Zone2sql and the bindbackend now understand the Bind $GENERATE{} syntax.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql can optionally gloss over non-existing zones with <command>--on-error-resume-next</command>.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql and the bindbackend now properly expand @ also on the right hand side of records.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Zone2sql now sets a default TTL.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		DNS UPDATEs and NOTIFYs are now logged properly and sent the right responses.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Performance enhancements:
	<itemizedlist>
	    <listitem>
	      <para>
		'Fancy records' are no longer queried for on ANY queries - this is a big speedup.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    FreeBSD version does not stop when requested to do so.
	  </para>
	  <para>
	    Zone2sql refuses named.confs with less than 100 domains.
	  </para>
	  <para>
	    Wildcard CNAMES do not work as they do with bind.
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>

            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend, gpgsqlbackend
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  
	  </para>
	</sect3>

      </sect2>
	    
      <sect2><title>Version 1.99.3 Early Access Prerelease</title>
	<para>
	  The big news in this release is the BindBackend which is now capable of parsing many more named.conf Bind configurations.
	  Furthermore, PDNS has successfully parsed very large named.confs with large numbers of small domains, as well as small numbers of
	  large domains (TLD).
	</para>
	<para>
	  Zone transfers are now also much improved.
	</para>
	<para>
	  Major bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		zone2sql leaked file descriptors on each domain, used wrong Bison recursion leading to
		parser stack overflows. This limited the amount of domains that could be parsed to 1024.
	      </para
	    </listitem>
	    <listitem>
	      <para>
		zone2sql can now read all known zonefiles, with the exception of those containing $GENERATE
	      </para
	    </listitem>
	    <listitem>
	      <para>
		Guardian relaunching a child lost two file descriptors
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Don't die on a connection reset by peer during zone transfer.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Webserver does not crash anymore on ringbuffer resize
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Feature enhancements:
	  <itemizedlist>
	    <listitem>
	      <para>
		AXFR can now be disabled, and re-enabled per IP address
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		--help accepts a parameter, will then show only help items with that prefix.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
	      zone2sql now accepts a --zone-name parameter
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		BindBackend maturing - 9500 zones parsed in 3.5 seconds. No longer case sensitive.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<para>
	  Performance enhancements:
	<itemizedlist>
	    <listitem>
	      <para>
		Implemented RFC-breaking AXFR format (which is the industry standard). Zone transfers now zoom along
		at wirespeed (many megabits/s).
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    FreeBSD version does not stop when requested to do so.
	  </para>
	  <para>
	    BindBackend cannot parse zones with $GENERATE statements. 
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>

            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend, gpgsqlbackend
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  
	  </para>
	</sect3>

      </sect2>
	    
      <sect2><title>Version 1.99.2 Early Access Prerelease</title>
	<para>
	  Major bugs fixed:
	  <itemizedlist>
	    <listitem>
	      <para>
		Database backend reload does not hang the daemon anymore
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Buffer overrun in local socket address initialisation may have caused binding problems
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		setuid changed the uid to the gid of the selected user
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		zone2sql doesn't coredump on invocation anymore. Fixed lots of small issues.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Don't parse configuration file when creating configuration file. This was a problem with reinstalling.
	      </para>
	    </listitem>
	  </itemizedlist>
	  Performance improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		removed a lot of unnecessary gettimeofday calls
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		removed needless select(2) call in case of listening on only one address
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		removed 3 useless syscalls in the fast path
	      </para>
	    </listitem>
	  </itemizedlist>
	  Having said that, more work may need to be done. Testing on a 486 saw packet rates in a simple setup 
	  (question/wait/answer/question..) improve from 200 queries/second to over 400.
	</para>
	<para>
	  Usability improvements:
	  <itemizedlist>
	    <listitem>
	      <para>
		Fixed error checking in init.d script (<command>show</command>, <command>mrtg</command>)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Added 'uptime' to the mrtg output
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		removed further GNUisms from installer and init.d scripts for use on FreeBSD
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Debian package and apt repository, thanks to Wichert Akkerman.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		FreeBSD /usr/ports, thanks to Peter van Dijk (in progress).
	      </para>
	    </listitem>
	  </itemizedlist>


	</para>
	<para>
	  Stability may be an issue as well as performance. This version has a tendency to log a bit too much which slows 
	  the nameserver down a lot.
	</para>
	<sect3>
	  <title>Known bugs</title>
	  <para>
	    Decreasing a ringbuffer on the website is a sure way to crash the daemon. Zone2sql, while improved, still
	    has problems with a zone in the following format:
	    
	    <programlisting>
name         IN            A        1.2.3.4
             IN            A        1.2.3.5
	    </programlisting>

	    To fix, add 'name' to the second line.
	  </para>
	  <para>
	    Zone2sql does not close filedescriptors.
	  </para>

	  <para>
	    FreeBSD version does not stop when requested via the init.d script.
	  </para>

	</sect3>
	<sect3><title>Missing features</title>
	  <para>
            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend, gpgsqlbackend
                </para>
              </listitem>
              <listitem>
                <para>
                  fully functioning bindbackend - will try to parse named.conf, but probably fail
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  


	  </para>
	</sect3>
      </sect2>
      <sect2><title>Version 1.99.1 Early Access Prerelease</title>
	<para>
	  This is the first public release of what is going to become PDNS 2.0. As such, it is not of production quality. 
	  Even PowerDNS-the-company does not run this yet.
	</para>
	<para>
	  Stability may be an issue as well as performance. This version has a tendency to log a bit too much which slows 
	  the nameserver down a lot.
	</para>
	<sect3><title>Known bugs</title>
	  <para>
	    Decreasing a ringbuffer on the website is a sure way to crash the daemon. Zone2sql is very buggy.
	  </para>
	</sect3>
	<sect3><title>Missing features</title>
	  <para>
            Features present in this document, but disabled or withheld from the current release:
            <itemizedlist>
              <listitem>
                <para>
                  gmysqlbackend, oraclebackend, gpgsqlbackend
                </para>
              </listitem>
              <listitem>
                <para>
                  fully functioning bindbackend - will not parse configuration files
                </para>
              </listitem>
            </itemizedlist>
            
            Some of these features will be present in newer releases.  


	  </para>
	</sect3>
      </sect2>
    </sect1>
    <sect1 id="security-policy"><title>Security</title>
      <para>
	As of the 11th of November 2006, no actual security problems with PowerDNS 2.9.18, Recursor 3.1.4, or later are known about.  This page 
	will be updated with all bugs which are deemed to be security problems, or could conceivably lead to those. Any such notifications
	will also be sent to all PowerDNS mailinglists.
      </para>
      <para>
	Version 3.1.3 and earlier of the PowerDNS recursor contain two security issues, both of which can lead to a denial of service, both of which can be triggered
	by remote users. One of the issues might lead be exploited and lead to a system compromise. For more detail, see <xref linkend="powerdns-advisory-2006-01"> and
	<xref linkend="powerdns-advisory-2006-02">.
      </para>
      <para>
	Version 3.0 of the PowerDNS recursor contains a denial of service bug which can be exploited remotely. This bug, which we believe to only lead to a crash,
	has been fixed in 3.0.1. There are no guarantees however, so an upgrade from 3.0 is highly recommended.
      </para>
      <para>
	All versions of PowerDNS before 2.9.18 contain the following two bugs, which only apply to installations running with the LDAP backend, or installations providing recursion
	to a limited range of IP addresses. If any of these apply to you, an upgrade is highly advised:
	<itemizedlist>
	  <listitem>
	    <para>
	      The LDAP backend did not properly escape all queries, allowing it to fail and not answer questions. We have not investigated further risks involved,
	      but we advise LDAP users to update as quickly as possible (Norbert Sendetzky, Jan de Groot)
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Questions from clients denied recursion could blank out answers to clients who are allowed recursion services, temporarily. Reported by Wilco Baan.
	      This would've made it possible for outsiders to blank out a domain temporarily to your users. Luckily PowerDNS would send out SERVFAIL or Refused, and
	      not a denial of a domain's existence.
	    </para>
	  </listitem>
	</itemizedlist>
      </para>
      <para>
	All versions of PowerDNS before 2.9.17 are known to suffer from remote denial of service problems which can disrupt operation. Please upgrade
	to 2.9.17 as this page will only contain detailed security information from 2.9.17 onwards.
      </para>
      <para>
	If you have a security problem to report, please email us at both <email>powerdns@powerdns.com</email> and at
	<email>ahu@ds9a.nl</email>. We adhere to the <ulink url="http://www.wiretrip.net/rfp/policy.html">Rain Forest Puppy
	  Full Disclosure Policy (RFPolicy) v2.0</ulink> and we ask you to do the same.
      </para>
      <para>
	We remind PowerDNS users that under the terms of the GNU General Public License, PowerDNS comes with ABSOLUTELY NO WARRANTY. 
	This license is included in the distribution and in this documentation, see <xref linkend="license">.
      </para>
    </sect1>
    <sect1 id="powerdns-advisory-2006-01">
      <title>PowerDNS Security Advisory 2006-01: Malformed TCP queries can lead to a buffer overflow which might be exploitable</title>
      <para>
	<table>
	  <title>PowerDNS Security Advisory</title>
	  <tgroup cols=2>
	    <tbody>
	      <row>
		<entry>
		  CVE
		</entry>
		<entry>
		  CVE-2006-4251
		</entry>
	      </row>
	      <row>
		<entry>
		  Date
		</entry>
		<entry>
		  13th of November 2006
		</entry>
	      </row>
	      <row>
		<entry>
		  Affects
		</entry>
		<entry>
		  PowerDNS Recursor versions 3.1.3 and earlier, on all operating systems.
		</entry>
	      </row>
	      <row>
		<entry>
		  Not affected
		</entry>
		<entry>
		  No versions of the PowerDNS Authoritative Server ('pdns_server') are affected.
		</entry>
	      </row>
	      <row>
		<entry>
		  Severity 
		</entry>
		<entry>
		  Critical
		</entry>
	      </row>
	      <row>
		<entry>
		  Impact
		</entry>
		<entry>
		  Potential remote system compromise. 
		</entry>
	      </row>
	      <row>
		<entry>
		  Exploit
		</entry>
		<entry>
		  As far as we know, no exploit is available as of 11th of November 2006.
		</entry>
	      </row>
	      <row>
		<entry>
		  Solution
		</entry>
		<entry>
		  Upgrade to PowerDNS Recursor 3.1.4, or apply the patches referred below and recompile
		</entry>
	      </row>
	      <row>
		<entry>
		  Workaround
		</entry>
		<entry>
		  Disable TCP access to the Recursor. This will have slight operational impact, but it is likely that this will not lead
		  to meaningful degradation of service. Disabling access is best performed at packet level, either by configuring a firewall, or 
		  instructing the host operating system to drop TCP connections to port 53.
		  Additionally, exposure can be limited by configuring the <command>allow-from</command> setting so only trusted users
		  can query your nameserver.
		</entry>
	      </row>
	  </tgroup>
	</table>
      </para>
      <para>
	PowerDNS Recursor 3.1.3 and previous miscalculate the length of incoming TCP DNS queries, and will attempt to read up to 4 gigabytes of query
	into a 65535 byte buffer.
      </para>
      <para>
	We have not verified if this problem might actually lead to a system compromise, but are acting on the assumption that it might.
      </para>
      <para>
	For distributors, a minimal patch is available on <ulink url="http://wiki.powerdns.com/cgi-bin/trac.fcgi/changeset/915">the PowerDNS wiki</ulink>.
	Additionally, those shipping very old versions of the PowerDNS Recursor might benefit from this <ulink url="http://ds9a.nl/tmp/cve-2006-4251.patch">
	  patch</ulink>.
      </para>
      <para>
        The impact of these and other security problems can be lessened by considering the advice in <xref linkend="security">.
      </para>
    </sect1>
    <sect1 id="powerdns-advisory-2006-02">
      <title>PowerDNS Security Advisory 2006-02: Zero second CNAME TTLs can make PowerDNS exhaust allocated stack space, and crash</title>
      <para>
	<table>
	  <title>PowerDNS Security Advisory</title>
	  <tgroup cols=2>
	    <tbody>
	      <row>
		<entry>
		  CVE
		</entry>
		<entry>
		  CVE-2006-4252
		</entry>
	      </row>
	      <row>
		<entry>
		  Date
		</entry>
		<entry>
		  13th of November 2006
		</entry>
	      </row>
	      <row>
		<entry>
		  Affects
		</entry>
		<entry>
		  PowerDNS Recursor versions 3.1.3 and earlier, on all operating systems.
		</entry>
	      </row>
	      <row>
		<entry>
		  Not affected
		</entry>
		<entry>
		  No versions of the PowerDNS Authoritative Server ('pdns_server') are affected.
		</entry>
	      </row>
	      <row>
		<entry>
		  Severity 
		</entry>
		<entry>
		  Moderate
		</entry>
	      </row>
	      <row>
		<entry>
		  Impact
		</entry>
		<entry>
		  Denial of service
		</entry>
	      </row>
	      <row>
		<entry>
		  Exploit
		</entry>
		<entry>
		  This problem can be triggered by sending queries for specifically configured domains
		</entry>
	      </row>
	      <row>
		<entry>
		  Solution
		</entry>
		<entry>
		  Upgrade to PowerDNS Recursor 3.1.4, or apply c919.
		</entry>
	      </row>
	      <row>
		<entry>
		  Workaround
		</entry>
		<entry>
		  None known. Exposure can be limited by configuring the <command>allow-from</command> setting so only trusted users
		  can query your nameserver.
		</entry>
	      </row>
	  </tgroup>
	</table>
      </para>
      <para>
	PowerDNS would recurse endlessly on encountering a CNAME loop consisting entirely of zero second CNAME records, eventually exceeding resources and crashing.
      </para>
    </sect1>
    <sect1 id="thanks-to"><title>Acknowledgements</title>
      <para>
	PowerDNS is grateful for the help of the following people or institutions:
	<itemizedlist>
	  <listitem><para>Dave Aaldering</para></listitem>
	  <listitem><para>Wichert Akkerman</para></listitem>
	  <listitem><para>Antony Antony</para></listitem>
	  <listitem><para>Mike Benoit (NetNation Communication Inc.)</para></listitem>
	  <listitem><para>Peter van Dijk</para></listitem>
	  <listitem><para>Koos van den Hout</para></listitem>
	  <listitem><para>Andre Koopal</para></listitem>
	  <listitem><para>Eric Veldhuyzen</para></listitem>
	  <listitem><para>Paul Wouters</para></listitem>
	  <listitem><para>Thomas Wouters</para></listitem>
	  <listitem><para>IETF Namedroppers mailinglist</para></listitem>
	</itemizedlist>
	Thanks!
      </para>
      <para>
	(these people don't share the blame for any errors or mistakes in powerdns - those are all ours)
      </para>
    </sect1>
</Chapter>

<Chapter id="installing-on-unix">
    <Title>Installing on Unix</Title>
    <para>
      You will typically install PDNS &gt; 2.9 via source or via a package. Earlier versions used a clumsy binary installer.
    </para>
    <sect1 id="problems">
      <title>Possible problems at this point</title>
      <para>
	At this point some things may have gone wrong. Typical errors include:
	<variablelist>
	  <varlistentry>
	    <term><errortype>error while loading shared libraries: libstdc++.so.x: cannot open shared object file: No such file or directory</errortype></term>
	    <listitem>
	      <para>
		Errors looking like this indicate a mismatch between your PDNS distribution and your Unix operating system. Download the static PDNS
		distribution for your operating system and try again. Please contact <email>pdns@powerdns.com</email> if this is impractical.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>

<Sect1 id="testing">
<Title>Testing your install</Title>
      <para>
	After installing, it is a good idea to test the basic functionality of the software before configuring database backends.
	For this purpose, PowerDNS contains the 'bindbackend' which has a domain built in example.com, which is
	officially reserved for testing.

	To test, edit <filename>pdns.conf</filename> and add the following if not already present:
	
	<screen>
	  launch=bind
	  bind-example-zones
	</screen>

	This configures powerdns to 'launch' the bindbackend, and enable the example zones. To fire up PDNS in testing mode, execute: 
	<command>/etc/init.d/pdns monitor</command>, where you may have to substitute the location of your SysV init.d location you 
	specified earlier.

	In monitor mode, the pdns process runs in the foreground and is very verbose, which is perfect for testing your install.
	
	If everything went all right, you can query the example.com domain like this:
	<screen>
	  <command>host www.example.com 127.0.0.1</command>
	</screen>
	www.example.com should now have IP address 1.2.3.4. The <command>host</command> command can usually be found in the dnsutils 
	package of your operating system. Alternate command is: <command>dig www.example.com A @127.0.0.1</command> or even 
	<command>nslookup www.example.com 127.0.0.1</command>, although nslookup is not advised for DNS diagnostics.

	<itemizedlist>
	  <listitem>
	    <para>
	      example.com SOA record
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      example.com NS record pointing to ns1.example.com
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      example.com NS record pointing to ns2.example.com
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      example.com MX record pointing to mail.example.com
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      example.com MX record pointing to mail1.example.com
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      mail.example.com A record pointing to 4.3.2.1
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      mail1.example.com A record pointing to 5.4.3.2
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      ns1.example.com A record pointing to 4.3.2.1
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      ns2.example.com A record pointing to 5.4.3.2
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      host-0 to host-9999.example.com A record pointing to 2.3.4.5
	    </para>
	  </listitem>

	</itemizedlist>

	When satisfied that basic functionality is there, type <command>QUIT</command> to exit the monitor mode. 
	The adventurous may also type <command>SHOW *</command> to see some internal statistics. 

	In case of problems, you will want to read the following section.
      </para>
      
      <sect2>
	<title>Typical errors</title>
	<para>
	  At this point some things may have gone wrong. Typical errors include:
	  <variablelist>
	    <varlistentry>
	      <term><errortype>binding to UDP socket: Address already in use</errortype></term>
	      <listitem>
		<para>
		  This means that another nameserver is listening on port 53 already. You can resolve this problem
		  by determining if it is safe to shutdown the nameserver already present, and doing so. If uncertain,
		  it is also possible to run PDNS on another port. To do so, add <command>local-port=5300</command> to
		  <filename>pdns.conf</filename>, and try again. This however implies that you can only test your nameserver
		  as clients expect the nameserver to live on port 53.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term><errortype>binding to UDP socket: Permission denied</errortype></term>
	      <listitem>
		<para>
		  You must be superuser in order to be able to bind to port 53. If this is not a possibility,
		  it is also possible to run PDNS on another port. To do so, add <command>local-port=5300</command> to
		  <filename>pdns.conf</filename>, and try again. This however implies that you can only test your nameserver
		  as clients expect the nameserver to live on port 53.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term><errortype>Unable to launch, no backends configured for querying</errortype></term>
	      <listitem>
		<para>
		  PDNS did not find the <command>launch=bind</command> instruction in pdns.conf.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term><errortype>Multiple IP addresses on your server, PDNS sending out answers on the wrong one</errortype></term>
	      <term><errortype>Massive amounts of 'recvfrom gave error, ignoring: Connection refused'</errortype></term>
	      <listitem>
		<para>
		  If you have multiple IP addresses on the internet on one machine, UNIX often sends out answers over another interface
		  than which the packet came in on. In such cases, use <command>local-address</command> to bind to specific IP addresses, which
		  can be comma separated. The second error comes from remotes disregarding answers to questions it didn't ask to that IP address
		  and sending back ICMP errors.
		</para>
	      </listitem>
	    </varlistentry>

	  </variablelist>
	</para>
      </sect2>
</Sect1>

    <sect1 id="pdns-on-unix">
    <Title>Running PDNS on unix</Title>

    <Para>
      PDNS is normally controlled via a SysV-style init.d script, often located in <filename>/etc/init.d</filename> or
      <filename>/etc/rc.d/init.d</filename>. This script accepts the following commands:
      <variablelist>
	<varlistentry>
	  <term>monitor</term>
	  <listitem>
	    <para>
	      Monitor is a special way to view the daemon. It executes PDNS in the foreground with 
	      a lot of logging turned on, which helps in determining startup problems. 

	      Besides running in the foreground, the raw PDNS control socket is made available. All external
	      communication with the daemon is normally sent over this socket. While useful, the control console 
	      is not an officially supported feature. Commands which work are: <command>QUIT</command>, <command>SHOW *</command>,
	      <command>SHOW varname</command>, <command>RPING</command>.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>start</term>
	  <listitem>
	    <para>
	      Start PDNS in the background. Launches the daemon but makes no special effort to determine success, 
	      as making database connections may take a while. Use <command>status</command> to query success. You
	      can safely run <command>start</command> many times, it will not start additional PDNS instances.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>restart</term>
	  <listitem>
	    <para>
	      Restarts PDNS if it was running, starts it otherwise.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>status</term>
	  <listitem>
	    <para>
	      Query PDNS for status. This can be used to figure out if a launch was successful.
	      The status found is prefixed by the PID of the main PDNS process. 
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>stop</term>
	  <listitem>
	    <para>
	      Requests that PDNS stop. Again, does not confirm success. Success can be ascertained with the <command>status</command> command.
	    </para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>dump</term>
	  <listitem>
	    <para>
	      Dumps a lot of statistics of a running PDNS daemon. It is also possible to single out specific variable by using 
	      the <command>show</command> command.
	    </para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>show variable</term>
	  <listitem>
	    <para>
	      Show a single statistic, as present in the output of the <command>dump</command>.
	    </para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>mrtg</term>
	  <listitem>
	    <para>
	      See the performance monitoring <xref linkend="monitoring">.
	    </para>
	  </listitem>
	</varlistentry>

      </variablelist>
    </Para>

  </sect1>
</Chapter>

<Chapter id="windows">
  <Title>Installing on Microsoft Windows</Title>
    <para>
    <note>
      <para>
	  PowerDNS support for Windows is, as of 1.99.12, very recent and therefore quite 'beta'. For reliability, we currently advise the use of 
	  the Unix versions. Furthermore there is no support for master or slave operation in the ODBC backend, which is the only one provided currently. 
	  This will be fixed soon.
      </para>
    </note>
    </para>
    <para>
      As of 1.99.12, PowerDNS supports Windows natively. PDNS can act as an NT service and works with any ODBC drivers you may have.
    </para>
    <para>
      To install PowerDNS for Windows you should check if your PC meets the following requirements:
      <itemizedlist>
      <listitem>
	  <para>
	    A PC running Microsoft NT (with a recent servicepack and at least mdac 2.5), 2000 or XP.
	    </para>
	</listitem>
	<listitem>
	  <para>An ODBC source containing valid zone information (an example MS Access database is supplied in the form of <filename>powerdns.mdb</filename>).
    </para>
	</listitem>
      </itemizedlist>
  </para>

  <para>
    If your system meets these requirements, download the installer from <ulink url="http://www.powerdns.com/pdns/">http://www.powerdns.com/pdns/</ulink>.
    After downloading the file begin the installation procedure by starting <filename>powerdns-VERSION.exe</filename>.

  </para>

  <para>
    After installing the software you should create a valid ODBC source.
    To do this you have open the ODBC sources dialog: <filename>Start->Settings->Control Panel->Administrative Tools->Data Sources (ODBC)</filename>.
  </para>

  <para>
    We'll use the example zone database that is included in the installation to explain how to create a source.
  </para>

  <para>
    When you are in the ODBC sources dialog you activate the <filename>System DSN</filename> tab. 
    <note><para>It is important to create a System DSN instead of an User DNS, otherwise the ODBC backend cannot function.</para></note>
  </para>

  <para>
    Press <filename>Add...</filename>, then you have to select a driver.
  </para>

  <para>
    Select <filename>Microsoft Access Driver (*.mdb)</filename>.
  </para>

  <para>
    Use <filename>PowerDNS</filename> as the DSN name, you can leave the description empty.
  </para>

  <para>    
    Then press <filename>Select...</filename> to select the database (ie. <filename>C:\Program Files\PowerDNS\powerdns.mdb</filename>).
  </para>

  <para>
    Press <function>Ok</function> and you should be done.
  </para>
  
  <para>
    For more information, see <xref linkend="odbc">.
  </para>

  <sect1 id="windows-configuration">
    <title>Configuring PDNS on Microsoft Windows</title>

    <para>
      You can specify program parameters in the <filename>pdns.conf</filename> file
      which should be located in pdns directory (ie. <filename>C:\Program Files\PowerDNS\</filename>).
    </para>

    <para>
      To see a list of available parameters you can run <filename>pdns.exe --help</filename>.
    </para>

    <note>
      <para>
        A default configuration file has been supplied with the installation.
      </para>
    </note>

  </sect1>

    <sect1 id="running-on-windows">
      <title>Running PDNS on Microsoft Windows</title>

    <para>
      If you installed pdns on Windows NT, 2000 or XP you can run pdns as a service.
	  </para>

  	<para>
      This is how to do it:
      Go to services (<filename>Start->Settings->Control Panel->Administrative Tools->Services</filename>) and locate <filename>PDNS</filename> (you should have registered the program as a NT service during the installation).
    </para>
    
    <para>
      Double-click on <filename>PDNS</filename> and push the start button. You should now see a progress bar that gets to the end and see the status change to 'Started'.
    </para>

    <para>
      This is the same as starting pdns like this:
      <filename>pdns.exe --ntservice</filename>
    </para>

    <para>
      If you haven't registered pdns as a service during the installation you can do so from the commandline by starting pdns like this:
      <filename>pdns.exe --register-service</filename>
    </para>

    <para>
      You can run pdns as a standard console program by using a command prompt or <filename>Start->Run...</filename>
      This way you can specify command-line parameters (see the documentation for commandline options).
    </para>

    <para>
      If you chose to add a PowerDNS menu to the start menu during the installation you can start pdns using the pdns shortcut in that menu.
    </para>

    </sect1>
  </Chapter>

  <Chapter id="configuring-db-connection">
    <title>Configure database connectivity</title>
    <para>
      This chapter shows you how to configure the Generic MySQL backend, which we like a lot. But feel free to use any of the myriad
      other backends.
      This backend is called 'gmysql', and needs to be configured
      in <filename>pdns.conf</filename>. Add the following lines, adjusted for your local setup:
      
      <screen>
	launch=gmysql
	gmysql-host=127.0.0.1
	gmysql-user=root
	gmysql-dbname=pdnstest
      </screen>
      
      Remove any earlier <command>launch</command> statements. Also remove the <command>bind-example-zones</command>
      statement as the <command>bind</command> module is no longer launched.
    </para>
    <para>
      <warning>
	<para>
	  Make sure that you can actually resolve the hostname of your database without accessing the database! It is advised to supply
	  an IP address here to prevent chicken/egg problems!
	</para>
      </warning>
      <warning>
	<para>
	  Be very very sure that you configure the *g*mysql backend and not the mysql backend. See
	  <xref linkend="generic-mypgsql-backends">. If you use the 'mysql' backend things will only appear to work.
	</para>
      </warning>
    </para>
    <para>
      Now start PDNS using the monitor command:
      <screen>
	# /etc/init.d/pdns monitor
	(...)
	15:31:30 About to create 3 backend threads
	15:31:30 [gMySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest'
	15:31:30 [gMySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest'
	15:31:30 [gMySQLbackend] Failed to connect to database: Error: Unknown database 'pdnstest'
      </screen>
      
      This is as to be expected - we did not yet add anything to MySQL for PDNS to read from. At this point you may also see
      other errors which indicate that PDNS either could not find your MySQL server or was unable to connect to it. Fix these 
      before proceeding.
    </para>
    <para>
      General MySQL knowledge is assumed in this chapter, please do not interpret these commands as DBA advice!
    </para>
    <sect1 id="configuring-mysql"><title>Configuring MySQL</title>
      <para>
	Connect to MySQL as a user with sufficient privileges and issue the following commands:
	<screen>
create table domains (
 id		 INT auto_increment,
 name		 VARCHAR(255) NOT NULL,
 master		 VARCHAR(128) DEFAULT NULL,
 last_check	 INT DEFAULT NULL,
 type		 VARCHAR(6) NOT NULL,
 notified_serial INT DEFAULT NULL, 
 account         VARCHAR(40) DEFAULT NULL,
 primary key (id)
)type=InnoDB;

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
  id              INT auto_increment,
  domain_id       INT DEFAULT NULL,
  name            VARCHAR(255) DEFAULT NULL,
  type            VARCHAR(6) DEFAULT NULL,
  content         VARCHAR(255) DEFAULT NULL,
  ttl             INT DEFAULT NULL,
  prio            INT DEFAULT NULL,
  change_date     INT DEFAULT NULL,
  primary key(id)
)type=InnoDB;

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

create table supermasters (
  ip VARCHAR(25) NOT NULL, 
  nameserver VARCHAR(255) NOT NULL, 
  account VARCHAR(40) DEFAULT NULL
);

GRANT SELECT ON supermasters TO pdns;
GRANT ALL ON domains TO pdns;
GRANT ALL ON records TO pdns;
	</screen>
	
	Now we have a database and an empty table. PDNS should now be able to launch in monitor mode and display no errors:

	<screen>
	  # /etc/init.d/pdns monitor
	  (...)
	  15:31:30 PowerDNS 1.99.0 (Mar 12 2002, 15:00:28) starting up
	  15:31:30 About to create 3 backend threads
	  15:39:55 [gMySQLbackend] MySQL connection succeeded
	  15:39:55 [gMySQLbackend] MySQL connection succeeded
	  15:39:55 [gMySQLbackend] MySQL connection succeeded
	</screen>
	
	A sample query sent to the database should now return quickly without data:
	<screen>
	  $ host www.test.com 127.0.0.1
	  www.test.com A record currently not present at localhost
	</screen>

	And indeed, the control console now shows:
	<screen>
	  Mar 12 15:41:12 We're not authoritative for 'www.test.com', sending unauth normal response
	</screen>

	Now we need to add some records to our database:
	<screen>
	  # mysql pdnstest
	  mysql> INSERT INTO domains (name, type) values ('test.com', 'NATIVE');
	  INSERT INTO records (domain_id, name, content, type,ttl,prio) 
	  VALUES (1,'test.com','localhost ahu@ds9a.nl 1','SOA',86400,NULL);
	  INSERT INTO records (domain_id, name, content, type,ttl,prio)
	  VALUES (1,'test.com','dns-us1.powerdns.net','NS',86400,NULL);
	  INSERT INTO records (domain_id, name, content, type,ttl,prio)
	  VALUES (1,'test.com','dns-eu1.powerdns.net','NS',86400,NULL);
	  INSERT INTO records (domain_id, name, content, type,ttl,prio)
	  VALUES (1,'www.test.com','199.198.197.196','A',120,NULL);
	  INSERT INTO records (domain_id, name, content, type,ttl,prio)
	  VALUES (1,'mail.test.com','195.194.193.192','A',120,NULL);
	  INSERT INTO records (domain_id, name, content, type,ttl,prio)
	  VALUES (1,'localhost.test.com','127.0.0.1','A',120,NULL);
	  INSERT INTO records (domain_id, name, content, type,ttl,prio)
	  VALUES (1,'test.com','mail.test.com','MX',120,25);
	</screen>
	
	If we now requery our database, <command>www.test.com</command> should be present:
	<screen>
	  $ host www.test.com 127.0.0.1
	  www.test.com        	A	199.198.197.196
	  
	  $ host -v -t mx test.com 127.0.0.1
	  Address: 127.0.0.1
	  Aliases: localhost

	  Query about test.com for record types MX
	  Trying test.com ...
	  Query done, 1 answer, authoritative status: no error
	  test.com            	120	IN	MX	25 mail.test.com
	  Additional information:
	  mail.test.com       	120	IN	A	195.194.193.192
	</screen>
	
	To confirm what happened, issue the command <command>SHOW *</command> to the control console:
	<screen>
	  % show *
	  corrupt-packets=0,latency=0,packetcache-hit=2,packetcache-miss=5,packetcache-size=0,
	  qsize-a=0,qsize-q=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,
	  timedout-packets=0,udp-answers=7,udp-queries=7,
	  % 
	</screen>
	The actual numbers will vary somewhat. Now enter <command>QUIT</command> and start PDNS as a regular daemon, and check launch status:

	<screen>
	  # /etc/init.d/pdns start 
	  pdns: started
	  # /etc/init.d/pdns status
	  pdns: 8239: Child running
	  # /etc/init.d/pdns dump  
	  pdns: corrupt-packets=0,latency=0,packetcache-hit=0,packetcache-miss=0,
	  packetcache-size=0,qsize-a=0,qsize-q=0,servfail-packets=0,tcp-answers=0,
	  tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,
	</screen>
	
	You now have a working database driven nameserver! To convert other zones already present, use the <command>zone2sql</command> 
        described in Appendix A.
      </para>
      <sect2><title>Common problems</title>
	<para>
	  Most problems involve PDNS not being able to connect to the database. 
	<variablelist>
	  <varlistentry>
	      <term><errortype> Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)</errortype></term>
	      <listitem>
		<para>
		  Your MySQL installation is probably defaulting to another location for its socket. Can be resolved
		  by figuring out this location (often <filename>/var/run/mysqld.sock</filename>), and specifying it 
		  in the configuration file with the <command>gmysql-socket</command> parameter.
		</para>
		<para>
		  Another solution is to not connect to the socket, but to 127.0.0.1, which can be achieved by specifying
		  <command>gmysql-host=127.0.0.1</command>.
		</para>
	      </listitem>
	    </varlistentry>
	  <varlistentry>
	      <term><errortype>Host 'x.y.z.w' is not allowed to connect to this MySQL server</errortype></term>
	      <listitem>
		<para>
		  These errors are generic MySQL errors. Solve them by trying to connect to your MySQL database with the MySQL 
		  console utility <command>mysql</command> with the parameters specified to PDNS. Consult the MySQL documentation.
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
	</sect2>
    </sect1>
  </chapter>

  <Chapter id="pipebackend-dynamic-resolution">
    <title>Dynamic resolution using the PipeBackend</title>
    <para>
      Also included in the PDNS distribution is the PipeBackend. The PipeBackend is primarily meant for
      allowing rapid development of new backends without tight integration with PowerDNS. It allows
      end-users to write PDNS backends in any language. A perl sample is provided.

      The PipeBackend is also very well suited for dynamic resolution of queries. Example applications include
      DNS based loadbalancing, geo-direction, DNS based failover with low TTLs.
    </para>
    <para>
      The Pipe Backend also has a separate chapter in the backends appendix, see <xref linkend="pipebackend">.
    </para>
    <para>
      <note>
	<para>
	  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.
	</para>
	<para>
	  Interestingly, the Linux PowerDNS binary running under the Linuxulator on FreeBSD does work.
	</para>
      </note>
    </para>
    <sect1 id="pipe-and-bind"><title>Deploying the PipeBackend with the BindBackend</title>
      <para>
        Included with the PDNS distribution is the example.pl backend which has knowledge of the example.com zone, just like
        the BindBackend. To install both, add the following to your <filename>pdns.conf</filename>:
        <screen>
          launch=pipe,bind
          bind-example-zones
          pipe-command=location/of/backend.pl
        </screen>
        Please adjust the <command>pipe-command</command> statement to the location of the unpacked PDNS distribution. If your backend is slow,
	raise <command>pipe-timeout</command> from its default of 2000ms.

        Now launch PDNS in monitor mode, and perform some queries. Note the difference with the earlier experiment where only the 
        BindBackend was loaded. The PipeBackend is launched first and thus gets queried first.

        The sample backend.pl script knows about:
	<itemizedlist>
	  <listitem>
	    <para>
	      webserver.example.com A records pointing to 1.2.3.4, 1.2.3.5, 1.2.3.6
	    </para>
          </listitem>
	  <listitem>
	    <para>
	      www.example.com CNAME pointing to webserver.example.com
	    </para>
          </listitem>
	  <listitem>
	    <para>
	      MBOXFW (mailbox forward) records pointing to powerdns@example.com.
              See the smtpredir documentation for information about MBOXFW.
	    </para>
          </listitem>
        </itemizedlist>

        For more information about how to write exciting backends with the PipeBackend, see Appendix A.
      </para>
    </sect1>
  </chapter>

  <Chapter id="monitoring">
    <title>Logging &amp; Monitoring PDNS performance</title>
    <para>
      In a production environment, you will want to be able to monitor PDNS performance. For this purpose, currently 
      two methods are available, the webserver and the init.d
<command>dump</command>, <command>show</command> and 
      <command>mrtg</command>, commands. Furthermore, PDNS can perform a configurable amount of operational logging. This chapter
	also explains how to configure syslog for best results.
    </para>
    <sect1 id="webserver"><title>Webserver</title>
      <para>
	To launch the internal webserver, add a <command>webserver</command> statement to the pdns.conf. This 
	will instruct the PDNS daemon to start a webserver on localhost at port 8081, without password protection. 
	Only local users (on the same host) will be able to access the webserver by default.

	The webserver 	lists a lot of information about the PDNS process, including frequent queries, frequently failing queries, 
	lists of remote hosts sending queries, hosts sending corrupt queries etc. The webserver does not allow
	remote management of the daemon.

	The following nameserver related configuration items are available:
	<variablelist>
	  <varlistentry>
	    <term>webserver</term>
	    <listitem>
	      <para>
		If set to anything but 'no', a webserver is launched.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>webserver-address</term>
	    <listitem>
	      <para>
		Address to bind the webserver to. Defaults to 127.0.0.1, which implies that only the local computer
		is able to connect to the nameserver! To allow remote hosts to connect, change to 0.0.0.0 or the
		physical IP address of your nameserver.
	      </para>
	    </listitem>
	  </varlistentry>
	<varlistentry>
	  <term>webserver-password</term>
	  <listitem>
	    <para>
	      If set, viewers will have to enter this plaintext password in order to gain access to the statistics.
	    </para>
	  </listitem>
	</varlistentry>
	  <varlistentry>
	    <term>webserver-port</term>
	    <listitem>
	      <para>
		Port to bind the webserver to. Defaults to 8081.
	      </para>
	    </listitem>
	  </varlistentry>

      </variablelist>
      </para>
      </sect1>
    <sect1 id="init-d-commands"><title>Via init.d commands</title>
      <para>
	As mentioned before, the init.d commands <command>dump</command>, <command>show</command> and 
	<command>mrtg</command> fetch data from a running PDNS process. Especially <command>mrtg</command> is powerful -
	it outputs data in a format that is ready for processing by the MRTG graphing tool. 
      </para>
      <para>
	MRTG can make insightful graphics on the performance of your nameserver, enabling the operator to easily spot trends.
	MRTG can be found on 
	<ulink url="http://people.ee.ethz.ch/~oetiker/webtools/mrtg/mrtg.html">
	  http://people.ee.ethz.ch/~oetiker/webtools/mrtg/mrtg.html
	</ulink>
      </para>
      <para>
	A sample mrtg.conf:
	<screen>
Interval: 5
WorkDir: /var/www/mrtg
WriteExpires: yes
Options[_]: growright,nopercent
XSize[_]: 600

#---------------------------------------------------------------

Target[udp-queries]: `/etc/init.d/pdns mrtg udp-queries udp-answers`
Options[udp-queries]: growright,nopercent,perminute
MaxBytes[udp-queries]: 600000
AbsMax[udp-queries]: 600000
Title[udp-queries]: Queries per minute
PageTop[udp-queries]: &lt;H2&gt;Queries per minute&lt;/H2&gt;
WithPeak[udp-queries]: ymwd
YLegend[udp-queries]: queries/minute
ShortLegend[udp-queries]: q/m
LegendI[udp-queries]: udp-questions
LegendO[udp-queries]: udp-answers


Target[perc-failed]: `/etc/init.d/pdns mrtg udp-queries udp-answers`
Options[perc-failed]: growright,dorelpercent,perminute
MaxBytes[perc-failed]: 600000
AbsMax[perc-failed]: 600000
Title[perc-failed]: Queries per minute, with percentage success
PageTop[perc-failed]: &lt;H2&gt;Queries per minute, with percentage success&lt;/H2&gt;
WithPeak[perc-failed]: ymwd
YLegend[perc-failed]: queries/minute
ShortLegend[perc-failed]: q/m
LegendI[perc-failed]: udp-questions
LegendO[perc-failed]: udp-answers


Target[packetcache-rate]: `/etc/init.d/pdns mrtg packetcache-hit udp-queries`
Options[packetcache-rate]: growright,dorelpercent,perminute
Title[packetcache-rate]: packetcache hitrate
MaxBytes[packetcache-rate]: 600000
AbsMax[packetcache-rate]: 600000
PageTop[packetcache-rate]: &lt;H2&gt;packetcache hitrate&lt;/H2&gt;
WithPeak[packetcache-rate]: ymwd
YLegend[packetcache-rate]: queries/minute
ShortLegend[packetcache-rate]: q/m
LegendO[packetcache-rate]: total
LegendI[packetcache-rate]: hit

Target[packetcache-missrate]: `/etc/init.d/pdns mrtg packetcache-miss udp-queries`
Options[packetcache-missrate]: growright,dorelpercent,perminute
Title[packetcache-missrate]: packetcache MISSrate
MaxBytes[packetcache-missrate]: 600000
AbsMax[packetcache-missrate]: 600000
PageTop[packetcache-missrate]: &lt;H2&gt;packetcache MISSrate&lt;/H2&gt;
WithPeak[packetcache-missrate]: ymwd
YLegend[packetcache-missrate]: queries/minute
ShortLegend[packetcache-missrate]: q/m
LegendO[packetcache-missrate]: total
LegendI[packetcache-missrate]: MISS

Target[latency]: `/etc/init.d/pdns mrtg latency`
Options[latency]: growright,nopercent,gauge
MaxBytes[latency]: 600000
AbsMax[latency]: 600000
Title[latency]: Query/answer latency
PageTop[latency]: &lt;H2&gt;Query/answer latency&lt;/H2&gt;
WithPeak[latency]: ymwd
YLegend[latency]: usec
ShortLegend[latency]: usec
LegendO[latency]: latency
LegendI[latency]: latency

Target[recursing]: `/etc/init.d/pdns mrtg recursing-questions recursing-answers`
Options[recursing]: growright,nopercent,gauge
MaxBytes[recursing]: 600000
AbsMax[recursing]: 600000
Title[recursing]: Recursive questions/answers
PageTop[recursing]: &lt;H2&gt;Recursing questions/answers&lt;/H2&gt;
WithPeak[recursing]: ymwd
YLegend[recursing]: queries/minute
ShortLegend[recursing]: q/m
LegendO[recursing]: recursing-questions
LegendI[recursing]: recursing-answers

	</screen>
      </para>
      </sect1>
      <sect1 id="syslog"><title>Operational logging using syslog</title>
      <para>(<command>logging-facility</command> is available from 1.99.10 and onwards)</para>
      <para>
	This chapter assumes familiarity with syslog, the unix logging device. PDNS logs messages with different levels. The more urgent the 
	message, the lower the 'priority'. By default, PDNS will only log messages with an urgency of 3 or lower, but this can be changed
	using the <command>loglevel</command> setting in the configuration file. Setting it to 0 will eliminate all logging, 9 will log
	everything.
      </para>
      <para>
	By default, logging is performed under the 'DAEMON' facility which is shared with lots of other programs. If you regard nameserving
	as important, you may want to have it under a dedicated facility so PDNS can log to its own files, and not clutter generic files.
      </para>
      <para>
	For this purpose, syslog knows about 'local' facilities, numbered from LOCAL0 to LOCAL7. To move PDNS logging to LOCAL0, add 
	<command>logging-facility=0</command> to your configuration.
      </para>
      <para>
	Furthermore, you may want to have separate files for the differing prioties - preventing lower priority messages from obscuring 
	important ones.
      </para>
      <para>
	A sample syslog.conf might be:
	<programlisting>
local0.info                       -/var/log/pdns.info
local0.warn                       -/var/log/pdns.warn
local0.err                        /var/log/pdns.err
	</programlisting>
      </para>
      <para>
	Where local0.err would store the really important messages. For performance and diskspace reasons, it is advised
	to audit your syslog.conf for statements also logging PDNS activities. Many syslog.confs have a '*.*' statement to
	/var/log/syslog, which you may want to remove.
      </para>
      <para>
	For performance reasons, be especially certain that no large amounts of synchronous logging take place. Under Linux, this 
	is indicated by filenames not starting with a '-' - indicating a synchronous log, which hurts performance.
      </para>
      <para>
	Be aware that syslog by default logs messages at the configured priority and higher! To log only info messages, use
	<command>local0.=info</command>.
      </para>
    </sect1>
  </chapter>
  <chapter id="security"><title>Security settings &amp; considerations</title>
    <sect1 id="settings"><title>Settings</title>
      <para>PDNS has several options to easily allow it to run more securely. Most notable are the <command>chroot</command>, 
	<command>setuid</command> and <command>setgid</command> options which can be specified.</para>
      <para>
	For additional information on PowerDNS security, PowerDNS security incidents and PowerDNS security policy, see <xref linkend="security-policy">.
      </para>
	<sect2><title>Running as a less privileged identity</title>
	<para>
	  By specifying <command>setuid</command> and <command>setgid</command>, PDNS changes to this identity shortly after
	  binding to the privileged DNS ports. These options are highly recommended. It is suggested that a separate identity
	  is created for PDNS as the user 'nobody' is in fact quite powerful on most systems.
	</para>

	<para>
	  Both these parameters can be specified either numerically or as real names.
	  You should set these parameters immediately if they are not set!
	</para>
	</sect2>
	<sect2><title>Jailing the process in a chroot</title>
	<para>
	  The <command>chroot</command> option secures PDNS to its own directory so that even if it should become compromised and
	  under control of external influences, it will have a hard time affecting the rest of the system.
	</para>
	<para>
	  Even though this will hamper hackers a lot, chroot jails have been known to be broken. 
	</para>
	<para>
	  <warning>
	    <para>
	      When chrooting PDNS, take care that backends will be able to get to their files. Many databases need access to a UNIX 
	      domain socket which should live within the chroot. It is often possible to hardlink such a socket into the chroot dir.
	    </para>
	    <para>
	      When running with master or slave support, be aware that many operating systems need access to specific libraries
	      (ofen <filename>/lib/libnss*</filename>) in order to support resolution of domain names! You can also hardlink these.
	    </para>
	  </warning>
	</para><para>
	  The default PDNS configuration is best chrooted to <filename>./</filename>, which boils down to the configured location
	  of the controlsocket. 
	</para><para>
	  This is achieved by adding the following to pdns.conf: <command>chroot=./</command>, and restarting PDNS.
	</para>
      </sect2>
    </sect1>
    <sect1 id="considerations"><title>Considerations</title>
      <para>
	In general, make sure that the PDNS process is unable to execute commands on your backend database. 
	Most database backends will only need SELECT privilege. Take care to not connect to your database as the 'root' 
	or 'sa' user, and configure the chosen user to have very slight privileges.
      </para>
      <para>
	Databases empathic-ally do not need to run on the same machine that runs PDNS! In fact, in benchmarks
	it has been discovered that having a separate database machine actually improves performance.
      </para>
      <para>
	Separation will enhance your database security highly. Recommended.
      </para>
      </sect1>
    </chapter>
    
  <chapter id="virtual"><title>Virtual hosting</title>
    <para>
      It may be advantageous to run multiple separate PDNS installations on a single host, for example to make sure
      that different customers cannot affect each others zones. PDNS fully supports running multiple instances on one host.
    </para>
    <para>
      To generate additional PDNS instances, copy the init.d script <filename>pdns</filename> to <filename>pdns-name</filename>, 
      where <filename>name</filename> is the name of your virtual configuration. Must not contain a - as this will confuse the 
      script.
    </para>
    <para>
      When you launch PDNS via this renamed script, it will seek configuration instructions not in <filename>pdns.conf</filename>
      but in <filename>pdns-name.conf</filename>, allowing for separate specification of parameters.
    </para>
    <para>
      Be aware however that the init.d <command>force-stop</command> will kill all PDNS instances!
    </para>
  </chapter>

  <chapter id="performance"><title>Performance</title>
    <sect1><title>General advice</title>
    <para>
      In general, best performance is achieved on recent Linux 2.6 kernels and using MySQL, although many of the largest PowerDNS 
      installations are based on PostgreSQL. FreeBSD appears to achieve lower packet rates both for the PowerDNS recursor as for the 
      authoritative nameserver, this is still being investigated. No comparative measurements have been done for Solaris installations.
    </para>
    <para>
      On Linux, make sure to read <xref linkend="nptl">.
    </para>
    <para>
      Database servers can require configuration to achieve decent performance. It is especially worth noting that 
      several vendors ship PostgreSQL with a slow default configuration.
    </para>
    </sect1>
    <sect1 id="nptl">
      <title>Native Posix Thread Library vs LinuxThreads</title>
      <para>
	To get the best performance under Linux, especially on SMP
	systems, the use of NPTL is advised. The difference in
	performance can be over a factor of ten in some circumstances.
      </para>
      <para>
	NPTL is the default library on modern Linux distributions, so
	there is generally not a problem, except if you use a
	statically compiled version that, for portability reasons,
	defaults to LinuxThreads. This includes all .deb's and .rpm's
	provided by us up to and including 2.9.18.
      </para>
      <para>
	When running a PowerDNS-provided static binary of 2.9.18 or
	lower, it may make sense to recompile, or to upgrade to a
	newer version, if available. When recompiling, be sure to use
	a supported compiler, like g++ &gt;3.2. You might also consider
	moving to a distribution supplied version.
      </para>
      <para>
	A good indication that your installation might benefit from
	such an upgrade is to watch the 'cs' count in the output of
	vmstat 1. If this is very high (&gt; 10000), you are suffering
	from a LinuxThreads performance problem called 'overspin'.
      </para>
      <para>
	Thanks are due to L. Bunt Jackson who noted the static
	compilation problem in an article in Dr. Dobb's Journal.
      </para>
    </sect1>
    <sect1 id="performance-settings">
    <title>Performance related settings</title>
    <para>
      Different backends will have different characteristics - some will want to have more parallel
      instances than others. In general, if your backend is latency bound, like most relational databases are, 
      it pays to open more backends.
    </para>
    <para>
      This is done with the <command>distributor-threads</command> setting. Of special importance is the choice between 1
      or more backends. In case of only 1 thread, PDNS reverts to unthreaded operation which may be a lot faster, depending
      on your operating system and architecture.
    </para>
    <para>
      Another very important setting <command>cache-ttl</command>. PDNS caches entire packets it sends out so as to save the
      time to query backends to assemble all data. The default setting of 10 seconds may be low for high traffic sites, a value of
      60 seconds rarely leads to problems.
    </para>
    <para>
      Some PDNS operators set cache-ttl to many hours or even days, and use <command>pdns_control purge</command> to selectively
      or globally notify PDNS of changes made in the backend. Also look at the Query Cache described in this chapter. It may
      materially improve your performance.
    </para>
    <para>
      To determine if PDNS is unable to keep up with packets, determine the value of the <command>qsize-q</command> variable. 
      This represents the number of packets waiting for database attention. During normal operations the queue should be small. 
    </para>
    <para>
      If it is known that backends will not contain CNAME records, the <command>skip-cname</command> setting can be used to prevent 
      the normally mandatory CNAME lookup that is needed at least once for each DNS query. 
    </para>

    <para>
      Much the same holds for the <command>wildcards</command> setting. On by default, each non-existent query will lead to a number of additional
      wildcard queries. If it is known that the backends do not contain wildcard records, performance can be improved by adding <command>wildcards=no</command>
      to <filename>pdns.conf</filename>.
    </para>
    <para>
      Logging truly kills performance as answering a question from the cache is an order of magnitude less work than logging a 
      line about it. Busy sites will prefer to turn <command>log-dns-details</command> and <command>log-failed-updates</command>
      off.
    </para>
    <sect2 id="packetcache"><title>Packet Cache</title>
      <para>
	PDNS by default uses the 'Packet Cache' to recognise identical questions and supply them with identical answers, without any further 
	processing. The default time to live is 10 seconds. It has been observed that the utility of the packet cache increases with the load on 
	your nameserver. 
      </para>
      <para>
	Not all backends may benefit from the packetcache. If your backend is memory based and does not lead to context switches, the packetcache
	may actually hurt performance. 
      </para>
      <para>
	The size of the packetcache can be observed with <command>/etc/init.d/pdns show packetcache-size</command>
      </para>
    </sect2>
    <sect2 id="querycache"><title>Query Cache</title>
      <para>
	Besides entire packets, PDNS can also cache individual backend queries. Each DNS query leads to a number of backend queries,
	the most obvious additional backend query is the check for a possible CNAME. So, when a query comes in for the 'A' record for
	'www.powerdns.com', PDNS must first check for a CNAME for 'www.powerdns.com'.
      </para>
      <para>
	The Query Cache caches these backend queries, many of which are quite repetitive. PDNS only caches queries with no answer,
	or with exactly one. In the future this may be expanded but this lightweight solution is very simple and therefore fast.
      </para>
      <para>
	Most gain is made from caching negative entries, ie, queries that have no answer. As these take little memory to store and
	are typically not a real problem in terms of speed-of-propagation, the default TTL for negative queries is a rather high 60 seconds.
      </para>
      <para>
	This only is a problem when first doing a query for a record, adding it, and immediately doing a query for that record again. It may
	then take up to 60 seconds to appear. Changes to existing records however do not fall under the negative query ttl (
	<command>negquery-cache-ttl</command>), but under the generic <command>query-ttl</command> which defaults to 20 seconds.
      </para>
      <para>
	The default values should work fine for many sites. When tuning, keep in mind that the Query Cache mostly saves database access 
	but that the Packet Cache also saves a lot of CPU because 0 internal processing is done when answering a question from the
	Packet Cache.
      </para>
    </sect2>
  </sect1>
  </chapter>
  <chapter id="migration"><title>Migrating to PDNS</title>
    <para>
      Before migrating to PDNS a few things should be considered. 
      <variablelist>
	<varlistentry>
	  <term>PDNS does not operate as a 'slave' or 'master' server with all backends</term>
	  <listitem>
	    <para>
	      Only the Generic SQL, OpenDBX and BIND backends have the ability to act as master or slave.
	    </para>
	  </listitem>
	</varlistentry>
      </variablelist>
      To migrate, the <command>zone2sql</command> tool is provided. 
      </para>
    <sect1 id="zone2sql"><title>Zone2sql</title>
      <para>
	Zone2sql parses Bind named.conf files and zonefiles and outputs SQL 
	on standard out, which can then be fed to your database.
      </para>
      <para>
	Zone2sql understands the Bind master file extension '$GENERATE' and will also honour '$ORIGIN' and '$TTL'.
      </para>
      <para>
	For backends supporting slave operation (currently only the Generic PostgreSQL, Generic MySQL and BIND backend), there is also an option to 
	keep slave zones as slaves, and not convert them to native operation. 
      </para>
      <para>
	By default, zone2sql outputs code suitable for the mysqlbackend, but it can also generate SQL for the Generic PostgreSQL, Generic MySQL and 
	Oracle backends. 
	The following commands are available:
      </para>

      <para>
	<variablelist>
	  <varlistentry>
	    <term>--bare</term>
	    <listitem>
	      <para>
	      Output in a bare format, suitable for further parsing. The output is formatted as follows:
		<screen>
		  domain_id&lt;TAB&gt;'qname'&lt;TAB&gt;'qtype'&lt;TAB&gt;'content'&lt;TAB&gt;prio&lt;TAB&gt;ttl
		</screen>
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--gmysql</term>
	    <listitem>
	      <para>
		Output in format suitable for the default configuration of the Generic MySQL backend.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--gpgsql</term>
	    <listitem>
	      <para>
		Output in format suitable for the default configuration of the Generic PostgreSQL backend.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--help</term>
	    <listitem>
	      <para>
		List options.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--mysql</term>
	    <listitem>
	      <para>
		Output in format suitable for the default configuration of the MySQL backend. Default.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--named-conf=...</term>
	    <listitem>
	      <para>
		Parse this named.conf to find locations of zones. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--on-error-resume-next</term>
	    <listitem>
	      <para>
		Ignore missing files during parsing. Dangerous.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--oracle</term>
	    <listitem>
	      <para>
		Output in format suitable for the default configuration of the Generic Oracle backend.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--slave</term>
	    <listitem>
	      <para>
		Maintain slave status of zones listed in named.conf as being slaves. The default behaviour is to convert all zones
		to native operation.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--startid</term>
	    <listitem>
	      <para>
		Supply a value for the first domain_id generated. Defaults at 0.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--transactions</term>
	    <listitem>
	      <para>
		For Oracle and PostgreSQL output, wrap each domain in a transaction for higher speed and integrity.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--verbose</term>
	    <listitem>
	      <para>
		Be verbose during conversion.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--zone=...</term>
	    <listitem>
	      <para>
		Parse only this zone file. Conflicts with <command>--named-conf</command> parameter. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>--zone-name=...</term>
	    <listitem>
	      <para>
		When parsing a single zone without $ORIGIN statement, set this as the zone name.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>
  </chapter>
  
  <chapter id="recursion"><title>Recursion</title>
    <para>(only available from 1.99.8 and onwards, recursing component available since 2.9.5)</para>
    <para>
      From 2.9.5 onwards, PowerDNS offers both authoritative nameserving capabilities and a recursive nameserver component. These two halves
      are normally separate but many users insist on combining both recursion and authoritative service on one IP address. This can be likened 
      to running Apache and Squid both on port 80.
    </para>
    <para>
      However, many sites want to do this anyhow and some with good reason. For example, a setup like this allows the creation of fake domains
      which only exist for local users. Such domains often don't end on ".com" or ".org" but on ".intern" or ".name-of-isp".
    </para>
    <para>
      PowerDNS can cooperate with either its own recursor or any other you have available to deliver recursive service on its port.
    </para>
    <para>
      By specifying the <command>recursor</command> option in the configuration file, questions requiring recursive treatment will be handed over
      to the IP address specified. An example configuration might be <command>recursor=130.161.180.1</command>, which designates 130.161.180.1 as
      the nameserver to handle recursive queries.
    </para>
    <para>
      As of 2.9.5, the recursing component of PowerDNS is a bit young and relatively untested but we hope people will want to use it anyhow. As an alternative,
      we highly advise the use of the DJBDNS dnscache (<ULINK URL="http://cr.yp.to/djbdns/dnscache.html" TYPE="alternate">http://cr.yp.to/djbdns/dnscache.html</ULINK>).
    </para>
    <para>
      Take care not to point <command>recursor</command> to PDNS, which leads to a very tight packet loop!
    </para>
    <para>
      By specifying <command>allow-recursion</command>, recursion can be restricted to netmasks specified. The default is to allow
      recursion from everywhere. Example: <command>allow-recursion=192.168.0.0/24, 10.0.0.0/8, 1.2.3.4</command>.
    </para>
    <sect1 id="recursion-details"><title>Details</title>
      <para>
	Questions carry a number of flags. One of these is called 'Recursion Desired'. If PDNS is configured to allow recursion, AND such a flag
	is seen, AND the IP address of the client is allowed to recurse via PDNS, then the packet may be handed to the recursing backend.
      </para>
      <para>
	If a Recursion Desired packet arrives and PDNS is configured to allow recursion, but not to the IP address of the client, resolution will proceed 
	as if the RD flag were unset and the answer will indicate that recursion was not available.
      </para>
      <para>
	It is also possible to use a resolver living on a different port. To do so, specify a recursor like this: 
	<command>recursor=130.161.180.1:5300</command>.
      </para>
      <para>
	If the backend does not answer a question within a large amount of time, this is logged as 'Recursive query for remote 10.96.0.2 with internal id 0 
	was not answered by backend within timeout, reusing id'. This may happen when using 'BIND' as a recursor as it is prone to drop queries which it can't 
	answer immediately.
      </para>
      <para>
	To make sure that the local authoritative database overrides recursive information, PowerDNS first tries to answer a question from its own database.
	If that succeeds, the answer packet is sent back immediately without involving the recursor in any way. This means that for questions for which there is no answer, PowerDNS will consult the recursor for an recursive query, even if PowerDNS is authoritative for a domain! This will only cause problems if you 'fake' domains which don't really exist.
      </para>
      <para>
	If you want to create such fake domains or override existing domains, please set the <command>allow-recursion-override</command> feature (available as of 2.9.14).
      </para>
      <para>
	Some packets, like those asking for MX records which are needed for SMTP transport of email, can be subject to 'additional processing'. This means
	that a recursing nameserver is obliged to try to add A records (IP addresses) for any of the mailservers mentioned in the packet, should it have 
	these addresses available.
      </para>
      <para>
	If PowerDNS encounters records needing such processing and finds that it does not have the data in its authoritative database, it will send 
	an opportunistic quick query to the recursing component to see if it perhaps has such data. This question is worded such that the recursing nameserver
	should return immediately such as not to block the authoritative nameserver.
      </para>
      <para>
	This marks a change from pre-2.9.5 behaviour where a packet was handed wholesale to the recursor in case it needed additional processing which could
	not proceed from the authoritative database.
      </para>
    </sect1>
  </chapter>
  <chapter id="built-in-recursor"><title>PowerDNS resolver/recursing nameserver</title>
    <para>
      The PowerDNS recursor is part of the source tarball of the main PowerDNS distribution, but it is released separately. Starting from
      the version 3.0 pre-releases, there are zero known bugs or issues with the recursor. It is known to power the resolving needs of over 2 million
      internet connections.
    </para>
    <para>
      The documentation below is only for the 3.0 series, users of older versions are urged to upgrade!
    </para>
    <para>
      Notable features:
      <itemizedlist>
	<listitem><para>
	    Uses MTasker (<ulink url="http://ds9a.nl/mtasker">homepage</ulink>)
	  </para></listitem>
	<listitem><para>
	    Can handle thousands of concurrent questions. A dual Xeon 3GHz has been measured functioning very well at 9000 real life replayed
	    packets per second, with 40% cpu idle. More testing equipment is needed to max out the recursor.
	  </para></listitem>
	<listitem><para>
	    Powered by a highly modern DNS packet parser that should be resistant against many forms of buffer overflows.
	  </para></listitem>
	<listitem><para>
	    Best spoofing protection that we know about, involving both source port randomisation and spoofing detection.
	  </para></listitem>
	<listitem><para>
	    Uses 'connected' UDP sockets which allow the recursor to react quickly to unreachable hosts or hosts for which 
	    the server is running, but the nameserver is down. This makes the recursor faster to respond in case of misconfigured domains,
	    which are sadly very frequent.
	  </para></listitem>
	<listitem><para>
	    Special support for FreeBSD, Linux and Solaris stateful multiplexing (kqueue, epoll, completion ports).
	  </para></listitem>
	<listitem><para>
	    Very fast, and contains innovative query-throttling code to save time talking to obsolete or broken nameservers.
	  </para></listitem>
	<listitem><para>
	    Code is written linearly, sequentially, which means that there are no problems with 'query restart' or anything.
	  </para></listitem>
	<listitem><para>
	    Relies heavily on Standard C++ Library infrastructure, which makes for little code (406 core lines).
	  </para></listitem>
	<listitem><para>
	    Is very verbose in showing how recursion actually works, when enabled to do so with --verbose.
	  </para></listitem>
	<listitem><para>
	    The algorithm is simple and quite nifty.
	  </para></listitem>
      </itemizedlist>
    </para>
    <para>
      The PowerDNS recursor is controlled and queried using the <filename>rec_control</filename> tool. 
    <sect1 id="recursor-settings"><title>pdns_recursor settings</title>
      <para>
	At startup, the recursing nameserver reads the file <filename>recursor.conf</filename> from the configuration directory,
	often <filename>/etc/powerdns</filename> or <filename>/usr/local/etc</filename>. Each setting below can appear on the command line,
	prefixed by '--', or in the configuration file. The command line overrides the configuration file.
      </para>
      <para>
	A switch can be set to on simply by passing it, like '--daemon', and turned off explicitly by '--daemon=off' or '--daemon=no'.
      </para>
      <para>
	The following settings can be configured:
	<variablelist>
	  <varlistentry>
	    <term>aaaa-additional-processing</term>
	    <listitem>
	      <para>
		If turned on, the recursor will attempt to add AAAA IPv6 records to questions for MX records and NS records.
		Can be quite slow as absence of these records in earlier answers does not guarantee their non-existance. Can double
		the amount of queries needed. Off by default.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>allow-from</term>
	    <listitem>
	      <para>
		Comma separated netmasks (both IPv4 and IPv6) that are allowed to use the server. The default allows access only from RFC 1918 
		private IP addresses, like 10.0.0.0/8. Due to the agressive nature of the internet these days, it is highly recommended
		to not open up the recursor for the entire internet. Questions from IP addresses not listed here are ignored and do 
		not get an answer.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>auth-can-lower-ttl</term>
	    <listitem>
	      <para>
		Authoritative zones can transmit a TTL value that is lower than that specified in the parent zone. This is called a
		'delegation inconsistency'. To follow RFC 2181 paragraphs 5.2 and 5.4 to the letter, enable this feature. 
		This will mean a slight deterioration of performance, and it will not solve any problems, but does make
		the recursor more standards compliant. Not recommended unless you have to tick an 'RFC 2181 compliant' box. Off by default.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>auth-zones</term>
	    <listitem>
	      <para>
		Comma separated list of 'zonename=filename' pairs. Zones read from these files are served authoritatively. Example:
		<command>auth-zones= ds9a.nl=/var/zones/ds9a.nl, powerdns.com=/var/zones/powerdns.com</command>. Available since 3.1.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry><term>chroot</term>
	    <listitem><para>
		If set, chroot to this directory for more security. See <xref linkend="security">.
	      </para></listitem></varlistentry>
	  <varlistentry>
	    <term>client-tcp-timeout</term>
	    <listitem>
	      <para>
	      Time to wait for data from TCP clients. Defaults to 2 seconds. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>config-dir</term>
	    <listitem>
	      <para>
		Directory where the configuration file can be found.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>daemon</term>
	    <listitem>
	      <para>
		Operate in the background, which is the default.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>delegation-only</term>
	    <listitem>
	      <para>
		A Verisign special.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>dont-query</term>
	    <listitem>
	      <para>
		The DNS is a public database, but sometimes contains delegations to private IP addresses, like for example 127.0.0.1. This can have odd effects, 
		depending on your network, and may even be a security risk. Therefore, since version 3.1.5, the PowerDNS recursor by default does not query
		private space IP addresses. This setting can be used to expand or reduce the limitations.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>export-etc-hosts</term>
	    <listitem>
	      <para>
		If set, this flag will export the host names and IP addresses mentioned in <filename>/etc/hosts</filename>. Available since 3.1.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>fork</term>
	    <listitem>
	      <para>
		If running on an SMP system with enough memory, this feature forks PowerDNS so it benefits from two processors. Experimental. Renames
		controlsockets, so care is needed to connect to the right one using <command>rec_control</command>, using <command>--socket-pid</command>.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>forward-zones</term>
	    <listitem>
	      <para>
		Comma separated list of 'zonename=IP' pairs. Queries for zones listed here will be forwarded to the IP address listed.
		<command>forward-zones= ds9a.nl=213.244.168.210, powerdns.com=127.0.0.1</command>. Available since 3.1.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>forward-zones-file</term>
	    <listitem>
	      <para>
		Same as <command>forward-zones</command>, parsed from a file. Only 1 zone is allowed per line, specified as follows:
		<command>ds9a.nl=213.244.168.210</command>. Available since 3.1.5.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>hint-file</term>
	    <listitem>
	      <para>
		If set, the root-hints are read from this file. If unset, default root hints are used. Available since 2.9.19.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>local-address</term>
	    <listitem>
	      <para>
		Local IPv4 or IPv6 addresses to bind to, comma separated. Defaults to only loopback. Addresses can also contain port numbers,
		for IPv4 specify like this: <command>1.2.3.4:5300</command>, for IPv6: <command>[::1]:5300</command>. Port specifications are available since
		3.1.2.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>local-port</term>
	    <listitem>
	      <para>
		Local port (singular) to bind to. Defaults to 53.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>log-common-errors</term>
	    <listitem>
	      <para>
		Some DNS errors occur rather frequently and are no cause for alarm. Logging these is on by default.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>logging-facility</term>
	    <listitem>
	      <para>
		If set to a digit, logging is performed under this LOCAL facility. See <xref linkend="syslog"/>. Available from 3.1.3 and onwards. Do not pass names like 'local0'!
	      </para>
	    </listitem>
	  </varlistentry>
	  

	  <varlistentry>
	    <term>max-cache-entries</term>
	    <listitem>
	      <para>
		Maximum number of cache entries. 1 million will generally suffice for most installations.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>max-negative-ttl</term>
	    <listitem>
	      <para>
		A query for which there is authoritatively no answer is cached to quickly deny a record's existence later on, without
		putting a heavy load on the remote server. In practice, caches can become saturated with hundreds of thousands of hosts
		which are tried only once. This setting, which defaults to 3600 seconds, puts a maximum on the amount of time negative
		entries are cached.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>max-tcp-clients</term>
	    <listitem>
	      <para>
	      Maximum number of simultaneous incoming TCP connections allowed. Defaults to 128. Available since 2.9.18. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>max-tcp-per-client</term>
	    <listitem>
	      <para>
	      Maximum number of simultaneous incoming TCP connections allowed per client (remote IP address). Defaults to 0, which means unlimited.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>query-local-address</term>
	    <listitem>
	      <para>
		Send out local queries from this address. Useful for anycast.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>query-local-address6</term>
	    <listitem>
	      <para>
		Send out local IPv6 queries from this address. Disabled by default, which also disables
		outgoing IPv6 support. A useful setting is <command>::0</command>.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>quiet</term>
	    <listitem>
	      <para>
		Don't log queries. On by default.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>remotes-ringbuffer-entries</term>
	    <listitem>
	      <para>
		Number of entries in the remotes ringbuffer, which keeps statistics on who is querying your server. Can be read out using
		<command>rec_control top-remotes</command>. Defaults to 0.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>serve-rfc1918</term>
	    <listitem>
	      <para>
		On by default, this makes the server authoritatively aware of: <filename>10.in-addr.arpa</filename>, 
		<filename>168.192.in-addr.arpa</filename>, <filename>16-31.172.in-addr.arpa</filename>, which saves
		load on the AS112 servers. Individual parts of these zones can still be loaded or forwarded.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>server-id</term>
	    <listitem>
	      <para>
		The PowerDNS recursor by replies to a query for 'id.server' with its hostname, useful for in clusters. Use this setting to override
		the answer it gives.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>setgid</term>
	    <term>setuid</term>
	    <listitem>
	      <para>
		PowerDNS can change its user and group id after binding to its socket. Can be used for better security.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>socket-dir</term>
	    <listitem>
	      <para>
		Where to store the control socket. This option also works with the controller, <command>rec_control</command>.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>spoof-nearmiss-max</term>
	    <listitem>
	      <para>
		If set to non-zero, PowerDNS will assume it is being spoofed after seeing this many answers with the wrong id. Defaults to 20.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>trace</term>
	    <listitem>
	      <para>
		If turned on, output impressive heaps of logging. May destroy performance under load.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>version</term>
	    <listitem>
	      <para>
		Print version of this binary. Useful for checking which version of the PowerDNS recursor is installed on a system. Available since 3.1.5.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>version-string</term>
	    <listitem>
	      <para>
		By default, PowerDNS replies to the 'version.bind' query with its version number. Security concious users may wish to override
		the reply PowerDNS issues.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      <para>
    </sect1>
    <sect1 id="rec-control"><title>Controlling and querying the recursor</title>
      <para>
	To control and query the PowerDNS recursor, the tool <filename>rec_control</filename> is provided. This program
	talks to the recursor over the 'controlsocket', often stored in <filename>/var/run</filename>.
      </para>
      <para>
	As a sample command, try:
	<screen>
	  # rec_control ping
	  pong
	</screen>
      </para>
      <para>
	When not running as root, <command>--socket-dir=/tmp</command> might be appropriate.
      </para>
	<para>
	  All rec_control commands are documented below:
	  <variablelist>
	    <varlistentry>
	      <term>dump-cache filename</term>
	      <listitem>
		<para>
		  Dumps the entire cache to the filename mentioned. This file should not exist already, PowerDNS
		  will refuse to overwrite it. While dumping, the recursor will not answer questions.
		</para>
	      </listitem>
	    </varlistentry>	  
	    <varlistentry>
	      <term>get statistic</term>
	      <listitem>
		<para>
		  Retrieve a statistic. For items that can be queried, see below.
		</para>
	      </listitem>
	    </varlistentry>	  
	    <varlistentry>
	      <term>ping</term>
	      <listitem>
		<para>
		  Check if server is alive.
		</para>
	      </listitem>
	    </varlistentry>	  
	    <varlistentry>
	      <term>quit</term>
	      <listitem>
		<para>
		  Request shutdown of the recursor.
		</para>
	      </listitem>
	    </varlistentry>	  
	    <varlistentry>
	      <term>reload-zones</term>
	      <listitem>
		<para>
		Reload data about all authoritative and forward zones. The configuration file is also scanned 
		to see if the <command>auth-domain</command>, <command>forward-domain</command> and <command>export-etc-hosts</command>
		statements have changed, and if so, these changes are incorporated.
		</para>
	      </listitem>
	    </varlistentry>	  
	    <varlistentry>
	      <term>top-remotes</term>
	      <listitem>
		<para>
		  Shows the top-20 most active remote hosts. Statistics are over the last 'remotes-ringbuffer-entries' queries, which
		  defaults to 0.
		</para>
	      </listitem>
	    </varlistentry>	  
	    <varlistentry>
	      <term>wipe-cache domain0. [domain1. domain2.]</term>
	      <listitem>
		<para>
		  Wipe entries from the cache. This is useful if, for example, an important server has a new IP address, but the TTL has not
		  yet expired. Multiple domain names can be passed. For versions before 3.1, you must terminate a domain with a .! So to wipe powerdns.org,
		  issue 'rec_control wipe-cache powerdns.org.'. For later versions, the dot is optional. 
		</para>
		<para>
		  Note that deletion is exact, wiping 'com.' will leave 'www.powerdns.com.' untouched!
		</para>
		<para>
		  <warning>
		    <para>
		    In PowerDNS versions 3.0.0 and 3.0.1 this command is slightly buggy and might cause your nameserver to crash if the first
		    query after wiping the cache is for the domain you just wiped.
		    </para>
		  </warning>
		  <warning>
		    <para>
		    Don't just wipe 'www.somedomain.com', its NS records or CNAME target may still be undesired, so wipe 'somedomain.com' as well.
		    </para>
		  </warning>
		</para>
	      </listitem>
	    </varlistentry>	  
	  </variablelist>
	</para>
	<para>
	  The command 'get' can query a large number of statistics, which are detailed in <xref linkend="recursor-stats">.

	</para>
	<para>
	  More details on what 'throttled' queries and the like are can be found below in <xref linkend="recursor-details">.
	</para>
    </sect1>
    <sect1 id="recursor-performance"><title>PowerDNS Recursor performance</title>
      <para>
	To get the best out of the PowerDNS recursor, which is important if you are doing thousands of queries per second, please 
	consider the following. 
	<itemizedlist>
	  <listitem>
	    <para>
	      Limit the size of the cache to a sensible value. Cache hit rate does not improve meaningfully beyond 4 million <command>max-cache-entries</command>,
	      reducing the memory footprint reduces CPU cache misses.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Compile using g++ 4.1 or later. This compiler really does a good job on PowerDNS, much better than 3.4 or 4.0.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Consider performing a 'profiled build' as described in the README. This is good for a 20% performance boost in some cases.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      When running with &gt;3000 queries per second, and running Linux versions prior to 2.6.17 on some motherboards, your computer may 
	      spend an inordinate amount of time working around an ACPI bug for each call to gettimeofday. This is solved by rebooting with 'clock=tsc'
	      or upgrading to a 2.6.17 kernel.
	    </para>
	    <para>
	      The above is relevant if dmesg shows <command>Using pmtmr for high-res timesource</command>
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      A busy server may need hundreds of file descriptors on startup, and deals with spikes better if it has that many available
	      later on. Linux by default restricts processes to 1024 file descriptors, which should suffice most of the time, but Solaris
	      has a default limit of 256. This can be raised using the ulimit command. FreeBSD has a default limit that is high enough for even
	      very heavy duty use.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      If you need it, try <command>--fork</command>, this will fork the daemon into two halves, allowing it to benefit from a second CPU.
	      This feature almost doubles performance, but is a bit of a hack. 
	    </para>
	  </listitem>
	</itemizedlist>
	Following the instructions above, you should be able to attain very high query rates.
      </para>
    </sect1>
    <sect1 id="recursor-details"><title>Details</title>
      <sect2 id="anti-spoofing"><title>Anti-spoofing</title>
	<para>
	  The PowerDNS recursor 3.0 uses a fresh UDP source port for each outgoing query, making spoofing around 64000 times harder. This 
	  raises the bar from 'easily doable given some time' to 'very hard'. Under some circimstances, 'some time' has been measured at 2 seconds. 
	  This technique was first used by <filename>dnscache</filename> by Dan J. Bernstein.
	</para>
	<para>
	  In addition, PowerDNS detects when it is being sent too many unexpected answers, and mistrusts a proper answer if found within
	  a clutch of unexpected ones.
	</para>
	<para>
	  This behaviour can be tuned using the <command>spoof-nearmiss-max</command>.
	</para>
      </sect2>
      <sect2><title>Throttling</title>
	<para>
	  PowerDNS implements a very simple but effective nameserver. Care has been taken not to overload remote servers in case
	  of overly active clients.
	</para>
	<para>
	  This is implemented using the 'throttle'. This accounts all recent traffic and prevents queries that have been sent out
	  recently from going out again.
	</para>
	<para>
	  There are three levels of throttling.
	  <itemizedlist>
	    <listitem>
	      <para>
		If a remote server indicates that it is lame for a zone, the exact question won't
		be repeated in the next 60 seconds.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		After 4 ServFail responses in 60 seconds, the query gets throttled too.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		5 timeouts in 20 seconds also lead to query suppression.
	      </para>
	    </listitem>
	  </itemizedlist>
	</para>
      </sect2>

    </sect1>
    <sect1 id="recursor-stats"><title>Statistics</title>
      <para>
	The <command>rec_control get</command> command can be used to query the following keys, either single keys or multiple keys 
	at once:
	  <screen>
all-outqueries      counts the number of outgoing UDP queries since starting
answers0-1          counts the number of queries answered within 1 milisecond
answers100-1000     counts the number of queries answered within 1 second
answers10-100       counts the number of queries answered within 100 miliseconds
answers1-10         counts the number of queries answered within 10 miliseconds
answers-slow        counts the number of queries answered after 1 second
cache-entries       shows the number of entries in the cache
cache-hits          counts the number of cache hits since starting
cache-misses        counts the number of cache misses since starting
chain-resends       number of queries chained to existing outstanding query
client-parse-errors counts number of client packets that could not be parsed
concurrent-queries  shows the number of MThreads currently running
dlg-only-drops      number of records dropped because of delegation only setting
negcache-entries    shows the number of entries in the Negative answer cache
noerror-answers     counts the number of times it answered NOERROR since starting
nsspeeds-entries    shows the number of entries in the NS speeds map
nsset-invalidations number of times an nsset was dropped because it no longer worked
nxdomain-answers    counts the number of times it answered NXDOMAIN since starting
outgoing-timeouts   counts the number of timeouts on outgoing UDP queries since starting
qa-latency          shows the current latency average
questions           counts all End-user initiated queries with the RD bit set
resource-limits     counts number of queries that could not be performed because of resource limits
server-parse-errors counts number of server replied packets that could not be parsed
servfail-answers    counts the number of times it answered SERVFAIL since starting
spoof-prevents      number of times PowerDNS considered itself spoofed, and dropped the data
sys-msec            number of CPU milliseconds spent in 'system' mode
tcp-client-overflow number of times an IP address was denied TCP access because it already had too many connections
tcp-outqueries      counts the number of outgoing TCP queries since starting
tcp-questions       counts all incoming TCP queries (since starting)
throttled-out       counts the number of throttled outgoing UDP queries since starting
throttle-entries    shows the number of entries in the throttle map
unauthorized-tcp    number of TCP questions denied because of allow-from restrictions
unauthorized-udp    number of UDP questions denied because of allow-from restrictions
unexpected-packets  number of answers from remote servers that were unexpected (might point to spoofing)
uptime              number of seconds process has been running (since 3.1.5)
user-msec           number of CPU milliseconds spent in 'user' mode
	  </screen>
	In the <filename>rrd/</filename> subdirectory a number of rrdtool scripts is provided to make nice
	graphs of all these numbers.
      </para>
      <para>
	Every half our or so, the recursor outputs a line with statistics. More infrastructure is planned so as to allow
	for Cricket or MRTG graphs. To force the output of statistics, send the process a SIGUSR1. A line of statistics looks 
	like this:
<screen>
Feb 10 14:16:03 stats: 125784 questions, 13971 cache entries, 309 negative entries, 84% cache hits, outpacket/query ratio 37%, 12% throttled
</screen>
	This means that there are 13791 different names cached, which each may have multiple records attached to them. There are 309 items
	in the negative cache, items of which it is known that don't exist and won't do so for the near future. 84% of incoming questions
	could be answered without any additional queries going out to the net.
      </para>
      <para>
	The outpacket/query ratio means that on average, 0.37 packets were needed to answer a question. Initially this ratio may be well over 100%
	as additional queries may be needed to actually recurse the DNS and figure out the addresses of nameservers.
      </para>
      <para>
	Finally, 12% of queries were not performed because identical queries had gone out previously, saving load servers worldwide.
      </para>
    </sect1>
    <sect1 id="recursor-design-and-engineering">
      <title>Design and Engineering of the PowerDNS Recursor</title>
      <para>
	<warning>
	  <para>
	    This section is aimed at programmers wanting to contibute to the recursor, or to help fix bugs. It is not required
	    reading for a PowerDNS operator, although it might prove interesting.
	  </para>
	</warning>
      </para>
      <para>The PowerDNS Recursor consists of very little code, the core DNS logic is less than a thousand lines.</para>
	  
	  <para>This smallness is achieved through the use of some fine infrastructure: MTasker, MOADNSParser, MPlexer and the C++ Standard Library/Boost. This page will explain the conceptual relation between these components, and the route of a packet through the program.</para>
	  
      <sect2>
	<title>The PowerDNS Recursor</title>
	<para>The Recursor started out as a tiny project, mostly a technology demonstration. These days it  consists of the core plus 9000 lines of features. This combined with a need for very high performance has made the recursor code less accessible than it was. The page you are reading hopes to rectify this situation.</para>
	
      </sect2>
      <sect2>
	<title>Synchronous code using MTasker</title>
	<para>The original name of the program was <command>syncres</command>, which is still reflected in the filename <literal>syncres.cc</literal>, and the class SyncRes. This means that PowerDNS is written naively, with one thread of execution per query, synchronously waiting for packets, Normally this would lead to very bad performance (unless running on a computer with very fast threading, like possibly the Sun CoolThreads family), so PowerDNS employs <ulink url="http://ds9a.nl/mtasker">MTasker</ulink> for very fast userspace threading.</para>
	
	<para>MTasker, which was developed separately from PowerDNS, does not provide a full multithreading system but restricts itself to those features a nameserver needs. It offers cooperative multitasking, which means there is no forced preemption of threads. This in turn means that no two <command>MThreads</command> ever really run at the same time.</para>
	
	<para>This is both good and bad, but mostly good. It means PowerDNS does not have to think about locking. No two threads will ever be talking to the DNS cache at the same time, for example.</para>
	
	<para>It also means that the recursor could block if any operation takes too long.</para>
	
	<para>The core interaction with MTasker are the waitEvent() and sendEvent() functions. These pass around PacketID objects. Everything PowerDNS needs to wait for is described by a PacketID event, so the name is a bit misleading. Waiting for a TCP socket to have data available is also passed via a PacketID, for example.</para>
	
	<para>The version of MTasker in PowerDNS is newer than that described at the MTasker site, with a vital difference being that thet waitEvent() structure passes along a copy of the exact PacketID sendEvent() transmitted. Furthermore, threads can trawl through the list of events being waited for and modify the respective PacketIDs. This is used for example with <command>near miss</command> packets: packets that appear to answer questions we asked, but differ in the DNS id. On seeing such a packet, the recursor trawls through all PacketIDs and if it finds any nearmisses, it updates the PacketID::nearMisses counter. The actual PacketID thus lives inside MTasker while any thread is waiting for it.</para>
	
      </sect2>
      <sect2>
	<title>MPlexer</title>
	<para>The Recursor uses a separate socket per outgoing query. This has the important benefit of making spoofing 64000 times harder, and additionally means that ICMP errors are reported back to the program. In measurements this appears to happen to one in ten queries, which would otherwise take a two-second timeout before PowerDNS moves on to another nameserver.</para>
	
	<para>However, this means that the program routinely needs to wait on hundreds or even thousands of sockets. Different operating systems offer various ways to monitor the state of sockets or more generally, filedescriptors. To abstract out the differing strategies (<function>select</function>, <function>epoll</function>, <function>kqueue</function>, <function>completion ports</function>), PowerDNS contains <command>MPlexer</command> classes, all of which descend from the FDMultiplexer class.</para>
	
	<para>This class is very simple and offers only five important methods: addReadFD(), addWriteFD(), removeReadFD(), removeWriteFD() and run.</para>
	
	<para>The arguments to the <command>add</command> functions consist of an fd, a callback, and a boost::any variable that is passed as a reference to the callback.</para>
	
	<para>This might remind you of the MTasker above, and it is indeed the same trick: state is stored within the MPlexer. As long as a filedescriptor remains within either the Read or Write active list, its state will remain stored.</para>
	
	<para>On arrival of a packet (or more generally, when an FD becomes readable or writable, which for example might mean a new TCP connection), the callback is called with the aforementioned reference to its parameter.</para>
	
	<para>The callback is free to call removeReadFD() or removeWriteFD() to remove itself from the active list.</para>
	
	<para>PowerDNS defines such callbacks as newUDPQuestion(), newTCPConnection(), handleRunningTCPConnection().</para>
	
	<para>Finally, the run() method needs to be called whenever the program is ready for new data. This happens in the main loop in pdns_recursor.cc. This loop is what MTasker refers to as <command>the kernel</command>. In this loop, any packets or other MPlexer events get translated either into new MThreads within MTasker, or into calls to sendEvent(), which in turn wakes up other MThreads.</para>
	
      </sect2>
      <sect2>
	<title>MOADNSParser</title>
	<para>Yes, this does stand for <command>the Mother of All DNS Parsers</command>. And even that name does not do it justice! The MOADNSParser is the third attempt I've made at writing DNS packet parser and after two miserable failures, I think I've finally gotten it right.</para>
	
	<para>Writing and parsing DNS packets, and the DNS records it contains, consists of four things:
	  <orderedlist>
	    <listitem>
	      <para>
		Parsing a DNS record (from packet) into memory
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Generating a DNS record from memory (to packet)
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Writing out memory to user-readable zone format
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		Reading said zone format into memory
	      </para>
	    </listitem>
	  </orderedlist>
	</para>

	<para>This gets tedious very quickly, as one needs to implement all four operations for each new record type, and there are dozens of them.</para>
	
	<para>While writing the MOADNSParser, it was discovered there is a remarkable symmetry between these four transitions. DNS Records are nearly always laid out in the same order in memory as in their zone format representation. And reading is nothing but inverse writing.</para>
	
	<para>So, the MOADNSParser is built around the notion of a <command>Conversion</command>, and we write all Conversion types once. So we have a Conversion from IP address in memory to an IP address in a DNS packet, and vice versa. And we have a Conversion from an IP address in zone format to memory, and vice versa.</para>
	
	<para>This in turn means that the entire implementation of the ARecordContent is as follows (wait for it!)</para>
	
	<literallayout class="monospaced">conv.xfrIP(d_ip);</literallayout>
	<para>Through the use of the magic called <literal>c++ Templates</literal>, this one line does everything needed to perform the four operations mentioned above.</para>
	
	<para>At one point, I got really obsessed with PowerDNS memory use. So, how do we store DNS data in the PowerDNS recorsor? I mentioned <command>memory</command> above a lot - this means we could just store the DNSRecordContent objects. However, this would be wasteful.</para>
	
	<para>For example, storing the following:</para>
	
	<literallayout class="monospaced">www.ds9a.nl  3600 IN   CNAME  outpost.ds9a.nl.</literallayout>
	<para>Would duplicate a lot of data. So, what is actually stored is a partial DNS packet. To store the CNAMEDNSRecordContent that corresponds to the above, we generate a DNS packet that has <command>www.ds9a.nl IN CNAME</command> as its question. Then we add <command>3600 IN CNAME outpost.ds9a.nl</command>. as its answer. Then we chop off the question part, and store the rest in the <command>www.ds9a.nl IN CNAME</command> key in our cache.</para>
	
	<para>When we need to retrieve <command>www.ds9a.nl IN CNAME</command>, the inverse happens. We find the proper partial packet, prefix it with a question for <command>www.ds9a.nl IN CNAME</command>, and expand the resulting packet into the answer <command>3600 IN CNAME outpost.ds9a.nl.</command>.</para>
	
	<para>Why do we go through all these motions? Because of DNS compression, which allows us to omit the whole <command>.ds9a.nl.</command> part, saving us 9 bytes. This is amplified when storing multiple MX records which all look more or less alike. This optimization is not performed yet though.</para>
	
	<para>Even without compression, it makes sense as all records are automatically stored very compactly.</para>
	
	<para>The PowerDNS recursor only parses a number of <command>well known record types</command> and passes all other information across verbatim - it doesn't have to know about the content it is serving.</para>
	
      </sect2>
      <sect2>
	<title>The C++ Standard Library / Boost</title>
	<para>C++ is a powerful language. Perhaps a bit too powerful at times, you can turn a program into a real freakshow if you so desire.</para>
	
	<para>PowerDNS generally tries not to go overboard in this respect, but we do build upon a very advanced part of the <ulink url="http://www.boost.org">Boost</ulink> C++ library: 
	  <ulink url="http://boost.org/libs/multi_index/doc/index.html">boost::multi index container</ulink>.</para>
	
	<para>This container provides the equivalent of SQL indexes on multiple keys. It also implements compound keys, which PowerDNS uses as well.</para>
	
	<para>The main DNS cache is implemented as a multi index container object, with a compound key on the name and type of a record. Furthermore, the cache is sequenced, each time a record is accessed it is moved to the end of the list. When cleanup is performed, we start at the beginning. New records also get inserted at the end. For DNS correctness, the sort order of the cache is case insensitive.</para>
	
	<para>The multi index container appears in other parts of PowerDNS, and MTasker as well.</para>
	
      </sect2>
      <sect2>
	<title>Actual DNS Algorithm</title>
	<para>The DNS rfcs do define the DNS algorithm, but you can't actually implement it exactly that way, it was written in 1987.</para>
	
	<para>Also, like what happened to HTML, it is expected that even non-standards conforming domains work, and a sizeable fraction of them is misconfigured these days.</para>
	
	<para>Everything begins with SyncRes::beginResolve(), which knows nothing about sockets, and needs to be passed a domain name, dns type and dns class which we are interested in. It returns a vector of DNSResourceRecord objects, ready for writing either into an answer packet, or for internal use.</para>
	
	<para>After checking if the query is for any of the hardcoded domains (localhost, version.bind, id.server), the query is passed to SyncRes::doResolve, together with two vital parameters: the <literal>depth</literal> and <literal>beenthere</literal> set. As the word <command>recursor</command> implies, we will need to recurse for answers. The <command>depth</command> parameter documents how deep we've recursed already.</para>
	
	<para>The <literal>beenthere</literal> set prevents loops. At each step, when a nameserver is queried, it is added to the <literal>beenthere</literal> set. No nameserver in the set will ever be queried again for the same question in the recursion process - we know for a fact it won't help us further. This prevents the process from getting stuck in loops.</para>
	
	<para>SyncRes::doResolve first checks if there is a CNAME in cache, using SyncRes::doCNAMECacheCheck, for the domain name and type queried and if so, changes the query (which is passed by reference) to the domain the CNAME points to. This is the cause of many DNS problems, a CNAME record really means <command>start over with this query</command>.</para>
	
	<para>This is followed by a call do SyncRes::doCacheCheck, which consults the cache for a straight answer to the question (as possibly rerouted by a CNAME). This function also consults the so called negative cache, but we won't go into that just yet.</para>
	
	<para>If this function finds the correct answer, and the answer hasn't expired yet, it gets returned and we are (almost) done. This happens in 80 to 90% of all queries. Which is good, as what follows is a lot of work.</para>
	
	<para>To recap:
	  <orderedlist>
	    <listitem>
	      <para>
		beginResolve() - entry point, does checks for hardcoded domains
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		doResolve() - start of recursion process, gets passed <literal>depth</literal> of 0 and empty <literal>beenthere</literal> set
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		doCNAMECacheCheck() - check if there is a CNAME in cache which would reroute the query
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		doCacheCheck() - see if cache contains straight answer to possibly rerouted query.
	      </para>
	    </listitem>
	  </orderedlist>
	</para>
	<para>If the data we were queried for was in the cache, we are almost done. One final step, which might as well be optional as nobody benefits from it, is SyncRes::addCruft. This function does additional processing, which means that if the query was for the MX record of a domain, we also add the IP address of the mail exchanger.</para>
	
      </sect2>
      <sect2>
	<title>The non-cached case</title>
	<para>This is where things get interesting, because we start out with a nearly empty cache and have to go out to the net to get answers to fill it.</para>
	
	<para>The way DNS works, if you don't know the answer to a question, you find somebody who does. Initially you have no other place to go than the root servers. This is embodied in the SyncRes::getBestNSNamesFromCache method, which gets passed the domain we are interested in, as well as the <literal>depth</literal> and <literal>beenthere</literal> parameters mentioned earlier.</para>
	
	<para>From now on, assume our query will be for <command><literal>www.powerdns.com.</literal></command>. SyncRes::getBestNSNamesFromCache will first check if there are NS records in cache for <literal><command>www.powerdns.com.</command></literal>, but there won't be. It then checks <literal>powerdns.com. NS</literal>, and while these records do exist on the internet, the recursor doesn't know about them yet. So, we go on to check the cache for <literal><command>com. NS</command></literal>, for which the same holds. Finally we end up checking for <literal><command>. NS</command></literal>, and these we do know about: they are the root servers and were loaded into PowerDNS on startup.</para>
	
	<para>So, SyncRes::getBestNSNamesFromCache fills out a set with the <command>names</command> of nameservers it knows about for the <command><literal>.</literal></command> zone.</para>
	
	<para>This set, together with the original query <command><literal>www.powerdns.com</literal></command> gets passed to SyncRes::doResolveAt. This function can't yet go to work immediately though, it only knows the names of nameservers it can try. This is like asking for directions and instead of hearing <command>take the third right</command> you are told <command>go to 123 Fifth Avenue, and take a right</command> - the answer doesn't help you further unless you know where 123 Fifth Avenue is.</para>
	
	<para>SyncRes::doResolveAt first shuffles the nameservers both randomly and on performance order. If it knows a nameserver was fast in the past, it will get queried first. More about this later.</para>
	
	<para>Ok, here is the part where things get a bit scary. How does SyncRes::doResolveAt find the IP address of a nameserver? Well, by calling SyncRes::getAs (<command>get A records</command>), which in turn calls.. SyncRes::doResolve. Hang on! That's where we came from! Massive potential for loops here. Well, it turns out that for any domain which can be resolved, this loop terminates. We do pass the <literal>beenthere</literal> set again, which makes sure we don't keep on asking the same questions to the same nameservers.</para>
	
	<para>Ok, SyncRes::getAs will give us the IP addresses of the chosen root-server, because these IP addresses were loaded on startup. We then ask these IP addresses (nameservers can have several) for its best answer for <command><literal>www.powerdns.com.</literal></command>. This is done using the LWRes class and specifically LWRes::asyncresolve, which gets passed domain name, type and IP address. This function interacts with MTasker and MPlexer above in ways which needn't concern us now. When it returns, the LWRes object contains the best answers the queried server had for our domain, which in this case means it tells us about the nameservers of <literal>com.</literal>, and their IP addresses.</para>
	
	<para>All the relevant answers it gives are stored in the cache (or actually, merged), after which SyncRes::doResolveAt (which we are still in) evaluates what to do now.</para>
	
	<para>There are 6 options:
	  <orderedlist>
	    <listitem>
	      <para>
		The final answer is in, we are done, return to SyncRes::doResolve and SyncRes::beginResolve
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The nameserver we queried tells us the domain we asked for authoritatively does not exist. In case of the root-servers, this happens when we query for <emphasis><literal>www.powerdns.kom.</literal></emphasis> for example, there is no <emphasis><literal>kom.</literal></emphasis>. Return to SyncRes::beginResolve, we are done.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		A lesser form - it tells us it is authoritative for the query we asked about, but there is no record matching our type. This happens when querying for the IPv6 address of a host which only has an IPv4 address. Return to SyncRes::beginResolve, we are done.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The nameserver passed us a CNAME to another domain, and we need to reroute. Go to SyncRes::doResolve for the new domain.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The namserver did not know about the domain, but does know who does, a <emphasis>referral</emphasis>. Stay within doResolveAt and loop to these new nameservers.
	      </para>
	    </listitem>
	    <listitem>
	      <para>
		The nameserver replied saying <emphasis>no idea</emphasis>. This is called a <emphasis>lame delegation</emphasis>. Stay within SyncRes::doResolveAt and try the other nameservers we have for this domain.
	      </para>
	    </listitem>
	  </orderedlist>
	</para>
	<para>When not redirected using a CNAME, this function will loop until it has exhausted all nameservers and all their IP addresses. DNS is surprisingly resilient that there is often only a single non-broken nameserver left to answer queries, and we need to be prepared for that.</para>
	
	<para>This is the whole DNS algorithm in PowerDNS, all in less than 700 lines of code. It contains a lot of tricky bits though, related to the cache.</para>
	
      </sect2>
      <sect2>
	<title>Some of the things we glossed over</title>
	<para>Whenever a packet is sent to a remote nameserver, the response time is stored in the SyncRes::s_nsSpeeds map, using an exponentially weighted moving average. This EWMA averages out different response times, and also makes them decrease over time. This means that a nameserver that hasn't been queried recently gradually becomes <command>faster</command> in the eyes of PowerDNS, giving it a chance again.</para>
	
	<para>A timeout is accounted as a 1s response time, which should take that server out of the running for a while.</para>
	
	<para>Furthermore, queries are throttled. This means that each query to a nameserver that has failed is accounted in the <literal>s_throttle</literal> object. Before performing a new query, the query and the nameserver are looked up via shouldThrottle. If so, the query is assumed to have failed without even being performed. This saves a lot of network traffic and makes PowerDNS quick to respond to lame servers.</para>
	
	<para>It also offers a modicum of protection against birthday attack powered spoofing attempts, as PowerDNS will not innundate a broken server with queries.</para>
	
	<para>The negative query cache we mentioned earlier caches the cases 2 and 3 in the enumeration above. This data needs to be stored separately, as it represents <command>non-data</command>. Each negcache query entry is the name of the SOA record that was presented with the evidence of non-existance. This SOA record is then retrieved from the regular cache, but with the TTL that originally came with the NXDOMAIN (case 2) or NXRRSET (case 3).</para>
	
      </sect2>
      <sect2>
	<title>The Recursor Cache</title>
	<para>As mentioned before, the cache stores partial packets. It also stores not the <command>Time To Live</command> of records, but in fact the <command>Time To Die</command>. If the cache contains data, but it is expired, that data should not be deemed present. This bit of PowerDNS has proven tricky, leading to deadlocks in the past.</para>
	
	<para>There are some other very tricky things to deal with. For example, through a process called <command>more details</command>, a domain might have more nameservers than listed in its parent zone. So, there might only be two nameservers for <literal><command>powerdns.com.</command></literal> in the <command><literal>com.</literal></command> zone, but the <command><literal>powerdns.com</literal></command> zone might list more.</para>
	
	<para>This means that the cache should not, when talking to the <command><literal>com.</literal></command> servers later on, overwrite these four nameservers with only the two copies the <command><literal>com.</literal></command> servers pass us.</para>
	
	<para>However, in other cases (like for example for SOA and CNAME records), new data should overwrite old data.</para>
	<para>Note that PowerDNS deviates from RFC 2181 (section 5.4.1) in this respect.</para>
	
      </sect2>
      <sect2>
	<title>Some small things</title>
	<para>The server-side part of PowerDNS (<literal>pdns_recursor.cc</literal>), which listens to queries by end-users, is fully IPv6 capable using the ComboAddress class. This class is in fact a union of a <literal>struct sockaddr_in</literal> and a <literal>struct sockaddr_in6</literal>. As long as the <literal>sin_family</literal> (or <literal>sin6_family</literal>) and <literal>sin_port</literal> members are in the same place, this works just fine, allowing us to pass a ComboAddress*, cast to a <literal>sockaddr*</literal> to the socket functions. For convenience, the ComboAddress also offers a length() method which can be used to indicate the length - either sizeof(sockaddr_in) or sizeof(sockaddr_in6).</para>
	
	<para>Access to the recursor is governed through the NetmaskGroup class, which internally contains Netmaks, which in turn contain a ComboAddress.</para>
      </sect2>
    </sect1>
  </chapter>
  <chapter id="replication"><title>Master/Slave operation &amp; replication</title>

    <para>
      PDNS offers full master and slave semantics for replicating domain information. Furthermore, PDNS can benefit from native
      database replication.
    </para>
    <sect1 id="native-replication"><title>Native replication</title>
      <para>
	Native replication is the default, unless other operation is specifically configured. Native replication basically means that PDNS will
	not send out DNS update notifications, nor will react to them. PDNS assumes that the backend is taking care of replication unaided.
      </para>
      <para>
	MySQL replication has proven to be very robust and well suited, even over transatlantic connections between badly peering ISPs. Other PDNS
	users employ Oracle replication which also works very well.
      </para>
      <para>
	To use native replication, configure your backend storage to do the replication and do not configure PDNS to do so.
      </para>
    </sect1>
    <sect1 id="slave"><title>Slave operation</title>
      <para>
	On launch, PDNS requests from all backends a list of domains which have not been checked recently for changes. This should happen every 
	'<command>refresh</command>' seconds, as specified in the SOA record. All domains that are unfresh are then checked for changes over at their
	master. If the <link linkend="soa-type">SOA</link> serial number there is higher, the domain is retrieved and inserted into the database. In 
	any case, after the check the domain is declared 'fresh', and will only be checked again after '<command>refresh</command>' seconds have passed.
      </para>
      <para>
	<warning>
	  <para>
	    Slave support is OFF by default, turn it on by adding <command>slave</command> to the configuration. The same 
	    holds for master operation. Both can be on simultaneously.
	  </para>
	</warning>
      </para>

      <para>
	PDNS also reacts to notifies by immediately checking if the zone has updated and if so, retransfering it.
      </para>
      <para>
	All backends which implement this feature must make sure that they can handle transactions so as to not leave the zone in a half updated state. 
	MySQL configured with either BerkeleyDB or InnoDB meets this requirement, as do PostgreSQL and Oracle. The Bindbackend implements transaction
	semantics by renaming files if and only if they have been retrieved completely and parsed correctly.
      </para>
      <para>
	Slave operation can also be programmed using several pdns_control commands, see <xref linkend="pdnscontrol">. The 'retrieve' command
	is especially useful as it triggers an immediate retrieval of the zone from the configured master.
      </para>
      <para>
	Since 2.9.21, PowerDNS supports multiple masters. For the BIND backend, the native BIND configuration language suffices to specify
	multiple masters, for SQL based backends, list all master servers separated by commas in the 'master' field of the domains table.
      </para>
      <sect2 id=supermaster><title>Supermaster automatic provisioning of slaves</title>
	<para>
	  PDNS can recognize so called 'supermasters'. A supermaster is a host which is master for domains and for which we are to be a slave. When
	  a master (re)loads a domain, it sends out a notification to its slaves. Normally, such a notification is only accepted if PDNS already 
	  knows that it is a slave for a domain.
	</para>
	<para>
	  However, a notification from a supermaster carries more persuasion. When PDNS determines that a notification comes from a supermaster and it 
	  is bonafide, PDNS can provision the domain automatically, and configure itself as a slave for that zone.
	</para>
	<para>
	  To enable this feature, a backend needs to know about the IP address of the supermaster, and how PDNS will be listed in the set of
	  NS records remotely, and the 'account' name of your supermaster. There is no need to fill this out but it does help keep track of
	  where a domain comes from.
	</para>
      </sect2>
    </sect1>

    <sect1 id="master"><title>Master operation</title>
      <para>
	When operating as a master, PDNS sends out notifications of changes to slaves, which react to these notifications by querying PDNS to see
	if the zone changed, and transferring its contents if it has. Notifications are a way to promptly propagate zone changes to slaves, as 
	described in RFC 1996.
      </para>
      <para>
	<warning>
	  <para>
	    Master support is OFF by default, turn it on by adding <command>master</command> to the configuration. The same 
	    holds for slave operation. Both can be on simultaneously.
	  </para>
	</warning>
      </para>

      <para>
	Left open by RFC 1996 is who is to be notified - which is harder to figure out than it sounds. All slaves for this domain must receive a notification
	but the nameserver only knows the names of the slaves - not the IP addresses, which is where the problem lies. The nameserver itself might
	be authoritative for the name of its secondary, but not have the data available.
      </para>
      <para>
	To resolve this issue, PDNS tries multiple tactics to figure out the IP addresses of the slaves, and notifies everybody. In contrived configurations
	this may lead to duplicate notifications being sent out, which shouldn't hurt.
      </para>
      <para>
	Some backends may be able to detect zone changes, others may chose to let the operator indicate which zones have changed and which haven't.
	Consult the documentation for your backend to see how it processes changes in zones.
      </para>
      <para>
	To help deal with slaves that may have missed notifications, or have failed to respond to them, several override commands are available via 
	the pdns_control tool (<xref linkend="pdnscontrol">):
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>pdns_control notify <command>domain</command></term>
	    <listitem>
	      <para>
		This instructs PDNS to notify all IP addresses it considers to be slaves of this domain. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>pdns_control notify-host <command>domain ip-address</command></term>
	    <listitem>
	      <para>
		This is truly an override and sends a notification to an arbitrary IP address. Can be used in 'also-notify' situations
		or when PDNS has trouble figuring out who to notify - which may happen in contrived configurations.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>
  </chapter>
  <chapter id="fancy-records"><title>Fancy records for seamless email and URL integration</title>

    <para>
      PDNS also supports so called 'fancy' records. A Fancy Record is actually not a DNS record, but it is translated into one. Currently,
      two fancy records are implemented, but not very useful without additional unreleased software. For completeness, they are listed here.
      The software will become available later on and is part of the Express and PowerMail suite of programs.
    </para>
    <para>
      These records imply extra database lookups which has a performance impact. Therefore fancy records are only queried for if they are enabled
      with the <command>fancy-records</command> command in <filename>pdns.conf</filename>. 
    </para>
    <para>
      <variablelist>
	<varlistentry>
	  <term>MBOXFW</term>
	  <listitem>
	    <para>
	      This record denotes an email forward. A typical entry looks like this:
	      <screen>
		support@yourdomain.com     MBOXFW       you@yourcompany.com
	      </screen>
	      When PDNS encounters a request for an MX record for yourdomain.com it will, if fancy records are enabled, also check for the existence
	      of an MBOXFW record ending on '@yourdomain.com', in which case it will hand out a record containing the configured 
	      <command>smtpredirector</command>. This server should then also be able to access the PDNS database to figure out where mail to 
	      support@yourdomain.com should go to.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>URL</term>
	  <listitem>
	    <para>
	      URL records work in much the same way, but for HTTP. A sample record:
	      <screen>
		yourdomain.com     URL       http://somewhere.else.com/yourdomain
	      </screen>
	      A URL record is converted into an A record containing the IP address configured with the <command>urlredirector</command>
	      setting. On that IP address a webserver should live that knows how to redirect yourdomain.com to 
	      http://somewhere.else.com/yourdomain.
	    </para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </para>
  </chapter>
  <chapter id="all-settings"><title>Index of all settings</title>
    <para>
      All PDNS settings are listed here, excluding those that originate from backends, which are documented in the relevant chapters.
      <variablelist>
	<varlistentry>
	  <term><anchor id="allow-axfr-ips">allow-axfr-ips=...</term>
	  <listitem>
	    <para>Behaviour pre 2.9.10: When not allowing AXFR (disable-axfr), DO allow from these IP addresses or netmasks.
	    </para>
	    <para>Behaviour post 2.9.10: If set, only these IP addresses or netmasks will be able to perform AXFR.
	    </para>
	  </listitem></varlistentry>
	<varlistentry>
	  <term>allow-recursion=...</term>
	  <listitem>
	    <para>
	      By specifying <command>allow-recursion</command>, recursion can be restricted to netmasks specified. The default is to allow
	      recursion from everywhere. Example: <command>allow-recursion=192.168.0.0/24, 10.0.0.0/8, 1.2.3.4</command>.
	    </para>
	  </listitem></varlistentry>
	<varlistentry>
	  <term>allow-recursion-override=on|off</term>
	  <listitem>
	    <para>
	      By specifying <command>allow-recursion-override</command>, local data even about hosts that don't exist will override
	      the internet. This allows you to generate zones that don't really exist on the internet. Does increase the number of SQL queries for hosts that truly don't exist, also not in your database.

	    </para>
	  </listitem></varlistentry>
	  <varlistentry><term>cache-ttl=...</term>
	    <listitem><para>
		Seconds to store packets in the PacketCache. See <xref linkend="packetcache">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>chroot=...</term>
	    <listitem><para>
		If set, chroot to this directory for more security. See <xref linkend="security">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>config-dir=...</term>
	    <listitem><para>
		Location of configuration directory (pdns.conf)
	      </para></listitem></varlistentry>
	  <varlistentry><term>config-name=...</term>
	    <listitem><para>
		Name of this virtual configuration - will rename the binary image. See <xref linkend="virtual">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>control-console=...</term>
	    <listitem><para>
		Debugging switch - don't use.
	      </para></listitem></varlistentry>
	  <varlistentry><term>daemon=...</term>
	    <listitem><para>
		Operate as a daemon
	      </para></listitem></varlistentry>
	  <varlistentry><term>default-soa-name=...</term>
	    <listitem><para>
		name to insert in the SOA record if none set in the backend
	      </para></listitem></varlistentry>
   	  <varlistentry><term>disable-axfr=...</term>
	    <listitem><para>
		Do not allow zone transfers. Before 2.9.10, this could be overridden by allow-axfr-ips.
	      </para></listitem></varlistentry>
	  <varlistentry><term>disable-tcp=...</term>
	    <listitem><para>
		Do not listen to TCP queries. Breaks RFC compliance.
	      </para></listitem></varlistentry>
	  <varlistentry><term>distributor-threads=...</term>
	    <listitem><para>
		Default number of Distributor (backend) threads to start. See <xref linkend="performance">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>do-ipv6-additional-processing=...</term>
	    <listitem><para>
		Perform AAAA additional processing. 
	      </para></listitem></varlistentry>
	  <varlistentry><term>fancy-records=...</term>
	    <listitem><para>
		Process URL and MBOXFW records. See <xref linkend="fancy-records">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>guardian | --guardian=yes | --guardian=no</term>
	    <listitem><para>
		Run within a guardian process. See <xref linkend="guardian">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>help</term>
	    <listitem><para>
		Provide a helpful message
	      </para></listitem></varlistentry>
	  <varlistentry><term>launch=...</term>
	    <listitem><para>
		Which backends to launch and order to query them in. See <xref linkend="modules">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>lazy-recursion=...</term>
	    <listitem><para>
	      On by default as of 2.1. Checks local data first before recursing. See <xref linkend="recursion">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>load-modules=...</term>
	    <listitem><para>
		Load this module - supply absolute or relative path. See <xref linkend="modules">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>local-address=...</term>
	    <listitem><para>
		Local IP address to which we bind. You can specify multiple addresses separated by commas or whitespace. It is highly 
	      advised to bind to specific interfaces and not use the default 'bind to any'. This causes big problems if you have multiple
	      IP addresses. Unix does not provide a way of figuring out what IP address a packet was sent to when binding to any.
	      </para></listitem></varlistentry>
	  <varlistentry><term>local-ipv6=...</term>
	    <listitem><para>
		Local IPv6 address to which we bind. You can specify multiple addresses separated by commas or whitespace.
	      </para></listitem></varlistentry>
	  <varlistentry><term>local-port=...</term>
	    <listitem><para>
		The port on which we listen. Only one port possible.
	      </para></listitem></varlistentry>
	  <varlistentry><term><anchor id="log-failed-updates">log-failed-updates=...</term>
	    <listitem><para>
	      If set to 'no', failed Windows Dynamic Updates will not be logged.
	      </para></listitem></varlistentry>
	  <varlistentry><term><anchor id="log-dns-details">log-dns-details=...</term>
	    <listitem><para>
	      If set to 'no', informative-only DNS details will not even be sent to syslog, improving performance. Available from 2.5 
	      and onwards.
	      </para></listitem></varlistentry>
	  <varlistentry><term>logging-facility=...</term>
	    <listitem><para>
	      If set to a digit, logging is performed under this LOCAL facility. See <xref linkend="syslog">. Available from 1.99.9 and onwards. Do not pass names like 'local0'!
	      </para></listitem></varlistentry>
	  <varlistentry><term>loglevel=...</term>
	    <listitem><para>
		Amount of logging. Higher is more. Do not set below 3
	      </para></listitem></varlistentry>
	  <varlistentry><term>max-queue-length=...</term>
	    <listitem><para>
	      If this many packets are waiting for database attention, consider the situation hopeless and respawn.
	      </para></listitem></varlistentry>
	  <varlistentry><term>max-tcp-connections=...</term>
	    <listitem><para>
	      Allow this many incoming TCP DNS connections simultaneously.
	      </para></listitem></varlistentry>
	  <varlistentry><term>module-dir=...</term>
	    <listitem><para>
		Default directory for modules. See <xref linkend="modules">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>negquery-cache-ttl=...</term>
	    <listitem><para>
		Seconds to store queries with no answer in the Query Cache. See <xref linkend="querycache">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>no-config</term>
	    <listitem><para>
	      Do not attempt to read the configuration file.
	      </para></listitem></varlistentry>
	  <varlistentry><term>no-shuffle</term>
	    <listitem><para>
	      Do not attempt to shuffle query results.
	      </para></listitem></varlistentry>
	  <varlistentry><term>out-of-zone-additional-processing | --out-of-zone-additional-processing=yes | --out-of-zone-additional-processing=no</term>
	    <listitem><para>
	      Do out of zone additional processing. This means that if a malicious user adds a '.com' zone to your server, it is not used for 
	      other domains and will not contaminate answers. Do not enable this setting if you run a public DNS service with untrusted users. Off by default.
	    </para></listitem></varlistentry>
	  <varlistentry><term>query-cache-ttl=...</term>
	    <listitem><para>
	      Seconds to store queries with an answer in the Query Cache. See <xref linkend="querycache">.
	    </para></listitem></varlistentry>
	  <varlistentry><term>query-local-address=...</term>
	    <listitem><para>
	      The IP address to use as a source address for sending queries. Useful if you have multiple IPs and pdns is not bound to the IP address your operating system uses by default for outgoing packets.
	    </para></listitem></varlistentry>
	  <varlistentry><term>query-logging | query-logging=yes | query-logging=no</term>
	    <listitem><para>
	      Hints to a backend that it should log a textual representation of queries it performs. Can be set at runtime.
	      </para></listitem></varlistentry>
	<varlistentry><term>queue-limit=...</term>
	    <listitem><para>
		Maximum number of miliseconds to queue a query. See <xref linkend="performance">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>recursive-cache-ttl=...</term>
	    <listitem><para>
		Seconds to store recursive packets in the PacketCache. See <xref linkend="packetcache">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>recursor=...</term>
	    <listitem><para>
	      If set, recursive queries will be handed to the recursor specified here. See <xref linkend="recursion">.
	    </para></listitem></varlistentry>
	<varlistentry><term>send-root-referral | --send-root-referral=yes | --send-root-referral=no | --send-root-referral=lean</term>
	    <listitem><para>
	      If set, PowerDNS will send out old-fashioned root-referrals when queried for domains for which it is not authoritative. Wastes some bandwidth
	      but may solve incoming query floods if domains are delegated to you for which you are not authoritative, but which are queried by broken
	      recursors. Available since 2.9.19.
	      </para>
	    <para>
	      Since 2.9.21, it is possible to specify 'lean' root referrals, which waste less bandwidth.
	    </para></listitem></varlistentry>
	<varlistentry><term>setgid=...</term>
	    <listitem><para>
	      If set, change group id to this gid for more security. See <xref linkend="security">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>setuid=...</term>
	    <listitem><para>
		If set, change user id to this uid for more security. See <xref linkend="security">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>skip-cname | --skip-cname=yes | --skip-cname=no</term>
	    <listitem><para>
		Do not perform CNAME indirection for each query. Has performance implications. See <xref linkend="security">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>slave-cycle-interval=60</term>
	    <listitem><para>
	      Schedule slave up-to-date checks of domains whose status is unknown every .. seconds. See <xref linkend="fancy-records">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>smtpredirector=...</term>
	    <listitem><para>
		Our smtpredir MX host. See <xref linkend="fancy-records">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>soa-expire-default=604800</term>
	    <listitem><para>
	      Default <link linkend="soa-type">SOA</link> expire.
	      </para></listitem></varlistentry>
	  <varlistentry><term>soa-minimum-ttl=3600</term>
	    <listitem><para>
	      Default <link linkend="soa-type">SOA</link> minimum ttl.
	      </para></listitem></varlistentry>
	  <varlistentry><term>soa-refresh-default=10800</term>
	    <listitem><para>
	      Default <link linkend="soa-type">SOA</link> refresh.
	      </para></listitem></varlistentry>
	  <varlistentry><term>soa-retry-default=3600</term>
	    <listitem><para>
	      Default <link linkend="soa-type">SOA</link> retry.
	      </para></listitem></varlistentry>
	  <varlistentry><term>soa-serial-offset=...</term>
	    <listitem><para>
	      If your database contains single-digit SOA serials and you need to host .DE domains, this setting can help
	      placate their 6-digit SOA serial requirements. Suggested value is to set this to 1000000 which adds 1000000 to all SOA Serials
	      under that offset.
	      </para></listitem></varlistentry>
	  <varlistentry><term>socket-dir=...</term>
	    <listitem><para>
		Where the controlsocket will live. See <xref linkend="controlsocket">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>strict-rfc-axfrs | --strict-rfc-axfrs=yes | --strict-rfc-axfrs=no</term>
	    <listitem><para>
	      Perform strictly RFC conformant AXFRs, which are slow, but needed to placate some old client tools.
	      </para></listitem></varlistentry>
	  <varlistentry><term>urlredirector=...</term>
	    <listitem><para>
		Where we send hosts to that need to be url redirected. See <xref linkend="fancy-records">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>version-string=anonymous|powerdns|full|custom</term>
	    <listitem><para>
	      When queried for its version over DNS (<command>dig chaos txt version.bind @pdns.ip.address</command>), PowerDNS normally
	      resonds truthfully. With this setting you can overrule what will be returned. Set the <command>version-string</command>
	      to 'full' to get the default behaviour, to 'powerdns' to just make it state 'served by PowerDNS - http://www.powerdns.com'. 
	      The 'anonymous' setting will return a ServFail, much like Microsoft nameservers do.  You can set this response
	      to a custom value as well.
	      </para></listitem></varlistentry>

	  <varlistentry><term>webserver | --webserver=yes | --webserver=no</term>
	    <listitem><para>
		Start a webserver for monitoring. See <xref linkend="monitoring">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>webserver-address=...</term>
	    <listitem><para>
		IP Address of webserver to listen on. See <xref linkend="monitoring">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>webserver-password=...</term>
	    <listitem><para>
		Password required for accessing the webserver. See <xref linkend="monitoring">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>webserver-port=...</term>
	    <listitem><para>
		Port of webserver to listen on. See <xref linkend="monitoring">.
	      </para></listitem></varlistentry>
	  <varlistentry><term>wildcard-url=...</term>
	    <listitem><para>
	      Check for wildcard URL records.
	      </para></listitem></varlistentry>
	  <varlistentry><term>wildcards=...</term>
	    <listitem><para>
		Honor wildcards in the database. On by default. Turning this off has performance implications, see <xref linkend="performance">.
	      </para></listitem></varlistentry>
      </variablelist>
    </para>
  </chapter>
  <chapter id="metrics"><title>Index of all internal metrics</title>
    <sect1 id="counters-variables"><title>Counters &amp; variables</title>
      <para>
      A number of counters and variables are set during PDNS operation. These can be queried with the init.d
      <command>dump</command>, <command>show</command> and <command>mrtg</command> commands, or viewed with the
      webserver.
      </para>
      <sect2 id="counters">
	<title>Counters</title>
      <para>
      <variablelist>
	<varlistentry>
	  <term>corrupt-packets</term>
	  <listitem><para>Number of corrupt packets received</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>latency</term>
	  <listitem><para>Average number of microseconds a packet spends within PDNS</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>packetcache-hit</term>
	  <listitem><para>Number of packets which were answered out of the cache</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>packetcache-miss</term>
	  <listitem><para>Number of times a packet could not be answered out of the cache</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>packetcache-size</term>
	  <listitem><para>Amount of packets in the packetcache</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>qsize-a</term>
	  <listitem><para>Size of the queue before the transmitting socket.</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>qsize-q</term>
	  <listitem><para>Number of packets waiting for database attention</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>servfail-packets</term>
	  <listitem><para>Amount of packets that could not be answered due to database problems</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>tcp-answers</term>
	  <listitem><para>Number of answers sent out over TCP</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>tcp-questions</term>
	  <listitem><para>Number of questions received over TCP</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>timedout-questions</term>
	  <listitem><para>Amount of packets that were dropped because they had to wait too long internally</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>udp-answers</term>
	  <listitem><para>Number of answers sent out over UDP</para></listitem>
	</varlistentry>
	<varlistentry>
	  <term>udp-questions</term>
	  <listitem><para>Number of questions received over UDP</para></listitem>
	</varlistentry>
      </variablelist>
    </para>
    </sect2>
    <sect2>
      <title>Ring buffers</title>
	<para>
	  Besides counters, PDNS also maintains the ringbuffers. A ringbuffer records events, each new event gets a place
	  in the buffer until it is full. When full, earlier entries get overwritten, hence the name 'ring'.
	</para>
    <para>
      By counting the entries in the buffer, statistics can be generated. These statistics can currently only be viewed 
      using the webserver and are in fact not even collected without the webserver running. 
    </para>
    <para>
      The following ringbuffers are available:
    </para>
    <para>
    <variablelist>
      <varlistentry>
	<term>Log messages (logmessages)</term>
	<listitem><para>All messages logged</para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Queries for existing records but for a type we don't have (noerror-queries)</term>
	<listitem><para>Queries for, say, the AAAA record of a domain, when only an A is available. 
	  Queries are listed in the following format: name/type. So an AAA query for pdns.powerdns.com looks like
	  pdns.powerdns.com/AAAA.</para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Queries for non-existing records within existing domains(nxdomain-queries)</term>
	<listitem><para>If PDNS knows it is authoritative over a domain, and it sees a question for a record in that domain
	    that does not exist, it is able to send out an authoritative 'no such domain' message. Indicates that hosts are
	    trying to connect to services really not in your zone.</para></listitem>
      </varlistentry>

      <varlistentry>
	<term>UDP queries received (udp-queries)</term>
	<listitem><para>
	    All UDP queries seen.
	  </para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Remote server IP addresses (remotes)</term>
	<listitem><para>
	    Hosts querying PDNS. Be aware that UDP is anonymous - person A can send queries that appear to be coming from
	    person B.
	  </para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Remotes sending corrupt packets (remote-corrupts)</term>
	<listitem><para>
	    Hosts sending PDNS broken packets, possibly meant to disrupt service. Be aware that UDP is 
	    anonymous - person A can send queries that appear to be coming from person B.
	  </para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Remotes querying domains for which we are not auth (remote-unauth)</term>
	<listitem><para>
	    It may happen that there are misconfigured hosts on the internet which are configured to
	    think that a PDNS installation is in fact a resolving nameserver. These hosts will not
	    get useful answers from PDNS. This buffer lists hosts sending queries for domains which 
	    PDNS does not know about.
	  </para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Queries that could not be answered due to backend errors (servfail-queries)</term>
	<listitem><para>
	    For one reason or another, a backend may be unable to extract answers for a certain domain from
	    its storage. This may be due to a corrupt database or to inconsistent data. When this happens,
	    PDNS sends out a 'servfail' packet indicating that it was unable to answer the question. This buffer
	    shows which queries have been causing servfails.
	  </para></listitem>
      </varlistentry>
      <varlistentry>
	<term>Queries for domains that we are not authoritative for (unauth-queries)</term>
	<listitem><para>
	    If a domain is delegated to a PDNS instance, but the backend is not made aware of this fact, questions come
	    in for which no answer is available, nor is the authority. Use this ringbuffer to spot such queries.
	  </para></listitem>
      </varlistentry>
    </variablelist>
  </para>
  </sect2>
  </sect1>
  </chapter>

  <chapter id="types"><title>Supported record types and their storage</title>
    <para>
      This chapter lists all record types PDNS supports, and how they are stored in backends. The list is mostly alphabetical but
      some types are grouped.
    <variablelist>
      <varlistentry>
	<term>A</term>
	  <listitem>
	    <para>
	      The A record contains an IP address. It is stored as a decimal dotted quad string,
	      for example: '213.244.168.210'.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>AAAA</term>
	  <listitem>
	    <para>
	      The AAAA record contains an IPv6 address. An example: '3ffe:8114:2000:bf0::1'. 
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>CNAME</term>
	  <listitem>
	    <para>
	      The CNAME record specifies the canonical name of a record. It is stored plainly. Like all other records, it is not
	      terminated by a dot. A sample might be 'webserver-01.yourcompany.com'.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>HINFO</term>
	  <listitem>
	    <para>
	      Hardware Info record, used to specify CPU and operating system. Stored with a single space separating these two, 
	      example: 'i386 Linux'.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>MX</term>
	  <listitem>
	    <para>
	      The MX record specifies a mail exchanger host for a domain. Each mail exchanger also has a priority or preference.
	      This should be specified in the separate field dedicated for that purpose, often called 'prio'. 
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term><anchor id="naptr">NAPTR</term>
	  <listitem>
	    <para>

	      Naming Authority Pointer, RFC 2915. Stored as follows:
	      <screen>
	      '100  50  "s"  "z3950+I2L+I2C"     ""  _z3950._tcp.gatech.edu'. 
	      </screen>
	      The fields are: order, preference, flags, service, regex, 
	      replacement. Note that the replacement is not enclosed in quotes, and should not be. The replacement may be omitted, in which 
	      case it is empty. See also RFC 2916 for how to use NAPTR for ENUM (E.164) purposes.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>NS</term>
	  <listitem>
	    <para>
	      Nameserver record. Specifies nameservers for a domain. Stored plainly: 'ns1.powerdns.com', as always without a terminating dot.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>PTR</term>
	  <listitem>
	    <para>
	      Reverse pointer, used to specify the host name belonging to an IP or IPv6 address. Name is stored plainly: 'www.powerdns.com'.
	      As always, no terminating dot.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>RP</term>
	  <listitem>
	    <para>
	      Responsible Person record, as described in RFC 1183. Stored with a single space between the mailbox name and the more-information
	      pointer. Example 'peter.powerdns.com peter.people.powerdns.com', to indicate that peter@powerdns.com is responsible and that more 
	      information about peter is available by querying the TXT record of peter.people.powerdns.com.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term><anchor id="soa-type">SOA</term>
	  <listitem>
	    <para>
	      The Start of Authority record is one of the most complex available. It specifies a lot about a domain: the name 
	      of the master nameserver ('the primary'), the hostmaster and a set of numbers indicating how the data in this domain
	      expires and how often it needs to be checked. Further more, it contains a serial number which should rise on each change
	      of the domain.
	    </para>
	    <para>
	      The stored format is:
	      <screen>
		primary hostmaster serial refresh retry expire default_ttl
	      </screen>
	      Besides the primary and the hostmaster, all fields are numerical. PDNS has a set of default values:
	      <table>
		<title>SOA fields</title>
		<tgroup cols=2>
		  <tbody>
		    <row>
		      <entry>primary</entry><entry><command>default-soa-name</command> configuration option</entry>
		    </row>
		    <row>
		      <entry>hostmaster</entry><entry>hostmaster@domain-name</entry>
		    </row>
		    <row>
		      <entry>serial</entry><entry>0</entry>
		    </row>
		    <row>
		      <entry>refresh</entry><entry>10800 (3 hours)</entry>
		    </row>
		    <row>
		      <entry>retry</entry><entry>3600 (1 hour)</entry>
		    </row>
		    <row>
		      <entry>expire</entry><entry>604800 (1 week)</entry>
		    </row>
		    <row>
		      <entry>default_ttl</entry><entry>3600 (1 hour)</entry>
		    </row>
		  </tbody>
		</tgroup>
	      </table>
	    </para>
	    <para>
	      The fields have complicated and sometimes controversial meanings. The 'serial' field is special. If left at 0, the default,
	      PDNS will perform an internal list of the domain to determine highest change_date field of all records within the zone, and use
	      that as the zone serial number. This means that the serial number is always raised when changes are made to the zone, as long
	      as the change_date field is being set.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>SRV</term>
	  <listitem>
	    <para>
	      SRV records can be used to encode the location and port of services on a domain name. When encoding, the priority field
	      is used to encode the priority. For example, '_ldap._tcp.dc._msdcs.conaxis.ch SRV     0 100 389 mars.conaxis.ch' would be 
	      encoded with 0 in the priority field and '100 389 mars.conaxis.ch' in the content field.
	    </para>
	  </listitem>      
	</varlistentry>
	<varlistentry>
	  <term>TXT</term>
	  <listitem>
	    <para>
	      The TXT field can be used to attach textual data to a domain. Text is stored plainly.
	    </para>
	  </listitem>      
	</varlistentry>
      </variablelist>
    </para>
  </chapter>
  <chapter id="faq"><title>HOWTO &amp; Frequently Asked Questions</title>
    <para>
      This chapter contains a number of FAQs and HOWTOs.
    </para>
    <sect1 id="pdns-help-faq"><title>Getting support, free and paid FAQ</title>
      <para>
	PowerDNS is an open source program so you may get help from the PowerDNS users' community or from its authors.
	You may also help others (please do).
      </para>
      <para>
	Some users may not have experience in interacting with developers or the open source community. This FAQ is to be considered 
	MANDATORY READING before asking us for help.
      </para>
      <para>
	You are also advised to look at <ulink url="http://wiki.powerdns.com">the Wiki</ulink> for more information.
      </para>
      <variablelist>
	<varlistentry>
	  <term>Q: Help!</term>
	  <listitem>
	    <para>
	      A: Please try harder. Specifically, before people will be able to help you, they need to know a lot about your system.
	      Things you may find irrelevant. But, as you have a problem, you are not in a good position to know what is relevant and what not.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: I have a question, what details should I supply?</term>
	  <listitem>
	    <para>
	      A: Start out with stating what you think should be happening. Quite often, wrong expectations are the actual proble. 
	      Furthermore, which database backend you use, your operating system, which version of PowerDNS you use and where you 
	      got it from (RPM, .DEB, tar.gz). If you compiled it yourself, what were the ./configure parameters.
	    </para>
	    <para>
	      In the Open Source community, not supplying vital details is interpreted as a lack of respect for those willing to take 
	      time to answer your questions!
	    </para>
	    <para>
	      If at *all* possible, supply the actual name of your domain and the IP address of your server(s).
	    </para>
	  </listitem>

	</varlistentry>
	<varlistentry>
	  <term>Q: Where should I send my question?</term>
	  <listitem>
	    <para>
	      A: To a mailinglist. Do not mail the authors directly unless you previously entered a support contract with them!
	      For subscription details, see <ulink url="http://mailman.powerdns.com/mailman/admin/">the mailinglists page</ulink>.
	    </para>
	    <para>
	      Questions about using PowerDNS should be sent to the pdns-users list, questions about compiler errors or feature requests
	      to pdns-dev.
	    </para>
	    <para>
	      Before posting, read all FAQs and tell people you did.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: I'm special, I don't email to mailinglists!</term>
	  <listitem>
	    <para>
	      We're special too, and we ask you to mail the mailinglists. If you need privacy, consider entering a support 
	      relationship with us, in which case you can email <email>support@powerdns.com</email>.
	    </para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </sect1>
    <sect1 id="pdns-users-faq"><title>Using and Compiling PowerDNS FAQ</title>
      <para>
	In the course of compiling and using PowerDNS, many questions may arise. Here are some we've heard earlier or questions 
	we expect people may have. Please read this list before mailing us!
      </para>
      <para>
	If you don't see your question answered here, please check out <ulink url="http://wiki.powerdns.com/projects/trac/wiki/TodoList">
	  the Wiki FAQ</ulink>, but do note that it is user-editable and not under our constant control.
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>Q: I get this entry a lot of times in my log file: Authoritative empty NO ERROR to 1.2.3.4 for 'powerdns.nl' (AAAA)..</term>
	    <listitem>
	      <para>
		As the name implies, this is not an error. It tells you there are questions for a domain which exists in your database, but for
		which no record of the requested type exists. To get rid of this error, add <command>log-dns-details=off</command> to your
		configuration.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Can I launch multiple backends simultaneously?</term>
	    <listitem>
	      <para>
		A: You can. This might for example be useful to keep an existing BIND configuration around but to store new zones in, say
		MySQL. The syntax to use is 'launch=bind,gmysql'.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: PowerDNS does not give authoritative answers, how come?</term>
	    <listitem>
	      <para>
		A: This is almost always not the case. An authoritative answer is recognized by the 'AA' bit being set. Many tools
		prominently print the number of Authority records included in an answer, leading users to conclude that the 
		absence or presence of these records indicates the authority of an answer. This is not the case.
	      </para>
	      <para>
		Verily, many misguided country code domain operators have fallen into this trap and demand authority records, even though
		these are fluff and quite often misleading. Invite such operators to look at section 6.2.1 of RFC 1034, which shows a correct
		authoritative answer without authority records. In fact, none of the non-deprecated authoritative answers shown have authority 
		records!
	      </para>
	      <para>
		Sorry for sounding like DJB on this, but we get so many misguided questions about authority..
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>Q: Which backend should I use? There are so many!</term>
	    <listitem>
	      <para>
		A: If you have no external constraints, the Generic MySQL (gmysql) and Generic PostgreSQL (gpgsql) ones are probably the
		most used and complete. By all means do not use the non-generic MySQL backend, which is deprecated and only available for older
		installations.
	      </para>
	      <para>
		The Oracle backend also has happy users, we know of no deployments of the DB2 backend. The BIND backend is pretty capable
		too in fact, but many prefer a relational database.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: I try to launch the pgmysqlbackend and it can't find it!</term>
	    <listitem>
	      <para>
		A: You did not read the changelog, nor the README. The 'pgmysql' backend is no more and has been split
		into the gmysql and gpgsql backends, with the common code residing within PowerDNS itself.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: PowerDNS compiles under OpenBSD, but crashes immediately, now what?</term>
	    <listitem>
	      <para>
		A: Reasons behind this are somewhat unclear but we hear they go away if you use a more recent compiler. Let us know
		on <email>pdns-dev@mailman.powerdns.com</email>. See also 
		<ulink url="http://www.codeninja.nl/openbsd/powerdns/">here</ulink>.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: I'm trying to build from CVS but I get lots of weird errors!</term>
	    <listitem>
	      <para>
		A: Read the 'HACKING' file, it lists the build requirements (mostly autoconf, automake, libtool). In many cases, 
		it may be easier to build from the source distribution though.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: I'm on Solaris 7 and AAAA records do not work</term>
	    <listitem>
	      <para>
		A: Indeed, and this is pretty sad. Either upgrade to Solaris 8 or convince people to write the replacement functions
		needed to encode AAAA if the host operating system does not offer them.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: When compiling I get errors about 'sstream' and 'ostringstream', or BITSPERCHAR</term>
	    <listitem>
	      <para>
		A: Your gcc is too old. Versions 2.95.2 and older are not supported. Many distributions have improved gcc 2.95.2 
		with an ostringstream implementation, in which case their 2.95.2 is also supported. We like gcc 3.2.1 best.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Ok, I've installed gcc 3.2.1 but now the gpgsql backend won't link</term>
	    <listitem>
	      <para>
		A: Sadly, the gcc C++ on-disk object format has changed a few times since the 2.95 days. This means that
		gcc 3.2.1 cannot link against libpq++.so compiled with 2.95. The trick is to recompile PostgreSQL with 3.2.1
		too and have it install in a separate location. Then reconfigure the pdns compile to look there, with
		<command>./configure --with-pgsql-lib=/opt/postgresql-with-3.2.1/lib</command>
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: I've installed PostgreSQL 7.3 but it has no libpq++.so</term>
	    <listitem>
	      <para>
		A: As of 7.3, libpq++ has been split out of the main PostgreSQL distribution. See <ulink url="http://gborg.postgresql.org/">here</ulink>.
		It would in fact be a great idea to move the gpgsql backend to the C interface instead of the C++ one. On Debian 'Sid', libpq++.so
		hides in the libpqpp-dev package.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: PowerDNS crashes when I install the pdns-static .deb on Debian SID</term>
	    <listitem>
	      <para>
		A: Indeed. Install the .debs that come with Debian or recompile PowerDNS yourself. If not using MySQL, the crashes
		will go away if you remove setuid and setgid statements from the configuration.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Why don't my slaves act on notifications and transfer my updated zone?</term>
	    <listitem>
	      <para>
		A: Raise the serial number of your zone. In most backends, this is the first digit of the SOA contents field. If this number
		is lower to equal to that on a slave, it will not consider your zone updated.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Master or Slave support is not working, PDNS is not picking up changes</term>
	    <listitem>
	      <para>
		A: The Master/Slave apparatus is off by default. Turn it on by adding a <command>slave</command> and/or
		<command>master</command> statement to the configuration file. Also, check that the configured backend is master or slave capable.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: My masters won't allow PowerDNS to access zones as it is using the wrong local IP address</term>
	    <listitem>
	      <para>
		A: Mark Bergsma contributed the query-local-address setting to tell PowerDNS which local IP address to use. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: I compiled PowerDNS myself and I see weird problems, especially on SMP</term>
	    <listitem>
	      <para>
		A: There are known issues between gcc &lt;3.2 and PowerDNS on Linux SMP systems. The exact cause is not known but
		moving to our precompiled version always fixes the problems. If you compile yourself, use a recent gcc!
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: I see this a lot: Backend error: Failed to execute mysql_query, perhaps connection died?</term>
	    <listitem>
	      <para>
		A: Check your MySQL timeout, it may be set too low. This can be changed in the <filename>my.cnf</filename> file.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: PowerDNS does not answer queries on all my IP addresses and I've ignored the warning I got about that at startup</term>
	    <listitem>
	      <para>
		A: Please don't ignore what PowerDNS says to you. Furthermore, read <xref linkend="all-settings"> about the <command>local-address</command>
		setting, and use it to specify which IP addresses PowerDNS should listen on.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Can I use a MySQL database with the Windows version of PowerDNS?</term>
	    <listitem>
	      <para>
		A: You can. MySQL support is supplied through the ODBC backend, which is compiled into the main binary.
		So if you want to use MySQL you can change the pdns.conf file, which is located in the PowerDNS for Windows directory, to use the 
		correct ODBC data sources.

		If you don't know how to use ODBC with MySQL:
		<itemizedlist>
		  <listitem><para>
		      Download MyODBC from <ulink url="http://www.mysql.com/">http://www.mysql.com/</ulink>
		    </para></listitem>
		  <listitem><para>
		      Install the MySQL ODBC driver.
		    </para></listitem>
		</itemizedlist>
		Then you can follow the instructions located in <xref linkend="windows">.
		But instead of selecting the Microsoft Access Driver you select the MySQL ODBC Driver and configure it to use your MySQL database.
    
		<note><para>For other databases for which an ODBC driver is available, the procedure is the same as this example.</para></note>
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>
    <sect1 id="pdns-devel-faq"><title>Backend developer HOWTO</title>
      <para>
	Writing backends without access to the full PDNS source means that you need to write code that can be loaded by PDNS at runtime. 
	This in turn means that you need to use the same compiler that we do. For linux, this is currently GCC 3.0.4, although any 3.0.x 
	compiler is probably fine. In tests, even 3.1 works.
      </para>
      <para>
	For FreeBSD we use GCC 2.95.2.
      </para>
      <para>
	Furthermore, your pdns_server executable must be dynamically linked. The default .rpm PDNS contains a static binary so you need to retrieve the
	dynamic rpm or the dynamic tar.gz or the Debian unstable ('Woody') deb. FreeBSD dynamic releases are forthcoming.
      </para>
      <variablelist>
	<varlistentry>
	  <term>Q: Will PDNS drivers work with other PDNS versions than they were compiled for?</term>
	  <listitem>
	    <para>
	      A: 'Probably'. We make no guarantees. Efforts have been made to keep the interface between the backend and PDNS as thin
	      as possible. For example, a backend compiled with the 1.99.11 backend development kit works with 1.99.10. But don't count on it.
	      We will notify when we think an incompatible API change has occured but you are best off recompiling your driver for each
	      new PDNS release.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: What is in that DNSPacket * pointer passed to lookup!</term>
	  <listitem>
	    <para>
	      A: For reasons outlined above, you should treat that pointer as opaque and only access it via the <function>getRemote()</function> 
	      functions made available and documented above. The DNSPacket class changes a lot and this level of indirection allows for greater
	      changes to be made without changing the API to the backend coder.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: How is the PowerDNS Open Source Backend Development Kit licensed?</term>
	  <listitem>
	    <para>
	      A: MIT X11, a very liberal license permitting basically everything.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: Can I release the backend I wrote?</term>
	  <listitem>
	    <para>
	      A: Please do! If you tell us about it we will list you on our page.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: Can I sell backends I wrote?</term>
	  <listitem>
	    <para>
	      A: You can. Again, if you tell us about them we will list your backend on the site. You can keep the source of your backend
	      secret if you want, or you can share it with the world under any license of your chosing.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: Will PowerDNS use my code in the PDNS distribution?</term>
	  <listitem>
	    <para>
	      A: If your license permits it and we like your backend, we sure will.  If your license does not permit it but we like your 
	      backend anyway we may contact you. 
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: My backend compiles but when I try to load it, it says 'undefined symbol: _Z13BackendMakersv'</term>
	  <listitem>
	    <para>
	      A: Your pdns_server binary is static and cannot load a backend driver at runtime. Get a dynamic version of pdns, or complain 
	      to pdns@powerdns.com if one isn't available. To check what kind of binary you have, execute 'file $(which pdns_server)'.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: My backend compiles but when I try to load it, it says 'undefined symbol: BackendMakers__Fv'</term>
	  <listitem>
	    <para>
	      A: You compiled with the wrong GCC. Use GCC 3.x for Linux, 2.95.x for FreeBSD. You may want to change g++ to g++-3.0 in the Makefile,
	      or change your path so that 3.x is used.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: I downloaded a dynamic copy of pdns_server but it doesn't run, even without my backend</term>
	  <listitem>
	    <para>
	      A: Run 'ldd' on the pdns_server binary and figure out what libraries you are missing. Most likely you need to install gcc 3.0 libraries, 
	      RedHat 7.1 and 7.2 have packages available, Debian installs these by default if you use the 'unstable deb' of PDNS.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: What is this 'AhuException' I keep reading about?</term>
	  <listitem>
	    <para>
	      A: This name has historical reasons and has <ulink url="http://ds9a.nl">no significance</ulink>. 
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Q: I need a backend but I can't write it, can you help?</term>
	  <listitem>
	    <para>
	      A: Yes, we also do custom development. Contact us at pdns@powerdns.com.
	    </para>
	  </listitem>
	</varlistentry>

      </variablelist>
    </sect1>
    <sect1 id="powerdns-company-faq"><title>About PowerDNS.COM BV, 'the company'</title>
      <para>
	As of 25 November 2002, the PowerDNS nameserver and its modules are open source. This has led to a lot of questions on the future
	of both PowerDNS, the company and the products. This FAQ attempts to address these questions.
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>Q: Is PowerDNS 2.9 really open source? What license?</term>
	    <listitem>
	      <para>
		A: PowerDNS 2.9 is licensed under the GNU General Public License version two, the same license that covers the Linux kernel.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Is the open source version crippled?</term>
	    <listitem>
	      <para>
		A: It is not. Not a single byte has been omitted.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Is the nameserver abandoned?</term>
	    <listitem>
	      <para>
		A: Far from it. In fact, we expect development to speed up now that we have joined the open source community.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Why is the nameserver now open source?</term>
	    <listitem>
	      <para>
		A: In the current economic climate and also the way the Internet is built up right now, selling software is very hard. Most  potential 
		customers had never before bought a piece of software for their UNIX internet setup. Even though we know (from the recent survey) that
		nameserver operators love PowerDNS, their suggested price for it is in the $100 range.
	      </para>
	      <para>
		For us, it makes far more sense to open source PowerDNS than to ask $100 for it. It is expected that open sourcing PowerDNS will lead
		to far higher adoption rates. We hope that PowerDNS will soon be included in major Linux and UNIX distributions.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: How does PowerDNS.COM BV expect to make money now that the nameserver is free?</term>
	    <listitem>
	      <para>
		A: In fact, we don't expect to in the near future. We also don't have a lot of expenses, basically 
		some hosting and a few domain names. 
	      </para>
	      <para>
		However, we are available for consulting work, for example to help a large registrar or registry migrate to PowerDNS, or to help
		integrate our software in existing provisioning systems.
	      </para>
	      <para>
		Furthermore, non-GPL licenses are available for those needing to do closed source modifications, or for customers 
		uncomfortable with the GPL. This is much like what <ulink url="http://www.mysql.com/company/index.html">MySQL AB</ulink> is doing now.
	      </para>
	      <para>
		In fact, their strategy is a lot like ours in general.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Can I buy support contracts for PowerDNS?</term>
	    <listitem>
	      <para>
		Sure, to do so, please contact us at <email>sales@powerdns.com</email>
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Will you accept patches? We've added a feature</term>
	    <listitem>
	      <para>
		Probably - in general, it is best to discuss your intentions and needs on the <email>pdns-dev@mailman.powerdns.com</email> (<ulink url="http://mailman.powerdns.com/mailman/listinfo/pdns-dev">subscribe</ulink>)
		mailinglist
		before doing the work. We may have suggestions or guidelines on how you should implement the feature. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: PowerDNS doesn't work on my platform, will you port it?</term>
	    <term>Q: PowerDNS doesn't have feature I need, will you add it?</term>
	    <listitem>
	      <para>
		Be sure to ask on the <email>pdns-dev@mailman.powerdns.com</email> (<ulink url="http://mailman.powerdns.com/mailman/listinfo/pdns-dev">subscribe</ulink>) mailinglist. You can even hire us to do work on PowerDNS
		if plain asking is not persuasive enough. This might be the case if we don't currently have time for your feature, but you
		need it quickly anyhow, and are not in a position to submit a patch implementing it.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Q: Will <ulink url="http://express.powerdns.com">PowerDNS Express</ulink> be open sourced?</term>
	    <listitem>
	      <para>
		Perhaps, we're not yet sure. 
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>Q: We are a Linux/Unix vendor, can we include PowerDNS?</term>
	    <listitem>
	      <para>
	      A: Please do. In fact, we'd be very happy to work with you to make this happen. Contact <email>ahu@ds9a.nl</email> 
	      if you have specific upstream needs.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>
  </chapter>
  <chapter id="analysis"><title>Tools to analyse DNS traffic</title>
    <para>
      DNS is highly mission critical, it is therefore necessary to be able to study and compare DNS traffic. Since 2.9.18, PowerDNS comes
      with three tools to aid in analysis:
      <warning>
	<para>
	  As of 2.9.18 these tools are somewhat rough - they have no help messages for example. They do work though.
	</para>
      </warning>
      <variablelist>
	<varlistentry>
	  <term>dnsreplay pcapfile [ipaddress] [port number]</term>
	  <listitem>
	    <para>
	      This program takes recorded questions and answers and replays them to a specified nameserver and reporting afterwards
	      which percentage of answers matched, were worse or better.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>dnswasher pcapfile output</term>
	  <listitem>
	    <para>
	      Anonymises recorded traffic, making sure it only contains DNS, and that the originating IP addresses of queries are stripped, which may
	      allow you to send traces to our company or mailing list without violating obligations towards your customers or privacy laws.
	    </para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>dnsscope pcapfile</term>
	  <listitem>
	    <para>
	      Calculates statistics without replaying traffic
	    </para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </para>
  </chapter>
  <Appendix id="backends-detail"><title>Backends in detail</title>
    <para>
      This appendix lists several of the available backends in more detail
    </para>
    
    
    <sect1 id="pipebackend"><title>PipeBackend</title>
      <para>
	<table>
	  <title>PipeBackend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>No</entry></row>
	      <row><entry>Case</entry><entry>Depends</entry></row>
	      <row><entry>Module name</entry><entry>pipe</entry></row>
	      <row><entry>Launch name</entry><entry>pipe</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	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. 
      </para>
    <para>
      <note>
	<para>
	  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.
	</para>
	<para>
	  Interestingly, the Linux PowerDNS binary running under the Linuxulator on FreeBSD does work.
	</para>
      </note>
    </para>
      <para>
	To configure, the following settings are available:
	<variablelist>
	  <varlistentry>
	    <term>pipe-command</term>
	    <listitem>
	      <para>
		Command to launch as backend. Mandatory.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>pipe-timeout</term>
	    <listitem>
	      <para>
		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.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>pipe-regex</term>
	    <listitem>
	      <para>
		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;.*$'.
	      </para>
	      <para>
		To match only ANY and A queries for www.powerdns.com, use '^www.powerdns.com;(A|ANY)$'. Available since 2.8.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>pipebackend-abi-version</term>
	    <listitem>
	      <para>
		This is the version of the question format that is sent to the co-process (pipe-command) for the pipe backend.
	      </para>
	      <para>
		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)
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      
      <sect2 id="pipebackend-protocol"><title>PipeBackend protocol</title>
	<para>
	  Questions come in over a file descriptor, by default standard input. Answers
	  are sent out over another file descriptor, standard output by default.
	</para>
	<sect3>
      <title>Handshake</title>
      <para>
        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.
      </para></sect3>
    <sect3><title>Questions</title>
      <para>
        Questions come in three forms and are prefixed by a tag indicating the kind:
	<variablelist>
	  <varlistentry>
	    <term>Q</term>
	    <listitem>
	      <para>
                Regular queries
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>AXFR</term>
	    <listitem>
	      <para>
                List requests, which mean that an entire zone should be listed
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>PING</term>
	    <listitem>
	      <para>
                Check if the coprocess is functioning
	      </para>
	    </listitem>
	  </varlistentry>
        </variablelist>
The question format:

pipebackend-abi-version = 1 [default]
<screen>
type	qname		qclass	qtype	id	remote-ip-address
</screen>

pipebackend-abi-version = 2
<screen>
type	qname		qclass	qtype	id	remote-ip-address	local-ip-address
</screen>

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.
      </para></sect3>
    <sect3><title>Answers</title>
      <para>

        Each answer starts with a tag, possibly followed by a TAB and more data.
	<variablelist>
	  <varlistentry>
	    <term>DATA</term>
	    <listitem>
	      <para>
                Indicating a successful line of DATA
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>END</term>
	    <listitem>
	      <para>
                Indicating the end of an answer - no further data
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>FAIL</term>
	    <listitem>
	      <para>
                Indicating a lookup failure. Also serves as 'END'. No further data.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>LOG</term>
	    <listitem>
	      <para>
                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
                
	      </para>
	    </listitem>
	  </varlistentry>
        </variablelist>


        So letting it be known that there is no data consists if sending 'END'
        without anything else.


The answer format:
<screen>
DATA	qname		qclass	qtype	ttl	id	content	
</screen>

'content' is as specified in <xref linkend="types">.

A sample dialogue may look like this:
<screen>
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
</screen>

	  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:
<screen>
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
</screen>

This is a typical zone transfer.
	  </para>
	</sect3>
	<sect3>
	<title>Sample perl backend</title>
	<para>
	<screen>
#!/usr/bin/perl -w
# sample PowerDNS Coprocess backend
#

use strict;


$|=1;					# no buffering

my $line=&lt;&gt;;
chomp($line);

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

while(&lt;&gt;)
{
	print STDERR "$$ Received: $_";
	chomp();
	my @arr=split(/\t/);
	if(@arr&lt;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";
}
	  </screen>
	</para>
	</sect3>
      </sect2>
		  
    </sect1>
    <sect1 id="mysqlbackend"><Title>MySQL backend</title>
      <para>
	<warning>
	  <para>
	    This backend is deprecated! Use the Generic MySQL backend which is better in <command>all</command> respects.
	    It does support master/slave operation, this backend does not. See <xref linkend="generic-mypgsql-backends">.
	  </para>
	  <para>
	    So stop reading here unless you already have a database filled with 'mysql' records.
	  </para>
	</warning>
      </para>
      <para>
	<table>
	  <title>MySQL backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>Yes</entry></row>
	      <row><entry>Case</entry><entry>Insensitive</entry></row>
	      <row><entry>Module name</entry><entry>mysql</entry></row>
	      <row><entry>Launch name</entry><entry>mysql</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
        The MySQL Backend as present in PDNS is fixed - it requires a certain database schema to function. This schema corresponds to this create statement:
        
        <screen>
          CREATE TABLE records (
	  id int(11) NOT NULL auto_increment,
	  domain_id int(11) NOT NULL,
	  name varchar(255) NOT NULL,
	  type varchar(6) NOT NULL,
	  content varchar(255) NOT NULL,
	  ttl int(11) NOT NULL,
	  prio int(11) default NULL,
	  change_date int(11) default NULL,
	  PRIMARY KEY (id),
	  KEY name_index(name),
	  KEY nametype_index(name,type),
	  KEY domainid_index(domain_id)
	  );
        </screen>
        
        Every domain should have a unique domain_id, which should remain identical for all records in a domain. Records with a domain_id that
	differs from that in the domain SOA record will not appear in a zone transfer.

      </para>
      <para>
	The change_date may optionally
        be updated to the time_t (the number of seconds since midnight UTC at the start of 1970), and is in that case used to auto calculate the 
        SOA serial number in case that is unspecified.
        
      </para>
      <sect2><title>Configuration settings</title>
        <para>
	  WARNING! Make sure that you can actually resolve the hostname of your database without accessing the database! It is advised to supply
	  an IP address here to prevent chicken/egg problems!
	</para>
	<para>
          <variablelist>
            <varlistentry>
              <term>mysql-dbname</term>
              <listitem>
                <para>
                  Database name to connect to
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>mysql-host</term>
              <listitem>
                <para>
                  Database host to connect to
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>mysql-password</term>
              <listitem>
                <para>
                  Password to connect with
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>mysql-socket</term>
              <listitem>
                <para>
                  MySQL socket to use for connecting
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>mysql-table</term>
              <listitem>
                <para>
                  MySQL table name. Defaults to 'records'.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>mysql-user</term>
              <listitem>
                <para>
                  MySQL user to connect as
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
	</para>
      </sect2>
      <sect2><title>Notes</title>
	<para>
	  It has been observed that InnoDB tables outperform the default MyISAM tables by a large margin. Furthermore, the default 
	  number of backends (3) should be raised to 10 or 15 for busy servers.
	</para>
      </sect2>
      
    </sect1>
    <sect1 id="randombackend"><title>Random Backend</title>
      <para>
	<table>
	  <title>Random Backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>No</entry></row>
	      <row><entry>Case</entry><entry>Depends</entry></row>
	      <row><entry>Module name</entry><entry>built in</entry></row>
	      <row><entry>Lauch name</entry><entry>random</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	This is a very silly backend which is discussed in <xref linkend="simple-backends"> as a demonstration on
	how to write a PowerDNS backend.
      </para>
      <para>
	This backend knows about only one hostname, and only about its IP address at that. With every query,
	a new random IP address is generated.
      </para>
      <para>
	It only makes sense to load the random backend in combination with a regular backend. This can be done by prepending
	it to the <command>launch=</command> instruction, such as <command>launch=random,gmysql</command>.
      </para>
      <para>
	Variables:
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>random-hostname</term>
	    <listitem>
	      <para>
		Hostname for which to supply a random IP address.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>

    <sect1 id="pdnsbackend"><Title>MySQL PDNS backend</title>
      <para>
	<table>
	  <title>MySQL backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>Yes</entry></row>
	      <row><entry>Case</entry><entry>Insensitive</entry></row>
	      <row><entry>Module name</entry><entry>pdns</entry></row>
	      <row><entry>Lauch name</entry><entry>pdns</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	This is the driver that corresponds to the set of XML-RPC tools available from PowerDNS. 
      </para>
      <para>
	The schema:
	<screen>
CREATE TABLE MailForwards (
  Id int(10) unsigned NOT NULL auto_increment,
  ZoneId int(10) unsigned NOT NULL default '0',
  Name varchar(255) NOT NULL default '',
  Destination varchar(255) NOT NULL default '',
  Flags int(11) NOT NULL default '0',
  ChangeDate timestamp(14) NOT NULL,
  CreateDate timestamp(14) NOT NULL,
  Active tinyint(4) NOT NULL default '0',
  PRIMARY KEY  (Id),
  KEY NameIndex (Name),
  KEY ZoneIdIndex (ZoneId)
);

--
-- Table structure for table 'Mailboxes'
--

CREATE TABLE Mailboxes (
  Id int(10) unsigned NOT NULL auto_increment,
  ZoneId int(10) unsigned NOT NULL default '0',
  Name varchar(255) NOT NULL default '',
  Password varchar(255) NOT NULL default '',
  Quota int(10) unsigned NOT NULL default '0',
  Flags int(11) NOT NULL default '0',
  ChangeDate timestamp(14) NOT NULL,
  CreateDate timestamp(14) NOT NULL,
  Active tinyint(4) NOT NULL default '0',
  PRIMARY KEY  (Id),
  UNIQUE KEY Name (Name),
  KEY ZoneIdIndex (ZoneId),
  KEY NameIndex (Name)
);

--
-- Table structure for table 'Records'
--

CREATE TABLE Records (
  Id int(10) unsigned NOT NULL auto_increment,
  ZoneId int(10) unsigned NOT NULL default '0',
  Name varchar(255) NOT NULL default '',
  Type varchar(8) NOT NULL default '',
  Content varchar(255) NOT NULL default '',
  TimeToLive int(11) NOT NULL default '60',
  Priority int(11) NOT NULL default '0',
  Flags int(11) NOT NULL default '0',
  ChangeDate timestamp(14) NOT NULL,
  CreateDate timestamp(14) NOT NULL,
  Active tinyint(4) NOT NULL default '0',
  PRIMARY KEY  (Id),
  KEY NameIndex (Name)
);

--
-- Table structure for table 'WebForwards'
--

CREATE TABLE WebForwards (
  Id int(10) unsigned NOT NULL auto_increment,
  ZoneId int(10) unsigned NOT NULL default '0',
  Name varchar(255) NOT NULL default '',
  Destination varchar(255) NOT NULL default '',
  Type varchar(7) NOT NULL default 'NORMAL',
  Title varchar(255) NOT NULL default '',
  Description varchar(255) NOT NULL default '',
  Keywords varchar(255) NOT NULL default '',
  FavIcon varchar(255) NOT NULL default '',
  Flags int(11) NOT NULL default '0',
  ChangeDate timestamp(14) NOT NULL,
  CreateDate timestamp(14) NOT NULL,
  Active tinyint(4) NOT NULL default '0',
  PRIMARY KEY  (Id),
  KEY NameIndex (Name),
  KEY ZoneIdIndex (ZoneId)
);

--
-- Table structure for table 'Zones'
--

CREATE TABLE Zones (
  Id int(10) unsigned NOT NULL auto_increment,
  Name varchar(255) NOT NULL default '',
  Hostmaster varchar(255) NOT NULL default '',
  Serial int(10) unsigned NOT NULL default '0',
  AutoSerial tinyint(4) NOT NULL default '0',
  Flags int(11) NOT NULL default '0',
  ChangeDate timestamp(14) NOT NULL,
  CreateDate timestamp(14) NOT NULL,
  Active tinyint(4) NOT NULL default '0',
  TimeToLive int(11) NOT NULL default '0',
  OwnerId varchar(255) NOT NULL default '',
  PRIMARY KEY  (Id),
  UNIQUE KEY Name (Name),
  KEY NameIndex (Name)
);

	</screen>
      </para>
      <para>
	It takes a number of parameters:
      </para>
	<para>
          <variablelist>
            <varlistentry>
              <term>pdns-dbname</term>
              <listitem>
                <para>
                  Database name to connect to
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>pdns-host</term>
              <listitem>
                <para>
                  Database host to connect to
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>pdns-password</term>
              <listitem>
                <para>
                  Password to connect with
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>pdns-socket</term>
              <listitem>
                <para>
                  MySQL socket to use for connecting
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>pdns-user</term>
              <listitem>
                <para>
                  MySQL user to connect as
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
	</para>
      <sect2><title>Notes</title>
	<para>
	  It has been observed that InnoDB tables outperform the default MyISAM tables by a large margin. Furthermore, the default 
	  number of backends (3) should be raised to 10 or 15 for busy servers.
	</para>
      </sect2>
      
    </sect1>

    <sect1 id="generic-mypgsql-backends"><Title>Generic MySQL and PgSQL backends</title>
      <para>
	<table>
	  <title>Generic PgSQL and MySQL backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes - but PostgreSQL does not replicate</entry></row>
	      <row><entry>Master</entry><entry>Yes</entry></row>
	      <row><entry>Slave</entry><entry>Yes</entry></row>
	      <row><entry>Superslave</entry><entry>Yes</entry></row>
	      <row><entry>Autoserial</entry><entry>NO</entry></row>
	      <row><entry>Case</entry><entry>All lower</entry></row>
	      <row><entry>Module name &lt; 2.9.3</entry><entry>pgmysql</entry></row>
	      <row><entry>Module name &gt; 2.9.2</entry><entry>gmysql and gpgsql</entry></row>
	      <row><entry>Lauch name</entry><entry>gmysql and gpgsql2 and gpgsql</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	PostgreSQL and MySQL backend with easily configurable SQL statements, allowing you to graft PDNS on any PostgreSQL or MySQL database of your choosing. 
	Because all database schemas will be different, a generic backend is needed to cover all needs. 
      </para>		
      <para>
	The template queries are expanded using the C function 'snprintf' which implies that substitutions are performed on the basis of %-place holders. 
	To place a a % in a query which will not be substituted, use %%. Make sure to fill out the search key, often called 'name' in lower case!
      </para>
      <para>
	There are in fact two backends, one for PostgreSQL and one for MySQL but they accept the same settings and use almost exactly the same database schema.
      </para>
      <sect2><title>MySQL specifics</title>
	<para>
	  <warning>
	    <para>
	      If using MySQL with 'slave' support enabled in PowerDNS you <command>must</command> run MySQL with a table engine that supports transactions.
	    </para>
	  </warning>
	</para>
	<para>
	  In practice, great results are achieved with the 'InnoDB' tables. PowerDNS will silently function with non-transaction aware MySQLs but at one point
	  this is going to harm your database, for example when an incoming zone transfer fails.
	</para>
	<para>
	  The default setup conforms to the following schema:
	  <programlisting>
create table domains (
 id		 INT auto_increment,
 name		 VARCHAR(255) NOT NULL,
 master		 VARCHAR(128) DEFAULT NULL,
 last_check	 INT DEFAULT NULL,
 type		 VARCHAR(6) NOT NULL,
 notified_serial INT DEFAULT NULL, 
 account         VARCHAR(40) DEFAULT NULL,
 primary key (id)
)type=InnoDB;

CREATE UNIQUE INDEX name_index ON domains(name);

CREATE TABLE records (
  id              INT auto_increment,
  domain_id       INT DEFAULT NULL,
  name            VARCHAR(255) DEFAULT NULL,
  type            VARCHAR(6) DEFAULT NULL,
  content         VARCHAR(255) DEFAULT NULL,
  ttl             INT DEFAULT NULL,
  prio            INT DEFAULT NULL,
  change_date     INT DEFAULT NULL,
  primary key(id)
)type=InnoDB;

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

create table supermasters (
  ip VARCHAR(25) NOT NULL, 
  nameserver VARCHAR(255) NOT NULL, 
  account VARCHAR(40) DEFAULT NULL
);

GRANT SELECT ON supermasters TO pdns;
GRANT ALL ON domains TO pdns;
GRANT ALL ON records TO pdns;
	  </programlisting>
	</para>
	<para>
	  Zone2sql with the --gmysql flag also assumes this layout is in place.
	</para>
	<para>
	  This schema contains all elements needed for master, slave and superslave operation. Depending on which features will be used, the 'GRANT' statements
	  can be trimmed to make sure PDNS cannot subvert the contents of your database.
	</para>
	<para>
	  When using the InnoDB storage engine, we suggest adding the following lines to the 'create table records' command above:
<programlisting>
CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains`
(`id`) ON DELETE CASCADE
</programlisting>
	</para>
	<para>
	  This automates deletion of records on deletion of a domain from the domains table.
	</para>
      </sect2>
      <sect2><title>PostgresSQL specifics</title>
      <para>
	The default setup conforms to the following schema, which you should add to a PostgreSQL database.
	<programlisting>
create table domains (
 id		 SERIAL PRIMARY KEY,
 name		 VARCHAR(255) NOT NULL,
 master		 VARCHAR(128) DEFAULT NULL,
 last_check	 INT DEFAULT NULL,
 type		 VARCHAR(6) NOT NULL,
 notified_serial INT DEFAULT NULL, 
 account         VARCHAR(40) DEFAULT NULL
);
CREATE UNIQUE INDEX name_index ON domains(name);
  
CREATE TABLE records (
        id              SERIAL PRIMARY KEY,
        domain_id       INT DEFAULT NULL,
        name            VARCHAR(255) DEFAULT NULL,
        type            VARCHAR(6) DEFAULT NULL,
        content         VARCHAR(255) DEFAULT NULL,
        ttl             INT DEFAULT NULL,
        prio            INT DEFAULT NULL,
        change_date     INT DEFAULT NULL, 
        CONSTRAINT domain_exists 
        FOREIGN KEY(domain_id) REFERENCES domains(id)
        ON DELETE CASCADE
);

CREATE INDEX rec_name_index ON records(name);
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);

create table supermasters (
	  ip VARCHAR(25) NOT NULL, 
	  nameserver VARCHAR(255) NOT NULL, 
	  account VARCHAR(40) DEFAULT NULL
);

GRANT SELECT ON supermasters TO pdns;
GRANT ALL ON domains TO pdns;
GRANT ALL ON domains_id_seq TO pdns;
GRANT ALL ON records TO pdns;
GRANT ALL ON records_id_seq TO pdns;
	</programlisting>
      </para>
      <para>
	This schema contains all elements needed for master, slave and superslave operation. Depending on which features will be used, the 'GRANT' statements
	can be trimmed to make sure PDNS cannot subvert the contents of your database.
      </para>
      <para>
	Zone2sql with the --gpgsql flag also assumes this layout is in place.
	</para>
	<para>
	  With PostgreSQL, you may have to run 'createdb powerdns' first and then connect to that database with 'psql powerdns', and 
	  feed it the schema above.
	</para>
      </sect2>
      <sect2 id="goracle"><title>Oracle specifics</title>
      <para>
	  Generic Oracle support is only available since version 2.9.18.
	The default setup conforms to the following schema, which you should add to an Oracle database. You may need or want to add 'namespace' statements.
	<programlisting>

create table domains (
 id		 NUMBER,
 name		 VARCHAR(255) NOT NULL,
 master		 VARCHAR(128) DEFAULT NULL,
 last_check	 INT DEFAULT NULL,
 type		 VARCHAR(6) NOT NULL,
 notified_serial INT DEFAULT NULL, 
 account         VARCHAR(40) DEFAULT NULL,
 primary key (id)
);
create sequence DOMAINS_ID_SEQUENCE; 
create index DOMAINS$NAME on Domains (NAME);

 
CREATE TABLE records (
        id              number(11) not NULL,
        domain_id       INT DEFAULT NULL REFERENCES Domains(ID) ON DELETE CASCADE,
        name            VARCHAR(255) DEFAULT NULL,
        type            VARCHAR(6) DEFAULT NULL,
        content         VARCHAR(255) DEFAULT NULL,
        ttl             INT DEFAULT NULL,
        prio            INT DEFAULT NULL,
        change_date     INT DEFAULT NULL, 
	primary key (id)
);

create index RECORDS$NAME on RECORDS (NAME);
create sequence RECORDS_ID_SEQUENCE;

create table supermasters (
	  ip VARCHAR(25) NOT NULL, 
	  nameserver VARCHAR(255) NOT NULL, 
	  account VARCHAR(40) DEFAULT NULL
);

	</programlisting>
      </para>
      <para>
	This schema contains all elements needed for master, slave and superslave operation. Depending on which features will be used,  'GRANT' statements
	can be trimmed to make sure PDNS cannot subvert the contents of your database.
      </para>
	<para>
	  Zone2sql with the --gpgsql flag also assumes this layout is in place.
	</para>
	<para>
	  Inserting records is a bit different compared to MySQL and PostgreSQL, you should use:
<screen>
insert into domains (id,name,type) values (domains_id_sequence.nextval,'netherlabs.nl','NATIVE');
	    </screen>
	  </para>
	  <para>
	  Furthermore, use the <command>goracle-tnsname</command> setting to specify which TNSNAME the Generic Oracle Backend
	  should be connectiong to. There are no <command>goracle-dbname</command>, <command>goracle-host</command> or
          <command>goracle-port</command> settings, their equivalent is in <filename>/etc/tnsnames.ora</filename>.
	  </para>
      </sect2>

      <sect2><title>Basic functionality</title>
	<para>
	  4 queries are needed for regular lookups, 4 for 'fancy records' which are disabled by default and 1 is needed for zone transfers.
	</para>
	<para>The 4+4 regular queries must return the following 6 fields, in this exact order:
	  <variablelist>
	    <varlistentry>
	      <term>content</term>
	      <listitem>
		<para>
		  This is the 'right hand side' of a DNS record. For an A record, this is the IP address for example.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>ttl</term>
	      <listitem>
		<para>
		  TTL of this record, in seconds. Must be a real value, no checking is performed.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>prio</term>
	      <listitem>
		<para>
		  For MX records, this should be the priority of the mail exchanger specified.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>qtype</term>
	      <listitem>
		<para>
		  The ASCII representation of the qtype of this record. Examples are 'A', 'MX', 'SOA', 'AAAA'. Make sure that this
		  field returns an exact answer - PDNS won't recognise 'A      ' as 'A'. This can be achieved by using a VARCHAR instead 
		  of a CHAR.
		</para>
	      </listitem>
	      
	    </varlistentry>
	    <varlistentry>
	      <term>domain_id</term>
	      <listitem>
		<para>
		  Each domain must have a unique domain_id. No two domains may share a domain_id, all records in a domain should have the same. A number.
		</para>
	    </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>name</term>
	      <listitem>
		<para>
		  Actual name of a record. Must not end in a '.' and be fully qualified - it is not relative to the name of the domain!
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	  Please note that the names of the fields are not relevant, but the order is!
	</para>
	<para>
	  As said earlier, there are 8 SQL queries for regular lookups. To configure them, set 'gmysql-basic-query' or 'gpgsql-basic-query', depending on your
	  choice of backend. If so called 'MBOXFW' fancy records are not used, four queries remain:
	  <variablelist>
	    <varlistentry>
	      <term>basic-query</term>
	      <listitem>
		<para>
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where type='%s' and name='%s'</command>
		  This is the most used query, needed for doing 1:1 lookups of qtype/name values. First %s is replaced by the ASCII representation
		  of the qtype of the question, the second by the name.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>id-query</term>
	      <listitem>
		<para>
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where type='%s' and name='%s' and domain_id=%d</command>
		  Used for doing lookups within a domain. First %s is replaced by the qtype, the %d which should appear after the %s by the numeric 
		  domain_id.
		</para>
	      </listitem>
	    </varlistentry>
	    
	    <varlistentry>
	      <term>any-query</term>
	      <listitem>
		<para>
		  For doing ANY queries. Also used internally.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where name='%s'</command>
		  The %s is replaced by the qname of the question.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>any-id-query</term>
	      <listitem>
		<para>
		  For doing ANY queries within a domain. Also used internally.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where name='%s' and domain_id=%d</command>
		  The %s is replaced by the name of the domain, the %d by the numerical domain id.
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
	<para>
	  The last query is for listing the entire contents of a zone. This is needed when performing a zone transfer, but sometimes also internally:
	  <variablelist>
	    <varlistentry>
	      <term>list-query</term>
	      <listitem>
		<para>
		  To list an entire zone.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where domain_id=%d</command>
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
      <sect2 id="master-slave-queries"><title>Master/slave queries</title>
	<para>
	  Most installations will have zero need to change the following settings, but should the need arise, here they are:
	  <variablelist>
	    <varlistentry>
	      <term>master-zone-query</term>
	      <listitem>
		<para>
		  Called to determine the master of a zone.
		  Default: <command>select master from domains where name='%s' and type='SLAVE'</command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>info-zone-query</term>
	      <listitem>
		<para>
		  Called to retrieve (nearly) all information for a domain:
		  Default: <command>select id,name,master,last_check,notified_serial,type from domains where name='%s'</command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>info-all-slaves-query</term>
	      <listitem>
		<para>
		  Called to retrieve all slave domains
		  Default: <command>select id,name,master,last_check,type from domains where type='SLAVE'</command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>supermaster-query</term>
	      <listitem>
		<para>
		  Called to determine if a certain host is a supermaster for a certain domain name.
		  Default: <command>
		    select account from supermasters where ip='%s' and nameserver='%s'");
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>insert-slave-query</term>
	      <listitem>
		<para>
		  Called to add a domain as slave after a supermaster notification.
		  Default: <command>
		    insert into domains (type,name,master,account) values('SLAVE','%s','%s','%s')
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>insert-record-query</term>
	      <listitem>
		<para>
		  Called during incoming AXFR.
		  Default: <command>
		    insert into records (content,ttl,prio,type,domain_id,name) values ('%s',%d,%d,'%s',%d,'%s')
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>update-serial-query</term>
	      <listitem>
		<para>
		  Called to update the last notified serial of a master domain.
		  Default: <command>
		    update domains set notified_serial=%d where id=%d
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>update-lastcheck-query</term>
	      <listitem>
		<para>
		  Called to update the last time a slave domain was checked for freshness.
		  Default: <command>
		    update domains set notified_serial=%d where id=%d
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>info-all-master-query</term>
	      <listitem>
		<para>
		  Called to get data on all domains for which the server is master.
		  Default: <command>
		    select id,name,master,last_check,notified_serial,type from domains where type='MASTER'
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>delete-zone-query</term>
	      <listitem>
		<para>
		  Called to delete all records of a zone. Used before an incoming AXFR.
		  Default: <command>
		    delete from records where domain_id=%d
		  </command>
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
      <sect2><title>Fancy records</title>
	<para>
	  If PDNS is used with so called 'Fancy Records', the 'MBOXFW' record exists which specifies an email address forwarding instruction, 
	  wildcard queries are sometimes needed. This is not enabled by default.  A wildcard query is 
	  an internal concept - it has no relation to *.domain-type lookups. You can safely leave these queries blank.
	  <variablelist>
	    <varlistentry>
	      <term>wildcard-query</term>
	      <listitem>
		<para>
		  Can be left blank. See above for an explanation.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where type='%s' and name like '%s'</command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>wildcard-id-query</term>
	      <listitem>
		<para>
		  Can be left blank. See above for an explanation.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where type='%s' and name like '%s' and domain_id=%d</command>
		  Used for doing lookups within a domain.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>wildcard-any-query</term>
	      <listitem>
		<para>
		  For doing wildcard ANY queries.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where name like '%s'</command>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>wildcard-any-id-query</term>
	      <listitem>
		<para>
		  For doing wildcard ANY queries within a domain.
		  Default: <command>select content,ttl,prio,type,domain_id,name from records where name like '%s' and domain_id=%d</command>
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
	  
      <sect2><title>Settings and specifying queries</title>
	<para>
	  The queries above are specified in pdns.conf. For example, the basic-query would appear as:
	  <screen>
	    gpgsql-basic-query=select content,ttl,prio,type,domain_id,name from records where type='%s' and name='%s'
	  </screen>
	  When using the Generic PostgreSQL backend, they appear as above. When using the generic MySQL backend, change the
	  "gpgsql-" prefix to "gmysql-".
	</para>
	<para>
	  Queries can span multiple lines, like this:
	  <screen>
	    gpgsql-basic-query=select content,ttl,prio,type,domain_id,name from records \
	    where type='%s' and name='%s'
	  </screen>
	  Do not wrap statements in quotes as this will not work.
	  Besides the query related settings, the following configuration options are available:
	</para>
	<para>
          <variablelist>
            <varlistentry>
              <term>gpgsql-dbname</term>
              <listitem>
                <para>
                  Database name to connect to
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>gpgsql-host</term>
              <listitem>
                <para>
                  Database host to connect to. WARNING: When specified as a hostname a chicken/egg situation might arise where the database
		  is needed to resolve the IP address of the database. It is best to supply an IP address of the database here.
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>gmysql-socket (only for MySQL!)</term>
              <listitem>
                <para>
		  Filename where the MySQL connection socket resides. Often <filename>/tmp/mysql.sock</filename> or <filename>/var/run/mysqld/mysqld.sock</filename>. 
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>gpgsql-password</term>
              <listitem>
                <para>
                  Password to connect with
                </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>gpgsql-user</term>
              <listitem>
                <para>
                  PgSQL user to connect as
                </para>
              </listitem>
            </varlistentry>
          </variablelist>
	</para>
      </sect2>
      <sect2><title>Native operation</title>
	<para>
	  For native operation, either drop the FOREIGN KEY on the domain_id field, or (recommended), make sure
	  the <command>domains</command> table is filled properly. To add a domain, issue the following:
	  <programlisting>
	    insert into domains (name,type) values ('powerdns.com','NATIVE');
	  </programlisting>
	  The records table can now be filled by with the domain_id set to the id of the domains table row just inserted.
	</para>
      </sect2>
      <sect2><title>Slave operation</title>
	<para>
	  The PostgreSQL backend is fully slave capable. To become a slave of the 'powerdns.com' domain, execute this:
	  <programlisting>
	    insert into domains (name,master,type) values ('powerdns.com','213.244.168.217','SLAVE');
	  </programlisting>
	  And wait a while for PDNS to pick up the addition - which happens within one minute. There is no need to inform PDNS that a new domain
	  was added.
	  Typical output is:
	  <programlisting>
	    Apr 09 13:34:29 All slave domains are fresh
	    Apr 09 13:35:29 1 slave domain needs checking
	    Apr 09 13:35:29 Domain powerdns.com is stale, master serial 1, our serial 0
	    Apr 09 13:35:30 [gPgSQLBackend] Connected to database
	    Apr 09 13:35:30 AXFR started for 'powerdns.com'
	    Apr 09 13:35:30 AXFR done for 'powerdns.com'
	    Apr 09 13:35:30 [gPgSQLBackend] Closing connection
	  </programlisting>
	</para>
	<para>
	  From now on, PDNS is authoritative for the 'powerdns.com' zone and will respond accordingly for queries within that zone. 
	</para>
	<para>
	  Periodically, PDNS schedules checks to see if domains are still fresh. The default <command>slave-cycle-interval</command> is 60 seconds, large installations may need to raise this value. Once a domain has been checked, it will not be checked before its SOA refresh timer has expired. Domains whose status is unknown get checked every 60 seconds by default.
	</para>
      </sect2>
      <sect2><title>Superslave operation</title>
	<para>
	  To configure a supermaster with IP address 10.0.0.11 which lists this installation as 'autoslave.powerdns.com', issue the following:
	  <programlisting>
	    insert into supermasters ('10.0.0.11','autoslave.powerdns.com','internal');
	  </programlisting>
	  From now on, valid notifies from 10.0.0.11 that list a NS record containing 'autoslave.powerdns.com' will lead to the
	  provisioning of a slave domain under the account 'internal'. See <xref linkend="supermaster"> for details.
	</para>
      </sect2>
      <sect2><title>Master operation</title>
	<para>
	  The PostgreSQL backend is fully master capable with automatic discovery of serial changes. Raising the serial number of a domain
	  suffices to trigger PDNS to send out notifications. To configure a domain for master operation instead of the default native replication,
	  issue:
	  <programlisting>
	    insert into domains (name,type) values ('powerdns.com','MASTER');
	  </programlisting>
	  Make sure that the assigned id in the domains table matches the domain_id field in the records table!
	</para>
      </sect2>
    </sect1>
    
    <sect1 id="oracle"><Title>Oracle backend</title>
      <para>
	<table>
	  <title>Oracle backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>Yes</entry></row>
	      <row><entry>Module name</entry><entry>oracle</entry></row>
	      <row><entry>Launch name</entry><entry>oracle</entry></row>

	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	Oracle backend with easily configurable SQL statements, allowing you to graft PDNS on any Oracle database of your choosing.
      </para>
      <para>
	PowerDNS is currently ascertaining if this backend can be distributed in binary form without violating Oracle licensing. In the meantime, 
	the source code to the Oracle backend is available in the pdns distribution.
      </para>
      <para>
	The following configuration settings are available:
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>oracle-debug-queries</term>
	    <listitem>
	      <para>
		Output all queries to disk for debugging purposes.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-time-queries</term>
	    <listitem>
	      <para>
		Output all queries to disk for timing purposes.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-uppercase-database</term>
	    <listitem>
	      <para>
		Change all domain names to uppercase before querying database.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-database</term>
	    <listitem>
	      <para>
		Oracle database name to connect to.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-home</term>
	    <listitem>
	      <para>
		PDNS can set the ORACLE_HOME environment variable from within the executable, allowing execution of
		the daemon from init.d scripts where ORACLE_HOME may not yet be set.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-sid</term>
	    <listitem>
	      <para>
		PDNS can set the ORACLE_SID environment variable from within the executable, allowing execution of
		the daemon from init.d scripts where ORACLE_SID may not yet be set.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-username</term>
	    <listitem>
	      <para>
		Oracle username to connect as.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-password</term>
	    <listitem>
	      <para>
		Oracle password to connect with.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      <para>
	The generic Oracle backend can be configured to use user-specified queries. The following are the default queries
	and their names:
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>oracle-forward-query</term>
	    <listitem>
	      <para>
		select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate,0) from Records where name = :name and type = :type
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-forward-query-by-zone</term>
	    <listitem>
	      <para>
		select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate,0) from records where name = :name and type = :type and ZoneId = :id
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-forward-any-query</term>
	    <listitem>
	      <para>
		select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate,0) from records where name = :name
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>oracle-list-query</term>
	    <listitem>
	      <para>
		select content, TimeToLive, Priority, type, ZoneId, nvl(ChangeDate, 0), name from records where ZoneId = :id
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      <sect2><title>Setting up Oracle for use with PowerDNS</title>
	<para>
	  To setup a database that corresponds to these default queries, issue the following as Oracle user sys:
	  <screen>
	    create user powerdns identified by YOURPASSWORD;
	    grant connect to powerdns;
	    
	    create tablespace powerdns datafile '/opt/oracle/oradata/oracle/powerdns.dbf'
	      size 256M extent management local autoallocate;
	    
	    alter user powerdns quota unlimited on powerdns; 
	  </screen>
	</para>
	<para>
	  As user 'powerdns' continue with:
	  <screen>
create table Domains (
 ID		 number(11) NOT NULL,
 NAME		 VARCHAR(255) NOT NULL,
 MASTER		 VARCHAR(128) DEFAULT NULL,
 LAST_CHECK	 INT DEFAULT NULL,
 TYPE		 VARCHAR(6) NOT NULL,
 NOTIFIED_SERIAL INT DEFAULT NULL,
 ACCOUNT	 VARCHAR(40) DEFAULT NULL,
 primary key (ID)
)tablespace POWERDNS;

create index DOMAINS$NAME on Domains (NAME) tablespace POWERDNS;
create sequence DOMAINS_ID_SEQUENCE;

create table Records
(
  ID                number(11) NOT NULL,
  ZoneID            number(11) default NULL REFERENCES Domains(ID) ON DELETE CASCADE,
  NAME              varchar2(255) default NULL,
  TYPE              varchar2(6) default NULL,  
  CONTENT           varchar2(255) default NULL,
  TimeToLive        number(11) default NULL,   
  Priority          number(11) default NULL,
  CreateDate        number(11) default NULL,
  ChangeDate        number(11) default NULL,
  primary key (ID)
)tablespace POWERDNS;

create index RECORDS$NAME on RECORDS (NAME) tablespace POWERDNS;
create sequence RECORDS_ID_SEQUENCE;
	  </screen>
	</para>
	<para>
	  To insert records, either use <command>zone2sql</command> with the <command>--oracle</command> setting, or execute sql
	  along the lines of:
	  <screen>
insert into domains (id,name,type) values (domains_id_sequence.nextval,'netherlabs.nl','NATIVE');
insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'SOA', 'ahu.casema.net. hostmaster.ds9a.nl. 2000081401 28800 7200 604800 86400', 3600, 0 from Domains where name='netherlabs.nl';
insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'NS', 'ahu.casema.net', 3600, 0 from Domains where name='netherlabs.nl';
insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'NS', 'ns1.pine.nl', 3600, 0 from Domains where name='netherlabs.nl';
insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'NS', 'ns2.pine.nl', 3600, 0 from Domains where name='netherlabs.nl';
insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'A', '213.244.168.210', 3600, 0 from Domains where name='netherlabs.nl';
insert into Records (id,ZoneId, name,type,content,TimeToLive,Priority) select RECORDS_ID_SEQUENCE.nextval,id ,'netherlabs.nl', 'MX', 'outpost.ds9a.nl', 3600, 10 from Domains where name='netherlabs.nl';

	  </screen>
	</para>
	<para>
	  For performance reasons it is best to specify <command>--transactions</command> too!
	</para>
      </sect2>
    </sect1>

    <sect1 id="gsqlite">
      <title>Generic SQLite backend (2 and 3)</title>
      <para>
      	<table>
	        <title>Generic SQLite backend capabilities</title>
	        <tgroup cols=2>
	          <tbody>
	            <row><entry>Native</entry><entry>Yes</entry></row>
	            <row><entry>Master</entry><entry>Yes</entry></row>
	            <row><entry>Slave</entry><entry>Yes</entry></row>
	            <row><entry>Superslave</entry><entry>Yes</entry></row>
	            <row><entry>Module name</entry><entry>gsqlite</entry></row>
	            <row><entry>Launch name</entry><entry>gsqlite</entry></row>
	          </tbody>
	        </tgroup>
	      </table>
      </para>
      <para>
        This backend retrieves all data from a SQLite database, which is a RDBMS that's embedded into the application itself, so you won't need to be running a seperate server process.
        It also reduces overhead, and simplifies installation.
        At <ulink url="http://www.sqlite.org">http://www.sqlite.org</ulink> you can find more information about SQLite.
      </para>
      <para>
        As this is a generic backend, built on top of the gSql framework, you can specify all queries as documented in <link linkend="generic-mypgsql-backends">Generic MySQL and PgSQL backends</link>.
      </para>
      <para>
	SQLite exists in two incompatible versions, numbered 2 and 3, and from 2.9.21 onwards, PowerDNS supports both. It is recommended to go with version 3 
	as it is newer, has better performance and is actively maintained.
      </para>
      <sect2>
        <title>Compiling the SQLite backend</title>
        <para>
          Before you can begin compiling PowerDNS with the SQLite backend you need to have the SQLite utility and library installed on your system.
          You can download these from <ulink url="http://www.sqlite.org/download.html">http://www.sqlite.org/download.html</ulink>, or you can use packages (if your distribution provides those).
        </para>
        <para>
          When you've installed the library you can use: <command>./configure --with-modules="gsqlite"</command> or
	  <command>./configure --with-modules="gsqlite3"</command> to configure PowerDNS to use the SQLite backend.
          Compilation can then proceed as usual. 
        </para>
	<para>
	  SQLite is included in most PowerDNS binary releases.
	</para>
      </sect2>
      <sect2>
        <title>Setting up the database</title>
	      <para>
	        Before you can use this backend you first have to set it up and fill it with data.	        
	        The default setup conforms to the following schema:
	        
	        <programlisting>
            create table domains (
              id                INTEGER PRIMARY KEY,
              name              VARCHAR(255) NOT NULL,
              master            VARCHAR(128) DEFAULT NULL,
              last_check        INTEGER DEFAULT NULL,
              type              VARCHAR(6) NOT NULL,
              notified_serial   INTEGER DEFAULT NULL, 
              account           VARCHAR(40) DEFAULT NULL
            );

            CREATE UNIQUE INDEX name_index ON domains(name);

            CREATE TABLE records (
              id              INTEGER PRIMARY KEY,
              domain_id       INTEGER DEFAULT NULL,
              name            VARCHAR(255) DEFAULT NULL,
              type            VARCHAR(6) DEFAULT NULL,
              content         VARCHAR(255) DEFAULT NULL,
              ttl             INTEGER DEFAULT NULL,
              prio            INTEGER DEFAULT NULL,
              change_date     INTEGER DEFAULT NULL
            );
              
            CREATE INDEX rec_name_index ON records(name);
            CREATE INDEX nametype_index ON records(name,type);
            CREATE INDEX domain_id ON records(domain_id);

            create table supermasters (
              ip          VARCHAR(25) NOT NULL, 
              nameserver  VARCHAR(255) NOT NULL, 
              account     VARCHAR(40) DEFAULT NULL
            );
	        </programlisting>
	      </para>
	      <para>
	        This schema contains all elements needed for master, slave and superslave operation.	  
	      </para>
      	<para>
	        After you have created the database you probably want to fill it with data. 
	        If you have a BIND zonefile it's as easy as: <command>zone2sql --zone=myzonefile --gmysql | sqlite powerdns.sqlite</command>, but
	        you can also use AXFR (or insert data manually).
	      </para>
	<para>
	  To communicate with a SQLite database, use either the 'sqlite' or 'sqlite3' program, and feed it SQL.
	</para>
      </sect2>
      <sect2>
        <title>Using the SQLite backend</title>
        <para>
          The last thing you need to do is telling PowerDNS to use the SQLite backend. 
        </para>
        <para>
          <programlisting>
            # in pdns.conf
            launch=gsqlite # or gsqlite3
            gsqlite-database=&lt;path to your SQLite database&gt;   # or gsqlite3-database
          </programlisting>
        </para>
        <para>
          Then you can start PowerDNS and it should notify you that a connection to the database was made.
        </para>
      </sect2>      
    </sect1>
    
    <sect1 id="db2"><Title>DB2 backend</title>
      <para>
	<table>
	  <title>DB2 backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>Yes</entry></row>
	      <row><entry>Module name</entry><entry>db2</entry></row>
	      <row><entry>Launch name</entry><entry>db2</entry></row>

	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	PowerDNS is currently ascertaining if this backend can be distributed in binary form without violating IBM DB2 licensing. 
      </para>
      <para>
	The DB2 backend executes the following queries:
	<variablelist>
	  <varlistentry>
	    <term>Forward Query</term>
	    <listitem>
	      <para>
		select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where Name = ? and type = ?
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Forward By Zone Query</term>
	    <listitem>
	      <para>
		select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where Name = ? and Type = ? and ZoneId = ?
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>Forward Any Query</term>
	    <listitem>
	      <para>
		select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where Name = ?
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>List Query</term>
	    <listitem>
	      <para>
		select Content, TimeToLive, Priority, Type, ZoneId, 0 as ChangeDate, Name from Records where ZoneId = ?
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      <para>
	Configuration settings:
	<variablelist>
	  <varlistentry>
	    <term>db2-server</term>
	    <listitem>
	      <para>
		Server name to connect to. Defaults to 'powerdns'. Make sure that your nameserver is not needed to resolve an IP address needed to connect as
		this might lead to a chicken/egg situation. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>db2-user</term>
	    <listitem>
	      <para>
		Username to connect as. Defaults to 'powerdns'.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>db2-password</term>
	    <listitem>
	      <para>
		Password to connect with. Defaults to 'powerdns'.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>
    
    <sect1 id="bindbackend"><Title>Bind zone file backend</title>
      <para>
	<table>
	  <title>Bind zone file backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>Yes</entry></row>
	      <row><entry>Slave</entry><entry>Yes</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>No</entry></row>
	      <row><entry>Module name</entry><entry>none (built in)</entry></row>
	      <row><entry>Launch</entry><entry>bind</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	The BindBackend started life as a demonstration of the versatility of PDNS but quickly gained in importance when there appeared to be demand
	for a Bind 'workalike'.
      </para>
      <para>
	The BindBackend parses a Bind-style named.conf and extracts information about zones from it. It makes no attempt to honour other configuration flags,
	which you should configure (when available) using the PDNS native configuration.
      </para>
      <para>
	<variablelist>
	  <varlistentry>
	    <term>--help=bind</term>
	    <listitem>
	      <para>
                Outputs all known parameters related to the bindbackend
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bind-example-zones</term>
	    <listitem>
	      <para>
		Loads the 'example.com' zone which can be queried to determine if PowerDNS is functioning without configuring 
		database backends. This feature is no longer supported from 2.9.21 onwards.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bind-config=</term>
	    <listitem>
	      <para>
		Location of the Bind configuration file to parse.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bind-check-interval=</term>
	    <listitem>
	      <para>
		How often to check for zone changes. See 'Operation' section.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bind-enable-huffman</term>
	    <listitem>
	      <para>
		Enable Huffman compression on zone data. Currently saves around 20% of memory actually used, but slows down operation
		somewhat.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      <sect2>
	<title>Operation</title>
	<para>
	  On launch, the BindBackend first parses the named.conf to determine which zones need to be loaded. These will then be parsed
	  and made available for serving, as they are parsed. So a named.conf with 100.000 zones may take 20 seconds to load, but after 10 seconds, 
	  50.000 zones will already be available. While a domain is being loaded, it is not yet available, to prevent incomplete answers.
	</para>
	<para>
	  Reloading is currently done only when a request for a zone comes in, and then only after <command>bind-check-interval</command> seconds have passed
	  after the last check. If a change occurred, access to the zone is disabled, the file is reloaded, access is restored, and the question is answered.
	  For regular zones, reloading is fast enough to answer the question which lead to the reload within the DNS timeout.
	</para>
        <para>
          If <command>bind-check-interval</command> is specified as zero, no checks will be performed until the <command>pdns_control reload</command>
	  is given.
        </para>
      </sect2>
      <sect2 id="bind-control-commands"><title>Pdns_control commands</title>
	<para>
	  <variablelist>
	    <varlistentry>
	      <term>bind-domain-status <userinput>domain</userinput> [<userinput>domain</userinput>]</term>
	      <listitem>
		<para>
		  Output status of domain or domains. Can be one of 'seen in named.conf, not parsed', 'parsed successfully at &lt;time;&gt;' or
		  'error parsing at line ... at &lt;time&gt;'.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>bind-list-rejects</term>
	      <listitem>
		<para>
		  Lists all zones that have problems, and what those problems are.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>bind-reload-now <userinput>domain</userinput></term>
	      <listitem>
		<para>
		  Reloads a zone from disk NOW, reporting back results.
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
      <sect2><title>Performance</title>
	<para>
	  The BindBackend does not benefit from the packet cache as it is fast enough on its own. Furthermore, on most systems, there will
	  be no benefit in using multiple CPUs for the packetcache, so a noticeable speedup can be attained by specifying 
	  <command>distributor-threads=1</command> in <filename>pdns.conf</filename>.
	</para>
      </sect2>
      <sect2><title>Master/slave configuration</title>
	<sect3><title>Master</title>
	  <para>
	    Works as expected. At startup, no notification storm is performed as this is generally not useful. Perhaps in the future the Bind Backend
	    will attempt to store zone metadata in the zone, allowing it to determine if a zone has changed its serial since the last time
	    notifications were sent out.
	  </para>
	  <para>
	    Changes which are discovered when reloading zones do lead to notifications however.
	  </para>
	</sect3>
	<sect3><title>Slave</title>
	  <para>
	    Also works as expected. The Bind backend expects to be able to write to a directory where a slave domain lives. The incoming zone is stored
	    as 'zonename.RANDOM' and atomically renamed if it is retrieved successfully, and parsed only then.
	  </para>
	  <para>
	    In the future, this may be improved so the old zone remains available should parsing fail.
	  </para>
	</sect3>
      </sect2>
      <sect2><title>Commands</title>
	<para>
	  <command>pdns_control</command> offers commands to communicate instructions to PowerDNS. These are detailed here.
	  <variablelist>
	    <varlistentry>
	      <term>rediscover</term>
	      <listitem>
		<para>
		  Reread the bind configuration file (<filename>named.conf</filename>). If parsing fails, the old configuration
		  remains in force and pdns_control reports the error. Any newly discovered domains are read, discarded domains 
		  are removed from memory.
		  <note>
		    <para>
		      Except that with 2.9.3, they are not removed from memory.
		    </para>
		  </note>
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>reload</term>
	      <listitem>
		<para>
		  All zones with a changed timestamp are reloaded at the next incoming query for them.
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
    </sect1>

  <sect1 id="odbc">
    <Title>ODBC backend</Title>
      <para>
	<table>
	  <title>ODBC backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>Yes (experimental)</entry></row>
	      <row><entry>Slave</entry><entry>Yes (experimental)</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>Yes</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
    <para>
      The ODBC backend can retrieve zone information from any source that has a ODBC driver available.
      <note><para>This backend is only available on PowerDNS for Windows.</para></note>
    </para>

    <para>
	The ODBC backend needs data in a fixed schema which is the same as the data needed by the MySQL backend. The create statement
	will resemble this:
        <screen>
          CREATE TABLE records (
	  id int(11) NOT NULL auto_increment,
	  domain_id int(11) default NULL,
	  name varchar(255) default NULL,
	  type varchar(6) default NULL,
	  content varchar(255) default NULL,
	  ttl int(11) default NULL,
	  prio int(11) default NULL,
	  change_date int(11) default NULL,
	  PRIMARY KEY (id),
	  KEY name_index(name),
	  KEY nametype_index(name,type),
	  KEY domainid_index(domain_id)
	  );
        </screen>
    </para>

    <para>
      To use the ODBC backend an ODBC source has to be created, to do this see the section Installing PowerDNS on Microsoft Windows, <xref linkend="windows">.
    </para>

    <para>
	The following configuration settings are available:

      <variablelist>
	  <varlistentry>
	  <term>odbc-datasource</term>
	  <listitem>
	      <para>
          Specifies the name of the data source to use. 
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	  <term>odbc-user</term>
	  <listitem>
	      <para>
          Specifies the username that has to be used to log into the datasource.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	  <term>odbc-pass</term>
	  <listitem>
	      <para>
          Specifies the user's password.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	  <term>odbc-table</term>
	  <listitem>
	      <para>
          Specifies the name of the table containing the zone information.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      <para>
	The ODBC backend has been tested with Microsoft Access, MySQL (via MyODBC) and Microsoft SQLServer. As the SQL statements used are very basic,
	it is expected to work with many ODBC drivers.
      </para>
    </sect1>
    <sect1 id="xdbbackend"><Title>XDB Backend</title>
      <para>
	Special purpose backend for grandiose performance. Can talk to Tridge's Trivial Database, or to regular *db tables on disk. Currently only sparsely
	documented. Very useful if you need to do &gt;50.000 queries/second, which we actually measured on the .ORG zone.
      </para>
      <para>
	More documentation will follow.
      </para>
    </sect1>
    <sect1 id="ldap"><Title>LDAP backend</title>
      <para>
	<warning>
	  <para>
	    This documentation has moved to <ulink url="http://wiki.linuxnetworks.de/index.php/PowerDNS_ldapbackend">its own page</ulink>. The information in this chapter
	    may be outdated!
	  </para>
	</warning>
      </para>
      <para>
	The main author for this module is Norbert Sendetzky who also has his own <ulink url="http://www.linuxnetworks.de/pdnsldap/index.html">PowerDNS-LDAP page</ulink>.
      </para>
      <para>
	He also maintains the <ulink url="http://wiki.linuxnetworks.de/index.php/PowerDNS_ldapbackend">LDAP backends documentation</ulink> there. The information 
	below may be outdated!
      </para>
      <para>
	<table>
	  <title>LDAP backend capabilities</title>
	  <tgroup cols=2>
	    <tbody>
	      <row><entry>Native</entry><entry>Yes</entry></row>
	      <row><entry>Master</entry><entry>No</entry></row>
	      <row><entry>Slave</entry><entry>No</entry></row>
	      <row><entry>Superslave</entry><entry>No</entry></row>
	      <row><entry>Autoserial</entry><entry>Yes</entry></row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	As of 2.9.6, PowerDNS comes with an LDAP backend. The code for this was submitted by Norbert Sendetzky.
      </para>
      <para>
	The following settings are available to configure the LDAP backend:
	<variablelist>
	  <varlistentry>
	    <term>ldap-host</term>
	    <listitem>
	      <para>
		LDAP host to connect to, defaults to localhost.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>ldap-port</term>
	    <listitem>
	      <para>
		LDAP port to connect to, defaults to 389.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>ldap-basedn</term>
	    <listitem>
	      <para>
		Root for DNS searches. Must be configured before the LDAP backend will work.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>ldap-binddn</term>
	    <listitem>
	      <para>
		Distinguished Name to bind with to the LDAP server. Defaults to the empty string for anonymous bind.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>ldap-secret</term>
	    <listitem>
	      <para>
		Secret to bind with to LDAP server. Defaults to the empty string for anonymous bind.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>ldap-default-ttl</term>
	    <listitem>
	      <para>
		TTL for records with no dnsttl attribute. Defaults to 86400 seconds.
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
      <para>
	The schema used is that defined by RFC 1279 and is present in OpenLDAP under the name 'cosine.schema'.
	An example LDIF file:
	<screen>
# zone related things including SOA, NS and MX records

dn: dc=example
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: example
soarecord: ns.example.dom hostmaster@example.dom 2002010401 1800 3600 604800 84600
nsrecord: ns.example.dom
mxrecord: 10 mail.example.dom
mxrecord: 20 mail2.example.dom
associateddomain: example.dom


# Simple record (mail.example.dom has address 172.168.0.2)

dn: dc=mail,dc=example
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: mail
arecord: 172.168.0.2
associateddomain: mail.example.dom

# There may more than one entry per record
# This is also applicable to all other records including "associateddomain"
# but not for a CNAME record

dn: dc=server,dc=snapcount
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: server
arecord: 10.1.0.1
arecord: 172.168.0.1
associateddomain: server.example.dom


# domain alias ({mail2,ns}.example.dom is CNAME for server.example.dom)
# cnamerecord must only contain one entry

dn: dc=backup,dc=snapcount
objectclass: top
objectclass: dnsdomain
objectclass: domainrelatedobject
dc: server
cnamerecord: server.example.dom
associateddomain: mail2.example.dom
associateddomain: ns.example.dom
</screen>
      </para>
    </sect1>
  </appendix>
<appendix id="pdns-internals"><title>PDNS internals</title>
    <para>
      PDNS is normally launched by the init.d script but is actually a binary called <filename>pdns_server</filename>. This 
      file is started by the <command>start</command> and <command>monitor</command> commands to the init.d script. Other commands
      are implemented using the controlsocket.
    </para>
    <sect1 id="controlsocket"><title>Controlsocket</title>
      <para>
        The controlsocket is the means to contact a running PDNS daemon, or as we now know, a running <filename>pdns_server</filename>.
        Over this sockets, instructions can be sent using the <filename>pdns_control</filename> program. Like the <filename>pdns_server</filename>,
        this program is normally accessed via the init.d script.
      </para>
      <sect2 id="pdnscontrol"><title>pdns_control</title>

	<para>
	  To communicate with PDNS over the controlsocket, the <command>pdns_control</command> command is used. The init.d script also calls 
	  pdns_control. The syntax is simple: <command>pdns_control command arguments</command>. Currently this is most useful for telling backends
	  to rediscover domains or to force the transmission of notifications. See <xref linkend="master">.
	</para>
	<para>
	  Besides the commands implemented by the init.d script, for which see <xref linkend="pdns-on-unix">, the following pdns_control commands
	  are available:
	  <variablelist>
	    <varlistentry>
	      <term>ccounts</term>
	      <listitem>
		<para>
		  Returns counts on the contents of the cache.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>notify <userinput>domain</userinput></term>
	      <listitem>
		<para>
		  Adds a domain to the notification list, causing PDNS to send out notifications to the nameservers of a domain. Can be used if 
		  a slave missed previous notifications or is generally hard of hearing.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>notify-host <userinput>domain</userinput> <userinput>host</userinput></term>
	      <listitem>
		<para>
		  Same as above but with operator specified IP address as destination, to be used if you know better than PowerDNS.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>purge</term>
	      <listitem>
		<para>
		  Purges the entire Packet Cache - see <xref linkend="performance">.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>purge <userinput>record</userinput></term>
	      <listitem>
		<para>
		  Purges all entries for this exact record name - see <xref linkend="performance">.
		</para>
	      </listitem>
	    </varlistentry>
 	    <varlistentry>
	      <term>purge <userinput>record</userinput>$</term>
	      <listitem>
		<para>
		  Purges all cache entries ending on this name, effectively purging an entire domain - see <xref linkend="performance">.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>purge</term>
	      <listitem>
		<para>
		  Purges the entire Packet Cache - see <xref linkend="performance">.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>purge <userinput>record</userinput></term>
	      <listitem>
		<para>
		  Purges all entries for this exact record name - see <xref linkend="performance">.
		</para>
	      </listitem>
	    </varlistentry>
 	    <varlistentry>
	      <term>rediscover</term>
	      <listitem>
		<para>
		  Instructs backends that new domains may have appeared in the database, or, in the case of the Bind backend, in
		  named.conf.
		</para>
	      </listitem>
	    </varlistentry>
 	    <varlistentry>
	      <term>reload</term>
	      <listitem>
		<para>
		  Instructs backends that the contents of domains may have changed. Many backends ignore this, the Bind backend will check
		  timestamps for all zones (once queries come in for it) and reload if needed.
		</para>
	      </listitem>
	    </varlistentry>
 	    <varlistentry>
	      <term>retrieve <userinput>domain</userinput></term>
	      <listitem>
		<para>
		  Retrieve a slave domain from its master. Done nearly immediatly.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>set <userinput>variable value</userinput></term>
	      <listitem>
		<para>
		  Set a configuration parameter. Currently only the 'query-logging' parameter can be set. 
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>uptime</term>
	      <listitem>
		<para>
		  Reports the uptime of the daemon in human readable form.
		</para>
	      </listitem>
	    </varlistentry>
	    <varlistentry>
	      <term>version</term>
	      <listitem>
		<para>
		  returns the version of a running pdns daemon.
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
    </sect1>

    <sect1 id="guardian"><title>Guardian</title>
      <para>
        When launched by the init.d script, <filename>pdns_server</filename> wraps itself inside a 'guardian'. This guardian monitors the
        performance of the inner <filename>pdns_server</filename> instance which shows up in the process list of your OS as 
        <filename>pdns_server-instance</filename>. 

        It is also this guardian that <filename>pdns_control</filename> talks to. A <command>STOP</command> is interpreted by the guardian, 
        which causes the guardian to sever the connection to the inner process and terminate it, after which it terminates itself.

        The init.d script <command>DUMP</command> and <command>SHOW</command> commands need to access the inner process, because
        the guardian itself does not run a nameserver. For this purpose, the guardian passes controlsocket requests to the control console of the
        inner process. This is the same console as seen with init.d <command>MONITOR</command>.
      </para></sect1>
    <sect1 id="modules"><title>Modules &amp; Backends</title>
      <para>
	PDNS has the concept of backends and modules. Non-static PDNS distributions have the ability to load new modules at runtime, while the
	static versions come with a number of modules built in, but cannot load more. 
      </para>
      <para>
	Related parameters are:
	<variablelist>
	  <varlistentry>
	    <term>--help</term>
	    <listitem>
	      <para>
                Outputs all known parameters, including those of launched backends, see below.
	      </para>
	    </listitem>
	  </varlistentry>
          <varlistentry>
            <term>--launch=backend,backend1,backend1:name</term>
            <listitem>
              <para>
                Launches backends. In its most simple form, supply all backends that need to be launched. If you find
                that you need to launch single backends multiple times, you can specify a name for later instantiations.
                In this case, there are 2 instances of backend1, and the second one is called 'name'.

                This means that <command>--backend1-setting</command> is available to configure the first or main instance, and
                <command>--backend1-name-setting</command> for the second one.
              </para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>--load-modules=/directory/libyourbackend.so</term>
            <listitem>
              <para>
                If backends are available in nonstandard directories, specify their location here. Multiple files
                can be loaded if separated by commas. Only available in non-static PDNS distributions.
              </para>
            </listitem>
          </varlistentry>
          <varlistentry>
            <term>--list-modules</term>
            <listitem>
              <para>
                Will list all available modules, both compiled in and in dynamically loadable modules.
              </para>
            </listitem>
          </varlistentry>
        </variablelist>
	To run on the commandline, use the <command>pdns_server</command> binary. For example, to see options for the gpgsql backend, 
	use the following:
	<screen>
	  $ /usr/sbin/pdns_server --launch=gpgsql --help=gpgsql
	</screen>
      </para>
    </sect1>
    <sect1 id="dns-to-query"><title>How PDNS translates DNS queries into backend queries</title>
      <para>
	A DNS query is not a straightforward lookup. Many DNS queries need to check the backend for additional data, for example to
	determine of an unfound record should lead to an NXDOMAIN ('we know about this domain, but that record does not exist') or an 
	unauthoritative response.
      </para>
      <para>
	Simplified, without CNAME processing and wildcards, the algorithm is like this:
      </para>
      <para>
	When a query for a <command>qname</command>/<command>qtype</command> tuple comes in, it is requested directly from the backend. 
	If present, PDNS adds the contents of the reply to the list of records to return. A question tuple may generate multiple answer 
	records.
      </para>
      <para>
	Each of these records is now investigated to see if it needs 'additional processing'. This holds for example for MX records which may
	point to hosts for which the PDNS backends also contain data. This involves further lookups for A or AAAA records.
      </para>
      <para>
	After all additional processing has been performed, PDNS sieves out all double records which may well have appeared. The resulting set of 
	records is added to the answer packet, and sent out.
      </para>
      <para>
	A zone transfer works by looking up the <command>domain_id</command> of the SOA record of the name and then listing all records of that 
	<command>domain_id</command>. This is why all records in a domain need to have the same domain_id.
      </para>
      <para>
	When a query comes in for an unknown domain, PDNS starts looking for SOA records of all subdomains of the qname, so 
	no.such.powerdns.com turns into a SOA query for no.such.powerdns.com, such.powerdns.com, powerdns.com, com, ''. When a SOA is found,
	that zone is consulted for relevant NS instructions which lead to a referral. If nothing is found within the zone, an authoritative 
	NXDOMAIN is sent out.
      </para>
      <para>
	If no SOA was found, an unauthoritative no-error is returned.
      </para>
      <para>
	In reality, each query for a question tuple first involves checking for a CNAME, unless that resolution has been disabled with the
	<command>skip-cname</command> option.
      </para>
      <para>
	PDNS breaks strict RFC compatability by not always checking for the presence of a SOA record first. This is unlikely to lead to 
	problems though.
      </para>
  </sect1>
  </appendix>
  <appendix id="backend-writers-guide"><title>Backend writers' guide</title>
    <para>
      PDNS backends are implemented via a simple yet powerful C++ interface. If your needs are not met by the PipeBackend, you 
      may want to write your own. Before doing any PowerDNS development, please visit <ulink url="http://wiki.powerdns.com">the wiki</ulink>.
    </para>
    <para>
      A backend contains zero DNS logic. It need not look for CNAMES, it need not return NS records unless explicitly asked for, etcetera.
      All DNS logic is contained within PDNS itself - backends should simply return records matching the description asked for. 
    </para>
    <para> 
      <warning><para>
      However, please note that your backend can get queries in aNy CAsE! If your database is case sensitive, like most are (with the notable
      exception of MySQL), you must make sure that you do find answers which differ only in case.
	</para></warning>
    </para>
    <para> 
      <warning><para>
	  PowerDNS may instantiate multiple instances of your backend, or destroy existing copies and instantiate new ones. Backend code
	  should therefore be thread-safe with respect to its static data. Additionally, it is wise if instantiation is a fast operation, 
	  with the possible exception of the first construction.
	</para></warning>
    </para>
    <sect1 id="simple-backends"><title>Simple read-only native backends</title>
      <para>
	Implementing a backend consists of inheriting from the DNSBackend class. For read-only backends, which do not support slave operation,
	only the following methods are relevant:
	
	<programlisting>
	class DNSBackend
	{
	public:

	virtual bool lookup(const QType &amp;qtype, const string &amp;qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0; 
	virtual bool list(int domain_id)=0; 
	virtual bool get(DNSResourceRecord &amp;r)=0;
	virtual bool getSOA(const string &amp;name, SOAData &amp;soadata);
	};
	</programlisting>
      
	Note that the first three methods must be implemented. <function>getSOA()</function> has a useful default implementation.
      </para>
      <para>
	The semantics are simple. Each instance of your class only handles one (1) query at a time. There is no need for locking as PDNS guarantees
	that your backend will never be called reentrantly. 
      </para>
      <para>
	Some examples, a more formal specification is down below. A normal lookup starts like this:
	
	<programlisting>
        YourBackend yb;
	yb.lookup(QType::CNAME,"www.powerdns.com");
	</programlisting>
      
	Your class should now do everything to start this query. Perform as much preparation as possible - handling errors at this stage is better for PDNS 
	than doing so later on. A real error should be reported by throwing an exception. 
      </para>
      <para>
	PDNS will then call the <function>get()</function> method to get <command>DNSResourceRecord</command>s back. The following code illustrates
	a typical query:
	
      <programlisting>
	yb.lookup(QType::CNAME,"www.powerdns.com");

	DNSResourceRecord rr;
	while(yb.get(rr))
   	  cout&lt;&lt;"Found cname pointing to '"+rr.content+"'"&lt;&lt;endl;
	}
	</programlisting>
      </para>
      <para>
	Each zone starts with a Start of Authority (SOA) record. This record is special so many backends will choose to implement it
	specially. The default <function>getSOA()</function> method performs a regular lookup on your backend to figure out the SOA, 
	so if you have no special treatment for SOA records, where is no need to implement your own <function>getSOA()</function>.
      </para>
      <para>
	Besides direct queries, PDNS also needs to be able to list a zone, to do zone transfers for example. Each zone has an id which should be
	unique within the backend. To list all records belonging to a zone id, the <function>list()</function> method is used. Conveniently,
	the domain_id is also available in the <command>SOAData</command> structure.
      </para>
      <para>
	The following lists the contents of a zone called "powerdns.com".
      
	<programlisting>
	SOAData sd;
	if(!yb.getSOA("powerdns.com",sd))  // are we authoritative over powerdns.com?
	  return RCode::NotAuth;           // no

	yb.list(sd.domain_id); 
	while(yb.get(rr))
   	  cout&lt;&lt;rr.qname&lt;&lt;"\t IN "&lt;&lt;rr.qtype.getName()&lt;&lt;"\t"&lt;&lt;rr.content&lt;&lt;endl;
	</programlisting>
      </para>
      <para>
	Please note that when so called 'fancy records' (see <xref linkend="fancy-records">) are enabled, a backend can receive
	wildcard lookups. These have a % as the first character of the qdomain in lookup. 
      </para>
      <sect2><title>A sample minimal backend</title>
	<para>
	  This backend only knows about the host "random.powerdns.com", and furthermore, only about its A record:
	  
	  <programlisting>
/* FIRST PART */
class RandomBackend : public DNSBackend
{
public:
  bool list(int id) {
    return false; // we don't support AXFR
  }
    
  void lookup(const QType &amp;type, const string &amp;qdomain, DNSPacket *p, int zoneId)
  {
    if(type.getCode()!=QType::A || qdomain!="random.powerdns.com")  // we only know about random.powerdns.com A
      d_answer="";                                                  // no answer
    else {
      ostringstream os;
      os&lt;&lt;random()%256&lt;&lt;"."&lt;&lt;random()%256&lt;&lt;"."&lt;&lt;random()%256&lt;&lt;"."&lt;&lt;random()%256;
      d_answer=os.str();                                           // our random ip address
    }
  }

  bool get(DNSResourceRecord &amp;rr)
  {
    if(!d_answer.empty()) {
      rr.qname="random.powerdns.com";                               // fill in details
      rr.qtype=QType::A;                                            // A record
      rr.ttl=86400;                                                 // 1 day
      rr.content=d_answer;

      d_answer="";                                                  // this was the last answer
      
      return true;
    }
    return false;                                                   // no more data
  }
  
private:
  string d_answer;
};

/* SECOND PART */

class RandomFactory : public BackendFactory
{
public:
  RandomFactory() : BackendFactory("random") {}

  DNSBackend *make(const string &amp;suffix)
  {
    return new RandomBackend();
  }
};

/* THIRD PART */

class RandomLoader
{
public:
  RandomLoader()
  {
    BackendMakers().report(new RandomFactory);
    
    L&lt;&lt;Logger::Info&lt;&lt;" [RandomBackend] This is the randombackend ("__DATE__", "__TIME__") reporting"&lt;&lt;endl;
  }  
};

static RandomLoader randomloader;
	</programlisting>	  
        This simple backend can be used as an 'overlay'. In other words, it only knows about a single record, another loaded backend would have
        to know about the SOA and NS records and such. But nothing prevents us from loading it without another backend.
      </para>
      <para>
        The first part of the code contains the actual logic and should be pretty straightforward. The second part is a boilerplate
        'factory' class which PDNS calls to create randombackend instances. Note that a 'suffix' parameter is passed. Real life backends
        also declare parameters for the configuration file; these get the 'suffix' appended to them. Note that the "random" in the 
        constructor denotes the name by which the backend will be known.
      </para>
      <para>
        The third part registers the RandomFactory with PDNS. This is a simple C++ trick which makes sure that this function
        is called on execution of the binary or when loading the dynamic module.
      </para>
	<para>
	  Please note that a RandomBackend is actually in most PDNS releases. By default it lives on random.example.com, but you can change
	  that by setting <command>random-hostname</command>.
	</para>
	<para>
	  NOTE: this simple backend neglects to handle case properly!
	</para>
    </sect2>
    <sect2><title>Interface definition</title>
      <para>
	Classes:
	<table>
	  <title>DNSResourceRecord class</title>
	  <tgroup cols=2>
	    <tbody>
	      <row>
		<entry>QType qtype</entry><entry>QType of this record</entry>
	      </row>
	      <row>
		<entry>string qname</entry><entry>name of this record</entry>
	      </row>
	      <row>
		<entry>string content</entry><entry>ASCII representation of right hand side</entry>
	      </row>
	      <row>
		<entry>u_int16_t priority</entry><entry>priority of an MX record.</entry>
	      </row>
	      <row>
		<entry>u_int32_t ttl</entry><entry>Time To Live of this record</entry>
	      </row>
	      <row>
		<entry>int domain_id</entry><entry>ID of the domain this record belongs to</entry>
	      </row>
	      <row>
		<entry>time_t last_modified</entry><entry>If unzero, last time_t this record was changed</entry>
	      </row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	<table>
	  <title>SOAData struct</title>
	  <tgroup cols=2>
	    <tbody>
	      <row>
		<entry>string nameserver</entry><entry>Name of the master nameserver of this zone</entry>
	      </row>
	      <row>
		<entry>string hostmaster</entry><entry>Hostmaster of this domain. May contain an @</entry>
	      </row>
	      <row>
		<entry>u_int32_t serial</entry><entry>Serial number of this zone</entry>
	      </row>
	      <row>
		<entry>u_int32_t refresh</entry><entry>How often this zone should be refreshed</entry>
	      </row>
	      <row>
		<entry>u_int32_t retry</entry><entry>How often a failed zone pull should be retried.</entry>
	      </row>
	      <row>
		<entry>u_int32_t expire</entry><entry>If zone pulls failed for this long, retire records</entry>
	      </row>
	      <row>
		<entry>u_int32_t default_ttl</entry><entry>Difficult</entry>
	      </row>
	      <row>
		<entry>int domain_id</entry><entry>The ID of the domain within this backend. Must be filled!</entry>
	      </row>
	      <row>
		<entry>DNSBackend *db</entry><entry>Pointer to the backend that feels authoritative for a domain and can act as a slave</entry>
	      </row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	Methods:
	<variablelist>
	  <varlistentry>
	    <term>void lookup(const QType &amp;qtype, const string &amp;qdomain, DNSPacket *pkt=0, int zoneId=-1)</term>
	    <listitem>
	      <para>
		This function is used to initiate a straight lookup for a record of name 'qdomain' and type 'qtype'.
		A QType can be converted into an integer by invoking its <function>getCode()</function> method and into
		a string with the <function>getCode()</function>.
	      </para>
	      <para>
		  The original question may or may not be passed in the pointer p. If it is, you can retrieve (from 1.99.11 onwards) 
		  information about who asked the question with the <function>getRemote(DNSPacket *)</function> method. Alternatively, 
		  <function>bool getRemote(struct sockaddr *sa, socklen_t *len)</function> is available.
		</para>
		<para>
		  Note that <command>qdomain</command> can be of any case and that your backend should make sure it is in effect case 
		  insensitive. Furthermore, the case of the original question should be retained in answers returned by <function>get()</function>!
		</para>
	      <para>
		Finally, the domain_id might also be passed indicating that only answers from the indicated zone need apply. This
		can both be used as a restriction or as a possible speedup, hinting your backend where the answer might be found.
	      </para>
	      <para>
		If initiated succesfully, as indicated by returning <command>true</command>, answers should be made available over the
		<function>get()</function> method.
		</para>
		<para>
		  Should throw an AhuException if an error occured accessing the database. Returning otherwise indicates that the query 
		  was started succesfully. If it is known that no data is available, no exception should be thrown! An exception indicates
		  that the backend considers itself broken - not that no answers are available for a question.
		</para>
		<para>
		  It is legal to return here, and have the first call to <function>get()</function> return false. This is interpreted as 'no data'
		</para>
	      </listitem>
	    </varlistentry>
	  
	  <varlistentry>
	    <term>bool list(int domain_id)</term>
	    <listitem>
	      <para>
		Initiates a list of the indicated domain. Records should then be made available via the <function>get()</function> method. 
		Need not include the SOA record. If it is, PDNS will not get confused.
	      </para>
	      <para>
		Should return false if the backend does not consider itself authoritative for this zone.
		Should throw an AhuException if an error occured accessing the database. Returning true indicates that data is or should be available.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>bool get(DNSResourceRecord &amp;rr)</term>
	    <listitem>
	      <para>
		Request a DNSResourceRecord from a query started by <function>get()</function> of <function>list()</function>. If this functions returns 
		<command>true</command>, <command>rr</command> has been filled with data. When it returns false, no more data is available, 
		and <command>rr</command> does not contain new data. A backend should make sure that it either fills out all fields of the 
		DNSResourceRecord or resets them to their default values.
	      </para>
		<para>
		  The qname field of the DNSResourceRecord should be filled out with the exact <function>qdomain</function> passed to lookup, preserving
		  its case. So if a query for 'CaSe.yourdomain.com' comes in and your database contains dat afor 'case.yourdomain.com', the qname field of rr
		  should contin 'CaSe.yourdomain.com'!
		</para>
	      <para>
		Should throw an AhuException in case a database error occurred.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>bool getSOA(const string &amp;name, SOAData &amp;soadata)</term>
	    <listitem>
	      <para>
		If the backend considers itself authoritative over domain <function>name</function>, this method should fill out
		the passed <command>SOAData</command> structure and return a positive number. If the backend is functioning correctly, but
		does not consider itself authoritative, it should return 0. In case of errors, an AhuException should be thrown.
	      </para>
	    </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
      </sect2>
    </sect1>
    <sect1 id="backend-error-reporting"><title>Reporting errors</title>
	<para>
	  To report errors, the Logger class is available which works mostly like an iostream. Example usage is as shown above in the RandomBackend.
	  Note that it is very important that each line is ended with <command>endl</command> as your message won't be visible otherwise.
	</para>
	<para>
	  To indicate the importance of an error, the standard syslog errorlevels are available. They can be set by outputting 
	  <function>Logger::Critical</function>,
	  <function>Logger::Error</function>,
	  <function>Logger::Warning</function>,
	  <function>Logger::Notice</function>,
	  <function>Logger::Info</function> or
	  <function>Logger::Debug</function> to <function>L</function>, in descending order of graveness.
	</para>
      </sect1>
      <sect1 id="backend-configuration-details"><title>Declaring and reading configuration details</title>
	<para>
	  It is highly likely that a backend needs configuration details. On launch, these parameters need to be declared with PDNS so it knows it
	  should accept them in the configuration file and on the commandline. Furthermore, they will be listed in the output of 
	  <command>--help</command>.
	</para>
	<para>
	  Declaring arguments is done by implementing the member function <function>declareArguments()</function> in the factory class of your
	  backend. PDNS will call this method after launching the backend.
	</para>
	<para>
	  In the <function>declareArguments()</function> method, the function <function>declare()</function> is available. The exact definitions:
	  <variablelist>
	    <varlistentry>
	      <term>void declareArguments(const string &amp;suffix="")</term>
	      <listitem>
		<para>
		  This method is called to allow a backend to register configurable parameters. The suffix is the sub-name of this module. There is
		  no need to touch this suffix, just pass it on to the declare method.
		</para>
	      </listitem>
	    </varlistentry>
	    
	    <varlistentry>
	      <term>void declare(const string &amp;suffix, const string &amp;param, const string &amp;explanation, const string &amp;value)</term>
	      <listitem>
		<para>The suffix is passed to your method, and can be passed on to declare. <command>param</command> is the name of your parameter.
		  <command>explanation</command> is what will appear in the output of --help. Furthermore, a default value can be supplied in the 
		  <command>value</command> parameter.
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
	<para>
	  A sample implementation:
	  <programlisting>
	    void declareArguments(const string &amp;suffix)
	    {
 	      declare(suffix,"dbname","Pdns backend database name to connect to","powerdns");
	      declare(suffix,"user","Pdns backend user to connect as","powerdns");
	      declare(suffix,"host","Pdns backend host to connect to","");
	      declare(suffix,"password","Pdns backend password to connect with","");
	    }
	  </programlisting>
	</para>
	<para>
	  After the arguments have been declared, they can be accessed from your backend using the <function>mustDo()</function>,
	  <function>getArg()</function> and <function>getArgAsNum()</function> methods. The are defined as follows in the DNSBackend class:
	</para>
	<para>
	  <variablelist>
	    <varlistentry>
	      <term>void setArgPrefix(const string &amp;prefix)</term>
	      <listitem>
		<para>
		  Must be called before any of the other accessing functions are used. Typical usage is '<function>setArgPrefix("mybackend"+suffix)</function>'
		  in the constructor of a backend.
		</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>bool mustDo(const string &amp;key)</term>
	      <listitem>
		<para>
		  Returns true if the variable <function>key</function> is set to anything but 'no'.
		</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>const string&amp; getArg(const string &amp;key)</term>
	      <listitem>
		<para>
		  Returns the exact value of a parameter.
		</para>
	      </listitem>
	    </varlistentry>

	    <varlistentry>
	      <term>int getArgAsNum(const string &amp;key)</term>
	      <listitem>
		<para>
		  Returns the numerical value of a parameter. Uses <function>atoi()</function> internally
		</para>
	      </listitem>
	    </varlistentry>
	  </variablelist>
	</para>
	<para>
	  Sample usage from the BindBackend, using the <command>bind-example-zones</command> and <command>bind-config</command>
	  parameters.
	  <programlisting>
  if(mustDo("example-zones")) {
    insert(0,"www.example.com","A","1.2.3.4");
    /* ... */
  }
  

  if(!getArg("config").empty()) {
    BindParser BP;
    
    BP.parse(getArg("config"));
  }

	  </programlisting>
	</para>
      </sect1>

    <sect1 id="rw-backends"><title>Read/write slave-capable backends</title>
      <para>
	The backends above are 'natively capable' in that they contain all data relevant for a domain and do not pull in data from other nameservers.
	To enable storage of information, a backend must be able to do more.
      </para>
      <para>
	Before diving into the details of the implementation some theory is in order. Slave domains are pulled from the master. PDNS needs to 
	know for which domains it is to be a slave, and for each slave domain, what the IP address of the master is.
      </para>
      <para>
	A slave zone is pulled from a master, after which it is 'fresh', but this is only temporary. In the SOA record of a zone there is a field
	which specifies the 'refresh' interval. After that interval has elapsed, the slave nameserver needs to check at the master ff the serial
	number there is higher than what is stored in the backend locally.
      </para>
      <para>
	If this is the case, PDNS dubs the domain 'stale', and schedules a transfer of data from the remote. This transfer remains scheduled
	until the serial numbers remote and locally are identical again.
      </para>
      <para>
	This theory is implemented by the <function>getUnfreshSlaveInfos</function> method, which is called on all backends periodically. 
	This method fills a vector of <command>SlaveDomain</command>s with domains that are unfresh and possibly stale. 
      </para>
      <para>
	PDNS then retrieves the SOA of those domains remotely and locally and creates a list of stale domains. For each of these domains, PDNS
	starts a zonetransfer to resynchronise. Because zone transfers can fail, it is important that the interface to the backend allows
	for transaction semantics because a zone might otherwise be left in a halfway updated situation.
      </para>
      <para>
	The following excerpt from the DNSBackend shows the relevant functions:
      </para>
      <para>
	<programlisting>
	  class DNSBackend {
	  public:
           /* ... */
           virtual bool getDomainInfo(const string &amp;domain, DomainInfo &amp;di);
	   virtual bool isMaster(const string &amp;name, const string &amp;ip);
	   virtual bool startTransaction(const string &amp;qname, int id);
	   virtual bool commitTransaction();
	   virtual bool abortTransaction();
	   virtual bool feedRecord(const DNSResourceRecord &amp;rr);
	   virtual void getUnfreshSlaveInfos(vector&lt;DomainInfo&gt;* domains);
	   virtual void setFresh(int id);
           /* ... */
	 }
	</programlisting>
      </para>
      <para>
        The mentioned DomainInfo struct looks like this:
	<table>
	  <title>DomainInfo struct</title>
	  <tgroup cols=2>
	    <tbody>
	      <row>
		<entry>int id</entry><entry>ID of this zone within this backend</entry>
	      </row>
	      <row>
		<entry>string master</entry><entry>IP address of the master of this domain, if any</entry>
	      </row>
	      <row>
		<entry>u_int32_t serial</entry><entry>Serial number of this zone</entry>
	      </row>
	      <row>
		<entry>u_int32_t notified_serial</entry><entry>Last serial number of this zone that slaves have seen</entry>
	      </row>
	      <row>
		<entry>time_t last_check</entry><entry>Last time this zone was checked over at the master for changes</entry>
	      </row>
	      <row>
		<entry>enum {Master,Slave,Native} kind</entry><entry>Type of zone</entry>
	      </row>
	      <row>
		<entry>DNSBackend *backend</entry><entry>Pointer to the backend that feels authoritative for a domain and can act as a slave</entry>
	      </row>
	    </tbody>
	  </tgroup>
	</table>
      </para>
      <para>
	These functions all have a default implementation that returns false - which explains that these methods can be omitted in simple backends. 
	Furthermore, unlike with simple backends, a slave capable backend must make sure that the 'DNSBackend *db' field of the SOAData record is filled 
	out correctly - it is used to determine which backend will house this zone. 
	<variablelist>
	  <varlistentry>
	    <term>bool isMaster(const string &amp;name, const string &amp;ip);</term>
	    <listitem>
	      <para>
		If a backend considers itself a slave for the domain <command>name</command> and if the IP address in <command>ip</command>
		is indeed a master, it should return true. False otherwise. This is a first line of checks to guard against reloading a domain
		unnecessarily.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>void getUnfreshSlaveInfos(vector&lt;DomainInfo&gt;* domains)</term>
	    <listitem>
	      <para>
		When called, the backend should examine its list of slave domains and add any unfresh ones to the domains vector.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bool getDomainInfo(const string &amp;name, DomainInfo &amp; di)</term>
	    <listitem>
	      <para>
                This is like getUnfreshSlaveInfos, but for a specific domain. If the backend considers itself authoritative for the named
                zone, <function>di</function> should be filled out, and 'true' be returned. Otherwise return false.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bool startTransaction(const string &amp;qname, int id)</term>
	    <listitem>
	      <para>
		When called, the backend should start a transaction that can be committed or rolled back atomically later on. 
		In SQL terms, this function should <command>BEGIN</command> a transaction and <command>DELETE</command> all
		records.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bool feedRecord(const DNSResourceRecord &amp;rr)</term>
	    <listitem>
	      <para>
		Insert this record.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>bool commitTransaction();</term>
	    <listitem>
	      <para>
		Make the changes effective. In SQL terms, execute <command>COMMIT</command>.
	      </para>
	    </listitem>
	  </varlistentry>
	      
	  <varlistentry>
	    <term>bool abortTransaction();</term>
	    <listitem>
	      <para>
		Abort changes. In SQL terms, execute <command>ABORT</command>.
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bool setFresh()</term>
	    <listitem>
	      <para>
		Indicate that a domain has either been updated or refreshed without the need for a retransfer. This causes
		the domain to vanish from the vector modified by <function>getUnfreshSlaveInfos()</function>.
	      </para>
	    </listitem>
	  </varlistentry>

	</variablelist>
      </para>
      <para>
	PDNS will always call <function>startTransaction()</function> before making calls to <function>feedRecord()</function>.
	Although it is likely that <function>abortTransaction()</function> will be called in case of problems, backends should also
	be prepared to abort from their destructor.
      </para>
      <para>
	The actual code in PDNS is currently (1.99.9):
	<programlisting>
    Resolver resolver;
    resolver.axfr(remote,domain.c_str());

    db->startTransaction(domain, domain_id);
    
    L&lt;&lt;Logger::Error&lt;&lt;"AXFR started for '"&lt;&lt;domain&lt;&lt;"'"&lt;&lt;endl;
    Resolver::res_t recs;
    
    while(resolver.axfrChunk(recs)) {
      for(Resolver::res_t::const_iterator i=recs.begin();i!=recs.end();++i) {
	db->feedRecord(*i);
      }
    }
    db->commitTransaction();
    db->setFresh(domain_id);
    L&lt;&lt;Logger::Error&lt;&lt;"AXFR done for '"&lt;&lt;domain&lt;&lt;"'"&lt;&lt;endl;
	</programlisting>
      </para>
      <sect2><title>Supermaster/Superslave capability</title>
        <para>
          A backend that wants to act as a 'superslave' for a master should implement the following method:
          <programlisting>
            class DNSBackend 
            {
               virtual bool superMasterBackend(const string &amp;ip, const string &amp;domain, const vector&lt;DNSResourceRecord&gt;&amp;nsset, string *account, DNSBackend **db)
            };
          </programlisting>
          This function gets called with the IP address of the potential supermaster, the domain it is sending a notification for and the set of NS records
          for this domain at that IP address. 
        </para>
        <para>
          Using the supplied data, the backend needs to determine if this is a bonafide 'supernotification' which should be honoured. If it decides that it
          should, the supplied pointer to 'account' needs to be filled with the configured name of the supermaster (if accounting is desired), and the 
          db needs to be filled with a pointer to your backend.
        </para>
        <para>
          Supermaster/superslave is a complicated concept, if this is all unclear see <xref linkend="supermaster">.
	</para>
      </sect2>
    </sect1>
    <sect1 id="master-backends"><title>Read/write master-capable backends</title>
      <para>
        In order to be a useful master for a domain, notifies must be sent out whenever a domain is changed. Periodically, PDNS
        queries backends for domains that may have changed, and sends out notifications for slave nameservers.
      </para>
      <para>
        In order to do so, PDNS calls the <function>getUpdatedMasters()</function> method. Like the <function>getUnfreshSlaveInfos()</function>
        function mentioned above, this should add changed domain names to the vector passed.
      </para>
      <para>
	The following excerpt from the DNSBackend shows the relevant functions:
      </para>
      <para>
	<programlisting>
	  class DNSBackend {
	  public:
           /* ... */
	   virtual void getUpdatedMasters(vector&lt;DomainInfo&gt;* domains);
	   virtual void setNotifed(int id, u_int32_t serial);
           /* ... */
	 }
	</programlisting>
      </para>
      <para>
	These functions all have a default implementation that returns false - which explains that these methods can be omitted in simple backends. 

	Furthermore, unlike with simple backends, a slave capable backend must make sure that the 'DNSBackend *db' field of the SOAData record is filled 
	out correctly - it is used to determine which backend will house this zone. 

	<variablelist>
	  <varlistentry>
	    <term>void getUpdatedMasters(vector&lt;DomainInfo&gt;* domains)</term>
	    <listitem>
	      <para>
		When called, the backend should examine its list of master domains and add any changed ones to the DomainInfo vector
	      </para>
	    </listitem>
	  </varlistentry>
	  <varlistentry>
	    <term>bool setNotified(int domain_id, u_int32_t serial)</term>
	    <listitem>
	      <para>
                Indicate that notifications have been queued for this domain and that it need not be considered 'updated' anymore
	      </para>
	    </listitem>
	  </varlistentry>
	</variablelist>
      </para>
    </sect1>

  </appendix>
  <appendix id="compiling-powerdns"><title>Compiling PowerDNS</title>
    <sect1 id="on-unix"><title>Compiling PowerDNS on Unix</title>
      <para>
	<note><para>
	    For now, see <ulink url="http://wiki.powerdns.com/">the Open Source PowerDNS site</ulink>. 
	    <command>./configure ; make ; make install</command> will do The Right Thing for most people.
	  </para></note>
      </para>
      <para>
	PowerDNS can becompiled with modules built in, or with modules designed to be loaded at runtime. All that is configured
	before compiling using the well known autoconf/automake system.
      </para>
      <para>
	To compile in modules, specify them as <command>--with-modules="mod1 mod2 mod3"</command>, substituting the desired module names.
	Each backend has a module name in the table at the beginning of its section.
      </para>
      <para>
	To compile a module for inclusion at runtime, which is great if you are a unix vendor, use <command>--with-dynmodules="mod1 mod2 mod3"</command>.
	These modules then end up as .so files in the compiled libdir. 
      </para>
      <para>
        Starting with version 2.9.18, PowerDNS requires 'Boost' to compile, it is available for most operating systems. Otherwise, see <ulink url="http://www.boost.org">the Boost 
	website</ulink>.
      </para>
      <para>
	If your operating system does not have a Boost package, you don't need to compile all of boost just for PowerDNS.
	PowerDNS only uses Boost include files, so there is no need to install all of boost. Just untar the Boost distribution file and 
	point instruct ./configure to find it, perhaps like this:
	<screen>
	$ CXXFLAGS=-I/home/bert/download/boost_1_33_0 ./configure ...
    </screen>
    </para>
      <sect2 id="unix-aix"><title>AIX</title>
	<para>
	  Known to compile with gcc, but only since 2.9.8. AIX lacks POSIX semaphores so they need to be emulated, as with MacOS X.
	</para>
      </sect2>
      <sect2 id="unix-freebsd"><title>FreeBSD</title>
	<para>
	  Works fine, but use gmake. Pipe backend is currently broken, for reasons, see <xref linkend="pipebackend">. Due to the threading model
	  of FreeBSD, PowerDNS does not benefit from additional CPUs on the system.
	</para>
	<para>
	  The FreeBSD Boost include files are installed in <filename>/usr/local/include</filename>, so prefix <command>CXXFLAGS=-I/usr/local/lib</command>
	  to your <command>./configure</command> invocation.
	</para>
      </sect2>
      <sect2 id="unix-linux"><title>Linux</title>
	<para>
	  Linux is probably the best supported platform as most of the main coders are Linux users. The static DEB distribution is known to have 
	  problems on Debian 'Sid', but that doesn't matter as PowerDNS is a native part of Debian 'Sid'. Just apt-get!
	</para>
      </sect2>
      <sect2 id="unix-macosx"><title>MacOS X</title>
	<para>
	  Did compile at one point but maintenance has lapsed. Let us know if you can provide us with a login on MacOS X or if you want to help.
	</para>
      </sect2>
      <sect2 id="unix-openbsd"><title>OpenBSD</title>
	<para>
	  Compiles but then does not work very well. We hear that it may work with more recent versions of gcc, please let us know on 
	  <email>pdns-dev@mailman.powerdns.com</email>.
	</para>
      </sect2>
      <sect2 id="unix-solaris"><title>Solaris</title>
	<para>
	  Solaris 7 is supported, but only just. AAAA records do not work on Solaris 7. Solaris 8 and 9 work fine. The 'Sunpro' compiler
	  has not been tried but is reported to be lacking large parts of the Standard Template Library, which PowerDNS relies on heavily. 
	  Use gcc and gmake (if available). Regular Solaris make has some issues with some PowerDNS Makefile constructs.
	</para>
	<para>
	  When compiling, make sure that you have <filename>/usr/ccs/bin</filename> in your path. Furthermore, with some versions of MySQL,
	  you may have to add "LDFLAGS=-lz" before <command>./configure</command>.
	</para>
      </sect2>
    </sect1>
    <sect1 id="on-windows"><title>Compiling PowerDNS on Windows</title>
      <para>
	By Michel Stol (<email>michel@powerdns.com</email>).
      </para>
      <sect2><title>Assumptions</title>
        <para>
	  I will assume these things from you:      
	</para>
	<variablelist>
          <varlistentry>
	    <term>
	      You have the PowerDNS sources.
	    </term>
	    <listitem>        
	      <para>
		There's not much to compile without the source files, eh? :)
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>      
	    <term>
	      You are using Microsoft Visual C++. If you get it to compile using a free compiler, please let us know!
	    </term>
	    <listitem>        
	      <para>
		From the day that we began porting the <acronym>UNIX</acronym> PowerDNS sources to Microsoft Windows
		we used Microsoft Visual C++ as our development environment of choice.            
	      </para>
	      
	      <para>
		We used Visual C++ 6.0 to compile all sources (both standard version and SP5). Other versions
		(including Visual C++ .NET) are untested.
	      </para>
	    </listitem>
	  </varlistentry>
	  
	  <varlistentry>
	    <term>
	      You are using Microsoft Windows NT, 2000 or XP
	    </term>
	    <listitem>        
	      <para>
		I will assume that the system where you want to compile the sources on is running
		Microsoft Windows NT, 2000 or XP. These are the operating systems that where found
		running PowerDNS for Windows.
		
	      </para>          
	      
	      <note>
		<para>
		  You probably can compile the sources on other Windows versions too, but that is currently untested.
		</para>
	      </note>
	    </listitem>
	  </varlistentry>
	  
	  <varlistentry>      
	    <term>
	      You are using an English Windows version.
	    </term>
	    <listitem>        
	      <para>
		Troughout this document I will use the English names for menu items, names etc., so if you are
		running a non-English Windows or <acronym>MSVC</acronym> version you have to translate those things yourself. But 
		I don't think that would be a big problem.
	      </para>          
	    </listitem>
	  </varlistentry>
	  
	</variablelist>
	
      </sect2>
      
      <sect2>
	<title>Prequisites</title>
	
	<para>
	  Although we tried to keep PowerDNS for Windows' dependencies down to a minimum, you will still need some
	  programs and libraries to be able to compile the sources.
	</para>
	
      <sect3>
	<title>pthreads for Windows</title>
	
	<para>
	  The pthreads for Windows library is a Windows implementation of the <acronym>POSIX</acronym> threads
	  specification, which is used a lot in <acronym>UNIX</acronym> programs.
	</para>
	
	<para>
	  PowerDNS uses pthreads too, and to ease the porting process we decided not to reinvent the wheel,
	  but to use pthreads for Windows instead.
	</para>
	
	<sect4>
	  <title>Getting pthreads for Windows</title>
	  
	  <para>
	    Pthreads for Windows is available from anonymous ftp at <ulink url="ftp://sources.redhat.com/pub/pthreads-win32/">ftp://sources.redhat.com/pub/pthreads-win32/</ulink>.
	    You should download the latest <filename>pthreads-YYYY-MM-DD.exe</filename> file.
	  </para>
	  
	  <note>
	    <para>
	      PowerDNS for Windows was tested with the snapshot of 2002-03-02 of the library.
	    </para>
	  </note>
	  
	  <para>
	    For more information you can visit the pthreads for Windows homepage at <ulink url="http://sources.redhat.com/pthreads-win32/">http://sources.redhat.com/pthreads-win32/</ulink>
	  </para>          
	</sect4>
	
	<sect4>
	  <title>Installing pthreads for Windows</title>
	  
	  <para>
	    To install the pthreads for Windows library you have to locate your <filename>pthreads-YYYY-MM-DD.exe</filename> 
	    file and start it.
	  </para>
	  
	  <para>
	    After starting the executable a self-extractor dialog will show up where you can specify where to extract
	    the contents of the file. When you selected a location you can press the <guibutton>Extract</guibutton> button
	    to extract all content to the target directory.
	  </para>
	  
	  <para>
	    The library is now installed, we still have to tell Visual C++ where it's located though, more
	    on that later.
	  </para>        
	</sect4>
      </sect3>
	
      </sect2>
      
      <sect2>
	<title>Nullsoft Installer</title>
	
	<para>
	  For our installation program we used Nullsoft's Installer System (<acronym>NSIS</acronym>). We used 
	  <acronym>NSIS</acronym> because it's easy to use, versatile and free (and it uses <acronym><trademark>SuperPiMP</trademark></acronym> technology, but
	  they refuse to tell us what it is ;)). If the name Nullsoft rings a bell, it's because they're the guys who made
	  <ulink url="http://www.winamp.com/">winamp</ulink>.
	</para>
	
	<sect3>
	  <title>Getting the Nullsoft Installer</title>
	  
	  <para>
	    The Nullsoft Installer can be downloaded at their website, which is
	    located at <ulink url="http://www.nullsoft.com/free/nsis/">http://www.nullsoft.com/free/nsis/</ulink>.
	    The file that you should download is called <filename>nsisXXX.exe</filename> (where XXX is the latest version).
	  </para>
	  
	  <note>
	    <para>
	      You can find the <acronym>NSIS</acronym> documentation at that website too.
	    </para>
	  </note>
	</sect3>
	
	<sect3>
	  <title> Installing the Nullsoft Installer</title>
	  
	  <para>
	    Installing <acronym>NSIS</acronym> is easy. All there is to it is locating the installer and execute it.
	    Then just follow the installation steps.
	  </para>
	</sect3>
	
      </sect2>
      
    <sect2>
      <title>Setting up the build-environment</title>
      
      <para>
	Before starting Microsoft Visual C++ and compile PowerDNS for Windows, you first
	have to set up your build environment.
      </para>
      
      <sect3>
	<title>Make Microsoft Visual C++ recognize <filename>*.cc</filename> and <filename>*.hh</filename> (optional)</title>
	
        <para>
          All PowerDNS source files are in the form <filename>name.cc</filename>, and all header files in the form
          <filename>name.hh</filename>. These extensions aren't recognized by <acronym>MSVC</acronym> by default, so
          you might want to change that first.
        </para>
        
        <note>
          <para>
            Only perform this step if you want to be able to edit the <filename>*.cc</filename> 
            and <filename>*.hh</filename> files in <acronym>MSVC</acronym>.
          </para>
        </note>
        
        <caution>
          <para>
            If you decide to perform this step, remember that it requires modification of the Windows registry, 
            always make a backup before modifying!
          </para>
        </caution>
        
        <para>
          Ok, after that word of caution we can now proceed. You have to follow these steps:
        </para>

        <orderedlist>
	  
          <listitem>
            <para>
              Start the registry editor by entering <filename>regedit.exe</filename> in the run prompt
              (<guimenu>Start-&gt;Run...</guimenu>).
            </para>
          </listitem>

          <listitem>
            <para>
              Right click on <filename>HKEY_CLASSES_ROOT</filename> and select <guimenu>New-&gt;Key</guimenu>. 
              A new key will appear, change that key to <quote><filename>.cc</filename></quote>, then change the default
              value to <quote>cppfile</quote>
            </para>

            <para>
              Then perform the same step for <quote><filename>.hh</filename></quote> (use <quote>hfile</quote> instead of <quote>cppfile</quote>).
            </para>
          </listitem>

          <listitem>
            <para>
              Go to <filename>HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Build System\Components\Platforms\Win32 (x86)\Tools\32-bit C/C++ Compiler for 80x86</filename>. And
              add <quote>;*.cc</quote> to the <filename>Input_Spec</filename> value (so that it becomes <quote>*.c;*.cpp;*.cxx;*.cc</quote>).
            </para>

            <note>
              <para>
                If you happen to use another platform (like alpha) to compile the sources, you have to do the step above for that platform.
              </para>
            </note>
          </listitem>

          <listitem>
            <para>
              Go to <filename>HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Search</filename>. And
              add <quote>;*.cc;*.hh</quote> to the <filename>FIF_Filter</filename> value (so that it becomes <quote>*.c;*.cpp;*.cxx;*.tli;*.h;*.tlh;*.inl;*.rc;*.cc;*.hh</quote>).
            </para>
          </listitem>

          <listitem>
            <para>
              Finally change <filename>HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Text Editor\Tabs/Language Settings\C/C++</filename>. And
              add <quote>;cc;hh</quote> to the <filename>FileExtensions</filename> value (so that it becomes <quote>cpp;cxx;c;h;hxx;hpp;inl;tlh;tli;rc;rc2;hh;cc</quote>).
            </para>
          </listitem>
          
          <listitem>
            <para>
              Close the registry editor.
            </para>
          </listitem>
          
        </orderedlist>       
        
        <para>
          Now should <acronym>MSVC</acronym> properly recognize the files as being C++.
        </para>
	
      </sect3>
      
      <sect3>
	<title>Setting Microsoft Visual C++'s directories</title>
	
	<para>
	  <acronym>MSVC</acronym> needs to locate some include files, libraries and executables
	  when it has to build PowerDNS for Windows. We are now going to tell <acronym>MSVC</acronym> where
	  to find those.
	</para>
	
	<para>
	  To enter the directory dialog you have to go to <guimenu>Tools-&gt;Options...-&gt;Directories</guimenu>.
	</para>
	
	<sect4>
	  <title>Setting the pthreads directories</title>
	  
	  <para>
	    When you are in the directory dialog you can add the pthreads for Windows directory.
	  </para>
	  
	  <para>
	    First add the include directory, to do this you have to select <guilabel>Include files</guilabel>
	    from the <guilabel>Show directories for:</guilabel> combobox. Then press the <guibutton>New</guibutton>
	    button and browse to the <command>include</command> directory of pthreads (ie. <filename>C:\pthreads\include</filename>).
	  </para>
	  
	  <para>
	    Then switch to <guilabel>Library files</guilabel> and add the <command>library</command> directory
	    (ie. <filename>C:\pthreads\lib</filename>) using the same method as above.
	  </para>        
	</sect4>
	
	<sect4>
	  <title>Setting the Nullsoft Installer directory</title>
	  
	  <para>
	    While still being in the directory dialog, switch to <guilabel>Executable files</guilabel>
	    and add the Nullsoft Installer directory (ie. <filename>C:\Program Files\NSIS</filename>) to the list.
	  </para>
	</sect4>
	
      
    </sect3>
      </sect2>
    
    <sect2>
      <title>Compilation</title>
      
      <para>
	Finally, after all the reading, installing and configuring we are ready to start compiling
	PowerDNS for Windows.
      </para>
      
      <sect3>
	<title>Starting the compilation</title>  
	
	<para>
	  To start the compilation you first have to open the PowerDNS workspace (<filename>powerdns.dsw</filename>) using explorer or
	  from the <guimenu>File-&gt;Open Workspace...</guimenu> menu in <acronym>MSVC</acronym>.
	</para>
	
	<para>
	  After you opened the workspace you can start compiling. Check all the checkboxes in the
	  <guimenu>Build-&gt;Batch Build...</guimenu> menu and press the <guibutton>Build</guibutton> button.
	</para>
	
	<para>
	  Now cross your fingers and go make some coffee or tea while compiling PowerDNS for Windows. :)
	</para>
	
      </sect3>
      
      <sect3>
	<title>Yay! It compiled</title>
	
	<para>
	  Congratulations, you have now compiled PowerDNS for Windows!
	</para>
	
	<para>
	  All the release builds of the binaries are in the <filename>Release</filename> directory (including the
	  generated installer). The debug builds are in the, guess what, <filename>Debug</filename> directory.
	</para>
	
	<para>
	  Now you can start installing PowerDNS, but that's beyond the scope of this document. See
	  the <ulink url="http://downloads.powerdns.com/documentation/html/">online documentation</ulink> for
	  more information about that.
	</para>
      </sect3>
      
      <sect3>
	<title>What if it went wrong?</title>
	
	<para>
	  If the compilation fails, then try reading this article again, and again to see if you did something wrong.
	</para>
	
	<para>
	  If you are pretty sure that it's a bug, either in the PowerDNS sources, the build
	  system or in this article, then please send an e-mail to <email>pdns-dev@mailman.powerdns.com</email> describing your
	  problem. We will then try to fix it.
	</para>
	
      </sect3>
      
    </sect2>
    
    <sect2>
      <title>Miscellaneous</title>

      <para>
	Some miscellaneous information.
      </para>
      
      <sect3>
	<title>Credits</title>

	<variablelist>
	  <title>Michel Stol would like to thank these people:</title>
	  
	  <varlistentry>
	    <term>
	      Bert Hubert
	    </term>
	    <listitem>
	      <para>
		For writing the wonderfull PowerDNS software and learning me stuff
		that I'd otherwise never had learned.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>
	      PowerDNS B.V.
	    </term>
	    <listitem>
	      <para>
		For being great colleagues.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>
	      The pthreads-win32 crew (see the pthreads-win32 <filename>CONTRIBUTORS</filename> file).
	    </term>
	    <listitem>
	      <para>
		For easing our porting process by writing a great Windows implementation of pthreads.
	      </para>
	    </listitem>
	  </varlistentry>

	  <varlistentry>
	    <term>
	      The guys over at Nullsoft.
	    </term>
	    <listitem>
	      <para>
		For creating the Nullsoft Installer System (<acronym>NSIS</acronym>), and Winamp, the program we use every
		day to make a lot of noise in the office.
	      </para>
	    </listitem>
	  </varlistentry>
	  
	</variablelist>
	
      </sect3>
      
      <sect3>
	<title>Contact information</title>
	
	<para>
	  If you have a comment, or a bug report concerning either this document or the PowerDNS sources
	  you can contact <email>pdns-dev@mailman.powerdns.com</email>
	</para>
	
	<para>
	  For general information about PowerDNS, the pdns server, express, documentation etc. I advice you to visit
	  <ulink url="http://www.powerdns.com/">http://www.powerdns.com/</ulink>
	</para>

	<para>
	  If you are interested in buying PowerDNS you can send a mail to <email>sales@powerdns.com</email>
	  or you can visit the PowerDNS website at <ulink url="http://www.powerdns.com/pdns/">http://www.powerdns.com/pdns/</ulink>
	</para>      
	
	<para>
	  If you want to praise my work, ask me to marry you, deposit $1.000.000 on my bank account or flame me to death, then 
	  you can mail me at <email>michel@powerdns.com</email> :)
	</para>
	
      </sect3>
      
      <sect3>
	<title>Legal information</title>
	
	<para>
	  Microsoft, Visual C++, Windows, Windows NT, Windows 2000, Windows XP and Win32 are 
	  either registered trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other countries.
	</para>
	
	<para>
	  Other product and company names mentioned herein may be the trademarks of their respective owners.
	</para>
	
	</sect3>
      
      </sect2>
    </sect1>
  </appendix>
  <appendix id="license"><title>PowerDNS license (GNU General Public License version 2)</title>
    <para>
      GNU GENERAL PUBLIC LICENSE
      TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    </para>
    <para>

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".
</para><para>
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
</para><para>
  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
</para><para>
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
</para><para>
  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
</para><para>
    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.
</para><para>
    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

</para><para>
    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
</para><para>
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
</para><para>
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
</para><para>
  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
</para><para>
    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,
</para><para>
    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,
</para><para>

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)
</para><para>
The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
</para><para>
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
</para><para>
  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
</para><para>
  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
</para><para>
  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
</para><para>
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

</para><para>
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
</para><para>
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.
</para><para>
  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
</para><para>
Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
</para><para>
  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
</para><para>
			    NO WARRANTY
</para><para>
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

</para><para>
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
</para><para>
		     END OF TERMS AND CONDITIONS
      </para>
  </appendix>

  </book>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-namecase-general:t
sgml-general-insert-case:lower
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
