+2355. [func] Extend the number statistics counters available.
+ [RT #17590]
+
2354. [bug] Failed to initialise sone rdatasetheader_t elements.
[RT #17927]
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: bind9.xsl,v 1.15 2008/04/01 23:47:10 tbox Exp $ -->
+<!-- $Id: bind9.xsl,v 1.16 2008/04/03 05:55:51 marka Exp $ -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
color: #ffffff;
}
+td, th {
+ padding-right: 5px;
+ padding-left: 5px;
+}
+
.header {
background-color: teal;
color: #ffffff;
<br/>
<table>
- <tr class="rowh"><th colspan="2">Server statistics</th></tr>
- <xsl:for-each select="server/counters/*">
+ <tr class="rowh"><th colspan="2">Incoming Requests</th></tr>
+ <xsl:for-each select="server/requests/opcode">
<tr class="lrow">
- <td><xsl:value-of select="name()"/></td>
- <td><xsl:value-of select="."/></td>
+ <td><xsl:value-of select="name"/></td>
+ <td><xsl:value-of select="counter"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+
+ <br/>
+
+ <table>
+ <tr class="rowh"><th colspan="2">Incoming Queries</th></tr>
+ <xsl:for-each select="server/queries-in/rdtype">
+ <tr class="lrow">
+ <td><xsl:value-of select="name"/></td>
+ <td><xsl:value-of select="counter"/></td>
</tr>
</xsl:for-each>
</table>
- <br/>
+ <br/>
+
+ <xsl:for-each select="views/view">
+ <table>
+ <tr class="rowh">
+ <th colspan="2">Outgoing Queries from View <xsl:value-of select="name"/></th>
+ </tr>
+ <xsl:for-each select="rdtype">
+ <tr class="lrow">
+ <td><xsl:value-of select="name"/></td>
+ <td><xsl:value-of select="counter"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ </xsl:for-each>
+
+ <br/>
+
+ <table>
+ <tr class="rowh"><th colspan="10">Server Statistics</th></tr>
+ <tr class="rowh">
+ <!-- The ordering of the following items must be consisten
+ with dns_nsstatscounter_xxx -->
+ <th>Requestv4</th>
+ <th>Requestv6</th>
+ <th>ReqEdns0</th>
+ <th>ReqBadEDNSVer</th>
+ <th>ReqTSIG</th>
+ <th>ReqSIG0</th>
+ <th>ReqBadSIG</th>
+ <th>ReqTCP</th>
+ <th>AuthQryRej</th>
+ <th>RecQryRej</th>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="server/nsstats/Requestv4"/></td>
+ <td><xsl:value-of select="server/nsstats/Requestv6"/></td>
+ <td><xsl:value-of select="server/nsstats/ReqEdns0"/></td>
+ <td><xsl:value-of select="server/nsstats/ReqBadEDNSVer"/></td>
+ <td><xsl:value-of select="server/nsstats/ReqTSIG"/></td>
+ <td><xsl:value-of select="server/nsstats/ReqSIG0"/></td>
+ <td><xsl:value-of select="server/nsstats/ReqBadSIG"/></td>
+ <td><xsl:value-of select="server/nsstats/ReqTCP"/></td>
+ <td><xsl:value-of select="server/nsstats/AuthQryRej"/></td>
+ <td><xsl:value-of select="server/nsstats/RecQryRej"/></td>
+ </tr>
+ <tr class="rowh">
+ <th>XfrRej</th>
+ <th>UpdateRej</th>
+ <th>Response</th>
+ <th>RespTruncated</th>
+ <th>RespEDNS0</th>
+ <th>RespTSIG</th>
+ <th>RespSIG0</th>
+ <th>QrySuccess</th>
+ <th>QryAuthAns</th>
+ <th>QryNoauthAns</th>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="server/nsstats/XfrRej"/></td>
+ <td><xsl:value-of select="server/nsstats/UpdateRej"/></td>
+ <td><xsl:value-of select="server/nsstats/Response"/></td>
+ <td><xsl:value-of select="server/nsstats/TruncatedResp"/></td>
+ <td><xsl:value-of select="server/nsstats/RespEDNS0"/></td>
+ <td><xsl:value-of select="server/nsstats/RespTSIG"/></td>
+ <td><xsl:value-of select="server/nsstats/RespSIG0"/></td>
+ <td><xsl:value-of select="server/nsstats/QrySuccess"/></td>
+ <td><xsl:value-of select="server/nsstats/QryAuthAns"/></td>
+ <td><xsl:value-of select="server/nsstats/QryNoauthAns"/></td>
+ </tr>
+ <tr class="rowh">
+ <th>QryReferral</th>
+ <th>QryNxrrset</th>
+ <th>QrySERVFAIL</th>
+ <th>QryFORMERR</th>
+ <th>QryNXDOMAIN</th>
+ <th>QryRecursion</th>
+ <th>QryDuplicate</th>
+ <th>QryDropped</th>
+ <th>QryFailure</th>
+ <th>XfrReqDone</th>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="server/nsstats/QryReferral"/></td>
+ <td><xsl:value-of select="server/nsstats/QryNxrrset"/></td>
+ <td><xsl:value-of select="server/nsstats/QrySERVFAIL"/></td>
+ <td><xsl:value-of select="server/nsstats/QryFORMERR"/></td>
+ <td><xsl:value-of select="server/nsstats/QryNXDOMAIN"/></td>
+ <td><xsl:value-of select="server/nsstats/QryRecursion"/></td>
+ <td><xsl:value-of select="server/nsstats/QryDuplicate"/></td>
+ <td><xsl:value-of select="server/nsstats/QryDropped"/></td>
+ <td><xsl:value-of select="server/nsstats/QryFailure"/></td>
+ <td><xsl:value-of select="server/nsstats/XfrReqDone"/></td>
+ </tr>
+ <tr class="rowh">
+ <th>UpdateReqFwd</th>
+ <th>UpdateRespFwd</th>
+ <th>UpdateFwdFail</th>
+ <th>UpdateDone</th>
+ <th>UpdateFail</th>
+ <th>UpdateBadPrereq</th>
+ <th>RespMismatch</th>
+ <th />
+ <th />
+ <th />
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="server/nsstats/UpdateReqFwd"/></td>
+ <td><xsl:value-of select="server/nsstats/UpdateRespFwd"/></td>
+ <td><xsl:value-of select="server/nsstats/UpdateFwdFail"/></td>
+ <td><xsl:value-of select="server/nsstats/UpdateDone"/></td>
+ <td><xsl:value-of select="server/nsstats/UpdateFail"/></td>
+ <td><xsl:value-of select="server/nsstats/UpdateBadPrereq"/></td>
+ <td><xsl:value-of select="server/resstats/Mismatch"/></td>
+ <td />
+ <td />
+ <td />
+ </tr>
+ </table>
+
+ <br/>
+
+ <table>
+ <tr class="rowh"><th colspan="10">Zone Maintenance Statistics</th></tr>
+ <tr class="rowh">
+ <!-- The ordering of the following items must be consisten
+ with dns_zonestatscounter_xxx -->
+ <th>NotifyOutv4</th>
+ <th>NotifyOutv6</th>
+ <th>NotifyInv4</th>
+ <th>NotifyInv6</th>
+ <th>NotifyRej</th>
+ <th>SOAOutv4</th>
+ <th>SOAOutv6</th>
+ <th>AXFRReqv4</th>
+ <th>AXFRReqv6</th>
+ <th>IXFRReqv4</th>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="server/zonestats/NotifyOutv4"/></td>
+ <td><xsl:value-of select="server/zonestats/NotifyOutv6"/></td>
+ <td><xsl:value-of select="server/zonestats/NotifyInv4"/></td>
+ <td><xsl:value-of select="server/zonestats/NotifyInv6"/></td>
+ <td><xsl:value-of select="server/zonestats/NotifyRej"/></td>
+ <td><xsl:value-of select="server/zonestats/SOAOutv4"/></td>
+ <td><xsl:value-of select="server/zonestats/SOAOutv6"/></td>
+ <td><xsl:value-of select="server/zonestats/AXFRReqv4"/></td>
+ <td><xsl:value-of select="server/zonestats/AXFRReqv6"/></td>
+ <td><xsl:value-of select="server/zonestats/IXFRReqv4"/></td>
+ </tr>
+ <tr class="rowh">
+ <th>IXFRReqv6</th>
+ <th>XfrSuccess</th>
+ <th>XfrFail</th>
+ <th/>
+ <th/>
+ <th/>
+ <th/>
+ <th/>
+ <th/>
+ <th/>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="server/zonestats/IXFRReqv6"/></td>
+ <td><xsl:value-of select="server/zonestats/XfrSuccess"/></td>
+ <td><xsl:value-of select="server/zonestats/XfrFail"/></td>
+ <td/>
+ <td/>
+ <td/>
+ <td/>
+ <td/>
+ <td/>
+ <td/>
+ </tr>
+ </table>
+
+ <br/>
+
+ <xsl:for-each select="views/view">
+ <table>
+ <tr class="rowh">
+ <th colspan="10">Resolver Statistics for View <xsl:value-of select="name"/></th>
+ </tr>
+ <tr class="rowh">
+ <!-- The ordering of the following items must be consisten
+ with dns_resstatscounter_xxx -->
+ <th>Queryv4</th>
+ <th>Queryv6</th>
+ <th>Responsev4</th>
+ <th>Responsev6</th>
+ <th>NXDOMAIN</th>
+ <th>SERVFAIL</th>
+ <th>FORMERR</th>
+ <th>OtherError</th>
+ <th>EDNS0Fail</th>
+ <!-- this counter is not applicable to per-view stat,
+ but keep it for generating the description table used in
+ the statschannel.c.
+ <th>Mismatch</th> -->
+ <th>Truncated</th>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="resstats/Queryv4"/></td>
+ <td><xsl:value-of select="resstats/Queryv6"/></td>
+ <td><xsl:value-of select="resstats/Responsev4"/></td>
+ <td><xsl:value-of select="resstats/Responsev6"/></td>
+ <td><xsl:value-of select="resstats/NXDOMAIN"/></td>
+ <td><xsl:value-of select="resstats/SERVFAIL"/></td>
+ <td><xsl:value-of select="resstats/FORMERR"/></td>
+ <td><xsl:value-of select="resstats/OtherError"/></td>
+ <td><xsl:value-of select="resstats/EDNS0Fail"/></td>
+ <!-- <td><xsl:value-of select="resstats/Mismatch"/></td> -->
+ <td><xsl:value-of select="resstats/Truncated"/></td>
+ </tr>
+ <tr class="rowh">
+ <th>Lame</th>
+ <th>Retry</th>
+ <th>GlueFetchv4</th>
+ <th>GlueFetchv6</th>
+ <th>GlueFetchv4Fail</th>
+ <th>GlueFetchv6Fail</th>
+ <th>ValAttempt</th>
+ <th>ValOk</th>
+ <th>ValNegOk</th>
+ <th>ValFail</th>
+ </tr>
+ <tr class="lrow">
+ <td><xsl:value-of select="resstats/Lame"/></td>
+ <td><xsl:value-of select="resstats/Retry"/></td>
+ <td><xsl:value-of select="resstats/GlueFetchv4"/></td>
+ <td><xsl:value-of select="resstats/GlueFetchv6"/></td>
+ <td><xsl:value-of select="resstats/GlueFetchv4Fail"/></td>
+ <td><xsl:value-of select="resstats/GlueFetchv6Fail"/></td>
+ <td><xsl:value-of select="resstats/ValAttempt"/></td>
+ <td><xsl:value-of select="resstats/ValOk"/></td>
+ <td><xsl:value-of select="resstats/ValNegOk"/></td>
+ <td><xsl:value-of select="resstats/ValFail"/></td>
+ </tr>
+ </table>
+ <br/>
+ </xsl:for-each>
+
+ <br/>
+
+ <xsl:for-each select="views/view">
+ <table>
+ <tr class="rowh">
+ <th colspan="2">Cache DB RRsets for View <xsl:value-of select="name"/></th>
+ </tr>
+ <xsl:for-each select="cache/rrset">
+ <tr class="lrow">
+ <td><xsl:value-of select="name"/></td>
+ <td><xsl:value-of select="counter"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <br/>
+ </xsl:for-each>
+
+ <br/>
<xsl:for-each select="views/view">
<table>
<tr class="rowh">
- <th colspan="11">Zones for View <xsl:value-of select="name"/></th>
+ <th colspan="10">Zones for View <xsl:value-of select="name"/></th>
</tr>
<tr class="rowh">
<th>Name</th>
<th>Referral</th>
<th>NXRRSET</th>
<th>NXDOMAIN</th>
- <th>Recursion</th>
<th>Failure</th>
- <th>Duplicate</th>
- <th>Dropped</th>
+ <th>XfrReqDone</th>
+ <th>XfrRej</th>
</tr>
<xsl:for-each select="zones/zone">
<tr class="lrow">
<xsl:value-of select="serial"/>
</td>
<td>
- <xsl:value-of select="counters/success"/>
- </td>
- <td>
- <xsl:value-of select="counters/referral"/>
+ <xsl:value-of select="counters/QrySuccess"/>
</td>
<td>
- <xsl:value-of select="counters/nxrrset"/>
+ <xsl:value-of select="counters/QryReferral"/>
</td>
<td>
- <xsl:value-of select="counters/nxdomain"/>
+ <xsl:value-of select="counters/QryNxrrset"/>
</td>
<td>
- <xsl:value-of select="counters/recursion"/>
+ <xsl:value-of select="counters/QryNXDOMAIN"/>
</td>
<td>
- <xsl:value-of select="counters/failure"/>
+ <xsl:value-of select="counters/QryFailure"/>
</td>
<td>
- <xsl:value-of select="counters/duplicate"/>
+ <xsl:value-of select="counters/XfrReqDone"/>
</td>
<td>
- <xsl:value-of select="counters/dropped"/>
+ <xsl:value-of select="counters/XfrRej"/>
</td>
</tr>
</xsl:for-each>
* Generated by convertxsl.pl 1.11 2008/04/02 23:46:57 tbox Exp
* From bind9.xsl 1.15 2008/04/01 23:47:10 tbox Exp
*/
-static char msg[] =
+static char xslmsg[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!--\n"
" - Copyright (C) 2006-2008 Internet Systems Consortium, Inc. (\"ISC\")\n"
" color: #ffffff;\n"
"}\n"
"\n"
+ "td, th {\n"
+ " padding-right: 5px;\n"
+ " padding-left: 5px;\n"
+ "}\n"
+ "\n"
".header {\n"
" background-color: teal;\n"
" color: #ffffff;\n"
" <br/>\n"
"\n"
" <table>\n"
- " <tr class=\"rowh\"><th colspan=\"2\">Server statistics</th></tr>\n"
- " <xsl:for-each select=\"server/counters/*\">\n"
+ " <tr class=\"rowh\"><th colspan=\"2\">Incoming Requests</th></tr>\n"
+ " <xsl:for-each select=\"server/requests/opcode\">\n"
" <tr class=\"lrow\">\n"
- " <td><xsl:value-of select=\"name()\"/></td>\n"
- " <td><xsl:value-of select=\".\"/></td>\n"
+ " <td><xsl:value-of select=\"name\"/></td>\n"
+ " <td><xsl:value-of select=\"counter\"/></td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ "\n"
+ " <br/>\n"
+ "\n"
+ " <table>\n"
+ " <tr class=\"rowh\"><th colspan=\"2\">Incoming Queries</th></tr>\n"
+ " <xsl:for-each select=\"server/queries-in/rdtype\">\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"name\"/></td>\n"
+ " <td><xsl:value-of select=\"counter\"/></td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ "\n"
+ " <br/>\n"
+ "\n"
+ " <xsl:for-each select=\"views/view\">\n"
+ " <table>\n"
+ " <tr class=\"rowh\">\n"
+ " <th colspan=\"2\">Outgoing Queries from View <xsl:value-of select=\"name\"/></th>\n"
+ " </tr>\n"
+ " <xsl:for-each select=\"rdtype\">\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"name\"/></td>\n"
+ " <td><xsl:value-of select=\"counter\"/></td>\n"
+ " </tr>\n"
+ " </xsl:for-each>\n"
+ " </table>\n"
+ " <br/>\n"
+ " </xsl:for-each>\n"
+ "\n"
+ " <br/>\n"
+ "\n"
+ " <table>\n"
+ " <tr class=\"rowh\"><th colspan=\"10\">Server Statistics</th></tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <!-- The ordering of the following items must be consisten\n"
+ " with dns_nsstatscounter_xxx -->\n"
+ " <th>Requestv4</th>\n"
+ " <th>Requestv6</th>\n"
+ " <th>ReqEdns0</th>\n"
+ " <th>ReqBadEDNSVer</th>\n"
+ " <th>ReqTSIG</th>\n"
+ " <th>ReqSIG0</th>\n"
+ " <th>ReqBadSIG</th>\n"
+ " <th>ReqTCP</th>\n"
+ " <th>AuthQryRej</th>\n"
+ " <th>RecQryRej</th>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"server/nsstats/Requestv4\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/Requestv6\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/ReqEdns0\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/ReqBadEDNSVer\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/ReqTSIG\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/ReqSIG0\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/ReqBadSIG\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/ReqTCP\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/AuthQryRej\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/RecQryRej\"/></td>\n"
+ " </tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <th>XfrRej</th>\n"
+ " <th>UpdateRej</th>\n"
+ " <th>Response</th>\n"
+ " <th>RespTruncated</th>\n"
+ " <th>RespEDNS0</th>\n"
+ " <th>RespTSIG</th>\n"
+ " <th>RespSIG0</th>\n"
+ " <th>QrySuccess</th>\n"
+ " <th>QryAuthAns</th>\n"
+ " <th>QryNoauthAns</th>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"server/nsstats/XfrRej\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateRej\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/Response\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/TruncatedResp\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/RespEDNS0\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/RespTSIG\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/RespSIG0\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QrySuccess\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryAuthAns\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryNoauthAns\"/></td>\n"
+ " </tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <th>QryReferral</th>\n"
+ " <th>QryNxrrset</th>\n"
+ " <th>QrySERVFAIL</th>\n"
+ " <th>QryFORMERR</th>\n"
+ " <th>QryNXDOMAIN</th>\n"
+ " <th>QryRecursion</th>\n"
+ " <th>QryDuplicate</th>\n"
+ " <th>QryDropped</th>\n"
+ " <th>QryFailure</th>\n"
+ " <th>XfrReqDone</th>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryReferral\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryNxrrset\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QrySERVFAIL\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryFORMERR\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryNXDOMAIN\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryRecursion\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryDuplicate\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryDropped\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/QryFailure\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/XfrReqDone\"/></td>\n"
+ " </tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <th>UpdateReqFwd</th>\n"
+ " <th>UpdateRespFwd</th>\n"
+ " <th>UpdateFwdFail</th>\n"
+ " <th>UpdateDone</th>\n"
+ " <th>UpdateFail</th>\n"
+ " <th>UpdateBadPrereq</th>\n"
+ " <th>RespMismatch</th>\n"
+ " <th />\n"
+ " <th />\n"
+ " <th />\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateReqFwd\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateRespFwd\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateFwdFail\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateDone\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateFail\"/></td>\n"
+ " <td><xsl:value-of select=\"server/nsstats/UpdateBadPrereq\"/></td>\n"
+ " <td><xsl:value-of select=\"server/resstats/Mismatch\"/></td>\n"
+ " <td />\n"
+ " <td />\n"
+ " <td />\n"
+ " </tr>\n"
+ " </table>\n"
+ "\n"
+ " <br/>\n"
+ "\n"
+ " <table>\n"
+ " <tr class=\"rowh\"><th colspan=\"10\">Zone Maintenance Statistics</th></tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <!-- The ordering of the following items must be consisten\n"
+ " with dns_zonestatscounter_xxx -->\n"
+ " <th>NotifyOutv4</th>\n"
+ " <th>NotifyOutv6</th>\n"
+ " <th>NotifyInv4</th>\n"
+ " <th>NotifyInv6</th>\n"
+ " <th>NotifyRej</th>\n"
+ " <th>SOAOutv4</th>\n"
+ " <th>SOAOutv6</th>\n"
+ " <th>AXFRReqv4</th>\n"
+ " <th>AXFRReqv6</th>\n"
+ " <th>IXFRReqv4</th>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"server/zonestats/NotifyOutv4\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/NotifyOutv6\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/NotifyInv4\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/NotifyInv6\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/NotifyRej\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/SOAOutv4\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/SOAOutv6\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/AXFRReqv4\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/AXFRReqv6\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/IXFRReqv4\"/></td>\n"
+ " </tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <th>IXFRReqv6</th>\n"
+ " <th>XfrSuccess</th>\n"
+ " <th>XfrFail</th>\n"
+ " <th/>\n"
+ " <th/>\n"
+ " <th/>\n"
+ " <th/>\n"
+ " <th/>\n"
+ " <th/>\n"
+ " <th/>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"server/zonestats/IXFRReqv6\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/XfrSuccess\"/></td>\n"
+ " <td><xsl:value-of select=\"server/zonestats/XfrFail\"/></td>\n"
+ " <td/>\n"
+ " <td/>\n"
+ " <td/>\n"
+ " <td/>\n"
+ " <td/>\n"
+ " <td/>\n"
+ " <td/>\n"
+ " </tr>\n"
+ " </table>\n"
+ "\n"
+ " <br/>\n"
+ "\n"
+ " <xsl:for-each select=\"views/view\">\n"
+ " <table>\n"
+ " <tr class=\"rowh\">\n"
+ " <th colspan=\"10\">Resolver Statistics for View <xsl:value-of select=\"name\"/></th>\n"
+ " </tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <!-- The ordering of the following items must be consisten\n"
+ " with dns_resstatscounter_xxx -->\n"
+ " <th>Queryv4</th>\n"
+ " <th>Queryv6</th>\n"
+ " <th>Responsev4</th>\n"
+ " <th>Responsev6</th>\n"
+ " <th>NXDOMAIN</th>\n"
+ " <th>SERVFAIL</th>\n"
+ " <th>FORMERR</th>\n"
+ " <th>OtherError</th>\n"
+ " <th>EDNS0Fail</th>\n"
+ " <!-- this counter is not applicable to per-view stat,\n"
+ " but keep it for generating the description table used in\n"
+ " the statschannel.c.\n"
+ " <th>Mismatch</th> -->\n"
+ " <th>Truncated</th>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"resstats/Queryv4\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/Queryv6\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/Responsev4\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/Responsev6\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/NXDOMAIN\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/SERVFAIL\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/FORMERR\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/OtherError\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/EDNS0Fail\"/></td>\n"
+ " <!-- <td><xsl:value-of select=\"resstats/Mismatch\"/></td> -->\n"
+ " <td><xsl:value-of select=\"resstats/Truncated\"/></td>\n"
+ " </tr>\n"
+ " <tr class=\"rowh\">\n"
+ " <th>Lame</th>\n"
+ " <th>Retry</th>\n"
+ " <th>GlueFetchv4</th>\n"
+ " <th>GlueFetchv6</th>\n"
+ " <th>GlueFetchv4Fail</th>\n"
+ " <th>GlueFetchv6Fail</th>\n"
+ " <th>ValAttempt</th>\n"
+ " <th>ValOk</th>\n"
+ " <th>ValNegOk</th>\n"
+ " <th>ValFail</th>\n"
+ " </tr>\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"resstats/Lame\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/Retry\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/GlueFetchv4\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/GlueFetchv6\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/GlueFetchv4Fail\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/GlueFetchv6Fail\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/ValAttempt\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/ValOk\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/ValNegOk\"/></td>\n"
+ " <td><xsl:value-of select=\"resstats/ValFail\"/></td>\n"
+ " </tr>\n"
+ " </table>\n"
+ " <br/>\n"
+ " </xsl:for-each>\n"
+ "\n"
+ " <br/>\n"
+ "\n"
+ " <xsl:for-each select=\"views/view\">\n"
+ " <table>\n"
+ " <tr class=\"rowh\">\n"
+ " <th colspan=\"2\">Cache DB RRsets for View <xsl:value-of select=\"name\"/></th>\n"
+ " </tr>\n"
+ " <xsl:for-each select=\"cache/rrset\">\n"
+ " <tr class=\"lrow\">\n"
+ " <td><xsl:value-of select=\"name\"/></td>\n"
+ " <td><xsl:value-of select=\"counter\"/></td>\n"
" </tr>\n"
" </xsl:for-each>\n"
" </table>\n"
+ " <br/>\n"
+ " </xsl:for-each>\n"
"\n"
- " <br/> \n"
+ " <br/>\n"
"\n"
" <xsl:for-each select=\"views/view\">\n"
" <table>\n"
" <tr class=\"rowh\">\n"
- " <th colspan=\"11\">Zones for View <xsl:value-of select=\"name\"/></th>\n"
+ " <th colspan=\"10\">Zones for View <xsl:value-of select=\"name\"/></th>\n"
" </tr>\n"
" <tr class=\"rowh\">\n"
" <th>Name</th>\n"
" <th>Referral</th>\n"
" <th>NXRRSET</th>\n"
" <th>NXDOMAIN</th>\n"
- " <th>Recursion</th>\n"
" <th>Failure</th>\n"
- " <th>Duplicate</th>\n"
- " <th>Dropped</th>\n"
+ " <th>XfrReqDone</th>\n"
+ " <th>XfrRej</th>\n"
" </tr>\n"
" <xsl:for-each select=\"zones/zone\">\n"
" <tr class=\"lrow\">\n"
" <xsl:value-of select=\"serial\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/success\"/>\n"
- " </td>\n"
- " <td>\n"
- " <xsl:value-of select=\"counters/referral\"/>\n"
+ " <xsl:value-of select=\"counters/QrySuccess\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/nxrrset\"/>\n"
+ " <xsl:value-of select=\"counters/QryReferral\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/nxdomain\"/>\n"
+ " <xsl:value-of select=\"counters/QryNxrrset\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/recursion\"/>\n"
+ " <xsl:value-of select=\"counters/QryNXDOMAIN\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/failure\"/>\n"
+ " <xsl:value-of select=\"counters/QryFailure\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/duplicate\"/>\n"
+ " <xsl:value-of select=\"counters/XfrReqDone\"/>\n"
" </td>\n"
" <td>\n"
- " <xsl:value-of select=\"counters/dropped\"/>\n"
+ " <xsl:value-of select=\"counters/XfrRej\"/>\n"
" </td>\n"
" </tr>\n"
" </xsl:for-each>\n"
" </html>\n"
" </xsl:template>\n"
"</xsl:stylesheet>\n";
+static const char *nsstats_xmldesc[] = { "Requestv4",
+ "Requestv6",
+ "ReqEdns0",
+ "ReqBadEDNSVer",
+ "ReqTSIG",
+ "ReqSIG0",
+ "ReqBadSIG",
+ "ReqTCP",
+ "AuthQryRej",
+ "RecQryRej",
+ "XfrRej",
+ "UpdateRej",
+ "Response",
+ "TruncatedResp",
+ "RespEDNS0",
+ "RespTSIG",
+ "RespSIG0",
+ "QrySuccess",
+ "QryAuthAns",
+ "QryNoauthAns",
+ "QryReferral",
+ "QryNxrrset",
+ "QrySERVFAIL",
+ "QryFORMERR",
+ "QryNXDOMAIN",
+ "QryRecursion",
+ "QryDuplicate",
+ "QryDropped",
+ "QryFailure",
+ "XfrReqDone",
+ "UpdateReqFwd",
+ "UpdateRespFwd",
+ "UpdateFwdFail",
+ "UpdateDone",
+ "UpdateFail",
+ "UpdateBadPrereq"
+};
+static const char *zonestats_xmldesc[] = { "NotifyOutv4",
+ "NotifyOutv6",
+ "NotifyInv4",
+ "NotifyInv6",
+ "NotifyRej",
+ "SOAOutv4",
+ "SOAOutv6",
+ "AXFRReqv4",
+ "AXFRReqv6",
+ "IXFRReqv4",
+ "IXFRReqv6",
+ "XfrSuccess",
+ "XfrFail"
+};
+static const char *resstats_xmldesc[] = { "Queryv4",
+ "Queryv6",
+ "Responsev4",
+ "Responsev6",
+ "NXDOMAIN",
+ "SERVFAIL",
+ "FORMERR",
+ "OtherError",
+ "EDNS0Fail",
+ "Mismatch",
+ "Truncated",
+ "Lame",
+ "Retry",
+ "GlueFetchv4",
+ "GlueFetchv6",
+ "GlueFetchv4Fail",
+ "GlueFetchv6Fail",
+ "ValAttempt",
+ "ValOk",
+ "ValNegOk",
+ "ValFail"
+};
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: client.c,v 1.255 2008/04/03 02:01:08 marka Exp $ */
+/* $Id: client.c,v 1.256 2008/04/03 05:55:51 marka Exp $ */
#include <config.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/resolver.h>
+#include <dns/stats.h>
#include <dns/tsig.h>
#include <dns/view.h>
#include <dns/zone.h>
unsigned char sendbuf[SEND_BUFFER_SIZE];
unsigned int dnssec_opts;
unsigned int preferred_glue;
+ isc_boolean_t opt_included = ISC_FALSE;
REQUIRE(NS_CLIENT_VALID(client));
if (client->opt != NULL) {
result = dns_message_setopt(client->message, client->opt);
+ opt_included = ISC_TRUE;
client->opt = NULL;
if (result != ISC_R_SUCCESS)
goto done;
result = client_sendpkg(client, &tcpbuffer);
} else
result = client_sendpkg(client, &buffer);
+
+ /* update statistics (XXXJT: is it okay to access message->xxxkey?) */
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_response);
+ if (opt_included) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_edns0out);
+ }
+ if (client->message->tsigkey != NULL) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_tsigout);
+ }
+ if (client->message->sig0key != NULL) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sig0out);
+ }
+ if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0)
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_truncatedresp);
+
if (result == ISC_R_SUCCESS)
return;
isc_buffer_t tbuffer;
dns_view_t *view;
dns_rdataset_t *opt;
+ dns_name_t *signame;
isc_boolean_t ra; /* Recursion available. */
isc_netaddr_t netaddr;
isc_netaddr_t destaddr;
}
}
+ /*
+ * Update some statistics counters. Don't count responses.
+ */
+ if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_requestv4);
+ } else {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_requestv6);
+ }
+ if (TCP_CLIENT(client))
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_tcp);
+
/*
* Hash the incoming request here as it is after
* dns_dispatch_importrecv().
goto cleanup;
}
+ dns_opcodestats_increment(ns_g_server->opcodestats,
+ client->message->opcode);
switch (client->message->opcode) {
case dns_opcode_query:
case dns_opcode_update:
*/
client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
if (client->ednsversion > 0) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_badednsver);
result = client_addopt(client);
if (result == ISC_R_SUCCESS)
result = DNS_R_BADVERS;
}
}
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_edns0in);
+
/*
* Create an OPT for our reply.
*/
client->signer = NULL;
dns_name_init(&client->signername, NULL);
result = dns_message_signer(client->message, &client->signername);
+ if (result != ISC_R_NOTFOUND) {
+ signame = NULL;
+ if (dns_message_gettsig(client->message, &signame) != NULL) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_tsigin);
+ } else {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_sig0in);
+ }
+
+ }
if (result == ISC_R_SUCCESS) {
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
} else {
char tsigrcode[64];
isc_buffer_t b;
- dns_name_t *name = NULL;
dns_rcode_t status;
isc_result_t tresult;
/* There is a signature, but it is bad. */
- if (dns_message_gettsig(client->message, &name) != NULL) {
+ dns_generalstats_increment(ns_g_server->nsstats,
+ dns_nsstatscounter_invalidsig);
+ signame = NULL;
+ if (dns_message_gettsig(client->message, &signame) != NULL) {
char namebuf[DNS_NAME_FORMATSIZE];
char cnamebuf[DNS_NAME_FORMATSIZE];
- dns_name_format(name, namebuf, sizeof(namebuf));
+ dns_name_format(signame, namebuf, sizeof(namebuf));
status = client->message->tsigstatus;
isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
tresult = dns_tsigrcode_totext(status, &b);
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: convertxsl.pl,v 1.11 2008/04/02 23:46:57 tbox Exp $
+# $Id: convertxsl.pl,v 1.12 2008/04/03 05:55:51 marka Exp $
use strict;
use warnings;
-my $rev = '$Id: convertxsl.pl,v 1.11 2008/04/02 23:46:57 tbox Exp $';
+my $rev = '$Id: convertxsl.pl,v 1.12 2008/04/03 05:55:51 marka Exp $';
$rev =~ s/\$//g;
$rev =~ s/,v//g;
$rev =~ s/Id: //;
my $xsl = "unknown";
-
my $lines = '';
+my (@nsstatsdesc, @zonestatsdesc, @resstatsdesc);
while (<>) {
chomp;
$xsl = $_ if (/<!-- .Id:.* -->/);
# convert Id string to a form not recognisable by cvs.
$_ =~ s/<!-- .Id:(.*). -->/<!-- \\045Id: $1\\045 -->/;
+ if (/server\/nsstats\/(\w+)\"/) {
+ push(@nsstatsdesc, $1);
+ } elsif (/server\/zonestats\/(\w+)\"/) {
+ push(@zonestatsdesc, $1);
+ } elsif (/\"resstats\/(\w+)\"/) {
+ push(@resstatsdesc, $1);
+ }
s/[\ \t]+/ /g;
s/\>\ \</\>\</g;
s/\"/\\\"/g;
$xsl =~ s/,v//;
print "/*\n * Generated by $rev \n * From $xsl\n */\n";
-print 'static char msg[] =',"\n";
+print 'static char xslmsg[] =',"\n";
print $lines;
print ';', "\n";
+
+print "static const char *nsstats_xmldesc[] = {";
+while (my $desc = shift(@nsstatsdesc)) {
+ print "\t\"$desc\"";
+ print "," if (@nsstatsdesc);
+ print "\n";
+}
+print "};\n";
+
+print "static const char *zonestats_xmldesc[] = {";
+while (my $desc = shift(@zonestatsdesc)) {
+ print "\t\"$desc\"";
+ print "," if (@zonestatsdesc);
+ print "\n";
+}
+print "};\n";
+
+print "static const char *resstats_xmldesc[] = {";
+while (my $desc = shift(@resstatsdesc)) {
+ print "\t\"$desc\"";
+ print "," if (@resstatsdesc);
+ print "\n";
+}
+print "};\n";
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.h,v 1.92 2008/01/24 02:00:44 jinmei Exp $ */
+/* $Id: server.h,v 1.93 2008/04/03 05:55:51 marka Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
isc_boolean_t flushonshutdown;
isc_boolean_t log_queries; /*%< For BIND 8 compatibility */
- dns_stats_t * querystats; /*%< Query statistics counters */
+ dns_stats_t * nsstats; /*%< Server statistics */
+ dns_stats_t * rcvquerystats; /*% Incoming query statistics */
+ dns_stats_t * opcodestats; /*%< Incoming message statistics */
+ dns_stats_t * zonestats; /*% Zone management statistics */
+ dns_stats_t * resolverstats; /*% Resolver statistics */
ns_controls_t * controls; /*%< Control channels */
unsigned int dispatchgen;
#define NS_SERVER_MAGIC ISC_MAGIC('S','V','E','R')
#define NS_SERVER_VALID(s) ISC_MAGIC_VALID(s, NS_SERVER_MAGIC)
+/*%
+ * Server statistics counters. Used as dns_statscounter_t values.
+ */
+enum {
+ dns_nsstatscounter_requestv4 = 0,
+ dns_nsstatscounter_requestv6 = 1,
+ dns_nsstatscounter_edns0in = 2,
+ dns_nsstatscounter_badednsver = 3,
+ dns_nsstatscounter_tsigin = 4,
+ dns_nsstatscounter_sig0in = 5,
+ dns_nsstatscounter_invalidsig = 6,
+ dns_nsstatscounter_tcp = 7,
+
+ dns_nsstatscounter_authrej = 8,
+ dns_nsstatscounter_recurserej = 9,
+ dns_nsstatscounter_xfrrej = 10,
+ dns_nsstatscounter_updaterej = 11,
+
+ dns_nsstatscounter_response = 12,
+ dns_nsstatscounter_truncatedresp = 13,
+ dns_nsstatscounter_edns0out = 14,
+ dns_nsstatscounter_tsigout = 15,
+ dns_nsstatscounter_sig0out = 16,
+
+ dns_nsstatscounter_success = 17,
+ dns_nsstatscounter_authans = 18,
+ dns_nsstatscounter_nonauthans = 19,
+ dns_nsstatscounter_referral = 20,
+ dns_nsstatscounter_nxrrset = 21,
+ dns_nsstatscounter_servfail = 22,
+ dns_nsstatscounter_formerr = 23,
+ dns_nsstatscounter_nxdomain = 24,
+ dns_nsstatscounter_recursion = 25,
+ dns_nsstatscounter_duplicate = 26,
+ dns_nsstatscounter_dropped = 27,
+ dns_nsstatscounter_failure = 28,
+
+ dns_nsstatscounter_xfrdone = 29,
+
+ dns_nsstatscounter_updatereqfwd = 30,
+ dns_nsstatscounter_updaterespfwd = 31,
+ dns_nsstatscounter_updatefwdfail = 32,
+ dns_nsstatscounter_updatedone = 33,
+ dns_nsstatscounter_updatefail = 34,
+ dns_nsstatscounter_updatebadprereq = 35,
+
+ dns_nsstatscounter_max = 36
+};
+
void
ns_server_create(isc_mem_t *mctx, ns_server_t **serverp);
/*%<
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.h,v 1.2 2008/01/17 00:15:13 jinmei Exp $ */
+/* $Id: statschannel.h,v 1.3 2008/04/03 05:55:51 marka Exp $ */
#ifndef NAMED_STATSCHANNEL_H
#define NAMED_STATSCHANNEL_H 1
* Initiate shutdown of all the statistics channel listeners.
*/
+isc_result_t
+ns_stats_dump(ns_server_t *server, FILE *fp);
+/*%<
+ * Dump statistics counters managed by the server to the file fp.
+ */
+
#endif /* NAMED_STATSCHANNEL_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: query.c,v 1.304 2008/04/01 01:37:24 marka Exp $ */
+/* $Id: query.c,v 1.305 2008/04/03 05:55:51 marka Exp $ */
/*! \file */
inc_stats(ns_client_t *client, dns_statscounter_t counter) {
dns_zone_t *zone = client->query.authzone;
- REQUIRE(counter < DNS_STATS_NCOUNTERS);
-
- dns_stats_incrementcounter(ns_g_server->querystats, counter);
+ dns_generalstats_increment(ns_g_server->nsstats, counter);
if (zone != NULL) {
- dns_stats_t *zonestats = dns_zone_getstats(zone);
+ dns_stats_t *zonestats = dns_zone_getrequeststats(zone);
if (zonestats != NULL)
- dns_stats_incrementcounter(zonestats, counter);
+ dns_generalstats_increment(zonestats, counter);
}
}
static void
query_send(ns_client_t *client) {
dns_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) {
- counter = dns_statscounter_referral;
+ counter = dns_nsstatscounter_referral;
} else {
- counter = dns_statscounter_nxrrset;
+ counter = dns_nsstatscounter_nxrrset;
}
} else {
- counter = dns_statscounter_success;
+ counter = dns_nsstatscounter_success;
}
} else if (client->message->rcode == dns_rcode_nxdomain) {
- counter = dns_statscounter_nxdomain;
+ counter = dns_nsstatscounter_nxdomain;
} else {
/* We end up here in case of YXDOMAIN, and maybe others */
- counter = dns_statscounter_failure;
+ counter = dns_nsstatscounter_failure;
}
inc_stats(client, counter);
ns_client_send(client);
static void
query_error(ns_client_t *client, isc_result_t result) {
- inc_stats(client, dns_statscounter_failure);
+ switch (result) {
+ case DNS_R_SERVFAIL:
+ inc_stats(client, dns_nsstatscounter_servfail);
+ break;
+ case DNS_R_FORMERR:
+ inc_stats(client, dns_nsstatscounter_formerr);
+ break;
+ default:
+ inc_stats(client, dns_nsstatscounter_failure);
+ break;
+ }
ns_client_error(client, result);
}
static void
query_next(ns_client_t *client, isc_result_t result) {
if (result == DNS_R_DUPLICATE)
- inc_stats(client, dns_statscounter_duplicate);
+ inc_stats(client, dns_nsstatscounter_duplicate);
else if (result == DNS_R_DROP)
- inc_stats(client, dns_statscounter_dropped);
+ inc_stats(client, dns_nsstatscounter_dropped);
else
- inc_stats(client, dns_statscounter_failure);
+ inc_stats(client, dns_nsstatscounter_failure);
ns_client_next(client, result);
}
dns_rdataset_t *rdataset, *sigrdataset;
isc_sockaddr_t *peeraddr;
- inc_stats(client, dns_statscounter_recursion);
+ inc_stats(client, dns_nsstatscounter_recursion);
/*
* We are about to recurse, which means that this client will
}
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_REFUSED) {
+ if (WANTRECURSION(client)) {
+ inc_stats(client,
+ dns_nsstatscounter_recurserej);
+ } else
+ inc_stats(client, dns_nsstatscounter_authrej);
if (!PARTIALANSWER(client))
QUERY_ERROR(DNS_R_REFUSED);
} else
rdataset = ISC_LIST_HEAD(client->query.qname->list);
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:
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: server.c,v 1.504 2008/04/03 02:01:08 marka Exp $ */
+/* $Id: server.c,v 1.505 2008/04/03 05:55:51 marka Exp $ */
/*! \file */
isc_mem_free(mctx, argv);
}
+static isc_result_t
+setquerystats(dns_zone_t *zone, isc_mem_t *mctx, isc_boolean_t on) {
+ isc_result_t result;
+ dns_stats_t *zoneqrystats;
+
+ zoneqrystats = NULL;
+ if (on) {
+ result = dns_generalstats_create(mctx, &zoneqrystats,
+ dns_nsstatscounter_max);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+ dns_zone_setrequeststats(zone, zoneqrystats);
+ if (zoneqrystats != NULL)
+ dns_stats_detach(&zoneqrystats);
+
+ return (ISC_R_SUCCESS);
+}
/*
* Configure 'view' according to 'vconfig', taking defaults from 'config'
isc_boolean_t empty_zones_enable;
const cfg_obj_t *disablelist = NULL;
isc_uint32_t nqports, qports_updateinterval;
+ dns_stats_t *resstats = NULL;
+ dns_stats_t *resquerystats = NULL;
REQUIRE(DNS_VIEW_VALID(view));
* Configure the view's cache. Try to reuse an existing
* cache if possible, otherwise create a new cache.
* Note that the ADB is not preserved in either case.
+ * When a matching view is found, the associated statistics are
+ * also retrieved and reused.
*
* XXX Determining when it is safe to reuse a cache is
* tricky. When the view's configuration changes, the cached
"reusing existing cache");
reused_cache = ISC_TRUE;
dns_cache_attach(pview->cache, &cache);
+ dns_view_getresstats(pview, &resstats);
+ dns_view_getresquerystats(pview, &resquerystats);
dns_view_detach(&pview);
} else {
CHECK(isc_mem_create(0, 0, &cmctx));
* 60));
}
+ if (resstats == NULL) {
+ CHECK(dns_generalstats_create(mctx, &resstats,
+ dns_resstatscounter_max));
+ }
+ dns_view_setresstats(view, resstats);
+ if (resquerystats == NULL)
+ CHECK(dns_rdatatypestats_create(mctx, &resquerystats));
+ dns_view_setresquerystats(view, resquerystats);
+
/*
* Set the ADB cache size to 1/8th of the max-cache-size.
*/
const char *empty_dbtype[4] =
{ "_builtin", "empty", NULL, NULL };
int empty_dbtypec = 4;
+ isc_boolean_t zonestats_on;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
} else
empty_dbtype[3] = ".";
+ obj = NULL;
+ result = ns_config_get(maps, "zone-statistics", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ zonestats_on = cfg_obj_asboolean(obj);
+
logit = ISC_TRUE;
for (empty = empty_zones[empty_zone].zone;
empty != NULL;
*/
(void)dns_view_findzone(view, name, &zone);
if (zone != NULL) {
+ CHECK(setquerystats(zone, mctx, zonestats_on));
dns_zone_detach(&zone);
continue;
}
if (zone != NULL) {
dns_zone_setview(zone, view);
CHECK(dns_view_addzone(view, zone));
+ CHECK(setquerystats(zone, mctx,
+ zonestats_on));
dns_zone_detach(&zone);
continue;
}
CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
dns_zone_setclass(zone, view->rdclass);
dns_zone_settype(zone, dns_zone_master);
+ dns_zone_setstats(zone, ns_g_server->zonestats);
CHECK(dns_zone_setdbtype(zone, empty_dbtypec,
empty_dbtype));
if (view->queryacl != NULL)
dns_zone_setnotifytype(zone, dns_notifytype_no);
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS,
ISC_TRUE);
+ CHECK(setquerystats(zone, mctx, zonestats_on));
CHECK(dns_view_addzone(view, zone));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
dns_dispatch_detach(&dispatch4);
if (dispatch6 != NULL)
dns_dispatch_detach(&dispatch6);
+ if (resstats != NULL)
+ dns_stats_detach(&resstats);
+ if (resquerystats != NULL)
+ dns_stats_detach(&resquerystats);
if (order != NULL)
dns_order_detach(&order);
if (cmctx != NULL)
if (view->acache != NULL)
dns_zone_setacache(zone, view->acache);
CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
+ dns_zone_setstats(zone, ns_g_server->zonestats);
}
/*
&ns_g_dispatchmgr),
"creating dispatch manager");
+ dns_dispatchmgr_setstats(ns_g_dispatchmgr, server->resolverstats);
+
CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr,
ns_g_socketmgr, ns_g_dispatchmgr,
&server->interfacemgr),
server->statsfile = isc_mem_strdup(server->mctx, "named.stats");
CHECKFATAL(server->statsfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
"isc_mem_strdup");
- server->querystats = NULL;
+ server->nsstats = NULL;
+ server->rcvquerystats = NULL;
+ server->opcodestats = NULL;
+ server->zonestats = NULL;
+ server->resolverstats = NULL;
server->dumpfile = isc_mem_strdup(server->mctx, "named_dump.db");
CHECKFATAL(server->dumpfile == NULL ? ISC_R_NOMEMORY : ISC_R_SUCCESS,
server->server_usehostname = ISC_FALSE;
server->server_id = NULL;
- CHECKFATAL(dns_stats_create(ns_g_mctx, &server->querystats),
- "dns_stats_create");
+ CHECKFATAL(dns_generalstats_create(ns_g_mctx, &server->nsstats,
+ dns_nsstatscounter_max),
+ "dns_stats_create (server)");
+
+ CHECKFATAL(dns_rdatatypestats_create(ns_g_mctx,
+ &server->rcvquerystats),
+ "dns_stats_create (rcvquery)");
+
+ CHECKFATAL(dns_opcodestats_create(ns_g_mctx, &server->opcodestats),
+ "dns_stats_create (opcode)");
+
+ CHECKFATAL(dns_generalstats_create(ns_g_mctx, &server->zonestats,
+ dns_zonestatscounter_max),
+ "dns_stats_create (zone)");
+
+ CHECKFATAL(dns_generalstats_create(ns_g_mctx, &server->resolverstats,
+ dns_resstatscounter_max),
+ "dns_stats_create (resolver)");
server->flushonshutdown = ISC_FALSE;
server->log_queries = ISC_FALSE;
ns_controls_destroy(&server->controls);
- dns_stats_destroy(server->mctx, &server->querystats);
+ dns_stats_detach(&server->nsstats);
+ dns_stats_detach(&server->rcvquerystats);
+ dns_stats_detach(&server->opcodestats);
+ dns_stats_detach(&server->zonestats);
+ dns_stats_detach(&server->resolverstats);
isc_mem_free(server->mctx, server->statsfile);
isc_mem_free(server->mctx, server->dumpfile);
isc_result_t
ns_server_dumpstats(ns_server_t *server) {
isc_result_t result;
- dns_zone_t *zone, *next;
- isc_stdtime_t now;
FILE *fp = NULL;
- int i;
- int ncounters;
- isc_uint64_t counters[DNS_STATS_NCOUNTERS];
-
- isc_stdtime_get(&now);
CHECKMF(isc_stdio_open(server->statsfile, "a", &fp),
"could not open statistics dump file", server->statsfile);
- ncounters = DNS_STATS_NCOUNTERS;
- fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
-
- dns_stats_copy(server->querystats, counters);
- for (i = 0; i < ncounters; i++)
- fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n",
- dns_statscounter_names[i], counters[i]);
-
- zone = NULL;
- for (result = dns_zone_first(server->zonemgr, &zone);
- result == ISC_R_SUCCESS;
- next = NULL, result = dns_zone_next(zone, &next), zone = next)
- {
- dns_stats_t *zonestats = dns_zone_getstats(zone);
- if (zonestats != NULL) {
- char zonename[DNS_NAME_FORMATSIZE];
- dns_view_t *view;
- char *viewname;
-
- dns_stats_copy(zonestats, counters);
- dns_name_format(dns_zone_getorigin(zone),
- zonename, sizeof(zonename));
- view = dns_zone_getview(zone);
- viewname = view->name;
- for (i = 0; i < ncounters; i++) {
- fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT
- "u %s",
- dns_statscounter_names[i],
- counters[i],
- zonename);
- if (strcmp(viewname, "_default") != 0)
- fprintf(fp, " %s", viewname);
- fprintf(fp, "\n");
- }
- }
- }
- if (result == ISC_R_NOMORE)
- result = ISC_R_SUCCESS;
+ result = ns_stats_dump(server, fp);
CHECK(result);
- fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
-
cleanup:
if (fp != NULL)
(void)isc_stdio_close(fp);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.c,v 1.6 2008/03/31 05:00:29 marka Exp $ */
+/* $Id: statschannel.c,v 1.7 2008/04/03 05:55:51 marka Exp $ */
/*! \file */
#include <isc/socket.h>
#include <isc/task.h>
+#include <dns/db.h>
+#include <dns/opcode.h>
+#include <dns/rdataclass.h>
+#include <dns/rdatatype.h>
#include <dns/stats.h>
#include <dns/view.h>
+#include <dns/zt.h>
#include <named/log.h>
#include <named/server.h>
#include <named/statschannel.h>
+#include "bind9.xsl.h"
+
struct ns_statschannel {
/* Unlocked */
isc_httpdmgr_t *httpdmgr;
ISC_LINK(struct ns_statschannel) link;
};
+typedef enum { statsformat_file, statsformat_xml } statsformat_t;
+
+typedef struct
+stats_dumparg {
+ statsformat_t type;
+ void *arg; /* type dependent argument */
+ const char **desc; /* used for general statistics */
+ int ncounters; /* used for general statistics */
+} stats_dumparg_t;
+
+static void
+generalstat_dump(dns_statscounter_t counter, isc_uint64_t val, void *arg) {
+ stats_dumparg_t *dumparg = arg;
+ FILE *fp;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#endif
+
+ REQUIRE(counter < dumparg->ncounters);
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val,
+ dumparg->desc[counter]);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR
+ dumparg->desc[counter]);
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer);
+#endif
+ break;
+ }
+}
+
+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;
+#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;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype");
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr);
+ xmlTextWriterEndElement(writer); /* name */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer); /* counter */
+
+ xmlTextWriterEndElement(writer); /* rdtype */
+#endif
+ break;
+ }
+}
+
+static void
+rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
+ stats_dumparg_t *dumparg = arg;
+ FILE *fp;
+ char typebuf[64];
+ const char *typestr;
+ isc_boolean_t nxrrset = ISC_FALSE;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#endif
+
+ if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN)
+ != 0) {
+ typestr = "NXDOMAIN";
+ } else if ((DNS_RDATASTATSTYPE_ATTR(type) &
+ DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0) {
+ typestr = "Others";
+ } else {
+ dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
+ sizeof(typebuf));
+ typestr = typebuf;
+ }
+
+ if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXRRSET)
+ != 0)
+ nxrrset = ISC_TRUE;
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s%s\n", val,
+ nxrrset ? "!" : "", typestr);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset");
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteFormatString(writer, "%s%s",
+ nxrrset ? "!" : "", typestr);
+ xmlTextWriterEndElement(writer); /* name */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer); /* counter */
+
+ xmlTextWriterEndElement(writer); /* rrset */
+#endif
+ break;
+ }
+}
+
+static void
+opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
+ FILE *fp = arg;
+ isc_buffer_t b;
+ char codebuf[64];
+ stats_dumparg_t *dumparg = arg;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#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;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode");
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf);
+ xmlTextWriterEndElement(writer); /* name */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer); /* counter */
+
+ xmlTextWriterEndElement(writer); /* opcode */
+#endif
+ break;
+ }
+}
+
#ifdef HAVE_LIBXML2
/* XXXMLG below here sucks. */
#define TRY(a) do { result = (a); INSIST(result == ISC_R_SUCCESS); } while(0);
#define TRY0(a) do { xmlrc = (a); INSIST(xmlrc >= 0); } while(0);
-#define NODES 8
-#define SPACES 3
+static isc_result_t
+zone_xmlrender(dns_zone_t *zone, void *arg) {
+ char buf[1024 + 32]; /* sufficiently large for zone name and class */
+ dns_rdataclass_t rdclass;
+ isc_uint32_t serial;
+ xmlTextWriterPtr writer = arg;
+ stats_dumparg_t dumparg;
+ dns_stats_t *zonestats;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone");
+
+ dns_zone_name(zone, buf, sizeof(buf));
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
+ xmlTextWriterEndElement(writer);
+
+ rdclass = dns_zone_getclass(zone);
+ dns_rdataclass_format(rdclass, buf, sizeof(buf));
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
+ xmlTextWriterEndElement(writer);
+
+ serial = dns_zone_getserial(zone);
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial");
+ xmlTextWriterWriteFormatString(writer, "%u", serial);
+ xmlTextWriterEndElement(writer);
+
+ dumparg.type = statsformat_xml;
+ dumparg.arg = writer;
+ dumparg.desc = nsstats_xmldesc;
+ dumparg.ncounters = dns_nsstatscounter_max;
+
+ zonestats = dns_zone_getrequeststats(zone);
+ if (zonestats != NULL) {
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters");
+ dns_generalstats_dump(zonestats, generalstat_dump,
+ &dumparg, DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* counters */
+ }
+
+ xmlTextWriterEndElement(writer); /* zone */
+
+ return (ISC_R_SUCCESS);
+}
static void
generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
xmlDocPtr doc;
int xmlrc;
dns_view_t *view;
- int i;
- isc_uint64_t counters[DNS_STATS_NCOUNTERS];
+ stats_dumparg_t dumparg;
+ dns_stats_t *cachestats;
isc_time_now(&now);
isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
ISC_XMLCHAR "1.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) {
- dns_view_xmlrender(view, writer, ISC_XML_RENDERALL);
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "view");
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name);
+ xmlTextWriterEndElement(writer);
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones");
+ dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender,
+ writer);
+ xmlTextWriterEndElement(writer);
+
+ if (view->resquerystats != NULL) {
+ dns_rdatatypestats_dump(view->resquerystats,
+ rdtypestat_dump, &dumparg, 0);
+ }
+
+ if (view->resstats != NULL) {
+ xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "resstats");
+ dumparg.ncounters = dns_resstatscounter_max;
+ dumparg.desc = resstats_xmldesc; /* auto-generated */
+ dns_generalstats_dump(view->resstats, generalstat_dump,
+ &dumparg, DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* resstats */
+ }
+
+ cachestats = dns_db_getrrsetstats(view->cachedb);
+ if (cachestats != NULL) {
+ xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "cache");
+ dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
+ &dumparg, 0);
+ xmlTextWriterEndElement(writer); /* cache */
+ }
+
+ xmlTextWriterEndElement(writer); /* view */
+
view = ISC_LIST_NEXT(view, link);
}
TRY0(xmlTextWriterEndElement(writer)); /* views */
xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time");
xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr);
xmlTextWriterEndElement(writer);
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
- dns_stats_copy(server->querystats, counters);
- for (i = 0; i < DNS_STATS_NCOUNTERS; i++) {
- xmlTextWriterStartElement(writer,
- ISC_XMLCHAR dns_statscounter_names[i]);
- xmlTextWriterWriteFormatString(writer,
- "%" ISC_PRINT_QUADFORMAT "u",
- counters[i]);
- xmlTextWriterEndElement(writer);
- }
- xmlTextWriterEndElement(writer); /* counters */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests"));
+ dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg,
+ 0);
+ xmlTextWriterEndElement(writer); /* requests */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in"));
+ dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
+ &dumparg, 0);
+ xmlTextWriterEndElement(writer); /* queries-in */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nsstats"));
+ dumparg.desc = nsstats_xmldesc; /* auto-generated in bind9.xsl.h */
+ dumparg.ncounters = dns_nsstatscounter_max;
+ dns_generalstats_dump(server->nsstats, generalstat_dump, &dumparg,
+ DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* nsstats */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zonestats"));
+ dumparg.desc = zonestats_xmldesc; /* auto-generated in bind9.xsl.h */
+ dumparg.ncounters = dns_zonestatscounter_max;
+ dns_generalstats_dump(server->zonestats, generalstat_dump, &dumparg,
+ DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* zonestats */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "resstats");
+ dumparg.ncounters = dns_resstatscounter_max;
+ dumparg.desc = resstats_xmldesc;
+ dns_generalstats_dump(server->resolverstats, generalstat_dump,
+ &dumparg, DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* resstats */
+
xmlTextWriterEndElement(writer); /* server */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
isc_buffer_t *b, isc_httpdfree_t **freecb,
void **freecb_args)
{
-#include "bind9.xsl.h"
-
UNUSED(url);
UNUSED(querystring);
UNUSED(args);
*retcode = 200;
*retmsg = "OK";
*mimetype = "text/xslt+xml";
- isc_buffer_reinit(b, msg, strlen(msg));
- isc_buffer_add(b, strlen(msg));
+ isc_buffer_reinit(b, xslmsg, strlen(xslmsg));
+ isc_buffer_add(b, strlen(xslmsg));
*freecb = NULL;
*freecb_args = NULL;
shutdown_listener(listener);
}
}
+
+/* name server statistics */
+static const char *nsstats_desc[] = {
+ "IPv4 requests received", /* dns_nsstatscounter_requestv4 */
+ "IPv6 requests received", /* dns_nsstatscounter_requestv6 */
+ "requests with EDNS(0) received", /* dns_nsstatscounter_edns0in */
+ "requests with unsupported EDNS "
+ "version received", /* dns_nsstatscounter_badednsver */
+ "requests with TSIG received", /* dns_nsstatscounter_tsigin */
+ "requests with SIG(0) received", /* dns_nsstatscounter_sig0in */
+ "requests with invalid signature",/* dns_nsstatscounter_invalidsig */
+ "TCP requests received", /* dns_nsstatscounter_tcp */
+
+ "auth queries rejected", /* dns_nsstatscounter_authrej */
+ "recursive queries rejected", /* dns_nsstatscounter_recurserej */
+ "transfer requests rejected", /* dns_nsstatscounter_xfrrej */
+ "update requests rejected", /* dns_nsstatscounter_updaterej */
+
+ "responses sent", /* dns_nsstatscounter_response */
+ "truncated responses sent", /* dns_nsstatscounter_truncatedresp */
+ "responses with EDNS(0) sent", /* dns_nsstatscounter_edns0out */
+ "responses with TSIG sent", /* dns_nsstatscounter_tsigout */
+ "responses with SIG(0) sent", /* dns_nsstatscounter_sig0out */
+
+ "queries resulted in successful answer",/* dns_nsstatscounter_success */
+ "queries resulted in "
+ "authoritative answer", /* dns_nsstatscounter_authans */
+ "queries resulted in non "
+ "authoritative answer", /* dns_nsstatscounter_nonauthans */
+ "queries resulted in referral answer", /* dns_nsstatscounter_referral */
+ "queries resulted in nxrrset", /* dns_nsstatscounter_nxrrset */
+ "queries resulted in SERVFAIL", /* dns_nsstatscounter_servfail */
+ "queries resulted in FORMERR", /* dns_nsstatscounter_formerr */
+ "queries resulted in NXDOMAIN", /* dns_nsstatscounter_nxdomain */
+ "queries caused recursion", /* dns_nsstatscounter_recursion */
+ "duplicate queries received", /* dns_nsstatscounter_duplicate */
+ "queries dropped", /* dns_nsstatscounter_dropped */
+ "other query failures", /* dns_nsstatscounter_failure */
+
+ "requested transfers completed", /* dns_nsstatscounter_xfrdone */
+
+ "update requests forwarded", /* dns_nsstatscounter_updatereqfwd */
+ "update responses forwarded", /* dns_nsstatscounter_updaterespfwd */
+ "update forward failed", /* dns_nsstatscounter_updatefwdfail */
+ "updates completed", /* dns_nsstatscounter_updatedone */
+ "updates failed", /* dns_nsstatscounter_updatefail */
+ "updates rejected due to "
+ "prerequisite failure" /* dns_nsstatscounter_updatebadprereq */
+};
+
+/* resolver statistics */
+static const char *resstats_desc[] = {
+ "IPv4 queries sent", /* dns_resstatscounter_queryv4 */
+ "IPv6 queries sent", /* dns_resstatscounter_queryv6 */
+ "IPv4 responses received", /* dns_resstatscounter_responsev4 */
+ "IPv6 responses received", /* dns_resstatscounter_responsev6 */
+ "NXDOMAIN received", /* dns_resstatscounter_nxdomain */
+ "SERVFAIL received", /* dns_resstatscounter_servfail */
+ "FORMERR received", /* dns_resstatscounter_formerr */
+ "other errors received", /* dns_resstatscounter_othererror */
+ "EDNS(0) query failures", /* dns_resstatscounter_edns0fail */
+ "mismatch responses received", /* dns_resstatscounter_mismatch */
+ "truncated responses received", /* dns_resstatscounter_truncated */
+ "lame delegations received", /* dns_resstatscounter_lame */
+ "query retries", /* dns_resstatscounter_retry */
+ "IPv4 NS address fetches", /* dns_resstatscounter_gluefetchv4 */
+ "IPv6 NS address fetches", /* dns_resstatscounter_gluefetchv6 */
+ "IPv4 NS address fetch failed", /* dns_resstatscounter_gluefetchv4fail */
+ "IPv6 NS address fetch failed", /* dns_resstatscounter_gluefetchv6fail */
+ "DNSSEC validation attempted", /* dns_resstatscounter_val */
+ "DNSSEC validation failed", /* dns_resstatscounter_valfail */
+ "DNSSEC validation succeeded", /* dns_resstatscounter_valsuccess */
+ "DNSSEC NX validation succeeded"/* dns_resstatscounter_valnegsuccess */
+};
+
+/* zone statistics */
+static const char *zonestats_desc[] = {
+ "IPv4 notifies sent", /* dns_zonestatscounter_notifyoutv4 */
+ "IPv6 notifies sent", /* dns_zonestatscounter_notifyoutv6 */
+ "IPv4 notifies received", /* dns_zonestatscounter_notifyinv4 */
+ "IPv6 notifies received", /* dns_zonestatscounter_notifyinv6 */
+ "notifies rejected", /* dns_zonestatscounter_notifyrej */
+ "IPv4 SOA queries sent", /* dns_zonestatscounter_soaoutv4 */
+ "IPv6 SOA queries sent", /* dns_zonestatscounter_soaoutv6 */
+ "IPv4 AXFR requested", /* dns_zonestatscounter_axfrreqv4 */
+ "IPv6 AXFR requested", /* dns_zonestatscounter_axfrreqv6 */
+ "IPv4 IXFR requested", /* dns_zonestatscounter_ixfrreqv4 */
+ "IPv6 IXFR requested", /* dns_zonestatscounter_ixfrreqv6 */
+ "transfer requests succeeded", /* dns_zonestatscounter_xfrsuccess */
+ "transfer requests failed" /* dns_zonestatscounter_xfrfail */
+};
+
+isc_result_t
+ns_stats_dump(ns_server_t *server, FILE *fp) {
+ isc_stdtime_t now;
+ isc_result_t result;
+ dns_view_t *view;
+ dns_zone_t *zone, *next;
+ stats_dumparg_t dumparg;
+
+ /* Set common fields */
+ dumparg.type = statsformat_file;
+ dumparg.arg = fp;
+
+ isc_stdtime_get(&now);
+ fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
+
+ fprintf(fp, "++ Incoming Requests ++\n");
+ dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg,
+ 0);
+
+ fprintf(fp, "++ Incoming Queries ++\n");
+ dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
+ &dumparg, 0);
+
+ fprintf(fp, "++ Outgoing Queries ++\n");
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ if (view->resquerystats == NULL)
+ continue;
+ if (strcmp(view->name, "_default") == 0)
+ fprintf(fp, "[View: default]\n");
+ else
+ fprintf(fp, "[View: %s]\n", view->name);
+ dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump,
+ &dumparg, 0);
+ }
+
+ fprintf(fp, "++ Name Server Statistics ++\n");
+ dumparg.desc = nsstats_desc;
+ dumparg.ncounters = dns_nsstatscounter_max;
+ dns_generalstats_dump(server->nsstats, generalstat_dump, &dumparg, 0);
+ fprintf(fp, "++ Zone Maintenance Statistics ++\n");
+ dumparg.desc = zonestats_desc;
+ dumparg.ncounters = dns_zonestatscounter_max;
+ dns_generalstats_dump(server->zonestats, generalstat_dump, &dumparg, 0);
+
+ fprintf(fp, "++ Resolver Statistics ++\n");
+ fprintf(fp, "[Common]\n");
+ dumparg.desc = resstats_desc;
+ dumparg.ncounters = dns_resstatscounter_max;
+ dns_generalstats_dump(server->resolverstats, generalstat_dump, &dumparg,
+ 0);
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ if (view->resstats == NULL)
+ continue;
+ if (strcmp(view->name, "_default") == 0)
+ fprintf(fp, "[View: default]\n");
+ else
+ fprintf(fp, "[View: %s]\n", view->name);
+ dns_generalstats_dump(view->resstats, generalstat_dump,
+ &dumparg, 0);
+ }
+
+ fprintf(fp, "++ Cache DB RRsets ++\n");
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ dns_stats_t *cachestats;
+
+ cachestats = dns_db_getrrsetstats(view->cachedb);
+ if (cachestats == NULL)
+ continue;
+ if (strcmp(view->name, "_default") == 0)
+ fprintf(fp, "[View: default]\n");
+ else
+ fprintf(fp, "[View: %s]\n", view->name);
+ dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg,
+ 0);
+ }
+
+ fprintf(fp, "++ Per Zone Query Statistics ++\n");
+ zone = NULL;
+ for (result = dns_zone_first(server->zonemgr, &zone);
+ result == ISC_R_SUCCESS;
+ next = NULL, result = dns_zone_next(zone, &next), zone = next)
+ {
+ dns_stats_t *zonestats = dns_zone_getrequeststats(zone);
+ if (zonestats != NULL) {
+ char zonename[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(dns_zone_getorigin(zone),
+ zonename, sizeof(zonename));
+ view = dns_zone_getview(zone);
+
+ fprintf(fp, "[%s", zonename);
+ if (strcmp(view->name, "_default") != 0)
+ fprintf(fp, " (view: %s)", view->name);
+ fprintf(fp, "]\n");
+
+ dumparg.desc = nsstats_desc;
+ dumparg.ncounters = dns_nsstatscounter_max;
+ dns_generalstats_dump(zonestats, generalstat_dump,
+ &dumparg, 0);
+ }
+ }
+
+ fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
+
+ return (ISC_R_SUCCESS); /* this function currently always succeeds */
+}
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update.c,v 1.145 2008/04/02 02:37:41 marka Exp $ */
+/* $Id: update.c,v 1.146 2008/04/03 05:55:51 marka Exp $ */
#include <config.h>
#include <dns/rdatatype.h>
#include <dns/soa.h>
#include <dns/ssu.h>
+#include <dns/stats.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
#include <named/client.h>
#include <named/log.h>
+#include <named/server.h>
#include <named/update.h>
/*! \file
msg, isc_result_totext(result)); \
if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
+#define PREREQFAILC(code, msg) \
+ do { \
+ inc_stats(zone, dns_nsstatscounter_updatebadprereq); \
+ FAILC(code, msg); \
+ } while (0)
#define FAILN(code, name, msg) \
do { \
} \
if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
+#define PREREQFAILN(code, name, msg) \
+ do { \
+ inc_stats(zone, dns_nsstatscounter_updatebadprereq); \
+ FAILN(code, name, msg); \
+ } while (0)
#define FAILNT(code, name, type, msg) \
do { \
} \
if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
+#define PREREQFAILNT(code, name, type, msg) \
+ do { \
+ inc_stats(zone, dns_nsstatscounter_updatebadprereq); \
+ FAILNT(code, name, type, msg); \
+ } while (0)
+
/*%
* Fail unconditionally and log as a server error.
* The test against ISC_R_SUCCESS is there to keep the Solaris compiler
namebuf, classbuf, message);
}
+/*%
+ * Increment updated-related statistics counters.
+ */
+static inline void
+inc_stats(dns_zone_t *zone, dns_statscounter_t counter) {
+ dns_generalstats_increment(ns_g_server->nsstats, counter);
+
+ if (zone != NULL) {
+ dns_stats_t *zonestats = dns_zone_getrequeststats(zone);
+ if (zonestats != NULL)
+ dns_generalstats_increment(zonestats, counter);
+ }
+}
+
/*%
* Override the default acl logging when checking whether a client
* can update the zone or whether we can forward the request to the
return;
failure:
+ if (result == DNS_R_REFUSED) {
+ INSIST(dns_zone_gettype(zone) == dns_zone_slave);
+ inc_stats(zone, dns_nsstatscounter_updaterej);
+ }
/*
* We failed without having sent an update event to the zone.
* We are still in the client task context, so we can
&name, &rdata, &covers, &ttl, &update_class);
if (ttl != 0)
- FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero");
+ PREREQFAILC(DNS_R_FORMERR,
+ "prerequisite TTL is not zero");
if (! dns_name_issubdomain(name, zonename))
- FAILN(DNS_R_NOTZONE, name,
- "prerequisite name is out of zone");
+ PREREQFAILN(DNS_R_NOTZONE, name,
+ "prerequisite name is out of zone");
if (update_class == dns_rdataclass_any) {
if (rdata.length != 0)
- FAILC(DNS_R_FORMERR,
+ PREREQFAILC(DNS_R_FORMERR,
"class ANY prerequisite "
"RDATA is not empty");
if (rdata.type == dns_rdatatype_any) {
CHECK(name_exists(db, ver, name, &flag));
if (! flag) {
- FAILN(DNS_R_NXDOMAIN, name,
- "'name in use' prerequisite "
- "not satisfied");
+ PREREQFAILN(DNS_R_NXDOMAIN, name,
+ "'name in use' "
+ "prerequisite not "
+ "satisfied");
}
} else {
CHECK(rrset_exists(db, ver, name,
rdata.type, covers, &flag));
if (! flag) {
/* RRset does not exist. */
- FAILNT(DNS_R_NXRRSET, name, rdata.type,
+ PREREQFAILNT(DNS_R_NXRRSET, name, rdata.type,
"'rrset exists (value independent)' "
"prerequisite not satisfied");
}
}
} else if (update_class == dns_rdataclass_none) {
if (rdata.length != 0)
- FAILC(DNS_R_FORMERR,
- "class NONE prerequisite "
- "RDATA is not empty");
+ PREREQFAILC(DNS_R_FORMERR,
+ "class NONE prerequisite "
+ "RDATA is not empty");
if (rdata.type == dns_rdatatype_any) {
CHECK(name_exists(db, ver, name, &flag));
if (flag) {
- FAILN(DNS_R_YXDOMAIN, name,
- "'name not in use' prerequisite "
- "not satisfied");
+ PREREQFAILN(DNS_R_YXDOMAIN, name,
+ "'name not in use' "
+ "prerequisite not "
+ "satisfied");
}
} else {
CHECK(rrset_exists(db, ver, name,
rdata.type, covers, &flag));
if (flag) {
/* RRset exists. */
- FAILNT(DNS_R_YXRRSET, name, rdata.type,
- "'rrset does not exist' "
- "prerequisite not satisfied");
+ PREREQFAILNT(DNS_R_YXRRSET, name,
+ rdata.type,
+ "'rrset does not exist' "
+ "prerequisite not "
+ "satisfied");
}
}
} else if (update_class == zoneclass) {
FAIL(ISC_R_UNEXPECTED);
}
} else {
- FAILC(DNS_R_FORMERR, "malformed prerequisite");
+ PREREQFAILC(DNS_R_FORMERR, "malformed prerequisite");
}
}
if (result != ISC_R_NOMORE)
goto common;
failure:
+ if (result == DNS_R_REFUSED)
+ inc_stats(zone, dns_nsstatscounter_updaterej);
+
/*
* The reason for failure should have been logged at this point.
*/
if (ssutable != NULL)
dns_ssutable_detach(&ssutable);
- if (zone != NULL)
- dns_zone_detach(&zone);
-
isc_task_detach(&task);
uev->result = result;
+ if (zone != NULL)
+ INSIST(uev->zone == zone); /* we use this later */
uev->ev_type = DNS_EVENT_UPDATEDONE;
uev->ev_action = updatedone_action;
isc_task_send(client->task, &event);
INSIST(task == client->task);
INSIST(client->nupdates > 0);
+ switch (uev->result) {
+ case ISC_R_SUCCESS:
+ inc_stats(uev->zone, dns_nsstatscounter_updatedone);
+ break;
+ case DNS_R_REFUSED:
+ inc_stats(uev->zone, dns_nsstatscounter_updaterej);
+ break;
+ default:
+ inc_stats(uev->zone, dns_nsstatscounter_updatefail);
+ break;
+ }
+ if (uev->zone != NULL)
+ dns_zone_detach(&uev->zone);
client->nupdates--;
respond(client, uev->result);
isc_event_free(&event);
forward_callback(void *arg, isc_result_t result, dns_message_t *answer) {
update_event_t *uev = arg;
ns_client_t *client = uev->ev_arg;
+ dns_zone_t *zone = uev->zone;
if (result != ISC_R_SUCCESS) {
INSIST(answer == NULL);
uev->ev_type = DNS_EVENT_UPDATEDONE;
uev->ev_action = forward_fail;
+ inc_stats(zone, dns_nsstatscounter_updatefwdfail);
} else {
uev->ev_type = DNS_EVENT_UPDATEDONE;
uev->ev_action = forward_done;
uev->answer = answer;
+ inc_stats(zone, dns_nsstatscounter_updaterespfwd);
}
isc_task_send(client->task, ISC_EVENT_PTR(&uev));
+ dns_zone_detach(&zone);
}
static void
uev->ev_type = DNS_EVENT_UPDATEDONE;
uev->ev_action = forward_fail;
isc_task_send(client->task, &event);
- }
- dns_zone_detach(&zone);
+ inc_stats(zone, dns_nsstatscounter_updatefwdfail);
+ dns_zone_detach(&zone);
+ } else
+ inc_stats(zone, dns_nsstatscounter_updatereqfwd);
isc_task_detach(&task);
}
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: xfrout.c,v 1.126 2007/06/18 23:47:19 tbox Exp $ */
+/* $Id: xfrout.c,v 1.127 2008/04/03 05:55:51 marka Exp $ */
#include <config.h>
#include <dns/rdatasetiter.h>
#include <dns/result.h>
#include <dns/soa.h>
+#include <dns/stats.h>
#include <dns/timer.h>
#include <dns/tsig.h>
#include <dns/view.h>
static void
db_rr_iterator_destroy(db_rr_iterator_t *it);
+static inline void
+inc_stats(dns_zone_t *zone, dns_statscounter_t counter) {
+ dns_generalstats_increment(ns_g_server->nsstats, counter);
+ if (zone != NULL) {
+ dns_stats_t *zonestats = dns_zone_getrequeststats(zone);
+ if (zonestats != NULL)
+ dns_generalstats_increment(zonestats, counter);
+ }
+}
+
static isc_result_t
db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
isc_stdtime_t now)
dns_name_t *qname; /* Question name of request */
dns_rdatatype_t qtype; /* dns_rdatatype_{a,i}xfr */
dns_rdataclass_t qclass;
+ dns_zone_t *zone; /* (necessary for stats) */
dns_db_t *db;
dns_dbversion_t *ver;
isc_quota_t *quota;
static isc_result_t
xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client,
unsigned int id, dns_name_t *qname, dns_rdatatype_t qtype,
- dns_rdataclass_t qclass,
+ dns_rdataclass_t qclass, dns_zone_t *zone,
dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota,
rrstream_t *stream, dns_tsigkey_t *tsigkey,
isc_buffer_t *lasttsig,
#ifdef DLZ
if (is_dlz)
CHECK(xfrout_ctx_create(mctx, client, request->id, question_name,
- reqtype, question_class, db, ver, quota,
- stream, dns_message_gettsigkey(request),
+ reqtype, question_class, zone, db, ver,
+ quota, stream,
+ dns_message_gettsigkey(request),
tsigbuf,
3600,
3600,
else
#endif
CHECK(xfrout_ctx_create(mctx, client, request->id, question_name,
- reqtype, question_class, db, ver, quota,
- stream, dns_message_gettsigkey(request),
+ reqtype, question_class, zone, db, ver,
+ quota, stream,
+ dns_message_gettsigkey(request),
tsigbuf,
dns_zone_getmaxxfrout(zone),
dns_zone_getidleout(zone),
result = ISC_R_SUCCESS;
failure:
+ if (result == DNS_R_REFUSED)
+ inc_stats(zone, dns_nsstatscounter_xfrrej);
if (quota != NULL)
isc_quota_detach("a);
if (current_soa_tuple != NULL)
static isc_result_t
xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
dns_name_t *qname, dns_rdatatype_t qtype,
- dns_rdataclass_t qclass,
+ dns_rdataclass_t qclass, dns_zone_t *zone,
dns_db_t *db, dns_dbversion_t *ver, isc_quota_t *quota,
rrstream_t *stream, dns_tsigkey_t *tsigkey,
isc_buffer_t *lasttsig, unsigned int maxtime,
xfr->qname = qname;
xfr->qtype = qtype;
xfr->qclass = qclass;
+ xfr->zone = NULL;
xfr->db = NULL;
xfr->ver = NULL;
+ dns_zone_attach(zone, &xfr->zone);
dns_db_attach(db, &xfr->db);
dns_db_attachversion(db, ver, &xfr->ver);
xfr->end_of_stream = ISC_FALSE;
isc_quota_detach(&xfr->quota);
if (xfr->ver != NULL)
dns_db_closeversion(xfr->db, &xfr->ver, ISC_FALSE);
+ if (xfr->zone != NULL)
+ dns_zone_detach(&xfr->zone);
if (xfr->db != NULL)
dns_db_detach(&xfr->db);
sendstream(xfr);
} else {
/* End of zone transfer stream. */
+ inc_stats(xfr->zone, dns_nsstatscounter_xfrdone);
xfrout_log(xfr, ISC_LOG_INFO, "%s ended", xfr->mnemonic);
ns_client_next(xfr->client, ISC_R_SUCCESS);
xfrout_ctx_destroy(&xfr);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zoneconf.c,v 1.143 2008/04/02 02:37:41 marka Exp $ */
+/* $Id: zoneconf.c,v 1.144 2008/04/03 05:55:51 marka Exp $ */
/*% */
#include <dns/name.h>
#include <dns/rdatatype.h>
#include <dns/ssu.h>
+#include <dns/stats.h>
#include <dns/view.h>
#include <dns/zone.h>
isc_boolean_t warn = ISC_FALSE, ignore = ISC_FALSE;
isc_boolean_t ixfrdiff;
dns_masterformat_t masterformat;
+ dns_stats_t *zoneqrystats;
+ isc_boolean_t zonestats_on;
int seconds;
i = 0;
obj = NULL;
result = ns_config_get(maps, "zone-statistics", &obj);
INSIST(result == ISC_R_SUCCESS);
- RETERR(dns_zone_setstatistics(zone, cfg_obj_asboolean(obj)));
+ zonestats_on = cfg_obj_asboolean(obj);
+ zoneqrystats = NULL;
+ if (zonestats_on) {
+ RETERR(dns_generalstats_create(mctx, &zoneqrystats,
+ dns_nsstatscounter_max));
+ }
+ dns_zone_setrequeststats(zone, zoneqrystats);
+ if (zoneqrystats != NULL)
+ dns_stats_detach(&zoneqrystats);
/*
* Configure master functionality. This applies
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.c,v 1.236 2008/03/20 19:23:42 jinmei Exp $ */
+/* $Id: adb.c,v 1.237 2008/04/03 05:55:51 marka Exp $ */
/*! \file
*
#include <dns/rdatatype.h>
#include <dns/resolver.h>
#include <dns/result.h>
+#include <dns/stats.h>
#define DNS_ADB_MAGIC ISC_MAGIC('D', 'a', 'd', 'b')
#define DNS_ADB_VALID(x) ISC_MAGIC_VALID(x, DNS_ADB_MAGIC)
va_end(args);
}
+/*%
+ * Increment resolver-related statistics counters.
+ */
+static inline void
+inc_stats(dns_adb_t *adb, dns_statscounter_t counter) {
+ if (adb->view->resstats != NULL)
+ dns_generalstats_increment(adb->view->resstats, counter);
+}
+
static inline dns_ttl_t
ttlclamp(dns_ttl_t ttl) {
if (ttl < ADB_CACHE_MINIMUM)
name->fetch_err = FIND_ERR_NXDOMAIN;
else
name->fetch_err = FIND_ERR_NXRRSET;
+ inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
} else {
DP(NCACHE_LEVEL, "adb fetch name %p: "
"caching negative entry for AAAA (ttl %u)",
name->fetch6_err = FIND_ERR_NXDOMAIN;
else
name->fetch6_err = FIND_ERR_NXRRSET;
+ inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
}
goto out;
}
if (address_type == DNS_ADBFIND_INET) {
name->expire_v4 = ISC_MIN(name->expire_v4, now + 300);
name->fetch_err = FIND_ERR_FAILURE;
+ inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
} else {
name->expire_v6 = ISC_MIN(name->expire_v6, now + 300);
name->fetch6_err = FIND_ERR_FAILURE;
+ inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
}
goto out;
}
if (result != ISC_R_SUCCESS)
goto cleanup;
- if (type == dns_rdatatype_a)
+ if (type == dns_rdatatype_a) {
adbname->fetch_a = fetch;
- else
+ inc_stats(adb, dns_resstatscounter_gluefetchv4);
+ } else {
adbname->fetch_aaaa = fetch;
+ inc_stats(adb, dns_resstatscounter_gluefetchv6);
+ }
fetch = NULL; /* Keep us from cleaning this up below. */
cleanup:
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.c,v 1.86 2008/04/01 23:47:10 tbox Exp $ */
+/* $Id: db.c,v 1.87 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
return (ISC_R_NOTFOUND);
}
+dns_stats_t *
+dns_db_getrrsetstats(dns_db_t *db) {
+ REQUIRE(DNS_DB_VALID(db));
+
+ if (db->methods->getrrsetstats != NULL)
+ return ((db->methods->getrrsetstats)(db));
+
+ return (NULL);
+}
+
isc_result_t
dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
isc_stdtime_t resign)
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.138 2008/04/03 02:01:08 marka Exp $ */
+/* $Id: dispatch.c,v 1.139 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
#include <dns/log.h>
#include <dns/message.h>
#include <dns/portlist.h>
+#include <dns/stats.h>
#include <dns/tcpmsg.h>
#include <dns/types.h>
isc_mem_t *mctx;
dns_acl_t *blackhole;
dns_portlist_t *portlist;
+ dns_stats_t *stats;
/* Locked by "lock". */
isc_mutex_t lock;
bucket, (resp == NULL ? "not found" : "found"));
if (resp == NULL) {
+ dns_generalstats_increment(mgr->stats,
+ dns_resstatscounter_mismatch);
free_buffer(disp, ev->region.base, ev->region.length);
goto unlock;
}
if (mgr->portlist != NULL)
dns_portlist_detach(&mgr->portlist);
+ if (mgr->stats != NULL)
+ dns_stats_detach(&mgr->stats);
+
isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t));
isc_mem_detach(&mctx);
}
mgr->blackhole = NULL;
mgr->portlist = NULL;
+ mgr->stats = NULL;
result = isc_mutex_init(&mgr->lock);
if (result != ISC_R_SUCCESS)
destroy_mgr(&mgr);
}
+void
+dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, dns_stats_t *stats) {
+ REQUIRE(VALID_DISPATCHMGR(mgr));
+ REQUIRE(ISC_LIST_EMPTY(mgr->list));
+ REQUIRE(mgr->stats == NULL);
+
+ dns_stats_attach(stats, &mgr->stats);
+}
+
static isc_boolean_t
blacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
isc_sockaddr_t *sockaddrp)
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.h,v 1.83 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: adb.h,v 1.84 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_ADB_H
#define DNS_ADB_H 1
*\li 'name' is valid.
*/
-
ISC_LANG_ENDDECLS
#endif /* DNS_ADB_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.h,v 1.91 2008/04/01 23:47:10 tbox Exp $ */
+/* $Id: db.h,v 1.92 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
void (*resigned)(dns_db_t *db, dns_rdataset_t *rdataset,
dns_dbversion_t *version);
isc_boolean_t (*isdnssec)(dns_db_t *db);
+ dns_stats_t *(*getrrsetstats)(dns_db_t *db);
} dns_dbmethods_t;
typedef isc_result_t
*/
+dns_stats_t *
+dns_db_getrrsetstats(dns_db_t *db);
+/*%<
+ * Get statistics information counting RRsets stored in the DB, when available.
+ * The statistics may not be available depending on the DB implementation.
+ *
+ * Requires:
+ *
+ * \li 'db' is a valid database (zone or cache).
+ *
+ * Returns:
+ * \li when available, a pointer to a statistics object created by
+ * dns_rdatasetstats_create(); otherwise NULL.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_DB_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.h,v 1.56 2007/06/26 02:52:15 marka Exp $ */
+/* $Id: dispatch.h,v 1.57 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
*\li mgr is a valid dispatchmgr
*/
-
+void
+dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, dns_stats_t *stats);
+/*%<
+ * Sets statistics counter for the dispatchmgr. This function is expected to
+ * be called only on zone creation (when necessary).
+ * Once installed, it cannot be removed or replaced. Also, there is no
+ * interface to get the installed stats from the zone; the caller must keep the
+ * stats to reference (e.g. dump) it later.
+ *
+ * Requires:
+ *\li mgr is a valid dispatchmgr with no managed dispatch.
+ *\li stats is a valid statistics supporting resolver statistics counters
+ * (see dns/stats.h).
+ */
isc_result_t
dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stats.h,v 1.15 2008/01/24 23:47:00 tbox Exp $ */
+/* $Id: stats.h,v 1.16 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_STATS_H
#define DNS_STATS_H 1
#include <dns/types.h>
/*%
- * Query statistics counter types.
+ * Statistics counters. Used as dns_statscounter_t values.
*/
-typedef enum {
+enum {
+ /*%
+ * Resolver statistics counters.
+ */
+ dns_resstatscounter_queryv4 = 0,
+ dns_resstatscounter_queryv6 = 1,
+ dns_resstatscounter_responsev4 = 2,
+ dns_resstatscounter_responsev6 = 3,
+ dns_resstatscounter_nxdomain = 4,
+ dns_resstatscounter_servfail = 5,
+ dns_resstatscounter_formerr = 6,
+ dns_resstatscounter_othererror = 7,
+ dns_resstatscounter_edns0fail = 8,
+ dns_resstatscounter_mismatch = 9,
+ dns_resstatscounter_truncated = 10,
+ dns_resstatscounter_lame = 11,
+ dns_resstatscounter_retry = 12,
+ dns_resstatscounter_gluefetchv4 = 13,
+ dns_resstatscounter_gluefetchv6 = 14,
+ dns_resstatscounter_gluefetchv4fail = 15,
+ dns_resstatscounter_gluefetchv6fail = 16,
+ dns_resstatscounter_val = 17,
+ dns_resstatscounter_valsuccess = 18,
+ dns_resstatscounter_valnegsuccess = 19,
+ dns_resstatscounter_valfail = 20,
+
+ dns_resstatscounter_max = 21,
+
+ /*%
+ * Zone statistics counters.
+ */
+ dns_zonestatscounter_notifyoutv4 = 0,
+ dns_zonestatscounter_notifyoutv6 = 1,
+ dns_zonestatscounter_notifyinv4 = 2,
+ dns_zonestatscounter_notifyinv6 = 3,
+ dns_zonestatscounter_notifyrej = 4,
+ dns_zonestatscounter_soaoutv4 = 5,
+ dns_zonestatscounter_soaoutv6 = 6,
+ dns_zonestatscounter_axfrreqv4 = 7,
+ dns_zonestatscounter_axfrreqv6 = 8,
+ dns_zonestatscounter_ixfrreqv4 = 9,
+ dns_zonestatscounter_ixfrreqv6 = 10,
+ dns_zonestatscounter_xfrsuccess = 11,
+ dns_zonestatscounter_xfrfail = 12,
+
+ dns_zonestatscounter_max = 13,
+
+ /*%
+ * Query statistics counters (obsolete).
+ */
dns_statscounter_success = 0, /*%< Successful lookup */
dns_statscounter_referral = 1, /*%< Referral result */
dns_statscounter_nxrrset = 2, /*%< NXRRSET result */
dns_statscounter_recursion = 4, /*%< Recursion was used */
dns_statscounter_failure = 5, /*%< Some other failure */
dns_statscounter_duplicate = 6, /*%< Duplicate query */
- dns_statscounter_dropped = 7 /*%< Duplicate query */
-} dns_statscounter_t;
+ dns_statscounter_dropped = 7 /*%< Duplicate query (dropped) */
+};
#define DNS_STATS_NCOUNTERS 8
+/*%<
+ * Flag(s) for dns_xxxstats_dump().
+ */
+#define DNS_STATSDUMP_VERBOSE 0x00000001 /*%< dump 0-value counters */
+
+/*%<
+ * (Obsoleted)
+ */
LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[];
+/*%
+ * Attributes for statistics counters of RRset and Rdatatype types.
+ *
+ * _OTHERTYPE
+ * The rdata type is not explicitly supported and the corresponding counter
+ * is counted for other such types, too. When this attribute is set,
+ * the base type is of no use.
+ *
+ * _NXRRSET
+ * RRset type counters only. Indicates the RRset is non existent.
+ *
+ * _NXDOMAIN
+ * RRset type counters only. Indicates a non existent name. When this
+ * attribute is set, the base type is of no use.
+ */
+#define DNS_RDATASTATSTYPE_ATTR_OTHERTYPE 0x0001
+#define DNS_RDATASTATSTYPE_ATTR_NXRRSET 0x0002
+#define DNS_RDATASTATSTYPE_ATTR_NXDOMAIN 0x0004
+
+/*%<
+ * Conversion macros among dns_rdatatype_t, attributes and dns_statscounter_t.
+ */
+#define DNS_RDATASTATSTYPE_BASE(type) ((dns_rdatatype_t)((type) & 0xFFFF))
+#define DNS_RDATASTATSTYPE_ATTR(type) ((type) >> 16)
+#define DNS_RDATASTATSTYPE_VALUE(b, a) (((a) << 16) | (b))
+
+/*%<
+ * Types of dump callbacks.
+ */
+typedef void (*dns_generalstats_dumper_t)(dns_statscounter_t, isc_uint64_t,
+ void *);
+typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, isc_uint64_t,
+ void *);
+typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, isc_uint64_t, void *);
+
isc_result_t
-dns_stats_create(isc_mem_t *mctx, dns_stats_t **statsp);
+dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters);
/*%<
- * Create a statistics counter structure.
+ * Create a statistics counter structure of general type. It counts a general
+ * set of counters indexed by an ID between 0 and ncounters -1.
*
* Requires:
+ *\li 'mctx' must be a valid memory context.
*
+ *\li 'statsp' != NULL && '*statsp' == NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS -- all ok
+ *
+ *\li anything else -- failure
+ */
+
+isc_result_t
+dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
+/*%<
+ * Create a statistics counter structure per rdatatype.
+ *
+ * Requires:
*\li 'mctx' must be a valid memory context.
*
*\li 'statsp' != NULL && '*statsp' == NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS -- all ok
+ *
+ *\li anything else -- failure
*/
-void
-dns_stats_destroy(isc_mem_t *mctx, dns_stats_t **statsp);
+isc_result_t
+dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp);
/*%<
- * Destroy a statistics counter structure.
+ * Create a statistics counter structure per RRset.
*
* Requires:
+ *\li 'mctx' must be a valid memory context.
+ *
+ *\li 'statsp' != NULL && '*statsp' == NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS -- all ok
+ *
+ *\li anything else -- failure
+ */
+
+isc_result_t
+dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
+/*%<
+ * Create a statistics counter structure per opcode.
*
+ * Requires:
*\li 'mctx' must be a valid memory context.
*
- *\li 'statsp' != NULL and '*statsp' be valid dns_stats_t.
+ *\li 'statsp' != NULL && '*statsp' == NULL.
*
- * Ensures:
+ * Returns:
+ *\li ISC_R_SUCCESS -- all ok
*
- *\li '*statsp' == NULL
+ *\li anything else -- failure
*/
void
-dns_stats_incrementcounter(dns_stats_t *stat, dns_statscounter_t counter);
+dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp);
/*%<
- * Increment a counter field of 'stat' specified by 'counter'.
+ * Attach to a statistics set.
*
* Requires:
+ *\li 'stats' is a valid dns_stats_t.
*
- *\li 'stat' be a valid dns_stats_t.
+ *\li 'statsp' != NULL && '*statsp' == NULL
+ */
+
+void
+dns_stats_detach(dns_stats_t **statsp);
+/*%<
+ * Detaches from the statistics set.
*
- *\li counter < DNS_STATS_NCOUNTERS
+ * Requires:
+ *\li 'statsp' != NULL and '*statsp' is a valid dns_stats_t.
+ */
+
+void
+dns_generalstats_increment(dns_stats_t *stats, dns_statscounter_t counter);
+/*%<
+ * Increment the counter-th counter of stats.
+ *
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
+ *
+ *\li counter is less than the maximum available ID for the stats specified
+ * on creation.
*/
void
-dns_stats_copy(dns_stats_t *src, isc_uint64_t *dst);
+dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type);
/*%<
- * Copy statistics counter fields of 'src' to the 'dst' array.
+ * Increment the statistics counter for 'type'.
*
* Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_rdatatypestats_create().
+ */
+
+void
+dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype);
+/*%<
+ * Increment the statistics counter for 'rrsettype'.
*
- *\li 'src' be a valid dns_stats_t.
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create().
+ */
+
+void
+dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype);
+/*%<
+ * Decrement the statistics counter for 'rrsettype'.
*
- *\li 'dst' be sufficiently large to store DNS_STATS_NCOUNTERS 64-bit
- * integers.
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_rdatasetstats_create().
+ */
+
+void
+dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
+/*%<
+ * Increment the statistics counter for 'code'.
+ *
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_opcodestats_create().
+ */
+
+void
+dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
+ void *arg, unsigned int options);
+/*%<
+ * Dump the current statistics counters in a specified way. For each counter
+ * in stats, dump_fn is called with its current value and the given argument
+ * arg. By default counters that have a value of 0 is skipped; if options has
+ * the DNS_STATSDUMP_VERBOSE flag, even such counters are dumped.
+ *
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
+ */
+
+void
+dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
+ void *arg, unsigned int options);
+/*%<
+ * Dump the current statistics counters in a specified way. For each counter
+ * in stats, dump_fn is called with the corresponding type in the form of
+ * dns_rdatastatstype_t, the current counter value and the given argument
+ * arg. By default counters that have a value of 0 is skipped; if options has
+ * the DNS_STATSDUMP_VERBOSE flag, even such counters are dumped.
+ *
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
+ */
+
+void
+dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
+ void *arg, unsigned int options);
+/*%<
+ * Dump the current statistics counters in a specified way. For each counter
+ * in stats, dump_fn is called with the corresponding type in the form of
+ * dns_rdatastatstype_t, the current counter value and the given argument
+ * arg. By default counters that have a value of 0 is skipped; if options has
+ * the DNS_STATSDUMP_VERBOSE flag, even such counters are dumped.
+ *
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
+ */
+
+void
+dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
+ void *arg, unsigned int options);
+/*%<
+ * Dump the current statistics counters in a specified way. For each counter
+ * in stats, dump_fn is called with the corresponding opcode, the current
+ * counter value and the given argument arg. By default counters that have a
+ * value of 0 is skipped; if options has the DNS_STATSDUMP_VERBOSE flag, even
+ * such counters are dumped.
+ *
+ * Requires:
+ *\li 'stats' is a valid dns_stats_t created by dns_generalstats_create().
+ */
+
+void
+dns_stats_incrementcounter(dns_stats_t *stat, dns_statscounter_t counter);
+/*%<
+ * Increment a counter field of 'stat' specified by 'counter'.
+ *
+ * Requires:
+ *
+ *\li 'stat' be a valid dns_stats_t.
+ *
+ *\li counter < DNS_STATS_NCOUNTERS
*/
isc_result_t
* Allocate an array of query statistics counters from the memory
* context 'mctx'.
*
- * This function is obsoleted. Use dns_stats_create() instead.
+ * This function is obsoleted. Use dns_xxxstats_create() instead.
*/
void
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.128 2008/01/24 23:47:00 tbox Exp $ */
+/* $Id: types.h,v 1.129 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
typedef struct dns_ssurule dns_ssurule_t;
typedef struct dns_ssutable dns_ssutable_t;
typedef struct dns_stats dns_stats_t;
+typedef int dns_statscounter_t;
+typedef isc_uint32_t dns_rdatastatstype_t;
typedef struct dns_tkeyctx dns_tkeyctx_t;
typedef isc_uint16_t dns_trust_t;
typedef struct dns_tsig_keyring dns_tsig_keyring_t;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.h,v 1.108 2008/04/03 02:01:08 marka Exp $ */
+/* $Id: view.h,v 1.109 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_VIEW_H
#define DNS_VIEW_H 1
#include <isc/refcount.h>
#include <isc/rwlock.h>
#include <isc/stdtime.h>
-#include <isc/xml.h>
#include <dns/acl.h>
#include <dns/fixedname.h>
isc_event_t resevent;
isc_event_t adbevent;
isc_event_t reqevent;
+ dns_stats_t * resstats;
+ dns_stats_t * resquerystats;
/* Configurable data. */
dns_tsig_keyring_t * statickeys;
* \li 'view' is valid.
*/
-#ifdef HAVE_LIBXML2
+void
+dns_view_setresstats(dns_view_t *view, dns_stats_t *stats);
+/*%<
+ * Set a general resolver statistics counter set 'stats' for 'view'.
+ *
+ * Requires:
+ * \li 'view' is valid and is not frozen.
+ *
+ *\li stats is a valid statistics supporting resolver statistics counters
+ * (see dns/stats.h).
+ */
-isc_result_t
-dns_view_xmlrender(dns_view_t *view, xmlTextWriterPtr xml, int flags);
+void
+dns_view_getresstats(dns_view_t *view, dns_stats_t **statsp);
+/*%<
+ * Get the general statistics counter set for 'view'. If a statistics set is
+ * set '*statsp' will be attached to the set; otherwise, '*statsp' will be
+ * untouched.
+ *
+ * Requires:
+ * \li 'view' is valid and is not frozen.
+ *
+ *\li 'statsp' != NULL && '*statsp' != NULL
+ */
-#endif
+void
+dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats);
+/*%<
+ * Set a statistics counter set of rdata type, 'stats', for 'view'. Once the
+ * statistic set is installed, view's resolver will count outgoing queries
+ * per rdata type.
+ *
+ * Requires:
+ * \li 'view' is valid and is not frozen.
+ *
+ *\li stats is a valid statistics created by dns_rdatatypestats_create().
+ */
+
+void
+dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp);
+/*%<
+ * Get the rdatatype statistics counter set for 'view'. If a statistics set is
+ * set '*statsp' will be attached to the set; otherwise, '*statsp' will be
+ * untouched.
+ *
+ * Requires:
+ * \li 'view' is valid and is not frozen.
+ *
+ *\li 'statsp' != NULL && '*statsp' != NULL
+ */
#endif /* DNS_VIEW_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.158 2008/04/02 02:37:42 marka Exp $ */
+/* $Id: zone.h,v 1.159 2008/04/03 05:55:52 marka Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
#include <isc/formatcheck.h>
#include <isc/lang.h>
#include <isc/rwlock.h>
-#include <isc/xml.h>
#include <dns/masterdump.h>
#include <dns/types.h>
*\li 'zone' to be a valid zone.
*/
+isc_uint32_t
+dns_zone_getserial(dns_zone_t *zone);
+/*%<
+ * Returns the current serial number of the zone.
+ *
+ * Requires:
+ *\li 'zone' to be a valid zone.
+ */
+
void
dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type);
/*%<
isc_result_t
dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on);
/*%<
- * Make the zone keep or not keep an array of statistics
- * counter.
- *
- * Requires:
- * \li zone be a valid zone.
+ * This function is obsoleted by dns_zone_setrequeststats().
*/
isc_uint64_t *
dns_zone_getstatscounters(dns_zone_t *zone);
/*%<
- * This function is obsoleted by dns_zone_getstats().
+ * This function is obsoleted by dns_zone_getrequeststats().
+ */
+
+void
+dns_zone_setstats(dns_zone_t *zone, dns_stats_t *stats);
+/*%<
+ * Set a general zone-maintenance statistics set 'stats' for 'zone'. This
+ * function is expected to be called only on zone creation (when necessary).
+ * Once installed, it cannot be removed or replaced. Also, there is no
+ * interface to get the installed stats from the zone; the caller must keep the
+ * stats to reference (e.g. dump) it later.
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone and does not have a statistics set already
+ * installed.
+ *
+ *\li stats is a valid statistics supporting zone statistics counters
+ * (see dns/stats.h).
+ */
+
+void
+dns_zone_setrequeststats(dns_zone_t *zone, dns_stats_t *stats);
+/*%<
+ * Set an additional statistics set to zone. It is attached in the zone
+ * but is not counted in the zone module; only the caller updates the counters.
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ *
+ *\li stats is a valid statistics.
*/
dns_stats_t *
-dns_zone_getstats(dns_zone_t *zone);
+dns_zone_getrequeststats(dns_zone_t *zone);
/*%<
+ * Get the additional statistics for zone, if one is installed.
+ *
* Requires:
- * zone be a valid zone.
+ * \li 'zone' to be a valid zone.
*
* Returns:
- * \li A pointer to the zone's array of statistics counters,
- * or NULL if it has none.
+ * \li when available, a pointer to the statistics set installed in zone;
+ * otherwise NULL.
*/
void
* will not be permanent.
*/
-#ifdef HAVE_LIBXML2
-
-isc_result_t
-dns_zone_xmlrender(dns_zone_t *zone, xmlTextWriterPtr xml, int flags);
-
-#endif
-
ISC_LANG_ENDDECLS
#endif /* DNS_ZONE_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.256 2008/04/03 04:00:38 marka Exp $ */
+/* $Id: rbtdb.c,v 1.257 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
#include <dns/rdatasetiter.h>
#include <dns/rdataslab.h>
#include <dns/result.h>
+#include <dns/stats.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zonekey.h>
#define RDATASET_ATTR_RETAIN 0x0008
#define RDATASET_ATTR_NXDOMAIN 0x0010
#define RDATASET_ATTR_RESIGN 0x0020
+#define RDATASET_ATTR_STATCOUNT 0x0040
#define RDATASET_ATTR_CACHE 0x1000 /* for debug */
#define RDATASET_ATTR_CANCELED 0x2000 /* for debug */
unsigned int node_lock_count;
rbtdb_nodelock_t * node_locks;
dns_rbtnode_t * origin_node;
+ dns_stats_t * rrsetstats; /* cache DB only */
/* Locked by lock. */
unsigned int active;
isc_refcount_t references;
free_rbtdb(rbtdb, ISC_TRUE, event);
}
+static void
+update_rrsetstats(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
+ isc_boolean_t increment)
+{
+ dns_rdatastatstype_t statattributes = 0;
+ dns_rdatastatstype_t base = 0;
+ dns_rdatastatstype_t type;
+
+ /* At the moment we count statistics only for cache DB */
+ INSIST(IS_CACHE(rbtdb));
+
+ if (NXDOMAIN(header))
+ statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN;
+ else if (RBTDB_RDATATYPE_BASE(header->type) == 0) {
+ statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET;
+ base = RBTDB_RDATATYPE_EXT(header->type);
+ } else
+ base = RBTDB_RDATATYPE_BASE(header->type);
+
+ type = DNS_RDATASTATSTYPE_VALUE(base, statattributes);
+ if (increment)
+ dns_rdatasetstats_increment(rbtdb->rrsetstats, type);
+ else
+ dns_rdatasetstats_decrement(rbtdb->rrsetstats, type);
+}
+
static void
set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
int idx;
sizeof(isc_heap_t *));
}
+ if (rbtdb->rrsetstats != NULL)
+ dns_stats_detach(&rbtdb->rrsetstats);
+
isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks,
rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
isc_rwlock_destroy(&rbtdb->tree_lock);
unsigned int size;
int idx;
+ if (EXISTS(rdataset) &&
+ (rdataset->attributes & RDATASET_ATTR_STATCOUNT) != 0) {
+ update_rrsetstats(rbtdb, rdataset, ISC_FALSE);
+ }
+
#ifdef LRU_DEBUG
/*
* for debug: statistics update.
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_write);
+ if (rbtdb->rrsetstats != NULL) {
+ newheader->attributes |= RDATASET_ATTR_STATCOUNT;
+ update_rrsetstats(rbtdb, newheader, ISC_TRUE);
+ }
+
#ifdef LRU_DEBUG
/* for debug: statistics update */
if (IS_CACHE(rbtdb) && rdataset->rdclass == dns_rdataclass_in) {
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
}
+static dns_stats_t *
+getrrsetstats(dns_db_t *db) {
+ dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
+
+ REQUIRE(VALID_RBTDB(rbtdb));
+ REQUIRE(IS_CACHE(rbtdb)); /* current restriction */
+
+ return (rbtdb->rrsetstats);
+}
+
static dns_dbmethods_t zone_methods = {
attach,
detach,
getsigningtime,
resigned,
isdnssec,
+ NULL
};
static dns_dbmethods_t cache_methods = {
NULL,
NULL,
NULL,
- isdnssec
+ isdnssec,
+ getrrsetstats
};
isc_result_t
goto cleanup_tree_lock;
}
+ rbtdb->rrsetstats = NULL;
if (IS_CACHE(rbtdb)) {
+ result = dns_rdatasetstats_create(mctx, &rbtdb->rrsetstats);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_node_locks;
rbtdb->rdatasets = isc_mem_get(mctx, rbtdb->node_lock_count *
sizeof(rdatasetheaderlist_t));
if (rbtdb->rdatasets == NULL) {
result = ISC_R_NOMEMORY;
- goto cleanup_node_locks;
+ goto cleanup_rrsetstats;
}
for (i = 0; i < (int)rbtdb->node_lock_count; i++)
ISC_LIST_INIT(rbtdb->rdatasets[i]);
if (rbtdb->rdatasets != NULL)
isc_mem_put(mctx, rbtdb->rdatasets, rbtdb->node_lock_count *
sizeof(rdatasetheaderlist_t));
+ cleanup_rrsetstats:
+ if (rbtdb->rrsetstats != NULL)
+ dns_stats_detach(&rbtdb->rrsetstats);
cleanup_node_locks:
isc_mem_put(mctx, rbtdb->node_locks,
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.364 2008/04/03 02:01:08 marka Exp $ */
+/* $Id: resolver.c,v 1.365 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
#include <dns/resolver.h>
#include <dns/result.h>
#include <dns/rootns.h>
+#include <dns/stats.h>
#include <dns/tsig.h>
#include <dns/validator.h>
static void timer_dump(isc_task_t *task, isc_event_t *ev);
#endif
+/*%
+ * Increment resolver-related statistics counters.
+ */
+static inline void
+inc_stats(dns_resolver_t *res, dns_statscounter_t counter) {
+ if (res->view->resstats != NULL)
+ dns_generalstats_increment(res->view->resstats, counter);
+}
+
static isc_result_t
valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
dns_rdatatype_t type, dns_rdataset_t *rdataset,
valoptions, task, validated, valarg,
&validator);
if (result == ISC_R_SUCCESS) {
+ inc_stats(fctx->res, dns_resstatscounter_val);
if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
INSIST(fctx->validator == NULL);
fctx->validator = validator;
ISC_LIST_APPEND(fctx->queries, query, link);
query->fctx->nqueries++;
+ if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET)
+ inc_stats(res, dns_resstatscounter_queryv4);
+ else
+ inc_stats(res, dns_resstatscounter_queryv6);
+ if (res->view->resquerystats != NULL)
+ dns_rdatatypestats_increment(res->view->resquerystats,
+ fctx->type);
return (ISC_R_SUCCESS);
REQUIRE(!ADDRWAIT(fctx));
+ if (fctx->restarts > 0)
+ inc_stats(fctx->res, dns_resstatscounter_retry);
+
addrinfo = fctx_nextaddress(fctx);
if (addrinfo == NULL) {
/*
if (vevent->result != ISC_R_SUCCESS) {
FCTXTRACE("validation failed");
+ inc_stats(fctx->res, dns_resstatscounter_valfail);
result = ISC_R_NOTFOUND;
if (vevent->rdataset != NULL)
result = dns_db_findnode(fctx->cache, vevent->name,
dns_rdatatype_t covers;
FCTXTRACE("nonexistence validation OK");
+ inc_stats(fctx->res, dns_resstatscounter_valnegsuccess);
+
if (fctx->rmessage->rcode == dns_rcode_nxdomain)
covers = dns_rdatatype_any;
else
if (result != ISC_R_SUCCESS)
goto noanswer_response;
goto answer_response;
- }
+ } else
+ inc_stats(fctx->res, dns_resstatscounter_valsuccess);
FCTXTRACE("validation OK");
QTRACE("response");
+ if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET)
+ inc_stats(fctx->res, dns_resstatscounter_responsev4);
+ else
+ inc_stats(fctx->res, dns_resstatscounter_responsev6);
+
(void)isc_timer_touch(fctx->timer);
keep_trying = ISC_FALSE;
query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);
+ inc_stats(fctx->res,
+ dns_resstatscounter_edns0fail);
} else {
broken_server = result;
keep_trying = ISC_TRUE;
query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);
+ inc_stats(fctx->res,
+ dns_resstatscounter_edns0fail);
} else {
broken_server = DNS_R_UNEXPECTEDRCODE;
keep_trying = ISC_TRUE;
truncated = ISC_TRUE;
if (truncated) {
+ inc_stats(fctx->res, dns_resstatscounter_truncated);
if ((options & DNS_FETCHOPT_TCP) != 0) {
broken_server = DNS_R_TRUNCATEDTCP;
keep_trying = ISC_TRUE;
goto done;
}
+ /*
+ * Update statistics about erroneous responses.
+ */
+ if (message->rcode != dns_rcode_noerror) {
+ switch (message->rcode) {
+ case dns_rcode_nxdomain:
+ inc_stats(fctx->res, dns_resstatscounter_nxdomain);
+ break;
+ case dns_rcode_servfail:
+ inc_stats(fctx->res, dns_resstatscounter_servfail);
+ break;
+ case dns_rcode_formerr:
+ inc_stats(fctx->res, dns_resstatscounter_formerr);
+ break;
+ default:
+ inc_stats(fctx->res, dns_resstatscounter_othererror);
+ break;
+ }
+ }
+
/*
* Is the remote server broken, or does it dislike us?
*/
dns_adb_changeflags(fctx->adb, query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);
+ inc_stats(fctx->res, dns_resstatscounter_edns0fail);
} else if (message->rcode == dns_rcode_formerr) {
if (ISFORWARDER(query->addrinfo)) {
/*
*/
if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
is_lame(fctx)) {
+ inc_stats(fctx->res, dns_resstatscounter_lame);
log_lame(fctx, query->addrinfo);
result = dns_adb_marklame(fctx->adb, query->addrinfo,
&fctx->name, fctx->type,
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.63 2008/04/01 01:37:25 marka Exp $ */
+/* $Id: sdb.c,v 1.64 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
NULL,
NULL,
NULL,
+ NULL,
NULL
};
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.c,v 1.16 2008/04/01 23:47:10 tbox Exp $ */
+/* $Id: sdlz.c,v 1.17 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
NULL,
NULL,
NULL,
+ NULL,
NULL
};
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stats.c,v 1.14 2008/01/24 23:47:00 tbox Exp $ */
+/* $Id: stats.c,v 1.15 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
#include <string.h>
#include <isc/atomic.h>
+#include <isc/buffer.h>
+#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/platform.h>
+#include <isc/print.h>
#include <isc/rwlock.h>
#include <isc/util.h>
+#include <dns/opcode.h>
+#include <dns/rdatatype.h>
#include <dns/stats.h>
-LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] =
- {
- "success",
- "referral",
- "nxrrset",
- "nxdomain",
- "recursion",
- "failure",
- "duplicate",
- "dropped"
- };
+#define DNS_STATS_MAGIC ISC_MAGIC('D', 's', 't', 't')
+#define DNS_STATS_VALID(x) ISC_MAGIC_VALID(x, DNS_STATS_MAGIC)
+
+/*%
+ * Statistics types.
+ */
+typedef enum {
+ dns_statstype_general = 0,
+ dns_statstype_rdtype = 1,
+ dns_statstype_rdataset = 2,
+ dns_statstype_opcode = 3
+} dns_statstype_t;
+
+/*%
+ * It doesn't make sense to have 2^16 counters for all possible types since
+ * most of them won't be used. We have counters for the first 256 types and
+ * those explicitly supported in the rdata implementation.
+ * XXXJT: this introduces tight coupling with the rdata implementation.
+ * Ideally, we should have rdata handle this type of details.
+ */
+enum {
+ /* For 0-255, we use the rdtype value as counter indices */
+ rdtypecounter_dlv = 256, /* for dns_rdatatype_dlv */
+ rdtypecounter_others = 257, /* anything else */
+ rdtypecounter_max = 258,
+ /* The following are used for rdataset */
+ rdtypenxcounter_max = rdtypecounter_max * 2,
+ rdtypecounter_nxdomain = rdtypenxcounter_max,
+ rdatasettypecounter_max = rdtypecounter_nxdomain + 1
+};
#ifndef DNS_STATS_USEMULTIFIELDS
#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEXADD) && !defined(ISC_PLATFORM_HAVEXADDQ)
#endif
struct dns_stats {
- /* XXXJT: do we need a magic? */
+ /*% Unlocked */
+ unsigned int magic;
+ dns_statstype_t type;
+ isc_mem_t *mctx;
+ int ncounters;
+
+ isc_mutex_t lock;
+ unsigned int references; /* locked by lock */
+
+ /*%
+ * Locked by counterlock or unlocked if efficient rwlock is not
+ * available.
+ */
#ifdef ISC_RWLOCK_USEATOMIC
- isc_rwlock_t lock;
+ isc_rwlock_t counterlock;
#endif
- dns_stat_t counters[DNS_STATS_NCOUNTERS];
+ dns_stat_t *counters;
+
+ /*%
+ * We don't want to lock the counters while we are dumping, so we first
+ * copy the current counter values into a local array. This buffer
+ * will be used as the copy destination. It's allocated on creation
+ * of the stats structure so that the dump operation won't fail due
+ * to memory allocation failure.
+ * XXX: this approach is weird for non-threaded build because the
+ * additional memory and the copy overhead could be avoided. We prefer
+ * simplicity here, however, under the assumption that this function
+ * should be only rarely called.
+ */
+ isc_uint64_t *copiedcounters;
};
-isc_result_t
-dns_stats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
+static isc_result_t
+create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters,
+ dns_stats_t **statsp)
+{
dns_stats_t *stats;
isc_result_t result = ISC_R_SUCCESS;
stats = isc_mem_get(mctx, sizeof(*stats));
if (stats == NULL)
return (ISC_R_NOMEMORY);
+
+ result = isc_mutex_init(&stats->lock);
+ if (result != ISC_R_SUCCESS)
+ goto clean_stats;
+
+ stats->counters = isc_mem_get(mctx, sizeof(dns_stat_t) * ncounters);
+ if (stats->counters == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto clean_mutex;
+ }
+ stats->copiedcounters = isc_mem_get(mctx,
+ sizeof(isc_uint64_t) * ncounters);
+ if (stats->copiedcounters == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto clean_counters;
+ }
#ifdef ISC_RWLOCK_USEATOMIC
- result = isc_rwlock_init(&stats->lock, 0, 0);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, stats, sizeof(*stats));
- return (result);
- }
+ result = isc_rwlock_init(&stats->counterlock, 0, 0);
+ if (result != ISC_R_SUCCESS)
+ goto clean_copiedcounters;
#endif
- memset(stats->counters, 0, sizeof(dns_stat_t) * DNS_STATS_NCOUNTERS);
+ stats->type = type;
+ stats->references = 1;
+ memset(stats->counters, 0, sizeof(dns_stat_t) * ncounters);
+ stats->mctx = NULL;
+ isc_mem_attach(mctx, &stats->mctx);
+ stats->ncounters = ncounters;
+ stats->magic = DNS_STATS_MAGIC;
*statsp = stats;
+ return (result);
+
+clean_counters:
+ isc_mem_put(mctx, stats->counters, sizeof(dns_stat_t) * ncounters);
+
+#ifdef ISC_RWLOCK_USEATOMIC
+clean_copiedcounters:
+ isc_mem_put(mctx, stats->copiedcounters,
+ sizeof(dns_stat_t) * ncounters);
+#endif
+
+clean_mutex:
+ DESTROYLOCK(&stats->lock);
+
+clean_stats:
+ isc_mem_put(mctx, stats, sizeof(*stats));
+
return (result);
}
void
-dns_stats_destroy(isc_mem_t *mctx, dns_stats_t **statsp) {
+dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) {
+ REQUIRE(DNS_STATS_VALID(stats));
+ REQUIRE(statsp != NULL && *statsp == NULL);
+
+ LOCK(&stats->lock);
+ stats->references++;
+ UNLOCK(&stats->lock);
+
+ *statsp = stats;
+}
+
+void
+dns_stats_detach(dns_stats_t **statsp) {
dns_stats_t *stats;
- REQUIRE(statsp != NULL && *statsp != NULL);
+ REQUIRE(statsp != NULL && DNS_STATS_VALID(*statsp));
stats = *statsp;
+ *statsp = NULL;
+ LOCK(&stats->lock);
+ stats->references--;
+ UNLOCK(&stats->lock);
+
+ if (stats->references == 0) {
+ isc_mem_put(stats->mctx, stats->copiedcounters,
+ sizeof(dns_stat_t) * stats->ncounters);
+ isc_mem_put(stats->mctx, stats->counters,
+ sizeof(dns_stat_t) * stats->ncounters);
+ DESTROYLOCK(&stats->lock);
#ifdef ISC_RWLOCK_USEATOMIC
- isc_rwlock_destroy(&stats->lock);
+ isc_rwlock_destroy(&stats->counterlock);
#endif
- isc_mem_put(mctx, stats, sizeof(*stats));
-
- *statsp = NULL;
+ isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
+ }
}
-void
-dns_stats_incrementcounter(dns_stats_t *stats, dns_statscounter_t counter) {
+static inline void
+incrementcounter(dns_stats_t *stats, int counter) {
isc_int32_t prev;
- REQUIRE(counter < DNS_STATS_NCOUNTERS);
-
#ifdef ISC_RWLOCK_USEATOMIC
/*
* We use a "read" lock to prevent other threads from reading the
* counter while we "writing" a counter field. The write access itself
* is protected by the atomic operation.
*/
- isc_rwlock_lock(&stats->lock, isc_rwlocktype_read);
+ isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read);
#endif
#if DNS_STATS_USEMULTIFIELDS
#endif
#ifdef ISC_RWLOCK_USEATOMIC
- isc_rwlock_unlock(&stats->lock, isc_rwlocktype_read);
+ isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read);
#endif
}
-void
-dns_stats_copy(dns_stats_t *src, isc_uint64_t *dst) {
- int i;
+static inline void
+decrementcounter(dns_stats_t *stats, int counter) {
+ isc_int32_t prev;
+
+#ifdef ISC_RWLOCK_USEATOMIC
+ isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_read);
+#endif
+
+#if DNS_STATS_USEMULTIFIELDS
+ prev = isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].lo, -1);
+ if (prev == 0)
+ isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi,
+ -1);
+#elif defined(ISC_PLATFORM_HAVEXADDQ)
+ UNUSED(prev);
+ isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], -1);
+#else
+ UNUSED(prev);
+ stats->counters[counter]--;
+#endif
+#ifdef ISC_RWLOCK_USEATOMIC
+ isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_read);
+#endif
+}
+
+static void
+copy_counters(dns_stats_t *stats) {
+ int i;
+
#ifdef ISC_RWLOCK_USEATOMIC
/*
* We use a "write" lock before "reading" the statistics counters as
* an exclusive lock.
*/
- isc_rwlock_lock(&src->lock, isc_rwlocktype_write);
+ isc_rwlock_lock(&stats->counterlock, isc_rwlocktype_write);
#endif
#if DNS_STATS_USEMULTIFIELDS
- for (i = 0; i < DNS_STATS_NCOUNTERS; i++) {
- dst[i] = ((isc_uint64_t)src->counters[i].hi) << 32 |
- src->counters[i].lo;
+ for (i = 0; i < stats->ncounters; i++) {
+ stats->copiedcounters[i] =
+ (isc_uint64_t)(stats->counters[i].hi) << 32 |
+ stats->counters[i].lo;
}
#else
UNUSED(i);
- memcpy(dst, src->counters, DNS_STATS_NCOUNTERS * sizeof(dst[0]));
+ memcpy(stats->copiedcounters, stats->counters,
+ stats->ncounters * sizeof(dns_stat_t));
#endif
#ifdef ISC_RWLOCK_USEATOMIC
- isc_rwlock_unlock(&src->lock, isc_rwlocktype_write);
+ isc_rwlock_unlock(&stats->counterlock, isc_rwlocktype_write);
#endif
}
+/*%
+ * Create methods
+ */
+isc_result_t
+dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters) {
+ REQUIRE(statsp != NULL && *statsp == NULL);
+
+ return (create_stats(mctx, dns_statstype_general, ncounters, statsp));
+}
+
+isc_result_t
+dns_rdatatypestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
+ REQUIRE(statsp != NULL && *statsp == NULL);
+
+ return (create_stats(mctx, dns_statstype_rdtype, rdtypecounter_max,
+ statsp));
+}
+
+isc_result_t
+dns_rdatasetstats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
+ REQUIRE(statsp != NULL && *statsp == NULL);
+
+ return (create_stats(mctx, dns_statstype_rdataset,
+ (rdtypecounter_max * 2) + 1, statsp));
+}
+
+isc_result_t
+dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
+ REQUIRE(statsp != NULL && *statsp == NULL);
+
+ return (create_stats(mctx, dns_statstype_opcode, 16, statsp));
+}
+
+/*%
+ * Increment/Decrement methods
+ */
+void
+dns_generalstats_increment(dns_stats_t *stats, dns_statscounter_t counter) {
+ REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general);
+ REQUIRE(counter < stats->ncounters);
+
+ incrementcounter(stats, (int)counter);
+}
+
+void
+dns_rdatatypestats_increment(dns_stats_t *stats, dns_rdatatype_t type) {
+ int counter;
+
+ REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype);
+
+ if (type == dns_rdatatype_dlv)
+ counter = rdtypecounter_dlv;
+ else if (type > dns_rdatatype_any)
+ counter = rdtypecounter_others;
+ else
+ counter = (int)type;
+
+ incrementcounter(stats, counter);
+}
+
+static inline void
+update_rdatasetstats(dns_stats_t *stats, dns_rdatastatstype_t rrsettype,
+ isc_boolean_t increment)
+{
+ int counter;
+ dns_rdatatype_t rdtype;
+
+ if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
+ DNS_RDATASTATSTYPE_ATTR_NXDOMAIN) != 0) {
+ counter = rdtypecounter_nxdomain;
+ } else {
+ rdtype = DNS_RDATASTATSTYPE_BASE(rrsettype);
+ if (rdtype == dns_rdatatype_dlv)
+ counter = (int)rdtypecounter_dlv;
+ else if (rdtype > dns_rdatatype_any)
+ counter = (int)rdtypecounter_others;
+ else
+ counter = (int)rdtype;
+
+ if ((DNS_RDATASTATSTYPE_ATTR(rrsettype) &
+ DNS_RDATASTATSTYPE_ATTR_NXRRSET) != 0)
+ counter += rdtypecounter_max;
+ }
+
+ if (increment)
+ incrementcounter(stats, counter);
+ else
+ decrementcounter(stats, counter);
+}
+
+void
+dns_rdatasetstats_increment(dns_stats_t *stats, dns_rdatastatstype_t rrsettype)
+{
+ REQUIRE(DNS_STATS_VALID(stats) &&
+ stats->type == dns_statstype_rdataset);
+
+ update_rdatasetstats(stats, rrsettype, ISC_TRUE);
+}
+
+void
+dns_rdatasetstats_decrement(dns_stats_t *stats, dns_rdatastatstype_t rrsettype)
+{
+ REQUIRE(DNS_STATS_VALID(stats) &&
+ stats->type == dns_statstype_rdataset);
+
+ update_rdatasetstats(stats, rrsettype, ISC_FALSE);
+}
+void
+dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code) {
+ REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode);
+
+ incrementcounter(stats, (int)code);
+}
+
+/*%
+ * Dump methods
+ */
+void
+dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
+ void *arg, unsigned int options)
+{
+ int i;
+
+ REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_general);
+
+ copy_counters(stats);
+
+ for (i = 0; i < stats->ncounters; i++) {
+ if ((options & DNS_STATSDUMP_VERBOSE) == 0 &&
+ stats->copiedcounters[i] == 0)
+ continue;
+ dump_fn(i, stats->copiedcounters[i], arg);
+ }
+}
+
+static void
+dump_rdentry(dns_stats_t *stats, int counter, int rdcounter,
+ dns_rdatastatstype_t attributes,
+ dns_rdatatypestats_dumper_t dump_fn, void * arg,
+ unsigned int options)
+{
+ dns_rdatatype_t rdtype = dns_rdatatype_none; /* sentinel */
+ dns_rdatastatstype_t type;
+
+ if ((options & DNS_STATSDUMP_VERBOSE) == 0 &&
+ stats->copiedcounters[counter] == 0)
+ return;
+ if (rdcounter == rdtypecounter_others)
+ attributes |= DNS_RDATASTATSTYPE_ATTR_OTHERTYPE;
+ else {
+ if (rdcounter == rdtypecounter_dlv)
+ rdtype = dns_rdatatype_dlv;
+ else
+ rdtype = (dns_rdatatype_t)rdcounter;
+ }
+ type = DNS_RDATASTATSTYPE_VALUE((dns_rdatastatstype_t)rdtype,
+ attributes);
+ dump_fn(type, stats->copiedcounters[counter], arg);
+}
+
+void
+dns_rdatatypestats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
+ void *arg, unsigned int options)
+{
+ int i;
+
+ REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rdtype);
+
+ copy_counters(stats);
+
+ for (i = 0; i < stats->ncounters; i++)
+ dump_rdentry(stats, i, i, 0, dump_fn, arg, options);
+}
+
+void
+dns_rdatasetstats_dump(dns_stats_t *stats, dns_rdatatypestats_dumper_t dump_fn,
+ void *arg, unsigned int options)
+{
+ int i;
+
+ REQUIRE(DNS_STATS_VALID(stats) &&
+ stats->type == dns_statstype_rdataset);
+
+ copy_counters(stats);
+
+ for (i = 0; i < rdtypecounter_max; i++)
+ dump_rdentry(stats, i, i, 0, dump_fn, arg, options);
+ for (i = rdtypecounter_max; i < rdtypenxcounter_max; i++) {
+ dump_rdentry(stats, i, i - rdtypecounter_max,
+ DNS_RDATASTATSTYPE_ATTR_NXRRSET,
+ dump_fn, arg, options);
+ }
+ dump_rdentry(stats, rdtypecounter_nxdomain, 0,
+ DNS_RDATASTATSTYPE_ATTR_NXDOMAIN, dump_fn, arg, options);
+
+ INSIST(i < stats->ncounters);
+}
+
+void
+dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
+ void *arg, unsigned int options)
+{
+ int i;
+
+ REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_opcode);
+
+ copy_counters(stats);
+
+ for (i = 0; i < stats->ncounters; i++) {
+ if ((options & DNS_STATSDUMP_VERBOSE) == 0 &&
+ stats->copiedcounters[i] == 0)
+ continue;
+ dump_fn((dns_opcode_t)i, stats->copiedcounters[i], arg);
+ }
+}
+
/***
- *** Obsolete functions follow
+ *** Obsolete variables and functions follow:
***/
+LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] =
+ {
+ "success",
+ "referral",
+ "nxrrset",
+ "nxdomain",
+ "recursion",
+ "failure",
+ "duplicate",
+ "dropped"
+ };
+
isc_result_t
dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
int i;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.145 2008/04/01 23:47:10 tbox Exp $ */
+/* $Id: view.c,v 1.146 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/task.h>
#include <isc/util.h>
-#include <isc/xml.h>
#include <dns/acache.h>
#include <dns/acl.h>
#include <dns/request.h>
#include <dns/resolver.h>
#include <dns/result.h>
+#include <dns/stats.h>
#include <dns/tsig.h>
#include <dns/zone.h>
#include <dns/zt.h>
view->delonly = NULL;
view->rootdelonly = ISC_FALSE;
view->rootexclude = NULL;
+ view->resstats = NULL;
+ view->resquerystats = NULL;
/*
* Initialize configuration data with default values.
sizeof(dns_namelist_t) * DNS_VIEW_DELONLYHASH);
view->rootexclude = NULL;
}
+ if (view->resstats != NULL)
+ dns_stats_detach(&view->resstats);
+ if (view->resquerystats != NULL)
+ dns_stats_detach(&view->resquerystats);
dns_keytable_detach(&view->trustedkeys);
dns_keytable_detach(&view->secroots);
dns_fwdtable_destroy(&view->fwdtable);
return (dns_zt_freezezones(view->zonetable, value));
}
-#ifdef HAVE_LIBXML2
-
-struct xmlarg {
- int flags;
- xmlTextWriterPtr xml;
-};
-
-static isc_result_t
-zone_xmlrender(dns_zone_t *zone, void *arg) {
- struct xmlarg *xmlarg = arg;
+void
+dns_view_setresstats(dns_view_t *view, dns_stats_t *stats) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(!view->frozen);
+ REQUIRE(view->resstats == NULL);
- return (dns_zone_xmlrender(zone, xmlarg->xml, xmlarg->flags));
+ dns_stats_attach(stats, &view->resstats);
}
-isc_result_t
-dns_view_xmlrender(dns_view_t *view, xmlTextWriterPtr xml, int flags)
-{
- struct xmlarg xmlargs;
-
- xmlargs.flags = flags;
- xmlargs.xml = xml;
-
- /* XXXMLG render config data here */
+void
+dns_view_getresstats(dns_view_t *view, dns_stats_t **statsp) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(statsp != NULL && *statsp == NULL);
- if ((flags & ISC_XML_RENDERSTATS) != 0) {
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "view");
+ if (view->resstats != NULL)
+ dns_stats_attach(view->resstats, statsp);
+}
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "name");
- xmlTextWriterWriteString(xml, ISC_XMLCHAR view->name);
- xmlTextWriterEndElement(xml);
+void
+dns_view_setresquerystats(dns_view_t *view, dns_stats_t *stats) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(!view->frozen);
+ REQUIRE(view->resquerystats == NULL);
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "zones");
- dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender,
- &xmlargs);
- xmlTextWriterEndElement(xml);
+ dns_stats_attach(stats, &view->resquerystats);
+}
- xmlTextWriterEndElement(xml);
- }
+void
+dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(statsp != NULL && *statsp == NULL);
- return (ISC_R_SUCCESS);
+ if (view->resquerystats != NULL)
+ dns_stats_attach(view->resquerystats, statsp);
}
-
-#endif /* HAVE_LIBXML2 */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.477 2008/04/03 02:01:08 marka Exp $ */
+/* $Id: zone.c,v 1.478 2008/04/03 05:55:52 marka Exp $ */
/*! \file */
#include <isc/taskpool.h>
#include <isc/timer.h>
#include <isc/util.h>
-#include <isc/xml.h>
#include <dns/acache.h>
#include <dns/acl.h>
ISC_LINK(dns_zone_t) statelink;
dns_zonelist_t *statelist;
/*%
- * Optional per-zone statistics counters (NULL if not present).
+ * Statistics counters about zone management.
*/
- dns_stats_t *counters;
+ dns_stats_t *stats;
+ /*%
+ * Optional per-zone statistics counters. Counted outside of this
+ * module.
+ */
+ isc_boolean_t requeststats_on;
+ dns_stats_t *requeststats;
isc_uint32_t notifydelay;
dns_isselffunc_t isself;
void *isselfarg;
} \
} while (0)
+/*%
+ * Increment resolver-related statistics counters. Zone must be locked.
+ */
+static inline void
+inc_stats(dns_zone_t *zone, dns_statscounter_t counter) {
+ if (zone->stats != NULL)
+ dns_generalstats_increment(zone->stats, counter);
+}
+
/***
*** Public functions.
***/
zone->checkns = NULL;
ISC_LINK_INIT(zone, statelink);
zone->statelist = NULL;
- zone->counters = NULL;
+ zone->stats = NULL;
+ zone->requeststats_on = ISC_FALSE;
+ zone->requeststats = NULL;
zone->notifydelay = 5;
zone->isself = NULL;
zone->isselfarg = NULL;
if (zone->journal != NULL)
isc_mem_free(zone->mctx, zone->journal);
zone->journal = NULL;
- if (zone->counters != NULL)
- dns_stats_destroy(zone->mctx, &zone->counters);
+ if (zone->stats != NULL)
+ dns_stats_detach(&zone->stats);
+ if (zone->requeststats != NULL)
+ dns_stats_detach(&zone->requeststats);
if (zone->db != NULL)
zone_detachdb(zone);
if (zone->acache != NULL)
}
dns_rdataclass_t
-dns_zone_getclass(dns_zone_t *zone){
+dns_zone_getclass(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->rdclass);
UNLOCK_ZONE(zone);
}
+isc_uint32_t
+dns_zone_getserial(dns_zone_t *zone) {
+ isc_uint32_t serial;
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ LOCK_ZONE(zone);
+ serial = zone->serial;
+ UNLOCK_ZONE(zone);
+
+ return (serial);
+}
+
/*
* Single shot.
*/
timeout * 3, timeout,
notify->zone->task, notify_done,
notify, ¬ify->request);
+ if (result == ISC_R_SUCCESS) {
+ if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
+ inc_stats(notify->zone,
+ dns_zonestatscounter_notifyoutv4);
+ } else {
+ inc_stats(notify->zone,
+ dns_zonestatscounter_notifyoutv6);
+ }
+ }
+
cleanup_key:
if (key != NULL)
dns_tsigkey_detach(&key);
"dns_request_createvia2() failed: %s",
dns_result_totext(result));
goto cleanup;
+ } else {
+ if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
+ inc_stats(zone, dns_zonestatscounter_soaoutv4);
+ else
+ inc_stats(zone, dns_zonestatscounter_soaoutv6);
}
cancel = ISC_FALSE;
* We only handle NOTIFY (SOA) at the present.
*/
LOCK_ZONE(zone);
+ if (isc_sockaddr_pf(from) == PF_INET)
+ inc_stats(zone, dns_zonestatscounter_notifyinv4);
+ else
+ inc_stats(zone, dns_zonestatscounter_notifyinv6);
if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
dns_rdatatype_soa, dns_rdatatype_none,
UNLOCK_ZONE(zone);
dns_zone_log(zone, ISC_LOG_INFO,
"refused notify from non-master: %s", fromtext);
+ inc_stats(zone, dns_zonestatscounter_notifyrej);
return (DNS_R_REFUSED);
}
dns_result_totext(result));
}
+ inc_stats(zone, dns_zonestatscounter_xfrsuccess);
break;
case DNS_R_BADIXFR:
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
again = ISC_TRUE;
}
+ inc_stats(zone, dns_zonestatscounter_xfrfail);
break;
}
zone_settimer(zone, &now);
zone->tsigkey, zone->mctx,
zone->zmgr->timermgr, zone->zmgr->socketmgr,
zone->task, zone_xfrdone, &zone->xfr);
+ if (result == ISC_R_SUCCESS) {
+ LOCK_ZONE(zone);
+ if (xfrtype == dns_rdatatype_axfr) {
+ if (isc_sockaddr_pf(&masteraddr) == PF_INET)
+ inc_stats(zone, dns_zonestatscounter_axfrreqv4);
+ else
+ inc_stats(zone, dns_zonestatscounter_axfrreqv6);
+ } else if (xfrtype == dns_rdatatype_ixfr) {
+ if (isc_sockaddr_pf(&masteraddr) == PF_INET)
+ inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
+ else
+ inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
+ }
+ UNLOCK_ZONE(zone);
+ }
cleanup:
/*
* Any failure in this function is handled like a failed
isc_result_t
dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
- isc_result_t result = ISC_R_SUCCESS;
-
- LOCK_ZONE(zone);
- if (on) {
- if (zone->counters != NULL)
- goto done;
- result = dns_stats_create(zone->mctx, &zone->counters);
- } else {
- if (zone->counters == NULL)
- goto done;
- dns_stats_destroy(zone->mctx, &zone->counters);
- }
- done:
- UNLOCK_ZONE(zone);
- return (result);
+ /*
+ * This function is obsoleted.
+ */
+ UNUSED(zone);
+ UNUSED(on);
+ return (ISC_R_NOTIMPLEMENTED);
}
isc_uint64_t *
dns_zone_getstatscounters(dns_zone_t *zone) {
/*
- * This function is obsoleted by dns_zone_getstats().
+ * This function is obsoleted.
*/
UNUSED(zone);
return (NULL);
}
+void
+dns_zone_setstats(dns_zone_t *zone, dns_stats_t *stats) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(zone->stats == NULL);
+
+ LOCK_ZONE(zone);
+ zone->stats = NULL;
+ dns_stats_attach(stats, &zone->stats);
+ UNLOCK_ZONE(zone);
+}
+
+void
+dns_zone_setrequeststats(dns_zone_t *zone, dns_stats_t *stats) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ LOCK_ZONE(zone);
+ if (zone->requeststats_on && stats == NULL)
+ zone->requeststats_on = ISC_FALSE;
+ else if (!zone->requeststats_on && stats != NULL) {
+ if (zone->requeststats == NULL) {
+ dns_stats_attach(stats, &zone->requeststats);
+ zone->requeststats_on = ISC_TRUE;
+ }
+ }
+ UNLOCK_ZONE(zone);
+
+ return;
+}
+
dns_stats_t *
-dns_zone_getstats(dns_zone_t *zone) {
- return (zone->counters);
+dns_zone_getrequeststats(dns_zone_t *zone) {
+ /*
+ * We don't lock zone for efficiency reason. This is not catastrophic
+ * because requeststats must always be valid when requeststats_on is
+ * true.
+ * Some counters may be incremented while requeststats_on is becoming
+ * false, or some cannot be incremented just after the statistics are
+ * installed, but it shouldn't matter much in practice.
+ */
+ if (zone->requeststats_on)
+ return (zone->requeststats);
+ else
+ return (NULL);
}
void
}
return (result);
}
-
-#ifdef HAVE_LIBXML2
-
-isc_result_t
-dns_zone_xmlrender(dns_zone_t *zone, xmlTextWriterPtr xml, int flags)
-{
- int i;
-
- /* XXXMLG render config data here */
-
- if ((flags & ISC_XML_RENDERSTATS) != 0) {
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "zone");
-
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "name");
- xmlTextWriterWriteString(xml, ISC_XMLCHAR zone->strname);
- xmlTextWriterEndElement(xml);
-
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "rdataclass");
- xmlTextWriterWriteString(xml, ISC_XMLCHAR zone->strrdclass);
- xmlTextWriterEndElement(xml);
-
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "serial");
- xmlTextWriterWriteFormatString(xml, "%u", zone->serial);
- xmlTextWriterEndElement(xml);
-
- if (zone->counters != NULL) {
- isc_uint64_t counters[DNS_STATS_NCOUNTERS];
-
- xmlTextWriterStartElement(xml, ISC_XMLCHAR "counters");
- dns_stats_copy(zone->counters, counters);
- for (i = 0 ; i < DNS_STATS_NCOUNTERS ; i++) {
- xmlTextWriterStartElement(xml,
- ISC_XMLCHAR dns_statscounter_names[i]);
- xmlTextWriterWriteFormatString(xml,
- "%" ISC_PRINT_QUADFORMAT "u",
- counters[i]);
- xmlTextWriterEndElement(xml);
- }
- xmlTextWriterEndElement(xml); /* counters */
- }
- xmlTextWriterEndElement(xml); /* zone */
- }
-
- return (ISC_R_SUCCESS);
-}
-
-#endif /* HAVE_LIBXML2 */