mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 23:55:27 +00:00
3252. [bug] When master zones using inline-signing were
updated while the server was offline, the source zone could fall out of sync with the signed copy. They can now resynchronize. [RT #26676]
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,3 +1,8 @@
|
||||
3252. [bug] When master zones using inline-signing were
|
||||
updated while the server was offline, the source
|
||||
zone could fall out of sync with the signed
|
||||
copy. They can now resynchronize. [RT #26676]
|
||||
|
||||
3251. [bug] Enforce a upper bound (65535 bytes) on the amount of
|
||||
memory dns_sdlz_putrr() can allocate per record to
|
||||
prevent run away memory consumption on ISC_R_NOSPACE.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check-tool.c,v 1.43 2011/12/09 23:47:02 tbox Exp $ */
|
||||
/* $Id: check-tool.c,v 1.44 2011/12/22 07:32:39 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -661,7 +661,6 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
|
||||
|
||||
result = dns_zone_dumptostream3(zone, output, fileformat, style,
|
||||
rawversion);
|
||||
|
||||
if (output != stdout)
|
||||
(void)isc_stdio_close(output);
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: named-checkzone.c,v 1.63 2011/12/09 23:47:02 tbox Exp $ */
|
||||
/* $Id: named-checkzone.c,v 1.64 2011/12/22 07:32:39 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <dns/db.h>
|
||||
#include <dns/fixedname.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/master.h>
|
||||
#include <dns/masterdump.h>
|
||||
#include <dns/name.h>
|
||||
#include <dns/rdataclass.h>
|
||||
@@ -112,8 +113,11 @@ main(int argc, char **argv) {
|
||||
const char *outputformatstr = NULL;
|
||||
dns_masterformat_t inputformat = dns_masterformat_text;
|
||||
dns_masterformat_t outputformat = dns_masterformat_text;
|
||||
isc_uint32_t rawversion = 1;
|
||||
dns_masterrawheader_t header;
|
||||
isc_uint32_t rawversion = 1, serialnum = 0;
|
||||
isc_boolean_t snset = ISC_FALSE;
|
||||
FILE *errout = stdout;
|
||||
char *endp;
|
||||
|
||||
outputstyle = &dns_master_style_full;
|
||||
|
||||
@@ -157,7 +161,7 @@ main(int argc, char **argv) {
|
||||
isc_commandline_errprint = ISC_FALSE;
|
||||
|
||||
while ((c = isc_commandline_parse(argc, argv,
|
||||
"c:df:hi:jk:m:n:qr:s:t:o:vw:DF:M:S:W:"))
|
||||
"c:df:hi:jk:L:m:n:qr:s:t:o:vw:DF:M:S:W:"))
|
||||
!= EOF) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
@@ -235,6 +239,17 @@ main(int argc, char **argv) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
snset = ISC_TRUE;
|
||||
endp = NULL;
|
||||
serialnum = strtol(isc_commandline_argument, &endp, 0);
|
||||
if (*endp != '\0') {
|
||||
fprintf(stderr, "source serial number "
|
||||
"must be numeric");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (ARGCMP("ignore")) {
|
||||
zone_options &= ~(DNS_ZONEOPT_CHECKNS|
|
||||
@@ -477,6 +492,13 @@ main(int argc, char **argv) {
|
||||
result = load_zone(mctx, origin, filename, inputformat, classname,
|
||||
&zone);
|
||||
|
||||
if (snset) {
|
||||
dns_master_initrawheader(&header);
|
||||
header.flags = DNS_MASTERRAW_SOURCESERIALSET;
|
||||
header.sourceserial = serialnum;
|
||||
dns_zone_setrawdata(zone, &header);
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS && dumpzone) {
|
||||
if (!quiet && progmode == progmode_compile) {
|
||||
fprintf(errout, "dump zone to %s...", output_filename);
|
||||
|
@@ -18,7 +18,7 @@
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- $Id: named-checkzone.docbook,v 1.43 2011/12/09 23:47:02 tbox Exp $ -->
|
||||
<!-- $Id: named-checkzone.docbook,v 1.44 2011/12/22 07:32:39 each Exp $ -->
|
||||
<refentry id="man.named-checkzone">
|
||||
<refentryinfo>
|
||||
<date>June 13, 2000</date>
|
||||
@@ -71,6 +71,7 @@
|
||||
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-M <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-L <replaceable class="parameter">serial</replaceable></option></arg>
|
||||
<arg><option>-o <replaceable class="parameter">filename</replaceable></option></arg>
|
||||
<arg><option>-r <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-s <replaceable class="parameter">style</replaceable></option></arg>
|
||||
@@ -96,6 +97,7 @@
|
||||
<arg><option>-k <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-m <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-n <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-L <replaceable class="parameter">serial</replaceable></option></arg>
|
||||
<arg><option>-r <replaceable class="parameter">mode</replaceable></option></arg>
|
||||
<arg><option>-s <replaceable class="parameter">style</replaceable></option></arg>
|
||||
<arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
|
||||
@@ -280,6 +282,17 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-L <replaceable class="parameter">serial</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
When compiling a zone to 'raw' format, set the "source serial"
|
||||
value in the header to the specified serial number. (This is
|
||||
expected to be used primarily for testing purposes.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-m <replaceable class="parameter">mode</replaceable></term>
|
||||
<listitem>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dnssec-signzone.c,v 1.284 2011/12/08 23:45:02 marka Exp $ */
|
||||
/* $Id: dnssec-signzone.c,v 1.285 2011/12/22 07:32:39 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -139,7 +139,8 @@ static char *tempfile = NULL;
|
||||
static const dns_master_style_t *masterstyle;
|
||||
static dns_masterformat_t inputformat = dns_masterformat_text;
|
||||
static dns_masterformat_t outputformat = dns_masterformat_text;
|
||||
static unsigned int rawversion = 1;
|
||||
static isc_uint32_t rawversion = 1, serialnum = 0;
|
||||
static isc_boolean_t snset = ISC_FALSE;
|
||||
static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
|
||||
static unsigned int nverified = 0, nverifyfailed = 0;
|
||||
static const char *directory = NULL, *dsdir = NULL;
|
||||
@@ -3470,7 +3471,7 @@ main(int argc, char *argv[]) {
|
||||
isc_boolean_t set_iter = ISC_FALSE;
|
||||
|
||||
#define CMDLINE_FLAGS \
|
||||
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xz"
|
||||
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xz"
|
||||
|
||||
/*
|
||||
* Process memory debugging argument first.
|
||||
@@ -3620,6 +3621,17 @@ main(int argc, char *argv[]) {
|
||||
dskeyfile[ndskeys++] = isc_commandline_argument;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
snset = ISC_TRUE;
|
||||
endp = NULL;
|
||||
serialnum = strtol(isc_commandline_argument, &endp, 0);
|
||||
if (*endp != '\0') {
|
||||
fprintf(stderr, "source serial number "
|
||||
"must be numeric");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
len = strlen(isc_commandline_argument);
|
||||
isc_buffer_init(&b, isc_commandline_argument, len);
|
||||
@@ -4077,6 +4089,10 @@ main(int argc, char *argv[]) {
|
||||
dns_master_initrawheader(&header);
|
||||
if (rawversion == 0U)
|
||||
header.flags = DNS_MASTERRAW_COMPAT;
|
||||
else if (snset) {
|
||||
header.flags = DNS_MASTERRAW_SOURCESERIALSET;
|
||||
header.sourceserial = serialnum;
|
||||
}
|
||||
result = dns_master_dumptostream3(mctx, gdb, gversion,
|
||||
masterstyle, outputformat,
|
||||
&header, fp);
|
||||
|
@@ -18,7 +18,7 @@
|
||||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- $Id: dnssec-signzone.docbook,v 1.51 2011/12/08 16:07:20 each Exp $ -->
|
||||
<!-- $Id: dnssec-signzone.docbook,v 1.52 2011/12/22 07:32:40 each Exp $ -->
|
||||
<refentry id="man.dnssec-signzone">
|
||||
<refentryinfo>
|
||||
<date>June 05, 2009</date>
|
||||
@@ -69,6 +69,7 @@
|
||||
<arg><option>-h</option></arg>
|
||||
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg>
|
||||
<arg><option>-k <replaceable class="parameter">key</replaceable></option></arg>
|
||||
<arg><option>-L <replaceable class="parameter">serial</replaceable></option></arg>
|
||||
<arg><option>-l <replaceable class="parameter">domain</replaceable></option></arg>
|
||||
<arg><option>-i <replaceable class="parameter">interval</replaceable></option></arg>
|
||||
<arg><option>-I <replaceable class="parameter">input-format</replaceable></option></arg>
|
||||
@@ -371,6 +372,17 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-L <replaceable class="parameter">serial</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
When writing a signed zone to 'raw' format, set the "source serial"
|
||||
value in the header to the specified serial number. (This is
|
||||
expected to be used primarily for testing purposes.)
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-n <replaceable class="parameter">ncpus</replaceable></term>
|
||||
<listitem>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: update.c,v 1.198 2011/10/28 06:20:04 each Exp $ */
|
||||
/* $Id: update.c,v 1.199 2011/12/22 07:32:40 each Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -3095,7 +3095,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
journal = NULL;
|
||||
result = dns_journal_open(mctx, journalfile,
|
||||
ISC_TRUE, &journal);
|
||||
DNS_JOURNAL_CREATE, &journal);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
FAILS(result, "journal open failed");
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrout.c,v 1.143 2011/12/01 00:53:58 marka Exp $ */
|
||||
/* $Id: xfrout.c,v 1.144 2011/12/22 07:32:40 each Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -252,7 +252,7 @@ ixfr_rrstream_create(isc_mem_t *mctx,
|
||||
s->journal = NULL;
|
||||
|
||||
CHECK(dns_journal_open(mctx, journal_filename,
|
||||
ISC_FALSE, &s->journal));
|
||||
DNS_JOURNAL_READ, &s->journal));
|
||||
CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial));
|
||||
|
||||
*sp = (rrstream_t *) s;
|
||||
|
@@ -12,13 +12,14 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: clean.sh,v 1.7 2011/12/02 02:44:01 marka Exp $
|
||||
# $Id: clean.sh,v 1.8 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
rm -f */named.memstats
|
||||
rm -f */named.run
|
||||
rm -f */trusted.conf
|
||||
rm -f ns1/K*
|
||||
rm -f ns1/dsset-*
|
||||
rm -f ns3/dsset-*
|
||||
rm -f ns1/root.db
|
||||
rm -f ns1/root.db.signed
|
||||
rm -f ns2/bits.db
|
||||
@@ -40,6 +41,10 @@ rm -f ns3/dynamic.db
|
||||
rm -f ns3/dynamic.db.jnl
|
||||
rm -f ns3/dynamic.db.signed
|
||||
rm -f ns3/dynamic.db.signed.jnl
|
||||
rm -f ns3/updated.db
|
||||
rm -f ns3/updated.db.jnl
|
||||
rm -f ns3/updated.db.signed
|
||||
rm -f ns3/updated.db.signed.jnl
|
||||
rm -f ns4/K*
|
||||
rm -f ns4/noixfr.db
|
||||
rm -f ns4/noixfr.db.jnl
|
||||
|
@@ -12,7 +12,7 @@
|
||||
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
; PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
; $Id: root.db.in,v 1.4 2011/10/26 20:56:45 marka Exp $
|
||||
; $Id: root.db.in,v 1.5 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
$TTL 300
|
||||
. IN SOA gson.nominum.com. a.root.servers.nil. (
|
||||
@@ -38,3 +38,6 @@ ns3.master. A 10.53.0.3
|
||||
|
||||
dynamic. NS ns3.dynamic.
|
||||
ns3.dynamic. A 10.53.0.3
|
||||
|
||||
updated. NS ns3.updated.
|
||||
ns3.updated. A 10.53.0.3
|
||||
|
@@ -14,7 +14,7 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: sign.sh,v 1.2 2011/10/25 01:54:20 marka Exp $
|
||||
# $Id: sign.sh,v 1.3 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -26,7 +26,7 @@ rm -f K.+*+*.key
|
||||
rm -f K.+*+*.private
|
||||
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
|
||||
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
|
||||
$SIGNER -S -x -T 1200 -o ${zone} root.db
|
||||
$SIGNER -S -x -T 1200 -o ${zone} root.db > /dev/null 2>&1
|
||||
|
||||
cat ${keyname}.key | grep -v '^; ' | $PERL -n -e '
|
||||
local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split;
|
||||
|
@@ -14,7 +14,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: named.conf,v 1.4 2011/10/26 20:56:45 marka Exp $ */
|
||||
/* $Id: named.conf,v 1.5 2011/12/22 07:32:40 each Exp $ */
|
||||
|
||||
// NS3
|
||||
|
||||
@@ -70,3 +70,11 @@ zone "dynamic" {
|
||||
allow-update { any; };
|
||||
file "dynamic.db";
|
||||
};
|
||||
|
||||
zone "updated" {
|
||||
type master;
|
||||
inline-signing yes;
|
||||
auto-dnssec maintain;
|
||||
allow-update { none; };
|
||||
file "updated.db";
|
||||
};
|
||||
|
@@ -14,7 +14,7 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: sign.sh,v 1.4 2011/10/26 20:56:45 marka Exp $
|
||||
# $Id: sign.sh,v 1.5 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -48,3 +48,12 @@ rm -f K${zone}.+*+*.private
|
||||
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
|
||||
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
|
||||
$DSFROMKEY -T 1200 $keyname >> ../ns1/root.db
|
||||
|
||||
zone=updated
|
||||
rm -f K${zone}.+*+*.key
|
||||
rm -f K${zone}.+*+*.private
|
||||
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
|
||||
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
|
||||
$DSFROMKEY -T 1200 $keyname >> ../ns1/root.db
|
||||
$SIGNER -S -O raw -L 2000042407 -o ${zone} ${zone}.db > /dev/null 2>&1
|
||||
cp master2.db.in updated.db
|
||||
|
@@ -12,7 +12,7 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: setup.sh,v 1.7 2011/12/09 22:09:25 marka Exp $
|
||||
# $Id: setup.sh,v 1.8 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
sh clean.sh
|
||||
|
||||
@@ -45,6 +45,7 @@ rm -f ns3/dynamic.db.signed.jnl
|
||||
|
||||
cp ns3/master.db.in ns3/master.db
|
||||
cp ns3/master.db.in ns3/dynamic.db
|
||||
cp ns3/master.db.in ns3/updated.db
|
||||
|
||||
touch ns4/trusted.conf
|
||||
cp ns4/noixfr.db.in ns4/noixfr.db
|
||||
|
@@ -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.10 2011/12/19 23:46:13 marka Exp $
|
||||
# $Id: tests.sh,v 1.11 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -353,6 +353,27 @@ do
|
||||
done
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo "I:checking master zone that was updated while offline is correct ($n)"
|
||||
ret=0
|
||||
serial=`$DIG $DIGOPTS +short @10.53.0.3 -p 5300 updated SOA | awk '{print $3}'`
|
||||
# serial should have changed
|
||||
[ "$serial" = "2000042407" ] && ret=1
|
||||
# e.updated should exist and should be signed
|
||||
$DIG $DIGOPTS @10.53.0.3 -p 5300 e.updated A > dig.out.ns3.test$n
|
||||
grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
|
||||
grep "ANSWER: 2," dig.out.ns3.test$n > /dev/null || ret=1
|
||||
# updated.db.signed.jnl should exist, should have the source serial
|
||||
# of master2.db, and should show a minimal diff: no more than 8 added
|
||||
# records (SOA/RRSIG, 2 x NSEC/RRSIG, A/RRSIG), and 4 removed records
|
||||
# (SOA/RRSIG, NSEC/RRSIG).
|
||||
serial=`$JOURNALPRINT ns3/updated.db.signed.jnl | head -1 | awk '{print $4}'`
|
||||
[ "$serial" = "2000042408" ] || ret=1
|
||||
diffsize=`$JOURNALPRINT ns3/updated.db.signed.jnl | wc -l`
|
||||
[ "$diffsize" -le 13 ] || ret=1
|
||||
if [ $ret != 0 ]; then echo "I:failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo "I:checking adding of record to unsigned master using UPDATE ($n)"
|
||||
ret=0
|
||||
|
@@ -14,11 +14,12 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: clean.sh,v 1.9 2011/12/08 16:07:20 each Exp $
|
||||
# $Id: clean.sh,v 1.10 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
rm -f named-compilezone
|
||||
rm -f ns1/example.db.raw*
|
||||
rm -f ns1/example.db.compat
|
||||
rm -f ns1/example.db.serial.raw
|
||||
rm -f ns2/example.db
|
||||
rm -f dig.out.*
|
||||
rm -f */named.memstats
|
||||
|
@@ -12,7 +12,7 @@
|
||||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: compile.sh,v 1.8 2011/12/09 23:47:03 tbox Exp $
|
||||
# $Id: compile.sh,v 1.9 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
../named-compilezone -D -F raw -o example.db.raw example \
|
||||
example.db > /dev/null 2>&1
|
||||
@@ -20,3 +20,5 @@
|
||||
example.db > /dev/null 2>&1
|
||||
../named-compilezone -D -F raw=0 -o example.db.compat example-compat \
|
||||
example.db > /dev/null 2>&1
|
||||
../named-compilezone -D -F raw -L 3333 -o example.db.serial.raw example \
|
||||
example.db > /dev/null 2>&1
|
||||
|
@@ -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.8 2011/12/08 16:07:20 each Exp $
|
||||
# $Id: tests.sh,v 1.9 2011/12/22 07:32:40 each Exp $
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
@@ -28,11 +28,24 @@ israw () {
|
||||
|
||||
rawversion () {
|
||||
perl -e '$input = <STDIN>;
|
||||
if (length($input) < 2) { print "not raw\n"; exit 0; };
|
||||
if (length($input) < 8) { print "not raw\n"; exit 0; };
|
||||
($style, $version) = unpack("NN", $input);
|
||||
print ($style == 2 ? "$version\n" : "not raw\n");' < $1
|
||||
}
|
||||
|
||||
sourceserial () {
|
||||
perl -e '$input = <STDIN>;
|
||||
if (length($input) < 20) { print "UNSET\n"; exit; };
|
||||
($format, $version, $dumptime, $flags, $sourceserial) =
|
||||
unpack("NNNNN", $input);
|
||||
if ($format != 2 || $version < 1) { print "UNSET\n"; exit; };
|
||||
if ($flags & 02) {
|
||||
print $sourceserial . "\n";
|
||||
} else {
|
||||
print "UNSET\n";
|
||||
}' < $1
|
||||
}
|
||||
|
||||
DIGOPTS="+tcp +noauth +noadd +nosea +nostat +noquest +nocomm +nocmd"
|
||||
|
||||
status=0
|
||||
@@ -62,6 +75,13 @@ israw ns1/example.db.compat || ret=1
|
||||
[ $ret -eq 0 ] || echo "I:failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:checking source serial numbers"
|
||||
ret=0
|
||||
[ "`sourceserial ns1/example.db.raw`" = "UNSET" ] || ret=1
|
||||
[ "`sourceserial ns1/example.db.serial.raw`" = "3333" ] || ret=1
|
||||
[ $ret -eq 0 ] || echo "I:failed"
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo "I:waiting for transfers to complete"
|
||||
sleep 1
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: journal.h,v 1.42 2011/12/05 23:46:35 tbox Exp $ */
|
||||
/* $Id: journal.h,v 1.43 2011/12/22 07:32:41 each Exp $ */
|
||||
|
||||
#ifndef DNS_JOURNAL_H
|
||||
#define DNS_JOURNAL_H 1
|
||||
@@ -106,7 +106,7 @@ dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode,
|
||||
*
|
||||
* DNS_JOURNAL_CREATE open the journal for reading and writing and create
|
||||
* the journal if it does not exist.
|
||||
* DNS_JOURNAL_WRITE open the journal for readinge and writing.
|
||||
* DNS_JOURNAL_WRITE open the journal for reading and writing.
|
||||
* DNS_JOURNAL_READ open the journal for reading only.
|
||||
*/
|
||||
|
||||
@@ -293,12 +293,15 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
|
||||
* exists and is non-empty 'serial' must exist in the journal.
|
||||
*/
|
||||
|
||||
isc_uint32_t
|
||||
dns_journal_get_sourceserial(dns_journal_t *j);
|
||||
isc_boolean_t
|
||||
dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial);
|
||||
void
|
||||
dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial);
|
||||
/*%<
|
||||
* Get and set source serial.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_TRUE if sourceserial has previously been set.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.h,v 1.198 2011/12/08 16:07:21 each Exp $ */
|
||||
/* $Id: zone.h,v 1.199 2011/12/22 07:32:41 each Exp $ */
|
||||
|
||||
#ifndef DNS_ZONE_H
|
||||
#define DNS_ZONE_H 1
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <isc/lang.h>
|
||||
#include <isc/rwlock.h>
|
||||
|
||||
#include <dns/master.h>
|
||||
#include <dns/masterdump.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
@@ -2029,6 +2030,13 @@ dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags,
|
||||
* Requires:
|
||||
* \li 'zone' to be valid.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header);
|
||||
/*%
|
||||
* Set the data to be included in the header when the zone is dumped in
|
||||
* binary format.
|
||||
*/
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_ZONE_H */
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: journal.c,v 1.119 2011/12/05 23:46:35 tbox Exp $ */
|
||||
/* $Id: journal.c,v 1.120 2011/12/22 07:32:41 each Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -111,6 +111,8 @@ static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config */
|
||||
if (result != ISC_R_SUCCESS) goto failure; \
|
||||
} while (0)
|
||||
|
||||
#define JOURNAL_SERIALSET 0x01U
|
||||
|
||||
static isc_result_t index_to_disk(dns_journal_t *);
|
||||
|
||||
static inline isc_uint32_t
|
||||
@@ -215,6 +217,7 @@ typedef union {
|
||||
unsigned char index_size[4];
|
||||
/*% Source serial number. */
|
||||
unsigned char sourceserial[4];
|
||||
unsigned char flags;
|
||||
} h;
|
||||
/* Pad the header to a fixed size. */
|
||||
unsigned char pad[JOURNAL_HEADER_SIZE];
|
||||
@@ -255,6 +258,7 @@ typedef struct {
|
||||
journal_pos_t end;
|
||||
isc_uint32_t index_size;
|
||||
isc_uint32_t sourceserial;
|
||||
isc_boolean_t serialset;
|
||||
} journal_header_t;
|
||||
|
||||
/*%
|
||||
@@ -287,7 +291,7 @@ typedef struct {
|
||||
*/
|
||||
|
||||
static journal_header_t
|
||||
initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0, 0 };
|
||||
initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0, 0, 0 };
|
||||
|
||||
#define JOURNAL_EMPTY(h) ((h)->begin.offset == (h)->end.offset)
|
||||
|
||||
@@ -358,10 +362,13 @@ journal_header_decode(journal_rawheader_t *raw, journal_header_t *cooked) {
|
||||
journal_pos_decode(&raw->h.end, &cooked->end);
|
||||
cooked->index_size = decode_uint32(raw->h.index_size);
|
||||
cooked->sourceserial = decode_uint32(raw->h.sourceserial);
|
||||
cooked->serialset = ISC_TF(raw->h.flags & JOURNAL_SERIALSET);
|
||||
}
|
||||
|
||||
static void
|
||||
journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) {
|
||||
unsigned char flags = 0;
|
||||
|
||||
INSIST(sizeof(cooked->format) == sizeof(raw->h.format));
|
||||
memset(raw->pad, 0, sizeof(raw->pad));
|
||||
memcpy(raw->h.format, cooked->format, sizeof(raw->h.format));
|
||||
@@ -369,6 +376,9 @@ journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) {
|
||||
journal_pos_encode(&raw->h.end, &cooked->end);
|
||||
encode_uint32(cooked->index_size, raw->h.index_size);
|
||||
encode_uint32(cooked->sourceserial, raw->h.sourceserial);
|
||||
if (cooked->serialset)
|
||||
flags |= JOURNAL_SERIALSET;
|
||||
raw->h.flags = flags;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -546,7 +556,8 @@ journal_file_create(isc_mem_t *mctx, const char *filename) {
|
||||
|
||||
static isc_result_t
|
||||
journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write,
|
||||
isc_boolean_t create, dns_journal_t **journalp) {
|
||||
isc_boolean_t create, dns_journal_t **journalp)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
isc_result_t result;
|
||||
journal_rawheader_t rawheader;
|
||||
@@ -674,7 +685,8 @@ journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write,
|
||||
|
||||
isc_result_t
|
||||
dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode,
|
||||
dns_journal_t **journalp) {
|
||||
dns_journal_t **journalp)
|
||||
{
|
||||
isc_result_t result;
|
||||
int namelen;
|
||||
char backup[1024];
|
||||
@@ -1164,10 +1176,8 @@ dns_journal_commit(dns_journal_t *j) {
|
||||
/*
|
||||
* Update the journal header.
|
||||
*/
|
||||
if (JOURNAL_EMPTY(&j->header)) {
|
||||
if (JOURNAL_EMPTY(&j->header))
|
||||
j->header.begin = j->x.pos[0];
|
||||
j->header.sourceserial = j->header.begin.serial;
|
||||
}
|
||||
j->header.end = j->x.pos[1];
|
||||
journal_header_encode(&j->header, &rawheader);
|
||||
CHECK(journal_seek(j, 0));
|
||||
@@ -1399,7 +1409,7 @@ dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
|
||||
REQUIRE(filename != NULL);
|
||||
|
||||
j = NULL;
|
||||
result = dns_journal_open(mctx, filename, ISC_FALSE, &j);
|
||||
result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
isc_log_write(JOURNAL_DEBUG_LOGARGS(3),
|
||||
"no journal file, but that's OK");
|
||||
@@ -1432,7 +1442,7 @@ dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) {
|
||||
REQUIRE(filename != NULL);
|
||||
|
||||
j = NULL;
|
||||
result = dns_journal_open(mctx, filename, ISC_FALSE, &j);
|
||||
result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file");
|
||||
return (DNS_R_NOJOURNAL);
|
||||
@@ -1445,7 +1455,8 @@ dns_journal_print(isc_mem_t *mctx, const char *filename, FILE *file) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
fprintf(file, "Source serial = %u\n", j->header.sourceserial);
|
||||
if (j->header.serialset)
|
||||
fprintf(file, "Source serial = %u\n", j->header.sourceserial);
|
||||
dns_diff_init(j->mctx, &diff);
|
||||
|
||||
/*
|
||||
@@ -1546,13 +1557,19 @@ dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial) {
|
||||
j->state == JOURNAL_STATE_TRANSACTION);
|
||||
|
||||
j->header.sourceserial = sourceserial;
|
||||
j->header.serialset = ISC_TRUE;
|
||||
if (j->state == JOURNAL_STATE_WRITE)
|
||||
j->state = JOURNAL_STATE_INLINE;
|
||||
}
|
||||
|
||||
isc_uint32_t
|
||||
dns_journal_get_sourceserial(dns_journal_t *j) {
|
||||
return (j->header.sourceserial);
|
||||
isc_boolean_t
|
||||
dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial) {
|
||||
REQUIRE(sourceserial != NULL);
|
||||
|
||||
if (!j->header.serialset)
|
||||
return (ISC_FALSE);
|
||||
*sourceserial = j->header.sourceserial;
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
@@ -2043,8 +2060,8 @@ dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera,
|
||||
dns_journal_t *journal = NULL;
|
||||
|
||||
if (filename != NULL) {
|
||||
result = dns_journal_open(diff->mctx, filename, ISC_TRUE,
|
||||
&journal);
|
||||
result = dns_journal_open(diff->mctx, filename,
|
||||
DNS_JOURNAL_CREATE, &journal);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
@@ -2213,6 +2230,7 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
|
||||
new->header.end.serial = j->header.end.serial;
|
||||
new->header.end.offset = indexend + copy_length;
|
||||
new->header.sourceserial = j->header.sourceserial;
|
||||
new->header.serialset = j->header.serialset;
|
||||
|
||||
/*
|
||||
* Update the journal header.
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: xfrin.c,v 1.171 2011/08/30 05:16:14 marka Exp $ */
|
||||
/* $Id: xfrin.c,v 1.172 2011/12/22 07:32:41 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -360,7 +360,7 @@ ixfr_init(dns_xfrin_ctx_t *xfr) {
|
||||
journalfile = dns_zone_getjournal(xfr->zone);
|
||||
if (journalfile != NULL)
|
||||
CHECK(dns_journal_open(xfr->mctx, journalfile,
|
||||
ISC_TRUE, &xfr->ixfr.journal));
|
||||
DNS_JOURNAL_CREATE, &xfr->ixfr.journal));
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
failure:
|
||||
|
497
lib/dns/zone.c
497
lib/dns/zone.c
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.c,v 1.657 2011/12/20 00:26:52 marka Exp $ */
|
||||
/* $Id: zone.c,v 1.658 2011/12/22 07:32:41 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -364,8 +364,8 @@ struct dns_zone {
|
||||
dns_zone_t *raw;
|
||||
dns_zone_t *secure;
|
||||
|
||||
isc_boolean_t rawserialset;
|
||||
isc_uint32_t rawserial;
|
||||
isc_boolean_t sourceserialset;
|
||||
isc_uint32_t sourceserial;
|
||||
};
|
||||
|
||||
#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
|
||||
@@ -655,6 +655,7 @@ static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
|
||||
static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
|
||||
static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
|
||||
static isc_result_t zone_send_secureserial(dns_zone_t *zone,
|
||||
isc_boolean_t locked,
|
||||
isc_uint32_t serial);
|
||||
|
||||
#if 0
|
||||
@@ -712,7 +713,8 @@ static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
|
||||
static void zone_rekey(dns_zone_t *zone);
|
||||
static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
|
||||
dst_key_t **keys, unsigned int nkeys);
|
||||
static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
|
||||
static isc_result_t zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked,
|
||||
dns_db_t *db);
|
||||
|
||||
#define ENTER zone_debuglog(zone, me, 1, "enter")
|
||||
|
||||
@@ -899,8 +901,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
|
||||
ISC_LIST_INIT(zone->forwards);
|
||||
zone->raw = NULL;
|
||||
zone->secure = NULL;
|
||||
zone->rawserial = 0;
|
||||
zone->rawserialset = ISC_FALSE;
|
||||
zone->sourceserial = 0;
|
||||
zone->sourceserialset = ISC_FALSE;
|
||||
|
||||
zone->magic = ZONE_MAGIC;
|
||||
|
||||
@@ -1038,6 +1040,28 @@ zone_free(dns_zone_t *zone) {
|
||||
isc_mem_detach(&mctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns ISC_TRUE iff this the signed side of an inline-signing zone
|
||||
*/
|
||||
static inline isc_boolean_t
|
||||
inline_secure(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
if (zone->raw != NULL)
|
||||
return (ISC_TRUE);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns ISC_TRUE iff this the unsigned side of an inline-signing zone
|
||||
*/
|
||||
static inline isc_boolean_t
|
||||
inline_raw(dns_zone_t *zone) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
if (zone->secure != NULL)
|
||||
return (ISC_TRUE);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Single shot.
|
||||
*/
|
||||
@@ -1066,7 +1090,7 @@ dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
|
||||
zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
|
||||
zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
|
||||
|
||||
if (zone->raw != NULL)
|
||||
if (inline_secure(zone))
|
||||
dns_zone_setclass(zone->raw, rdclass);
|
||||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
@@ -1259,7 +1283,7 @@ dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
|
||||
zone_viewname_tostr(zone, namebuf, sizeof namebuf);
|
||||
zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
|
||||
|
||||
if (zone->raw != NULL)
|
||||
if (inline_secure(zone))
|
||||
dns_zone_setview(zone->raw, view);
|
||||
|
||||
UNLOCK_ZONE(zone);
|
||||
@@ -1298,7 +1322,7 @@ dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
|
||||
zone_name_tostr(zone, namebuf, sizeof namebuf);
|
||||
zone->strname = isc_mem_strdup(zone->mctx, namebuf);
|
||||
|
||||
if (result == ISC_R_SUCCESS && zone->raw != NULL)
|
||||
if (result == ISC_R_SUCCESS && inline_secure(zone))
|
||||
result = dns_zone_setorigin(zone->raw, origin);
|
||||
UNLOCK_ZONE(zone);
|
||||
return (result);
|
||||
@@ -1470,7 +1494,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
|
||||
LOCK_ZONE(zone);
|
||||
TIME_NOW(&now);
|
||||
|
||||
if (zone->raw != NULL) {
|
||||
if (inline_secure(zone)) {
|
||||
result = zone_load(zone->raw, flags);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
@@ -1723,7 +1747,11 @@ isc_result_t
|
||||
dns_zone_loadandthaw(dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
|
||||
result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
|
||||
if (inline_raw(zone))
|
||||
result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW);
|
||||
else
|
||||
result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
|
||||
|
||||
switch (result) {
|
||||
case DNS_R_CONTINUE:
|
||||
/* Deferred thaw. */
|
||||
@@ -1846,7 +1874,7 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
|
||||
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||
dns_db_currentversion(zone->db, &version);
|
||||
dns_master_initrawheader(&rawdata);
|
||||
if (zone->raw != NULL)
|
||||
if (inline_secure(zone))
|
||||
get_raw_serial(zone->raw, &rawdata);
|
||||
result = dns_master_dumpinc3(zone->mctx, zone->db, version,
|
||||
&dns_master_style_default,
|
||||
@@ -1864,24 +1892,28 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
|
||||
dump_done(zone, result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the raw serial number for inline-signing zones.
|
||||
* (XXX: Other information from the header will be used
|
||||
* for other purposes in the future, but for now this is
|
||||
* all we're interested in.)
|
||||
*/
|
||||
static void
|
||||
zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
|
||||
if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
|
||||
return;
|
||||
|
||||
zone->sourceserial = header->sourceserial;
|
||||
zone->sourceserialset = ISC_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
|
||||
if (zone == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Save the raw serial number for inline-signing zones.
|
||||
* (XXX: Other information from the header will be used
|
||||
* for other purposes in the future, but for now this is
|
||||
* all we're interested in.)
|
||||
*/
|
||||
if (zone->raw != NULL ||
|
||||
((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0))
|
||||
return;
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
zone->rawserial = header->sourceserial;
|
||||
zone->rawserialset = ISC_TRUE;
|
||||
zone_setrawdata(zone, header);
|
||||
UNLOCK_ZONE(zone);
|
||||
}
|
||||
|
||||
@@ -3289,30 +3321,32 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
|
||||
const char *journalfile;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_journal_t *journal = NULL;
|
||||
unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
|
||||
|
||||
ENTER;
|
||||
journalfile = dns_zone_getjournal(zone);
|
||||
if (journalfile != NULL) {
|
||||
result = dns_journal_open(zone->mctx, journalfile,
|
||||
DNS_JOURNAL_CREATE, &journal);
|
||||
result = dns_journal_open(zone->mctx, journalfile, mode,
|
||||
&journal);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"%s:dns_journal_open -> %s\n",
|
||||
caller, dns_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (sourceserial != NULL)
|
||||
dns_journal_set_sourceserial(journal, *sourceserial);
|
||||
|
||||
result = dns_journal_write_transaction(journal, diff);
|
||||
dns_journal_destroy(&journal);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"%s:dns_journal_write_transaction -> %s\n",
|
||||
caller, dns_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
dns_journal_destroy(&journal);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -3515,12 +3549,34 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_send_securedb(dns_zone_t *zone) {
|
||||
maybe_send_secure(dns_zone_t *zone) {
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* We've finished loading, or else failed to load, an inline-signing
|
||||
* 'secure' zone. We now need information about the status of the
|
||||
* 'raw' zone. If we failed to load, then we need it to send a
|
||||
* copy of its database; if we succeeded, we need it to send its
|
||||
* serial number so that we can sync with it. If it has not yet
|
||||
* loaded, we set a flag so that it will send the necessary
|
||||
* information when it has finished loading.
|
||||
*/
|
||||
LOCK_ZONE(zone->raw);
|
||||
if (zone->raw->db != NULL)
|
||||
zone_send_securedb(zone->raw, zone->raw->db);
|
||||
else
|
||||
if (zone->raw->db != NULL) {
|
||||
if (zone->db != NULL) {
|
||||
isc_uint32_t serial;
|
||||
result = zone_get_from_db(zone->raw, zone->raw->db,
|
||||
NULL, NULL, &serial, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
zone_send_secureserial(zone->raw, ISC_TRUE,
|
||||
serial);
|
||||
} else
|
||||
zone_send_securedb(zone->raw, ISC_TRUE, zone->raw->db);
|
||||
|
||||
} else
|
||||
DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
|
||||
|
||||
UNLOCK_ZONE(zone->raw);
|
||||
}
|
||||
|
||||
@@ -3538,6 +3594,9 @@ zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
|
||||
return (answer);
|
||||
}
|
||||
|
||||
/*
|
||||
* The zone is presumed to be locked.
|
||||
*/
|
||||
static isc_result_t
|
||||
zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
isc_result_t result)
|
||||
@@ -3574,10 +3633,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
zone->masterfile,
|
||||
dns_result_totext(result));
|
||||
} else if (zone->type == dns_zone_master &&
|
||||
zone->raw != NULL && result == ISC_R_FILENOTFOUND) {
|
||||
inline_secure(zone) && result == ISC_R_FILENOTFOUND)
|
||||
{
|
||||
dns_zone_log(zone, ISC_LOG_DEBUG(1),
|
||||
"no master file, requesting db");
|
||||
maybe_send_securedb(zone);
|
||||
maybe_send_secure(zone);
|
||||
} else {
|
||||
int level = ISC_LOG_ERROR;
|
||||
if (zone->type == dns_zone_key &&
|
||||
@@ -3677,7 +3737,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
dns_journal_t *journal = NULL;
|
||||
|
||||
result = dns_journal_open(zone->mctx, zone->journal,
|
||||
ISC_FALSE, &journal);
|
||||
DNS_JOURNAL_READ, &journal);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
jserial = dns_journal_last_serial(journal);
|
||||
dns_journal_destroy(&journal);
|
||||
@@ -3843,6 +3903,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
&zone->expiretime) >= 0)
|
||||
zone->refreshtime = now;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case dns_zone_key:
|
||||
@@ -3895,10 +3956,23 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
|
||||
DNS_ZONE_SETFLAG(zone,
|
||||
DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
|
||||
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
|
||||
zone->secure != NULL)
|
||||
zone_send_securedb(zone, db);
|
||||
inline_raw(zone))
|
||||
{
|
||||
if (zone->secure->db == NULL)
|
||||
zone_send_securedb(zone, ISC_FALSE, db);
|
||||
else
|
||||
zone_send_secureserial(zone, ISC_FALSE, serial);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finished loading inline-signing zone; need to get status
|
||||
* from the raw side now.
|
||||
*/
|
||||
if (zone->type == dns_zone_master && inline_secure(zone))
|
||||
maybe_send_secure(zone);
|
||||
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
if (needdump) {
|
||||
@@ -8491,7 +8565,7 @@ dns_zone_markdirty(dns_zone_t *zone) {
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
if (zone->type == dns_zone_master) {
|
||||
if (zone->secure != NULL) {
|
||||
if (inline_raw(zone)) {
|
||||
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||
if (zone->db != NULL) {
|
||||
result = zone_get_from_db(zone, zone->db, NULL,
|
||||
@@ -8502,7 +8576,7 @@ dns_zone_markdirty(dns_zone_t *zone) {
|
||||
result = DNS_R_NOTLOADED;
|
||||
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
zone_send_secureserial(zone, serial);
|
||||
zone_send_secureserial(zone, ISC_FALSE, serial);
|
||||
}
|
||||
set_resigntime(zone); /* XXXMPA make separate call back */
|
||||
}
|
||||
@@ -8694,8 +8768,9 @@ dump_done(void *arg, isc_result_t result) {
|
||||
* If there is a secure version of this zone
|
||||
* use its serial if it is less than ours.
|
||||
*/
|
||||
if (tresult == ISC_R_SUCCESS &&
|
||||
zone->secure != NULL && zone->secure->db != NULL) {
|
||||
if (tresult == ISC_R_SUCCESS && inline_raw(zone) &&
|
||||
zone->secure->db != NULL)
|
||||
{
|
||||
isc_uint32_t sserial;
|
||||
isc_result_t mresult;
|
||||
|
||||
@@ -8816,7 +8891,7 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
|
||||
dns_masterrawheader_t rawdata;
|
||||
dns_db_currentversion(db, &version);
|
||||
dns_master_initrawheader(&rawdata);
|
||||
if (zone->raw != NULL)
|
||||
if (inline_secure(zone))
|
||||
get_raw_serial(zone->raw, &rawdata);
|
||||
result = dns_master_dump3(zone->mctx, db, version,
|
||||
&dns_master_style_default,
|
||||
@@ -8880,8 +8955,12 @@ dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
|
||||
dns_master_initrawheader(&rawdata);
|
||||
if (rawversion == 0)
|
||||
rawdata.flags |= DNS_MASTERRAW_COMPAT;
|
||||
if (zone->raw != NULL && rawversion > 0)
|
||||
else if (inline_secure(zone))
|
||||
get_raw_serial(zone->raw, &rawdata);
|
||||
else if (zone->sourceserialset) {
|
||||
rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
|
||||
rawdata.sourceserial = zone->sourceserial;
|
||||
}
|
||||
result = dns_master_dumptostream3(zone->mctx, db, version, style,
|
||||
format, &rawdata, fd);
|
||||
dns_db_closeversion(db, &version, ISC_FALSE);
|
||||
@@ -10984,11 +11063,11 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
|
||||
free_needed = exit_check(zone);
|
||||
if (zone->raw != NULL) {
|
||||
if (inline_secure(zone)) {
|
||||
raw = zone->raw;
|
||||
zone->raw = NULL;
|
||||
}
|
||||
if (zone->secure != NULL) {
|
||||
if (inline_raw(zone)) {
|
||||
secure = zone->secure;
|
||||
zone->secure = NULL;
|
||||
}
|
||||
@@ -11360,7 +11439,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
|
||||
* Notify messages are processed by the raw zone.
|
||||
*/
|
||||
LOCK_ZONE(zone);
|
||||
if (zone->raw != NULL) {
|
||||
if (inline_secure(zone)) {
|
||||
result = dns_zone_notifyreceive(zone->raw, from, msg);
|
||||
UNLOCK_ZONE(zone);
|
||||
return (result);
|
||||
@@ -11771,9 +11850,9 @@ zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
|
||||
isc_buffer_putstr(&buffer, "/");
|
||||
isc_buffer_putstr(&buffer, zone->view->name);
|
||||
}
|
||||
if (zone->raw != NULL && 9U < isc_buffer_availablelength(&buffer))
|
||||
if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
|
||||
isc_buffer_putstr(&buffer, " (signed)");
|
||||
if (zone->secure != NULL && 11U < isc_buffer_availablelength(&buffer))
|
||||
if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
|
||||
isc_buffer_putstr(&buffer, " (unsigned)");
|
||||
|
||||
buf[isc_buffer_usedlength(&buffer)] = '\0';
|
||||
@@ -12092,8 +12171,9 @@ notify_done(isc_task_t *task, isc_event_t *event) {
|
||||
dns_message_destroy(&message);
|
||||
}
|
||||
|
||||
struct secure_serial {
|
||||
struct secure_event {
|
||||
isc_event_t e;
|
||||
dns_db_t *db;
|
||||
isc_uint32_t serial;
|
||||
};
|
||||
|
||||
@@ -12103,89 +12183,55 @@ update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
|
||||
dns_zone_log(zone, level, "%s", message);
|
||||
}
|
||||
|
||||
static void
|
||||
receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
dns_journal_t *rjournal = NULL, *sjournal = NULL;
|
||||
isc_uint32_t start, end;
|
||||
dns_zone_t *zone;
|
||||
int n_soa = 0;
|
||||
dns_db_t *db = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_dbversion_t *newver = NULL, *oldver = NULL;
|
||||
isc_uint32_t oldserial, newserial;
|
||||
static isc_result_t
|
||||
sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
|
||||
isc_uint32_t start, isc_uint32_t end,
|
||||
dns_difftuple_t **soatuplep, dns_diff_t *diff)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_difftuple_t *tuple = NULL;
|
||||
dns_diffop_t op = DNS_DIFFOP_ADD;
|
||||
dns_diff_t diff;
|
||||
dns_difftuple_t *tuple = NULL, *soatuple = NULL;
|
||||
dns_update_log_t log = { update_log_cb, NULL };
|
||||
isc_time_t timenow;
|
||||
int n_soa = 0;
|
||||
|
||||
zone = event->ev_arg;
|
||||
end = ((struct secure_serial *)event)->serial;
|
||||
REQUIRE(soatuplep != NULL);
|
||||
|
||||
dns_diff_init(zone->mctx, &diff);
|
||||
if (start == end)
|
||||
return (DNS_R_UNCHANGED);
|
||||
|
||||
UNUSED(task);
|
||||
CHECK(dns_journal_open(zone->raw->mctx, zone->raw->journal,
|
||||
DNS_JOURNAL_WRITE, &rjournal));
|
||||
result = dns_journal_open(zone->raw->mctx, zone->journal,
|
||||
DNS_JOURNAL_READ, &sjournal);
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
|
||||
goto failure;
|
||||
|
||||
start = dns_journal_get_sourceserial(rjournal);
|
||||
if (sjournal != NULL) {
|
||||
isc_uint32_t serial = dns_journal_get_sourceserial(sjournal);
|
||||
/*
|
||||
* We write the secure journal first so if that exists
|
||||
* use its value provided it is greater that from the
|
||||
* raw journal.
|
||||
*/
|
||||
if (isc_serial_gt(serial, start))
|
||||
start = serial;
|
||||
dns_journal_destroy(&sjournal);
|
||||
}
|
||||
|
||||
if (start == end)
|
||||
goto failure;
|
||||
CHECK(dns_journal_iter_init(rjournal, start, end));
|
||||
|
||||
dns_db_attach(zone->db, &db);
|
||||
dns_db_currentversion(db, &oldver);
|
||||
CHECK(dns_db_newversion(db, &newver));
|
||||
|
||||
for (result = dns_journal_first_rr(rjournal);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_journal_next_rr(rjournal)) {
|
||||
dns_name_t *name = NULL;
|
||||
isc_uint32_t ttl;
|
||||
dns_rdata_t *rdata = NULL;
|
||||
dns_journal_current_rr(rjournal, &name, &ttl, &rdata);
|
||||
|
||||
if (rdata->type == dns_rdatatype_soa) {
|
||||
n_soa++;
|
||||
if (n_soa == 2) {
|
||||
/*
|
||||
* Save the lastest raw SOA record.
|
||||
*/
|
||||
if (soatuple != NULL)
|
||||
dns_difftuple_free(&soatuple);
|
||||
CHECK(dns_difftuple_create(diff.mctx,
|
||||
DNS_DIFFOP_ADD,
|
||||
name, ttl, rdata,
|
||||
&soatuple));
|
||||
}
|
||||
if (n_soa == 3)
|
||||
n_soa = 1;
|
||||
CHECK(dns_journal_iter_init(journal, start, end));
|
||||
for (result = dns_journal_first_rr(journal);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_journal_next_rr(journal))
|
||||
{
|
||||
dns_name_t *name = NULL;
|
||||
isc_uint32_t ttl;
|
||||
dns_rdata_t *rdata = NULL;
|
||||
dns_journal_current_rr(journal, &name, &ttl, &rdata);
|
||||
|
||||
if (rdata->type == dns_rdatatype_soa) {
|
||||
n_soa++;
|
||||
if (n_soa == 2) {
|
||||
/*
|
||||
* Save the latest raw SOA record.
|
||||
*/
|
||||
if (*soatuplep != NULL)
|
||||
dns_difftuple_free(soatuplep);
|
||||
CHECK(dns_difftuple_create(diff->mctx,
|
||||
DNS_DIFFOP_ADD,
|
||||
name, ttl, rdata,
|
||||
soatuplep));
|
||||
}
|
||||
if (n_soa == 3)
|
||||
n_soa = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Sanity. */
|
||||
/* Sanity. */
|
||||
if (n_soa == 0) {
|
||||
dns_zone_log(zone->raw, ISC_LOG_ERROR,
|
||||
"corrupt journal file: '%s'\n",
|
||||
zone->raw->journal);
|
||||
goto failure;
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
if (zone->privatetype != 0 &&
|
||||
@@ -12201,18 +12247,149 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
|
||||
|
||||
CHECK(dns_difftuple_create(diff.mctx, op, name, ttl, rdata,
|
||||
CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
|
||||
&tuple));
|
||||
dns_diff_appendminimal(&diff, &tuple);
|
||||
dns_diff_appendminimal(diff, &tuple);
|
||||
}
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
failure:
|
||||
return(result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb,
|
||||
dns_dbversion_t *secver, dns_diff_t *diff)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_db_t *rawdb = NULL;
|
||||
dns_dbversion_t *rawver = NULL;
|
||||
dns_difftuple_t *tuple = NULL, *next;
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(seczone));
|
||||
REQUIRE(inline_secure(seczone));
|
||||
|
||||
if (!seczone->sourceserialset)
|
||||
return (DNS_R_UNCHANGED);
|
||||
|
||||
dns_db_attach(seczone->raw->db, &rawdb);
|
||||
dns_db_currentversion(rawdb, &rawver);
|
||||
result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
|
||||
dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
|
||||
dns_db_detach(&rawdb);
|
||||
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
for (tuple = ISC_LIST_HEAD(diff->tuples);
|
||||
tuple != NULL;
|
||||
tuple = next)
|
||||
{
|
||||
next = ISC_LIST_NEXT(tuple, link);
|
||||
if (tuple->rdata.type == dns_rdatatype_nsec ||
|
||||
tuple->rdata.type == dns_rdatatype_rrsig ||
|
||||
tuple->rdata.type == dns_rdatatype_dnskey ||
|
||||
tuple->rdata.type == dns_rdatatype_nsec3 ||
|
||||
tuple->rdata.type == dns_rdatatype_soa ||
|
||||
tuple->rdata.type == dns_rdatatype_nsec3param)
|
||||
{
|
||||
ISC_LIST_UNLINK(diff->tuples, tuple, link);
|
||||
dns_difftuple_free(&tuple);
|
||||
}
|
||||
}
|
||||
|
||||
if (ISC_LIST_EMPTY(diff->tuples))
|
||||
return (DNS_R_UNCHANGED);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
dns_journal_t *rjournal = NULL;
|
||||
isc_uint32_t start, end;
|
||||
dns_zone_t *zone;
|
||||
dns_db_t *db = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_dbversion_t *newver = NULL, *oldver = NULL;
|
||||
dns_diff_t diff;
|
||||
dns_difftuple_t *tuple = NULL, *soatuple = NULL;
|
||||
dns_update_log_t log = { update_log_cb, NULL };
|
||||
isc_time_t timenow;
|
||||
|
||||
zone = event->ev_arg;
|
||||
end = ((struct secure_event *)event)->serial;
|
||||
isc_event_free(&event);
|
||||
|
||||
REQUIRE(inline_secure(zone));
|
||||
|
||||
dns_diff_init(zone->mctx, &diff);
|
||||
|
||||
UNUSED(task);
|
||||
|
||||
/*
|
||||
* We first attempt to sync the raw zone to the secure zone
|
||||
* by using the raw zone's journal, applying all the deltas
|
||||
* from the latest source-serial of the secure zone up to
|
||||
* the current serial number of the raw zone.
|
||||
*
|
||||
* If that fails, then we'll fall back to a direct comparison
|
||||
* between raw and secure zones.
|
||||
*/
|
||||
result = dns_journal_open(zone->raw->mctx, zone->raw->journal,
|
||||
DNS_JOURNAL_WRITE, &rjournal);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
else {
|
||||
dns_journal_t *sjournal = NULL;
|
||||
|
||||
result = dns_journal_open(zone->raw->mctx, zone->journal,
|
||||
DNS_JOURNAL_READ, &sjournal);
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
|
||||
goto failure;
|
||||
|
||||
if (!dns_journal_get_sourceserial(rjournal, &start)) {
|
||||
start = dns_journal_first_serial(rjournal);
|
||||
dns_journal_set_sourceserial(rjournal, start);
|
||||
}
|
||||
if (sjournal != NULL) {
|
||||
isc_uint32_t serial;
|
||||
/*
|
||||
* We read the secure journal first, if that exists
|
||||
* use its value provided it is greater that from the
|
||||
* raw journal.
|
||||
*/
|
||||
if (dns_journal_get_sourceserial(sjournal, &serial)) {
|
||||
if (isc_serial_gt(serial, start))
|
||||
start = serial;
|
||||
}
|
||||
dns_journal_destroy(&sjournal);
|
||||
}
|
||||
}
|
||||
|
||||
dns_db_attach(zone->db, &db);
|
||||
dns_db_currentversion(db, &oldver);
|
||||
CHECK(dns_db_newversion(db, &newver));
|
||||
|
||||
/*
|
||||
* Try to apply diffs from the raw zone's journal to the secure
|
||||
* zone. If that fails, we recover by syncing up the databases
|
||||
* directly.
|
||||
*/
|
||||
result = sync_secure_journal(zone, rjournal, start, end,
|
||||
&soatuple, &diff);
|
||||
if (result == DNS_R_UNCHANGED)
|
||||
goto failure;
|
||||
else if (result != ISC_R_SUCCESS) {
|
||||
CHECK(sync_secure_db(zone, db, oldver, &diff));
|
||||
}
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
CHECK(result);
|
||||
|
||||
CHECK(dns_diff_apply(&diff, db, newver));
|
||||
|
||||
if (soatuple != NULL) {
|
||||
isc_uint32_t desired;
|
||||
isc_uint32_t oldserial, newserial, desired;
|
||||
|
||||
CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
|
||||
DNS_DIFFOP_DEL, &tuple));
|
||||
@@ -12243,8 +12420,8 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
||||
LOCK_ZONE(zone);
|
||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
|
||||
|
||||
zone->rawserial = start;
|
||||
zone->rawserialset = ISC_TRUE;
|
||||
zone->sourceserial = end;
|
||||
zone->sourceserialset = ISC_TRUE;
|
||||
zone_needdump(zone, DNS_DUMP_DELAY);
|
||||
|
||||
TIME_NOW(&timenow);
|
||||
@@ -12256,6 +12433,9 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
||||
dns_db_closeversion(db, &newver, ISC_TRUE);
|
||||
|
||||
failure:
|
||||
if (result != ISC_R_SUCCESS)
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
|
||||
dns_result_totext(result));
|
||||
if (tuple != NULL)
|
||||
dns_difftuple_free(&tuple);
|
||||
if (soatuple != NULL)
|
||||
@@ -12271,33 +12451,33 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
if (rjournal != NULL)
|
||||
dns_journal_destroy(&rjournal);
|
||||
if (sjournal != NULL)
|
||||
dns_journal_destroy(&sjournal);
|
||||
dns_diff_clear(&diff);
|
||||
isc_event_free(&event);
|
||||
dns_zone_idetach(&zone);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
zone_send_secureserial(dns_zone_t *zone, isc_uint32_t serial) {
|
||||
zone_send_secureserial(dns_zone_t *zone, isc_boolean_t locked,
|
||||
isc_uint32_t serial)
|
||||
{
|
||||
isc_event_t *e;
|
||||
dns_zone_t *dummy = NULL;
|
||||
|
||||
e = isc_event_allocate(zone->secure->mctx, zone,
|
||||
DNS_EVENT_ZONESECURESERIAL,
|
||||
receive_secure_serial, zone->secure,
|
||||
sizeof(struct secure_serial));
|
||||
sizeof(struct secure_event));
|
||||
if (e == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
((struct secure_serial *)e)->serial = serial;
|
||||
|
||||
((struct secure_event *)e)->serial = serial;
|
||||
if (locked)
|
||||
zone_iattach(zone->secure, &dummy);
|
||||
else
|
||||
dns_zone_iattach(zone->secure, &dummy);
|
||||
isc_task_send(zone->secure->task, &e);
|
||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
struct secure_db {
|
||||
isc_event_t e;
|
||||
dns_db_t *db;
|
||||
};
|
||||
|
||||
static void
|
||||
receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
@@ -12315,7 +12495,11 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
||||
UNUSED(task);
|
||||
|
||||
zone = event->ev_arg;
|
||||
rawdb = ((struct secure_db *)event)->db;
|
||||
rawdb = ((struct secure_event *)event)->db;
|
||||
isc_event_free(&event);
|
||||
|
||||
REQUIRE(inline_secure(zone));
|
||||
|
||||
dns_fixedname_init(&fname);
|
||||
name = dns_fixedname_name(&fname);
|
||||
dns_rdataset_init(&rdataset);
|
||||
@@ -12400,22 +12584,27 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
||||
dns_db_detach(&rawdb);
|
||||
if (dbiterator != NULL)
|
||||
dns_dbiterator_destroy(&dbiterator);
|
||||
isc_event_free(&event);
|
||||
dns_zone_idetach(&zone);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
|
||||
zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, dns_db_t *db) {
|
||||
isc_event_t *e;
|
||||
dns_db_t *dummy = NULL;
|
||||
dns_zone_t *secure = NULL;
|
||||
|
||||
e = isc_event_allocate(zone->secure->mctx, zone,
|
||||
DNS_EVENT_ZONESECUREDB,
|
||||
receive_secure_db, zone->secure,
|
||||
sizeof(struct secure_db));
|
||||
sizeof(struct secure_event));
|
||||
if (e == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
dns_db_attach(db, &dummy);
|
||||
((struct secure_db *)e)->db = dummy;
|
||||
((struct secure_event *)e)->db = dummy;
|
||||
if (locked)
|
||||
zone_iattach(zone->secure, &secure);
|
||||
else
|
||||
dns_zone_iattach(zone->secure, &secure);
|
||||
|
||||
isc_task_send(zone->secure->task, &e);
|
||||
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
|
||||
@@ -12483,7 +12672,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
|
||||
*/
|
||||
if (zone->db != NULL && zone->journal != NULL &&
|
||||
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
|
||||
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
|
||||
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
|
||||
{
|
||||
isc_uint32_t serial, oldserial;
|
||||
|
||||
dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
|
||||
@@ -12542,8 +12732,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (zone->type == dns_zone_master && zone->secure != NULL)
|
||||
zone_send_secureserial(zone, serial);
|
||||
if (zone->type == dns_zone_master && inline_raw(zone))
|
||||
zone_send_secureserial(zone, ISC_FALSE, serial);
|
||||
} else {
|
||||
if (dump && zone->masterfile != NULL) {
|
||||
/*
|
||||
@@ -12594,8 +12784,9 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
|
||||
zone->journal, strbuf);
|
||||
}
|
||||
}
|
||||
if (zone->secure != NULL)
|
||||
zone_send_securedb(zone, db);
|
||||
|
||||
if (inline_raw(zone))
|
||||
zone_send_securedb(zone, ISC_FALSE, db);
|
||||
}
|
||||
|
||||
dns_db_closeversion(db, &ver, ISC_FALSE);
|
||||
@@ -12747,8 +12938,8 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
|
||||
dns_zone_log(zone, ISC_LOG_INFO,
|
||||
"transferred serial %u%s",
|
||||
serial, buf);
|
||||
if (zone->secure != NULL)
|
||||
zone_send_secureserial(zone, serial);
|
||||
if (inline_raw(zone))
|
||||
zone_send_secureserial(zone, ISC_FALSE, serial);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user