summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorInternet Software Consortium, Inc <@isc.org>2011-11-01 14:45:10 -0600
committerInternet Software Consortium, Inc <@isc.org>2011-11-01 14:45:10 -0600
commitcf94dd77f7578bef7bc0ff3feac9aaa548180641 (patch)
tree02b5994fd9a1c51c845f2f094bbe3a48b89b35fa /lib
parent15c17fb71db9b8f876da1be5e6ddbba25ce61aba (diff)
downloadbind9-cf94dd77f7578bef7bc0ff3feac9aaa548180641.tar.gz
9.9.0a3
Diffstat (limited to 'lib')
-rw-r--r--lib/dns/Makefile.in6
-rw-r--r--lib/dns/clientinfo.c38
-rw-r--r--lib/dns/db.c91
-rw-r--r--lib/dns/ecdb.c6
-rw-r--r--lib/dns/include/dns/clientinfo.h85
-rw-r--r--lib/dns/include/dns/db.h50
-rw-r--r--lib/dns/include/dns/dlz_dlopen.h17
-rw-r--r--lib/dns/include/dns/log.h5
-rw-r--r--lib/dns/include/dns/rpz.h56
-rw-r--r--lib/dns/include/dns/sdb.h9
-rw-r--r--lib/dns/include/dns/sdlz.h20
-rw-r--r--lib/dns/log.c5
-rw-r--r--lib/dns/rbtdb.c170
-rw-r--r--lib/dns/rdata/generic/nsec3_50.c6
-rw-r--r--lib/dns/resolver.c11
-rw-r--r--lib/dns/rpz.c181
-rw-r--r--lib/dns/sdb.c50
-rw-r--r--lib/dns/sdlz.c86
-rw-r--r--lib/dns/tests/Makefile.in10
-rw-r--r--lib/dns/tests/dbversion_test.c740
-rw-r--r--lib/dns/tests/dnstest.c5
-rw-r--r--lib/dns/tests/update_test.c4
-rw-r--r--lib/dns/win32/libdns.def5
-rw-r--r--lib/dns/win32/libdns.dsp8
-rw-r--r--lib/dns/win32/libdns.mak24
-rw-r--r--lib/dns/zone.c28
-rw-r--r--lib/isc/include/isc/queue.h100
-rw-r--r--lib/isc/tests/Makefile.in10
-rw-r--r--lib/isc/tests/queue_test.c144
-rw-r--r--lib/isccfg/namedconf.c8
30 files changed, 1697 insertions, 281 deletions
diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in
index e037806d..cfdf31ef 100644
--- a/lib/dns/Makefile.in
+++ b/lib/dns/Makefile.in
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.179 2011-07-01 02:25:47 marka Exp $
+# $Id: Makefile.in,v 1.180 2011-10-11 00:09:03 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -55,7 +55,7 @@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
# Alphabetically
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
- cache.@O@ callbacks.@O@ compress.@O@ \
+ cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \
journal.@O@ keydata.@O@ keytable.@O@ \
@@ -84,7 +84,7 @@ DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
hmac_link.c key.c
DNSSRCS = acache.c acl.c adb.c byaddr.c \
- cache.c callbacks.c compress.c \
+ cache.c callbacks.c clientinfo.c compress.c \
db.c dbiterator.c dbtable.c diff.c dispatch.c \
dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \
keydata.c keytable.c lib.c log.c lookup.c \
diff --git a/lib/dns/clientinfo.c b/lib/dns/clientinfo.c
new file mode 100644
index 00000000..b5da5d70
--- /dev/null
+++ b/lib/dns/clientinfo.c
@@ -0,0 +1,38 @@
+/*
+ * 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: clientinfo.c,v 1.3 2011-10-11 00:25:12 marka Exp $ */
+
+/*! \file */
+
+#include "config.h"
+
+#include <dns/clientinfo.h>
+
+void
+dns_clientinfomethods_init(dns_clientinfomethods_t *methods,
+ dns_clientinfo_sourceip_t sourceip)
+{
+ methods->version = DNS_CLIENTINFOMETHODS_VERSION;
+ methods->age = DNS_CLIENTINFOMETHODS_AGE;
+ methods->sourceip = sourceip;
+}
+
+void
+dns_clientinfo_init(dns_clientinfo_t *ci, void *data) {
+ ci->version = DNS_CLIENTINFO_VERSION;
+ ci->data = data;
+}
diff --git a/lib/dns/db.c b/lib/dns/db.c
index c74d24df..33c7f494 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.c,v 1.97 2011-01-13 04:59:25 tbox Exp $ */
+/* $Id: db.c,v 1.99 2011-10-13 01:32:33 vjs Exp $ */
/*! \file */
@@ -33,6 +33,7 @@
#include <isc/util.h>
#include <dns/callbacks.h>
+#include <dns/clientinfo.h>
#include <dns/db.h>
#include <dns/dbiterator.h>
#include <dns/log.h>
@@ -478,7 +479,31 @@ dns_db_findnode(dns_db_t *db, dns_name_t *name,
REQUIRE(DNS_DB_VALID(db));
REQUIRE(nodep != NULL && *nodep == NULL);
- return ((db->methods->findnode)(db, name, create, nodep));
+ if (db->methods->findnode != NULL)
+ return ((db->methods->findnode)(db, name, create, nodep));
+ else
+ return ((db->methods->findnodeext)(db, name, create,
+ NULL, NULL, nodep));
+}
+
+isc_result_t
+dns_db_findnodeext(dns_db_t *db, dns_name_t *name,
+ isc_boolean_t create, dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep)
+{
+ /*
+ * Find the node with name 'name', passing 'arg' to the database
+ * implementation.
+ */
+
+ REQUIRE(DNS_DB_VALID(db));
+ REQUIRE(nodep != NULL && *nodep == NULL);
+
+ if (db->methods->findnodeext != NULL)
+ return ((db->methods->findnodeext)(db, name, create,
+ methods, clientinfo, nodep));
+ else
+ return ((db->methods->findnode)(db, name, create, nodep));
}
isc_result_t
@@ -502,7 +527,6 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
-
/*
* Find the best match for 'name' and 'type' in version 'version'
* of 'db'.
@@ -519,8 +543,50 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
(DNS_RDATASET_VALID(sigrdataset) &&
! dns_rdataset_isassociated(sigrdataset)));
- return ((db->methods->find)(db, name, version, type, options, now,
- nodep, foundname, rdataset, sigrdataset));
+ if (db->methods->find != NULL)
+ return ((db->methods->find)(db, name, version, type,
+ options, now, nodep, foundname,
+ rdataset, sigrdataset));
+ else
+ return ((db->methods->findext)(db, name, version, type,
+ options, now, nodep, foundname,
+ NULL, NULL,
+ rdataset, sigrdataset));
+}
+
+isc_result_t
+dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+{
+
+ /*
+ * Find the best match for 'name' and 'type' in version 'version'
+ * of 'db', passing in 'arg'.
+ */
+
+ REQUIRE(DNS_DB_VALID(db));
+ REQUIRE(type != dns_rdatatype_rrsig);
+ REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
+ REQUIRE(dns_name_hasbuffer(foundname));
+ REQUIRE(rdataset == NULL ||
+ (DNS_RDATASET_VALID(rdataset) &&
+ ! dns_rdataset_isassociated(rdataset)));
+ REQUIRE(sigrdataset == NULL ||
+ (DNS_RDATASET_VALID(sigrdataset) &&
+ ! dns_rdataset_isassociated(sigrdataset)));
+
+ if (db->methods->findext != NULL)
+ return ((db->methods->findext)(db, name, version, type,
+ options, now, nodep, foundname,
+ methods, clientinfo,
+ rdataset, sigrdataset));
+ else
+ return ((db->methods->find)(db, name, version, type,
+ options, now, nodep, foundname,
+ rdataset, sigrdataset));
}
isc_result_t
@@ -653,11 +719,6 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset)
{
- /*
- * Search for an rdataset of type 'type' at 'node' that are in version
- * 'version' of 'db'. If found, make 'rdataset' refer to it.
- */
-
REQUIRE(DNS_DB_VALID(db));
REQUIRE(node != NULL);
REQUIRE(DNS_RDATASET_VALID(rdataset));
@@ -668,8 +729,9 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
(DNS_RDATASET_VALID(sigrdataset) &&
! dns_rdataset_isassociated(sigrdataset)));
- return ((db->methods->findrdataset)(db, node, version, type, covers,
- now, rdataset, sigrdataset));
+ return ((db->methods->findrdataset)(db, node, version, type,
+ covers, now, rdataset,
+ sigrdataset));
}
isc_result_t
@@ -955,10 +1017,11 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
isc_result_t
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
- dns_rdataset_t *ardataset, dns_rpz_st_t *st)
+ dns_rdataset_t *ardataset, dns_rpz_st_t *st,
+ dns_name_t *query_qname)
{
if (db->methods->rpz_findips == NULL)
return (ISC_R_NOTIMPLEMENTED);
return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
- ardataset, st));
+ ardataset, st, query_qname));
}
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
index d98a3eb8..1ad03feb 100644
--- a/lib/dns/ecdb.c
+++ b/lib/dns/ecdb.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ecdb.c,v 1.8 2011-01-14 00:51:43 tbox Exp $ */
+/* $Id: ecdb.c,v 1.9 2011-10-11 13:33:45 marka Exp $ */
#include "config.h"
@@ -580,7 +580,9 @@ static dns_dbmethods_t ecdb_methods = {
NULL, /* isdnssec */
NULL, /* getrrsetstats */
NULL, /* rpz_enabled */
- NULL /* rpz_findips */
+ NULL, /* rpz_findips */
+ NULL, /* findnodeext */
+ NULL /* findext */
};
static isc_result_t
diff --git a/lib/dns/include/dns/clientinfo.h b/lib/dns/include/dns/clientinfo.h
new file mode 100644
index 00000000..4a3f1a73
--- /dev/null
+++ b/lib/dns/include/dns/clientinfo.h
@@ -0,0 +1,85 @@
+/*
+ * 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: clientinfo.h,v 1.3 2011-10-11 23:46:45 tbox Exp $ */
+
+#ifndef DNS_CLIENTINFO_H
+#define DNS_CLIENTINFO_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file dns/clientinfo.h
+ * \brief
+ * The DNS clientinfo interface allows libdns to retrieve information
+ * about the client from the caller.
+ *
+ * The clientinfo interface is used by the DNS DB and DLZ interfaces;
+ * it allows databases to modify their answers on the basis of information
+ * about the client, such as source IP address.
+ *
+ * dns_clientinfo_t contains a pointer to an opaque structure containing
+ * client information in some form. dns_clientinfomethods_t contains a
+ * list of methods which operate on that opaque structure to return
+ * potentially useful data. Both structures also contain versioning
+ * information.
+ */
+
+/*****
+ ***** Imports
+ *****/
+
+#include <isc/sockaddr.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Types
+ *****/
+
+#define DNS_CLIENTINFO_VERSION 1
+typedef struct dns_clientinfo {
+ isc_uint16_t version;
+ void *data;
+} dns_clientinfo_t;
+
+typedef isc_result_t (*dns_clientinfo_sourceip_t)(dns_clientinfo_t *client,
+ isc_sockaddr_t **addrp);
+
+#define DNS_CLIENTINFOMETHODS_VERSION 1
+#define DNS_CLIENTINFOMETHODS_AGE 0
+
+typedef struct dns_clientinfomethods {
+ isc_uint16_t version;
+ isc_uint16_t age;
+ dns_clientinfo_sourceip_t sourceip;
+} dns_clientinfomethods_t;
+
+/*****
+ ***** Methods
+ *****/
+void
+dns_clientinfomethods_init(dns_clientinfomethods_t *methods,
+ dns_clientinfo_sourceip_t sourceip);
+
+void
+dns_clientinfo_init(dns_clientinfo_t *ci, void *data);
+
+ISC_LANG_ENDDECLS
+
+#endif /* DNS_CLIENTINFO_H */
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index 38fab175..06d13cab 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.h,v 1.105 2011-05-19 00:31:57 smann Exp $ */
+/* $Id: db.h,v 1.107 2011-10-13 01:32:34 vjs Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -59,6 +59,7 @@
#include <isc/ondestroy.h>
#include <isc/stdtime.h>
+#include <dns/clientinfo.h>
#include <dns/fixedname.h>
#include <dns/name.h>
#include <dns/rdata.h>
@@ -177,7 +178,22 @@ typedef struct dns_dbmethods {
dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *version,
dns_rdataset_t *ardataset,
- dns_rpz_st_t *st);
+ dns_rpz_st_t *st,
+ dns_name_t *query_qname);
+ isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name,
+ isc_boolean_t create,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo,
+ dns_dbnode_t **nodep);
+ isc_result_t (*findext)(dns_db_t *db, dns_name_t *name,
+ dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options,
+ isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo,
+ dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset);
} dns_dbmethods_t;
typedef isc_result_t
@@ -659,9 +675,19 @@ dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp,
isc_result_t
dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_dbnode_t **nodep);
+
+isc_result_t
+dns_db_findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep);
/*%<
* Find the node with name 'name'.
*
+ * dns_db_findnodeext() (findnode extended) also accepts parameters
+ * 'methods' and 'clientinfo', which, when provided, enable the database to
+ * retreive information about the client from the caller, and modify its
+ * response on the basis of that information.
+ *
* Notes:
* \li If 'create' is ISC_TRUE and no node with name 'name' exists, then
* such a node will be created.
@@ -698,9 +724,21 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
+
+isc_result_t
+dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
/*%<
* Find the best match for 'name' and 'type' in version 'version' of 'db'.
*
+ * dns_db_findext() (find extended) also accepts parameters 'methods'
+ * and 'clientinfo', which when provided enable the database to retreive
+ * information about the client from the caller, and modify its response
+ * on the basis of this information.
+ *
* Notes:
*
* \li If type == dns_rdataset_any, then rdataset will not be bound.
@@ -1047,6 +1085,7 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset);
+
/*%<
* Search for an rdataset of type 'type' at 'node' that are in version
* 'version' of 'db'. If found, make 'rdataset' refer to it.
@@ -1509,7 +1548,8 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
isc_result_t
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
- dns_rdataset_t *ardataset, dns_rpz_st_t *st);
+ dns_rdataset_t *ardataset, dns_rpz_st_t *st,
+ dns_name_t *query_qname);
/*%<
* Search the CDIR block tree of a response policy tree of trees for the best
* match to any of the IP addresses in an A or AAAA rdataset.
@@ -1522,6 +1562,10 @@ dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
* \li 'ardataset' is an A or AAAA rdataset of addresses to check
* \li 'found' specifies the previous best match if any or
* or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_UNEXPECTED
*/
ISC_LANG_ENDDECLS
diff --git a/lib/dns/include/dns/dlz_dlopen.h b/lib/dns/include/dns/dlz_dlopen.h
index 7c2f5a3d..93fa9189 100644
--- a/lib/dns/include/dns/dlz_dlopen.h
+++ b/lib/dns/include/dns/dlz_dlopen.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dlz_dlopen.h,v 1.2 2011-03-17 09:25:54 fdupont Exp $ */
+/* $Id: dlz_dlopen.h,v 1.4 2011-10-11 23:46:45 tbox Exp $ */
/*! \file dns/dlz_open.h */
@@ -30,7 +30,7 @@ ISC_LANG_BEGINDECLS
* for the entry points of an external DLZ module for bind9.
*/
-#define DLZ_DLOPEN_VERSION 1
+#define DLZ_DLOPEN_VERSION 2
/*
* dlz_dlopen_version() is required for all DLZ external drivers. It
@@ -65,7 +65,9 @@ typedef isc_result_t dlz_dlopen_findzonedb_t (void *dbdata,
typedef isc_result_t dlz_dlopen_lookup_t (const char *zone,
const char *name,
void *dbdata,
- dns_sdlzlookup_t *lookup);
+ dns_sdlzlookup_t *lookup,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo);
/*
* dlz_dlopen_authority is optional() if dlz_dlopen_lookup()
@@ -116,6 +118,15 @@ typedef isc_result_t dlz_dlopen_configure_t (dns_view_t *view,
void *dbdata);
/*
+ * dlz_dlopen_setclientcallback() is optional, but must be supplied if you
+ * want to retrieve information about the client (e.g., source address)
+ * before sending a replay.
+ */
+typedef isc_result_t dlz_dlopen_setclientcallback_t (dns_view_t *view,
+ void *dbdata);
+
+
+/*
* dlz_dlopen_ssumatch() is optional, but must be supplied if you want
* to support dynamic updates
*/
diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h
index a5650edf..5ce4e57c 100644
--- a/lib/dns/include/dns/log.h
+++ b/lib/dns/include/dns/log.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) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.h,v 1.45 2009-12-18 22:16:49 each Exp $ */
+/* $Id: log.h,v 1.47 2011-10-13 22:48:24 tbox Exp $ */
/*! \file dns/log.h
* \author Principal Authors: DCL */
@@ -42,6 +42,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
#define DNS_LOGCATEGORY_LAME_SERVERS (&dns_categories[9])
#define DNS_LOGCATEGORY_DELEGATION_ONLY (&dns_categories[10])
#define DNS_LOGCATEGORY_EDNS_DISABLED (&dns_categories[11])
+#define DNS_LOGCATEGORY_RPZ (&dns_categories[12])
/* Backwards compatibility. */
#define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL
diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h
index 404f5176..adafd292 100644
--- a/lib/dns/include/dns/rpz.h
+++ b/lib/dns/include/dns/rpz.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rpz.h,v 1.3 2011-01-13 04:59:26 tbox Exp $ */
+/* $Id: rpz.h,v 1.4 2011-10-13 01:32:34 vjs Exp $ */
#ifndef DNS_RPZ_H
#define DNS_RPZ_H 1
@@ -37,21 +37,24 @@ typedef enum {
DNS_RPZ_TYPE_BAD,
DNS_RPZ_TYPE_QNAME,
DNS_RPZ_TYPE_IP,
- DNS_RPZ_TYPE_NSIP,
- DNS_RPZ_TYPE_NSDNAME
+ DNS_RPZ_TYPE_NSDNAME,
+ DNS_RPZ_TYPE_NSIP
} dns_rpz_type_t;
/*
- * Require DNS_RPZ_POLICY_NO_OP < DNS_RPZ_POLICY_NXDOMAIN <
- * DNS_RPZ_POLICY_NODATA < DNS_RPZ_POLICY_CNAME.
+ * Require DNS_RPZ_POLICY_PASSTHRU < DNS_RPZ_POLICY_NXDOMAIN <
+ * DNS_RPZ_POLICY_NODATA < DNS_RPZ_POLICY_CNAME to choose among competing
+ * policies.
*/
typedef enum {
- DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what something else says */
- DNS_RPZ_POLICY_NO_OP = 1, /* 'no-op': do not rewrite */
- DNS_RPZ_POLICY_NXDOMAIN = 2, /* 'nxdomain': answer with NXDOMAIN */
- DNS_RPZ_POLICY_NODATA = 3, /* 'nodata': answer with ANCOUNT=0 */
- DNS_RPZ_POLICY_CNAME = 4, /* 'cname x': answer with x's rrsets */
- DNS_RPZ_POLICY_RECORD = 5,
+ DNS_RPZ_POLICY_GIVEN = 0, /* 'given': what policy record says */
+ DNS_RPZ_POLICY_DISABLED = 1, /* 'cname x': answer with x's rrsets */
+ DNS_RPZ_POLICY_PASSTHRU = 2, /* 'passthru': do not rewrite */
+ DNS_RPZ_POLICY_NXDOMAIN = 3, /* 'nxdomain': answer with NXDOMAIN */
+ DNS_RPZ_POLICY_NODATA = 4, /* 'nodata': answer with ANCOUNT=0 */
+ DNS_RPZ_POLICY_CNAME = 5, /* 'cname x': answer with x's rrsets */
+ DNS_RPZ_POLICY_RECORD,
+ DNS_RPZ_POLICY_WILDCNAME,
DNS_RPZ_POLICY_MISS,
DNS_RPZ_POLICY_ERROR
} dns_rpz_policy_t;
@@ -65,10 +68,9 @@ struct dns_rpz_zone {
ISC_LINK(dns_rpz_zone_t) link;
int num;
dns_name_t origin; /* Policy zone name */
- dns_name_t nsdname; /* RPZ_NSDNAME_ZONE.origin */
- dns_rpz_policy_t policy; /* RPZ_POLICY_GIVEN or override */
- dns_name_t cname; /* override name for
- RPZ_POLICY_CNAME */
+ dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */
+ dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
+ dns_name_t cname; /* override value for ..._CNAME */
};
/*
@@ -82,13 +84,15 @@ typedef struct dns_rpz_cidr dns_rpz_cidr_t;
typedef struct {
unsigned int state;
# define DNS_RPZ_REWRITTEN 0x0001
-# define DNS_RPZ_DONE_QNAME 0x0002
-# define DNS_RPZ_DONE_A 0x0004
-# define DNS_RPZ_RECURSING 0x0008
-# define DNS_RPZ_HAVE_IP 0x0010
-# define DNS_RPZ_HAVE_NSIPv4 0x0020
-# define DNS_RPZ_HAVE_NSIPv6 0x0040
-# define DNS_RPZ_HAD_NSDNAME 0x0080
+# define DNS_RPZ_DONE_QNAME 0x0002 /* qname checked */
+# define DNS_RPZ_DONE_QNAME_IP 0x0004 /* IP addresses of qname checked */
+# define DNS_RPZ_DONE_NSDNAME 0x0008 /* NS name missed; checking addresses */
+# define DNS_RPZ_DONE_IPv4 0x0010
+# define DNS_RPZ_RECURSING 0x0020
+# define DNS_RPZ_HAVE_IP 0x0040 /* a policy zone has IP addresses */
+# define DNS_RPZ_HAVE_NSIPv4 0x0080 /* IPv4 NISP addresses */
+# define DNS_RPZ_HAVE_NSIPv6 0x0100 /* IPv6 NISP addresses */
+# define DNS_RPZ_HAVE_NSDNAME 0x0200 /* NS names */
/*
* Best match so far.
*/
@@ -105,7 +109,7 @@ typedef struct {
dns_rdataset_t *rdataset;
} m;
/*
- * State for chasing NS names and addresses including recursion.
+ * State for chasing IP addresses and NS names including recursion.
*/
struct {
unsigned int label;
@@ -114,7 +118,7 @@ typedef struct {
dns_rdatatype_t r_type;
isc_result_t r_result;
dns_rdataset_t *r_rdataset;
- } ns;
+ } r;
/*
* State of real query while recursing for NSIP or NSDNAME.
*/
@@ -146,6 +150,7 @@ typedef struct {
#define DNS_RPZ_INFO_LEVEL ISC_LOG_INFO
#define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
#define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
+#define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
const char *
dns_rpz_type2str(dns_rpz_type_t type);
@@ -153,6 +158,9 @@ dns_rpz_type2str(dns_rpz_type_t type);
dns_rpz_policy_t
dns_rpz_str2policy(const char *str);
+const char *
+dns_rpz_policy2str(dns_rpz_policy_t policy);
+
void
dns_rpz_set_need(isc_boolean_t need);
diff --git a/lib/dns/include/dns/sdb.h b/lib/dns/include/dns/sdb.h
index 5744837c..7b456fb2 100644
--- a/lib/dns/include/dns/sdb.h
+++ b/lib/dns/include/dns/sdb.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) 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: sdb.h,v 1.23 2009-01-17 23:47:43 tbox Exp $ */
+/* $Id: sdb.h,v 1.25 2011-10-11 23:46:45 tbox Exp $ */
#ifndef DNS_SDB_H
#define DNS_SDB_H 1
@@ -35,6 +35,7 @@
#include <isc/lang.h>
+#include <dns/clientinfo.h>
#include <dns/types.h>
/***
@@ -58,7 +59,9 @@ typedef struct dns_sdballnodes dns_sdballnodes_t;
typedef isc_result_t
(*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata,
- dns_sdblookup_t *);
+ dns_sdblookup_t *lookup,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo);
typedef isc_result_t
(*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *);
diff --git a/lib/dns/include/dns/sdlz.h b/lib/dns/include/dns/sdlz.h
index bd7b521c..ff3d05e6 100644
--- a/lib/dns/include/dns/sdlz.h
+++ b/lib/dns/include/dns/sdlz.h
@@ -50,13 +50,14 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.h,v 1.16 2011-03-17 23:47:30 tbox Exp $ */
+/* $Id: sdlz.h,v 1.17 2011-10-11 00:09:03 each Exp $ */
/*! \file dns/sdlz.h */
#ifndef SDLZ_H
#define SDLZ_H 1
+#include <dns/clientinfo.h>
#include <dns/dlz.h>
ISC_LANG_BEGINDECLS
@@ -182,18 +183,23 @@ typedef isc_result_t
typedef isc_result_t
(*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg,
- void *dbdata, dns_sdlzlookup_t *lookup);
+ void *dbdata, dns_sdlzlookup_t *lookup,
+ dns_clientinfomethods_t *methods,
+ dns_clientinfo_t *clientinfo);
/*%<
* Method prototype. Drivers implementing the SDLZ interface MUST
- * supply a lookup method. This method is called when the DNS server
- * is performing a query, after the find zone and before any other
- * methods have been called. This function returns record DNS record
+ * supply a lookup method. This method is called when the
+ * DNS server is performing a query, after the find zone and before any
+ * other methods have been called. This function returns DNS record
* information using the dns_sdlz_putrr and dns_sdlz_putsoa functions.
* If this function supplies authority information for the DNS record
* the authority method is not required. If it does not, the
- * authority function is required. A SDLZ driver must implement a
- * lookup method.
+ * authority function is required.
+ *
+ * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve
+ * information about the querying client (such as source IP address)
+ * from the caller.
*/
typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone,
diff --git a/lib/dns/log.c b/lib/dns/log.c
index 9de5976a..d137294e 100644
--- a/lib/dns/log.c
+++ b/lib/dns/log.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-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: log.c,v 1.47 2009-12-18 23:49:03 tbox Exp $ */
+/* $Id: log.c,v 1.49 2011-10-13 22:48:24 tbox Exp $ */
/*! \file */
@@ -44,6 +44,7 @@ LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = {
{ "lame-servers", 0 },
{ "delegation-only", 0 },
{ "edns-disabled", 0 },
+ { "rpz", 0 },
{ NULL, 0 }
};
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 91f33bf5..8fc81e1f 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.316 2011-08-23 00:59:23 each Exp $ */
+/* $Id: rbtdb.c,v 1.319 2011-10-13 01:32:33 vjs Exp $ */
/*! \file */
@@ -365,9 +365,12 @@ typedef enum {
dns_db_secure
} dns_db_secure_t;
+typedef struct dns_rbtdb dns_rbtdb_t;
+
typedef struct rbtdb_version {
/* Not locked */
rbtdb_serial_t serial;
+ dns_rbtdb_t * rbtdb;
/*
* Protected in the refcount routines.
* XXXJT: should we change the lock policy based on the refcount
@@ -392,7 +395,7 @@ typedef struct rbtdb_version {
typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t;
-typedef struct {
+struct dns_rbtdb {
/* Unlocked. */
dns_db_t common;
/* Locks the data in this struct */
@@ -452,7 +455,7 @@ typedef struct {
/* Unlocked */
unsigned int quantum;
-} dns_rbtdb_t;
+};
#define RBTDB_ATTR_LOADED 0x01
#define RBTDB_ATTR_LOADING 0x02
@@ -1105,6 +1108,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) {
version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1,
ISC_TRUE);
if (version != NULL) {
+ version->rbtdb = rbtdb;
version->commit_ok = ISC_TRUE;
version->secure = rbtdb->current_version->secure;
version->havensec3 = rbtdb->current_version->havensec3;
@@ -1146,6 +1150,7 @@ attachversion(dns_db_t *db, dns_dbversion_t *source,
unsigned int refs;
REQUIRE(VALID_RBTDB(rbtdb));
+ INSIST(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
isc_refcount_increment(&rbtversion->references, &refs);
INSIST(refs > 1);
@@ -2182,6 +2187,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
REQUIRE(VALID_RBTDB(rbtdb));
version = (rbtdb_version_t *)*versionp;
+ INSIST(version->rbtdb == rbtdb);
cleanup_version = NULL;
ISC_LIST_INIT(cleanup_list);
@@ -3649,6 +3655,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
search.rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(search.rbtdb));
+ INSIST(version == NULL ||
+ ((rbtdb_version_t *)version)->rbtdb == (dns_rbtdb_t *)db);
/*
* We don't care about 'now'.
@@ -4580,15 +4588,19 @@ get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
* Search the CDIR block tree of a response policy tree of trees for all of
* the IP addresses in an A or AAAA rdataset.
* Among the policies for all IPv4 and IPv6 addresses for a name, choose
- * the longest prefix. Among those with the longest prefix, the first
- * configured policy. Among answers for with the longest prefixes for
- * two or more IP addresses in the A and AAAA rdatasets the lexically
- * smallest address.
+ * the earliest configured policy,
+ * QNAME over IP over NSDNAME over NSIP,
+ * the longest prefix,
+ * the lexically smallest address.
+ * The caller must have already checked that any existing policy was not
+ * configured earlier than this policy zone and does not have a higher
+ * precedence type.
*/
static isc_result_t
rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
- dns_rdataset_t *ardataset, dns_rpz_st_t *st)
+ dns_rdataset_t *ardataset, dns_rpz_st_t *st,
+ dns_name_t *query_qname)
{
dns_rbtdb_t *rbtdb;
struct in_addr ina;
@@ -4609,8 +4621,6 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
if (rbtdb->rpz_cidr == NULL) {
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- dns_db_detach(&db);
- dns_zone_detach(&zone);
return (ISC_R_UNEXPECTED);
}
@@ -4645,17 +4655,19 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
continue;
/*
- * Choose the policy with the longest matching prefix.
- * Between policies with the same prefix, choose the first
- * configured.
+ * If we already have a rule, discard this new rule if
+ * is not better.
+ * The caller has checked that st->m.rpz->num > rpz->num
+ * or st->m.rpz->num == rpz->num and st->m.type >= rpz_type
*/
- if (st->m.policy != DNS_RPZ_POLICY_MISS) {
- if (prefix < st->m.prefix)
- continue;
- if (prefix == st->m.prefix &&
- rpz->num > st->m.rpz->num)
- continue;
- }
+ if (st->m.policy != DNS_RPZ_POLICY_MISS &&
+ st->m.rpz->num == rpz->num &&
+ (st->m.type < rpz_type ||
+ (st->m.type == rpz_type &&
+ (st->m.prefix > prefix ||
+ (st->m.prefix == prefix &&
+ 0 > dns_name_rdatacompare(st->qname, qname))))))
+ continue;
/*
* We have rpz_st an entry with a prefix at least as long as
@@ -4669,8 +4681,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(qname, namebuf, sizeof(namebuf));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
- DNS_LOGMODULE_CACHE, DNS_RPZ_ERROR_LEVEL,
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
+ DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
"rpz_findips findnode(%s): %s",
namebuf, isc_result_totext(result));
continue;
@@ -4694,7 +4706,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
} else {
rpz_policy = dns_rpz_decode_cname(&zrdataset,
selfname);
- if (rpz_policy == DNS_RPZ_POLICY_RECORD)
+ if (rpz_policy == DNS_RPZ_POLICY_RECORD ||
+ rpz_policy == DNS_RPZ_POLICY_WILDCNAME)
result = DNS_R_CNAME;
}
ttl = zrdataset.ttl;
@@ -4707,44 +4720,59 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
/*
* Use an overriding action specified in the configuration file
*/
- if (rpz->policy != DNS_RPZ_POLICY_GIVEN &&
- rpz_policy != DNS_RPZ_POLICY_NO_OP)
+ if (rpz->policy != DNS_RPZ_POLICY_GIVEN) {
+ /*
+ * only log DNS_RPZ_POLICY_DISABLED hits
+ */
+ if (rpz->policy == DNS_RPZ_POLICY_DISABLED) {
+ if (isc_log_wouldlog(dns_lctx,
+ DNS_RPZ_INFO_LEVEL)) {
+ char qname_buf[DNS_NAME_FORMATSIZE];
+ char rpz_qname_buf[DNS_NAME_FORMATSIZE];
+ dns_name_format(query_qname, qname_buf,
+ sizeof(qname_buf));
+ dns_name_format(qname, rpz_qname_buf,
+ sizeof(rpz_qname_buf));
+
+ isc_log_write(dns_lctx,
+ DNS_LOGCATEGORY_RPZ,
+ DNS_LOGMODULE_RBTDB,
+ DNS_RPZ_INFO_LEVEL,
+ "disabled rpz %s %s rewrite"
+ " %s via %s",
+ dns_rpz_type2str(rpz_type),
+ dns_rpz_policy2str(rpz_policy),
+ qname_buf, rpz_qname_buf);
+ }
+ continue;
+ }
+
rpz_policy = rpz->policy;
+ }
- /*
- * We know the new prefix is at least as long as the current.
- * Prefer the new answer if the new prefix is longer.
- * Prefer the zone configured first if the prefixes are equal.
- * With two actions from the same zone, prefer the action
- * on the "smallest" name.
- */
- if (st->m.policy == DNS_RPZ_POLICY_MISS ||
- prefix > st->m.prefix ||
- rpz->num <= st->m.rpz->num ||
- 0 > dns_name_compare(qname, st->qname)) {
- if (dns_rdataset_isassociated(st->m.rdataset))
- dns_rdataset_disassociate(st->m.rdataset);
- if (st->m.node != NULL)
- dns_db_detachnode(st->m.db, &st->m.node);
- if (st->m.db != NULL)
- dns_db_detach(&st->m.db);
- if (st->m.zone != NULL)
- dns_zone_detach(&st->m.zone);
- st->m.rpz = rpz;
- st->m.type = rpz_type;
- st->m.prefix = prefix;
- st->m.policy = rpz_policy;
- st->m.ttl = ttl;
- st->m.result = result;
- dns_name_copy(qname, st->qname, NULL);
- if (rpz_policy == DNS_RPZ_POLICY_RECORD &&
- result != DNS_R_NXRRSET) {
- dns_rdataset_clone(&zrdataset,st->m.rdataset);
- dns_db_attachnode(db, node, &st->m.node);
- }
- dns_db_attach(db, &st->m.db);
- dns_zone_attach(zone, &st->m.zone);
+ if (dns_rdataset_isassociated(st->m.rdataset))
+ dns_rdataset_disassociate(st->m.rdataset);
+ if (st->m.node != NULL)
+ dns_db_detachnode(st->m.db, &st->m.node);
+ if (st->m.db != NULL)
+ dns_db_detach(&st->m.db);
+ if (st->m.zone != NULL)
+ dns_zone_detach(&st->m.zone);
+ st->m.rpz = rpz;
+ st->m.type = rpz_type;
+ st->m.prefix = prefix;
+ st->m.policy = rpz_policy;
+ st->m.ttl = ttl;
+ st->m.result = result;
+ dns_name_copy(qname, st->qname, NULL);
+ if ((rpz_policy == DNS_RPZ_POLICY_RECORD ||
+ rpz_policy == DNS_RPZ_POLICY_WILDCNAME) &&
+ result != DNS_R_NXRRSET) {
+ dns_rdataset_clone(&zrdataset,st->m.rdataset);
+ dns_db_attachnode(db, node, &st->m.node);
}
+ dns_db_attach(db, &st->m.db);
+ dns_zone_attach(zone, &st->m.zone);
if (dns_rdataset_isassociated(&zrdataset))
dns_rdataset_disassociate(&zrdataset);
}
@@ -5544,6 +5572,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(type != dns_rdatatype_any);
+ INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
if (rbtversion == NULL) {
currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion));
@@ -5732,6 +5761,8 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
else {
unsigned int refs;
+ INSIST(rbtversion->rbtdb == rbtdb);
+
isc_refcount_increment(&rbtversion->references,
&refs);
INSIST(refs > 1);
@@ -6401,6 +6432,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_boolean_t cache_is_overmem = ISC_FALSE;
REQUIRE(VALID_RBTDB(rbtdb));
+ INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
if (rbtdb->common.methods == &zone_methods)
REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
@@ -6417,8 +6449,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
now = 0;
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- &region,
- sizeof(rdatasetheader_t));
+ &region, sizeof(rdatasetheader_t));
if (result != ISC_R_SUCCESS)
return (result);
@@ -6591,6 +6622,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
rbtdb_changed_t *changed;
REQUIRE(VALID_RBTDB(rbtdb));
+ REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
if (rbtdb->common.methods == &zone_methods)
REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
@@ -6771,6 +6803,7 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
rdatasetheader_t *newheader;
REQUIRE(VALID_RBTDB(rbtdb));
+ INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
if (type == dns_rdatatype_any)
return (ISC_R_NOTIMPLEMENTED);
@@ -7064,10 +7097,12 @@ static isc_result_t
dump(dns_db_t *db, dns_dbversion_t *version, const char *filename,
dns_masterformat_t masterformat) {
dns_rbtdb_t *rbtdb;
+ rbtdb_version_t *rbtversion = version;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
+ INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
#ifdef BIND9
return (dns_master_dump2(rbtdb->common.mctx, db, version,
@@ -7206,6 +7241,7 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
+ INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
@@ -7335,11 +7371,16 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(rdataset != NULL);
+ REQUIRE(rdataset->methods == &rdataset_methods);
REQUIRE(rbtdb->future_version == rbtversion);
+ REQUIRE(rbtversion != NULL);
REQUIRE(rbtversion->writer);
+ REQUIRE(rbtversion->rbtdb == rbtdb);
node = rdataset->private2;
+ INSIST(node != NULL);
header = rdataset->private3;
+ INSIST(header != NULL);
header--;
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
@@ -7408,11 +7449,13 @@ static dns_dbmethods_t zone_methods = {
NULL,
#ifdef BIND9
get_rpz_enabled,
- rpz_findips
+ rpz_findips,
#else
NULL,
- NULL
+ NULL,
#endif
+ NULL,
+ NULL
};
static dns_dbmethods_t cache_methods = {
@@ -7453,6 +7496,8 @@ static dns_dbmethods_t cache_methods = {
isdnssec,
getrrsetstats,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -7750,6 +7795,7 @@ dns_rbtdb_create
free_rbtdb(rbtdb, ISC_FALSE, NULL);
return (ISC_R_NOMEMORY);
}
+ rbtdb->current_version->rbtdb = rbtdb;
rbtdb->current_version->secure = dns_db_insecure;
rbtdb->current_version->havensec3 = ISC_FALSE;
rbtdb->current_version->flags = 0;
diff --git a/lib/dns/rdata/generic/nsec3_50.c b/lib/dns/rdata/generic/nsec3_50.c
index 36ef3772..59d3ac4d 100644
--- a/lib/dns/rdata/generic/nsec3_50.c
+++ b/lib/dns/rdata/generic/nsec3_50.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3_50.c,v 1.10 2011-03-07 13:42:11 marka Exp $ */
+/* $Id: nsec3_50.c,v 1.11 2011-10-05 03:47:59 marka Exp $ */
/*
* Copyright (C) 2004 Nominet, Ltd.
@@ -202,8 +202,10 @@ totext_nsec3(ARGS_TOTEXT) {
/* Types covered */
first = ISC_TRUE;
for (i = 0; i < sr.length; i += len) {
- if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
+ RETERR(str_totext(tctx->linebreak, target));
first = ISC_TRUE;
+ }
INSIST(i + 2 <= sr.length);
window = sr.base[i];
len = sr.base[i + 1];
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 59cdfd6c..9b9e2564 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.434 2011-06-08 22:13:50 each Exp $ */
+/* $Id: resolver.c,v 1.435 2011-10-12 00:18:11 marka Exp $ */
/*! \file */
@@ -5418,6 +5418,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
if (aa)
rdataset->trust =
dns_trust_authauthority;
+ else if (ISFORWARDER(fctx->addrinfo))
+ rdataset->trust =
+ dns_trust_answer;
else
rdataset->trust =
dns_trust_additional;
@@ -5471,6 +5474,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
if (aa)
rdataset->trust =
dns_trust_authauthority;
+ else if (ISFORWARDER(fctx->addrinfo))
+ rdataset->trust =
+ dns_trust_answer;
else
rdataset->trust =
dns_trust_additional;
@@ -5512,6 +5518,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
if (aa)
rdataset->trust =
dns_trust_authauthority;
+ else if (ISFORWARDER(fctx->addrinfo))
+ rdataset->trust =
+ dns_trust_answer;
else
rdataset->trust =
dns_trust_additional;
diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c
index f809e7b0..12d6a8df 100644
--- a/lib/dns/rpz.c
+++ b/lib/dns/rpz.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rpz.c,v 1.7 2011-01-17 04:27:23 marka Exp $ */
+/* $Id: rpz.c,v 1.8 2011-10-13 01:32:34 vjs Exp $ */
/*! \file */
@@ -116,20 +116,17 @@ struct dns_rpz_cidr_node {
struct dns_rpz_cidr {
isc_mem_t *mctx;
- isc_boolean_t had_nsdname;
+ isc_boolean_t have_nsdname; /* zone has NSDNAME record */
dns_rpz_cidr_node_t *root;
- dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */
+ dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */
dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */
dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */
};
-
static isc_boolean_t have_rpz_zones = ISC_FALSE;
-
const char *
-dns_rpz_type2str(dns_rpz_type_t type)
-{
+dns_rpz_type2str(dns_rpz_type_t type) {
switch (type) {
case DNS_RPZ_TYPE_QNAME:
return ("QNAME");
@@ -143,31 +140,61 @@ dns_rpz_type2str(dns_rpz_type_t type)
break;
}
FATAL_ERROR(__FILE__, __LINE__,
- "impossible response policy zone type %d", type);
+ "impossible rpz type %d", type);
return ("impossible");
}
-
-
dns_rpz_policy_t
-dns_rpz_str2policy(const char *str)
-{
+dns_rpz_str2policy(const char *str) {
if (str == NULL)
return (DNS_RPZ_POLICY_ERROR);
if (!strcasecmp(str, "given"))
return (DNS_RPZ_POLICY_GIVEN);
- if (!strcasecmp(str, "no-op"))
- return (DNS_RPZ_POLICY_NO_OP);
+ if (!strcasecmp(str, "disabled"))
+ return (DNS_RPZ_POLICY_DISABLED);
+ if (!strcasecmp(str, "passthru"))
+ return (DNS_RPZ_POLICY_PASSTHRU);
if (!strcasecmp(str, "nxdomain"))
return (DNS_RPZ_POLICY_NXDOMAIN);
if (!strcasecmp(str, "nodata"))
return (DNS_RPZ_POLICY_NODATA);
if (!strcasecmp(str, "cname"))
return (DNS_RPZ_POLICY_CNAME);
+ /*
+ * Obsolete
+ */
+ if (!strcasecmp(str, "no-op"))
+ return (DNS_RPZ_POLICY_PASSTHRU);
return (DNS_RPZ_POLICY_ERROR);
}
+const char *
+dns_rpz_policy2str(dns_rpz_policy_t policy) {
+ const char *str;
+ switch (policy) {
+ case DNS_RPZ_POLICY_PASSTHRU:
+ str = "PASSTHRU";
+ break;
+ case DNS_RPZ_POLICY_NXDOMAIN:
+ str = "NXDOMAIN";
+ break;
+ case DNS_RPZ_POLICY_NODATA:
+ str = "NODATA";
+ break;
+ case DNS_RPZ_POLICY_RECORD:
+ str = "records";
+ break;
+ case DNS_RPZ_POLICY_CNAME:
+ case DNS_RPZ_POLICY_WILDCNAME:
+ str = "CNAME";
+ break;
+ default:
+ str = "";
+ INSIST(0);
+ }
+ return (str);
+}
/*
* Free the radix tree of a response policy database.
@@ -214,8 +241,6 @@ dns_rpz_cidr_free(dns_rpz_cidr_t **cidrp) {
*cidrp = NULL;
}
-
-
/*
* Forget a view's list of policy zones.
*/
@@ -244,20 +269,15 @@ dns_rpz_view_destroy(dns_view_t *view) {
* zone is in at least one view's list of policy zones.
*/
void
-dns_rpz_set_need(isc_boolean_t need)
-{
+dns_rpz_set_need(isc_boolean_t need) {
have_rpz_zones = need;
}
-
isc_boolean_t
-dns_rpz_needed(void)
-{
+dns_rpz_needed(void) {
return (have_rpz_zones);
}
-
-
/*
* Start a new radix tree for a response policy zone.
*/
@@ -313,12 +333,13 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
return (ISC_R_SUCCESS);
}
-
/*
* See if a policy zone has IP, NSIP, or NSDNAME rules or records.
*/
void
dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
+ if (cidr == NULL)
+ return;
if (cidr->root != NULL &&
(cidr->root->flags & DNS_RPZ_CIDR_FG_IP) != 0)
st->state |= DNS_RPZ_HAVE_IP;
@@ -328,8 +349,8 @@ dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
if (cidr->root != NULL &&
(cidr->root->flags & DNS_RPZ_CIDR_FG_NSIPv6) != 0)
st->state |= DNS_RPZ_HAVE_NSIPv6;
- if (cidr->had_nsdname)
- st->state |= DNS_RPZ_HAD_NSDNAME;
+ if (cidr->have_nsdname)
+ st->state |= DNS_RPZ_HAVE_NSDNAME;
}
static inline dns_rpz_cidr_flags_t
@@ -350,8 +371,6 @@ get_flags(const dns_rpz_cidr_key_t *ip, dns_rpz_cidr_bits_t prefix,
}
}
-
-
/*
* Mark a node as having IP or NSIP data and all of its parents
* as members of the IP or NSIP tree.
@@ -371,8 +390,6 @@ set_node_flags(dns_rpz_cidr_node_t *node, dns_rpz_type_t rpz_type) {
}
}
-
-
/*
* Make a radix tree node.
*/
@@ -409,24 +426,18 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip,
return (node);
}
-
-
static void
-badname(int level, dns_name_t *name, const char *comment)
-{
+badname(int level, dns_name_t *name, const char *comment) {
char printname[DNS_NAME_FORMATSIZE];
if (isc_log_wouldlog(dns_lctx, level)) {
dns_name_format(name, printname, sizeof(printname));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, level,
- "invalid response policy name \"%s\"%s",
- printname, comment);
+ "invalid rpz \"%s\"%s", printname, comment);
}
}
-
-
/*
* Convert an IP address from radix tree binary (host byte order) to
* to its canonical response policy domain name and its name in the
@@ -520,8 +531,6 @@ ip2name(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
return (ISC_R_SUCCESS);
}
-
-
/*
* Decide which kind of IP address response policy zone a name is in.
*/
@@ -548,8 +557,6 @@ set_type(dns_rpz_cidr_t *cidr, dns_name_t *name) {
return (DNS_RPZ_TYPE_QNAME);
}
-
-
/*
* Convert an IP address from canonical response policy domain name form
* to radix tree binary (host byte order).
@@ -695,26 +702,37 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
return (ISC_R_SUCCESS);
}
-
-
/*
- * find first differing bit
+ * Find first differing bit.
*/
static int
ffbit(dns_rpz_cidr_word_t w) {
int bit;
- if (w == 0)
- return (DNS_RPZ_CIDR_WORD_BITS);
- for (bit = 0; (w & (1U << (DNS_RPZ_CIDR_WORD_BITS-1))) == 0; bit++)
- w <<= 1;
+ bit = DNS_RPZ_CIDR_WORD_BITS-1;
+ if ((w & 0xffff0000) != 0) {
+ w >>= 16;
+ bit -= 16;
+ }
+ if ((w & 0xff00) != 0) {
+ w >>= 8;
+ bit -= 8;
+ }
+ if ((w & 0xf0) != 0) {
+ w >>= 4;
+ bit -= 4;
+ }
+ if ((w & 0xc) != 0) {
+ w >>= 2;
+ bit -= 2;
+ }
+ if ((w & 2) != 0)
+ --bit;
return (bit);
}
-
-
/*
- * find the first differing bit in two keys
+ * Find the first differing bit in two keys.
*/
static int
diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_cidr_bits_t bits1,
@@ -741,14 +759,12 @@ diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_cidr_bits_t bits1,
return (ISC_MIN(bit, maxbit));
}
-
-
/*
* Search a radix tree for an IP address for ordinary lookup
* or for a CIDR block adding or deleting an entry
* The tree read (for simple search) or write lock must be held by the caller.
*
- * return ISC_R_SUCCESS, ISC_R_NOTFOUND, DNS_R_PARTIALMATCH, ISC_R_EXISTS,
+ * Return ISC_R_SUCCESS, ISC_R_NOTFOUND, DNS_R_PARTIALMATCH, ISC_R_EXISTS,
* ISC_R_NOMEMORY
*/
static isc_result_t
@@ -912,15 +928,12 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
}
}
-
-
/*
* Add an IP address to the radix tree of a response policy database.
* The tree write lock must be held by the caller.
*/
void
-dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
-{
+dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
dns_rpz_cidr_key_t tgt_ip;
dns_rpz_cidr_bits_t tgt_prefix;
dns_rpz_type_t type;
@@ -929,7 +942,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
return;
/*
- * no worries if the new name is not an IP address
+ * No worries if the new name is not an IP address.
*/
type = set_type(cidr, name);
switch (type) {
@@ -937,7 +950,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
case DNS_RPZ_TYPE_NSIP:
break;
case DNS_RPZ_TYPE_NSDNAME:
- cidr->had_nsdname = ISC_TRUE;
+ cidr->have_nsdname = ISC_TRUE;
return;
case DNS_RPZ_TYPE_QNAME:
case DNS_RPZ_TYPE_BAD:
@@ -953,15 +966,12 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name)
char printname[DNS_NAME_FORMATSIZE];
dns_name_format(name, printname, sizeof(printname));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "duplicate response policy name \"%s\"",
- printname);
+ "duplicate rpz name \"%s\"", printname);
}
}
-
-
/*
* Delete an IP address from the radix tree of a response policy database.
* The tree write lock must be held by the caller.
@@ -1000,7 +1010,7 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
/*
* Do not get excited about the deletion of interior rbt nodes.
*/
- if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL2, name,
+ if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name,
type, &tgt_ip, &tgt_prefix))
return;
if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type,
@@ -1009,10 +1019,9 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
char printname[DNS_NAME_FORMATSIZE];
dns_name_format(name, printname, sizeof(printname));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "missing response policy node \"%s\"",
- printname);
+ "missing rpz node \"%s\"", printname);
}
return;
}
@@ -1073,8 +1082,6 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
} while (tgt != NULL);
}
-
-
/*
* Caller must hold tree lock.
* Return ISC_R_NOTFOUND
@@ -1124,8 +1131,6 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
canon_name, search_name));
}
-
-
/*
* Translate CNAME rdata to a QNAME response policy action.
*/
@@ -1148,21 +1153,31 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
if (dns_name_equal(&cname.cname, dns_rootname))
return (DNS_RPZ_POLICY_NXDOMAIN);
- /*
- * CNAME *. means NODATA
- */
- if (dns_name_countlabels(&cname.cname) == 2
- && dns_name_iswildcard(&cname.cname))
- return (DNS_RPZ_POLICY_NODATA);
+ if (dns_name_iswildcard(&cname.cname)) {
+ /*
+ * CNAME *. means NODATA
+ */
+ if (dns_name_countlabels(&cname.cname) == 2)
+ return (DNS_RPZ_POLICY_NODATA);
+
+ /*
+ * A qname of www.evil.com and a policy of
+ * *.evil.com CNAME *.garden.net
+ * gives a result of
+ * evil.com CNAME evil.com.garden.net
+ */
+ if (dns_name_countlabels(&cname.cname) > 2)
+ return (DNS_RPZ_POLICY_WILDCNAME);
+ }
/*
* 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite"
*/
if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
- return (DNS_RPZ_POLICY_NO_OP);
+ return (DNS_RPZ_POLICY_PASSTHRU);
/*
- * evil.com CNAME garden.net rewrites www.evil.com to www.garden.net.
+ * Any other rdata gives a response consisting of the rdata.
*/
return (DNS_RPZ_POLICY_RECORD);
}
diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c
index 10e3c1c4..9e934fce 100644
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.78 2011-03-14 13:40:52 fdupont Exp $ */
+/* $Id: sdb.c,v 1.79 2011-10-11 00:09:03 each Exp $ */
/*! \file */
@@ -727,8 +727,9 @@ destroynode(dns_sdbnode_t *node) {
}
static isc_result_t
-findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep)
+findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
+ dns_dbnode_t **nodep)
{
dns_sdb_t *sdb = (dns_sdb_t *)db;
dns_sdbnode_t *node = NULL;
@@ -773,7 +774,8 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
isorigin = dns_name_equal(name, &sdb->common.origin);
MAYBE_LOCK(sdb);
- result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, node);
+ result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata,
+ node, methods, clientinfo);
MAYBE_UNLOCK(sdb);
if (result != ISC_R_SUCCESS &&
!(result == ISC_R_NOTFOUND &&
@@ -798,10 +800,11 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
}
static isc_result_t
-find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
dns_sdb_t *sdb = (dns_sdb_t *)db;
dns_dbnode_t *node = NULL;
@@ -840,7 +843,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* Look up the next label.
*/
dns_name_getlabelsequence(name, nlabels - i, i, xname);
- result = findnode(db, xname, ISC_FALSE, &node);
+ result = findnodeext(db, xname, ISC_FALSE, methods,
+ clientinfo, &node);
if (result != ISC_R_SUCCESS) {
result = DNS_R_NXDOMAIN;
continue;
@@ -1227,8 +1231,8 @@ static dns_dbmethods_t sdb_methods = {
newversion,
attachversion,
closeversion,
- findnode,
- find,
+ NULL,
+ NULL,
findzonecut,
attachnode,
detachnode,
@@ -1245,17 +1249,19 @@ static dns_dbmethods_t sdb_methods = {
ispersistent,
overmem,
settask,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
+ NULL, /* getoriginnode */
+ NULL, /* transfernode */
+ NULL, /* getnsec3parameters */
+ NULL, /* findnsec3node */
+ NULL, /* setsigningtime */
+ NULL, /* getsigningtime */
+ NULL, /* resigned */
+ NULL, /* isdnssec */
+ NULL, /* getrrsetstats */
+ NULL, /* rpz_enabled */
+ NULL, /* rpz_findips */
+ findnodeext,
+ findext
};
static isc_result_t
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 7706064f..107bf43f 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.33 2011-03-21 19:54:03 each Exp $ */
+/* $Id: sdlz.c,v 1.34 2011-10-11 00:09:03 each Exp $ */
/*! \file */
@@ -538,8 +538,9 @@ destroynode(dns_sdlznode_t *node) {
}
static isc_result_t
-findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep)
+findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
+ dns_dbnode_t **nodep)
{
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
dns_sdlznode_t *node = NULL;
@@ -598,17 +599,18 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
/* try to lookup the host (namestr) */
result = sdlz->dlzimp->methods->lookup(zonestr, namestr,
sdlz->dlzimp->driverarg,
- sdlz->dbdata, node);
+ sdlz->dbdata, node,
+ methods, clientinfo);
/*
* if the host (namestr) was not found, try to lookup a
* "wildcard" host.
*/
- if (result != ISC_R_SUCCESS && !create) {
+ if (result != ISC_R_SUCCESS && !create)
result = sdlz->dlzimp->methods->lookup(zonestr, "*",
sdlz->dlzimp->driverarg,
- sdlz->dbdata, node);
- }
+ sdlz->dbdata, node,
+ methods, clientinfo);
MAYBE_UNLOCK(sdlz->dlzimp);
@@ -652,6 +654,13 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
}
static isc_result_t
+findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_dbnode_t **nodep)
+{
+ return (findnodeext(db, name, create, NULL, NULL, nodep));
+}
+
+static isc_result_t
findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
@@ -825,10 +834,11 @@ findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
static isc_result_t
-find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
- dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
- dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
dns_dbnode_t *node = NULL;
@@ -867,7 +877,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* Look up the next label.
*/
dns_name_getlabelsequence(name, nlabels - i, i, xname);
- result = findnode(db, xname, ISC_FALSE, &node);
+ result = findnodeext(db, xname, ISC_FALSE,
+ methods, clientinfo, &node);
if (result != ISC_R_SUCCESS) {
result = DNS_R_NXDOMAIN;
continue;
@@ -879,8 +890,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*/
if (i < nlabels) {
result = findrdataset(db, node, version,
- dns_rdatatype_dname,
- 0, now, rdataset, sigrdataset);
+ dns_rdatatype_dname, 0, now,
+ rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
result = DNS_R_DNAME;
break;
@@ -893,8 +904,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*/
if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) {
result = findrdataset(db, node, version,
- dns_rdatatype_ns,
- 0, now, rdataset, sigrdataset);
+ dns_rdatatype_ns, 0, now,
+ rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
if (i == nlabels && type == dns_rdatatype_any)
{
@@ -933,8 +944,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
/*
* Look for the qtype.
*/
- result = findrdataset(db, node, version, type,
- 0, now, rdataset, sigrdataset);
+ result = findrdataset(db, node, version, type, 0, now,
+ rdataset, sigrdataset);
if (result == ISC_R_SUCCESS)
break;
@@ -943,8 +954,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*/
if (type != dns_rdatatype_cname) {
result = findrdataset(db, node, version,
- dns_rdatatype_cname,
- 0, now, rdataset, sigrdataset);
+ dns_rdatatype_cname, 0, now,
+ rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
result = DNS_R_CNAME;
break;
@@ -980,6 +991,16 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
}
static isc_result_t
+find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
+ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
+ dns_dbnode_t **nodep, dns_name_t *foundname,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+{
+ return (findext(db, name, version, type, options, now, nodep,
+ foundname, NULL, NULL, rdataset, sigrdataset));
+}
+
+static isc_result_t
allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdatasetiter_t **iteratorp)
{
@@ -1194,7 +1215,8 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
if (sdlz->dlzimp->methods->newversion == NULL)
return (ISC_R_NOTIMPLEMENTED);
- result = findnode(db, &sdlz->common.origin, ISC_FALSE, nodep);
+ result = findnodeext(db, &sdlz->common.origin, ISC_FALSE,
+ NULL, NULL, nodep);
if (result != ISC_R_SUCCESS)
sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed : %s",
isc_result_totext(result));
@@ -1230,16 +1252,18 @@ static dns_dbmethods_t sdlzdb_methods = {
overmem,
settask,
getoriginnode,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
+ NULL, /* transfernode */
+ NULL, /* getnsec3parameters */
+ NULL, /* findnsec3node */
+ NULL, /* setsigningtime */
+ NULL, /* getsigningtime */
+ NULL, /* resigned */
+ NULL, /* isdnssec */
+ NULL, /* getrrsetstats */
+ NULL, /* rpz_enabled */
+ NULL, /* rpz_findips */
+ findnodeext,
+ findext
};
/*
diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in
index bf18e285..ddf569b4 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.8 2011-09-02 21:15:37 each Exp $
+# $Id: Makefile.in,v 1.9 2011-10-12 23:09:35 marka Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -42,7 +42,8 @@ SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \
SUBDIRS =
TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \
- update_test@EXEEXT@ zonemgr_test@EXEEXT@ zt_test@EXEEXT@
+ update_test@EXEEXT@ zonemgr_test@EXEEXT@ zt_test@EXEEXT@ \
+ dbversion_test@EXEEXT@
@BIND9_MAKE_RULES@
@@ -71,6 +72,11 @@ dbiterator_test@EXEEXT@: dbiterator_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPL
dbiterator_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} \
+ ${ISCLIBS} ${LIBS}
+
zt_test@EXEEXT@: zt_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
zt_test.@O@ dnstest.@O@ ${DNSLIBS} \
diff --git a/lib/dns/tests/dbversion_test.c b/lib/dns/tests/dbversion_test.c
new file mode 100644
index 00000000..18149e92
--- /dev/null
+++ b/lib/dns/tests/dbversion_test.c
@@ -0,0 +1,740 @@
+/*
+ * 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: dbversion_test.c,v 1.5 2011-10-13 22:48:24 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <isc/file.h>
+#include <isc/result.h>
+#include <isc/serial.h>
+#include <isc/stdtime.h>
+#include <isc/msgcat.h>
+
+#include <dns/db.h>
+#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
+#include <dns/rdatasetiter.h>
+#include <dns/nsec3.h>
+
+#include "dnstest.h"
+
+static char tempname[11] = "dtXXXXXXXX";
+
+static void
+callback(const char *file, int line, isc_assertiontype_t type,
+ const char *cond)
+{
+ UNUSED(file); UNUSED(line); UNUSED(type); UNUSED(cond);
+ if (strcmp(tempname, "dtXXXXXXXX"))
+ unlink(tempname);
+ atf_tc_pass();
+ exit(0);
+}
+
+static dns_db_t *db1 = NULL, *db2 = NULL;
+static dns_dbversion_t *v1 = NULL, *v2 = NULL;
+
+static void
+setup_db() {
+ isc_result_t result;
+ result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
+ dns_rdataclass_in, 0, NULL, &db1);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ dns_db_newversion(db1, &v1);
+
+ result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
+ dns_rdataclass_in, 0, NULL, &db2);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+ dns_db_newversion(db2, &v2);
+}
+
+static void
+close_db() {
+ if (v1 != NULL) {
+ dns_db_closeversion(db1, &v1, ISC_FALSE);
+ ATF_REQUIRE_EQ(v1, NULL);
+ }
+ if (db1 != NULL) {
+ dns_db_detach(&db1);
+ ATF_REQUIRE_EQ(db1, NULL);
+ }
+
+ if (v2 != NULL) {
+ dns_db_closeversion(db2, &v2, ISC_FALSE);
+ ATF_REQUIRE_EQ(v2, NULL);
+ }
+ if (db2 != NULL) {
+ dns_db_detach(&db2);
+ ATF_REQUIRE_EQ(db2, NULL);
+ }
+}
+
+#define VERSION(callback) ((callback == NULL) ? v1 : v2)
+#define VERSIONP(callback) ((callback == NULL) ? &v1 : &v2)
+/*
+ * Individual unit tests
+ */
+static void
+attachversion(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_dbversion_t *v = NULL;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ isc_assertion_setcallback(callback);
+ dns_db_attachversion(db1, VERSION(callback), &v);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_attachversion did not assert");
+
+ ATF_REQUIRE_EQ(v, v1);
+ dns_db_closeversion(db1, &v, ISC_FALSE);
+ ATF_REQUIRE_EQ(v, NULL);
+
+ close_db();
+ dns_test_end();
+}
+
+ATF_TC(attachversion);
+ATF_TC_HEAD(attachversion, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_attachversion passes with matching db/verison");
+}
+ATF_TC_BODY(attachversion, tc) {
+
+ UNUSED(tc);
+
+ attachversion(NULL);
+}
+
+ATF_TC(attachversion_bad);
+ATF_TC_HEAD(attachversion_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_attachversion aborts with mis-matching db/verison");
+}
+ATF_TC_BODY(attachversion_bad, tc) {
+
+ UNUSED(tc);
+
+ attachversion(callback);
+}
+
+static void
+closeversion(isc_assertioncallback_t callback) {
+ isc_result_t result;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ isc_assertion_setcallback(callback);
+ dns_db_closeversion(db1, VERSIONP(callback), ISC_FALSE);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_closeversion did not assert");
+ ATF_REQUIRE_EQ(v1, NULL);
+
+ close_db();
+ dns_test_end();
+}
+
+ATF_TC(closeversion);
+ATF_TC_HEAD(closeversion, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_closeversion passes with matching db/verison");
+}
+ATF_TC_BODY(closeversion, tc) {
+
+ UNUSED(tc);
+
+ closeversion(NULL);
+}
+
+ATF_TC(closeversion_bad);
+ATF_TC_HEAD(closeversion_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_closeversion asserts with mis-matching db/verison");
+}
+ATF_TC_BODY(closeversion_bad, tc) {
+
+ UNUSED(tc);
+
+ closeversion(callback);
+}
+
+static void
+find(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fixed;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ dns_rdataset_init(&rdataset);
+ dns_fixedname_init(&fixed);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_find(db1, dns_rootname, VERSION(callback),
+ dns_rdatatype_soa, 0, 0, NULL,
+ dns_fixedname_name(&fixed), &rdataset, NULL);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_find did not assert");
+ ATF_REQUIRE_EQ(result, DNS_R_NXDOMAIN);
+
+ close_db();
+
+ dns_test_end();
+}
+ATF_TC(find);
+ATF_TC_HEAD(find, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_find passes with matching db/version");
+}
+ATF_TC_BODY(find, tc) {
+
+ UNUSED(tc);
+
+ find(NULL);
+}
+
+ATF_TC(find_bad);
+ATF_TC_HEAD(find_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_find asserts with mis-matching db/version");
+}
+ATF_TC_BODY(find_bad, tc) {
+
+ UNUSED(tc);
+
+ find(callback);
+}
+
+static void
+allrdatasets(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_dbnode_t *node = NULL;
+ dns_rdatasetiter_t *iterator = NULL;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_allrdatasets(db1, node, VERSION(callback), 0,
+ &iterator);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_allrdatasets did not assert");
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ dns_rdatasetiter_destroy(&iterator);
+ ATF_REQUIRE_EQ(iterator, NULL);
+
+ dns_db_detachnode(db1, &node);
+ ATF_REQUIRE_EQ(node, NULL);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(allrdatasets);
+ATF_TC_HEAD(allrdatasets, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_allrdatasets passes with matching db/version");
+}
+ATF_TC_BODY(allrdatasets, tc) {
+
+ UNUSED(tc);
+
+ allrdatasets(NULL);
+}
+
+ATF_TC(allrdatasets_bad);
+ATF_TC_HEAD(allrdatasets_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_allrdatasets aborts with mis-matching db/version");
+}
+ATF_TC_BODY(allrdatasets_bad, tc) {
+
+ UNUSED(tc);
+
+ allrdatasets(callback);
+}
+
+static void
+findrdataset(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fixed;
+ dns_dbnode_t *node = NULL;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ dns_rdataset_init(&rdataset);
+ dns_fixedname_init(&fixed);
+
+ result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_findrdataset(db1, node, VERSION(callback),
+ dns_rdatatype_soa, 0, 0, &rdataset, NULL);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_findrdataset did not assert");
+ ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
+
+ dns_db_detachnode(db1, &node);
+ ATF_REQUIRE_EQ(node, NULL);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(findrdataset);
+ATF_TC_HEAD(findrdataset, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_findrdataset passes with matching db/version");
+}
+ATF_TC_BODY(findrdataset, tc) {
+
+ UNUSED(tc);
+
+ findrdataset(NULL);
+}
+
+ATF_TC(findrdataset_bad);
+ATF_TC_HEAD(findrdataset_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_findrdataset aborts with mis-matching db/version");
+}
+ATF_TC_BODY(findrdataset_bad, tc) {
+
+ UNUSED(tc);
+
+ findrdataset(callback);
+}
+
+static void
+deleterdataset(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fixed;
+ dns_dbnode_t *node = NULL;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ dns_rdataset_init(&rdataset);
+ dns_fixedname_init(&fixed);
+
+ result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_deleterdataset(db1, node, VERSION(callback),
+ dns_rdatatype_soa, 0);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_deleterdataset did not assert");
+ ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED);
+
+ dns_db_detachnode(db1, &node);
+ ATF_REQUIRE_EQ(node, NULL);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(deleterdataset);
+ATF_TC_HEAD(deleterdataset, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_deleterdataset passes with matching db/version");
+}
+ATF_TC_BODY(deleterdataset, tc) {
+
+ UNUSED(tc);
+
+ deleterdataset(NULL);
+}
+
+ATF_TC(deleterdataset_bad);
+ATF_TC_HEAD(deleterdataset_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_deleterdataset aborts with mis-matching db/version");
+}
+ATF_TC_BODY(deleterdataset_bad, tc) {
+
+ UNUSED(tc);
+
+ deleterdataset(callback);
+}
+
+static void
+subtract(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fixed;
+ dns_dbnode_t *node = NULL;
+ dns_rdatalist_t rdatalist;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ dns_rdataset_init(&rdataset);
+ dns_rdatalist_init(&rdatalist);
+ dns_fixedname_init(&fixed);
+
+ rdatalist.rdclass = dns_rdataclass_in;
+
+ result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_subtractrdataset(db1, node, VERSION(callback),
+ &rdataset, 0, NULL);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_dns_db_subtractrdataset did not assert");
+ ATF_REQUIRE_EQ(result, DNS_R_UNCHANGED);
+
+ dns_db_detachnode(db1, &node);
+ ATF_REQUIRE_EQ(node, NULL);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(subtractrdataset);
+ATF_TC_HEAD(subtractrdataset, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_subtractrdataset passes with matching db/version");
+}
+ATF_TC_BODY(subtractrdataset, tc) {
+
+ UNUSED(tc);
+
+ subtract(NULL);
+}
+
+ATF_TC(subtractrdataset_bad);
+ATF_TC_HEAD(subtractrdataset_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_subtractrdataset aborts with mis-matching db/version");
+}
+ATF_TC_BODY(subtractrdataset_bad, tc) {
+
+ UNUSED(tc);
+
+ subtract(callback);
+}
+
+static void
+dump(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ FILE *f = NULL;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ result = isc_file_openunique(tempname, &f);
+ fclose(f);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_dump(db1, VERSION(callback), tempname);
+ (void)unlink(tempname);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_dump did not assert");
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(dump);
+ATF_TC_HEAD(dump, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_dump passes with matching db/version");
+}
+ATF_TC_BODY(dump, tc) {
+
+ UNUSED(tc);
+
+ dump(NULL);
+}
+
+ATF_TC(dump_bad);
+ATF_TC_HEAD(dump_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_dump aborts with mis-matching db/version");
+}
+ATF_TC_BODY(dump_bad, tc) {
+
+ UNUSED(tc);
+
+ dump(callback);
+}
+
+static void
+addrdataset(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_rdataset_t rdataset;
+ dns_fixedname_t fixed;
+ dns_dbnode_t *node = NULL;
+ dns_rdatalist_t rdatalist;
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ dns_rdataset_init(&rdataset);
+ dns_rdatalist_init(&rdatalist);
+ dns_fixedname_init(&fixed);
+
+ rdatalist.rdclass = dns_rdataclass_in;
+
+ result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_addrdataset(db1, node, VERSION(callback), 0, &rdataset,
+ 0, NULL);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_adddataset did not assert");
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ dns_db_detachnode(db1, &node);
+ ATF_REQUIRE_EQ(node, NULL);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(addrdataset);
+ATF_TC_HEAD(addrdataset, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_addrdataset passes with matching db/version");
+}
+ATF_TC_BODY(addrdataset, tc) {
+
+ UNUSED(tc);
+
+ addrdataset(NULL);
+}
+
+ATF_TC(addrdataset_bad);
+ATF_TC_HEAD(addrdataset_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_addrdataset aborts with mis-matching db/version");
+}
+ATF_TC_BODY(addrdataset_bad, tc) {
+
+ UNUSED(tc);
+
+ addrdataset(callback);
+}
+
+static void
+getnsec3parameters(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_hash_t hash;
+ isc_uint8_t flags;
+ isc_uint16_t iterations;
+ unsigned char salt[DNS_NSEC3_SALTSIZE];
+ size_t salt_length = sizeof(salt);
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ isc_assertion_setcallback(callback);
+ result = dns_db_getnsec3parameters(db1, VERSION(callback), &hash,
+ &flags, &iterations, salt,
+ &salt_length);
+ if (callback != NULL)
+ atf_tc_fail("dns_db_dump did not assert");
+ ATF_REQUIRE_EQ(result, ISC_R_NOTFOUND);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(getnsec3parameters);
+ATF_TC_HEAD(getnsec3parameters, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_getnsec3parameters passes with matching db/version");
+}
+ATF_TC_BODY(getnsec3parameters, tc) {
+
+ UNUSED(tc);
+
+ getnsec3parameters(NULL);
+}
+
+ATF_TC(getnsec3parameters_bad);
+ATF_TC_HEAD(getnsec3parameters_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_db_getnsec3parameters aborts with mis-matching db/version");
+}
+ATF_TC_BODY(getnsec3parameters_bad, tc) {
+
+ UNUSED(tc);
+
+ getnsec3parameters(callback);
+}
+
+static void
+resigned(isc_assertioncallback_t callback) {
+ isc_result_t result;
+ dns_rdataset_t rdataset, added;
+ dns_dbnode_t *node = NULL;
+ dns_rdatalist_t rdatalist;
+ dns_rdata_rrsig_t rrsig;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_buffer_t b;
+ unsigned char buf[1024];
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ setup_db();
+
+ /*
+ * Create a dummy RRSIG record and set a resigning time.
+ */
+ dns_rdataset_init(&added);
+ dns_rdataset_init(&rdataset);
+ dns_rdatalist_init(&rdatalist);
+ isc_buffer_init(&b, buf, sizeof(buf));
+
+ DNS_RDATACOMMON_INIT(&rrsig, dns_rdatatype_rrsig, dns_rdataclass_in);
+ rrsig.covered = dns_rdatatype_a;
+ rrsig.algorithm = 100;
+ rrsig.labels = 0;
+ rrsig.originalttl = 0;
+ rrsig.timeexpire = 3600;
+ rrsig.timesigned = 0;
+ rrsig.keyid = 0;
+ dns_name_init(&rrsig.signer, NULL);
+ dns_name_clone(dns_rootname, &rrsig.signer);
+ rrsig.siglen = 0;
+ rrsig.signature = NULL;
+
+ result = dns_rdata_fromstruct(&rdata, dns_rdataclass_in,
+ dns_rdatatype_rrsig, &rrsig, &b);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ rdatalist.rdclass = dns_rdataclass_in;
+ rdatalist.type = dns_rdatatype_rrsig;
+ ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
+
+ result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ rdataset.attributes |= DNS_RDATASETATTR_RESIGN;
+ rdataset.resign = 7200;
+
+ result = dns_db_findnode(db1, dns_rootname, ISC_FALSE, &node);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_addrdataset(db1, node, v1, 0, &rdataset, 0, &added);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ dns_db_detachnode(db1, &node);
+ ATF_REQUIRE_EQ(node, NULL);
+
+ isc_assertion_setcallback(callback);
+ dns_db_resigned(db1, &added, VERSION(callback));
+ if (callback != NULL)
+ atf_tc_fail("dns_db_resigned did not assert");
+
+ dns_rdataset_disassociate(&added);
+
+ close_db();
+
+ dns_test_end();
+}
+
+ATF_TC(resigned);
+ATF_TC_HEAD(resigned, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_rdataset_resigned passes with matching db/version");
+}
+ATF_TC_BODY(resigned, tc) {
+
+ UNUSED(tc);
+
+ resigned(NULL);
+}
+
+ATF_TC(resigned_bad);
+ATF_TC_HEAD(resigned_bad, tc) {
+ atf_tc_set_md_var(tc, "descr", "check dns_rdataset_resigned aborts with mis-matching db/version");
+}
+ATF_TC_BODY(resigned_bad, tc) {
+
+ UNUSED(tc);
+
+ resigned(callback);
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, dump);
+ ATF_TP_ADD_TC(tp, dump_bad);
+ ATF_TP_ADD_TC(tp, find);
+ ATF_TP_ADD_TC(tp, find_bad);
+ ATF_TP_ADD_TC(tp, allrdatasets);
+ ATF_TP_ADD_TC(tp, allrdatasets_bad);
+ ATF_TP_ADD_TC(tp, findrdataset);
+ ATF_TP_ADD_TC(tp, findrdataset_bad);
+ ATF_TP_ADD_TC(tp, addrdataset);
+ ATF_TP_ADD_TC(tp, addrdataset_bad);
+ ATF_TP_ADD_TC(tp, deleterdataset);
+ ATF_TP_ADD_TC(tp, deleterdataset_bad);
+ ATF_TP_ADD_TC(tp, subtractrdataset);
+ ATF_TP_ADD_TC(tp, subtractrdataset_bad);
+ ATF_TP_ADD_TC(tp, attachversion);
+ ATF_TP_ADD_TC(tp, attachversion_bad);
+ ATF_TP_ADD_TC(tp, closeversion);
+ ATF_TP_ADD_TC(tp, closeversion_bad);
+ ATF_TP_ADD_TC(tp, getnsec3parameters);
+ ATF_TP_ADD_TC(tp, getnsec3parameters_bad);
+ ATF_TP_ADD_TC(tp, resigned);
+ ATF_TP_ADD_TC(tp, resigned_bad);
+
+ return (atf_no_error());
+}
diff --git a/lib/dns/tests/dnstest.c b/lib/dns/tests/dnstest.c
index 019154ab..9e9af61e 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.7 2011-09-03 19:22:43 each Exp $ */
+/* $Id: dnstest.c,v 1.8 2011-10-10 02:46:16 marka Exp $ */
/*! \file */
@@ -101,7 +101,6 @@ create_managers() {
CHECK(isc_timermgr_create(mctx, &timermgr));
CHECK(isc_socketmgr_create(mctx, &socketmgr));
CHECK(isc_task_create(taskmgr, 0, &maintask));
- CHECK(isc_app_start());
return (ISC_R_SUCCESS);
cleanup:
@@ -113,6 +112,8 @@ isc_result_t
dns_test_begin(FILE *logfile, isc_boolean_t start_managers) {
isc_result_t result;
+ if (start_managers)
+ CHECK(isc_app_start());
isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
CHECK(isc_mem_create(0, 0, &mctx));
CHECK(isc_entropy_create(mctx, &ectx));
diff --git a/lib/dns/tests/update_test.c b/lib/dns/tests/update_test.c
index 6ed9335c..d0c85f4b 100644
--- a/lib/dns/tests/update_test.c
+++ b/lib/dns/tests/update_test.c
@@ -14,9 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: update_test.c,v 1.5 2011-08-23 01:29:38 each Exp $ */
-
-/* $Id: */
+/* $Id: update_test.c,v 1.6 2011-10-12 23:09:35 marka Exp $ */
/*! \file */
diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def
index 6ced2e95..11efee00 100644
--- a/lib/dns/win32/libdns.def
+++ b/lib/dns/win32/libdns.def
@@ -71,6 +71,8 @@ dns_cache_setcleaninginterval
dns_cache_setfilename
dns_cert_fromtext
dns_cert_totext
+dns_clientinfo_init
+dns_clientinfomethods_init
dns_compress_add
dns_compress_findglobal
dns_compress_getedns
@@ -101,7 +103,9 @@ dns_db_dump
dns_db_endload
dns_db_expirenode
dns_db_find
+dns_db_findext
dns_db_findnode
+dns_db_findnodeext
dns_db_findnsec3node
dns_db_findrdataset
dns_db_findzonecut
@@ -622,6 +626,7 @@ dns_rpz_decode_cname
dns_rpz_enabled
dns_rpz_needed
dns_rpz_new_cidr
+dns_rpz_policy2str
dns_rpz_set_need
dns_rpz_str2policy
dns_rpz_type2str
diff --git a/lib/dns/win32/libdns.dsp b/lib/dns/win32/libdns.dsp
index c8d4a162..6a0c2c91 100644
--- a/lib/dns/win32/libdns.dsp
+++ b/lib/dns/win32/libdns.dsp
@@ -130,6 +130,10 @@ SOURCE=..\include\dns\cert.h
# End Source File
# Begin Source File
+SOURCE=..\include\dns\clientinfo.h
+# End Source File
+# Begin Source File
+
SOURCE=..\code.h
# End Source File
# Begin Source File
@@ -466,6 +470,10 @@ SOURCE=..\callbacks.c
# End Source File
# Begin Source File
+SOURCE=..\clientinfo.c
+# End Source File
+# Begin Source File
+
SOURCE=..\compress.c
# End Source File
# Begin Source File
diff --git a/lib/dns/win32/libdns.mak b/lib/dns/win32/libdns.mak
index a03d9fa3..c0c37ddb 100644
--- a/lib/dns/win32/libdns.mak
+++ b/lib/dns/win32/libdns.mak
@@ -126,6 +126,7 @@ CLEAN :
-@erase "$(INTDIR)\byaddr.obj"
-@erase "$(INTDIR)\cache.obj"
-@erase "$(INTDIR)\callbacks.obj"
+ -@erase "$(INTDIR)\clientinfo.obj"
-@erase "$(INTDIR)\compress.obj"
-@erase "$(INTDIR)\db.obj"
-@erase "$(INTDIR)\dbiterator.obj"
@@ -263,6 +264,7 @@ LINK32_OBJS= \
"$(INTDIR)\byaddr.obj" \
"$(INTDIR)\cache.obj" \
"$(INTDIR)\callbacks.obj" \
+ "$(INTDIR)\clientinfo.obj" \
"$(INTDIR)\compress.obj" \
"$(INTDIR)\db.obj" \
"$(INTDIR)\dbiterator.obj" \
@@ -385,6 +387,8 @@ CLEAN :
-@erase "$(INTDIR)\cache.sbr"
-@erase "$(INTDIR)\callbacks.obj"
-@erase "$(INTDIR)\callbacks.sbr"
+ -@erase "$(INTDIR)\clientinfo.obj"
+ -@erase "$(INTDIR)\clientinfo.sbr"
-@erase "$(INTDIR)\compress.obj"
-@erase "$(INTDIR)\compress.sbr"
-@erase "$(INTDIR)\db.obj"
@@ -602,6 +606,7 @@ BSC32_SBRS= \
"$(INTDIR)\byaddr.sbr" \
"$(INTDIR)\cache.sbr" \
"$(INTDIR)\callbacks.sbr" \
+ "$(INTDIR)\clientinfo.sbr" \
"$(INTDIR)\compress.sbr" \
"$(INTDIR)\db.sbr" \
"$(INTDIR)\dbiterator.sbr" \
@@ -698,6 +703,7 @@ LINK32_OBJS= \
"$(INTDIR)\byaddr.obj" \
"$(INTDIR)\cache.obj" \
"$(INTDIR)\callbacks.obj" \
+ "$(INTDIR)\clientinfo.obj" \
"$(INTDIR)\compress.obj" \
"$(INTDIR)\db.obj" \
"$(INTDIR)\dbiterator.obj" \
@@ -906,6 +912,24 @@ SOURCE=..\callbacks.c
!ENDIF
+SOURCE=..\clientinfo.c
+
+!IF "$(CFG)" == "libdns - Win32 Release"
+
+
+"$(INTDIR)\clientinfo.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "libdns - Win32 Debug"
+
+
+"$(INTDIR)\clientinfo.obj" "$(INTDIR)\clientinfo.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
SOURCE=..\compress.c
!IF "$(CFG)" == "libdns - Win32 Release"
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index e2ffeb9f..4fe4c7d4 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.632 2011-09-06 22:29:33 smann Exp $ */
+/* $Id: zone.c,v 1.635 2011-10-12 23:46:34 tbox Exp $ */
/*! \file */
@@ -412,6 +412,7 @@ struct dns_zone {
#define DNS_ZONEFLG_THAW 0x08000000U
#define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
#define DNS_ZONEFLG_NODELAY 0x20000000U
+#define DNS_ZONEFLG_SENDSECURE 0x40000000U
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
@@ -709,6 +710,7 @@ 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);
#define ENTER zone_debuglog(zone, me, 1, "enter")
@@ -3458,6 +3460,16 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
return (result);
}
+static void
+maybe_send_securedb(dns_zone_t *zone) {
+ LOCK_ZONE(zone->raw);
+ if (zone->raw->db != NULL)
+ zone_send_securedb(zone->raw, zone->raw->db);
+ else
+ DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
+ UNLOCK_ZONE(zone->raw);
+}
+
static isc_result_t
zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
isc_result_t result)
@@ -3493,6 +3505,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
"failed: %s",
zone->masterfile,
dns_result_totext(result));
+ } else if (zone->type == dns_zone_master &&
+ zone->raw != NULL && result == ISC_R_FILENOTFOUND) {
+ dns_zone_log(zone, ISC_LOG_DEBUG(1),
+ "no master file, requesting db");
+ maybe_send_securedb(zone);
} else {
dns_zone_log(zone, ISC_LOG_ERROR,
"loading from master file %s failed: %s",
@@ -3797,6 +3814,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
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);
}
result = ISC_R_SUCCESS;
@@ -4898,7 +4918,6 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
isc_result_t result;
dns_dbnode_t *node = NULL;
dns_rdataset_t rdataset;
- dns_rdata_t rdata = DNS_RDATA_INIT;
unsigned int i;
dns_rdata_rrsig_t rrsig;
isc_boolean_t found, changed;
@@ -4931,6 +4950,8 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
dns_rdataset_current(&rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -4942,7 +4963,6 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
rdataset.ttl, &rdata);
if (incremental)
changed = ISC_TRUE;
- dns_rdata_reset(&rdata);
if (result != ISC_R_SUCCESS)
break;
} else {
@@ -5038,7 +5058,6 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = update_one_rr(db, ver, diff,
DNS_DIFFOP_DELRESIGN, name,
rdataset.ttl, &rdata);
- dns_rdata_reset(&rdata);
if (result != ISC_R_SUCCESS)
break;
}
@@ -12240,6 +12259,7 @@ zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
((struct secure_db *)e)->db = dummy;
isc_task_send(zone->secure->task, &e);
+ DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
return (ISC_R_SUCCESS);
}
diff --git a/lib/isc/include/isc/queue.h b/lib/isc/include/isc/queue.h
new file mode 100644
index 00000000..04964fc6
--- /dev/null
+++ b/lib/isc/include/isc/queue.h
@@ -0,0 +1,100 @@
+/*
+ * 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: queue.h,v 1.2 2011-10-10 22:57:13 each Exp $ */
+
+/*
+ * This is a generic implementation of a two-lock concurrent queue.
+ * There are built-in mutex locks for the head and tail of the queue,
+ * allowing elements to be safely added and removed at the same time.
+ */
+
+#ifndef ISC_QUEUE_H
+#define ISC_QUEUE_H 1
+#include <isc/assertions.h>
+#include <isc/boolean.h>
+#include <isc/mutex.h>
+
+#ifdef ISC_QUEUE_CHECKINIT
+#define ISC_QLINK_INSIST(x) ISC_INSIST(x)
+#else
+#define ISC_QLINK_INSIST(x) (void)0
+#endif
+
+#define ISC_QLINK(type) struct { void *next; isc_boolean_t linked; }
+#define ISC_QLINK_INIT(elt, link) \
+ do { \
+ (elt)->link.next = (void *)(-1); \
+ (elt)->link.linked = ISC_FALSE; \
+ } while (0)
+#define ISC_QLINK_LINKED(elt, link) ((elt)->link.linked)
+
+#define ISC_QUEUE(type) struct { \
+ type headnode; \
+ type *head, *tail; \
+ isc_mutex_t headlock, taillock; \
+}
+
+#define ISC_QUEUE_INIT(queue, link) \
+ do { \
+ isc_mutex_init(&(queue).headlock); \
+ isc_mutex_init(&(queue).taillock); \
+ (queue).head = (void *) &((queue).headnode); \
+ (queue).tail = (void *) &((queue).headnode); \
+ ISC_QLINK_INIT((queue).head, link); \
+ } while (0)
+
+#define ISC_QUEUE_EMPTY(queue) ISC_TF((queue).head == (queue).tail)
+
+#define ISC_QUEUE_DESTROY(queue) \
+ do { \
+ ISC_QLINK_INSIST(ISC_QUEUE_EMPTY(queue)); \
+ isc_mutex_destroy(&(queue).headlock); \
+ isc_mutex_destroy(&(queue).taillock); \
+ } while (0)
+
+#define ISC_QUEUE_PUSH(queue, elt, link) \
+ do { \
+ ISC_QLINK_INSIST(!ISC_QLINK_LINKED(elt, link)); \
+ (elt)->link.next = (void *)(-1); \
+ LOCK(&(queue).taillock); \
+ (queue).tail->link.next = elt; \
+ (queue).tail = elt; \
+ UNLOCK(&(queue).taillock); \
+ (elt)->link.linked = ISC_TRUE; \
+ } while (0)
+
+#define ISC_QUEUE_POP(queue, link, ret) \
+ do { \
+ LOCK(&(queue).headlock); \
+ ret = (queue).head->link.next; \
+ if (ret == (void *)(-1)) { \
+ UNLOCK(&(queue).headlock); \
+ ret = NULL; \
+ } else { \
+ (queue).head->link.next = ret->link.next; \
+ if (ret->link.next == (void *)(-1)) { \
+ LOCK(&(queue).taillock); \
+ (queue).tail = (queue).head; \
+ UNLOCK(&(queue).taillock); \
+ } \
+ UNLOCK(&(queue).headlock); \
+ ret->link.next = (void *)(-1); \
+ ret->link.linked = ISC_FALSE; \
+ } \
+ } while (0)
+
+#endif /* ISC_QUEUE_H */
diff --git a/lib/isc/tests/Makefile.in b/lib/isc/tests/Makefile.in
index 8c0a088b..a9a64f66 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.7 2011-09-02 21:15:38 each Exp $
+# $Id: Makefile.in,v 1.8 2011-10-10 22:57:13 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
+ task_test.c queue_test.c
SUBDIRS =
TARGETS = taskpool_test@EXEEXT@ socket_test@EXEEXT@ hash_test@EXEEXT@ \
- task_test@EXEEXT@
+ task_test@EXEEXT@ queue_test@EXEEXT@
@BIND9_MAKE_RULES@
@@ -60,6 +60,10 @@ hash_test@EXEEXT@: hash_test.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
hash_test.@O@ ${ISCLIBS} ${LIBS}
+queue_test@EXEEXT@: queue_test.@O@ isctest.@O@ ${ISCDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ queue_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
+
unit::
sh ${top_srcdir}/unit/unittest.sh
diff --git a/lib/isc/tests/queue_test.c b/lib/isc/tests/queue_test.c
new file mode 100644
index 00000000..eb1178e6
--- /dev/null
+++ b/lib/isc/tests/queue_test.c
@@ -0,0 +1,144 @@
+/*
+ * 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: queue_test.c,v 1.3 2011-10-12 02:17:53 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+#include <time.h>
+
+#include <isc/queue.h>
+
+#include "isctest.h"
+
+typedef struct item {
+ int value;
+ ISC_QLINK(item_t) qlink;
+} item_t;
+
+typedef ISC_QUEUE(item_t) item_queue_t;
+
+static void
+item_init(item_t *item, int value) {
+ item->value = value;
+ ISC_QLINK_INIT(item, qlink);
+}
+
+/*
+ * Individual unit tests
+ */
+
+/* Test UDP sendto/recv (IPv4) */
+ATF_TC(queue_valid);
+ATF_TC_HEAD(queue_valid, tc) {
+ atf_tc_set_md_var(tc, "descr", "Check queue validity");
+}
+ATF_TC_BODY(queue_valid, tc) {
+ isc_result_t result;
+ item_queue_t queue;
+ item_t one, two, three, four, five;
+ item_t *p;
+
+ UNUSED(tc);
+
+ ISC_QUEUE_INIT(queue, qlink);
+
+ item_init(&one, 1);
+ item_init(&two, 2);
+ item_init(&three, 3);
+ item_init(&four, 4);
+ item_init(&five, 5);
+
+ result = isc_test_begin(NULL, ISC_TRUE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ ATF_CHECK(ISC_QUEUE_EMPTY(queue));
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_CHECK(p == NULL);
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&one, qlink));
+ ISC_QUEUE_PUSH(queue, &one, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&one, qlink));
+
+ ATF_CHECK(! ISC_QUEUE_EMPTY(queue));
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 1);
+ ATF_CHECK(ISC_QUEUE_EMPTY(queue));
+ ATF_CHECK(! ISC_QLINK_LINKED(p, qlink));
+
+ ISC_QUEUE_PUSH(queue, p, qlink);
+ ATF_CHECK(! ISC_QUEUE_EMPTY(queue));
+ ATF_CHECK(ISC_QLINK_LINKED(p, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&two, qlink));
+ ISC_QUEUE_PUSH(queue, &two, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&two, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&three, qlink));
+ ISC_QUEUE_PUSH(queue, &three, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&three, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&four, qlink));
+ ISC_QUEUE_PUSH(queue, &four, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&four, qlink));
+
+ ATF_CHECK(! ISC_QLINK_LINKED(&five, qlink));
+ ISC_QUEUE_PUSH(queue, &five, qlink);
+ ATF_CHECK(ISC_QLINK_LINKED(&five, qlink));
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 1);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 2);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 3);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 4);
+
+ ISC_QUEUE_POP(queue, qlink, p);
+ ATF_REQUIRE(p != NULL);
+ ATF_CHECK_EQ(p->value, 5);
+
+ ATF_CHECK(ISC_QUEUE_EMPTY(queue));
+
+ ISC_QUEUE_DESTROY(queue);
+ isc_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, queue_valid);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index b66b943b..89d49641 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: namedconf.c,v 1.141 2011-09-06 22:29:33 smann Exp $ */
+/* $Id: namedconf.c,v 1.142 2011-10-13 01:32:34 vjs Exp $ */
/*! \file */
@@ -1027,7 +1027,8 @@ static cfg_type_t cfg_type_masterformat = {
/*
* response-policy {
- * zone <string> [ policy (given|no-op|nxdomain|nodata|cname <domain> ) ];
+ * zone <string> [ policy (given|disabled|passthru|
+ * nxdomain|nodata|cname <domain> ) ];
* };
*
* this is a chimera of doc_optional_keyvalue() and cfg_doc_enum()
@@ -1095,7 +1096,8 @@ cleanup:
}
static const char *rpz_policies[] = {
- "given", "no-op", "nxdomain", "nodata", "cname", NULL
+ "given", "disabled", "passthru", "no-op", "nxdomain", "nodata",
+ "cname", NULL
};
static cfg_type_t cfg_type_rpz_policylist = {
"policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,