summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorInternet Software Consortium, Inc <@isc.org>2012-01-18 10:11:16 -0700
committerInternet Software Consortium, Inc <@isc.org>2012-01-18 10:11:16 -0700
commitf8bb4eefd76094703b91acc987d8df0603639376 (patch)
treee2b41a79e5cee716e4c8b9c07c83910509e6ac2e /lib
parent8b08ed79737eaec2fd64fbecce719fc5d91c0f48 (diff)
downloadbind9-f8bb4eefd76094703b91acc987d8df0603639376.tar.gz
9.9.0rc1
Diffstat (limited to 'lib')
-rw-r--r--lib/bind9/api2
-rw-r--r--lib/bind9/check.c6
-rw-r--r--lib/dns/adb.c216
-rw-r--r--lib/dns/api4
-rw-r--r--lib/dns/callbacks.c6
-rw-r--r--lib/dns/dispatch.c6
-rw-r--r--lib/dns/dnssec.c13
-rw-r--r--lib/dns/ecdb.c18
-rw-r--r--lib/dns/include/dns/adb.h60
-rw-r--r--lib/dns/include/dns/callbacks.h12
-rw-r--r--lib/dns/include/dns/journal.h27
-rw-r--r--lib/dns/include/dns/master.h31
-rw-r--r--lib/dns/include/dns/masterdump.h39
-rw-r--r--lib/dns/include/dns/resolver.h5
-rw-r--r--lib/dns/include/dns/types.h6
-rw-r--r--lib/dns/include/dns/zone.h20
-rw-r--r--lib/dns/journal.c135
-rw-r--r--lib/dns/master.c66
-rw-r--r--lib/dns/masterdump.c83
-rw-r--r--lib/dns/rbtdb.c4
-rw-r--r--lib/dns/rdata.c5
-rw-r--r--lib/dns/rdata/in_1/wks_11.c53
-rw-r--r--lib/dns/rdataslab.c3
-rw-r--r--lib/dns/resolver.c184
-rw-r--r--lib/dns/sdlz.c6
-rw-r--r--lib/dns/tests/Makefile.in20
-rw-r--r--lib/dns/tests/dbdiff_test.c172
-rw-r--r--lib/dns/tests/dbiterator_test.c66
-rw-r--r--lib/dns/tests/dnstest.c27
-rw-r--r--lib/dns/tests/dnstest.h6
-rw-r--r--lib/dns/tests/master_test.c272
-rw-r--r--lib/dns/tests/mkraw.pl31
-rw-r--r--lib/dns/tests/testdata/diff/zone1.data20
-rw-r--r--lib/dns/tests/testdata/diff/zone2.data21
-rw-r--r--lib/dns/tests/testdata/diff/zone3.data19
-rw-r--r--lib/dns/tests/testdata/master/master1.data6
-rw-r--r--lib/dns/tests/testdata/master/master12.data.in1
-rw-r--r--lib/dns/tests/testdata/master/master13.data.in1
-rw-r--r--lib/dns/tests/testdata/master/master14.data.in1
-rw-r--r--lib/dns/win32/libdns.def12
-rw-r--r--lib/dns/xfrin.c4
-rw-r--r--lib/dns/zone.c616
-rw-r--r--lib/dns/zt.c18
-rw-r--r--lib/export/irs/include/Makefile.in6
-rw-r--r--lib/export/isc/include/Makefile.in6
-rw-r--r--lib/export/isc/nothreads/include/Makefile.in6
-rw-r--r--lib/export/isc/pthreads/include/Makefile.in6
-rw-r--r--lib/export/isc/unix/include/Makefile.in6
-rw-r--r--lib/export/isccfg/include/Makefile.in6
-rw-r--r--lib/isc/api2
-rw-r--r--lib/isc/include/isc/symtab.h12
-rw-r--r--lib/isc/symtab.c53
-rw-r--r--lib/isc/tests/Makefile.in10
-rw-r--r--lib/isc/tests/isctest.h3
-rw-r--r--lib/isc/tests/socket_test.c9
-rw-r--r--lib/isc/tests/symtab_test.c147
-rw-r--r--lib/isc/tests/task_test.c22
-rw-r--r--lib/isc/unix/errno2result.c11
-rw-r--r--lib/isc/unix/errno2result.h8
-rw-r--r--lib/isc/unix/socket.c77
-rw-r--r--lib/isc/unix/stdio.c8
-rw-r--r--lib/isc/win32/socket.c4
62 files changed, 1801 insertions, 924 deletions
diff --git a/lib/bind9/api b/lib/bind9/api
index 6404d993..2a59ac92 100644
--- a/lib/bind9/api
+++ b/lib/bind9/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 90
-LIBREVISION = 1
+LIBREVISION = 2
LIBAGE = 0
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index 0f8f2699..f95f72d9 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.138 2011-11-07 00:14:11 marka Exp $ */
+/* $Id: check.c,v 1.139 2011-11-30 04:27:17 each Exp $ */
/*! \file */
@@ -2149,7 +2149,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
* Check that all zone statements are syntactically correct and
* there are no duplicate zones.
*/
- tresult = isc_symtab_create(mctx, 100, freekey, mctx,
+ tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
ISC_FALSE, &symtab);
if (tresult != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY);
@@ -2213,7 +2213,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
* Check that all key statements are syntactically correct and
* there are no duplicate keys.
*/
- tresult = isc_symtab_create(mctx, 100, freekey, mctx,
+ tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
ISC_FALSE, &symtab);
if (tresult != ISC_R_SUCCESS)
return (ISC_R_NOMEMORY);
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index b6109ec7..5c5fe8b1 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.c,v 1.262 2011-10-28 04:57:34 marka Exp $ */
+/* $Id: adb.c,v 1.264 2011-12-05 17:10:51 each Exp $ */
/*! \file
*
@@ -34,7 +34,6 @@
#include <isc/netaddr.h>
#include <isc/random.h>
#include <isc/stats.h>
-#include <isc/stdio.h> /* temporary */
#include <isc/string.h> /* Required for HP/UX (and others?) */
#include <isc/task.h>
#include <isc/util.h>
@@ -66,24 +65,6 @@
#define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6')
#define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC)
-/***
- *** Constants for EDNS0 packets
- *** DNS_ADB_EDNS0_MAX_LEN - max udpsize for edns0, should come from
- *** named.conf
- *** DNS_ADB_EDNS0_MIN_LEN - min udpsize for edns0
- *** DNS_ADB_EDNS_RESET_TIME - after this period of time, drop count
- *** is set to 0 and EDNS may be tried at
- *** bigger size - surface to user?
- *** DNS_ADB_EDNS_MAX_DROP_COUNT - after this many times EDNS has been
- *** reduced, edns->fetch_flag set
- *** DNS_ADB_EDNS_MAX_DROP_TIME - after this time retry EDNS at larger size
- ***/
-#define DNS_ADB_EDNS0_MAX_LEN 4096
-#define DNS_ADB_EDNS0_MIN_LEN 512
-#define DNS_ADB_EDNS_RESET_TIME 300 /*make this user configurable?*/
-#define DNS_ADB_EDNS_MAX_DROP_COUNT 5 /*make this user configurable?*/
-#define DNS_ADB_EDNS_MAX_DROP_TIME 3600 /*make this user configurable?*/
-
/*!
* For type 3 negative cache entries, we will remember that the address is
* broken for this long. XXXMLG This is also used for actual addresses, too.
@@ -271,31 +252,6 @@ struct dns_adbentry {
* name.
*/
-
- unsigned int edns_big_size;
- unsigned int edns_last_size;
- unsigned int edns_fetch_flag;
- unsigned int edns_drop_count;
- isc_stdtime_t edns_drop_timestamp;
- isc_stdtime_t edns_expires_timestamp;
- isc_boolean_t edns_timer_set;
- /*%<
- * The above fields beginning with edns_* determine
- * past success with edns for this server.
- * edns_big_size - biggest successful size received (e.g., 512)
- * edns_last_size - last packet size received
- * edns_fetch_flag - current EDNS state for this server (one of
- * DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_EDNS512 or
- * 0 meaning use DNS_ADB_EDNS0_MAX_LEN)
- * edns_drop_count - keeps count of the number of times EDNS udpsize
- * was dropped - reset to 0 every
- * DNS_ADB_EDNS_RESET_TIME
- * edns_drop_timestamp - The time at which the first EDNS drop
- * in packet size was recorded
- *
- * See also dns_adb_drop/setednssize()
- */
-
ISC_LIST(dns_adblameinfo_t) lameinfo;
ISC_LINK(dns_adbentry_t) plink;
@@ -1791,13 +1747,6 @@ new_adbentry(dns_adb_t *adb) {
isc_random_get(&r);
e->srtt = (r & 0x1f) + 1;
e->expires = 0;
- e->edns_big_size = 0;
- e->edns_last_size = 0;
- e->edns_fetch_flag = 0;
- e->edns_drop_timestamp = 0;
- e->edns_drop_count = 0;
- e->edns_expires_timestamp = 0;
- e->edns_timer_set = isc_boolean_false;
ISC_LIST_INIT(e->lameinfo);
ISC_LINK_INIT(e, plink);
LOCK(&adb->entriescntlock);
@@ -3961,169 +3910,6 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
UNLOCK(&adb->entrylocks[bucket]);
}
-unsigned int
-dns_adb_getednsflag(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now)
-{
- int bucket = 0;
- int flag_to_use = 0; /* assume max by default */
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
-
- /*
- * The purpose of this function is to return
- * edns_fetch_flag, which effectively sets the udpsize for EDNS
- * or turns off EDNS (if NOEDNS0 has been recorded).
- *
- * Also, this function checks to see if the timer needs resetting.
- * ---> this part should really be done via a callback?
- */
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
-
- if((addr->entry->edns_timer_set) &&
- (now >= addr->entry->edns_expires_timestamp)) {
-
- /* Eventually, we may support more sizes */
- if((addr->entry->edns_big_size <= 512) &&
- (addr->entry->edns_big_size > 0))
- flag_to_use = DNS_FETCHOPT_EDNS512;
-
- addr->entry->edns_fetch_flag = flag_to_use;
- addr->entry->edns_expires_timestamp = 0;
- addr->entry->edns_timer_set = isc_boolean_false;
-
- }
-
- flag_to_use = addr->entry->edns_fetch_flag;
-
- UNLOCK(&adb->entrylocks[bucket]);
-
- return(flag_to_use);
-}
-
-void
-dns_adb_setednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int length)
-{
- int bucket = 0;
- unsigned int length_to_use;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
-
- /*
- * The purpose of this function is to record
- * the maximum sized udp response seen from the
- * instant server.
- */
-
- length_to_use = addr->entry->edns_big_size;
-
- if (length > DNS_ADB_EDNS0_MAX_LEN)
- length = DNS_ADB_EDNS0_MAX_LEN;
- if (length < DNS_ADB_EDNS0_MIN_LEN)
- length = DNS_ADB_EDNS0_MIN_LEN;
- if (length > length_to_use)
- length_to_use = length;
-
- addr->entry->edns_big_size = length_to_use;
-
- UNLOCK(&adb->entrylocks[bucket]);
-}
-
-void
-dns_adb_dropednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int length, isc_stdtime_t now)
-{
- isc_stdtime_t expires_ts_to_use;
- isc_boolean_t timer_setting_to_use;
- unsigned int length_to_use;
- unsigned int drop_counter_to_use;
- unsigned int drop_ts_to_use;
- unsigned int flag_to_use;
- int bucket = 0;
-
- REQUIRE(DNS_ADB_VALID(adb));
- REQUIRE(DNS_ADBADDRINFO_VALID(addr));
-
- if (length > DNS_ADB_EDNS0_MAX_LEN)
- length = DNS_ADB_EDNS0_MAX_LEN;
- if (length < DNS_ADB_EDNS0_MIN_LEN)
- length = DNS_ADB_EDNS0_MIN_LEN;
-
- bucket = addr->entry->lock_bucket;
- LOCK(&adb->entrylocks[bucket]);
-
- expires_ts_to_use = addr->entry->edns_expires_timestamp;
- timer_setting_to_use = addr->entry->edns_timer_set;
- length_to_use = addr->entry->edns_big_size;
- drop_ts_to_use = addr->entry->edns_drop_timestamp;
- flag_to_use = addr->entry->edns_fetch_flag;
-
- /*
- * This function keeps a count of the number of times
- * within DNS_ADB_EDNS_RESET_TIME that a particular server
- * has dropped the udpsize in order to communicate with the
- * server. If the number of times this occurs exceeds
- * DNS_ADB_EDNS_MAX_DROP_COUNT, then the udpsize is reduced
- * by way of edns_fetch_flag for DNS_ADB_EDNS_MAX_DROP_TIME,
- * after which the largest size is retried again.
- * NOTE: currently, only 4096 and 512 are supported sizes
- */
-
- if (length > length_to_use)
- length_to_use = length;
-
- if ((now - addr->entry->edns_drop_timestamp) >=
- DNS_ADB_EDNS_RESET_TIME) {
-
- drop_counter_to_use = 1;
- drop_ts_to_use = now;
- } else {
-
- drop_counter_to_use = addr->entry->edns_drop_count + 1;
-
- if (drop_counter_to_use >= DNS_ADB_EDNS_MAX_DROP_COUNT) {
- /*
- * At this point, we are dropping down the
- * udpsize because we've had too many misses
- * at larger sizes.
- */
- if (timer_setting_to_use == isc_boolean_false) {
- /*
- * if we haven't already set a timer,
- * do so now. After DNS_ADB_EDNS_MAX_DROP_TIME,
- * we'll go back to the largest size
- */
- expires_ts_to_use =
- now + DNS_ADB_EDNS_MAX_DROP_TIME;
- timer_setting_to_use = isc_boolean_true;
- }
-
- if (length == 0)
- flag_to_use = DNS_FETCHOPT_NOEDNS0;
- else /* eventually, more edns sizes here */
- flag_to_use = DNS_FETCHOPT_EDNS512;
-
- drop_ts_to_use = 0;
- drop_counter_to_use = 0;
- }
- }
-
- addr->entry->edns_drop_timestamp = drop_ts_to_use;
- addr->entry->edns_drop_count = drop_counter_to_use;
- addr->entry->edns_fetch_flag = flag_to_use;
- addr->entry->edns_expires_timestamp = expires_ts_to_use;
- addr->entry->edns_timer_set = timer_setting_to_use;
-
- UNLOCK(&adb->entrylocks[bucket]);
-}
-
void
dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int bits, unsigned int mask)
diff --git a/lib/dns/api b/lib/dns/api
index 580ddcfd..63ac0c79 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 91
+LIBINTERFACE = 92
LIBREVISION = 0
-LIBAGE = 1
+LIBAGE = 0
diff --git a/lib/dns/callbacks.c b/lib/dns/callbacks.c
index 474d4e2d..a4b46235 100644
--- a/lib/dns/callbacks.c
+++ b/lib/dns/callbacks.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: callbacks.c,v 1.17 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: callbacks.c,v 1.19 2011-12-09 23:47:05 tbox Exp $ */
/*! \file */
@@ -88,6 +88,8 @@ dns_rdatacallbacks_initcommon(dns_rdatacallbacks_t *callbacks) {
REQUIRE(callbacks != NULL);
callbacks->add = NULL;
+ callbacks->rawdata = NULL;
+ callbacks->zone = NULL;
callbacks->add_private = NULL;
callbacks->error_private = NULL;
callbacks->warn_private = NULL;
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index f9acc101..eea01b07 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.174 2011-07-28 23:47:58 tbox Exp $ */
+/* $Id: dispatch.c,v 1.175 2011-11-29 01:03:47 marka Exp $ */
/*! \file */
@@ -1810,6 +1810,10 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
result = isc_socket_dup(dup_socket, &sock);
if (result != ISC_R_SUCCESS)
return (result);
+
+ isc_socket_setname(sock, "dispatcher", NULL);
+ *sockp = sock;
+ return (ISC_R_SUCCESS);
} else {
result = isc_socket_create(mgr, isc_sockaddr_pf(local),
isc_sockettype_udp, &sock);
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index 3c568c73..27b9e65e 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -16,7 +16,7 @@
*/
/*
- * $Id: dnssec.c,v 1.125 2011-08-26 05:29:48 marka Exp $
+ * $Id: dnssec.c,v 1.126 2011-12-07 22:36:25 marka Exp $
*/
/*! \file */
@@ -1142,17 +1142,15 @@ dns_dnsseckey_destroy(isc_mem_t *mctx, dns_dnsseckey_t **dkp) {
}
static void
-get_hints(dns_dnsseckey_t *key) {
+get_hints(dns_dnsseckey_t *key, isc_stdtime_t now) {
isc_result_t result;
- isc_stdtime_t now, publish, active, revoke, inactive, delete;
+ isc_stdtime_t publish, active, revoke, inactive, delete;
isc_boolean_t pubset = ISC_FALSE, actset = ISC_FALSE;
isc_boolean_t revset = ISC_FALSE, inactset = ISC_FALSE;
isc_boolean_t delset = ISC_FALSE;
REQUIRE(key != NULL && key->key != NULL);
- isc_stdtime_get(&now);
-
result = dst_key_gettime(key->key, DST_TIME_PUBLISH, &publish);
if (result == ISC_R_SUCCESS)
pubset = ISC_TRUE;
@@ -1249,6 +1247,7 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
char namebuf[DNS_NAME_FORMATSIZE], *p;
isc_buffer_t b;
unsigned int len;
+ isc_stdtime_t now;
REQUIRE(keylist != NULL);
ISC_LIST_INIT(list);
@@ -1264,6 +1263,8 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
RETERR(isc_dir_open(&dir, directory));
dir_open = ISC_TRUE;
+ isc_stdtime_get(&now);
+
while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
if (dir.entry.name[0] == 'K' &&
dir.entry.length > len + 1 &&
@@ -1294,7 +1295,7 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
RETERR(dns_dnsseckey_create(mctx, &dstkey, &key));
key->source = dns_keysource_repository;
- get_hints(key);
+ get_hints(key, now);
if (key->legacy) {
dns_dnsseckey_destroy(mctx, &key);
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
index 1ad03feb..eb2910f0 100644
--- a/lib/dns/ecdb.c
+++ b/lib/dns/ecdb.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ecdb.c,v 1.9 2011-10-11 13:33:45 marka Exp $ */
+/* $Id: ecdb.c,v 1.10 2011-12-20 00:06:53 marka Exp $ */
#include "config.h"
@@ -37,10 +37,6 @@
#define ECDBNODE_MAGIC ISC_MAGIC('E', 'C', 'D', 'N')
#define VALID_ECDBNODE(ecdbn) ISC_MAGIC_VALID(ecdbn, ECDBNODE_MAGIC)
-#if DNS_RDATASET_FIXED
-#error "Fixed rdataset isn't supported in this implementation"
-#endif
-
/*%
* The 'ephemeral' cache DB (ecdb) implementation. An ecdb just provides
* temporary storage for ongoing name resolution with the common DB interfaces.
@@ -662,7 +658,11 @@ rdataset_first(dns_rdataset_t *rdataset) {
rdataset->private5 = NULL;
return (ISC_R_NOMORE);
}
+#if DNS_RDATASET_FIXED
+ raw += 2 + (4 * count);
+#else
raw += 2;
+#endif
/*
* The privateuint4 field is the number of rdata beyond the cursor
* position, so we decrement the total count by one before storing
@@ -688,7 +688,11 @@ rdataset_next(dns_rdataset_t *rdataset) {
rdataset->privateuint4 = count;
raw = rdataset->private5;
length = raw[0] * 256 + raw[1];
+#if DNS_RDATASET_FIXED
+ raw += length + 4;
+#else
raw += length + 2;
+#endif
rdataset->private5 = raw;
return (ISC_R_SUCCESS);
@@ -704,7 +708,11 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
REQUIRE(raw != NULL);
length = raw[0] * 256 + raw[1];
+#if DNS_RDATASET_FIXED
+ raw += 4;
+#else
raw += 2;
+#endif
if (rdataset->type == dns_rdatatype_rrsig) {
if (*raw & DNS_RDATASLAB_OFFLINE)
flags |= DNS_RDATA_OFFLINE;
diff --git a/lib/dns/include/dns/adb.h b/lib/dns/include/dns/adb.h
index 170fc846..9b15f102 100644
--- a/lib/dns/include/dns/adb.h
+++ b/lib/dns/include/dns/adb.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.h,v 1.87 2011-10-27 23:46:31 tbox Exp $ */
+/* $Id: adb.h,v 1.88 2011-12-05 17:10:51 each Exp $ */
#ifndef DNS_ADB_H
#define DNS_ADB_H 1
@@ -548,64 +548,6 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
* srtt value. This may include changes made by others.
*/
-unsigned int
-dns_adb_getednsflag(dns_adb_t *adb, dns_adbaddrinfo_t *addr, isc_stdtime_t now);
-/*%
- * Get the EDNS big size
- *
- *\brief
- * Return the edns_fetchopt_flag from the instant dns_adbentry struct
- * This value may be DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_EDNS512,
- * or 0. If 0, the default maximum EDNS udp size is assumed.
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li addr be valid.
- */
-
-void
-dns_adb_setednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int length);
-/*%
- * Set the EDNS size
- *
- *\brief
- * Record the biggest length of received packet and maintain information
- * about reductions in udp size.
- *
- *\li length - size of packet
- *\li now - current time in seconds
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li addr be valid.
- */
-
-void
-dns_adb_dropednssize(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
- unsigned int length, isc_stdtime_t now);
-/*%
- * Drop the EDNS size
- *
- *\brief
- * Record a notification that the packetsize has been dropped because of
- * communication failures. If enough of these occur, this server's EDNS size
- * will be dropped for DNS_ADB_EDNS_MAX_DROP_TIME.
- *
- *\li length - size of packet
- *\li now - current time in seconds
- *
- * Requires:
- *
- *\li adb be valid.
- *
- *\li addr be valid.
- */
-
void
dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int bits, unsigned int mask);
diff --git a/lib/dns/include/dns/callbacks.h b/lib/dns/include/dns/callbacks.h
index 1b920080..7503f15c 100644
--- a/lib/dns/include/dns/callbacks.h
+++ b/lib/dns/include/dns/callbacks.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: callbacks.h,v 1.24 2007-06-19 23:47:16 tbox Exp $ */
+/* $Id: callbacks.h,v 1.26 2011-12-09 23:47:05 tbox Exp $ */
#ifndef DNS_CALLBACKS_H
#define DNS_CALLBACKS_H 1
@@ -41,6 +41,14 @@ struct dns_rdatacallbacks {
* dns_load_master calls this when it has rdatasets to commit.
*/
dns_addrdatasetfunc_t add;
+
+ /*%
+ * dns_master_load*() call this when loading a raw zonefile,
+ * to pass back information obtained from the file header
+ */
+ dns_rawdatafunc_t rawdata;
+ dns_zone_t *zone;
+
/*%
* dns_load_master / dns_rdata_fromtext call this to issue a error.
*/
diff --git a/lib/dns/include/dns/journal.h b/lib/dns/include/dns/journal.h
index c5024a37..3141351f 100644
--- a/lib/dns/include/dns/journal.h
+++ b/lib/dns/include/dns/journal.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.h,v 1.39 2011-08-30 23:46:53 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
@@ -76,7 +76,7 @@ ISC_LANG_BEGINDECLS
isc_result_t
dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
- dns_diffop_t op, dns_difftuple_t **tp);
+ dns_diffop_t op, dns_difftuple_t **tp);
/*!< brief
* Create a diff tuple for the current database SOA.
* XXX this probably belongs somewhere else.
@@ -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.
*/
@@ -270,12 +270,18 @@ dns_db_diff(isc_mem_t *mctx,
dns_db_t *dba, dns_dbversion_t *dbvera,
dns_db_t *dbb, dns_dbversion_t *dbverb,
const char *journal_filename);
+
+isc_result_t
+dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb,
+ const char *journal_filename);
/*%<
- * Compare the databases 'dba' and 'dbb' and generate a journal
+ * Compare the databases 'dba' and 'dbb' and generate a diff/journal
* entry containing the changes to make 'dba' from 'dbb' (note
* the order). This journal entry will consist of a single,
* possibly very large transaction. Append the journal
- * entry to the journal file specified by 'journal_filename'.
+ * entry to the journal file specified by 'journal_filename' if
+ * non-NULL.
*/
isc_result_t
@@ -287,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_bitws(dns_journal_t *j);
+isc_boolean_t
+dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial);
void
-dns_journal_set_bitws(dns_journal_t *j, isc_uint32_t bitws);
+dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial);
/*%<
- * Get and set bump in the wire serial.
+ * Get and set source serial.
+ *
+ * Returns:
+ * ISC_TRUE if sourceserial has previously been set.
*/
ISC_LANG_ENDDECLS
diff --git a/lib/dns/include/dns/master.h b/lib/dns/include/dns/master.h
index 2ee63748..3c217255 100644
--- a/lib/dns/include/dns/master.h
+++ b/lib/dns/include/dns/master.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.h,v 1.53 2009-07-01 23:47:36 tbox Exp $ */
+/* $Id: master.h,v 1.55 2011-12-09 23:47:05 tbox Exp $ */
#ifndef DNS_MASTER_H
#define DNS_MASTER_H 1
@@ -66,18 +66,29 @@ ISC_LANG_BEGINDECLS
* encoding, we directly read/write each field so that the encoded data
* is always "packed", regardless of the hardware architecture.
*/
-#define DNS_RAWFORMAT_VERSION 0
+#define DNS_RAWFORMAT_VERSION 1
+
+/*
+ * Flags to indicate the status of the data in the raw file header
+ */
+#define DNS_MASTERRAW_COMPAT 0x01
+#define DNS_MASTERRAW_SOURCESERIALSET 0x02
+#define DNS_MASTERRAW_LASTXFRINSET 0x04
/* Common header */
-typedef struct {
+struct dns_masterrawheader {
isc_uint32_t format; /* must be
* dns_masterformat_raw */
isc_uint32_t version; /* compatibility for future
* extensions */
isc_uint32_t dumptime; /* timestamp on creation
- * (currently unused)
- */
-} dns_masterrawheader_t;
+ * (currently unused) */
+ isc_uint32_t flags; /* Flags */
+ isc_uint32_t sourceserial; /* Source serial number (used
+ * by inline-signing zones) */
+ isc_uint32_t lastxfrin; /* timestamp of last transfer
+ * (used by slave zones) */
+};
/* The structure for each RRset */
typedef struct {
@@ -302,6 +313,12 @@ dns_loadctx_cancel(dns_loadctx_t *ctx);
*\li 'ctx' to be valid
*/
+void
+dns_master_initrawheader(dns_masterrawheader_t *header);
+/*%<
+ * Initializes the header for a raw master file, setting all
+ * values to zero.
+ */
ISC_LANG_ENDDECLS
#endif /* DNS_MASTER_H */
diff --git a/lib/dns/include/dns/masterdump.h b/lib/dns/include/dns/masterdump.h
index be43875b..266877a1 100644
--- a/lib/dns/include/dns/masterdump.h
+++ b/lib/dns/include/dns/masterdump.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.h,v 1.45 2011-05-26 07:56:39 marka Exp $ */
+/* $Id: masterdump.h,v 1.47 2011-12-08 23:46:49 tbox Exp $ */
#ifndef DNS_MASTERDUMP_H
#define DNS_MASTERDUMP_H 1
@@ -220,13 +220,25 @@ dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db,
dns_dbversion_t *version,
const dns_master_style_t *style,
dns_masterformat_t format, FILE *f);
+
+isc_result_t
+dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
+ dns_dbversion_t *version,
+ const dns_master_style_t *style,
+ dns_masterformat_t format,
+ dns_masterrawheader_t *header, FILE *f);
/*%<
* Dump the database 'db' to the steam 'f' in the specified format by
* 'format'. If the format is dns_masterformat_text (the RFC1035 format),
* 'style' specifies the file style (e.g., &dns_master_style_default).
*
- * dns_master_dumptostream() is an old form of dns_master_dumptostream2(),
+ * dns_master_dumptostream() is an old form of dns_master_dumptostream3(),
* which always specifies the dns_masterformat_text format.
+ * dns_master_dumptostream2() is an old form which always specifies
+ * a NULL header.
+ *
+ * If 'format' is dns_masterformat_raw, then 'header' can contain
+ * information to be written to the file header.
*
* Temporary dynamic memory may be allocated from 'mctx'.
*
@@ -257,6 +269,13 @@ dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format);
isc_result_t
+dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
+ const dns_master_style_t *style, const char *filename,
+ isc_task_t *task, dns_dumpdonefunc_t done, void
+ *done_arg, dns_dumpctx_t **dctxp,
+ dns_masterformat_t format, dns_masterrawheader_t *header);
+
+isc_result_t
dns_master_dump(isc_mem_t *mctx, dns_db_t *db,
dns_dbversion_t *version,
const dns_master_style_t *style, const char *filename);
@@ -267,14 +286,24 @@ dns_master_dump2(isc_mem_t *mctx, dns_db_t *db,
const dns_master_style_t *style, const char *filename,
dns_masterformat_t format);
+isc_result_t
+dns_master_dump3(isc_mem_t *mctx, dns_db_t *db,
+ dns_dbversion_t *version,
+ const dns_master_style_t *style, const char *filename,
+ dns_masterformat_t format, dns_masterrawheader_t *header);
+
/*%<
* Dump the database 'db' to the file 'filename' in the specified format by
* 'format'. If the format is dns_masterformat_text (the RFC1035 format),
* 'style' specifies the file style (e.g., &dns_master_style_default).
*
- * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc2()
- * and _dump2(), respectively, which always specify the dns_masterformat_text
- * format.
+ * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc3()
+ * and _dump3(), respectively, which always specify the dns_masterformat_text
+ * format. dns_master_dumpinc2() and dns_master_dump2() are old forms which
+ * always specify a NULL header.
+ *
+ * If 'format' is dns_masterformat_raw, then 'header' can contain
+ * information to be written to the file header.
*
* Temporary dynamic memory may be allocated from 'mctx'.
*
diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h
index f6cd6325..043ede4a 100644
--- a/lib/dns/include/dns/resolver.h
+++ b/lib/dns/include/dns/resolver.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.h,v 1.71 2011-11-16 22:18:52 marka Exp $ */
+/* $Id: resolver.h,v 1.72 2011-12-05 17:10:51 each Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -96,9 +96,6 @@ typedef struct dns_fetchevent {
#define DNS_FETCHOPT_EDNS512 0x40 /*%< Advertise a 512 byte
UDP buffer. */
#define DNS_FETCHOPT_WANTNSID 0x80 /*%< Request NSID */
-#define DNS_FETCHOPT_CACHENOEDNS 0x100 /*%< This is a candidate
- for setting NOEDNS
- in adb. */
#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000
#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 3814aef4..716285b6 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.145 2011-07-01 23:47:44 tbox Exp $ */
+/* $Id: types.h,v 1.146 2011-12-08 16:07:21 each Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
@@ -85,6 +85,7 @@ typedef struct dns_keytable dns_keytable_t;
typedef isc_uint16_t dns_keytag_t;
typedef struct dns_loadctx dns_loadctx_t;
typedef struct dns_loadmgr dns_loadmgr_t;
+typedef struct dns_masterrawheader dns_masterrawheader_t;
typedef struct dns_message dns_message_t;
typedef isc_uint16_t dns_messageid_t;
typedef isc_region_t dns_label_t;
@@ -355,6 +356,9 @@ typedef void
typedef void
(*dns_loaddonefunc_t)(void *, isc_result_t);
+typedef void
+(*dns_rawdatafunc_t)(dns_zone_t *, dns_masterrawheader_t *);
+
typedef isc_result_t
(*dns_addrdatasetfunc_t)(void *, dns_name_t *, dns_rdataset_t *);
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index f9e534b3..765f73fa 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.197 2011-11-04 05:51:01 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>
@@ -510,6 +511,10 @@ dns_zone_dumptostream(dns_zone_t *zone, FILE *fd);
isc_result_t
dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
const dns_master_style_t *style);
+isc_result_t
+dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
+ const dns_master_style_t *style,
+ const isc_uint32_t rawversion);
/*%<
* Write the zone to stream 'fd' in the specified 'format'.
* If the 'format' is dns_masterformat_text (RFC1035), 'style' also
@@ -519,7 +524,11 @@ dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
* dns_zone_dumptostream2(), which always uses the dns_masterformat_text
* format and the dns_master_style_default style.
*
- * Note that dns_zone_dumptostream2() is the most flexible form. It
+ * dns_zone_dumptostream2() is a backward-compatible form of
+ * dns_zone_dumptostream3(), which always uses the current
+ * default raw file format version.
+ *
+ * Note that dns_zone_dumptostream3() is the most flexible form. It
* can also provide the functionality of dns_zone_fulldumptostream().
*
* Require:
@@ -2021,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 */
diff --git a/lib/dns/journal.c b/lib/dns/journal.c
index 16fe541b..4f2f5a03 100644
--- a/lib/dns/journal.c
+++ b/lib/dns/journal.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.c,v 1.116 2011-08-30 23:46:52 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
@@ -213,8 +215,9 @@ typedef union {
journal_rawpos_t end;
/*% Number of index entries following the header. */
unsigned char index_size[4];
- /*% Bump in the wire serial. */
- unsigned char bitws[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];
@@ -254,7 +257,8 @@ typedef struct {
journal_pos_t begin;
journal_pos_t end;
isc_uint32_t index_size;
- isc_uint32_t bitws;
+ 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)
@@ -296,7 +300,7 @@ typedef enum {
JOURNAL_STATE_READ,
JOURNAL_STATE_WRITE,
JOURNAL_STATE_TRANSACTION,
- JOURNAL_STATE_BITWS
+ JOURNAL_STATE_INLINE
} journal_state_t;
struct dns_journal {
@@ -357,18 +361,24 @@ journal_header_decode(journal_rawheader_t *raw, journal_header_t *cooked) {
journal_pos_decode(&raw->h.begin, &cooked->begin);
journal_pos_decode(&raw->h.end, &cooked->end);
cooked->index_size = decode_uint32(raw->h.index_size);
- cooked->bitws = decode_uint32(raw->h.bitws);
+ 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));
journal_pos_encode(&raw->h.begin, &cooked->begin);
journal_pos_encode(&raw->h.end, &cooked->end);
encode_uint32(cooked->index_size, raw->h.index_size);
- encode_uint32(cooked->bitws, raw->h.bitws);
+ 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];
@@ -955,7 +967,7 @@ dns_journal_begin_transaction(dns_journal_t *j) {
REQUIRE(DNS_JOURNAL_VALID(j));
REQUIRE(j->state == JOURNAL_STATE_WRITE ||
- j->state == JOURNAL_STATE_BITWS);
+ j->state == JOURNAL_STATE_INLINE);
/*
* Find the file offset where the new transaction should
@@ -1079,12 +1091,12 @@ dns_journal_commit(dns_journal_t *j) {
REQUIRE(DNS_JOURNAL_VALID(j));
REQUIRE(j->state == JOURNAL_STATE_TRANSACTION ||
- j->state == JOURNAL_STATE_BITWS);
+ j->state == JOURNAL_STATE_INLINE);
/*
* Just write out a updated header.
*/
- if (j->state == JOURNAL_STATE_BITWS) {
+ if (j->state == JOURNAL_STATE_INLINE) {
CHECK(journal_fsync(j));
journal_header_encode(&j->header, &rawheader);
CHECK(journal_seek(j, 0));
@@ -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.bitws = 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, "BITWS = %u\n", j->header.bitws);
+ if (j->header.serialset)
+ fprintf(file, "Source serial = %u\n", j->header.sourceserial);
dns_diff_init(j->mctx, &diff);
/*
@@ -1539,20 +1550,26 @@ dns_journal_last_serial(dns_journal_t *j) {
}
void
-dns_journal_set_bitws(dns_journal_t *j, isc_uint32_t bitws) {
+dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial) {
REQUIRE(j->state == JOURNAL_STATE_WRITE ||
- j->state == JOURNAL_STATE_BITWS ||
+ j->state == JOURNAL_STATE_INLINE ||
j->state == JOURNAL_STATE_TRANSACTION);
- j->header.bitws = bitws;
+ j->header.sourceserial = sourceserial;
+ j->header.serialset = ISC_TRUE;
if (j->state == JOURNAL_STATE_WRITE)
- j->state = JOURNAL_STATE_BITWS;
+ j->state = JOURNAL_STATE_INLINE;
}
-isc_uint32_t
-dns_journal_get_bitws(dns_journal_t *j) {
- return (j->header.bitws);
+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);
}
/**************************************************************************/
@@ -1910,8 +1927,7 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) {
}
static isc_result_t
-diff_namespace(isc_mem_t *mctx,
- dns_db_t *dba, dns_dbversion_t *dbvera,
+diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera,
dns_db_t *dbb, dns_dbversion_t *dbverb,
unsigned int options, dns_diff_t *resultdiff)
{
@@ -1927,8 +1943,8 @@ diff_namespace(isc_mem_t *mctx,
db[0] = dba, db[1] = dbb;
ver[0] = dbvera, ver[1] = dbverb;
- dns_diff_init(mctx, &diff[0]);
- dns_diff_init(mctx, &diff[1]);
+ dns_diff_init(resultdiff->mctx, &diff[0]);
+ dns_diff_init(resultdiff->mctx, &diff[1]);
dns_fixedname_init(&fixname[0]);
dns_fixedname_init(&fixname[1]);
@@ -2006,8 +2022,11 @@ diff_namespace(isc_mem_t *mctx,
failure:
dns_dbiterator_destroy(&dbit[1]);
+
cleanup_iterator:
dns_dbiterator_destroy(&dbit[0]);
+ dns_diff_clear(&diff[0]);
+ dns_diff_clear(&diff[1]);
return (result);
}
@@ -2018,33 +2037,48 @@ diff_namespace(isc_mem_t *mctx,
* possibly very large transaction.
*/
isc_result_t
-dns_db_diff(isc_mem_t *mctx,
- dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb,
- const char *journal_filename)
+dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename)
+{
+ isc_result_t result;
+ dns_diff_t diff;
+
+ dns_diff_init(mctx, &diff);
+
+ result = dns_db_diffx(&diff, dba, dbvera, dbb, dbverb, filename);
+
+ dns_diff_clear(&diff);
+
+ return (result);
+}
+
+isc_result_t
+dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename)
{
isc_result_t result;
dns_journal_t *journal = NULL;
- dns_diff_t resultdiff;
- result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal);
- if (result != ISC_R_SUCCESS)
- return (result);
+ if (filename != NULL) {
+ result = dns_journal_open(diff->mctx, filename,
+ DNS_JOURNAL_CREATE, &journal);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
- dns_diff_init(mctx, &resultdiff);
+ CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NONSEC3, diff));
+ CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NSEC3ONLY, diff));
- CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb,
- DNS_DB_NONSEC3, &resultdiff));
- CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb,
- DNS_DB_NSEC3ONLY, &resultdiff));
- if (ISC_LIST_EMPTY(resultdiff.tuples)) {
- isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes");
- } else {
- CHECK(dns_journal_write_transaction(journal, &resultdiff));
+ if (journal != NULL) {
+ if (ISC_LIST_EMPTY(diff->tuples))
+ isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes");
+ else
+ CHECK(dns_journal_write_transaction(journal, diff));
}
+
failure:
- dns_diff_clear(&resultdiff);
- dns_journal_destroy(&journal);
+ if (journal != NULL)
+ dns_journal_destroy(&journal);
return (result);
}
@@ -2195,7 +2229,8 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
new->header.begin.offset = indexend;
new->header.end.serial = j->header.end.serial;
new->header.end.offset = indexend + copy_length;
- new->header.bitws = j->header.bitws;
+ new->header.sourceserial = j->header.sourceserial;
+ new->header.serialset = j->header.serialset;
/*
* Update the journal header.
diff --git a/lib/dns/master.c b/lib/dns/master.c
index d6ac002a..4e1f274e 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.c,v 1.180 2011-03-12 04:59:48 tbox Exp $ */
+/* $Id: master.c,v 1.181 2011-12-08 16:07:20 each Exp $ */
/*! \file */
@@ -133,6 +133,7 @@ struct dns_loadctx {
/* Members specific to the raw format: */
FILE *f;
isc_boolean_t first;
+ dns_masterrawheader_t header;
/* Which fixed buffers we are using? */
unsigned int loop_cnt; /*% records per quantum,
@@ -595,6 +596,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
lctx->f = NULL;
lctx->first = ISC_TRUE;
+ dns_master_initrawheader(&lctx->header);
lctx->loop_cnt = (done != NULL) ? 100 : 0;
lctx->callbacks = callbacks;
@@ -2086,48 +2088,72 @@ load_raw(dns_loadctx_t *lctx) {
int target_size = TSIZ;
isc_buffer_t target;
unsigned char *target_mem = NULL;
+ dns_masterrawheader_t header;
REQUIRE(DNS_LCTX_VALID(lctx));
callbacks = lctx->callbacks;
+ dns_master_initrawheader(&header);
+
if (lctx->first) {
- dns_masterrawheader_t header;
- isc_uint32_t format, version, dumptime;
- size_t hdrlen = sizeof(format) + sizeof(version) +
- sizeof(dumptime);
+ unsigned char data[sizeof(header)];
+ size_t commonlen =
+ sizeof(header.format) + sizeof(header.version);
+ size_t remainder;
- INSIST(hdrlen <= sizeof(header));
- isc_buffer_init(&target, &header, sizeof(header));
+ INSIST(commonlen <= sizeof(header));
+ isc_buffer_init(&target, data, sizeof(data));
- result = isc_stdio_read(&header, 1, hdrlen, lctx->f, NULL);
+ result = isc_stdio_read(data, 1, commonlen, lctx->f, NULL);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_stdio_read failed: %s",
isc_result_totext(result));
return (result);
}
- isc_buffer_add(&target, hdrlen);
- format = isc_buffer_getuint32(&target);
- if (format != dns_masterformat_raw) {
+ isc_buffer_add(&target, commonlen);
+ header.format = isc_buffer_getuint32(&target);
+ if (header.format != dns_masterformat_raw) {
(*callbacks->error)(callbacks,
"dns_master_load: "
"file format mismatch");
return (ISC_R_NOTIMPLEMENTED);
}
- version = isc_buffer_getuint32(&target);
- if (version > DNS_RAWFORMAT_VERSION) {
+ header.version = isc_buffer_getuint32(&target);
+ switch (header.version) {
+ case 0:
+ remainder = sizeof(header.dumptime);
+ break;
+ case DNS_RAWFORMAT_VERSION:
+ remainder = sizeof(header) - commonlen;
+ break;
+ default:
(*callbacks->error)(callbacks,
"dns_master_load: "
"unsupported file format version");
return (ISC_R_NOTIMPLEMENTED);
}
- /* Empty read: currently, we do not use dumptime */
- dumptime = isc_buffer_getuint32(&target);
- POST(dumptime);
+ result = isc_stdio_read(data + commonlen, 1, remainder,
+ lctx->f, NULL);
+ if (result != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_stdio_read failed: %s",
+ isc_result_totext(result));
+ return (result);
+ }
+
+ isc_buffer_add(&target, remainder);
+ header.dumptime = isc_buffer_getuint32(&target);
+ if (header.version == DNS_RAWFORMAT_VERSION) {
+ header.flags = isc_buffer_getuint32(&target);
+ header.sourceserial = isc_buffer_getuint32(&target);
+ header.lastxfrin = isc_buffer_getuint32(&target);
+ }
lctx->first = ISC_FALSE;
+ lctx->header = header;
}
ISC_LIST_INIT(head);
@@ -2353,6 +2379,9 @@ load_raw(dns_loadctx_t *lctx) {
} else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS)
result = lctx->result;
+ if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL)
+ (*callbacks->rawdata)(callbacks->zone, &header);
+
cleanup:
if (rdata != NULL)
isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
@@ -2935,3 +2964,8 @@ dns_loadctx_cancel(dns_loadctx_t *lctx) {
lctx->canceled = ISC_TRUE;
UNLOCK(&lctx->lock);
}
+
+void
+dns_master_initrawheader(dns_masterrawheader_t *header) {
+ memset(header, 0, sizeof(dns_masterrawheader_t));
+}
diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c
index 93e07054..7705026a 100644
--- a/lib/dns/masterdump.c
+++ b/lib/dns/masterdump.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.110 2011-11-07 23:16:31 each Exp $ */
+/* $Id: masterdump.c,v 1.113 2011-12-20 00:06:53 marka Exp $ */
/*! \file */
@@ -188,6 +188,7 @@ struct dns_dumpctx {
char *file;
char *tmpfile;
dns_masterformat_t format;
+ dns_masterrawheader_t header;
isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name,
dns_rdatasetiter_t *rdsiter,
dns_totext_ctx_t *ctx,
@@ -931,6 +932,7 @@ dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset,
REQUIRE(buffer->length > 0);
REQUIRE(DNS_RDATASET_VALID(rdataset));
+ rdataset->attributes |= DNS_RDATASETATTR_LOADORDER;
restart:
totallen = 0;
result = dns_rdataset_first(rdataset);
@@ -1265,7 +1267,7 @@ task_send(dns_dumpctx_t *dctx) {
static isc_result_t
dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp,
- dns_masterformat_t format)
+ dns_masterformat_t format, dns_masterrawheader_t *header)
{
dns_dumpctx_t *dctx;
isc_result_t result;
@@ -1289,6 +1291,10 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
dctx->file = NULL;
dctx->tmpfile = NULL;
dctx->format = format;
+ if (header == NULL)
+ dns_master_initrawheader(&dctx->header);
+ else
+ dctx->header = *header;
switch (format) {
case dns_masterformat_text:
@@ -1356,7 +1362,7 @@ dumptostreaminc(dns_dumpctx_t *dctx) {
dns_fixedname_t fixname;
unsigned int nodes;
dns_masterrawheader_t rawheader;
- isc_uint32_t now32;
+ isc_uint32_t rawversion, now32;
isc_time_t start;
bufmem = isc_mem_get(dctx->mctx, initial_buffer_length);
@@ -1391,8 +1397,6 @@ dumptostreaminc(dns_dumpctx_t *dctx) {
r.base = (unsigned char *)&rawheader;
r.length = sizeof(rawheader);
isc_buffer_region(&buffer, &r);
- isc_buffer_putuint32(&buffer, dns_masterformat_raw);
- isc_buffer_putuint32(&buffer, DNS_RAWFORMAT_VERSION);
#if !defined(STDTIME_ON_32BITS) || (STDTIME_ON_32BITS + 0) != 1
/*
* We assume isc_stdtime_t is a 32-bit integer,
@@ -1411,7 +1415,22 @@ dumptostreaminc(dns_dumpctx_t *dctx) {
#else
now32 = dctx->now;
#endif
+ rawversion = 1;
+ if ((dctx->header.flags & DNS_MASTERRAW_COMPAT) != 0)
+ rawversion = 0;
+ isc_buffer_putuint32(&buffer, dns_masterformat_raw);
+ isc_buffer_putuint32(&buffer, rawversion);
isc_buffer_putuint32(&buffer, now32);
+
+ if (rawversion == 1) {
+ isc_buffer_putuint32(&buffer,
+ dctx->header.flags);
+ isc_buffer_putuint32(&buffer,
+ dctx->header.sourceserial);
+ isc_buffer_putuint32(&buffer,
+ dctx->header.lastxfrin);
+ }
+
INSIST(isc_buffer_usedlength(&buffer) <=
sizeof(rawheader));
result = isc_stdio_write(buffer.base, 1,
@@ -1530,7 +1549,7 @@ dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db,
REQUIRE(done != NULL);
result = dumpctx_create(mctx, db, version, style, f, &dctx,
- dns_masterformat_text);
+ dns_masterformat_text, NULL);
if (result != ISC_R_SUCCESS)
return (result);
isc_task_attach(task, &dctx->task);
@@ -1557,8 +1576,8 @@ dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db,
const dns_master_style_t *style,
FILE *f)
{
- return (dns_master_dumptostream2(mctx, db, version, style,
- dns_masterformat_text, f));
+ return (dns_master_dumptostream3(mctx, db, version, style,
+ dns_masterformat_text, NULL, f));
}
isc_result_t
@@ -1567,10 +1586,22 @@ dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db,
const dns_master_style_t *style,
dns_masterformat_t format, FILE *f)
{
+ return (dns_master_dumptostream3(mctx, db, version, style,
+ format, NULL, f));
+}
+
+isc_result_t
+dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
+ dns_dbversion_t *version,
+ const dns_master_style_t *style,
+ dns_masterformat_t format,
+ dns_masterrawheader_t *header, FILE *f)
+{
dns_dumpctx_t *dctx = NULL;
isc_result_t result;
- result = dumpctx_create(mctx, db, version, style, f, &dctx, format);
+ result = dumpctx_create(mctx, db, version, style, f, &dctx,
+ format, header);
if (result != ISC_R_SUCCESS)
return (result);
@@ -1621,9 +1652,9 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
dns_dumpctx_t **dctxp)
{
- return (dns_master_dumpinc2(mctx, db, version, style, filename, task,
+ return (dns_master_dumpinc3(mctx, db, version, style, filename, task,
done, done_arg, dctxp,
- dns_masterformat_text));
+ dns_masterformat_text, NULL));
}
isc_result_t
@@ -1632,6 +1663,17 @@ dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
dns_dumpctx_t **dctxp, dns_masterformat_t format)
{
+ return (dns_master_dumpinc3(mctx, db, version, style, filename, task,
+ done, done_arg, dctxp, format, NULL));
+}
+
+isc_result_t
+dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
+ const dns_master_style_t *style, const char *filename,
+ isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg,
+ dns_dumpctx_t **dctxp, dns_masterformat_t format,
+ dns_masterrawheader_t *header)
+{
FILE *f = NULL;
isc_result_t result;
char *tempname = NULL;
@@ -1646,7 +1688,8 @@ dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = dumpctx_create(mctx, db, version, style, f, &dctx, format);
+ result = dumpctx_create(mctx, db, version, style, f, &dctx,
+ format, header);
if (result != ISC_R_SUCCESS) {
(void)isc_stdio_close(f);
(void)isc_file_remove(tempname);
@@ -1682,8 +1725,8 @@ isc_result_t
dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
const dns_master_style_t *style, const char *filename)
{
- return (dns_master_dump2(mctx, db, version, style, filename,
- dns_masterformat_text));
+ return (dns_master_dump3(mctx, db, version, style, filename,
+ dns_masterformat_text, NULL));
}
isc_result_t
@@ -1691,6 +1734,15 @@ dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
const dns_master_style_t *style, const char *filename,
dns_masterformat_t format)
{
+ return (dns_master_dump3(mctx, db, version, style, filename,
+ format, NULL));
+}
+
+isc_result_t
+dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
+ const dns_master_style_t *style, const char *filename,
+ dns_masterformat_t format, dns_masterrawheader_t *header)
+{
FILE *f = NULL;
isc_result_t result;
char *tempname;
@@ -1700,7 +1752,8 @@ dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
return (result);
- result = dumpctx_create(mctx, db, version, style, f, &dctx, format);
+ result = dumpctx_create(mctx, db, version, style, f, &dctx,
+ format, header);
if (result != ISC_R_SUCCESS)
goto cleanup;
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index fbbdcb93..7091a399 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.322 2011-11-18 18:40:31 each Exp $ */
+/* $Id: rbtdb.c,v 1.323 2011-12-07 22:21:05 marka Exp $ */
/*! \file */
@@ -2003,9 +2003,9 @@ iszonesecure(dns_db_t *db, rbtdb_version_t *version, dns_dbnode_t *origin) {
result = dns_db_findrdataset(db, origin, version, dns_rdatatype_dnskey,
0, 0, &keyset, NULL);
if (result == ISC_R_SUCCESS) {
- dns_rdata_t keyrdata = DNS_RDATA_INIT;
result = dns_rdataset_first(&keyset);
while (result == ISC_R_SUCCESS) {
+ dns_rdata_t keyrdata = DNS_RDATA_INIT;
dns_rdataset_current(&keyset, &keyrdata);
if (dns_zonekey_iszonekey(&keyrdata)) {
haszonekey = ISC_TRUE;
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c
index 08a12619..eb43935e 100644
--- a/lib/dns/rdata.c
+++ b/lib/dns/rdata.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdata.c,v 1.214 2011-11-02 01:01:52 marka Exp $ */
+/* $Id: rdata.c,v 1.215 2011-12-22 07:41:29 marka Exp $ */
/*! \file */
@@ -1138,7 +1138,8 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
}
escape = ISC_FALSE;
if (nrem == 0)
- return (ISC_R_NOSPACE);
+ return ((tregion.length <= 256U) ?
+ ISC_R_NOSPACE : DNS_R_SYNTAX);
*t++ = c;
nrem--;
}
diff --git a/lib/dns/rdata/in_1/wks_11.c b/lib/dns/rdata/in_1/wks_11.c
index 29983ec1..fff9da81 100644
--- a/lib/dns/rdata/in_1/wks_11.c
+++ b/lib/dns/rdata/in_1/wks_11.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: wks_11.c,v 1.57 2009-12-04 21:09:34 marka Exp $ */
+/* $Id: wks_11.c,v 1.59 2011-11-30 23:46:25 tbox Exp $ */
/* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */
@@ -27,16 +27,46 @@
#include <isc/net.h>
#include <isc/netdb.h>
+#include <isc/once.h>
#define RRTYPE_WKS_ATTRIBUTES (0)
+static isc_mutex_t wks_lock;
+
+static void init_lock(void) {
+ RUNTIME_CHECK(isc_mutex_init(&wks_lock) == ISC_R_SUCCESS);
+}
+
+static isc_boolean_t
+mygetprotobyname(const char *name, long *proto) {
+ struct protoent *pe;
+
+ LOCK(&wks_lock);
+ pe = getprotobyname(name);
+ if (pe != NULL)
+ *proto = pe->p_proto;
+ UNLOCK(&wks_lock);
+ return (ISC_TF(pe != NULL));
+}
+
+static isc_boolean_t
+mygetservbyname(const char *name, const char *proto, long *port) {
+ struct servent *se;
+
+ LOCK(&wks_lock);
+ se = getservbyname(name, proto);
+ if (se != NULL)
+ *port = ntohs(se->s_port);
+ UNLOCK(&wks_lock);
+ return (ISC_TF(se != NULL));
+}
+
static inline isc_result_t
fromtext_in_wks(ARGS_FROMTEXT) {
+ static isc_once_t once = ISC_ONCE_INIT;
isc_token_t token;
isc_region_t region;
struct in_addr addr;
- struct protoent *pe;
- struct servent *se;
char *e;
long proto;
unsigned char bm[8*1024]; /* 64k bits */
@@ -55,6 +85,8 @@ fromtext_in_wks(ARGS_FROMTEXT) {
UNUSED(options);
UNUSED(rdclass);
+ RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
+
/*
* IPv4 dotted quad.
*/
@@ -78,10 +110,9 @@ fromtext_in_wks(ARGS_FROMTEXT) {
proto = strtol(DNS_AS_STR(token), &e, 10);
if (*e == 0)
;
- else if ((pe = getprotobyname(DNS_AS_STR(token))) != NULL)
- proto = pe->p_proto;
- else
+ else if (!mygetprotobyname(DNS_AS_STR(token), &proto))
RETTOK(DNS_R_UNKNOWNPROTO);
+
if (proto < 0 || proto > 0xff)
RETTOK(ISC_R_RANGE);
@@ -112,12 +143,8 @@ fromtext_in_wks(ARGS_FROMTEXT) {
port = strtol(DNS_AS_STR(token), &e, 10);
if (*e == 0)
;
- else if ((se = getservbyname(service, ps)) != NULL)
- port = ntohs(se->s_port);
- else if ((se = getservbyname(DNS_AS_STR(token), ps))
- != NULL)
- port = ntohs(se->s_port);
- else
+ else if (!mygetservbyname(service, ps, &port) &&
+ !mygetservbyname(DNS_AS_STR(token), ps, &port))
RETTOK(DNS_R_UNKNOWNSERVICE);
if (port < 0 || port > 0xffff)
RETTOK(ISC_R_RANGE);
diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c
index 1b20bd52..d4fce614 100644
--- a/lib/dns/rdataslab.c
+++ b/lib/dns/rdataslab.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataslab.c,v 1.54 2011-02-03 12:18:11 tbox Exp $ */
+/* $Id: rdataslab.c,v 1.55 2011-12-20 00:55:01 marka Exp $ */
/*! \file */
@@ -53,6 +53,7 @@
* record count (2 bytes)
* data records
* data length (2 bytes)
+ * meta data (1 byte for RRSIG's)
* data (data length bytes)
*
* Offsets are from the end of the header.
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 6b64461b..c97aa780 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.442 2011-11-16 22:18:52 marka Exp $ */
+/* $Id: resolver.c,v 1.446 2011-12-07 23:08:42 marka Exp $ */
/*! \file */
@@ -453,7 +453,7 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
dns_rdataset_t *ardataset,
isc_result_t *eresultp);
static void validated(isc_task_t *task, isc_event_t *event);
-static void maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
+static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
isc_result_t reason, badnstype_t badtype);
@@ -746,8 +746,11 @@ resquery_destroy(resquery_t **queryp) {
INSIST(query->tcpsocket == NULL);
query->fctx->nqueries--;
- if (SHUTTINGDOWN(query->fctx))
- maybe_destroy(query->fctx, ISC_FALSE); /* Locks bucket. */
+ if (SHUTTINGDOWN(query->fctx)) {
+ dns_resolver_t *res = query->fctx->res;
+ if (maybe_destroy(query->fctx, ISC_FALSE))
+ empty_bucket(res);
+ }
query->magic = 0;
isc_mem_put(query->mctx, query, sizeof(*query));
*queryp = NULL;
@@ -1324,9 +1327,7 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
* We retry every .8 seconds the first two times through the address
* list, and then we do exponential back-off.
*/
- if (fctx->restarts == 0)
- us = 400000;
- else if (fctx->restarts < 3)
+ if (fctx->restarts < 3)
us = 800000;
else
us = (800000 << (fctx->restarts - 2));
@@ -1687,8 +1688,6 @@ resquery_send(resquery_t *query) {
isc_boolean_t cleanup_cctx = ISC_FALSE;
isc_boolean_t secure_domain;
isc_boolean_t connecting = ISC_FALSE;
- unsigned int edns_fetchopt_flag;
- isc_stdtime_t now;
fctx = query->fctx;
QTRACE("send");
@@ -1799,16 +1798,6 @@ resquery_send(resquery_t *query) {
(void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
/*
- * Get the fetchopt flag for this server from the adb cache
- * NOTE: if the NOEDNS flag has been set on addrinfo->flags,
- * it will over write this below.
- */
- isc_stdtime_get(&now);
- edns_fetchopt_flag = dns_adb_getednsflag(fctx->adb, query->addrinfo,
- now);
- query->options |= edns_fetchopt_flag;
-
- /*
* The ADB does not know about servers with "edns no". Check this,
* and then inform the ADB for future use.
*/
@@ -1842,24 +1831,17 @@ resquery_send(resquery_t *query) {
* * packet loss / link outage.
*/
if (fctx->timeout) {
- if ((triededns512(fctx, &query->addrinfo->sockaddr) &&
- fctx->timeouts > MAX_EDNS0_TIMEOUTS) &&
+ if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
+ fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
query->options |= DNS_FETCHOPT_NOEDNS0;
- query->options |= DNS_FETCHOPT_CACHENOEDNS;
fctx->reason = "disabling EDNS";
} else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
- fctx->timeouts >= 1) &&
+ fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
query->options |= DNS_FETCHOPT_EDNS512;
- if (edns_fetchopt_flag != DNS_FETCHOPT_EDNS512) {
- dns_adb_dropednssize(fctx->adb, query->addrinfo,
- 512, now);
- fctx->reason = "reducing the advertised EDNS "
- "UDP packet size to 512 octets";
- } else
- fctx->reason = "continuing to use lower EDNS "
- "UDP packet size of 512 octets";
+ fctx->reason = "reducing the advertised EDNS UDP "
+ "packet size to 512 octets";
}
fctx->timeout = ISC_FALSE;
}
@@ -1918,12 +1900,11 @@ resquery_send(resquery_t *query) {
goto cleanup_message;
}
- if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
+ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
add_triededns(fctx, &query->addrinfo->sockaddr);
- if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
- add_triededns512(fctx, &query->addrinfo->sockaddr);
- }
+ if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
+ add_triededns512(fctx, &query->addrinfo->sockaddr);
/*
* Clear CD if EDNS is not in use.
@@ -2183,6 +2164,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_try = ISC_FALSE;
isc_boolean_t want_done = ISC_FALSE;
isc_boolean_t bucket_empty = ISC_FALSE;
+ isc_boolean_t destroy = ISC_FALSE;
unsigned int bucketnum;
find = event->ev_sender;
@@ -2194,6 +2176,9 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
FCTXTRACE("finddone");
+ bucketnum = fctx->bucketnum;
+ LOCK(&res->buckets[bucketnum].lock);
+
INSIST(fctx->pending > 0);
fctx->pending--;
@@ -2218,17 +2203,17 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
}
} else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
- bucketnum = fctx->bucketnum;
- LOCK(&res->buckets[bucketnum].lock);
/*
* Note that we had to wait until we had the lock before
* looking at fctx->references.
*/
if (fctx->references == 0)
- bucket_empty = fctx_destroy(fctx);
- UNLOCK(&res->buckets[bucketnum].lock);
+ destroy = ISC_TRUE;
}
+ UNLOCK(&res->buckets[bucketnum].lock);
+ if (destroy)
+ bucket_empty = fctx_destroy(fctx);
isc_event_free(&event);
dns_adb_destroyfind(&find);
@@ -3911,13 +3896,15 @@ clone_results(fetchctx_t *fctx) {
/*
* Destroy '*fctx' if it is ready to be destroyed (i.e., if it has
- * no references and is no longer waiting for any events). If this
- * was the last fctx in the resolver, destroy the resolver.
+ * no references and is no longer waiting for any events).
*
* Requires:
* '*fctx' is shutting down.
+ *
+ * Returns:
+ * true if the resolver is exiting and this is the last fctx in the bucket.
*/
-static void
+static isc_boolean_t
maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
unsigned int bucketnum;
isc_boolean_t bucket_empty = ISC_FALSE;
@@ -3926,8 +3913,11 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
REQUIRE(SHUTTINGDOWN(fctx));
+ bucketnum = fctx->bucketnum;
+ if (!locked)
+ LOCK(&res->buckets[bucketnum].lock);
if (fctx->pending != 0 || fctx->nqueries != 0)
- return;
+ goto unlock;
for (validator = ISC_LIST_HEAD(fctx->validators);
validator != NULL; validator = next_validator) {
@@ -3935,16 +3925,12 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
dns_validator_cancel(validator);
}
- bucketnum = fctx->bucketnum;
- if (!locked)
- LOCK(&res->buckets[bucketnum].lock);
if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators))
bucket_empty = fctx_destroy(fctx);
+ unlock:
if (!locked)
UNLOCK(&res->buckets[bucketnum].lock);
-
- if (bucket_empty)
- empty_bucket(res);
+ return (bucket_empty);
}
/*
@@ -3952,31 +3938,33 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
*/
static void
validated(isc_task_t *task, isc_event_t *event) {
- isc_result_t result = ISC_R_SUCCESS;
- isc_result_t eresult = ISC_R_SUCCESS;
- isc_stdtime_t now;
- fetchctx_t *fctx;
- dns_validatorevent_t *vevent;
- dns_fetchevent_t *hevent;
- dns_rdataset_t *ardataset = NULL;
- dns_rdataset_t *asigrdataset = NULL;
+ dns_adbaddrinfo_t *addrinfo;
dns_dbnode_t *node = NULL;
- isc_boolean_t negative;
- isc_boolean_t chaining;
- isc_boolean_t sentresponse;
- isc_uint32_t ttl;
dns_dbnode_t *nsnode = NULL;
+ dns_fetchevent_t *hevent;
dns_name_t *name;
+ dns_rdataset_t *ardataset = NULL;
+ dns_rdataset_t *asigrdataset = NULL;
dns_rdataset_t *rdataset;
dns_rdataset_t *sigrdataset;
+ dns_resolver_t *res;
dns_valarg_t *valarg;
- dns_adbaddrinfo_t *addrinfo;
+ dns_validatorevent_t *vevent;
+ fetchctx_t *fctx;
+ isc_boolean_t chaining;
+ isc_boolean_t negative;
+ isc_boolean_t sentresponse;
+ isc_result_t eresult = ISC_R_SUCCESS;
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_stdtime_t now;
+ isc_uint32_t ttl;
UNUSED(task); /* for now */
REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
valarg = event->ev_arg;
fctx = valarg->fctx;
+ res = fctx->res;
addrinfo = valarg->addrinfo;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
@@ -3986,7 +3974,7 @@ validated(isc_task_t *task, isc_event_t *event) {
FCTXTRACE("received validation completion event");
- LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ LOCK(&res->buckets[fctx->bucketnum].lock);
ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
fctx->validator = NULL;
@@ -3996,7 +3984,7 @@ validated(isc_task_t *task, isc_event_t *event) {
* destroy the fctx if necessary.
*/
dns_validator_destroy(&vevent->validator);
- isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx,
+ isc_mem_put(res->buckets[fctx->bucketnum].mctx,
valarg, sizeof(*valarg));
negative = ISC_TF(vevent->rdataset == NULL);
@@ -4009,8 +3997,12 @@ validated(isc_task_t *task, isc_event_t *event) {
* so, destroy the fctx.
*/
if (SHUTTINGDOWN(fctx) && !sentresponse) {
- maybe_destroy(fctx, ISC_TRUE);
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ isc_uint32_t bucketnum = fctx->bucketnum;
+ isc_boolean_t bucket_empty;
+ bucket_empty = maybe_destroy(fctx, ISC_TRUE);
+ UNLOCK(&res->buckets[bucketnum].lock);
+ if (bucket_empty)
+ empty_bucket(res);
goto cleanup_event;
}
@@ -4059,7 +4051,7 @@ validated(isc_task_t *task, isc_event_t *event) {
if (vevent->result != ISC_R_SUCCESS) {
FCTXTRACE("validation failed");
- inc_stats(fctx->res, dns_resstatscounter_valfail);
+ inc_stats(res, dns_resstatscounter_valfail);
fctx->valfail++;
fctx->vresult = vevent->result;
if (fctx->vresult != DNS_R_BROKENCHAIN) {
@@ -4108,7 +4100,7 @@ validated(isc_task_t *task, isc_event_t *event) {
result = fctx->vresult;
add_bad(fctx, addrinfo, result, badns_validation);
isc_event_free(&event);
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ UNLOCK(&res->buckets[fctx->bucketnum].lock);
INSIST(fctx->validator == NULL);
fctx->validator = ISC_LIST_HEAD(fctx->validators);
if (fctx->validator != NULL)
@@ -4127,8 +4119,7 @@ validated(isc_task_t *task, isc_event_t *event) {
fctx->type == dns_rdatatype_dlv ||
fctx->type == dns_rdatatype_ds) &&
tresult == ISC_R_SUCCESS)
- dns_resolver_addbadcache(fctx->res,
- &fctx->name,
+ dns_resolver_addbadcache(res, &fctx->name,
fctx->type, &expire);
fctx_done(fctx, result, __LINE__); /* Locks bucket. */
} else
@@ -4141,7 +4132,7 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_rdatatype_t covers;
FCTXTRACE("nonexistence validation OK");
- inc_stats(fctx->res, dns_resstatscounter_valnegsuccess);
+ inc_stats(res, dns_resstatscounter_valnegsuccess);
if (fctx->rmessage->rcode == dns_rcode_nxdomain)
covers = dns_rdatatype_any;
@@ -4158,10 +4149,9 @@ validated(isc_task_t *task, isc_event_t *event) {
* to zero to facilitate locating the containing zone of
* a arbitrary zone.
*/
- ttl = fctx->res->view->maxncachettl;
+ ttl = res->view->maxncachettl;
if (fctx->type == dns_rdatatype_soa &&
- covers == dns_rdatatype_any &&
- fctx->res->zero_no_soa_ttl)
+ covers == dns_rdatatype_any && res->zero_no_soa_ttl)
ttl = 0;
result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
@@ -4171,7 +4161,7 @@ validated(isc_task_t *task, isc_event_t *event) {
goto noanswer_response;
goto answer_response;
} else
- inc_stats(fctx->res, dns_resstatscounter_valsuccess);
+ inc_stats(res, dns_resstatscounter_valsuccess);
FCTXTRACE("validation OK");
@@ -4219,14 +4209,17 @@ validated(isc_task_t *task, isc_event_t *event) {
}
if (sentresponse) {
+ isc_boolean_t bucket_empty = ISC_FALSE;
/*
* If we only deferred the destroy because we wanted to cache
* the data, destroy now.
*/
dns_db_detachnode(fctx->cache, &node);
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
if (SHUTTINGDOWN(fctx))
- maybe_destroy(fctx, ISC_FALSE); /* Locks bucket. */
+ bucket_empty = maybe_destroy(fctx, ISC_TRUE);
+ UNLOCK(&res->buckets[fctx->bucketnum].lock);
+ if (bucket_empty)
+ empty_bucket(res);
goto cleanup_event;
}
@@ -4241,7 +4234,7 @@ validated(isc_task_t *task, isc_event_t *event) {
* be validated.
*/
dns_db_detachnode(fctx->cache, &node);
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ UNLOCK(&res->buckets[fctx->bucketnum].lock);
dns_validator_send(ISC_LIST_HEAD(fctx->validators));
goto cleanup_event;
}
@@ -4316,7 +4309,7 @@ validated(isc_task_t *task, isc_event_t *event) {
if (node != NULL)
dns_db_detachnode(fctx->cache, &node);
- UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ UNLOCK(&res->buckets[fctx->bucketnum].lock);
fctx_done(fctx, result, __LINE__); /* Locks bucket. */
cleanup_event:
@@ -6580,25 +6573,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
}
goto done;
-#if 0
- } else if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0 &&
- (query->options & DNS_FETCHOPT_CACHENOEDNS) != 0 &&
- triededns512(fctx, &query->addrinfo->sockaddr)) {
- char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
- sizeof(addrbuf));
- /*
- * We had a successful response to a DNS_FETCHOPT_NOEDNS0
- * query.
- */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
- "%s: setting NOEDNS flag in adb cache for '%s'",
- fctx->info, addrbuf);
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
-#endif
}
message = fctx->rmessage;
@@ -6742,10 +6716,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
sizeof(addrbuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
- "%s: changed rcode: setting NOEDNS flag in "
- "adb cache for '%s'", fctx->info, addrbuf);
dns_adb_changeflags(fctx->adb, query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);
@@ -6918,16 +6888,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
/*
- * Update the packet received sizes
- */
- if (((query->options & DNS_FETCHOPT_NOEDNS0) == 0) &&
- ((devent->attributes & DNS_DISPATCHATTR_UDP) != 0))
- dns_adb_setednssize(fctx->adb,
- query->addrinfo,
- devent->buffer.length);
-
-
- /*
* Enforce delegations only zones like NET and COM.
*/
if (!ISFORWARDER(query->addrinfo) &&
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 107bf43f..35c88c9b 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.c,v 1.34 2011-10-11 00:09:03 each Exp $ */
+/* $Id: sdlz.c,v 1.35 2011-12-22 07:15:05 marka Exp $ */
/*! \file */
@@ -1860,7 +1860,11 @@ dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
&lookup->callbacks);
if (result != ISC_R_SUCCESS)
isc_buffer_free(&rdatabuf);
+ if (size >= 65535)
+ break;
size *= 2;
+ if (size >= 65535)
+ size = 65535;
} while (result == ISC_R_NOSPACE);
if (result != ISC_R_SUCCESS)
diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in
index 17d0ca5d..8e802d73 100644
--- a/lib/dns/tests/Makefile.in
+++ b/lib/dns/tests/Makefile.in
@@ -12,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.10 2011-10-28 06:20:07 each Exp $
+# $Id: Makefile.in,v 1.12 2011-12-08 16:07:21 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -38,16 +38,23 @@ LIBS = @LIBS@ @ATFLIBS@
OBJS = dnstest.@O@
SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \
- private_test.c update_test.c zonemgr_test.c zt_test.c
+ private_test.c update_test.c zonemgr_test.c zt_test.c \
+ dbdiff_test.c
SUBDIRS =
TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \
private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \
- zt_test@EXEEXT@ dbversion_test@EXEEXT@
+ zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@
@BIND9_MAKE_RULES@
master_test@EXEEXT@: master_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ ${PERL} mkraw.pl < testdata/master/master12.data.in \
+ > testdata/master/master12.data
+ ${PERL} mkraw.pl < testdata/master/master13.data.in \
+ > testdata/master/master13.data
+ ${PERL} mkraw.pl < testdata/master/master14.data.in \
+ > testdata/master/master14.data
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
master_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS}
@@ -77,6 +84,11 @@ dbiterator_test@EXEEXT@: dbiterator_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPL
dbiterator_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS}
+dbdiff_test@EXEEXT@: dbdiff_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ dbdiff_test.@O@ dnstest.@O@ ${DNSLIBS} \
+ ${ISCLIBS} ${LIBS}
+
dbversion_test@EXEEXT@: dbversion_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
dbversion_test.@O@ dnstest.@O@ ${DNSLIBS} \
@@ -93,3 +105,5 @@ unit::
clean distclean::
rm -f ${TARGETS}
rm -f atf.out
+ rm -f testdata/master/master12.data testdata/master/master13.data \
+ testdata/master/master14.data
diff --git a/lib/dns/tests/dbdiff_test.c b/lib/dns/tests/dbdiff_test.c
new file mode 100644
index 00000000..d787f5c0
--- /dev/null
+++ b/lib/dns/tests/dbdiff_test.c
@@ -0,0 +1,172 @@
+/*
+ * 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: dbdiff_test.c,v 1.2 2011-12-04 23:48:12 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <dns/db.h>
+#include <dns/dbiterator.h>
+#include <dns/name.h>
+#include <dns/journal.h>
+
+#include "dnstest.h"
+
+/*
+ * Helper functions
+ */
+
+#define BUFLEN 255
+#define BIGBUFLEN (64 * 1024)
+#define TEST_ORIGIN "test"
+
+static void
+test_create(const atf_tc_t *tc, dns_db_t **old, dns_db_t **new) {
+ isc_result_t result;
+
+ result = dns_test_loaddb(old, dns_dbtype_zone, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-old"));
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_test_loaddb(new, dns_dbtype_zone, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-new"));
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+}
+
+/*
+ * Individual unit tests
+ */
+
+ATF_TC(diffx_same);
+ATF_TC_HEAD(diffx_same, tc) {
+ atf_tc_set_md_var(tc, "descr", "dns_db_diffx of identical content");
+ atf_tc_set_md_var(tc, "X-old", "testdata/diff/zone1.data");
+ atf_tc_set_md_var(tc, "X-new", "testdata/diff/zone1.data"); }
+ATF_TC_BODY(diffx_same, tc) {
+ dns_db_t *new = NULL, *old = NULL;
+ isc_result_t result;
+ dns_diff_t diff;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ test_create(tc, &old, &new);
+
+ dns_diff_init(mctx, &diff);
+
+ result = dns_db_diffx(&diff, new, NULL, old, NULL, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_REQUIRE_EQ(ISC_LIST_EMPTY(diff.tuples), ISC_TRUE);
+
+ dns_diff_clear(&diff);
+ dns_db_detach(&new);
+ dns_db_detach(&old);
+ dns_test_end();
+}
+
+ATF_TC(diffx_add);
+ATF_TC_HEAD(diffx_add, tc) {
+ atf_tc_set_md_var(tc, "descr",
+ "dns_db_diffx of zone with record added");
+ atf_tc_set_md_var(tc, "X-old", "testdata/diff/zone1.data");
+ atf_tc_set_md_var(tc, "X-new", "testdata/diff/zone2.data");
+}
+ATF_TC_BODY(diffx_add, tc) {
+ dns_db_t *new = NULL, *old = NULL;
+ dns_difftuple_t *tuple;
+ isc_result_t result;
+ dns_diff_t diff;
+ int count = 0;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ test_create(tc, &old, &new);
+
+ dns_diff_init(mctx, &diff);
+
+ result = dns_db_diffx(&diff, new, NULL, old, NULL, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_REQUIRE_EQ(ISC_LIST_EMPTY(diff.tuples), ISC_FALSE);
+ for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ ATF_REQUIRE_EQ(tuple->op, DNS_DIFFOP_ADD);
+ count++;
+ }
+ ATF_REQUIRE_EQ(count, 1);
+
+ dns_diff_clear(&diff);
+ dns_db_detach(&new);
+ dns_db_detach(&old);
+ dns_test_end();
+}
+
+ATF_TC(diffx_remove);
+ATF_TC_HEAD(diffx_remove, tc) {
+ atf_tc_set_md_var(tc, "descr",
+ "dns_db_diffx of zone with record removed");
+ atf_tc_set_md_var(tc, "X-old", "testdata/diff/zone1.data");
+ atf_tc_set_md_var(tc, "X-new", "testdata/diff/zone3.data");
+}
+ATF_TC_BODY(diffx_remove, tc) {
+ dns_db_t *new = NULL, *old = NULL;
+ dns_difftuple_t *tuple;
+ isc_result_t result;
+ dns_diff_t diff;
+ int count = 0;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ test_create(tc, &old, &new);
+
+ dns_diff_init(mctx, &diff);
+
+ result = dns_db_diffx(&diff, new, NULL, old, NULL, NULL);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_REQUIRE_EQ(ISC_LIST_EMPTY(diff.tuples), ISC_FALSE);
+ for (tuple = ISC_LIST_HEAD(diff.tuples); tuple != NULL;
+ tuple = ISC_LIST_NEXT(tuple, link)) {
+ ATF_REQUIRE_EQ(tuple->op, DNS_DIFFOP_DEL);
+ count++;
+ }
+ ATF_REQUIRE_EQ(count, 1);
+
+ dns_diff_clear(&diff);
+ dns_db_detach(&new);
+ dns_db_detach(&old);
+ dns_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, diffx_same);
+ ATF_TP_ADD_TC(tp, diffx_add);
+ ATF_TP_ADD_TC(tp, diffx_remove);
+ return (atf_no_error());
+}
diff --git a/lib/dns/tests/dbiterator_test.c b/lib/dns/tests/dbiterator_test.c
index 12af6908..00341d55 100644
--- a/lib/dns/tests/dbiterator_test.c
+++ b/lib/dns/tests/dbiterator_test.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dbiterator_test.c,v 1.5 2011-08-29 23:44:07 marka Exp $ */
+/* $Id: dbiterator_test.c,v 1.6 2011-12-04 23:48:12 marka Exp $ */
/*! \file */
@@ -40,46 +40,6 @@
#define TEST_ORIGIN "test"
static isc_result_t
-setup_db(const char *testfile, dns_dbtype_t dbtype, dns_db_t **db) {
- 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];
-
- strcpy(origin, TEST_ORIGIN);
- len = strlen(origin);
- isc_buffer_init(&source, origin, len);
- isc_buffer_add(&source, len);
- isc_buffer_setactive(&source, len);
- isc_buffer_init(&target, name_buf, BUFLEN);
- dns_name_init(&dns_origin, NULL);
-
- result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
- 0, &target);
- if (result != ISC_R_SUCCESS)
- return(result);
-
- result = dns_db_create(mctx, "rbt", &dns_origin, dbtype,
- dns_rdataclass_in, 0, NULL, db);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * atf-run changes us to a /tmp directory, so tests
- * that access test data files must first chdir to the proper
- * location.
- */
- if (chdir(TESTS) == -1)
- return (ISC_R_FAILURE);
-
- result = dns_db_load(*db, testfile);
- return (result);
-}
-
-static isc_result_t
make_name(const char *src, dns_name_t *name) {
isc_buffer_t b;
isc_buffer_init(&b, src, strlen(src));
@@ -101,8 +61,8 @@ test_create(const atf_tc_t *tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = setup_db(atf_tc_get_md_var(tc, "X-filename"),
- dns_dbtype_cache, &db);
+ result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-filename"));
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_db_createiterator(db, 0, &iter);
@@ -150,8 +110,8 @@ test_walk(const atf_tc_t *tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = setup_db(atf_tc_get_md_var(tc, "X-filename"),
- dns_dbtype_cache, &db);
+ result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-filename"));
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_db_createiterator(db, 0, &iter);
@@ -213,8 +173,8 @@ static void test_reverse(const atf_tc_t *tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = setup_db(atf_tc_get_md_var(tc, "X-filename"),
- dns_dbtype_cache, &db);
+ result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-filename"));
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_db_createiterator(db, 0, &iter);
@@ -276,8 +236,8 @@ static void test_seek(const atf_tc_t *tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = setup_db(atf_tc_get_md_var(tc, "X-filename"),
- dns_dbtype_cache, &db);
+ result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-filename"));
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_db_createiterator(db, 0, &iter);
@@ -347,8 +307,8 @@ static void test_seek_empty(const atf_tc_t *tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = setup_db(atf_tc_get_md_var(tc, "X-filename"),
- dns_dbtype_cache, &db);
+ result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-filename"));
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_db_createiterator(db, 0, &iter);
@@ -404,8 +364,8 @@ static void test_seek_nx(const atf_tc_t *tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = setup_db(atf_tc_get_md_var(tc, "X-filename"),
- dns_dbtype_cache, &db);
+ result = dns_test_loaddb(&db, dns_dbtype_cache, TEST_ORIGIN,
+ atf_tc_get_md_var(tc, "X-filename"));
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_db_createiterator(db, 0, &iter);
diff --git a/lib/dns/tests/dnstest.c b/lib/dns/tests/dnstest.c
index 9e9af61e..a5d15a04 100644
--- a/lib/dns/tests/dnstest.c
+++ b/lib/dns/tests/dnstest.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnstest.c,v 1.8 2011-10-10 02:46:16 marka Exp $ */
+/* $Id: dnstest.c,v 1.11 2011-12-05 23:46:35 tbox Exp $ */
/*! \file */
@@ -35,6 +35,7 @@
#include <isc/timer.h>
#include <isc/util.h>
+#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/log.h>
#include <dns/name.h>
@@ -297,3 +298,27 @@ dns_test_nap(isc_uint32_t usec) {
sleep((usec / 1000000) + 1);
#endif
}
+
+isc_result_t
+dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin,
+ const char *testfile)
+{
+ isc_result_t result;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
+
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+
+ result = dns_name_fromstring(name, origin, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ return(result);
+
+ result = dns_db_create(mctx, "rbt", name, dbtype, dns_rdataclass_in,
+ 0, NULL, db);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dns_db_load(*db, testfile);
+ return (result);
+}
diff --git a/lib/dns/tests/dnstest.h b/lib/dns/tests/dnstest.h
index 8bddd410..bdd4b09d 100644
--- a/lib/dns/tests/dnstest.h
+++ b/lib/dns/tests/dnstest.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnstest.h,v 1.4 2011-09-02 21:15:37 each Exp $ */
+/* $Id: dnstest.h,v 1.6 2011-12-05 23:46:35 tbox Exp $ */
/*! \file */
@@ -75,3 +75,7 @@ dns_test_closezonemgr(void);
void
dns_test_nap(isc_uint32_t usec);
+
+isc_result_t
+dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin,
+ const char *testfile);
diff --git a/lib/dns/tests/master_test.c b/lib/dns/tests/master_test.c
index afe6eaa4..db93b203 100644
--- a/lib/dns/tests/master_test.c
+++ b/lib/dns/tests/master_test.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master_test.c,v 1.6 2011-09-07 19:11:14 each Exp $ */
+/* $Id: master_test.c,v 1.7 2011-12-08 16:07:22 each Exp $ */
/*! \file */
@@ -26,6 +26,7 @@
#include <dns/cache.h>
#include <dns/callbacks.h>
+#include <dns/db.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/name.h>
@@ -43,9 +44,15 @@
#define BIGBUFLEN (64 * 1024)
#define TEST_ORIGIN "test"
+static dns_masterrawheader_t header;
+static isc_boolean_t headerset;
+
static isc_result_t
add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset);
+static void
+rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *header);
+
static isc_result_t
add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) {
char buf[BIGBUFLEN];
@@ -60,8 +67,15 @@ add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) {
return(result);
}
+static void
+rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *h) {
+ UNUSED(zone);
+ header = *h;
+ headerset = ISC_TRUE;
+}
+
static int
-test_master(const char *testfile) {
+test_master(const char *testfile, dns_masterformat_t format) {
isc_result_t result;
int len;
char origin[sizeof(TEST_ORIGIN)];
@@ -78,6 +92,7 @@ test_master(const char *testfile) {
isc_buffer_setactive(&source, len);
isc_buffer_init(&target, name_buf, BUFLEN);
dns_name_init(&dns_origin, NULL);
+ dns_master_initrawheader(&header);
result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
0, &target);
@@ -86,10 +101,12 @@ test_master(const char *testfile) {
dns_rdatacallbacks_init_stdio(&callbacks);
callbacks.add = add_callback;
-
- result = dns_master_loadfile(testfile, &dns_origin, &dns_origin,
- dns_rdataclass_in, ISC_TRUE,
- &callbacks, mctx);
+ callbacks.rawdata = rawdata_callback;
+ callbacks.zone = NULL;
+ headerset = ISC_FALSE;
+ result = dns_master_loadfile2(testfile, &dns_origin, &dns_origin,
+ dns_rdataclass_in, ISC_TRUE,
+ &callbacks, mctx, format);
return (result);
}
@@ -98,12 +115,12 @@ test_master(const char *testfile) {
*/
/* Successful load test */
-ATF_TC(master_load);
-ATF_TC_HEAD(master_load, tc) {
+ATF_TC(load);
+ATF_TC_HEAD(load, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a "
"valid master file and returns success");
}
-ATF_TC_BODY(master_load, tc) {
+ATF_TC_BODY(load, tc) {
isc_result_t result;
UNUSED(tc);
@@ -111,7 +128,8 @@ ATF_TC_BODY(master_load, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master1.data");
+ result = test_master("testdata/master/master1.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
@@ -119,13 +137,13 @@ ATF_TC_BODY(master_load, tc) {
/* Unepxected end of file test */
-ATF_TC(master_unexpected);
-ATF_TC_HEAD(master_unexpected, tc) {
+ATF_TC(unexpected);
+ATF_TC_HEAD(unexpected, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns "
"DNS_R_UNEXPECTED when file ends "
"too soon");
}
-ATF_TC_BODY(master_unexpected, tc) {
+ATF_TC_BODY(unexpected, tc) {
isc_result_t result;
UNUSED(tc);
@@ -133,7 +151,8 @@ ATF_TC_BODY(master_unexpected, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master2.data");
+ result = test_master("testdata/master/master2.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_UNEXPECTEDEND);
dns_test_end();
@@ -141,13 +160,13 @@ ATF_TC_BODY(master_unexpected, tc) {
/* No owner test */
-ATF_TC(master_noowner);
-ATF_TC_HEAD(master_noowner, tc) {
+ATF_TC(noowner);
+ATF_TC_HEAD(noowner, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() accepts broken "
"zones with no TTL for first record "
"if it is an SOA");
}
-ATF_TC_BODY(master_noowner, tc) {
+ATF_TC_BODY(noowner, tc) {
isc_result_t result;
UNUSED(tc);
@@ -155,7 +174,8 @@ ATF_TC_BODY(master_noowner, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master3.data");
+ result = test_master("testdata/master/master3.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_NOOWNER);
dns_test_end();
@@ -163,14 +183,14 @@ ATF_TC_BODY(master_noowner, tc) {
/* No TTL test */
-ATF_TC(master_nottl);
-ATF_TC_HEAD(master_nottl, tc) {
+ATF_TC(nottl);
+ATF_TC_HEAD(nottl, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns "
"DNS_R_NOOWNER when no owner name "
"is specified");
}
-ATF_TC_BODY(master_nottl, tc) {
+ATF_TC_BODY(nottl, tc) {
isc_result_t result;
UNUSED(tc);
@@ -178,7 +198,8 @@ ATF_TC_BODY(master_nottl, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master4.data");
+ result = test_master("testdata/master/master4.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
@@ -186,13 +207,13 @@ ATF_TC_BODY(master_nottl, tc) {
/* Bad class test */
-ATF_TC(master_badclass);
-ATF_TC_HEAD(master_badclass, tc) {
+ATF_TC(badclass);
+ATF_TC_HEAD(badclass, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns "
"DNS_R_BADCLASS when record class "
"doesn't match zone class");
}
-ATF_TC_BODY(master_badclass, tc) {
+ATF_TC_BODY(badclass, tc) {
isc_result_t result;
UNUSED(tc);
@@ -200,19 +221,20 @@ ATF_TC_BODY(master_badclass, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master5.data");
+ result = test_master("testdata/master/master5.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_BADCLASS);
dns_test_end();
}
/* DNSKEY test */
-ATF_TC(master_dnskey);
-ATF_TC_HEAD(master_dnskey, tc) {
+ATF_TC(dnskey);
+ATF_TC_HEAD(dnskey, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"DNSKEY with key material");
}
-ATF_TC_BODY(master_dnskey, tc) {
+ATF_TC_BODY(dnskey, tc) {
isc_result_t result;
UNUSED(tc);
@@ -220,7 +242,8 @@ ATF_TC_BODY(master_dnskey, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master6.data");
+ result = test_master("testdata/master/master6.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
@@ -228,12 +251,12 @@ ATF_TC_BODY(master_dnskey, tc) {
/* DNSKEY with no key material test */
-ATF_TC(master_dnsnokey);
-ATF_TC_HEAD(master_dnsnokey, tc) {
+ATF_TC(dnsnokey);
+ATF_TC_HEAD(dnsnokey, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"DNSKEY with no key material");
}
-ATF_TC_BODY(master_dnsnokey, tc) {
+ATF_TC_BODY(dnsnokey, tc) {
isc_result_t result;
UNUSED(tc);
@@ -241,19 +264,20 @@ ATF_TC_BODY(master_dnsnokey, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master7.data");
+ result = test_master("testdata/master/master7.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
}
/* Include test */
-ATF_TC(master_include);
-ATF_TC_HEAD(master_include, tc) {
+ATF_TC(include);
+ATF_TC_HEAD(include, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"$INCLUDE");
}
-ATF_TC_BODY(master_include, tc) {
+ATF_TC_BODY(include, tc) {
isc_result_t result;
UNUSED(tc);
@@ -261,19 +285,20 @@ ATF_TC_BODY(master_include, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master8.data");
+ result = test_master("testdata/master/master8.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_SEENINCLUDE);
dns_test_end();
}
/* Include failure test */
-ATF_TC(master_includefail);
-ATF_TC_HEAD(master_includefail, tc) {
+ATF_TC(includefail);
+ATF_TC_HEAD(includefail, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"$INCLUDE failures");
}
-ATF_TC_BODY(master_includefail, tc) {
+ATF_TC_BODY(includefail, tc) {
isc_result_t result;
UNUSED(tc);
@@ -281,7 +306,8 @@ ATF_TC_BODY(master_includefail, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master9.data");
+ result = test_master("testdata/master/master9.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_BADCLASS);
dns_test_end();
@@ -289,12 +315,12 @@ ATF_TC_BODY(master_includefail, tc) {
/* Non-empty blank lines test */
-ATF_TC(master_blanklines);
-ATF_TC_HEAD(master_blanklines, tc) {
+ATF_TC(blanklines);
+ATF_TC_HEAD(blanklines, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() handles "
"non-empty blank lines");
}
-ATF_TC_BODY(master_blanklines, tc) {
+ATF_TC_BODY(blanklines, tc) {
isc_result_t result;
UNUSED(tc);
@@ -302,19 +328,20 @@ ATF_TC_BODY(master_blanklines, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master10.data");
+ result = test_master("testdata/master/master10.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
}
/* SOA leading zeroes test */
-ATF_TC(master_leadingzero);
-ATF_TC_HEAD(master_leadingzero, tc) {
+ATF_TC(leadingzero);
+ATF_TC_HEAD(leadingzero, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() allows "
"leading zeroes in SOA");
}
-ATF_TC_BODY(master_leadingzero, tc) {
+ATF_TC_BODY(leadingzero, tc) {
isc_result_t result;
UNUSED(tc);
@@ -322,17 +349,18 @@ ATF_TC_BODY(master_leadingzero, tc) {
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master11.data");
+ result = test_master("testdata/master/master11.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
}
-ATF_TC(master_totext);
-ATF_TC_HEAD(master_totext, tc) {
+ATF_TC(totext);
+ATF_TC_HEAD(totext, tc) {
atf_tc_set_md_var(tc, "descr", "masterfile totext tests");
}
-ATF_TC_BODY(master_totext, tc) {
+ATF_TC_BODY(totext, tc) {
isc_result_t result;
dns_rdataset_t rdataset;
dns_rdatalist_t rdatalist;
@@ -372,22 +400,136 @@ ATF_TC_BODY(master_totext, tc) {
dns_test_end();
}
+/* Raw load */
+ATF_TC(loadraw);
+ATF_TC_HEAD(loadraw, tc) {
+ atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a "
+ "valid raw file and returns success");
+}
+ATF_TC_BODY(loadraw, tc) {
+ isc_result_t result;
+
+ UNUSED(tc);
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /* Raw format version 0 */
+ result = test_master("testdata/master/master12.data",
+ dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK_EQ(header.flags, 0);
+
+ /* Raw format version 1, no source serial */
+ result = test_master("testdata/master/master13.data",
+ dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK_EQ(header.flags, 0);
+
+ /* Raw format version 1, source serial == 2011120101 */
+ result = test_master("testdata/master/master14.data",
+ dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0);
+ ATF_CHECK_EQ(header.sourceserial, 2011120101);
+
+ dns_test_end();
+}
+
+/* Raw dump*/
+ATF_TC(dumpraw);
+ATF_TC_HEAD(dumpraw, tc) {
+ atf_tc_set_md_var(tc, "descr", "dns_master_dump*() functions "
+ "dump valid raw files");
+}
+ATF_TC_BODY(dumpraw, tc) {
+ isc_result_t result;
+ dns_db_t *db = NULL;
+ dns_dbversion_t *version = NULL;
+ char origin[sizeof(TEST_ORIGIN)];
+ dns_name_t dns_origin;
+ isc_buffer_t source, target;
+ unsigned char name_buf[BUFLEN];
+ int len;
+
+ UNUSED(tc);
+
+ strcpy(origin, TEST_ORIGIN);
+ len = strlen(origin);
+ isc_buffer_init(&source, origin, len);
+ isc_buffer_add(&source, len);
+ isc_buffer_setactive(&source, len);
+ isc_buffer_init(&target, name_buf, BUFLEN);
+ dns_name_init(&dns_origin, NULL);
+ result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
+ 0, &target);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_create(mctx, "rbt", &dns_origin, dns_dbtype_zone,
+ dns_rdataclass_in, 0, NULL, &db);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_load(db, "testdata/master/master1.data");
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ dns_db_currentversion(db, &version);
+
+ result = dns_master_dump2(mctx, db, version,
+ &dns_master_style_default, "test.dump",
+ dns_masterformat_raw);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = test_master("test.dump", dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK_EQ(header.flags, 0);
+
+ dns_master_initrawheader(&header);
+ header.sourceserial = 12345;
+ header.flags |= DNS_MASTERRAW_SOURCESERIALSET;
+
+ unlink("test.dump");
+ result = dns_master_dump3(mctx, db, version,
+ &dns_master_style_default, "test.dump",
+ dns_masterformat_raw, &header);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = test_master("test.dump", dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0);
+ ATF_CHECK_EQ(header.sourceserial, 12345);
+
+ unlink("test.dump");
+ dns_db_closeversion(db, &version, ISC_FALSE);
+ dns_db_detach(&db);
+ dns_test_end();
+}
+
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
- ATF_TP_ADD_TC(tp, master_load);
- ATF_TP_ADD_TC(tp, master_unexpected);
- ATF_TP_ADD_TC(tp, master_noowner);
- ATF_TP_ADD_TC(tp, master_nottl);
- ATF_TP_ADD_TC(tp, master_badclass);
- ATF_TP_ADD_TC(tp, master_dnskey);
- ATF_TP_ADD_TC(tp, master_dnsnokey);
- ATF_TP_ADD_TC(tp, master_include);
- ATF_TP_ADD_TC(tp, master_includefail);
- ATF_TP_ADD_TC(tp, master_blanklines);
- ATF_TP_ADD_TC(tp, master_leadingzero);
- ATF_TP_ADD_TC(tp, master_totext);
+ ATF_TP_ADD_TC(tp, load);
+ ATF_TP_ADD_TC(tp, unexpected);
+ ATF_TP_ADD_TC(tp, noowner);
+ ATF_TP_ADD_TC(tp, nottl);
+ ATF_TP_ADD_TC(tp, badclass);
+ ATF_TP_ADD_TC(tp, dnskey);
+ ATF_TP_ADD_TC(tp, dnsnokey);
+ ATF_TP_ADD_TC(tp, include);
+ ATF_TP_ADD_TC(tp, includefail);
+ ATF_TP_ADD_TC(tp, blanklines);
+ ATF_TP_ADD_TC(tp, leadingzero);
+ ATF_TP_ADD_TC(tp, totext);
+ ATF_TP_ADD_TC(tp, loadraw);
+ ATF_TP_ADD_TC(tp, dumpraw);
return (atf_no_error());
}
diff --git a/lib/dns/tests/mkraw.pl b/lib/dns/tests/mkraw.pl
new file mode 100644
index 00000000..31fa1b0d
--- /dev/null
+++ b/lib/dns/tests/mkraw.pl
@@ -0,0 +1,31 @@
+#!/usr/bin/perl -w
+#
+# 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: mkraw.pl,v 1.2 2011-12-08 16:07:22 each Exp $
+
+# Convert a hexdump to binary format.
+#
+# To convert binary data to the input format for this command,
+# use the following:
+#
+# perl -e 'while (read(STDIN, my $byte, 1)) {
+# print unpack("H2", $byte);
+# }
+# print "\n";' < file > file.in
+
+use strict;
+chomp(my $line = <STDIN>);
+print pack("H*", $line);
diff --git a/lib/dns/tests/testdata/diff/zone1.data b/lib/dns/tests/testdata/diff/zone1.data
new file mode 100644
index 00000000..a3e0a1db
--- /dev/null
+++ b/lib/dns/tests/testdata/diff/zone1.data
@@ -0,0 +1,20 @@
+; 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: zone1.data,v 1.3 2011-12-06 23:46:31 tbox Exp $
+
+@ 0 SOA . . 0 0 0 0 0
+@ 0 NS @
+@ 0 A 1.2.3.4
+remove 0 A 5.6.7.8
diff --git a/lib/dns/tests/testdata/diff/zone2.data b/lib/dns/tests/testdata/diff/zone2.data
new file mode 100644
index 00000000..2de15a0a
--- /dev/null
+++ b/lib/dns/tests/testdata/diff/zone2.data
@@ -0,0 +1,21 @@
+; 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: zone2.data,v 1.3 2011-12-06 23:46:32 tbox Exp $
+
+@ 0 SOA . . 0 0 0 0 0
+@ 0 NS @
+@ 0 A 1.2.3.4
+remove 0 A 5.6.7.8
+added 0 A 5.6.7.8
diff --git a/lib/dns/tests/testdata/diff/zone3.data b/lib/dns/tests/testdata/diff/zone3.data
new file mode 100644
index 00000000..f31960b3
--- /dev/null
+++ b/lib/dns/tests/testdata/diff/zone3.data
@@ -0,0 +1,19 @@
+; 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: zone3.data,v 1.3 2011-12-06 23:46:32 tbox Exp $
+
+@ 0 SOA . . 0 0 0 0 0
+@ 0 NS @
+@ 0 A 1.2.3.4
diff --git a/lib/dns/tests/testdata/master/master1.data b/lib/dns/tests/testdata/master/master1.data
index 9b814740..030bc689 100644
--- a/lib/dns/tests/testdata/master/master1.data
+++ b/lib/dns/tests/testdata/master/master1.data
@@ -5,7 +5,7 @@ $TTL 1000
1800 ;retry
604800 ;expiration
3600 ) ;minimum
-a in ns ns.vix.com.
-a in ns ns2vix.com.
-a in ns ns3vix.com.
+ in ns ns.vix.com.
+ in ns ns2.vix.com.
+ in ns ns3.vix.com.
b in a 1.2.3.4
diff --git a/lib/dns/tests/testdata/master/master12.data.in b/lib/dns/tests/testdata/master/master12.data.in
new file mode 100644
index 00000000..36343882
--- /dev/null
+++ b/lib/dns/tests/testdata/master/master12.data.in
@@ -0,0 +1 @@
+00000002000000004ed7306600000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
diff --git a/lib/dns/tests/testdata/master/master13.data.in b/lib/dns/tests/testdata/master/master13.data.in
new file mode 100644
index 00000000..d1c262f0
--- /dev/null
+++ b/lib/dns/tests/testdata/master/master13.data.in
@@ -0,0 +1 @@
+00000002000000014ed7337f00000000000000000000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
diff --git a/lib/dns/tests/testdata/master/master14.data.in b/lib/dns/tests/testdata/master/master14.data.in
new file mode 100644
index 00000000..149a25f3
--- /dev/null
+++ b/lib/dns/tests/testdata/master/master14.data.in
@@ -0,0 +1 @@
+00000002000000014ed7337f0000000277df41e50000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def
index 7ddceb0b..615d068f 100644
--- a/lib/dns/win32/libdns.def
+++ b/lib/dns/win32/libdns.def
@@ -99,6 +99,7 @@ dns_db_deleterdataset
dns_db_detach
dns_db_detachnode
dns_db_diff
+dns_db_diffx
dns_db_dump
dns_db_endload
dns_db_expirenode
@@ -242,6 +243,7 @@ dns_journal_current_rr
dns_journal_destroy
dns_journal_first_rr
dns_journal_first_serial
+dns_journal_get_sourceserial
dns_journal_iter_init
dns_journal_last_serial
dns_journal_next_rr
@@ -249,6 +251,7 @@ dns_journal_open
dns_journal_print
dns_journal_rollforward
dns_journal_rollforward2
+dns_journal_set_sourceserial
dns_journal_write_transaction
dns_journal_writediff
dns_keydata_fromdnskey
@@ -286,11 +289,18 @@ dns_lookup_cancel
dns_lookup_create
dns_lookup_destroy
dns_master_dump
+dns_master_dump2
+dns_master_dump3
+dns_master_dumpinc
+dns_master_dumpinc2
+dns_master_dumpinc3
dns_master_dumpnode
dns_master_dumpnodetostream
dns_master_dumptostream
dns_master_dumptostream2
+dns_master_dumptostream3
dns_master_dumptostreaminc
+dns_master_initrawheader
dns_master_loadbuffer
dns_master_loadbufferinc
dns_master_loadfile
@@ -779,6 +789,7 @@ dns_zone_dlzpostload
dns_zone_dump
dns_zone_dumptostream
dns_zone_dumptostream2
+dns_zone_dumptostream3
dns_zone_expire
dns_zone_first
dns_zone_flush
@@ -892,6 +903,7 @@ dns_zone_setorigin
dns_zone_setprivatetype
dns_zone_setqueryacl
dns_zone_setqueryonacl
+dns_zone_setrawdata
dns_zone_setrefreshkeyinterval
dns_zone_setrequestixfr
dns_zone_setrequeststats
diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
index e0a23ecc..b433d39e 100644
--- a/lib/dns/xfrin.c
+++ b/lib/dns/xfrin.c
@@ -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:
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 541d5e9e..30e35227 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.647 2011-11-04 05:51:01 each Exp $ */
+/* $Id: zone.c,v 1.658 2011-12-22 07:32:41 each Exp $ */
/*! \file */
@@ -363,6 +363,9 @@ struct dns_zone {
dns_zone_t *raw;
dns_zone_t *secure;
+
+ isc_boolean_t sourceserialset;
+ isc_uint32_t sourceserial;
};
#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
@@ -652,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
@@ -709,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")
@@ -896,6 +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->sourceserial = 0;
+ zone->sourceserialset = ISC_FALSE;
zone->magic = ZONE_MAGIC;
@@ -1034,6 +1041,28 @@ zone_free(dns_zone_t *zone) {
}
/*
+ * 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.
*/
void
@@ -1061,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);
}
@@ -1254,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);
@@ -1293,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);
@@ -1465,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;
@@ -1718,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. */
@@ -1788,8 +1821,7 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
result = dns_master_loadfileinc3(load->zone->masterfile,
dns_db_origin(load->db),
dns_db_origin(load->db),
- load->zone->rdclass,
- options,
+ load->zone->rdclass, options,
load->zone->sigresigninginterval,
&load->callbacks, task,
zone_loaddone, load,
@@ -1805,11 +1837,28 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
}
static void
+get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
+ isc_result_t result;
+
+ LOCK(&raw->lock);
+ if (raw->db != NULL) {
+ result = zone_get_from_db(raw, raw->db, NULL, NULL,
+ &rawdata->sourceserial,
+ NULL, NULL, NULL, NULL,
+ NULL);
+ if (result == ISC_R_SUCCESS)
+ rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
+ }
+ UNLOCK(&raw->lock);
+}
+
+static void
zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
const char me[] = "zone_gotwritehandle";
dns_zone_t *zone = event->ev_arg;
isc_result_t result = ISC_R_SUCCESS;
dns_dbversion_t *version = NULL;
+ dns_masterrawheader_t rawdata;
REQUIRE(DNS_ZONE_VALID(zone));
INSIST(task == zone->task);
@@ -1824,10 +1873,14 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
LOCK_ZONE(zone);
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
dns_db_currentversion(zone->db, &version);
- result = dns_master_dumpinc2(zone->mctx, zone->db, version,
+ dns_master_initrawheader(&rawdata);
+ if (inline_secure(zone))
+ get_raw_serial(zone->raw, &rawdata);
+ result = dns_master_dumpinc3(zone->mctx, zone->db, version,
&dns_master_style_default,
zone->masterfile, zone->task, dump_done,
- zone, &zone->dctx, zone->masterformat);
+ zone, &zone->dctx, zone->masterformat,
+ &rawdata);
dns_db_closeversion(zone->db, &version, ISC_FALSE);
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
UNLOCK_ZONE(zone);
@@ -1839,6 +1892,31 @@ 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;
+
+ LOCK_ZONE(zone);
+ zone_setrawdata(zone, header);
+ UNLOCK_ZONE(zone);
+}
+
static isc_result_t
zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
dns_load_t *load;
@@ -1866,6 +1944,8 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
zone_iattach(zone, &load->zone);
dns_db_attach(db, &load->db);
dns_rdatacallbacks_init(&load->callbacks);
+ load->callbacks.rawdata = zone_setrawdata;
+ zone_iattach(zone, &load->callbacks.zone);
result = dns_db_beginload(db, &load->callbacks.add,
&load->callbacks.add_private);
if (result != ISC_R_SUCCESS)
@@ -1887,18 +1967,24 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
dns_rdatacallbacks_t callbacks;
dns_rdatacallbacks_init(&callbacks);
+ callbacks.rawdata = zone_setrawdata;
+ zone_iattach(zone, &callbacks.zone);
result = dns_db_beginload(db, &callbacks.add,
&callbacks.add_private);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ zone_idetach(&callbacks.zone);
return (result);
- result = dns_master_loadfile3(zone->masterfile, &zone->origin,
- &zone->origin, zone->rdclass,
- options, zone->sigresigninginterval,
+ }
+ result = dns_master_loadfile3(zone->masterfile,
+ &zone->origin, &zone->origin,
+ zone->rdclass, options,
+ zone->sigresigninginterval,
&callbacks, zone->mctx,
zone->masterformat);
tresult = dns_db_endload(db, &callbacks.add_private);
if (result == ISC_R_SUCCESS)
result = tresult;
+ zone_idetach(&callbacks.zone);
}
return (result);
@@ -1907,6 +1993,7 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
load->magic = 0;
dns_db_detach(&load->db);
zone_idetach(&load->zone);
+ zone_idetach(&load->callbacks.zone);
isc_mem_detach(&load->mctx);
isc_mem_put(zone->mctx, load, sizeof(*load));
return (result);
@@ -3227,37 +3314,39 @@ update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
* Write all transactions in 'diff' to the zone journal file.
*/
static isc_result_t
-zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *bitws,
+zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
const char *caller)
{
const char me[] = "zone_journal";
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 (bitws != NULL)
- dns_journal_set_bitws(journal, *bitws);
+
+ 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);
}
@@ -3460,15 +3549,54 @@ 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);
}
+static isc_boolean_t
+zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
+ isc_result_t result;
+ isc_boolean_t answer = ISC_FALSE;
+ dns_diff_t diff;
+
+ dns_diff_init(mctx, &diff);
+ result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
+ if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
+ answer = ISC_TRUE;
+ dns_diff_clear(&diff);
+ 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)
@@ -3505,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 &&
@@ -3608,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);
@@ -3700,6 +3829,14 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
INSIST(zone->type == dns_zone_master);
+ if (serial == oldserial &&
+ zone_unchanged(zone->db, db, zone->mctx)) {
+ dns_zone_log(zone, ISC_LOG_INFO,
+ "ixfr-from-differences: "
+ "unchanged");
+ return(ISC_R_SUCCESS);
+ }
+
serialmin = (oldserial + 1) & 0xffffffffU;
serialmax = (oldserial + 0x7fffffffU) &
0xffffffffU;
@@ -3766,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:
@@ -3818,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) {
@@ -4732,6 +4883,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone,
/*
* Everything is ok so attach to the zone.
*/
+ zone->curmaster = 0;
zone->mastersok = newok;
zone->masters = newaddrs;
zone->masterkeynames = newnames;
@@ -8413,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,
@@ -8424,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 */
}
@@ -8616,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;
@@ -8735,10 +8888,15 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
result = DNS_R_CONTINUE;
UNLOCK_ZONE(zone);
} else {
+ dns_masterrawheader_t rawdata;
dns_db_currentversion(db, &version);
- result = dns_master_dump2(zone->mctx, db, version,
+ dns_master_initrawheader(&rawdata);
+ if (inline_secure(zone))
+ get_raw_serial(zone->raw, &rawdata);
+ result = dns_master_dump3(zone->mctx, db, version,
&dns_master_style_default,
- masterfile, masterformat);
+ masterfile, masterformat,
+ &rawdata);
dns_db_closeversion(db, &version, ISC_FALSE);
}
fail:
@@ -8777,11 +8935,12 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
static isc_result_t
dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
- dns_masterformat_t format)
+ dns_masterformat_t format, const isc_uint32_t rawversion)
{
isc_result_t result;
dns_dbversion_t *version = NULL;
dns_db_t *db = NULL;
+ dns_masterrawheader_t rawdata;
REQUIRE(DNS_ZONE_VALID(zone));
@@ -8793,29 +8952,46 @@ dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
return (DNS_R_NOTLOADED);
dns_db_currentversion(db, &version);
- result = dns_master_dumptostream2(zone->mctx, db, version, style,
- format, fd);
+ dns_master_initrawheader(&rawdata);
+ if (rawversion == 0)
+ rawdata.flags |= DNS_MASTERRAW_COMPAT;
+ 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);
dns_db_detach(&db);
return (result);
}
isc_result_t
+dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
+ const dns_master_style_t *style,
+ const isc_uint32_t rawversion)
+{
+ return (dumptostream(zone, fd, style, format, rawversion));
+}
+
+isc_result_t
dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
const dns_master_style_t *style) {
- return dumptostream(zone, fd, style, format);
+ return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
}
isc_result_t
dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
- return dumptostream(zone, fd, &dns_master_style_default,
- dns_masterformat_text);
+ return (dumptostream(zone, fd, &dns_master_style_default,
+ dns_masterformat_text, 0));
}
isc_result_t
dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
- return dumptostream(zone, fd, &dns_master_style_full,
- dns_masterformat_text);
+ return (dumptostream(zone, fd, &dns_master_style_full,
+ dns_masterformat_text, 0));
}
void
@@ -10887,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;
}
@@ -11263,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);
@@ -11674,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';
@@ -11995,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;
};
@@ -12006,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;
-
- zone = event->ev_arg;
- end = ((struct secure_serial *)event)->serial;
-
- dns_diff_init(zone->mctx, &diff);
-
- 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_bitws(rjournal);
- if (sjournal != NULL) {
- isc_uint32_t serial = dns_journal_get_bitws(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);
- }
+ int n_soa = 0;
- if (start == end)
- goto failure;
- CHECK(dns_journal_iter_init(rjournal, start, end));
+ REQUIRE(soatuplep != NULL);
- dns_db_attach(zone->db, &db);
- dns_db_currentversion(db, &oldver);
- CHECK(dns_db_newversion(db, &newver));
+ if (start == end)
+ return (DNS_R_UNCHANGED);
- 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 &&
@@ -12104,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));
@@ -12140,12 +12414,14 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial"));
- dns_journal_set_bitws(rjournal, end);
+ dns_journal_set_sourceserial(rjournal, end);
dns_journal_commit(rjournal);
LOCK_ZONE(zone);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
+ zone->sourceserial = end;
+ zone->sourceserialset = ISC_TRUE;
zone_needdump(zone, DNS_DUMP_DELAY);
TIME_NOW(&timenow);
@@ -12157,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)
@@ -12172,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;
@@ -12216,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);
@@ -12301,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);
@@ -12384,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");
@@ -12443,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) {
/*
@@ -12495,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);
@@ -12648,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);
}
/*
@@ -12802,6 +13092,7 @@ zone_loaddone(void *arg, isc_result_t result) {
(void)zone_postload(load->zone, load->db, load->loadtime, result);
zonemgr_putio(&load->zone->readio);
DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
+ zone_idetach(&load->callbacks.zone);
/*
* Leave the zone frozen if the reload fails.
*/
@@ -13949,8 +14240,9 @@ zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
if (result != ISC_R_SUCCESS)
goto cleanup;
- dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
- path, buf);
+ dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
+ "renaming file to '%s' for failure analysis and "
+ "retransferring.", path, buf);
cleanup:
isc_mem_put(zone->mctx, buf, buflen);
@@ -14985,6 +15277,9 @@ zone_rekey(dns_zone_t *zone) {
CHECK(dns_db_newversion(db, &ver));
CHECK(dns_db_getoriginnode(db, &node));
+ TIME_NOW(&timenow);
+ now = isc_time_seconds(&timenow);
+
dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
/* Get the SOA record's TTL */
@@ -15084,7 +15379,6 @@ zone_rekey(dns_zone_t *zone) {
dns_db_closeversion(db, &ver, commit);
if (commit) {
- isc_time_t timenow;
dns_difftuple_t *tuple;
LOCK_ZONE(zone);
@@ -15092,7 +15386,6 @@ zone_rekey(dns_zone_t *zone) {
zone_needdump(zone, DNS_DUMP_DELAY);
- TIME_NOW(&timenow);
zone_settimer(zone, &timenow);
/* Remove any signatures from removed keys. */
@@ -15209,13 +15502,6 @@ zone_rekey(dns_zone_t *zone) {
UNLOCK_ZONE(zone);
}
- /*
- * If we are doing automatic key maintenance and the key metadata
- * indicates there is a key change event scheduled in the future,
- * set the key refresh timer.
- */
- isc_stdtime_get(&now);
- TIME_NOW(&timenow);
isc_time_settoepoch(&zone->refreshkeytime);
/*
diff --git a/lib/dns/zt.c b/lib/dns/zt.c
index 0995377a..3751b4c4 100644
--- a/lib/dns/zt.c
+++ b/lib/dns/zt.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zt.c,v 1.56 2011-09-07 00:50:06 marka Exp $ */
+/* $Id: zt.c,v 1.59 2011-12-10 22:09:41 marka Exp $ */
/*! \file */
@@ -357,15 +357,25 @@ freezezones(dns_zone_t *zone, void *uap) {
isc_result_t result = ISC_R_SUCCESS;
char classstr[DNS_RDATACLASS_FORMATSIZE];
char zonename[DNS_NAME_FORMATSIZE];
+ dns_zone_t *raw = NULL;
dns_view_t *view;
const char *vname;
const char *sep;
int level;
- if (dns_zone_gettype(zone) != dns_zone_master)
+ dns_zone_getraw(zone, &raw);
+ if (raw != NULL)
+ zone = raw;
+ if (dns_zone_gettype(zone) != dns_zone_master) {
+ if (raw != NULL)
+ dns_zone_detach(&raw);
return (ISC_R_SUCCESS);
- if (!dns_zone_isdynamic(zone, ISC_TRUE))
+ }
+ if (!dns_zone_isdynamic(zone, ISC_TRUE)) {
+ if (raw != NULL)
+ dns_zone_detach(&raw);
return (ISC_R_SUCCESS);
+ }
frozen = dns_zone_getupdatedisabled(zone);
if (freeze) {
@@ -402,6 +412,8 @@ freezezones(dns_zone_t *zone, void *uap) {
freeze ? "freezing" : "thawing",
zonename, classstr, sep, vname,
isc_result_totext(result));
+ if (raw != NULL)
+ dns_zone_detach(&raw);
return (result);
}
diff --git a/lib/export/irs/include/Makefile.in b/lib/export/irs/include/Makefile.in
index e6d4eae7..9dda2cff 100644
--- a/lib/export/irs/include/Makefile.in
+++ b/lib/export/irs/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 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
@@ -12,9 +12,9 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.2 2009-09-01 00:22:27 jinmei Exp $
+# $Id: Makefile.in,v 1.4 2011-12-20 23:46:27 tbox Exp $
-srcdir = @srdir@
+srcdir = @srcdir@
top_srcdir = @top_srcdir@
diff --git a/lib/export/isc/include/Makefile.in b/lib/export/isc/include/Makefile.in
index f89628b9..80a63ca6 100644
--- a/lib/export/isc/include/Makefile.in
+++ b/lib/export/isc/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 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
@@ -12,9 +12,9 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.2 2009-09-01 00:22:27 jinmei Exp $
+# $Id: Makefile.in,v 1.4 2011-12-20 23:46:27 tbox Exp $
-srcdir = @srdir@
+srcdir = @srcdir@
top_srcdir = @top_srcdir@
diff --git a/lib/export/isc/nothreads/include/Makefile.in b/lib/export/isc/nothreads/include/Makefile.in
index f89628b9..80a63ca6 100644
--- a/lib/export/isc/nothreads/include/Makefile.in
+++ b/lib/export/isc/nothreads/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 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
@@ -12,9 +12,9 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.2 2009-09-01 00:22:27 jinmei Exp $
+# $Id: Makefile.in,v 1.4 2011-12-20 23:46:27 tbox Exp $
-srcdir = @srdir@
+srcdir = @srcdir@
top_srcdir = @top_srcdir@
diff --git a/lib/export/isc/pthreads/include/Makefile.in b/lib/export/isc/pthreads/include/Makefile.in
index f89628b9..80a63ca6 100644
--- a/lib/export/isc/pthreads/include/Makefile.in
+++ b/lib/export/isc/pthreads/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 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
@@ -12,9 +12,9 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.2 2009-09-01 00:22:27 jinmei Exp $
+# $Id: Makefile.in,v 1.4 2011-12-20 23:46:27 tbox Exp $
-srcdir = @srdir@
+srcdir = @srcdir@
top_srcdir = @top_srcdir@
diff --git a/lib/export/isc/unix/include/Makefile.in b/lib/export/isc/unix/include/Makefile.in
index f89628b9..80a63ca6 100644
--- a/lib/export/isc/unix/include/Makefile.in
+++ b/lib/export/isc/unix/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 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
@@ -12,9 +12,9 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.2 2009-09-01 00:22:27 jinmei Exp $
+# $Id: Makefile.in,v 1.4 2011-12-20 23:46:27 tbox Exp $
-srcdir = @srdir@
+srcdir = @srcdir@
top_srcdir = @top_srcdir@
diff --git a/lib/export/isccfg/include/Makefile.in b/lib/export/isccfg/include/Makefile.in
index 896c4671..3b7803a7 100644
--- a/lib/export/isccfg/include/Makefile.in
+++ b/lib/export/isccfg/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 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
@@ -12,9 +12,9 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.2 2009-09-01 00:22:27 jinmei Exp $
+# $Id: Makefile.in,v 1.4 2011-12-20 23:46:29 tbox Exp $
-srcdir = @srdir@
+srcdir = @srcdir@
top_srcdir = @top_srcdir@
diff --git a/lib/isc/api b/lib/isc/api
index 6404d993..2a59ac92 100644
--- a/lib/isc/api
+++ b/lib/isc/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 90
-LIBREVISION = 1
+LIBREVISION = 2
LIBAGE = 0
diff --git a/lib/isc/include/isc/symtab.h b/lib/isc/include/isc/symtab.h
index c61d0eaf..7bb89278 100644
--- a/lib/isc/include/isc/symtab.h
+++ b/lib/isc/include/isc/symtab.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: symtab.h,v 1.26 2009-01-18 23:48:14 tbox Exp $ */
+/* $Id: symtab.h,v 1.28 2011-11-30 23:46:25 tbox Exp $ */
#ifndef ISC_SYMTAB_H
#define ISC_SYMTAB_H 1
@@ -57,6 +57,14 @@
* undefined. It can be used to free memory associated with keys and/or
* values.
*
+ * A symbol table is implemented as a hash table of lists; the size of the
+ * hash table is set by the 'size' parameter to isc_symtbl_create(). When
+ * the number of entries in the symbol table reaches three quarters of this
+ * value, the hash table is reallocated with size doubled, in order to
+ * optimize lookup performance. This has a negative effect on insertion
+ * performance, which can be mitigated by sizing the table appropriately
+ * when creating it.
+ *
* \li MP:
* The callers of this module must ensure any required synchronization.
*
diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c
index c30054fb..94a03f13 100644
--- a/lib/isc/symtab.c
+++ b/lib/isc/symtab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: symtab.c,v 1.30 2007-06-19 23:47:17 tbox Exp $ */
+/* $Id: symtab.c,v 1.34 2011-12-01 01:33:27 marka Exp $ */
/*! \file */
@@ -46,6 +46,8 @@ struct isc_symtab {
unsigned int magic;
isc_mem_t * mctx;
unsigned int size;
+ unsigned int count;
+ unsigned int maxload;
eltlist_t * table;
isc_symtabaction_t undefine_action;
void * undefine_arg;
@@ -79,6 +81,8 @@ isc_symtab_create(isc_mem_t *mctx, unsigned int size,
INIT_LIST(symtab->table[i]);
symtab->mctx = mctx;
symtab->size = size;
+ symtab->count = 0;
+ symtab->maxload = size * 3 / 4;
symtab->undefine_action = undefine_action;
symtab->undefine_arg = undefine_arg;
symtab->case_sensitive = case_sensitive;
@@ -181,6 +185,46 @@ isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type,
return (ISC_R_SUCCESS);
}
+static void
+grow_table(isc_symtab_t *symtab) {
+ eltlist_t *newtable;
+ unsigned int i, newsize, newmax;
+
+ REQUIRE(symtab != NULL);
+
+ newsize = symtab->size * 2;
+ newmax = newsize * 3 / 4;
+ INSIST(newsize > 0U && newmax > 0U);
+
+ newtable = isc_mem_get(symtab->mctx, newsize * sizeof(eltlist_t));
+ if (newtable == NULL)
+ return;
+
+ for (i = 0; i < newsize; i++)
+ INIT_LIST(newtable[i]);
+
+ for (i = 0; i < symtab->size; i++) {
+ elt_t *elt, *nelt;
+
+ for (elt = HEAD(symtab->table[i]); elt != NULL; elt = nelt) {
+ unsigned int hv;
+
+ nelt = NEXT(elt, link);
+
+ UNLINK(symtab->table[i], elt, link);
+ hv = hash(elt->key, symtab->case_sensitive);
+ APPEND(newtable[hv % newsize], elt, link);
+ }
+ }
+
+ isc_mem_put(symtab->mctx, symtab->table,
+ symtab->size * sizeof(eltlist_t));
+
+ symtab->table = newtable;
+ symtab->size = newsize;
+ symtab->maxload = newmax;
+}
+
isc_result_t
isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type,
isc_symvalue_t value, isc_symexists_t exists_policy)
@@ -208,6 +252,7 @@ isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type,
if (elt == NULL)
return (ISC_R_NOMEMORY);
ISC_LINK_INIT(elt, link);
+ symtab->count++;
}
/*
@@ -226,6 +271,9 @@ isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type,
*/
PREPEND(symtab->table[bucket], elt, link);
+ if (symtab->count > symtab->maxload)
+ grow_table(symtab);
+
return (ISC_R_SUCCESS);
}
@@ -247,6 +295,7 @@ isc_symtab_undefine(isc_symtab_t *symtab, const char *key, unsigned int type) {
elt->value, symtab->undefine_arg);
UNLINK(symtab->table[bucket], elt, link);
isc_mem_put(symtab->mctx, elt, sizeof(*elt));
+ symtab->count--;
return (ISC_R_SUCCESS);
}
diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in
index a9a64f66..280fb5c9 100644
--- a/lib/isc/tests/Makefile.in
+++ b/lib/isc/tests/Makefile.in
@@ -12,7 +12,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.8 2011-10-10 22:57:13 each Exp $
+# $Id: Makefile.in,v 1.9 2011-11-30 04:27:17 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -36,11 +36,11 @@ LIBS = @LIBS@ @ATFLIBS@
OBJS = isctest.@O@
SRCS = isctest.c taskpool_test.c socket_test.c hash_test.c \
- task_test.c queue_test.c
+ symtab_test.c task_test.c queue_test.c
SUBDIRS =
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
- task_test@EXEEXT@ queue_test@EXEEXT@
+ symtab_test@EXEEXT@ task_test@EXEEXT@ queue_test@EXEEXT@
@BIND9_MAKE_RULES@
@@ -64,6 +64,10 @@ queue_test@EXEEXT@: queue_test.@O@ isctest.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
queue_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+symtab_test@EXEEXT@: symtab_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ symtab_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
unit::
sh ${top_srcdir}/unit/unittest.sh
diff --git a/lib/isc/tests/isctest.h b/lib/isc/tests/isctest.h
index 2d5914f8..764d9d1d 100644
--- a/lib/isc/tests/isctest.h
+++ b/lib/isc/tests/isctest.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: isctest.h,v 1.4 2011-09-02 21:15:38 each Exp $ */
+/* $Id: isctest.h,v 1.5 2011-11-30 06:10:44 each Exp $ */
/*! \file */
@@ -25,6 +25,7 @@
#include <isc/hash.h>
#include <isc/log.h>
#include <isc/mem.h>
+#include <isc/print.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/task.h>
diff --git a/lib/isc/tests/socket_test.c b/lib/isc/tests/socket_test.c
index 266ea2fc..9a4e47d9 100644
--- a/lib/isc/tests/socket_test.c
+++ b/lib/isc/tests/socket_test.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket_test.c,v 1.4 2011-09-02 21:15:38 each Exp $ */
+/* $Id: socket_test.c,v 1.5 2011-11-29 01:03:47 marka Exp $ */
/*! \file */
@@ -181,12 +181,10 @@ ATF_TC_BODY(udp_dup, tc) {
result = isc_socket_create(socketmgr, PF_INET, isc_sockettype_udp, &s2);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = isc_socket_dup(s2, &s3);
- ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
-
result = isc_socket_bind(s2, &addr2, ISC_SOCKET_REUSEADDRESS);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = isc_socket_bind(s3, &addr2, ISC_SOCKET_REUSEADDRESS);
+
+ result = isc_socket_dup(s2, &s3);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task);
@@ -245,7 +243,6 @@ ATF_TC_BODY(udp_dup, tc) {
isc_test_end();
}
-
/*
* Main
*/
diff --git a/lib/isc/tests/symtab_test.c b/lib/isc/tests/symtab_test.c
new file mode 100644
index 00000000..22fbc887
--- /dev/null
+++ b/lib/isc/tests/symtab_test.c
@@ -0,0 +1,147 @@
+/*
+ * 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: symtab_test.c,v 1.3 2011-11-30 06:09:41 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <isc/symtab.h>
+#include <isc/print.h>
+
+#include "isctest.h"
+
+static void
+undefine(char *key, unsigned int type, isc_symvalue_t value, void *arg) {
+ UNUSED(arg);
+
+ ATF_REQUIRE_EQ(type, 1);
+ isc_mem_free(mctx, key);
+ isc_mem_free(mctx, value.as_pointer);
+}
+
+/*
+ * Individual unit tests
+ */
+
+ATF_TC(symtab_grow);
+ATF_TC_HEAD(symtab_grow, tc) {
+ atf_tc_set_md_var(tc, "descr", "symbol table growth");
+}
+ATF_TC_BODY(symtab_grow, tc) {
+ isc_result_t result;
+ isc_symtab_t *st = NULL;
+ isc_symvalue_t value;
+ isc_symexists_t policy = isc_symexists_reject;
+ int i;
+
+ UNUSED(tc);
+
+ result = isc_test_begin(NULL, ISC_TRUE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = isc_symtab_create(mctx, 3, undefine, NULL, ISC_FALSE, &st);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ ATF_REQUIRE(st != NULL);
+
+ /* Nothing should be in the table yet */
+
+ /*
+ * Put 1024 entries in the table (this should necessate
+ * regrowing the hash table several times
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16], *key;
+
+ snprintf(str, sizeof(str), "%04x", i);
+ key = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(key != NULL);
+ value.as_pointer = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(value.as_pointer != NULL);
+ result = isc_symtab_define(st, key, 1, value, policy);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS)
+ undefine(key, 1, value, NULL);
+ }
+
+ /*
+ * Try to put them in again; this should fail
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16], *key;
+
+ snprintf(str, sizeof(str), "%04x", i);
+ key = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(key != NULL);
+ value.as_pointer = isc_mem_strdup(mctx, str);
+ ATF_REQUIRE(value.as_pointer != NULL);
+ result = isc_symtab_define(st, key, 1, value, policy);
+ ATF_CHECK_EQ(result, ISC_R_EXISTS);
+ undefine(key, 1, value, NULL);
+ }
+
+ /*
+ * Retrieve them; this should succeed
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_lookup(st, str, 0, &value);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ ATF_CHECK_STREQ(str, value.as_pointer);
+ }
+
+ /*
+ * Undefine them
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_undefine(st, str, 1);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ }
+
+ /*
+ * Retrieve them again; this should fail
+ */
+ for (i = 0; i < 1024; i++) {
+ char str[16];
+
+ snprintf(str, sizeof(str), "%04x", i);
+ result = isc_symtab_lookup(st, str, 0, &value);
+ ATF_CHECK_EQ(result, ISC_R_NOTFOUND);
+ }
+
+ isc_symtab_destroy(&st);
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, symtab_grow);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isc/tests/task_test.c b/lib/isc/tests/task_test.c
index 5f03ff17..95d8ce58 100644
--- a/lib/isc/tests/task_test.c
+++ b/lib/isc/tests/task_test.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: task_test.c,v 1.4 2011-10-18 02:00:56 marka Exp $ */
+/* $Id: task_test.c,v 1.6 2011-12-01 22:30:37 marka Exp $ */
/*! \file */
@@ -131,7 +131,7 @@ ATF_TC_BODY(all_events, tc) {
ATF_CHECK_EQ(b, 0);
isc_task_send(task, &event);
- while (a == 0 && b == 0 && i++ < 5000) {
+ while ((a == 0 || b == 0) && i++ < 5000) {
#ifndef ISC_PLATFORM_USETHREADS
while (isc__taskmgr_ready(taskmgr))
isc__taskmgr_dispatch(taskmgr);
@@ -286,7 +286,7 @@ ATF_TC_BODY(privilege_drop, tc) {
isc_result_t result;
isc_task_t *task1 = NULL, *task2 = NULL;
isc_event_t *event;
- int a = 0, b = 0, c = 0, d = 0, e = 0;
+ int a = -1, b = -1, c = -1, d = -1, e = -1; /* non valid states */
int i = 0;
UNUSED(tc);
@@ -323,7 +323,7 @@ ATF_TC_BODY(privilege_drop, tc) {
set_and_drop, &a, sizeof (isc_event_t));
ATF_REQUIRE(event != NULL);
- ATF_CHECK_EQ(a, 0);
+ ATF_CHECK_EQ(a, -1);
isc_task_send(task1, &event);
/* Second event: not privileged */
@@ -331,7 +331,7 @@ ATF_TC_BODY(privilege_drop, tc) {
set_and_drop, &b, sizeof (isc_event_t));
ATF_REQUIRE(event != NULL);
- ATF_CHECK_EQ(b, 0);
+ ATF_CHECK_EQ(b, -1);
isc_task_send(task2, &event);
/* Third event: privileged */
@@ -339,7 +339,7 @@ ATF_TC_BODY(privilege_drop, tc) {
set_and_drop, &c, sizeof (isc_event_t));
ATF_REQUIRE(event != NULL);
- ATF_CHECK_EQ(c, 0);
+ ATF_CHECK_EQ(c, -1);
isc_task_send(task1, &event);
/* Fourth event: privileged */
@@ -347,7 +347,7 @@ ATF_TC_BODY(privilege_drop, tc) {
set_and_drop, &d, sizeof (isc_event_t));
ATF_REQUIRE(event != NULL);
- ATF_CHECK_EQ(d, 0);
+ ATF_CHECK_EQ(d, -1);
isc_task_send(task1, &event);
/* Fifth event: not privileged */
@@ -355,7 +355,7 @@ ATF_TC_BODY(privilege_drop, tc) {
set_and_drop, &e, sizeof (isc_event_t));
ATF_REQUIRE(event != NULL);
- ATF_CHECK_EQ(e, 0);
+ ATF_CHECK_EQ(e, -1);
isc_task_send(task2, &event);
ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
@@ -366,8 +366,9 @@ ATF_TC_BODY(privilege_drop, tc) {
isc__taskmgr_resume(taskmgr);
#endif
- /* We're waiting for *any* variable to be set */
- while ((a == 0 && b == 0 && c == 0 && d == 0 && e == 0) && i++ < 5000) {
+ /* We're waiting for all variables to be set. */
+ while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) &&
+ i++ < 5000) {
#ifndef ISC_PLATFORM_USETHREADS
while (isc__taskmgr_ready(taskmgr))
isc__taskmgr_dispatch(taskmgr);
@@ -400,6 +401,7 @@ ATF_TC_BODY(privilege_drop, tc) {
isc_test_end();
}
+
/*
* Main
*/
diff --git a/lib/isc/unix/errno2result.c b/lib/isc/unix/errno2result.c
index 4252de6e..3ed8e9f7 100644
--- a/lib/isc/unix/errno2result.c
+++ b/lib/isc/unix/errno2result.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: errno2result.c,v 1.17 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: errno2result.c,v 1.19 2011-12-02 23:46:56 tbox Exp $ */
/*! \file */
@@ -34,7 +34,7 @@
* not already there.
*/
isc_result_t
-isc__errno2result(int posixerrno) {
+isc___errno2result(int posixerrno, const char *file, unsigned int line) {
char strbuf[ISC_STRERRORSIZE];
switch (posixerrno) {
@@ -55,7 +55,7 @@ isc__errno2result(int posixerrno) {
return (ISC_R_IOERROR);
case ENOMEM:
return (ISC_R_NOMEMORY);
- case ENFILE:
+ case ENFILE:
case EMFILE:
return (ISC_R_TOOMANYOPENFILES);
case EPIPE:
@@ -108,8 +108,7 @@ isc__errno2result(int posixerrno) {
return (ISC_R_CONNREFUSED);
default:
isc__strerror(posixerrno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "unable to convert errno "
+ UNEXPECTED_ERROR(file, line, "unable to convert errno "
"to isc_result: %d: %s",
posixerrno, strbuf);
/*
diff --git a/lib/isc/unix/errno2result.h b/lib/isc/unix/errno2result.h
index 8770a056..4fce0379 100644
--- a/lib/isc/unix/errno2result.h
+++ b/lib/isc/unix/errno2result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: errno2result.h,v 1.12 2007-06-19 23:47:18 tbox Exp $ */
+/* $Id: errno2result.h,v 1.14 2011-12-02 23:46:56 tbox Exp $ */
#ifndef UNIX_ERRNO2RESULT_H
#define UNIX_ERRNO2RESULT_H 1
@@ -31,8 +31,10 @@
ISC_LANG_BEGINDECLS
+#define isc__errno2result(x) isc___errno2result(x, __FILE__, __LINE__)
+
isc_result_t
-isc__errno2result(int posixerrno);
+isc___errno2result(int posixerrno, const char *file, unsigned int line);
ISC_LANG_ENDDECLS
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
index 5e97b902..e24d887d 100644
--- a/lib/isc/unix/socket.c
+++ b/lib/isc/unix/socket.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.348 2011-08-25 11:37:13 marka Exp $ */
+/* $Id: socket.c,v 1.349 2011-11-29 01:03:47 marka Exp $ */
/*! \file */
@@ -2270,6 +2270,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
} else {
sock->fd = dup(dup_socket->fd);
sock->dupped = 1;
+ sock->bound = dup_socket->bound;
}
if (sock->fd == -1 && errno == EINTR && tries++ < 42)
goto again;
@@ -5028,54 +5029,55 @@ isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr,
LOCK(&sock->lock);
INSIST(!sock->bound);
+ INSIST(!sock->dupped);
if (sock->pf != sockaddr->type.sa.sa_family) {
UNLOCK(&sock->lock);
return (ISC_R_FAMILYMISMATCH);
}
- if (!sock->dupped) {
- /*
- * Only set SO_REUSEADDR when we want a specific port.
- */
+
+ /*
+ * Only set SO_REUSEADDR when we want a specific port.
+ */
#ifdef AF_UNIX
- if (sock->pf == AF_UNIX)
- goto bind_socket;
+ if (sock->pf == AF_UNIX)
+ goto bind_socket;
#endif
- if ((options & ISC_SOCKET_REUSEADDRESS) != 0 &&
- isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
- setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
- sizeof(on)) < 0) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "setsockopt(%d) %s", sock->fd,
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
- /* Press on... */
- }
+ if ((options & ISC_SOCKET_REUSEADDRESS) != 0 &&
+ isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
+ setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
+ sizeof(on)) < 0) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "setsockopt(%d) %s", sock->fd,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ /* Press on... */
+ }
#ifdef AF_UNIX
- bind_socket:
+ bind_socket:
#endif
- if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) {
- inc_stats(sock->manager->stats,
- sock->statsindex[STATID_BINDFAIL]);
+ if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) {
+ inc_stats(sock->manager->stats,
+ sock->statsindex[STATID_BINDFAIL]);
- UNLOCK(&sock->lock);
- switch (errno) {
- case EACCES:
- return (ISC_R_NOPERM);
- case EADDRNOTAVAIL:
- return (ISC_R_ADDRNOTAVAIL);
- case EADDRINUSE:
- return (ISC_R_ADDRINUSE);
- case EINVAL:
- return (ISC_R_BOUND);
- default:
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s",
- strbuf);
- return (ISC_R_UNEXPECTED);
- }
+ UNLOCK(&sock->lock);
+ switch (errno) {
+ case EACCES:
+ return (ISC_R_NOPERM);
+ case EADDRNOTAVAIL:
+ return (ISC_R_ADDRNOTAVAIL);
+ case EADDRINUSE:
+ return (ISC_R_ADDRINUSE);
+ case EINVAL:
+ return (ISC_R_BOUND);
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s",
+ strbuf);
+ return (ISC_R_UNEXPECTED);
}
}
+
socket_log(sock, sockaddr, TRACE,
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_BOUND, "bound");
sock->bound = 1;
@@ -5718,6 +5720,7 @@ isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) {
#endif
REQUIRE(VALID_SOCKET(sock));
+ INSIST(!sock->dupped);
#ifdef IPV6_V6ONLY
if (sock->pf == AF_INET6) {
diff --git a/lib/isc/unix/stdio.c b/lib/isc/unix/stdio.c
index c7aa5f42..20b37444 100644
--- a/lib/isc/unix/stdio.c
+++ b/lib/isc/unix/stdio.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: stdio.c,v 1.10 2011-03-05 23:52:31 tbox Exp $ */
+/* $Id: stdio.c,v 1.11 2011-12-22 08:49:01 marka Exp $ */
#include <config.h>
@@ -110,7 +110,11 @@ isc_stdio_sync(FILE *f) {
int r;
r = fsync(fileno(f));
- if (r == 0)
+ /*
+ * fsync is not supported on sockets and pipes which
+ * result in EINVAL / ENOTSUP.
+ */
+ if (r == 0 || errno == EINVAL || errno == ENOTSUP)
return (ISC_R_SUCCESS);
else
return (isc__errno2result(errno));
diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c
index 1484d3e4..c6426a1d 100644
--- a/lib/isc/win32/socket.c
+++ b/lib/isc/win32/socket.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.92 2011-08-23 18:24:33 each Exp $ */
+/* $Id: socket.c,v 1.93 2011-11-29 01:03:47 marka Exp $ */
/* This code uses functions which are only available on Server 2003 and
* higher, and Windows XP and higher.
@@ -1688,6 +1688,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
*/
sock->fd = _dup(dup_socket->fd);
sock->dupped = 1;
+ sock->bound = dup_socket->bound;
}
if (sock->fd == INVALID_SOCKET) {
@@ -3175,6 +3176,7 @@ isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
}
INSIST(!sock->bound);
+ INSIST(!sock->dupped);
if (sock->pf != sockaddr->type.sa.sa_family) {
UNLOCK(&sock->lock);