3271. [func] New "rndc zonestatus" command prints information

about the specified zone. [RT #21671]
This commit is contained in:
Evan Hunt 2012-01-31 03:35:41 +00:00
parent 477327ab65
commit 2855e27723
17 changed files with 791 additions and 61 deletions

View file

@ -1,3 +1,6 @@
3271. [func] New "rndc zonestatus" command prints information
about the specified zone. [RT #21671]
--- 9.9.0rc2 released ---
3270. [bug] "rndc reload" didn't reuse existing zones correctly

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: control.c,v 1.47 2011/11/03 23:05:30 each Exp $ */
/* $Id: control.c,v 1.48 2012/01/31 03:35:39 each Exp $ */
/*! \file */
@ -207,6 +207,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
result = ns_server_del_zone(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_SIGNING)) {
result = ns_server_signing(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_ZONESTATUS)) {
result = ns_server_zonestatus(ns_g_server, command, text);
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: control.h,v 1.36 2011/10/28 06:20:04 each Exp $ */
/* $Id: control.h,v 1.37 2012/01/31 03:35:39 each Exp $ */
#ifndef NAMED_CONTROL_H
#define NAMED_CONTROL_H 1
@ -65,6 +65,7 @@
#define NS_COMMAND_DELZONE "delzone"
#define NS_COMMAND_SYNC "sync"
#define NS_COMMAND_SIGNING "signing"
#define NS_COMMAND_ZONESTATUS "zonestatus"
isc_result_t
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.h,v 1.116 2011/11/03 23:05:30 each Exp $ */
/* $Id: server.h,v 1.117 2012/01/31 03:35:39 each Exp $ */
#ifndef NAMED_SERVER_H
#define NAMED_SERVER_H 1
@ -348,4 +348,11 @@ ns_server_del_zone(ns_server_t *server, char *args);
*/
isc_result_t
ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text);
/*%
* Lists status information for a given zone (e.g., name, type, files,
* load time, expiry, etc).
*/
isc_result_t
ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t *text);
#endif /* NAMED_SERVER_H */

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.639 2012/01/31 01:13:09 each Exp $ */
/* $Id: server.c,v 1.640 2012/01/31 03:35:39 each Exp $ */
/*! \file */
@ -8026,3 +8026,251 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) {
return (result);
}
isc_result_t
ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t *text) {
isc_result_t result = ISC_R_SUCCESS;
dns_zone_t *zone = NULL, *raw = NULL;
const char *type, *file, *zonename = NULL;
isc_uint32_t serial, signed_serial, nodes;
char serbuf[16], sserbuf[16], nodebuf[16], resignbuf[512];
char lbuf[80], xbuf[80], rbuf[80], kbuf[80], rtbuf[80];
isc_time_t loadtime, expiretime, refreshtime;
isc_time_t refreshkeytime, resigntime;
dns_zonetype_t zonetype;
isc_boolean_t dynamic = ISC_FALSE, frozen = ISC_FALSE;
isc_boolean_t hasraw = ISC_FALSE;
isc_boolean_t secure, maintain, allow;
dns_db_t *db = NULL, *rawdb = NULL;
char **incfiles = NULL;
int nfiles = 0;
isc_time_settoepoch(&loadtime);
isc_time_settoepoch(&refreshtime);
isc_time_settoepoch(&expiretime);
isc_time_settoepoch(&refreshkeytime);
isc_time_settoepoch(&resigntime);
CHECK(zone_from_args(server, args, &zone, &zonename, ISC_TRUE));
if (result != ISC_R_SUCCESS)
return (result);
if (zone == NULL) {
result = ISC_R_UNEXPECTEDEND;
goto cleanup;
}
zonetype = dns_zone_gettype(zone);
switch (zonetype) {
case dns_zone_master:
type = "master";
break;
case dns_zone_slave:
type = "slave";
break;
case dns_zone_stub:
type = "stub";
break;
case dns_zone_staticstub:
type = "staticstub";
break;
case dns_zone_redirect:
type = "redirect";
break;
case dns_zone_key:
type = "key";
break;
case dns_zone_dlz:
type = "dlz";
break;
default:
type = "unknown";
}
/* Inline signing? */
CHECK(dns_zone_getdb(zone, &db));
dns_zone_getraw(zone, &raw);
hasraw = ISC_TF(raw != NULL);
if (hasraw)
CHECK(dns_zone_getdb(raw, &rawdb));
/* Serial number */
serial = dns_zone_getserial(hasraw ? raw : zone);
snprintf(serbuf, sizeof(serbuf), "%d", serial);
if (hasraw) {
signed_serial = dns_zone_getserial(zone);
snprintf(sserbuf, sizeof(sserbuf), "%d", signed_serial);
}
/* Database node count */
nodes = dns_db_nodecount(hasraw ? rawdb : db);
snprintf(nodebuf, sizeof(nodebuf), "%d", nodes);
/* Security */
secure = dns_db_issecure(db);
allow = ISC_TF((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_ALLOW) != 0);
maintain = ISC_TF((dns_zone_getkeyopts(zone) &
DNS_ZONEKEY_MAINTAIN) != 0);
/* Master files */
file = dns_zone_getfile(hasraw ? raw : zone);
nfiles = dns_zone_getincludes(hasraw ? raw : zone, &incfiles);
/* Load time */
dns_zone_getloadtime(zone, &loadtime);
isc_time_formathttptimestamp(&loadtime, lbuf, sizeof(lbuf));
/* Refresh/expire times */
if (zonetype == dns_zone_slave ||
zonetype == dns_zone_stub ||
zonetype == dns_zone_redirect)
{
dns_zone_getexpiretime(zone, &expiretime);
isc_time_formathttptimestamp(&expiretime, xbuf, sizeof(xbuf));
dns_zone_getrefreshtime(zone, &refreshtime);
isc_time_formathttptimestamp(&refreshtime, rbuf, sizeof(rbuf));
}
/* Key refresh time */
if (zonetype == dns_zone_master ||
(zonetype == dns_zone_slave && hasraw))
{
dns_zone_getrefreshkeytime(zone, &refreshkeytime);
isc_time_formathttptimestamp(&refreshkeytime, kbuf,
sizeof(kbuf));
}
/* Dynamic? */
if (zonetype == dns_zone_master) {
dynamic = dns_zone_isdynamic(hasraw ? raw : zone, ISC_TRUE);
frozen = dynamic && !dns_zone_isdynamic(hasraw ? raw : zone,
ISC_FALSE);
}
/* Next resign event */
if (secure && (zonetype == dns_zone_master ||
(zonetype == dns_zone_slave && hasraw)) &&
((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_NORESIGN) == 0))
{
dns_name_t *name;
dns_fixedname_t fixed;
dns_rdataset_t next;
dns_db_t *signingdb;
dns_rdataset_init(&next);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
signingdb = hasraw ? rawdb : db;
result = dns_db_getsigningtime(signingdb, &next, name);
if (result == ISC_R_SUCCESS) {
isc_stdtime_t timenow;
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
isc_stdtime_get(&timenow);
dns_name_format(name, namebuf, sizeof(namebuf));
dns_rdatatype_format(next.covers,
typebuf, sizeof(typebuf));
snprintf(resignbuf, sizeof(resignbuf),
"%s/%s", namebuf, typebuf);
isc_time_set(&resigntime, next.resign, 0);
isc_time_formathttptimestamp(&resigntime, rtbuf,
sizeof(rtbuf));
dns_rdataset_disassociate(&next);
}
}
/* Create text */
isc_buffer_putstr(text, "name: ");
isc_buffer_putstr(text, zonename);
isc_buffer_putstr(text, "\ntype: ");
isc_buffer_putstr(text, type);
if (file != NULL) {
int i;
isc_buffer_putstr(text, "\nfiles: ");
isc_buffer_putstr(text, dns_zone_getfile(zone));
for (i = 0; i < nfiles; i++) {
isc_buffer_putstr(text, ", ");
isc_buffer_putstr(text, incfiles[i]);
}
}
isc_buffer_putstr(text, "\nserial: ");
isc_buffer_putstr(text, serbuf);
if (hasraw) {
isc_buffer_putstr(text, "\nsigned serial: ");
isc_buffer_putstr(text, sserbuf);
}
isc_buffer_putstr(text, "\nnodes: ");
isc_buffer_putstr(text, nodebuf);
if (! isc_time_isepoch(&loadtime)) {
isc_buffer_putstr(text, "\nlast loaded: ");
isc_buffer_putstr(text, lbuf);
}
if (! isc_time_isepoch(&refreshtime)) {
isc_buffer_putstr(text, "\nnext refresh: ");
isc_buffer_putstr(text, rbuf);
}
if (! isc_time_isepoch(&expiretime)) {
isc_buffer_putstr(text, "\nexpires: ");
isc_buffer_putstr(text, lbuf);
}
if (secure) {
isc_buffer_putstr(text, "\nsecure: yes");
if (hasraw)
isc_buffer_putstr(text, "\ninline signing: yes");
else
isc_buffer_putstr(text, "\ninline signing: no");
} else
isc_buffer_putstr(text, "\nsecure: no");
if (maintain) {
isc_buffer_putstr(text, "\nkey maintenance: automatic");
if (! isc_time_isepoch(&refreshkeytime)) {
isc_buffer_putstr(text, "\nnext key event: ");
isc_buffer_putstr(text, kbuf);
}
} else if (allow)
isc_buffer_putstr(text, "\nkey maintenance: on command");
else if (secure || hasraw)
isc_buffer_putstr(text, "\nkey maintenance: none");
if (!isc_time_isepoch(&resigntime)) {
isc_buffer_putstr(text, "\nnext resign node: ");
isc_buffer_putstr(text, resignbuf);
isc_buffer_putstr(text, "\nnext resign time: ");
isc_buffer_putstr(text, rtbuf);
}
if (dynamic) {
isc_buffer_putstr(text, "\ndynamic: yes");
if (frozen)
isc_buffer_putstr(text, "\nfrozen: yes");
else
isc_buffer_putstr(text, "\nfrozen: no");
} else
isc_buffer_putstr(text, "\ndynamic: no");
isc_buffer_putuint8(text, 0);
cleanup:
if (db != NULL)
dns_db_detach(&db);
if (hasraw) {
dns_db_detach(&rawdb);
dns_zone_detach(&raw);
}
if (incfiles != NULL)
isc_mem_free(server->mctx, incfiles);
if (zone != NULL)
dns_zone_detach(&zone);
return (result);
}

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rndc.c,v 1.139 2011/11/29 00:49:26 marka Exp $ */
/* $Id: rndc.c,v 1.140 2012/01/31 03:35:39 each Exp $ */
/*! \file */
@ -126,6 +126,8 @@ command is one of the following:\n\
Update zone keys, and sign as needed.\n\
loadkeys zone [class [view]]\n\
Update keys without signing immediately.\n\
zonestatus zone [class [view]]\n\
Display the current status of a zone.\n\
stats Write server statistics to the statistics file.\n\
querylog newstate\n\
Enable / disable query logging.\n\

View file

@ -14,7 +14,10 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: clean.sh,v 1.6 2007/09/26 03:22:44 marka Exp $
# $Id: clean.sh,v 1.7 2012/01/31 03:35:39 each Exp $
rm -f *.out
rm -f */named.memstats
rm -f */*.db */*.db.signed */K*.key */K*.private */*.jnl */dsset-*
rm -f rndc.out.*
rm -f random.data

View file

@ -0,0 +1,53 @@
/*
* Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.2 2012/01/31 03:35:40 each Exp $ */
// NS1
controls { /* empty */ };
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
dnssec-enable yes;
dnssec-validation yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};
zone "master.example" {
type master;
file "master.db";
allow-update { any; };
allow-transfer { any; };
auto-dnssec maintain;
};

View file

@ -0,0 +1,51 @@
/*
* Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.2 2012/01/31 03:35:40 each Exp $ */
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
notify yes;
dnssec-enable yes;
dnssec-validation yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
zone "master.example" {
type slave;
masters { 10.53.0.1; };
file "slave.db";
};

View file

@ -0,0 +1,29 @@
#!/bin/sh
#
# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: setup.sh,v 1.2 2012/01/31 03:35:39 each Exp $
sh clean.sh
../../../tools/genrandom 400 random.data
sh ../genzone.sh 1 > ns1/master.db
cd ns1
touch master.db.signed
echo '$INCLUDE "master.db.signed"' >> master.db
$KEYGEN -r ../random.data -3q master.example > /dev/null 2>&1
$KEYGEN -r ../random.data -3qfk master.example > /dev/null 2>&1
$SIGNER -SD -o master.example master.db > /dev/null 2>&1

View file

@ -14,7 +14,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: tests.sh,v 1.6 2009/12/04 22:06:37 tbox Exp $
# $Id: tests.sh,v 1.7 2012/01/31 03:35:39 each Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
@ -25,13 +25,13 @@ status=0
echo "I: checking that we detect a NS which refers to a CNAME"
if $CHECKZONE . cname.db > cname.out 2>&1
then
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
else
if grep "is a CNAME" cname.out > /dev/null
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
fi
@ -39,13 +39,13 @@ fi
echo "I: checking that we detect a NS which is below a DNAME"
if $CHECKZONE . dname.db > dname.out 2>&1
then
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
else
if grep "is below a DNAME" dname.out > /dev/null
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
fi
@ -53,13 +53,13 @@ fi
echo "I: checking that we detect a NS which has no address records (A/AAAA)"
if $CHECKZONE . noaddress.db > noaddress.out
then
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
else
if grep "has no address records" noaddress.out > /dev/null
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
fi
@ -67,13 +67,13 @@ fi
echo "I: checking that we detect a NS which has no records"
if $CHECKZONE . nxdomain.db > nxdomain.out
then
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
else
if grep "has no address records" noaddress.out > /dev/null
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
fi
@ -81,13 +81,13 @@ fi
echo "I: checking that we detect a NS which looks like a A record (fail)"
if $CHECKZONE -n fail . a.db > a.out 2>&1
then
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
else
if grep "appears to be an address" a.out > /dev/null
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
fi
@ -99,10 +99,10 @@ then
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
else
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
fi
#
@ -111,25 +111,25 @@ if $CHECKZONE -n ignore . a.db > a.out 2>&1
then
if grep "appears to be an address" a.out > /dev/null
then
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
else
:
fi
else
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
fi
#
echo "I: checking that we detect a NS which looks like a AAAA record (fail)"
if $CHECKZONE -n fail . aaaa.db > aaaa.out 2>&1
then
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
else
if grep "appears to be an address" aaaa.out > /dev/null
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
fi
@ -141,10 +141,10 @@ then
then
:
else
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
fi
else
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
fi
#
@ -153,12 +153,44 @@ if $CHECKZONE -n ignore . aaaa.db > aaaa.out 2>&1
then
if grep "appears to be an address" aaaa.out > /dev/null
then
echo "I:failed (message)"; status=1
echo "I:failed (message)"; status=`expr $status + 1`
else
:
fi
else
echo "I:failed (status)"; status=1
echo "I:failed (status)"; status=`expr $status + 1`
fi
#
echo "I: checking 'rdnc zonestatus' output"
ret=0
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 zonestatus master.example > rndc.out.master 2>&1
grep "name: master.example" rndc.out.master > /dev/null 2>&1 || ret=1
grep "type: master" rndc.out.master > /dev/null 2>&1 || ret=1
grep "files: master.db, master.db.signed" rndc.out.master > /dev/null 2>&1 || ret=1
grep "serial: " rndc.out.master > /dev/null 2>&1 || ret=1
grep "nodes: " rndc.out.master > /dev/null 2>&1 || ret=1
grep "last loaded: " rndc.out.master > /dev/null 2>&1 || ret=1
grep "secure: yes" rndc.out.master > /dev/null 2>&1 || ret=1
grep "inline signing: no" rndc.out.master > /dev/null 2>&1 || ret=1
grep "key maintenance: automatic" rndc.out.master > /dev/null 2>&1 || ret=1
grep "next key event: " rndc.out.master > /dev/null 2>&1 || ret=1
grep "next resign node: " rndc.out.master > /dev/null 2>&1 || ret=1
grep "next resign time: " rndc.out.master > /dev/null 2>&1 || ret=1
grep "dynamic: yes" rndc.out.master > /dev/null 2>&1 || ret=1
grep "frozen: no" rndc.out.master > /dev/null 2>&1 || ret=1
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 zonestatus master.example > rndc.out.slave 2>&1
grep "name: master.example" rndc.out.slave > /dev/null 2>&1 || ret=1
grep "type: slave" rndc.out.slave > /dev/null 2>&1 || ret=1
grep "files: slave.db" rndc.out.slave > /dev/null 2>&1 || ret=1
grep "serial: " rndc.out.slave > /dev/null 2>&1 || ret=1
grep "nodes: " rndc.out.slave > /dev/null 2>&1 || ret=1
grep "next refresh: " rndc.out.slave > /dev/null 2>&1 || ret=1
grep "expires: " rndc.out.slave > /dev/null 2>&1 || ret=1
grep "secure: yes" rndc.out.slave > /dev/null 2>&1 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View file

@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.521 2012/01/15 21:16:04 each Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.522 2012/01/31 03:35:40 each Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@ -1311,6 +1311,26 @@ zone "eng.example.com" {
</listitem>
</varlistentry>
<varlistentry>
<term><userinput>zonestatus
<optional><replaceable>zone</replaceable>
<optional><replaceable>class</replaceable>
<optional><replaceable>view</replaceable></optional></optional></optional></userinput></term>
<listitem>
<para>
Displays the current status of the given zone,
including the master file name and any include
files from which it was loaded, when it was most
recently loaded, the current serial number, the
number of nodes, whether the zone supports
dynamic updates, whether the zone is DNSSEC
signed, whether it uses automatic DNSSEC key
management or inline signing, and the scheduled
refresh or expiry times for the zone.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><userinput>stats</userinput></term>
<listitem>

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: master.h,v 1.55 2011/12/09 23:47:05 tbox Exp $ */
/* $Id: master.h,v 1.56 2012/01/31 03:35:41 each Exp $ */
#ifndef DNS_MASTER_H
#define DNS_MASTER_H 1
@ -103,6 +103,13 @@ typedef struct {
/* followed by encoded owner name, and then rdata */
} dns_masterrawrdataset_t;
/*
* Method prototype: a callback to register each include file as
* it is encountered.
*/
typedef void
(*dns_masterincludecb_t)(const char *file, void *arg);
/***
*** Function
***/
@ -137,6 +144,18 @@ dns_master_loadfile3(const char *master_file,
isc_mem_t *mctx,
dns_masterformat_t format);
isc_result_t
dns_master_loadfile4(const char *master_file,
dns_name_t *top,
dns_name_t *origin,
dns_rdataclass_t zclass,
unsigned int options,
isc_uint32_t resign,
dns_rdatacallbacks_t *callbacks,
dns_masterincludecb_t include_cb,
void *include_arg, isc_mem_t *mctx,
dns_masterformat_t format);
isc_result_t
dns_master_loadstream(FILE *stream,
dns_name_t *top,
@ -200,6 +219,20 @@ dns_master_loadfileinc3(const char *master_file,
dns_loadctx_t **ctxp, isc_mem_t *mctx,
dns_masterformat_t format);
isc_result_t
dns_master_loadfileinc4(const char *master_file,
dns_name_t *top,
dns_name_t *origin,
dns_rdataclass_t zclass,
unsigned int options,
isc_uint32_t resign,
dns_rdatacallbacks_t *callbacks,
isc_task_t *task,
dns_loaddonefunc_t done, void *done_arg,
dns_loadctx_t **ctxp,
dns_masterincludecb_t include_cb, void *include_arg,
isc_mem_t *mctx, dns_masterformat_t format);
isc_result_t
dns_master_loadstreaminc(FILE *stream,
dns_name_t *top,

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.h,v 1.201 2012/01/25 23:46:49 tbox Exp $ */
/* $Id: zone.h,v 1.202 2012/01/31 03:35:41 each Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
@ -2039,4 +2039,37 @@ dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header);
*/
ISC_LANG_ENDDECLS
isc_result_t
dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime);
/*%
* Return the time when the zone was last loaded.
*/
isc_result_t
dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime);
/*%
* Return the time when the (slave) zone will need to be refreshed.
*/
isc_result_t
dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime);
/*%
* Return the time when the (slave) zone will expire.
*/
isc_result_t
dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime);
/*%
* Return the time of the next scheduled DNSSEC key event.
*/
int
dns_zone_getincludes(dns_zone_t *zone, char ***includesp);
/*%
* Return the number include files that were encountered
* during load. If the number is greater than zero, 'includesp'
* will point to an array containing the filenames.
*/
#endif /* DNS_ZONE_H */

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: master.c,v 1.181 2011/12/08 16:07:20 each Exp $ */
/* $Id: master.c,v 1.182 2012/01/31 03:35:40 each Exp $ */
/*! \file */
@ -145,6 +145,9 @@ struct dns_loadctx {
isc_uint32_t references;
dns_incctx_t *inc;
isc_uint32_t resign;
dns_masterincludecb_t include_cb;
void *include_arg;
};
struct dns_incctx {
@ -512,8 +515,9 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
unsigned int options, isc_uint32_t resign, dns_name_t *top,
dns_rdataclass_t zclass, dns_name_t *origin,
dns_rdatacallbacks_t *callbacks, isc_task_t *task,
dns_loaddonefunc_t done, void *done_arg, isc_lex_t *lex,
dns_loadctx_t **lctxp)
dns_loaddonefunc_t done, void *done_arg,
dns_masterincludecb_t include_cb, void *include_arg,
isc_lex_t *lex, dns_loadctx_t **lctxp)
{
dns_loadctx_t *lctx;
isc_result_t result;
@ -588,6 +592,8 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
lctx->zclass = zclass;
lctx->resign = resign;
lctx->result = ISC_R_SUCCESS;
lctx->include_cb = include_cb;
lctx->include_arg = include_arg;
dns_fixedname_init(&lctx->fixed_top);
lctx->top = dns_fixedname_name(&lctx->fixed_top);
@ -2044,6 +2050,9 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) {
goto cleanup;
new->parent = ictx;
lctx->inc = new;
if (lctx->include_cb != NULL)
lctx->include_cb(master_file, lctx->include_arg);
return (ISC_R_SUCCESS);
cleanup:
@ -2401,8 +2410,9 @@ dns_master_loadfile(const char *master_file, dns_name_t *top,
dns_rdataclass_t zclass, unsigned int options,
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx)
{
return (dns_master_loadfile3(master_file, top, origin, zclass, options,
0, callbacks, mctx, dns_masterformat_text));
return (dns_master_loadfile4(master_file, top, origin, zclass, options,
0, callbacks, NULL, NULL, mctx,
dns_masterformat_text));
}
isc_result_t
@ -2412,8 +2422,8 @@ dns_master_loadfile2(const char *master_file, dns_name_t *top,
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
dns_masterformat_t format)
{
return (dns_master_loadfile3(master_file, top, origin, zclass, options,
0, callbacks, mctx, format));
return (dns_master_loadfile4(master_file, top, origin, zclass, options,
0, callbacks, NULL, NULL, mctx, format));
}
isc_result_t
@ -2422,13 +2432,26 @@ dns_master_loadfile3(const char *master_file, dns_name_t *top,
unsigned int options, isc_uint32_t resign,
dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx,
dns_masterformat_t format)
{
return (dns_master_loadfile4(master_file, top, origin, zclass, options,
resign, callbacks, NULL, NULL, mctx,
format));
}
isc_result_t
dns_master_loadfile4(const char *master_file, dns_name_t *top,
dns_name_t *origin, dns_rdataclass_t zclass,
unsigned int options, isc_uint32_t resign,
dns_rdatacallbacks_t *callbacks,
dns_masterincludecb_t include_cb, void *include_arg,
isc_mem_t *mctx, dns_masterformat_t format)
{
dns_loadctx_t *lctx = NULL;
isc_result_t result;
result = loadctx_create(format, mctx, options, resign, top, zclass,
origin, callbacks, NULL, NULL, NULL, NULL,
&lctx);
origin, callbacks, NULL, NULL, NULL,
include_cb, include_arg, NULL, &lctx);
if (result != ISC_R_SUCCESS)
return (result);
@ -2451,9 +2474,9 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top,
isc_task_t *task, dns_loaddonefunc_t done,
void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx)
{
return (dns_master_loadfileinc3(master_file, top, origin, zclass,
return (dns_master_loadfileinc4(master_file, top, origin, zclass,
options, 0, callbacks, task, done,
done_arg, lctxp, mctx,
done_arg, lctxp, NULL, NULL, mctx,
dns_masterformat_text));
}
@ -2465,9 +2488,10 @@ dns_master_loadfileinc2(const char *master_file, dns_name_t *top,
void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx,
dns_masterformat_t format)
{
return (dns_master_loadfileinc3(master_file, top, origin, zclass,
return (dns_master_loadfileinc4(master_file, top, origin, zclass,
options, 0, callbacks, task, done,
done_arg, lctxp, mctx, format));
done_arg, lctxp, NULL, NULL, mctx,
format));
}
isc_result_t
@ -2478,6 +2502,22 @@ dns_master_loadfileinc3(const char *master_file, dns_name_t *top,
dns_loaddonefunc_t done, void *done_arg,
dns_loadctx_t **lctxp, isc_mem_t *mctx,
dns_masterformat_t format)
{
return (dns_master_loadfileinc4(master_file, top, origin, zclass,
options, resign, callbacks, task,
done, done_arg, lctxp, NULL, NULL,
mctx, format));
}
isc_result_t
dns_master_loadfileinc4(const char *master_file, dns_name_t *top,
dns_name_t *origin, dns_rdataclass_t zclass,
unsigned int options, isc_uint32_t resign,
dns_rdatacallbacks_t *callbacks,
isc_task_t *task, dns_loaddonefunc_t done,
void *done_arg, dns_loadctx_t **lctxp,
dns_masterincludecb_t include_cb, void *include_arg,
isc_mem_t *mctx, dns_masterformat_t format)
{
dns_loadctx_t *lctx = NULL;
isc_result_t result;
@ -2486,8 +2526,8 @@ dns_master_loadfileinc3(const char *master_file, dns_name_t *top,
REQUIRE(done != NULL);
result = loadctx_create(format, mctx, options, resign, top, zclass,
origin, callbacks, task, done, done_arg, NULL,
&lctx);
origin, callbacks, task, done, done_arg,
include_cb, include_arg, NULL, &lctx);
if (result != ISC_R_SUCCESS)
return (result);
@ -2518,7 +2558,7 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin,
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
zclass, origin, callbacks, NULL, NULL, NULL,
NULL, &lctx);
NULL, NULL, NULL, &lctx);
if (result != ISC_R_SUCCESS)
goto cleanup;
@ -2551,7 +2591,7 @@ dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin,
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
zclass, origin, callbacks, task, done,
done_arg, NULL, &lctx);
done_arg, NULL, NULL, NULL, &lctx);
if (result != ISC_R_SUCCESS)
goto cleanup;
@ -2584,7 +2624,7 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top,
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
zclass, origin, callbacks, NULL, NULL, NULL,
NULL, &lctx);
NULL, NULL, NULL, &lctx);
if (result != ISC_R_SUCCESS)
return (result);
@ -2617,7 +2657,7 @@ dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top,
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
zclass, origin, callbacks, task, done,
done_arg, NULL, &lctx);
done_arg, NULL, NULL, NULL, &lctx);
if (result != ISC_R_SUCCESS)
return (result);
@ -2649,7 +2689,7 @@ dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top,
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
zclass, origin, callbacks, NULL, NULL, NULL,
lex, &lctx);
NULL, NULL, lex, &lctx);
if (result != ISC_R_SUCCESS)
return (result);
@ -2677,7 +2717,7 @@ dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top,
result = loadctx_create(dns_masterformat_text, mctx, options, 0, top,
zclass, origin, callbacks, task, done,
done_arg, lex, &lctx);
done_arg, NULL, NULL, lex, &lctx);
if (result != ISC_R_SUCCESS)
return (result);

View file

@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: master_test.c,v 1.7 2011/12/08 16:07:22 each Exp $ */
/* $Id: master_test.c,v 1.8 2012/01/31 03:35:41 each Exp $ */
/*! \file */
@ -47,6 +47,10 @@
static dns_masterrawheader_t header;
static isc_boolean_t headerset;
dns_name_t dns_origin;
dns_rdatacallbacks_t callbacks;
char *include_file = NULL;
static isc_result_t
add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset);
@ -74,16 +78,14 @@ rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *h) {
headerset = ISC_TRUE;
}
static int
test_master(const char *testfile, dns_masterformat_t format) {
static isc_result_t
setup_master() {
isc_result_t result;
int len;
char origin[sizeof(TEST_ORIGIN)];
dns_name_t dns_origin;
isc_buffer_t source;
isc_buffer_t target;
unsigned char name_buf[BUFLEN];
dns_rdatacallbacks_t callbacks;
strcpy(origin, TEST_ORIGIN);
len = strlen(origin);
@ -103,6 +105,13 @@ test_master(const char *testfile, dns_masterformat_t format) {
callbacks.add = add_callback;
callbacks.rawdata = rawdata_callback;
callbacks.zone = NULL;
return (result);
}
static isc_result_t
test_master(const char *testfile, dns_masterformat_t format) {
isc_result_t result;
headerset = ISC_FALSE;
result = dns_master_loadfile2(testfile, &dns_origin, &dns_origin,
dns_rdataclass_in, ISC_TRUE,
@ -110,6 +119,12 @@ test_master(const char *testfile, dns_masterformat_t format) {
return (result);
}
static void
include_callback(const char *filename, void *arg) {
char **argp = (char **) arg;
*argp = isc_mem_strdup(mctx, filename);
}
/*
* Individual unit tests
*/
@ -128,6 +143,7 @@ ATF_TC_BODY(load, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master1.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
@ -151,6 +167,7 @@ ATF_TC_BODY(unexpected, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master2.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_UNEXPECTEDEND);
@ -174,6 +191,7 @@ ATF_TC_BODY(noowner, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master3.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_NOOWNER);
@ -198,6 +216,7 @@ ATF_TC_BODY(nottl, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master4.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
@ -221,6 +240,7 @@ ATF_TC_BODY(badclass, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master5.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_BADCLASS);
@ -242,6 +262,7 @@ ATF_TC_BODY(dnskey, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master6.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
@ -264,6 +285,7 @@ ATF_TC_BODY(dnsnokey, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master7.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
@ -285,6 +307,7 @@ ATF_TC_BODY(include, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master8.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_SEENINCLUDE);
@ -292,6 +315,37 @@ ATF_TC_BODY(include, tc) {
dns_test_end();
}
/* Include file list test */
ATF_TC(master_includelist);
ATF_TC_HEAD(master_includelist, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile4() returns "
"names of included file");
}
ATF_TC_BODY(master_includelist, tc) {
isc_result_t result;
char *filename = NULL;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = dns_master_loadfile4("testdata/master/master8.data",
&dns_origin, &dns_origin,
dns_rdataclass_in, 0, ISC_TRUE,
&callbacks, include_callback,
&filename, mctx, dns_masterformat_text);
ATF_CHECK_EQ(result, DNS_R_SEENINCLUDE);
ATF_CHECK(filename != NULL);
if (filename != NULL) {
ATF_CHECK_STREQ(filename, "testdata/master/master7.data");
isc_mem_free(mctx, filename);
}
dns_test_end();
}
/* Include failure test */
ATF_TC(includefail);
ATF_TC_HEAD(includefail, tc) {
@ -306,6 +360,7 @@ ATF_TC_BODY(includefail, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master9.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_BADCLASS);
@ -328,6 +383,7 @@ ATF_TC_BODY(blanklines, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master10.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
@ -349,6 +405,7 @@ ATF_TC_BODY(leadingzero, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("testdata/master/master11.data",
dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
@ -415,6 +472,7 @@ ATF_TC_BODY(loadraw, tc) {
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/* Raw format version 0 */
setup_master();
result = test_master("testdata/master/master12.data",
dns_masterformat_raw);
ATF_CHECK_STREQ(isc_result_totext(result), "success");
@ -422,6 +480,7 @@ ATF_TC_BODY(loadraw, tc) {
ATF_CHECK_EQ(header.flags, 0);
/* Raw format version 1, no source serial */
setup_master();
result = test_master("testdata/master/master13.data",
dns_masterformat_raw);
ATF_CHECK_STREQ(isc_result_totext(result), "success");
@ -429,6 +488,7 @@ ATF_TC_BODY(loadraw, tc) {
ATF_CHECK_EQ(header.flags, 0);
/* Raw format version 1, source serial == 2011120101 */
setup_master();
result = test_master("testdata/master/master14.data",
dns_masterformat_raw);
ATF_CHECK_STREQ(isc_result_totext(result), "success");
@ -485,6 +545,7 @@ ATF_TC_BODY(dumpraw, tc) {
dns_masterformat_raw);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("test.dump", dns_masterformat_raw);
ATF_CHECK_STREQ(isc_result_totext(result), "success");
ATF_CHECK(headerset);
@ -500,6 +561,7 @@ ATF_TC_BODY(dumpraw, tc) {
dns_masterformat_raw, &header);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
setup_master();
result = test_master("test.dump", dns_masterformat_raw);
ATF_CHECK_STREQ(isc_result_totext(result), "success");
ATF_CHECK(headerset);
@ -524,6 +586,7 @@ ATF_TP_ADD_TCS(tp) {
ATF_TP_ADD_TC(tp, dnskey);
ATF_TP_ADD_TC(tp, dnsnokey);
ATF_TP_ADD_TC(tp, include);
ATF_TP_ADD_TC(tp, master_includelist);
ATF_TP_ADD_TC(tp, includefail);
ATF_TP_ADD_TC(tp, blanklines);
ATF_TP_ADD_TC(tp, leadingzero);

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: zone.c,v 1.668 2012/01/31 01:13:10 each Exp $ */
/* $Id: zone.c,v 1.669 2012/01/31 03:35:40 each Exp $ */
/*! \file */
@ -150,6 +150,7 @@ typedef struct dns_nsec3chain dns_nsec3chain_t;
typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
typedef struct dns_keyfetch dns_keyfetch_t;
typedef struct dns_asyncload dns_asyncload_t;
typedef struct dns_include dns_include_t;
#define DNS_ZONE_CHECKLOCK
#ifdef DNS_ZONE_CHECKLOCK
@ -203,6 +204,8 @@ struct dns_zone {
unsigned int irefs;
dns_name_t origin;
char *masterfile;
ISC_LIST(dns_include_t) includes; /* Include files */
unsigned int nincludes;
dns_masterformat_t masterformat;
char *journal;
isc_int32_t journalsize;
@ -617,6 +620,14 @@ struct dns_asyncload {
void *loaded_arg;
};
/*%
* Reference to an include file encountered during loading
*/
struct dns_include {
char *name;
ISC_LINK(dns_include_t) link;
};
#define HOUR 3600
#define DAY (24*HOUR)
#define MONTH (30*DAY)
@ -805,6 +816,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->strrdclass = NULL;
zone->strviewname = NULL;
zone->masterfile = NULL;
ISC_LIST_INIT(zone->includes);
zone->nincludes = 0;
zone->masterformat = dns_masterformat_none;
zone->keydirectory = NULL;
zone->journalsize = -1;
@ -942,6 +955,7 @@ zone_free(dns_zone_t *zone) {
isc_mem_t *mctx = NULL;
dns_signing_t *signing;
dns_nsec3chain_t *nsec3chain;
dns_include_t *include;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(isc_refcount_current(&zone->erefs) == 0);
@ -982,6 +996,13 @@ zone_free(dns_zone_t *zone) {
dns_dbiterator_destroy(&nsec3chain->dbiterator);
isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
}
for (include = ISC_LIST_HEAD(zone->includes);
include != NULL;
include = ISC_LIST_HEAD(zone->includes)) {
ISC_LIST_UNLINK(zone->includes, include, link);
isc_mem_free(zone->mctx, include->name);
isc_mem_put(zone->mctx, include, sizeof *include);
}
if (zone->masterfile != NULL)
isc_mem_free(zone->mctx, zone->masterfile);
zone->masterfile = NULL;
@ -1810,6 +1831,25 @@ get_master_options(dns_zone_t *zone) {
return (options);
}
static void
zone_registerinclude(const char *filename, void *arg) {
dns_zone_t *zone = (dns_zone_t *) arg;
dns_include_t *inc = NULL;
REQUIRE(DNS_ZONE_VALID(zone));
if (filename == NULL)
return;
fprintf(stderr, "register callback: %s\n", filename);
inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
inc->name = isc_mem_strdup(zone->mctx, filename);
ISC_LINK_INIT(inc, link);
ISC_LIST_APPEND(zone->includes, inc, link);
zone->nincludes++;
}
static void
zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
dns_load_t *load = event->ev_arg;
@ -1826,14 +1866,16 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
options = get_master_options(load->zone);
result = dns_master_loadfileinc3(load->zone->masterfile,
result = dns_master_loadfileinc4(load->zone->masterfile,
dns_db_origin(load->db),
dns_db_origin(load->db),
load->zone->rdclass, options,
load->zone->sigresigninginterval,
&load->callbacks, task,
zone_loaddone, load,
&load->zone->lctx, load->zone->mctx,
&load->zone->lctx,
zone_registerinclude,
load->zone, load->zone->mctx,
load->zone->masterformat);
if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
result != DNS_R_SEENINCLUDE)
@ -1983,11 +2025,13 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
zone_idetach(&callbacks.zone);
return (result);
}
result = dns_master_loadfile3(zone->masterfile,
result = dns_master_loadfile4(zone->masterfile,
&zone->origin, &zone->origin,
zone->rdclass, options,
zone->sigresigninginterval,
&callbacks, zone->mctx,
&callbacks,
zone_registerinclude,
zone, zone->mctx,
zone->masterformat);
tresult = dns_db_endload(db, &callbacks.add_private);
if (result == ISC_R_SUCCESS)
@ -16211,3 +16255,69 @@ dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
UNLOCK_ZONE(zone);
return (result);
}
isc_result_t
dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(loadtime != NULL);
LOCK_ZONE(zone);
*loadtime = zone->loadtime;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(expiretime != NULL);
LOCK_ZONE(zone);
*expiretime = zone->expiretime;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(refreshtime != NULL);
LOCK_ZONE(zone);
*refreshtime = zone->refreshtime;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(refreshkeytime != NULL);
LOCK_ZONE(zone);
*refreshkeytime = zone->refreshkeytime;
UNLOCK_ZONE(zone);
return (ISC_R_SUCCESS);
}
int
dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
dns_include_t *include;
char **array = NULL;
int n = 0;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(includesp != NULL && *includesp == NULL);
LOCK_ZONE(zone);
if (zone->nincludes == 0)
goto done;
array = isc_mem_allocate(zone->mctx, sizeof(char *) * n);
for (include = ISC_LIST_HEAD(zone->includes);
include != NULL;
include = ISC_LIST_NEXT(include, link)) {
array[n++] = include->name;
}
*includesp = array;
done:
UNLOCK_ZONE(zone);
return (n);
}