diff options
Diffstat (limited to 'lib')
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, - ®ion, - sizeof(rdatasetheader_t)); + ®ion, 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, |