summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/bin/named
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/named')
-rw-r--r--contrib/bind9/bin/named/Makefile.in9
-rw-r--r--contrib/bind9/bin/named/bind9.ver3.xsl738
-rw-r--r--contrib/bind9/bin/named/bind9.ver3.xsl.h740
-rw-r--r--contrib/bind9/bin/named/builtin.c15
-rw-r--r--contrib/bind9/bin/named/client.c500
-rw-r--r--contrib/bind9/bin/named/config.c19
-rw-r--r--contrib/bind9/bin/named/control.c14
-rw-r--r--contrib/bind9/bin/named/controlconf.c2
-rw-r--r--contrib/bind9/bin/named/include/dlz/dlz_dlopen_driver.h2
-rw-r--r--contrib/bind9/bin/named/include/named/client.h21
-rw-r--r--contrib/bind9/bin/named/include/named/control.h7
-rw-r--r--contrib/bind9/bin/named/include/named/globals.h3
-rw-r--r--contrib/bind9/bin/named/include/named/interfacemgr.h11
-rw-r--r--contrib/bind9/bin/named/include/named/server.h26
-rw-r--r--contrib/bind9/bin/named/include/named/zoneconf.h6
-rw-r--r--contrib/bind9/bin/named/interfacemgr.c70
-rw-r--r--contrib/bind9/bin/named/logconf.c2
-rw-r--r--contrib/bind9/bin/named/main.c21
-rw-r--r--contrib/bind9/bin/named/named.819
-rw-r--r--contrib/bind9/bin/named/named.conf.512
-rw-r--r--contrib/bind9/bin/named/named.conf.docbook14
-rw-r--r--contrib/bind9/bin/named/named.conf.html44
-rw-r--r--contrib/bind9/bin/named/named.docbook22
-rw-r--r--contrib/bind9/bin/named/named.html28
-rw-r--r--contrib/bind9/bin/named/query.c401
-rw-r--r--contrib/bind9/bin/named/server.c908
-rw-r--r--contrib/bind9/bin/named/statschannel.c507
-rw-r--r--contrib/bind9/bin/named/unix/Makefile.in2
-rw-r--r--contrib/bind9/bin/named/unix/dlz_dlopen_driver.c11
-rw-r--r--contrib/bind9/bin/named/unix/os.c2
-rw-r--r--contrib/bind9/bin/named/update.c1261
-rw-r--r--contrib/bind9/bin/named/xfrout.c26
-rw-r--r--contrib/bind9/bin/named/zoneconf.c358
33 files changed, 3874 insertions, 1947 deletions
diff --git a/contrib/bind9/bin/named/Makefile.in b/contrib/bind9/bin/named/Makefile.in
index e3ce3bd..6894135 100644
--- a/contrib/bind9/bin/named/Makefile.in
+++ b/contrib/bind9/bin/named/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.114.14.2 2011/03/10 23:47:25 tbox Exp $
+# $Id: Makefile.in,v 1.116 2011/03/10 23:47:49 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -161,8 +161,11 @@ maintainer-clean::
bind9.xsl.h: bind9.xsl ${srcdir}/convertxsl.pl
${PERL} ${srcdir}/convertxsl.pl < ${srcdir}/bind9.xsl > bind9.xsl.h
-depend: bind9.xsl.h
-statschannel.@O@: bind9.xsl.h
+bind9.ver3.xsl.h: bind9.ver3.xsl ${srcdir}/convertxsl.pl
+ ${PERL} ${srcdir}/convertxsl.pl < ${srcdir}/bind9.ver3.xsl > bind9.ver3.xsl.h
+
+depend: bind9.xsl.h bind9.ver3.xsl.h
+statschannel.@O@: bind9.xsl.h bind9.ver3.xsl.h
installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
diff --git a/contrib/bind9/bin/named/bind9.ver3.xsl b/contrib/bind9/bin/named/bind9.ver3.xsl
new file mode 100644
index 0000000..22e5c45
--- /dev/null
+++ b/contrib/bind9/bin/named/bind9.ver3.xsl
@@ -0,0 +1,738 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ - Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id$ -->
+
+<!-- %Id: bind9.xsl,v 1.21 2009/01/27 23:47:54 tbox Exp % -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
+ <xsl:output method="html" indent="yes" version="4.0"/>
+ <xsl:template match="statistics[@version=&quot;3.0&quot;]">
+ <html>
+ <head>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <script type="text/javascript" src="https://www.google.com/jsapi"/>
+ <script type="text/javascript">
+
+ google.load("visualization", "1", {packages:["corechart"]});
+ google.setOnLoadCallback(loadGraphs);
+
+ var graphs=[];
+
+ function drawChart(chart_title,target,data) {
+ var data = google.visualization.arrayToDataTable(data);
+
+ var options = {
+ title: chart_title
+ };
+
+ var chart = new google.visualization.BarChart(document.getElementById(target));
+ chart.draw(data, options);
+ }
+
+ function loadGraphs(){
+ //alert("here we are!");
+ var g;
+
+ // Server Incoming query Types
+ while(g = graphs.shift()){
+ // alert("going for: " + g.target);
+ if(g.data.length > 1){
+ drawChart(g.title,g.target,g.data);
+ }
+ }
+ }
+
+ // Server Incoming Queries Types
+ graphs.push({
+ 'title' : "Server Incoming Query Types",
+ 'target': 'chart_incoming_qtypes',
+ 'data': [['Type','Counter'],<xsl:for-each select="server/counters[@type=&quot;qtype&quot;]/counter">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]
+ });
+
+
+ // Server Incoming Requests
+ graphs.push({
+ 'title' : "Server Incoming Requests",
+ 'target': 'chart_incoming_requests',
+ 'data': [['Requests','Counter'],<xsl:for-each select="server/counters[@type=&quot;opcode&quot;]/counter">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]});
+
+
+
+
+ </script>
+ </xsl:if>
+ <style type="text/css">
+ body {
+ font-family: sans-serif;
+ background-color: #ffffff;
+ color: #000000;
+ font-size: 10pt;
+ }
+
+ .odd{
+ background-color: #f0f0f0;
+ }
+
+ .even{
+ background-color: #ffffff;
+ }
+
+ p.footer{
+ font-style:italic;
+ color: grey;
+ }
+
+ table {
+ border-collapse: collapse;
+ border: 1px solid grey;
+ }
+
+ table.counters{
+ border: 1px solid grey;
+ width: 500px;
+ }
+
+ table.counters th {
+ text-align: center;
+ border: 1px solid grey;
+ width: 120px;
+ }
+ table.counters td{
+ text-align:center;
+
+ }
+
+ table.counters tr:hover{
+ background-color: #99ddff;
+ }
+
+ .totals {
+ background-color: rgb(1,169,206);
+ color: #ffffff;
+ }
+
+ td, th {
+ padding-right: 5px;
+ padding-left: 5px;
+ border: 1px solid grey;
+ }
+
+ .header h1 {
+ color: rgb(1,169,206);
+ padding: 0px;
+ }
+
+ .content {
+ background-color: #ffffff;
+ color: #000000;
+ padding: 4px;
+ }
+
+ .item {
+ padding: 4px;
+ text-align: right;
+ }
+
+ .value {
+ padding: 4px;
+ font-weight: bold;
+ }
+
+
+ h2 {
+ color: grey;
+ font-size: 14pt;
+ width:500px;
+ text-align:center;
+ }
+
+ h3 {
+ color: #444444;
+ font-size: 12pt;
+ width:500px;
+ text-align:center;
+
+ }
+ h4 {
+ color: rgb(1,169,206);
+ font-size: 10pt;
+ width:500px;
+ text-align:center;
+
+ }
+
+ .pie {
+ width:500px;
+ height: 500px;
+ }
+
+ </style>
+ <title>ISC BIND 9 Statistics</title>
+ </head>
+ <body>
+ <div class="header">
+ <h1>ISC Bind 9 Configuration and Statistics</h1>
+ </div>
+ <hr/>
+ <h2>Server Times</h2>
+ <table class="counters">
+ <tr>
+ <th>Boot time:</th>
+ <td>
+ <xsl:value-of select="server/boot-time"/>
+ </td>
+ </tr>
+ <tr>
+ <th>Sample time:</th>
+ <td>
+ <xsl:value-of select="server/current-time"/>
+ </td>
+ </tr>
+ </table>
+ <br/>
+ <h2>Incoming Requests</h2>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <div class="pie" id="chart_incoming_requests">[no incoming requests]</div>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="server/counters[@type=&quot;opcode&quot;]/counter">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <tr>
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <tr>
+ <th class="totals">Total:</th>
+ <td class="totals">
+ <xsl:value-of select="sum(server/counters[@type=&quot;opcode&quot;]/counter)"/>
+ </td>
+ </tr>
+ </table>
+ <br/>
+ <h3>Incoming Queries by Type</h3>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <div class="pie" id="chart_incoming_qtypes">[no incoming queries]</div>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="server/counters[@type=&quot;qtype&quot;]/counter">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <xsl:variable name="css-class">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ <tr>
+ <th class="totals">Total:</th>
+ <td class="totals">
+ <xsl:value-of select="sum(server/counters[@type=&quot;qtype&quot;]/counter)"/>
+ </td>
+ </tr>
+ </table>
+ <br/>
+ <h2>Outgoing Queries per view</h2>
+ <xsl:for-each select="views/view[count(counters[@type=&quot;resqtype&quot;]/counter) &gt; 0]">
+ <h3>View <xsl:value-of select="@name"/></h3>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <script type="text/javascript">
+ graphs.push({
+ 'title': "Outgoing queries for view: <xsl:value-of select="@name"/>",
+ 'target': 'chart_outgoing_queries_view_<xsl:value-of select="@name"/>',
+ 'data': [['Type','Counter'],<xsl:for-each select="counters[@type=&quot;resqtype&quot;]/counter">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]
+ });
+
+ </script>
+ <xsl:variable name="target">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <div class="pie" id="chart_outgoing_queries_view_{$target}"/>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="counters[@type=&quot;resqtype&quot;]/counter">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <xsl:variable name="css-class1">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class1}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ </xsl:for-each>
+ <h2>Server Statistics</h2>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <script type="text/javascript">
+ graphs.push({
+ 'title' : "Server Counters",
+ 'target': 'chart_server_nsstat_restype',
+ 'data': [['Type','Counter'],<xsl:for-each select="server/counters[@type=&quot;nsstat&quot;]/counter[.&gt;0]">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]
+ });
+
+ </script>
+ <div class="pie" id="chart_server_nsstat_restype"/>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="server/counters[@type=&quot;nsstat&quot;]/counter[.&gt;0]">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <xsl:variable name="css-class2">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class2}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ <h2>Zone Maintenance Statistics</h2>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <script type="text/javascript">
+ graphs.push({
+ 'title' : "Zone Maintenance Stats",
+ 'target': 'chart_server_zone_maint',
+ 'data': [['Type','Counter'],<xsl:for-each select="server/counters[@type=&quot;zonestat&quot;]/counter">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]
+ });
+
+ </script>
+ <!-- Non Mozilla specific markup -->
+ <div class="pie" id="chart_server_zone_maint"/>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="server/counters[@type=&quot;zonestat&quot;]/counter">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <xsl:variable name="css-class3">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class3}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <h2>Resolver Statistics (Common)</h2>
+ <table class="counters">
+ <xsl:for-each select="server/counters[@type=&quot;restat&quot;]/counter">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <xsl:variable name="css-class4">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class4}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <xsl:for-each select="views/view">
+ <h3>Resolver Statistics for View <xsl:value-of select="@name"/></h3>
+ <table class="counters">
+ <xsl:for-each select="counters[@type=&quot;resstats&quot;]/counter[.&gt;0]">
+ <xsl:sort select="." data-type="number" order="descending"/>
+ <xsl:variable name="css-class5">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class5}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:for-each>
+ <h3>Cache DB RRsets for View <xsl:value-of select="@name"/></h3>
+ <xsl:for-each select="views/view">
+ <table class="counters">
+ <xsl:for-each select="cache/rrset">
+ <xsl:variable name="css-class6">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class6}">
+ <th>
+ <xsl:value-of select="name"/>
+ </th>
+ <td>
+ <xsl:value-of select="counter"/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ </xsl:for-each>
+ <h2>Socket I/O Statistics</h2>
+ <table class="counters">
+ <xsl:for-each select="server/counters[@type=&quot;sockstat&quot;]/counter[.&gt;0]">
+ <xsl:variable name="css-class7">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class7}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ <br/>
+ <h2>Response Codes per view/zone</h2>
+ <xsl:for-each select="views/view[zones/zone/counters[@type=&quot;rcode&quot;]/counter &gt;0]">
+ <h3>View <xsl:value-of select="@name"/></h3>
+ <xsl:variable name="thisview">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <xsl:for-each select="zones/zone">
+ <xsl:if test="counters[@type=&quot;rcode&quot;]/counter[. &gt; 0]">
+ <h4>Zone <xsl:value-of select="@name"/></h4>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <script type="text/javascript">
+ graphs.push({
+ 'title': "Response Codes for zone <xsl:value-of select="@name"/>",
+ 'target': 'chart_rescode_<xsl:value-of select="../../@name"/>_<xsl:value-of select="@name"/>',
+ 'data': [['Type','Counter'],<xsl:for-each select="counters[@type=&quot;rcode&quot;]/counter[.&gt;0 and @name != &quot;QryAuthAns&quot;]">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]
+ });
+
+ </script>
+ <xsl:variable name="target">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <div class="pie" id="chart_rescode_{$thisview}_{$target}"/>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="counters[@type=&quot;rcode&quot;]/counter[.&gt;0 and @name != &quot;QryAuthAns&quot;]">
+ <xsl:sort select="."/>
+ <xsl:variable name="css-class10">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class10}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:for-each>
+ <h2>Received QTYPES per view/zone</h2>
+ <xsl:for-each select="views/view[zones/zone/counters[@type=&quot;qtype&quot;]/counter &gt;0]">
+ <h3>View <xsl:value-of select="@name"/></h3>
+ <xsl:variable name="thisview2">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <xsl:for-each select="zones/zone">
+ <xsl:if test="counters[@type=&quot;qtype&quot;]/counter[count(.) &gt; 0]">
+ <h4>Zone <xsl:value-of select="@name"/></h4>
+ <xsl:if test="system-property('xsl:vendor')!='Transformiix'">
+ <!-- Non Mozilla specific markup -->
+ <script type="text/javascript">
+ graphs.push({
+ 'title': "Query Types for zone <xsl:value-of select="@name"/>",
+ 'target': 'chart_qtype_<xsl:value-of select="../../@name"/>_<xsl:value-of select="@name"/>',
+ 'data': [['Type','Counter'],<xsl:for-each select="counters[@type=&quot;qtype&quot;]/counter[.&gt;0 and @name != &quot;QryAuthAns&quot;]">['<xsl:value-of select="@name"/>',<xsl:value-of select="."/>],</xsl:for-each>]
+ });
+
+ </script>
+ <xsl:variable name="target">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <div class="pie" id="chart_qtype_{$thisview2}_{$target}"/>
+ </xsl:if>
+ <table class="counters">
+ <xsl:for-each select="counters[@type=&quot;qtype&quot;]/counter">
+ <xsl:sort select="."/>
+ <xsl:variable name="css-class11">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class11}">
+ <th>
+ <xsl:value-of select="@name"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:for-each>
+ <h2>Network Status</h2>
+ <table class="counters">
+ <tr>
+ <th>ID</th>
+ <th>Name</th>
+ <th>Type</th>
+ <th>References</th>
+ <th>LocalAddress</th>
+ <th>PeerAddress</th>
+ <th>State</th>
+ </tr>
+ <xsl:for-each select="socketmgr/sockets/socket">
+ <xsl:sort select="id"/>
+ <xsl:variable name="css-class12">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class12}">
+ <td>
+ <xsl:value-of select="id"/>
+ </td>
+ <td>
+ <xsl:value-of select="name"/>
+ </td>
+ <td>
+ <xsl:value-of select="type"/>
+ </td>
+ <td>
+ <xsl:value-of select="references"/>
+ </td>
+ <td>
+ <xsl:value-of select="local-address"/>
+ </td>
+ <td>
+ <xsl:value-of select="peer-address"/>
+ </td>
+ <td>
+ <xsl:for-each select="states">
+ <xsl:value-of select="."/>
+ </xsl:for-each>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ <h2>Task Manager Configuration</h2>
+ <table class="counters">
+ <tr>
+ <th class="even">Thread-Model</th>
+ <td>
+ <xsl:value-of select="taskmgr/thread-model/type"/>
+ </td>
+ </tr>
+ <tr class="odd">
+ <th>Worker Threads</th>
+ <td>
+ <xsl:value-of select="taskmgr/thread-model/worker-threads"/>
+ </td>
+ </tr>
+ <tr class="even">
+ <th>Default Quantum</th>
+ <td>
+ <xsl:value-of select="taskmgr/thread-model/default-quantum"/>
+ </td>
+ </tr>
+ <tr class="odd">
+ <th>Tasks Running</th>
+ <td>
+ <xsl:value-of select="taskmgr/thread-model/tasks-running"/>
+ </td>
+ </tr>
+ </table>
+ <br/>
+ <h2>Tasks</h2>
+ <table class="counters">
+ <tr>
+ <th>ID</th>
+ <th>Name</th>
+ <th>References</th>
+ <th>State</th>
+ <th>Quantum</th>
+ </tr>
+ <xsl:for-each select="taskmgr/tasks/task">
+ <xsl:sort select="name"/>
+ <xsl:variable name="css-class14">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class14}">
+ <td>
+ <xsl:value-of select="id"/>
+ </td>
+ <td>
+ <xsl:value-of select="name"/>
+ </td>
+ <td>
+ <xsl:value-of select="references"/>
+ </td>
+ <td>
+ <xsl:value-of select="state"/>
+ </td>
+ <td>
+ <xsl:value-of select="quantum"/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ <h2>Memory Usage Summary</h2>
+ <table class="counters">
+ <xsl:for-each select="memory/summary/*">
+ <xsl:variable name="css-class13">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class13}">
+ <th>
+ <xsl:value-of select="name()"/>
+ </th>
+ <td>
+ <xsl:value-of select="."/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ <h2>Memory Contexts</h2>
+ <table class="counters">
+ <tr>
+ <th>ID</th>
+ <th>Name</th>
+ <th>References</th>
+ <th>TotalUse</th>
+ <th>InUse</th>
+ <th>MaxUse</th>
+ <th>BlockSize</th>
+ <th>Pools</th>
+ <th>HiWater</th>
+ <th>LoWater</th>
+ </tr>
+ <xsl:for-each select="memory/contexts/context">
+ <xsl:sort select="total" data-type="number" order="descending"/>
+ <xsl:variable name="css-class14">
+ <xsl:choose>
+ <xsl:when test="position() mod 2 = 0">even</xsl:when>
+ <xsl:otherwise>odd</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <tr class="{$css-class14}">
+ <td>
+ <xsl:value-of select="id"/>
+ </td>
+ <td>
+ <xsl:value-of select="name"/>
+ </td>
+ <td>
+ <xsl:value-of select="references"/>
+ </td>
+ <td>
+ <xsl:value-of select="total"/>
+ </td>
+ <td>
+ <xsl:value-of select="inuse"/>
+ </td>
+ <td>
+ <xsl:value-of select="maxinuse"/>
+ </td>
+ <td>
+ <xsl:value-of select="blocksize"/>
+ </td>
+ <td>
+ <xsl:value-of select="pools"/>
+ </td>
+ <td>
+ <xsl:value-of select="hiwater"/>
+ </td>
+ <td>
+ <xsl:value-of select="lowater"/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <hr/>
+ <p class="footer">Internet Systems Consortium Inc.<br/><a href="http://www.isc.org">http://www.isc.org</a></p>
+ </body>
+ </html>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/contrib/bind9/bin/named/bind9.ver3.xsl.h b/contrib/bind9/bin/named/bind9.ver3.xsl.h
new file mode 100644
index 0000000..c55714a
--- /dev/null
+++ b/contrib/bind9/bin/named/bind9.ver3.xsl.h
@@ -0,0 +1,740 @@
+/*
+ * Generated by convertxsl.pl 1.14 2008/07/17 23:43:26 jinmei Exp
+ * From <!-- %Id: bind9.xsl 1.21 2009/01/27 23:47:54 tbox Exp %
+ */
+static char xslmsg[] =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!--\n"
+ " - Copyright (C) 2006-2009 Internet Systems Consortium, Inc. (\"ISC\")\n"
+ " -\n"
+ " - Permission to use, copy, modify, and/or distribute this software for any\n"
+ " - purpose with or without fee is hereby granted, provided that the above\n"
+ " - copyright notice and this permission notice appear in all copies.\n"
+ " -\n"
+ " - THE SOFTWARE IS PROVIDED \"AS IS\" AND ISC DISCLAIMS ALL WARRANTIES WITH\n"
+ " - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n"
+ " - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,\n"
+ " - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n"
+ " - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n"
+ " - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n"
+ " - PERFORMANCE OF THIS SOFTWARE.\n"
+ "-->\n"
+ "<!-- \045Id: bind9.xsl,v 1.21 2009/01/27 23:47:54 tbox Exp \045 -->\n"
+ "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns=\"http://www.w3.org/1999/xhtml\" version=\"1.0\">\n"
+ " <xsl:output method=\"html\" indent=\"yes\" version=\"4.0\"/>\n"
+ " <xsl:template match=\"statistics[@version=&quot;3.0&quot;]\">\n"
+ " <html>\n"
+ " <head>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"/>\n"
+ " <script type=\"text/javascript\">\n"
+ " \n"
+ " google.load(\"visualization\", \"1\", {packages:[\"corechart\"]});\n"
+ " google.setOnLoadCallback(loadGraphs);\n"
+ "\n"
+ " var graphs=[];\n"
+ " \n"
+ " function drawChart(chart_title,target,data) {\n"
+ " var data = google.visualization.arrayToDataTable(data);\n"
+ "\n"
+ " var options = {\n"
+ " title: chart_title\n"
+ " };\n"
+ " \n"
+ " var chart = new google.visualization.BarChart(document.getElementById(target));\n"
+ " chart.draw(data, options);\n"
+ " }\n"
+ " \n"
+ " function loadGraphs(){\n"
+ " //alert(\"here we are!\");\n"
+ " var g;\n"
+ " \n"
+ " // Server Incoming query Types\n"
+ " while(g = graphs.shift()){\n"
+ " // alert(\"going for: \" + g.target);\n"
+ " if(g.data.length > 1){\n"
+ " drawChart(g.title,g.target,g.data);\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " \n"
+ " // Server Incoming Queries Types \n"
+ " graphs.push({\n"
+ " 'title' : \"Server Incoming Query Types\",\n"
+ " 'target': 'chart_incoming_qtypes',\n"
+ " 'data': [['Type','Counter'],<xsl:for-each select=\"server/counters[@type=&quot;qtype&quot;]/counter\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]\n"
+ " });\n"
+ "\n"
+ "\n"
+ " // Server Incoming Requests \n"
+ " graphs.push({\n"
+ " 'title' : \"Server Incoming Requests\",\n"
+ " 'target': 'chart_incoming_requests',\n"
+ " 'data': [['Requests','Counter'],<xsl:for-each select=\"server/counters[@type=&quot;opcode&quot;]/counter\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]});\n"
+ " \n"
+ " \n"
+ " \n"
+ " \n"
+ " </script>\n"
+ " </xsl:if>\n"
+ " <style type=\"text/css\">\n"
+ " body {\n"
+ " font-family: sans-serif;\n"
+ " background-color: #ffffff;\n"
+ " color: #000000;\n"
+ " font-size: 10pt;\n"
+ " }\n"
+ " \n"
+ " .odd{\n"
+ " background-color: #f0f0f0;\n"
+ " }\n"
+ " \n"
+ " .even{\n"
+ " background-color: #ffffff;\n"
+ " }\n"
+ " \n"
+ " p.footer{\n"
+ " font-style:italic;\n"
+ " color: grey;\n"
+ " }\n"
+ "\n"
+ " table {\n"
+ " border-collapse: collapse;\n"
+ " border: 1px solid grey;\n"
+ " }\n"
+ "\n"
+ " table.counters{\n"
+ " border: 1px solid grey;\n"
+ " width: 500px;\n"
+ " }\n"
+ " \n"
+ " table.counters th {\n"
+ " text-align: center;\n"
+ " border: 1px solid grey;\n"
+ " width: 120px;\n"
+ " }\n"
+ " table.counters td{\n"
+ " text-align:center;\n"
+ " \n"
+ " }\n"
+ " \n"
+ " table.counters tr:hover{\n"
+ " background-color: #99ddff;\n"
+ " }\n"
+ " \n"
+ " .totals {\n"
+ " background-color: rgb(1,169,206);\n"
+ " color: #ffffff;\n"
+ " }\n"
+ "\n"
+ " td, th {\n"
+ " padding-right: 5px;\n"
+ " padding-left: 5px;\n"
+ " border: 1px solid grey;\n"
+ " }\n"
+ "\n"
+ " .header h1 {\n"
+ " color: rgb(1,169,206);\n"
+ " padding: 0px;\n"
+ " }\n"
+ "\n"
+ " .content {\n"
+ " background-color: #ffffff;\n"
+ " color: #000000;\n"
+ " padding: 4px;\n"
+ " }\n"
+ "\n"
+ " .item {\n"
+ " padding: 4px;\n"
+ " text-align: right;\n"
+ " }\n"
+ "\n"
+ " .value {\n"
+ " padding: 4px;\n"
+ " font-weight: bold;\n"
+ " }\n"
+ "\n"
+ "\n"
+ " h2 {\n"
+ " color: grey;\n"
+ " font-size: 14pt;\n"
+ " width:500px;\n"
+ " text-align:center;\n"
+ " }\n"
+ " \n"
+ " h3 {\n"
+ " color: #444444;\n"
+ " font-size: 12pt;\n"
+ " width:500px;\n"
+ " text-align:center;\n"
+ " \n"
+ " }\n"
+ " h4 {\n"
+ " color: rgb(1,169,206);\n"
+ " font-size: 10pt;\n"
+ " width:500px;\n"
+ " text-align:center;\n"
+ " \n"
+ " }\n"
+ "\n"
+ " .pie {\n"
+ " width:500px;\n"
+ " height: 500px;\n"
+ " }\n"
+ "\n"
+ " </style>\n"
+ " <title>ISC BIND 9 Statistics</title>\n"
+ " </head>\n"
+ " <body>\n"
+ " <div class=\"header\">\n"
+ " <h1>ISC Bind 9 Configuration and Statistics</h1>\n"
+ " </div>\n"
+ " <hr/>\n"
+ " <h2>Server Times</h2>\n"
+ " <table class=\"counters\">\n"
+ " <tr>\n"
+ " <th>Boot time:</th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"server/boot-time\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " <tr>\n"
+ " <th>Sample time:</th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"server/current-time\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Incoming Requests</h2>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <div class=\"pie\" id=\"chart_incoming_requests\">[graph incoming requests]</div>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"server/counters[@type=&quot;opcode&quot;]/counter\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <tr>\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " <tr>\n"
+ " <th class=\"totals\">Total:</th>\n"
+ " <td class=\"totals\">\n"
+ " <xsl:value-of select=\"sum(server/counters[@type=&quot;opcode&quot;]/counter)\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h3>Incoming Queries by Type</h3>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <div class=\"pie\" id=\"chart_incoming_qtypes\">[graph incoming qtypes]</div>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"server/counters[@type=&quot;qtype&quot;]/counter\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " <tr>\n"
+ " <th class=\"totals\">Total:</th>\n"
+ " <td class=\"totals\">\n"
+ " <xsl:value-of select=\"sum(server/counters[@type=&quot;qtype&quot;]/counter)\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Outgoing Queries per view</h2>\n"
+ " <xsl:for-each select=\"views/view[count(counters[@type=&quot;resqtype&quot;]/counter) &gt; 0]\">\n"
+ " <h3>View <xsl:value-of select=\"@name\"/></h3>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <script type=\"text/javascript\">\n"
+ " graphs.push({\n"
+ " 'title': \"Outgoing queries for view: <xsl:value-of select=\"@name\"/>\",\n"
+ " 'target': 'chart_outgoing_queries_view_<xsl:value-of select=\"@name\"/>',\n"
+ " 'data': [['Type','Counter'],<xsl:for-each select=\"counters[@type=&quot;resqtype&quot;]/counter\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]\n"
+ " });\n"
+ " \n"
+ " </script>\n"
+ " <xsl:variable name=\"target\">\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </xsl:variable>\n"
+ " <div class=\"pie\" id=\"chart_outgoing_queries_view_{$target}\"/>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"counters[@type=&quot;resqtype&quot;]/counter\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class1\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class1}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " </xsl:for-each>\n"
+ " <h2>Server Statistics</h2>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <script type=\"text/javascript\">\n"
+ " graphs.push({\n"
+ " 'title' : \"Server Response Types\",\n"
+ " 'target': 'chart_server_nsstat_restype',\n"
+ " 'data': [['Type','Counter'],<xsl:for-each select=\"server/counters[@type=&quot;nsstat&quot;]/counter[.&gt;0]\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]\n"
+ " });\n"
+ " \n"
+ " </script>\n"
+ " <div class=\"pie\" id=\"chart_server_nsstat_restype\"/>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"server/counters[@type=&quot;nsstat&quot;]/counter[.&gt;0]\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class2\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class2}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Zone Maintenance Statistics</h2>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <script type=\"text/javascript\">\n"
+ " graphs.push({\n"
+ " 'title' : \"Zone Maintenance Stats\",\n"
+ " 'target': 'chart_server_zone_maint',\n"
+ " 'data': [['Type','Counter'],<xsl:for-each select=\"server/counters[@type=&quot;zonestat&quot;]/counter\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]\n"
+ " });\n"
+ "\n"
+ " </script>\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <div class=\"pie\" id=\"chart_server_zone_maint\"/>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"server/counters[@type=&quot;zonestat&quot;]/counter\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class3\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class3}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <h2>Resolver Statistics (Common)</h2>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"server/counters[@type=&quot;restat&quot;]/counter\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class4\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class4}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <xsl:for-each select=\"views/view\">\n"
+ " <h3>Resolver Statistics for View <xsl:value-of select=\"@name\"/></h3>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"counters[@type=&quot;resstats&quot;]/counter[.&gt;0]\">\n"
+ " <xsl:sort select=\".\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class5\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class5}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " </xsl:for-each>\n"
+ " <h3>Cache DB RRsets for View <xsl:value-of select=\"@name\"/></h3>\n"
+ " <xsl:for-each select=\"views/view\">\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"cache/rrset\">\n"
+ " <xsl:variable name=\"css-class6\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class6}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"counter\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " </xsl:for-each>\n"
+ " <h2>Socket I/O Statistics</h2>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"server/counters[@type=&quot;sockstat&quot;]/counter[.&gt;0]\">\n"
+ " <xsl:variable name=\"css-class7\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class7}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <br/>\n"
+ " <h2>Response Codes per view/zone</h2>\n"
+ " <xsl:for-each select=\"views/view[zones/zone/counters[@type=&quot;rcode&quot;]/counter &gt;0]\">\n"
+ " <h3>View <xsl:value-of select=\"@name\"/></h3>\n"
+ " <xsl:variable name=\"thisview\">\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </xsl:variable>\n"
+ " <xsl:for-each select=\"zones/zone\">\n"
+ " <xsl:if test=\"counters[@type=&quot;rcode&quot;]/counter[. &gt; 0]\">\n"
+ " <h4>Zone <xsl:value-of select=\"@name\"/></h4>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <script type=\"text/javascript\">\n"
+ " graphs.push({\n"
+ " 'title': \"Response Codes for zone <xsl:value-of select=\"@name\"/>\",\n"
+ " 'target': 'chart_rescode_<xsl:value-of select=\"../../@name\"/>_<xsl:value-of select=\"@name\"/>',\n"
+ " 'data': [['Type','Counter'],<xsl:for-each select=\"counters[@type=&quot;rcode&quot;]/counter[.&gt;0 and @name != &quot;QryAuthAns&quot;]\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]\n"
+ " });\n"
+ "\n"
+ " </script>\n"
+ " <xsl:variable name=\"target\">\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </xsl:variable>\n"
+ " <div class=\"pie\" id=\"chart_rescode_{$thisview}_{$target}\"/>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"counters[@type=&quot;rcode&quot;]/counter[.&gt;0 and @name != &quot;QryAuthAns&quot;]\">\n"
+ " <xsl:sort select=\".\"/>\n"
+ " <xsl:variable name=\"css-class10\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class10}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " </xsl:if>\n"
+ " </xsl:for-each>\n"
+ " </xsl:for-each>\n"
+ " <h2>Received QTYPES per view/zone</h2>\n"
+ " <xsl:for-each select=\"views/view[zones/zone/counters[@type=&quot;qtype&quot;]/counter &gt;0]\">\n"
+ " <h3>View <xsl:value-of select=\"@name\"/></h3>\n"
+ " <xsl:variable name=\"thisview2\">\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </xsl:variable>\n"
+ " <xsl:for-each select=\"zones/zone\">\n"
+ " <xsl:if test=\"counters[@type=&quot;qtype&quot;]/counter[count(.) &gt; 0]\">\n"
+ " <h4>Zone <xsl:value-of select=\"@name\"/></h4>\n"
+ " <xsl:if test=\"system-property('xsl:vendor')!='Transformiix'\">\n"
+ " <!-- Non Mozilla specific markup -->\n"
+ " <script type=\"text/javascript\">\n"
+ " graphs.push({\n"
+ " 'title': \"Query Types for zone <xsl:value-of select=\"@name\"/>\",\n"
+ " 'target': 'chart_qtype_<xsl:value-of select=\"../../@name\"/>_<xsl:value-of select=\"@name\"/>',\n"
+ " 'data': [['Type','Counter'],<xsl:for-each select=\"counters[@type=&quot;qtype&quot;]/counter[.&gt;0 and @name != &quot;QryAuthAns&quot;]\">['<xsl:value-of select=\"@name\"/>',<xsl:value-of select=\".\"/>],</xsl:for-each>]\n"
+ " });\n"
+ "\n"
+ " </script>\n"
+ " <xsl:variable name=\"target\">\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </xsl:variable>\n"
+ " <div class=\"pie\" id=\"chart_qtype_{$thisview2}_{$target}\"/>\n"
+ " </xsl:if>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"counters[@type=&quot;qtype&quot;]/counter\">\n"
+ " <xsl:sort select=\".\"/>\n"
+ " <xsl:variable name=\"css-class11\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class11}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"@name\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " </xsl:if>\n"
+ " </xsl:for-each>\n"
+ " </xsl:for-each>\n"
+ " <h2>Network Status</h2>\n"
+ " <table class=\"counters\">\n"
+ " <tr>\n"
+ " <th>ID</th>\n"
+ " <th>Name</th>\n"
+ " <th>Type</th>\n"
+ " <th>References</th>\n"
+ " <th>LocalAddress</th>\n"
+ " <th>PeerAddress</th>\n"
+ " <th>State</th>\n"
+ " </tr>\n"
+ " <xsl:for-each select=\"socketmgr/sockets/socket\">\n"
+ " <xsl:sort select=\"id\"/>\n"
+ " <xsl:variable name=\"css-class12\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class12}\">\n"
+ " <td>\n"
+ " <xsl:value-of select=\"id\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"name\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"type\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"references\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"local-address\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"peer-address\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:for-each select=\"states\">\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </xsl:for-each>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Task Manager Configuration</h2>\n"
+ " <table class=\"counters\">\n"
+ " <tr>\n"
+ " <th class=\"even\">Thread-Model</th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"taskmgr/thread-model/type\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " <tr class=\"odd\">\n"
+ " <th>Worker Threads</th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"taskmgr/thread-model/worker-threads\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " <tr class=\"even\">\n"
+ " <th>Default Quantum</th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"taskmgr/thread-model/default-quantum\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " <tr class=\"odd\">\n"
+ " <th>Tasks Running</th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"taskmgr/thread-model/tasks-running\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Tasks</h2>\n"
+ " <table class=\"counters\">\n"
+ " <tr>\n"
+ " <th>ID</th>\n"
+ " <th>Name</th>\n"
+ " <th>References</th>\n"
+ " <th>State</th>\n"
+ " <th>Quantum</th>\n"
+ " </tr>\n"
+ " <xsl:for-each select=\"taskmgr/tasks/task\">\n"
+ " <xsl:sort select=\"name\"/>\n"
+ " <xsl:variable name=\"css-class14\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class14}\">\n"
+ " <td>\n"
+ " <xsl:value-of select=\"id\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"name\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"references\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"state\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"quantum\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Memory Usage Summary</h2>\n"
+ " <table class=\"counters\">\n"
+ " <xsl:for-each select=\"memory/summary/*\">\n"
+ " <xsl:variable name=\"css-class13\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class13}\">\n"
+ " <th>\n"
+ " <xsl:value-of select=\"name()\"/>\n"
+ " </th>\n"
+ " <td>\n"
+ " <xsl:value-of select=\".\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " <h2>Memory Contexts</h2>\n"
+ " <table class=\"counters\">\n"
+ " <tr>\n"
+ " <th>ID</th>\n"
+ " <th>Name</th>\n"
+ " <th>References</th>\n"
+ " <th>TotalUse</th>\n"
+ " <th>InUse</th>\n"
+ " <th>MaxUse</th>\n"
+ " <th>BlockSize</th>\n"
+ " <th>Pools</th>\n"
+ " <th>HiWater</th>\n"
+ " <th>LoWater</th>\n"
+ " </tr>\n"
+ " <xsl:for-each select=\"memory/contexts/context\">\n"
+ " <xsl:sort select=\"total\" data-type=\"number\" order=\"descending\"/>\n"
+ " <xsl:variable name=\"css-class14\">\n"
+ " <xsl:choose>\n"
+ " <xsl:when test=\"position() mod 2 = 0\">even</xsl:when>\n"
+ " <xsl:otherwise>odd</xsl:otherwise>\n"
+ " </xsl:choose>\n"
+ " </xsl:variable>\n"
+ " <tr class=\"{$css-class14}\">\n"
+ " <td>\n"
+ " <xsl:value-of select=\"id\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"name\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"references\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"total\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"inuse\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"maxinuse\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"blocksize\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"pools\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"hiwater\"/>\n"
+ " </td>\n"
+ " <td>\n"
+ " <xsl:value-of select=\"lowater\"/>\n"
+ " </td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <hr/>\n"
+ " <p class=\"footer\">Internet Systems Consortium Inc.<br/><a href=\"http://www.isc.org\">http://www.isc.org</a></p>\n"
+ " </body>\n"
+ " </html>\n"
+ " </xsl:template>\n"
+ "</xsl:stylesheet>\n";
diff --git a/contrib/bind9/bin/named/builtin.c b/contrib/bind9/bin/named/builtin.c
index 14204cd..4604cb3 100644
--- a/contrib/bind9/bin/named/builtin.c
+++ b/contrib/bind9/bin/named/builtin.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: builtin.c,v 1.20.14.3 2012/01/11 20:19:40 ckb Exp $ */
+/* $Id: builtin.c,v 1.26 2012/01/21 19:44:18 each Exp $ */
/*! \file
* \brief
@@ -281,11 +281,14 @@ dns64_cname(const dns_name_t *zone, const dns_name_t *name,
static isc_result_t
builtin_lookup(const char *zone, const char *name, void *dbdata,
- dns_sdblookup_t *lookup)
+ dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo)
{
builtin_t *b = (builtin_t *) dbdata;
UNUSED(zone);
+ UNUSED(methods);
+ UNUSED(clientinfo);
if (strcmp(name, "@") == 0)
return (b->do_lookup(lookup));
@@ -295,10 +298,14 @@ builtin_lookup(const char *zone, const char *name, void *dbdata,
static isc_result_t
dns64_lookup(const dns_name_t *zone, const dns_name_t *name, void *dbdata,
- dns_sdblookup_t *lookup)
+ dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo)
{
builtin_t *b = (builtin_t *) dbdata;
+ UNUSED(methods);
+ UNUSED(clientinfo);
+
if (name->labels == 0 && name->length == 0)
return (b->do_lookup(lookup));
else
@@ -353,6 +360,8 @@ do_authors_lookup(dns_sdblookup_t *lookup) {
"Curtis Blackburn",
"James Brister",
"Ben Cottrell",
+ "John H. DuBois III",
+ "Francis Dupont",
"Michael Graff",
"Andreas Gustafsson",
"Bob Halley",
diff --git a/contrib/bind9/bin/named/client.c b/contrib/bind9/bin/named/client.c
index ff4ab69..933abc7 100644
--- a/contrib/bind9/bin/named/client.c
+++ b/contrib/bind9/bin/named/client.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.271.10.4 2012/01/31 23:46:39 tbox Exp $ */
+/* $Id$ */
#include <config.h>
@@ -24,6 +24,7 @@
#include <isc/once.h>
#include <isc/platform.h>
#include <isc/print.h>
+#include <isc/queue.h>
#include <isc/stats.h>
#include <isc/stdio.h>
#include <isc/string.h>
@@ -116,15 +117,26 @@
struct ns_clientmgr {
/* Unlocked. */
unsigned int magic;
+
+ /* The queue object has its own locks */
+ client_queue_t inactive; /*%< To be recycled */
+
isc_mem_t * mctx;
isc_taskmgr_t * taskmgr;
isc_timermgr_t * timermgr;
+
+ /* Lock covers manager state. */
isc_mutex_t lock;
- /* Locked by lock. */
isc_boolean_t exiting;
- client_list_t active; /*%< Active clients */
- client_list_t recursing; /*%< Recursing clients */
- client_list_t inactive; /*%< To be recycled */
+
+ /* Lock covers the clients list */
+ isc_mutex_t listlock;
+ client_list_t clients; /*%< All active clients */
+
+ /* Lock covers the recursing list */
+ isc_mutex_t reclock;
+ client_list_t recursing; /*%< Recursing clients */
+
#if NMCTXS > 0
/*%< mctx pool for clients. */
unsigned int nextmctx;
@@ -188,6 +200,12 @@ struct ns_clientmgr {
* recursion quota, and an outstanding write request.
*/
+#define NS_CLIENTSTATE_RECURSING 5
+/*%<
+ * The client object is recursing. It will be on the 'recursing'
+ * list.
+ */
+
#define NS_CLIENTSTATE_MAX 9
/*%<
* Sentinel value used to indicate "no state". When client->newstate
@@ -210,20 +228,21 @@ static void client_udprecv(ns_client_t *client);
static void clientmgr_destroy(ns_clientmgr_t *manager);
static isc_boolean_t exit_check(ns_client_t *client);
static void ns_client_endrequest(ns_client_t *client);
-static void ns_client_checkactive(ns_client_t *client);
static void client_start(isc_task_t *task, isc_event_t *event);
static void client_request(isc_task_t *task, isc_event_t *event);
static void ns_client_dumpmessage(ns_client_t *client, const char *reason);
+static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ dns_dispatch_t *disp, isc_boolean_t tcp);
void
ns_client_recursing(ns_client_t *client) {
REQUIRE(NS_CLIENT_VALID(client));
+ REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
- LOCK(&client->manager->lock);
- ISC_LIST_UNLINK(*client->list, client, link);
- ISC_LIST_APPEND(client->manager->recursing, client, link);
- client->list = &client->manager->recursing;
- UNLOCK(&client->manager->lock);
+ LOCK(&client->manager->reclock);
+ client->newstate = client->state = NS_CLIENTSTATE_RECURSING;
+ ISC_LIST_APPEND(client->manager->recursing, client, rlink);
+ UNLOCK(&client->manager->reclock);
}
void
@@ -231,15 +250,14 @@ ns_client_killoldestquery(ns_client_t *client) {
ns_client_t *oldest;
REQUIRE(NS_CLIENT_VALID(client));
- LOCK(&client->manager->lock);
+ LOCK(&client->manager->reclock);
oldest = ISC_LIST_HEAD(client->manager->recursing);
if (oldest != NULL) {
+ ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink);
+ UNLOCK(&client->manager->reclock);
ns_query_cancel(oldest);
- ISC_LIST_UNLINK(*oldest->list, oldest, link);
- ISC_LIST_APPEND(client->manager->active, oldest, link);
- oldest->list = &client->manager->active;
- }
- UNLOCK(&client->manager->lock);
+ } else
+ UNLOCK(&client->manager->reclock);
}
void
@@ -268,15 +286,16 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
*/
static isc_boolean_t
exit_check(ns_client_t *client) {
- ns_clientmgr_t *locked_manager = NULL;
- ns_clientmgr_t *destroy_manager = NULL;
+ isc_boolean_t destroy_manager = ISC_FALSE;
+ ns_clientmgr_t *manager = NULL;
REQUIRE(NS_CLIENT_VALID(client));
+ manager = client->manager;
if (client->state <= client->newstate)
return (ISC_FALSE); /* Business as usual. */
- INSIST(client->newstate < NS_CLIENTSTATE_WORKING);
+ INSIST(client->newstate < NS_CLIENTSTATE_RECURSING);
/*
* We need to detach from the view early when shutting down
@@ -293,13 +312,16 @@ exit_check(ns_client_t *client) {
client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL)
dns_view_detach(&client->view);
- if (client->state == NS_CLIENTSTATE_WORKING) {
+ if (client->state == NS_CLIENTSTATE_WORKING ||
+ client->state == NS_CLIENTSTATE_RECURSING)
+ {
INSIST(client->newstate <= NS_CLIENTSTATE_READING);
/*
* Let the update processing complete.
*/
if (client->nupdates > 0)
return (ISC_TRUE);
+
/*
* We are trying to abort request processing.
*/
@@ -322,23 +344,28 @@ exit_check(ns_client_t *client) {
*/
return (ISC_TRUE);
}
+
/*
* I/O cancel is complete. Burn down all state
* related to the current request. Ensure that
- * the client is on the active list and not the
- * recursing list.
+ * the client is no longer on the recursing list.
+ *
+ * We need to check whether the client is still linked,
+ * because it may already have been removed from the
+ * recursing list by ns_client_killoldestquery()
*/
- LOCK(&client->manager->lock);
- if (client->list == &client->manager->recursing) {
- ISC_LIST_UNLINK(*client->list, client, link);
- ISC_LIST_APPEND(client->manager->active, client, link);
- client->list = &client->manager->active;
+ if (client->state == NS_CLIENTSTATE_RECURSING) {
+ LOCK(&manager->reclock);
+ if (ISC_LINK_LINKED(client, rlink))
+ ISC_LIST_UNLINK(manager->recursing,
+ client, rlink);
+ UNLOCK(&manager->reclock);
}
- UNLOCK(&client->manager->lock);
ns_client_endrequest(client);
client->state = NS_CLIENTSTATE_READING;
INSIST(client->recursionquota == NULL);
+
if (NS_CLIENTSTATE_READING == client->newstate) {
client_read(client);
client->newstate = NS_CLIENTSTATE_MAX;
@@ -389,8 +416,27 @@ exit_check(ns_client_t *client) {
* or UDP request, but we may have enough clients doing
* that already. Check whether this client needs to remain
* active and force it to go inactive if not.
+ *
+ * UDP clients go inactive at this point, but TCP clients
+ * may remain active if we have fewer active TCP client
+ * objects than desired due to an earlier quota exhaustion.
*/
- ns_client_checkactive(client);
+ if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) {
+ LOCK(&client->interface->lock);
+ if (client->interface->ntcpcurrent <
+ client->interface->ntcptarget)
+ client->mortal = ISC_FALSE;
+ UNLOCK(&client->interface->lock);
+ }
+
+ /*
+ * We don't need the client; send it to the inactive
+ * queue for recycling.
+ */
+ if (client->mortal) {
+ if (client->newstate > NS_CLIENTSTATE_INACTIVE)
+ client->newstate = NS_CLIENTSTATE_INACTIVE;
+ }
if (NS_CLIENTSTATE_READY == client->newstate) {
if (TCP_CLIENT(client)) {
@@ -404,6 +450,7 @@ exit_check(ns_client_t *client) {
if (client->state == NS_CLIENTSTATE_READY) {
INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE);
+
/*
* We are trying to enter the inactive state.
*/
@@ -411,25 +458,22 @@ exit_check(ns_client_t *client) {
isc_socket_cancel(client->tcplistener, client->task,
ISC_SOCKCANCEL_ACCEPT);
- if (! (client->naccepts == 0)) {
- /* Still waiting for accept cancel completion. */
+ /* Still waiting for accept cancel completion. */
+ if (! (client->naccepts == 0))
return (ISC_TRUE);
- }
- /* Accept cancel is complete. */
+ /* Accept cancel is complete. */
if (client->nrecvs > 0)
isc_socket_cancel(client->udpsocket, client->task,
ISC_SOCKCANCEL_RECV);
- if (! (client->nrecvs == 0)) {
- /* Still waiting for recv cancel completion. */
+
+ /* Still waiting for recv cancel completion. */
+ if (! (client->nrecvs == 0))
return (ISC_TRUE);
- }
- /* Recv cancel is complete. */
- if (client->nctls > 0) {
- /* Still waiting for control event to be delivered */
+ /* Still waiting for control event to be delivered */
+ if (client->nctls > 0)
return (ISC_TRUE);
- }
/* Deactivate the client. */
if (client->interface)
@@ -449,7 +493,6 @@ exit_check(ns_client_t *client) {
client->attributes = 0;
client->mortal = ISC_FALSE;
- LOCK(&client->manager->lock);
/*
* Put the client on the inactive list. If we are aiming for
* the "freed" state, it will be removed from the inactive
@@ -457,18 +500,18 @@ exit_check(ns_client_t *client) {
* that has been done, lest the manager decide to reactivate
* the dying client inbetween.
*/
- locked_manager = client->manager;
- ISC_LIST_UNLINK(*client->list, client, link);
- ISC_LIST_APPEND(client->manager->inactive, client, link);
- client->list = &client->manager->inactive;
client->state = NS_CLIENTSTATE_INACTIVE;
INSIST(client->recursionquota == NULL);
if (client->state == client->newstate) {
client->newstate = NS_CLIENTSTATE_MAX;
+ if (!ns_g_clienttest && manager != NULL &&
+ !manager->exiting)
+ ISC_QUEUE_PUSH(manager->inactive, client,
+ ilink);
if (client->needshutdown)
isc_task_shutdown(client->task);
- goto unlock;
+ return (ISC_TRUE);
}
}
@@ -485,6 +528,7 @@ exit_check(ns_client_t *client) {
REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE);
INSIST(client->recursionquota == NULL);
+ INSIST(!ISC_QLINK_LINKED(client, ilink));
ns_query_free(client);
isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
@@ -493,27 +537,27 @@ exit_check(ns_client_t *client) {
isc_timer_detach(&client->timer);
if (client->tcpbuf != NULL)
- isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
+ isc_mem_put(client->mctx, client->tcpbuf,
+ TCP_BUFFER_SIZE);
if (client->opt != NULL) {
INSIST(dns_rdataset_isassociated(client->opt));
dns_rdataset_disassociate(client->opt);
- dns_message_puttemprdataset(client->message, &client->opt);
+ dns_message_puttemprdataset(client->message,
+ &client->opt);
}
+
dns_message_destroy(&client->message);
- if (client->manager != NULL) {
- ns_clientmgr_t *manager = client->manager;
- if (locked_manager == NULL) {
- LOCK(&manager->lock);
- locked_manager = manager;
- }
- ISC_LIST_UNLINK(*client->list, client, link);
- client->list = NULL;
+ if (manager != NULL) {
+ LOCK(&manager->listlock);
+ ISC_LIST_UNLINK(manager->clients, client, link);
+ LOCK(&manager->lock);
if (manager->exiting &&
- ISC_LIST_EMPTY(manager->active) &&
- ISC_LIST_EMPTY(manager->inactive) &&
- ISC_LIST_EMPTY(manager->recursing))
- destroy_manager = manager;
+ ISC_LIST_EMPTY(manager->clients))
+ destroy_manager = ISC_TRUE;
+ UNLOCK(&manager->lock);
+ UNLOCK(&manager->listlock);
}
+
/*
* Detaching the task must be done after unlinking from
* the manager's lists because the manager accesses
@@ -524,6 +568,7 @@ exit_check(ns_client_t *client) {
CTRACE("free");
client->magic = 0;
+
/*
* Check that there are no other external references to
* the memory context.
@@ -533,22 +578,10 @@ exit_check(ns_client_t *client) {
INSIST(0);
}
isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
-
- goto unlock;
- }
-
- unlock:
- if (locked_manager != NULL) {
- UNLOCK(&locked_manager->lock);
- locked_manager = NULL;
}
- /*
- * Only now is it safe to destroy the client manager (if needed),
- * because we have accessed its lock for the last time.
- */
- if (destroy_manager != NULL)
- clientmgr_destroy(destroy_manager);
+ if (destroy_manager && manager != NULL)
+ clientmgr_destroy(manager);
return (ISC_TRUE);
}
@@ -604,6 +637,9 @@ client_shutdown(isc_task_t *task, isc_event_t *event) {
client->shutdown_arg = NULL;
}
+ if (ISC_QLINK_LINKED(client, ilink))
+ ISC_QUEUE_UNLINK(client->manager->inactive, client, ilink);
+
client->newstate = NS_CLIENTSTATE_FREED;
client->needshutdown = ISC_FALSE;
(void)exit_check(client);
@@ -616,7 +652,8 @@ ns_client_endrequest(ns_client_t *client) {
INSIST(client->nsends == 0);
INSIST(client->nrecvs == 0);
INSIST(client->nupdates == 0);
- INSIST(client->state == NS_CLIENTSTATE_WORKING);
+ INSIST(client->state == NS_CLIENTSTATE_WORKING ||
+ client->state == NS_CLIENTSTATE_RECURSING);
CTRACE("endrequest");
@@ -649,46 +686,13 @@ ns_client_endrequest(ns_client_t *client) {
client->attributes &= NS_CLIENTATTR_TCP;
}
-static void
-ns_client_checkactive(ns_client_t *client) {
- if (client->mortal) {
- /*
- * This client object should normally go inactive
- * at this point, but if we have fewer active client
- * objects than desired due to earlier quota exhaustion,
- * keep it active to make up for the shortage.
- */
- isc_boolean_t need_another_client = ISC_FALSE;
- if (TCP_CLIENT(client) && !ns_g_clienttest) {
- LOCK(&client->interface->lock);
- if (client->interface->ntcpcurrent <
- client->interface->ntcptarget)
- need_another_client = ISC_TRUE;
- UNLOCK(&client->interface->lock);
- } else {
- /*
- * The UDP client quota is enforced by making
- * requests fail rather than by not listening
- * for new ones. Therefore, there is always a
- * full set of UDP clients listening.
- */
- }
- if (! need_another_client) {
- /*
- * We don't need this client object. Recycle it.
- */
- if (client->newstate >= NS_CLIENTSTATE_INACTIVE)
- client->newstate = NS_CLIENTSTATE_INACTIVE;
- }
- }
-}
-
void
ns_client_next(ns_client_t *client, isc_result_t result) {
int newstate;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
+ client->state == NS_CLIENTSTATE_RECURSING ||
client->state == NS_CLIENTSTATE_READING);
CTRACE("next");
@@ -745,9 +749,6 @@ client_senddone(isc_task_t *task, isc_event_t *event) {
client->tcpbuf = NULL;
}
- if (exit_check(client))
- return;
-
ns_client_next(client, ISC_R_SUCCESS);
}
@@ -1974,6 +1975,11 @@ static isc_result_t
get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) {
isc_mem_t *clientmctx;
isc_result_t result;
+#if NMCTXS > 0
+ unsigned int nextmctx;
+#endif
+
+ MTRACE("clientmctx");
/*
* Caller must be holding the manager lock.
@@ -1985,19 +1991,21 @@ get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) {
return (result);
}
#if NMCTXS > 0
- INSIST(manager->nextmctx < NMCTXS);
- clientmctx = manager->mctxpool[manager->nextmctx];
+ nextmctx = manager->nextmctx++;
+ if (manager->nextmctx == NMCTXS)
+ manager->nextmctx = 0;
+
+ INSIST(nextmctx < NMCTXS);
+
+ clientmctx = manager->mctxpool[nextmctx];
if (clientmctx == NULL) {
result = isc_mem_create(0, 0, &clientmctx);
if (result != ISC_R_SUCCESS)
return (result);
isc_mem_setname(clientmctx, "client", NULL);
- manager->mctxpool[manager->nextmctx] = clientmctx;
+ manager->mctxpool[nextmctx] = clientmctx;
}
- manager->nextmctx++;
- if (manager->nextmctx == NMCTXS)
- manager->nextmctx = 0;
#else
clientmctx = manager->mctx;
#endif
@@ -2118,6 +2126,8 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
#ifdef ALLOW_FILTER_AAAA_ON_V4
client->filter_aaaa = dns_v4_aaaa_ok;
#endif
+ client->needshutdown = ns_g_clienttest;
+
ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL,
NS_EVENT_CLIENTCONTROL, client_start, client, client,
NULL, NULL);
@@ -2129,7 +2139,8 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
client->formerrcache.time = 0;
client->formerrcache.id = 0;
ISC_LINK_INIT(client, link);
- client->list = NULL;
+ ISC_LINK_INIT(client, rlink);
+ ISC_QLINK_INIT(client, ilink);
/*
* We call the init routines for the various kinds of client here,
@@ -2144,8 +2155,6 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
if (result != ISC_R_SUCCESS)
goto cleanup_query;
- client->needshutdown = ns_g_clienttest;
-
CTRACE("create");
*clientp = client;
@@ -2410,10 +2419,8 @@ ns_client_replace(ns_client_t *client) {
REQUIRE(client != NULL);
REQUIRE(client->manager != NULL);
- result = ns_clientmgr_createclients(client->manager,
- 1, client->interface,
- (TCP_CLIENT(client) ?
- ISC_TRUE : ISC_FALSE));
+ result = get_client(client->manager, client->interface,
+ client->dispatch, TCP_CLIENT(client));
if (result != ISC_R_SUCCESS)
return (result);
@@ -2437,9 +2444,7 @@ clientmgr_destroy(ns_clientmgr_t *manager) {
int i;
#endif
- REQUIRE(ISC_LIST_EMPTY(manager->active));
- REQUIRE(ISC_LIST_EMPTY(manager->inactive));
- REQUIRE(ISC_LIST_EMPTY(manager->recursing));
+ REQUIRE(ISC_LIST_EMPTY(manager->clients));
MTRACE("clientmgr_destroy");
@@ -2450,7 +2455,10 @@ clientmgr_destroy(ns_clientmgr_t *manager) {
}
#endif
+ ISC_QUEUE_DESTROY(manager->inactive);
DESTROYLOCK(&manager->lock);
+ DESTROYLOCK(&manager->listlock);
+ DESTROYLOCK(&manager->reclock);
manager->magic = 0;
isc_mem_put(manager->mctx, manager, sizeof(*manager));
}
@@ -2473,13 +2481,21 @@ ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
if (result != ISC_R_SUCCESS)
goto cleanup_manager;
+ result = isc_mutex_init(&manager->listlock);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_lock;
+
+ result = isc_mutex_init(&manager->reclock);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_listlock;
+
manager->mctx = mctx;
manager->taskmgr = taskmgr;
manager->timermgr = timermgr;
manager->exiting = ISC_FALSE;
- ISC_LIST_INIT(manager->active);
- ISC_LIST_INIT(manager->inactive);
+ ISC_LIST_INIT(manager->clients);
ISC_LIST_INIT(manager->recursing);
+ ISC_QUEUE_INIT(manager->inactive, ilink);
#if NMCTXS > 0
manager->nextmctx = 0;
for (i = 0; i < NMCTXS; i++)
@@ -2493,6 +2509,12 @@ ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
return (ISC_R_SUCCESS);
+ cleanup_listlock:
+ (void) isc_mutex_destroy(&manager->listlock);
+
+ cleanup_lock:
+ (void) isc_mutex_destroy(&manager->lock);
+
cleanup_manager:
isc_mem_put(manager->mctx, manager, sizeof(*manager));
@@ -2501,9 +2523,10 @@ ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
void
ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
+ isc_result_t result;
ns_clientmgr_t *manager;
ns_client_t *client;
- isc_boolean_t need_destroy = ISC_FALSE;
+ isc_boolean_t need_destroy = ISC_FALSE, unlock = ISC_FALSE;
REQUIRE(managerp != NULL);
manager = *managerp;
@@ -2511,31 +2534,27 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
MTRACE("destroy");
- LOCK(&manager->lock);
+ /*
+ * Check for success because we may already be task-exclusive
+ * at this point. Only if we succeed at obtaining an exclusive
+ * lock now will we need to relinquish it later.
+ */
+ result = isc_task_beginexclusive(ns_g_server->task);
+ if (result == ISC_R_SUCCESS)
+ unlock = ISC_TRUE;
manager->exiting = ISC_TRUE;
- for (client = ISC_LIST_HEAD(manager->recursing);
- client != NULL;
- client = ISC_LIST_NEXT(client, link))
- isc_task_shutdown(client->task);
-
- for (client = ISC_LIST_HEAD(manager->active);
- client != NULL;
- client = ISC_LIST_NEXT(client, link))
- isc_task_shutdown(client->task);
-
- for (client = ISC_LIST_HEAD(manager->inactive);
+ for (client = ISC_LIST_HEAD(manager->clients);
client != NULL;
client = ISC_LIST_NEXT(client, link))
isc_task_shutdown(client->task);
- if (ISC_LIST_EMPTY(manager->active) &&
- ISC_LIST_EMPTY(manager->inactive) &&
- ISC_LIST_EMPTY(manager->recursing))
+ if (ISC_LIST_EMPTY(manager->clients))
need_destroy = ISC_TRUE;
- UNLOCK(&manager->lock);
+ if (unlock)
+ isc_task_endexclusive(ns_g_server->task);
if (need_destroy)
clientmgr_destroy(manager);
@@ -2543,81 +2562,86 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
*managerp = NULL;
}
-isc_result_t
-ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
- ns_interface_t *ifp, isc_boolean_t tcp)
+static isc_result_t
+get_client(ns_clientmgr_t *manager, ns_interface_t *ifp,
+ dns_dispatch_t *disp, isc_boolean_t tcp)
{
isc_result_t result = ISC_R_SUCCESS;
- unsigned int i;
+ isc_event_t *ev;
ns_client_t *client;
+ MTRACE("get client");
- REQUIRE(VALID_MANAGER(manager));
- REQUIRE(n > 0);
+ REQUIRE(manager != NULL);
- MTRACE("createclients");
+ if (manager->exiting)
+ return (ISC_R_SHUTTINGDOWN);
/*
- * We MUST lock the manager lock for the entire client creation
- * process. If we didn't do this, then a client could get a
- * shutdown event and disappear out from under us.
+ * Allocate a client. First try to get a recycled one;
+ * if that fails, make a new one.
*/
+ client = NULL;
+ if (!ns_g_clienttest)
+ ISC_QUEUE_POP(manager->inactive, ilink, client);
- LOCK(&manager->lock);
+ if (client != NULL)
+ MTRACE("recycle");
+ else {
+ MTRACE("create new");
- for (i = 0; i < n; i++) {
- isc_event_t *ev;
- /*
- * Allocate a client. First try to get a recycled one;
- * if that fails, make a new one.
- */
- client = NULL;
- if (!ns_g_clienttest)
- client = ISC_LIST_HEAD(manager->inactive);
- if (client != NULL) {
- MTRACE("recycle");
- ISC_LIST_UNLINK(manager->inactive, client, link);
- client->list = NULL;
- } else {
- MTRACE("create new");
- result = client_create(manager, &client);
- if (result != ISC_R_SUCCESS)
- break;
- }
+ LOCK(&manager->lock);
+ result = client_create(manager, &client);
+ UNLOCK(&manager->lock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
- ns_interface_attach(ifp, &client->interface);
- client->state = NS_CLIENTSTATE_READY;
- INSIST(client->recursionquota == NULL);
+ LOCK(&manager->listlock);
+ ISC_LIST_APPEND(manager->clients, client, link);
+ UNLOCK(&manager->listlock);
+ }
- if (tcp) {
- client->attributes |= NS_CLIENTATTR_TCP;
- isc_socket_attach(ifp->tcpsocket,
- &client->tcplistener);
- } else {
- isc_socket_t *sock;
+ client->manager = manager;
+ ns_interface_attach(ifp, &client->interface);
+ client->state = NS_CLIENTSTATE_READY;
+ INSIST(client->recursionquota == NULL);
- dns_dispatch_attach(ifp->udpdispatch,
- &client->dispatch);
- sock = dns_dispatch_getsocket(client->dispatch);
- isc_socket_attach(sock, &client->udpsocket);
- }
- client->manager = manager;
- ISC_LIST_APPEND(manager->active, client, link);
- client->list = &manager->active;
+ if (tcp) {
+ client->attributes |= NS_CLIENTATTR_TCP;
+ isc_socket_attach(ifp->tcpsocket,
+ &client->tcplistener);
+ } else {
+ isc_socket_t *sock;
- INSIST(client->nctls == 0);
- client->nctls++;
- ev = &client->ctlevent;
- isc_task_send(client->task, &ev);
- }
- if (i != 0) {
- /*
- * We managed to create at least one client, so we
- * declare victory.
- */
- result = ISC_R_SUCCESS;
+ dns_dispatch_attach(disp, &client->dispatch);
+ sock = dns_dispatch_getsocket(client->dispatch);
+ isc_socket_attach(sock, &client->udpsocket);
}
- UNLOCK(&manager->lock);
+ INSIST(client->nctls == 0);
+ client->nctls++;
+ ev = &client->ctlevent;
+ isc_task_send(client->task, &ev);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
+ ns_interface_t *ifp, isc_boolean_t tcp)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned int disp;
+
+ REQUIRE(VALID_MANAGER(manager));
+ REQUIRE(n > 0);
+
+ MTRACE("createclients");
+
+ for (disp = 0; disp < n; disp++) {
+ result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
return (result);
}
@@ -2702,19 +2726,41 @@ ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
{
char msgbuf[2048];
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
- const char *name = "";
- const char *sep = "";
+ char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE];
+ const char *viewname = "";
+ const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = "";
+ const char *signer = "", *qname = "";
+ dns_name_t *q = NULL;
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
+
ns_client_name(client, peerbuf, sizeof(peerbuf));
+
+ if (client->signer != NULL) {
+ dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
+ sep1 = "/key ";
+ signer = signerbuf;
+ }
+
+ q = client->query.origqname != NULL
+ ? client->query.origqname : client->query.qname;
+ if (q != NULL) {
+ dns_name_format(q, qnamebuf, sizeof(qnamebuf));
+ sep2 = " (";
+ sep3 = ")";
+ qname = qnamebuf;
+ }
+
if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
strcmp(client->view->name, "_default") != 0) {
- name = client->view->name;
- sep = ": view ";
+ sep4 = ": view ";
+ viewname = client->view->name;
}
isc_log_write(ns_g_lctx, category, module, level,
- "client %s%s%s: %s", peerbuf, sep, name, msgbuf);
+ "client %s%s%s%s%s%s%s%s: %s",
+ peerbuf, sep1, signer, sep2, qname, sep3,
+ sep4, viewname, msgbuf);
}
void
@@ -2796,9 +2842,11 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
REQUIRE(VALID_MANAGER(manager));
- LOCK(&manager->lock);
+ LOCK(&manager->reclock);
client = ISC_LIST_HEAD(manager->recursing);
while (client != NULL) {
+ INSIST(client->state == NS_CLIENTSTATE_RECURSING);
+
ns_client_name(client, peerbuf, sizeof(peerbuf));
if (client->view != NULL &&
strcmp(client->view->name, "_bind") != 0 &&
@@ -2809,6 +2857,9 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
name = "";
sep = "";
}
+
+ LOCK(&client->query.fetchlock);
+ INSIST(client->query.qname != NULL);
dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
if (client->query.qname != client->query.origqname &&
client->query.origqname != NULL) {
@@ -2831,20 +2882,19 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
strcpy(typebuf, "-");
strcpy(classbuf, "-");
}
+ UNLOCK(&client->query.fetchlock);
fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s "
"requesttime %d\n", peerbuf, sep, name,
client->message->id, namebuf, typebuf, classbuf,
origfor, original, client->requesttime);
- client = ISC_LIST_NEXT(client, link);
+ client = ISC_LIST_NEXT(client, rlink);
}
- UNLOCK(&manager->lock);
+ UNLOCK(&manager->reclock);
}
void
ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
-
- if (client->manager != NULL)
- LOCK(&client->manager->lock);
+ LOCK(&client->query.fetchlock);
if (client->query.restarts > 0) {
/*
* client->query.qname was dynamically allocated.
@@ -2853,6 +2903,16 @@ ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
&client->query.qname);
}
client->query.qname = name;
- if (client->manager != NULL)
- UNLOCK(&client->manager->lock);
+ UNLOCK(&client->query.fetchlock);
+}
+
+isc_result_t
+ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) {
+ ns_client_t *client = (ns_client_t *) ci->data;
+
+ REQUIRE(NS_CLIENT_VALID(client));
+ REQUIRE(addrp != NULL);
+
+ *addrp = &client->peeraddr;
+ return (ISC_R_SUCCESS);
}
diff --git a/contrib/bind9/bin/named/config.c b/contrib/bind9/bin/named/config.c
index 25ebac4..fa349ee 100644
--- a/contrib/bind9/bin/named/config.c
+++ b/contrib/bind9/bin/named/config.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: config.c,v 1.113.16.2 2011/02/28 01:19:58 tbox Exp $ */
+/* $Id: config.c,v 1.123 2012/01/06 23:46:41 tbox Exp $ */
/*! \file */
@@ -73,6 +73,7 @@ options {\n\
listen-on {any;};\n\
listen-on-v6 {none;};\n\
match-mapped-addresses no;\n\
+ max-rsa-exponent-size 0; /* no limit */\n\
memstatistics-file \"named.memstats\";\n\
multiple-cnames no;\n\
# named-xfer <obsolete>;\n\
@@ -90,7 +91,7 @@ options {\n\
"\
recursive-clients 1000;\n\
resolver-query-timeout 10;\n\
- rrset-order {type NS order random; order cyclic; };\n\
+ rrset-order { order random; };\n\
serial-queries 20;\n\
serial-query-rate 20;\n\
server-id none;\n\
@@ -200,7 +201,8 @@ options {\n\
sig-signing-nodes 100;\n\
sig-signing-signatures 10;\n\
sig-signing-type 65534;\n\
- zone-statistics false;\n\
+ inline-signing no;\n\
+ zone-statistics terse;\n\
max-journal-size unlimited;\n\
ixfr-from-differences false;\n\
check-wildcard yes;\n\
@@ -210,7 +212,10 @@ options {\n\
check-srv-cname warn;\n\
zero-no-soa-ttl yes;\n\
update-check-ksk yes;\n\
+ serial-update-method increment;\n\
+ dnssec-update-mode maintain;\n\
dnssec-dnskey-kskonly no;\n\
+ dnssec-loadkeys-interval 60;\n\
try-tcp-refresh yes; /* BIND 8 compat */\n\
};\n\
"
@@ -292,7 +297,8 @@ ns_checknames_get(const cfg_obj_t **maps, const char *which,
if (maps[i] == NULL)
return (ISC_R_NOTFOUND);
checknames = NULL;
- if (cfg_map_get(maps[i], "check-names", &checknames) == ISC_R_SUCCESS) {
+ if (cfg_map_get(maps[i], "check-names",
+ &checknames) == ISC_R_SUCCESS) {
/*
* Zone map entry is not a list.
*/
@@ -305,7 +311,8 @@ ns_checknames_get(const cfg_obj_t **maps, const char *which,
element = cfg_list_next(element)) {
value = cfg_listelt_value(element);
type = cfg_tuple_get(value, "type");
- if (strcasecmp(cfg_obj_asstring(type), which) == 0) {
+ if (strcasecmp(cfg_obj_asstring(type),
+ which) == 0) {
*obj = cfg_tuple_get(value, "mode");
return (ISC_R_SUCCESS);
}
@@ -378,6 +385,8 @@ ns_config_getzonetype(const cfg_obj_t *zonetypeobj) {
ztype = dns_zone_stub;
else if (strcasecmp(str, "static-stub") == 0)
ztype = dns_zone_staticstub;
+ else if (strcasecmp(str, "redirect") == 0)
+ ztype = dns_zone_redirect;
else
INSIST(0);
return (ztype);
diff --git a/contrib/bind9/bin/named/control.c b/contrib/bind9/bin/named/control.c
index 2a1a5a8..fabe442 100644
--- a/contrib/bind9/bin/named/control.c
+++ b/contrib/bind9/bin/named/control.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: control.c,v 1.41 2010/12/03 22:05:19 each Exp $ */
+/* $Id$ */
/*! \file */
@@ -154,7 +154,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
} else if (command_compare(command, NS_COMMAND_DUMPSTATS)) {
result = ns_server_dumpstats(ns_g_server);
} else if (command_compare(command, NS_COMMAND_QUERYLOG)) {
- result = ns_server_togglequerylog(ns_g_server);
+ result = ns_server_togglequerylog(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_DUMPDB)) {
ns_server_dumpdb(ns_g_server, command);
result = ISC_R_SUCCESS;
@@ -169,7 +169,9 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
} else if (command_compare(command, NS_COMMAND_FLUSH)) {
result = ns_server_flushcache(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_FLUSHNAME)) {
- result = ns_server_flushname(ns_g_server, command);
+ result = ns_server_flushnode(ns_g_server, command, ISC_FALSE);
+ } else if (command_compare(command, NS_COMMAND_FLUSHTREE)) {
+ result = ns_server_flushnode(ns_g_server, command, ISC_TRUE);
} else if (command_compare(command, NS_COMMAND_STATUS)) {
result = ns_server_status(ns_g_server, text);
} else if (command_compare(command, NS_COMMAND_TSIGLIST)) {
@@ -183,6 +185,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
command_compare(command, NS_COMMAND_THAW)) {
result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
text);
+ } else if (command_compare(command, NS_COMMAND_SYNC)) {
+ result = ns_server_sync(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_RECURSING)) {
result = ns_server_dumprecursing(ns_g_server);
} else if (command_compare(command, NS_COMMAND_TIMERPOKE)) {
@@ -201,6 +205,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
result = ns_server_add_zone(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_DELZONE)) {
result = ns_server_del_zone(ns_g_server, command);
+ } else if (command_compare(command, NS_COMMAND_SIGNING)) {
+ result = ns_server_signing(ns_g_server, command, text);
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
diff --git a/contrib/bind9/bin/named/controlconf.c b/contrib/bind9/bin/named/controlconf.c
index 73c0f37..c46a6e1 100644
--- a/contrib/bind9/bin/named/controlconf.c
+++ b/contrib/bind9/bin/named/controlconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: controlconf.c,v 1.60.544.3 2011/12/22 08:10:09 marka Exp $ */
+/* $Id: controlconf.c,v 1.63 2011/12/22 08:07:48 marka Exp $ */
/*! \file */
diff --git a/contrib/bind9/bin/named/include/dlz/dlz_dlopen_driver.h b/contrib/bind9/bin/named/include/dlz/dlz_dlopen_driver.h
index 7af325a..602b3c0 100644
--- a/contrib/bind9/bin/named/include/dlz/dlz_dlopen_driver.h
+++ b/contrib/bind9/bin/named/include/dlz/dlz_dlopen_driver.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dlz_dlopen_driver.h,v 1.1.4.4 2011/03/17 09:41:06 fdupont Exp $ */
+/* $Id: dlz_dlopen_driver.h,v 1.4 2011/03/17 09:25:53 fdupont Exp $ */
#ifndef DLZ_DLOPEN_DRIVER_H
#define DLZ_DLOPEN_DRIVER_H
diff --git a/contrib/bind9/bin/named/include/named/client.h b/contrib/bind9/bin/named/include/named/client.h
index e6414d2..98e79df 100644
--- a/contrib/bind9/bin/named/include/named/client.h
+++ b/contrib/bind9/bin/named/include/named/client.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.h,v 1.91.278.2 2012/01/31 23:46:39 tbox Exp $ */
+/* $Id$ */
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
@@ -66,7 +66,9 @@
#include <isc/magic.h>
#include <isc/stdtime.h>
#include <isc/quota.h>
+#include <isc/queue.h>
+#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
@@ -81,8 +83,6 @@
*** Types
***/
-typedef ISC_LIST(ns_client_t) client_list_t;
-
/*% nameserver client structure */
struct ns_client {
unsigned int magic;
@@ -155,13 +155,15 @@ struct ns_client {
isc_stdtime_t time;
dns_messageid_t id;
} formerrcache;
+
ISC_LINK(ns_client_t) link;
- /*%
- * The list 'link' is part of, or NULL if not on any list.
- */
- client_list_t *list;
+ ISC_LINK(ns_client_t) rlink;
+ ISC_QLINK(ns_client_t) ilink;
};
+typedef ISC_QUEUE(ns_client_t) client_queue_t;
+typedef ISC_LIST(ns_client_t) client_list_t;
+
#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c')
#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
@@ -379,4 +381,7 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
* Isself callback.
*/
+isc_result_t
+ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp);
+
#endif /* NAMED_CLIENT_H */
diff --git a/contrib/bind9/bin/named/include/named/control.h b/contrib/bind9/bin/named/include/named/control.h
index 24e5909..d730a83 100644
--- a/contrib/bind9/bin/named/include/named/control.h
+++ b/contrib/bind9/bin/named/include/named/control.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: control.h,v 1.31 2010/08/16 22:21:06 marka Exp $ */
+/* $Id$ */
#ifndef NAMED_CONTROL_H
#define NAMED_CONTROL_H 1
@@ -47,6 +47,7 @@
#define NS_COMMAND_NOTRACE "notrace"
#define NS_COMMAND_FLUSH "flush"
#define NS_COMMAND_FLUSHNAME "flushname"
+#define NS_COMMAND_FLUSHTREE "flushtree"
#define NS_COMMAND_STATUS "status"
#define NS_COMMAND_TSIGLIST "tsig-list"
#define NS_COMMAND_TSIGDELETE "tsig-delete"
@@ -62,6 +63,8 @@
#define NS_COMMAND_LOADKEYS "loadkeys"
#define NS_COMMAND_ADDZONE "addzone"
#define NS_COMMAND_DELZONE "delzone"
+#define NS_COMMAND_SYNC "sync"
+#define NS_COMMAND_SIGNING "signing"
isc_result_t
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
diff --git a/contrib/bind9/bin/named/include/named/globals.h b/contrib/bind9/bin/named/include/named/globals.h
index 39307f3..cbc14d8 100644
--- a/contrib/bind9/bin/named/include/named/globals.h
+++ b/contrib/bind9/bin/named/include/named/globals.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: globals.h,v 1.89.54.2 2011/06/17 23:47:10 tbox Exp $ */
+/* $Id: globals.h,v 1.92 2011/11/09 18:44:04 each Exp $ */
#ifndef NAMED_GLOBALS_H
#define NAMED_GLOBALS_H 1
@@ -51,6 +51,7 @@
EXTERN isc_mem_t * ns_g_mctx INIT(NULL);
EXTERN unsigned int ns_g_cpus INIT(0);
+EXTERN unsigned int ns_g_udpdisp INIT(0);
EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL);
EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL);
EXTERN isc_entropy_t * ns_g_entropy INIT(NULL);
diff --git a/contrib/bind9/bin/named/include/named/interfacemgr.h b/contrib/bind9/bin/named/include/named/interfacemgr.h
index 2724c39..380dbed 100644
--- a/contrib/bind9/bin/named/include/named/interfacemgr.h
+++ b/contrib/bind9/bin/named/include/named/interfacemgr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfacemgr.h,v 1.33 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: interfacemgr.h,v 1.35 2011/07/28 23:47:58 tbox Exp $ */
#ifndef NAMED_INTERFACEMGR_H
#define NAMED_INTERFACEMGR_H 1
@@ -65,7 +65,8 @@
#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC)
#define NS_INTERFACEFLAG_ANYADDR 0x01U /*%< bound to "any" address */
-
+#define MAX_UDP_DISPATCH 128 /*%< Maximum number of UDP dispatchers
+ to start per interface */
/*% The nameserver interface structure */
struct ns_interface {
unsigned int magic; /*%< Magic number. */
@@ -76,11 +77,13 @@ struct ns_interface {
isc_sockaddr_t addr; /*%< Address and port. */
unsigned int flags; /*%< Interface characteristics */
char name[32]; /*%< Null terminated. */
- dns_dispatch_t * udpdispatch; /*%< UDP dispatcher. */
+ dns_dispatch_t * udpdispatch[MAX_UDP_DISPATCH];
+ /*%< UDP dispatchers. */
isc_socket_t * tcpsocket; /*%< TCP socket. */
int ntcptarget; /*%< Desired number of concurrent
TCP accepts */
int ntcpcurrent; /*%< Current ditto, locked */
+ int nudpdispatch; /*%< Number of UDP dispatches */
ns_clientmgr_t * clientmgr; /*%< Client manager. */
ISC_LINK(ns_interface_t) link;
};
diff --git a/contrib/bind9/bin/named/include/named/server.h b/contrib/bind9/bin/named/include/named/server.h
index 9982e88..3ba0c64 100644
--- a/contrib/bind9/bin/named/include/named/server.h
+++ b/contrib/bind9/bin/named/include/named/server.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.h,v 1.110 2010/08/16 23:46:52 tbox Exp $ */
+/* $Id$ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
@@ -230,9 +230,10 @@ ns_server_retransfercommand(ns_server_t *server, char *args);
*/
isc_result_t
-ns_server_togglequerylog(ns_server_t *server);
+ns_server_togglequerylog(ns_server_t *server, char *args);
/*%<
- * Toggle logging of queries, as in BIND 8.
+ * Enable/disable logging of queries. (Takes "yes" or "no" argument,
+ * but can also be used as a toggle for backward comptibility.)
*/
/*%
@@ -266,10 +267,12 @@ isc_result_t
ns_server_flushcache(ns_server_t *server, char *args);
/*%
- * Flush a particular name from the server's cache(s)
+ * Flush a particular name from the server's cache. If 'tree' is false,
+ * also flush the name from the ADB and badcache. If 'tree' is true, also
+ * flush all the names under the specified name.
*/
isc_result_t
-ns_server_flushname(ns_server_t *server, char *args);
+ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree);
/*%
* Report the server's status.
@@ -297,6 +300,12 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
isc_buffer_t *text);
/*%
+ * Dump zone updates to disk, optionally removing the journal file
+ */
+isc_result_t
+ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text);
+
+/*%
* Update a zone's DNSKEY set from the key repository. If
* the command that triggered the call to this function was "sign",
* then force a full signing of the zone. If it was "loadkeys",
@@ -336,4 +345,9 @@ ns_server_add_zone(ns_server_t *server, char *args);
isc_result_t
ns_server_del_zone(ns_server_t *server, char *args);
+/*%
+ * Lists the status of the signing records for a given zone.
+ */
+isc_result_t
+ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text);
#endif /* NAMED_SERVER_H */
diff --git a/contrib/bind9/bin/named/include/named/zoneconf.h b/contrib/bind9/bin/named/include/named/zoneconf.h
index ebaad68..0e684d2 100644
--- a/contrib/bind9/bin/named/include/named/zoneconf.h
+++ b/contrib/bind9/bin/named/include/named/zoneconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.h,v 1.28 2010/12/20 23:47:20 tbox Exp $ */
+/* $Id: zoneconf.h,v 1.30 2011/08/30 23:46:51 tbox Exp $ */
#ifndef NS_ZONECONF_H
#define NS_ZONECONF_H 1
@@ -33,7 +33,7 @@ ISC_LANG_BEGINDECLS
isc_result_t
ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
- dns_zone_t *zone);
+ dns_zone_t *zone, dns_zone_t *raw);
/*%<
* Configure or reconfigure a zone according to the named.conf
* data in 'cctx' and 'czone'.
diff --git a/contrib/bind9/bin/named/interfacemgr.c b/contrib/bind9/bin/named/interfacemgr.c
index 15ffe00..84bf21d 100644
--- a/contrib/bind9/bin/named/interfacemgr.c
+++ b/contrib/bind9/bin/named/interfacemgr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,13 +15,14 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: interfacemgr.c,v 1.95.426.2 2011/03/12 04:59:14 tbox Exp $ */
+/* $Id: interfacemgr.c,v 1.101 2011/11/09 18:44:03 each Exp $ */
/*! \file */
#include <config.h>
#include <isc/interfaceiter.h>
+#include <isc/os.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/util.h>
@@ -185,11 +186,14 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
{
ns_interface_t *ifp;
isc_result_t result;
+ int disp;
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
+
ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));
if (ifp == NULL)
return (ISC_R_NOMEMORY);
+
ifp->mgr = NULL;
ifp->generation = mgr->generation;
ifp->addr = *addr;
@@ -212,9 +216,11 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
goto clientmgr_create_failure;
}
- ifp->udpdispatch = NULL;
+ for (disp = 0; disp < MAX_UDP_DISPATCH; disp++)
+ ifp->udpdispatch[disp] = NULL;
ifp->tcpsocket = NULL;
+
/*
* Create a single TCP client object. It will replace itself
* with a new one as soon as it gets a connection, so the actual
@@ -223,6 +229,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
*/
ifp->ntcptarget = 1;
ifp->ntcpcurrent = 0;
+ ifp->nudpdispatch = 0;
ISC_LINK_INIT(ifp, link);
@@ -237,6 +244,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
clientmgr_create_failure:
DESTROYLOCK(&ifp->lock);
+
lock_create_failure:
ifp->magic = 0;
isc_mem_put(mgr->mctx, ifp, sizeof(*ifp));
@@ -249,6 +257,7 @@ ns_interface_listenudp(ns_interface_t *ifp) {
isc_result_t result;
unsigned int attrs;
unsigned int attrmask;
+ int disp, i;
attrs = 0;
attrs |= DNS_DISPATCHATTR_UDP;
@@ -260,18 +269,28 @@ ns_interface_listenudp(ns_interface_t *ifp) {
attrmask = 0;
attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;
attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
- result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr,
- ns_g_taskmgr, &ifp->addr,
- 4096, 1000, 32768, 8219, 8237,
- attrs, attrmask, &ifp->udpdispatch);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
- "could not listen on UDP socket: %s",
- isc_result_totext(result));
- goto udp_dispatch_failure;
+
+ ifp->nudpdispatch = ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
+ for (disp = 0; disp < ifp->nudpdispatch; disp++) {
+ result = dns_dispatch_getudp_dup(ifp->mgr->dispatchmgr,
+ ns_g_socketmgr,
+ ns_g_taskmgr, &ifp->addr,
+ 4096, 1000, 32768, 8219, 8237,
+ attrs, attrmask,
+ &ifp->udpdispatch[disp],
+ disp == 0
+ ? NULL
+ : ifp->udpdispatch[0]);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
+ "could not listen on UDP socket: %s",
+ isc_result_totext(result));
+ goto udp_dispatch_failure;
+ }
+
}
- result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus,
+ result = ns_clientmgr_createclients(ifp->clientmgr, ifp->nudpdispatch,
ifp, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -279,12 +298,17 @@ ns_interface_listenudp(ns_interface_t *ifp) {
isc_result_totext(result));
goto addtodispatch_failure;
}
+
return (ISC_R_SUCCESS);
addtodispatch_failure:
- dns_dispatch_changeattributes(ifp->udpdispatch, 0,
- DNS_DISPATCHATTR_NOLISTEN);
- dns_dispatch_detach(&ifp->udpdispatch);
+ for (i = disp - 1; i <= 0; i--) {
+ dns_dispatch_changeattributes(ifp->udpdispatch[i], 0,
+ DNS_DISPATCHATTR_NOLISTEN);
+ dns_dispatch_detach(&(ifp->udpdispatch[i]));
+ }
+ ifp->nudpdispatch = 0;
+
udp_dispatch_failure:
return (result);
}
@@ -398,15 +422,19 @@ ns_interface_shutdown(ns_interface_t *ifp) {
static void
ns_interface_destroy(ns_interface_t *ifp) {
isc_mem_t *mctx = ifp->mgr->mctx;
+ int disp;
+
REQUIRE(NS_INTERFACE_VALID(ifp));
ns_interface_shutdown(ifp);
- if (ifp->udpdispatch != NULL) {
- dns_dispatch_changeattributes(ifp->udpdispatch, 0,
- DNS_DISPATCHATTR_NOLISTEN);
- dns_dispatch_detach(&ifp->udpdispatch);
- }
+ for (disp = 0; disp < ifp->nudpdispatch; disp++)
+ if (ifp->udpdispatch[disp] != NULL) {
+ dns_dispatch_changeattributes(ifp->udpdispatch[disp], 0,
+ DNS_DISPATCHATTR_NOLISTEN);
+ dns_dispatch_detach(&(ifp->udpdispatch[disp]));
+ }
+
if (ifp->tcpsocket != NULL)
isc_socket_detach(&ifp->tcpsocket);
diff --git a/contrib/bind9/bin/named/logconf.c b/contrib/bind9/bin/named/logconf.c
index f02b97f..b99a167 100644
--- a/contrib/bind9/bin/named/logconf.c
+++ b/contrib/bind9/bin/named/logconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: logconf.c,v 1.42.816.3 2011/03/05 23:52:06 tbox Exp $ */
+/* $Id: logconf.c,v 1.45 2011/03/05 23:52:29 tbox Exp $ */
/*! \file */
diff --git a/contrib/bind9/bin/named/main.c b/contrib/bind9/bin/named/main.c
index f6c929e..a546724 100644
--- a/contrib/bind9/bin/named/main.c
+++ b/contrib/bind9/bin/named/main.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: main.c,v 1.180.14.4 2011/11/05 00:45:52 each Exp $ */
+/* $Id$ */
/*! \file */
@@ -418,7 +418,7 @@ parse_command_line(int argc, char *argv[]) {
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv,
"46c:C:d:E:fFgi:lm:n:N:p:P:"
- "sS:t:T:u:vVx:")) != -1) {
+ "sS:t:T:U:u:vVx:")) != -1) {
switch (ch) {
case '4':
if (disable4)
@@ -531,6 +531,11 @@ parse_command_line(int argc, char *argv[]) {
fprintf(stderr, "unknown -T flag '%s\n",
isc_commandline_argument);
break;
+ case 'U':
+ ns_g_udpdisp = parse_int(isc_commandline_argument,
+ "number of UDP listeners "
+ "per interface");
+ break;
case 'u':
ns_g_username = isc_commandline_argument;
break;
@@ -595,6 +600,18 @@ create_managers(void) {
#else
ns_g_cpus = 1;
#endif
+#ifdef WIN32
+ ns_g_udpdisp = 1;
+#else
+ if (ns_g_udpdisp == 0)
+ ns_g_udpdisp = ns_g_cpus_detected;
+ if (ns_g_udpdisp > ns_g_cpus)
+ ns_g_udpdisp = ns_g_cpus;
+#endif
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_INFO, "using %u UDP listener%s per interface",
+ ns_g_udpdisp, ns_g_udpdisp == 1 ? "" : "s");
+
result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
diff --git a/contrib/bind9/bin/named/named.8 b/contrib/bind9/bin/named/named.8
index 222ff42..b27be31 100644
--- a/contrib/bind9/bin/named/named.8
+++ b/contrib/bind9/bin/named/named.8
@@ -1,4 +1,4 @@
-.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
.\" Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
.\"
.\" Permission to use, copy, modify, and/or distribute this software for any
@@ -33,7 +33,7 @@
named \- Internet domain name server
.SH "SYNOPSIS"
.HP 6
-\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-E\ \fR\fB\fIengine\-name\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-S\ \fR\fB\fI#max\-socks\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-V\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR]
+\fBnamed\fR [\fB\-4\fR] [\fB\-6\fR] [\fB\-c\ \fR\fB\fIconfig\-file\fR\fR] [\fB\-d\ \fR\fB\fIdebug\-level\fR\fR] [\fB\-E\ \fR\fB\fIengine\-name\fR\fR] [\fB\-f\fR] [\fB\-g\fR] [\fB\-m\ \fR\fB\fIflag\fR\fR] [\fB\-n\ \fR\fB\fI#cpus\fR\fR] [\fB\-p\ \fR\fB\fIport\fR\fR] [\fB\-s\fR] [\fB\-S\ \fR\fB\fI#max\-socks\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-U\ \fR\fB\fI#listeners\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-V\fR] [\fB\-x\ \fR\fB\fIcache\-file\fR\fR]
.SH "DESCRIPTION"
.PP
\fBnamed\fR
@@ -168,6 +168,19 @@ is defined allows a process with root privileges to escape a chroot jail.
.RE
.RE
.PP
+\-U \fI#listeners\fR
+.RS 4
+Use
+\fI#listeners\fR
+worker threads to listen for incoming UDP packets on each address. If not specified,
+\fBnamed\fR
+will use the number of detected CPUs. If
+\fB\-n\fR
+has been set to a higher value than the number of CPUs, then
+\fB\-U\fR
+may be increased as high as that value, but no higher.
+.RE
+.PP
\-u \fIuser\fR
.RS 4
Setuid to
@@ -267,7 +280,7 @@ BIND 9 Administrator Reference Manual.
.PP
Internet Systems Consortium
.SH "COPYRIGHT"
-Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC")
+Copyright \(co 2004\-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
.br
Copyright \(co 2000, 2001, 2003 Internet Software Consortium.
.br
diff --git a/contrib/bind9/bin/named/named.conf.5 b/contrib/bind9/bin/named/named.conf.5
index 09b147e..8d01222 100644
--- a/contrib/bind9/bin/named/named.conf.5
+++ b/contrib/bind9/bin/named/named.conf.5
@@ -289,7 +289,8 @@ options {
notify\-delay \fIseconds\fR;
notify\-to\-soa \fIboolean\fR;
also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR )
- [ port \fIinteger\fR ]; ... };
+ [ port \fIinteger\fR ]; ...
+ [ key \fIkeyname\fR ] ... };
allow\-notify { \fIaddress_match_element\fR; ... };
forward ( first | only );
forwarders [ port \fIinteger\fR ] {
@@ -458,7 +459,8 @@ view \fIstring\fR \fIoptional_class\fR {
notify\-delay \fIseconds\fR;
notify\-to\-soa \fIboolean\fR;
also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR )
- [ port \fIinteger\fR ]; ... };
+ [ port \fIinteger\fR ]; ...
+ [ key \fIkeyname\fR ] ... };
allow\-notify { \fIaddress_match_element\fR; ... };
forward ( first | only );
forwarders [ port \fIinteger\fR ] {
@@ -502,7 +504,7 @@ view \fIstring\fR \fIoptional_class\fR {
.RS 4
.nf
zone \fIstring\fR \fIoptional_class\fR {
- type ( master | slave | stub | hint |
+ type ( master | slave | stub | hint | redirect |
forward | delegation\-only );
file \fIquoted_string\fR;
masters [ port \fIinteger\fR ] {
@@ -544,7 +546,8 @@ zone \fIstring\fR \fIoptional_class\fR {
notify\-delay \fIseconds\fR;
notify\-to\-soa \fIboolean\fR;
also\-notify [ port \fIinteger\fR ] { ( \fIipv4_address\fR | \fIipv6_address\fR )
- [ port \fIinteger\fR ]; ... };
+ [ port \fIinteger\fR ]; ...
+ [ key \fIkeyname\fR ] ... };
allow\-notify { \fIaddress_match_element\fR; ... };
forward ( first | only );
forwarders [ port \fIinteger\fR ] {
@@ -560,6 +563,7 @@ zone \fIstring\fR \fIoptional_class\fR {
max\-refresh\-time \fIinteger\fR;
min\-refresh\-time \fIinteger\fR;
multi\-master \fIboolean\fR;
+ request\-ixfr \fIboolean\fR;
sig\-validity\-interval \fIinteger\fR;
transfer\-source ( \fIipv4_address\fR | * )
[ port ( \fIinteger\fR | * ) ];
diff --git a/contrib/bind9/bin/named/named.conf.docbook b/contrib/bind9/bin/named/named.conf.docbook
index 2527ac3..d778706 100644
--- a/contrib/bind9/bin/named/named.conf.docbook
+++ b/contrib/bind9/bin/named/named.conf.docbook
@@ -17,7 +17,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.conf.docbook,v 1.49.14.2 2011/11/07 00:31:47 marka Exp $ -->
+<!-- $Id: named.conf.docbook,v 1.55 2011/11/07 00:25:53 each Exp $ -->
<refentry>
<refentryinfo>
<date>Aug 13, 2004</date>
@@ -326,7 +326,8 @@ options {
notify-delay <replaceable>seconds</replaceable>;
notify-to-soa <replaceable>boolean</replaceable>;
also-notify <optional> port <replaceable>integer</replaceable> </optional> { ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> )
- <optional> port <replaceable>integer</replaceable> </optional>; ... };
+ <optional> port <replaceable>integer</replaceable> </optional>; ...
+ <optional> key <replaceable>keyname</replaceable> </optional> ... };
allow-notify { <replaceable>address_match_element</replaceable>; ... };
forward ( first | only );
@@ -513,7 +514,8 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
notify-delay <replaceable>seconds</replaceable>;
notify-to-soa <replaceable>boolean</replaceable>;
also-notify <optional> port <replaceable>integer</replaceable> </optional> { ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> )
- <optional> port <replaceable>integer</replaceable> </optional>; ... };
+ <optional> port <replaceable>integer</replaceable> </optional>; ...
+ <optional> key <replaceable>keyname</replaceable> </optional> ... };
allow-notify { <replaceable>address_match_element</replaceable>; ... };
forward ( first | only );
@@ -563,7 +565,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
<title>ZONE</title>
<literallayout>
zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable> {
- type ( master | slave | stub | hint |
+ type ( master | slave | stub | hint | redirect |
forward | delegation-only );
file <replaceable>quoted_string</replaceable>;
@@ -609,7 +611,8 @@ zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
notify-delay <replaceable>seconds</replaceable>;
notify-to-soa <replaceable>boolean</replaceable>;
also-notify <optional> port <replaceable>integer</replaceable> </optional> { ( <replaceable>ipv4_address</replaceable> | <replaceable>ipv6_address</replaceable> )
- <optional> port <replaceable>integer</replaceable> </optional>; ... };
+ <optional> port <replaceable>integer</replaceable> </optional>; ...
+ <optional> key <replaceable>keyname</replaceable> </optional> ... };
allow-notify { <replaceable>address_match_element</replaceable>; ... };
forward ( first | only );
@@ -627,6 +630,7 @@ zone <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
max-refresh-time <replaceable>integer</replaceable>;
min-refresh-time <replaceable>integer</replaceable>;
multi-master <replaceable>boolean</replaceable>;
+ request-ixfr <replaceable>boolean</replaceable>;
sig-validity-interval <replaceable>integer</replaceable>;
transfer-source ( <replaceable>ipv4_address</replaceable> | * )
diff --git a/contrib/bind9/bin/named/named.conf.html b/contrib/bind9/bin/named/named.conf.html
index a8b35ed..23d9391 100644
--- a/contrib/bind9/bin/named/named.conf.html
+++ b/contrib/bind9/bin/named/named.conf.html
@@ -21,7 +21,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en">
-<a name="id2476275"></a><div class="titlepage"></div>
+<a name="id2476274"></a><div class="titlepage"></div>
<div class="refnamediv">
<h2>Name</h2>
<p><code class="filename">named.conf</code> &#8212; configuration file for named</p>
@@ -31,7 +31,7 @@
<div class="cmdsynopsis"><p><code class="command">named.conf</code> </p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543356"></a><h2>DESCRIPTION</h2>
+<a name="id2543357"></a><h2>DESCRIPTION</h2>
<p><code class="filename">named.conf</code> is the configuration file
for
<span><strong class="command">named</strong></span>. Statements are enclosed
@@ -50,14 +50,14 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543384"></a><h2>ACL</h2>
+<a name="id2543385"></a><h2>ACL</h2>
<div class="literallayout"><p><br>
acl <em class="replaceable"><code>string</code></em> { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543400"></a><h2>KEY</h2>
+<a name="id2543401"></a><h2>KEY</h2>
<div class="literallayout"><p><br>
key <em class="replaceable"><code>domain_name</code></em> {<br>
algorithm <em class="replaceable"><code>string</code></em>;<br>
@@ -66,7 +66,7 @@ key <em class="replaceable"><code>domain_name</code></em> {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543419"></a><h2>MASTERS</h2>
+<a name="id2543420"></a><h2>MASTERS</h2>
<div class="literallayout"><p><br>
masters <em class="replaceable"><code>string</code></em> [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br>
( <em class="replaceable"><code>masters</code></em> | <em class="replaceable"><code>ipv4_address</code></em> [<span class="optional">port <em class="replaceable"><code>integer</code></em></span>] |<br>
@@ -75,7 +75,7 @@ masters <em class="replaceable"><code>string</code></em> [<span class="optional"
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543465"></a><h2>SERVER</h2>
+<a name="id2543466"></a><h2>SERVER</h2>
<div class="literallayout"><p><br>
server ( <em class="replaceable"><code>ipv4_address[<span class="optional">/prefixlen</span>]</code></em> | <em class="replaceable"><code>ipv6_address[<span class="optional">/prefixlen</span>]</code></em> ) {<br>
bogus <em class="replaceable"><code>boolean</code></em>;<br>
@@ -97,7 +97,7 @@ server ( <em class="replaceable"><code>ipv4_address[<span class="optional">/pref
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543533"></a><h2>TRUSTED-KEYS</h2>
+<a name="id2543534"></a><h2>TRUSTED-KEYS</h2>
<div class="literallayout"><p><br>
trusted-keys {<br>
<em class="replaceable"><code>domain_name</code></em> <em class="replaceable"><code>flags</code></em> <em class="replaceable"><code>protocol</code></em> <em class="replaceable"><code>algorithm</code></em> <em class="replaceable"><code>key</code></em>; ... <br>
@@ -105,7 +105,7 @@ trusted-keys {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543559"></a><h2>MANAGED-KEYS</h2>
+<a name="id2543560"></a><h2>MANAGED-KEYS</h2>
<div class="literallayout"><p><br>
managed-keys {<br>
<em class="replaceable"><code>domain_name</code></em> <code class="constant">initial-key</code> <em class="replaceable"><code>flags</code></em> <em class="replaceable"><code>protocol</code></em> <em class="replaceable"><code>algorithm</code></em> <em class="replaceable"><code>key</code></em>; ... <br>
@@ -113,7 +113,7 @@ managed-keys {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543588"></a><h2>CONTROLS</h2>
+<a name="id2543589"></a><h2>CONTROLS</h2>
<div class="literallayout"><p><br>
controls {<br>
inet ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> | * )<br>
@@ -125,7 +125,7 @@ controls {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543623"></a><h2>LOGGING</h2>
+<a name="id2543624"></a><h2>LOGGING</h2>
<div class="literallayout"><p><br>
logging {<br>
channel <em class="replaceable"><code>string</code></em> {<br>
@@ -143,7 +143,7 @@ logging {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543661"></a><h2>LWRES</h2>
+<a name="id2543662"></a><h2>LWRES</h2>
<div class="literallayout"><p><br>
lwres {<br>
listen-on [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] {<br>
@@ -156,7 +156,7 @@ lwres {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543703"></a><h2>OPTIONS</h2>
+<a name="id2543704"></a><h2>OPTIONS</h2>
<div class="literallayout"><p><br>
options {<br>
avoid-v4-udp-ports { <em class="replaceable"><code>port</code></em>; ... };<br>
@@ -291,7 +291,8 @@ options {<br>
notify-delay <em class="replaceable"><code>seconds</code></em>;<br>
notify-to-soa <em class="replaceable"><code>boolean</code></em>;<br>
also-notify [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> )<br>
- [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ... };<br>
+ [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br>
+ [<span class="optional"> key <em class="replaceable"><code>keyname</code></em> </span>] ... };<br>
allow-notify { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
<br>
forward ( first | only );<br>
@@ -360,7 +361,7 @@ options {<br>
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544578"></a><h2>VIEW</h2>
+<a name="id2544585"></a><h2>VIEW</h2>
<div class="literallayout"><p><br>
view <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br>
match-clients { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
@@ -477,7 +478,8 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
notify-delay <em class="replaceable"><code>seconds</code></em>;<br>
notify-to-soa <em class="replaceable"><code>boolean</code></em>;<br>
also-notify [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> )<br>
- [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ... };<br>
+ [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br>
+ [<span class="optional"> key <em class="replaceable"><code>keyname</code></em> </span>] ... };<br>
allow-notify { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
<br>
forward ( first | only );<br>
@@ -523,10 +525,10 @@ view <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2545287"></a><h2>ZONE</h2>
+<a name="id2545301"></a><h2>ZONE</h2>
<div class="literallayout"><p><br>
zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><code>optional_class</code></em> {<br>
- type ( master | slave | stub | hint |<br>
+ type ( master | slave | stub | hint | redirect |<br>
forward | delegation-only );<br>
file <em class="replaceable"><code>quoted_string</code></em>;<br>
<br>
@@ -572,7 +574,8 @@ zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
notify-delay <em class="replaceable"><code>seconds</code></em>;<br>
notify-to-soa <em class="replaceable"><code>boolean</code></em>;<br>
also-notify [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>] { ( <em class="replaceable"><code>ipv4_address</code></em> | <em class="replaceable"><code>ipv6_address</code></em> )<br>
- [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ... };<br>
+ [<span class="optional"> port <em class="replaceable"><code>integer</code></em> </span>]; ...<br>
+ [<span class="optional"> key <em class="replaceable"><code>keyname</code></em> </span>] ... };<br>
allow-notify { <em class="replaceable"><code>address_match_element</code></em>; ... };<br>
<br>
forward ( first | only );<br>
@@ -590,6 +593,7 @@ zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
max-refresh-time <em class="replaceable"><code>integer</code></em>;<br>
min-refresh-time <em class="replaceable"><code>integer</code></em>;<br>
multi-master <em class="replaceable"><code>boolean</code></em>;<br>
+ request-ixfr <em class="replaceable"><code>boolean</code></em>;<br>
sig-validity-interval <em class="replaceable"><code>integer</code></em>;<br>
<br>
transfer-source ( <em class="replaceable"><code>ipv4_address</code></em> | * )<br>
@@ -618,12 +622,12 @@ zone <em class="replaceable"><code>string</code></em> <em class="replaceable"><c
</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2545667"></a><h2>FILES</h2>
+<a name="id2545690"></a><h2>FILES</h2>
<p><code class="filename">/etc/named.conf</code>
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2545678"></a><h2>SEE ALSO</h2>
+<a name="id2545702"></a><h2>SEE ALSO</h2>
<p><span class="citerefentry"><span class="refentrytitle">named</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">named-checkconf</span>(8)</span>,
<span class="citerefentry"><span class="refentrytitle">rndc</span>(8)</span>,
diff --git a/contrib/bind9/bin/named/named.docbook b/contrib/bind9/bin/named/named.docbook
index c748911..1f08e19 100644
--- a/contrib/bind9/bin/named/named.docbook
+++ b/contrib/bind9/bin/named/named.docbook
@@ -2,7 +2,7 @@
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
[<!ENTITY mdash "&#8212;">]>
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named.docbook,v 1.26 2009/10/05 17:30:49 fdupont Exp $ -->
+<!-- $Id: named.docbook,v 1.28 2011/11/09 23:46:23 tbox Exp $ -->
<refentry id="man.named">
<refentryinfo>
<date>May 21, 2009</date>
@@ -43,6 +43,8 @@
<year>2007</year>
<year>2008</year>
<year>2009</year>
+ <year>2011</year>
+ <year>2013</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
<copyright>
@@ -69,6 +71,7 @@
<arg><option>-s</option></arg>
<arg><option>-S <replaceable class="parameter">#max-socks</replaceable></option></arg>
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
+ <arg><option>-U <replaceable class="parameter">#listeners</replaceable></option></arg>
<arg><option>-u <replaceable class="parameter">user</replaceable></option></arg>
<arg><option>-v</option></arg>
<arg><option>-V</option></arg>
@@ -282,6 +285,21 @@
</varlistentry>
<varlistentry>
+ <term>-U <replaceable class="parameter">#listeners</replaceable></term>
+ <listitem>
+ <para>
+ Use <replaceable class="parameter">#listeners</replaceable>
+ worker threads to listen for incoming UDP packets on each
+ address. If not specified, <command>named</command> will
+ use the number of detected CPUs. If <option>-n</option>
+ has been set to a higher value than the number of CPUs,
+ then <option>-U</option> may be increased as high as that
+ value, but no higher.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-u <replaceable class="parameter">user</replaceable></term>
<listitem>
<para>Setuid
diff --git a/contrib/bind9/bin/named/named.html b/contrib/bind9/bin/named/named.html
index cf3cb26..fc8de51 100644
--- a/contrib/bind9/bin/named/named.html
+++ b/contrib/bind9/bin/named/named.html
@@ -1,5 +1,5 @@
<!--
- - Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ - Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
- Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
-
- Permission to use, copy, modify, and/or distribute this software for any
@@ -29,10 +29,10 @@
</div>
<div class="refsynopsisdiv">
<h2>Synopsis</h2>
-<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine-name</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
+<div class="cmdsynopsis"><p><code class="command">named</code> [<code class="option">-4</code>] [<code class="option">-6</code>] [<code class="option">-c <em class="replaceable"><code>config-file</code></em></code>] [<code class="option">-d <em class="replaceable"><code>debug-level</code></em></code>] [<code class="option">-E <em class="replaceable"><code>engine-name</code></em></code>] [<code class="option">-f</code>] [<code class="option">-g</code>] [<code class="option">-m <em class="replaceable"><code>flag</code></em></code>] [<code class="option">-n <em class="replaceable"><code>#cpus</code></em></code>] [<code class="option">-p <em class="replaceable"><code>port</code></em></code>] [<code class="option">-s</code>] [<code class="option">-S <em class="replaceable"><code>#max-socks</code></em></code>] [<code class="option">-t <em class="replaceable"><code>directory</code></em></code>] [<code class="option">-U <em class="replaceable"><code>#listeners</code></em></code>] [<code class="option">-u <em class="replaceable"><code>user</code></em></code>] [<code class="option">-v</code>] [<code class="option">-V</code>] [<code class="option">-x <em class="replaceable"><code>cache-file</code></em></code>]</p></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543482"></a><h2>DESCRIPTION</h2>
+<a name="id2543497"></a><h2>DESCRIPTION</h2>
<p><span><strong class="command">named</strong></span>
is a Domain Name System (DNS) server,
part of the BIND 9 distribution from ISC. For more
@@ -47,7 +47,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2543507"></a><h2>OPTIONS</h2>
+<a name="id2543522"></a><h2>OPTIONS</h2>
<div class="variablelist"><dl>
<dt><span class="term">-4</span></dt>
<dd><p>
@@ -178,6 +178,16 @@
</p>
</div>
</dd>
+<dt><span class="term">-U <em class="replaceable"><code>#listeners</code></em></span></dt>
+<dd><p>
+ Use <em class="replaceable"><code>#listeners</code></em>
+ worker threads to listen for incoming UDP packets on each
+ address. If not specified, <span><strong class="command">named</strong></span> will
+ use the number of detected CPUs. If <code class="option">-n</code>
+ has been set to a higher value than the number of CPUs,
+ then <code class="option">-U</code> may be increased as high as that
+ value, but no higher.
+ </p></dd>
<dt><span class="term">-u <em class="replaceable"><code>user</code></em></span></dt>
<dd>
<p>Setuid
@@ -228,7 +238,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2543964"></a><h2>SIGNALS</h2>
+<a name="id2544012"></a><h2>SIGNALS</h2>
<p>
In routine operation, signals should not be used to control
the nameserver; <span><strong class="command">rndc</strong></span> should be used
@@ -249,7 +259,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544012"></a><h2>CONFIGURATION</h2>
+<a name="id2544060"></a><h2>CONFIGURATION</h2>
<p>
The <span><strong class="command">named</strong></span> configuration file is too complex
to describe in detail here. A complete description is provided
@@ -266,7 +276,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544049"></a><h2>FILES</h2>
+<a name="id2544233"></a><h2>FILES</h2>
<div class="variablelist"><dl>
<dt><span class="term"><code class="filename">/etc/named.conf</code></span></dt>
<dd><p>
@@ -279,7 +289,7 @@
</dl></div>
</div>
<div class="refsect1" lang="en">
-<a name="id2544088"></a><h2>SEE ALSO</h2>
+<a name="id2544273"></a><h2>SEE ALSO</h2>
<p><em class="citetitle">RFC 1033</em>,
<em class="citetitle">RFC 1034</em>,
<em class="citetitle">RFC 1035</em>,
@@ -292,7 +302,7 @@
</p>
</div>
<div class="refsect1" lang="en">
-<a name="id2544295"></a><h2>AUTHOR</h2>
+<a name="id2544343"></a><h2>AUTHOR</h2>
<p><span class="corpauthor">Internet Systems Consortium</span>
</p>
</div>
diff --git a/contrib/bind9/bin/named/query.c b/contrib/bind9/bin/named/query.c
index 8c58984..5093cb2 100644
--- a/contrib/bind9/bin/named/query.c
+++ b/contrib/bind9/bin/named/query.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.353.8.24 2012/02/07 01:14:39 marka Exp $ */
+/* $Id$ */
/*! \file */
@@ -172,39 +172,66 @@ rpz_st_clear(ns_client_t *client);
static inline void
inc_stats(ns_client_t *client, isc_statscounter_t counter) {
dns_zone_t *zone = client->query.authzone;
+ isc_stats_t *zonestats;
+#ifdef NEWSTATS
+ dns_rdatatype_t qtype;
+ dns_rdataset_t *rdataset;
+ dns_stats_t *querystats = NULL;
+#endif
isc_stats_increment(ns_g_server->nsstats, counter);
- if (zone != NULL) {
- isc_stats_t *zonestats = dns_zone_getrequeststats(zone);
- if (zonestats != NULL)
- isc_stats_increment(zonestats, counter);
+ if (zone == NULL)
+ return;
+
+ /* Do regular response type stats */
+ zonestats = dns_zone_getrequeststats(zone);
+
+ if (zonestats != NULL)
+ isc_stats_increment(zonestats, counter);
+
+#ifdef NEWSTATS
+ /* Do query type statistics
+ *
+ * We only increment per-type if we're using the authoriative
+ * answer counter, preventing double-counting.
+ */
+ if (counter == dns_nsstatscounter_authans) {
+ querystats = dns_zone_getrcvquerystats(zone);
+ if (querystats != NULL) {
+ rdataset = ISC_LIST_HEAD(client->query.qname->list);
+ if (rdataset != NULL) {
+ qtype = rdataset->type;
+ dns_rdatatypestats_increment(querystats, qtype);
+ }
+ }
}
+#endif
}
static void
query_send(ns_client_t *client) {
isc_statscounter_t counter;
+
if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0)
inc_stats(client, dns_nsstatscounter_nonauthans);
else
inc_stats(client, dns_nsstatscounter_authans);
+
if (client->message->rcode == dns_rcode_noerror) {
- if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER])) {
- if (client->query.isreferral) {
+ dns_section_t answer = DNS_SECTION_ANSWER;
+ if (ISC_LIST_EMPTY(client->message->sections[answer])) {
+ if (client->query.isreferral)
counter = dns_nsstatscounter_referral;
- } else {
+ else
counter = dns_nsstatscounter_nxrrset;
- }
- } else {
+ } else
counter = dns_nsstatscounter_success;
- }
- } else if (client->message->rcode == dns_rcode_nxdomain) {
+ } else if (client->message->rcode == dns_rcode_nxdomain)
counter = dns_nsstatscounter_nxdomain;
- } else {
- /* We end up here in case of YXDOMAIN, and maybe others */
+ else /* We end up here in case of YXDOMAIN, and maybe others */
counter = dns_nsstatscounter_failure;
- }
+
inc_stats(client, counter);
ns_client_send(client);
}
@@ -1180,6 +1207,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
isc_boolean_t added_something, need_addname;
dns_zone_t *zone;
dns_rdatatype_t type;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(qtype != dns_rdatatype_any);
@@ -1204,6 +1233,9 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
need_addname = ISC_FALSE;
zone = NULL;
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
/*
* We treat type A additional section processing as if it
* were "any address type" additional section processing.
@@ -1248,9 +1280,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
* necessarily in the same database.
*/
node = NULL;
- result = dns_db_find(db, name, version, type, client->query.dboptions,
- client->now, &node, fname, rdataset,
- sigrdataset);
+ result = dns_db_findext(db, name, version, type,
+ client->query.dboptions,
+ client->now, &node, fname, &cm, &ci,
+ rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
if (sigrdataset != NULL && !dns_db_issecure(db) &&
dns_rdataset_isassociated(sigrdataset))
@@ -1286,11 +1319,11 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
if (sigrdataset == NULL)
goto cleanup;
}
- result = dns_db_find(db, name, version, type,
- client->query.dboptions |
- DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
- client->now, &node, fname, rdataset,
- sigrdataset);
+ result = dns_db_findext(db, name, version, type,
+ client->query.dboptions |
+ DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
+ client->now, &node, fname, &cm, &ci,
+ rdataset, sigrdataset);
if (result == DNS_R_GLUE &&
validate(client, db, fname, rdataset, sigrdataset))
result = ISC_R_SUCCESS;
@@ -1333,10 +1366,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto cleanup;
dns_db_attach(client->query.gluedb, &db);
- result = dns_db_find(db, name, version, type,
- client->query.dboptions | DNS_DBFIND_GLUEOK,
- client->now, &node, fname, rdataset,
- sigrdataset);
+ result = dns_db_findext(db, name, version, type,
+ client->query.dboptions | DNS_DBFIND_GLUEOK,
+ client->now, &node, fname, &cm, &ci,
+ rdataset, sigrdataset);
if (!(result == ISC_R_SUCCESS ||
result == DNS_R_ZONECUT ||
result == DNS_R_GLUE))
@@ -1410,8 +1443,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto aaaa_lookup;
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_a, 0,
- client->now, rdataset,
- sigrdataset);
+ client->now,
+ rdataset, sigrdataset);
if (result == DNS_R_NCACHENXDOMAIN)
goto addname;
if (result == DNS_R_NCACHENXRRSET) {
@@ -1461,8 +1494,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto addname;
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_aaaa, 0,
- client->now, rdataset,
- sigrdataset);
+ client->now,
+ rdataset, sigrdataset);
if (result == DNS_R_NCACHENXDOMAIN)
goto addname;
if (result == DNS_R_NCACHENXRRSET) {
@@ -1636,6 +1669,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
dns_zone_t *zone;
dns_rdatatype_t type;
dns_rdatasetadditional_t additionaltype;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
/*
* If we don't have an additional cache call query_addadditional.
@@ -1674,6 +1709,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
POST(needadditionalcache);
additionaltype = dns_rdatasetadditional_fromauth;
dns_name_init(&cfname, NULL);
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
CTRACE("query_addadditional2");
@@ -1776,8 +1813,10 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
* necessarily in the same database.
*/
node = NULL;
- result = dns_db_find(db, name, version, type, client->query.dboptions,
- client->now, &node, fname, NULL, NULL);
+ result = dns_db_findext(db, name, version, type,
+ client->query.dboptions,
+ client->now, &node, fname, &cm, &ci,
+ NULL, NULL);
if (result == ISC_R_SUCCESS)
goto found;
@@ -1804,10 +1843,11 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
*/
goto try_glue;
- result = dns_db_find(db, name, version, type,
- client->query.dboptions |
- DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
- client->now, &node, fname, NULL, NULL);
+ result = dns_db_findext(db, name, version, type,
+ client->query.dboptions |
+ DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK,
+ client->now, &node, fname, &cm, &ci,
+ NULL, NULL);
if (result == ISC_R_SUCCESS)
goto found;
@@ -1876,9 +1916,10 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
findglue:
dns_db_attach(client->query.gluedb, &db);
- result = dns_db_find(db, name, version, type,
- client->query.dboptions | DNS_DBFIND_GLUEOK,
- client->now, &node, fname, NULL, NULL);
+ result = dns_db_findext(db, name, version, type,
+ client->query.dboptions | DNS_DBFIND_GLUEOK,
+ client->now, &node, fname, &cm, &ci,
+ NULL, NULL);
if (!(result == ISC_R_SUCCESS ||
result == DNS_R_ZONECUT ||
result == DNS_R_GLUE)) {
@@ -2528,6 +2569,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
isc_result_t result, eresult;
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
dns_rdataset_t **sigrdatasetp = NULL;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
CTRACE("query_addsoa");
/*
@@ -2538,6 +2581,9 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
rdataset = NULL;
node = NULL;
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
/*
* Don't add the SOA record for test which set "-T nosoa".
*/
@@ -2571,9 +2617,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
result = dns_db_getoriginnode(db, &node);
if (result == ISC_R_SUCCESS) {
result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_soa,
- 0, client->now, rdataset,
- sigrdataset);
+ dns_rdatatype_soa, 0, client->now,
+ rdataset, sigrdataset);
} else {
dns_fixedname_t foundname;
dns_name_t *fname;
@@ -2581,9 +2626,9 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
dns_fixedname_init(&foundname);
fname = dns_fixedname_name(&foundname);
- result = dns_db_find(db, name, version, dns_rdatatype_soa,
- client->query.dboptions, 0, &node,
- fname, rdataset, sigrdataset);
+ result = dns_db_findext(db, name, version, dns_rdatatype_soa,
+ client->query.dboptions, 0, &node,
+ fname, &cm, &ci, rdataset, sigrdataset);
}
if (result != ISC_R_SUCCESS) {
/*
@@ -2648,6 +2693,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
dns_fixedname_t foundname;
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
dns_rdataset_t **sigrdatasetp = NULL;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
CTRACE("query_addns");
/*
@@ -2659,6 +2706,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
node = NULL;
dns_fixedname_init(&foundname);
fname = dns_fixedname_name(&foundname);
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
/*
* Get resources and make 'name' be the database origin.
@@ -2691,14 +2740,13 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
result = dns_db_getoriginnode(db, &node);
if (result == ISC_R_SUCCESS) {
result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_ns,
- 0, client->now, rdataset,
- sigrdataset);
+ dns_rdatatype_ns, 0, client->now,
+ rdataset, sigrdataset);
} else {
CTRACE("query_addns: calling dns_db_find");
- result = dns_db_find(db, name, NULL, dns_rdatatype_ns,
- client->query.dboptions, 0, &node,
- fname, rdataset, sigrdataset);
+ result = dns_db_findext(db, name, NULL, dns_rdatatype_ns,
+ client->query.dboptions, 0, &node,
+ fname, &cm, &ci, rdataset, sigrdataset);
CTRACE("query_addns: dns_db_find complete");
}
if (result != ISC_R_SUCCESS) {
@@ -2820,15 +2868,19 @@ mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name,
{
isc_result_t result;
dns_dbnode_t *node = NULL;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
isc_stdtime_t now;
rdataset->trust = dns_trust_secure;
sigrdataset->trust = dns_trust_secure;
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
/*
* Save the updated secure state. Ignore failures.
*/
- result = dns_db_findnode(db, name, ISC_TRUE, &node);
+ result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node);
if (result != ISC_R_SUCCESS)
return;
@@ -2856,9 +2908,15 @@ get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
isc_result_t result;
dns_dbnode_t *node = NULL;
isc_boolean_t secure = ISC_FALSE;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
+
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
if (!dns_rdataset_isassociated(keyrdataset)) {
- result = dns_db_findnode(db, &rrsig->signer, ISC_FALSE, &node);
+ result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE,
+ &cm, &ci, &node);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
@@ -2901,7 +2959,7 @@ get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig,
static isc_boolean_t
verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
- dns_rdata_t *rdata, isc_mem_t *mctx, isc_boolean_t acceptexpired)
+ dns_rdata_t *rdata, ns_client_t *client)
{
isc_result_t result;
dns_fixedname_t fixed;
@@ -2910,9 +2968,10 @@ verify(dst_key_t *key, dns_name_t *name, dns_rdataset_t *rdataset,
dns_fixedname_init(&fixed);
again:
- result = dns_dnssec_verify2(name, rdataset, key, ignore, mctx,
+ result = dns_dnssec_verify3(name, rdataset, key, ignore,
+ client->view->maxbits, client->mctx,
rdata, NULL);
- if (result == DNS_R_SIGEXPIRED && acceptexpired) {
+ if (result == DNS_R_SIGEXPIRED && client->view->acceptexpired) {
ignore = ISC_TRUE;
goto again;
}
@@ -2955,8 +3014,7 @@ validate(ns_client_t *client, dns_db_t *db, dns_name_t *name,
do {
if (!get_key(client, db, &rrsig, &keyrdataset, &key))
break;
- if (verify(key, name, rdataset, &rdata, client->mctx,
- client->view->acceptexpired)) {
+ if (verify(key, name, rdataset, &rdata, client)) {
dst_key_free(&key);
dns_rdataset_disassociate(&keyrdataset);
mark_secure(client, db, name, &rrsig,
@@ -2983,6 +3041,8 @@ query_addbestns(ns_client_t *client) {
dns_dbversion_t *version;
dns_zone_t *zone;
isc_buffer_t b;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
CTRACE("query_addbestns");
fname = NULL;
@@ -2999,6 +3059,9 @@ query_addbestns(ns_client_t *client) {
is_zone = ISC_FALSE;
use_zone = ISC_FALSE;
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
/*
* Find the right database.
*/
@@ -3032,10 +3095,11 @@ query_addbestns(ns_client_t *client) {
* Now look for the zonecut.
*/
if (is_zone) {
- result = dns_db_find(db, client->query.qname, version,
- dns_rdatatype_ns, client->query.dboptions,
- client->now, &node, fname,
- rdataset, sigrdataset);
+ result = dns_db_findext(db, client->query.qname, version,
+ dns_rdatatype_ns,
+ client->query.dboptions,
+ client->now, &node, fname,
+ &cm, &ci, rdataset, sigrdataset);
if (result != DNS_R_DELEGATION)
goto cleanup;
if (USECACHE(client)) {
@@ -3312,6 +3376,8 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
int order;
dns_fixedname_t cfixed;
dns_name_t *cname;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
CTRACE("query_addwildcardproof");
fname = NULL;
@@ -3319,6 +3385,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
sigrdataset = NULL;
node = NULL;
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
/*
* Get the NOQNAME proof then if !ispositive
* get the NOWILDCARD proof.
@@ -3378,8 +3447,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
goto cleanup;
- result = dns_db_find(db, name, version, dns_rdatatype_nsec, options,
- 0, &node, fname, rdataset, sigrdataset);
+ result = dns_db_findext(db, name, version, dns_rdatatype_nsec,
+ options, 0, &node, fname, &cm, &ci,
+ rdataset, sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
@@ -3401,10 +3471,10 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
if (labels == 0U)
goto cleanup;
dns_name_split(cname, labels, NULL, cname);
- result = dns_db_find(db, cname, version,
- dns_rdatatype_nsec,
- options, 0, NULL, fname,
- NULL, NULL);
+ result = dns_db_findext(db, cname, version,
+ dns_rdatatype_nsec,
+ options, 0, NULL, fname,
+ &cm, &ci, NULL, NULL);
}
/*
* Add closest (provable) encloser NSEC3.
@@ -3904,6 +3974,11 @@ rpz_rrset_find(ns_client_t *client, dns_rpz_type_t rpz_type,
dns_fixedname_t fixed;
dns_name_t *found;
isc_result_t result;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
+
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
st = client->query.rpz_st;
if ((st->state & DNS_RPZ_RECURSING) != 0) {
@@ -3959,8 +4034,9 @@ rpz_rrset_find(ns_client_t *client, dns_rpz_type_t rpz_type,
node = NULL;
dns_fixedname_init(&fixed);
found = dns_fixedname_name(&fixed);
- result = dns_db_find(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
- client->now, &node, found, *rdatasetp, NULL);
+ result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
+ client->now, &node, found,
+ &cm, &ci, *rdatasetp, NULL);
if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) {
/*
* Try the cache if we're authoritative for an
@@ -3969,9 +4045,9 @@ rpz_rrset_find(ns_client_t *client, dns_rpz_type_t rpz_type,
rpz_clean(NULL, dbp, &node, rdatasetp);
version = NULL;
dns_db_attach(client->view->cachedb, dbp);
- result = dns_db_find(*dbp, name, version, dns_rdatatype_ns,
- 0, client->now, &node, found,
- *rdatasetp, NULL);
+ result = dns_db_findext(*dbp, name, version, dns_rdatatype_ns,
+ 0, client->now, &node, found,
+ &cm, &ci, *rdatasetp, NULL);
}
rpz_clean(NULL, dbp, &node, NULL);
if (result == DNS_R_DELEGATION) {
@@ -4169,9 +4245,14 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
dns_fixedname_t fixed;
dns_name_t *found;
isc_result_t result;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
REQUIRE(nodep != NULL);
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
result = rpz_ready(client, zonep, dbp, nodep, rdatasetp);
if (result != ISC_R_SUCCESS) {
*policyp = DNS_RPZ_POLICY_ERROR;
@@ -4191,8 +4272,9 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
dns_fixedname_init(&fixed);
found = dns_fixedname_name(&fixed);
- result = dns_db_find(*dbp, qnamef, *versionp, dns_rdatatype_any, 0,
- client->now, nodep, found, *rdatasetp, NULL);
+ result = dns_db_findext(*dbp, qnamef, *versionp, dns_rdatatype_any, 0,
+ client->now, nodep, found, &cm, &ci,
+ *rdatasetp, NULL);
if (result == ISC_R_SUCCESS) {
dns_rdatasetiter_t *rdsiter;
@@ -4236,10 +4318,10 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef,
qtype == dns_rdatatype_sig)
result = DNS_R_NXRRSET;
else
- result = dns_db_find(*dbp, qnamef, *versionp,
- qtype, 0, client->now,
- nodep, found, *rdatasetp,
- NULL);
+ result = dns_db_findext(*dbp, qnamef, *versionp,
+ qtype, 0, client->now,
+ nodep, found, &cm, &ci,
+ *rdatasetp, NULL);
}
}
switch (result) {
@@ -5183,6 +5265,8 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
dns_rdata_nsec3_t nsec3;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_boolean_t optout;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
salt_length = sizeof(salt);
result = dns_db_getnsec3parameters(db, version, &hash, NULL,
@@ -5192,6 +5276,8 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
dns_name_init(&name, NULL);
dns_name_clone(qname, &name);
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
/*
* Map unknown algorithm to known value.
@@ -5208,9 +5294,9 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db,
return;
dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3;
- result = dns_db_find(db, dns_fixedname_name(&fixed), version,
- dns_rdatatype_nsec3, dboptions, client->now,
- NULL, fname, rdataset, sigrdataset);
+ result = dns_db_findext(db, dns_fixedname_name(&fixed), version,
+ dns_rdatatype_nsec3, dboptions, client->now,
+ NULL, fname, &cm, &ci, rdataset, sigrdataset);
if (result == DNS_R_NXDOMAIN) {
if (!dns_rdataset_isassociated(rdataset)) {
@@ -5350,6 +5436,121 @@ dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
}
/*
+ * Look for the name and type in the redirection zone. If found update
+ * the arguments as appropriate. Return ISC_TRUE if a update was
+ * performed.
+ *
+ * Only perform the update if the client is in the allow query acl and
+ * returning the update would not cause a DNSSEC validation failure.
+ */
+static isc_boolean_t
+redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
+ dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
+ dns_rdatatype_t qtype)
+{
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_fixedname_t fixed;
+ dns_name_t *found;
+ dns_rdataset_t trdataset;
+ isc_result_t result;
+ dns_rdatatype_t type;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
+ ns_dbversion_t *dbversion;
+
+ CTRACE("redirect");
+
+ if (client->view->redirect == NULL)
+ return (ISC_FALSE);
+
+ dns_fixedname_init(&fixed);
+ found = dns_fixedname_name(&fixed);
+ dns_rdataset_init(&trdataset);
+
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
+ if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
+ return (ISC_FALSE);
+
+ if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
+ if (rdataset->trust == dns_trust_secure)
+ return (ISC_FALSE);
+ if (rdataset->trust == dns_trust_ultimate &&
+ (rdataset->type == dns_rdatatype_nsec ||
+ rdataset->type == dns_rdatatype_nsec3))
+ return (ISC_FALSE);
+ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
+ for (result = dns_rdataset_first(rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(rdataset)) {
+ dns_ncache_current(rdataset, found, &trdataset);
+ type = trdataset.type;
+ dns_rdataset_disassociate(&trdataset);
+ if (type == dns_rdatatype_nsec ||
+ type == dns_rdatatype_nsec3 ||
+ type == dns_rdatatype_rrsig)
+ return (ISC_FALSE);
+ }
+ }
+ }
+
+ result = ns_client_checkaclsilent(client, NULL,
+ dns_zone_getqueryacl(client->view->redirect),
+ ISC_TRUE);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+
+ result = dns_zone_getdb(client->view->redirect, &db);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+
+ dbversion = query_findversion(client, db);
+ if (dbversion == NULL) {
+ dns_db_detach(&db);
+ return (ISC_FALSE);
+ }
+
+ /*
+ * Lookup the requested data in the redirect zone.
+ */
+ result = dns_db_findext(db, client->query.qname, dbversion->version,
+ qtype, 0, client->now, &node, found, &cm, &ci,
+ &trdataset, NULL);
+ if (result != ISC_R_SUCCESS) {
+ if (dns_rdataset_isassociated(&trdataset))
+ dns_rdataset_disassociate(&trdataset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ dns_db_detach(&db);
+ return (ISC_FALSE);
+ }
+ CTRACE("redirect: found data: done");
+
+ dns_name_copy(found, name, NULL);
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ if (dns_rdataset_isassociated(&trdataset)) {
+ dns_rdataset_clone(&trdataset, rdataset);
+ dns_rdataset_disassociate(&trdataset);
+ }
+ if (*nodep != NULL)
+ dns_db_detachnode(*dbp, nodep);
+ dns_db_detach(dbp);
+ dns_db_attachnode(db, node, nodep);
+ dns_db_attach(db, dbp);
+ dns_db_detachnode(db, &node);
+ dns_db_detach(&db);
+ *versionp = dbversion->version;
+
+ client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
+ NS_QUERYATTR_NOADDITIONAL);
+
+ return (ISC_TRUE);
+}
+
+/*
* Do the bulk of query processing for the current query of 'client'.
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
* is ignored. Otherwise, 'qtype' is the query type.
@@ -5387,6 +5588,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
isc_boolean_t resuming;
int line = -1;
isc_boolean_t dns64_exclude, dns64;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
CTRACE("query_find");
@@ -5418,6 +5621,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
is_zone = ISC_FALSE;
is_staticstub_zone = ISC_FALSE;
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, client);
+
if (event != NULL) {
/*
* We're returning from recursion. Restore the query context
@@ -5652,9 +5858,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
/*
* Now look for an answer in the database.
*/
- result = dns_db_find(db, client->query.qname, version, type,
- client->query.dboptions, client->now,
- &node, fname, rdataset, sigrdataset);
+ result = dns_db_findext(db, client->query.qname, version, type,
+ client->query.dboptions, client->now,
+ &node, fname, &cm, &ci, rdataset, sigrdataset);
resume:
CTRACE("query_find: resume");
@@ -5828,10 +6034,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
result = ISC_R_FAILURE;
} else {
dns_db_attach(client->view->hints, &db);
- result = dns_db_find(db, dns_rootname,
- NULL, dns_rdatatype_ns,
- 0, client->now, &node, fname,
- rdataset, sigrdataset);
+ result = dns_db_findext(db, dns_rootname,
+ NULL, dns_rdatatype_ns,
+ 0, client->now, &node,
+ fname, &cm, &ci,
+ rdataset, sigrdataset);
}
if (result != ISC_R_SUCCESS) {
/*
@@ -6301,6 +6508,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
case DNS_R_NXDOMAIN:
INSIST(is_zone);
+ if (!empty_wild &&
+ redirect(client, fname, rdataset, &node, &db, &version,
+ type))
+ break;
if (dns_rdataset_isassociated(rdataset)) {
/*
* If we've got a NSEC record, we need to save the
@@ -6360,6 +6571,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
+ if (redirect(client, fname, rdataset, &node, &db, &version,
+ type))
+ break;
case DNS_R_NCACHENXRRSET:
ncache_nxrrset:
INSIST(!is_zone);
@@ -6862,9 +7076,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
if (qtype == dns_rdatatype_aaaa) {
trdataset = query_newrdataset(client);
result = dns_db_findrdataset(db, node, version,
- dns_rdatatype_a, 0,
- client->now,
- trdataset, NULL);
+ dns_rdatatype_a, 0,
+ client->now,
+ trdataset, NULL);
if (dns_rdataset_isassociated(trdataset))
dns_rdataset_disassociate(trdataset);
query_putrdataset(client, &trdataset);
@@ -7340,6 +7554,7 @@ ns_query_start(ns_client_t *client) {
INSIST(rdataset != NULL);
qtype = rdataset->type;
dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype);
+
if (dns_rdatatype_ismeta(qtype)) {
switch (qtype) {
case dns_rdatatype_any:
diff --git a/contrib/bind9/bin/named/server.c b/contrib/bind9/bin/named/server.c
index 05c68b9..aef922b 100644
--- a/contrib/bind9/bin/named/server.c
+++ b/contrib/bind9/bin/named/server.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.599.8.19 2012/02/22 00:33:32 each Exp $ */
+/* $Id$ */
/*! \file */
@@ -34,11 +34,13 @@
#include <isc/entropy.h>
#include <isc/file.h>
#include <isc/hash.h>
+#include <isc/hex.h>
#include <isc/httpd.h>
#include <isc/lex.h>
#include <isc/parseint.h>
#include <isc/portset.h>
#include <isc/print.h>
+#include <isc/refcount.h>
#include <isc/resource.h>
#include <isc/sha2.h>
#include <isc/socket.h>
@@ -72,6 +74,7 @@
#include <dns/order.h>
#include <dns/peer.h>
#include <dns/portlist.h>
+#include <dns/private.h>
#include <dns/rbt.h>
#include <dns/rdataclass.h>
#include <dns/rdataset.h>
@@ -112,6 +115,10 @@
#define PATH_MAX 1024
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)-1)
+#endif
+
/*%
* Check an operation for failure. Assumes that the function
* using it has a 'result' variable and a 'cleanup' label.
@@ -215,122 +222,129 @@ struct cfg_context {
cfg_aclconfctx_t * actx;
};
+/*%
+ * Holds state information for the initial zone loading process.
+ * Uses the isc_refcount structure to count the number of views
+ * with pending zone loads, dereferencing as each view finishes.
+ */
+typedef struct {
+ ns_server_t *server;
+ isc_refcount_t refs;
+} ns_zoneload_t;
+
/*
* These zones should not leak onto the Internet.
*/
-static const struct {
- const char *zone;
- isc_boolean_t rfc1918;
-} empty_zones[] = {
+const char *empty_zones[] = {
/* RFC 1918 */
- { "10.IN-ADDR.ARPA", ISC_TRUE },
- { "16.172.IN-ADDR.ARPA", ISC_TRUE },
- { "17.172.IN-ADDR.ARPA", ISC_TRUE },
- { "18.172.IN-ADDR.ARPA", ISC_TRUE },
- { "19.172.IN-ADDR.ARPA", ISC_TRUE },
- { "20.172.IN-ADDR.ARPA", ISC_TRUE },
- { "21.172.IN-ADDR.ARPA", ISC_TRUE },
- { "22.172.IN-ADDR.ARPA", ISC_TRUE },
- { "23.172.IN-ADDR.ARPA", ISC_TRUE },
- { "24.172.IN-ADDR.ARPA", ISC_TRUE },
- { "25.172.IN-ADDR.ARPA", ISC_TRUE },
- { "26.172.IN-ADDR.ARPA", ISC_TRUE },
- { "27.172.IN-ADDR.ARPA", ISC_TRUE },
- { "28.172.IN-ADDR.ARPA", ISC_TRUE },
- { "29.172.IN-ADDR.ARPA", ISC_TRUE },
- { "30.172.IN-ADDR.ARPA", ISC_TRUE },
- { "31.172.IN-ADDR.ARPA", ISC_TRUE },
- { "168.192.IN-ADDR.ARPA", ISC_TRUE },
+ "10.IN-ADDR.ARPA",
+ "16.172.IN-ADDR.ARPA",
+ "17.172.IN-ADDR.ARPA",
+ "18.172.IN-ADDR.ARPA",
+ "19.172.IN-ADDR.ARPA",
+ "20.172.IN-ADDR.ARPA",
+ "21.172.IN-ADDR.ARPA",
+ "22.172.IN-ADDR.ARPA",
+ "23.172.IN-ADDR.ARPA",
+ "24.172.IN-ADDR.ARPA",
+ "25.172.IN-ADDR.ARPA",
+ "26.172.IN-ADDR.ARPA",
+ "27.172.IN-ADDR.ARPA",
+ "28.172.IN-ADDR.ARPA",
+ "29.172.IN-ADDR.ARPA",
+ "30.172.IN-ADDR.ARPA",
+ "31.172.IN-ADDR.ARPA",
+ "168.192.IN-ADDR.ARPA",
/* RFC 6598 */
- { "64.100.IN-ADDR.ARPA", ISC_FALSE },
- { "65.100.IN-ADDR.ARPA", ISC_FALSE },
- { "66.100.IN-ADDR.ARPA", ISC_FALSE },
- { "67.100.IN-ADDR.ARPA", ISC_FALSE },
- { "68.100.IN-ADDR.ARPA", ISC_FALSE },
- { "69.100.IN-ADDR.ARPA", ISC_FALSE },
- { "70.100.IN-ADDR.ARPA", ISC_FALSE },
- { "71.100.IN-ADDR.ARPA", ISC_FALSE },
- { "72.100.IN-ADDR.ARPA", ISC_FALSE },
- { "73.100.IN-ADDR.ARPA", ISC_FALSE },
- { "74.100.IN-ADDR.ARPA", ISC_FALSE },
- { "75.100.IN-ADDR.ARPA", ISC_FALSE },
- { "76.100.IN-ADDR.ARPA", ISC_FALSE },
- { "77.100.IN-ADDR.ARPA", ISC_FALSE },
- { "78.100.IN-ADDR.ARPA", ISC_FALSE },
- { "79.100.IN-ADDR.ARPA", ISC_FALSE },
- { "80.100.IN-ADDR.ARPA", ISC_FALSE },
- { "81.100.IN-ADDR.ARPA", ISC_FALSE },
- { "82.100.IN-ADDR.ARPA", ISC_FALSE },
- { "83.100.IN-ADDR.ARPA", ISC_FALSE },
- { "84.100.IN-ADDR.ARPA", ISC_FALSE },
- { "85.100.IN-ADDR.ARPA", ISC_FALSE },
- { "86.100.IN-ADDR.ARPA", ISC_FALSE },
- { "87.100.IN-ADDR.ARPA", ISC_FALSE },
- { "88.100.IN-ADDR.ARPA", ISC_FALSE },
- { "89.100.IN-ADDR.ARPA", ISC_FALSE },
- { "90.100.IN-ADDR.ARPA", ISC_FALSE },
- { "91.100.IN-ADDR.ARPA", ISC_FALSE },
- { "92.100.IN-ADDR.ARPA", ISC_FALSE },
- { "93.100.IN-ADDR.ARPA", ISC_FALSE },
- { "94.100.IN-ADDR.ARPA", ISC_FALSE },
- { "95.100.IN-ADDR.ARPA", ISC_FALSE },
- { "96.100.IN-ADDR.ARPA", ISC_FALSE },
- { "97.100.IN-ADDR.ARPA", ISC_FALSE },
- { "98.100.IN-ADDR.ARPA", ISC_FALSE },
- { "99.100.IN-ADDR.ARPA", ISC_FALSE },
- { "100.100.IN-ADDR.ARPA", ISC_FALSE },
- { "101.100.IN-ADDR.ARPA", ISC_FALSE },
- { "102.100.IN-ADDR.ARPA", ISC_FALSE },
- { "103.100.IN-ADDR.ARPA", ISC_FALSE },
- { "104.100.IN-ADDR.ARPA", ISC_FALSE },
- { "105.100.IN-ADDR.ARPA", ISC_FALSE },
- { "106.100.IN-ADDR.ARPA", ISC_FALSE },
- { "107.100.IN-ADDR.ARPA", ISC_FALSE },
- { "108.100.IN-ADDR.ARPA", ISC_FALSE },
- { "109.100.IN-ADDR.ARPA", ISC_FALSE },
- { "110.100.IN-ADDR.ARPA", ISC_FALSE },
- { "111.100.IN-ADDR.ARPA", ISC_FALSE },
- { "112.100.IN-ADDR.ARPA", ISC_FALSE },
- { "113.100.IN-ADDR.ARPA", ISC_FALSE },
- { "114.100.IN-ADDR.ARPA", ISC_FALSE },
- { "115.100.IN-ADDR.ARPA", ISC_FALSE },
- { "116.100.IN-ADDR.ARPA", ISC_FALSE },
- { "117.100.IN-ADDR.ARPA", ISC_FALSE },
- { "118.100.IN-ADDR.ARPA", ISC_FALSE },
- { "119.100.IN-ADDR.ARPA", ISC_FALSE },
- { "120.100.IN-ADDR.ARPA", ISC_FALSE },
- { "121.100.IN-ADDR.ARPA", ISC_FALSE },
- { "122.100.IN-ADDR.ARPA", ISC_FALSE },
- { "123.100.IN-ADDR.ARPA", ISC_FALSE },
- { "124.100.IN-ADDR.ARPA", ISC_FALSE },
- { "125.100.IN-ADDR.ARPA", ISC_FALSE },
- { "126.100.IN-ADDR.ARPA", ISC_FALSE },
- { "127.100.IN-ADDR.ARPA", ISC_FALSE },
+ "64.100.IN-ADDR.ARPA",
+ "65.100.IN-ADDR.ARPA",
+ "66.100.IN-ADDR.ARPA",
+ "67.100.IN-ADDR.ARPA",
+ "68.100.IN-ADDR.ARPA",
+ "69.100.IN-ADDR.ARPA",
+ "70.100.IN-ADDR.ARPA",
+ "71.100.IN-ADDR.ARPA",
+ "72.100.IN-ADDR.ARPA",
+ "73.100.IN-ADDR.ARPA",
+ "74.100.IN-ADDR.ARPA",
+ "75.100.IN-ADDR.ARPA",
+ "76.100.IN-ADDR.ARPA",
+ "77.100.IN-ADDR.ARPA",
+ "78.100.IN-ADDR.ARPA",
+ "79.100.IN-ADDR.ARPA",
+ "80.100.IN-ADDR.ARPA",
+ "81.100.IN-ADDR.ARPA",
+ "82.100.IN-ADDR.ARPA",
+ "83.100.IN-ADDR.ARPA",
+ "84.100.IN-ADDR.ARPA",
+ "85.100.IN-ADDR.ARPA",
+ "86.100.IN-ADDR.ARPA",
+ "87.100.IN-ADDR.ARPA",
+ "88.100.IN-ADDR.ARPA",
+ "89.100.IN-ADDR.ARPA",
+ "90.100.IN-ADDR.ARPA",
+ "91.100.IN-ADDR.ARPA",
+ "92.100.IN-ADDR.ARPA",
+ "93.100.IN-ADDR.ARPA",
+ "94.100.IN-ADDR.ARPA",
+ "95.100.IN-ADDR.ARPA",
+ "96.100.IN-ADDR.ARPA",
+ "97.100.IN-ADDR.ARPA",
+ "98.100.IN-ADDR.ARPA",
+ "99.100.IN-ADDR.ARPA",
+ "100.100.IN-ADDR.ARPA",
+ "101.100.IN-ADDR.ARPA",
+ "102.100.IN-ADDR.ARPA",
+ "103.100.IN-ADDR.ARPA",
+ "104.100.IN-ADDR.ARPA",
+ "105.100.IN-ADDR.ARPA",
+ "106.100.IN-ADDR.ARPA",
+ "107.100.IN-ADDR.ARPA",
+ "108.100.IN-ADDR.ARPA",
+ "109.100.IN-ADDR.ARPA",
+ "110.100.IN-ADDR.ARPA",
+ "111.100.IN-ADDR.ARPA",
+ "112.100.IN-ADDR.ARPA",
+ "113.100.IN-ADDR.ARPA",
+ "114.100.IN-ADDR.ARPA",
+ "115.100.IN-ADDR.ARPA",
+ "116.100.IN-ADDR.ARPA",
+ "117.100.IN-ADDR.ARPA",
+ "118.100.IN-ADDR.ARPA",
+ "119.100.IN-ADDR.ARPA",
+ "120.100.IN-ADDR.ARPA",
+ "121.100.IN-ADDR.ARPA",
+ "122.100.IN-ADDR.ARPA",
+ "123.100.IN-ADDR.ARPA",
+ "124.100.IN-ADDR.ARPA",
+ "125.100.IN-ADDR.ARPA",
+ "126.100.IN-ADDR.ARPA",
+ "127.100.IN-ADDR.ARPA",
/* RFC 5735 and RFC 5737 */
- { "0.IN-ADDR.ARPA", ISC_FALSE }, /* THIS NETWORK */
- { "127.IN-ADDR.ARPA", ISC_FALSE }, /* LOOPBACK */
- { "254.169.IN-ADDR.ARPA", ISC_FALSE }, /* LINK LOCAL */
- { "2.0.192.IN-ADDR.ARPA", ISC_FALSE }, /* TEST NET */
- { "100.51.198.IN-ADDR.ARPA", ISC_FALSE }, /* TEST NET 2 */
- { "113.0.203.IN-ADDR.ARPA", ISC_FALSE }, /* TEST NET 3 */
- { "255.255.255.255.IN-ADDR.ARPA", ISC_FALSE }, /* BROADCAST */
+ "0.IN-ADDR.ARPA", /* THIS NETWORK */
+ "127.IN-ADDR.ARPA", /* LOOPBACK */
+ "254.169.IN-ADDR.ARPA", /* LINK LOCAL */
+ "2.0.192.IN-ADDR.ARPA", /* TEST NET */
+ "100.51.198.IN-ADDR.ARPA", /* TEST NET 2 */
+ "113.0.203.IN-ADDR.ARPA", /* TEST NET 3 */
+ "255.255.255.255.IN-ADDR.ARPA", /* BROADCAST */
/* Local IPv6 Unicast Addresses */
- { "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE },
- { "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", ISC_FALSE },
+ "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA",
+ "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA",
/* LOCALLY ASSIGNED LOCAL ADDRESS SCOPE */
- { "D.F.IP6.ARPA", ISC_FALSE },
- { "8.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
- { "9.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
- { "A.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
- { "B.E.F.IP6.ARPA", ISC_FALSE }, /* LINK LOCAL */
+ "D.F.IP6.ARPA",
+ "8.E.F.IP6.ARPA", /* LINK LOCAL */
+ "9.E.F.IP6.ARPA", /* LINK LOCAL */
+ "A.E.F.IP6.ARPA", /* LINK LOCAL */
+ "B.E.F.IP6.ARPA", /* LINK LOCAL */
/* Example Prefix, RFC 3849. */
- { "8.B.D.0.1.0.0.2.IP6.ARPA", ISC_FALSE },
+ "8.B.D.0.1.0.0.2.IP6.ARPA",
- { NULL, ISC_FALSE }
+ NULL
};
ISC_PLATFORM_NORETURN_PRE static void
@@ -1334,12 +1348,14 @@ check_dbtype(dns_zone_t **zonep, unsigned int dbtypec, const char **dbargv,
}
static isc_result_t
-setquerystats(dns_zone_t *zone, isc_mem_t *mctx, isc_boolean_t on) {
+setquerystats(dns_zone_t *zone, isc_mem_t *mctx, dns_zonestat_level_t level) {
isc_result_t result;
isc_stats_t *zoneqrystats;
+ dns_zone_setstatlevel(zone, level);
+
zoneqrystats = NULL;
- if (on) {
+ if (level == dns_zonestat_full) {
result = isc_stats_create(mctx, &zoneqrystats,
dns_nsstatscounter_max);
if (result != ISC_R_SUCCESS)
@@ -1387,7 +1403,7 @@ static isc_boolean_t
cache_sharable(dns_view_t *originview, dns_view_t *view,
isc_boolean_t new_zero_no_soattl,
unsigned int new_cleaning_interval,
- isc_uint32_t new_max_cache_size)
+ isc_uint64_t new_max_cache_size)
{
/*
* If the cache cannot even reused for the same view, it cannot be
@@ -1420,11 +1436,11 @@ dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) {
result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone);
if (result != ISC_R_SUCCESS)
- return result;
+ return (result);
dns_zone_setstats(zone, ns_g_server->zonestats);
- return ns_zone_configure_writeable_dlz(view->dlzdatabase,
- zone, zclass, origin);
+ return (ns_zone_configure_writeable_dlz(view->dlzdatabase,
+ zone, zclass, origin));
}
static isc_result_t
@@ -1493,7 +1509,7 @@ dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
dns_zone_setdialup(zone, dns_dialuptype_no);
dns_zone_setnotifytype(zone, dns_notifytype_no);
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE);
- CHECK(setquerystats(zone, mctx, ISC_FALSE)); /* XXXMPA */
+ CHECK(setquerystats(zone, mctx, dns_zonestat_none)); /* XXXMPA */
CHECK(dns_view_addzone(view, zone));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep,
@@ -1654,10 +1670,10 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
in_port_t port;
dns_cache_t *cache = NULL;
isc_result_t result;
- isc_uint32_t max_adb_size;
unsigned int cleaning_interval;
- isc_uint32_t max_cache_size;
- isc_uint32_t max_acache_size;
+ size_t max_cache_size;
+ size_t max_acache_size;
+ size_t max_adb_size;
isc_uint32_t lame_ttl;
dns_tsig_keyring_t *ring = NULL;
dns_view_t *pview = NULL; /* Production view */
@@ -1671,13 +1687,13 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
const char *cachename = NULL;
dns_order_t *order = NULL;
isc_uint32_t udpsize;
+ isc_uint32_t maxbits;
unsigned int resopts = 0;
dns_zone_t *zone = NULL;
isc_uint32_t max_clients_per_query;
const char *sep = ": view ";
const char *viewname = view->name;
const char *forview = " for view ";
- isc_boolean_t rfc1918;
isc_boolean_t empty_zones_enable;
const cfg_obj_t *disablelist = NULL;
isc_stats_t *resstats = NULL;
@@ -1687,7 +1703,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
ns_cache_t *nsc;
isc_boolean_t zero_no_soattl;
dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
- unsigned int query_timeout;
+ unsigned int query_timeout, ndisp;
struct cfg_context *nzctx;
dns_rpz_zone_t *rpz;
@@ -1763,18 +1779,18 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
max_acache_size = ISC_UINT32_MAX;
} else {
isc_resourcevalue_t value;
-
value = cfg_obj_asuint64(obj);
- if (value > ISC_UINT32_MAX) {
- cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
+ if (value > SIZE_MAX) {
+ cfg_obj_log(obj, ns_g_lctx,
+ ISC_LOG_WARNING,
"'max-acache-size "
- "%" ISC_PRINT_QUADFORMAT
- "d' is too large",
- value);
- result = ISC_R_RANGE;
- goto cleanup;
+ "%" ISC_PRINT_QUADFORMAT "u' "
+ "is too large for this "
+ "system; reducing to %lu",
+ value, (unsigned long)SIZE_MAX);
+ value = SIZE_MAX;
}
- max_acache_size = (isc_uint32_t)value;
+ max_acache_size = (size_t) value;
}
dns_acache_setcachesize(view->acache, max_acache_size);
}
@@ -1961,15 +1977,17 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
} else {
isc_resourcevalue_t value;
value = cfg_obj_asuint64(obj);
- if (value > ISC_UINT32_MAX) {
- cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,
+ if (value > SIZE_MAX) {
+ cfg_obj_log(obj, ns_g_lctx,
+ ISC_LOG_WARNING,
"'max-cache-size "
- "%" ISC_PRINT_QUADFORMAT "d' is too large",
- value);
- result = ISC_R_RANGE;
- goto cleanup;
+ "%" ISC_PRINT_QUADFORMAT "u' "
+ "is too large for this "
+ "system; reducing to %lu",
+ value, (unsigned long)SIZE_MAX);
+ value = SIZE_MAX;
}
- max_cache_size = (isc_uint32_t)value;
+ max_cache_size = (size_t) value;
}
/* Check-names. */
@@ -2278,7 +2296,9 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
result = ISC_R_UNEXPECTED;
goto cleanup;
}
- CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
+
+ ndisp = 4 * ISC_MIN(ns_g_udpdisp, MAX_UDP_DISPATCH);
+ CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31, ndisp,
ns_g_socketmgr, ns_g_timermgr,
resopts, ns_g_dispatchmgr,
dispatch4, dispatch6));
@@ -2363,6 +2383,19 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
view->maxudp = udpsize;
/*
+ * Set the maximum rsa exponent bits.
+ */
+ obj = NULL;
+ result = ns_config_get(maps, "max-rsa-exponent-size", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ maxbits = cfg_obj_asuint32(obj);
+ if (maxbits != 0 && maxbits < 35)
+ maxbits = 35;
+ if (maxbits > 4096)
+ maxbits = 4096;
+ view->maxbits = maxbits;
+
+ /*
* Set supported DNSSEC algorithms.
*/
dns_resolver_reset_algorithms(view->resolver);
@@ -2690,11 +2723,6 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
ns_g_mctx, &view->upfwdacl));
obj = NULL;
- result = ns_config_get(maps, "request-ixfr", &obj);
- INSIST(result == ISC_R_SUCCESS);
- view->requestixfr = cfg_obj_asboolean(obj);
-
- obj = NULL;
result = ns_config_get(maps, "provide-ixfr", &obj);
INSIST(result == ISC_R_SUCCESS);
view->provideixfr = cfg_obj_asboolean(obj);
@@ -2847,16 +2875,13 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
(void)ns_config_get(maps, "disable-empty-zone", &disablelist);
if (obj == NULL && disablelist == NULL &&
view->rdclass == dns_rdataclass_in) {
- rfc1918 = ISC_FALSE;
empty_zones_enable = view->recursion;
} else if (view->rdclass == dns_rdataclass_in) {
- rfc1918 = ISC_TRUE;
if (obj != NULL)
empty_zones_enable = cfg_obj_asboolean(obj);
else
empty_zones_enable = view->recursion;
} else {
- rfc1918 = ISC_FALSE;
empty_zones_enable = ISC_FALSE;
}
if (empty_zones_enable && !lwresd_g_useresolvconf) {
@@ -2868,11 +2893,10 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
const char *str;
char server[DNS_NAME_FORMATSIZE + 1];
char contact[DNS_NAME_FORMATSIZE + 1];
- isc_boolean_t logit;
const char *empty_dbtype[4] =
{ "_builtin", "empty", NULL, NULL };
int empty_dbtypec = 4;
- isc_boolean_t zonestats_on;
+ dns_zonestat_level_t statlevel;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
@@ -2910,12 +2934,26 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
obj = NULL;
result = ns_config_get(maps, "zone-statistics", &obj);
INSIST(result == ISC_R_SUCCESS);
- zonestats_on = cfg_obj_asboolean(obj);
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj))
+ statlevel = dns_zonestat_full;
+ else
+ statlevel = dns_zonestat_terse; /* XXX */
+ } else {
+ const char *levelstr = cfg_obj_asstring(obj);
+ if (strcasecmp(levelstr, "full") == 0)
+ statlevel = dns_zonestat_full;
+ else if (strcasecmp(levelstr, "terse") == 0)
+ statlevel = dns_zonestat_terse;
+ else if (strcasecmp(levelstr, "none") == 0)
+ statlevel = dns_zonestat_none;
+ else
+ INSIST(0);
+ }
- logit = ISC_TRUE;
- for (empty = empty_zones[empty_zone].zone;
+ for (empty = empty_zones[empty_zone];
empty != NULL;
- empty = empty_zones[++empty_zone].zone)
+ empty = empty_zones[++empty_zone])
{
dns_forwarders_t *forwarders = NULL;
dns_view_t *pview = NULL;
@@ -2950,23 +2988,6 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
forwarders->fwdpolicy == dns_fwdpolicy_only)
continue;
- if (!rfc1918 && empty_zones[empty_zone].rfc1918) {
- if (logit) {
- isc_log_write(ns_g_lctx,
- NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER,
- ISC_LOG_WARNING,
- "Warning%s%s: "
- "'empty-zones-enable/"
- "disable-empty-zone' "
- "not set: disabling "
- "RFC 1918 empty zones",
- sep, viewname);
- logit = ISC_FALSE;
- }
- continue;
- }
-
/*
* See if we can re-use a existing zone.
*/
@@ -2987,13 +3008,14 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
dns_zone_setview(zone, view);
CHECK(dns_view_addzone(view, zone));
CHECK(setquerystats(zone, mctx,
- zonestats_on));
+ statlevel));
dns_zone_detach(&zone);
continue;
}
}
- CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr,
+ &zone));
CHECK(dns_zone_setorigin(zone, name));
dns_zone_setview(zone, view);
CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr,
@@ -3011,7 +3033,7 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
dns_zone_setnotifytype(zone, dns_notifytype_no);
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS,
ISC_TRUE);
- CHECK(setquerystats(zone, mctx, zonestats_on));
+ CHECK(setquerystats(zone, mctx, statlevel));
CHECK(dns_view_addzone(view, zone));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
@@ -3357,6 +3379,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
{
dns_view_t *pview = NULL; /* Production view */
dns_zone_t *zone = NULL; /* New or reused zone */
+ dns_zone_t *raw = NULL; /* New or reused raw zone */
dns_zone_t *dupzone = NULL;
const cfg_obj_t *options = NULL;
const cfg_obj_t *zoptions = NULL;
@@ -3364,6 +3387,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
const cfg_obj_t *forwarders = NULL;
const cfg_obj_t *forwardtype = NULL;
const cfg_obj_t *only = NULL;
+ const cfg_obj_t *signing = NULL;
isc_result_t result;
isc_result_t tresult;
isc_buffer_t buffer;
@@ -3487,6 +3511,38 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
}
/*
+ * Redirect zones only require minimal configuration.
+ */
+ if (strcasecmp(ztypestr, "redirect") == 0) {
+ if (view->redirect != NULL) {
+ cfg_obj_log(zconfig, ns_g_lctx, ISC_LOG_ERROR,
+ "redirect zone already exists");
+ result = ISC_R_EXISTS;
+ goto cleanup;
+ }
+ result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
+ view->rdclass, &pview);
+ if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (pview != NULL && pview->redirect != NULL) {
+ dns_zone_attach(pview->redirect, &zone);
+ dns_zone_setview(zone, view);
+ } else {
+ CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr,
+ &zone));
+ CHECK(dns_zone_setorigin(zone, origin));
+ dns_zone_setview(zone, view);
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr,
+ zone));
+ dns_zone_setstats(zone, ns_g_server->zonestats);
+ }
+ CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf,
+ zone, NULL));
+ dns_zone_attach(zone, &view->redirect);
+ goto cleanup;
+ }
+
+ /*
* Check for duplicates in the new zone table.
*/
result = dns_view_findzone(view, origin, &dupzone);
@@ -3527,15 +3583,15 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
* be reused if the options specify a slave zone)
* - The zone was and is or was not and is not a policy zone
*/
- result = dns_viewlist_find(&ns_g_server->viewlist,
- view->name, view->rdclass,
- &pview);
+ result = dns_viewlist_find(&ns_g_server->viewlist, view->name,
+ view->rdclass, &pview);
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
goto cleanup;
if (pview != NULL)
result = dns_view_findzone(pview, origin, &zone);
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
goto cleanup;
+
if (zone != NULL && !ns_zone_reusable(zone, zconfig))
dns_zone_detach(&zone);
@@ -3555,7 +3611,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
* We cannot reuse an existing zone, we have
* to create a new one.
*/
- CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone));
CHECK(dns_zone_setorigin(zone, origin));
dns_zone_setview(zone, view);
if (view->acache != NULL)
@@ -3605,10 +3661,28 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
*/
dns_zone_setadded(zone, added);
+ signing = NULL;
+ if ((strcasecmp(ztypestr, "master") == 0 ||
+ strcasecmp(ztypestr, "slave") == 0) &&
+ cfg_map_get(zoptions, "inline-signing", &signing) == ISC_R_SUCCESS &&
+ cfg_obj_asboolean(signing))
+ {
+ dns_zone_getraw(zone, &raw);
+ if (raw == NULL) {
+ CHECK(dns_zone_create(&raw, mctx));
+ CHECK(dns_zone_setorigin(raw, origin));
+ dns_zone_setview(raw, view);
+ if (view->acache != NULL)
+ dns_zone_setacache(raw, view->acache);
+ dns_zone_setstats(raw, ns_g_server->zonestats);
+ CHECK(dns_zone_link(zone, raw));
+ }
+ }
+
/*
* Configure the zone.
*/
- CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone));
+ CHECK(ns_zone_configure(config, vconfig, zconfig, aclconf, zone, raw));
/*
* Add the zone to its view in the new view list.
@@ -3624,6 +3698,8 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
cleanup:
if (zone != NULL)
dns_zone_detach(&zone);
+ if (raw != NULL)
+ dns_zone_detach(&raw);
if (pview != NULL)
dns_view_detach(&pview);
@@ -3666,7 +3742,7 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
}
/* No existing keydata zone was found; create one */
- CHECK(dns_zone_create(&zone, mctx));
+ CHECK(dns_zonemgr_createzone(ns_g_server->zonemgr, &zone));
CHECK(dns_zone_setorigin(zone, dns_rootname));
isc_sha256_data((void *)view->name, strlen(view->name), buffer);
@@ -3700,7 +3776,7 @@ add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx) {
dns_zone_setjournalsize(zone, 0);
dns_zone_setstats(zone, ns_g_server->zonestats);
- CHECK(setquerystats(zone, mctx, ISC_FALSE));
+ CHECK(setquerystats(zone, mctx, dns_zonestat_none));
if (view->managed_keys != NULL)
dns_zone_detach(&view->managed_keys);
@@ -4108,6 +4184,9 @@ removed(dns_zone_t *zone, void *uap) {
case dns_zone_stub:
type = "stub";
break;
+ case dns_zone_redirect:
+ type = "redirect";
+ break;
default:
type = "other";
break;
@@ -5337,32 +5416,102 @@ load_configuration(const char *filename, ns_server_t *server,
}
static isc_result_t
-load_zones(ns_server_t *server, isc_boolean_t stop) {
+view_loaded(void *arg) {
+ isc_result_t result;
+ ns_zoneload_t *zl = (ns_zoneload_t *) arg;
+ ns_server_t *server = zl->server;
+ unsigned int refs;
+
+
+ /*
+ * Force zone maintenance. Do this after loading
+ * so that we know when we need to force AXFR of
+ * slave zones whose master files are missing.
+ *
+ * We use the zoneload reference counter to let us
+ * know when all views are finished.
+ */
+ isc_refcount_decrement(&zl->refs, &refs);
+ if (refs != 0)
+ return (ISC_R_SUCCESS);
+
+ isc_refcount_destroy(&zl->refs);
+ isc_mem_put(server->mctx, zl, sizeof (*zl));
+
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_NOTICE, "all zones loaded");
+ CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr),
+ "forcing zone maintenance");
+
+ ns_os_started();
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_NOTICE, "running");
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+load_zones(ns_server_t *server) {
isc_result_t result;
dns_view_t *view;
+ ns_zoneload_t *zl;
+ unsigned int refs = 0;
+
+ zl = isc_mem_get(server->mctx, sizeof (*zl));
+ if (zl == NULL)
+ return (ISC_R_NOMEMORY);
+ zl->server = server;
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ isc_refcount_init(&zl->refs, 1);
+
/*
- * Load zone data from disk.
+ * Schedule zones to be loaded from disk.
*/
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
- CHECK(dns_view_load(view, stop));
- if (view->managed_keys != NULL)
- CHECK(dns_zone_load(view->managed_keys));
+ if (view->managed_keys != NULL) {
+ result = dns_zone_load(view->managed_keys);
+ if (result != ISC_R_SUCCESS &&
+ result != DNS_R_UPTODATE &&
+ result != DNS_R_CONTINUE)
+ goto cleanup;
+ }
+ if (view->redirect != NULL) {
+ result = dns_zone_load(view->redirect);
+ if (result != ISC_R_SUCCESS &&
+ result != DNS_R_UPTODATE &&
+ result != DNS_R_CONTINUE)
+ goto cleanup;
+ }
+
+ /*
+ * 'dns_view_asyncload' calls view_loaded if there are no
+ * zones.
+ */
+ isc_refcount_increment(&zl->refs, NULL);
+ CHECK(dns_view_asyncload(view, view_loaded, zl));
}
- /*
- * Force zone maintenance. Do this after loading
- * so that we know when we need to force AXFR of
- * slave zones whose master files are missing.
- */
- CHECK(dns_zonemgr_forcemaint(server->zonemgr));
cleanup:
+ isc_refcount_decrement(&zl->refs, &refs);
+ if (refs == 0) {
+ isc_refcount_destroy(&zl->refs);
+ isc_mem_put(server->mctx, zl, sizeof (*zl));
+ } else {
+ /*
+ * Place the task manager into privileged mode. This
+ * ensures that after we leave task-exclusive mode, no
+ * other tasks will be able to run except for the ones
+ * that are loading zones.
+ */
+ isc_taskmgr_setmode(ns_g_taskmgr, isc_taskmgrmode_privileged);
+ }
+
isc_task_endexclusive(server->task);
return (result);
}
@@ -5387,6 +5536,8 @@ load_new_zones(ns_server_t *server, isc_boolean_t stop) {
/* Load managed-keys data */
if (view->managed_keys != NULL)
CHECK(dns_zone_loadnew(view->managed_keys));
+ if (view->redirect != NULL)
+ CHECK(dns_zone_loadnew(view->redirect));
}
/*
@@ -5448,11 +5599,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
isc_hash_init();
- CHECKFATAL(load_zones(server, ISC_FALSE), "loading zones");
-
- ns_os_started();
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
- ISC_LOG_NOTICE, "running");
+ CHECKFATAL(load_zones(server), "loading zones");
}
void
@@ -5889,7 +6036,7 @@ reload(ns_server_t *server) {
isc_result_t result;
CHECK(loadconfig(server));
- result = load_zones(server, ISC_FALSE);
+ result = load_zones(server);
if (result == ISC_R_SUCCESS)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
@@ -5970,11 +6117,10 @@ next_token(char **stringp, const char *delim) {
* set '*zonep' to NULL.
*/
static isc_result_t
-zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep,
- const char **zonename)
+zone_from_args(ns_server_t *server, char *args, const char *zonetxt,
+ dns_zone_t **zonep, const char **zonename, isc_boolean_t skip)
{
char *input, *ptr;
- const char *zonetxt;
char *classtxt;
const char *viewtxt = NULL;
dns_fixedname_t name;
@@ -5988,13 +6134,16 @@ zone_from_args(ns_server_t *server, char *args, dns_zone_t **zonep,
input = args;
- /* Skip the command name. */
- ptr = next_token(&input, " \t");
- if (ptr == NULL)
- return (ISC_R_UNEXPECTEDEND);
+ if (skip) {
+ /* Skip the command name. */
+ ptr = next_token(&input, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+ }
/* Look for the zone name. */
- zonetxt = next_token(&input, " \t");
+ if (zonetxt == NULL)
+ zonetxt = next_token(&input, " \t");
if (zonetxt == NULL)
return (ISC_R_SUCCESS);
if (zonename != NULL)
@@ -6057,13 +6206,20 @@ isc_result_t
ns_server_retransfercommand(ns_server_t *server, char *args) {
isc_result_t result;
dns_zone_t *zone = NULL;
+ dns_zone_t *raw = NULL;
dns_zonetype_t type;
- result = zone_from_args(server, args, &zone, NULL);
+ result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
return (ISC_R_UNEXPECTEDEND);
+ dns_zone_getraw(zone, &raw);
+ if (raw != NULL) {
+ dns_zone_detach(&zone);
+ dns_zone_attach(raw, &zone);
+ dns_zone_detach(&raw);
+ }
type = dns_zone_gettype(zone);
if (type == dns_zone_slave || type == dns_zone_stub)
dns_zone_forcereload(zone);
@@ -6083,7 +6239,7 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zonetype_t type;
const char *msg = NULL;
- result = zone_from_args(server, args, &zone, NULL);
+ result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
@@ -6143,7 +6299,7 @@ ns_server_notifycommand(ns_server_t *server, char *args, isc_buffer_t *text) {
dns_zone_t *zone = NULL;
const unsigned char msg[] = "zone notify queued";
- result = zone_from_args(server, args, &zone, NULL);
+ result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -6168,7 +6324,7 @@ ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
const unsigned char msg2[] = "not a slave or stub zone";
dns_zonetype_t type;
- result = zone_from_args(server, args, &zone, NULL);
+ result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -6190,8 +6346,29 @@ ns_server_refreshcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
}
isc_result_t
-ns_server_togglequerylog(ns_server_t *server) {
- server->log_queries = server->log_queries ? ISC_FALSE : ISC_TRUE;
+ns_server_togglequerylog(ns_server_t *server, char *args) {
+ isc_boolean_t value;
+ char *ptr;
+
+ /* Skip the command name. */
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ value = server->log_queries ? ISC_FALSE : ISC_TRUE;
+ else if (strcasecmp(ptr, "yes") == 0 || strcasecmp(ptr, "on") == 0)
+ value = ISC_TRUE;
+ else if (strcasecmp(ptr, "no") == 0 || strcasecmp(ptr, "off") == 0)
+ value = ISC_FALSE;
+ else
+ return (ISC_R_NOTFOUND);
+
+ if (server->log_queries == value)
+ return (ISC_R_SUCCESS);
+
+ server->log_queries = value;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
@@ -6598,6 +6775,7 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
ptr = next_token(&args, " \t");
if (ptr == NULL)
return (ISC_R_UNEXPECTEDEND);
+
ptr = next_token(&args, " \t");
CHECKMF(isc_stdio_open(server->secrootsfile, "w", &fp),
@@ -6895,7 +7073,7 @@ ns_server_flushcache(ns_server_t *server, char *args) {
}
isc_result_t
-ns_server_flushname(ns_server_t *server, char *args) {
+ns_server_flushnode(ns_server_t *server, char *args, isc_boolean_t tree) {
char *ptr, *target, *viewname;
dns_view_t *view;
isc_boolean_t flushed;
@@ -6942,13 +7120,15 @@ ns_server_flushname(ns_server_t *server, char *args) {
* if some of the views share a single cache. But since the
* operation is lightweight we prefer simplicity here.
*/
- result = dns_view_flushname(view, name);
+ result = dns_view_flushnode(view, name, tree);
if (result != ISC_R_SUCCESS) {
flushed = ISC_FALSE;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
- "flushing name '%s' in cache view '%s' "
- "failed: %s", target, view->name,
+ "flushing %s '%s' in cache view '%s' "
+ "failed: %s",
+ tree ? "tree" : "name",
+ target, view->name,
isc_result_totext(result));
}
}
@@ -6956,21 +7136,26 @@ ns_server_flushname(ns_server_t *server, char *args) {
if (viewname != NULL)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
- "flushing name '%s' in cache view '%s' "
- "succeeded", target, viewname);
+ "flushing %s '%s' in cache view '%s' "
+ "succeeded",
+ tree ? "tree" : "name",
+ target, viewname);
else
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
- "flushing name '%s' in all cache views "
- "succeeded", target);
+ "flushing %s '%s' in all cache views "
+ "succeeded",
+ tree ? "tree" : "name",
+ target);
result = ISC_R_SUCCESS;
} else {
if (!found)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
- "flushing name '%s' in cache view '%s' "
- "failed: view not found", target,
- viewname);
+ "flushing %s '%s' in cache view '%s' "
+ "failed: view not found",
+ tree ? "tree" : "name",
+ target, viewname);
result = ISC_R_FAILURE;
}
isc_task_endexclusive(server->task);
@@ -7005,6 +7190,7 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
#ifdef ISC_PLATFORM_USETHREADS
"CPUs found: %u\n"
"worker threads: %u\n"
+ "UDP listeners per interface: %u\n"
#endif
"number of zones: %u\n"
"debug level: %d\n"
@@ -7017,7 +7203,7 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
"server is up and running",
ns_g_version, ob, alt, cb,
#ifdef ISC_PLATFORM_USETHREADS
- ns_g_cpus_detected, ns_g_cpus,
+ ns_g_cpus_detected, ns_g_cpus, ns_g_udpdisp,
#endif
zonecount, ns_g_debuglevel, xferrunning, xferdeferred,
soaqueries, server->log_queries ? "ON" : "OFF",
@@ -7269,7 +7455,7 @@ ns_server_rekey(ns_server_t *server, char *args) {
if (strncasecmp(args, NS_COMMAND_SIGN, strlen(NS_COMMAND_SIGN)) == 0)
fullsign = ISC_TRUE;
- result = zone_from_args(server, args, &zone, NULL);
+ result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL)
@@ -7296,6 +7482,112 @@ ns_server_rekey(ns_server_t *server, char *args) {
}
/*
+ * Act on a "sync" command from the command channel.
+*/
+static isc_result_t
+synczone(dns_zone_t *zone, void *uap) {
+ isc_boolean_t cleanup = *(isc_boolean_t *)uap;
+ isc_result_t result;
+ dns_zone_t *raw = NULL;
+ char *journal;
+
+ dns_zone_getraw(zone, &raw);
+ if (raw != NULL) {
+ synczone(raw, uap);
+ dns_zone_detach(&raw);
+ }
+
+ result = dns_zone_flush(zone);
+ if (result != ISC_R_SUCCESS)
+ cleanup = ISC_FALSE;
+ if (cleanup) {
+ journal = dns_zone_getjournal(zone);
+ if (journal != NULL)
+ (void)isc_file_remove(journal);
+ }
+
+ return (result);
+}
+
+isc_result_t
+ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text) {
+ isc_result_t result, tresult;
+ dns_view_t *view;
+ dns_zone_t *zone = NULL;
+ char classstr[DNS_RDATACLASS_FORMATSIZE];
+ char zonename[DNS_NAME_FORMATSIZE];
+ const char *vname, *sep, *msg = NULL, *arg;
+ isc_boolean_t cleanup = ISC_FALSE;
+
+ (void) next_token(&args, " \t");
+
+ arg = next_token(&args, " \t");
+ if (arg != NULL &&
+ (strcmp(arg, "-clean") == 0 || strcmp(arg, "-clear") == 0)) {
+ cleanup = ISC_TRUE;
+ arg = next_token(&args, " \t");
+ }
+
+ result = zone_from_args(server, args, arg, &zone, NULL, ISC_FALSE);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (zone == NULL) {
+ result = isc_task_beginexclusive(server->task);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ tresult = ISC_R_SUCCESS;
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ result = dns_zt_apply(view->zonetable, ISC_FALSE,
+ synczone, &cleanup);
+ if (result != ISC_R_SUCCESS &&
+ tresult == ISC_R_SUCCESS)
+ tresult = result;
+ }
+ isc_task_endexclusive(server->task);
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "dumping all zones%s: %s",
+ cleanup ? ", removing journal files" : "",
+ isc_result_totext(result));
+ return (tresult);
+ }
+
+ result = isc_task_beginexclusive(server->task);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ result = synczone(zone, &cleanup);
+ isc_task_endexclusive(server->task);
+
+ if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text))
+ isc_buffer_putmem(text, (const unsigned char *)msg,
+ strlen(msg) + 1);
+
+ view = dns_zone_getview(zone);
+ if (strcmp(view->name, "_default") == 0 ||
+ strcmp(view->name, "_bind") == 0)
+ {
+ vname = "";
+ sep = "";
+ } else {
+ vname = view->name;
+ sep = " ";
+ }
+ dns_rdataclass_format(dns_zone_getclass(zone), classstr,
+ sizeof(classstr));
+ dns_name_format(dns_zone_getorigin(zone),
+ zonename, sizeof(zonename));
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "sync: dumping zone '%s/%s'%s%s%s: %s",
+ zonename, classstr, sep, vname,
+ cleanup ? ", removing journal file" : "",
+ isc_result_totext(result));
+ dns_zone_detach(&zone);
+ return (result);
+}
+
+/*
* Act on a "freeze" or "thaw" command from the command channel.
*/
isc_result_t
@@ -7303,17 +7595,16 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
isc_buffer_t *text)
{
isc_result_t result, tresult;
- dns_zone_t *zone = NULL;
+ dns_zone_t *zone = NULL, *raw = NULL;
dns_zonetype_t type;
char classstr[DNS_RDATACLASS_FORMATSIZE];
char zonename[DNS_NAME_FORMATSIZE];
dns_view_t *view;
- char *journal;
const char *vname, *sep;
isc_boolean_t frozen;
const char *msg = NULL;
- result = zone_from_args(server, args, &zone, NULL);
+ result = zone_from_args(server, args, NULL, &zone, NULL, ISC_TRUE);
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
@@ -7336,12 +7627,23 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
isc_result_totext(tresult));
return (tresult);
}
+ dns_zone_getraw(zone, &raw);
+ if (raw != NULL) {
+ dns_zone_detach(&zone);
+ dns_zone_attach(raw, &zone);
+ dns_zone_detach(&raw);
+ }
type = dns_zone_gettype(zone);
if (type != dns_zone_master) {
dns_zone_detach(&zone);
return (DNS_R_NOTMASTER);
}
+ if (freeze && !dns_zone_isdynamic(zone, ISC_TRUE)) {
+ dns_zone_detach(&zone);
+ return (DNS_R_NOTDYNAMIC);
+ }
+
result = isc_task_beginexclusive(server->task);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
frozen = dns_zone_getupdatedisabled(zone);
@@ -7358,11 +7660,6 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
msg = "Flushing the zone updates to "
"disk failed.";
}
- if (result == ISC_R_SUCCESS) {
- journal = dns_zone_getjournal(zone);
- if (journal != NULL)
- (void)isc_file_remove(journal);
- }
if (result == ISC_R_SUCCESS)
dns_zone_setupdatedisabled(zone, freeze);
} else {
@@ -7642,7 +7939,7 @@ ns_server_del_zone(ns_server_t *server, char *args) {
FILE *ifp = NULL, *ofp = NULL;
/* Parse parameters */
- CHECK(zone_from_args(server, args, &zone, &zonename));
+ CHECK(zone_from_args(server, args, NULL, &zone, &zonename, ISC_TRUE));
if (zone == NULL) {
result = ISC_R_UNEXPECTEDEND;
@@ -7809,3 +8106,162 @@ newzone_cfgctx_destroy(void **cfgp) {
isc_mem_putanddetach(&cfg->mctx, cfg, sizeof(*cfg));
*cfgp = NULL;
}
+
+isc_result_t
+ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) {
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_zone_t *zone = NULL;
+ dns_name_t *origin;
+ dns_db_t *db = NULL;
+ dns_dbnode_t *node = NULL;
+ dns_dbversion_t *version = NULL;
+ dns_rdatatype_t privatetype;
+ dns_rdataset_t privset;
+ isc_boolean_t first = ISC_TRUE;
+ isc_boolean_t list = ISC_FALSE, clear = ISC_FALSE;
+ isc_boolean_t chain = ISC_FALSE;
+ char keystr[DNS_SECALG_FORMATSIZE + 7];
+ unsigned short hash = 0, flags = 0, iter = 0, saltlen = 0;
+ unsigned char salt[255];
+ const char *ptr;
+ size_t n;
+
+ dns_rdataset_init(&privset);
+
+ /* Skip the command name. */
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+
+ /* Find out what we are to do. */
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+
+ if (strcasecmp(ptr, "-list") == 0)
+ list = ISC_TRUE;
+ else if ((strcasecmp(ptr, "-clear") == 0) ||
+ (strcasecmp(ptr, "-clean") == 0)) {
+ clear = ISC_TRUE;
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+ memcpy(keystr, ptr, sizeof(keystr));
+ } else if(strcasecmp(ptr, "-nsec3param") == 0) {
+ const char *hashstr, *flagstr, *iterstr;
+ char nbuf[512];
+
+ chain = ISC_TRUE;
+ hashstr = next_token(&args, " \t");
+ if (hashstr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+
+ if (strcasecmp(hashstr, "none") == 0)
+ hash = 0;
+ else {
+ flagstr = next_token(&args, " \t");
+ iterstr = next_token(&args, " \t");
+ if (flagstr == NULL || iterstr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+
+ n = snprintf(nbuf, sizeof(nbuf), "%s %s %s",
+ hashstr, flagstr, iterstr);
+ if (n == sizeof(nbuf))
+ return (ISC_R_NOSPACE);
+ n = sscanf(nbuf, "%hu %hu %hu", &hash, &flags, &iter);
+ if (n != 3U)
+ return (ISC_R_BADNUMBER);
+
+ if (hash > 0xffU || flags > 0xffU)
+ return (ISC_R_RANGE);
+
+ ptr = next_token(&args, " \t");
+ if (ptr == NULL)
+ return (ISC_R_UNEXPECTEDEND);
+ if (strcmp(ptr, "-") != 0) {
+ isc_buffer_t buf;
+
+ isc_buffer_init(&buf, salt, sizeof(salt));
+ CHECK(isc_hex_decodestring(ptr, &buf));
+ saltlen = isc_buffer_usedlength(&buf);
+ }
+ }
+ } else
+ CHECK(DNS_R_SYNTAX);
+
+ CHECK(zone_from_args(server, args, NULL, &zone, NULL, ISC_FALSE));
+ if (zone == NULL)
+ CHECK(ISC_R_UNEXPECTEDEND);
+
+ if (clear) {
+ CHECK(dns_zone_keydone(zone, keystr));
+ isc_buffer_putstr(text, "request queued");
+ isc_buffer_putuint8(text, 0);
+ } else if (chain) {
+ CHECK(dns_zone_setnsec3param(zone, (isc_uint8_t)hash,
+ (isc_uint8_t)flags, iter,
+ (isc_uint8_t)saltlen, salt,
+ ISC_TRUE));
+ isc_buffer_putstr(text, "request queued");
+ isc_buffer_putuint8(text, 0);
+ } else if (list) {
+ privatetype = dns_zone_getprivatetype(zone);
+ origin = dns_zone_getorigin(zone);
+ CHECK(dns_zone_getdb(zone, &db));
+ CHECK(dns_db_findnode(db, origin, ISC_FALSE, &node));
+ dns_db_currentversion(db, &version);
+
+ result = dns_db_findrdataset(db, node, version, privatetype,
+ dns_rdatatype_none, 0,
+ &privset, NULL);
+ if (result == ISC_R_NOTFOUND) {
+ isc_buffer_putstr(text, "No signing records found");
+ isc_buffer_putuint8(text, 0);
+ result = ISC_R_SUCCESS;
+ goto cleanup;
+ }
+
+ for (result = dns_rdataset_first(&privset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&privset))
+ {
+ dns_rdata_t priv = DNS_RDATA_INIT;
+ char output[BUFSIZ];
+ isc_buffer_t buf;
+
+ dns_rdataset_current(&privset, &priv);
+
+ isc_buffer_init(&buf, output, sizeof(output));
+ CHECK(dns_private_totext(&priv, &buf));
+
+ if (!first)
+ isc_buffer_putstr(text, "\n");
+ first = ISC_FALSE;
+
+ n = snprintf((char *)isc_buffer_used(text),
+ isc_buffer_availablelength(text),
+ "%s", output);
+ if (n >= isc_buffer_availablelength(text))
+ CHECK(ISC_R_NOSPACE);
+
+ isc_buffer_add(text, n);
+ }
+
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ }
+
+ cleanup:
+ if (dns_rdataset_isassociated(&privset))
+ dns_rdataset_disassociate(&privset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ if (version != NULL)
+ dns_db_closeversion(db, &version, ISC_FALSE);
+ if (db != NULL)
+ dns_db_detach(&db);
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+
+ return (result);
+}
diff --git a/contrib/bind9/bin/named/statschannel.c b/contrib/bind9/bin/named/statschannel.c
index 8d30b45..bb642cc 100644
--- a/contrib/bind9/bin/named/statschannel.c
+++ b/contrib/bind9/bin/named/statschannel.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.c,v 1.26.150.2 2011/03/12 04:59:14 tbox Exp $ */
+/* $Id: statschannel.c,v 1.28 2011/03/12 04:59:46 tbox Exp $ */
/*! \file */
@@ -43,7 +43,11 @@
#include <named/server.h>
#include <named/statschannel.h>
-#include "bind9.xsl.h"
+#ifdef NEWSTATS
+ #include "bind9.ver3.xsl.h"
+#else /* OLDSTATS */
+ #include "bind9.xsl.h"
+#endif /* NEWSTATS */
struct ns_statschannel {
/* Unlocked */
@@ -187,7 +191,7 @@ init_desc(void) {
SET_NSSTATDESC(servfail, "queries resulted in SERVFAIL", "QrySERVFAIL");
SET_NSSTATDESC(formerr, "queries resulted in FORMERR", "QryFORMERR");
SET_NSSTATDESC(nxdomain, "queries resulted in NXDOMAIN", "QryNXDOMAIN");
- SET_NSSTATDESC(recursion, "queries caused recursion","QryRecursion");
+ SET_NSSTATDESC(recursion, "queries caused recursion", "QryRecursion");
SET_NSSTATDESC(duplicate, "duplicate queries received", "QryDuplicate");
SET_NSSTATDESC(dropped, "queries dropped", "QryDropped");
SET_NSSTATDESC(failure, "other query failures", "QryFailure");
@@ -304,7 +308,8 @@ init_desc(void) {
SET_ZONESTATDESC(axfrreqv6, "IPv6 AXFR requested", "AXFRReqv6");
SET_ZONESTATDESC(ixfrreqv4, "IPv4 IXFR requested", "IXFRReqv4");
SET_ZONESTATDESC(ixfrreqv6, "IPv6 IXFR requested", "IXFRReqv6");
- SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded","XfrSuccess");
+ SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded",
+ "XfrSuccess");
SET_ZONESTATDESC(xfrfail, "transfer requests failed", "XfrFail");
INSIST(i == dns_zonestatscounter_max);
@@ -427,7 +432,7 @@ init_desc(void) {
do { \
set_desc(dns_dnssecstats_ ## counterid, \
dns_dnssecstats_max, \
- desc, dnssecstats_desc,\
+ desc, dnssecstats_desc, \
xmldesc, dnssecstats_xmldesc); \
dnssecstats_index[i++] = dns_dnssecstats_ ## counterid; \
} while (0)
@@ -519,6 +524,51 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
break;
case statsformat_xml:
#ifdef HAVE_LIBXML2
+#ifdef NEWSTATS
+ writer = arg;
+
+ if (category != NULL) {
+ /* <NameOfCategory> */
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ category));
+ /* <name> inside category */
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ "name"));
+ TRY0(xmlTextWriterWriteString(writer,
+ ISC_XMLCHAR
+ desc[index]));
+ TRY0(xmlTextWriterEndElement(writer));
+ /* </name> */
+
+ /* <counter> */
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ "counter"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u", value));
+
+ TRY0(xmlTextWriterEndElement(writer));
+ /* </counter> */
+ TRY0(xmlTextWriterEndElement(writer));
+ /* </NameOfCategory> */
+
+ } else {
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR
+ "counter"));
+ TRY0(xmlTextWriterWriteAttribute(writer,
+ ISC_XMLCHAR
+ "name",
+ ISC_XMLCHAR
+ desc[index]));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u", value));
+ TRY0(xmlTextWriterEndElement(writer));
+ /* counter */
+ }
+#else /* !NEWSTATS */
writer = arg;
if (category != NULL) {
@@ -548,17 +598,73 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
TRY0(xmlTextWriterEndElement(writer)); /* counter */
if (category != NULL)
TRY0(xmlTextWriterEndElement(writer)); /* category */
-#endif
+#endif /* NEWSTATS */
+#endif /* LIBXML2 */
break;
}
}
return (ISC_R_SUCCESS);
#ifdef HAVE_LIBXML2
error:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR, "failed at dump_counters()");
return (ISC_R_FAILURE);
#endif
}
+#ifdef NEWSTATS
+static void
+rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
+ char typebuf[64];
+ const char *typestr;
+ stats_dumparg_t *dumparg = arg;
+ FILE *fp;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+ int xmlrc;
+#endif
+
+ if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE)
+ == 0) {
+ dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
+ sizeof(typebuf));
+ typestr = typebuf;
+ } else
+ typestr = "Others";
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, typestr);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+
+ writer = dumparg->arg;
+
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
+ ISC_XMLCHAR typestr));
+
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val));
+
+ TRY0(xmlTextWriterEndElement(writer)); /* type */
+#endif
+ break;
+ }
+ return;
+#ifdef HAVE_LIBXML2
+ error:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR, "failed at rdtypestat_dump()");
+ dumparg->result = ISC_R_FAILURE;
+ return;
+#endif
+}
+#else /* NEWSTATS */
static void
rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
char typebuf[64];
@@ -610,6 +716,7 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
return;
#endif
}
+#endif /* NEWSTATS */
static void
rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
@@ -668,11 +775,58 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
return;
#ifdef HAVE_LIBXML2
error:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR, "failed at rdatasetstats_dump()");
dumparg->result = ISC_R_FAILURE;
#endif
}
+#ifdef NEWSTATS
+static void
+opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
+ FILE *fp;
+ isc_buffer_t b;
+ char codebuf[64];
+ stats_dumparg_t *dumparg = arg;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+ int xmlrc;
+#endif
+
+ isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
+ dns_opcode_totext(code, &b);
+ codebuf[isc_buffer_usedlength(&b)] = '\0';
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, codebuf);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
+ ISC_XMLCHAR codebuf ));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val));
+ TRY0(xmlTextWriterEndElement(writer)); /* counter */
+#endif
+ break;
+ }
+ return;
+
+#ifdef HAVE_LIBXML2
+ error:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR, "failed at opcodestat_dump()");
+ dumparg->result = ISC_R_FAILURE;
+ return;
+#endif
+}
+#else /* NEWSTATS */
static void
opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
FILE *fp;
@@ -721,12 +875,96 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
return;
#endif
}
+#endif /* NEWSTATS */
#ifdef HAVE_LIBXML2
-/* XXXMLG below here sucks. */
+/* XXXMLG below here sucks. (not so much) */
+
+#ifdef NEWSTATS
+static isc_result_t
+zone_xmlrender(dns_zone_t *zone, void *arg) {
+ isc_result_t result;
+ char buf[1024 + 32]; /* sufficiently large for zone name and class */
+ char *zone_name_only = NULL;
+ dns_rdataclass_t rdclass;
+ isc_uint32_t serial;
+ xmlTextWriterPtr writer = arg;
+ isc_stats_t *zonestats;
+ dns_stats_t *rcvquerystats;
+ dns_zonestat_level_t statlevel;
+ isc_uint64_t nsstat_values[dns_nsstatscounter_max];
+ int xmlrc;
+ stats_dumparg_t dumparg;
+
+ statlevel = dns_zone_getstatlevel(zone);
+ if (statlevel == dns_zonestat_none)
+ return (ISC_R_SUCCESS);
+
+ dumparg.type = statsformat_xml;
+ dumparg.arg = writer;
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"));
+ dns_zone_name(zone, buf, sizeof(buf));
+ zone_name_only = strtok(buf, "/");
+ if(zone_name_only == NULL)
+ zone_name_only = buf;
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
+ ISC_XMLCHAR zone_name_only));
+ rdclass = dns_zone_getclass(zone);
+ dns_rdataclass_format(rdclass, buf, sizeof(buf));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass",
+ ISC_XMLCHAR buf));
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"));
+ if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS)
+ TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial));
+ else
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
+ TRY0(xmlTextWriterEndElement(writer)); /* serial */
+
+ zonestats = dns_zone_getrequeststats(zone);
+ rcvquerystats = dns_zone_getrcvquerystats(zone);
+ if (statlevel == dns_zonestat_full && zonestats != NULL) {
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "rcode"));
+
+ result = dump_counters(zonestats, statsformat_xml, writer,
+ NULL, nsstats_xmldesc,
+ dns_nsstatscounter_max, nsstats_index,
+ nsstat_values, ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+ /* counters type="rcode"*/
+ TRY0(xmlTextWriterEndElement(writer));
+ }
+
+ if (statlevel == dns_zonestat_full && rcvquerystats != NULL) {
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "qtype"));
+
+ dumparg.result = ISC_R_SUCCESS;
+ dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump,
+ &dumparg, 0);
+ if(dumparg.result != ISC_R_SUCCESS)
+ goto error;
+
+ /* counters type="qtype"*/
+ TRY0(xmlTextWriterEndElement(writer));
+ }
+
+ TRY0(xmlTextWriterEndElement(writer)); /* zone */
+
+ return (ISC_R_SUCCESS);
+ error:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR, "Failed at zone_xmlrender()");
+ return (ISC_R_FAILURE);
+}
+#else /* NEWSTATS */
static isc_result_t
zone_xmlrender(dns_zone_t *zone, void *arg) {
char buf[1024 + 32]; /* sufficiently large for zone name and class */
@@ -776,7 +1014,237 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
error:
return (ISC_R_FAILURE);
}
+#endif /* NEWSTATS */
+
+#ifdef NEWSTATS
+static isc_result_t
+generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
+ char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
+ char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"];
+ isc_time_t now;
+ xmlTextWriterPtr writer = NULL;
+ xmlDocPtr doc = NULL;
+ int xmlrc;
+ dns_view_t *view;
+ stats_dumparg_t dumparg;
+ dns_stats_t *cacherrstats;
+ isc_uint64_t nsstat_values[dns_nsstatscounter_max];
+ isc_uint64_t resstat_values[dns_resstatscounter_max];
+ isc_uint64_t zonestat_values[dns_zonestatscounter_max];
+ isc_uint64_t sockstat_values[isc_sockstatscounter_max];
+ isc_result_t result;
+
+ isc_time_now(&now);
+ isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
+ isc_time_formatISO8601(&now, nowstr, sizeof nowstr);
+
+ writer = xmlNewTextWriterDoc(&doc, 0);
+ if (writer == NULL)
+ goto error;
+ TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL));
+ TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet",
+ ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.ver3.xsl\""));
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
+ ISC_XMLCHAR "3.0"));
+
+ /* Set common fields for statistics dump */
+ dumparg.type = statsformat_xml;
+ dumparg.arg = writer;
+
+ /*
+ * Start by rendering the views we know of here. For each view we
+ * know of, call its rendering function.
+ */
+ view = ISC_LIST_HEAD(server->viewlist);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views"));
+ while (view != NULL) {
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
+ ISC_XMLCHAR view->name));
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones"));
+ result = dns_zt_apply(view->zonetable, ISC_TRUE, zone_xmlrender,
+ writer);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* zones */
+
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "resqtype"));
+
+ if (view->resquerystats != NULL) {
+ dumparg.result = ISC_R_SUCCESS;
+ dns_rdatatypestats_dump(view->resquerystats,
+ rdtypestat_dump, &dumparg, 0);
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+ }
+ TRY0(xmlTextWriterEndElement(writer));
+
+ /* <resstats> */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "resstats"));
+ if (view->resstats != NULL) {
+ result = dump_counters(view->resstats,
+ statsformat_xml, writer,
+ NULL, resstats_xmldesc,
+ dns_resstatscounter_max,
+ resstats_index, resstat_values,
+ ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+ }
+ TRY0(xmlTextWriterEndElement(writer)); /* </resstats> */
+
+ cacherrstats = dns_db_getrrsetstats(view->cachedb);
+ if (cacherrstats != NULL) {
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "cache"));
+ TRY0(xmlTextWriterWriteAttribute(writer,
+ ISC_XMLCHAR "name",
+ ISC_XMLCHAR
+ dns_cache_getname(view->cache)));
+ dumparg.result = ISC_R_SUCCESS;
+ dns_rdatasetstats_dump(cacherrstats, rdatasetstats_dump,
+ &dumparg, 0);
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* cache */
+ }
+
+ TRY0(xmlTextWriterEndElement(writer)); /* view */
+
+ view = ISC_LIST_NEXT(view, link);
+ }
+ TRY0(xmlTextWriterEndElement(writer)); /* views */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socketmgr"));
+ isc_socketmgr_renderxml(ns_g_socketmgr, writer);
+ TRY0(xmlTextWriterEndElement(writer)); /* socketmgr */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "taskmgr"));
+ isc_taskmgr_renderxml(ns_g_taskmgr, writer);
+ TRY0(xmlTextWriterEndElement(writer)); /* taskmgr */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server"));
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime));
+ TRY0(xmlTextWriterEndElement(writer)); /* boot-time */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr));
+ TRY0(xmlTextWriterEndElement(writer)); /* current-time */
+
+ dumparg.result = ISC_R_SUCCESS;
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "opcode"));
+
+ dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg,
+ 0);
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+
+ TRY0(xmlTextWriterEndElement(writer)); /* counters type=opcode */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "qtype"));
+
+ dumparg.result = ISC_R_SUCCESS;
+ dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
+ &dumparg, 0);
+ if (dumparg.result != ISC_R_SUCCESS)
+ goto error;
+ TRY0(xmlTextWriterEndElement(writer)); /* counters */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "nsstat"));
+
+ result = dump_counters(server->nsstats, statsformat_xml,
+ writer, NULL, nsstats_xmldesc,
+ dns_nsstatscounter_max,
+ nsstats_index, nsstat_values,
+ ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+
+ TRY0(xmlTextWriterEndElement(writer)); /* counters type=nsstat */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "zonestat"));
+
+ result = dump_counters(server->zonestats, statsformat_xml, writer,
+ NULL, zonestats_xmldesc,
+ dns_zonestatscounter_max, zonestats_index,
+ zonestat_values, ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+
+ TRY0(xmlTextWriterEndElement(writer)); /* counters type=zonestat */
+
+ /*
+ * Most of the common resolver statistics entries are 0, so we don't
+ * use the verbose dump here.
+ */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "resstat"));
+ result = dump_counters(server->resolverstats, statsformat_xml,
+ writer, NULL, resstats_xmldesc,
+ dns_resstatscounter_max, resstats_index,
+ resstat_values, 0);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+
+ TRY0(xmlTextWriterEndElement(writer)); /* counters type=resstat */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+ TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR "sockstat"));
+
+ result = dump_counters(server->sockstats, statsformat_xml,
+ writer, NULL, sockstats_xmldesc,
+ isc_sockstatscounter_max, sockstats_index,
+ sockstat_values, ISC_STATSDUMP_VERBOSE);
+ if (result != ISC_R_SUCCESS)
+ goto error;
+
+ TRY0(xmlTextWriterEndElement(writer)); /* counters type=sockstat */
+
+ TRY0(xmlTextWriterEndElement(writer)); /* server */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
+ isc_mem_renderxml(writer);
+ TRY0(xmlTextWriterEndElement(writer)); /* memory */
+
+ TRY0(xmlTextWriterEndElement(writer)); /* statistics */
+
+ TRY0(xmlTextWriterEndDocument(writer));
+
+ xmlFreeTextWriter(writer);
+
+ xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0);
+ xmlFreeDoc(doc);
+ return (ISC_R_SUCCESS);
+
+ error:
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+ ISC_LOG_ERROR, "failed generating XML response");
+ if (writer != NULL)
+ xmlFreeTextWriter(writer);
+ if (doc != NULL)
+ xmlFreeDoc(doc);
+ return (ISC_R_FAILURE);
+}
+#else /* OLDSTATS */
static isc_result_t
generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
@@ -968,6 +1436,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
xmlFreeDoc(doc);
return (ISC_R_FAILURE);
}
+#endif /* NEWSTATS */
static void
wrap_xmlfree(isc_buffer_t *buffer, void *arg) {
@@ -1000,7 +1469,10 @@ render_index(const char *url, const char *querystring, void *arg,
isc_buffer_add(b, msglen);
*freecb = wrap_xmlfree;
*freecb_args = NULL;
- }
+ } else
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "failed at rendering XML()");
return (result);
}
@@ -1032,7 +1504,7 @@ static void
shutdown_listener(ns_statschannel_t *listener) {
char socktext[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&listener->address, socktext, sizeof(socktext));
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,NS_LOGMODULE_SERVER,
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_NOTICE, "stopping statistics channel on %s",
socktext);
@@ -1150,10 +1622,22 @@ add_listener(ns_server_t *server, ns_statschannel_t **listenerp,
#ifdef HAVE_LIBXML2
isc_httpdmgr_addurl(listener->httpdmgr, "/", render_index, server);
+ isc_httpdmgr_addurl(listener->httpdmgr, "/xml", render_index, server);
+#ifdef NEWSTATS
+ isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v3", render_index,
+ server);
+#else /* OLDSTATS */
+ isc_httpdmgr_addurl(listener->httpdmgr, "/xml/v2", render_index,
+ server);
+#endif /* NEWSTATS */
#endif
+#ifdef NEWSTATS
+ isc_httpdmgr_addurl(listener->httpdmgr, "/bind9.ver3.xsl", render_xsl,
+ server);
+#else /* OLDSTATS */
isc_httpdmgr_addurl(listener->httpdmgr, "/bind9.xsl", render_xsl,
server);
-
+#endif /* NEWSTATS */
*listenerp = listener;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_NOTICE,
@@ -1285,7 +1769,8 @@ ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config,
obj = cfg_tuple_get(listen_params, "address");
addr = *cfg_obj_assockaddr(obj);
if (isc_sockaddr_getport(&addr) == 0)
- isc_sockaddr_setport(&addr, NS_STATSCHANNEL_HTTPPORT);
+ isc_sockaddr_setport(&addr,
+ NS_STATSCHANNEL_HTTPPORT);
isc_sockaddr_format(&addr, socktext,
sizeof(socktext));
diff --git a/contrib/bind9/bin/named/unix/Makefile.in b/contrib/bind9/bin/named/unix/Makefile.in
index ff2ecce..17bb43e 100644
--- a/contrib/bind9/bin/named/unix/Makefile.in
+++ b/contrib/bind9/bin/named/unix/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.13.244.2 2011/03/10 23:47:26 tbox Exp $
+# $Id: Makefile.in,v 1.15 2011/03/10 23:47:49 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
diff --git a/contrib/bind9/bin/named/unix/dlz_dlopen_driver.c b/contrib/bind9/bin/named/unix/dlz_dlopen_driver.c
index 98dfc5a..2ba8a02 100644
--- a/contrib/bind9/bin/named/unix/dlz_dlopen_driver.c
+++ b/contrib/bind9/bin/named/unix/dlz_dlopen_driver.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dlz_dlopen_driver.c,v 1.1.4.6 2012/02/22 23:46:35 tbox Exp $ */
+/* $Id$ */
#include <config.h>
@@ -143,7 +143,7 @@ dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name,
static isc_result_t
dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata,
- dns_sdlzlookup_t *lookup)
+ dns_sdlzlookup_t *lookup)
{
dlopen_data_t *cd = (dlopen_data_t *) dbdata;
isc_result_t result;
@@ -177,7 +177,9 @@ dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name)
static isc_result_t
dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg,
- void *dbdata, dns_sdlzlookup_t *lookup)
+ void *dbdata, dns_sdlzlookup_t *lookup,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo)
{
dlopen_data_t *cd = (dlopen_data_t *) dbdata;
isc_result_t result;
@@ -185,7 +187,8 @@ dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg,
UNUSED(driverarg);
MAYBE_LOCK(cd);
- result = cd->dlz_lookup(zone, name, cd->dbdata, lookup);
+ result = cd->dlz_lookup(zone, name, cd->dbdata, lookup,
+ methods, clientinfo);
MAYBE_UNLOCK(cd);
return (result);
}
diff --git a/contrib/bind9/bin/named/unix/os.c b/contrib/bind9/bin/named/unix/os.c
index 9637ded..4f5f55c 100644
--- a/contrib/bind9/bin/named/unix/os.c
+++ b/contrib/bind9/bin/named/unix/os.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: os.c,v 1.104.38.3 2011/03/02 00:04:01 marka Exp $ */
+/* $Id: os.c,v 1.107 2011/03/02 00:02:54 marka Exp $ */
/*! \file */
diff --git a/contrib/bind9/bin/named/update.c b/contrib/bind9/bin/named/update.c
index abf5c08..0df00c0 100644
--- a/contrib/bind9/bin/named/update.c
+++ b/contrib/bind9/bin/named/update.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update.c,v 1.186.16.7 2011/11/03 02:55:34 each Exp $ */
+/* $Id: update.c,v 1.199 2011/12/22 07:32:40 each Exp $ */
#include <config.h>
@@ -47,6 +47,7 @@
#include <dns/soa.h>
#include <dns/ssu.h>
#include <dns/tsig.h>
+#include <dns/update.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
@@ -268,6 +269,11 @@ update_log(ns_client_t *client, dns_zone_t *zone,
namebuf, classbuf, message);
}
+static void
+update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
+ update_log(arg, zone, level, "%s", message);
+}
+
/*%
* Increment updated-related statistics counters.
*/
@@ -721,45 +727,6 @@ rrset_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
}
/*%
- * Set '*visible' to true if the RRset exists and is part of the
- * visible zone. Otherwise '*visible' is set to false unless a
- * error occurs.
- */
-static isc_result_t
-rrset_visible(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_rdatatype_t type, isc_boolean_t *visible)
-{
- isc_result_t result;
- dns_fixedname_t fixed;
-
- dns_fixedname_init(&fixed);
- result = dns_db_find(db, name, ver, type, DNS_DBFIND_NOWILD,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&fixed), NULL, NULL);
- switch (result) {
- case ISC_R_SUCCESS:
- *visible = ISC_TRUE;
- break;
- /*
- * Glue, obscured, deleted or replaced records.
- */
- case DNS_R_DELEGATION:
- case DNS_R_DNAME:
- case DNS_R_CNAME:
- case DNS_R_NXDOMAIN:
- case DNS_R_NXRRSET:
- case DNS_R_EMPTYNAME:
- case DNS_R_COVERINGNSEC:
- *visible = ISC_FALSE;
- result = ISC_R_SUCCESS;
- break;
- default:
- break;
- }
- return (result);
-}
-
-/*%
* Helper function for cname_incompatible_rrset_exists.
*/
static isc_result_t
@@ -1174,16 +1141,6 @@ true_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
}
/*%
- * Return true if the record is a RRSIG.
- */
-static isc_boolean_t
-rrsig_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
- UNUSED(update_rr);
- return ((db_rr->type == dns_rdatatype_rrsig) ?
- ISC_TRUE : ISC_FALSE);
-}
-
-/*%
* Return true iff the two RRs have identical rdata.
*/
static isc_boolean_t
@@ -1425,8 +1382,8 @@ get_current_rr(dns_message_t *msg, dns_section_t section,
*/
static isc_result_t
-increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
- dns_diff_t *diff, isc_mem_t *mctx)
+update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
+ isc_mem_t *mctx, dns_updatemethod_t method)
{
dns_difftuple_t *deltuple = NULL;
dns_difftuple_t *addtuple = NULL;
@@ -1438,12 +1395,7 @@ increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
addtuple->op = DNS_DIFFOP_ADD;
serial = dns_soa_getserial(&addtuple->rdata);
-
- /* RFC1982 */
- serial = (serial + 1) & 0xFFFFFFFF;
- if (serial == 0)
- serial = 1;
-
+ serial = dns_update_soaserial(serial, method);
dns_soa_setserial(serial, &addtuple->rdata);
CHECK(do_one_tuple(&deltuple, db, ver, diff));
CHECK(do_one_tuple(&addtuple, db, ver, diff));
@@ -1502,1129 +1454,6 @@ check_soa_increment(dns_db_t *db, dns_dbversion_t *ver,
}
/**************************************************************************/
-/*
- * Incremental updating of NSECs and RRSIGs.
- */
-
-/*%
- * We abuse the dns_diff_t type to represent a set of domain names
- * affected by the update.
- */
-static isc_result_t
-namelist_append_name(dns_diff_t *list, dns_name_t *name) {
- isc_result_t result;
- dns_difftuple_t *tuple = NULL;
- static dns_rdata_t dummy_rdata = DNS_RDATA_INIT;
-
- CHECK(dns_difftuple_create(list->mctx, DNS_DIFFOP_EXISTS, name, 0,
- &dummy_rdata, &tuple));
- dns_diff_append(list, &tuple);
- failure:
- return (result);
-}
-
-static isc_result_t
-namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected)
-{
- isc_result_t result;
- dns_fixedname_t fixedname;
- dns_name_t *child;
- dns_dbiterator_t *dbit = NULL;
-
- dns_fixedname_init(&fixedname);
- child = dns_fixedname_name(&fixedname);
-
- CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
-
- for (result = dns_dbiterator_seek(dbit, name);
- result == ISC_R_SUCCESS;
- result = dns_dbiterator_next(dbit))
- {
- dns_dbnode_t *node = NULL;
- CHECK(dns_dbiterator_current(dbit, &node, child));
- dns_db_detachnode(db, &node);
- if (! dns_name_issubdomain(child, name))
- break;
- CHECK(namelist_append_name(affected, child));
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
- failure:
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
- return (result);
-}
-
-
-
-/*%
- * Helper function for non_nsec_rrset_exists().
- */
-static isc_result_t
-is_non_nsec_action(void *data, dns_rdataset_t *rrset) {
- UNUSED(data);
- if (!(rrset->type == dns_rdatatype_nsec ||
- rrset->type == dns_rdatatype_nsec3 ||
- (rrset->type == dns_rdatatype_rrsig &&
- (rrset->covers == dns_rdatatype_nsec ||
- rrset->covers == dns_rdatatype_nsec3))))
- return (ISC_R_EXISTS);
- return (ISC_R_SUCCESS);
-}
-
-/*%
- * Check whether there is an rrset other than a NSEC or RRSIG NSEC,
- * i.e., anything that justifies the continued existence of a name
- * after a secure update.
- *
- * If such an rrset exists, set '*exists' to ISC_TRUE.
- * Otherwise, set it to ISC_FALSE.
- */
-static isc_result_t
-non_nsec_rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
- dns_name_t *name, isc_boolean_t *exists)
-{
- isc_result_t result;
- result = foreach_rrset(db, ver, name, is_non_nsec_action, NULL);
- RETURN_EXISTENCE_FLAG;
-}
-
-/*%
- * A comparison function for sorting dns_diff_t:s by name.
- */
-static int
-name_order(const void *av, const void *bv) {
- dns_difftuple_t const * const *ap = av;
- dns_difftuple_t const * const *bp = bv;
- dns_difftuple_t const *a = *ap;
- dns_difftuple_t const *b = *bp;
- return (dns_name_compare(&a->name, &b->name));
-}
-
-static isc_result_t
-uniqify_name_list(dns_diff_t *list) {
- isc_result_t result;
- dns_difftuple_t *p, *q;
-
- CHECK(dns_diff_sort(list, name_order));
-
- p = ISC_LIST_HEAD(list->tuples);
- while (p != NULL) {
- do {
- q = ISC_LIST_NEXT(p, link);
- if (q == NULL || ! dns_name_equal(&p->name, &q->name))
- break;
- ISC_LIST_UNLINK(list->tuples, q, link);
- dns_difftuple_free(&q);
- } while (1);
- p = ISC_LIST_NEXT(p, link);
- }
- failure:
- return (result);
-}
-
-static isc_result_t
-is_active(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- isc_boolean_t *flag, isc_boolean_t *cut, isc_boolean_t *unsecure)
-{
- isc_result_t result;
- dns_fixedname_t foundname;
- dns_fixedname_init(&foundname);
- result = dns_db_find(db, name, ver, dns_rdatatype_any,
- DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&foundname),
- NULL, NULL);
- if (result == ISC_R_SUCCESS || result == DNS_R_EMPTYNAME) {
- *flag = ISC_TRUE;
- *cut = ISC_FALSE;
- if (unsecure != NULL)
- *unsecure = ISC_FALSE;
- return (ISC_R_SUCCESS);
- } else if (result == DNS_R_ZONECUT) {
- *flag = ISC_TRUE;
- *cut = ISC_TRUE;
- if (unsecure != NULL) {
- /*
- * We are at the zonecut. Check to see if there
- * is a DS RRset.
- */
- if (dns_db_find(db, name, ver, dns_rdatatype_ds, 0,
- (isc_stdtime_t) 0, NULL,
- dns_fixedname_name(&foundname),
- NULL, NULL) == DNS_R_NXRRSET)
- *unsecure = ISC_TRUE;
- else
- *unsecure = ISC_FALSE;
- }
- return (ISC_R_SUCCESS);
- } else if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
- result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
- *flag = ISC_FALSE;
- *cut = ISC_FALSE;
- if (unsecure != NULL)
- *unsecure = ISC_FALSE;
- return (ISC_R_SUCCESS);
- } else {
- /*
- * Silence compiler.
- */
- *flag = ISC_FALSE;
- *cut = ISC_FALSE;
- if (unsecure != NULL)
- *unsecure = ISC_FALSE;
- return (result);
- }
-}
-
-/*%
- * Find the next/previous name that has a NSEC record.
- * In other words, skip empty database nodes and names that
- * have had their NSECs removed because they are obscured by
- * a zone cut.
- */
-static isc_result_t
-next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *ver, dns_name_t *oldname, dns_name_t *newname,
- isc_boolean_t forward)
-{
- isc_result_t result;
- dns_dbiterator_t *dbit = NULL;
- isc_boolean_t has_nsec = ISC_FALSE;
- unsigned int wraps = 0;
- isc_boolean_t secure = dns_db_issecure(db);
-
- CHECK(dns_db_createiterator(db, 0, &dbit));
-
- CHECK(dns_dbiterator_seek(dbit, oldname));
- do {
- dns_dbnode_t *node = NULL;
-
- if (forward)
- result = dns_dbiterator_next(dbit);
- else
- result = dns_dbiterator_prev(dbit);
- if (result == ISC_R_NOMORE) {
- /*
- * Wrap around.
- */
- if (forward)
- CHECK(dns_dbiterator_first(dbit));
- else
- CHECK(dns_dbiterator_last(dbit));
- wraps++;
- if (wraps == 2) {
- update_log(client, zone, ISC_LOG_ERROR,
- "secure zone with no NSECs");
- result = DNS_R_BADZONE;
- goto failure;
- }
- }
- CHECK(dns_dbiterator_current(dbit, &node, newname));
- dns_db_detachnode(db, &node);
-
- /*
- * The iterator may hold the tree lock, and
- * rrset_exists() calls dns_db_findnode() which
- * may try to reacquire it. To avoid deadlock
- * we must pause the iterator first.
- */
- CHECK(dns_dbiterator_pause(dbit));
- if (secure) {
- CHECK(rrset_exists(db, ver, newname,
- dns_rdatatype_nsec, 0, &has_nsec));
- } else {
- dns_fixedname_t ffound;
- dns_name_t *found;
- dns_fixedname_init(&ffound);
- found = dns_fixedname_name(&ffound);
- result = dns_db_find(db, newname, ver,
- dns_rdatatype_soa,
- DNS_DBFIND_NOWILD, 0, NULL, found,
- NULL, NULL);
- if (result == ISC_R_SUCCESS ||
- result == DNS_R_EMPTYNAME ||
- result == DNS_R_NXRRSET ||
- result == DNS_R_CNAME ||
- (result == DNS_R_DELEGATION &&
- dns_name_equal(newname, found))) {
- has_nsec = ISC_TRUE;
- result = ISC_R_SUCCESS;
- } else if (result != DNS_R_NXDOMAIN)
- break;
- }
- } while (! has_nsec);
- failure:
- if (dbit != NULL)
- dns_dbiterator_destroy(&dbit);
-
- return (result);
-}
-
-/*%
- * Add a NSEC record for "name", recording the change in "diff".
- * The existing NSEC is removed.
- */
-static isc_result_t
-add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *ver, dns_name_t *name, dns_ttl_t nsecttl,
- dns_diff_t *diff)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- unsigned char buffer[DNS_NSEC_BUFFERSIZE];
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_difftuple_t *tuple = NULL;
- dns_fixedname_t fixedname;
- dns_name_t *target;
-
- dns_fixedname_init(&fixedname);
- target = dns_fixedname_name(&fixedname);
-
- /*
- * Find the successor name, aka NSEC target.
- */
- CHECK(next_active(client, zone, db, ver, name, target, ISC_TRUE));
-
- /*
- * Create the NSEC RDATA.
- */
- CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
- dns_rdata_init(&rdata);
- CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata));
- dns_db_detachnode(db, &node);
-
- /*
- * Delete the old NSEC and record the change.
- */
- CHECK(delete_if(true_p, db, ver, name, dns_rdatatype_nsec, 0,
- NULL, diff));
- /*
- * Add the new NSEC and record the change.
- */
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,
- nsecttl, &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- INSIST(tuple == NULL);
-
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-/*%
- * Add a placeholder NSEC record for "name", recording the change in "diff".
- */
-static isc_result_t
-add_placeholder_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_diff_t *diff)
-{
- isc_result_t result;
- dns_difftuple_t *tuple = NULL;
- isc_region_t r;
- unsigned char data[1] = { 0 }; /* The root domain, no bits. */
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- r.base = data;
- r.length = sizeof(data);
- dns_rdata_fromregion(&rdata, dns_db_class(db), dns_rdatatype_nsec, &r);
- CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name, 0,
- &rdata, &tuple));
- CHECK(do_one_tuple(&tuple, db, ver, diff));
- failure:
- return (result);
-}
-
-static isc_result_t
-find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
- isc_mem_t *mctx, unsigned int maxkeys,
- dst_key_t **keys, unsigned int *nkeys)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- const char *directory = dns_zone_getkeydirectory(zone);
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- CHECK(dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
- directory, mctx, maxkeys, keys, nkeys));
- failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-/*%
- * Add RRSIG records for an RRset, recording the change in "diff".
- */
-static isc_result_t
-add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *ver, dns_name_t *name, dns_rdatatype_t type,
- dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys,
- isc_stdtime_t inception, isc_stdtime_t expire,
- isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t sig_rdata = DNS_RDATA_INIT;
- isc_buffer_t buffer;
- unsigned char data[1024]; /* XXX */
- unsigned int i, j;
- isc_boolean_t added_sig = ISC_FALSE;
- isc_mem_t *mctx = client->mctx;
-
- dns_rdataset_init(&rdataset);
- isc_buffer_init(&buffer, data, sizeof(data));
-
- /* Get the rdataset to sign. */
- if (type == dns_rdatatype_nsec3)
- CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
- else
- CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
- CHECK(dns_db_findrdataset(db, node, ver, type, 0,
- (isc_stdtime_t) 0, &rdataset, NULL));
- dns_db_detachnode(db, &node);
-
-#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
-#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
-#define ALG(x) dst_key_alg(x)
-
- /*
- * If we are honoring KSK flags then we need to check that we
- * have both KSK and non-KSK keys that are not revoked per
- * algorithm.
- */
- for (i = 0; i < nkeys; i++) {
- isc_boolean_t both = ISC_FALSE;
-
- if (!dst_key_isprivate(keys[i]))
- continue;
-
- if (check_ksk && !REVOKE(keys[i])) {
- isc_boolean_t have_ksk, have_nonksk;
- if (KSK(keys[i])) {
- have_ksk = ISC_TRUE;
- have_nonksk = ISC_FALSE;
- } else {
- have_ksk = ISC_FALSE;
- have_nonksk = ISC_TRUE;
- }
- for (j = 0; j < nkeys; j++) {
- if (j == i || ALG(keys[i]) != ALG(keys[j]))
- continue;
- if (REVOKE(keys[j]))
- continue;
- if (KSK(keys[j]))
- have_ksk = ISC_TRUE;
- else
- have_nonksk = ISC_TRUE;
- both = have_ksk && have_nonksk;
- if (both)
- break;
- }
- }
-
- if (both) {
- if (type == dns_rdatatype_dnskey) {
- if (!KSK(keys[i]) && keyset_kskonly)
- continue;
- } else if (KSK(keys[i]))
- continue;
- } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
- continue;
-
- /* Calculate the signature, creating a RRSIG RDATA. */
- CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
- &inception, &expire,
- mctx, &buffer, &sig_rdata));
-
- /* Update the database and journal with the RRSIG. */
- /* XXX inefficient - will cause dataset merging */
- CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
- rdataset.ttl, &sig_rdata));
- dns_rdata_reset(&sig_rdata);
- isc_buffer_init(&buffer, data, sizeof(data));
- added_sig = ISC_TRUE;
- }
- if (!added_sig) {
- update_log(client, zone, ISC_LOG_ERROR,
- "found no active private keys, "
- "unable to generate any signatures");
- result = ISC_R_NOTFOUND;
- }
-
- failure:
- if (dns_rdataset_isassociated(&rdataset))
- dns_rdataset_disassociate(&rdataset);
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-/*
- * Delete expired RRsigs and any RRsigs we are about to re-sign.
- * See also zone.c:del_sigs().
- */
-static isc_result_t
-del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys)
-{
- isc_result_t result;
- dns_dbnode_t *node = NULL;
- dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- unsigned int i;
- dns_rdata_rrsig_t rrsig;
- isc_boolean_t found;
-
- dns_rdataset_init(&rdataset);
-
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- goto failure;
- result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig,
- dns_rdatatype_dnskey, (isc_stdtime_t) 0,
- &rdataset, NULL);
- dns_db_detachnode(db, &node);
-
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- goto failure;
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset)) {
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- found = ISC_FALSE;
- for (i = 0; i < nkeys; i++) {
- if (rrsig.keyid == dst_key_id(keys[i])) {
- found = ISC_TRUE;
- if (!dst_key_isprivate(keys[i])) {
- /*
- * The re-signing code in zone.c
- * will mark this as offline.
- * Just skip the record for now.
- */
- break;
- }
- result = update_one_rr(db, ver, diff,
- DNS_DIFFOP_DEL, name,
- rdataset.ttl, &rdata);
- break;
- }
- }
- /*
- * If there is not a matching DNSKEY then delete the RRSIG.
- */
- if (!found)
- result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
- name, rdataset.ttl, &rdata);
- dns_rdata_reset(&rdata);
- if (result != ISC_R_SUCCESS)
- break;
- }
- dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-failure:
- if (node != NULL)
- dns_db_detachnode(db, &node);
- return (result);
-}
-
-static isc_result_t
-add_exposed_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *ver, dns_name_t *name, isc_boolean_t cut,
- dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys,
- isc_stdtime_t inception, isc_stdtime_t expire,
- isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly)
-{
- isc_result_t result;
- dns_dbnode_t *node;
- dns_rdatasetiter_t *iter;
-
- node = NULL;
- result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- iter = NULL;
- result = dns_db_allrdatasets(db, node, ver,
- (isc_stdtime_t) 0, &iter);
- if (result != ISC_R_SUCCESS)
- goto cleanup_node;
-
- for (result = dns_rdatasetiter_first(iter);
- result == ISC_R_SUCCESS;
- result = dns_rdatasetiter_next(iter))
- {
- dns_rdataset_t rdataset;
- dns_rdatatype_t type;
- isc_boolean_t flag;
-
- dns_rdataset_init(&rdataset);
- dns_rdatasetiter_current(iter, &rdataset);
- type = rdataset.type;
- dns_rdataset_disassociate(&rdataset);
-
- /*
- * We don't need to sign unsigned NSEC records at the cut
- * as they are handled elsewhere.
- */
- if ((type == dns_rdatatype_rrsig) ||
- (cut && type != dns_rdatatype_ds))
- continue;
- result = rrset_exists(db, ver, name, dns_rdatatype_rrsig,
- type, &flag);
- if (result != ISC_R_SUCCESS)
- goto cleanup_iterator;
- if (flag)
- continue;;
- result = add_sigs(client, zone, db, ver, name, type, diff,
- keys, nkeys, inception, expire,
- check_ksk, keyset_kskonly);
- if (result != ISC_R_SUCCESS)
- goto cleanup_iterator;
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
-
- cleanup_iterator:
- dns_rdatasetiter_destroy(&iter);
-
- cleanup_node:
- dns_db_detachnode(db, &node);
-
- return (result);
-}
-
-/*%
- * Update RRSIG, NSEC and NSEC3 records affected by an update. The original
- * update, including the SOA serial update but excluding the RRSIG & NSEC
- * changes, is in "diff" and has already been applied to "newver" of "db".
- * The database version prior to the update is "oldver".
- *
- * The necessary RRSIG, NSEC and NSEC3 changes will be applied to "newver"
- * and added (as a minimal diff) to "diff".
- *
- * The RRSIGs generated will be valid for 'sigvalidityinterval' seconds.
- */
-static isc_result_t
-update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
- dns_dbversion_t *oldver, dns_dbversion_t *newver,
- dns_diff_t *diff, isc_uint32_t sigvalidityinterval)
-{
- isc_result_t result;
- dns_difftuple_t *t;
- dns_diff_t diffnames;
- dns_diff_t affected;
- dns_diff_t sig_diff;
- dns_diff_t nsec_diff;
- dns_diff_t nsec_mindiff;
- isc_boolean_t flag, build_nsec, build_nsec3;
- dst_key_t *zone_keys[DNS_MAXZONEKEYS];
- unsigned int nkeys = 0;
- unsigned int i;
- isc_stdtime_t now, inception, expire;
- dns_ttl_t nsecttl;
- dns_rdata_soa_t soa;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t rdataset;
- dns_dbnode_t *node = NULL;
- isc_boolean_t check_ksk, keyset_kskonly;
- isc_boolean_t unsecure;
- isc_boolean_t cut;
- dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
-
- dns_diff_init(client->mctx, &diffnames);
- dns_diff_init(client->mctx, &affected);
-
- dns_diff_init(client->mctx, &sig_diff);
- sig_diff.resign = dns_zone_getsigresigninginterval(zone);
- dns_diff_init(client->mctx, &nsec_diff);
- dns_diff_init(client->mctx, &nsec_mindiff);
-
- result = find_zone_keys(zone, db, newver, client->mctx,
- DNS_MAXZONEKEYS, zone_keys, &nkeys);
- if (result != ISC_R_SUCCESS) {
- update_log(client, zone, ISC_LOG_ERROR,
- "could not get zone keys for secure dynamic update");
- goto failure;
- }
-
- isc_stdtime_get(&now);
- inception = now - 3600; /* Allow for some clock skew. */
- expire = now + sigvalidityinterval;
-
- /*
- * Do we look at the KSK flag on the DNSKEY to determining which
- * keys sign which RRsets? First check the zone option then
- * check the keys flags to make sure at least one has a ksk set
- * and one doesn't.
- */
- check_ksk = ISC_TF((dns_zone_getoptions(zone) &
- DNS_ZONEOPT_UPDATECHECKKSK) != 0);
- keyset_kskonly = ISC_TF((dns_zone_getoptions(zone) &
- DNS_ZONEOPT_DNSKEYKSKONLY) != 0);
-
- /*
- * Get the NSEC/NSEC3 TTL from the SOA MINIMUM field.
- */
- CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
- dns_rdataset_init(&rdataset);
- CHECK(dns_db_findrdataset(db, node, newver, dns_rdatatype_soa, 0,
- (isc_stdtime_t) 0, &rdataset, NULL));
- CHECK(dns_rdataset_first(&rdataset));
- dns_rdataset_current(&rdataset, &rdata);
- CHECK(dns_rdata_tostruct(&rdata, &soa, NULL));
- nsecttl = soa.minimum;
- dns_rdataset_disassociate(&rdataset);
- dns_db_detachnode(db, &node);
-
- /*
- * Find all RRsets directly affected by the update, and
- * update their RRSIGs. Also build a list of names affected
- * by the update in "diffnames".
- */
- CHECK(dns_diff_sort(diff, temp_order));
-
- t = ISC_LIST_HEAD(diff->tuples);
- while (t != NULL) {
- dns_name_t *name = &t->name;
- /* Now "name" is a new, unique name affected by the update. */
-
- CHECK(namelist_append_name(&diffnames, name));
-
- while (t != NULL && dns_name_equal(&t->name, name)) {
- dns_rdatatype_t type;
- type = t->rdata.type;
-
- /*
- * Now "name" and "type" denote a new unique RRset
- * affected by the update.
- */
-
- /* Don't sign RRSIGs. */
- if (type == dns_rdatatype_rrsig)
- goto skip;
-
- /*
- * Delete all old RRSIGs covering this type, since they
- * are all invalid when the signed RRset has changed.
- * We may not be able to recreate all of them - tough.
- * Special case changes to the zone's DNSKEY records
- * to support offline KSKs.
- */
- if (type == dns_rdatatype_dnskey)
- del_keysigs(db, newver, name, &sig_diff,
- zone_keys, nkeys);
- else
- CHECK(delete_if(true_p, db, newver, name,
- dns_rdatatype_rrsig, type,
- NULL, &sig_diff));
-
- /*
- * If this RRset is still visible after the update,
- * add a new signature for it.
- */
- CHECK(rrset_visible(db, newver, name, type, &flag));
- if (flag) {
- CHECK(add_sigs(client, zone, db, newver, name,
- type, &sig_diff, zone_keys,
- nkeys, inception, expire,
- check_ksk, keyset_kskonly));
- }
- skip:
- /* Skip any other updates to the same RRset. */
- while (t != NULL &&
- dns_name_equal(&t->name, name) &&
- t->rdata.type == type)
- {
- t = ISC_LIST_NEXT(t, link);
- }
- }
- }
- update_log(client, zone, ISC_LOG_DEBUG(3), "updated data signatures");
-
- /* Remove orphaned NSECs and RRSIG NSECs. */
- for (t = ISC_LIST_HEAD(diffnames.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- CHECK(non_nsec_rrset_exists(db, newver, &t->name, &flag));
- if (! flag) {
- CHECK(delete_if(true_p, db, newver, &t->name,
- dns_rdatatype_any, 0,
- NULL, &sig_diff));
- }
- }
- update_log(client, zone, ISC_LOG_DEBUG(3),
- "removed any orphaned NSEC records");
-
- /*
- * See if we need to build NSEC or NSEC3 chains.
- */
- CHECK(dns_private_chains(db, newver, privatetype, &build_nsec,
- &build_nsec3));
- if (!build_nsec)
- goto update_nsec3;
-
- update_log(client, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC chain");
-
- /*
- * When a name is created or deleted, its predecessor needs to
- * have its NSEC updated.
- */
- for (t = ISC_LIST_HEAD(diffnames.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_boolean_t existed, exists;
- dns_fixedname_t fixedname;
- dns_name_t *prevname;
-
- dns_fixedname_init(&fixedname);
- prevname = dns_fixedname_name(&fixedname);
-
- CHECK(name_exists(db, oldver, &t->name, &existed));
- CHECK(name_exists(db, newver, &t->name, &exists));
- if (exists == existed)
- continue;
-
- /*
- * Find the predecessor.
- * When names become obscured or unobscured in this update
- * transaction, we may find the wrong predecessor because
- * the NSECs have not yet been updated to reflect the delegation
- * change. This should not matter because in this case,
- * the correct predecessor is either the delegation node or
- * a newly unobscured node, and those nodes are on the
- * "affected" list in any case.
- */
- CHECK(next_active(client, zone, db, newver,
- &t->name, prevname, ISC_FALSE));
- CHECK(namelist_append_name(&affected, prevname));
- }
-
- /*
- * Find names potentially affected by delegation changes
- * (obscured by adding an NS or DNAME, or unobscured by
- * removing one).
- */
- for (t = ISC_LIST_HEAD(diffnames.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_boolean_t ns_existed, dname_existed;
- isc_boolean_t ns_exists, dname_exists;
-
- CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_ns, 0,
- &ns_existed));
- CHECK(rrset_exists(db, oldver, &t->name, dns_rdatatype_dname, 0,
- &dname_existed));
- CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_ns, 0,
- &ns_exists));
- CHECK(rrset_exists(db, newver, &t->name, dns_rdatatype_dname, 0,
- &dname_exists));
- if ((ns_exists || dname_exists) == (ns_existed || dname_existed))
- continue;
- /*
- * There was a delegation change. Mark all subdomains
- * of t->name as potentially needing a NSEC update.
- */
- CHECK(namelist_append_subdomain(db, &t->name, &affected));
- }
-
- ISC_LIST_APPENDLIST(affected.tuples, diffnames.tuples, link);
- INSIST(ISC_LIST_EMPTY(diffnames.tuples));
-
- CHECK(uniqify_name_list(&affected));
-
- /*
- * Determine which names should have NSECs, and delete/create
- * NSECs to make it so. We don't know the final NSEC targets yet,
- * so we just create placeholder NSECs with arbitrary contents
- * to indicate that their respective owner names should be part of
- * the NSEC chain.
- */
- for (t = ISC_LIST_HEAD(affected.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- isc_boolean_t exists;
- dns_name_t *name = &t->name;
-
- CHECK(name_exists(db, newver, name, &exists));
- if (! exists)
- continue;
- CHECK(is_active(db, newver, name, &flag, &cut, NULL));
- if (!flag) {
- /*
- * This name is obscured. Delete any
- * existing NSEC record.
- */
- CHECK(delete_if(true_p, db, newver, name,
- dns_rdatatype_nsec, 0,
- NULL, &nsec_diff));
- CHECK(delete_if(rrsig_p, db, newver, name,
- dns_rdatatype_any, 0, NULL, diff));
- } else {
- /*
- * This name is not obscured. It needs to have a
- * NSEC unless it is the at the origin, in which
- * case it should already exist if there is a complete
- * NSEC chain and if there isn't a complete NSEC chain
- * we don't want to add one as that would signal that
- * there is a complete NSEC chain.
- */
- if (!dns_name_equal(name, dns_db_origin(db))) {
- CHECK(rrset_exists(db, newver, name,
- dns_rdatatype_nsec, 0,
- &flag));
- if (!flag)
- CHECK(add_placeholder_nsec(db, newver,
- name, diff));
- }
- CHECK(add_exposed_sigs(client, zone, db, newver, name,
- cut, &sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk,
- keyset_kskonly));
- }
- }
-
- /*
- * Now we know which names are part of the NSEC chain.
- * Make them all point at their correct targets.
- */
- for (t = ISC_LIST_HEAD(affected.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- CHECK(rrset_exists(db, newver, &t->name,
- dns_rdatatype_nsec, 0, &flag));
- if (flag) {
- /*
- * There is a NSEC, but we don't know if it is correct.
- * Delete it and create a correct one to be sure.
- * If the update was unnecessary, the diff minimization
- * will take care of eliminating it from the journal,
- * IXFRs, etc.
- *
- * The RRSIG bit should always be set in the NSECs
- * we generate, because they will all get RRSIG NSECs.
- * (XXX what if the zone keys are missing?).
- * Because the RRSIG NSECs have not necessarily been
- * created yet, the correctness of the bit mask relies
- * on the assumption that NSECs are only created if
- * there is other data, and if there is other data,
- * there are other RRSIGs.
- */
- CHECK(add_nsec(client, zone, db, newver, &t->name,
- nsecttl, &nsec_diff));
- }
- }
-
- /*
- * Minimize the set of NSEC updates so that we don't
- * have to regenerate the RRSIG NSECs for NSECs that were
- * replaced with identical ones.
- */
- while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_diff.tuples, t, link);
- dns_diff_appendminimal(&nsec_mindiff, &t);
- }
-
- update_log(client, zone, ISC_LOG_DEBUG(3),
- "signing rebuilt NSEC chain");
-
- /* Update RRSIG NSECs. */
- for (t = ISC_LIST_HEAD(nsec_mindiff.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- if (t->op == DNS_DIFFOP_DEL) {
- CHECK(delete_if(true_p, db, newver, &t->name,
- dns_rdatatype_rrsig, dns_rdatatype_nsec,
- NULL, &sig_diff));
- } else if (t->op == DNS_DIFFOP_ADD) {
- CHECK(add_sigs(client, zone, db, newver, &t->name,
- dns_rdatatype_nsec, &sig_diff,
- zone_keys, nkeys, inception, expire,
- check_ksk, keyset_kskonly));
- } else {
- INSIST(0);
- }
- }
-
- update_nsec3:
-
- /* Record our changes for the journal. */
- while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(sig_diff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
- while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
-
- INSIST(ISC_LIST_EMPTY(sig_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples));
-
- if (!build_nsec3) {
- update_log(client, zone, ISC_LOG_DEBUG(3),
- "no NSEC3 chains to rebuild");
- goto failure;
- }
-
- update_log(client, zone, ISC_LOG_DEBUG(3), "rebuilding NSEC3 chains");
-
- dns_diff_clear(&diffnames);
- dns_diff_clear(&affected);
-
- CHECK(dns_diff_sort(diff, temp_order));
-
- /*
- * Find names potentially affected by delegation changes
- * (obscured by adding an NS or DNAME, or unobscured by
- * removing one).
- */
- t = ISC_LIST_HEAD(diff->tuples);
- while (t != NULL) {
- dns_name_t *name = &t->name;
-
- isc_boolean_t ns_existed, dname_existed;
- isc_boolean_t ns_exists, dname_exists;
- isc_boolean_t exists, existed;
-
- if (t->rdata.type == dns_rdatatype_nsec ||
- t->rdata.type == dns_rdatatype_rrsig) {
- t = ISC_LIST_NEXT(t, link);
- continue;
- }
-
- CHECK(namelist_append_name(&affected, name));
-
- CHECK(rrset_exists(db, oldver, name, dns_rdatatype_ns, 0,
- &ns_existed));
- CHECK(rrset_exists(db, oldver, name, dns_rdatatype_dname, 0,
- &dname_existed));
- CHECK(rrset_exists(db, newver, name, dns_rdatatype_ns, 0,
- &ns_exists));
- CHECK(rrset_exists(db, newver, name, dns_rdatatype_dname, 0,
- &dname_exists));
-
- exists = ns_exists || dname_exists;
- existed = ns_existed || dname_existed;
- if (exists == existed)
- goto nextname;
- /*
- * There was a delegation change. Mark all subdomains
- * of t->name as potentially needing a NSEC3 update.
- */
- CHECK(namelist_append_subdomain(db, name, &affected));
-
- nextname:
- while (t != NULL && dns_name_equal(&t->name, name))
- t = ISC_LIST_NEXT(t, link);
- }
-
- for (t = ISC_LIST_HEAD(affected.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link)) {
- dns_name_t *name = &t->name;
-
- unsecure = ISC_FALSE; /* Silence compiler warning. */
- CHECK(is_active(db, newver, name, &flag, &cut, &unsecure));
-
- if (!flag) {
- CHECK(delete_if(rrsig_p, db, newver, name,
- dns_rdatatype_any, 0, NULL, diff));
- CHECK(dns_nsec3_delnsec3sx(db, newver, name,
- privatetype, &nsec_diff));
- } else {
- CHECK(add_exposed_sigs(client, zone, db, newver, name,
- cut, &sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk,
- keyset_kskonly));
- CHECK(dns_nsec3_addnsec3sx(db, newver, name, nsecttl,
- unsecure, privatetype,
- &nsec_diff));
- }
- }
-
- /*
- * Minimize the set of NSEC3 updates so that we don't
- * have to regenerate the RRSIG NSEC3s for NSEC3s that were
- * replaced with identical ones.
- */
- while ((t = ISC_LIST_HEAD(nsec_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_diff.tuples, t, link);
- dns_diff_appendminimal(&nsec_mindiff, &t);
- }
-
- update_log(client, zone, ISC_LOG_DEBUG(3),
- "signing rebuilt NSEC3 chain");
-
- /* Update RRSIG NSEC3s. */
- for (t = ISC_LIST_HEAD(nsec_mindiff.tuples);
- t != NULL;
- t = ISC_LIST_NEXT(t, link))
- {
- if (t->op == DNS_DIFFOP_DEL) {
- CHECK(delete_if(true_p, db, newver, &t->name,
- dns_rdatatype_rrsig,
- dns_rdatatype_nsec3,
- NULL, &sig_diff));
- } else if (t->op == DNS_DIFFOP_ADD) {
- CHECK(add_sigs(client, zone, db, newver, &t->name,
- dns_rdatatype_nsec3,
- &sig_diff, zone_keys, nkeys,
- inception, expire, check_ksk,
- keyset_kskonly));
- } else {
- INSIST(0);
- }
- }
-
- /* Record our changes for the journal. */
- while ((t = ISC_LIST_HEAD(sig_diff.tuples)) != NULL) {
- ISC_LIST_UNLINK(sig_diff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
- while ((t = ISC_LIST_HEAD(nsec_mindiff.tuples)) != NULL) {
- ISC_LIST_UNLINK(nsec_mindiff.tuples, t, link);
- dns_diff_appendminimal(diff, &t);
- }
-
- INSIST(ISC_LIST_EMPTY(sig_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_diff.tuples));
- INSIST(ISC_LIST_EMPTY(nsec_mindiff.tuples));
-
- failure:
- dns_diff_clear(&sig_diff);
- dns_diff_clear(&nsec_diff);
- dns_diff_clear(&nsec_mindiff);
-
- dns_diff_clear(&affected);
- dns_diff_clear(&diffnames);
-
- for (i = 0; i < nkeys; i++)
- dst_key_free(&zone_keys[i]);
-
- return (result);
-}
-
-
-/**************************************************************************/
/*%
* The actual update code in all its glory. We try to follow
* the RFC2136 pseudocode as closely as possible.
@@ -2686,7 +1515,7 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
isc_result_t result;
dns_name_t *zonename;
dns_rdataset_t *zone_rdataset;
- dns_zone_t *zone = NULL;
+ dns_zone_t *zone = NULL, *raw = NULL;
/*
* Interpret the zone section.
@@ -2720,6 +1549,17 @@ ns_update_start(ns_client_t *client, isc_result_t sigresult) {
if (result != ISC_R_SUCCESS)
FAILC(DNS_R_NOTAUTH, "not authoritative for update zone");
+ /*
+ * If there is a raw (unsigned) zone associated with this
+ * zone then it processes the UPDATE request.
+ */
+ dns_zone_getraw(zone, &raw);
+ if (raw != NULL) {
+ dns_zone_detach(&zone);
+ dns_zone_attach(raw, &zone);
+ dns_zone_detach(&raw);
+ }
+
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
case dns_zone_dlz:
@@ -3066,8 +1906,19 @@ check_dnssec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
}
/* Check existing DB for NSEC-only DNSKEY */
- if (!nseconly)
- CHECK(dns_nsec_nseconly(db, ver, &nseconly));
+ if (!nseconly) {
+ result = dns_nsec_nseconly(db, ver, &nseconly);
+
+ /*
+ * An NSEC3PARAM update can proceed without a DNSKEY (it
+ * will trigger a delayed change), so we can ignore
+ * ISC_R_NOTFOUND here.
+ */
+ if (result == ISC_R_NOTFOUND)
+ result = ISC_R_SUCCESS;
+
+ CHECK(result);
+ }
/* Check existing DB for NSEC3 */
if (!nsec3)
@@ -3238,9 +2089,11 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
ttl_good = ISC_TRUE;
}
if (tuple->op == DNS_DIFFOP_ADD) {
+ isc_boolean_t nseconly = ISC_FALSE;
+
/*
* Look for any deletes which match this ADD ignoring
- * OPTOUT. We don't need to explictly remove them as
+ * flags. We don't need to explictly remove them as
* they will be removed a side effect of processing
* the add.
*/
@@ -3262,12 +2115,28 @@ add_nsec3param_records(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
ISC_LIST_APPEND(diff->tuples, next, link);
next = ISC_LIST_HEAD(temp_diff.tuples);
}
+
/*
- * See if we already have a CREATE request in progress.
+ * Create a private-type record to signal that
+ * we want a delayed NSEC3 chain add/delete
*/
dns_nsec3param_toprivate(&tuple->rdata, &rdata,
privatetype, buf, sizeof(buf));
buf[2] |= DNS_NSEC3FLAG_CREATE;
+
+ /*
+ * If the zone is not currently capable of
+ * supporting an NSEC3 chain, then we set the
+ * INITIAL flag to indicate that these parameters
+ * are to be used later.
+ */
+ result = dns_nsec_nseconly(db, ver, &nseconly);
+ if (result == ISC_R_NOTFOUND || nseconly)
+ buf[2] |= DNS_NSEC3FLAG_INITIAL;
+
+ /*
+ * See if this CREATE request already exists.
+ */
CHECK(rr_exists(db, ver, name, &rdata, &flag));
if (!flag) {
@@ -3379,7 +2248,7 @@ rollback_private(dns_db_t *db, dns_rdatatype_t privatetype,
/*
* Allow records which indicate that a zone has been
- * signed with a DNSKEY to be be removed.
+ * signed with a DNSKEY to be removed.
*/
if (tuple->op == DNS_DIFFOP_DEL &&
tuple->rdata.length == 5 &&
@@ -4157,7 +3026,8 @@ update_action(isc_task_t *task, isc_event_t *event) {
* changed as a result of an update operation.
*/
if (! soa_serial_changed) {
- CHECK(increment_soa_serial(db, ver, &diff, mctx));
+ CHECK(update_soa_serial(db, ver, &diff, mctx,
+ dns_zone_getserialupdatemethod(zone)));
}
CHECK(check_mx(client, zone, db, ver, &diff));
@@ -4191,7 +3061,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
CHECK(add_nsec3param_records(client, zone, db, ver, &diff));
- if (!has_dnskey) {
+ if (had_dnskey && !has_dnskey) {
/*
* We are transitioning from secure to insecure.
* Cause all NSEC3 chains to be deleted. When the
@@ -4199,12 +3069,17 @@ update_action(isc_task_t *task, isc_event_t *event) {
* remove any NSEC chain present will also be removed.
*/
CHECK(dns_nsec3param_deletechains(db, ver, zone,
- &diff));
+ ISC_TRUE, &diff));
} else if (has_dnskey && isdnssec(db, ver, privatetype)) {
isc_uint32_t interval;
+ dns_update_log_t log;
+
interval = dns_zone_getsigvalidityinterval(zone);
- result = update_signatures(client, zone, db, oldver,
- ver, &diff, interval);
+ log.func = update_log_cb;
+ log.arg = client;
+ result = dns_update_signatures(&log, zone, db, oldver,
+ ver, &diff, interval);
+
if (result != ISC_R_SUCCESS) {
update_log(client, zone,
ISC_LOG_ERROR,
@@ -4221,7 +3096,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
journal = NULL;
result = dns_journal_open(mctx, journalfile,
- ISC_TRUE, &journal);
+ DNS_JOURNAL_CREATE, &journal);
if (result != ISC_R_SUCCESS)
FAILS(result, "journal open failed");
diff --git a/contrib/bind9/bin/named/xfrout.c b/contrib/bind9/bin/named/xfrout.c
index 0363500..a0a617d 100644
--- a/contrib/bind9/bin/named/xfrout.c
+++ b/contrib/bind9/bin/named/xfrout.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011, 2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: xfrout.c,v 1.139.16.4 2011/12/01 01:00:50 marka Exp $ */
+/* $Id$ */
#include <config.h>
@@ -247,12 +247,13 @@ ixfr_rrstream_create(isc_mem_t *mctx,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
return (ISC_R_NOMEMORY);
- s->common.mctx = mctx;
+ s->common.mctx = NULL;
+ isc_mem_attach(mctx, &s->common.mctx);
s->common.methods = &ixfr_rrstream_methods;
s->journal = NULL;
CHECK(dns_journal_open(mctx, journal_filename,
- ISC_FALSE, &s->journal));
+ DNS_JOURNAL_READ, &s->journal));
CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial));
*sp = (rrstream_t *) s;
@@ -289,7 +290,7 @@ ixfr_rrstream_destroy(rrstream_t **rsp) {
ixfr_rrstream_t *s = (ixfr_rrstream_t *) *rsp;
if (s->journal != 0)
dns_journal_destroy(&s->journal);
- isc_mem_put(s->common.mctx, s, sizeof(*s));
+ isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
}
static rrstream_methods_t ixfr_rrstream_methods = {
@@ -335,7 +336,8 @@ axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
return (ISC_R_NOMEMORY);
- s->common.mctx = mctx;
+ s->common.mctx = NULL;
+ isc_mem_attach(mctx, &s->common.mctx);
s->common.methods = &axfr_rrstream_methods;
s->it_valid = ISC_FALSE;
@@ -413,7 +415,7 @@ axfr_rrstream_destroy(rrstream_t **rsp) {
axfr_rrstream_t *s = (axfr_rrstream_t *) *rsp;
if (s->it_valid)
dns_rriterator_destroy(&s->it);
- isc_mem_put(s->common.mctx, s, sizeof(*s));
+ isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
}
static rrstream_methods_t axfr_rrstream_methods = {
@@ -455,7 +457,8 @@ soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
return (ISC_R_NOMEMORY);
- s->common.mctx = mctx;
+ s->common.mctx = NULL;
+ isc_mem_attach(mctx, &s->common.mctx);
s->common.methods = &soa_rrstream_methods;
s->soa_tuple = NULL;
@@ -497,7 +500,7 @@ soa_rrstream_destroy(rrstream_t **rsp) {
soa_rrstream_t *s = (soa_rrstream_t *) *rsp;
if (s->soa_tuple != NULL)
dns_difftuple_free(&s->soa_tuple);
- isc_mem_put(s->common.mctx, s, sizeof(*s));
+ isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
}
static rrstream_methods_t soa_rrstream_methods = {
@@ -561,7 +564,8 @@ compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
return (ISC_R_NOMEMORY);
- s->common.mctx = mctx;
+ s->common.mctx = NULL;
+ isc_mem_attach(mctx, &s->common.mctx);
s->common.methods = &compound_rrstream_methods;
s->components[0] = *soa_stream;
s->components[1] = *data_stream;
@@ -634,7 +638,7 @@ compound_rrstream_destroy(rrstream_t **rsp) {
s->components[0]->methods->destroy(&s->components[0]);
s->components[1]->methods->destroy(&s->components[1]);
s->components[2] = NULL; /* Copy of components[0]. */
- isc_mem_put(s->common.mctx, s, sizeof(*s));
+ isc_mem_putanddetach(&s->common.mctx, s, sizeof(*s));
}
static rrstream_methods_t compound_rrstream_methods = {
diff --git a/contrib/bind9/bin/named/zoneconf.c b/contrib/bind9/bin/named/zoneconf.c
index 404c238..7f36b14 100644
--- a/contrib/bind9/bin/named/zoneconf.c
+++ b/contrib/bind9/bin/named/zoneconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.c,v 1.170.14.7 2012/01/31 23:46:39 tbox Exp $ */
+/* $Id$ */
/*% */
@@ -792,7 +792,7 @@ checknames(dns_zonetype_t ztype, const cfg_obj_t **maps,
isc_result_t
ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const cfg_obj_t *zconfig, cfg_aclconfctx_t *ac,
- dns_zone_t *zone)
+ dns_zone_t *zone, dns_zone_t *raw)
{
isc_result_t result;
const char *zname;
@@ -824,8 +824,12 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
isc_boolean_t ixfrdiff;
dns_masterformat_t masterformat;
isc_stats_t *zoneqrystats;
- isc_boolean_t zonestats_on;
+#ifdef NEWSTATS
+ dns_stats_t *rcvquerystats;
+#endif
+ dns_zonestat_level_t statlevel;
int seconds;
+ dns_zone_t *mayberaw = (raw != NULL) ? raw : zone;
i = 0;
if (zconfig != NULL) {
@@ -857,9 +861,16 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
RETERR(ns_config_getclass(cfg_tuple_get(zconfig, "class"),
vclass, &zclass));
dns_zone_setclass(zone, zclass);
+ if (raw != NULL)
+ dns_zone_setclass(raw, zclass);
ztype = zonetype_fromconfig(zoptions);
- dns_zone_settype(zone, ztype);
+ if (raw != NULL) {
+ dns_zone_settype(raw, ztype);
+ dns_zone_settype(zone, dns_zone_master);
+ } else
+ dns_zone_settype(zone, ztype);
+
obj = NULL;
result = cfg_map_get(zoptions, "database", &obj);
@@ -907,7 +918,10 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
return (ISC_R_FAILURE);
}
- masterformat = dns_masterformat_text;
+ if (ztype == dns_zone_slave)
+ masterformat = dns_masterformat_raw;
+ else
+ masterformat = dns_masterformat_text;
obj = NULL;
result= ns_config_get(maps, "masterfile-format", &obj);
if (result == ISC_R_SUCCESS) {
@@ -920,18 +934,40 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
else
INSIST(0);
}
- RETERR(dns_zone_setfile2(zone, filename, masterformat));
+
+ if (raw != NULL && filename != NULL) {
+#define SIGNED ".signed"
+ size_t signedlen = strlen(filename) + sizeof(SIGNED);
+ char *signedname;
+
+ RETERR(dns_zone_setfile2(raw, filename, masterformat));
+ signedname = isc_mem_get(mctx, signedlen);
+ if (signedname == NULL)
+ return (ISC_R_NOMEMORY);
+
+ (void)snprintf(signedname, signedlen, "%s" SIGNED, filename);
+ result = dns_zone_setfile2(zone, signedname,
+ dns_masterformat_raw);
+ isc_mem_put(mctx, signedname, signedlen);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ } else
+ RETERR(dns_zone_setfile2(zone, filename, masterformat));
obj = NULL;
result = cfg_map_get(zoptions, "journal", &obj);
if (result == ISC_R_SUCCESS)
- RETERR(dns_zone_setjournal(zone, cfg_obj_asstring(obj)));
+ RETERR(dns_zone_setjournal(mayberaw, cfg_obj_asstring(obj)));
+ /*
+ * Notify messages are processed by the raw zone if it exists.
+ */
if (ztype == dns_zone_slave)
RETERR(configure_zone_acl(zconfig, vconfig, config,
- allow_notify, ac, zone,
+ allow_notify, ac, mayberaw,
dns_zone_setnotifyacl,
dns_zone_clearnotifyacl));
+
/*
* XXXAG This probably does not make sense for stubs.
*/
@@ -966,27 +1002,63 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
else
INSIST(0);
}
+ if (raw != NULL)
+ dns_zone_setdialup(raw, dialup);
dns_zone_setdialup(zone, dialup);
obj = NULL;
result = ns_config_get(maps, "zone-statistics", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- zonestats_on = cfg_obj_asboolean(obj);
- zoneqrystats = NULL;
- if (zonestats_on) {
+ if (cfg_obj_isboolean(obj)) {
+ if (cfg_obj_asboolean(obj))
+ statlevel = dns_zonestat_full;
+ else
+ statlevel = dns_zonestat_terse; /* XXX */
+ } else {
+ const char *levelstr = cfg_obj_asstring(obj);
+ if (strcasecmp(levelstr, "full") == 0)
+ statlevel = dns_zonestat_full;
+ else if (strcasecmp(levelstr, "terse") == 0)
+ statlevel = dns_zonestat_terse;
+ else if (strcasecmp(levelstr, "none") == 0)
+ statlevel = dns_zonestat_none;
+ else
+ INSIST(0);
+ }
+ dns_zone_setstatlevel(zone, statlevel);
+
+ zoneqrystats = NULL;
+#ifdef NEWSTATS
+ rcvquerystats = NULL;
+#endif
+ if (statlevel == dns_zonestat_full) {
RETERR(isc_stats_create(mctx, &zoneqrystats,
dns_nsstatscounter_max));
+#ifdef NEWSTATS
+ RETERR(dns_rdatatypestats_create(mctx,
+ &rcvquerystats));
+#endif
}
- dns_zone_setrequeststats(zone, zoneqrystats);
+ dns_zone_setrequeststats(zone, zoneqrystats );
+#ifdef NEWSTATS
+ dns_zone_setrcvquerystats(zone, rcvquerystats);
+#endif
+
if (zoneqrystats != NULL)
isc_stats_detach(&zoneqrystats);
+#ifdef NEWSTATS
+ if(rcvquerystats != NULL)
+ dns_stats_detach(&rcvquerystats);
+#endif
+
/*
* Configure master functionality. This applies
* to primary masters (type "master") and slaves
* acting as masters (type "slave"), but not to stubs.
*/
- if (ztype != dns_zone_stub && ztype != dns_zone_staticstub) {
+ if (ztype != dns_zone_stub && ztype != dns_zone_staticstub &&
+ ztype != dns_zone_redirect) {
obj = NULL;
result = ns_config_get(maps, "notify", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
@@ -1004,22 +1076,28 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
else
INSIST(0);
}
+ if (raw != NULL)
+ dns_zone_setnotifytype(raw, dns_notifytype_no);
dns_zone_setnotifytype(zone, notifytype);
obj = NULL;
result = ns_config_get(maps, "also-notify", &obj);
if (result == ISC_R_SUCCESS) {
- isc_sockaddr_t *addrs = NULL;
isc_uint32_t addrcount;
- result = ns_config_getiplist(config, obj, 0, mctx,
- &addrs, &addrcount);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = dns_zone_setalsonotify(zone, addrs,
- addrcount);
- ns_config_putiplist(mctx, &addrs, addrcount);
- if (result != ISC_R_SUCCESS)
- return (result);
+ addrs = NULL;
+ keynames = NULL;
+ RETERR(ns_config_getipandkeylist(config, obj, mctx,
+ &addrs, &keynames,
+ &addrcount));
+ result = dns_zone_setalsonotifywithkeys(zone, addrs,
+ keynames,
+ addrcount);
+ if (addrcount != 0)
+ ns_config_putipandkeylist(mctx, &addrs,
+ &keynames, addrcount);
+ else
+ INSIST(addrs == NULL && keynames == NULL);
+ RETERR(result);
} else
RETERR(dns_zone_setalsonotify(zone, NULL, 0));
@@ -1059,8 +1137,10 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setidleout(zone, cfg_obj_asuint32(obj) * 60);
obj = NULL;
- result = ns_config_get(maps, "max-journal-size", &obj);
+ result = ns_config_get(maps, "max-journal-size", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ if (raw != NULL)
+ dns_zone_setjournalsize(raw, -1);
dns_zone_setjournalsize(zone, -1);
if (cfg_obj_isstring(obj)) {
const char *str = cfg_obj_asstring(obj);
@@ -1080,6 +1160,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
}
journal_size = (isc_uint32_t)value;
}
+ if (raw != NULL)
+ dns_zone_setjournalsize(raw, journal_size);
dns_zone_setjournalsize(zone, journal_size);
obj = NULL;
@@ -1095,7 +1177,19 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
ixfrdiff = ISC_TRUE;
else
ixfrdiff = ISC_FALSE;
- dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS, ixfrdiff);
+ if (raw != NULL) {
+ dns_zone_setoption(raw, DNS_ZONEOPT_IXFRFROMDIFFS,
+ ISC_TRUE);
+ dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
+ ISC_TRUE);
+ } else
+ dns_zone_setoption(zone, DNS_ZONEOPT_IXFRFROMDIFFS,
+ ixfrdiff);
+
+ obj = NULL;
+ result = ns_config_get(maps, "request-ixfr", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_zone_setrequestixfr(zone, cfg_obj_asboolean(obj));
checknames(ztype, maps, &obj);
INSIST(obj != NULL);
@@ -1108,8 +1202,21 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
fail = check = ISC_FALSE;
} else
INSIST(0);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES, check);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL, fail);
+ if (raw != NULL) {
+ dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMES,
+ check);
+ dns_zone_setoption(raw, DNS_ZONEOPT_CHECKNAMESFAIL,
+ fail);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
+ ISC_FALSE);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
+ ISC_FALSE);
+ } else {
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMES,
+ check);
+ dns_zone_setoption(zone, DNS_ZONEOPT_CHECKNAMESFAIL,
+ fail);
+ }
obj = NULL;
result = ns_config_get(maps, "notify-delay", &obj);
@@ -1143,6 +1250,32 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
cfg_obj_asboolean(obj));
+ } else if (ztype == dns_zone_redirect) {
+ dns_zone_setnotifytype(zone, dns_notifytype_no);
+
+ obj = NULL;
+ result = ns_config_get(maps, "max-journal-size", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setjournalsize(zone, -1);
+ if (cfg_obj_isstring(obj)) {
+ const char *str = cfg_obj_asstring(obj);
+ INSIST(strcasecmp(str, "unlimited") == 0);
+ journal_size = ISC_UINT32_MAX / 2;
+ } else {
+ isc_resourcevalue_t value;
+ value = cfg_obj_asuint64(obj);
+ if (value > ISC_UINT32_MAX / 2) {
+ cfg_obj_log(obj, ns_g_lctx,
+ ISC_LOG_ERROR,
+ "'max-journal-size "
+ "%" ISC_PRINT_QUADFORMAT "d' "
+ "is too large",
+ value);
+ RETERR(ISC_R_RANGE);
+ }
+ journal_size = (isc_uint32_t)value;
+ }
+ dns_zone_setjournalsize(zone, journal_size);
}
/*
@@ -1153,11 +1286,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_acl_t *updateacl;
RETERR(configure_zone_acl(zconfig, vconfig, config,
- allow_update, ac, zone,
+ allow_update, ac, mayberaw,
dns_zone_setupdateacl,
dns_zone_clearupdateacl));
- updateacl = dns_zone_getupdateacl(zone);
+ updateacl = dns_zone_getupdateacl(mayberaw);
if (updateacl != NULL && dns_acl_isinsecure(updateacl))
isc_log_write(ns_g_lctx, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
@@ -1165,7 +1298,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
"address, which is insecure",
zname);
- RETERR(configure_zone_ssutable(zoptions, zone, zname));
+ RETERR(configure_zone_ssutable(zoptions, mayberaw, zname));
+ }
+
+ if (ztype == dns_zone_master || raw != NULL) {
+ isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
obj = NULL;
result = ns_config_get(maps, "sig-validity-interval", &obj);
@@ -1224,10 +1361,34 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setoption(zone, DNS_ZONEOPT_DNSKEYKSKONLY,
cfg_obj_asboolean(obj));
- } else if (ztype == dns_zone_slave) {
+
+ obj = NULL;
+ result = ns_config_get(maps, "dnssec-loadkeys-interval", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ RETERR(dns_zone_setrefreshkeyinterval(zone,
+ cfg_obj_asuint32(obj)));
+
+ obj = NULL;
+ result = cfg_map_get(zoptions, "auto-dnssec", &obj);
+ if (result == ISC_R_SUCCESS) {
+ const char *arg = cfg_obj_asstring(obj);
+ if (strcasecmp(arg, "allow") == 0)
+ allow = ISC_TRUE;
+ else if (strcasecmp(arg, "maintain") == 0)
+ allow = maint = ISC_TRUE;
+ else if (strcasecmp(arg, "off") == 0)
+ ;
+ else
+ INSIST(0);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
+ }
+ }
+
+ if (ztype == dns_zone_slave) {
RETERR(configure_zone_acl(zconfig, vconfig, config,
- allow_update_forwarding, ac, zone,
- dns_zone_setforwardacl,
+ allow_update_forwarding, ac,
+ mayberaw, dns_zone_setforwardacl,
dns_zone_clearforwardacl));
}
@@ -1235,15 +1396,13 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
* Primary master functionality.
*/
if (ztype == dns_zone_master) {
- isc_boolean_t allow = ISC_FALSE, maint = ISC_FALSE;
-
obj = NULL;
result = ns_config_get(maps, "check-wildcard", &obj);
if (result == ISC_R_SUCCESS)
check = cfg_obj_asboolean(obj);
else
check = ISC_FALSE;
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKWILDCARD, check);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKWILDCARD, check);
obj = NULL;
result = ns_config_get(maps, "check-dup-records", &obj);
@@ -1257,8 +1416,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
fail = check = ISC_FALSE;
} else
INSIST(0);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRR, check);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRR, check);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKDUPRRFAIL, fail);
obj = NULL;
result = ns_config_get(maps, "check-mx", &obj);
@@ -1272,13 +1431,13 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
fail = check = ISC_FALSE;
} else
INSIST(0);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMX, check);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKMXFAIL, fail);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMX, check);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKMXFAIL, fail);
obj = NULL;
result = ns_config_get(maps, "check-integrity", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setoption(zone, DNS_ZONEOPT_CHECKINTEGRITY,
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_CHECKINTEGRITY,
cfg_obj_asboolean(obj));
obj = NULL;
@@ -1293,8 +1452,8 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
warn = ignore = ISC_TRUE;
} else
INSIST(0);
- dns_zone_setoption(zone, DNS_ZONEOPT_WARNMXCNAME, warn);
- dns_zone_setoption(zone, DNS_ZONEOPT_IGNOREMXCNAME, ignore);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNMXCNAME, warn);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNOREMXCNAME, ignore);
obj = NULL;
result = ns_config_get(maps, "check-srv-cname", &obj);
@@ -1308,30 +1467,38 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
warn = ignore = ISC_TRUE;
} else
INSIST(0);
- dns_zone_setoption(zone, DNS_ZONEOPT_WARNSRVCNAME, warn);
- dns_zone_setoption(zone, DNS_ZONEOPT_IGNORESRVCNAME, ignore);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_WARNSRVCNAME, warn);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_IGNORESRVCNAME,
+ ignore);
obj = NULL;
result = ns_config_get(maps, "dnssec-secure-to-insecure", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setoption(zone, DNS_ZONEOPT_SECURETOINSECURE,
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_SECURETOINSECURE,
cfg_obj_asboolean(obj));
obj = NULL;
- result = cfg_map_get(zoptions, "auto-dnssec", &obj);
+ result = cfg_map_get(zoptions, "dnssec-update-mode", &obj);
if (result == ISC_R_SUCCESS) {
const char *arg = cfg_obj_asstring(obj);
- if (strcasecmp(arg, "allow") == 0)
- allow = ISC_TRUE;
+ if (strcasecmp(arg, "no-resign") == 0)
+ dns_zone_setkeyopt(zone, DNS_ZONEKEY_NORESIGN,
+ ISC_TRUE);
else if (strcasecmp(arg, "maintain") == 0)
- allow = maint = ISC_TRUE;
- else if (strcasecmp(arg, "off") == 0)
;
else
INSIST(0);
- dns_zone_setkeyopt(zone, DNS_ZONEKEY_ALLOW, allow);
- dns_zone_setkeyopt(zone, DNS_ZONEKEY_MAINTAIN, maint);
}
+
+ obj = NULL;
+ result = ns_config_get(maps, "serial-update-method", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ if (strcasecmp(cfg_obj_asstring(obj), "unixtime") == 0)
+ dns_zone_setserialupdatemethod(zone,
+ dns_updatemethod_unixtime);
+ else
+ dns_zone_setserialupdatemethod(zone,
+ dns_updatemethod_increment);
}
/*
@@ -1340,6 +1507,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
switch (ztype) {
case dns_zone_slave:
case dns_zone_stub:
+ case dns_zone_redirect:
count = 0;
obj = NULL;
(void)cfg_map_get(zoptions, "masters", &obj);
@@ -1349,7 +1517,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
RETERR(ns_config_getipandkeylist(config, obj, mctx,
&addrs, &keynames,
&count));
- result = dns_zone_setmasterswithkeys(zone, addrs,
+ result = dns_zone_setmasterswithkeys(mayberaw, addrs,
keynames, count);
if (count != 0)
ns_config_putipandkeylist(mctx, &addrs,
@@ -1357,7 +1525,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
else
INSIST(addrs == NULL && keynames == NULL);
} else
- result = dns_zone_setmasters(zone, NULL, 0);
+ result = dns_zone_setmasters(mayberaw, NULL, 0);
RETERR(result);
multi = ISC_FALSE;
@@ -1367,59 +1535,63 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
multi = cfg_obj_asboolean(obj);
}
- dns_zone_setoption(zone, DNS_ZONEOPT_MULTIMASTER, multi);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
obj = NULL;
result = ns_config_get(maps, "max-transfer-time-in", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setmaxxfrin(zone, cfg_obj_asuint32(obj) * 60);
+ dns_zone_setmaxxfrin(mayberaw, cfg_obj_asuint32(obj) * 60);
obj = NULL;
result = ns_config_get(maps, "max-transfer-idle-in", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setidlein(zone, cfg_obj_asuint32(obj) * 60);
+ dns_zone_setidlein(mayberaw, cfg_obj_asuint32(obj) * 60);
obj = NULL;
result = ns_config_get(maps, "max-refresh-time", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setmaxrefreshtime(zone, cfg_obj_asuint32(obj));
+ dns_zone_setmaxrefreshtime(mayberaw, cfg_obj_asuint32(obj));
obj = NULL;
result = ns_config_get(maps, "min-refresh-time", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setminrefreshtime(zone, cfg_obj_asuint32(obj));
+ dns_zone_setminrefreshtime(mayberaw, cfg_obj_asuint32(obj));
obj = NULL;
result = ns_config_get(maps, "max-retry-time", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setmaxretrytime(zone, cfg_obj_asuint32(obj));
+ dns_zone_setmaxretrytime(mayberaw, cfg_obj_asuint32(obj));
obj = NULL;
result = ns_config_get(maps, "min-retry-time", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- dns_zone_setminretrytime(zone, cfg_obj_asuint32(obj));
+ dns_zone_setminretrytime(mayberaw, cfg_obj_asuint32(obj));
obj = NULL;
result = ns_config_get(maps, "transfer-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- RETERR(dns_zone_setxfrsource4(zone, cfg_obj_assockaddr(obj)));
+ RETERR(dns_zone_setxfrsource4(mayberaw,
+ cfg_obj_assockaddr(obj)));
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
obj = NULL;
result = ns_config_get(maps, "transfer-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- RETERR(dns_zone_setxfrsource6(zone, cfg_obj_assockaddr(obj)));
+ RETERR(dns_zone_setxfrsource6(mayberaw,
+ cfg_obj_assockaddr(obj)));
ns_add_reserved_dispatch(ns_g_server, cfg_obj_assockaddr(obj));
obj = NULL;
result = ns_config_get(maps, "alt-transfer-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- RETERR(dns_zone_setaltxfrsource4(zone, cfg_obj_assockaddr(obj)));
+ RETERR(dns_zone_setaltxfrsource4(mayberaw,
+ cfg_obj_assockaddr(obj)));
obj = NULL;
result = ns_config_get(maps, "alt-transfer-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
- RETERR(dns_zone_setaltxfrsource6(zone, cfg_obj_assockaddr(obj)));
+ RETERR(dns_zone_setaltxfrsource6(mayberaw,
+ cfg_obj_assockaddr(obj)));
obj = NULL;
(void)ns_config_get(maps, "use-alt-transfer-source", &obj);
@@ -1435,11 +1607,11 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
alt = ISC_FALSE;
} else
alt = cfg_obj_asboolean(obj);
- dns_zone_setoption(zone, DNS_ZONEOPT_USEALTXFRSRC, alt);
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_USEALTXFRSRC, alt);
obj = NULL;
(void)ns_config_get(maps, "try-tcp-refresh", &obj);
- dns_zone_setoption(zone, DNS_ZONEOPT_TRYTCPREFRESH,
+ dns_zone_setoption(mayberaw, DNS_ZONEOPT_TRYTCPREFRESH,
cfg_obj_asboolean(obj));
break;
@@ -1472,10 +1644,10 @@ ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone,
dns_zone_settype(zone, dns_zone_dlz);
result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db);
if (result != ISC_R_SUCCESS)
- return result;
+ return (result);
result = dns_zone_dlzpostload(zone, db);
dns_db_detach(&db);
- return result;
+ return (result);
}
isc_boolean_t
@@ -1484,15 +1656,12 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
const cfg_obj_t *obj = NULL;
const char *cfilename;
const char *zfilename;
+ dns_zone_t *raw = NULL;
+ isc_boolean_t has_raw;
+ dns_zonetype_t ztype;
zoptions = cfg_tuple_get(zconfig, "options");
- if (zonetype_fromconfig(zoptions) != dns_zone_gettype(zone)) {
- dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "not reusable: type mismatch");
- return (ISC_FALSE);
- }
-
/*
* We always reconfigure a static-stub zone for simplicity, assuming
* the amount of data to be loaded is small.
@@ -1503,18 +1672,49 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) {
return (ISC_FALSE);
}
+ /* If there's a raw zone, use that for filename and type comparison */
+ dns_zone_getraw(zone, &raw);
+ if (raw != NULL) {
+ zfilename = dns_zone_getfile(raw);
+ ztype = dns_zone_gettype(raw);
+ dns_zone_detach(&raw);
+ has_raw = ISC_TRUE;
+ } else {
+ zfilename = dns_zone_getfile(zone);
+ ztype = dns_zone_gettype(zone);
+ has_raw = ISC_FALSE;
+ }
+
+ obj = NULL;
+ (void)cfg_map_get(zoptions, "inline-signing", &obj);
+ if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) {
+ dns_zone_log(zone, ISC_LOG_DEBUG(1),
+ "not reusable: old zone was inline-signing");
+ return (ISC_FALSE);
+ } else if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) {
+ dns_zone_log(zone, ISC_LOG_DEBUG(1),
+ "not reusable: old zone was not inline-signing");
+ return (ISC_FALSE);
+ }
+
+ if (zonetype_fromconfig(zoptions) != ztype) {
+ dns_zone_log(zone, ISC_LOG_DEBUG(1),
+ "not reusable: type mismatch");
+ return (ISC_FALSE);
+ }
+
obj = NULL;
(void)cfg_map_get(zoptions, "file", &obj);
if (obj != NULL)
cfilename = cfg_obj_asstring(obj);
else
cfilename = NULL;
- zfilename = dns_zone_getfile(zone);
if (!((cfilename == NULL && zfilename == NULL) ||
(cfilename != NULL && zfilename != NULL &&
- strcmp(cfilename, zfilename) == 0))) {
+ strcmp(cfilename, zfilename) == 0)))
+ {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
- "not reusable: filename mismatch");
+ "not reusable: filename mismatch");
return (ISC_FALSE);
}
OpenPOWER on IntegriCloud