diff options
author | dougb <dougb@FreeBSD.org> | 2007-06-02 23:21:47 +0000 |
---|---|---|
committer | dougb <dougb@FreeBSD.org> | 2007-06-02 23:21:47 +0000 |
commit | 6df9693fc1899de774712d6421c2fc401db2eadd (patch) | |
tree | 6e65ba28d6d850f4d5c07cd37f26842e97b4aecf /contrib/bind9/lib/dns | |
parent | fb8cb3b3a3d2367752c01dc81b68c0b7390f7760 (diff) | |
download | FreeBSD-src-6df9693fc1899de774712d6421c2fc401db2eadd.zip FreeBSD-src-6df9693fc1899de774712d6421c2fc401db2eadd.tar.gz |
Vendor import of BIND 9.4.1
Diffstat (limited to 'contrib/bind9/lib/dns')
267 files changed, 19584 insertions, 6203 deletions
diff --git a/contrib/bind9/lib/dns/Makefile.in b/contrib/bind9/lib/dns/Makefile.in index 9c368d1..286a5f9 100644 --- a/contrib/bind9/lib/dns/Makefile.in +++ b/contrib/bind9/lib/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and distribute this software for any @@ -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.126.2.3.2.19 2006/01/06 00:01:42 marka Exp $ +# $Id: Makefile.in,v 1.144.18.10 2006/01/06 00:01:43 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -49,17 +49,18 @@ DSTOBJS = dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ opensslrsa_link.@O@ # Alphabetically -DNSOBJS = acl.@O@ adb.@O@ byaddr.@O@ \ +DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ cache.@O@ callbacks.@O@ compress.@O@ \ db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \ - dnssec.@O@ ds.@O@ forward.@O@ journal.@O@ keytable.@O@ \ + dlz.@O@ dnssec.@O@ ds.@O@ forward.@O@ journal.@O@ keytable.@O@ \ lib.@O@ log.@O@ lookup.@O@ \ master.@O@ masterdump.@O@ message.@O@ \ name.@O@ ncache.@O@ nsec.@O@ order.@O@ peer.@O@ portlist.@O@ \ rbt.@O@ rbtdb.@O@ rbtdb64.@O@ rcode.@O@ rdata.@O@ \ rdatalist.@O@ \ rdataset.@O@ rdatasetiter.@O@ rdataslab.@O@ request.@O@ \ - resolver.@O@ result.@O@ rootns.@O@ sdb.@O@ soa.@O@ ssu.@O@ \ + resolver.@O@ result.@O@ rootns.@O@ sdb.@O@ sdlz.@O@ \ + soa.@O@ ssu.@O@ \ stats.@O@ tcpmsg.@O@ time.@O@ timer.@O@ tkey.@O@ \ tsig.@O@ ttl.@O@ validator.@O@ \ version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@ @@ -73,17 +74,18 @@ DSTSRCS = dst_api.c dst_lib.c dst_parse.c \ openssl_link.c openssldh_link.c \ openssldsa_link.c opensslrsa_link.c -SRCS = acl.c adb.c byaddr.c \ +DNSSRCS = acache.c acl.c adb.c byaddr.c \ cache.c callbacks.c compress.c \ db.c dbiterator.c dbtable.c diff.c dispatch.c \ - dnssec.c ds.c forward.c journal.c keytable.c \ + dlz.c dnssec.c ds.c forward.c journal.c keytable.c \ lib.c log.c lookup.c \ master.c masterdump.c message.c \ name.c ncache.c nsec.c order.c peer.c portlist.c \ rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c \ rdatalist.c \ rdataset.c rdatasetiter.c rdataslab.c request.c \ - resolver.c result.c rootns.c sdb.c soa.c ssu.c \ + resolver.c result.c rootns.c sdb.c sdlz.c \ + soa.c ssu.c \ stats.c tcpmsg.c time.c timer.c tkey.c \ tsig.c ttl.c validator.c \ version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS} diff --git a/contrib/bind9/lib/dns/acache.c b/contrib/bind9/lib/dns/acache.c new file mode 100644 index 0000000..5787a5a --- /dev/null +++ b/contrib/bind9/lib/dns/acache.c @@ -0,0 +1,1778 @@ +/* + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: acache.c,v 1.3.2.16 2006/07/19 00:34:56 marka Exp $ */ + +#include <config.h> + +#include <isc/atomic.h> +#include <isc/event.h> +#include <isc/hash.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/mutex.h> +#include <isc/random.h> +#include <isc/refcount.h> +#include <isc/rwlock.h> +#include <isc/task.h> +#include <isc/time.h> +#include <isc/timer.h> + +#include <dns/acache.h> +#include <dns/db.h> +#include <dns/events.h> +#include <dns/log.h> +#include <dns/message.h> +#include <dns/name.h> +#include <dns/rdataset.h> +#include <dns/result.h> +#include <dns/zone.h> + +#define ACACHE_MAGIC ISC_MAGIC('A', 'C', 'H', 'E') +#define DNS_ACACHE_VALID(acache) ISC_MAGIC_VALID(acache, ACACHE_MAGIC) + +#define ACACHEENTRY_MAGIC ISC_MAGIC('A', 'C', 'E', 'T') +#define DNS_ACACHEENTRY_VALID(entry) ISC_MAGIC_VALID(entry, ACACHEENTRY_MAGIC) + +#define DBBUCKETS 67 + +#if 0 +#define ATRACE(m) isc_log_write(dns_lctx, \ + DNS_LOGCATEGORY_DATABASE, \ + DNS_LOGMODULE_ACACHE, \ + ISC_LOG_DEBUG(3), \ + "acache %p: %s", acache, (m)) +#define AATRACE(a,m) isc_log_write(dns_lctx, \ + DNS_LOGCATEGORY_DATABASE, \ + DNS_LOGMODULE_ACACHE, \ + ISC_LOG_DEBUG(3), \ + "acache %p: %s", (a), (m)) +#else +#define ATRACE(m) +#define AATRACE(a, m) +#endif + +/* + * The following variables control incremental cleaning. + * MINSIZE is how many bytes is the floor for dns_acache_setcachesize(). + * CLEANERINCREMENT is how many entries are examined in one pass. + * (XXX simply derived from definitions in cache.c There may be better + * constants here.) + */ +#define DNS_ACACHE_MINSIZE 2097152 /* Bytes. 2097152 = 2 MB */ +#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */ + +#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */ + +#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE) +#define ACACHE_USE_RWLOCK 1 +#endif + +#ifdef ACACHE_USE_RWLOCK +#define ACACHE_INITLOCK(l) isc_rwlock_init((l), 0, 0) +#define ACACHE_DESTROYLOCK(l) isc_rwlock_destroy(l) +#define ACACHE_LOCK(l, t) RWLOCK((l), (t)) +#define ACACHE_UNLOCK(l, t) RWUNLOCK((l), (t)) + +#define acache_storetime(entry, t) \ + (isc_atomic_store((isc_int32_t *)&(entry)->lastused, (t))) +#else +#define ACACHE_INITLOCK(l) isc_mutex_init(l) +#define ACACHE_DESTROYLOCK(l) DESTROYLOCK(l) +#define ACACHE_LOCK(l, t) LOCK(l) +#define ACACHE_UNLOCK(l, t) UNLOCK(l) + +#define acache_storetime(entry, t) ((entry)->lastused = (t)) +#endif + +/* Locked by acache lock */ +typedef struct dbentry { + ISC_LINK(struct dbentry) link; + + dns_db_t *db; + ISC_LIST(dns_acacheentry_t) originlist; + ISC_LIST(dns_acacheentry_t) referlist; +} dbentry_t; + +typedef ISC_LIST(dbentry_t) dbentrylist_t; + +typedef struct acache_cleaner acache_cleaner_t; + +typedef enum { + cleaner_s_idle, /* Waiting for cleaning-interval to expire. */ + cleaner_s_busy, /* Currently cleaning. */ + cleaner_s_done /* Freed enough memory after being overmem. */ +} cleaner_state_t; + +/* + * Convenience macros for comprehensive assertion checking. + */ +#define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \ + (c)->resched_event != NULL) +#define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \ + (c)->resched_event == NULL) + +struct acache_cleaner { + isc_mutex_t lock; + /* + * Locks overmem_event, overmem. (See cache.c) + */ + + dns_acache_t *acache; + unsigned int cleaning_interval; /* The cleaning-interval + from named.conf, + in seconds. */ + + isc_stdtime_t last_cleanup_time; /* The time when the last + cleanup task completed */ + + isc_timer_t *cleaning_timer; + isc_event_t *resched_event; /* Sent by cleaner task to + itself to reschedule */ + isc_event_t *overmem_event; + + dns_acacheentry_t *current_entry; /* The bookmark entry to + restart the cleaning. + Locked by acache lock. */ + int increment; /* Number of entries to + clean in one increment */ + + unsigned long ncleaned; /* Number of entries cleaned + up (for logging purposes) */ + cleaner_state_t state; /* Idle/Busy/Done. */ + isc_boolean_t overmem; /* The acache is in an overmem + state. */ +}; + +struct dns_acachestats { + unsigned int hits; + unsigned int queries; + unsigned int misses; + unsigned int adds; + unsigned int deleted; + unsigned int cleaned; + unsigned int cleaner_runs; + unsigned int overmem; + unsigned int overmem_nocreates; + unsigned int nomem; +}; + +/* + * The actual acache object. + */ + +struct dns_acache { + unsigned int magic; + + isc_mem_t *mctx; + isc_refcount_t refs; + +#ifdef ACACHE_USE_RWLOCK + isc_rwlock_t *entrylocks; +#else + isc_mutex_t *entrylocks; +#endif + + isc_mutex_t lock; + + int live_cleaners; + acache_cleaner_t cleaner; + ISC_LIST(dns_acacheentry_t) entries; + unsigned int dbentries; + dbentrylist_t dbbucket[DBBUCKETS]; + + isc_boolean_t shutting_down; + + isc_task_t *task; + isc_event_t cevent; + isc_boolean_t cevent_sent; + + dns_acachestats_t stats; +}; + +struct dns_acacheentry { + unsigned int magic; + + unsigned int locknum; + isc_refcount_t references; + + dns_acache_t *acache; + + /* Data for Management of cache entries */ + ISC_LINK(dns_acacheentry_t) link; + ISC_LINK(dns_acacheentry_t) olink; + ISC_LINK(dns_acacheentry_t) rlink; + + dns_db_t *origdb; /* reference to the DB + holding this entry */ + + /* Cache data */ + dns_zone_t *zone; /* zone this entry + belongs to */ + dns_db_t *db; /* DB this entry belongs to */ + dns_dbversion_t *version; /* the version of the DB */ + dns_dbnode_t *node; /* node this entry + belongs to */ + dns_name_t *foundname; /* corresponding DNS name + and rdataset */ + + /* Callback function and its argument */ + void (*callback)(dns_acacheentry_t *, void **); + void *cbarg; + + /* Timestamp of the last time this entry is referred to */ + isc_stdtime32_t lastused; +}; + +/* + * Internal functions (and prototypes). + */ +static inline isc_boolean_t check_noentry(dns_acache_t *acache); +static void destroy(dns_acache_t *acache); +static void shutdown_entries(dns_acache_t *acache); +static void shutdown_buckets(dns_acache_t *acache); +static void destroy_entry(dns_acacheentry_t *ent); +static inline void unlink_dbentries(dns_acache_t *acache, + dns_acacheentry_t *ent); +static inline isc_result_t finddbent(dns_acache_t *acache, + dns_db_t *db, dbentry_t **dbentryp); +static inline void clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry); +static isc_result_t acache_cleaner_init(dns_acache_t *acache, + isc_timermgr_t *timermgr, + acache_cleaner_t *cleaner); +static void acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event); +static void acache_incremental_cleaning_action(isc_task_t *task, + isc_event_t *event); +static void acache_overmem_cleaning_action(isc_task_t *task, + isc_event_t *event); +static void acache_cleaner_shutdown_action(isc_task_t *task, + isc_event_t *event); + +/* + * acache should be locked. If it is not, the stats can get out of whack, + * which is not a big deal for us since this is for debugging / stats + */ +static void +reset_stats(dns_acache_t *acache) { + acache->stats.hits = 0; + acache->stats.queries = 0; + acache->stats.misses = 0; + acache->stats.adds = 0; + acache->stats.deleted = 0; + acache->stats.cleaned = 0; + acache->stats.overmem = 0; + acache->stats.overmem_nocreates = 0; + acache->stats.nomem = 0; +} + +/* + * The acache must be locked before calling. + */ +static inline isc_boolean_t +check_noentry(dns_acache_t *acache) { + if (ISC_LIST_EMPTY(acache->entries) && acache->dbentries == 0) { + return (ISC_TRUE); + } + + return (ISC_FALSE); +} + +/* + * The acache must be locked before calling. + */ +static void +shutdown_entries(dns_acache_t *acache) { + dns_acacheentry_t *entry, *entry_next; + + REQUIRE(DNS_ACACHE_VALID(acache)); + INSIST(acache->shutting_down); + + /* + * Release the dependency of all entries, and detach them. + */ + for (entry = ISC_LIST_HEAD(acache->entries); + entry != NULL; + entry = entry_next) { + entry_next = ISC_LIST_NEXT(entry, link); + + ACACHE_LOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + /* + * If the cleaner holds this entry, it will be unlinked and + * freed in the cleaner later. + */ + if (acache->cleaner.current_entry != entry) + ISC_LIST_UNLINK(acache->entries, entry, link); + unlink_dbentries(acache, entry); + if (entry->callback != NULL) { + (entry->callback)(entry, &entry->cbarg); + entry->callback = NULL; + } + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + if (acache->cleaner.current_entry != entry) + dns_acache_detachentry(&entry); + } +} + +/* + * The acache must be locked before calling. + */ +static void +shutdown_buckets(dns_acache_t *acache) { + int i; + dbentry_t *dbent; + + REQUIRE(DNS_ACACHE_VALID(acache)); + INSIST(acache->shutting_down); + + for (i = 0; i < DBBUCKETS; i++) { + while ((dbent = ISC_LIST_HEAD(acache->dbbucket[i])) != NULL) { + INSIST(ISC_LIST_EMPTY(dbent->originlist) && + ISC_LIST_EMPTY(dbent->referlist)); + ISC_LIST_UNLINK(acache->dbbucket[i], dbent, link); + + dns_db_detach(&dbent->db); + + isc_mem_put(acache->mctx, dbent, sizeof(*dbent)); + + acache->dbentries--; + } + } + + INSIST(acache->dbentries == 0); +} + +static void +shutdown_task(isc_task_t *task, isc_event_t *ev) { + dns_acache_t *acache; + + UNUSED(task); + + acache = ev->ev_arg; + INSIST(DNS_ACACHE_VALID(acache)); + + isc_event_free(&ev); + + LOCK(&acache->lock); + + shutdown_entries(acache); + shutdown_buckets(acache); + + UNLOCK(&acache->lock); + + dns_acache_detach(&acache); +} + +/* The acache and the entry must be locked before calling. */ +static inline void +unlink_dbentries(dns_acache_t *acache, dns_acacheentry_t *ent) { + isc_result_t result; + dbentry_t *dbent; + + if (ISC_LINK_LINKED(ent, olink)) { + INSIST(ent->origdb != NULL); + dbent = NULL; + result = finddbent(acache, ent->origdb, &dbent); + INSIST(result == ISC_R_SUCCESS); + + ISC_LIST_UNLINK(dbent->originlist, ent, olink); + } + if (ISC_LINK_LINKED(ent, rlink)) { + INSIST(ent->db != NULL); + dbent = NULL; + result = finddbent(acache, ent->db, &dbent); + INSIST(result == ISC_R_SUCCESS); + + ISC_LIST_UNLINK(dbent->referlist, ent, rlink); + } +} + +/* There must not be a reference to this entry. */ +static void +destroy_entry(dns_acacheentry_t *entry) { + dns_acache_t *acache; + + REQUIRE(DNS_ACACHEENTRY_VALID(entry)); + + acache = entry->acache; + REQUIRE(DNS_ACACHE_VALID(acache)); + + /* + * Since there is no reference to this entry, it is safe to call + * clear_entry() here. + */ + clear_entry(acache, entry); + + isc_mem_put(acache->mctx, entry, sizeof(*entry)); + + dns_acache_detach(&acache); +} + +static void +destroy(dns_acache_t *acache) { + int i; + + REQUIRE(DNS_ACACHE_VALID(acache)); + + ATRACE("destroy"); + + isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0); + + if (acache->cleaner.overmem_event != NULL) + isc_event_free(&acache->cleaner.overmem_event); + + if (acache->cleaner.resched_event != NULL) + isc_event_free(&acache->cleaner.resched_event); + + if (acache->task != NULL) + isc_task_detach(&acache->task); + + for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) + ACACHE_DESTROYLOCK(&acache->entrylocks[i]); + isc_mem_put(acache->mctx, acache->entrylocks, + sizeof(*acache->entrylocks) * + DEFAULT_ACACHE_ENTRY_LOCK_COUNT); + + DESTROYLOCK(&acache->cleaner.lock); + + DESTROYLOCK(&acache->lock); + acache->magic = 0; + + isc_mem_putanddetach(&acache->mctx, acache, sizeof(*acache)); +} + +static inline isc_result_t +finddbent(dns_acache_t *acache, dns_db_t *db, dbentry_t **dbentryp) { + int bucket; + dbentry_t *dbentry; + + REQUIRE(DNS_ACACHE_VALID(acache)); + REQUIRE(db != NULL); + REQUIRE(dbentryp != NULL && *dbentryp == NULL); + + /* + * The caller must be holding the acache lock. + */ + + bucket = isc_hash_calc((const unsigned char *)&db, + sizeof(db), ISC_TRUE) % DBBUCKETS; + + for (dbentry = ISC_LIST_HEAD(acache->dbbucket[bucket]); + dbentry != NULL; + dbentry = ISC_LIST_NEXT(dbentry, link)) { + if (dbentry->db == db) + break; + } + + *dbentryp = dbentry; + + if (dbentry == NULL) + return (ISC_R_NOTFOUND); + else + return (ISC_R_SUCCESS); +} + +static inline void +clear_entry(dns_acache_t *acache, dns_acacheentry_t *entry) { + REQUIRE(DNS_ACACHE_VALID(acache)); + REQUIRE(DNS_ACACHEENTRY_VALID(entry)); + + /* + * The caller must be holing the entry lock. + */ + + if (entry->foundname) { + dns_rdataset_t *rdataset, *rdataset_next; + + for (rdataset = ISC_LIST_HEAD(entry->foundname->list); + rdataset != NULL; + rdataset = rdataset_next) { + rdataset_next = ISC_LIST_NEXT(rdataset, link); + ISC_LIST_UNLINK(entry->foundname->list, + rdataset, link); + dns_rdataset_disassociate(rdataset); + isc_mem_put(acache->mctx, rdataset, sizeof(*rdataset)); + } + if (dns_name_dynamic(entry->foundname)) + dns_name_free(entry->foundname, acache->mctx); + isc_mem_put(acache->mctx, entry->foundname, + sizeof(*entry->foundname)); + entry->foundname = NULL; + } + + if (entry->node != NULL) { + INSIST(entry->db != NULL); + dns_db_detachnode(entry->db, &entry->node); + } + if (entry->version != NULL) { + INSIST(entry->db != NULL); + dns_db_closeversion(entry->db, &entry->version, ISC_FALSE); + } + if (entry->db != NULL) + dns_db_detach(&entry->db); + if (entry->zone != NULL) + dns_zone_detach(&entry->zone); + + if (entry->origdb != NULL) + dns_db_detach(&entry->origdb); +} + +static isc_result_t +acache_cleaner_init(dns_acache_t *acache, isc_timermgr_t *timermgr, + acache_cleaner_t *cleaner) +{ + int result; + + ATRACE("acache cleaner init"); + + result = isc_mutex_init(&cleaner->lock); + if (result != ISC_R_SUCCESS) + goto fail; + + cleaner->increment = DNS_ACACHE_CLEANERINCREMENT; + cleaner->state = cleaner_s_idle; + cleaner->acache = acache; + cleaner->overmem = ISC_FALSE; + + cleaner->cleaning_timer = NULL; + cleaner->resched_event = NULL; + cleaner->overmem_event = NULL; + cleaner->current_entry = NULL; + + if (timermgr != NULL) { + cleaner->acache->live_cleaners++; + + result = isc_task_onshutdown(acache->task, + acache_cleaner_shutdown_action, + acache); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "acache cleaner: " + "isc_task_onshutdown() failed: %s", + dns_result_totext(result)); + goto cleanup; + } + + cleaner->cleaning_interval = 0; /* Initially turned off. */ + isc_stdtime_get(&cleaner->last_cleanup_time); + result = isc_timer_create(timermgr, isc_timertype_inactive, + NULL, NULL, + acache->task, + acache_cleaning_timer_action, + cleaner, &cleaner->cleaning_timer); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_timer_create() failed: %s", + dns_result_totext(result)); + result = ISC_R_UNEXPECTED; + goto cleanup; + } + + cleaner->resched_event = + isc_event_allocate(acache->mctx, cleaner, + DNS_EVENT_ACACHECLEAN, + acache_incremental_cleaning_action, + cleaner, sizeof(isc_event_t)); + if (cleaner->resched_event == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + + cleaner->overmem_event = + isc_event_allocate(acache->mctx, cleaner, + DNS_EVENT_ACACHEOVERMEM, + acache_overmem_cleaning_action, + cleaner, sizeof(isc_event_t)); + if (cleaner->overmem_event == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + } + + return (ISC_R_SUCCESS); + + cleanup: + if (cleaner->overmem_event != NULL) + isc_event_free(&cleaner->overmem_event); + if (cleaner->resched_event != NULL) + isc_event_free(&cleaner->resched_event); + if (cleaner->cleaning_timer != NULL) + isc_timer_detach(&cleaner->cleaning_timer); + cleaner->acache->live_cleaners--; + DESTROYLOCK(&cleaner->lock); + fail: + return (result); +} + +static void +begin_cleaning(acache_cleaner_t *cleaner) { + dns_acacheentry_t *head; + dns_acache_t *acache = cleaner->acache; + + /* + * This function does not have to lock the cleaner, since critical + * parameters (except current_entry, which is locked by acache lock,) + * are only used in a single task context. + */ + + REQUIRE(CLEANER_IDLE(cleaner)); + INSIST(DNS_ACACHE_VALID(acache)); + INSIST(cleaner->current_entry == NULL); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), + "begin acache cleaning, mem inuse %lu", + (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); + + LOCK(&acache->lock); + + head = ISC_LIST_HEAD(acache->entries); + if (head != NULL) + dns_acache_attachentry(head, &cleaner->current_entry); + + UNLOCK(&acache->lock); + + if (cleaner->current_entry != NULL) { + cleaner->ncleaned = 0; + cleaner->state = cleaner_s_busy; + isc_task_send(acache->task, &cleaner->resched_event); + } + + return; +} + +static void +end_cleaning(acache_cleaner_t *cleaner, isc_event_t *event) { + dns_acache_t *acache = cleaner->acache; + + REQUIRE(CLEANER_BUSY(cleaner)); + REQUIRE(event != NULL); + REQUIRE(DNS_ACACHEENTRY_VALID(cleaner->current_entry)); + + /* No need to lock the cleaner (see begin_cleaning()). */ + + LOCK(&acache->lock); + + /* + * Even if the cleaner has the last reference to the entry, which means + * the entry has been unused, it may still be linked if unlinking the + * entry has been delayed due to the reference. + */ + if (isc_refcount_current(&cleaner->current_entry->references) == 1) { + INSIST(cleaner->current_entry->callback == NULL); + + if (ISC_LINK_LINKED(cleaner->current_entry, link)) { + ISC_LIST_UNLINK(acache->entries, + cleaner->current_entry, link); + } + } + dns_acache_detachentry(&cleaner->current_entry); + + if (cleaner->overmem) + acache->stats.overmem++; + acache->stats.cleaned += cleaner->ncleaned; + acache->stats.cleaner_runs++; + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, + ISC_LOG_NOTICE, + "acache %p stats: hits=%d misses=%d queries=%d " + "adds=%d deleted=%d " + "cleaned=%d cleaner_runs=%d overmem=%d " + "overmem_nocreates=%d nomem=%d", + acache, + acache->stats.hits, acache->stats.misses, + acache->stats.queries, + acache->stats.adds, acache->stats.deleted, + acache->stats.cleaned, acache->stats.cleaner_runs, + acache->stats.overmem, acache->stats.overmem_nocreates, + acache->stats.nomem); + reset_stats(acache); + + isc_stdtime_get(&cleaner->last_cleanup_time); + + UNLOCK(&acache->lock); + + dns_acache_setcleaninginterval(cleaner->acache, + cleaner->cleaning_interval); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, + ISC_LOG_DEBUG(1), "end acache cleaning, " + "%lu entries cleaned, mem inuse %lu", + cleaner->ncleaned, + (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); + + if (cleaner->overmem) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, + "acache is still in overmem state " + "after cleaning"); + } + + cleaner->ncleaned = 0; + cleaner->state = cleaner_s_idle; + cleaner->resched_event = event; +} + +/* + * This is run once for every acache-cleaning-interval as defined + * in named.conf. + */ +static void +acache_cleaning_timer_action(isc_task_t *task, isc_event_t *event) { + acache_cleaner_t *cleaner = event->ev_arg; + + UNUSED(task); + + INSIST(event->ev_type == ISC_TIMEREVENT_TICK); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, + ISC_LOG_DEBUG(1), "acache cleaning timer fired, " + "cleaner state = %d", cleaner->state); + + if (cleaner->state == cleaner_s_idle) + begin_cleaning(cleaner); + + isc_event_free(&event); +} + +/* The caller must hold entry lock. */ +static inline isc_boolean_t +entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry, + isc_stdtime32_t now32, unsigned int interval) +{ + /* + * If the callback has been canceled, we definitely do not need the + * entry. + */ + if (entry->callback == NULL) + return (ISC_TRUE); + + if (interval > cleaner->cleaning_interval) + interval = cleaner->cleaning_interval; + + if (entry->lastused + interval < now32) + return (ISC_TRUE); + + /* + * If the acache is in the overmem state, probabilistically decide if + * the entry should be purged, based on the time passed from its last + * use and the cleaning interval. + */ + if (cleaner->overmem) { + unsigned int passed = + now32 - entry->lastused; /* <= interval */ + isc_uint32_t val; + + if (passed > interval / 2) + return (ISC_TRUE); + isc_random_get(&val); + if (passed > interval / 4) + return (ISC_TF(val % 4 == 0)); + return (ISC_TF(val % 8 == 0)); + } + + return (ISC_FALSE); +} + +/* + * Do incremental cleaning. + */ +static void +acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { + acache_cleaner_t *cleaner = event->ev_arg; + dns_acache_t *acache = cleaner->acache; + dns_acacheentry_t *entry, *next = NULL; + int n_entries; + isc_stdtime32_t now32, last32; + isc_stdtime_t now; + unsigned int interval; + + INSIST(DNS_ACACHE_VALID(acache)); + INSIST(task == acache->task); + INSIST(event->ev_type == DNS_EVENT_ACACHECLEAN); + + if (cleaner->state == cleaner_s_done) { + cleaner->state = cleaner_s_busy; + end_cleaning(cleaner, event); + return; + } + + INSIST(CLEANER_BUSY(cleaner)); + + n_entries = cleaner->increment; + + isc_stdtime_get(&now); + isc_stdtime_convert32(now, &now32); + + LOCK(&acache->lock); + + entry = cleaner->current_entry; + isc_stdtime_convert32(cleaner->last_cleanup_time, &last32); + INSIST(now32 > last32); + interval = now32 - last32; + + while (n_entries-- > 0) { + isc_boolean_t is_stale = ISC_FALSE; + + INSIST(entry != NULL); + + next = ISC_LIST_NEXT(entry, link); + + ACACHE_LOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + is_stale = entry_stale(cleaner, entry, now32, interval); + if (is_stale) { + ISC_LIST_UNLINK(acache->entries, entry, link); + unlink_dbentries(acache, entry); + if (entry->callback != NULL) + (entry->callback)(entry, &entry->cbarg); + entry->callback = NULL; + + cleaner->ncleaned++; + } + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + if (is_stale) + dns_acache_detachentry(&entry); + + if (next == NULL) { + if (cleaner->overmem) { + entry = ISC_LIST_HEAD(acache->entries); + if (entry != NULL) { + /* + * If we are still in the overmem + * state, keep cleaning. + */ + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_ACACHE, + ISC_LOG_DEBUG(1), + "acache cleaner: " + "still overmem, " + "reset and try again"); + continue; + } + } + + UNLOCK(&acache->lock); + end_cleaning(cleaner, event); + return; + } + + entry = next; + } + + /* + * We have successfully performed a cleaning increment but have + * not gone through the entire cache. Remember the entry that will + * be the starting point in the next clean-up, and reschedule another + * batch. If it fails, just try to continue anyway. + */ + INSIST(next != NULL && next != cleaner->current_entry); + dns_acache_detachentry(&cleaner->current_entry); + dns_acache_attachentry(next, &cleaner->current_entry); + + UNLOCK(&acache->lock); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, + ISC_LOG_DEBUG(1), "acache cleaner: checked %d entries, " + "mem inuse %lu, sleeping", cleaner->increment, + (unsigned long)isc_mem_inuse(cleaner->acache->mctx)); + + isc_task_send(task, &event); + INSIST(CLEANER_BUSY(cleaner)); + + return; +} + +/* + * This is called when the acache either surpasses its upper limit + * or shrinks beyond its lower limit. + */ +static void +acache_overmem_cleaning_action(isc_task_t *task, isc_event_t *event) { + acache_cleaner_t *cleaner = event->ev_arg; + isc_boolean_t want_cleaning = ISC_FALSE; + + UNUSED(task); + + INSIST(event->ev_type == DNS_EVENT_ACACHEOVERMEM); + INSIST(cleaner->overmem_event == NULL); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ACACHE, + ISC_LOG_DEBUG(1), "overmem_cleaning_action called, " + "overmem = %d, state = %d", cleaner->overmem, + cleaner->state); + + LOCK(&cleaner->lock); + + if (cleaner->overmem) { + if (cleaner->state == cleaner_s_idle) + want_cleaning = ISC_TRUE; + } else { + if (cleaner->state == cleaner_s_busy) + /* + * end_cleaning() can't be called here because + * then both cleaner->overmem_event and + * cleaner->resched_event will point to this + * event. Set the state to done, and then + * when the acache_incremental_cleaning_action() event + * is posted, it will handle the end_cleaning. + */ + cleaner->state = cleaner_s_done; + } + + cleaner->overmem_event = event; + + UNLOCK(&cleaner->lock); + + if (want_cleaning) + begin_cleaning(cleaner); +} + +static void +water(void *arg, int mark) { + dns_acache_t *acache = arg; + isc_boolean_t overmem = ISC_TF(mark == ISC_MEM_HIWATER); + + REQUIRE(DNS_ACACHE_VALID(acache)); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_ACACHE, ISC_LOG_DEBUG(1), + "acache memory reaches %s watermark, mem inuse %lu", + overmem ? "high" : "low", + (unsigned long)isc_mem_inuse(acache->mctx)); + + LOCK(&acache->cleaner.lock); + + acache->cleaner.overmem = overmem; + + if (acache->cleaner.overmem_event != NULL) + isc_task_send(acache->task, &acache->cleaner.overmem_event); + + UNLOCK(&acache->cleaner.lock); +} + +/* + * The cleaner task is shutting down; do the necessary cleanup. + */ +static void +acache_cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) { + dns_acache_t *acache = event->ev_arg; + isc_boolean_t should_free = ISC_FALSE; + + INSIST(task == acache->task); + INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN); + INSIST(DNS_ACACHE_VALID(acache)); + + ATRACE("acache cleaner shutdown"); + + if (CLEANER_BUSY(&acache->cleaner)) + end_cleaning(&acache->cleaner, event); + else + isc_event_free(&event); + + LOCK(&acache->lock); + + acache->live_cleaners--; + INSIST(acache->live_cleaners == 0); + + if (isc_refcount_current(&acache->refs) == 0) { + INSIST(check_noentry(acache) == ISC_TRUE); + should_free = ISC_TRUE; + } + + /* + * By detaching the timer in the context of its task, + * we are guaranteed that there will be no further timer + * events. + */ + if (acache->cleaner.cleaning_timer != NULL) + isc_timer_detach(&acache->cleaner.cleaning_timer); + + /* Make sure we don't reschedule anymore. */ + (void)isc_task_purge(task, NULL, DNS_EVENT_ACACHECLEAN, NULL); + + UNLOCK(&acache->lock); + + if (should_free) + destroy(acache); +} + +/* + * Public functions. + */ + +isc_result_t +dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx, + isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr) +{ + int i; + isc_result_t result; + dns_acache_t *acache; + + REQUIRE(acachep != NULL && *acachep == NULL); + REQUIRE(mctx != NULL); + REQUIRE(taskmgr != NULL); + + acache = isc_mem_get(mctx, sizeof(*acache)); + if (acache == NULL) + return (ISC_R_NOMEMORY); + + ATRACE("create"); + + result = isc_refcount_init(&acache->refs, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, acache, sizeof(*acache)); + return (result); + } + + result = isc_mutex_init(&acache->lock); + if (result != ISC_R_SUCCESS) { + isc_refcount_decrement(&acache->refs, NULL); + isc_refcount_destroy(&acache->refs); + isc_mem_put(mctx, acache, sizeof(*acache)); + return (result); + } + + acache->mctx = NULL; + isc_mem_attach(mctx, &acache->mctx); + ISC_LIST_INIT(acache->entries); + + acache->shutting_down = ISC_FALSE; + + acache->task = NULL; + acache->entrylocks = NULL; + + result = isc_task_create(taskmgr, 1, &acache->task); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_task_create() failed(): %s", + dns_result_totext(result)); + result = ISC_R_UNEXPECTED; + goto cleanup; + } + isc_task_setname(acache->task, "acachetask", acache); + ISC_EVENT_INIT(&acache->cevent, sizeof(acache->cevent), 0, NULL, + DNS_EVENT_ACACHECONTROL, shutdown_task, NULL, + NULL, NULL, NULL); + acache->cevent_sent = ISC_FALSE; + + acache->dbentries = 0; + for (i = 0; i < DBBUCKETS; i++) + ISC_LIST_INIT(acache->dbbucket[i]); + + acache->entrylocks = isc_mem_get(mctx, sizeof(*acache->entrylocks) * + DEFAULT_ACACHE_ENTRY_LOCK_COUNT); + if (acache->entrylocks == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) { + result = ACACHE_INITLOCK(&acache->entrylocks[i]); + if (result != ISC_R_SUCCESS) { + while (i-- > 0) + ACACHE_DESTROYLOCK(&acache->entrylocks[i]); + isc_mem_put(mctx, acache->entrylocks, + sizeof(*acache->entrylocks) * + DEFAULT_ACACHE_ENTRY_LOCK_COUNT); + acache->entrylocks = NULL; + goto cleanup; + } + } + + acache->live_cleaners = 0; + result = acache_cleaner_init(acache, timermgr, &acache->cleaner); + if (result != ISC_R_SUCCESS) + goto cleanup; + + acache->stats.cleaner_runs = 0; + reset_stats(acache); + + acache->magic = ACACHE_MAGIC; + + *acachep = acache; + return (ISC_R_SUCCESS); + + cleanup: + if (acache->task != NULL) + isc_task_detach(&acache->task); + DESTROYLOCK(&acache->lock); + isc_refcount_decrement(&acache->refs, NULL); + isc_refcount_destroy(&acache->refs); + if (acache->entrylocks != NULL) { + for (i = 0; i < DEFAULT_ACACHE_ENTRY_LOCK_COUNT; i++) + ACACHE_DESTROYLOCK(&acache->entrylocks[i]); + isc_mem_put(mctx, acache->entrylocks, + sizeof(*acache->entrylocks) * + DEFAULT_ACACHE_ENTRY_LOCK_COUNT); + } + isc_mem_put(mctx, acache, sizeof(*acache)); + isc_mem_detach(&mctx); + + return (result); +} + +void +dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp) { + REQUIRE(DNS_ACACHE_VALID(source)); + REQUIRE(targetp != NULL && *targetp == NULL); + + AATRACE(source, "attach"); + + isc_refcount_increment(&source->refs, NULL); + + *targetp = source; +} + +void +dns_acache_countquerymiss(dns_acache_t *acache) { + acache->stats.misses++; /* XXXSK danger: unlocked! */ + acache->stats.queries++; /* XXXSK danger: unlocked! */ +} + +void +dns_acache_detach(dns_acache_t **acachep) { + dns_acache_t *acache; + unsigned int refs; + isc_boolean_t should_free = ISC_FALSE; + + REQUIRE(acachep != NULL && DNS_ACACHE_VALID(*acachep)); + acache = *acachep; + + ATRACE("detach"); + + isc_refcount_decrement(&acache->refs, &refs); + if (refs == 0) { + INSIST(check_noentry(acache) == ISC_TRUE); + should_free = ISC_TRUE; + } + + *acachep = NULL; + + /* + * If we're exiting and the cleaner task exists, let it free the cache. + */ + if (should_free && acache->live_cleaners > 0) { + isc_task_shutdown(acache->task); + should_free = ISC_FALSE; + } + + if (should_free) + destroy(acache); +} + +void +dns_acache_shutdown(dns_acache_t *acache) { + REQUIRE(DNS_ACACHE_VALID(acache)); + + LOCK(&acache->lock); + + ATRACE("shutdown"); + + if (!acache->shutting_down) { + isc_event_t *event; + dns_acache_t *acache_evarg = NULL; + + INSIST(!acache->cevent_sent); + + acache->shutting_down = ISC_TRUE; + + isc_mem_setwater(acache->mctx, NULL, NULL, 0, 0); + + /* + * Self attach the object in order to prevent it from being + * destroyed while waiting for the event. + */ + dns_acache_attach(acache, &acache_evarg); + event = &acache->cevent; + event->ev_arg = acache_evarg; + isc_task_send(acache->task, &event); + acache->cevent_sent = ISC_TRUE; + } + + UNLOCK(&acache->lock); +} + +isc_result_t +dns_acache_setdb(dns_acache_t *acache, dns_db_t *db) { + int bucket; + dbentry_t *dbentry; + isc_result_t result = ISC_R_SUCCESS; + + REQUIRE(DNS_ACACHE_VALID(acache)); + REQUIRE(db != NULL); + + ATRACE("setdb"); + + LOCK(&acache->lock); + + dbentry = NULL; + result = finddbent(acache, db, &dbentry); + if (result == ISC_R_SUCCESS) { + result = ISC_R_EXISTS; + goto end; + } + result = ISC_R_SUCCESS; + + dbentry = isc_mem_get(acache->mctx, sizeof(*dbentry)); + if (dbentry == NULL) { + result = ISC_R_NOMEMORY; + goto end; + } + + ISC_LINK_INIT(dbentry, link); + ISC_LIST_INIT(dbentry->originlist); + ISC_LIST_INIT(dbentry->referlist); + + dbentry->db = NULL; + dns_db_attach(db, &dbentry->db); + + bucket = isc_hash_calc((const unsigned char *)&db, + sizeof(db), ISC_TRUE) % DBBUCKETS; + + ISC_LIST_APPEND(acache->dbbucket[bucket], dbentry, link); + + acache->dbentries++; + + end: + UNLOCK(&acache->lock); + + return (result); +} + +isc_result_t +dns_acache_putdb(dns_acache_t *acache, dns_db_t *db) { + int bucket; + isc_result_t result; + dbentry_t *dbentry; + dns_acacheentry_t *entry; + + REQUIRE(DNS_ACACHE_VALID(acache)); + REQUIRE(db != NULL); + + ATRACE("putdb"); + + LOCK(&acache->lock); + + dbentry = NULL; + result = finddbent(acache, db, &dbentry); + if (result != ISC_R_SUCCESS) { + /* + * The entry may have not been created due to memory shortage. + */ + UNLOCK(&acache->lock); + return (ISC_R_NOTFOUND); + } + + /* + * Release corresponding cache entries: for each entry, release all + * links the entry has, and then callback to the entry holder (if any). + * If no other external references exist (this can happen if the + * original holder has canceled callback,) destroy it here. + */ + while ((entry = ISC_LIST_HEAD(dbentry->originlist)) != NULL) { + ACACHE_LOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + /* + * Releasing olink first would avoid finddbent() in + * unlink_dbentries(). + */ + ISC_LIST_UNLINK(dbentry->originlist, entry, olink); + if (acache->cleaner.current_entry != entry) + ISC_LIST_UNLINK(acache->entries, entry, link); + unlink_dbentries(acache, entry); + + if (entry->callback != NULL) + (entry->callback)(entry, &entry->cbarg); + entry->callback = NULL; + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + if (acache->cleaner.current_entry != entry) + dns_acache_detachentry(&entry); + } + while ((entry = ISC_LIST_HEAD(dbentry->referlist)) != NULL) { + ACACHE_LOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + ISC_LIST_UNLINK(dbentry->referlist, entry, rlink); + if (acache->cleaner.current_entry != entry) + ISC_LIST_UNLINK(acache->entries, entry, link); + unlink_dbentries(acache, entry); + + if (entry->callback != NULL) + (entry->callback)(entry, &entry->cbarg); + entry->callback = NULL; + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + if (acache->cleaner.current_entry != entry) + dns_acache_detachentry(&entry); + } + + INSIST(ISC_LIST_EMPTY(dbentry->originlist) && + ISC_LIST_EMPTY(dbentry->referlist)); + + bucket = isc_hash_calc((const unsigned char *)&db, + sizeof(db), ISC_TRUE) % DBBUCKETS; + ISC_LIST_UNLINK(acache->dbbucket[bucket], dbentry, link); + dns_db_detach(&dbentry->db); + + isc_mem_put(acache->mctx, dbentry, sizeof(*dbentry)); + + acache->dbentries--; + + acache->stats.deleted++; + + UNLOCK(&acache->lock); + + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, + void (*callback)(dns_acacheentry_t *, void **), + void *cbarg, dns_acacheentry_t **entryp) +{ + dns_acacheentry_t *newentry; + isc_result_t result; + isc_uint32_t r; + + REQUIRE(DNS_ACACHE_VALID(acache)); + REQUIRE(entryp != NULL && *entryp == NULL); + REQUIRE(origdb != NULL); + + /* + * Should we exceed our memory limit for some reason (for + * example, if the cleaner does not run aggressively enough), + * then we will not create additional entries. + * + * XXXSK: It might be better to lock the acache->cleaner->lock, + * but locking may be an expensive bottleneck. If we misread + * the value, we will occasionally refuse to create a few + * cache entries, or create a few that we should not. I do not + * expect this to happen often, and it will not have very bad + * effects when it does. So no lock for now. + */ + if (acache->cleaner.overmem) { + acache->stats.overmem_nocreates++; /* XXXSK danger: unlocked! */ + return (ISC_R_NORESOURCES); + } + + newentry = isc_mem_get(acache->mctx, sizeof(*newentry)); + if (newentry == NULL) { + acache->stats.nomem++; /* XXXMLG danger: unlocked! */ + return (ISC_R_NOMEMORY); + } + + isc_random_get(&r); + newentry->locknum = r % DEFAULT_ACACHE_ENTRY_LOCK_COUNT; + + result = isc_refcount_init(&newentry->references, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(acache->mctx, newentry, sizeof(*newentry)); + return (result); + }; + + ISC_LINK_INIT(newentry, link); + ISC_LINK_INIT(newentry, olink); + ISC_LINK_INIT(newentry, rlink); + + newentry->acache = NULL; + dns_acache_attach(acache, &newentry->acache); + + newentry->zone = NULL; + newentry->db = NULL; + newentry->version = NULL; + newentry->node = NULL; + newentry->foundname = NULL; + + newentry->callback = callback; + newentry->cbarg = cbarg; + newentry->origdb = NULL; + dns_db_attach(origdb, &newentry->origdb); + + isc_stdtime_get(&newentry->lastused); + + newentry->magic = ACACHEENTRY_MAGIC; + + *entryp = newentry; + + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep, + dns_db_t **dbp, dns_dbversion_t **versionp, + dns_dbnode_t **nodep, dns_name_t *fname, + dns_message_t *msg, isc_stdtime_t now) +{ + isc_result_t result = ISC_R_SUCCESS; + dns_rdataset_t *erdataset; + isc_stdtime32_t now32; + dns_acache_t *acache; + int locknum; + + REQUIRE(DNS_ACACHEENTRY_VALID(entry)); + REQUIRE(zonep == NULL || *zonep == NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + REQUIRE(versionp != NULL && *versionp == NULL); + REQUIRE(nodep != NULL && *nodep == NULL); + REQUIRE(fname != NULL); + REQUIRE(msg != NULL); + acache = entry->acache; + REQUIRE(DNS_ACACHE_VALID(acache)); + + locknum = entry->locknum; + ACACHE_LOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); + + isc_stdtime_convert32(now, &now32); + acache_storetime(entry, now32); + + if (entry->zone != NULL && zonep != NULL) + dns_zone_attach(entry->zone, zonep); + + if (entry->db == NULL) { + *dbp = NULL; + *versionp = NULL; + } else { + dns_db_attach(entry->db, dbp); + dns_db_attachversion(entry->db, entry->version, versionp); + } + if (entry->node == NULL) + *nodep = NULL; + else { + dns_db_attachnode(entry->db, entry->node, nodep); + + INSIST(entry->foundname != NULL); + dns_name_copy(entry->foundname, fname, NULL); + for (erdataset = ISC_LIST_HEAD(entry->foundname->list); + erdataset != NULL; + erdataset = ISC_LIST_NEXT(erdataset, link)) { + dns_rdataset_t *ardataset; + + ardataset = NULL; + result = dns_message_gettemprdataset(msg, &ardataset); + if (result != ISC_R_SUCCESS) { + ACACHE_UNLOCK(&acache->entrylocks[locknum], + isc_rwlocktype_read); + goto fail; + } + + /* + * XXXJT: if we simply clone the rdataset, we'll get + * lost wrt cyclic ordering. We'll need an additional + * trick to get the latest counter from the original + * header. + */ + dns_rdataset_init(ardataset); + dns_rdataset_clone(erdataset, ardataset); + ISC_LIST_APPEND(fname->list, ardataset, link); + } + } + + entry->acache->stats.hits++; /* XXXMLG danger: unlocked! */ + entry->acache->stats.queries++; + + ACACHE_UNLOCK(&acache->entrylocks[locknum], isc_rwlocktype_read); + + return (result); + + fail: + while ((erdataset = ISC_LIST_HEAD(fname->list)) != NULL) { + ISC_LIST_UNLINK(fname->list, erdataset, link); + dns_rdataset_disassociate(erdataset); + dns_message_puttemprdataset(msg, &erdataset); + } + if (*nodep != NULL) + dns_db_detachnode(*dbp, nodep); + if (*versionp != NULL) + dns_db_closeversion(*dbp, versionp, ISC_FALSE); + if (*dbp != NULL) + dns_db_detach(dbp); + if (zonep != NULL && *zonep != NULL) + dns_zone_detach(zonep); + + return (result); +} + +isc_result_t +dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, + dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, + dns_dbnode_t *node, dns_name_t *fname) +{ + isc_result_t result; + dbentry_t *odbent; + dbentry_t *rdbent = NULL; + isc_boolean_t close_version = ISC_FALSE; + dns_acacheentry_t *dummy_entry = NULL; + + REQUIRE(DNS_ACACHE_VALID(acache)); + REQUIRE(DNS_ACACHEENTRY_VALID(entry)); + + LOCK(&acache->lock); /* XXX: need to lock it here for ordering */ + ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); + + /* Set zone */ + if (zone != NULL) + dns_zone_attach(zone, &entry->zone); + /* Set DB */ + if (db != NULL) + dns_db_attach(db, &entry->db); + /* + * Set DB version. If the version is not given by the caller, + * which is the case for glue or cache DBs, use the current version. + */ + if (version == NULL) { + if (db != NULL) { + dns_db_currentversion(db, &version); + close_version = ISC_TRUE; + } + } + if (version != NULL) { + INSIST(db != NULL); + dns_db_attachversion(db, version, &entry->version); + } + if (close_version) + dns_db_closeversion(db, &version, ISC_FALSE); + /* Set DB node. */ + if (node != NULL) { + INSIST(db != NULL); + dns_db_attachnode(db, node, &entry->node); + } + + /* + * Set list of the corresponding rdatasets, if given. + * To minimize the overhead and memory consumption, we'll do this for + * positive cache only, in which case the DB node is non NULL. + * We do not want to cache incomplete information, so give up the + * entire entry when a memory shortage happen during the process. + */ + if (node != NULL) { + dns_rdataset_t *ardataset, *crdataset; + + entry->foundname = isc_mem_get(acache->mctx, + sizeof(*entry->foundname)); + + if (entry->foundname == NULL) { + result = ISC_R_NOMEMORY; + goto fail; + } + dns_name_init(entry->foundname, NULL); + result = dns_name_dup(fname, acache->mctx, + entry->foundname); + if (result != ISC_R_SUCCESS) + goto fail; + + for (ardataset = ISC_LIST_HEAD(fname->list); + ardataset != NULL; + ardataset = ISC_LIST_NEXT(ardataset, link)) { + crdataset = isc_mem_get(acache->mctx, + sizeof(*crdataset)); + if (crdataset == NULL) { + result = ISC_R_NOMEMORY; + goto fail; + } + + dns_rdataset_init(crdataset); + dns_rdataset_clone(ardataset, crdataset); + ISC_LIST_APPEND(entry->foundname->list, crdataset, + link); + } + } + + odbent = NULL; + result = finddbent(acache, entry->origdb, &odbent); + if (result != ISC_R_SUCCESS) + goto fail; + if (db != NULL) { + rdbent = NULL; + result = finddbent(acache, db, &rdbent); + if (result != ISC_R_SUCCESS) + goto fail; + } + + ISC_LIST_APPEND(acache->entries, entry, link); + ISC_LIST_APPEND(odbent->originlist, entry, olink); + if (rdbent != NULL) + ISC_LIST_APPEND(rdbent->referlist, entry, rlink); + + /* + * The additional cache needs an implicit reference to entries in its + * link. + */ + dns_acache_attachentry(entry, &dummy_entry); + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + + acache->stats.adds++; + UNLOCK(&acache->lock); + + return (ISC_R_SUCCESS); + + fail: + clear_entry(acache, entry); + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + UNLOCK(&acache->lock); + + return (result); +} + +void +dns_acache_cancelentry(dns_acacheentry_t *entry) { + dns_acache_t *acache = entry->acache; + + REQUIRE(DNS_ACACHEENTRY_VALID(entry)); + INSIST(DNS_ACACHE_VALID(acache)); + + LOCK(&acache->lock); + ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write); + + /* + * Release dependencies stored in this entry as much as possible. + * The main link cannot be released, since the acache object has + * a reference to this entry; the empty entry will be released in + * the next cleaning action. + */ + unlink_dbentries(acache, entry); + clear_entry(entry->acache, entry); + + entry->callback = NULL; + entry->cbarg = NULL; + + ACACHE_UNLOCK(&acache->entrylocks[entry->locknum], + isc_rwlocktype_write); + UNLOCK(&acache->lock); +} + +void +dns_acache_attachentry(dns_acacheentry_t *source, + dns_acacheentry_t **targetp) +{ + REQUIRE(DNS_ACACHEENTRY_VALID(source)); + REQUIRE(targetp != NULL && *targetp == NULL); + + isc_refcount_increment(&source->references, NULL); + + *targetp = source; +} + +void +dns_acache_detachentry(dns_acacheentry_t **entryp) { + dns_acacheentry_t *entry; + unsigned int refs; + + REQUIRE(entryp != NULL && DNS_ACACHEENTRY_VALID(*entryp)); + entry = *entryp; + + isc_refcount_decrement(&entry->references, &refs); + + /* + * If there are no references to the entry, the entry must have been + * unlinked and can be destroyed safely. + */ + if (refs == 0) { + INSIST(!ISC_LINK_LINKED(entry, link)); + (*entryp)->acache->stats.deleted++; + destroy_entry(entry); + } + + *entryp = NULL; +} + +void +dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t) { + isc_interval_t interval; + isc_result_t result; + + REQUIRE(DNS_ACACHE_VALID(acache)); + + ATRACE("dns_acache_setcleaninginterval"); + + LOCK(&acache->lock); + + /* + * It may be the case that the acache has already shut down. + * If so, it has no timer. (Not sure if this can really happen.) + */ + if (acache->cleaner.cleaning_timer == NULL) + goto unlock; + + acache->cleaner.cleaning_interval = t; + + if (t == 0) { + result = isc_timer_reset(acache->cleaner.cleaning_timer, + isc_timertype_inactive, + NULL, NULL, ISC_TRUE); + } else { + isc_interval_set(&interval, acache->cleaner.cleaning_interval, + 0); + result = isc_timer_reset(acache->cleaner.cleaning_timer, + isc_timertype_ticker, + NULL, &interval, ISC_FALSE); + } + if (result != ISC_R_SUCCESS) + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_ACACHE, ISC_LOG_WARNING, + "could not set acache cleaning interval: %s", + isc_result_totext(result)); + else + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_ACACHE, ISC_LOG_NOTICE, + "acache %p cleaning interval set to %d.", + acache, t); + + unlock: + UNLOCK(&acache->lock); +} + +/* + * This function was derived from cache.c:dns_cache_setcachesize(). See the + * function for more details about the logic. + */ +void +dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size) { + isc_uint32_t lowater; + isc_uint32_t hiwater; + + REQUIRE(DNS_ACACHE_VALID(acache)); + + if (size != 0 && size < DNS_ACACHE_MINSIZE) + size = DNS_ACACHE_MINSIZE; + + hiwater = size - (size >> 3); + lowater = size - (size >> 2); + + if (size == 0 || hiwater == 0 || lowater == 0) + isc_mem_setwater(acache->mctx, water, acache, 0, 0); + else + isc_mem_setwater(acache->mctx, water, acache, + hiwater, lowater); +} diff --git a/contrib/bind9/lib/dns/acl.c b/contrib/bind9/lib/dns/acl.c index e81d5ef..844c132 100644 --- a/contrib/bind9/lib/dns/acl.c +++ b/contrib/bind9/lib/dns/acl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acl.c,v 1.23.52.6 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: acl.c,v 1.25.18.5 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -41,7 +43,11 @@ dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) { return (ISC_R_NOMEMORY); acl->mctx = mctx; acl->name = NULL; - isc_refcount_init(&acl->refcount, 1); + result = isc_refcount_init(&acl->refcount, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, acl, sizeof(*acl)); + return (result); + } acl->elements = NULL; acl->alloc = 0; acl->length = 0; diff --git a/contrib/bind9/lib/dns/adb.c b/contrib/bind9/lib/dns/adb.c index 3fe436a..714df96 100644 --- a/contrib/bind9/lib/dns/adb.c +++ b/contrib/bind9/lib/dns/adb.c @@ -15,19 +15,18 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: adb.c,v 1.181.2.11.2.26 2006/01/04 23:50:20 marka Exp $ */ +/* $Id: adb.c,v 1.215.18.13 2006/08/30 23:49:57 marka Exp $ */ -/* - * Implementation notes - * -------------------- +/*! \file * + * \note * In finds, if task == NULL, no events will be generated, and no events * have been sent. If task != NULL but taskaction == NULL, an event has been * posted but not yet freed. If neither are NULL, no event was posted. * */ -/* +/*% * After we have cleaned all buckets, dump the database contents. */ #if 0 @@ -53,6 +52,7 @@ #include <dns/rdata.h> #include <dns/rdataset.h> #include <dns/rdatastruct.h> +#include <dns/rdatatype.h> #include <dns/resolver.h> #include <dns/result.h> @@ -62,8 +62,8 @@ #define DNS_ADBNAME_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAME_MAGIC) #define DNS_ADBNAMEHOOK_MAGIC ISC_MAGIC('a', 'd', 'N', 'H') #define DNS_ADBNAMEHOOK_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBNAMEHOOK_MAGIC) -#define DNS_ADBZONEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z') -#define DNS_ADBZONEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBZONEINFO_MAGIC) +#define DNS_ADBLAMEINFO_MAGIC ISC_MAGIC('a', 'd', 'b', 'Z') +#define DNS_ADBLAMEINFO_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBLAMEINFO_MAGIC) #define DNS_ADBENTRY_MAGIC ISC_MAGIC('a', 'd', 'b', 'E') #define DNS_ADBENTRY_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBENTRY_MAGIC) #define DNS_ADBFETCH_MAGIC ISC_MAGIC('a', 'd', 'F', '4') @@ -71,51 +71,54 @@ #define DNS_ADBFETCH6_MAGIC ISC_MAGIC('a', 'd', 'F', '6') #define DNS_ADBFETCH6_VALID(x) ISC_MAGIC_VALID(x, DNS_ADBFETCH6_MAGIC) -/* +/*! * The number of buckets needs to be a prime (for good hashing). * * XXXRTH How many buckets do we need? */ -#define NBUCKETS 1009 /* how many buckets for names/addrs */ +#define NBUCKETS 1009 /*%< how many buckets for names/addrs */ -/* +/*! * For type 3 negative cache entries, we will remember that the address is * broken for this long. XXXMLG This is also used for actual addresses, too. * The intent is to keep us from constantly asking about A/AAAA records * if the zone has extremely low TTLs. */ -#define ADB_CACHE_MINIMUM 10 /* seconds */ -#define ADB_CACHE_MAXIMUM 86400 /* seconds (86400 = 24 hours) */ -#define ADB_ENTRY_WINDOW 1800 /* seconds */ +#define ADB_CACHE_MINIMUM 10 /*%< seconds */ +#define ADB_CACHE_MAXIMUM 86400 /*%< seconds (86400 = 24 hours) */ +#define ADB_ENTRY_WINDOW 1800 /*%< seconds */ -/* +/*% * Wake up every CLEAN_SECONDS and clean CLEAN_BUCKETS buckets, so that all * buckets are cleaned in CLEAN_PERIOD seconds. */ #define CLEAN_PERIOD 3600 +/*% See #CLEAN_PERIOD */ #define CLEAN_SECONDS 30 +/*% See #CLEAN_PERIOD */ #define CLEAN_BUCKETS ((NBUCKETS * CLEAN_SECONDS) / CLEAN_PERIOD) -#define FREE_ITEMS 64 /* free count for memory pools */ -#define FILL_COUNT 16 /* fill count for memory pools */ +#define FREE_ITEMS 64 /*%< free count for memory pools */ +#define FILL_COUNT 16 /*%< fill count for memory pools */ -#define DNS_ADB_INVALIDBUCKET (-1) /* invalid bucket address */ +#define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */ -#define DNS_ADB_MINADBSIZE (1024*1024) /* 1 Megabyte */ +#define DNS_ADB_MINADBSIZE (1024*1024) /*%< 1 Megabyte */ typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t; typedef struct dns_adbnamehook dns_adbnamehook_t; typedef ISC_LIST(dns_adbnamehook_t) dns_adbnamehooklist_t; -typedef struct dns_adbzoneinfo dns_adbzoneinfo_t; +typedef struct dns_adblameinfo dns_adblameinfo_t; typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t; typedef struct dns_adbfetch dns_adbfetch_t; typedef struct dns_adbfetch6 dns_adbfetch6_t; +/*% dns adb structure */ struct dns_adb { unsigned int magic; isc_mutex_t lock; - isc_mutex_t reflock; /* Covers irefcnt, erefcnt */ + isc_mutex_t reflock; /*%< Covers irefcnt, erefcnt */ isc_mem_t *mctx; dns_view_t *view; isc_timermgr_t *timermgr; @@ -131,32 +134,35 @@ struct dns_adb { unsigned int erefcnt; isc_mutex_t mplock; - isc_mempool_t *nmp; /* dns_adbname_t */ - isc_mempool_t *nhmp; /* dns_adbnamehook_t */ - isc_mempool_t *zimp; /* dns_adbzoneinfo_t */ - isc_mempool_t *emp; /* dns_adbentry_t */ - isc_mempool_t *ahmp; /* dns_adbfind_t */ - isc_mempool_t *aimp; /* dns_adbaddrinfo_t */ - isc_mempool_t *afmp; /* dns_adbfetch_t */ - - /* + isc_mempool_t *nmp; /*%< dns_adbname_t */ + isc_mempool_t *nhmp; /*%< dns_adbnamehook_t */ + isc_mempool_t *limp; /*%< dns_adblameinfo_t */ + isc_mempool_t *emp; /*%< dns_adbentry_t */ + isc_mempool_t *ahmp; /*%< dns_adbfind_t */ + isc_mempool_t *aimp; /*%< dns_adbaddrinfo_t */ + isc_mempool_t *afmp; /*%< dns_adbfetch_t */ + + /*! * Bucketized locks and lists for names. * * XXXRTH Have a per-bucket structure that contains all of these? */ dns_adbnamelist_t names[NBUCKETS]; + /*% See dns_adbnamelist_t */ isc_mutex_t namelocks[NBUCKETS]; + /*% See dns_adbnamelist_t */ isc_boolean_t name_sd[NBUCKETS]; + /*% See dns_adbnamelist_t */ unsigned int name_refcnt[NBUCKETS]; - /* + /*! * Bucketized locks for entries. * * XXXRTH Have a per-bucket structure that contains all of these? */ dns_adbentrylist_t entries[NBUCKETS]; isc_mutex_t entrylocks[NBUCKETS]; - isc_boolean_t entry_sd[NBUCKETS]; /* shutting down */ + isc_boolean_t entry_sd[NBUCKETS]; /*%< shutting down */ unsigned int entry_refcnt[NBUCKETS]; isc_event_t cevent; @@ -169,6 +175,7 @@ struct dns_adb { * XXXMLG Document these structures. */ +/*% dns_adbname structure */ struct dns_adbname { unsigned int magic; dns_name_t name; @@ -191,6 +198,7 @@ struct dns_adbname { ISC_LINK(dns_adbname_t) plink; }; +/*% The adbfetch structure */ struct dns_adbfetch { unsigned int magic; dns_adbnamehook_t *namehook; @@ -199,9 +207,7 @@ struct dns_adbfetch { dns_rdataset_t rdataset; }; -/* - * dns_adbnamehook_t - * +/*% * This is a small widget that dangles off a dns_adbname_t. It contains a * pointer to the address information about this host, and a link to the next * namehook that will contain the next address this host has. @@ -212,23 +218,22 @@ struct dns_adbnamehook { ISC_LINK(dns_adbnamehook_t) plink; }; -/* - * dns_adbzoneinfo_t - * - * This is a small widget that holds zone-specific information about an +/*% + * This is a small widget that holds qname-specific information about an * address. Currently limited to lameness, but could just as easily be * extended to other types of information about zones. */ -struct dns_adbzoneinfo { +struct dns_adblameinfo { unsigned int magic; - dns_name_t zone; + dns_name_t qname; + dns_rdatatype_t qtype; isc_stdtime_t lame_timer; - ISC_LINK(dns_adbzoneinfo_t) plink; + ISC_LINK(dns_adblameinfo_t) plink; }; -/* +/*% * An address entry. It holds quite a bit of information about addresses, * including edns state (in "flags"), rtt, and of course the address of * the host. @@ -244,7 +249,7 @@ struct dns_adbentry { isc_sockaddr_t sockaddr; isc_stdtime_t expires; - /* + /*%< * A nonzero 'expires' field indicates that the entry should * persist until that time. This allows entries found * using dns_adb_findaddrinfo() to persist for a limited time @@ -252,7 +257,7 @@ struct dns_adbentry { * name. */ - ISC_LIST(dns_adbzoneinfo_t) zoneinfo; + ISC_LIST(dns_adblameinfo_t) lameinfo; ISC_LINK(dns_adbentry_t) plink; }; @@ -264,8 +269,9 @@ static inline void free_adbname(dns_adb_t *, dns_adbname_t **); static inline dns_adbnamehook_t *new_adbnamehook(dns_adb_t *, dns_adbentry_t *); static inline void free_adbnamehook(dns_adb_t *, dns_adbnamehook_t **); -static inline dns_adbzoneinfo_t *new_adbzoneinfo(dns_adb_t *, dns_name_t *); -static inline void free_adbzoneinfo(dns_adb_t *, dns_adbzoneinfo_t **); +static inline dns_adblameinfo_t *new_adblameinfo(dns_adb_t *, dns_name_t *, + dns_rdatatype_t); +static inline void free_adblameinfo(dns_adb_t *, dns_adblameinfo_t **); static inline dns_adbentry_t *new_adbentry(dns_adb_t *); static inline void free_adbentry(dns_adb_t *, dns_adbentry_t **); static inline dns_adbfind_t *new_adbfind(dns_adb_t *); @@ -1321,42 +1327,42 @@ free_adbnamehook(dns_adb_t *adb, dns_adbnamehook_t **namehook) { isc_mempool_put(adb->nhmp, nh); } -static inline dns_adbzoneinfo_t * -new_adbzoneinfo(dns_adb_t *adb, dns_name_t *zone) { - dns_adbzoneinfo_t *zi; +static inline dns_adblameinfo_t * +new_adblameinfo(dns_adb_t *adb, dns_name_t *qname, dns_rdatatype_t qtype) { + dns_adblameinfo_t *li; - zi = isc_mempool_get(adb->zimp); - if (zi == NULL) + li = isc_mempool_get(adb->limp); + if (li == NULL) return (NULL); - dns_name_init(&zi->zone, NULL); - if (dns_name_dup(zone, adb->mctx, &zi->zone) != ISC_R_SUCCESS) { - isc_mempool_put(adb->zimp, zi); + dns_name_init(&li->qname, NULL); + if (dns_name_dup(qname, adb->mctx, &li->qname) != ISC_R_SUCCESS) { + isc_mempool_put(adb->limp, li); return (NULL); } + li->magic = DNS_ADBLAMEINFO_MAGIC; + li->lame_timer = 0; + li->qtype = qtype; + ISC_LINK_INIT(li, plink); - zi->magic = DNS_ADBZONEINFO_MAGIC; - zi->lame_timer = 0; - ISC_LINK_INIT(zi, plink); - - return (zi); + return (li); } static inline void -free_adbzoneinfo(dns_adb_t *adb, dns_adbzoneinfo_t **zoneinfo) { - dns_adbzoneinfo_t *zi; +free_adblameinfo(dns_adb_t *adb, dns_adblameinfo_t **lameinfo) { + dns_adblameinfo_t *li; - INSIST(zoneinfo != NULL && DNS_ADBZONEINFO_VALID(*zoneinfo)); - zi = *zoneinfo; - *zoneinfo = NULL; + INSIST(lameinfo != NULL && DNS_ADBLAMEINFO_VALID(*lameinfo)); + li = *lameinfo; + *lameinfo = NULL; - INSIST(!ISC_LINK_LINKED(zi, plink)); + INSIST(!ISC_LINK_LINKED(li, plink)); - dns_name_free(&zi->zone, adb->mctx); + dns_name_free(&li->qname, adb->mctx); - zi->magic = 0; + li->magic = 0; - isc_mempool_put(adb->zimp, zi); + isc_mempool_put(adb->limp, li); } static inline dns_adbentry_t * @@ -1375,7 +1381,7 @@ new_adbentry(dns_adb_t *adb) { isc_random_get(&r); e->srtt = (r & 0x1f) + 1; e->expires = 0; - ISC_LIST_INIT(e->zoneinfo); + ISC_LIST_INIT(e->lameinfo); ISC_LINK_INIT(e, plink); return (e); @@ -1384,7 +1390,7 @@ new_adbentry(dns_adb_t *adb) { static inline void free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) { dns_adbentry_t *e; - dns_adbzoneinfo_t *zi; + dns_adblameinfo_t *li; INSIST(entry != NULL && DNS_ADBENTRY_VALID(*entry)); e = *entry; @@ -1396,11 +1402,11 @@ free_adbentry(dns_adb_t *adb, dns_adbentry_t **entry) { e->magic = 0; - zi = ISC_LIST_HEAD(e->zoneinfo); - while (zi != NULL) { - ISC_LIST_UNLINK(e->zoneinfo, zi, plink); - free_adbzoneinfo(adb, &zi); - zi = ISC_LIST_HEAD(e->zoneinfo); + li = ISC_LIST_HEAD(e->lameinfo); + while (li != NULL) { + ISC_LIST_UNLINK(e->lameinfo, li, plink); + free_adblameinfo(adb, &li); + li = ISC_LIST_HEAD(e->lameinfo); } isc_mempool_put(adb->emp, e); @@ -1436,8 +1442,6 @@ new_adbfind(dns_adb_t *adb) { */ result = isc_mutex_init(&h->lock); if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init failed in new_adbfind()"); isc_mempool_put(adb->ahmp, h); return (NULL); } @@ -1647,45 +1651,48 @@ find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp) { * Entry bucket MUST be locked! */ static isc_boolean_t -entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone, - isc_stdtime_t now) +entry_is_lame(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *qname, + dns_rdatatype_t qtype, isc_stdtime_t now) { - dns_adbzoneinfo_t *zi, *next_zi; + dns_adblameinfo_t *li, *next_li; isc_boolean_t is_bad; is_bad = ISC_FALSE; - zi = ISC_LIST_HEAD(entry->zoneinfo); - if (zi == NULL) + li = ISC_LIST_HEAD(entry->lameinfo); + if (li == NULL) return (ISC_FALSE); - while (zi != NULL) { - next_zi = ISC_LIST_NEXT(zi, plink); + while (li != NULL) { + next_li = ISC_LIST_NEXT(li, plink); /* * Has the entry expired? */ - if (zi->lame_timer < now) { - ISC_LIST_UNLINK(entry->zoneinfo, zi, plink); - free_adbzoneinfo(adb, &zi); + if (li->lame_timer < now) { + ISC_LIST_UNLINK(entry->lameinfo, li, plink); + free_adblameinfo(adb, &li); } /* * Order tests from least to most expensive. + * + * We do not break out of the main loop here as + * we use the loop for house keeping. */ - if (zi != NULL && !is_bad) { - if (dns_name_equal(zone, &zi->zone)) - is_bad = ISC_TRUE; - } + if (li != NULL && !is_bad && li->qtype == qtype && + dns_name_equal(qname, &li->qname)) + is_bad = ISC_TRUE; - zi = next_zi; + li = next_li; } return (is_bad); } static void -copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone, - dns_adbname_t *name, isc_stdtime_t now) +copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname, + dns_rdatatype_t qtype, dns_adbname_t *name, + isc_stdtime_t now) { dns_adbnamehook_t *namehook; dns_adbaddrinfo_t *addrinfo; @@ -1702,7 +1709,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone, LOCK(&adb->entrylocks[bucket]); if (!FIND_RETURNLAME(find) - && entry_is_bad_for_zone(adb, entry, zone, now)) { + && entry_is_lame(adb, entry, qname, qtype, now)) { find->options |= DNS_ADBFIND_LAMEPRUNED; goto nextv4; } @@ -1731,7 +1738,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone, bucket = entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); - if (entry_is_bad_for_zone(adb, entry, zone, now)) + if (entry_is_lame(adb, entry, qname, qtype, now)) goto nextv6; addrinfo = new_adbaddrinfo(adb, entry, find->port); if (addrinfo == NULL) { @@ -1971,7 +1978,7 @@ destroy(dns_adb_t *adb) { isc_mempool_destroy(&adb->nmp); isc_mempool_destroy(&adb->nhmp); - isc_mempool_destroy(&adb->zimp); + isc_mempool_destroy(&adb->limp); isc_mempool_destroy(&adb->emp); isc_mempool_destroy(&adb->ahmp); isc_mempool_destroy(&adb->aimp); @@ -2019,7 +2026,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, adb->irefcnt = 0; adb->nmp = NULL; adb->nhmp = NULL; - adb->zimp = NULL; + adb->limp = NULL; adb->emp = NULL; adb->ahmp = NULL; adb->aimp = NULL; @@ -2091,7 +2098,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, MPINIT(dns_adbname_t, adb->nmp, "adbname"); MPINIT(dns_adbnamehook_t, adb->nhmp, "adbnamehook"); - MPINIT(dns_adbzoneinfo_t, adb->zimp, "adbzoneinfo"); + MPINIT(dns_adblameinfo_t, adb->limp, "adblameinfo"); MPINIT(dns_adbentry_t, adb->emp, "adbentry"); MPINIT(dns_adbfind_t, adb->ahmp, "adbfind"); MPINIT(dns_adbaddrinfo_t, adb->aimp, "adbaddrinfo"); @@ -2144,8 +2151,8 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, isc_mempool_destroy(&adb->nmp); if (adb->nhmp != NULL) isc_mempool_destroy(&adb->nhmp); - if (adb->zimp != NULL) - isc_mempool_destroy(&adb->zimp); + if (adb->limp != NULL) + isc_mempool_destroy(&adb->limp); if (adb->emp != NULL) isc_mempool_destroy(&adb->emp); if (adb->ahmp != NULL) @@ -2265,8 +2272,9 @@ dns_adb_shutdown(dns_adb_t *adb) { isc_result_t dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_name_t *name, dns_name_t *zone, - unsigned int options, isc_stdtime_t now, dns_name_t *target, + void *arg, dns_name_t *name, dns_name_t *qname, + dns_rdatatype_t qtype, unsigned int options, + isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **findp) { dns_adbfind_t *find; @@ -2283,7 +2291,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, REQUIRE(action != NULL); } REQUIRE(name != NULL); - REQUIRE(zone != NULL); + REQUIRE(qname != NULL); REQUIRE(findp != NULL && *findp == NULL); REQUIRE(target == NULL || dns_name_hasbuffer(target)); @@ -2511,7 +2519,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, * Run through the name and copy out the bits we are * interested in. */ - copy_namehook_lists(adb, find, zone, adbname, now); + copy_namehook_lists(adb, find, qname, qtype, adbname, now); post_copy: if (NAME_FETCH_V4(adbname)) @@ -2826,8 +2834,9 @@ dump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug, isc_stdtime_t now) { char addrbuf[ISC_NETADDR_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; isc_netaddr_t netaddr; - dns_adbzoneinfo_t *zi; + dns_adblameinfo_t *li; isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr); isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf)); @@ -2840,12 +2849,14 @@ dump_entry(FILE *f, dns_adbentry_t *entry, isc_boolean_t debug, if (entry->expires != 0) fprintf(f, " [ttl %d]", entry->expires - now); fprintf(f, "\n"); - for (zi = ISC_LIST_HEAD(entry->zoneinfo); - zi != NULL; - zi = ISC_LIST_NEXT(zi, plink)) { + for (li = ISC_LIST_HEAD(entry->lameinfo); + li != NULL; + li = ISC_LIST_NEXT(li, plink)) { fprintf(f, ";\t\t"); - print_dns_name(f, &zi->zone); - fprintf(f, " [lame TTL %d]\n", zi->lame_timer - now); + print_dns_name(f, &li->qname); + dns_rdatatype_format(li->qtype, typebuf, sizeof(typebuf)); + fprintf(f, " %s [lame TTL %d]\n", typebuf, + li->lame_timer - now); } } @@ -3332,36 +3343,37 @@ fetch_name(dns_adbname_t *adbname, * since these can be extracted from the find itself. */ isc_result_t -dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone, - isc_stdtime_t expire_time) +dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname, + dns_rdatatype_t qtype, isc_stdtime_t expire_time) { - dns_adbzoneinfo_t *zi; + dns_adblameinfo_t *li; int bucket; isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ADB_VALID(adb)); REQUIRE(DNS_ADBADDRINFO_VALID(addr)); - REQUIRE(zone != NULL); + REQUIRE(qname != NULL); bucket = addr->entry->lock_bucket; LOCK(&adb->entrylocks[bucket]); - zi = ISC_LIST_HEAD(addr->entry->zoneinfo); - while (zi != NULL && !dns_name_equal(zone, &zi->zone)) - zi = ISC_LIST_NEXT(zi, plink); - if (zi != NULL) { - if (expire_time > zi->lame_timer) - zi->lame_timer = expire_time; + li = ISC_LIST_HEAD(addr->entry->lameinfo); + while (li != NULL && + (li->qtype != qtype || !dns_name_equal(qname, &li->qname))) + li = ISC_LIST_NEXT(li, plink); + if (li != NULL) { + if (expire_time > li->lame_timer) + li->lame_timer = expire_time; goto unlock; } - zi = new_adbzoneinfo(adb, zone); - if (zi == NULL) { + li = new_adblameinfo(adb, qname, qtype); + if (li == NULL) { result = ISC_R_NOMEMORY; goto unlock; } - zi->lame_timer = expire_time; + li->lame_timer = expire_time; - ISC_LIST_PREPEND(addr->entry->zoneinfo, zi, plink); + ISC_LIST_PREPEND(addr->entry->lameinfo, li, plink); unlock: UNLOCK(&adb->entrylocks[bucket]); diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api index 95b29be..5798ebc 100644 --- a/contrib/bind9/lib/dns/api +++ b/contrib/bind9/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 23 -LIBREVISION = 0 +LIBINTERFACE = 33 +LIBREVISION = 1 LIBAGE = 1 diff --git a/contrib/bind9/lib/dns/byaddr.c b/contrib/bind9/lib/dns/byaddr.c index ace4fb0..38d6e8b 100644 --- a/contrib/bind9/lib/dns/byaddr.c +++ b/contrib/bind9/lib/dns/byaddr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: byaddr.c,v 1.29.2.1.2.8 2004/08/28 06:25:18 marka Exp $ */ +/* $Id: byaddr.c,v 1.34.18.3 2005/04/29 00:15:49 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/cache.c b/contrib/bind9/lib/dns/cache.c index f45af90..011dbf7 100644 --- a/contrib/bind9/lib/dns/cache.c +++ b/contrib/bind9/lib/dns/cache.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cache.c,v 1.45.2.4.8.15 2006/08/01 01:07:05 marka Exp $ */ +/* $Id: cache.c,v 1.57.18.16 2006/08/01 01:06:48 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -29,6 +31,7 @@ #include <dns/db.h> #include <dns/dbiterator.h> #include <dns/events.h> +#include <dns/lib.h> #include <dns/log.h> #include <dns/masterdump.h> #include <dns/rdata.h> @@ -39,13 +42,18 @@ #define CACHE_MAGIC ISC_MAGIC('$', '$', '$', '$') #define VALID_CACHE(cache) ISC_MAGIC_VALID(cache, CACHE_MAGIC) -/* - * The following two variables control incremental cleaning. - * MINSIZE is how many bytes is the floor for dns_cache_setcachesize(). +/*! + * Control incremental cleaning. + * DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize(). + * See also DNS_CACHE_CLEANERINCREMENT + */ +#define DNS_CACHE_MINSIZE 2097152 /*%< Bytes. 2097152 = 2 MB */ +/*! + * Control incremental cleaning. * CLEANERINCREMENT is how many nodes are examined in one pass. + * See also DNS_CACHE_MINSIZE */ -#define DNS_CACHE_MINSIZE 2097152 /* Bytes. 2097152 = 2 MB */ -#define DNS_CACHE_CLEANERINCREMENT 1000 /* Number of nodes. */ +#define DNS_CACHE_CLEANERINCREMENT 1000U /*%< Number of nodes. */ /*** *** Types @@ -59,9 +67,9 @@ typedef struct cache_cleaner cache_cleaner_t; typedef enum { - cleaner_s_idle, /* Waiting for cleaning-interval to expire. */ - cleaner_s_busy, /* Currently cleaning. */ - cleaner_s_done /* Freed enough memory after being overmem. */ + cleaner_s_idle, /*%< Waiting for cleaning-interval to expire. */ + cleaner_s_busy, /*%< Currently cleaning. */ + cleaner_s_done /*%< Freed enough memory after being overmem. */ } cleaner_state_t; /* @@ -73,13 +81,13 @@ typedef enum { (c)->iterator != NULL && \ (c)->resched_event == NULL) -/* +/*% * Accesses to a cache cleaner object are synchronized through * task/event serialization, or locked from the cache object. */ struct cache_cleaner { isc_mutex_t lock; - /* + /*%< * Locks overmem_event, overmem. Note: never allocate memory * while holding this lock - that could lead to deadlock since * the lock is take by water() which is called from the memory @@ -88,22 +96,22 @@ struct cache_cleaner { dns_cache_t *cache; isc_task_t *task; - unsigned int cleaning_interval; /* The cleaning-interval from + unsigned int cleaning_interval; /*% The cleaning-interval from named.conf, in seconds. */ isc_timer_t *cleaning_timer; - isc_event_t *resched_event; /* Sent by cleaner task to + isc_event_t *resched_event; /*% Sent by cleaner task to itself to reschedule */ isc_event_t *overmem_event; dns_dbiterator_t *iterator; - int increment; /* Number of names to + unsigned int increment; /*% Number of names to clean in one increment */ - cleaner_state_t state; /* Idle/Busy. */ - isc_boolean_t overmem; /* The cache is in an overmem state. */ + cleaner_state_t state; /*% Idle/Busy. */ + isc_boolean_t overmem; /*% The cache is in an overmem state. */ isc_boolean_t replaceiterator; }; -/* +/*% * The actual cache object. */ @@ -149,6 +157,79 @@ cleaner_shutdown_action(isc_task_t *task, isc_event_t *event); static void overmem_cleaning_action(isc_task_t *task, isc_event_t *event); +/*% + * Work out how many nodes can be cleaned in the time between two + * requests to the nameserver. Smooth the resulting number and use + * it as a estimate for the number of nodes to be cleaned in the next + * iteration. + */ +static void +adjust_increment(cache_cleaner_t *cleaner, unsigned int remaining, + isc_time_t *start) +{ + isc_time_t end; + isc_uint64_t usecs; + isc_uint64_t new; + unsigned int pps = dns_pps; + unsigned int interval; + unsigned int names; + + /* + * Tune for minumum of 100 packets per second (pps). + */ + if (pps < 100) + pps = 100; + + isc_time_now(&end); + + interval = 1000000 / pps; /* Interval between packets in usecs. */ + if (interval == 0) + interval = 1; + + INSIST(cleaner->increment >= remaining); + names = cleaner->increment - remaining; + usecs = isc_time_microdiff(&end, start); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, + ISC_LOG_DEBUG(1), "adjust_increment interval=%u " + "names=%u usec=%" ISC_PLATFORM_QUADFORMAT "u", + interval, names, usecs); + + if (usecs == 0) { + /* + * If we cleaned all the nodes in unmeasurable time + * double the number of nodes to be cleaned next time. + */ + if (names == cleaner->increment) { + cleaner->increment *= 2; + if (cleaner->increment > DNS_CACHE_CLEANERINCREMENT) + cleaner->increment = DNS_CACHE_CLEANERINCREMENT; + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), + "%p:new cleaner->increment = %u\n", + cleaner, cleaner->increment); + } + return; + } + + new = (names * interval); + new /= (usecs * 2); + if (new == 0) + new = 1; + + /* Smooth */ + new = (new + cleaner->increment * 7) / 8; + + if (new > DNS_CACHE_CLEANERINCREMENT) + new = DNS_CACHE_CLEANERINCREMENT; + + cleaner->increment = (unsigned int)new; + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, + ISC_LOG_DEBUG(1), "%p:new cleaner->increment = %u\n", + cleaner, cleaner->increment); +} + static inline isc_result_t cache_create_db(dns_cache_t *cache, dns_db_t **db) { return (dns_db_create(cache->mctx, cache->db_type, dns_rootname, @@ -178,22 +259,12 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_mem_attach(mctx, &cache->mctx); result = isc_mutex_init(&cache->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_mem; - } result = isc_mutex_init(&cache->filelock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_lock; - } cache->references = 1; cache->live_tasks = 0; @@ -488,13 +559,8 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, isc_result_t result; result = isc_mutex_init(&cleaner->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - dns_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto fail; - } cleaner->increment = DNS_CACHE_CLEANERINCREMENT; cleaner->state = cleaner_s_idle; @@ -740,7 +806,8 @@ static void incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { cache_cleaner_t *cleaner = event->ev_arg; isc_result_t result; - int n_names; + unsigned int n_names; + isc_time_t start; UNUSED(task); @@ -770,6 +837,7 @@ incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { REQUIRE(DNS_DBITERATOR_VALID(cleaner->iterator)); + isc_time_now(&start); while (n_names-- > 0) { dns_dbnode_t *node = NULL; @@ -780,6 +848,7 @@ incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { "cache cleaner: dns_dbiterator_current() " "failed: %s", dns_result_totext(result)); + adjust_increment(cleaner, n_names, &start); end_cleaning(cleaner, event); return; } @@ -823,11 +892,14 @@ incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { } } + adjust_increment(cleaner, n_names, &start); end_cleaning(cleaner, event); return; } } + adjust_increment(cleaner, 0U, &start); + /* * We have successfully performed a cleaning increment but have * not gone through the entire cache. Free the iterator locks @@ -838,7 +910,7 @@ incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, - ISC_LOG_DEBUG(1), "cache cleaner: checked %d nodes, " + ISC_LOG_DEBUG(1), "cache cleaner: checked %u nodes, " "mem inuse %lu, sleeping", cleaner->increment, (unsigned long)isc_mem_inuse(cleaner->cache->mctx)); diff --git a/contrib/bind9/lib/dns/callbacks.c b/contrib/bind9/lib/dns/callbacks.c index 431c7ef..a487ed0 100644 --- a/contrib/bind9/lib/dns/callbacks.c +++ b/contrib/bind9/lib/dns/callbacks.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: callbacks.c,v 1.12.206.1 2004/03/06 08:13:36 marka Exp $ */ +/* $Id: callbacks.c,v 1.13.18.2 2005/04/29 00:15:49 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/compress.c b/contrib/bind9/lib/dns/compress.c index 2122436..2103767 100644 --- a/contrib/bind9/lib/dns/compress.c +++ b/contrib/bind9/lib/dns/compress.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.c,v 1.50.206.4 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: compress.c,v 1.52.18.5 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ #define DNS_NAME_USEINLINE 1 @@ -82,13 +84,31 @@ void dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) { REQUIRE(VALID_CCTX(cctx)); - cctx->allowed = allowed; + cctx->allowed &= ~DNS_COMPRESS_ALL; + cctx->allowed |= (allowed & DNS_COMPRESS_ALL); } unsigned int dns_compress_getmethods(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); - return (cctx->allowed); + return (cctx->allowed & DNS_COMPRESS_ALL); +} + +void +dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive) { + REQUIRE(VALID_CCTX(cctx)); + + if (sensitive) + cctx->allowed |= DNS_COMPRESS_CASESENSITIVE; + else + cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE; +} + +isc_boolean_t +dns_compress_getsensitive(dns_compress_t *cctx) { + REQUIRE(VALID_CCTX(cctx)); + + return (ISC_TF((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0)); } int @@ -138,8 +158,13 @@ dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, for (node = cctx->table[hash]; node != NULL; node = node->next) { NODENAME(node, &nname); - if (dns_name_equal(&nname, &tname)) - break; + if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) { + if (dns_name_caseequal(&nname, &tname)) + break; + } else { + if (dns_name_equal(&nname, &tname)) + break; + } } if (node != NULL) break; diff --git a/contrib/bind9/lib/dns/db.c b/contrib/bind9/lib/dns/db.c index 347ce1e..32ff6ae 100644 --- a/contrib/bind9/lib/dns/db.c +++ b/contrib/bind9/lib/dns/db.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.c,v 1.69.2.1.10.4 2004/03/08 02:07:52 marka Exp $ */ +/* $Id: db.c,v 1.74.18.6 2005/10/13 02:12:24 marka Exp $ */ + +/*! \file */ /*** *** Imports @@ -301,6 +303,11 @@ dns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp) { isc_result_t dns_db_load(dns_db_t *db, const char *filename) { + return (dns_db_load2(db, filename, dns_masterformat_text)); +} + +isc_result_t +dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format) { isc_result_t result, eresult; dns_rdatacallbacks_t callbacks; unsigned int options = 0; @@ -319,9 +326,9 @@ dns_db_load(dns_db_t *db, const char *filename) { result = dns_db_beginload(db, &callbacks.add, &callbacks.add_private); if (result != ISC_R_SUCCESS) return (result); - result = dns_master_loadfile(filename, &db->origin, &db->origin, - db->rdclass, options, - &callbacks, db->mctx); + result = dns_master_loadfile2(filename, &db->origin, &db->origin, + db->rdclass, options, + &callbacks, db->mctx, format); eresult = dns_db_endload(db, &callbacks.add_private); /* * We always call dns_db_endload(), but we only want to return its @@ -337,13 +344,22 @@ dns_db_load(dns_db_t *db, const char *filename) { isc_result_t dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { + return ((db->methods->dump)(db, version, filename, + dns_masterformat_text)); +} + +isc_result_t +dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) { /* - * Dump 'db' into master file 'filename'. + * Dump 'db' into master file 'filename' in the 'masterformat' format. + * XXXJT: is it okay to modify the interface to the existing "dump" + * method? */ REQUIRE(DNS_DB_VALID(db)); - return ((db->methods->dump)(db, version, filename)); + return ((db->methods->dump)(db, version, filename, masterformat)); } /*** @@ -791,3 +807,15 @@ dns_db_unregister(dns_dbimplementation_t **dbimp) { isc_mem_detach(&mctx); RWUNLOCK(&implock, isc_rwlocktype_write); } + +isc_result_t +dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(dns_db_iszone(db) == ISC_TRUE); + REQUIRE(nodep != NULL && *nodep == NULL); + + if (db->methods->getoriginnode != NULL) + return ((db->methods->getoriginnode)(db, nodep)); + + return (ISC_R_NOTFOUND); +} diff --git a/contrib/bind9/lib/dns/dbiterator.c b/contrib/bind9/lib/dns/dbiterator.c index 0bf354b..d462ad5 100644 --- a/contrib/bind9/lib/dns/dbiterator.c +++ b/contrib/bind9/lib/dns/dbiterator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dbiterator.c,v 1.13.206.1 2004/03/06 08:13:37 marka Exp $ */ +/* $Id: dbiterator.c,v 1.14.18.2 2005/04/29 00:15:50 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/dbtable.c b/contrib/bind9/lib/dns/dbtable.c index d027fa3..b091e42 100644 --- a/contrib/bind9/lib/dns/dbtable.c +++ b/contrib/bind9/lib/dns/dbtable.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,10 +16,11 @@ */ /* - * $Id: dbtable.c,v 1.25.12.4 2004/03/09 05:21:08 marka Exp $ + * $Id: dbtable.c,v 1.28.18.3 2005/07/12 01:22:19 marka Exp $ */ -/* +/*! \file + * \author * Principal Author: DCL */ @@ -86,7 +87,6 @@ dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, result = isc_rwlock_init(&dbtable->tree_lock, 0, 0); if (result != ISC_R_SUCCESS) goto clean3; - dbtable->default_db = NULL; dbtable->mctx = mctx; diff --git a/contrib/bind9/lib/dns/diff.c b/contrib/bind9/lib/dns/diff.c index 8cd5643..22a3938 100644 --- a/contrib/bind9/lib/dns/diff.c +++ b/contrib/bind9/lib/dns/diff.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: diff.c,v 1.4.2.1.8.4 2004/03/08 02:07:52 marka Exp $ */ +/* $Id: diff.c,v 1.9.18.3 2005/04/27 05:01:15 sra Exp $ */ + +/*! \file */ #include <config.h> @@ -30,8 +32,10 @@ #include <dns/db.h> #include <dns/diff.h> #include <dns/log.h> +#include <dns/rdataclass.h> #include <dns/rdatalist.h> #include <dns/rdataset.h> +#include <dns/rdatatype.h> #include <dns/result.h> #define CHECK(op) \ @@ -195,6 +199,9 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, dns_difftuple_t *t; dns_dbnode_t *node = NULL; isc_result_t result; + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + char classbuf[DNS_RDATACLASS_FORMATSIZE]; REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(DNS_DB_VALID(db)); @@ -254,11 +261,19 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, t->rdata.type == type && rdata_covers(&t->rdata) == covers) { + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(t->rdata.type, typebuf, + sizeof(typebuf)); + dns_rdataclass_format(t->rdata.rdclass, + classbuf, + sizeof(classbuf)); if (t->ttl != rdl.ttl && warn) isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_WARNING, - "TTL differs in rdataset, " - "adjusting %lu -> %lu", + "'%s/%s/%s': TTL differs in " + "rdataset, adjusting " + "%lu -> %lu", + namebuf, typebuf, classbuf, (unsigned long) t->ttl, (unsigned long) rdl.ttl); ISC_LIST_APPEND(rdl.rdata, &t->rdata, link); diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c index 91ef2c5..02accdf 100644 --- a/contrib/bind9/lib/dns/dispatch.c +++ b/contrib/bind9/lib/dns/dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.c,v 1.101.2.6.2.13 2006/07/19 00:44:04 marka Exp $ */ +/* $Id: dispatch.c,v 1.116.18.13 2007/02/07 23:57:58 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -43,12 +45,12 @@ typedef ISC_LIST(dns_dispentry_t) dns_displist_t; typedef struct dns_qid { unsigned int magic; - unsigned int qid_nbuckets; /* hash table size */ - unsigned int qid_increment; /* id increment on collision */ + unsigned int qid_nbuckets; /*%< hash table size */ + unsigned int qid_increment; /*%< id increment on collision */ isc_mutex_t lock; - isc_lfsr_t qid_lfsr1; /* state generator info */ - isc_lfsr_t qid_lfsr2; /* state generator info */ - dns_displist_t *qid_table; /* the table itself */ + isc_lfsr_t qid_lfsr1; /*%< state generator info */ + isc_lfsr_t qid_lfsr2; /*%< state generator info */ + dns_displist_t *qid_table; /*%< the table itself */ } dns_qid_t; struct dns_dispatchmgr { @@ -66,18 +68,18 @@ struct dns_dispatchmgr { /* locked by buffer lock */ dns_qid_t *qid; isc_mutex_t buffer_lock; - unsigned int buffers; /* allocated buffers */ - unsigned int buffersize; /* size of each buffer */ - unsigned int maxbuffers; /* max buffers */ + unsigned int buffers; /*%< allocated buffers */ + unsigned int buffersize; /*%< size of each buffer */ + unsigned int maxbuffers; /*%< max buffers */ /* Locked internally. */ isc_mutex_t pool_lock; - isc_mempool_t *epool; /* memory pool for events */ - isc_mempool_t *rpool; /* memory pool for replies */ - isc_mempool_t *dpool; /* dispatch allocations */ - isc_mempool_t *bpool; /* memory pool for buffers */ + isc_mempool_t *epool; /*%< memory pool for events */ + isc_mempool_t *rpool; /*%< memory pool for replies */ + isc_mempool_t *dpool; /*%< dispatch allocations */ + isc_mempool_t *bpool; /*%< memory pool for buffers */ - isc_entropy_t *entropy; /* entropy source */ + isc_entropy_t *entropy; /*%< entropy source */ }; #define MGR_SHUTTINGDOWN 0x00000001U @@ -103,32 +105,32 @@ struct dns_dispentry { struct dns_dispatch { /* Unlocked. */ - unsigned int magic; /* magic */ - dns_dispatchmgr_t *mgr; /* dispatch manager */ - isc_task_t *task; /* internal task */ - isc_socket_t *socket; /* isc socket attached to */ - isc_sockaddr_t local; /* local address */ - unsigned int maxrequests; /* max requests */ + unsigned int magic; /*%< magic */ + dns_dispatchmgr_t *mgr; /*%< dispatch manager */ + isc_task_t *task; /*%< internal task */ + isc_socket_t *socket; /*%< isc socket attached to */ + isc_sockaddr_t local; /*%< local address */ + unsigned int maxrequests; /*%< max requests */ isc_event_t *ctlevent; - /* Locked by mgr->lock. */ + /*% Locked by mgr->lock. */ ISC_LINK(dns_dispatch_t) link; /* Locked by "lock". */ - isc_mutex_t lock; /* locks all below */ + isc_mutex_t lock; /*%< locks all below */ isc_sockettype_t socktype; unsigned int attributes; - unsigned int refcount; /* number of users */ - dns_dispatchevent_t *failsafe_ev; /* failsafe cancel event */ + unsigned int refcount; /*%< number of users */ + dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */ unsigned int shutting_down : 1, shutdown_out : 1, connected : 1, tcpmsg_valid : 1, - recv_pending : 1; /* is a recv() pending? */ + recv_pending : 1; /*%< is a recv() pending? */ isc_result_t shutdown_why; - unsigned int requests; /* how many requests we have */ - unsigned int tcpbuffers; /* allocated buffers */ - dns_tcpmsg_t tcpmsg; /* for tcp streams */ + unsigned int requests; /*%< how many requests we have */ + unsigned int tcpbuffers; /*%< allocated buffers */ + dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ dns_qid_t *qid; }; @@ -970,6 +972,9 @@ startrecv(dns_dispatch_t *disp) { INSIST(disp->recv_pending == 0); disp->recv_pending = 1; break; + default: + INSIST(0); + break; } } @@ -1239,6 +1244,7 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, if (isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool) != ISC_R_SUCCESS) { + UNLOCK(&mgr->buffer_lock); return (ISC_R_NOMEMORY); } @@ -1396,6 +1402,7 @@ qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, { dns_qid_t *qid; unsigned int i; + isc_result_t result; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ @@ -1413,12 +1420,12 @@ qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, return (ISC_R_NOMEMORY); } - if (isc_mutex_init(&qid->lock) != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init failed"); + result = isc_mutex_init(&qid->lock); + if (result != ISC_R_SUCCESS) { isc_mem_put(mgr->mctx, qid->qid_table, buckets * sizeof(dns_displist_t)); isc_mem_put(mgr->mctx, qid, sizeof(*qid)); - return (ISC_R_UNEXPECTED); + return (result); } for (i = 0; i < buckets; i++) @@ -1471,7 +1478,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, dns_dispatch_t **dispp) { dns_dispatch_t *disp; - isc_result_t res; + isc_result_t result; REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(dispp != NULL && *dispp == NULL); @@ -1502,15 +1509,13 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, disp->tcpbuffers = 0; disp->qid = NULL; - if (isc_mutex_init(&disp->lock) != ISC_R_SUCCESS) { - res = ISC_R_UNEXPECTED; - UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init failed"); + result = isc_mutex_init(&disp->lock); + if (result != ISC_R_SUCCESS) goto deallocate; - } disp->failsafe_ev = allocate_event(disp); if (disp->failsafe_ev == NULL) { - res = ISC_R_NOMEMORY; + result = ISC_R_NOMEMORY; goto kill_lock; } @@ -1527,7 +1532,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, deallocate: isc_mempool_put(mgr->dpool, disp); - return (res); + return (result); } diff --git a/contrib/bind9/lib/dns/dlz.c b/contrib/bind9/lib/dns/dlz.c new file mode 100644 index 0000000..ee6c03b --- /dev/null +++ b/contrib/bind9/lib/dns/dlz.c @@ -0,0 +1,510 @@ +/* + * Portions Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +/* + * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. + * + * Permission to use, copy, modify, and 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 STICHTING NLNET + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * STICHTING NLNET 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. + * + * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was + * conceived and contributed by Rob Butler. + * + * Permission to use, copy, modify, and 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 ROB BUTLER + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * ROB BUTLER 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: dlz.c,v 1.2.2.2 2005/09/06 03:47:17 marka Exp $ */ + +/*! \file */ + +/*** + *** Imports + ***/ + +#include <config.h> + +#include <dns/fixedname.h> +#include <dns/log.h> +#include <dns/master.h> +#include <dns/dlz.h> + + +#include <isc/buffer.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/once.h> +#include <isc/rwlock.h> +#include <isc/string.h> +#include <isc/util.h> + +/*** + *** Supported DLZ DB Implementations Registry + ***/ + +static ISC_LIST(dns_dlzimplementation_t) dlz_implementations; +static isc_rwlock_t dlz_implock; +static isc_once_t once = ISC_ONCE_INIT; + +static void +dlz_initialize(void) { + RUNTIME_CHECK(isc_rwlock_init(&dlz_implock, 0, 0) == ISC_R_SUCCESS); + ISC_LIST_INIT(dlz_implementations); +} + +/*% + * Searches the dlz_implementations list for a driver matching name. + */ +static inline dns_dlzimplementation_t * +dlz_impfind(const char *name) { + dns_dlzimplementation_t *imp; + + for (imp = ISC_LIST_HEAD(dlz_implementations); + imp != NULL; + imp = ISC_LIST_NEXT(imp, link)) + if (strcasecmp(name, imp->name) == 0) + return (imp); + return (NULL); +} + +/*** + *** Basic DLZ Methods + ***/ + +isc_result_t +dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, + isc_sockaddr_t *clientaddr, dns_db_t **dbp) +{ + isc_result_t result; + dns_dlzallowzonexfr_t allowzonexfr; + dns_dlzdb_t *dlzdatabase; + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(DNS_DLZ_VALID(view->dlzdatabase)); + REQUIRE(name != NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + + /* ask driver if the zone is supported */ + dlzdatabase = view->dlzdatabase; + allowzonexfr = dlzdatabase->implementation->methods->allowzonexfr; + result = (*allowzonexfr)(dlzdatabase->implementation->driverarg, + dlzdatabase->dbdata, dlzdatabase->mctx, + view->rdclass, name, clientaddr, dbp); + + if (result == ISC_R_NOTIMPLEMENTED) + return (ISC_R_NOTFOUND); + return (result); +} + +isc_result_t +dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, + unsigned int argc, char *argv[], dns_dlzdb_t **dbp) +{ + dns_dlzimplementation_t *impinfo; + isc_result_t result; + + /* + * initialize the dlz_implementations list, this is guaranteed + * to only really happen once. + */ + RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(dbp != NULL && *dbp == NULL); + REQUIRE(dlzname != NULL); + REQUIRE(drivername != NULL); + REQUIRE(mctx != NULL); + + /* write log message */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_INFO, + "Loading '%s' using driver %s", dlzname, drivername); + + /* lock the dlz_implementations list so we can search it. */ + RWLOCK(&dlz_implock, isc_rwlocktype_read); + + /* search for the driver implementation */ + impinfo = dlz_impfind(drivername); + if (impinfo == NULL) { + RWUNLOCK(&dlz_implock, isc_rwlocktype_read); + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, + "unsupported DLZ database driver '%s'." + " %s not loaded.", + drivername, dlzname); + + return (ISC_R_NOTFOUND); + } + + /* Allocate memory to hold the DLZ database driver */ + (*dbp) = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); + if ((*dbp) == NULL) { + RWUNLOCK(&dlz_implock, isc_rwlocktype_read); + return (ISC_R_NOMEMORY); + } + + /* Make sure memory region is set to all 0's */ + memset((*dbp), 0, sizeof(dns_dlzdb_t)); + + (*dbp)->implementation = impinfo; + + /* Create a new database using implementation 'drivername'. */ + result = ((impinfo->methods->create)(mctx, dlzname, argc, argv, + impinfo->driverarg, + &(*dbp)->dbdata)); + + /* mark the DLZ driver as valid */ + if (result == ISC_R_SUCCESS) { + RWUNLOCK(&dlz_implock, isc_rwlocktype_read); + (*dbp)->magic = DNS_DLZ_MAGIC; + isc_mem_attach(mctx, &(*dbp)->mctx); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "DLZ driver loaded successfully."); + return (ISC_R_SUCCESS); + } else { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, + "DLZ driver failed to load."); + } + + /* impinfo->methods->create failed. */ + RWUNLOCK(&dlz_implock, isc_rwlocktype_read); + isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t)); + return (result); +} + +void +dns_dlzdestroy(dns_dlzdb_t **dbp) { + isc_mem_t *mctx; + dns_dlzdestroy_t destroy; + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Unloading DLZ driver."); + + /* + * Perform checks to make sure data is as we expect it to be. + */ + REQUIRE(dbp != NULL && DNS_DLZ_VALID(*dbp)); + + /* call the drivers destroy method */ + if ((*dbp) != NULL) { + mctx = (*dbp)->mctx; + destroy = (*dbp)->implementation->methods->destroy; + (*destroy)((*dbp)->implementation->driverarg,(*dbp)->dbdata); + /* return memory */ + isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t)); + isc_mem_detach(&mctx); + } + + *dbp = NULL; +} + + +isc_result_t +dns_dlzfindzone(dns_view_t *view, dns_name_t *name, unsigned int minlabels, + dns_db_t **dbp) +{ + dns_fixedname_t fname; + dns_name_t *zonename; + unsigned int namelabels; + unsigned int i; + isc_result_t result; + dns_dlzfindzone_t findzone; + dns_dlzdb_t *dlzdatabase; + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(DNS_DLZ_VALID(view->dlzdatabase)); + REQUIRE(name != NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + + /* setup a "fixed" dns name */ + dns_fixedname_init(&fname); + zonename = dns_fixedname_name(&fname); + + /* count the number of labels in the name */ + namelabels = dns_name_countlabels(name); + + /* + * loop through starting with the longest domain name and + * trying shorter names portions of the name until we find a + * match, have an error, or are below the 'minlabels' + * threshold. minlabels is 0, if the standard database didn't + * have a zone name match. Otherwise minlables is the number + * of labels in that name. We need to beat that for a + * "better" match for the DLZ database to be authoritative + * instead of the standard database. + */ + for (i = namelabels; i > minlabels && i > 1; i--) { + if (i == namelabels) { + result = dns_name_copy(name, zonename, NULL); + if (result != ISC_R_SUCCESS) + return (result); + } else + dns_name_split(name, i, NULL, zonename); + + /* ask SDLZ driver if the zone is supported */ + dlzdatabase = view->dlzdatabase; + findzone = dlzdatabase->implementation->methods->findzone; + result = (*findzone)(dlzdatabase->implementation->driverarg, + dlzdatabase->dbdata, dlzdatabase->mctx, + view->rdclass, zonename, dbp); + if (result != ISC_R_NOTFOUND) + return (result); + } + return (ISC_R_NOTFOUND); +} + +/*% + * Registers a DLZ driver. This basically just adds the dlz + * driver to the list of available drivers in the dlz_implementations list. + */ +isc_result_t +dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods, + void *driverarg, isc_mem_t *mctx, + dns_dlzimplementation_t **dlzimp) +{ + + dns_dlzimplementation_t *dlz_imp; + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Registering DLZ driver '%s'", drivername); + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(drivername != NULL); + REQUIRE(methods != NULL); + REQUIRE(methods->create != NULL); + REQUIRE(methods->destroy != NULL); + REQUIRE(methods->findzone != NULL); + REQUIRE(mctx != NULL); + REQUIRE(dlzimp != NULL && *dlzimp == NULL); + + /* + * initialize the dlz_implementations list, this is guaranteed + * to only really happen once. + */ + RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); + + /* lock the dlz_implementations list so we can modify it. */ + RWLOCK(&dlz_implock, isc_rwlocktype_write); + + /* + * check that another already registered driver isn't using + * the same name + */ + dlz_imp = dlz_impfind(drivername); + if (dlz_imp != NULL) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "DLZ Driver '%s' already registered", + drivername); + RWUNLOCK(&dlz_implock, isc_rwlocktype_write); + return (ISC_R_EXISTS); + } + + /* + * Allocate memory for a dlz_implementation object. Error if + * we cannot. + */ + dlz_imp = isc_mem_get(mctx, sizeof(dns_dlzimplementation_t)); + if (dlz_imp == NULL) { + RWUNLOCK(&dlz_implock, isc_rwlocktype_write); + return (ISC_R_NOMEMORY); + } + + /* Make sure memory region is set to all 0's */ + memset(dlz_imp, 0, sizeof(dns_dlzimplementation_t)); + + /* Store the data passed into this method */ + dlz_imp->name = drivername; + dlz_imp->methods = methods; + dlz_imp->mctx = NULL; + dlz_imp->driverarg = driverarg; + + /* attach the new dlz_implementation object to a memory context */ + isc_mem_attach(mctx, &dlz_imp->mctx); + + /* + * prepare the dlz_implementation object to be put in a list, + * and append it to the list + */ + ISC_LINK_INIT(dlz_imp, link); + ISC_LIST_APPEND(dlz_implementations, dlz_imp, link); + + /* Unlock the dlz_implementations list. */ + RWUNLOCK(&dlz_implock, isc_rwlocktype_write); + + /* Pass back the dlz_implementation that we created. */ + *dlzimp = dlz_imp; + + return (ISC_R_SUCCESS); +} + +/*% + * Helper function for dns_dlzstrtoargv(). + * Pardon the gratuitous recursion. + */ +static isc_result_t +dns_dlzstrtoargvsub(isc_mem_t *mctx, char *s, unsigned int *argcp, + char ***argvp, unsigned int n) +{ + isc_result_t result; + + restart: + /* Discard leading whitespace. */ + while (*s == ' ' || *s == '\t') + s++; + + if (*s == '\0') { + /* We have reached the end of the string. */ + *argcp = n; + *argvp = isc_mem_get(mctx, n * sizeof(char *)); + if (*argvp == NULL) + return (ISC_R_NOMEMORY); + } else { + char *p = s; + while (*p != ' ' && *p != '\t' && *p != '\0' && *p != '{') { + if (*p == '\n') { + *p = ' '; + goto restart; + } + p++; + } + + /* do "grouping", items between { and } are one arg */ + if (*p == '{') { + char *t = p; + /* + * shift all characters to left by 1 to get rid of '{' + */ + while (*t != '\0') { + t++; + *(t-1) = *t; + } + while (*p != '\0' && *p != '}') { + p++; + } + /* get rid of '}' character */ + if (*p == '}') { + *p = '\0'; + p++; + } + /* normal case, no "grouping" */ + } else if (*p != '\0') + *p++ = '\0'; + + result = dns_dlzstrtoargvsub(mctx, p, argcp, argvp, n + 1); + if (result != ISC_R_SUCCESS) + return (result); + (*argvp)[n] = s; + } + return (ISC_R_SUCCESS); +} + +/*% + * Tokenize the string "s" into whitespace-separated words, + * return the number of words in '*argcp' and an array + * of pointers to the words in '*argvp'. The caller + * must free the array using isc_mem_put(). The string + * is modified in-place. + */ +isc_result_t +dns_dlzstrtoargv(isc_mem_t *mctx, char *s, + unsigned int *argcp, char ***argvp) +{ + return(dns_dlzstrtoargvsub(mctx, s, argcp, argvp, 0)); +} + +/*% + * Unregisters a DLZ driver. This basically just removes the dlz + * driver from the list of available drivers in the dlz_implementations list. + */ +void +dns_dlzunregister(dns_dlzimplementation_t **dlzimp) { + dns_dlzimplementation_t *dlz_imp; + isc_mem_t *mctx; + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Unregistering DLZ driver."); + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(dlzimp != NULL && *dlzimp != NULL); + + /* + * initialize the dlz_implementations list, this is guaranteed + * to only really happen once. + */ + RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); + + dlz_imp = *dlzimp; + + /* lock the dlz_implementations list so we can modify it. */ + RWLOCK(&dlz_implock, isc_rwlocktype_write); + + /* remove the dlz_implementation object from the list */ + ISC_LIST_UNLINK(dlz_implementations, dlz_imp, link); + mctx = dlz_imp->mctx; + + /* + * return the memory back to the available memory pool and + * remove it from the memory context. + */ + isc_mem_put(mctx, dlz_imp, sizeof(dns_dlzimplementation_t)); + isc_mem_detach(&mctx); + + /* Unlock the dlz_implementations list. */ + RWUNLOCK(&dlz_implock, isc_rwlocktype_write); +} diff --git a/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c index 91f7a99..c0339a1 100644 --- a/contrib/bind9/lib/dns/dnssec.c +++ b/contrib/bind9/lib/dns/dnssec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,9 +16,10 @@ */ /* - * $Id: dnssec.c,v 1.69.2.5.2.9 2006/01/04 23:50:20 marka Exp $ + * $Id: dnssec.c,v 1.81.18.6 2006/03/07 00:34:53 marka Exp $ */ +/*! \file */ #include <config.h> @@ -519,10 +520,10 @@ dns_dnssec_verify(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_result_t dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, - dns_dbnode_t *node, dns_name_t *name, - const char *directory, isc_mem_t *mctx, - unsigned int maxkeys, dst_key_t **keys, - unsigned int *nkeys) + dns_dbnode_t *node, dns_name_t *name, + const char *directory, isc_mem_t *mctx, + unsigned int maxkeys, dst_key_t **keys, + unsigned int *nkeys) { dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; diff --git a/contrib/bind9/lib/dns/ds.c b/contrib/bind9/lib/dns/ds.c index b0ca523..7cd1609 100644 --- a/contrib/bind9/lib/dns/ds.c +++ b/contrib/bind9/lib/dns/ds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds.c,v 1.4.2.1 2004/03/08 02:07:53 marka Exp $ */ +/* $Id: ds.c,v 1.4.20.5 2006/02/22 23:50:09 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -24,6 +26,7 @@ #include <isc/buffer.h> #include <isc/region.h> #include <isc/sha1.h> +#include <isc/sha2.h> #include <isc/util.h> #include <dns/ds.h> @@ -40,10 +43,9 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata) { - isc_sha1_t sha1; dns_fixedname_t fname; dns_name_t *name; - unsigned char digest[ISC_SHA1_DIGESTLENGTH]; + unsigned char digest[ISC_SHA256_DIGESTLENGTH]; isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; @@ -51,7 +53,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); - if (digest_type != DNS_DSDIGEST_SHA1) + if (!dns_ds_digest_supported(digest_type)) return (ISC_R_NOTIMPLEMENTED); dns_fixedname_init(&fname); @@ -61,23 +63,42 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); - isc_sha1_init(&sha1); - dns_name_toregion(name, &r); - isc_sha1_update(&sha1, r.base, r.length); - dns_rdata_toregion(key, &r); - INSIST(r.length >= 4); - isc_sha1_update(&sha1, r.base, r.length); - isc_sha1_final(&sha1, digest); + if (digest_type == DNS_DSDIGEST_SHA1) { + isc_sha1_t sha1; + isc_sha1_init(&sha1); + dns_name_toregion(name, &r); + isc_sha1_update(&sha1, r.base, r.length); + dns_rdata_toregion(key, &r); + INSIST(r.length >= 4); + isc_sha1_update(&sha1, r.base, r.length); + isc_sha1_final(&sha1, digest); + } else { + isc_sha256_t sha256; + isc_sha256_init(&sha256); + dns_name_toregion(name, &r); + isc_sha256_update(&sha256, r.base, r.length); + dns_rdata_toregion(key, &r); + INSIST(r.length >= 4); + isc_sha256_update(&sha256, r.base, r.length); + isc_sha256_final(digest, &sha256); + } ds.mctx = NULL; ds.common.rdclass = key->rdclass; ds.common.rdtype = dns_rdatatype_ds; ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); - ds.digest_type = DNS_DSDIGEST_SHA1; - ds.length = ISC_SHA1_DIGESTLENGTH; + ds.digest_type = digest_type; + ds.length = (digest_type == DNS_DSDIGEST_SHA1) ? + ISC_SHA1_DIGESTLENGTH : ISC_SHA256_DIGESTLENGTH; ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, &ds, &b)); } + +isc_boolean_t +dns_ds_digest_supported(unsigned int digest_type) { + return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || + digest_type == DNS_DSDIGEST_SHA256)); +} diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c index b7b03e6..7d98e10 100644 --- a/contrib/bind9/lib/dns/dst_api.c +++ b/contrib/bind9/lib/dns/dst_api.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,9 +18,11 @@ /* * Principal Author: Brian Wellington - * $Id: dst_api.c,v 1.1.4.3 2006/01/04 23:50:20 marka Exp $ + * $Id: dst_api.c,v 1.1.6.7 2006/01/27 23:57:44 marka Exp $ */ +/*! \file */ + #include <config.h> #include <stdlib.h> @@ -29,6 +31,7 @@ #include <isc/dir.h> #include <isc/entropy.h> #include <isc/fsaccess.h> +#include <isc/hmacsha.h> #include <isc/lex.h> #include <isc/mem.h> #include <isc/once.h> @@ -69,10 +72,6 @@ static dst_key_t * get_key_struct(dns_name_t *name, unsigned int bits, dns_rdataclass_t rdclass, isc_mem_t *mctx); -static isc_result_t read_public_key(const char *filename, - int type, - isc_mem_t *mctx, - dst_key_t **keyp); static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory); static isc_result_t buildfilename(dns_name_t *name, @@ -111,6 +110,20 @@ static isc_result_t addsuffix(char *filename, unsigned int len, return (_r); \ } while (0); \ +static void * +default_memalloc(void *arg, size_t size) { + UNUSED(arg); + if (size == 0U) + size = 1; + return (malloc(size)); +} + +static void +default_memfree(void *arg, void *ptr) { + UNUSED(arg); + free(ptr); +} + isc_result_t dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { isc_result_t result; @@ -126,9 +139,12 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { * When using --with-openssl, there seems to be no good way of not * leaking memory due to the openssl error handling mechanism. * Avoid assertions by using a local memory context and not checking - * for leaks on exit. + * for leaks on exit. Note: as there are leaks we cannot use + * ISC_MEMFLAG_INTERNAL as it will free up memory still being used + * by libcrypto. */ - result = isc_mem_create(0, 0, &dst__memory_pool); + result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, + NULL, &dst__memory_pool, 0); if (result != ISC_R_SUCCESS) return (result); isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE); @@ -142,6 +158,11 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { memset(dst_t_func, 0, sizeof(dst_t_func)); RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5])); + RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1])); + RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224])); + RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256])); + RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384])); + RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); #ifdef OPENSSL RETERR(dst__openssl_init()); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5])); @@ -392,7 +413,16 @@ dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx, REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); - result = read_public_key(filename, type, mctx, &pubkey); + newfilenamelen = strlen(filename) + 5; + newfilename = isc_mem_get(mctx, newfilenamelen); + if (newfilename == NULL) + return (ISC_R_NOMEMORY); + result = addsuffix(newfilename, newfilenamelen, filename, ".key"); + INSIST(result == ISC_R_SUCCESS); + + result = dst_key_read_public(newfilename, type, mctx, &pubkey); + isc_mem_put(mctx, newfilename, newfilenamelen); + newfilename = NULL; if (result != ISC_R_SUCCESS) return (result); @@ -482,7 +512,7 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) { & 0xffff)); } - if (key->opaque == NULL) /* NULL KEY */ + if (key->opaque == NULL) /*%< NULL KEY */ return (ISC_R_SUCCESS); return (key->func->todns(key, target)); @@ -629,7 +659,7 @@ dst_key_generate(dns_name_t *name, unsigned int alg, if (key == NULL) return (ISC_R_NOMEMORY); - if (bits == 0) { /* NULL KEY */ + if (bits == 0) { /*%< NULL KEY */ key->key_flags |= DNS_KEYTYPE_NOKEY; *keyp = key; return (ISC_R_SUCCESS); @@ -753,8 +783,23 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) { case DST_ALG_HMACMD5: *n = 16; break; + case DST_ALG_HMACSHA1: + *n = ISC_SHA1_DIGESTLENGTH; + break; + case DST_ALG_HMACSHA224: + *n = ISC_SHA224_DIGESTLENGTH; + break; + case DST_ALG_HMACSHA256: + *n = ISC_SHA256_DIGESTLENGTH; + break; + case DST_ALG_HMACSHA384: + *n = ISC_SHA384_DIGESTLENGTH; + break; + case DST_ALG_HMACSHA512: + *n = ISC_SHA512_DIGESTLENGTH; + break; case DST_ALG_GSSAPI: - *n = 128; /* XXX */ + *n = 128; /*%< XXX */ break; case DST_ALG_DH: default: @@ -780,7 +825,7 @@ dst_key_secretsize(const dst_key_t *key, unsigned int *n) { *** Static methods ***/ -/* +/*% * Allocates a key structure and fills in some of the fields. */ static dst_key_t * @@ -822,12 +867,12 @@ get_key_struct(dns_name_t *name, unsigned int alg, return (key); } -/* +/*% * Reads a public key from disk */ -static isc_result_t -read_public_key(const char *filename, int type, - isc_mem_t *mctx, dst_key_t **keyp) +isc_result_t +dst_key_read_public(const char *filename, int type, + isc_mem_t *mctx, dst_key_t **keyp) { u_char rdatabuf[DST_KEY_MAXSIZE]; isc_buffer_t b; @@ -837,25 +882,16 @@ read_public_key(const char *filename, int type, isc_result_t ret; dns_rdata_t rdata = DNS_RDATA_INIT; unsigned int opt = ISC_LEXOPT_DNSMULTILINE; - char *newfilename; - unsigned int newfilenamelen; dns_rdataclass_t rdclass = dns_rdataclass_in; isc_lexspecials_t specials; isc_uint32_t ttl; isc_result_t result; dns_rdatatype_t keytype; - newfilenamelen = strlen(filename) + 5; - newfilename = isc_mem_get(mctx, newfilenamelen); - if (newfilename == NULL) - return (ISC_R_NOMEMORY); - ret = addsuffix(newfilename, newfilenamelen, filename, ".key"); - INSIST(ret == ISC_R_SUCCESS); - /* * Open the file and read its formatted contents * File format: - * domain.name [ttl] [class] KEY <flags> <protocol> <algorithm> <key> + * domain.name [ttl] [class] [KEY|DNSKEY] <flags> <protocol> <algorithm> <key> */ /* 1500 should be large enough for any key */ @@ -870,7 +906,7 @@ read_public_key(const char *filename, int type, isc_lex_setspecials(lex, specials); isc_lex_setcomments(lex, ISC_LEXCOMMENT_DNSMASTERFILE); - ret = isc_lex_openfile(lex, newfilename); + ret = isc_lex_openfile(lex, filename); if (ret != ISC_R_SUCCESS) goto cleanup; @@ -918,7 +954,7 @@ read_public_key(const char *filename, int type, if (strcasecmp(DST_AS_STR(token), "DNSKEY") == 0) keytype = dns_rdatatype_dnskey; else if (strcasecmp(DST_AS_STR(token), "KEY") == 0) - keytype = dns_rdatatype_key; /* SIG(0), TKEY */ + keytype = dns_rdatatype_key; /*%< SIG(0), TKEY */ else BADTOKEN(); @@ -942,8 +978,6 @@ read_public_key(const char *filename, int type, cleanup: if (lex != NULL) isc_lex_destroy(&lex); - isc_mem_put(mctx, newfilename, newfilenamelen); - return (ret); } @@ -967,7 +1001,7 @@ issymmetric(const dst_key_t *key) { } } -/* +/*% * Writes a public key to disk in DNS format. */ static isc_result_t diff --git a/contrib/bind9/lib/dns/dst_internal.h b/contrib/bind9/lib/dns/dst_internal.h index 982eb6d..f2deb72 100644 --- a/contrib/bind9/lib/dns/dst_internal.h +++ b/contrib/bind9/lib/dns/dst_internal.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -16,7 +16,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_internal.h,v 1.1.4.1 2004/12/09 04:07:16 marka Exp $ */ +/* $Id: dst_internal.h,v 1.1.6.5 2006/01/27 23:57:44 marka Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -46,18 +46,20 @@ extern isc_mem_t *dst__memory_pool; typedef struct dst_func dst_func_t; +/*% DST Key Structure */ struct dst_key { unsigned int magic; - dns_name_t * key_name; /* name of the key */ - unsigned int key_size; /* size of the key in bits */ - unsigned int key_proto; /* protocols this key is used for */ - unsigned int key_alg; /* algorithm of the key */ - isc_uint32_t key_flags; /* flags of the public key */ - isc_uint16_t key_id; /* identifier of the key */ - dns_rdataclass_t key_class; /* class of the key record */ - isc_mem_t *mctx; /* memory context */ - void * opaque; /* pointer to key in crypto pkg fmt */ - dst_func_t * func; /* crypto package specific functions */ + dns_name_t * key_name; /*%< name of the key */ + unsigned int key_size; /*%< size of the key in bits */ + unsigned int key_proto; /*%< protocols this key is used for */ + unsigned int key_alg; /*%< algorithm of the key */ + isc_uint32_t key_flags; /*%< flags of the public key */ + isc_uint16_t key_id; /*%< identifier of the key */ + isc_uint16_t key_bits; /*%< hmac digest bits */ + dns_rdataclass_t key_class; /*%< class of the key record */ + isc_mem_t *mctx; /*%< memory context */ + void * opaque; /*%< pointer to key in crypto pkg fmt */ + dst_func_t * func; /*%< crypto package specific functions */ }; struct dst_context { @@ -100,30 +102,35 @@ struct dst_func { void (*cleanup)(void); }; -/* +/*% * Initializers */ isc_result_t dst__openssl_init(void); isc_result_t dst__hmacmd5_init(struct dst_func **funcp); +isc_result_t dst__hmacsha1_init(struct dst_func **funcp); +isc_result_t dst__hmacsha224_init(struct dst_func **funcp); +isc_result_t dst__hmacsha256_init(struct dst_func **funcp); +isc_result_t dst__hmacsha384_init(struct dst_func **funcp); +isc_result_t dst__hmacsha512_init(struct dst_func **funcp); isc_result_t dst__opensslrsa_init(struct dst_func **funcp); isc_result_t dst__openssldsa_init(struct dst_func **funcp); isc_result_t dst__openssldh_init(struct dst_func **funcp); isc_result_t dst__gssapi_init(struct dst_func **funcp); -/* +/*% * Destructors */ void dst__openssl_destroy(void); -/* +/*% * Memory allocators using the DST memory pool. */ void * dst__mem_alloc(size_t size); void dst__mem_free(void *ptr); void * dst__mem_realloc(void *ptr, size_t size); -/* +/*% * Entropy retriever using the DST entropy pool. */ isc_result_t dst__entropy_getdata(void *buf, unsigned int len, @@ -132,3 +139,4 @@ isc_result_t dst__entropy_getdata(void *buf, unsigned int len, ISC_LANG_ENDDECLS #endif /* DST_DST_INTERNAL_H */ +/*! \file */ diff --git a/contrib/bind9/lib/dns/dst_lib.c b/contrib/bind9/lib/dns/dst_lib.c index 8046110..305051c 100644 --- a/contrib/bind9/lib/dns/dst_lib.c +++ b/contrib/bind9/lib/dns/dst_lib.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -17,9 +17,11 @@ /* * Principal Author: Brian Wellington - * $Id: dst_lib.c,v 1.1.4.1 2004/12/09 04:07:16 marka Exp $ + * $Id: dst_lib.c,v 1.1.6.3 2005/04/29 00:15:51 marka Exp $ */ +/*! \file */ + #include <config.h> #include <stddef.h> diff --git a/contrib/bind9/lib/dns/dst_openssl.h b/contrib/bind9/lib/dns/dst_openssl.h index 8dbc350..79e10b0 100644 --- a/contrib/bind9/lib/dns/dst_openssl.h +++ b/contrib/bind9/lib/dns/dst_openssl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_openssl.h,v 1.1.2.1 2004/12/09 04:07:17 marka Exp $ */ +/* $Id: dst_openssl.h,v 1.1.4.3 2005/04/29 00:15:52 marka Exp $ */ #ifndef DST_OPENSSL_H #define DST_OPENSSL_H 1 @@ -31,3 +31,4 @@ dst__openssl_toresult(isc_result_t fallback); ISC_LANG_ENDDECLS #endif /* DST_OPENSSL_H */ +/*! \file */ diff --git a/contrib/bind9/lib/dns/dst_parse.c b/contrib/bind9/lib/dns/dst_parse.c index d34aeca..aad7998 100644 --- a/contrib/bind9/lib/dns/dst_parse.c +++ b/contrib/bind9/lib/dns/dst_parse.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -16,9 +16,9 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* +/*% * Principal Author: Brian Wellington - * $Id: dst_parse.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ + * $Id: dst_parse.c,v 1.1.6.7 2006/05/16 03:59:26 marka Exp $ */ #include <config.h> @@ -67,6 +67,23 @@ static struct parse_map map[] = { {TAG_DSA_PUBLIC, "Public_value(y):"}, {TAG_HMACMD5_KEY, "Key:"}, + {TAG_HMACMD5_BITS, "Bits:"}, + + {TAG_HMACSHA1_KEY, "Key:"}, + {TAG_HMACSHA1_BITS, "Bits:"}, + + {TAG_HMACSHA224_KEY, "Key:"}, + {TAG_HMACSHA224_BITS, "Bits:"}, + + {TAG_HMACSHA256_KEY, "Key:"}, + {TAG_HMACSHA256_BITS, "Bits:"}, + + {TAG_HMACSHA384_KEY, "Key:"}, + {TAG_HMACSHA384_BITS, "Bits:"}, + + {TAG_HMACSHA512_KEY, "Key:"}, + {TAG_HMACSHA512_BITS, "Bits:"}, + {0, NULL} }; @@ -141,16 +158,53 @@ check_dsa(const dst_private_t *priv) { } static int -check_hmac_md5(const dst_private_t *priv) { - if (priv->nelements != HMACMD5_NTAGS) +check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) { + int i, j; + + if (priv->nelements != HMACMD5_NTAGS) { + /* + * If this is a good old format and we are accepting + * the old format return success. + */ + if (old && priv->nelements == OLD_HMACMD5_NTAGS && + priv->elements[0].tag == TAG_HMACMD5_KEY) + return (0); return (-1); - if (priv->elements[0].tag != TAG_HMACMD5_KEY) + } + /* + * We must be new format at this point. + */ + for (i = 0; i < HMACMD5_NTAGS; i++) { + for (j = 0; j < priv->nelements; j++) + if (priv->elements[j].tag == TAG(DST_ALG_HMACMD5, i)) + break; + if (j == priv->nelements) + return (-1); + } + return (0); +} + +static int +check_hmac_sha(const dst_private_t *priv, unsigned int ntags, + unsigned int alg) +{ + unsigned int i, j; + if (priv->nelements != ntags) return (-1); + for (i = 0; i < ntags; i++) { + for (j = 0; j < priv->nelements; j++) + if (priv->elements[j].tag == TAG(alg, i)) + break; + if (j == priv->nelements) + return (-1); + } return (0); } static int -check_data(const dst_private_t *priv, const unsigned int alg) { +check_data(const dst_private_t *priv, const unsigned int alg, + isc_boolean_t old) +{ /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (alg) { case DST_ALG_RSAMD5: @@ -161,7 +215,17 @@ check_data(const dst_private_t *priv, const unsigned int alg) { case DST_ALG_DSA: return (check_dsa(priv)); case DST_ALG_HMACMD5: - return (check_hmac_md5(priv)); + return (check_hmac_md5(priv, old)); + case DST_ALG_HMACSHA1: + return (check_hmac_sha(priv, HMACSHA1_NTAGS, alg)); + case DST_ALG_HMACSHA224: + return (check_hmac_sha(priv, HMACSHA224_NTAGS, alg)); + case DST_ALG_HMACSHA256: + return (check_hmac_sha(priv, HMACSHA256_NTAGS, alg)); + case DST_ALG_HMACSHA384: + return (check_hmac_sha(priv, HMACSHA384_NTAGS, alg)); + case DST_ALG_HMACSHA512: + return (check_hmac_sha(priv, HMACSHA512_NTAGS, alg)); default: return (DST_R_UNSUPPORTEDALG); } @@ -313,7 +377,7 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex, done: priv->nelements = n; - if (check_data(priv, alg) < 0) + if (check_data(priv, alg, ISC_TRUE) < 0) goto fail; return (ISC_R_SUCCESS); @@ -341,7 +405,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, REQUIRE(priv != NULL); - if (check_data(priv, dst_key_alg(key)) < 0) + if (check_data(priv, dst_key_alg(key), ISC_FALSE) < 0) return (DST_R_INVALIDPRIVATEKEY); isc_buffer_init(&b, filename, sizeof(filename)); @@ -380,6 +444,21 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; + case DST_ALG_HMACSHA1: + fprintf(fp, "(HMAC_SHA1)\n"); + break; + case DST_ALG_HMACSHA224: + fprintf(fp, "(HMAC_SHA224)\n"); + break; + case DST_ALG_HMACSHA256: + fprintf(fp, "(HMAC_SHA256)\n"); + break; + case DST_ALG_HMACSHA384: + fprintf(fp, "(HMAC_SHA384)\n"); + break; + case DST_ALG_HMACSHA512: + fprintf(fp, "(HMAC_SHA512)\n"); + break; default: fprintf(fp, "(?)\n"); break; @@ -410,3 +489,5 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, fclose(fp); return (ISC_R_SUCCESS); } + +/*! \file */ diff --git a/contrib/bind9/lib/dns/dst_parse.h b/contrib/bind9/lib/dns/dst_parse.h index 9ecef4f..8656f59 100644 --- a/contrib/bind9/lib/dns/dst_parse.h +++ b/contrib/bind9/lib/dns/dst_parse.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -16,8 +16,9 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_parse.h,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ */ +/* $Id: dst_parse.h,v 1.1.6.5 2006/01/27 23:57:44 marka Exp $ */ +/*! \file */ #ifndef DST_DST_PARSE_H #define DST_DST_PARSE_H 1 @@ -59,8 +60,30 @@ #define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3) #define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4) -#define HMACMD5_NTAGS 1 +#define OLD_HMACMD5_NTAGS 1 +#define HMACMD5_NTAGS 2 #define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) +#define TAG_HMACMD5_BITS ((DST_ALG_HMACMD5 << TAG_SHIFT) + 1) + +#define HMACSHA1_NTAGS 2 +#define TAG_HMACSHA1_KEY ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 0) +#define TAG_HMACSHA1_BITS ((DST_ALG_HMACSHA1 << TAG_SHIFT) + 1) + +#define HMACSHA224_NTAGS 2 +#define TAG_HMACSHA224_KEY ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 0) +#define TAG_HMACSHA224_BITS ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 1) + +#define HMACSHA256_NTAGS 2 +#define TAG_HMACSHA256_KEY ((DST_ALG_HMACSHA256 << TAG_SHIFT) + 0) +#define TAG_HMACSHA256_BITS ((DST_ALG_HMACSHA224 << TAG_SHIFT) + 1) + +#define HMACSHA384_NTAGS 2 +#define TAG_HMACSHA384_KEY ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 0) +#define TAG_HMACSHA384_BITS ((DST_ALG_HMACSHA384 << TAG_SHIFT) + 1) + +#define HMACSHA512_NTAGS 2 +#define TAG_HMACSHA512_KEY ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 0) +#define TAG_HMACSHA512_BITS ((DST_ALG_HMACSHA512 << TAG_SHIFT) + 1) struct dst_private_element { unsigned short tag; diff --git a/contrib/bind9/lib/dns/dst_result.c b/contrib/bind9/lib/dns/dst_result.c index 9b1536c..c9bf073 100644 --- a/contrib/bind9/lib/dns/dst_result.c +++ b/contrib/bind9/lib/dns/dst_result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* +/*% * Principal Author: Brian Wellington - * $Id: dst_result.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ + * $Id: dst_result.c,v 1.1.6.3 2005/04/29 00:15:52 marka Exp $ */ #include <config.h> @@ -29,27 +29,27 @@ #include <dst/lib.h> static const char *text[DST_R_NRESULTS] = { - "algorithm is unsupported", /* 0 */ - "openssl failure", /* 1 */ - "built with no crypto support", /* 2 */ - "illegal operation for a null key", /* 3 */ - "public key is invalid", /* 4 */ - "private key is invalid", /* 5 */ - "UNUSED6", /* 6 */ - "error occurred writing key to disk", /* 7 */ - "invalid algorithm specific parameter", /* 8 */ - "UNUSED9", /* 9 */ - "UNUSED10", /* 10 */ - "sign failure", /* 11 */ - "UNUSED12", /* 12 */ - "UNUSED13", /* 13 */ - "verify failure", /* 14 */ - "not a public key", /* 15 */ - "not a private key", /* 16 */ - "not a key that can compute a secret", /* 17 */ - "failure computing a shared secret", /* 18 */ - "no randomness available", /* 19 */ - "bad key type" /* 20 */ + "algorithm is unsupported", /*%< 0 */ + "openssl failure", /*%< 1 */ + "built with no crypto support", /*%< 2 */ + "illegal operation for a null key", /*%< 3 */ + "public key is invalid", /*%< 4 */ + "private key is invalid", /*%< 5 */ + "UNUSED6", /*%< 6 */ + "error occurred writing key to disk", /*%< 7 */ + "invalid algorithm specific parameter", /*%< 8 */ + "UNUSED9", /*%< 9 */ + "UNUSED10", /*%< 10 */ + "sign failure", /*%< 11 */ + "UNUSED12", /*%< 12 */ + "UNUSED13", /*%< 13 */ + "verify failure", /*%< 14 */ + "not a public key", /*%< 15 */ + "not a private key", /*%< 16 */ + "not a key that can compute a secret", /*%< 17 */ + "failure computing a shared secret", /*%< 18 */ + "no randomness available", /*%< 19 */ + "bad key type" /*%< 20 */ }; #define DST_RESULT_RESULTSET 2 @@ -84,3 +84,5 @@ void dst_result_register(void) { initialize(); } + +/*! \file */ diff --git a/contrib/bind9/lib/dns/forward.c b/contrib/bind9/lib/dns/forward.c index 1455fbad..e80a477 100644 --- a/contrib/bind9/lib/dns/forward.c +++ b/contrib/bind9/lib/dns/forward.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: forward.c,v 1.5.206.3 2005/03/17 03:58:30 marka Exp $ */ +/* $Id: forward.c,v 1.6.18.4 2005/07/12 01:22:20 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -62,13 +64,8 @@ dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep) { goto cleanup_fwdtable; result = isc_rwlock_init(&fwdtable->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_rwlock_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_rbt; - } fwdtable->mctx = NULL; isc_mem_attach(mctx, &fwdtable->mctx); diff --git a/contrib/bind9/lib/dns/gen-unix.h b/contrib/bind9/lib/dns/gen-unix.h index bd007c4..fc2dbf2 100644 --- a/contrib/bind9/lib/dns/gen-unix.h +++ b/contrib/bind9/lib/dns/gen-unix.h @@ -15,9 +15,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gen-unix.h,v 1.12.12.5 2005/06/09 23:54:29 marka Exp $ */ +/* $Id: gen-unix.h,v 1.14.18.3 2005/06/08 02:07:54 marka Exp $ */ -/* +/*! \file + * \brief * This file is responsible for defining two operations that are not * directly portable between Unix-like systems and Windows NT, option * parsing and directory scanning. It is here because it was decided diff --git a/contrib/bind9/lib/dns/gen.c b/contrib/bind9/lib/dns/gen.c index 1d83023..1e6212a 100644 --- a/contrib/bind9/lib/dns/gen.c +++ b/contrib/bind9/lib/dns/gen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gen.c,v 1.65.2.5.2.9 2006/10/02 06:31:26 marka Exp $ */ +/* $Id: gen.c,v 1.73.18.6 2006/10/02 06:36:43 marka Exp $ */ + +/*! \file */ #ifdef WIN32 /* @@ -123,6 +125,8 @@ const char copyright[] = " *************** DO NOT EDIT!\n" " ***************\n" " ***************/\n" +"\n" +"/*! \\file */\n" "\n"; #define TYPENAMES 256 @@ -168,7 +172,7 @@ sd(int, const char *, const char *, char); void insert_into_typenames(int, const char *, const char *); -/* +/*% * If you use more than 10 of these in, say, a printf(), you'll have problems. */ char * @@ -832,13 +836,10 @@ main(int argc, char **argv) { } while (0) for (cc = classes; cc != NULL; cc = cc->next) { - if (cc->rdclass == 4) { - PRINTCLASS("ch", 3); + if (cc->rdclass == 3) PRINTCLASS("chaos", 3); - - } else if (cc->rdclass == 255) { + else if (cc->rdclass == 255) PRINTCLASS("none", 254); - } PRINTCLASS(cc->classname, cc->rdclass); } diff --git a/contrib/bind9/lib/dns/gssapi_link.c b/contrib/bind9/lib/dns/gssapi_link.c index 0a2e848..a6a367a 100644 --- a/contrib/bind9/lib/dns/gssapi_link.c +++ b/contrib/bind9/lib/dns/gssapi_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,7 +16,7 @@ */ /* - * $Id: gssapi_link.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ + * $Id: gssapi_link.c,v 1.1.6.3 2005/04/29 00:15:53 marka Exp $ */ #ifdef GSSAPI @@ -194,17 +194,17 @@ static dst_func_t gssapi_functions = { gssapi_adddata, gssapi_sign, gssapi_verify, - NULL, /* computesecret */ + NULL, /*%< computesecret */ gssapi_compare, - NULL, /* paramcompare */ + NULL, /*%< paramcompare */ gssapi_generate, gssapi_isprivate, gssapi_destroy, - NULL, /* todns */ - NULL, /* fromdns */ - NULL, /* tofile */ - NULL, /* parse */ - NULL, /* cleanup */ + NULL, /*%< todns */ + NULL, /*%< fromdns */ + NULL, /*%< tofile */ + NULL, /*%< parse */ + NULL, /*%< cleanup */ }; isc_result_t @@ -218,3 +218,5 @@ dst__gssapi_init(dst_func_t **funcp) { #else int gssapi_link_unneeded = 1; #endif + +/*! \file */ diff --git a/contrib/bind9/lib/dns/gssapictx.c b/contrib/bind9/lib/dns/gssapictx.c index 2605a7a..ce5d6fa 100644 --- a/contrib/bind9/lib/dns/gssapictx.c +++ b/contrib/bind9/lib/dns/gssapictx.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gssapictx.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ */ +/* $Id: gssapictx.c,v 1.1.6.3 2005/04/29 00:15:54 marka Exp $ */ #include <config.h> @@ -260,3 +260,5 @@ dst_gssapi_acceptctx(dns_name_t *name, void *cred, } #endif + +/*! \file */ diff --git a/contrib/bind9/lib/dns/hmac_link.c b/contrib/bind9/lib/dns/hmac_link.c index 762fcee..9655c89 100644 --- a/contrib/bind9/lib/dns/hmac_link.c +++ b/contrib/bind9/lib/dns/hmac_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,14 +18,16 @@ /* * Principal Author: Brian Wellington - * $Id: hmac_link.c,v 1.1.4.1 2004/12/09 04:07:17 marka Exp $ + * $Id: hmac_link.c,v 1.1.6.5 2006/01/27 23:57:44 marka Exp $ */ #include <config.h> #include <isc/buffer.h> #include <isc/hmacmd5.h> +#include <isc/hmacsha.h> #include <isc/md5.h> +#include <isc/sha1.h> #include <isc/mem.h> #include <isc/string.h> #include <isc/util.h> @@ -46,6 +48,17 @@ typedef struct hmackey { } HMAC_Key; static isc_result_t +getkeybits(dst_key_t *key, struct dst_private_element *element) { + + if (element->length != 2) + return (DST_R_INVALIDPRIVATEKEY); + + key->key_bits = (element->data[0] << 8) + element->data[1]; + + return (ISC_R_SUCCESS); +} + +static isc_result_t hmacmd5_createctx(dst_key_t *key, dst_context_t *dctx) { isc_hmacmd5_t *hmacmd5ctx; HMAC_Key *hkey = key->opaque; @@ -95,10 +108,10 @@ static isc_result_t hmacmd5_verify(dst_context_t *dctx, const isc_region_t *sig) { isc_hmacmd5_t *hmacmd5ctx = dctx->opaque; - if (sig->length < ISC_MD5_DIGESTLENGTH) + if (sig->length > ISC_MD5_DIGESTLENGTH) return (DST_R_VERIFYFAILURE); - if (isc_hmacmd5_verify(hmacmd5ctx, sig->base)) + if (isc_hmacmd5_verify2(hmacmd5ctx, sig->base, sig->length)) return (ISC_R_SUCCESS); else return (DST_R_VERIFYFAILURE); @@ -130,9 +143,9 @@ hmacmd5_generate(dst_key_t *key, int pseudorandom_ok) { unsigned char data[HMAC_LEN]; bytes = (key->key_size + 7) / 8; - if (bytes > 64) { - bytes = 64; - key->key_size = 512; + if (bytes > HMAC_LEN) { + bytes = HMAC_LEN; + key->key_size = HMAC_LEN * 8; } memset(data, 0, HMAC_LEN); @@ -220,6 +233,7 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) { HMAC_Key *hkey; dst_private_t priv; int bytes = (key->key_size + 7) / 8; + unsigned char buf[2]; if (key->opaque == NULL) return (DST_R_NULLKEY); @@ -230,6 +244,12 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) { priv.elements[cnt].length = bytes; priv.elements[cnt++].data = hkey->key; + buf[0] = (key->key_bits >> 8) & 0xffU; + buf[1] = key->key_bits & 0xffU; + priv.elements[cnt].tag = TAG_HMACMD5_BITS; + priv.elements[cnt].data = buf; + priv.elements[cnt++].length = 2; + priv.nelements = cnt; return (dst__privstruct_writefile(key, &priv, directory)); } @@ -237,21 +257,40 @@ hmacmd5_tofile(const dst_key_t *key, const char *directory) { static isc_result_t hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer) { dst_private_t priv; - isc_result_t ret; + isc_result_t result, tresult; isc_buffer_t b; isc_mem_t *mctx = key->mctx; + unsigned int i; /* read private key file */ - ret = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv); - if (ret != ISC_R_SUCCESS) - return (ret); + result = dst__privstruct_parse(key, DST_ALG_HMACMD5, lexer, mctx, &priv); + if (result != ISC_R_SUCCESS) + return (result); - isc_buffer_init(&b, priv.elements[0].data, priv.elements[0].length); - isc_buffer_add(&b, priv.elements[0].length); - ret = hmacmd5_fromdns(key, &b); + key->key_bits = 0; + for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { + switch (priv.elements[i].tag) { + case TAG_HMACMD5_KEY: + isc_buffer_init(&b, priv.elements[i].data, + priv.elements[i].length); + isc_buffer_add(&b, priv.elements[i].length); + tresult = hmacmd5_fromdns(key, &b); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + case TAG_HMACMD5_BITS: + tresult = getkeybits(key, &priv.elements[i]); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + default: + result = DST_R_INVALIDPRIVATEKEY; + break; + } + } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); - return (ret); + return (result); } static dst_func_t hmacmd5_functions = { @@ -260,9 +299,9 @@ static dst_func_t hmacmd5_functions = { hmacmd5_adddata, hmacmd5_sign, hmacmd5_verify, - NULL, /* computesecret */ + NULL, /*%< computesecret */ hmacmd5_compare, - NULL, /* paramcompare */ + NULL, /*%< paramcompare */ hmacmd5_generate, hmacmd5_isprivate, hmacmd5_destroy, @@ -270,7 +309,7 @@ static dst_func_t hmacmd5_functions = { hmacmd5_fromdns, hmacmd5_tofile, hmacmd5_parse, - NULL, /* cleanup */ + NULL, /*%< cleanup */ }; isc_result_t @@ -280,3 +319,1350 @@ dst__hmacmd5_init(dst_func_t **funcp) { *funcp = &hmacmd5_functions; return (ISC_R_SUCCESS); } + +static isc_result_t hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data); + +typedef struct { + unsigned char key[ISC_SHA1_DIGESTLENGTH]; +} HMACSHA1_Key; + +static isc_result_t +hmacsha1_createctx(dst_key_t *key, dst_context_t *dctx) { + isc_hmacsha1_t *hmacsha1ctx; + HMACSHA1_Key *hkey = key->opaque; + + hmacsha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha1_t)); + if (hmacsha1ctx == NULL) + return (ISC_R_NOMEMORY); + isc_hmacsha1_init(hmacsha1ctx, hkey->key, ISC_SHA1_DIGESTLENGTH); + dctx->opaque = hmacsha1ctx; + return (ISC_R_SUCCESS); +} + +static void +hmacsha1_destroyctx(dst_context_t *dctx) { + isc_hmacsha1_t *hmacsha1ctx = dctx->opaque; + + if (hmacsha1ctx != NULL) { + isc_hmacsha1_invalidate(hmacsha1ctx); + isc_mem_put(dctx->mctx, hmacsha1ctx, sizeof(isc_hmacsha1_t)); + dctx->opaque = NULL; + } +} + +static isc_result_t +hmacsha1_adddata(dst_context_t *dctx, const isc_region_t *data) { + isc_hmacsha1_t *hmacsha1ctx = dctx->opaque; + + isc_hmacsha1_update(hmacsha1ctx, data->base, data->length); + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha1_sign(dst_context_t *dctx, isc_buffer_t *sig) { + isc_hmacsha1_t *hmacsha1ctx = dctx->opaque; + unsigned char *digest; + + if (isc_buffer_availablelength(sig) < ISC_SHA1_DIGESTLENGTH) + return (ISC_R_NOSPACE); + digest = isc_buffer_used(sig); + isc_hmacsha1_sign(hmacsha1ctx, digest, ISC_SHA1_DIGESTLENGTH); + isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha1_verify(dst_context_t *dctx, const isc_region_t *sig) { + isc_hmacsha1_t *hmacsha1ctx = dctx->opaque; + + if (sig->length > ISC_SHA1_DIGESTLENGTH || sig->length == 0) + return (DST_R_VERIFYFAILURE); + + if (isc_hmacsha1_verify(hmacsha1ctx, sig->base, sig->length)) + return (ISC_R_SUCCESS); + else + return (DST_R_VERIFYFAILURE); +} + +static isc_boolean_t +hmacsha1_compare(const dst_key_t *key1, const dst_key_t *key2) { + HMACSHA1_Key *hkey1, *hkey2; + + hkey1 = (HMACSHA1_Key *)key1->opaque; + hkey2 = (HMACSHA1_Key *)key2->opaque; + + if (hkey1 == NULL && hkey2 == NULL) + return (ISC_TRUE); + else if (hkey1 == NULL || hkey2 == NULL) + return (ISC_FALSE); + + if (memcmp(hkey1->key, hkey2->key, ISC_SHA1_DIGESTLENGTH) == 0) + return (ISC_TRUE); + else + return (ISC_FALSE); +} + +static isc_result_t +hmacsha1_generate(dst_key_t *key, int pseudorandom_ok) { + isc_buffer_t b; + isc_result_t ret; + int bytes; + unsigned char data[HMAC_LEN]; + + bytes = (key->key_size + 7) / 8; + if (bytes > HMAC_LEN) { + bytes = HMAC_LEN; + key->key_size = HMAC_LEN * 8; + } + + memset(data, 0, HMAC_LEN); + ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); + + if (ret != ISC_R_SUCCESS) + return (ret); + + isc_buffer_init(&b, data, bytes); + isc_buffer_add(&b, bytes); + ret = hmacsha1_fromdns(key, &b); + memset(data, 0, ISC_SHA1_DIGESTLENGTH); + + return (ret); +} + +static isc_boolean_t +hmacsha1_isprivate(const dst_key_t *key) { + UNUSED(key); + return (ISC_TRUE); +} + +static void +hmacsha1_destroy(dst_key_t *key) { + HMACSHA1_Key *hkey = key->opaque; + memset(hkey, 0, sizeof(HMACSHA1_Key)); + isc_mem_put(key->mctx, hkey, sizeof(HMACSHA1_Key)); + key->opaque = NULL; +} + +static isc_result_t +hmacsha1_todns(const dst_key_t *key, isc_buffer_t *data) { + HMACSHA1_Key *hkey; + unsigned int bytes; + + REQUIRE(key->opaque != NULL); + + hkey = (HMACSHA1_Key *) key->opaque; + + bytes = (key->key_size + 7) / 8; + if (isc_buffer_availablelength(data) < bytes) + return (ISC_R_NOSPACE); + isc_buffer_putmem(data, hkey->key, bytes); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha1_fromdns(dst_key_t *key, isc_buffer_t *data) { + HMACSHA1_Key *hkey; + int keylen; + isc_region_t r; + isc_sha1_t sha1ctx; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + hkey = (HMACSHA1_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA1_Key)); + if (hkey == NULL) + return (ISC_R_NOMEMORY); + + memset(hkey->key, 0, sizeof(hkey->key)); + + if (r.length > ISC_SHA1_DIGESTLENGTH) { + isc_sha1_init(&sha1ctx); + isc_sha1_update(&sha1ctx, r.base, r.length); + isc_sha1_final(&sha1ctx, hkey->key); + keylen = ISC_SHA1_DIGESTLENGTH; + } + else { + memcpy(hkey->key, r.base, r.length); + keylen = r.length; + } + + key->key_size = keylen * 8; + key->opaque = hkey; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha1_tofile(const dst_key_t *key, const char *directory) { + int cnt = 0; + HMACSHA1_Key *hkey; + dst_private_t priv; + int bytes = (key->key_size + 7) / 8; + unsigned char buf[2]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + hkey = (HMACSHA1_Key *) key->opaque; + + priv.elements[cnt].tag = TAG_HMACSHA1_KEY; + priv.elements[cnt].length = bytes; + priv.elements[cnt++].data = hkey->key; + + buf[0] = (key->key_bits >> 8) & 0xffU; + buf[1] = key->key_bits & 0xffU; + priv.elements[cnt].tag = TAG_HMACSHA1_BITS; + priv.elements[cnt].data = buf; + priv.elements[cnt++].length = 2; + + priv.nelements = cnt; + return (dst__privstruct_writefile(key, &priv, directory)); +} + +static isc_result_t +hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer) { + dst_private_t priv; + isc_result_t result, tresult; + isc_buffer_t b; + isc_mem_t *mctx = key->mctx; + unsigned int i; + + /* read private key file */ + result = dst__privstruct_parse(key, DST_ALG_HMACSHA1, lexer, mctx, + &priv); + if (result != ISC_R_SUCCESS) + return (result); + + key->key_bits = 0; + for (i = 0; i < priv.nelements; i++) { + switch (priv.elements[i].tag) { + case TAG_HMACSHA1_KEY: + isc_buffer_init(&b, priv.elements[i].data, + priv.elements[i].length); + isc_buffer_add(&b, priv.elements[i].length); + tresult = hmacsha1_fromdns(key, &b); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + case TAG_HMACSHA1_BITS: + tresult = getkeybits(key, &priv.elements[i]); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + default: + result = DST_R_INVALIDPRIVATEKEY; + break; + } + } + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (result); +} + +static dst_func_t hmacsha1_functions = { + hmacsha1_createctx, + hmacsha1_destroyctx, + hmacsha1_adddata, + hmacsha1_sign, + hmacsha1_verify, + NULL, /* computesecret */ + hmacsha1_compare, + NULL, /* paramcompare */ + hmacsha1_generate, + hmacsha1_isprivate, + hmacsha1_destroy, + hmacsha1_todns, + hmacsha1_fromdns, + hmacsha1_tofile, + hmacsha1_parse, + NULL, /* cleanup */ +}; + +isc_result_t +dst__hmacsha1_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + if (*funcp == NULL) + *funcp = &hmacsha1_functions; + return (ISC_R_SUCCESS); +} + +static isc_result_t hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data); + +typedef struct { + unsigned char key[ISC_SHA224_DIGESTLENGTH]; +} HMACSHA224_Key; + +static isc_result_t +hmacsha224_createctx(dst_key_t *key, dst_context_t *dctx) { + isc_hmacsha224_t *hmacsha224ctx; + HMACSHA224_Key *hkey = key->opaque; + + hmacsha224ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha224_t)); + if (hmacsha224ctx == NULL) + return (ISC_R_NOMEMORY); + isc_hmacsha224_init(hmacsha224ctx, hkey->key, ISC_SHA224_DIGESTLENGTH); + dctx->opaque = hmacsha224ctx; + return (ISC_R_SUCCESS); +} + +static void +hmacsha224_destroyctx(dst_context_t *dctx) { + isc_hmacsha224_t *hmacsha224ctx = dctx->opaque; + + if (hmacsha224ctx != NULL) { + isc_hmacsha224_invalidate(hmacsha224ctx); + isc_mem_put(dctx->mctx, hmacsha224ctx, sizeof(isc_hmacsha224_t)); + dctx->opaque = NULL; + } +} + +static isc_result_t +hmacsha224_adddata(dst_context_t *dctx, const isc_region_t *data) { + isc_hmacsha224_t *hmacsha224ctx = dctx->opaque; + + isc_hmacsha224_update(hmacsha224ctx, data->base, data->length); + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha224_sign(dst_context_t *dctx, isc_buffer_t *sig) { + isc_hmacsha224_t *hmacsha224ctx = dctx->opaque; + unsigned char *digest; + + if (isc_buffer_availablelength(sig) < ISC_SHA224_DIGESTLENGTH) + return (ISC_R_NOSPACE); + digest = isc_buffer_used(sig); + isc_hmacsha224_sign(hmacsha224ctx, digest, ISC_SHA224_DIGESTLENGTH); + isc_buffer_add(sig, ISC_SHA224_DIGESTLENGTH); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha224_verify(dst_context_t *dctx, const isc_region_t *sig) { + isc_hmacsha224_t *hmacsha224ctx = dctx->opaque; + + if (sig->length > ISC_SHA224_DIGESTLENGTH || sig->length == 0) + return (DST_R_VERIFYFAILURE); + + if (isc_hmacsha224_verify(hmacsha224ctx, sig->base, sig->length)) + return (ISC_R_SUCCESS); + else + return (DST_R_VERIFYFAILURE); +} + +static isc_boolean_t +hmacsha224_compare(const dst_key_t *key1, const dst_key_t *key2) { + HMACSHA224_Key *hkey1, *hkey2; + + hkey1 = (HMACSHA224_Key *)key1->opaque; + hkey2 = (HMACSHA224_Key *)key2->opaque; + + if (hkey1 == NULL && hkey2 == NULL) + return (ISC_TRUE); + else if (hkey1 == NULL || hkey2 == NULL) + return (ISC_FALSE); + + if (memcmp(hkey1->key, hkey2->key, ISC_SHA224_DIGESTLENGTH) == 0) + return (ISC_TRUE); + else + return (ISC_FALSE); +} + +static isc_result_t +hmacsha224_generate(dst_key_t *key, int pseudorandom_ok) { + isc_buffer_t b; + isc_result_t ret; + int bytes; + unsigned char data[HMAC_LEN]; + + bytes = (key->key_size + 7) / 8; + if (bytes > HMAC_LEN) { + bytes = HMAC_LEN; + key->key_size = HMAC_LEN * 8; + } + + memset(data, 0, HMAC_LEN); + ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); + + if (ret != ISC_R_SUCCESS) + return (ret); + + isc_buffer_init(&b, data, bytes); + isc_buffer_add(&b, bytes); + ret = hmacsha224_fromdns(key, &b); + memset(data, 0, ISC_SHA224_DIGESTLENGTH); + + return (ret); +} + +static isc_boolean_t +hmacsha224_isprivate(const dst_key_t *key) { + UNUSED(key); + return (ISC_TRUE); +} + +static void +hmacsha224_destroy(dst_key_t *key) { + HMACSHA224_Key *hkey = key->opaque; + memset(hkey, 0, sizeof(HMACSHA224_Key)); + isc_mem_put(key->mctx, hkey, sizeof(HMACSHA224_Key)); + key->opaque = NULL; +} + +static isc_result_t +hmacsha224_todns(const dst_key_t *key, isc_buffer_t *data) { + HMACSHA224_Key *hkey; + unsigned int bytes; + + REQUIRE(key->opaque != NULL); + + hkey = (HMACSHA224_Key *) key->opaque; + + bytes = (key->key_size + 7) / 8; + if (isc_buffer_availablelength(data) < bytes) + return (ISC_R_NOSPACE); + isc_buffer_putmem(data, hkey->key, bytes); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha224_fromdns(dst_key_t *key, isc_buffer_t *data) { + HMACSHA224_Key *hkey; + int keylen; + isc_region_t r; + isc_sha224_t sha224ctx; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + hkey = (HMACSHA224_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA224_Key)); + if (hkey == NULL) + return (ISC_R_NOMEMORY); + + memset(hkey->key, 0, sizeof(hkey->key)); + + if (r.length > ISC_SHA224_DIGESTLENGTH) { + isc_sha224_init(&sha224ctx); + isc_sha224_update(&sha224ctx, r.base, r.length); + isc_sha224_final(hkey->key, &sha224ctx); + keylen = ISC_SHA224_DIGESTLENGTH; + } + else { + memcpy(hkey->key, r.base, r.length); + keylen = r.length; + } + + key->key_size = keylen * 8; + key->opaque = hkey; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha224_tofile(const dst_key_t *key, const char *directory) { + int cnt = 0; + HMACSHA224_Key *hkey; + dst_private_t priv; + int bytes = (key->key_size + 7) / 8; + unsigned char buf[2]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + hkey = (HMACSHA224_Key *) key->opaque; + + priv.elements[cnt].tag = TAG_HMACSHA224_KEY; + priv.elements[cnt].length = bytes; + priv.elements[cnt++].data = hkey->key; + + buf[0] = (key->key_bits >> 8) & 0xffU; + buf[1] = key->key_bits & 0xffU; + priv.elements[cnt].tag = TAG_HMACSHA224_BITS; + priv.elements[cnt].data = buf; + priv.elements[cnt++].length = 2; + + priv.nelements = cnt; + return (dst__privstruct_writefile(key, &priv, directory)); +} + +static isc_result_t +hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer) { + dst_private_t priv; + isc_result_t result, tresult; + isc_buffer_t b; + isc_mem_t *mctx = key->mctx; + unsigned int i; + + /* read private key file */ + result = dst__privstruct_parse(key, DST_ALG_HMACSHA224, lexer, mctx, + &priv); + if (result != ISC_R_SUCCESS) + return (result); + + key->key_bits = 0; + for (i = 0; i < priv.nelements; i++) { + switch (priv.elements[i].tag) { + case TAG_HMACSHA224_KEY: + isc_buffer_init(&b, priv.elements[i].data, + priv.elements[i].length); + isc_buffer_add(&b, priv.elements[i].length); + tresult = hmacsha224_fromdns(key, &b); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + case TAG_HMACSHA224_BITS: + tresult = getkeybits(key, &priv.elements[i]); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + default: + result = DST_R_INVALIDPRIVATEKEY; + break; + } + } + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (result); +} + +static dst_func_t hmacsha224_functions = { + hmacsha224_createctx, + hmacsha224_destroyctx, + hmacsha224_adddata, + hmacsha224_sign, + hmacsha224_verify, + NULL, /* computesecret */ + hmacsha224_compare, + NULL, /* paramcompare */ + hmacsha224_generate, + hmacsha224_isprivate, + hmacsha224_destroy, + hmacsha224_todns, + hmacsha224_fromdns, + hmacsha224_tofile, + hmacsha224_parse, + NULL, /* cleanup */ +}; + +isc_result_t +dst__hmacsha224_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + if (*funcp == NULL) + *funcp = &hmacsha224_functions; + return (ISC_R_SUCCESS); +} + +static isc_result_t hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data); + +typedef struct { + unsigned char key[ISC_SHA256_DIGESTLENGTH]; +} HMACSHA256_Key; + +static isc_result_t +hmacsha256_createctx(dst_key_t *key, dst_context_t *dctx) { + isc_hmacsha256_t *hmacsha256ctx; + HMACSHA256_Key *hkey = key->opaque; + + hmacsha256ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha256_t)); + if (hmacsha256ctx == NULL) + return (ISC_R_NOMEMORY); + isc_hmacsha256_init(hmacsha256ctx, hkey->key, ISC_SHA256_DIGESTLENGTH); + dctx->opaque = hmacsha256ctx; + return (ISC_R_SUCCESS); +} + +static void +hmacsha256_destroyctx(dst_context_t *dctx) { + isc_hmacsha256_t *hmacsha256ctx = dctx->opaque; + + if (hmacsha256ctx != NULL) { + isc_hmacsha256_invalidate(hmacsha256ctx); + isc_mem_put(dctx->mctx, hmacsha256ctx, sizeof(isc_hmacsha256_t)); + dctx->opaque = NULL; + } +} + +static isc_result_t +hmacsha256_adddata(dst_context_t *dctx, const isc_region_t *data) { + isc_hmacsha256_t *hmacsha256ctx = dctx->opaque; + + isc_hmacsha256_update(hmacsha256ctx, data->base, data->length); + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha256_sign(dst_context_t *dctx, isc_buffer_t *sig) { + isc_hmacsha256_t *hmacsha256ctx = dctx->opaque; + unsigned char *digest; + + if (isc_buffer_availablelength(sig) < ISC_SHA256_DIGESTLENGTH) + return (ISC_R_NOSPACE); + digest = isc_buffer_used(sig); + isc_hmacsha256_sign(hmacsha256ctx, digest, ISC_SHA256_DIGESTLENGTH); + isc_buffer_add(sig, ISC_SHA256_DIGESTLENGTH); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha256_verify(dst_context_t *dctx, const isc_region_t *sig) { + isc_hmacsha256_t *hmacsha256ctx = dctx->opaque; + + if (sig->length > ISC_SHA256_DIGESTLENGTH || sig->length == 0) + return (DST_R_VERIFYFAILURE); + + if (isc_hmacsha256_verify(hmacsha256ctx, sig->base, sig->length)) + return (ISC_R_SUCCESS); + else + return (DST_R_VERIFYFAILURE); +} + +static isc_boolean_t +hmacsha256_compare(const dst_key_t *key1, const dst_key_t *key2) { + HMACSHA256_Key *hkey1, *hkey2; + + hkey1 = (HMACSHA256_Key *)key1->opaque; + hkey2 = (HMACSHA256_Key *)key2->opaque; + + if (hkey1 == NULL && hkey2 == NULL) + return (ISC_TRUE); + else if (hkey1 == NULL || hkey2 == NULL) + return (ISC_FALSE); + + if (memcmp(hkey1->key, hkey2->key, ISC_SHA256_DIGESTLENGTH) == 0) + return (ISC_TRUE); + else + return (ISC_FALSE); +} + +static isc_result_t +hmacsha256_generate(dst_key_t *key, int pseudorandom_ok) { + isc_buffer_t b; + isc_result_t ret; + int bytes; + unsigned char data[HMAC_LEN]; + + bytes = (key->key_size + 7) / 8; + if (bytes > HMAC_LEN) { + bytes = HMAC_LEN; + key->key_size = HMAC_LEN * 8; + } + + memset(data, 0, HMAC_LEN); + ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); + + if (ret != ISC_R_SUCCESS) + return (ret); + + isc_buffer_init(&b, data, bytes); + isc_buffer_add(&b, bytes); + ret = hmacsha256_fromdns(key, &b); + memset(data, 0, ISC_SHA256_DIGESTLENGTH); + + return (ret); +} + +static isc_boolean_t +hmacsha256_isprivate(const dst_key_t *key) { + UNUSED(key); + return (ISC_TRUE); +} + +static void +hmacsha256_destroy(dst_key_t *key) { + HMACSHA256_Key *hkey = key->opaque; + memset(hkey, 0, sizeof(HMACSHA256_Key)); + isc_mem_put(key->mctx, hkey, sizeof(HMACSHA256_Key)); + key->opaque = NULL; +} + +static isc_result_t +hmacsha256_todns(const dst_key_t *key, isc_buffer_t *data) { + HMACSHA256_Key *hkey; + unsigned int bytes; + + REQUIRE(key->opaque != NULL); + + hkey = (HMACSHA256_Key *) key->opaque; + + bytes = (key->key_size + 7) / 8; + if (isc_buffer_availablelength(data) < bytes) + return (ISC_R_NOSPACE); + isc_buffer_putmem(data, hkey->key, bytes); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha256_fromdns(dst_key_t *key, isc_buffer_t *data) { + HMACSHA256_Key *hkey; + int keylen; + isc_region_t r; + isc_sha256_t sha256ctx; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + hkey = (HMACSHA256_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA256_Key)); + if (hkey == NULL) + return (ISC_R_NOMEMORY); + + memset(hkey->key, 0, sizeof(hkey->key)); + + if (r.length > ISC_SHA256_DIGESTLENGTH) { + isc_sha256_init(&sha256ctx); + isc_sha256_update(&sha256ctx, r.base, r.length); + isc_sha256_final(hkey->key, &sha256ctx); + keylen = ISC_SHA256_DIGESTLENGTH; + } + else { + memcpy(hkey->key, r.base, r.length); + keylen = r.length; + } + + key->key_size = keylen * 8; + key->opaque = hkey; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha256_tofile(const dst_key_t *key, const char *directory) { + int cnt = 0; + HMACSHA256_Key *hkey; + dst_private_t priv; + int bytes = (key->key_size + 7) / 8; + unsigned char buf[2]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + hkey = (HMACSHA256_Key *) key->opaque; + + priv.elements[cnt].tag = TAG_HMACSHA256_KEY; + priv.elements[cnt].length = bytes; + priv.elements[cnt++].data = hkey->key; + + buf[0] = (key->key_bits >> 8) & 0xffU; + buf[1] = key->key_bits & 0xffU; + priv.elements[cnt].tag = TAG_HMACSHA256_BITS; + priv.elements[cnt].data = buf; + priv.elements[cnt++].length = 2; + + priv.nelements = cnt; + return (dst__privstruct_writefile(key, &priv, directory)); +} + +static isc_result_t +hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer) { + dst_private_t priv; + isc_result_t result, tresult; + isc_buffer_t b; + isc_mem_t *mctx = key->mctx; + unsigned int i; + + /* read private key file */ + result = dst__privstruct_parse(key, DST_ALG_HMACSHA256, lexer, mctx, + &priv); + if (result != ISC_R_SUCCESS) + return (result); + + key->key_bits = 0; + for (i = 0; i < priv.nelements; i++) { + switch (priv.elements[i].tag) { + case TAG_HMACSHA256_KEY: + isc_buffer_init(&b, priv.elements[i].data, + priv.elements[i].length); + isc_buffer_add(&b, priv.elements[i].length); + tresult = hmacsha256_fromdns(key, &b); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + case TAG_HMACSHA256_BITS: + tresult = getkeybits(key, &priv.elements[i]); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + default: + result = DST_R_INVALIDPRIVATEKEY; + break; + } + } + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (result); +} + +static dst_func_t hmacsha256_functions = { + hmacsha256_createctx, + hmacsha256_destroyctx, + hmacsha256_adddata, + hmacsha256_sign, + hmacsha256_verify, + NULL, /* computesecret */ + hmacsha256_compare, + NULL, /* paramcompare */ + hmacsha256_generate, + hmacsha256_isprivate, + hmacsha256_destroy, + hmacsha256_todns, + hmacsha256_fromdns, + hmacsha256_tofile, + hmacsha256_parse, + NULL, /* cleanup */ +}; + +isc_result_t +dst__hmacsha256_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + if (*funcp == NULL) + *funcp = &hmacsha256_functions; + return (ISC_R_SUCCESS); +} + +static isc_result_t hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data); + +typedef struct { + unsigned char key[ISC_SHA384_DIGESTLENGTH]; +} HMACSHA384_Key; + +static isc_result_t +hmacsha384_createctx(dst_key_t *key, dst_context_t *dctx) { + isc_hmacsha384_t *hmacsha384ctx; + HMACSHA384_Key *hkey = key->opaque; + + hmacsha384ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha384_t)); + if (hmacsha384ctx == NULL) + return (ISC_R_NOMEMORY); + isc_hmacsha384_init(hmacsha384ctx, hkey->key, ISC_SHA384_DIGESTLENGTH); + dctx->opaque = hmacsha384ctx; + return (ISC_R_SUCCESS); +} + +static void +hmacsha384_destroyctx(dst_context_t *dctx) { + isc_hmacsha384_t *hmacsha384ctx = dctx->opaque; + + if (hmacsha384ctx != NULL) { + isc_hmacsha384_invalidate(hmacsha384ctx); + isc_mem_put(dctx->mctx, hmacsha384ctx, sizeof(isc_hmacsha384_t)); + dctx->opaque = NULL; + } +} + +static isc_result_t +hmacsha384_adddata(dst_context_t *dctx, const isc_region_t *data) { + isc_hmacsha384_t *hmacsha384ctx = dctx->opaque; + + isc_hmacsha384_update(hmacsha384ctx, data->base, data->length); + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha384_sign(dst_context_t *dctx, isc_buffer_t *sig) { + isc_hmacsha384_t *hmacsha384ctx = dctx->opaque; + unsigned char *digest; + + if (isc_buffer_availablelength(sig) < ISC_SHA384_DIGESTLENGTH) + return (ISC_R_NOSPACE); + digest = isc_buffer_used(sig); + isc_hmacsha384_sign(hmacsha384ctx, digest, ISC_SHA384_DIGESTLENGTH); + isc_buffer_add(sig, ISC_SHA384_DIGESTLENGTH); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha384_verify(dst_context_t *dctx, const isc_region_t *sig) { + isc_hmacsha384_t *hmacsha384ctx = dctx->opaque; + + if (sig->length > ISC_SHA384_DIGESTLENGTH || sig->length == 0) + return (DST_R_VERIFYFAILURE); + + if (isc_hmacsha384_verify(hmacsha384ctx, sig->base, sig->length)) + return (ISC_R_SUCCESS); + else + return (DST_R_VERIFYFAILURE); +} + +static isc_boolean_t +hmacsha384_compare(const dst_key_t *key1, const dst_key_t *key2) { + HMACSHA384_Key *hkey1, *hkey2; + + hkey1 = (HMACSHA384_Key *)key1->opaque; + hkey2 = (HMACSHA384_Key *)key2->opaque; + + if (hkey1 == NULL && hkey2 == NULL) + return (ISC_TRUE); + else if (hkey1 == NULL || hkey2 == NULL) + return (ISC_FALSE); + + if (memcmp(hkey1->key, hkey2->key, ISC_SHA384_DIGESTLENGTH) == 0) + return (ISC_TRUE); + else + return (ISC_FALSE); +} + +static isc_result_t +hmacsha384_generate(dst_key_t *key, int pseudorandom_ok) { + isc_buffer_t b; + isc_result_t ret; + int bytes; + unsigned char data[HMAC_LEN]; + + bytes = (key->key_size + 7) / 8; + if (bytes > HMAC_LEN) { + bytes = HMAC_LEN; + key->key_size = HMAC_LEN * 8; + } + + memset(data, 0, HMAC_LEN); + ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); + + if (ret != ISC_R_SUCCESS) + return (ret); + + isc_buffer_init(&b, data, bytes); + isc_buffer_add(&b, bytes); + ret = hmacsha384_fromdns(key, &b); + memset(data, 0, ISC_SHA384_DIGESTLENGTH); + + return (ret); +} + +static isc_boolean_t +hmacsha384_isprivate(const dst_key_t *key) { + UNUSED(key); + return (ISC_TRUE); +} + +static void +hmacsha384_destroy(dst_key_t *key) { + HMACSHA384_Key *hkey = key->opaque; + memset(hkey, 0, sizeof(HMACSHA384_Key)); + isc_mem_put(key->mctx, hkey, sizeof(HMACSHA384_Key)); + key->opaque = NULL; +} + +static isc_result_t +hmacsha384_todns(const dst_key_t *key, isc_buffer_t *data) { + HMACSHA384_Key *hkey; + unsigned int bytes; + + REQUIRE(key->opaque != NULL); + + hkey = (HMACSHA384_Key *) key->opaque; + + bytes = (key->key_size + 7) / 8; + if (isc_buffer_availablelength(data) < bytes) + return (ISC_R_NOSPACE); + isc_buffer_putmem(data, hkey->key, bytes); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha384_fromdns(dst_key_t *key, isc_buffer_t *data) { + HMACSHA384_Key *hkey; + int keylen; + isc_region_t r; + isc_sha384_t sha384ctx; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + hkey = (HMACSHA384_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA384_Key)); + if (hkey == NULL) + return (ISC_R_NOMEMORY); + + memset(hkey->key, 0, sizeof(hkey->key)); + + if (r.length > ISC_SHA384_DIGESTLENGTH) { + isc_sha384_init(&sha384ctx); + isc_sha384_update(&sha384ctx, r.base, r.length); + isc_sha384_final(hkey->key, &sha384ctx); + keylen = ISC_SHA384_DIGESTLENGTH; + } + else { + memcpy(hkey->key, r.base, r.length); + keylen = r.length; + } + + key->key_size = keylen * 8; + key->opaque = hkey; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha384_tofile(const dst_key_t *key, const char *directory) { + int cnt = 0; + HMACSHA384_Key *hkey; + dst_private_t priv; + int bytes = (key->key_size + 7) / 8; + unsigned char buf[2]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + hkey = (HMACSHA384_Key *) key->opaque; + + priv.elements[cnt].tag = TAG_HMACSHA384_KEY; + priv.elements[cnt].length = bytes; + priv.elements[cnt++].data = hkey->key; + + buf[0] = (key->key_bits >> 8) & 0xffU; + buf[1] = key->key_bits & 0xffU; + priv.elements[cnt].tag = TAG_HMACSHA384_BITS; + priv.elements[cnt].data = buf; + priv.elements[cnt++].length = 2; + + priv.nelements = cnt; + return (dst__privstruct_writefile(key, &priv, directory)); +} + +static isc_result_t +hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer) { + dst_private_t priv; + isc_result_t result, tresult; + isc_buffer_t b; + isc_mem_t *mctx = key->mctx; + unsigned int i; + + /* read private key file */ + result = dst__privstruct_parse(key, DST_ALG_HMACSHA384, lexer, mctx, + &priv); + if (result != ISC_R_SUCCESS) + return (result); + + key->key_bits = 0; + for (i = 0; i < priv.nelements; i++) { + switch (priv.elements[i].tag) { + case TAG_HMACSHA384_KEY: + isc_buffer_init(&b, priv.elements[i].data, + priv.elements[i].length); + isc_buffer_add(&b, priv.elements[i].length); + tresult = hmacsha384_fromdns(key, &b); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + case TAG_HMACSHA384_BITS: + tresult = getkeybits(key, &priv.elements[i]); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + default: + result = DST_R_INVALIDPRIVATEKEY; + break; + } + } + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (result); +} + +static dst_func_t hmacsha384_functions = { + hmacsha384_createctx, + hmacsha384_destroyctx, + hmacsha384_adddata, + hmacsha384_sign, + hmacsha384_verify, + NULL, /* computesecret */ + hmacsha384_compare, + NULL, /* paramcompare */ + hmacsha384_generate, + hmacsha384_isprivate, + hmacsha384_destroy, + hmacsha384_todns, + hmacsha384_fromdns, + hmacsha384_tofile, + hmacsha384_parse, + NULL, /* cleanup */ +}; + +isc_result_t +dst__hmacsha384_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + if (*funcp == NULL) + *funcp = &hmacsha384_functions; + return (ISC_R_SUCCESS); +} + +static isc_result_t hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data); + +typedef struct { + unsigned char key[ISC_SHA512_DIGESTLENGTH]; +} HMACSHA512_Key; + +static isc_result_t +hmacsha512_createctx(dst_key_t *key, dst_context_t *dctx) { + isc_hmacsha512_t *hmacsha512ctx; + HMACSHA512_Key *hkey = key->opaque; + + hmacsha512ctx = isc_mem_get(dctx->mctx, sizeof(isc_hmacsha512_t)); + if (hmacsha512ctx == NULL) + return (ISC_R_NOMEMORY); + isc_hmacsha512_init(hmacsha512ctx, hkey->key, ISC_SHA512_DIGESTLENGTH); + dctx->opaque = hmacsha512ctx; + return (ISC_R_SUCCESS); +} + +static void +hmacsha512_destroyctx(dst_context_t *dctx) { + isc_hmacsha512_t *hmacsha512ctx = dctx->opaque; + + if (hmacsha512ctx != NULL) { + isc_hmacsha512_invalidate(hmacsha512ctx); + isc_mem_put(dctx->mctx, hmacsha512ctx, sizeof(isc_hmacsha512_t)); + dctx->opaque = NULL; + } +} + +static isc_result_t +hmacsha512_adddata(dst_context_t *dctx, const isc_region_t *data) { + isc_hmacsha512_t *hmacsha512ctx = dctx->opaque; + + isc_hmacsha512_update(hmacsha512ctx, data->base, data->length); + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha512_sign(dst_context_t *dctx, isc_buffer_t *sig) { + isc_hmacsha512_t *hmacsha512ctx = dctx->opaque; + unsigned char *digest; + + if (isc_buffer_availablelength(sig) < ISC_SHA512_DIGESTLENGTH) + return (ISC_R_NOSPACE); + digest = isc_buffer_used(sig); + isc_hmacsha512_sign(hmacsha512ctx, digest, ISC_SHA512_DIGESTLENGTH); + isc_buffer_add(sig, ISC_SHA512_DIGESTLENGTH); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha512_verify(dst_context_t *dctx, const isc_region_t *sig) { + isc_hmacsha512_t *hmacsha512ctx = dctx->opaque; + + if (sig->length > ISC_SHA512_DIGESTLENGTH || sig->length == 0) + return (DST_R_VERIFYFAILURE); + + if (isc_hmacsha512_verify(hmacsha512ctx, sig->base, sig->length)) + return (ISC_R_SUCCESS); + else + return (DST_R_VERIFYFAILURE); +} + +static isc_boolean_t +hmacsha512_compare(const dst_key_t *key1, const dst_key_t *key2) { + HMACSHA512_Key *hkey1, *hkey2; + + hkey1 = (HMACSHA512_Key *)key1->opaque; + hkey2 = (HMACSHA512_Key *)key2->opaque; + + if (hkey1 == NULL && hkey2 == NULL) + return (ISC_TRUE); + else if (hkey1 == NULL || hkey2 == NULL) + return (ISC_FALSE); + + if (memcmp(hkey1->key, hkey2->key, ISC_SHA512_DIGESTLENGTH) == 0) + return (ISC_TRUE); + else + return (ISC_FALSE); +} + +static isc_result_t +hmacsha512_generate(dst_key_t *key, int pseudorandom_ok) { + isc_buffer_t b; + isc_result_t ret; + int bytes; + unsigned char data[HMAC_LEN]; + + bytes = (key->key_size + 7) / 8; + if (bytes > HMAC_LEN) { + bytes = HMAC_LEN; + key->key_size = HMAC_LEN * 8; + } + + memset(data, 0, HMAC_LEN); + ret = dst__entropy_getdata(data, bytes, ISC_TF(pseudorandom_ok != 0)); + + if (ret != ISC_R_SUCCESS) + return (ret); + + isc_buffer_init(&b, data, bytes); + isc_buffer_add(&b, bytes); + ret = hmacsha512_fromdns(key, &b); + memset(data, 0, ISC_SHA512_DIGESTLENGTH); + + return (ret); +} + +static isc_boolean_t +hmacsha512_isprivate(const dst_key_t *key) { + UNUSED(key); + return (ISC_TRUE); +} + +static void +hmacsha512_destroy(dst_key_t *key) { + HMACSHA512_Key *hkey = key->opaque; + memset(hkey, 0, sizeof(HMACSHA512_Key)); + isc_mem_put(key->mctx, hkey, sizeof(HMACSHA512_Key)); + key->opaque = NULL; +} + +static isc_result_t +hmacsha512_todns(const dst_key_t *key, isc_buffer_t *data) { + HMACSHA512_Key *hkey; + unsigned int bytes; + + REQUIRE(key->opaque != NULL); + + hkey = (HMACSHA512_Key *) key->opaque; + + bytes = (key->key_size + 7) / 8; + if (isc_buffer_availablelength(data) < bytes) + return (ISC_R_NOSPACE); + isc_buffer_putmem(data, hkey->key, bytes); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha512_fromdns(dst_key_t *key, isc_buffer_t *data) { + HMACSHA512_Key *hkey; + int keylen; + isc_region_t r; + isc_sha512_t sha512ctx; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + hkey = (HMACSHA512_Key *) isc_mem_get(key->mctx, sizeof(HMACSHA512_Key)); + if (hkey == NULL) + return (ISC_R_NOMEMORY); + + memset(hkey->key, 0, sizeof(hkey->key)); + + if (r.length > ISC_SHA512_DIGESTLENGTH) { + isc_sha512_init(&sha512ctx); + isc_sha512_update(&sha512ctx, r.base, r.length); + isc_sha512_final(hkey->key, &sha512ctx); + keylen = ISC_SHA512_DIGESTLENGTH; + } + else { + memcpy(hkey->key, r.base, r.length); + keylen = r.length; + } + + key->key_size = keylen * 8; + key->opaque = hkey; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +hmacsha512_tofile(const dst_key_t *key, const char *directory) { + int cnt = 0; + HMACSHA512_Key *hkey; + dst_private_t priv; + int bytes = (key->key_size + 7) / 8; + unsigned char buf[2]; + + if (key->opaque == NULL) + return (DST_R_NULLKEY); + + hkey = (HMACSHA512_Key *) key->opaque; + + priv.elements[cnt].tag = TAG_HMACSHA512_KEY; + priv.elements[cnt].length = bytes; + priv.elements[cnt++].data = hkey->key; + + buf[0] = (key->key_bits >> 8) & 0xffU; + buf[1] = key->key_bits & 0xffU; + priv.elements[cnt].tag = TAG_HMACSHA512_BITS; + priv.elements[cnt].data = buf; + priv.elements[cnt++].length = 2; + + priv.nelements = cnt; + return (dst__privstruct_writefile(key, &priv, directory)); +} + +static isc_result_t +hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer) { + dst_private_t priv; + isc_result_t result, tresult; + isc_buffer_t b; + isc_mem_t *mctx = key->mctx; + unsigned int i; + + /* read private key file */ + result = dst__privstruct_parse(key, DST_ALG_HMACSHA512, lexer, mctx, + &priv); + if (result != ISC_R_SUCCESS) + return (result); + + key->key_bits = 0; + for (i = 0; i < priv.nelements; i++) { + switch (priv.elements[i].tag) { + case TAG_HMACSHA512_KEY: + isc_buffer_init(&b, priv.elements[i].data, + priv.elements[i].length); + isc_buffer_add(&b, priv.elements[i].length); + tresult = hmacsha512_fromdns(key, &b); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + case TAG_HMACSHA512_BITS: + tresult = getkeybits(key, &priv.elements[i]); + if (tresult != ISC_R_SUCCESS) + result = tresult; + break; + default: + result = DST_R_INVALIDPRIVATEKEY; + break; + } + } + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (result); +} + +static dst_func_t hmacsha512_functions = { + hmacsha512_createctx, + hmacsha512_destroyctx, + hmacsha512_adddata, + hmacsha512_sign, + hmacsha512_verify, + NULL, /* computesecret */ + hmacsha512_compare, + NULL, /* paramcompare */ + hmacsha512_generate, + hmacsha512_isprivate, + hmacsha512_destroy, + hmacsha512_todns, + hmacsha512_fromdns, + hmacsha512_tofile, + hmacsha512_parse, + NULL, /* cleanup */ +}; + +isc_result_t +dst__hmacsha512_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + if (*funcp == NULL) + *funcp = &hmacsha512_functions; + return (ISC_R_SUCCESS); +} + +/*! \file */ diff --git a/contrib/bind9/lib/dns/include/Makefile.in b/contrib/bind9/lib/dns/include/Makefile.in index 92dfb3b..593ad5a 100644 --- a/contrib/bind9/lib/dns/include/Makefile.in +++ b/contrib/bind9/lib/dns/include/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.11.206.2 2004/12/09 04:07:19 marka Exp $ +# $Id: Makefile.in,v 1.12.18.1 2004/12/09 04:41:46 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ diff --git a/contrib/bind9/lib/dns/include/dns/Makefile.in b/contrib/bind9/lib/dns/include/dns/Makefile.in index 267bc8d..3f367bc 100644 --- a/contrib/bind9/lib/dns/include/dns/Makefile.in +++ b/contrib/bind9/lib/dns/include/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.43.2.1.10.6 2004/03/08 09:04:34 marka Exp $ +# $Id: Makefile.in,v 1.50 2004/03/05 05:09:40 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ diff --git a/contrib/bind9/lib/dns/include/dns/acache.h b/contrib/bind9/lib/dns/include/dns/acache.h new file mode 100644 index 0000000..50d7fc1 --- /dev/null +++ b/contrib/bind9/lib/dns/include/dns/acache.h @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: acache.h,v 1.3.2.4 2006/05/03 00:07:49 marka Exp $ */ + +#ifndef DNS_ACACHE_H +#define DNS_ACACHE_H 1 + +/***** + ***** Module Info + *****/ + +/* + * Acache + * + * The Additional Cache Object + * + * This module manages internal caching entries that correspond to + * the additional section data of a DNS DB node (an RRset header, more + * accurately). An additional cache entry is expected to be (somehow) + * attached to a particular RR in a particular DB node, and contains a set + * of information of an additional data for the DB node. + * + * An additional cache object is intended to be created as a per-view + * object, and manages all cache entries within the view. + * + * The intended usage of the additional caching is to provide a short cut + * to additional glue RRs of an NS RR. For each NS RR, it is often + * necessary to look for glue RRs to make a proper response. Once the + * glue RRs are known, the additional caching allows the client to + * associate the information to the original NS RR so that further + * expensive lookups can be avoided for the NS RR. + * + * Each additional cache entry contains information to identify a + * particular DB node and (optionally) an associated RRset. The + * information consists of its zone, database, the version of the + * database, database node, and RRset. + * + * A "negative" information can also be cached. For example, if a glue + * RR does not exist as an authoritative data in the same zone as that + * of the NS RR, this fact can be cached by specifying a NULL pointer + * for the database, version, and node. (See the description for + * dns_acache_getentry() below for more details.) + * + * Since each member stored in an additional cache entry holds a reference + * to a corresponding object, a stale cache entry may cause unnecessary + * memory consumption. For instance, when a zone is reloaded, additional + * cache entries that have a reference to the zone (and its DB and/or + * DB nodes) can delay the cleanup of the referred objects. In order to + * minimize such a bad effect, this module provides several cleanup + * mechanisms. + * + * The first one is a shutdown procedure called when the associated view + * is shut down. In this case, dns_acache_shutdown() will be called and + * all cache entries will be purged. This mechanism will help the + * situation when the configuration is reloaded or the main server is + * stopped. + * + * Per-DB cleanup mechanism is also provided. Each additional cache entry + * is associated with related DB, which is expected to have been + * registered when the DB was created by dns_acache_setdb(). If a + * particular DB is going to be destroyed, the primary holder of the DB, + * a typical example of which is a zone, will call dns_acache_putdb(). + * Then this module will clean-up all cache entries associated with the + * DB. This mechanism is effective when a secondary zone DB is going to + * be stale after a zone transfer. + * + * Finally, this module supports for periodic clean-up of stale entries. + * Each cache entry has a timestamp field, which is updated every time + * the entry is referred. A periodically invoked cleaner checks the + * timestamp of each entry, and purge entries that have not been referred + * for a certain period. The cleaner interval can be specified by + * dns_acache_setcleaninginterval(). If the periodic clean-up is not + * enough, it is also possible to specify the upper limit of entries + * in terms of the memory consumption. If the maximum value is + * specified, the cleaner is invoked when the memory consumption reaches + * the high watermark inferred from the maximum value. In this case, + * the cleaner will use more aggressive algorithm to decide the "victim" + * entries. The maximum value can be specified by + * dns_acache_setcachesize(). + * + * When a cache entry is going to be purged within this module, the + * callback function specified at the creation time will be called. + * The callback function is expected to release all internal resources + * related to the entry, which will typically be specific to DB + * implementation, and to call dns_acache_detachentry(). The callback + * mechanism is very important, since the holder of an additional cache + * entry may not be able to initiate the clean-up of the entry, due to + * the reference ordering. For example, as long as an additional cache + * entry has a reference to a DB object, the DB cannot be freed, in which + * a DB node may have a reference to the cache entry. + * + * Credits: + * The basic idea of this kind of short-cut for frequently used + * information is similar to the "pre-compiled answer" approach adopted + * in nsd by NLnet LABS with RIPE NCC. Our work here is an independent + * effort, but the success of nsd encouraged us to pursue this path. + * + * The design and implementation of the periodic memory management and + * the upper limitation of memory consumption was derived from the cache + * DB implementation of BIND9. + * + * MP: + * There are two main locks in this module. One is for each entry, and + * the other is for the additional cache object. + * + * Reliability: + * The callback function for a cache entry is called with holding the + * entry lock. Thus, it implicitly assumes the callback function does not + * call a function that can require the lock. Typically, the only + * function that can be called from the callback function safely is + * dns_acache_detachentry(). The breakage of this implicit assumption + * may cause a deadlock. + * + * Resources: + * In a 32-bit architecture (such as i386), the following additional + * memory is required comparing to the case that disables this module. + * - 76 bytes for each additional cache entry + * - if the entry has a DNS name and associated RRset, + * * 44 bytes + size of the name (1-255 bytes) + * * 52 bytes x number_of_RRs + * - 28 bytes for each DB related to this module + * + * Using the additional cache also requires extra memory consumption in + * the DB implementation. In the current implementation for rbtdb, we + * need: + * - two additional pointers for each DB node (8 bytes for a 32-bit + * architecture + * - for each RR associated to an RR in a DB node, we also need + * a pointer and management objects to support the additional cache + * function. These are allocated on-demand. The total size is + * 32 bytes for a 32-bit architecture. + * + * Security: + * Since this module does not handle any low-level data directly, + * no security issue specific to this module is anticipated. + * + * Standards: + * None. + */ + +/*** + *** Imports + ***/ + +#include <isc/mutex.h> +#include <isc/lang.h> +#include <isc/refcount.h> +#include <isc/stdtime.h> + +#include <dns/types.h> + +/*** + *** Functions + ***/ +ISC_LANG_BEGINDECLS + +isc_result_t +dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx, + isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr); +/* + * Create a new DNS additional cache object. + * + * Requires: + * + * 'mctx' is a valid memory context + * + * 'taskmgr' is a valid task manager + * + * 'timermgr' is a valid timer or NULL. If NULL, no periodic cleaning of + * the cache will take place. + * + * 'acachep' is a valid pointer, and *acachep == NULL + * + * Ensures: + * + * '*acachep' is attached to the newly created cache + * + * Returns: + * + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + * ISC_R_UNEXPECTED + */ + +void +dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp); +/* + * Attach *targetp to cache. + * + * Requires: + * + * 'acache' is a valid additional cache. + * + * 'targetp' points to a NULL dns_acache_t *. + * + * Ensures: + * + * *targetp is attached to the 'source' additional cache. + */ + +void +dns_acache_detach(dns_acache_t **acachep); +/* + * Detach *acachep from its cache. + * + * Requires: + * + * '*acachep' points to a valid additional cache. + * + * Ensures: + * + * *acachep is NULL. + * + * If '*acachep' is the last reference to the cache and the additional + * cache does not have an outstanding task, all resources used by the + * cache will be freed. + */ + +void +dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t); +/* + * Set the periodic cleaning interval of an additional cache to 'interval' + * seconds. + */ + +void +dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size); +/* + * Set the maximum additional cache size. 0 means unlimited. + */ + +isc_result_t +dns_acache_setdb(dns_acache_t *acache, dns_db_t *db); +/* + * Set 'db' in 'acache' when the db can be referred from acache, in order + * to provide a hint for resolving the back reference. + * + * Requires: + * 'acache' is a valid acache pointer. + * 'db' is a valid DNS DB pointer. + * + * Ensures: + * 'acache' will have a reference to 'db'. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_EXISTS (which means the specified 'db' is already set) + * ISC_R_NOMEMORY + */ + +isc_result_t +dns_acache_putdb(dns_acache_t *acache, dns_db_t *db); +/* + * Release 'db' from 'acache' if it has been set by dns_acache_setdb(). + * + * Requires: + * 'acache' is a valid acache pointer. + * 'db' is a valid DNS DB pointer. + * + * Ensures: + * 'acache' will release the reference to 'db'. Additionally, the content + * of each cache entry that is related to the 'db' will be released via + * the callback function. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOTFOUND (which means the specified 'db' is not set in 'acache') + * ISC_R_NOMEMORY + */ + +void +dns_acache_shutdown(dns_acache_t *acache); +/* + * Shutdown 'acache'. + * + * Requires: + * + * '*acache' is a valid additional cache. + */ + +isc_result_t +dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb, + void (*callback)(dns_acacheentry_t *, void **), + void *cbarg, dns_acacheentry_t **entryp); +/* + * Create an additional cache entry. A new entry is created and attached to + * the given additional cache object. A callback function is also associated + * with the created entry, which will be called when the cache entry is purged + * for some reason. + * + * Requires: + * + * 'acache' is a valid additional cache. + * 'entryp' is a valid pointer, and *entryp == NULL + * 'origdb' is a valid DNS DB pointer. + * 'callback' and 'cbarg' can be NULL. In this case, however, the entry + * is meaningless (and will be cleaned-up in the next periodical + * cleaning). + * + * Ensures: + * '*entryp' will point to a new additional cache entry. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +isc_result_t +dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep, + dns_db_t **dbp, dns_dbversion_t **versionp, + dns_dbnode_t **nodep, dns_name_t *fname, + dns_message_t *msg, isc_stdtime_t now); +/* + * Get content from a particular additional cache entry. + * + * Requires: + * + * 'entry' is a valid additional cache entry. + * 'zonep' is a NULL pointer or '*zonep' == NULL (this is the only + * optional parameter.) + * 'dbp' is a valid pointer, and '*dbp' == NULL + * 'versionp' is a valid pointer, and '*versionp' == NULL + * 'nodep' is a valid pointer, and '*nodep' == NULL + * 'fname' is a valid DNS name. + * 'msg' is a valid DNS message. + * + * Ensures: + * Several possible cases can happen according to the content. + * 1. For a positive cache entry, + * '*zonep' will point to the corresponding zone (if zonep is a valid + * pointer), + * '*dbp' will point to a DB for the zone, + * '*versionp' will point to its version, and + * '*nodep' will point to the corresponding DB node. + * 'fname' will have the DNS name of the DB node and contain a list of + * rdataset for the node (which can be an empty list). + * + * 2. For a negative cache entry that means no corresponding zone exists, + * '*zonep' == NULL (if zonep is a valid pointer) + * '*dbp', '*versionp', and '*nodep' will be NULL. + * + * 3. For a negative cache entry that means no corresponding DB node + * exists, '*zonep' will point to the corresponding zone (if zonep is a + * valid pointer), + * '*dbp' will point to a corresponding DB for zone, + * '*versionp' will point to its version. + * '*nodep' will be kept as NULL. + * 'fname' will not change. + * + * On failure, no new references will be created. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + */ + +isc_result_t +dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry, + dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version, + dns_dbnode_t *node, dns_name_t *fname); +/* + * Set content to a particular additional cache entry. + * + * Requires: + * 'acache' is a valid additional cache. + * 'entry' is a valid additional cache entry. + * All the others pointers are NULL or a valid pointer of the + * corresponding type. + * + * Returns: + * ISC_R_SUCCESS + * ISC_R_NOMEMORY + * ISC_R_NOTFOUND + */ + +void +dns_acache_cancelentry(dns_acacheentry_t *entry); +/* + * Cancel the use of the cache entry 'entry'. This function is supposed to + * be called when the node that holds the entry finds the content is not + * correct any more. This function will try to release as much dependency as + * possible, and will be ready to be cleaned-up. The registered callback + * function will be canceled and will never called. + * + * Requires: + * 'entry' is a valid additional cache entry. + */ + +void +dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp); +/* + * Attach *targetp to the cache entry 'source'. + * + * Requires: + * + * 'source' is a valid additional cache entry. + * + * 'targetp' points to a NULL dns_acacheentry_t *. + * + * Ensures: + * + * *targetp is attached to 'source'. + */ + +void +dns_acache_detachentry(dns_acacheentry_t **entryp); +/* + * Detach *entryp from its cache. + * + * Requires: + * + * '*entryp' points to a valid additional cache entry. + * + * Ensures: + * + * *entryp is NULL. + * + * If '*entryp' is the last reference to the entry, + * cache does not have an outstanding task, all resources used by the + * entry (including the entry object itself) will be freed. + */ + +void +dns_acache_countquerymiss(dns_acache_t *acache); +/* + * Count up a missed acache query. XXXMLG need more docs. + */ + +ISC_LANG_ENDDECLS + +#endif /* DNS_ACACHE_H */ diff --git a/contrib/bind9/lib/dns/include/dns/acl.h b/contrib/bind9/lib/dns/include/dns/acl.h index ce4c8b6..34e394f 100644 --- a/contrib/bind9/lib/dns/include/dns/acl.h +++ b/contrib/bind9/lib/dns/include/dns/acl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acl.h,v 1.20.52.5 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: acl.h,v 1.22.18.4 2006/03/02 00:37:21 marka Exp $ */ #ifndef DNS_ACL_H #define DNS_ACL_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * Address match list handling. */ @@ -75,10 +76,10 @@ struct dns_acl { isc_mem_t *mctx; isc_refcount_t refcount; dns_aclelement_t *elements; - unsigned int alloc; /* Elements allocated */ - unsigned int length; /* Elements initialized */ - char *name; /* Temporary use only */ - ISC_LINK(dns_acl_t) nextincache; /* Ditto */ + unsigned int alloc; /*%< Elements allocated */ + unsigned int length; /*%< Elements initialized */ + char *name; /*%< Temporary use only */ + ISC_LINK(dns_acl_t) nextincache; /*%< Ditto */ }; struct dns_aclenv { @@ -98,26 +99,26 @@ ISC_LANG_BEGINDECLS isc_result_t dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target); -/* +/*%< * Create a new ACL with room for 'n' elements. * The elements are uninitialized and the length is 0. */ isc_result_t dns_acl_appendelement(dns_acl_t *acl, const dns_aclelement_t *elt); -/* +/*%< * Append an element to an existing ACL. */ isc_result_t dns_acl_any(isc_mem_t *mctx, dns_acl_t **target); -/* +/*%< * Create a new ACL that matches everything. */ isc_result_t dns_acl_none(isc_mem_t *mctx, dns_acl_t **target); -/* +/*%< * Create a new ACL that matches nothing. */ @@ -135,13 +136,13 @@ dns_acl_equal(const dns_acl_t *a, const dns_acl_t *b); isc_boolean_t dns_acl_isinsecure(const dns_acl_t *a); -/* - * Return ISC_TRUE iff the acl 'a' is considered insecure, that is, +/*%< + * Return #ISC_TRUE iff the acl 'a' is considered insecure, that is, * if it contains IP addresses other than those of the local host. * This is intended for applications such as printing warning * messages for suspect ACLs; it is not intended for making access * control decisions. We make no guarantee that an ACL for which - * this function returns ISC_FALSE is safe. + * this function returns #ISC_FALSE is safe. */ isc_result_t @@ -160,7 +161,7 @@ dns_acl_match(const isc_netaddr_t *reqaddr, const dns_aclenv_t *env, int *match, const dns_aclelement_t **matchelt); -/* +/*%< * General, low-level ACL matching. This is expected to * be useful even for weird stuff like the topology and sortlist statements. * @@ -181,7 +182,7 @@ dns_acl_match(const isc_netaddr_t *reqaddr, * If there is no match, *match will be set to zero. * * Returns: - * ISC_R_SUCCESS Always succeeds. + *\li #ISC_R_SUCCESS Always succeeds. */ isc_boolean_t @@ -190,7 +191,7 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr, const dns_aclelement_t *e, const dns_aclenv_t *env, const dns_aclelement_t **matchelt); -/* +/*%< * Like dns_acl_match, but matches against the single ACL element 'e' * rather than a complete list and returns ISC_TRUE iff it matched. * To determine whether the match was prositive or negative, the @@ -203,7 +204,7 @@ isc_result_t dns_acl_elementmatch(const dns_acl_t *acl, const dns_aclelement_t *elt, const dns_aclelement_t **matchelt); -/* +/*%< * Search for an ACL element in 'acl' which is exactly the same as 'elt'. * If there is one, and 'matchelt' is non NULL, then '*matchelt' will point * to the entry. @@ -212,8 +213,8 @@ dns_acl_elementmatch(const dns_acl_t *acl, * before adding an entry. * * Returns: - * ISC_R_SUCCESS Match succeeds. - * ISC_R_NOTFOUND Match fails. + *\li #ISC_R_SUCCESS Match succeeds. + *\li #ISC_R_NOTFOUND Match fails. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/adb.h b/contrib/bind9/lib/dns/include/dns/adb.h index 7a17eff..1e3cd61 100644 --- a/contrib/bind9/lib/dns/include/dns/adb.h +++ b/contrib/bind9/lib/dns/include/dns/adb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: adb.h,v 1.66.2.5.2.4 2004/03/06 08:13:50 marka Exp $ */ +/* $Id: adb.h,v 1.76.18.3 2005/06/23 04:23:16 marka Exp $ */ #ifndef DNS_ADB_H #define DNS_ADB_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + *\brief * DNS Address Database * * This module implements an address database (ADB) for mapping a name @@ -49,21 +50,21 @@ * Records are stored internally until a timer expires. The timer is the * smaller of the TTL or signature validity period. * - * Lameness is stored per-zone, and this data hangs off each address field. - * When an address is marked lame for a given zone the address will not - * be returned to a caller. + * Lameness is stored per <qname,qtype> tuple, and this data hangs off each + * address field. When an address is marked lame for a given tuple the address + * will not be returned to a caller. * * * MP: * - * The ADB takes care of all necessary locking. + *\li The ADB takes care of all necessary locking. * - * Only the task which initiated the name lookup can cancel the lookup. + *\li Only the task which initiated the name lookup can cancel the lookup. * * * Security: * - * None, since all data stored is required to be pre-filtered. + *\li None, since all data stored is required to be pre-filtered. * (Cache needs to be sane, fetches return bounds-checked and sanity- * checked data, caller passes a good dns_name_t for the zone, etc) */ @@ -98,8 +99,8 @@ ISC_LANG_BEGINDECLS typedef struct dns_adbname dns_adbname_t; -/* dns_adbfind_t - * +/*! + *\brief * Represents a lookup for a single name. * * On return, the client can safely use "list", and can reorder the list. @@ -108,14 +109,14 @@ typedef struct dns_adbname dns_adbname_t; */ struct dns_adbfind { /* Public */ - unsigned int magic; /* RO: magic */ - dns_adbaddrinfolist_t list; /* RO: list of addrs */ - unsigned int query_pending; /* RO: partial list */ - unsigned int partial_result; /* RO: addrs missing */ - unsigned int options; /* RO: options */ - isc_result_t result_v4; /* RO: v4 result */ - isc_result_t result_v6; /* RO: v6 result */ - ISC_LINK(dns_adbfind_t) publink; /* RW: client use */ + unsigned int magic; /*%< RO: magic */ + dns_adbaddrinfolist_t list; /*%< RO: list of addrs */ + unsigned int query_pending; /*%< RO: partial list */ + unsigned int partial_result; /*%< RO: addrs missing */ + unsigned int options; /*%< RO: options */ + isc_result_t result_v4; /*%< RO: v4 result */ + isc_result_t result_v6; /*%< RO: v6 result */ + ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */ /* Private */ isc_mutex_t lock; /* locks all below */ @@ -161,34 +162,65 @@ struct dns_adbfind { * At least one address was omitted from the list because it was lame. * This bit will NEVER be set if _RETURNLAME is set in the createfind(). */ +/*% Return addresses of type INET. */ #define DNS_ADBFIND_INET 0x00000001 +/*% Return addresses of type INET6. */ #define DNS_ADBFIND_INET6 0x00000002 #define DNS_ADBFIND_ADDRESSMASK 0x00000003 - +/*% + * Only schedule an event if no addresses are known. + * Must set _WANTEVENT for this to be meaningful. + */ #define DNS_ADBFIND_EMPTYEVENT 0x00000004 +/*% + * An event is desired. Check this bit in the returned find to see + * if one will actually be generated. + */ #define DNS_ADBFIND_WANTEVENT 0x00000008 +/*% + * If set, fetches will not be generated unless no addresses are + * available in any of the address families requested. + */ #define DNS_ADBFIND_AVOIDFETCHES 0x00000010 +/*% + * Fetches will start using the closest zone data or use the root servers. + * This is useful for reestablishing glue that has expired. + */ #define DNS_ADBFIND_STARTATZONE 0x00000020 +/*% + * Glue or hints are ok. These are used when matching names already + * in the adb, and when dns databases are searched. + */ #define DNS_ADBFIND_GLUEOK 0x00000040 +/*% + * Glue or hints are ok. These are used when matching names already + * in the adb, and when dns databases are searched. + */ #define DNS_ADBFIND_HINTOK 0x00000080 +/*% + * Return lame servers in a find, so that all addresses are returned. + */ #define DNS_ADBFIND_RETURNLAME 0x00000100 +/*% + * Only schedule an event if no addresses are known. + * Must set _WANTEVENT for this to be meaningful. + */ #define DNS_ADBFIND_LAMEPRUNED 0x00000200 -/* dns_adbaddrinfo_t - * +/*% * The answers to queries come back as a list of these. */ struct dns_adbaddrinfo { - unsigned int magic; /* private */ + unsigned int magic; /*%< private */ - isc_sockaddr_t sockaddr; /* [rw] */ - unsigned int srtt; /* [rw] microseconds */ - unsigned int flags; /* [rw] */ - dns_adbentry_t *entry; /* private */ + isc_sockaddr_t sockaddr; /*%< [rw] */ + unsigned int srtt; /*%< [rw] microseconds */ + unsigned int flags; /*%< [rw] */ + dns_adbentry_t *entry; /*%< private */ ISC_LINK(dns_adbaddrinfo_t) publink; }; -/* +/*!< * The event sent to the caller task is just a plain old isc_event_t. It * contains no data other than a simple status, passed in the "type" field * to indicate that another address resolved, or all partially resolved @@ -198,13 +230,13 @@ struct dns_adbaddrinfo { * * This is simply a standard event, with the "type" set to: * - * DNS_EVENT_ADBMOREADDRESSES -- another address resolved. - * DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed, + *\li #DNS_EVENT_ADBMOREADDRESSES -- another address resolved. + *\li #DNS_EVENT_ADBNOMOREADDRESSES -- all pending addresses failed, * were canceled, or otherwise will * not be usable. - * DNS_EVENT_ADBCANCELED -- The request was canceled by a + *\li #DNS_EVENT_ADBCANCELED -- The request was canceled by a * 3rd party. - * DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request + *\li #DNS_EVENT_ADBNAMEDELETED -- The name was deleted, so this request * was canceled. * * In each of these cases, the addresses returned by the initial call @@ -219,89 +251,90 @@ struct dns_adbaddrinfo { isc_result_t dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *tmgr, isc_taskmgr_t *taskmgr, dns_adb_t **newadb); -/* +/*%< * Create a new ADB. * * Notes: * - * Generally, applications should not create an ADB directly, but + *\li Generally, applications should not create an ADB directly, but * should instead call dns_view_createresolver(). * * Requires: * - * 'mem' must be a valid memory context. + *\li 'mem' must be a valid memory context. * - * 'view' be a pointer to a valid view. + *\li 'view' be a pointer to a valid view. * - * 'tmgr' be a pointer to a valid timer manager. + *\li 'tmgr' be a pointer to a valid timer manager. * - * 'taskmgr' be a pointer to a valid task manager. + *\li 'taskmgr' be a pointer to a valid task manager. * - * 'newadb' != NULL && '*newadb' == NULL. + *\li 'newadb' != NULL && '*newadb' == NULL. * * Returns: * - * ISC_R_SUCCESS after happiness. - * ISC_R_NOMEMORY after resource allocation failure. + *\li #ISC_R_SUCCESS after happiness. + *\li #ISC_R_NOMEMORY after resource allocation failure. */ void dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbp); -/* +/*% * Attach to an 'adb' to 'adbp'. * * Requires: - * 'adb' to be a valid dns_adb_t, created via dns_adb_create(). - * 'adbp' to be a valid pointer to a *dns_adb_t which is initialized + *\li 'adb' to be a valid dns_adb_t, created via dns_adb_create(). + *\li 'adbp' to be a valid pointer to a *dns_adb_t which is initialized * to NULL. */ void dns_adb_detach(dns_adb_t **adb); -/* +/*% * Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests. * * Requires: * - * 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via + *\li 'adb' be non-NULL and '*adb' be a valid dns_adb_t, created via * dns_adb_create(). */ void dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp); -/* +/*% * Send '*eventp' to 'task' when 'adb' has shutdown. * * Requires: * - * '*adb' is a valid dns_adb_t. + *\li '*adb' is a valid dns_adb_t. * - * eventp != NULL && *eventp is a valid event. + *\li eventp != NULL && *eventp is a valid event. * * Ensures: * - * *eventp == NULL + *\li *eventp == NULL * - * The event's sender field is set to the value of adb when the event + *\li The event's sender field is set to the value of adb when the event * is sent. */ void dns_adb_shutdown(dns_adb_t *adb); -/* +/*%< * Shutdown 'adb'. * * Requires: * - * '*adb' is a valid dns_adb_t. + * \li '*adb' is a valid dns_adb_t. */ isc_result_t dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_name_t *name, dns_name_t *zone, - unsigned int options, isc_stdtime_t now, dns_name_t *target, + void *arg, dns_name_t *name, dns_name_t *qname, + dns_rdatatype_t qtype, unsigned int options, + isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **find); -/* +/*%< * Main interface for clients. The adb will look up the name given in * "name" and will build up a list of found addresses, and perhaps start * internal fetches to resolve names that are unknown currently. @@ -311,9 +344,9 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, * set to a pointer to the dns_adbfind_t returned by this function. * * If no events will be generated, the *find->result_v4 and/or result_v6 - * members may be examined for address lookup status. The usual ISC_R_SUCCESS, - * ISC_R_FAILURE, and DNS_R_NX{DOMAIN,RRSET} are returned, along with - * ISC_R_NOTFOUND meaning the ADB has not _yet_ found the values. In this + * members may be examined for address lookup status. The usual #ISC_R_SUCCESS, + * #ISC_R_FAILURE, and #DNS_R_NX{DOMAIN,RRSET} are returned, along with + * #ISC_R_NOTFOUND meaning the ADB has not _yet_ found the values. In this * latter case, retrying may produce more addresses. * * If events will be returned, the result_v[46] members are only valid @@ -346,42 +379,42 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, * * Requires: * - * *adb be a valid isc_adb_t object. + *\li *adb be a valid isc_adb_t object. * - * If events are to be sent, *task be a valid task, + *\li If events are to be sent, *task be a valid task, * and isc_taskaction_t != NULL. * - * *name is a valid dns_name_t. + *\li *name is a valid dns_name_t. * - * zone != NULL and *zone be a valid dns_name_t. + *\li qname != NULL and *qname be a valid dns_name_t. * - * target == NULL or target is a valid name with a buffer. + *\li target == NULL or target is a valid name with a buffer. * - * find != NULL && *find == NULL. + *\li find != NULL && *find == NULL. * * Returns: * - * ISC_R_SUCCESS Addresses might have been returned, and events will be + *\li #ISC_R_SUCCESS Addresses might have been returned, and events will be * delivered for unresolved addresses. - * ISC_R_NOMORE Addresses might have been returned, but no events + *\li #ISC_R_NOMORE Addresses might have been returned, but no events * will ever be posted for this context. This is only * returned if task != NULL. - * ISC_R_NOMEMORY insufficient resources - * DNS_R_ALIAS 'name' is an alias for another name. + *\li #ISC_R_NOMEMORY insufficient resources + *\li #DNS_R_ALIAS 'name' is an alias for another name. * * Calls, and returns error codes from: * - * isc_stdtime_get() + *\li isc_stdtime_get() * * Notes: * - * No internal reference to "name" exists after this function + *\li No internal reference to "name" exists after this function * returns. */ void dns_adb_cancelfind(dns_adbfind_t *find); -/* +/*%< * Cancels the find, and sends the event off to the caller. * * It is an error to call dns_adb_cancelfind() on a find where @@ -389,7 +422,7 @@ dns_adb_cancelfind(dns_adbfind_t *find); * * Note: * - * It is possible that the real completion event was posted just + *\li It is possible that the real completion event was posted just * before the dns_adb_cancelfind() call was made. In this case, * dns_adb_cancelfind() will do nothing. The event callback needs * to be prepared to find this situation (i.e. result is valid but @@ -397,101 +430,105 @@ dns_adb_cancelfind(dns_adbfind_t *find); * * Requires: * - * 'find' be a valid dns_adbfind_t pointer. + *\li 'find' be a valid dns_adbfind_t pointer. * - * events would have been posted to the task. This can be checked + *\li events would have been posted to the task. This can be checked * with (find->options & DNS_ADBFIND_WANTEVENT). * * Ensures: * - * The event was posted to the task. + *\li The event was posted to the task. */ void dns_adb_destroyfind(dns_adbfind_t **find); -/* +/*%< * Destroys the find reference. * * Note: * - * This can only be called after the event was delivered for a + *\li This can only be called after the event was delivered for a * find. Additionally, the event MUST have been freed via * isc_event_free() BEFORE this function is called. * * Requires: * - * 'find' != NULL and *find be valid dns_adbfind_t pointer. + *\li 'find' != NULL and *find be valid dns_adbfind_t pointer. * * Ensures: * - * No "address found" events will be posted to the originating task + *\li No "address found" events will be posted to the originating task * after this function returns. */ void dns_adb_dump(dns_adb_t *adb, FILE *f); -/* +/*%< * This function is only used for debugging. It will dump as much of the * state of the running system as possible. * * Requires: * - * adb be valid. + *\li adb be valid. * - * f != NULL, and is a file open for writing. + *\li f != NULL, and is a file open for writing. */ void dns_adb_dumpfind(dns_adbfind_t *find, FILE *f); -/* +/*%< * This function is only used for debugging. Dump the data associated * with a find. * * Requires: * - * find is valid. + *\li find is valid. * - * f != NULL, and is a file open for writing. + * \li f != NULL, and is a file open for writing. */ isc_result_t -dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone, - isc_stdtime_t expire_time); -/* - * Mark the given address as lame for the zone "zone". expire_time should +dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *qname, + dns_rdatatype_t type, isc_stdtime_t expire_time); +/*%< + * Mark the given address as lame for the <qname,qtype>. expire_time should * be set to the time when the entry should expire. That is, if it is to * expire 10 minutes in the future, it should set it to (now + 10 * 60). * * Requires: * - * adb be valid. + *\li adb be valid. * - * addr be valid. + *\li addr be valid. * - * zone be the zone used in the dns_adb_createfind() call. + *\li qname be the qname used in the dns_adb_createfind() call. * * Returns: * - * ISC_R_SUCCESS -- all is well. - * ISC_R_NOMEMORY -- could not mark address as lame. + *\li #ISC_R_SUCCESS -- all is well. + *\li #ISC_R_NOMEMORY -- could not mark address as lame. */ /* * A reasonable default for RTT adjustments */ -#define DNS_ADB_RTTADJDEFAULT 7 /* default scale */ -#define DNS_ADB_RTTADJREPLACE 0 /* replace with our rtt */ -#define DNS_ADB_RTTADJAGE 10 /* age this rtt */ +#define DNS_ADB_RTTADJDEFAULT 7 /*%< default scale */ +#define DNS_ADB_RTTADJREPLACE 0 /*%< replace with our rtt */ +#define DNS_ADB_RTTADJAGE 10 /*%< age this rtt */ void dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor); -/* - * Mix the round trip time into the existing smoothed rtt. The formula used +/*%< + * Mix the round trip time into the existing smoothed rtt. + + * The formula used * (where srtt is the existing rtt value, and rtt and factor are arguments to * this function): * + *\code * new_srtt = (old_srtt / 10 * factor) + (rtt / 10 * (10 - factor)); + *\endcode * * XXXRTH Do we want to publish the formula? What if we want to change how * this works later on? Recommend/require that the units are @@ -499,77 +536,79 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr, * * Requires: * - * adb be valid. + *\li adb be valid. * - * addr be valid. + *\li addr be valid. * - * 0 <= factor <= 10 + *\li 0 <= factor <= 10 * * Note: * - * The srtt in addr will be updated to reflect the new global + *\li The srtt in addr will be updated to reflect the new global * srtt value. This may include changes made by others. */ void dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits, unsigned int mask); -/* +/*% + * Change Flags. + * * Set the flags as given by: * - * newflags = (oldflags & ~mask) | (bits & mask); + *\li newflags = (oldflags & ~mask) | (bits & mask); * * Requires: * - * adb be valid. + *\li adb be valid. * - * addr be valid. + *\li addr be valid. */ isc_result_t dns_adb_findaddrinfo(dns_adb_t *adb, isc_sockaddr_t *sa, dns_adbaddrinfo_t **addrp, isc_stdtime_t now); -/* +/*%< * Return a dns_adbaddrinfo_t that is associated with address 'sa'. * * Requires: * - * adb is valid. + *\li adb is valid. * - * sa is valid. + *\li sa is valid. * - * addrp != NULL && *addrp == NULL + *\li addrp != NULL && *addrp == NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_SHUTTINGDOWN + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SHUTTINGDOWN */ void dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp); -/* +/*%< * Free a dns_adbaddrinfo_t allocated by dns_adb_findaddrinfo(). * * Requires: * - * adb is valid. + *\li adb is valid. * - * *addrp is a valid dns_adbaddrinfo_t *. + *\li *addrp is a valid dns_adbaddrinfo_t *. */ void dns_adb_flush(dns_adb_t *adb); -/* +/*%< * Flushes all cached data from the adb. * * Requires: - * adb is valid. + *\li adb is valid. */ void dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size); -/* +/*%< * Set a target memory size. If memory usage exceeds the target * size entries will be removed before they would have expired on * a random basis. @@ -577,17 +616,17 @@ dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size); * If 'size' is 0 then memory usage is unlimited. * * Requires: - * 'adb' is valid. + *\li 'adb' is valid. */ void dns_adb_flushname(dns_adb_t *adb, dns_name_t *name); -/* +/*%< * Flush 'name' from the adb cache. * * Requires: - * 'adb' is valid. - * 'name' is valid. + *\li 'adb' is valid. + *\li 'name' is valid. */ diff --git a/contrib/bind9/lib/dns/include/dns/bit.h b/contrib/bind9/lib/dns/include/dns/bit.h index e4a7d20..770f294 100644 --- a/contrib/bind9/lib/dns/include/dns/bit.h +++ b/contrib/bind9/lib/dns/include/dns/bit.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: bit.h,v 1.7.206.1 2004/03/06 08:13:51 marka Exp $ */ +/* $Id: bit.h,v 1.8.18.2 2005/04/29 00:16:09 marka Exp $ */ #ifndef DNS_BIT_H #define DNS_BIT_H 1 +/*! \file */ + #include <isc/int.h> #include <isc/boolean.h> diff --git a/contrib/bind9/lib/dns/include/dns/byaddr.h b/contrib/bind9/lib/dns/include/dns/byaddr.h index 8f69cd9..1f1e88c 100644 --- a/contrib/bind9/lib/dns/include/dns/byaddr.h +++ b/contrib/bind9/lib/dns/include/dns/byaddr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: byaddr.h,v 1.12.2.1.2.4 2004/03/08 09:04:34 marka Exp $ */ +/* $Id: byaddr.h,v 1.16.18.2 2005/04/29 00:16:09 marka Exp $ */ #ifndef DNS_BYADDR_H #define DNS_BYADDR_H 1 @@ -24,28 +24,27 @@ ***** Module Info *****/ -/* - * DNS ByAddr - * +/*! \file + * \brief * The byaddr module provides reverse lookup services for IPv4 and IPv6 * addresses. * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * RFCs: 1034, 1035, 2181, <TBS> - * Drafts: <TBS> + *\li RFCs: 1034, 1035, 2181, TBS + *\li Drafts: TBS */ #include <isc/lang.h> @@ -55,7 +54,7 @@ ISC_LANG_BEGINDECLS -/* +/*% * A 'dns_byaddrevent_t' is returned when a byaddr completes. * The sender field will be set to the byaddr that completed. If 'result' * is ISC_R_SUCCESS, then 'names' will contain a list of names associated @@ -72,76 +71,79 @@ typedef struct dns_byaddrevent { * This option is deprecated since we now only consider nibbles. #define DNS_BYADDROPT_IPV6NIBBLE 0x0001 */ +/*% Note DNS_BYADDROPT_IPV6NIBBLE is now deprecated. */ #define DNS_BYADDROPT_IPV6INT 0x0002 isc_result_t dns_byaddr_create(isc_mem_t *mctx, isc_netaddr_t *address, dns_view_t *view, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_byaddr_t **byaddrp); -/* +/*%< * Find the domain name of 'address'. * * Notes: * - * There is a reverse lookup format for IPv6 addresses, 'nibble' + *\li There is a reverse lookup format for IPv6 addresses, 'nibble' * - * The 'nibble' format for that address is + *\li The 'nibble' format for that address is * + * \code * 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa. + * \endcode * - * DNS_BYADDROPT_IPV6INT can be used to get nibble lookups under ip6.int. + *\li #DNS_BYADDROPT_IPV6INT can be used to get nibble lookups under ip6.int. * * Requires: * - * 'mctx' is a valid mctx. + *\li 'mctx' is a valid mctx. * - * 'address' is a valid IPv4 or IPv6 address. + *\li 'address' is a valid IPv4 or IPv6 address. * - * 'view' is a valid view which has a resolver. + *\li 'view' is a valid view which has a resolver. * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * byaddrp != NULL && *byaddrp == NULL + *\li byaddrp != NULL && *byaddrp == NULL * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY * - * Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be + *\li Any resolver-related error (e.g. #ISC_R_SHUTTINGDOWN) may also be * returned. */ void dns_byaddr_cancel(dns_byaddr_t *byaddr); -/* +/*%< * Cancel 'byaddr'. * * Notes: * - * If 'byaddr' has not completed, post its BYADDRDONE event with a - * result code of ISC_R_CANCELED. + *\li If 'byaddr' has not completed, post its #BYADDRDONE event with a + * result code of #ISC_R_CANCELED. * * Requires: * - * 'byaddr' is a valid byaddr. + *\li 'byaddr' is a valid byaddr. */ void dns_byaddr_destroy(dns_byaddr_t **byaddrp); -/* +/*%< * Destroy 'byaddr'. * * Requires: * - * '*byaddrp' is a valid byaddr. + *\li '*byaddrp' is a valid byaddr. * - * The caller has received the BYADDRDONE event (either because the + *\li The caller has received the BYADDRDONE event (either because the * byaddr completed or because dns_byaddr_cancel() was called). * * Ensures: * - * *byaddrp == NULL. + *\li *byaddrp == NULL. */ isc_result_t @@ -151,7 +153,7 @@ dns_byaddr_createptrname(isc_netaddr_t *address, isc_boolean_t nibble, isc_result_t dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options, dns_name_t *name); -/* +/*%< * Creates a name that would be used in a PTR query for this address. The * nibble flag indicates that the 'nibble' format is to be used if an IPv6 * address is provided, instead of the 'bitstring' format. Since we dropped @@ -160,8 +162,8 @@ dns_byaddr_createptrname2(isc_netaddr_t *address, unsigned int options, * * Requires: * - * 'address' is a valid address. - * 'name' is a valid name with a dedicated buffer. + * \li 'address' is a valid address. + * \li 'name' is a valid name with a dedicated buffer. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/cache.h b/contrib/bind9/lib/dns/include/dns/cache.h index 4b775c9..fc4f78e 100644 --- a/contrib/bind9/lib/dns/include/dns/cache.h +++ b/contrib/bind9/lib/dns/include/dns/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cache.h,v 1.17.12.5 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: cache.h,v 1.19.18.3 2005/08/23 02:31:38 marka Exp $ */ #ifndef DNS_CACHE_H #define DNS_CACHE_H 1 @@ -24,18 +24,17 @@ ***** Module Info *****/ -/* - * cache - * +/*! \file + * \brief * Defines dns_cache_t, the cache object. * * Notes: - * A cache object contains DNS data of a single class. + *\li A cache object contains DNS data of a single class. * Multiple classes will be handled by creating multiple * views, each with a different class and its own cache. * * MP: - * See notes at the individual functions. + *\li See notes at the individual functions. * * Reliability: * @@ -66,71 +65,70 @@ dns_cache_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, dns_rdataclass_t rdclass, const char *db_type, unsigned int db_argc, char **db_argv, dns_cache_t **cachep); -/* +/*%< * Create a new DNS cache. * * Requires: * - * 'mctx' is a valid memory context + *\li 'mctx' is a valid memory context * - * 'taskmgr' is a valid task manager and 'timermgr' is a valid timer + *\li 'taskmgr' is a valid task manager and 'timermgr' is a valid timer * manager, or both are NULL. If NULL, no periodic cleaning of the * cache will take place. * - * 'cachep' is a valid pointer, and *cachep == NULL + *\li 'cachep' is a valid pointer, and *cachep == NULL * * Ensures: * - * '*cachep' is attached to the newly created cache + *\li '*cachep' is attached to the newly created cache * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ void dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp); -/* +/*%< * Attach *targetp to cache. * * Requires: * - * 'cache' is a valid cache. + *\li 'cache' is a valid cache. * - * 'targetp' points to a NULL dns_cache_t *. + *\li 'targetp' points to a NULL dns_cache_t *. * * Ensures: * - * *targetp is attached to cache. + *\li *targetp is attached to cache. */ void dns_cache_detach(dns_cache_t **cachep); -/* +/*%< * Detach *cachep from its cache. * * Requires: * - * 'cachep' points to a valid cache. + *\li 'cachep' points to a valid cache. * * Ensures: * - * *cachep is NULL. - * - * If '*cachep' is the last reference to the cache, + *\li *cachep is NULL. * - * All resources used by the cache will be freed + *\li If '*cachep' is the last reference to the cache, + * all resources used by the cache will be freed */ void dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp); -/* +/*%< * Attach *dbp to the cache's database. * * Notes: * - * This may be used to get a reference to the database for + *\li This may be used to get a reference to the database for * the purpose of cache lookups (XXX currently it is also * the way to add data to the cache, but having a * separate dns_cache_add() interface instead would allow @@ -140,39 +138,39 @@ dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp); * * Requires: * - * 'cache' is a valid cache. + *\li 'cache' is a valid cache. * - * 'dbp' points to a NULL dns_db *. + *\li 'dbp' points to a NULL dns_db *. * * Ensures: * - * *dbp is attached to the database. + *\li *dbp is attached to the database. */ isc_result_t -dns_cache_setfilename(dns_cache_t *cahce, const char *filename); -/* +dns_cache_setfilename(dns_cache_t *cache, const char *filename); +/*%< * If 'filename' is non-NULL, make the cache persistent. * The cache's data will be stored in the given file. * If 'filename' is NULL, make the cache non-persistent. * Files that are no longer used are not unlinked automatically. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * Various file-related failures + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li Various file-related failures */ isc_result_t dns_cache_load(dns_cache_t *cache); -/* +/*%< * If the cache has a file name, load the cache contents from the file. * Previous cache contents are not discarded. * If no file name has been set, do nothing and return success. * * MT: - * Multiple simultaneous attempts to load or dump the cache + *\li Multiple simultaneous attempts to load or dump the cache * will be serialized with respect to one another, but * the cache may be read and updated while the dump is * in progress. Updates performed during loading @@ -181,19 +179,19 @@ dns_cache_load(dns_cache_t *cache); * * Returns: * - * ISC_R_SUCCESS - * Various failures depending on the database implementation type + *\li #ISC_R_SUCCESS + * \li Various failures depending on the database implementation type */ isc_result_t dns_cache_dump(dns_cache_t *cache); -/* +/*%< * If the cache has a file name, write the cache contents to disk, * overwriting any preexisting file. If no file name has been set, * do nothing and return success. * * MT: - * Multiple simultaneous attempts to load or dump the cache + *\li Multiple simultaneous attempts to load or dump the cache * will be serialized with respect to one another, but * the cache may be read and updated while the dump is * in progress. Updates performed during the dump may @@ -201,13 +199,13 @@ dns_cache_dump(dns_cache_t *cache); * * Returns: * - * ISC_R_SUCCESS - * Various failures depending on the database implementation type + *\li #ISC_R_SUCCESS + * \li Various failures depending on the database implementation type */ isc_result_t dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now); -/* +/*%< * Force immediate cleaning of the cache, freeing all rdatasets * whose TTL has expired as of 'now' and that have no pending * references. @@ -215,24 +213,24 @@ dns_cache_clean(dns_cache_t *cache, isc_stdtime_t now); void dns_cache_setcleaninginterval(dns_cache_t *cache, unsigned int interval); -/* +/*%< * Set the periodic cache cleaning interval to 'interval' seconds. */ void dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size); -/* +/*%< * Set the maximum cache size. 0 means unlimited. */ isc_result_t dns_cache_flush(dns_cache_t *cache); -/* +/*%< * Flushes all data from the cache. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ isc_result_t @@ -241,13 +239,13 @@ dns_cache_flushname(dns_cache_t *cache, dns_name_t *name); * Flushes a given name from the cache. * * Requires: - * 'cache' to be valid. - * 'name' to be valid. + *\li 'cache' to be valid. + *\li 'name' to be valid. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * other error returns. + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li other error returns. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/callbacks.h b/contrib/bind9/lib/dns/include/dns/callbacks.h index 9c2710a..6aee70b 100644 --- a/contrib/bind9/lib/dns/include/dns/callbacks.h +++ b/contrib/bind9/lib/dns/include/dns/callbacks.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: callbacks.h,v 1.15.2.2.8.1 2004/03/06 08:13:51 marka Exp $ */ +/* $Id: callbacks.h,v 1.18.18.2 2005/04/29 00:16:10 marka Exp $ */ #ifndef DNS_CALLBACKS_H #define DNS_CALLBACKS_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -35,19 +37,19 @@ ISC_LANG_BEGINDECLS ***/ struct dns_rdatacallbacks { - /* + /*% * dns_load_master calls this when it has rdatasets to commit. */ dns_addrdatasetfunc_t add; - /* + /*% * dns_load_master / dns_rdata_fromtext call this to issue a error. */ void (*error)(struct dns_rdatacallbacks *, const char *, ...); - /* + /*% * dns_load_master / dns_rdata_fromtext call this to issue a warning. */ void (*warn)(struct dns_rdatacallbacks *, const char *, ...); - /* + /*% * Private data handles for use by the above callback functions. */ void *add_private; @@ -61,20 +63,22 @@ struct dns_rdatacallbacks { void dns_rdatacallbacks_init(dns_rdatacallbacks_t *callbacks); -/* +/*%< * Initialize 'callbacks'. - * 'error' and 'warn' are set to default callbacks that print the + * + * + * \li 'error' and 'warn' are set to default callbacks that print the * error message through the DNS library log context. * - * All other elements are initialized to NULL. + *\li All other elements are initialized to NULL. * * Requires: - * 'callbacks' is a valid dns_rdatacallbacks_t, + * \li 'callbacks' is a valid dns_rdatacallbacks_t, */ void dns_rdatacallbacks_init_stdio(dns_rdatacallbacks_t *callbacks); -/* +/*%< * Like dns_rdatacallbacks_init, but logs to stdio. */ diff --git a/contrib/bind9/lib/dns/include/dns/cert.h b/contrib/bind9/lib/dns/include/dns/cert.h index 28a3d4c..4de1aec 100644 --- a/contrib/bind9/lib/dns/include/dns/cert.h +++ b/contrib/bind9/lib/dns/include/dns/cert.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cert.h,v 1.12.206.1 2004/03/06 08:13:51 marka Exp $ */ +/* $Id: cert.h,v 1.13.18.2 2005/04/29 00:16:10 marka Exp $ */ #ifndef DNS_CERT_H #define DNS_CERT_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,38 +30,38 @@ ISC_LANG_BEGINDECLS isc_result_t dns_cert_fromtext(dns_cert_t *certp, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a certificate type. * The text may contain either a mnemonic type name or a decimal type number. * * Requires: - * 'certp' is a valid pointer. + *\li 'certp' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_RANGE numeric type is out of range - * DNS_R_UNKNOWN mnemonic type is unknown + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_RANGE numeric type is out of range + *\li #DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_cert_totext(dns_cert_t cert, isc_buffer_t *target); -/* +/*%< * Put a textual representation of certificate type 'cert' into 'target'. * * Requires: - * 'cert' is a valid cert. + *\li 'cert' is a valid cert. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * * Ensures: - * If the result is success: + *\li If the result is success: * The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/compress.h b/contrib/bind9/lib/dns/include/dns/compress.h index 042a4ea..4d9c011 100644 --- a/contrib/bind9/lib/dns/include/dns/compress.h +++ b/contrib/bind9/lib/dns/include/dns/compress.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.h,v 1.29.2.2.8.3 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: compress.h,v 1.32.18.6 2006/03/02 00:37:21 marka Exp $ */ #ifndef DNS_COMPRESS_H #define DNS_COMPRESS_H 1 @@ -27,11 +27,12 @@ ISC_LANG_BEGINDECLS -#define DNS_COMPRESS_NONE 0x00 /* no compression */ -#define DNS_COMPRESS_GLOBAL14 0x01 /* "normal" compression. */ -#define DNS_COMPRESS_ALL 0x01 /* all compression. */ +#define DNS_COMPRESS_NONE 0x00 /*%< no compression */ +#define DNS_COMPRESS_GLOBAL14 0x01 /*%< "normal" compression. */ +#define DNS_COMPRESS_ALL 0x01 /*%< all compression. */ +#define DNS_COMPRESS_CASESENSITIVE 0x02 /*%< case sensitive compression. */ -/* +/*! \file * Direct manipulation of the structures is strongly discouraged. */ @@ -49,198 +50,218 @@ struct dns_compressnode { }; struct dns_compress { - unsigned int magic; /* Magic number. */ - unsigned int allowed; /* Allowed methods. */ - int edns; /* Edns version or -1. */ - /* Global compression table. */ + unsigned int magic; /*%< Magic number. */ + unsigned int allowed; /*%< Allowed methods. */ + int edns; /*%< Edns version or -1. */ + /*% Global compression table. */ dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE]; - /* Preallocated nodes for the table. */ + /*% Preallocated nodes for the table. */ dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES]; - isc_uint16_t count; /* Number of nodes. */ - isc_mem_t *mctx; /* Memory context. */ + isc_uint16_t count; /*%< Number of nodes. */ + isc_mem_t *mctx; /*%< Memory context. */ }; typedef enum { - DNS_DECOMPRESS_ANY, /* Any compression */ - DNS_DECOMPRESS_STRICT, /* Allowed compression */ - DNS_DECOMPRESS_NONE /* No compression */ + DNS_DECOMPRESS_ANY, /*%< Any compression */ + DNS_DECOMPRESS_STRICT, /*%< Allowed compression */ + DNS_DECOMPRESS_NONE /*%< No compression */ } dns_decompresstype_t; struct dns_decompress { - unsigned int magic; /* Magic number. */ - unsigned int allowed; /* Allowed methods. */ - int edns; /* Edns version or -1. */ - dns_decompresstype_t type; /* Strict checking */ + unsigned int magic; /*%< Magic number. */ + unsigned int allowed; /*%< Allowed methods. */ + int edns; /*%< Edns version or -1. */ + dns_decompresstype_t type; /*%< Strict checking */ }; isc_result_t dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx); -/* +/*%< * Inialise the compression context structure pointed to by 'cctx'. * * Requires: - * 'cctx' is a valid dns_compress_t structure. - * 'mctx' is an initialized memory context. + * \li 'cctx' is a valid dns_compress_t structure. + * \li 'mctx' is an initialized memory context. * Ensures: - * cctx->global is initialized. + * \li cctx->global is initialized. * * Returns: - * ISC_R_SUCCESS - * failures from dns_rbt_create() + * \li #ISC_R_SUCCESS + * \li failures from dns_rbt_create() */ void dns_compress_invalidate(dns_compress_t *cctx); -/* +/*%< * Invalidate the compression structure pointed to by cctx. * * Requires: - * 'cctx' to be initialized. + *\li 'cctx' to be initialized. */ void dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed); -/* +/*%< * Sets allowed compression methods. * * Requires: - * 'cctx' to be initialized. + *\li 'cctx' to be initialized. */ unsigned int dns_compress_getmethods(dns_compress_t *cctx); -/* +/*%< * Gets allowed compression methods. * * Requires: - * 'cctx' to be initialized. + *\li 'cctx' to be initialized. * * Returns: - * allowed compression bitmap. + *\li allowed compression bitmap. + */ + +void +dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive); + +/* + * Preserve the case of compressed domain names. + * + * Requires: + * 'cctx' to be initialized. + */ + +isc_boolean_t +dns_compress_getsensitive(dns_compress_t *cctx); +/* + * Return whether case is to be preservered when compressing + * domain names. + * + * Requires: + * 'cctx' to be initialized. */ int dns_compress_getedns(dns_compress_t *cctx); -/* +/*%< * Gets edns value. * * Requires: - * 'cctx' to be initialized. + *\li 'cctx' to be initialized. * * Returns: - * -1 .. 255 + *\li -1 .. 255 */ isc_boolean_t dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, dns_name_t *prefix, isc_uint16_t *offset); -/* +/*%< * Finds longest possible match of 'name' in the global compression table. * * Requires: - * 'cctx' to be initialized. - * 'name' to be a absolute name. - * 'prefix' to be initialized. - * 'offset' to point to an isc_uint16_t. + *\li 'cctx' to be initialized. + *\li 'name' to be a absolute name. + *\li 'prefix' to be initialized. + *\li 'offset' to point to an isc_uint16_t. * * Ensures: - * 'prefix' and 'offset' are valid if ISC_TRUE is returned. + *\li 'prefix' and 'offset' are valid if ISC_TRUE is returned. * * Returns: - * ISC_TRUE / ISC_FALSE + *\li #ISC_TRUE / #ISC_FALSE */ void dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, const dns_name_t *prefix, isc_uint16_t offset); -/* +/*%< * Add compression pointers for 'name' to the compression table, * not replacing existing pointers. * * Requires: - * 'cctx' initialized + *\li 'cctx' initialized * - * 'name' must be initialized and absolute, and must remain + *\li 'name' must be initialized and absolute, and must remain * valid until the message compression is complete. * - * 'prefix' must be a prefix returned by + *\li 'prefix' must be a prefix returned by * dns_compress_findglobal(), or the same as 'name'. */ void dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset); -/* +/*%< * Remove any compression pointers from global table >= offset. * * Requires: - * 'cctx' is initialized. + *\li 'cctx' is initialized. */ void dns_decompress_init(dns_decompress_t *dctx, int edns, dns_decompresstype_t type); -/* +/*%< * Initializes 'dctx'. * Records 'edns' and 'type' into the structure. * * Requires: - * 'dctx' to be a valid pointer. + *\li 'dctx' to be a valid pointer. */ void dns_decompress_invalidate(dns_decompress_t *dctx); -/* +/*%< * Invalidates 'dctx'. * * Requires: - * 'dctx' to be initialized + *\li 'dctx' to be initialized */ void dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed); -/* +/*%< * Sets 'dctx->allowed' to 'allowed'. * * Requires: - * 'dctx' to be initialized + *\li 'dctx' to be initialized */ unsigned int dns_decompress_getmethods(dns_decompress_t *dctx); -/* +/*%< * Returns 'dctx->allowed' * * Requires: - * 'dctx' to be initialized + *\li 'dctx' to be initialized */ int dns_decompress_edns(dns_decompress_t *dctx); -/* +/*%< * Returns 'dctx->edns' * * Requires: - * 'dctx' to be initialized + *\li 'dctx' to be initialized */ dns_decompresstype_t dns_decompress_type(dns_decompress_t *dctx); -/* +/*%< * Returns 'dctx->type' * * Requires: - * 'dctx' to be initialized + *\li 'dctx' to be initialized */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h index 8e08882..a791a2e 100644 --- a/contrib/bind9/lib/dns/include/dns/db.h +++ b/contrib/bind9/lib/dns/include/dns/db.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.h,v 1.67.12.8 2004/05/14 05:06:41 marka Exp $ */ +/* $Id: db.h,v 1.76.18.7 2005/10/13 02:12:25 marka Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -24,31 +24,30 @@ ***** Module Info *****/ -/* - * DNS DB - * +/*! \file + * \brief * The DNS DB interface allows named rdatasets to be stored and retrieved. * * The dns_db_t type is like a "virtual class". To actually use * DBs, an implementation of the class is required. * - * XXX <more> XXX + * XXX more XXX * * MP: - * The module ensures appropriate synchronization of data structures it + * \li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: - * No anticipated impact. + * \li No anticipated impact. * * Resources: - * <TBS> + * \li TBS * * Security: - * No anticipated impact. + * \li No anticipated impact. * * Standards: - * None. + * \li None. */ /***** @@ -76,7 +75,8 @@ typedef struct dns_dbmethods { dns_dbload_t **dbloadp); isc_result_t (*endload)(dns_db_t *db, dns_dbload_t **dbloadp); isc_result_t (*dump)(dns_db_t *db, dns_dbversion_t *version, - const char *filename); + const char *filename, + dns_masterformat_t masterformat); void (*currentversion)(dns_db_t *db, dns_dbversion_t **versionp); isc_result_t (*newversion)(dns_db_t *db, @@ -145,6 +145,7 @@ typedef struct dns_dbmethods { isc_boolean_t (*ispersistent)(dns_db_t *db); void (*overmem)(dns_db_t *db, isc_boolean_t overmem); void (*settask)(dns_db_t *db, isc_task_t *); + isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep); } dns_dbmethods_t; typedef isc_result_t @@ -156,10 +157,10 @@ typedef isc_result_t #define DNS_DB_MAGIC ISC_MAGIC('D','N','S','D') #define DNS_DB_VALID(db) ISC_MAGIC_VALID(db, DNS_DB_MAGIC) -/* +/*% * This structure is actually just the common prefix of a DNS db * implementation's version of a dns_db_t. - * + * \brief * Direct use of this structure by clients is forbidden. DB implementations * may change the structure. 'magic' must be DNS_DB_MAGIC for any of the * dns_db_ routines to work. DB implementations must maintain all DB @@ -179,7 +180,8 @@ struct dns_db { #define DNS_DBATTR_CACHE 0x01 #define DNS_DBATTR_STUB 0x02 -/* +/*@{*/ +/*% * Options that can be specified for dns_db_find(). */ #define DNS_DBFIND_GLUEOK 0x01 @@ -189,16 +191,19 @@ struct dns_db { #define DNS_DBFIND_NOEXACT 0x10 #define DNS_DBFIND_FORCENSEC 0x20 #define DNS_DBFIND_COVERINGNSEC 0x40 +/*@}*/ -/* +/*@{*/ +/*% * Options that can be specified for dns_db_addrdataset(). */ #define DNS_DBADD_MERGE 0x01 #define DNS_DBADD_FORCE 0x02 #define DNS_DBADD_EXACT 0x04 #define DNS_DBADD_EXACTTTL 0x08 +/*@}*/ -/* +/*% * Options that can be specified for dns_db_subtractrdataset(). */ #define DNS_DBSUB_EXACT 0x01 @@ -215,78 +220,77 @@ isc_result_t dns_db_create(isc_mem_t *mctx, const char *db_type, dns_name_t *origin, dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc, char *argv[], dns_db_t **dbp); -/* +/*%< * Create a new database using implementation 'db_type'. * * Notes: - * All names in the database must be subdomains of 'origin' and in class + * \li All names in the database must be subdomains of 'origin' and in class * 'rdclass'. The database makes its own copy of the origin, so the * caller may do whatever they like with 'origin' and its storage once the * call returns. * - * DB implementation-specific parameters are passed using argc and argv. + * \li DB implementation-specific parameters are passed using argc and argv. * * Requires: * - * dbp != NULL and *dbp == NULL + * \li dbp != NULL and *dbp == NULL * - * 'origin' is a valid absolute domain name. + * \li 'origin' is a valid absolute domain name. * - * mctx is a valid memory context + * \li mctx is a valid memory context * * Ensures: * - * A copy of 'origin' has been made for the databases use, and the + * \li A copy of 'origin' has been made for the databases use, and the * caller is free to do whatever they want with the name and storage * associated with 'origin'. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_NOTFOUND db_type not found + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY + * \li #ISC_R_NOTFOUND db_type not found * - * Many other errors are possible, depending on what db_type was + * \li Many other errors are possible, depending on what db_type was * specified. */ void dns_db_attach(dns_db_t *source, dns_db_t **targetp); -/* +/*%< * Attach *targetp to source. * * Requires: * - * 'source' is a valid database. + * \li 'source' is a valid database. * - * 'targetp' points to a NULL dns_db_t *. + * \li 'targetp' points to a NULL dns_db_t *. * * Ensures: * - * *targetp is attached to source. + * \li *targetp is attached to source. */ void dns_db_detach(dns_db_t **dbp); -/* +/*%< * Detach *dbp from its database. * * Requires: * - * 'dbp' points to a valid database. + * \li 'dbp' points to a valid database. * * Ensures: * - * *dbp is NULL. - * - * If '*dbp' is the last reference to the database, + * \li *dbp is NULL. * - * All resources used by the database will be freed + * \li If '*dbp' is the last reference to the database, + * all resources used by the database will be freed */ isc_result_t dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp); -/* +/*%< * Causes 'eventp' to be sent to be sent to 'task' when the database is * destroyed. * @@ -297,189 +301,198 @@ dns_db_ondestroy(dns_db_t *db, isc_task_t *task, isc_event_t **eventp); isc_boolean_t dns_db_iscache(dns_db_t *db); -/* +/*%< * Does 'db' have cache semantics? * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: - * ISC_TRUE 'db' has cache semantics - * ISC_FALSE otherwise + * \li #ISC_TRUE 'db' has cache semantics + * \li #ISC_FALSE otherwise */ isc_boolean_t dns_db_iszone(dns_db_t *db); -/* +/*%< * Does 'db' have zone semantics? * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: - * ISC_TRUE 'db' has zone semantics - * ISC_FALSE otherwise + * \li #ISC_TRUE 'db' has zone semantics + * \li #ISC_FALSE otherwise */ isc_boolean_t dns_db_isstub(dns_db_t *db); -/* +/*%< * Does 'db' have stub semantics? * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: - * ISC_TRUE 'db' has zone semantics - * ISC_FALSE otherwise + * \li #ISC_TRUE 'db' has zone semantics + * \li #ISC_FALSE otherwise */ isc_boolean_t dns_db_issecure(dns_db_t *db); -/* +/*%< * Is 'db' secure? * * Requires: * - * 'db' is a valid database with zone semantics. + * \li 'db' is a valid database with zone semantics. * * Returns: - * ISC_TRUE 'db' is secure. - * ISC_FALSE 'db' is not secure. + * \li #ISC_TRUE 'db' is secure. + * \li #ISC_FALSE 'db' is not secure. */ dns_name_t * dns_db_origin(dns_db_t *db); -/* +/*%< * The origin of the database. * * Note: caller must not try to change this name. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: * - * The origin of the database. + * \li The origin of the database. */ dns_rdataclass_t dns_db_class(dns_db_t *db); -/* +/*%< * The class of the database. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: * - * The class of the database. + * \li The class of the database. */ isc_result_t dns_db_beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp); -/* +/*%< * Begin loading 'db'. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * This is the first attempt to load 'db'. + * \li This is the first attempt to load 'db'. * - * addp != NULL && *addp == NULL + * \li addp != NULL && *addp == NULL * - * dbloadp != NULL && *dbloadp == NULL + * \li dbloadp != NULL && *dbloadp == NULL * * Ensures: * - * On success, *addp will be a valid dns_addrdatasetfunc_t suitable + * \li On success, *addp will be a valid dns_addrdatasetfunc_t suitable * for loading 'db'. *dbloadp will be a valid DB load context which * should be used as 'arg' when *addp is called. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used, syntax errors in the master file, etc. */ isc_result_t dns_db_endload(dns_db_t *db, dns_dbload_t **dbloadp); -/* +/*%< * Finish loading 'db'. * * Requires: * - * 'db' is a valid database that is being loaded. + * \li 'db' is a valid database that is being loaded. * - * dbloadp != NULL and *dbloadp is a valid database load context. + * \li dbloadp != NULL and *dbloadp is a valid database load context. * * Ensures: * - * *dbloadp == NULL + * \li *dbloadp == NULL * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used, syntax errors in the master file, etc. */ isc_result_t dns_db_load(dns_db_t *db, const char *filename); -/* + +isc_result_t +dns_db_load2(dns_db_t *db, const char *filename, dns_masterformat_t format); +/*%< * Load master file 'filename' into 'db'. * * Notes: - * This routine is equivalent to calling + * \li This routine is equivalent to calling * + *\code * dns_db_beginload(); * dns_master_loadfile(); * dns_db_endload(); + *\endcode * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * This is the first attempt to load 'db'. + * \li This is the first attempt to load 'db'. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used, syntax errors in the master file, etc. */ isc_result_t dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename); -/* + +isc_result_t +dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat); +/*%< * Dump version 'version' of 'db' to master file 'filename'. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'version' is a valid version. + * \li 'version' is a valid version. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used, OS file errors, etc. */ @@ -489,68 +502,68 @@ dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename); void dns_db_currentversion(dns_db_t *db, dns_dbversion_t **versionp); -/* +/*%< * Open the current version for reading. * * Requires: * - * 'db' is a valid database with zone semantics. + * \li 'db' is a valid database with zone semantics. * - * versionp != NULL && *verisonp == NULL + * \li versionp != NULL && *verisonp == NULL * * Ensures: * - * On success, '*versionp' is attached to the current version. + * \li On success, '*versionp' is attached to the current version. * */ isc_result_t dns_db_newversion(dns_db_t *db, dns_dbversion_t **versionp); -/* +/*%< * Open a new version for reading and writing. * * Requires: * - * 'db' is a valid database with zone semantics. + * \li 'db' is a valid database with zone semantics. * - * versionp != NULL && *verisonp == NULL + * \li versionp != NULL && *verisonp == NULL * * Ensures: * - * On success, '*versionp' is attached to the current version. + * \li On success, '*versionp' is attached to the current version. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ void dns_db_attachversion(dns_db_t *db, dns_dbversion_t *source, dns_dbversion_t **targetp); -/* +/*%< * Attach '*targetp' to 'source'. * * Requires: * - * 'db' is a valid database with zone semantics. + * \li 'db' is a valid database with zone semantics. * - * source is a valid open version + * \li source is a valid open version * - * targetp != NULL && *targetp == NULL + * \li targetp != NULL && *targetp == NULL * * Ensures: * - * '*targetp' is attached to source. + * \li '*targetp' is attached to source. */ void dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit); -/* +/*%< * Close version '*versionp'. * * Note: if '*versionp' is a read-write version and 'commit' is ISC_TRUE, @@ -560,19 +573,19 @@ dns_db_closeversion(dns_db_t *db, dns_dbversion_t **versionp, * * Requires: * - * 'db' is a valid database with zone semantics. + * \li 'db' is a valid database with zone semantics. * - * '*versionp' refers to a valid version. + * \li '*versionp' refers to a valid version. * - * If committing a writable version, then there must be no other + * \li If committing a writable version, then there must be no other * outstanding references to the version (e.g. an active rdataset * iterator). * * Ensures: * - * *versionp == NULL + * \li *versionp == NULL * - * If *versionp is a read-write version, and commit is ISC_TRUE, then + * \li If *versionp is a read-write version, and commit is ISC_TRUE, then * the version will become the current version. If !commit, then all * changes made in the version will be undone, and the version will * not become the current version. @@ -585,37 +598,37 @@ 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); -/* +/*%< * Find the node with name 'name'. * * Notes: - * If 'create' is ISC_TRUE and no node with name 'name' exists, then + * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then * such a node will be created. * - * This routine is for finding or creating a node with the specified + * \li This routine is for finding or creating a node with the specified * name. There are no partial matches. It is not suitable for use * in building responses to ordinary DNS queries; clients which wish * to do that should use dns_db_find() instead. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'name' is a valid, non-empty, absolute name. + * \li 'name' is a valid, non-empty, absolute name. * - * nodep != NULL && *nodep == NULL + * \li nodep != NULL && *nodep == NULL * * Ensures: * - * On success, *nodep is attached to the node with name 'name'. + * \li On success, *nodep is attached to the node with name 'name'. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOTFOUND If !create and name not found. - * ISC_R_NOMEMORY Can only happen if create is ISC_TRUE. + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND If !create and name not found. + * \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE. * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ @@ -624,44 +637,44 @@ 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); -/* +/*%< * Find the best match for 'name' and 'type' in version 'version' of 'db'. * * Notes: * - * If type == dns_rdataset_any, then rdataset will not be bound. + * \li If type == dns_rdataset_any, then rdataset will not be bound. * - * If 'options' does not have DNS_DBFIND_GLUEOK set, then no glue will - * be returned. For zone databases, glue is as defined in RFC 2181. + * \li If 'options' does not have #DNS_DBFIND_GLUEOK set, then no glue will + * be returned. For zone databases, glue is as defined in RFC2181. * For cache databases, glue is any rdataset with a trust of * dns_trust_glue. * - * If 'options' does not have DNS_DBFIND_PENDINGOK set, then no + * \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no * pending data will be returned. This option is only meaningful for * cache databases. * - * If the DNS_DBFIND_NOWILD option is set, then wildcard matching will + * \li If the #DNS_DBFIND_NOWILD option is set, then wildcard matching will * be disabled. This option is only meaningful for zone databases. * - * If the DNS_DBFIND_FORCENSEC option is set, the database is assumed to + * \li If the #DNS_DBFIND_FORCENSEC option is set, the database is assumed to * have NSEC records, and these will be returned when appropriate. This * is only necessary when querying a database that was not secure * when created. * - * If the DNS_DBFIND_COVERINGNSEC option is set, then look for a + * \li If the DNS_DBFIND_COVERINGNSEC option is set, then look for a * NSEC record that potentially covers 'name' if a answer cannot * be found. Note the returned NSEC needs to be checked to ensure * that it is correct. This only affects answers returned from the * cache. * - * To respond to a query for SIG records, the caller should create a + * \li To respond to a query for SIG records, the caller should create a * rdataset iterator and extract the signatures from each rdataset. * - * Making queries of type ANY with DNS_DBFIND_GLUEOK is not recommended, + * \li Making queries of type ANY with #DNS_DBFIND_GLUEOK is not recommended, * because the burden of determining whether a given rdataset is valid * glue or not falls upon the caller. * - * The 'now' field is ignored if 'db' is a zone database. If 'db' is a + * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a * cache database, an rdataset will not be found unless it expires after * 'now'. Any ANY query will not match unless at least one rdataset at * the node expires after 'now'. If 'now' is zero, then the current time @@ -669,43 +682,41 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'type' is not SIG, or a meta-RR type other than 'ANY' (e.g. 'OPT'). + * \li 'type' is not SIG, or a meta-RR type other than 'ANY' (e.g. 'OPT'). * - * 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. + * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. * - * 'foundname' is a valid name with a dedicated buffer. + * \li 'foundname' is a valid name with a dedicated buffer. * - * 'rdataset' is NULL, or is a valid unassociated rdataset. + * \li 'rdataset' is NULL, or is a valid unassociated rdataset. * - * Ensures: - * On a non-error completion: + * Ensures, + * on a non-error completion: * - * If nodep != NULL, then it is bound to the found node. + * \li If nodep != NULL, then it is bound to the found node. * - * If foundname != NULL, then it contains the full name of the + * \li If foundname != NULL, then it contains the full name of the * found node. * - * If rdataset != NULL and type != dns_rdatatype_any, then + * \li If rdataset != NULL and type != dns_rdatatype_any, then * rdataset is bound to the found rdataset. * - * Returns: - * * Non-error results are: * - * ISC_R_SUCCESS The desired node and type were + * \li #ISC_R_SUCCESS The desired node and type were * found. * - * DNS_R_WILDCARD The desired node and type were + * \li #DNS_R_WILDCARD The desired node and type were * found after performing * wildcard matching. This is * only returned if the - * DNS_DBFIND_INDICATEWILD + * #DNS_DBFIND_INDICATEWILD * option is set; otherwise - * ISC_R_SUCCESS is returned. + * #ISC_R_SUCCESS is returned. * - * DNS_R_GLUE The desired node and type were + * \li #DNS_R_GLUE The desired node and type were * found, but are glue. This * result can only occur if * the DNS_DBFIND_GLUEOK option @@ -720,7 +731,7 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * take care not to return invalid * glue to a client. * - * DNS_R_DELEGATION The data requested is beneath + * \li #DNS_R_DELEGATION The data requested is beneath * a zone cut. node, foundname, * and rdataset reference the * NS RRset of the zone cut. @@ -728,7 +739,7 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * then this is the deepest known * delegation. * - * DNS_R_ZONECUT type == dns_rdatatype_any, and + * \li #DNS_R_ZONECUT type == dns_rdatatype_any, and * the desired node is a zonecut. * The caller must take care not * to return inappropriate glue @@ -737,24 +748,24 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * database and DNS_DBFIND_GLUEOK * is set. * - * DNS_R_DNAME The data requested is beneath + * \li #DNS_R_DNAME The data requested is beneath * a DNAME. node, foundname, * and rdataset reference the * DNAME RRset. * - * DNS_R_CNAME The rdataset requested was not + * \li #DNS_R_CNAME The rdataset requested was not * found, but there is a CNAME * at the desired name. node, * foundname, and rdataset * reference the CNAME RRset. * - * DNS_R_NXDOMAIN The desired name does not + * \li #DNS_R_NXDOMAIN The desired name does not * exist. * - * DNS_R_NXRRSET The desired name exists, but + * \li #DNS_R_NXRRSET The desired name exists, but * the desired type does not. * - * ISC_R_NOTFOUND The desired name does not + * \li #ISC_R_NOTFOUND The desired name does not * exist, and no delegation could * be found. This result can only * occur if 'db' is a cache @@ -762,34 +773,34 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * use its nameserver(s) of last * resort (e.g. root hints). * - * DNS_R_NCACHENXDOMAIN The desired name does not + * \li #DNS_R_NCACHENXDOMAIN The desired name does not * exist. 'node' is bound to the * cache node with the desired * name, and 'rdataset' contains * the negative caching proof. * - * DNS_R_NCACHENXRRSET The desired type does not + * \li #DNS_R_NCACHENXRRSET The desired type does not * exist. 'node' is bound to the * cache node with the desired * name, and 'rdataset' contains * the negative caching proof. * - * DNS_R_EMPTYNAME The name exists but there is + * \li #DNS_R_EMPTYNAME The name exists but there is * no data at the name. * - * DNS_R_COVERINGNSEC The returned data is a NSEC + * \li #DNS_R_COVERINGNSEC The returned data is a NSEC * that potentially covers 'name'. * * Error results: * - * ISC_R_NOMEMORY + * \li #ISC_R_NOMEMORY * - * DNS_R_BADDB Data that is required to be + * \li #DNS_R_BADDB Data that is required to be * present in the DB, e.g. an NSEC * record in a secure zone, is not * present. * - * Other results are possible, and should all be treated as + * \li Other results are possible, and should all be treated as * errors. */ @@ -798,100 +809,97 @@ dns_db_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); -/* +/*%< * Find the deepest known zonecut which encloses 'name' in 'db'. * * Notes: * - * If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned + * \li If the #DNS_DBFIND_NOEXACT option is set, then the zonecut returned * (if any) will be the deepest known ancestor of 'name'. * - * If 'now' is zero, then the current time will be used. + * \li If 'now' is zero, then the current time will be used. * * Requires: * - * 'db' is a valid database with cache semantics. + * \li 'db' is a valid database with cache semantics. * - * 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. + * \li 'nodep' is NULL, or nodep is a valid pointer and *nodep == NULL. * - * 'foundname' is a valid name with a dedicated buffer. + * \li 'foundname' is a valid name with a dedicated buffer. * - * 'rdataset' is NULL, or is a valid unassociated rdataset. + * \li 'rdataset' is NULL, or is a valid unassociated rdataset. * - * Ensures: - * On a non-error completion: + * Ensures, on a non-error completion: * - * If nodep != NULL, then it is bound to the found node. + * \li If nodep != NULL, then it is bound to the found node. * - * If foundname != NULL, then it contains the full name of the - * found node. + * \li If foundname != NULL, then it contains the full name of the + * found node. * - * If rdataset != NULL and type != dns_rdatatype_any, then - * rdataset is bound to the found rdataset. + * \li If rdataset != NULL and type != dns_rdatatype_any, then + * rdataset is bound to the found rdataset. * - * Returns: + * Non-error results are: * - * Non-error results are: - * - * ISC_R_SUCCESS + * \li #ISC_R_SUCCESS * - * ISC_R_NOTFOUND + * \li #ISC_R_NOTFOUND * - * Other results are possible, and should all be treated as - * errors. + * \li Other results are possible, and should all be treated as + * errors. */ void dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp); -/* +/*%< * Attach *targetp to source. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'source' is a valid node. + * \li 'source' is a valid node. * - * 'targetp' points to a NULL dns_node_t *. + * \li 'targetp' points to a NULL dns_node_t *. * * Ensures: * - * *targetp is attached to source. + * \li *targetp is attached to source. */ void dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep); -/* +/*%< * Detach *nodep from its node. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'nodep' points to a valid node. + * \li 'nodep' points to a valid node. * * Ensures: * - * *nodep is NULL. + * \li *nodep is NULL. */ isc_result_t dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now); -/* +/*%< * Mark as stale all records at 'node' which expire at or before 'now'. * * Note: if 'now' is zero, then the current time will be used. * * Requires: * - * 'db' is a valid cache database. + * \li 'db' is a valid cache database. * - * 'node' is a valid node. + * \li 'node' is a valid node. */ void dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out); -/* +/*%< * Print a textual representation of the contents of the node to * 'out'. * @@ -899,9 +907,9 @@ dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out); * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'node' is a valid node. + * \li 'node' is a valid node. */ /*** @@ -911,29 +919,29 @@ dns_db_printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out); isc_result_t dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names, dns_dbiterator_t **iteratorp); -/* +/*%< * Create an iterator for version 'version' of 'db'. * * Notes: * - * If 'relative_names' is ISC_TRUE, then node names returned by the + * \li If 'relative_names' is ISC_TRUE, then node names returned by the * iterator will be relative to the iterator's current origin. If - * ISC_FALSE, then the node names will be absolute. + * #ISC_FALSE, then the node names will be absolute. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * iteratorp != NULL && *iteratorp == NULL + * \li iteratorp != NULL && *iteratorp == NULL * * Ensures: * - * On success, *iteratorp will be a valid database iterator. + * \li On success, *iteratorp will be a valid database iterator. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY */ /*** @@ -949,62 +957,62 @@ 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. * * Notes: * - * If 'version' is NULL, then the current version will be used. + * \li If 'version' is NULL, then the current version will be used. * - * Care must be used when using this routine to build a DNS response: + * \li Care must be used when using this routine to build a DNS response: * 'node' should have been found with dns_db_find(), not * dns_db_findnode(). No glue checking is done. No checking for * pending data is done. * - * The 'now' field is ignored if 'db' is a zone database. If 'db' is a + * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a * cache database, an rdataset will not be found unless it expires after * 'now'. If 'now' is zero, then the current time will be used. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'node' is a valid node. + * \li 'node' is a valid node. * - * 'rdataset' is a valid, disassociated rdataset. + * \li 'rdataset' is a valid, disassociated rdataset. * - * 'sigrdataset' is a valid, disassociated rdataset, or it is NULL. + * \li 'sigrdataset' is a valid, disassociated rdataset, or it is NULL. * - * If 'covers' != 0, 'type' must be SIG. + * \li If 'covers' != 0, 'type' must be SIG. * - * 'type' is not a meta-RR type such as 'ANY' or 'OPT'. + * \li 'type' is not a meta-RR type such as 'ANY' or 'OPT'. * * Ensures: * - * On success, 'rdataset' is associated with the found rdataset. + * \li On success, 'rdataset' is associated with the found rdataset. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp); -/* +/*%< * Make '*iteratorp' an rdataset iteratator for all rdatasets at 'node' in * version 'version' of 'db'. * * Notes: * - * If 'version' is NULL, then the current version will be used. + * \li If 'version' is NULL, then the current version will be used. * - * The 'now' field is ignored if 'db' is a zone database. If 'db' is a + * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is a * cache database, an rdataset will not be found unless it expires after * 'now'. Any ANY query will not match unless at least one rdataset at * the node expires after 'now'. If 'now' is zero, then the current time @@ -1012,22 +1020,22 @@ dns_db_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'node' is a valid node. + * \li 'node' is a valid node. * - * iteratorp != NULL && *iteratorp == NULL + * \li iteratorp != NULL && *iteratorp == NULL * * Ensures: * - * On success, '*iteratorp' is a valid rdataset iterator. + * \li On success, '*iteratorp' is a valid rdataset iterator. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ @@ -1035,58 +1043,58 @@ isc_result_t dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *addedrdataset); -/* +/*%< * Add 'rdataset' to 'node' in version 'version' of 'db'. * * Notes: * - * If the database has zone semantics, the DNS_DBADD_MERGE option is set, + * \li If the database has zone semantics, the #DNS_DBADD_MERGE option is set, * and an rdataset of the same type as 'rdataset' already exists at * 'node' then the contents of 'rdataset' will be merged with the existing * rdataset. If the option is not set, then rdataset will replace any * existing rdataset of the same type. If not merging and the - * DNS_DBADD_FORCE option is set, then the data will update the database + * #DNS_DBADD_FORCE option is set, then the data will update the database * without regard to trust levels. If not forcing the data, then the * rdataset will only be added if its trust level is >= the trust level of * any existing rdataset. Forcing is only meaningful for cache databases. - * If DNS_DBADD_EXACT is set then there must be no rdata in common between - * the old and new rdata sets. If DNS_DBADD_EXACTTTL is set then both + * If #DNS_DBADD_EXACT is set then there must be no rdata in common between + * the old and new rdata sets. If #DNS_DBADD_EXACTTTL is set then both * the old and new rdata sets must have the same ttl. * - * The 'now' field is ignored if 'db' is a zone database. If 'db' is + * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is * a cache database, then the added rdataset will expire no later than * now + rdataset->ttl. * - * If 'addedrdataset' is not NULL, then it will be attached to the + * \li If 'addedrdataset' is not NULL, then it will be attached to the * resulting new rdataset in the database, or to the existing data if * the existing data was better. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'node' is a valid node. + * \li 'node' is a valid node. * - * 'rdataset' is a valid, associated rdataset with the same class + * \li 'rdataset' is a valid, associated rdataset with the same class * as 'db'. * - * 'addedrdataset' is NULL, or a valid, unassociated rdataset. + * \li 'addedrdataset' is NULL, or a valid, unassociated rdataset. * - * The database has zone semantics and 'version' is a valid + * \li The database has zone semantics and 'version' is a valid * read-write version, or the database has cache semantics * and version is NULL. * - * If the database has cache semantics, the DNS_DBADD_MERGE option must + * \li If the database has cache semantics, the #DNS_DBADD_MERGE option must * not be set. * * Returns: * - * ISC_R_SUCCESS - * DNS_R_UNCHANGED The operation did not change anything. - * ISC_R_NOMEMORY - * DNS_R_NOTEXACT + * \li #ISC_R_SUCCESS + * \li #DNS_R_UNCHANGED The operation did not change anything. + * \li #ISC_R_NOMEMORY + * \li #DNS_R_NOTEXACT * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ @@ -1094,41 +1102,41 @@ isc_result_t dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_t *rdataset, unsigned int options, dns_rdataset_t *newrdataset); -/* +/*%< * Remove any rdata in 'rdataset' from 'node' in version 'version' of * 'db'. * * Notes: * - * If 'newrdataset' is not NULL, then it will be attached to the + * \li If 'newrdataset' is not NULL, then it will be attached to the * resulting new rdataset in the database, unless the rdataset has * become nonexistent. If DNS_DBSUB_EXACT is set then all elements * of 'rdataset' must exist at 'node'. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'node' is a valid node. + * \li 'node' is a valid node. * - * 'rdataset' is a valid, associated rdataset with the same class + * \li 'rdataset' is a valid, associated rdataset with the same class * as 'db'. * - * 'newrdataset' is NULL, or a valid, unassociated rdataset. + * \li 'newrdataset' is NULL, or a valid, unassociated rdataset. * - * The database has zone semantics and 'version' is a valid + * \li The database has zone semantics and 'version' is a valid * read-write version. * * Returns: * - * ISC_R_SUCCESS - * DNS_R_UNCHANGED The operation did not change anything. - * DNS_R_NXRRSET All rdata of the same type as those + * \li #ISC_R_SUCCESS + * \li #DNS_R_UNCHANGED The operation did not change anything. + * \li #DNS_R_NXRRSET All rdata of the same type as those * in 'rdataset' have been deleted. - * DNS_R_NOTEXACT Some part of 'rdataset' did not + * \li #DNS_R_NOTEXACT Some part of 'rdataset' did not * exist and DNS_DBSUB_EXACT was set. * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ @@ -1136,134 +1144,154 @@ isc_result_t dns_db_deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, dns_rdatatype_t covers); -/* +/*%< * Make it so that no rdataset of type 'type' exists at 'node' in version * version 'version' of 'db'. * * Notes: * - * If 'type' is dns_rdatatype_any, then no rdatasets will exist in + * \li If 'type' is dns_rdatatype_any, then no rdatasets will exist in * 'version' (provided that the dns_db_deleterdataset() isn't followed * by one or more dns_db_addrdataset() calls). * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * - * 'node' is a valid node. + * \li 'node' is a valid node. * - * The database has zone semantics and 'version' is a valid + * \li The database has zone semantics and 'version' is a valid * read-write version, or the database has cache semantics * and version is NULL. * - * 'type' is not a meta-RR type, except for dns_rdatatype_any, which is + * \li 'type' is not a meta-RR type, except for dns_rdatatype_any, which is * allowed. * - * If 'covers' != 0, 'type' must be SIG. + * \li If 'covers' != 0, 'type' must be SIG. * * Returns: * - * ISC_R_SUCCESS - * DNS_R_UNCHANGED No rdatasets of 'type' existed before + * \li #ISC_R_SUCCESS + * \li #DNS_R_UNCHANGED No rdatasets of 'type' existed before * the operation was attempted. * - * Other results are possible, depending upon the database + * \li Other results are possible, depending upon the database * implementation used. */ isc_result_t dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp); -/* +/*%< * Get the current SOA serial number from a zone database. * * Requires: - * 'db' is a valid database with zone semantics. - * 'ver' is a valid version. + * \li 'db' is a valid database with zone semantics. + * \li 'ver' is a valid version. */ void dns_db_overmem(dns_db_t *db, isc_boolean_t overmem); -/* +/*%< * Enable / disable agressive cache cleaning. */ unsigned int dns_db_nodecount(dns_db_t *db); -/* +/*%< * Count the number of nodes in 'db'. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: - * The number of nodes in the database + * \li The number of nodes in the database */ void dns_db_settask(dns_db_t *db, isc_task_t *task); -/* +/*%< * If task is set then the final detach maybe performed asynchronously. * * Requires: - * 'db' is a valid database. - * 'task' to be valid or NULL. + * \li 'db' is a valid database. + * \li 'task' to be valid or NULL. */ isc_boolean_t dns_db_ispersistent(dns_db_t *db); -/* +/*%< * Is 'db' persistent? A persistent database does not need to be loaded * from disk or written to disk. * * Requires: * - * 'db' is a valid database. + * \li 'db' is a valid database. * * Returns: - * ISC_TRUE 'db' is persistent. - * ISC_FALSE 'db' is not persistent. + * \li #ISC_TRUE 'db' is persistent. + * \li #ISC_FALSE 'db' is not persistent. */ isc_result_t dns_db_register(const char *name, dns_dbcreatefunc_t create, void *driverarg, isc_mem_t *mctx, dns_dbimplementation_t **dbimp); -/* +/*%< * Register a new database implementation and add it to the list of * supported implementations. * * Requires: * - * 'name' is not NULL - * 'order' is a valid function pointer - * 'mctx' is a valid memory context - * dbimp != NULL && *dbimp == NULL + * \li 'name' is not NULL + * \li 'order' is a valid function pointer + * \li 'mctx' is a valid memory context + * \li dbimp != NULL && *dbimp == NULL * * Returns: - * ISC_R_SUCCESS The registration succeeded - * ISC_R_NOMEMORY Out of memory - * ISC_R_EXISTS A database implementation with the same name exists + * \li #ISC_R_SUCCESS The registration succeeded + * \li #ISC_R_NOMEMORY Out of memory + * \li #ISC_R_EXISTS A database implementation with the same name exists * * Ensures: * - * *dbimp points to an opaque structure which must be passed to + * \li *dbimp points to an opaque structure which must be passed to * dns_db_unregister(). */ void dns_db_unregister(dns_dbimplementation_t **dbimp); -/* +/*%< * Remove a database implementation from the the list of supported * implementations. No databases of this type can be active when this * is called. * * Requires: - * dbimp != NULL && *dbimp == NULL + * \li dbimp != NULL && *dbimp == NULL * * Ensures: * - * Any memory allocated in *dbimp will be freed. + * \li Any memory allocated in *dbimp will be freed. + */ + +isc_result_t +dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep); +/*%< + * Get the origin DB node corresponding to the DB's zone. This function + * should typically succeed unless the underlying DB implementation doesn't + * support the feature. + * + * Requires: + * + * \li 'db' is a valid zone database. + * \li 'nodep' != NULL && '*nodep' == NULL + * + * Ensures: + * \li On success, '*nodep' will point to the DB node of the zone's origin. + * + * Returns: + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND - the DB implementation does not support this feature. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/dbiterator.h b/contrib/bind9/lib/dns/include/dns/dbiterator.h index 8b8cb1b..47ce082 100644 --- a/contrib/bind9/lib/dns/include/dns/dbiterator.h +++ b/contrib/bind9/lib/dns/include/dns/dbiterator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dbiterator.h,v 1.18.206.1 2004/03/06 08:13:54 marka Exp $ */ +/* $Id: dbiterator.h,v 1.19.18.2 2005/04/29 00:16:11 marka Exp $ */ #ifndef DNS_DBITERATOR_H #define DNS_DBITERATOR_H 1 @@ -24,9 +24,8 @@ ***** Module Info *****/ -/* - * DNS DB Iterator - * +/*! \file + * \brief * The DNS DB Iterator interface allows iteration of all of the nodes in a * database. * @@ -37,25 +36,25 @@ * It is the client's responsibility to call dns_db_detachnode() on all * nodes returned. * - * XXX <more> XXX + * XXX <more> XXX * * MP: - * The iterator itself is not locked. The caller must ensure + *\li The iterator itself is not locked. The caller must ensure * synchronization. * - * The iterator methods ensure appropriate database locking. + *\li The iterator methods ensure appropriate database locking. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ /***** @@ -89,7 +88,7 @@ typedef struct dns_dbiteratormethods { #define DNS_DBITERATOR_MAGIC ISC_MAGIC('D','N','S','I') #define DNS_DBITERATOR_VALID(dbi) ISC_MAGIC_VALID(dbi, DNS_DBITERATOR_MAGIC) -/* +/*% * This structure is actually just the common prefix of a DNS db * implementation's version of a dns_dbiterator_t. * @@ -110,136 +109,136 @@ struct dns_dbiterator { void dns_dbiterator_destroy(dns_dbiterator_t **iteratorp); -/* +/*%< * Destroy '*iteratorp'. * * Requires: * - * '*iteratorp' is a valid iterator. + *\li '*iteratorp' is a valid iterator. * * Ensures: * - * All resources used by the iterator are freed. + *\li All resources used by the iterator are freed. * - * *iteratorp == NULL. + *\li *iteratorp == NULL. */ isc_result_t dns_dbiterator_first(dns_dbiterator_t *iterator); -/* +/*%< * Move the node cursor to the first node in the database (if any). * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no nodes in the database. + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no nodes in the database. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_last(dns_dbiterator_t *iterator); -/* +/*%< * Move the node cursor to the last node in the database (if any). * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no nodes in the database. + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no nodes in the database. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name); -/* +/*%< * Move the node cursor to the node with name 'name'. * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * - * 'name' is a valid name. + *\li 'name' is a valid name. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOTFOUND * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_prev(dns_dbiterator_t *iterator); -/* +/*%< * Move the node cursor to the previous node in the database (if any). * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no more nodes in the + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no more nodes in the * database. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_next(dns_dbiterator_t *iterator); -/* +/*%< * Move the node cursor to the next node in the database (if any). * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no more nodes in the + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no more nodes in the * database. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, dns_name_t *name); -/* +/*%< * Return the current node. * * Notes: - * If 'name' is not NULL, it will be set to the name of the node. + *\li If 'name' is not NULL, it will be set to the name of the node. * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * - * nodep != NULL && *nodep == NULL + *\li nodep != NULL && *nodep == NULL * - * The node cursor of 'iterator' is at a valid location (i.e. the + *\li The node cursor of 'iterator' is at a valid location (i.e. the * result of last call to a cursor movement command was ISC_R_SUCCESS). * - * 'name' is NULL, or is a valid name with a dedicated buffer. + *\li 'name' is NULL, or is a valid name with a dedicated buffer. * * Returns: * - * ISC_R_SUCCESS - * DNS_R_NEWORIGIN If this iterator was created with + *\li #ISC_R_SUCCESS + *\li #DNS_R_NEWORIGIN If this iterator was created with * 'relative_names' set to ISC_TRUE, - * then DNS_R_NEWORIGIN will be returned + * then #DNS_R_NEWORIGIN will be returned * when the origin the names are * relative to changes. This result * can occur only when 'name' is not * NULL. This is also a successful * result. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_pause(dns_dbiterator_t *iterator); -/* +/*%< * Pause iteration. * * Calling a cursor movement method or dns_dbiterator_current() may cause @@ -250,47 +249,47 @@ dns_dbiterator_pause(dns_dbiterator_t *iterator); * iterator method in the immediate future. * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Ensures: - * Any database locks being held for efficiency of iterator access are + *\li Any database locks being held for efficiency of iterator access are * released. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name); -/* +/*%< * Return the origin to which returned node names are relative. * * Requires: * - * 'iterator' is a valid relative_names iterator. + *\li 'iterator' is a valid relative_names iterator. * - * 'name' is a valid name with a dedicated buffer. + *\li 'name' is a valid name with a dedicated buffer. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOSPACE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ void dns_dbiterator_setcleanmode(dns_dbiterator_t *iterator, isc_boolean_t mode); -/* +/*%< * Indicate that the given iterator is/is not cleaning the DB. * * Notes: - * When 'mode' is ISC_TRUE, + *\li When 'mode' is ISC_TRUE, * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/dbtable.h b/contrib/bind9/lib/dns/include/dns/dbtable.h index 3874b46..18d3e50 100644 --- a/contrib/bind9/lib/dns/include/dns/dbtable.h +++ b/contrib/bind9/lib/dns/include/dns/dbtable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dbtable.h,v 1.16.206.1 2004/03/06 08:13:55 marka Exp $ */ +/* $Id: dbtable.h,v 1.17.18.2 2005/04/29 00:16:11 marka Exp $ */ #ifndef DNS_DBTABLE_H #define DNS_DBTABLE_H 1 @@ -24,26 +24,27 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * DNS DB Tables * - * XXX <TBS> XXX + * XXX TBS XXX * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * None. + *\li None. * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ #include <isc/lang.h> @@ -57,106 +58,106 @@ ISC_LANG_BEGINDECLS isc_result_t dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_dbtable_t **dbtablep); -/* +/*%< * Make a new dbtable of class 'rdclass' * * Requires: - * mctx != NULL - * dbtablep != NULL && *dptablep == NULL - * 'rdclass' is a valid class + *\li mctx != NULL + * \li dbtablep != NULL && *dptablep == NULL + *\li 'rdclass' is a valid class * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_UNEXPECTED + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_UNEXPECTED */ void dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp); -/* +/*%< * Attach '*targetp' to 'source'. * * Requires: * - * 'source' is a valid dbtable. + *\li 'source' is a valid dbtable. * - * 'targetp' points to a NULL dns_dbtable_t *. + *\li 'targetp' points to a NULL dns_dbtable_t *. * * Ensures: * - * *targetp is attached to source. + *\li *targetp is attached to source. */ void dns_dbtable_detach(dns_dbtable_t **dbtablep); -/* +/*%< * Detach *dbtablep from its dbtable. * * Requires: * - * '*dbtablep' points to a valid dbtable. + *\li '*dbtablep' points to a valid dbtable. * * Ensures: * - * *dbtablep is NULL. - * - * If '*dbtablep' is the last reference to the dbtable, + *\li *dbtablep is NULL. * - * All resources used by the dbtable will be freed + *\li If '*dbtablep' is the last reference to the dbtable, + * all resources used by the dbtable will be freed */ isc_result_t dns_dbtable_add(dns_dbtable_t *dbtable, dns_db_t *db); -/* +/*%< * Add 'db' to 'dbtable'. * * Requires: - * 'dbtable' is a valid dbtable. + *\li 'dbtable' is a valid dbtable. * - * 'db' is a valid database with the same class as 'dbtable' + *\li 'db' is a valid database with the same class as 'dbtable' */ void dns_dbtable_remove(dns_dbtable_t *dbtable, dns_db_t *db); -/* +/*%< * Remove 'db' from 'dbtable'. * * Requires: - * 'db' was previously added to 'dbtable'. + *\li 'db' was previously added to 'dbtable'. */ void dns_dbtable_adddefault(dns_dbtable_t *dbtable, dns_db_t *db); -/* +/*%< * Use 'db' as the result of a dns_dbtable_find() if no better match is * available. */ void dns_dbtable_getdefault(dns_dbtable_t *dbtable, dns_db_t **db); -/* +/*%< * Get the 'db' used as the result of a dns_dbtable_find() * if no better match is available. */ void dns_dbtable_removedefault(dns_dbtable_t *dbtable); -/* +/*%< * Remove the default db from 'dbtable'. */ isc_result_t dns_dbtable_find(dns_dbtable_t *dbtable, dns_name_t *name, unsigned int options, dns_db_t **dbp); -/* +/*%< * Find the deepest match to 'name' in the dbtable, and return it * * Notes: - * If the DNS_DBTABLEFIND_NOEXACT option is set, the best partial + *\li If the DNS_DBTABLEFIND_NOEXACT option is set, the best partial * match (if any) to 'name' will be returned. * - * Returns: ISC_R_SUCCESS on success - * <something else> no default and match + * Returns: + * \li #ISC_R_SUCCESS on success + *\li something else: no default and match */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/diff.h b/contrib/bind9/lib/dns/include/dns/diff.h index 604f702..cd96a0b 100644 --- a/contrib/bind9/lib/dns/include/dns/diff.h +++ b/contrib/bind9/lib/dns/include/dns/diff.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: diff.h,v 1.4.12.3 2004/03/08 09:04:35 marka Exp $ */ +/* $Id: diff.h,v 1.6.18.2 2005/04/29 00:16:12 marka Exp $ */ #ifndef DNS_DIFF_H #define DNS_DIFF_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * A diff is a convenience type representing a list of changes to be * made to a database. */ @@ -44,7 +45,7 @@ *** Types ***/ -/* +/*% * A dns_difftuple_t represents a single RR being added or deleted. * The RR type and class are in the 'rdata' member; the class is always * the real one, not a DynDNS meta-class, so that the rdatas can be @@ -61,9 +62,9 @@ */ typedef enum { - DNS_DIFFOP_ADD, /* Add an RR. */ - DNS_DIFFOP_DEL, /* Delete an RR. */ - DNS_DIFFOP_EXISTS /* Assert RR existence. */ + DNS_DIFFOP_ADD, /*%< Add an RR. */ + DNS_DIFFOP_DEL, /*%< Delete an RR. */ + DNS_DIFFOP_EXISTS /*%< Assert RR existence. */ } dns_diffop_t; typedef struct dns_difftuple dns_difftuple_t; @@ -82,7 +83,7 @@ struct dns_difftuple { /* Variable-size name data and rdata follows. */ }; -/* +/*% * A dns_diff_t represents a set of changes being applied to * a zone. Diffs are also used to represent "RRset exists * (value dependent)" prerequisites. @@ -116,106 +117,106 @@ isc_result_t dns_difftuple_create(isc_mem_t *mctx, dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata, dns_difftuple_t **tp); -/* +/*%< * Create a tuple. Deep copies are made of the name and rdata, so * they need not remain valid after the call. * * Requires: - * *tp != NULL && *tp == NULL. + *\li *tp != NULL && *tp == NULL. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li ISC_R_SUCCESS + * \li ISC_R_NOMEMORY */ void dns_difftuple_free(dns_difftuple_t **tp); -/* +/*%< * Free a tuple. * * Requires: - * **tp is a valid tuple. + * \li **tp is a valid tuple. * * Ensures: - * *tp == NULL - * All memory used by the tuple is freed. + * \li *tp == NULL + * \li All memory used by the tuple is freed. */ isc_result_t dns_difftuple_copy(dns_difftuple_t *orig, dns_difftuple_t **copyp); -/* +/*%< * Copy a tuple. * * Requires: - * 'orig' points to a valid tuple - * copyp != NULL && *copyp == NULL + * \li 'orig' points to a valid tuple + *\li copyp != NULL && *copyp == NULL */ void dns_diff_init(isc_mem_t *mctx, dns_diff_t *diff); -/* +/*%< * Initialize a diff. * * Requires: - * 'diff' points to an uninitialized dns_diff_t - * allocated by the caller. + * \li 'diff' points to an uninitialized dns_diff_t + * \li allocated by the caller. * * Ensures: - * '*diff' is a valid, empty diff. + * \li '*diff' is a valid, empty diff. */ void dns_diff_clear(dns_diff_t *diff); -/* +/*%< * Clear a diff, destroying all its tuples. * * Requires: - * 'diff' points to a valid dns_diff_t. + * \li 'diff' points to a valid dns_diff_t. * * Ensures: - * Any tuples in the diff are destroyed. + * \li Any tuples in the diff are destroyed. * The diff now empty, but it is still valid * and may be reused without calling dns_diff_init * again. The only memory used is that of the * dns_diff_t structure itself. * * Notes: - * Managing the memory of the dns_diff_t structure itself + * \li Managing the memory of the dns_diff_t structure itself * is the caller's responsibility. */ void dns_diff_append(dns_diff_t *diff, dns_difftuple_t **tuple); -/* +/*%< * Append a single tuple to a diff. * - * 'diff' is a valid diff. - * '*tuple' is a valid tuple. + *\li 'diff' is a valid diff. + * \li '*tuple' is a valid tuple. * * Ensures: - * *tuple is NULL. - * The tuple has been freed, or will be freed when the diff is cleared. + *\li *tuple is NULL. + *\li The tuple has been freed, or will be freed when the diff is cleared. */ void dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuple); -/* +/*%< * Append 'tuple' to 'diff', removing any duplicate * or conflicting updates as needed to create a minimal diff. * * Requires: - * 'diff' is a minimal diff. + *\li 'diff' is a minimal diff. * * Ensures: - * 'diff' is still a minimal diff. - * *tuple is NULL. - * The tuple has been freed, or will be freed when the diff is cleared. + *\li 'diff' is still a minimal diff. + * \li *tuple is NULL. + * \li The tuple has been freed, or will be freed when the diff is cleared. * */ isc_result_t dns_diff_sort(dns_diff_t *diff, dns_diff_compare_func *compare); -/* +/*%< * Sort 'diff' in-place according to the comparison function 'compare'. */ @@ -223,7 +224,7 @@ isc_result_t dns_diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); isc_result_t dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); -/* +/*%< * Apply 'diff' to the database 'db'. * * dns_diff_apply() logs warnings about updates with no effect or @@ -234,44 +235,44 @@ dns_diff_applysilently(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver); * but less efficient. * * Requires: - * *diff is a valid diff (possibly empty), containing - * tuples of type DNS_DIFFOP_ADD and/or - * For DNS_DIFFOP_DEL tuples, the TTL is ignored. + *\li *diff is a valid diff (possibly empty), containing + * tuples of type #DNS_DIFFOP_ADD and/or + * For #DNS_DIFFOP_DEL tuples, the TTL is ignored. * */ isc_result_t dns_diff_load(dns_diff_t *diff, dns_addrdatasetfunc_t addfunc, void *add_private); -/* +/*%< * Like dns_diff_apply, but for use when loading a new database * instead of modifying an existing one. This bypasses the * database transaction mechanisms. * * Requires: - * 'addfunc' is a valid dns_addradatasetfunc_t obtained from + *\li 'addfunc' is a valid dns_addradatasetfunc_t obtained from * dns_db_beginload() * - * 'add_private' points to a corresponding dns_dbload_t * + *\li 'add_private' points to a corresponding dns_dbload_t * * (XXX why is it a void pointer, then?) */ isc_result_t dns_diff_print(dns_diff_t *diff, FILE *file); -/* +/*%< * Print the differences to 'file' or if 'file' is NULL via the * logging system. * * Require: - * 'diff' to be valid. - * 'file' to refer to a open file or NULL. + *\li 'diff' to be valid. + *\li 'file' to refer to a open file or NULL. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_UNEXPECTED - * any error from dns_rdataset_totext() + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_UNEXPECTED + *\li any error from dns_rdataset_totext() */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/dispatch.h b/contrib/bind9/lib/dns/include/dns/dispatch.h index 201a65a..47f6b20 100644 --- a/contrib/bind9/lib/dns/include/dns/dispatch.h +++ b/contrib/bind9/lib/dns/include/dns/dispatch.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.h,v 1.45.2.2.4.2 2004/03/06 08:13:55 marka Exp $ */ +/* $Id: dispatch.h,v 1.48.18.2 2005/04/29 00:16:12 marka Exp $ */ #ifndef DNS_DISPATCH_H #define DNS_DISPATCH_H 1 @@ -24,14 +24,14 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * DNS Dispatch Management - * * Shared UDP and single-use TCP dispatches for queries and responses. * * MP: * - * All locking is performed internally to each dispatch. + *\li All locking is performed internally to each dispatch. * Restrictions apply to dns_dispatch_removeresponse(). * * Reliability: @@ -40,12 +40,12 @@ * * Security: * - * Depends on the isc_socket_t and dns_message_t for prevention of + *\li Depends on the isc_socket_t and dns_message_t for prevention of * buffer overruns. * * Standards: * - * None. + *\li None. */ /*** @@ -61,7 +61,7 @@ ISC_LANG_BEGINDECLS -/* +/*% * This event is sent to a task when a response comes in. * No part of this structure should ever be modified by the caller, * other than parts of the buffer. The holy parts of the buffer are @@ -79,16 +79,17 @@ ISC_LANG_BEGINDECLS */ struct dns_dispatchevent { - ISC_EVENT_COMMON(dns_dispatchevent_t); /* standard event common */ - isc_result_t result; /* result code */ - isc_int32_t id; /* message id */ - isc_sockaddr_t addr; /* address recv'd from */ - struct in6_pktinfo pktinfo; /* reply info for v6 */ - isc_buffer_t buffer; /* data buffer */ - isc_uint32_t attributes; /* mirrored from socket.h */ + ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */ + isc_result_t result; /*%< result code */ + isc_int32_t id; /*%< message id */ + isc_sockaddr_t addr; /*%< address recv'd from */ + struct in6_pktinfo pktinfo; /*%< reply info for v6 */ + isc_buffer_t buffer; /*%< data buffer */ + isc_uint32_t attributes; /*%< mirrored from socket.h */ }; -/* +/*@{*/ +/*% * Attributes for added dispatchers. * * Values with the mask 0xffff0000 are application defined. @@ -121,83 +122,84 @@ struct dns_dispatchevent { #define DNS_DISPATCHATTR_NOLISTEN 0x00000020U #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U #define DNS_DISPATCHATTR_CONNECTED 0x00000080U +/*@}*/ isc_result_t dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, dns_dispatchmgr_t **mgrp); -/* +/*%< * Creates a new dispatchmgr object. * * Requires: - * "mctx" be a valid memory context. + *\li "mctx" be a valid memory context. * - * mgrp != NULL && *mgrp == NULL + *\li mgrp != NULL && *mgrp == NULL * - * "entropy" may be NULL, in which case an insecure random generator + *\li "entropy" may be NULL, in which case an insecure random generator * will be used. If it is non-NULL, it must be a valid entropy * source. * * Returns: - * ISC_R_SUCCESS -- all ok + *\li ISC_R_SUCCESS -- all ok * - * anything else -- failure + *\li anything else -- failure */ void dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp); -/* +/*%< * Destroys the dispatchmgr when it becomes empty. This could be * immediately. * * Requires: - * mgrp != NULL && *mgrp is a valid dispatchmgr. + *\li mgrp != NULL && *mgrp is a valid dispatchmgr. */ void dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole); -/* +/*%< * Sets the dispatcher's "blackhole list," a list of addresses that will * be ignored by all dispatchers created by the dispatchmgr. * * Requires: - * mgrp is a valid dispatchmgr - * blackhole is a valid acl + * \li mgrp is a valid dispatchmgr + * \li blackhole is a valid acl */ dns_acl_t * dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr); -/* +/*%< * Gets a pointer to the dispatcher's current blackhole list, * without incrementing its reference count. * * Requires: - * mgr is a valid dispatchmgr + *\li mgr is a valid dispatchmgr * Returns: - * A pointer to the current blackhole list, or NULL. + *\li A pointer to the current blackhole list, or NULL. */ void dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, dns_portlist_t *portlist); -/* +/*%< * Sets a list of UDP ports that won't be used when creating a udp * dispatch with a wildcard port. * * Requires: - * mgr is a valid dispatchmgr - * portlist to be NULL or a valid port list. + *\li mgr is a valid dispatchmgr + *\li portlist to be NULL or a valid port list. */ dns_portlist_t * dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr); -/* +/*%< * Return the current port list. * * Requires: - * mgr is a valid dispatchmgr + *\li mgr is a valid dispatchmgr */ @@ -210,29 +212,29 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp); -/* +/*%< * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, * otherwise create a new UDP dispatch. * * Requires: - * All pointer parameters be valid for their respective types. + *\li All pointer parameters be valid for their respective types. * - * dispp != NULL && *disp == NULL + *\li dispp != NULL && *disp == NULL * - * 512 <= buffersize <= 64k + *\li 512 <= buffersize <= 64k * - * maxbuffers > 0 + *\li maxbuffers > 0 * - * buckets < 2097169 + *\li buckets < 2097169 * - * increment > buckets + *\li increment > buckets * - * (attributes & DNS_DISPATCHATTR_TCP) == 0 + *\li (attributes & DNS_DISPATCHATTR_TCP) == 0 * * Returns: - * ISC_R_SUCCESS -- success. + *\li ISC_R_SUCCESS -- success. * - * Anything else -- failure. + *\li Anything else -- failure. */ isc_result_t @@ -241,7 +243,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, dns_dispatch_t **dispp); -/* +/*%< * Create a new dns_dispatch and attach it to the provided isc_socket_t. * * For all dispatches, "buffersize" is the maximum packet size we will @@ -258,65 +260,65 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, * * Requires: * - * mgr is a valid dispatch manager. + *\li mgr is a valid dispatch manager. * - * sock is a valid. + *\li sock is a valid. * - * task is a valid task that can be used internally to this dispatcher. + *\li task is a valid task that can be used internally to this dispatcher. * - * 512 <= buffersize <= 64k + * \li 512 <= buffersize <= 64k * - * maxbuffers > 0. + *\li maxbuffers > 0. * - * maxrequests <= maxbuffers. + *\li maxrequests <= maxbuffers. * - * buckets < 2097169 (the next prime after 65536 * 32) + *\li buckets < 2097169 (the next prime after 65536 * 32) * - * increment > buckets (and prime). + *\li increment > buckets (and prime). * - * attributes includes DNS_DISPATCHATTR_TCP and does not include - * DNS_DISPATCHATTR_UDP. + *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include + * #DNS_DISPATCHATTR_UDP. * * Returns: - * ISC_R_SUCCESS -- success. + *\li ISC_R_SUCCESS -- success. * - * Anything else -- failure. + *\li Anything else -- failure. */ void dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp); -/* +/*%< * Attach to a dispatch handle. * * Requires: - * disp is valid. + *\li disp is valid. * - * dispp != NULL && *dispp == NULL + *\li dispp != NULL && *dispp == NULL */ void dns_dispatch_detach(dns_dispatch_t **dispp); -/* +/*%< * Detaches from the dispatch. * * Requires: - * dispp != NULL and *dispp be a valid dispatch. + *\li dispp != NULL and *dispp be a valid dispatch. */ void dns_dispatch_starttcp(dns_dispatch_t *disp); -/* +/*%< * Start processing of a TCP dispatch once the socket connects. * * Requires: - * 'disp' is valid. + *\li 'disp' is valid. */ isc_result_t dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, isc_task_t *task, isc_taskaction_t action, void *arg, isc_uint16_t *idp, dns_dispentry_t **resp); -/* +/*%< * Add a response entry for this dispatch. * * "*idp" is filled in with the assigned message ID, and *resp is filled in @@ -327,24 +329,24 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, * or through dns_dispatch_removeresponse() for another to be delivered. * * Requires: - * "idp" be non-NULL. + *\li "idp" be non-NULL. * - * "task" "action" and "arg" be set as appropriate. + *\li "task" "action" and "arg" be set as appropriate. * - * "dest" be non-NULL and valid. + *\li "dest" be non-NULL and valid. * - * "resp" be non-NULL and *resp be NULL + *\li "resp" be non-NULL and *resp be NULL * * Ensures: * - * <id, dest> is a unique tuple. That means incoming messages + *\li <id, dest> is a unique tuple. That means incoming messages * are identifiable. * * Returns: * - * ISC_R_SUCCESS -- all is well. - * ISC_R_NOMEMORY -- memory could not be allocated. - * ISC_R_NOMORE -- no more message ids can be allocated + *\li ISC_R_SUCCESS -- all is well. + *\li ISC_R_NOMEMORY -- memory could not be allocated. + *\li ISC_R_NOMORE -- no more message ids can be allocated * for this destination. */ @@ -352,88 +354,90 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, void dns_dispatch_removeresponse(dns_dispentry_t **resp, dns_dispatchevent_t **sockevent); -/* +/*%< * Stops the flow of responses for the provided id and destination. * If "sockevent" is non-NULL, the dispatch event and associated buffer is * also returned to the system. * * Requires: - * "resp" != NULL and "*resp" contain a value previously allocated + *\li "resp" != NULL and "*resp" contain a value previously allocated * by dns_dispatch_addresponse(); * - * May only be called from within the task given as the 'task' + *\li May only be called from within the task given as the 'task' * argument to dns_dispatch_addresponse() when allocating '*resp'. */ isc_socket_t * dns_dispatch_getsocket(dns_dispatch_t *disp); -/* +/*%< * Return the socket associated with this dispatcher. * * Requires: - * disp is valid. + *\li disp is valid. * * Returns: - * The socket the dispatcher is using. + *\li The socket the dispatcher is using. */ isc_result_t dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp); -/* +/*%< * Return the local address for this dispatch. * This currently only works for dispatches using UDP sockets. * * Requires: - * disp is valid. - * addrp to be non null. + *\li disp is valid. + *\li addrp to be non null. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTIMPLEMENTED + *\li ISC_R_SUCCESS + *\li ISC_R_NOTIMPLEMENTED */ void dns_dispatch_cancel(dns_dispatch_t *disp); -/* +/*%< * cancel outstanding clients * * Requires: - * disp is valid. + *\li disp is valid. */ void dns_dispatch_changeattributes(dns_dispatch_t *disp, unsigned int attributes, unsigned int mask); -/* +/*%< * Set the bits described by "mask" to the corresponding values in * "attributes". * * That is: * + * \code * new = (old & ~mask) | (attributes & mask) + * \endcode * - * This function has a side effect when DNS_DISPATCHATTR_NOLISTEN changes. + * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes. * When the flag becomes off, the dispatch will start receiving on the * corresponding socket. When the flag becomes on, receive events on the * corresponding socket will be canceled. * * Requires: - * disp is valid. + *\li disp is valid. * - * attributes are reasonable for the dispatch. That is, setting the UDP + *\li attributes are reasonable for the dispatch. That is, setting the UDP * attribute on a TCP socket isn't reasonable. */ void dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event); -/* +/*%< * Inform the dispatcher of a socket receive. This is used for sockets * shared between dispatchers and clients. If the dispatcher fails to copy * or send the event, nothing happens. * * Requires: - * disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. + *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. * event != NULL */ diff --git a/contrib/bind9/lib/dns/include/dns/dlz.h b/contrib/bind9/lib/dns/include/dns/dlz.h new file mode 100644 index 0000000..4c61c91 --- /dev/null +++ b/contrib/bind9/lib/dns/include/dns/dlz.h @@ -0,0 +1,290 @@ +/* + * Portions Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +/* + * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. + * + * Permission to use, copy, modify, and 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 STICHTING NLNET + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * STICHTING NLNET 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. + * + * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was + * conceived and contributed by Rob Butler. + * + * Permission to use, copy, modify, and 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 ROB BUTLER + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * ROB BUTLER 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: dlz.h,v 1.2.2.2 2005/09/06 03:47:18 marka Exp $ */ + +/*! \file */ + +#ifndef DLZ_H +#define DLZ_H 1 + +/***** + ***** Module Info + *****/ + +/* + * DLZ Interface + * + * The DLZ interface allows zones to be looked up using a driver instead of + * Bind's default in memory zone table. + * + * + * Reliability: + * No anticipated impact. + * + * Resources: + * + * Security: + * No anticipated impact. + * + * Standards: + * None. + */ + +/***** + ***** Imports + *****/ + +#include <dns/name.h> +#include <dns/types.h> +#include <dns/view.h> + +#include <isc/lang.h> + +ISC_LANG_BEGINDECLS + +/*** + *** Types + ***/ + +#define DNS_DLZ_MAGIC ISC_MAGIC('D','L','Z','D') +#define DNS_DLZ_VALID(dlz) ISC_MAGIC_VALID(dlz, DNS_DLZ_MAGIC) + +typedef isc_result_t +(*dns_dlzallowzonexfr_t)(void *driverarg, void *dbdata, isc_mem_t *mctx, + dns_rdataclass_t rdclass, dns_name_t *name, + isc_sockaddr_t *clientaddr, + dns_db_t **dbp); + +/*%< + * Method prototype. Drivers implementing the DLZ interface MUST + * supply an allow zone transfer method. This method is called when + * the DNS server is performing a zone transfer query. The driver's + * method should return ISC_R_SUCCESS and a database pointer to the + * name server if the zone is supported by the database, and zone + * transfer is allowed. Otherwise it will return ISC_R_NOTFOUND if + * the zone is not supported by the database, or ISC_R_NOPERM if zone + * transfers are not allowed. If an error occurs it should return a + * result code indicating the type of error. + */ + +typedef isc_result_t +(*dns_dlzcreate_t)(isc_mem_t *mctx, const char *dlzname, unsigned int argc, + char *argv[], void *driverarg, void **dbdata); + +/*%< + * Method prototype. Drivers implementing the DLZ interface MUST + * supply a create method. This method is called when the DNS server + * is starting up and creating drivers for use later. + */ + +typedef void +(*dns_dlzdestroy_t)(void *driverarg, void **dbdata); + +/*%< + * Method prototype. Drivers implementing the DLZ interface MUST + * supply a destroy method. This method is called when the DNS server + * is shuting down and no longer needs the driver. + */ + +typedef isc_result_t +(*dns_dlzfindzone_t)(void *driverarg, void *dbdata, isc_mem_t *mctx, + dns_rdataclass_t rdclass, dns_name_t *name, + dns_db_t **dbp); + +/*%< + + * Method prototype. Drivers implementing the DLZ interface MUST + * supply a find zone method. This method is called when the DNS + * server is performing a query. The find zone method will be called + * with the longest possible name first, and continue to be called + * with successively shorter domain names, until any of the following + * occur: + * + * \li 1) a match is found, and the function returns (ISC_R_SUCCESS) + * + * \li 2) a problem occurs, and the functions returns anything other + * than (ISC_R_NOTFOUND) + * \li 3) we run out of domain name labels. I.E. we have tried the + * shortest domain name + * \li 4) the number of labels in the domain name is less than + * min_lables for dns_dlzfindzone + * + * The driver's find zone method should return ISC_R_SUCCESS and a + * database pointer to the name server if the zone is supported by the + * database. Otherwise it will return ISC_R_NOTFOUND, and a null + * pointer if the zone is not supported. If an error occurs it should + * return a result code indicating the type of error. + */ + +/*% the methods supplied by a DLZ driver */ +typedef struct dns_dlzmethods { + dns_dlzcreate_t create; + dns_dlzdestroy_t destroy; + dns_dlzfindzone_t findzone; + dns_dlzallowzonexfr_t allowzonexfr; +} dns_dlzmethods_t; + +/*% information about a DLZ driver */ +struct dns_dlzimplementation { + const char *name; + const dns_dlzmethods_t *methods; + isc_mem_t *mctx; + void *driverarg; + ISC_LINK(dns_dlzimplementation_t) link; +}; + +/*% an instance of a DLZ driver */ +struct dns_dlzdb { + unsigned int magic; + isc_mem_t *mctx; + dns_dlzimplementation_t *implementation; + void *dbdata; +}; + + +/*** + *** Method declarations + ***/ + +isc_result_t +dns_dlzallowzonexfr(dns_view_t *view, dns_name_t *name, + isc_sockaddr_t *clientaddr, dns_db_t **dbp); + +/*%< + * This method is called when the DNS server is performing a zone + * transfer query. It will call the DLZ driver's allow zone tranfer + * method. + */ + +isc_result_t +dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, + const char *drivername, unsigned int argc, + char *argv[], dns_dlzdb_t **dbp); + +/*%< + * This method is called when the DNS server is starting up and + * creating drivers for use later. It will search the DLZ driver list + * for 'drivername' and return a DLZ driver via dbp if a match is + * found. If the DLZ driver supplies a create method, this function + * will call it. + */ + +void +dns_dlzdestroy(dns_dlzdb_t **dbp); + +/*%< + * This method is called when the DNS server is shuting down and no + * longer needs the driver. If the DLZ driver supplies a destroy + * methods, this function will call it. + */ + +isc_result_t +dns_dlzfindzone(dns_view_t *view, dns_name_t *name, + unsigned int minlabels, dns_db_t **dbp); + +/*%< + * This method is called when the DNS server is performing a query. + * It will call the DLZ driver's find zone method. + */ + +isc_result_t +dns_dlzregister(const char *drivername, const dns_dlzmethods_t *methods, + void *driverarg, isc_mem_t *mctx, + dns_dlzimplementation_t **dlzimp); + +/*%< + * Register a dynamically loadable zones (DLZ) driver for the database + * type 'drivername', implemented by the functions in '*methods'. + * + * dlzimp must point to a NULL dlz_implementation_t pointer. That is, + * dlzimp != NULL && *dlzimp == NULL. It will be assigned a value that + * will later be used to identify the driver when deregistering it. + */ + +isc_result_t +dns_dlzstrtoargv(isc_mem_t *mctx, char *s, unsigned int *argcp, char ***argvp); + +/*%< + * This method is called when the name server is starting up to parse + * the DLZ driver command line from named.conf. Basically it splits + * up a string into and argc / argv. The primary difference of this + * method is items between braces { } are considered only 1 word. for + * example the command line "this is { one grouped phrase } and this + * isn't" would be parsed into: + * + * \li argv[0]: "this" + * \li argv[1]: "is" + * \li argv{2]: " one grouped phrase " + * \li argv[3]: "and" + * \li argv[4]: "this" + * \li argv{5}: "isn't" + * + * braces should NOT be nested, more than one grouping in the command + * line is allowed. Notice, argv[2] has an extra space at the + * beginning and end. Extra spaces are not stripped between a + * grouping. You can do so in your driver if needed, or be sure not + * to put extra spaces before / after the braces. + */ + +void +dns_dlzunregister(dns_dlzimplementation_t **dlzimp); + +/*%< + * Removes the dlz driver from the list of registered dlz drivers. + * There must be no active dlz drivers of this type when this function + * is called. + */ + +ISC_LANG_ENDDECLS + +#endif /* DLZ_H */ diff --git a/contrib/bind9/lib/dns/include/dns/dnssec.h b/contrib/bind9/lib/dns/include/dns/dnssec.h index 5f86178..2804e03 100644 --- a/contrib/bind9/lib/dns/include/dns/dnssec.h +++ b/contrib/bind9/lib/dns/include/dns/dnssec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec.h,v 1.21.12.5 2004/03/08 09:04:35 marka Exp $ */ +/* $Id: dnssec.h,v 1.26.18.2 2005/04/29 00:16:12 marka Exp $ */ #ifndef DNS_DNSSEC_H #define DNS_DNSSEC_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/stdtime.h> @@ -32,51 +34,51 @@ ISC_LANG_BEGINDECLS isc_result_t dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx, dst_key_t **key); -/* +/*%< * Creates a DST key from a DNS record. Basically a wrapper around * dst_key_fromdns(). * * Requires: - * 'name' is not NULL - * 'rdata' is not NULL - * 'mctx' is not NULL - * 'key' is not NULL - * '*key' is NULL + *\li 'name' is not NULL + *\li 'rdata' is not NULL + *\li 'mctx' is not NULL + *\li 'key' is not NULL + *\li '*key' is NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * DST_R_INVALIDPUBLICKEY - * various errors from dns_name_totext + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li DST_R_INVALIDPUBLICKEY + *\li various errors from dns_name_totext */ isc_result_t dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_stdtime_t *inception, isc_stdtime_t *expire, isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata); -/* +/*%< * Generates a SIG record covering this rdataset. This has no effect * on existing SIG records. * * Requires: - * 'name' (the owner name of the record) is a valid name - * 'set' is a valid rdataset - * 'key' is a valid key - * 'inception' is not NULL - * 'expire' is not NULL - * 'mctx' is not NULL - * 'buffer' is not NULL - * 'sigrdata' is not NULL + *\li 'name' (the owner name of the record) is a valid name + *\li 'set' is a valid rdataset + *\li 'key' is a valid key + *\li 'inception' is not NULL + *\li 'expire' is not NULL + *\li 'mctx' is not NULL + *\li 'buffer' is not NULL + *\li 'sigrdata' is not NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_NOSPACE - * DNS_R_INVALIDTIME - the expiration is before the inception - * DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_NOSPACE + *\li #DNS_R_INVALIDTIME - the expiration is before the inception + *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either * it is not a zone key or its flags prevent * authentication) - * DST_R_* + *\li DST_R_* */ isc_result_t @@ -88,35 +90,36 @@ isc_result_t dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); -/* +/*%< * Verifies the SIG record covering this rdataset signed by a specific * key. This does not determine if the key's owner is authorized to * sign this record, as this requires a resolver or database. * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked. * * Requires: - * 'name' (the owner name of the record) is a valid name - * 'set' is a valid rdataset - * 'key' is a valid key - * 'mctx' is not NULL - * 'sigrdata' is a valid rdata containing a SIG record - * 'wild' if non-NULL then is a valid and has a buffer. + *\li 'name' (the owner name of the record) is a valid name + *\li 'set' is a valid rdataset + *\li 'key' is a valid key + *\li 'mctx' is not NULL + *\li 'sigrdata' is a valid rdata containing a SIG record + *\li 'wild' if non-NULL then is a valid and has a buffer. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * DNS_R_FROMWILDCARD - the signature is valid and is from + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #DNS_R_FROMWILDCARD - the signature is valid and is from * a wildcard expansion. dns_dnssec_verify2() only. * 'wild' contains the name of the wildcard if non-NULL. - * DNS_R_SIGINVALID - the signature fails to verify - * DNS_R_SIGEXPIRED - the signature has expired - * DNS_R_SIGFUTURE - the signature's validity period has not begun - * DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either + *\li #DNS_R_SIGINVALID - the signature fails to verify + *\li #DNS_R_SIGEXPIRED - the signature has expired + *\li #DNS_R_SIGFUTURE - the signature's validity period has not begun + *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either * it is not a zone key or its flags prevent * authentication) - * DST_R_* + *\li DST_R_* */ +/*@{*/ isc_result_t dns_dnssec_findzonekeys(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, isc_mem_t *mctx, @@ -128,50 +131,51 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, const char *directory, isc_mem_t *mctx, unsigned int maxkeys, dst_key_t **keys, unsigned int *nkeys); -/* +/*%< * Finds a set of zone keys. * XXX temporary - this should be handled in dns_zone_t. */ +/*@}*/ isc_result_t dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key); -/* +/*%< * Signs a message with a SIG(0) record. This is implicitly called by * dns_message_renderend() if msg->sig0key is not NULL. * * Requires: - * 'msg' is a valid message - * 'key' is a valid key that can be used for signing + *\li 'msg' is a valid message + *\li 'key' is a valid key that can be used for signing * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * DST_R_* + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li DST_R_* */ isc_result_t dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, dst_key_t *key); -/* +/*%< * Verifies a message signed by a SIG(0) record. This is not * called implicitly by dns_message_parse(). If dns_message_signer() * is called before dns_dnssec_verifymessage(), it will return - * DNS_R_NOTVERIFIEDYET. dns_dnssec_verifymessage() will set + * #DNS_R_NOTVERIFIEDYET. dns_dnssec_verifymessage() will set * the verified_sig0 flag in msg if the verify succeeds, and * the sig0status field otherwise. * * Requires: - * 'source' is a valid buffer containing the unparsed message - * 'msg' is a valid message - * 'key' is a valid key + *\li 'source' is a valid buffer containing the unparsed message + *\li 'msg' is a valid message + *\li 'key' is a valid key * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_NOTFOUND - no SIG(0) was found - * DNS_R_SIGINVALID - the SIG record is not well-formed or + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_NOTFOUND - no SIG(0) was found + *\li #DNS_R_SIGINVALID - the SIG record is not well-formed or * was not generated by the key. - * DST_R_* + *\li DST_R_* */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/ds.h b/contrib/bind9/lib/dns/include/dns/ds.h index 979ac9f..5e4cc40 100644 --- a/contrib/bind9/lib/dns/include/dns/ds.h +++ b/contrib/bind9/lib/dns/include/dns/ds.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds.h,v 1.3.2.1 2004/03/08 02:08:00 marka Exp $ */ +/* $Id: ds.h,v 1.3.20.5 2006/02/22 23:50:09 marka Exp $ */ #ifndef DNS_DS_H #define DNS_DS_H 1 @@ -25,11 +25,12 @@ #include <dns/types.h> #define DNS_DSDIGEST_SHA1 (1) +#define DNS_DSDIGEST_SHA256 (2) /* - * Assuming SHA-1 digest type. + * Assuming SHA-256 digest type. */ -#define DNS_DS_BUFFERSIZE (24) +#define DNS_DS_BUFFERSIZE (36) ISC_LANG_BEGINDECLS @@ -37,20 +38,26 @@ isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, dns_rdata_t *rdata); -/* +/*%< * Build the rdata of a DS record. * * Requires: - * key Points to a valid DNS KEY record. - * buffer Points to a temporary buffer of at least - * DNS_DS_BUFFERSIZE bytes. - * rdata Points to an initialized dns_rdata_t. + *\li key Points to a valid DNS KEY record. + *\li buffer Points to a temporary buffer of at least + * #DNS_DS_BUFFERSIZE bytes. + *\li rdata Points to an initialized dns_rdata_t. * * Ensures: - * *rdata Contains a valid DS rdata. The 'data' member refers + * \li *rdata Contains a valid DS rdata. The 'data' member refers * to 'buffer'. */ +isc_boolean_t +dns_ds_digest_supported(unsigned int digest_type); +/*%< + * Is this digest algorithm supported by dns_ds_buildrdata()? + */ + ISC_LANG_ENDDECLS #endif /* DNS_DS_H */ diff --git a/contrib/bind9/lib/dns/include/dns/events.h b/contrib/bind9/lib/dns/include/dns/events.h index 1e66139..d1ebef3 100644 --- a/contrib/bind9/lib/dns/include/dns/events.h +++ b/contrib/bind9/lib/dns/include/dns/events.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,14 +15,15 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: events.h,v 1.37.2.1.4.4 2004/03/08 09:04:36 marka Exp $ */ +/* $Id: events.h,v 1.42.18.3 2005/04/29 00:16:13 marka Exp $ */ #ifndef DNS_EVENTS_H #define DNS_EVENTS_H 1 #include <isc/eventclass.h> -/* +/*! \file + * \brief * Registry of DNS event numbers. */ @@ -63,6 +64,10 @@ #define DNS_EVENT_DUMPQUANTUM (ISC_EVENTCLASS_DNS + 34) #define DNS_EVENT_IMPORTRECVDONE (ISC_EVENTCLASS_DNS + 35) #define DNS_EVENT_FREESTORAGE (ISC_EVENTCLASS_DNS + 36) +#define DNS_EVENT_VIEWACACHESHUTDOWN (ISC_EVENTCLASS_DNS + 37) +#define DNS_EVENT_ACACHECONTROL (ISC_EVENTCLASS_DNS + 38) +#define DNS_EVENT_ACACHECLEAN (ISC_EVENTCLASS_DNS + 39) +#define DNS_EVENT_ACACHEOVERMEM (ISC_EVENTCLASS_DNS + 40) #define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0) #define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535) diff --git a/contrib/bind9/lib/dns/include/dns/fixedname.h b/contrib/bind9/lib/dns/include/dns/fixedname.h index 3ee306f..8380de6 100644 --- a/contrib/bind9/lib/dns/include/dns/fixedname.h +++ b/contrib/bind9/lib/dns/include/dns/fixedname.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: fixedname.h,v 1.12.206.1 2004/03/06 08:13:55 marka Exp $ */ +/* $Id: fixedname.h,v 1.13.18.2 2005/04/29 00:16:13 marka Exp $ */ #ifndef DNS_FIXEDNAME_H #define DNS_FIXEDNAME_H 1 @@ -24,28 +24,31 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * Fixed-size Names * * dns_fixedname_t is a convenience type containing a name, an offsets table, * and a dedicated buffer big enough for the longest possible name. * * MP: - * The caller must ensure any required synchronization. + *\li The caller must ensure any required synchronization. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * Per dns_fixedname_t: + *\li Per dns_fixedname_t: + *\code * sizeof(dns_name_t) + sizeof(dns_offsets_t) + * sizeof(isc_buffer_t) + 255 bytes + structure padding + *\endcode * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ /***** diff --git a/contrib/bind9/lib/dns/include/dns/forward.h b/contrib/bind9/lib/dns/include/dns/forward.h index 1eb62d2..ddf6d7f 100644 --- a/contrib/bind9/lib/dns/include/dns/forward.h +++ b/contrib/bind9/lib/dns/include/dns/forward.h @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: forward.h,v 1.2.206.3 2005/03/17 03:58:31 marka Exp $ */ +/* $Id: forward.h,v 1.3.18.3 2005/04/27 05:01:33 sra Exp $ */ #ifndef DNS_FORWARD_H #define DNS_FORWARD_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/result.h> @@ -34,68 +36,81 @@ struct dns_forwarders { isc_result_t dns_fwdtable_create(isc_mem_t *mctx, dns_fwdtable_t **fwdtablep); -/* +/*%< * Creates a new forwarding table. * * Requires: - * mctx is a valid memory context. - * fwdtablep != NULL && *fwdtablep == NULL + * \li mctx is a valid memory context. + * \li fwdtablep != NULL && *fwdtablep == NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY */ isc_result_t dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name, isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy); -/* +/*%< * Adds an entry to the forwarding table. The entry associates * a domain with a list of forwarders and a forwarding policy. The * addrs list is copied if not empty, so the caller should free its copy. * * Requires: - * fwdtable is a valid forwarding table. - * name is a valid name - * addrs is a valid list of sockaddrs, which may be empty. + * \li fwdtable is a valid forwarding table. + * \li name is a valid name + * \li addrs is a valid list of sockaddrs, which may be empty. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY */ isc_result_t dns_fwdtable_find(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_forwarders_t **forwardersp); +/*%< + * Finds a domain in the forwarding table. The closest matching parent + * domain is returned. + * + * Requires: + * \li fwdtable is a valid forwarding table. + * \li name is a valid name + * \li forwardersp != NULL && *forwardersp == NULL + * + * Returns: + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND + */ isc_result_t dns_fwdtable_find2(dns_fwdtable_t *fwdtable, dns_name_t *name, dns_name_t *foundname, dns_forwarders_t **forwardersp); -/* +/*%< * Finds a domain in the forwarding table. The closest matching parent * domain is returned. * * Requires: - * fwdtable is a valid forwarding table. - * name is a valid name - * forwardersp != NULL && *forwardersp == NULL - * foundname to be NULL or a valid name with buffer. + * \li fwdtable is a valid forwarding table. + * \li name is a valid name + * \li forwardersp != NULL && *forwardersp == NULL + * \li foundname to be NULL or a valid name with buffer. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND */ void dns_fwdtable_destroy(dns_fwdtable_t **fwdtablep); -/* +/*%< * Destroys a forwarding table. * * Requires: - * fwtablep != NULL && *fwtablep != NULL + * \li fwtablep != NULL && *fwtablep != NULL * * Ensures: - * all memory associated with the forwarding table is freed. + * \li all memory associated with the forwarding table is freed. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/journal.h b/contrib/bind9/lib/dns/include/dns/journal.h index fdf6094..b776a30 100644 --- a/contrib/bind9/lib/dns/include/dns/journal.h +++ b/contrib/bind9/lib/dns/include/dns/journal.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: journal.h,v 1.23.12.3 2004/03/08 09:04:36 marka Exp $ */ +/* $Id: journal.h,v 1.25.18.2 2005/04/29 00:16:13 marka Exp $ */ #ifndef DNS_JOURNAL_H #define DNS_JOURNAL_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * Database journalling. */ @@ -44,7 +45,7 @@ *** Types ***/ -/* +/*% * A dns_journal_t represents an open journal file. This is an opaque type. * * A particular dns_journal_t object may be opened for writing, in which case @@ -67,19 +68,21 @@ ISC_LANG_BEGINDECLS isc_result_t dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, dns_diffop_t op, dns_difftuple_t **tp); -/* +/*!< brief * Create a diff tuple for the current database SOA. * XXX this probably belongs somewhere else. */ +/*@{*/ #define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0) #define DNS_SERIAL_GE(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) >= 0) -/* +/*!< brief * Compare SOA serial numbers. DNS_SERIAL_GT(a, b) returns true iff * a is "greater than" b where "greater than" is as defined in RFC1982. * DNS_SERIAL_GE(a, b) returns true iff a is "greater than or equal to" b. */ +/*@}*/ /**************************************************************************/ /* @@ -89,7 +92,7 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, isc_result_t dns_journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write, dns_journal_t **journalp); -/* +/*%< * Open the journal file 'filename' and create a dns_journal_t object for it. * * If 'write' is ISC_TRUE, the journal is open for writing. If it does @@ -101,7 +104,7 @@ dns_journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write, void dns_journal_destroy(dns_journal_t **journalp); -/* +/*%< * Destroy a dns_journal_t, closing any open files and freeing its memory. */ @@ -112,52 +115,52 @@ dns_journal_destroy(dns_journal_t **journalp); isc_result_t dns_journal_begin_transaction(dns_journal_t *j); -/* +/*%< * Prepare to write a new transaction to the open journal file 'j'. * * Requires: - * 'j' is open for writing. + * \li 'j' is open for writing. */ isc_result_t dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff); -/* +/*%< * Write 'diff' to the current transaction of journal file 'j'. * * Requires: - * 'j' is open for writing and dns_journal_begin_transaction() + * \li 'j' is open for writing and dns_journal_begin_transaction() * has been called. * - * 'diff' is a full or partial, correctly ordered IXFR + *\li 'diff' is a full or partial, correctly ordered IXFR * difference sequence. */ isc_result_t dns_journal_commit(dns_journal_t *j); -/* +/*%< * Commit the current transaction of journal file 'j'. * * Requires: - * 'j' is open for writing and dns_journal_begin_transaction() + * \li 'j' is open for writing and dns_journal_begin_transaction() * has been called. * - * dns_journal_writediff() has been called one or more times + * \li dns_journal_writediff() has been called one or more times * to form a complete, correctly ordered IXFR difference * sequence. */ isc_result_t dns_journal_write_transaction(dns_journal_t *j, dns_diff_t *diff); -/* +/*% * Write a complete transaction at once to a journal file, * sorting it if necessary, and commit it. Equivalent to calling * dns_diff_sort(), dns_journal_begin_transaction(), * dns_journal_writediff(), and dns_journal_commit(). * * Requires: - * 'j' is open for writing. + *\li 'j' is open for writing. * - * 'diff' contains exactly one SOA deletion, one SOA addition + * \li 'diff' contains exactly one SOA deletion, one SOA addition * with a greater serial number, and possibly other changes, * in arbitrary order. */ @@ -171,46 +174,48 @@ isc_uint32_t dns_journal_first_serial(dns_journal_t *j); isc_uint32_t dns_journal_last_serial(dns_journal_t *j); -/* +/*%< * Get the first and last addressable serial number in the journal. */ isc_result_t dns_journal_iter_init(dns_journal_t *j, isc_uint32_t begin_serial, isc_uint32_t end_serial); -/* +/*%< * Prepare to iterate over the transactions that will bring the database * from SOA serial number 'begin_serial' to 'end_serial'. * * Returns: - * ISC_R_SUCCESS - * ISC_R_RANGE begin_serial is outside the addressable range. - * ISC_R_NOTFOUND begin_serial is within the range of adressable + *\li ISC_R_SUCCESS + *\li ISC_R_RANGE begin_serial is outside the addressable range. + *\li ISC_R_NOTFOUND begin_serial is within the range of adressable * serial numbers covered by the journal, but * this particular serial number does not exist. */ +/*@{*/ isc_result_t dns_journal_first_rr(dns_journal_t *j); isc_result_t dns_journal_next_rr(dns_journal_t *j); -/* +/*%< * Position the iterator at the first/next RR in a journal * transaction sequence established using dns_journal_iter_init(). * * Requires: - * dns_journal_iter_init() has been called. + * \li dns_journal_iter_init() has been called. * */ +/*@}*/ void dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl, dns_rdata_t **rdata); -/* +/*%< * Get the name, ttl, and rdata of the current journal RR. * * Requires: - * The last call to dns_journal_first_rr() or dns_journal_next_rr() + * \li The last call to dns_journal_first_rr() or dns_journal_next_rr() * returned ISC_R_SUCCESS. */ @@ -221,22 +226,22 @@ dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl, isc_result_t dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, const char *filename); -/* +/*%< * Roll forward (play back) the journal file "filename" into the * database "db". This should be called when the server starts * after a shutdown or crash. * * Requires: - * 'mctx' is a valid memory context. - * 'db' is a valid database which does not have a version + *\li 'mctx' is a valid memory context. + *\li 'db' is a valid database which does not have a version * open for writing. - * 'filename' is the name of the journal file belonging to 'db'. + * \li 'filename' is the name of the journal file belonging to 'db'. * * Returns: - * DNS_R_NOJOURNAL when journal does not exist. - * ISC_R_NOTFOUND when current serial in not in journal. - * ISC_R_RANGE when current serial in not in journals range. - * ISC_R_SUCCESS journal has been applied successfully to database. + *\li DNS_R_NOJOURNAL when journal does not exist. + *\li ISC_R_NOTFOUND when current serial in not in journal. + *\li ISC_R_RANGE when current serial in not in journals range. + *\li ISC_R_SUCCESS journal has been applied successfully to database. * others */ @@ -249,7 +254,7 @@ dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, const char *journal_filename); -/* +/*%< * Compare the databases 'dba' and 'dbb' and generate a journal * entry containing the changes to make 'dba' from 'dbb' (note * the order). This journal entry will consist of a single, @@ -260,7 +265,7 @@ dns_db_diff(isc_mem_t *mctx, isc_result_t dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial, isc_uint32_t target_size); -/* +/*%< * Attempt to compact the journal if it is greater that 'target_size'. * Changes from 'serial' onwards will be preserved. If the journal * exists and is non-empty 'serial' must exist in the journal. diff --git a/contrib/bind9/lib/dns/include/dns/keyflags.h b/contrib/bind9/lib/dns/include/dns/keyflags.h index 025b137..665b517 100644 --- a/contrib/bind9/lib/dns/include/dns/keyflags.h +++ b/contrib/bind9/lib/dns/include/dns/keyflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keyflags.h,v 1.9.206.1 2004/03/06 08:13:56 marka Exp $ */ +/* $Id: keyflags.h,v 1.10.18.2 2005/04/29 00:16:13 marka Exp $ */ #ifndef DNS_KEYFLAGS_H #define DNS_KEYFLAGS_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,7 +30,7 @@ ISC_LANG_BEGINDECLS isc_result_t dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a DNSSEC KEY flags value. * The text may contain either a set of flag mnemonics separated by * vertical bars or a decimal flags value. For compatibility with @@ -37,14 +39,14 @@ dns_keyflags_fromtext(dns_keyflags_t *flagsp, isc_textregion_t *source); * are also accepted. * * Requires: - * 'flagsp' is a valid pointer. + *\li 'flagsp' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_RANGE numeric flag value is out of range - * DNS_R_UNKNOWN mnemonic flag is unknown + *\li ISC_R_SUCCESS on success + *\li ISC_R_RANGE numeric flag value is out of range + *\li DNS_R_UNKNOWN mnemonic flag is unknown */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/keytable.h b/contrib/bind9/lib/dns/include/dns/keytable.h index f3a21a6..b8bfcc1 100644 --- a/contrib/bind9/lib/dns/include/dns/keytable.h +++ b/contrib/bind9/lib/dns/include/dns/keytable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keytable.h,v 1.10.206.3 2006/01/06 00:01:42 marka Exp $ */ +/* $Id: keytable.h,v 1.11.18.3 2005/12/05 00:00:03 marka Exp $ */ #ifndef DNS_KEYTABLE_H #define DNS_KEYTABLE_H 1 @@ -24,22 +24,21 @@ ***** Module Info *****/ -/* - * Key Tables - * +/*! \file + * \brief * The keytable module provides services for storing and retrieving DNSSEC * trusted keys, as well as the ability to find the deepest matching key * for a given domain name. * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. */ #include <isc/lang.h> @@ -52,203 +51,202 @@ ISC_LANG_BEGINDECLS isc_result_t dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep); -/* +/*%< * Create a keytable. * * Requires: * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. * - * keytablep != NULL && *keytablep == NULL + *\li keytablep != NULL && *keytablep == NULL * * Ensures: * - * On success, *keytablep is a valid, empty key table. + *\li On success, *keytablep is a valid, empty key table. * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Any other result indicates failure. + *\li Any other result indicates failure. */ void dns_keytable_attach(dns_keytable_t *source, dns_keytable_t **targetp); -/* +/*%< * Attach *targetp to source. * * Requires: * - * 'source' is a valid keytable. + *\li 'source' is a valid keytable. * - * 'targetp' points to a NULL dns_keytable_t *. + *\li 'targetp' points to a NULL dns_keytable_t *. * * Ensures: * - * *targetp is attached to source. + *\li *targetp is attached to source. */ void dns_keytable_detach(dns_keytable_t **keytablep); -/* +/*%< * Detach *keytablep from its keytable. * * Requires: * - * 'keytablep' points to a valid keytable. + *\li 'keytablep' points to a valid keytable. * * Ensures: * - * *keytablep is NULL. - * - * If '*keytablep' is the last reference to the keytable, + *\li *keytablep is NULL. * - * All resources used by the keytable will be freed + *\li If '*keytablep' is the last reference to the keytable, + * all resources used by the keytable will be freed */ isc_result_t dns_keytable_add(dns_keytable_t *keytable, dst_key_t **keyp); -/* +/*%< * Add '*keyp' to 'keytable'. * * Notes: * - * Ownership of *keyp is transferred to the keytable. + *\li Ownership of *keyp is transferred to the keytable. * * Requires: * - * keyp != NULL && *keyp is a valid dst_key_t *. + *\li keyp != NULL && *keyp is a valid dst_key_t *. * * Ensures: * - * On success, *keyp == NULL + *\li On success, *keyp == NULL * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Any other result indicates failure. + *\li Any other result indicates failure. */ isc_result_t dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, dns_secalg_t algorithm, dns_keytag_t tag, dns_keynode_t **keynodep); -/* +/*%< * Search for a key named 'name', matching 'algorithm' and 'tag' in * 'keytable'. This finds the first instance which matches. Use * dns_keytable_findnextkeynode() to find other instances. * * Requires: * - * 'keytable' is a valid keytable. + *\li 'keytable' is a valid keytable. * - * 'name' is a valid absolute name. + *\li 'name' is a valid absolute name. * - * keynodep != NULL && *keynodep == NULL + *\li keynodep != NULL && *keynodep == NULL * * Returns: * - * ISC_R_SUCCESS - * DNS_R_PARTIALMATCH the name existed in the keytable. - * ISC_R_NOTFOUND + *\li ISC_R_SUCCESS + *\li DNS_R_PARTIALMATCH the name existed in the keytable. + *\li ISC_R_NOTFOUND * - * Any other result indicates an error. + *\li Any other result indicates an error. */ isc_result_t dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_keynode_t **nextnodep); -/* +/*%< * Search for the next key with the same properties as 'keynode' in * 'keytable' as found by dns_keytable_findkeynode(). * * Requires: * - * 'keytable' is a valid keytable. + *\li 'keytable' is a valid keytable. * - * 'keynode' is a valid keynode. + *\li 'keynode' is a valid keynode. * - * nextnodep != NULL && *nextnodep == NULL + *\li nextnodep != NULL && *nextnodep == NULL * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + *\li ISC_R_SUCCESS + *\li ISC_R_NOTFOUND * - * Any other result indicates an error. + *\li Any other result indicates an error. */ isc_result_t dns_keytable_finddeepestmatch(dns_keytable_t *keytable, dns_name_t *name, dns_name_t *foundname); -/* +/*%< * Search for the deepest match of 'name' in 'keytable'. * * Requires: * - * 'keytable' is a valid keytable. + *\li 'keytable' is a valid keytable. * - * 'name' is a valid absolute name. + *\li 'name' is a valid absolute name. * - * 'foundname' is a name with a dedicated buffer. + *\li 'foundname' is a name with a dedicated buffer. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + *\li ISC_R_SUCCESS + *\li ISC_R_NOTFOUND * - * Any other result indicates an error. + *\li Any other result indicates an error. */ void dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep); -/* +/*%< * Give back a keynode found via dns_keytable_findkeynode(). * * Requires: * - * 'keytable' is a valid keytable. + *\li 'keytable' is a valid keytable. * - * *keynodep is a valid keynode returned by a call to + *\li *keynodep is a valid keynode returned by a call to * dns_keytable_findkeynode(). * * Ensures: * - * *keynodep == NULL + *\li *keynodep == NULL */ isc_result_t dns_keytable_issecuredomain(dns_keytable_t *keytable, dns_name_t *name, isc_boolean_t *wantdnssecp); -/* +/*%< * Is 'name' at or beneath a trusted key? * * Requires: * - * 'keytable' is a valid keytable. + *\li 'keytable' is a valid keytable. * - * 'name' is a valid absolute name. + *\li 'name' is a valid absolute name. * - * '*wantsdnssecp' is a valid isc_boolean_t. + *\li '*wantsdnssecp' is a valid isc_boolean_t. * * Ensures: * - * On success, *wantsdnssecp will be ISC_TRUE if and only if 'name' + *\li On success, *wantsdnssecp will be ISC_TRUE if and only if 'name' * is at or beneath a trusted key. * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Any other result is an error. + *\li Any other result is an error. */ dst_key_t * dns_keynode_key(dns_keynode_t *keynode); -/* +/*%< * Get the DST key associated with keynode. */ diff --git a/contrib/bind9/lib/dns/include/dns/keyvalues.h b/contrib/bind9/lib/dns/include/dns/keyvalues.h index ef9e821..df17ace 100644 --- a/contrib/bind9/lib/dns/include/dns/keyvalues.h +++ b/contrib/bind9/lib/dns/include/dns/keyvalues.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,36 +15,38 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keyvalues.h,v 1.11.12.3 2004/03/06 08:13:56 marka Exp $ */ +/* $Id: keyvalues.h,v 1.15.18.2 2005/04/29 00:16:14 marka Exp $ */ #ifndef DNS_KEYVALUES_H #define DNS_KEYVALUES_H 1 +/*! \file */ + /* * Flags field of the KEY RR rdata */ -#define DNS_KEYFLAG_TYPEMASK 0xC000 /* Mask for "type" bits */ -#define DNS_KEYTYPE_AUTHCONF 0x0000 /* Key usable for both */ -#define DNS_KEYTYPE_CONFONLY 0x8000 /* Key usable for confidentiality */ -#define DNS_KEYTYPE_AUTHONLY 0x4000 /* Key usable for authentication */ -#define DNS_KEYTYPE_NOKEY 0xC000 /* No key usable for either; no key */ +#define DNS_KEYFLAG_TYPEMASK 0xC000 /*%< Mask for "type" bits */ +#define DNS_KEYTYPE_AUTHCONF 0x0000 /*%< Key usable for both */ +#define DNS_KEYTYPE_CONFONLY 0x8000 /*%< Key usable for confidentiality */ +#define DNS_KEYTYPE_AUTHONLY 0x4000 /*%< Key usable for authentication */ +#define DNS_KEYTYPE_NOKEY 0xC000 /*%< No key usable for either; no key */ #define DNS_KEYTYPE_NOAUTH DNS_KEYTYPE_CONFONLY #define DNS_KEYTYPE_NOCONF DNS_KEYTYPE_AUTHONLY -#define DNS_KEYFLAG_RESERVED2 0x2000 /* reserved - must be zero */ -#define DNS_KEYFLAG_EXTENDED 0x1000 /* key has extended flags */ -#define DNS_KEYFLAG_RESERVED4 0x0800 /* reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED5 0x0400 /* reserved - must be zero */ -#define DNS_KEYFLAG_OWNERMASK 0x0300 /* these bits determine the type */ -#define DNS_KEYOWNER_USER 0x0000 /* key is assoc. with user */ -#define DNS_KEYOWNER_ENTITY 0x0200 /* key is assoc. with entity eg host */ -#define DNS_KEYOWNER_ZONE 0x0100 /* key is zone key */ -#define DNS_KEYOWNER_RESERVED 0x0300 /* reserved meaning */ -#define DNS_KEYFLAG_RESERVED8 0x0080 /* reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED9 0x0040 /* reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED10 0x0020 /* reserved - must be zero */ -#define DNS_KEYFLAG_RESERVED11 0x0010 /* reserved - must be zero */ -#define DNS_KEYFLAG_SIGNATORYMASK 0x000F /* key can sign RR's of same name */ +#define DNS_KEYFLAG_RESERVED2 0x2000 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_EXTENDED 0x1000 /*%< key has extended flags */ +#define DNS_KEYFLAG_RESERVED4 0x0800 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_RESERVED5 0x0400 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_OWNERMASK 0x0300 /*%< these bits determine the type */ +#define DNS_KEYOWNER_USER 0x0000 /*%< key is assoc. with user */ +#define DNS_KEYOWNER_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ +#define DNS_KEYOWNER_ZONE 0x0100 /*%< key is zone key */ +#define DNS_KEYOWNER_RESERVED 0x0300 /*%< reserved meaning */ +#define DNS_KEYFLAG_RESERVED8 0x0080 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_RESERVED9 0x0040 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_RESERVED10 0x0020 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_RESERVED11 0x0010 /*%< reserved - must be zero */ +#define DNS_KEYFLAG_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ #define DNS_KEYFLAG_RESERVEDMASK (DNS_KEYFLAG_RESERVED2 | \ DNS_KEYFLAG_RESERVED4 | \ @@ -53,21 +55,21 @@ DNS_KEYFLAG_RESERVED9 | \ DNS_KEYFLAG_RESERVED10 | \ DNS_KEYFLAG_RESERVED11 ) -#define DNS_KEYFLAG_KSK 0x0001 /* key signing key */ +#define DNS_KEYFLAG_KSK 0x0001 /*%< key signing key */ -#define DNS_KEYFLAG_RESERVEDMASK2 0xFFFF /* no bits defined here */ +#define DNS_KEYFLAG_RESERVEDMASK2 0xFFFF /*%< no bits defined here */ /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ -#define DNS_KEYALG_RSAMD5 1 /* RSA with MD5 */ +#define DNS_KEYALG_RSAMD5 1 /*%< RSA with MD5 */ #define DNS_KEYALG_RSA DNS_KEYALG_RSAMD5 -#define DNS_KEYALG_DH 2 /* Diffie Hellman KEY */ -#define DNS_KEYALG_DSA 3 /* DSA KEY */ +#define DNS_KEYALG_DH 2 /*%< Diffie Hellman KEY */ +#define DNS_KEYALG_DSA 3 /*%< DSA KEY */ #define DNS_KEYALG_DSS NS_ALG_DSA #define DNS_KEYALG_ECC 4 #define DNS_KEYALG_RSASHA1 5 #define DNS_KEYALG_INDIRECT 252 #define DNS_KEYALG_PRIVATEDNS 253 -#define DNS_KEYALG_PRIVATEOID 254 /* Key begins with OID giving alg */ +#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ /* Protocol values */ #define DNS_KEYPROTO_RESERVED 0 @@ -78,11 +80,11 @@ #define DNS_KEYPROTO_ANY 255 /* Signatures */ -#define DNS_SIG_RSAMINBITS 512 /* Size of a mod or exp in bits */ +#define DNS_SIG_RSAMINBITS 512 /*%< Size of a mod or exp in bits */ #define DNS_SIG_RSAMAXBITS 2552 /* Total of binary mod and exp */ #define DNS_SIG_RSAMAXBYTES ((DNS_SIG_RSAMAXBITS+7/8)*2+3) - /* Max length of text sig block */ + /*%< Max length of text sig block */ #define DNS_SIG_RSAMAXBASE64 (((DNS_SIG_RSAMAXBYTES+2)/3)*4) #define DNS_SIG_RSAMINSIZE ((DNS_SIG_RSAMINBITS+7)/8) #define DNS_SIG_RSAMAXSIZE ((DNS_SIG_RSAMAXBITS+7)/8) diff --git a/contrib/bind9/lib/dns/include/dns/lib.h b/contrib/bind9/lib/dns/include/dns/lib.h index e53dd2b..d59dde3 100644 --- a/contrib/bind9/lib/dns/include/dns/lib.h +++ b/contrib/bind9/lib/dns/include/dns/lib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,21 +15,27 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lib.h,v 1.6.12.3 2004/03/08 09:04:36 marka Exp $ */ +/* $Id: lib.h,v 1.8.18.4 2005/09/20 04:33:48 marka Exp $ */ #ifndef DNS_LIB_H #define DNS_LIB_H 1 +/*! \file */ + #include <isc/types.h> #include <isc/lang.h> ISC_LANG_BEGINDECLS +/*% + * Tuning: external query load in packets per seconds. + */ +LIBDNS_EXTERNAL_DATA extern unsigned int dns_pps; LIBDNS_EXTERNAL_DATA extern isc_msgcat_t *dns_msgcat; void dns_lib_initmsgcat(void); -/* +/*%< * Initialize the DNS library's message catalog, dns_msgcat, if it * has not already been initialized. */ diff --git a/contrib/bind9/lib/dns/include/dns/log.h b/contrib/bind9/lib/dns/include/dns/log.h index 9901fc9..7bee174 100644 --- a/contrib/bind9/lib/dns/include/dns/log.h +++ b/contrib/bind9/lib/dns/include/dns/log.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: log.h,v 1.30.2.1.10.2 2004/03/06 08:13:57 marka Exp $ */ +/* $Id: log.h,v 1.33.18.4 2005/09/05 00:18:27 marka Exp $ */ -/* Principal Authors: DCL */ +/*! \file + * \author Principal Authors: DCL */ #ifndef DNS_LOG_H #define DNS_LOG_H 1 @@ -69,33 +70,35 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[]; #define DNS_LOGMODULE_SDB (&dns_modules[22]) #define DNS_LOGMODULE_DIFF (&dns_modules[23]) #define DNS_LOGMODULE_HINTS (&dns_modules[24]) +#define DNS_LOGMODULE_ACACHE (&dns_modules[25]) +#define DNS_LOGMODULE_DLZ (&dns_modules[26]) ISC_LANG_BEGINDECLS void dns_log_init(isc_log_t *lctx); -/* +/*% * Make the libdns categories and modules available for use with the * ISC logging library. * * Requires: - * lctx is a valid logging context. + *\li lctx is a valid logging context. * - * dns_log_init() is called only once. + *\li dns_log_init() is called only once. * * Ensures: - * The catgories and modules defined above are available for + * \li The catgories and modules defined above are available for * use by isc_log_usechannnel() and isc_log_write(). */ void dns_log_setcontext(isc_log_t *lctx); -/* +/*% * Make the libdns library use the provided context for logging internal * messages. * * Requires: - * lctx is a valid logging context. + *\li lctx is a valid logging context. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/lookup.h b/contrib/bind9/lib/dns/include/dns/lookup.h index 2be254c..aea6f84 100644 --- a/contrib/bind9/lib/dns/include/dns/lookup.h +++ b/contrib/bind9/lib/dns/include/dns/lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lookup.h,v 1.5.206.1 2004/03/06 08:13:57 marka Exp $ */ +/* $Id: lookup.h,v 1.6.18.2 2005/04/29 00:16:15 marka Exp $ */ #ifndef DNS_LOOKUP_H #define DNS_LOOKUP_H 1 @@ -24,29 +24,28 @@ ***** Module Info *****/ -/* - * DNS Lookup - * +/*! \file + * \brief * The lookup module performs simple DNS lookups. It implements * the full resolver algorithm, both looking for local data and * resoving external names as necessary. * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * RFCs: 1034, 1035, 2181, <TBS> - * Drafts: <TBS> + *\li RFCs: 1034, 1035, 2181, TBS + *\li Drafts: TBS */ #include <isc/lang.h> @@ -56,7 +55,7 @@ ISC_LANG_BEGINDECLS -/* +/*% * A 'dns_lookupevent_t' is returned when a lookup completes. * The sender field will be set to the lookup that completed. If 'result' * is ISC_R_SUCCESS, then 'names' will contain a list of names associated @@ -77,60 +76,60 @@ isc_result_t dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type, dns_view_t *view, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_lookup_t **lookupp); -/* +/*%< * Finds the rrsets matching 'name' and 'type'. * * Requires: * - * 'mctx' is a valid mctx. + *\li 'mctx' is a valid mctx. * - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'view' is a valid view which has a resolver. + *\li 'view' is a valid view which has a resolver. * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * lookupp != NULL && *lookupp == NULL + *\li lookupp != NULL && *lookupp == NULL * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li ISC_R_SUCCESS + *\li ISC_R_NOMEMORY * - * Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be + *\li Any resolver-related error (e.g. ISC_R_SHUTTINGDOWN) may also be * returned. */ void dns_lookup_cancel(dns_lookup_t *lookup); -/* +/*%< * Cancel 'lookup'. * * Notes: * - * If 'lookup' has not completed, post its LOOKUPDONE event with a + *\li If 'lookup' has not completed, post its LOOKUPDONE event with a * result code of ISC_R_CANCELED. * * Requires: * - * 'lookup' is a valid lookup. + *\li 'lookup' is a valid lookup. */ void dns_lookup_destroy(dns_lookup_t **lookupp); -/* +/*%< * Destroy 'lookup'. * * Requires: * - * '*lookupp' is a valid lookup. + *\li '*lookupp' is a valid lookup. * - * The caller has received the LOOKUPDONE event (either because the + *\li The caller has received the LOOKUPDONE event (either because the * lookup completed or because dns_lookup_cancel() was called). * * Ensures: * - * *lookupp == NULL. + *\li *lookupp == NULL. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/master.h b/contrib/bind9/lib/dns/include/dns/master.h index 0b861c6..1f94c8c 100644 --- a/contrib/bind9/lib/dns/include/dns/master.h +++ b/contrib/bind9/lib/dns/include/dns/master.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.h,v 1.31.2.3.2.7 2004/03/08 09:04:36 marka Exp $ */ +/* $Id: master.h,v 1.38.18.6 2005/06/20 01:19:43 marka Exp $ */ #ifndef DNS_MASTER_H #define DNS_MASTER_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -33,21 +35,60 @@ /* * Flags to be passed in the 'options' argument in the functions below. */ -#define DNS_MASTER_AGETTL 0x00000001 /* Age the ttl based on $DATE. */ -#define DNS_MASTER_MANYERRORS 0x00000002 /* Continue processing on errors. */ -#define DNS_MASTER_NOINCLUDE 0x00000004 /* Disallow $INCLUDE directives. */ -#define DNS_MASTER_ZONE 0x00000008 /* Loading a zone master file. */ -#define DNS_MASTER_HINT 0x00000010 /* Loading a hint master file. */ -#define DNS_MASTER_SLAVE 0x00000020 /* Loading a slave master file. */ -#define DNS_MASTER_CHECKNS 0x00000040 /* Check NS records to see if - * they are an address */ -#define DNS_MASTER_FATALNS 0x00000080 /* Treat DNS_MASTER_CHECKNS - * matches as fatal */ +#define DNS_MASTER_AGETTL 0x00000001 /*%< Age the ttl based on $DATE. */ +#define DNS_MASTER_MANYERRORS 0x00000002 /*%< Continue processing on errors. */ +#define DNS_MASTER_NOINCLUDE 0x00000004 /*%< Disallow $INCLUDE directives. */ +#define DNS_MASTER_ZONE 0x00000008 /*%< Loading a zone master file. */ +#define DNS_MASTER_HINT 0x00000010 /*%< Loading a hint master file. */ +#define DNS_MASTER_SLAVE 0x00000020 /*%< Loading a slave master file. */ +#define DNS_MASTER_CHECKNS 0x00000040 /*%< + * Check NS records to see + * if they are an address + */ +#define DNS_MASTER_FATALNS 0x00000080 /*%< + * Treat DNS_MASTER_CHECKNS + * matches as fatal + */ #define DNS_MASTER_CHECKNAMES 0x00000100 #define DNS_MASTER_CHECKNAMESFAIL 0x00000200 +#define DNS_MASTER_CHECKWILDCARD 0x00000400 /* Check for internal wildcards. */ +#define DNS_MASTER_CHECKMX 0x00000800 +#define DNS_MASTER_CHECKMXFAIL 0x00001000 ISC_LANG_BEGINDECLS +/* + * Structures that implement the "raw" format for master dump. + * These are provided for a reference purpose only; in the actual + * encoding, we directly read/write each field so that the encoded data + * is always "packed", regardless of the hardware architecture. + */ +#define DNS_RAWFORMAT_VERSION 0 + +/* Common header */ +typedef struct { + isc_uint32_t format; /* must be + * dns_masterformat_raw */ + isc_uint32_t version; /* compatibility for future + * extensions */ + isc_uint32_t dumptime; /* timestamp on creation + * (currently unused) + */ +} dns_masterrawheader_t; + +/* The structure for each RRset */ +typedef struct { + isc_uint32_t totallen; /* length of the data for this + * RRset, including the + * "header" part */ + dns_rdataclass_t rdclass; /* 16-bit class */ + dns_rdatatype_t type; /* 16-bit type */ + dns_rdatatype_t covers; /* same as type */ + dns_ttl_t ttl; /* 32-bit TTL */ + isc_uint32_t nrdata; /* number of RRs in this set */ + /* followed by encoded owner name, and then rdata */ +} dns_masterrawrdataset_t; + /*** *** Function ***/ @@ -62,6 +103,16 @@ dns_master_loadfile(const char *master_file, isc_mem_t *mctx); isc_result_t +dns_master_loadfile2(const char *master_file, + dns_name_t *top, + dns_name_t *origin, + dns_rdataclass_t zclass, + unsigned int options, + dns_rdatacallbacks_t *callbacks, + isc_mem_t *mctx, + dns_masterformat_t format); + +isc_result_t dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, @@ -100,6 +151,18 @@ dns_master_loadfileinc(const char *master_file, dns_loadctx_t **ctxp, isc_mem_t *mctx); isc_result_t +dns_master_loadfileinc2(const char *master_file, + dns_name_t *top, + dns_name_t *origin, + dns_rdataclass_t zclass, + unsigned int options, + dns_rdatacallbacks_t *callbacks, + isc_task_t *task, + dns_loaddonefunc_t done, void *done_arg, + dns_loadctx_t **ctxp, isc_mem_t *mctx, + dns_masterformat_t format); + +isc_result_t dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, @@ -132,8 +195,8 @@ dns_master_loadlexerinc(isc_lex_t *lex, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx); -/* - * Loads a RFC 1305 master file from a file, stream, buffer, or existing +/*%< + * Loads a RFC1305 master file from a file, stream, buffer, or existing * lexer into rdatasets and then calls 'callbacks->commit' to commit the * rdatasets. Rdata memory belongs to dns_master_load and will be * reused / released when the callback completes. dns_load_master will @@ -150,63 +213,63 @@ dns_master_loadlexerinc(isc_lex_t *lex, * not called. * * Requires: - * 'master_file' points to a valid string. - * 'lexer' points to a valid lexer. - * 'top' points to a valid name. - * 'origin' points to a valid name. - * 'callbacks->commit' points to a valid function. - * 'callbacks->error' points to a valid function. - * 'callbacks->warn' points to a valid function. - * 'mctx' points to a valid memory context. - * 'task' and 'done' to be valid. - * 'lmgr' to be valid. - * 'ctxp != NULL && ctxp == NULL'. + *\li 'master_file' points to a valid string. + *\li 'lexer' points to a valid lexer. + *\li 'top' points to a valid name. + *\li 'origin' points to a valid name. + *\li 'callbacks->commit' points to a valid function. + *\li 'callbacks->error' points to a valid function. + *\li 'callbacks->warn' points to a valid function. + *\li 'mctx' points to a valid memory context. + *\li 'task' and 'done' to be valid. + *\li 'lmgr' to be valid. + *\li 'ctxp != NULL && ctxp == NULL'. * * Returns: - * ISC_R_SUCCESS upon successfully loading the master file. - * ISC_R_SEENINCLUDE upon successfully loading the master file with + *\li ISC_R_SUCCESS upon successfully loading the master file. + *\li ISC_R_SEENINCLUDE upon successfully loading the master file with * a $INCLUDE statement. - * ISC_R_NOMEMORY out of memory. - * ISC_R_UNEXPECTEDEND expected to be able to read a input token and + *\li ISC_R_NOMEMORY out of memory. + *\li ISC_R_UNEXPECTEDEND expected to be able to read a input token and * there was not one. - * ISC_R_UNEXPECTED - * DNS_R_NOOWNER failed to specify a ownername. - * DNS_R_NOTTL failed to specify a ttl. - * DNS_R_BADCLASS record class did not match zone class. - * DNS_R_CONTINUE load still in progress (dns_master_load*inc() only). - * Any dns_rdata_fromtext() error code. - * Any error code from callbacks->commit(). + *\li ISC_R_UNEXPECTED + *\li DNS_R_NOOWNER failed to specify a ownername. + *\li DNS_R_NOTTL failed to specify a ttl. + *\li DNS_R_BADCLASS record class did not match zone class. + *\li DNS_R_CONTINUE load still in progress (dns_master_load*inc() only). + *\li Any dns_rdata_fromtext() error code. + *\li Any error code from callbacks->commit(). */ void dns_loadctx_detach(dns_loadctx_t **ctxp); -/* +/*%< * Detach from the load context. * * Requires: - * '*ctxp' to be valid. + *\li '*ctxp' to be valid. * * Ensures: - * '*ctxp == NULL' + *\li '*ctxp == NULL' */ void dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target); -/* +/*%< * Attach to the load context. * * Requires: - * 'source' to be valid. - * 'target != NULL && *target == NULL'. + *\li 'source' to be valid. + *\li 'target != NULL && *target == NULL'. */ void dns_loadctx_cancel(dns_loadctx_t *ctx); -/* +/*%< * Cancel loading the zone file associated with this load context. * * Requires: - * 'ctx' to be valid + *\li 'ctx' to be valid */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/masterdump.h b/contrib/bind9/lib/dns/include/dns/masterdump.h index 888c588..8cf5c13 100644 --- a/contrib/bind9/lib/dns/include/dns/masterdump.h +++ b/contrib/bind9/lib/dns/include/dns/masterdump.h @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.h,v 1.22.12.10 2005/09/06 02:12:41 marka Exp $ */ +/* $Id: masterdump.h,v 1.31.14.4 2005/09/01 03:04:28 marka Exp $ */ #ifndef DNS_MASTERDUMP_H #define DNS_MASTERDUMP_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -46,10 +48,10 @@ typedef struct dns_master_style dns_master_style_t; * rdata.h. */ -/* Omit the owner name when possible. */ +/*% Omit the owner name when possible. */ #define DNS_STYLEFLAG_OMIT_OWNER 0x00010000U -/* +/*% * Omit the TTL when possible. If DNS_STYLEFLAG_TTL is * also set, this means no TTLs are ever printed * because $TTL directives are generated before every @@ -67,32 +69,32 @@ typedef struct dns_master_style dns_master_style_t; */ #define DNS_STYLEFLAG_OMIT_TTL 0x00020000U -/* Omit the class when possible. */ +/*% Omit the class when possible. */ #define DNS_STYLEFLAG_OMIT_CLASS 0x00040000U -/* Output $TTL directives. */ +/*% Output $TTL directives. */ #define DNS_STYLEFLAG_TTL 0x00080000U -/* +/*% * Output $ORIGIN directives and print owner names relative to * the origin when possible. */ #define DNS_STYLEFLAG_REL_OWNER 0x00100000U -/* Print domain names in RR data in relative form when possible. +/*% Print domain names in RR data in relative form when possible. For this to take effect, DNS_STYLEFLAG_REL_OWNER must also be set. */ #define DNS_STYLEFLAG_REL_DATA 0x00200000U -/* Print the trust level of each rdataset. */ +/*% Print the trust level of each rdataset. */ #define DNS_STYLEFLAG_TRUST 0x00400000U -/* Print negative caching entries. */ +/*% Print negative caching entries. */ #define DNS_STYLEFLAG_NCACHE 0x00800000U -/* Never print the TTL */ +/*% Never print the TTL */ #define DNS_STYLEFLAG_NO_TTL 0x01000000U -/* Never print the CLASS */ +/*% Never print the CLASS */ #define DNS_STYLEFLAG_NO_CLASS 0x02000000U ISC_LANG_BEGINDECLS @@ -101,7 +103,7 @@ ISC_LANG_BEGINDECLS *** Constants ***/ -/* +/*% * The default master file style. * * This uses $TTL directives to avoid the need to dedicate a @@ -110,13 +112,13 @@ ISC_LANG_BEGINDECLS */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_default; -/* +/*% * A master file style that dumps zones to a very generic format easily * imported/checked with external tools. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_full; -/* +/*% * A master file style that prints explicit TTL values on each * record line, never using $TTL statements. The TTL has a tab * stop of its own, but the class and type share one. @@ -124,13 +126,13 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_full; LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_explicitttl; -/* +/*% * A master style format designed for cache files. It prints explicit TTL * values on each record line and never uses $ORIGIN or relative names. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_cache; -/* +/*% * A master style that prints name, ttl, class, type, and value on * every line. Similar to explicitttl above, but more verbose. * Intended for generating master files which can be easily parsed @@ -138,7 +140,7 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_cache; */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_simple; -/* +/*% * The style used for debugging, "dig" output, etc. */ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_debug; @@ -149,54 +151,55 @@ LIBDNS_EXTERNAL_DATA extern const dns_master_style_t dns_master_style_debug; void dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target); -/* +/*%< * Attach to a dump context. * * Require: - * 'source' to be valid. - * 'target' to be non NULL and '*target' to be NULL. + *\li 'source' to be valid. + *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_dumpctx_detach(dns_dumpctx_t **dctxp); -/* +/*%< * Detach from a dump context. * * Require: - * 'dctxp' to point to a valid dump context. + *\li 'dctxp' to point to a valid dump context. * * Ensures: - * '*dctxp' is NULL. + *\li '*dctxp' is NULL. */ void dns_dumpctx_cancel(dns_dumpctx_t *dctx); -/* +/*%< * Cancel a in progress dump. * * Require: - * 'dctx' to be valid. + *\li 'dctx' to be valid. */ dns_dbversion_t * dns_dumpctx_version(dns_dumpctx_t *dctx); -/* +/*%< * Return the version handle (if any) of the database being dumped. * * Require: - * 'dctx' to be valid. + *\li 'dctx' to be valid. */ dns_db_t * dns_dumpctx_db(dns_dumpctx_t *dctx); -/* +/*%< * Return the database being dumped. * * Require: - * 'dctx' to be valid. + *\li 'dctx' to be valid. */ +/*@{*/ isc_result_t dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, @@ -208,26 +211,37 @@ isc_result_t dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f); -/* - * Dump the database 'db' to the steam 'f' in RFC1035 master - * file format, in the style defined by 'style' - * (e.g., &dns_default_master_style_default) + +isc_result_t +dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, + dns_masterformat_t format, FILE *f); +/*%< + * Dump the database 'db' to the steam 'f' in the specified format by + * 'format'. If the format is dns_masterformat_text (the RFC1035 format), + * 'style' specifies the file style (e.g., &dns_master_style_default). + * + * dns_master_dumptostream() is an old form of dns_master_dumptostream2(), + * which always specifies the dns_masterformat_text format. * * Temporary dynamic memory may be allocated from 'mctx'. * * Require: - * 'task' to be valid. - * 'done' to be non NULL. - * 'dctxp' to be non NULL && '*dctxp' to be NULL. + *\li 'task' to be valid. + *\li 'done' to be non NULL. + *\li 'dctxp' to be non NULL && '*dctxp' to be NULL. * * Returns: - * ISC_R_SUCCESS - * DNS_R_CONTINUE dns_master_dumptostreaminc() only. - * ISC_R_NOMEMORY - * Any database or rrset iterator error. - * Any dns_rdata_totext() error code. + *\li ISC_R_SUCCESS + *\li ISC_R_CONTINUE dns_master_dumptostreaminc() only. + *\li ISC_R_NOMEMORY + *\li Any database or rrset iterator error. + *\li Any dns_rdata_totext() error code. */ +/*@}*/ +/*@{*/ isc_result_t dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, @@ -235,39 +249,56 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dns_dumpctx_t **dctxp); isc_result_t +dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format); + +isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename); -/* - * Dump the database 'db' to the file 'filename' in RFC1035 master - * file format, in the style defined by 'style' - * (e.g., &dns_default_master_style_default) + +isc_result_t +dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + dns_masterformat_t format); + +/*%< + * Dump the database 'db' to the file 'filename' in the specified format by + * 'format'. If the format is dns_masterformat_text (the RFC1035 format), + * 'style' specifies the file style (e.g., &dns_master_style_default). + * + * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc2() + * and _dump2(), respectively, which always specify the dns_masterformat_text + * format. * * Temporary dynamic memory may be allocated from 'mctx'. * * Returns: - * ISC_R_SUCCESS - * DNS_R_CONTINUE dns_master_dumpinc() only. - * ISC_R_NOMEMORY - * Any database or rrset iterator error. - * Any dns_rdata_totext() error code. + *\li ISC_R_SUCCESS + *\li ISC_R_CONTINUE dns_master_dumpinc() only. + *\li ISC_R_NOMEMORY + *\li Any database or rrset iterator error. + *\li Any dns_rdata_totext() error code. */ +/*@}*/ isc_result_t dns_master_rdatasettotext(dns_name_t *owner_name, dns_rdataset_t *rdataset, const dns_master_style_t *style, isc_buffer_t *target); -/* +/*%< * Convert 'rdataset' to text format, storing the result in 'target'. * * Notes: - * The rdata cursor position will be changed. + *\li The rdata cursor position will be changed. * * Requires: - * 'rdataset' is a valid non-question rdataset. + *\li 'rdataset' is a valid non-question rdataset. * - * 'rdataset' is not empty. + *\li 'rdataset' is not empty. */ isc_result_t diff --git a/contrib/bind9/lib/dns/include/dns/message.h b/contrib/bind9/lib/dns/include/dns/message.h index 960c11a..9002b83 100644 --- a/contrib/bind9/lib/dns/include/dns/message.h +++ b/contrib/bind9/lib/dns/include/dns/message.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.h,v 1.100.2.3.8.10 2006/02/28 06:32:54 marka Exp $ */ +/* $Id: message.h,v 1.114.18.6 2006/03/02 23:19:20 marka Exp $ */ #ifndef DNS_MESSAGE_H #define DNS_MESSAGE_H 1 @@ -33,7 +33,9 @@ #include <dst/dst.h> -/* +/*! \file + * \brief Message Handling Module + * * How this beast works: * * When a dns message is received in a buffer, dns_message_fromwire() is called @@ -54,9 +56,9 @@ * one of two ways. Assume a name was allocated via * dns_message_gettempname(): * - * (1) insert it into a section, using dns_message_addname(). + *\li (1) insert it into a section, using dns_message_addname(). * - * (2) return it to the message using dns_message_puttempname(). + *\li (2) return it to the message using dns_message_puttempname(). * * The same applies to rdatasets. * @@ -74,6 +76,7 @@ * Since the buffer itself exists until the message is destroyed, this sort * of code can be written: * + * \code * buffer = isc_buffer_allocate(mctx, 512); * name = NULL; * name = dns_message_gettempname(message, &name); @@ -81,6 +84,7 @@ * result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE, * buffer); * dns_message_takebuffer(message, &buffer); + * \endcode * * * TODO: @@ -102,7 +106,7 @@ #define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) -#define DNS_MESSAGE_HEADERLEN 12 /* 6 isc_uint16_t's */ +#define DNS_MESSAGE_HEADERLEN 12 /*%< 6 isc_uint16_t's */ #define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@') #define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC) @@ -140,32 +144,32 @@ typedef int dns_messagetextflag_t; /* * These tell the message library how the created dns_message_t will be used. */ -#define DNS_MESSAGE_INTENTUNKNOWN 0 /* internal use only */ -#define DNS_MESSAGE_INTENTPARSE 1 /* parsing messages */ -#define DNS_MESSAGE_INTENTRENDER 2 /* rendering */ +#define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ +#define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ +#define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ /* * Control behavior of parsing */ -#define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /* preserve rdata order */ -#define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /* return a message if a +#define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */ +#define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a recoverable parse error occurs */ -#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /* save a copy of the +#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /*%< save a copy of the source buffer */ -#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /* trucation errors are +#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< trucation errors are * not fatal. */ /* * Control behavior of rendering */ -#define DNS_MESSAGERENDER_ORDERED 0x0001 /* don't change order */ -#define DNS_MESSAGERENDER_PARTIAL 0x0002 /* allow a partial rdataset */ -#define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /* omit DNSSEC records */ -#define DNS_MESSAGERENDER_PREFER_A 0x0008 /* prefer A records in - * additional section. */ -#define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /* prefer AAAA records in - * additional section. */ +#define DNS_MESSAGERENDER_ORDERED 0x0001 /*%< don't change order */ +#define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */ +#define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */ +#define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in + additional section. */ +#define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in + additional section. */ typedef struct dns_msgblock dns_msgblock_t; @@ -248,32 +252,32 @@ ISC_LANG_BEGINDECLS isc_result_t dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); -/* +/*%< * Create msg structure. * * This function will allocate some internal blocks of memory that are * expected to be needed for parsing or rendering nearly any type of message. * * Requires: - * 'mctx' be a valid memory context. + *\li 'mctx' be a valid memory context. * - * 'msgp' be non-null and '*msg' be NULL. + *\li 'msgp' be non-null and '*msg' be NULL. * - * 'intent' must be one of DNS_MESSAGE_INTENTPARSE or - * DNS_MESSAGE_INTENTRENDER. + *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or + * #DNS_MESSAGE_INTENTRENDER. * * Ensures: - * The data in "*msg" is set to indicate an unused and empty msg + *\li The data in "*msg" is set to indicate an unused and empty msg * structure. * * Returns: - * ISC_R_NOMEMORY -- out of memory - * ISC_R_SUCCESS -- success + *\li #ISC_R_NOMEMORY -- out of memory + *\li #ISC_R_SUCCESS -- success */ void dns_message_reset(dns_message_t *msg, unsigned int intent); -/* +/*%< * Reset a message structure to default state. All internal lists are freed * or reset to a default state as well. This is simply a more efficient * way to call dns_message_destroy() followed by dns_message_allocate(), @@ -286,22 +290,22 @@ dns_message_reset(dns_message_t *msg, unsigned int intent); * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER + *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER */ void dns_message_destroy(dns_message_t **msgp); -/* +/*%< * Destroy all state in the message. * * Requires: * - * 'msgp' be valid. + *\li 'msgp' be valid. * * Ensures: - * '*msgp' == NULL + *\li '*msgp' == NULL */ isc_result_t @@ -316,85 +320,83 @@ dns_message_pseudosectiontotext(dns_message_t *msg, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target); -/* +/*%< * Convert section 'section' or 'pseudosection' of message 'msg' to * a cleartext representation * * Notes: - * See dns_message_totext for meanings of flags. + * \li See dns_message_totext for meanings of flags. * * Requires: * - * 'msg' is a valid message. + *\li 'msg' is a valid message. * - * 'style' is a valid master dump style. + *\li 'style' is a valid master dump style. * - * 'target' is a valid buffer. + *\li 'target' is a valid buffer. * - * 'section' is a valid section label. + *\li 'section' is a valid section label. * * Ensures: * - * If the result is success: - * + *\li If the result is success: * The used space in 'target' is updated. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOSPACE - * ISC_R_NOMORE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE + *\li #ISC_R_NOMORE * - * Note: On error return, *target may be partially filled with data. + *\li Note: On error return, *target may be partially filled with data. */ isc_result_t dns_message_totext(dns_message_t *msg, const dns_master_style_t *style, dns_messagetextflag_t flags, isc_buffer_t *target); -/* +/*%< * Convert all sections of message 'msg' to a cleartext representation * * Notes: - * In flags, If DNS_MESSAGETEXTFLAG_OMITDOT is set, then the + * \li In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the * final '.' in absolute names will not be emitted. If - * DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning + * #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning * with ";;" will be emitted indicating section name. If - * DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will + * #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will * be emitted. * * Requires: * - * 'msg' is a valid message. + *\li 'msg' is a valid message. * - * 'style' is a valid master dump style. + *\li 'style' is a valid master dump style. * - * 'target' is a valid buffer. + *\li 'target' is a valid buffer. * * Ensures: * - * If the result is success: - * + *\li If the result is success: * The used space in 'target' is updated. * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOSPACE - * ISC_R_NOMORE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE + *\li #ISC_R_NOMORE * - * Note: On error return, *target may be partially filled with data. + *\li Note: On error return, *target may be partially filled with data. */ isc_result_t dns_message_parse(dns_message_t *msg, isc_buffer_t *source, unsigned int options); -/* +/*%< * Parse raw wire data in 'source' as a DNS message. * * OPT records are detected and stored in the pseudo-section "opt". * TSIGs are detected and stored in the pseudo-section "tsig". * - * If DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message + * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message * is UPDATE, a separate dns_name_t object will be created for each RR in the * message. Each such dns_name_t will have a single rdataset containing the * single RR, and the order of the RRs in the message is preserved. @@ -403,39 +405,39 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, * of rdatasets. To access the names and their data, use * dns_message_firstname() and dns_message_nextname(). * - * If DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will + * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will * not be considered FORMERRs. If the entire message can be parsed, it * will be returned and DNS_R_RECOVERABLE will be returned. * - * If DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete + * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete * RR's as possible, DNS_R_RECOVERABLE will be returned. * * OPT and TSIG records are always handled specially, regardless of the * 'preserve_order' setting. * * Requires: - * "msg" be valid. + *\li "msg" be valid. * - * "buffer" be a wire format buffer. + *\li "buffer" be a wire format buffer. * * Ensures: - * The buffer's data format is correct. + *\li The buffer's data format is correct. * - * The buffer's contents verify as correct regarding header bits, buffer + *\li The buffer's contents verify as correct regarding header bits, buffer * and rdata sizes, etc. * * Returns: - * ISC_R_SUCCESS -- all is well - * ISC_R_NOMEMORY -- no memory - * DNS_R_RECOVERABLE -- the message parsed properly, but contained + *\li #ISC_R_SUCCESS -- all is well + *\li #ISC_R_NOMEMORY -- no memory + *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained * errors. - * Many other errors possible XXXMLG + *\li Many other errors possible XXXMLG */ isc_result_t dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, isc_buffer_t *buffer); -/* +/*%< * Begin rendering on a message. Only one call can be made to this function * per message. * @@ -447,24 +449,24 @@ dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * 'cctx' be valid. + *\li 'cctx' be valid. * - * 'buffer' is a valid buffer. + *\li 'buffer' is a valid buffer. * * Side Effects: * - * The buffer is cleared before it is used. + *\li The buffer is cleared before it is used. * * Returns: - * ISC_R_SUCCESS -- all is well - * ISC_R_NOSPACE -- output buffer is too small + *\li #ISC_R_SUCCESS -- all is well + *\li #ISC_R_NOSPACE -- output buffer is too small */ isc_result_t dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); -/* +/*%< * Reset the buffer. This can be used after growing the old buffer * on a ISC_R_NOSPACE return from most of the render functions. * @@ -474,20 +476,20 @@ dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * dns_message_renderbegin() was called. + *\li dns_message_renderbegin() was called. * - * buffer != NULL. + *\li buffer != NULL. * * Returns: - * ISC_R_NOSPACE -- new buffer is too small - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_NOSPACE -- new buffer is too small + *\li #ISC_R_SUCCESS -- all is well. */ isc_result_t dns_message_renderreserve(dns_message_t *msg, unsigned int space); -/* +/*%< * XXXMLG should use size_t rather than unsigned int once the buffer * API is cleaned up * @@ -495,18 +497,18 @@ dns_message_renderreserve(dns_message_t *msg, unsigned int space); * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * dns_message_renderbegin() was called. + *\li dns_message_renderbegin() was called. * * Returns: - * ISC_R_SUCCESS -- all is well. - * ISC_R_NOSPACE -- not enough free space in the buffer. + *\li #ISC_R_SUCCESS -- all is well. + *\li #ISC_R_NOSPACE -- not enough free space in the buffer. */ void dns_message_renderrelease(dns_message_t *msg, unsigned int space); -/* +/*%< * XXXMLG should use size_t rather than unsigned int once the buffer * API is cleaned up * @@ -514,87 +516,87 @@ dns_message_renderrelease(dns_message_t *msg, unsigned int space); * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * 'space' is less than or equal to the total amount of space reserved + *\li 'space' is less than or equal to the total amount of space reserved * via prior calls to dns_message_renderreserve(). * - * dns_message_renderbegin() was called. + *\li dns_message_renderbegin() was called. */ isc_result_t dns_message_rendersection(dns_message_t *msg, dns_section_t section, unsigned int options); -/* +/*%< * Render all names, rdatalists, etc from the given section at the * specified priority or higher. * * Requires: - * 'msg' be valid. + *\li 'msg' be valid. * - * 'section' be a valid section. + *\li 'section' be a valid section. * - * dns_message_renderbegin() was called. + *\li dns_message_renderbegin() was called. * * Returns: - * ISC_R_SUCCESS -- all records were written, and there are + *\li #ISC_R_SUCCESS -- all records were written, and there are * no more records for this section. - * ISC_R_NOSPACE -- Not enough room in the buffer to write + *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write * all records requested. - * DNS_R_MOREDATA -- All requested records written, and there + *\li #DNS_R_MOREDATA -- All requested records written, and there * are records remaining for this section. */ void dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); -/* +/*%< * Render the message header. This is implicitly called by * dns_message_renderend(). * * Requires: * - * 'msg' be a valid message. + *\li 'msg' be a valid message. * - * dns_message_renderbegin() was called. + *\li dns_message_renderbegin() was called. * - * 'target' is a valid buffer with enough space to hold a message header + *\li 'target' is a valid buffer with enough space to hold a message header */ isc_result_t dns_message_renderend(dns_message_t *msg); -/* +/*%< * Finish rendering to the buffer. Note that more data can be in the * 'msg' structure. Destroying the structure will free this, or in a multi- * part EDNS1 message this data can be rendered to another buffer later. * * Requires: * - * 'msg' be a valid message. + *\li 'msg' be a valid message. * - * dns_message_renderbegin() was called. + *\li dns_message_renderbegin() was called. * * Returns: - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_SUCCESS -- all is well. */ void dns_message_renderreset(dns_message_t *msg); -/* +/*%< * Reset the message so that it may be rendered again. * * Notes: * - * If dns_message_renderbegin() has been called, dns_message_renderend() + *\li If dns_message_renderbegin() has been called, dns_message_renderend() * must be called before calling this function. * * Requires: * - * 'msg' be a valid message with rendering intent. + *\li 'msg' be a valid message with rendering intent. */ isc_result_t dns_message_firstname(dns_message_t *msg, dns_section_t section); -/* +/*%< * Set internal per-section name pointer to the beginning of the section. * * The functions dns_message_firstname() and dns_message_nextname() may @@ -602,39 +604,39 @@ dns_message_firstname(dns_message_t *msg, dns_section_t section); * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * 'section' be a valid section. + *\li 'section' be a valid section. * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMORE -- No names on given section. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMORE -- No names on given section. */ isc_result_t dns_message_nextname(dns_message_t *msg, dns_section_t section); -/* +/*%< * Sets the internal per-section name pointer to point to the next name * in that section. * * Requires: * - * 'msg' be valid. + * \li 'msg' be valid. * - * 'section' be a valid section. + *\li 'section' be a valid section. * - * dns_message_firstname() must have been called on this section, + *\li dns_message_firstname() must have been called on this section, * and the result was ISC_R_SUCCESS. * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMORE -- No more names in given section. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMORE -- No more names in given section. */ void dns_message_currentname(dns_message_t *msg, dns_section_t section, dns_name_t **name); -/* +/*%< * Sets 'name' to point to the name where the per-section internal name * pointer is currently set. * @@ -643,15 +645,15 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section, * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * 'name' be non-NULL, and *name be NULL. + *\li 'name' be non-NULL, and *name be NULL. * - * 'section' be a valid section. + *\li 'section' be a valid section. * - * dns_message_firstname() must have been called on this section, + *\li dns_message_firstname() must have been called on this section, * and the result of it and any dns_message_nextname() calls was - * ISC_R_SUCCESS. + * #ISC_R_SUCCESS. */ isc_result_t @@ -659,55 +661,55 @@ dns_message_findname(dns_message_t *msg, dns_section_t section, dns_name_t *target, dns_rdatatype_t type, dns_rdatatype_t covers, dns_name_t **foundname, dns_rdataset_t **rdataset); -/* +/*%< * Search for a name in the specified section. If it is found, *name is * set to point to the name, and *rdataset is set to point to the found * rdataset (if type is specified as other than dns_rdatatype_any). * * Requires: - * 'msg' be valid. + *\li 'msg' be valid. * - * 'section' be a valid section. + *\li 'section' be a valid section. * - * If a pointer to the name is desired, 'foundname' should be non-NULL. + *\li If a pointer to the name is desired, 'foundname' should be non-NULL. * If it is non-NULL, '*foundname' MUST be NULL. * - * If a type other than dns_datatype_any is searched for, 'rdataset' + *\li If a type other than dns_datatype_any is searched for, 'rdataset' * may be non-NULL, '*rdataset' be NULL, and will point at the found * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. * - * 'target' be a valid name. + *\li 'target' be a valid name. * - * 'type' be a valid type. + *\li 'type' be a valid type. * - * If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. + *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. * Otherwise it should be 0. * * Returns: - * ISC_R_SUCCESS -- all is well. - * DNS_R_NXDOMAIN -- name does not exist in that section. - * DNS_R_NXRRSET -- The name does exist, but the desired + *\li #ISC_R_SUCCESS -- all is well. + *\li #DNS_R_NXDOMAIN -- name does not exist in that section. + *\li #DNS_R_NXRRSET -- The name does exist, but the desired * type does not. */ isc_result_t dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdataset_t **rdataset); -/* +/*%< * Search the name for the specified type. If it is found, *rdataset is * filled in with a pointer to that rdataset. * * Requires: - * if '**rdataset' is non-NULL, *rdataset needs to be NULL. + *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. * - * 'type' be a valid type, and NOT dns_rdatatype_any. + *\li 'type' be a valid type, and NOT dns_rdatatype_any. * - * If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. + *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. * Otherwise it should be 0. * * Returns: - * ISC_R_SUCCESS -- all is well. - * ISC_R_NOTFOUND -- the desired type does not exist. + *\li #ISC_R_SUCCESS -- all is well. + *\li #ISC_R_NOTFOUND -- the desired type does not exist. */ isc_result_t @@ -735,24 +737,24 @@ void dns_message_movename(dns_message_t *msg, dns_name_t *name, dns_section_t fromsection, dns_section_t tosection); -/* +/*%< * Move a name from one section to another. * * Requires: * - * 'msg' be valid. + *\li 'msg' be valid. * - * 'name' must be a name already in 'fromsection'. + *\li 'name' must be a name already in 'fromsection'. * - * 'fromsection' must be a valid section. + *\li 'fromsection' must be a valid section. * - * 'tosection' must be a valid section. + *\li 'tosection' must be a valid section. */ void dns_message_addname(dns_message_t *msg, dns_name_t *name, dns_section_t section); -/* +/*%< * Adds the name to the given section. * * It is the caller's responsibility to enforce any unique name requirements @@ -760,13 +762,32 @@ dns_message_addname(dns_message_t *msg, dns_name_t *name, * * Requires: * - * 'msg' be valid, and be a renderable message. + *\li 'msg' be valid, and be a renderable message. + * + *\li 'name' be a valid absolute name. + * + *\li 'section' be a named section. + */ + +void +dns_message_removename(dns_message_t *msg, dns_name_t *name, + dns_section_t section); +/*%< + * Remove a existing name from a given section. + * + * It is the caller's responsibility to ensure the name is part of the + * given section. + * + * Requires: + * + *\li 'msg' be valid, and be a renderable message. * - * 'name' be a valid absolute name. + *\li 'name' be a valid absolute name. * - * 'section' be a named section. + *\li 'section' be a named section. */ + /* * LOANOUT FUNCTIONS * @@ -777,7 +798,7 @@ dns_message_addname(dns_message_t *msg, dns_name_t *name, isc_result_t dns_message_gettempname(dns_message_t *msg, dns_name_t **item); -/* +/*%< * Return a name that can be used for any temporary purpose, including * inserting into the message's linked lists. The name must be returned * to the message code using dns_message_puttempname() or inserted into @@ -786,180 +807,180 @@ dns_message_gettempname(dns_message_t *msg, dns_name_t **item); * It is the caller's responsibility to initialize this name. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item == NULL + *\li item != NULL && *item == NULL * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMEMORY -- No item can be allocated. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); -/* +/*%< * Return an offsets array that can be used for any temporary purpose, * such as attaching to a temporary name. The offsets will be freed * when the message is destroyed or reset. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item == NULL + *\li item != NULL && *item == NULL * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMEMORY -- No item can be allocated. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); -/* +/*%< * Return a rdata that can be used for any temporary purpose, including * inserting into the message's linked lists. The rdata will be freed * when the message is destroyed or reset. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item == NULL + *\li item != NULL && *item == NULL * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMEMORY -- No item can be allocated. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); -/* +/*%< * Return a rdataset that can be used for any temporary purpose, including * inserting into the message's linked lists. The name must be returned * to the message code using dns_message_puttempname() or inserted into * one of the message's sections before the message is destroyed. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item == NULL + *\li item != NULL && *item == NULL * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMEMORY -- No item can be allocated. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMEMORY -- No item can be allocated. */ isc_result_t dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); -/* +/*%< * Return a rdatalist that can be used for any temporary purpose, including * inserting into the message's linked lists. The rdatalist will be * destroyed when the message is destroyed or reset. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item == NULL + *\li item != NULL && *item == NULL * * Returns: - * ISC_R_SUCCESS -- All is well. - * ISC_R_NOMEMORY -- No item can be allocated. + *\li #ISC_R_SUCCESS -- All is well. + *\li #ISC_R_NOMEMORY -- No item can be allocated. */ void dns_message_puttempname(dns_message_t *msg, dns_name_t **item); -/* +/*%< * Return a borrowed name to the message's name free list. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item point to a name returned by + *\li item != NULL && *item point to a name returned by * dns_message_gettempname() * * Ensures: - * *item == NULL + *\li *item == NULL */ void dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); -/* +/*%< * Return a borrowed rdata to the message's rdata free list. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item point to a rdata returned by + *\li item != NULL && *item point to a rdata returned by * dns_message_gettemprdata() * * Ensures: - * *item == NULL + *\li *item == NULL */ void dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); -/* +/*%< * Return a borrowed rdataset to the message's rdataset free list. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item point to a rdataset returned by + *\li item != NULL && *item point to a rdataset returned by * dns_message_gettemprdataset() * * Ensures: - * *item == NULL + *\li *item == NULL */ void dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); -/* +/*%< * Return a borrowed rdatalist to the message's rdatalist free list. * * Requires: - * msg be a valid message + *\li msg be a valid message * - * item != NULL && *item point to a rdatalist returned by + *\li item != NULL && *item point to a rdatalist returned by * dns_message_gettemprdatalist() * * Ensures: - * *item == NULL + *\li *item == NULL */ isc_result_t dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, unsigned int *flagsp); -/* +/*%< * Assume the remaining region of "source" is a DNS message. Peek into * it and fill in "*idp" with the message id, and "*flagsp" with the flags. * * Requires: * - * source != NULL + *\li source != NULL * * Ensures: * - * if (idp != NULL) *idp == message id. + *\li if (idp != NULL) *idp == message id. * - * if (flagsp != NULL) *flagsp == message flags. + *\li if (flagsp != NULL) *flagsp == message flags. * * Returns: * - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_SUCCESS -- all is well. * - * ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. + *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. */ isc_result_t dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); -/* +/*%< * Start formatting a reply to the query in 'msg'. * * Requires: * - * 'msg' is a valid message with parsing intent, and contains a query. + *\li 'msg' is a valid message with parsing intent, and contains a query. * * Ensures: * - * The message will have a rendering intent. If 'want_question_section' + *\li The message will have a rendering intent. If 'want_question_section' * is true, the message opcode is query or notify, and the question * section is present and properly formatted, then the question section * will be included in the reply. All other sections will be cleared. @@ -968,9 +989,9 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); * * Returns: * - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_SUCCESS -- all is well. * - * DNS_R_FORMERR -- the header or question section of the + *\li #DNS_R_FORMERR -- the header or question section of the * message is invalid, replying is impossible. * If DNS_R_FORMERR is returned when * want_question_section is ISC_FALSE, then @@ -981,308 +1002,308 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); dns_rdataset_t * dns_message_getopt(dns_message_t *msg); -/* +/*%< * Get the OPT record for 'msg'. * * Requires: * - * 'msg' is a valid message. + *\li 'msg' is a valid message. * * Returns: * - * The OPT rdataset of 'msg', or NULL if there isn't one. + *\li The OPT rdataset of 'msg', or NULL if there isn't one. */ isc_result_t dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); -/* +/*%< * Set the OPT record for 'msg'. * * Requires: * - * 'msg' is a valid message with rendering intent + *\li 'msg' is a valid message with rendering intent * and no sections have been rendered. * - * 'opt' is a valid OPT record. + *\li 'opt' is a valid OPT record. * * Ensures: * - * The OPT record has either been freed or ownership of it has + *\li The OPT record has either been freed or ownership of it has * been transferred to the message. * - * If ISC_R_SUCCESS was returned, the OPT record will be rendered + *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered * when dns_message_renderend() is called. * * Returns: * - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_SUCCESS -- all is well. * - * ISC_R_NOSPACE -- there is no space for the OPT record. + *\li #ISC_R_NOSPACE -- there is no space for the OPT record. */ dns_rdataset_t * dns_message_gettsig(dns_message_t *msg, dns_name_t **owner); -/* +/*%< * Get the TSIG record and owner for 'msg'. * * Requires: * - * 'msg' is a valid message. - * 'owner' is NULL or *owner is NULL. + *\li 'msg' is a valid message. + *\li 'owner' is NULL or *owner is NULL. * * Returns: * - * The TSIG rdataset of 'msg', or NULL if there isn't one. + *\li The TSIG rdataset of 'msg', or NULL if there isn't one. * * Ensures: * - * If 'owner' is not NULL, it will point to the owner name. + * \li If 'owner' is not NULL, it will point to the owner name. */ isc_result_t dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key); -/* +/*%< * Set the tsig key for 'msg'. This is only necessary for when rendering a * query or parsing a response. The key (if non-NULL) is attached to, and * will be detached when the message is destroyed. * * Requires: * - * 'msg' is a valid message with rendering intent, + *\li 'msg' is a valid message with rendering intent, * dns_message_renderbegin() has been called, and no sections have been * rendered. - * 'key' is a valid tsig key or NULL. + *\li 'key' is a valid tsig key or NULL. * * Returns: * - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_SUCCESS -- all is well. * - * ISC_R_NOSPACE -- there is no space for the TSIG record. + *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. */ dns_tsigkey_t * dns_message_gettsigkey(dns_message_t *msg); -/* +/*%< * Gets the tsig key for 'msg'. * * Requires: * - * 'msg' is a valid message + *\li 'msg' is a valid message */ isc_result_t dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig); -/* +/*%< * Indicates that 'querytsig' is the TSIG from the signed query for which * 'msg' is the response. This is also used for chained TSIGs in TCP * responses. * * Requires: * - * 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() + *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() * or NULL * - * 'msg' is a valid message + *\li 'msg' is a valid message * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ isc_result_t dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t **querytsig); -/* +/*%< * Gets the tsig from the TSIG from the signed query 'msg'. This is also used * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes * a copy of the data, so can be used if the message is destroyed. * * Requires: * - * 'msg' is a valid signed message - * 'mctx' is a valid memory context - * querytsig != NULL && *querytsig == NULL + *\li 'msg' is a valid signed message + *\li 'mctx' is a valid memory context + *\li querytsig != NULL && *querytsig == NULL * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY * * Ensures: - * 'tsig' points to NULL or an allocated buffer which must be freed + *\li 'tsig' points to NULL or an allocated buffer which must be freed * by the caller. */ dns_rdataset_t * dns_message_getsig0(dns_message_t *msg, dns_name_t **owner); -/* +/*%< * Get the SIG(0) record and owner for 'msg'. * * Requires: * - * 'msg' is a valid message. - * 'owner' is NULL or *owner is NULL. + *\li 'msg' is a valid message. + *\li 'owner' is NULL or *owner is NULL. * * Returns: * - * The SIG(0) rdataset of 'msg', or NULL if there isn't one. + *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. * * Ensures: * - * If 'owner' is not NULL, it will point to the owner name. + * \li If 'owner' is not NULL, it will point to the owner name. */ isc_result_t dns_message_setsig0key(dns_message_t *msg, dst_key_t *key); -/* +/*%< * Set the SIG(0) key for 'msg'. * * Requires: * - * 'msg' is a valid message with rendering intent, + *\li 'msg' is a valid message with rendering intent, * dns_message_renderbegin() has been called, and no sections have been * rendered. - * 'key' is a valid sig key or NULL. + *\li 'key' is a valid sig key or NULL. * * Returns: * - * ISC_R_SUCCESS -- all is well. + *\li #ISC_R_SUCCESS -- all is well. * - * ISC_R_NOSPACE -- there is no space for the SIG(0) record. + *\li #ISC_R_NOSPACE -- there is no space for the SIG(0) record. */ dst_key_t * dns_message_getsig0key(dns_message_t *msg); -/* +/*%< * Gets the SIG(0) key for 'msg'. * * Requires: * - * 'msg' is a valid message + *\li 'msg' is a valid message */ void dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); -/* +/*%< * Give the *buffer to the message code to clean up when it is no * longer needed. This is usually when the message is reset or * destroyed. * * Requires: * - * msg be a valid message. + *\li msg be a valid message. * - * buffer != NULL && *buffer is a valid isc_buffer_t, which was + *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was * dynamincally allocated via isc_buffer_allocate(). */ isc_result_t dns_message_signer(dns_message_t *msg, dns_name_t *signer); -/* +/*%< * If this message was signed, return the identity of the signer. * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the * key that signed the message. * * Requires: * - * msg is a valid parsed message. - * signer is a valid name + *\li msg is a valid parsed message. + *\li signer is a valid name * * Returns: * - * ISC_R_SUCCESS - the message was signed, and *signer + *\li #ISC_R_SUCCESS - the message was signed, and *signer * contains the signing identity * - * ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the + *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the * message * - * DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the + *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the * signature failed to verify * - * DNS_R_TSIGERRORSET - the message was signed by a TSIG and + *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and * verified, but the query was rejected by * the server * - * DNS_R_NOIDENTITY - the message was signed by a TSIG and + *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and * verified, but the key has no identity since * it was generated by an unsigned TKEY process * - * DNS_R_SIGINVALID - the message was signed by a SIG(0), but + *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but * the signature failed to verify * - * DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), + *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), * but the signature has not been verified yet */ isc_result_t dns_message_checksig(dns_message_t *msg, dns_view_t *view); -/* +/*%< * If this message was signed, verify the signature. * * Requires: * - * msg is a valid parsed message. - * view is a valid view or NULL + *\li msg is a valid parsed message. + *\li view is a valid view or NULL * * Returns: * - * ISC_R_SUCCESS - the message was unsigned, or the message + *\li #ISC_R_SUCCESS - the message was unsigned, or the message * was signed correctly. * - * DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen - * DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - * DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify + *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen + *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected + *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify */ isc_result_t dns_message_rechecksig(dns_message_t *msg, dns_view_t *view); -/* +/*%< * Reset the signature state and then if the message was signed, * verify the message. * * Requires: * - * msg is a valid parsed message. - * view is a valid view or NULL + *\li msg is a valid parsed message. + *\li view is a valid view or NULL * * Returns: * - * ISC_R_SUCCESS - the message was unsigned, or the message + *\li #ISC_R_SUCCESS - the message was unsigned, or the message * was signed correctly. * - * DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen - * DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - * DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify + *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen + *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected + *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify */ void dns_message_resetsig(dns_message_t *msg); -/* +/*%< * Reset the signature state. * * Requires: - * 'msg' is a valid parsed message. + *\li 'msg' is a valid parsed message. */ isc_region_t * dns_message_getrawmessage(dns_message_t *msg); -/* +/*%< * Retrieve the raw message in compressed wire format. The message must * have been successfully parsed for it to have been saved. * * Requires: - * msg is a valid parsed message. + *\li msg is a valid parsed message. * * Returns: - * NULL if there is no saved message. + *\li NULL if there is no saved message. * a pointer to a region which refers the dns message. */ void dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, const void *order_arg); -/* +/*%< * Define the order in which RR sets get rendered by * dns_message_rendersection() to be the ascending order * defined by the integer value returned by 'order' when @@ -1290,27 +1311,27 @@ dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, * 'order_arg' are NULL, a default order is used. * * Requires: - * msg be a valid message. - * order_arg is NULL if and only if order is NULL. + *\li msg be a valid message. + *\li order_arg is NULL if and only if order is NULL. */ void dns_message_settimeadjust(dns_message_t *msg, int timeadjust); -/* +/*%< * Adjust the time used to sign/verify a message by timeadjust. * Currently only TSIG. * * Requires: - * msg be a valid message. + *\li msg be a valid message. */ int dns_message_gettimeadjust(dns_message_t *msg); -/* +/*%< * Return the current time adjustment. * * Requires: - * msg be a valid message. + *\li msg be a valid message. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h index ce9e1f1..038ae05 100644 --- a/contrib/bind9/lib/dns/include/dns/name.h +++ b/contrib/bind9/lib/dns/include/dns/name.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.h,v 1.95.2.3.2.14 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: name.h,v 1.107.18.15 2006/03/02 00:37:21 marka Exp $ */ #ifndef DNS_NAME_H #define DNS_NAME_H 1 @@ -24,9 +24,8 @@ ***** Module Info *****/ -/* - * DNS Names and Labels - * +/*! \file + * \brief * Provides facilities for manipulating DNS names and labels, including * conversions to and from wire format and text format. * @@ -45,26 +44,26 @@ * handles. * * MP: - * Clients of this module must impose any required synchronization. + *\li Clients of this module must impose any required synchronization. * * Reliability: - * This module deals with low-level byte streams. Errors in any of + *\li This module deals with low-level byte streams. Errors in any of * the functions are likely to crash the server or corrupt memory. * * Resources: - * None. + *\li None. * * Security: * - * *** WARNING *** + *\li *** WARNING *** * - * dns_name_fromwire() deals with raw network data. An error in + *\li dns_name_fromwire() deals with raw network data. An error in * this routine could result in the failure or hijacking of the server. * * Standards: - * RFC 1035 - * Draft EDNS0 (0) - * Draft Binary Labels (2) + *\li RFC1035 + *\li Draft EDNS0 (0) + *\li Draft Binary Labels (2) * */ @@ -109,7 +108,7 @@ ISC_LANG_BEGINDECLS *** Types ***/ -/* +/*% * Clients are strongly discouraged from using this type directly, with * the exception of the 'link' and 'list' fields which may be used directly * for whatever purpose the client desires. @@ -135,89 +134,100 @@ struct dns_name { /* * Attributes below 0x0100 reserved for name.c usage. */ -#define DNS_NAMEATTR_CACHE 0x0100 /* Used by resolver. */ -#define DNS_NAMEATTR_ANSWER 0x0200 /* Used by resolver. */ -#define DNS_NAMEATTR_NCACHE 0x0400 /* Used by resolver. */ -#define DNS_NAMEATTR_CHAINING 0x0800 /* Used by resolver. */ -#define DNS_NAMEATTR_CHASE 0x1000 /* Used by resolver. */ -#define DNS_NAMEATTR_WILDCARD 0x2000 /* Used by server. */ +#define DNS_NAMEATTR_CACHE 0x0100 /*%< Used by resolver. */ +#define DNS_NAMEATTR_ANSWER 0x0200 /*%< Used by resolver. */ +#define DNS_NAMEATTR_NCACHE 0x0400 /*%< Used by resolver. */ +#define DNS_NAMEATTR_CHAINING 0x0800 /*%< Used by resolver. */ +#define DNS_NAMEATTR_CHASE 0x1000 /*%< Used by resolver. */ +#define DNS_NAMEATTR_WILDCARD 0x2000 /*%< Used by server. */ #define DNS_NAME_DOWNCASE 0x0001 -#define DNS_NAME_CHECKNAMES 0x0002 /* Used by rdata. */ -#define DNS_NAME_CHECKNAMESFAIL 0x0004 /* Used by rdata. */ -#define DNS_NAME_CHECKREVERSE 0x0008 /* Used by rdata. */ +#define DNS_NAME_CHECKNAMES 0x0002 /*%< Used by rdata. */ +#define DNS_NAME_CHECKNAMESFAIL 0x0004 /*%< Used by rdata. */ +#define DNS_NAME_CHECKREVERSE 0x0008 /*%< Used by rdata. */ +#define DNS_NAME_CHECKMX 0x0010 /*%< Used by rdata. */ +#define DNS_NAME_CHECKMXFAIL 0x0020 /*%< Used by rdata. */ LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_rootname; LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname; -/* +/*% * Standard size of a wire format name */ #define DNS_NAME_MAXWIRE 255 +/* + * Text output filter procedure. + * 'target' is the buffer to be converted. The region to be converted + * is from 'buffer'->base + 'used_org' to the end of the used region. + */ +typedef isc_result_t (*dns_name_totextfilter_t)(isc_buffer_t *target, + unsigned int used_org, + isc_boolean_t absolute); + /*** *** Initialization ***/ void dns_name_init(dns_name_t *name, unsigned char *offsets); -/* +/*%< * Initialize 'name'. * * Notes: - * 'offsets' is never required to be non-NULL, but specifying a + * \li 'offsets' is never required to be non-NULL, but specifying a * dns_offsets_t for 'offsets' will improve the performance of most * name operations if the name is used more than once. * * Requires: - * 'name' is not NULL and points to a struct dns_name. + * \li 'name' is not NULL and points to a struct dns_name. * - * offsets == NULL or offsets is a dns_offsets_t. + * \li offsets == NULL or offsets is a dns_offsets_t. * * Ensures: - * 'name' is a valid name. - * dns_name_countlabels(name) == 0 - * dns_name_isabsolute(name) == ISC_FALSE + * \li 'name' is a valid name. + * \li dns_name_countlabels(name) == 0 + * \li dns_name_isabsolute(name) == ISC_FALSE */ void dns_name_reset(dns_name_t *name); -/* +/*%< * Reinitialize 'name'. * * Notes: - * This function distinguishes itself from dns_name_init() in two + * \li This function distinguishes itself from dns_name_init() in two * key ways: * - * + If any buffer is associated with 'name' (via dns_name_setbuffer() + * \li + If any buffer is associated with 'name' (via dns_name_setbuffer() * or by being part of a dns_fixedname_t) the link to the buffer * is retained but the buffer itself is cleared. * - * + Of the attributes associated with 'name', all are retained except + * \li + Of the attributes associated with 'name', all are retained except * DNS_NAMEATTR_ABSOLUTE. * * Requires: - * 'name' is a valid name. + * \li 'name' is a valid name. * * Ensures: - * 'name' is a valid name. - * dns_name_countlabels(name) == 0 - * dns_name_isabsolute(name) == ISC_FALSE + * \li 'name' is a valid name. + * \li dns_name_countlabels(name) == 0 + * \li dns_name_isabsolute(name) == ISC_FALSE */ void dns_name_invalidate(dns_name_t *name); -/* +/*%< * Make 'name' invalid. * * Requires: - * 'name' is a valid name. + * \li 'name' is a valid name. * * Ensures: - * If assertion checking is enabled, future attempts to use 'name' + * \li If assertion checking is enabled, future attempts to use 'name' * without initializing it will cause an assertion failure. * - * If the name had a dedicated buffer, that association is ended. + * \li If the name had a dedicated buffer, that association is ended. */ @@ -227,93 +237,92 @@ dns_name_invalidate(dns_name_t *name); void dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer); -/* +/*%< * Dedicate a buffer for use with 'name'. * * Notes: - * Specification of a target buffer in dns_name_fromwire(), + * \li Specification of a target buffer in dns_name_fromwire(), * dns_name_fromtext(), and dns_name_concatentate() is optional if * 'name' has a dedicated buffer. * - * The caller must not write to buffer until the name has been + * \li The caller must not write to buffer until the name has been * invalidated or is otherwise known not to be in use. * - * If buffer is NULL and the name previously had a dedicated buffer, + * \li If buffer is NULL and the name previously had a dedicated buffer, * than that buffer is no longer dedicated to use with this name. * The caller is responsible for ensuring that the storage used by * the name remains valid. * * Requires: - * 'name' is a valid name. + * \li 'name' is a valid name. * - * 'buffer' is a valid binary buffer and 'name' doesn't have a + * \li 'buffer' is a valid binary buffer and 'name' doesn't have a * dedicated buffer already, or 'buffer' is NULL. */ isc_boolean_t dns_name_hasbuffer(const dns_name_t *name); -/* +/*%< * Does 'name' have a dedicated buffer? * * Requires: - * 'name' is a valid name. + * \li 'name' is a valid name. * * Returns: - * ISC_TRUE 'name' has a dedicated buffer. - * ISC_FALSE 'name' does not have a dedicated buffer. + * \li ISC_TRUE 'name' has a dedicated buffer. + * \li ISC_FALSE 'name' does not have a dedicated buffer. */ - /*** *** Properties ***/ isc_boolean_t dns_name_isabsolute(const dns_name_t *name); -/* +/*%< * Does 'name' end in the root label? * * Requires: - * 'name' is a valid name + * \li 'name' is a valid name * * Returns: - * TRUE The last label in 'name' is the root label. - * FALSE The last label in 'name' is not the root label. + * \li TRUE The last label in 'name' is the root label. + * \li FALSE The last label in 'name' is not the root label. */ isc_boolean_t dns_name_iswildcard(const dns_name_t *name); -/* +/*%< * Is 'name' a wildcard name? * * Requires: - * 'name' is a valid name + * \li 'name' is a valid name * - * dns_name_countlabels(name) > 0 + * \li dns_name_countlabels(name) > 0 * * Returns: - * TRUE The least significant label of 'name' is '*'. - * FALSE The least significant label of 'name' is not '*'. + * \li TRUE The least significant label of 'name' is '*'. + * \li FALSE The least significant label of 'name' is not '*'. */ unsigned int dns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive); -/* +/*%< * Provide a hash value for 'name'. * * Note: if 'case_sensitive' is ISC_FALSE, then names which differ only in * case will have the same hash value. * * Requires: - * 'name' is a valid name + * \li 'name' is a valid name * * Returns: - * A hash value + * \li A hash value */ unsigned int dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive); -/* +/*%< * Provide a hash value for 'name'. Unlike dns_name_hash(), this function * always takes into account of the entire name to calculate the hash value. * @@ -321,15 +330,15 @@ dns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive); * case will have the same hash value. * * Requires: - * 'name' is a valid name + *\li 'name' is a valid name * * Returns: - * A hash value + *\li A hash value */ unsigned int dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive); -/* +/*%< * Provide a hash value for 'name', where the hash value is the sum * of the hash values of each label. * @@ -337,20 +346,20 @@ dns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive); * case will have the same hash value. * * Requires: - * 'name' is a valid name + *\li 'name' is a valid name * * Returns: - * A hash value + *\li A hash value */ -/*** +/* *** Comparisons ***/ dns_namereln_t dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, int *orderp, unsigned int *nlabelsp); -/* +/*%< * Determine the relative ordering under the DNSSEC order relation of * 'name1' and 'name2', and also determine the hierarchical * relationship of the names. @@ -361,39 +370,39 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2, * same domain. * * Requires: - * 'name1' is a valid name + *\li 'name1' is a valid name * - * dns_name_countlabels(name1) > 0 + *\li dns_name_countlabels(name1) > 0 * - * 'name2' is a valid name + *\li 'name2' is a valid name * - * dns_name_countlabels(name2) > 0 + *\li dns_name_countlabels(name2) > 0 * - * orderp and nlabelsp are valid pointers. + *\li orderp and nlabelsp are valid pointers. * - * Either name1 is absolute and name2 is absolute, or neither is. + *\li Either name1 is absolute and name2 is absolute, or neither is. * * Ensures: * - * *orderp is < 0 if name1 < name2, 0 if name1 = name2, > 0 if + *\li *orderp is < 0 if name1 < name2, 0 if name1 = name2, > 0 if * name1 > name2. * - * *nlabelsp is the number of common significant labels. + *\li *nlabelsp is the number of common significant labels. * * Returns: - * dns_namereln_none There's no hierarchical relationship + *\li dns_namereln_none There's no hierarchical relationship * between name1 and name2. - * dns_namereln_contains name1 properly contains name2; i.e. + *\li dns_namereln_contains name1 properly contains name2; i.e. * name2 is a proper subdomain of name1. - * dns_namereln_subdomain name1 is a proper subdomain of name2. - * dns_namereln_equal name1 and name2 are equal. - * dns_namereln_commonancestor name1 and name2 share a common + *\li dns_namereln_subdomain name1 is a proper subdomain of name2. + *\li dns_namereln_equal name1 and name2 are equal. + *\li dns_namereln_commonancestor name1 and name2 share a common * ancestor. */ int dns_name_compare(const dns_name_t *name1, const dns_name_t *name2); -/* +/*%< * Determine the relative ordering under the DNSSEC order relation of * 'name1' and 'name2'. * @@ -403,124 +412,130 @@ dns_name_compare(const dns_name_t *name1, const dns_name_t *name2); * same domain. * * Requires: - * 'name1' is a valid name + * \li 'name1' is a valid name * - * 'name2' is a valid name + * \li 'name2' is a valid name * - * Either name1 is absolute and name2 is absolute, or neither is. + * \li Either name1 is absolute and name2 is absolute, or neither is. * * Returns: - * < 0 'name1' is less than 'name2' - * 0 'name1' is equal to 'name2' - * > 0 'name1' is greater than 'name2' + * \li < 0 'name1' is less than 'name2' + * \li 0 'name1' is equal to 'name2' + * \li > 0 'name1' is greater than 'name2' */ isc_boolean_t dns_name_equal(const dns_name_t *name1, const dns_name_t *name2); -/* +/*%< * Are 'name1' and 'name2' equal? * * Notes: - * Because it only needs to test for equality, dns_name_equal() can be + * \li Because it only needs to test for equality, dns_name_equal() can be * significantly faster than dns_name_fullcompare() or dns_name_compare(). * - * Offsets tables are not used in the comparision. + * \li Offsets tables are not used in the comparision. * - * It makes no sense for one of the names to be relative and the + * \li It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: - * 'name1' is a valid name + * \li 'name1' is a valid name * - * 'name2' is a valid name + * \li 'name2' is a valid name * - * Either name1 is absolute and name2 is absolute, or neither is. + * \li Either name1 is absolute and name2 is absolute, or neither is. * * Returns: - * ISC_TRUE 'name1' and 'name2' are equal - * ISC_FALSE 'name1' and 'name2' are not equal + * \li ISC_TRUE 'name1' and 'name2' are equal + * \li ISC_FALSE 'name1' and 'name2' are not equal + */ + +isc_boolean_t +dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2); +/*%< + * Case sensitive version of dns_name_equal(). */ int dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2); -/* +/*%< * Compare two names as if they are part of rdata in DNSSEC canonical * form. * * Requires: - * 'name1' is a valid absolute name + * \li 'name1' is a valid absolute name * - * dns_name_countlabels(name1) > 0 + * \li dns_name_countlabels(name1) > 0 * - * 'name2' is a valid absolute name + * \li 'name2' is a valid absolute name * - * dns_name_countlabels(name2) > 0 + * \li dns_name_countlabels(name2) > 0 * * Returns: - * < 0 'name1' is less than 'name2' - * 0 'name1' is equal to 'name2' - * > 0 'name1' is greater than 'name2' + * \li < 0 'name1' is less than 'name2' + * \li 0 'name1' is equal to 'name2' + * \li > 0 'name1' is greater than 'name2' */ isc_boolean_t dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2); -/* +/*%< * Is 'name1' a subdomain of 'name2'? * * Notes: - * name1 is a subdomain of name2 if name1 is contained in name2, or + * \li name1 is a subdomain of name2 if name1 is contained in name2, or * name1 equals name2. * - * It makes no sense for one of the names to be relative and the + * \li It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: - * 'name1' is a valid name + * \li 'name1' is a valid name * - * 'name2' is a valid name + * \li 'name2' is a valid name * - * Either name1 is absolute and name2 is absolute, or neither is. + * \li Either name1 is absolute and name2 is absolute, or neither is. * * Returns: - * TRUE 'name1' is a subdomain of 'name2' - * FALSE 'name1' is not a subdomain of 'name2' + * \li TRUE 'name1' is a subdomain of 'name2' + * \li FALSE 'name1' is not a subdomain of 'name2' */ isc_boolean_t dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname); -/* +/*%< * Does 'name' match the wildcard specified in 'wname'? * * Notes: - * name matches the wildcard specified in wname if all labels + * \li name matches the wildcard specified in wname if all labels * following the wildcard in wname are identical to the same number * of labels at the end of name. * - * It makes no sense for one of the names to be relative and the + * \li It makes no sense for one of the names to be relative and the * other absolute. If both names are relative, then to be meaningfully * compared the caller must ensure that they are both relative to the * same domain. * * Requires: - * 'name' is a valid name + * \li 'name' is a valid name * - * dns_name_countlabels(name) > 0 + * \li dns_name_countlabels(name) > 0 * - * 'wname' is a valid name + * \li 'wname' is a valid name * - * dns_name_countlabels(wname) > 0 + * \li dns_name_countlabels(wname) > 0 * - * dns_name_iswildcard(wname) is true + * \li dns_name_iswildcard(wname) is true * - * Either name is absolute and wname is absolute, or neither is. + * \li Either name is absolute and wname is absolute, or neither is. * * Returns: - * TRUE 'name' matches the wildcard specified in 'wname' - * FALSE 'name' does not match the wildcard specified in 'wname' + * \li TRUE 'name' matches the wildcard specified in 'wname' + * \li FALSE 'name' does not match the wildcard specified in 'wname' */ /*** @@ -529,89 +544,91 @@ dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname); unsigned int dns_name_countlabels(const dns_name_t *name); -/* +/*%< * How many labels does 'name' have? * * Notes: - * In this case, as in other places, a 'label' is an ordinary label. + * \li In this case, as in other places, a 'label' is an ordinary label. * * Requires: - * 'name' is a valid name + * \li 'name' is a valid name * * Ensures: - * The result is <= 128. + * \li The result is <= 128. * * Returns: - * The number of labels in 'name'. + * \li The number of labels in 'name'. */ void dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label); -/* +/*%< * Make 'label' refer to the 'n'th least significant label of 'name'. * * Notes: - * Numbering starts at 0. + * \li Numbering starts at 0. * - * Given "rc.vix.com.", the label 0 is "rc", and label 3 is the + * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the * root label. * - * 'label' refers to the same memory as 'name', so 'name' must not + * \li 'label' refers to the same memory as 'name', so 'name' must not * be changed while 'label' is still in use. * * Requires: - * n < dns_name_countlabels(name) + * \li n < dns_name_countlabels(name) */ void dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, unsigned int n, dns_name_t *target); -/* +/*%< * Make 'target' refer to the 'n' labels including and following 'first' * in 'source'. * * Notes: - * Numbering starts at 0. + * \li Numbering starts at 0. * - * Given "rc.vix.com.", the label 0 is "rc", and label 3 is the + * \li Given "rc.vix.com.", the label 0 is "rc", and label 3 is the * root label. * - * 'target' refers to the same memory as 'source', so 'source' + * \li 'target' refers to the same memory as 'source', so 'source' * must not be changed while 'target' is still in use. * * Requires: - * 'source' and 'target' are valid names. + * \li 'source' and 'target' are valid names. * - * first < dns_name_countlabels(name) + * \li first < dns_name_countlabels(name) * - * first + n <= dns_name_countlabels(name) + * \li first + n <= dns_name_countlabels(name) */ void dns_name_clone(const dns_name_t *source, dns_name_t *target); -/* +/*%< * Make 'target' refer to the same name as 'source'. * * Notes: * - * 'target' refers to the same memory as 'source', so 'source' + * \li 'target' refers to the same memory as 'source', so 'source' * must not be changed while 'target' is still in use. * - * This call is functionally equivalent to: + * \li This call is functionally equivalent to: * + * \code * dns_name_getlabelsequence(source, 0, * dns_name_countlabels(source), * target); + * \endcode * * but is more efficient. Also, dns_name_clone() works even if 'source' * is empty. * * Requires: * - * 'source' is a valid name. + * \li 'source' is a valid name. * - * 'target' is a valid name that is not read-only. + * \li 'target' is a valid name that is not read-only. */ /*** @@ -620,206 +637,205 @@ dns_name_clone(const dns_name_t *source, dns_name_t *target); void dns_name_fromregion(dns_name_t *name, const isc_region_t *r); -/* +/*%< * Make 'name' refer to region 'r'. * * Note: - * If the conversion encounters a root label before the end of the + * \li If the conversion encounters a root label before the end of the * region the conversion stops and the length is set to the length * so far converted. A maximum of 255 bytes is converted. * * Requires: - * The data in 'r' is a sequence of one or more type 00 or type 01000001 + * \li The data in 'r' is a sequence of one or more type 00 or type 01000001 * labels. */ void dns_name_toregion(dns_name_t *name, isc_region_t *r); -/* +/*%< * Make 'r' refer to 'name'. * * Requires: * - * 'name' is a valid name. + * \li 'name' is a valid name. * - * 'r' is a valid region. + * \li 'r' is a valid region. */ isc_result_t dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target); -/* +/*%< * Copy the possibly-compressed name at source (active region) into target, * decompressing it. * * Notes: - * Decompression policy is controlled by 'dctx'. + * \li Decompression policy is controlled by 'dctx'. * - * If DNS_NAME_DOWNCASE is set, any uppercase letters in 'source' will be + * \li If DNS_NAME_DOWNCASE is set, any uppercase letters in 'source' will be * downcased when they are copied into 'target'. * * Security: * - * *** WARNING *** + * \li *** WARNING *** * - * This routine will often be used when 'source' contains raw network + * \li This routine will often be used when 'source' contains raw network * data. A programming error in this routine could result in a denial * of service, or in the hijacking of the server. * * Requires: * - * 'name' is a valid name. + * \li 'name' is a valid name. * - * 'source' is a valid buffer and the first byte of the active + * \li 'source' is a valid buffer and the first byte of the active * region should be the first byte of a DNS wire format domain name. * - * 'target' is a valid buffer or 'target' is NULL and 'name' has + * \li 'target' is a valid buffer or 'target' is NULL and 'name' has * a dedicated buffer. * - * 'dctx' is a valid decompression context. + * \li 'dctx' is a valid decompression context. * * Ensures: * * If result is success: - * If 'target' is not NULL, 'name' is attached to it. + * \li If 'target' is not NULL, 'name' is attached to it. * - * Uppercase letters are downcased in the copy iff + * \li Uppercase letters are downcased in the copy iff * DNS_NAME_DOWNCASE is set in options. * - * The current location in source is advanced, and the used space + * \li The current location in source is advanced, and the used space * in target is updated. * * Result: - * Success - * Bad Form: Label Length - * Bad Form: Unknown Label Type - * Bad Form: Name Length - * Bad Form: Compression type not allowed - * Bad Form: Bad compression pointer - * Bad Form: Input too short - * Resource Limit: Too many compression pointers - * Resource Limit: Not enough space in buffer + * \li Success + * \li Bad Form: Label Length + * \li Bad Form: Unknown Label Type + * \li Bad Form: Name Length + * \li Bad Form: Compression type not allowed + * \li Bad Form: Bad compression pointer + * \li Bad Form: Input too short + * \li Resource Limit: Too many compression pointers + * \li Resource Limit: Not enough space in buffer */ isc_result_t dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, - isc_buffer_t *target); -/* + isc_buffer_t *target); +/*%< * Convert 'name' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. * * Notes: - * If the compression context allows global compression, then the + * \li If the compression context allows global compression, then the * global compression table may be updated. * * Requires: - * 'name' is a valid name + * \li 'name' is a valid name * - * dns_name_countlabels(name) > 0 + * \li dns_name_countlabels(name) > 0 * - * dns_name_isabsolute(name) == TRUE + * \li dns_name_isabsolute(name) == TRUE * - * target is a valid buffer. + * \li target is a valid buffer. * - * Any offsets specified in a global compression table are valid + * \li Any offsets specified in a global compression table are valid * for buffer. * * Ensures: * * If the result is success: * - * The used space in target is updated. + * \li The used space in target is updated. * * Returns: - * Success - * Resource Limit: Not enough space in buffer + * \li Success + * \li Resource Limit: Not enough space in buffer */ isc_result_t dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, dns_name_t *origin, unsigned int options, isc_buffer_t *target); -/* +/*%< * Convert the textual representation of a DNS name at source * into uncompressed wire form stored in target. * * Notes: - * Relative domain names will have 'origin' appended to them + * \li Relative domain names will have 'origin' appended to them * unless 'origin' is NULL, in which case relative domain names * will remain relative. * - * If DNS_NAME_DOWNCASE is set in 'options', any uppercase letters + * \li If DNS_NAME_DOWNCASE is set in 'options', any uppercase letters * in 'source' will be downcased when they are copied into 'target'. * * Requires: * - * 'name' is a valid name. + * \li 'name' is a valid name. * - * 'source' is a valid buffer. + * \li 'source' is a valid buffer. * - * 'target' is a valid buffer or 'target' is NULL and 'name' has + * \li 'target' is a valid buffer or 'target' is NULL and 'name' has * a dedicated buffer. * * Ensures: * * If result is success: - * If 'target' is not NULL, 'name' is attached to it. + * \li If 'target' is not NULL, 'name' is attached to it. * - * Uppercase letters are downcased in the copy iff + * \li Uppercase letters are downcased in the copy iff * DNS_NAME_DOWNCASE is set in 'options'. * - * The current location in source is advanced, and the used space + * \li The current location in source is advanced, and the used space * in target is updated. * * Result: - * ISC_R_SUCCESS - * DNS_R_EMPTYLABEL - * DNS_R_LABELTOOLONG - * DNS_R_BADESCAPE - * (DNS_R_BADBITSTRING: should not be returned) - * (DNS_R_BITSTRINGTOOLONG: should not be returned) - * DNS_R_BADDOTTEDQUAD - * ISC_R_NOSPACE - * ISC_R_UNEXPECTEDEND + *\li #ISC_R_SUCCESS + *\li #DNS_R_EMPTYLABEL + *\li #DNS_R_LABELTOOLONG + *\li #DNS_R_BADESCAPE + *\li (#DNS_R_BADBITSTRING: should not be returned) + *\li (#DNS_R_BITSTRINGTOOLONG: should not be returned) + *\li #DNS_R_BADDOTTEDQUAD + *\li #ISC_R_NOSPACE + *\li #ISC_R_UNEXPECTEDEND */ isc_result_t dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target); -/* +/*%< * Convert 'name' into text format, storing the result in 'target'. * * Notes: - * If 'omit_final_dot' is true, then the final '.' in absolute + *\li If 'omit_final_dot' is true, then the final '.' in absolute * names other than the root name will be omitted. * - * If dns_name_countlabels == 0, the name will be "@", representing the - * current origin as described by RFC 1035. + *\li If dns_name_countlabels == 0, the name will be "@", representing the + * current origin as described by RFC1035. * - * The name is not NUL terminated. + *\li The name is not NUL terminated. * * Requires: * - * 'name' is a valid name + *\li 'name' is a valid name * - * 'target' is a valid buffer. + *\li 'target' is a valid buffer. * - * if dns_name_isabsolute == FALSE, then omit_final_dot == FALSE + *\li if dns_name_isabsolute == FALSE, then omit_final_dot == FALSE * * Ensures: * - * If the result is success: - * - * The used space in target is updated. + *\li If the result is success: + * the used space in target is updated. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE */ #define DNS_NAME_MAXTEXT 1023 -/* +/*%< * The maximum length of the text representation of a domain * name as generated by dns_name_totext(). This does not * include space for a terminating NULL. @@ -844,56 +860,53 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_result_t dns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target); -/* +/*%< * Convert 'name' into an alternate text format appropriate for filenames, * storing the result in 'target'. The name data is downcased, guaranteeing * that the filename does not depend on the case of the converted name. * * Notes: - * If 'omit_final_dot' is true, then the final '.' in absolute + *\li If 'omit_final_dot' is true, then the final '.' in absolute * names other than the root name will be omitted. * - * The name is not NUL terminated. + *\li The name is not NUL terminated. * * Requires: * - * 'name' is a valid absolute name + *\li 'name' is a valid absolute name * - * 'target' is a valid buffer. + *\li 'target' is a valid buffer. * * Ensures: * - * If the result is success: - * - * The used space in target is updated. + *\li If the result is success: + * the used space in target is updated. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE */ isc_result_t dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target); -/* +/*%< * Downcase 'source'. * * Requires: * - * 'source' and 'name' are valid names. - * - * If source == name, then + *\li 'source' and 'name' are valid names. * + *\li If source == name, then * 'source' must not be read-only * - * Otherwise, - * + *\li Otherwise, * 'target' is a valid buffer or 'target' is NULL and * 'name' has a dedicated buffer. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE * * Note: if source == name, then the result will always be ISC_R_SUCCESS. */ @@ -901,199 +914,198 @@ dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_result_t dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target); -/* +/*%< * Concatenate 'prefix' and 'suffix'. * * Requires: * - * 'prefix' is a valid name or NULL. + *\li 'prefix' is a valid name or NULL. * - * 'suffix' is a valid name or NULL. + *\li 'suffix' is a valid name or NULL. * - * 'name' is a valid name or NULL. + *\li 'name' is a valid name or NULL. * - * 'target' is a valid buffer or 'target' is NULL and 'name' has + *\li 'target' is a valid buffer or 'target' is NULL and 'name' has * a dedicated buffer. * - * If 'prefix' is absolute, 'suffix' must be NULL or the empty name. + *\li If 'prefix' is absolute, 'suffix' must be NULL or the empty name. * * Ensures: * - * On success, + *\li On success, * If 'target' is not NULL and 'name' is not NULL, then 'name' * is attached to it. - * * The used space in target is updated. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE - * DNS_R_NAMETOOLONG + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE + *\li #DNS_R_NAMETOOLONG */ void dns_name_split(dns_name_t *name, unsigned int suffixlabels, dns_name_t *prefix, dns_name_t *suffix); -/* +/*%< * * Split 'name' into two pieces on a label boundary. * * Notes: - * 'name' is split such that 'suffix' holds the most significant + * \li 'name' is split such that 'suffix' holds the most significant * 'suffixlabels' labels. All other labels are stored in 'prefix'. * - * Copying name data is avoided as much as possible, so 'prefix' + *\li Copying name data is avoided as much as possible, so 'prefix' * and 'suffix' will end up pointing at the data for 'name'. * - * It is legitimate to pass a 'prefix' or 'suffix' that has + *\li It is legitimate to pass a 'prefix' or 'suffix' that has * its name data stored someplace other than the dedicated buffer. * This is useful to avoid name copying in the calling function. * - * It is also legitimate to pass a 'prefix' or 'suffix' that is + *\li It is also legitimate to pass a 'prefix' or 'suffix' that is * the same dns_name_t as 'name'. * * Requires: - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'suffixlabels' cannot exceed the number of labels in 'name'. + *\li 'suffixlabels' cannot exceed the number of labels in 'name'. * - * 'prefix' is a valid name or NULL, and cannot be read-only. + * \li 'prefix' is a valid name or NULL, and cannot be read-only. * - * 'suffix' is a valid name or NULL, and cannot be read-only. + *\li 'suffix' is a valid name or NULL, and cannot be read-only. * - * If non-NULL, 'prefix' and 'suffix' must have dedicated buffers. + *\li If non-NULL, 'prefix' and 'suffix' must have dedicated buffers. * - * 'prefix' and 'suffix' cannot point to the same buffer. + *\li 'prefix' and 'suffix' cannot point to the same buffer. * * Ensures: * - * On success: + *\li On success: * If 'prefix' is not NULL it will contain the least significant * labels. - * * If 'suffix' is not NULL it will contain the most significant * labels. dns_name_countlabels(suffix) will be equal to * suffixlabels. * - * On failure: + *\li On failure: * Either 'prefix' or 'suffix' is invalidated (depending * on which one the problem was encountered with). * * Returns: - * ISC_R_SUCCESS No worries. (This function should always success). + *\li #ISC_R_SUCCESS No worries. (This function should always success). */ isc_result_t -dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target); -/* +dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, + dns_name_t *target); +/*%< * Make 'target' a dynamically allocated copy of 'source'. * * Requires: * - * 'source' is a valid non-empty name. + *\li 'source' is a valid non-empty name. * - * 'target' is a valid name that is not read-only. + *\li 'target' is a valid name that is not read-only. * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. */ isc_result_t dns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target); -/* +/*%< * Make 'target' a read-only dynamically allocated copy of 'source'. * 'target' will also have a dynamically allocated offsets table. * * Requires: * - * 'source' is a valid non-empty name. + *\li 'source' is a valid non-empty name. * - * 'target' is a valid name that is not read-only. + *\li 'target' is a valid name that is not read-only. * - * 'target' has no offsets table. + *\li 'target' has no offsets table. * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. */ void dns_name_free(dns_name_t *name, isc_mem_t *mctx); -/* +/*%< * Free 'name'. * * Requires: * - * 'name' is a valid name created previously in 'mctx' by dns_name_dup(). + *\li 'name' is a valid name created previously in 'mctx' by dns_name_dup(). * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. * * Ensures: * - * All dynamic resources used by 'name' are freed and the name is + *\li All dynamic resources used by 'name' are freed and the name is * invalidated. */ isc_result_t dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg); -/* +/*%< * Send 'name' in DNSSEC canonical form to 'digest'. * * Requires: * - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'digest' is a valid dns_digestfunc_t. + *\li 'digest' is a valid dns_digestfunc_t. * * Ensures: * - * If successful, the DNSSEC canonical form of 'name' will have been + *\li If successful, the DNSSEC canonical form of 'name' will have been * sent to 'digest'. * - * If digest() returns something other than ISC_R_SUCCESS, that result + *\li If digest() returns something other than ISC_R_SUCCESS, that result * will be returned as the result of dns_name_digest(). * * Returns: * - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS * - * Many other results are possible if not successful. + *\li Many other results are possible if not successful. * */ isc_boolean_t dns_name_dynamic(dns_name_t *name); -/* +/*%< * Returns whether there is dynamic memory associated with this name. * * Requires: * - * 'name' is a valid name. + *\li 'name' is a valid name. * * Returns: * - * 'ISC_TRUE' if the name is dynamic othewise 'ISC_FALSE'. + *\li 'ISC_TRUE' if the name is dynamic othewise 'ISC_FALSE'. */ isc_result_t dns_name_print(dns_name_t *name, FILE *stream); -/* +/*%< * Print 'name' on 'stream'. * * Requires: * - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'stream' is a valid stream. + *\li 'stream' is a valid stream. * * Returns: * - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS * - * Any error that dns_name_totext() can return. + *\li Any error that dns_name_totext() can return. */ void dns_name_format(dns_name_t *name, char *cp, unsigned int size); -/* +/*%< * Format 'name' as text appropriate for use in log messages. * * Store the formatted name at 'cp', writing no more than @@ -1108,47 +1120,63 @@ dns_name_format(dns_name_t *name, char *cp, unsigned int size); * * Requires: * - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'cp' points a valid character array of size 'size'. + *\li 'cp' points a valid character array of size 'size'. * - * 'size' > 0. + *\li 'size' > 0. * */ +isc_result_t +dns_name_settotextfilter(dns_name_totextfilter_t proc); +/*%< + * Set / clear a thread specific function 'proc' to be called at the + * end of dns_name_totext(). + * + * Note: Under Windows you need to call "dns_name_settotextfilter(NULL);" + * prior to exiting the thread otherwise memory will be leaked. + * For other platforms, which are pthreads based, this is still a good + * idea but not required. + * + * Returns + *\li #ISC_R_SUCCESS + *\li #ISC_R_UNEXPECTED + */ + #define DNS_NAME_FORMATSIZE (DNS_NAME_MAXTEXT + 1) -/* +/*%< * Suggested size of buffer passed to dns_name_format(). * Includes space for the terminating NULL. */ isc_result_t dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target); -/* +/*%< * Makes 'dest' refer to a copy of the name in 'source'. The data are * either copied to 'target' or the dedicated buffer in 'dest'. * * Requires: - * 'source' is a valid name. + * \li 'source' is a valid name. * - * 'dest' is an initialized name with a dedicated buffer. + * \li 'dest' is an initialized name with a dedicated buffer. * - * 'target' is NULL or an initialized buffer. + * \li 'target' is NULL or an initialized buffer. * - * Either dest has a dedicated buffer or target != NULL. + * \li Either dest has a dedicated buffer or target != NULL. * * Ensures: * - * On success, the used space in target is updated. + *\li On success, the used space in target is updated. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE */ isc_boolean_t dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard); -/* +/*%< * Return if 'name' is a valid hostname. RFC 952 / RFC 1123. * If 'wildcard' is ISC_TRUE then allow the first label of name to * be a wildcard. @@ -1161,16 +1189,37 @@ dns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard); isc_boolean_t dns_name_ismailbox(const dns_name_t *name); -/* +/*%< * Return if 'name' is a valid mailbox. RFC 821. * * Requires: - * 'name' to be valid. + * \li 'name' to be valid. + */ + +isc_boolean_t +dns_name_internalwildcard(const dns_name_t *name); +/*%< + * Return if 'name' contains a internal wildcard name. + * + * Requires: + * \li 'name' to be valid. + */ + +void +dns_name_destroy(void); +/*%< + * Cleanup dns_name_settotextfilter() / dns_name_totext() state. + * + * This should be called as part of the final cleanup process. + * + * Note: dns_name_settotextfilter(NULL); should be called for all + * threads which have called dns_name_settotextfilter() with a + * non-NULL argument prior to calling dns_name_destroy(); */ ISC_LANG_ENDDECLS -/*** +/* *** High Peformance Macros ***/ diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h index 6bf6003..459effb 100644 --- a/contrib/bind9/lib/dns/include/dns/ncache.h +++ b/contrib/bind9/lib/dns/include/dns/ncache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.h,v 1.12.12.5 2004/03/08 09:04:37 marka Exp $ */ +/* $Id: ncache.h,v 1.17.18.2 2005/04/29 00:16:16 marka Exp $ */ #ifndef DNS_NCACHE_H #define DNS_NCACHE_H 1 @@ -24,25 +24,26 @@ ***** Module Info *****/ -/* +/*! \file + *\brief * DNS Ncache * - * XXX <TBS> XXX + * XXX TBS XXX * * MP: - * The caller must ensure any required synchronization. + *\li The caller must ensure any required synchronization. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * RFC 2308 + *\li RFC2308 */ #include <isc/lang.h> @@ -52,7 +53,7 @@ ISC_LANG_BEGINDECLS -/* +/*% * _OMITDNSSEC: * Omit DNSSEC records when rendering. */ @@ -62,7 +63,7 @@ isc_result_t dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, dns_rdataset_t *addedrdataset); -/* +/*%< * Convert the authority data from 'message' into a negative cache * rdataset, and store it in 'cache' at 'node' with a TTL limited to * 'maxttl'. @@ -71,21 +72,21 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, * or dns_rdatatype_any when caching a NXDOMAIN response. * * Note: - * If 'addedrdataset' is not NULL, then it will be attached to the added + *\li If 'addedrdataset' is not NULL, then it will be attached to the added * rdataset. See dns_db_addrdataset() for more details. * * Requires: - * 'message' is a valid message with a properly formatting negative cache + *\li 'message' is a valid message with a properly formatting negative cache * authority section. * - * The requirements of dns_db_addrdataset() apply to 'cache', 'node', + *\li The requirements of dns_db_addrdataset() apply to 'cache', 'node', * 'now', and 'addedrdataset'. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE * - * Any result code of dns_db_addrdataset() is a possible result code + *\li Any result code of dns_db_addrdataset() is a possible result code * of dns_ncache_add(). */ @@ -93,63 +94,63 @@ isc_result_t dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp); -/* +/*%< * Convert the negative caching rdataset 'rdataset' to wire format, * compressing names as specified in 'cctx', and storing the result in * 'target'. If 'omit_dnssec' is set, DNSSEC records will not * be added to 'target'. * * Notes: - * The number of RRs added to target will be added to *countp. + *\li The number of RRs added to target will be added to *countp. * * Requires: - * 'rdataset' is a valid negative caching rdataset. + *\li 'rdataset' is a valid negative caching rdataset. * - * 'rdataset' is not empty. + *\li 'rdataset' is not empty. * - * 'countp' is a valid pointer. + *\li 'countp' is a valid pointer. * * Ensures: - * On a return of ISC_R_SUCCESS, 'target' contains a wire format + *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format * for the data contained in 'rdataset'. Any error return leaves * the buffer unchanged. * - * *countp has been incremented by the number of RRs added to + *\li *countp has been incremented by the number of RRs added to * target. * * Returns: - * ISC_R_SUCCESS - all ok - * ISC_R_NOSPACE - 'target' doesn't have enough room + *\li #ISC_R_SUCCESS - all ok + *\li #ISC_R_NOSPACE - 'target' doesn't have enough room * - * Any error returned by dns_rdata_towire(), dns_rdataset_next(), + *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(), * dns_name_towire(). */ isc_result_t dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset); -/* +/*%< * Search the negative caching rdataset for an rdataset with the * specified name and type. * * Requires: - * 'ncacherdataset' is a valid negative caching rdataset. + *\li 'ncacherdataset' is a valid negative caching rdataset. * - * 'ncacherdataset' is not empty. + *\li 'ncacherdataset' is not empty. * - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'type' is not SIG, or a meta-RR type. + *\li 'type' is not SIG, or a meta-RR type. * - * 'rdataset' is a valid disassociated rdataset. + *\li 'rdataset' is a valid disassociated rdataset. * * Ensures: - * On a return of ISC_R_SUCCESS, 'rdataset' is bound to the found + *\li On a return of ISC_R_SUCCESS, 'rdataset' is bound to the found * rdataset. * * Returns: - * ISC_R_SUCCESS - the rdataset was found. - * ISC_R_NOTFOUND - the rdataset was not found. + *\li #ISC_R_SUCCESS - the rdataset was found. + *\li #ISC_R_NOTFOUND - the rdataset was not found. * */ diff --git a/contrib/bind9/lib/dns/include/dns/nsec.h b/contrib/bind9/lib/dns/include/dns/nsec.h index 68a5833..46b75fa 100644 --- a/contrib/bind9/lib/dns/include/dns/nsec.h +++ b/contrib/bind9/lib/dns/include/dns/nsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsec.h,v 1.4.2.1 2004/03/08 02:08:00 marka Exp $ */ +/* $Id: nsec.h,v 1.4.20.2 2005/04/29 00:16:16 marka Exp $ */ #ifndef DNS_NSEC_H #define DNS_NSEC_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -33,33 +35,33 @@ isc_result_t dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, unsigned char *buffer, dns_rdata_t *rdata); -/* +/*%< * Build the rdata of a NSEC record. * * Requires: - * buffer Points to a temporary buffer of at least + *\li buffer Points to a temporary buffer of at least * DNS_NSEC_BUFFERSIZE bytes. - * rdata Points to an initialized dns_rdata_t. + *\li rdata Points to an initialized dns_rdata_t. * * Ensures: - * *rdata Contains a valid NSEC rdata. The 'data' member refers + * \li *rdata Contains a valid NSEC rdata. The 'data' member refers * to 'buffer'. */ isc_result_t dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, dns_ttl_t ttl); -/* +/*%< * Build a NSEC record and add it to a database. */ isc_boolean_t dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type); -/* +/*%< * Determine if a type is marked as present in an NSEC record. * * Requires: - * 'nsec' points to a valid rdataset of type NSEC + *\li 'nsec' points to a valid rdataset of type NSEC */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/opcode.h b/contrib/bind9/lib/dns/include/dns/opcode.h index 4d656b8..4796dba 100644 --- a/contrib/bind9/lib/dns/include/dns/opcode.h +++ b/contrib/bind9/lib/dns/include/dns/opcode.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: opcode.h,v 1.1.200.3 2004/03/08 09:04:37 marka Exp $ */ +/* $Id: opcode.h,v 1.2.18.2 2005/04/29 00:16:16 marka Exp $ */ #ifndef DNS_OPCODE_H #define DNS_OPCODE_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -27,21 +29,21 @@ ISC_LANG_BEGINDECLS isc_result_t dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target); -/* +/*%< * Put a textual representation of error 'opcode' into 'target'. * * Requires: - * 'opcode' is a valid opcode. + *\li 'opcode' is a valid opcode. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * * Ensures: - * If the result is success: + *\li If the result is success: * The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/order.h b/contrib/bind9/lib/dns/include/dns/order.h index e28e3ca..6458db0 100644 --- a/contrib/bind9/lib/dns/include/dns/order.h +++ b/contrib/bind9/lib/dns/include/dns/order.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: order.h,v 1.2.202.3 2004/03/08 09:04:37 marka Exp $ */ +/* $Id: order.h,v 1.3.18.2 2005/04/29 00:16:17 marka Exp $ */ #ifndef DNS_ORDER_H #define DNS_ORDER_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/types.h> @@ -29,67 +31,67 @@ ISC_LANG_BEGINDECLS isc_result_t dns_order_create(isc_mem_t *mctx, dns_order_t **orderp); -/* +/*%< * Create a order object. * * Requires: - * 'orderp' to be non NULL and '*orderp == NULL'. - * 'mctx' to be valid. + * \li 'orderp' to be non NULL and '*orderp == NULL'. + *\li 'mctx' to be valid. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li ISC_R_SUCCESS + *\li ISC_R_NOMEMORY */ isc_result_t dns_order_add(dns_order_t *order, dns_name_t *name, dns_rdatatype_t rdtype, dns_rdataclass_t rdclass, unsigned int mode); -/* +/*%< * Add a entry to the end of the order list. * * Requires: - * 'order' to be valid. - * 'name' to be valid. - * 'mode' to be one of DNS_RDATASERATTR_RANDOMIZE, - * DNS_RDATASERATTR_RANDOMIZE or zero (DNS_RDATASERATTR_CYCLIC). + * \li 'order' to be valid. + *\li 'name' to be valid. + *\li 'mode' to be one of #DNS_RDATASERATTR_RANDOMIZE, + * #DNS_RDATASERATTR_RANDOMIZE or zero (#DNS_RDATASERATTR_CYCLIC). * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ unsigned int dns_order_find(dns_order_t *order, dns_name_t *name, dns_rdatatype_t rdtype, dns_rdataclass_t rdclass); -/* +/*%< * Find the first matching entry on the list. * * Requires: - * 'order' to be valid. - * 'name' to be valid. + *\li 'order' to be valid. + *\li 'name' to be valid. * * Returns the mode set by dns_order_add() or zero. */ void dns_order_attach(dns_order_t *source, dns_order_t **target); -/* +/*%< * Attach to the 'source' object. * * Requires: - * 'source' to be valid. - * 'target' to be non NULL and '*target == NULL'. + * \li 'source' to be valid. + *\li 'target' to be non NULL and '*target == NULL'. */ void dns_order_detach(dns_order_t **orderp); -/* +/*%< * Detach from the object. Clean up if last this was the last * reference. * * Requires: - * '*orderp' to be valid. + *\li '*orderp' to be valid. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/peer.h b/contrib/bind9/lib/dns/include/dns/peer.h index 9032964..be5a8c3 100644 --- a/contrib/bind9/lib/dns/include/dns/peer.h +++ b/contrib/bind9/lib/dns/include/dns/peer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.h,v 1.16.2.1.10.5 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: peer.h,v 1.20.18.8 2006/02/28 03:10:48 marka Exp $ */ #ifndef DNS_PEER_H #define DNS_PEER_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * Data structures for peers (e.g. a 'server' config file statement) */ @@ -64,6 +65,7 @@ struct dns_peer { isc_mem_t *mem; isc_netaddr_t address; + unsigned int prefixlen; isc_boolean_t bogus; dns_transfer_format_t transfer_format; isc_uint32_t transfers; @@ -73,6 +75,10 @@ struct dns_peer { isc_boolean_t support_edns; dns_name_t *key; isc_sockaddr_t *transfer_source; + isc_sockaddr_t *notify_source; + isc_sockaddr_t *query_source; + isc_uint16_t udpsize; /* recieve size */ + isc_uint16_t maxudp; /* transmit size */ isc_uint32_t bitflags; @@ -115,6 +121,10 @@ dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval); isc_result_t dns_peer_new(isc_mem_t *mem, isc_netaddr_t *ipaddr, dns_peer_t **peer); +isc_result_t +dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *ipaddr, + unsigned int prefixlen, dns_peer_t **peer); + void dns_peer_attach(dns_peer_t *source, dns_peer_t **target); @@ -173,6 +183,30 @@ dns_peer_settransfersource(dns_peer_t *peer, isc_result_t dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); +isc_result_t +dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize); + +isc_result_t +dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize); + +isc_result_t +dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp); + +isc_result_t +dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp); + +isc_result_t +dns_peer_setnotifysource(dns_peer_t *peer, const isc_sockaddr_t *notify_source); + +isc_result_t +dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source); + +isc_result_t +dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source); + +isc_result_t +dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source); + ISC_LANG_ENDDECLS #endif /* DNS_PEER_H */ diff --git a/contrib/bind9/lib/dns/include/dns/portlist.h b/contrib/bind9/lib/dns/include/dns/portlist.h index ea672a9..2d400d4 100644 --- a/contrib/bind9/lib/dns/include/dns/portlist.h +++ b/contrib/bind9/lib/dns/include/dns/portlist.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: portlist.h,v 1.2.84.2 2004/03/06 08:13:58 marka Exp $ */ +/* $Id: portlist.h,v 1.3.18.2 2005/04/29 00:16:17 marka Exp $ */ + +/*! \file */ #include <isc/lang.h> #include <isc/net.h> @@ -27,73 +29,73 @@ ISC_LANG_BEGINDECLS isc_result_t dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp); -/* +/*%< * Create a port list. * * Requires: - * 'mctx' to be valid. - * 'portlistp' to be non NULL and '*portlistp' to be NULL; + *\li 'mctx' to be valid. + *\li 'portlistp' to be non NULL and '*portlistp' to be NULL; * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_UNEXPECTED + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_UNEXPECTED */ isc_result_t dns_portlist_add(dns_portlist_t *portlist, int af, in_port_t port); -/* +/*%< * Add the given <port,af> tuple to the portlist. * * Requires: - * 'portlist' to be valid. - * 'af' to be AF_INET or AF_INET6 + *\li 'portlist' to be valid. + *\li 'af' to be AF_INET or AF_INET6 * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ void dns_portlist_remove(dns_portlist_t *portlist, int af, in_port_t port); -/* +/*%< * Remove the given <port,af> tuple to the portlist. * * Requires: - * 'portlist' to be valid. - * 'af' to be AF_INET or AF_INET6 + *\li 'portlist' to be valid. + *\li 'af' to be AF_INET or AF_INET6 */ isc_boolean_t dns_portlist_match(dns_portlist_t *portlist, int af, in_port_t port); -/* +/*%< * Find the given <port,af> tuple to the portlist. * * Requires: - * 'portlist' to be valid. - * 'af' to be AF_INET or AF_INET6 + *\li 'portlist' to be valid. + *\li 'af' to be AF_INET or AF_INET6 * * Returns - * ISC_TRUE if the tuple is found, ISC_FALSE otherwise. + * \li #ISC_TRUE if the tuple is found, ISC_FALSE otherwise. */ void dns_portlist_attach(dns_portlist_t *portlist, dns_portlist_t **portlistp); -/* +/*%< * Attach to a port list. * * Requires: - * 'portlist' to be valid. - * 'portlistp' to be non NULL and '*portlistp' to be NULL; + *\li 'portlist' to be valid. + *\li 'portlistp' to be non NULL and '*portlistp' to be NULL; */ void dns_portlist_detach(dns_portlist_t **portlistp); -/* +/*%< * Detach from a port list. * * Requires: - * '*portlistp' to be valid. + *\li '*portlistp' to be valid. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rbt.h b/contrib/bind9/lib/dns/include/dns/rbt.h index 6f99a7d..a1edf0c 100644 --- a/contrib/bind9/lib/dns/include/dns/rbt.h +++ b/contrib/bind9/lib/dns/include/dns/rbt.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,13 +15,16 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbt.h,v 1.55.12.6 2004/10/11 05:55:51 marka Exp $ */ +/* $Id: rbt.h,v 1.59.18.5 2005/10/13 01:26:07 marka Exp $ */ #ifndef DNS_RBT_H #define DNS_RBT_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/magic.h> +#include <isc/refcount.h> #include <dns/types.h> @@ -29,7 +32,8 @@ ISC_LANG_BEGINDECLS #define DNS_RBT_USEHASH 1 -/* +/*@{*/ +/*% * Option values for dns_rbt_findnode() and dns_rbt_findname(). * These are used to form a bitmask. */ @@ -37,6 +41,13 @@ ISC_LANG_BEGINDECLS #define DNS_RBTFIND_EMPTYDATA 0x01 #define DNS_RBTFIND_NOEXACT 0x02 #define DNS_RBTFIND_NOPREDECESSOR 0x04 +/*@}*/ + +#ifndef DNS_RBT_USEISCREFCOUNT +#ifdef ISC_REFCOUNT_HAVEATOMIC +#define DNS_RBT_USEISCREFCOUNT 1 +#endif +#endif /* * These should add up to 30. @@ -51,7 +62,7 @@ ISC_LANG_BEGINDECLS #define DNS_RBTNODE_VALID(n) ISC_TRUE #endif -/* +/*% * This is the structure that is used for each node in the red/black * tree of trees. NOTE WELL: the implementation manages this as a variable * length structure, with the actual wire-format name and other data @@ -69,7 +80,8 @@ typedef struct dns_rbtnode { #ifdef DNS_RBT_USEHASH struct dns_rbtnode *hashnext; #endif - /* + /*@{*/ + /*! * The following bitfields add up to a total bitwidth of 32. * The range of values necessary for each item is indicated, * but in the case of "attributes" the field is wider to accomodate @@ -81,19 +93,21 @@ typedef struct dns_rbtnode { * In each case below the "range" indicated is what's _necessary_ for * the bitfield to hold, not what it actually _can_ hold. */ - unsigned int is_root : 1; /* range is 0..1 */ - unsigned int color : 1; /* range is 0..1 */ - unsigned int find_callback : 1; /* range is 0..1 */ - unsigned int attributes : 4; /* range is 0..2 */ - unsigned int namelen : 8; /* range is 1..255 */ - unsigned int offsetlen : 8; /* range is 1..128 */ - unsigned int padbytes : 9; /* range is 0..380 */ + unsigned int is_root : 1; /*%< range is 0..1 */ + unsigned int color : 1; /*%< range is 0..1 */ + unsigned int find_callback : 1; /*%< range is 0..1 */ + unsigned int attributes : 4; /*%< range is 0..2 */ + unsigned int namelen : 8; /*%< range is 1..255 */ + unsigned int offsetlen : 8; /*%< range is 1..128 */ + unsigned int padbytes : 9; /*%< range is 0..380 */ + /*@}*/ #ifdef DNS_RBT_USEHASH unsigned int hashval; #endif - /* + /*@{*/ + /*! * These values are used in the RBT DB implementation. The appropriate * node lock must be held before accessing them. */ @@ -101,7 +115,12 @@ typedef struct dns_rbtnode { unsigned int dirty:1; unsigned int wild:1; unsigned int locknum:DNS_RBT_LOCKLENGTH; +#ifndef DNS_RBT_USEISCREFCOUNT unsigned int references:DNS_RBT_REFLENGTH; +#else + isc_refcount_t references; /* note that this is not in the bitfield */ +#endif + /*@}*/ } dns_rbtnode_t; typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node, @@ -112,7 +131,7 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node, ***** Chain Info *****/ -/* +/*! * A chain is used to keep track of the sequence of nodes to reach any given * node from the root of the tree. Originally nodes did not have parent * pointers in them (for memory usage reasons) so there was no way to find @@ -151,7 +170,7 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node, * functions but additionally can provide the node to which the chain points. */ -/* +/*% * The number of level blocks to allocate at a time. Currently the maximum * number of levels is allocated directly in the structure, but future * revisions of this code might have a static initial block with dynamic @@ -165,14 +184,14 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node, typedef struct dns_rbtnodechain { unsigned int magic; isc_mem_t * mctx; - /* + /*% * The terminal node of the chain. It is not in levels[]. * This is ostensibly private ... but in a pinch it could be * used tell that the chain points nowhere without needing to * call dns_rbtnodechain_current(). */ dns_rbtnode_t * end; - /* + /*% * The maximum number of labels in a name is 128; bitstrings mean * a conceptually very large number (which I have not bothered to * compute) of logical levels because splitting can potentially occur @@ -181,7 +200,7 @@ typedef struct dns_rbtnodechain { * in the worst case. */ dns_rbtnode_t * levels[DNS_RBT_LEVELBLOCK]; - /* + /*% * level_count indicates how deep the chain points into the * tree of trees, and is the index into the levels[] array. * Thus, levels[level_count - 1] is the last level node stored. @@ -190,7 +209,7 @@ typedef struct dns_rbtnodechain { * so on. */ unsigned int level_count; - /* + /*% * level_matches tells how many levels matched above the node * returned by dns_rbt_findnode(). A match (partial or exact) found * in the first level thus results in level_matches being set to 1. @@ -203,44 +222,43 @@ typedef struct dns_rbtnodechain { /***** ***** Public interfaces. *****/ - isc_result_t dns_rbt_create(isc_mem_t *mctx, void (*deleter)(void *, void *), void *deleter_arg, dns_rbt_t **rbtp); -/* +/*%< * Initialize a red-black tree of trees. * * Notes: - * The deleter argument, if non-null, points to a function that is + *\li The deleter argument, if non-null, points to a function that is * responsible for cleaning up any memory associated with the data * pointer of a node when the node is deleted. It is passed the * deleted node's data pointer as its first argument and deleter_arg * as its second argument. * * Requires: - * mctx is a pointer to a valid memory context. - * rbtp != NULL && *rbtp == NULL - * arg == NULL iff deleter == NULL + * \li mctx is a pointer to a valid memory context. + *\li rbtp != NULL && *rbtp == NULL + *\li arg == NULL iff deleter == NULL * * Ensures: - * If result is ISC_R_SUCCESS: + *\li If result is ISC_R_SUCCESS: * *rbtp points to a valid red-black tree manager * - * If result is failure: + *\li If result is failure: * *rbtp does not point to a valid red-black tree manager. * * Returns: - * ISC_R_SUCCESS Success - * ISC_R_NOMEMORY Resource limit: Out of Memory + *\li #ISC_R_SUCCESS Success + *\li #ISC_R_NOMEMORY Resource limit: Out of Memory */ isc_result_t dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data); -/* +/*%< * Add 'name' to the tree of trees, associated with 'data'. * * Notes: - * 'data' is never required to be non-NULL, but specifying it + *\li 'data' is never required to be non-NULL, but specifying it * when the name is added is faster than searching for 'name' * again and then setting the data pointer. The lack of a data pointer * for a node also has other ramifications regarding whether @@ -248,106 +266,103 @@ dns_rbt_addname(dns_rbt_t *rbt, dns_name_t *name, void *data); * joins nodes. * * Requires: - * rbt is a valid rbt manager. - * dns_name_isabsolute(name) == TRUE + *\li rbt is a valid rbt manager. + *\li dns_name_isabsolute(name) == TRUE * * Ensures: - * 'name' is not altered in any way. + *\li 'name' is not altered in any way. * - * Any external references to nodes in the tree are unaffected by + *\li Any external references to nodes in the tree are unaffected by * node splits that are necessary to insert the new name. * - * If result is ISC_R_SUCCESS: + *\li If result is #ISC_R_SUCCESS: * 'name' is findable in the red/black tree of trees in O(log N). - * * The data pointer of the node for 'name' is set to 'data'. * - * If result is ISC_R_EXISTS or ISC_R_NOSPACE: + *\li If result is #ISC_R_EXISTS or #ISC_R_NOSPACE: * The tree of trees is unaltered. * - * If result is ISC_R_NOMEMORY: + *\li If result is #ISC_R_NOMEMORY: * No guarantees. * * Returns: - * ISC_R_SUCCESS Success - * ISC_R_EXISTS The name already exists with associated data. - * ISC_R_NOSPACE The name had more logical labels than are allowed. - * ISC_R_NOMEMORY Resource Limit: Out of Memory + *\li #ISC_R_SUCCESS Success + *\li #ISC_R_EXISTS The name already exists with associated data. + *\li #ISC_R_NOSPACE The name had more logical labels than are allowed. + *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory */ isc_result_t dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep); -/* +/*%< * Just like dns_rbt_addname, but returns the address of the node. * * Requires: - * rbt is a valid rbt structure. - * dns_name_isabsolute(name) == TRUE - * nodep != NULL && *nodep == NULL + *\li rbt is a valid rbt structure. + *\li dns_name_isabsolute(name) == TRUE + *\li nodep != NULL && *nodep == NULL * * Ensures: - * 'name' is not altered in any way. + *\li 'name' is not altered in any way. * - * Any external references to nodes in the tree are unaffected by + *\li Any external references to nodes in the tree are unaffected by * node splits that are necessary to insert the new name. * - * If result is ISC_R_SUCCESS: + *\li If result is ISC_R_SUCCESS: * 'name' is findable in the red/black tree of trees in O(log N). - * * *nodep is the node that was added for 'name'. * - * If result is ISC_R_EXISTS: + *\li If result is ISC_R_EXISTS: * The tree of trees is unaltered. - * * *nodep is the existing node for 'name'. * - * If result is ISC_R_NOMEMORY: + *\li If result is ISC_R_NOMEMORY: * No guarantees. * * Returns: - * ISC_R_SUCCESS Success - * ISC_R_EXISTS The name already exists, possibly without data. - * ISC_R_NOMEMORY Resource Limit: Out of Memory + *\li #ISC_R_SUCCESS Success + *\li #ISC_R_EXISTS The name already exists, possibly without data. + *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory */ isc_result_t dns_rbt_findname(dns_rbt_t *rbt, dns_name_t *name, unsigned int options, dns_name_t *foundname, void **data); -/* +/*%< * Get the data pointer associated with 'name'. * * Notes: - * When DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is - * returned (also subject to DNS_RBTFIND_EMPTYDATA), even when there is + *\li When #DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is + * returned (also subject to #DNS_RBTFIND_EMPTYDATA), even when there is * an exact match in the tree. * - * A node that has no data is considered not to exist for this function, - * unless the DNS_RBTFIND_EMPTYDATA option is set. + *\li A node that has no data is considered not to exist for this function, + * unless the #DNS_RBTFIND_EMPTYDATA option is set. * * Requires: - * rbt is a valid rbt manager. - * dns_name_isabsolute(name) == TRUE - * data != NULL && *data == NULL + *\li rbt is a valid rbt manager. + *\li dns_name_isabsolute(name) == TRUE + *\li data != NULL && *data == NULL * * Ensures: - * 'name' and the tree are not altered in any way. + *\li 'name' and the tree are not altered in any way. * - * If result is ISC_R_SUCCESS: + *\li If result is ISC_R_SUCCESS: * *data is the data associated with 'name'. * - * If result is DNS_R_PARTIALMATCH: + *\li If result is DNS_R_PARTIALMATCH: * *data is the data associated with the deepest superdomain * of 'name' which has data. * - * If result is ISC_R_NOTFOUND: + *\li If result is ISC_R_NOTFOUND: * Neither the name nor a superdomain was found with data. * * Returns: - * ISC_R_SUCCESS Success - * DNS_R_PARTIALMATCH Superdomain found with data - * ISC_R_NOTFOUND No match - * ISC_R_NOSPACE Concatenating nodes to form foundname failed + *\li #ISC_R_SUCCESS Success + *\li #DNS_R_PARTIALMATCH Superdomain found with data + *\li #ISC_R_NOTFOUND No match + *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed */ isc_result_t @@ -355,20 +370,20 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname, dns_rbtnode_t **node, dns_rbtnodechain_t *chain, unsigned int options, dns_rbtfindcallback_t callback, void *callback_arg); -/* +/*%< * Find the node for 'name'. * * Notes: - * A node that has no data is considered not to exist for this function, + *\li A node that has no data is considered not to exist for this function, * unless the DNS_RBTFIND_EMPTYDATA option is set. This applies to both * exact matches and partial matches. * - * If the chain parameter is non-NULL, then the path through the tree + *\li If the chain parameter is non-NULL, then the path through the tree * to the DNSSEC predecessor of the searched for name is maintained, * unless the DNS_RBTFIND_NOPREDECESSOR or DNS_RBTFIND_NOEXACT option * is used. (For more details on those options, see below.) * - * If there is no predecessor, then the chain will point to nowhere, as + *\li If there is no predecessor, then the chain will point to nowhere, as * indicated by chain->end being NULL or dns_rbtnodechain_current * returning ISC_R_NOTFOUND. Note that in a normal Internet DNS RBT * there will always be a predecessor for all names except the root @@ -376,23 +391,23 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname, * everything. But you can certainly construct a trivial tree and a * search for it that has no predecessor. * - * Within the chain structure, the 'levels' member of the structure holds + *\li Within the chain structure, the 'levels' member of the structure holds * the root node of each level except the first. * - * The 'level_count' of the chain indicates how deep the chain to the + *\li The 'level_count' of the chain indicates how deep the chain to the * predecessor name is, as an index into the 'levels[]' array. It does * not count name elements, per se, but only levels of the tree of trees, * the distinction arrising because multiple labels from a name can be * stored on only one level. It is also does not include the level * that has the node, since that level is not stored in levels[]. * - * The chain's 'level_matches' is not directly related to the predecessor. + *\li The chain's 'level_matches' is not directly related to the predecessor. * It is the number of levels above the level of the found 'node', * regardless of whether it was a partial match or exact match. When * the node is found in the top level tree, or no node is found at all, * level_matches is 0. * - * When DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is + *\li When DNS_RBTFIND_NOEXACT is set, the closest matching superdomain is * returned (also subject to DNS_RBTFIND_EMPTYDATA), even when * there is an exact match in the tree. In this case, the chain * will not point to the DNSSEC predecessor, but will instead point @@ -407,26 +422,29 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname, * where you want the chain pointed, so this can be made more firm. * * Requires: - * rbt is a valid rbt manager. - * dns_name_isabsolute(name) == TRUE. - * node != NULL && *node == NULL. - * DNS_RBTFIND_NOEXACT and DNS_RBTFIND_NOPREDECESSOR are mutally + *\li rbt is a valid rbt manager. + *\li dns_name_isabsolute(name) == TRUE. + *\li node != NULL && *node == NULL. + *\li #DNS_RBTFIND_NOEXACT and DNS_RBTFIND_NOPREDECESSOR are mutally * exclusive. * * Ensures: - * 'name' and the tree are not altered in any way. + *\li 'name' and the tree are not altered in any way. * - * If result is ISC_R_SUCCESS: + *\li If result is ISC_R_SUCCESS: + *\verbatim * *node is the terminal node for 'name'. - * + * 'foundname' and 'name' represent the same name (though not * the same memory). - * + * 'chain' points to the DNSSEC predecessor, if any, of 'name'. * * chain->level_matches and chain->level_count are equal. + *\endverbatim * * If result is DNS_R_PARTIALMATCH: + *\verbatim * *node is the data associated with the deepest superdomain * of 'name' which has data. * @@ -434,59 +452,62 @@ dns_rbt_findnode(dns_rbt_t *rbt, dns_name_t *name, dns_name_t *foundname, * data, unless the DNS_RBTFIND_EMPTYDATA option is set). * * 'chain' points to the DNSSEC predecessor, if any, of 'name'. + *\endverbatim * - * If result is ISC_R_NOTFOUND: + *\li If result is ISC_R_NOTFOUND: + *\verbatim * Neither the name nor a superdomain was found. *node is NULL. * * 'chain' points to the DNSSEC predecessor, if any, of 'name'. * * chain->level_matches is 0. + *\endverbatim * * Returns: - * ISC_R_SUCCESS Success - * DNS_R_PARTIALMATCH Superdomain found with data - * ISC_R_NOTFOUND No match, or superdomain with no data - * ISC_R_NOSPACE Concatenating nodes to form foundname failed + *\li #ISC_R_SUCCESS Success + *\li #DNS_R_PARTIALMATCH Superdomain found with data + *\li #ISC_R_NOTFOUND No match, or superdomain with no data + *\li #ISC_R_NOSPACE Concatenating nodes to form foundname failed */ isc_result_t dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse); -/* +/*%< * Delete 'name' from the tree of trees. * * Notes: - * When 'name' is removed, if recurse is ISC_TRUE then all of its + *\li When 'name' is removed, if recurse is ISC_TRUE then all of its * subnames are removed too. * * Requires: - * rbt is a valid rbt manager. - * dns_name_isabsolute(name) == TRUE + *\li rbt is a valid rbt manager. + *\li dns_name_isabsolute(name) == TRUE * * Ensures: - * 'name' is not altered in any way. + *\li 'name' is not altered in any way. * - * Does NOT ensure that any external references to nodes in the tree + *\li Does NOT ensure that any external references to nodes in the tree * are unaffected by node joins. * - * If result is ISC_R_SUCCESS: + *\li If result is ISC_R_SUCCESS: * 'name' does not appear in the tree with data; however, * the node for the name might still exist which can be * found with dns_rbt_findnode (but not dns_rbt_findname). * - * If result is ISC_R_NOTFOUND: + *\li If result is ISC_R_NOTFOUND: * 'name' does not appear in the tree with data, because * it did not appear in the tree before the function was called. * - * If result is something else: + *\li If result is something else: * See result codes for dns_rbt_findnode (if it fails, the * node is not deleted) or dns_rbt_deletenode (if it fails, * the node is deleted, but the tree is not optimized when * it could have been). * * Returns: - * ISC_R_SUCCESS Success - * ISC_R_NOTFOUND No match - * something_else Any return code from dns_rbt_findnode except + *\li #ISC_R_SUCCESS Success + *\li #ISC_R_NOTFOUND No match + *\li something_else Any return code from dns_rbt_findnode except * DNS_R_PARTIALMATCH (which causes ISC_R_NOTFOUND * to be returned instead), and any code from * dns_rbt_deletenode. @@ -494,115 +515,115 @@ dns_rbt_deletename(dns_rbt_t *rbt, dns_name_t *name, isc_boolean_t recurse); isc_result_t dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse); -/* +/*%< * Delete 'node' from the tree of trees. * * Notes: - * When 'node' is removed, if recurse is ISC_TRUE then all nodes + *\li When 'node' is removed, if recurse is ISC_TRUE then all nodes * in levels down from it are removed too. * * Requires: - * rbt is a valid rbt manager. - * node != NULL. + *\li rbt is a valid rbt manager. + *\li node != NULL. * * Ensures: - * Does NOT ensure that any external references to nodes in the tree + *\li Does NOT ensure that any external references to nodes in the tree * are unaffected by node joins. * - * If result is ISC_R_SUCCESS: + *\li If result is ISC_R_SUCCESS: * 'node' does not appear in the tree with data; however, * the node might still exist if it serves as a pointer to * a lower tree level as long as 'recurse' was false, hence * the node could can be found with dns_rbt_findnode whem * that function's empty_data_ok parameter is true. * - * If result is ISC_R_NOMEMORY or ISC_R_NOSPACE: + *\li If result is ISC_R_NOMEMORY or ISC_R_NOSPACE: * The node was deleted, but the tree structure was not * optimized. * * Returns: - * ISC_R_SUCCESS Success - * ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes. - * ISC_R_NOSPACE dns_name_concatenate failed when joining nodes. + *\li #ISC_R_SUCCESS Success + *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory when joining nodes. + *\li #ISC_R_NOSPACE dns_name_concatenate failed when joining nodes. */ void dns_rbt_namefromnode(dns_rbtnode_t *node, dns_name_t *name); -/* +/*%< * Convert the sequence of labels stored at 'node' into a 'name'. * * Notes: - * This function does not return the full name, from the root, but + *\li This function does not return the full name, from the root, but * just the labels at the indicated node. * - * The name data pointed to by 'name' is the information stored + *\li The name data pointed to by 'name' is the information stored * in the node, not a copy. Altering the data at this pointer * will likely cause grief. * * Requires: - * name->offsets == NULL + * \li name->offsets == NULL * * Ensures: - * 'name' is DNS_NAMEATTR_READONLY. + * \li 'name' is DNS_NAMEATTR_READONLY. * - * 'name' will point directly to the labels stored after the + * \li 'name' will point directly to the labels stored after the * dns_rbtnode_t struct. * - * 'name' will have offsets that also point to the information stored + * \li 'name' will have offsets that also point to the information stored * as part of the node. */ isc_result_t dns_rbt_fullnamefromnode(dns_rbtnode_t *node, dns_name_t *name); -/* +/*%< * Like dns_rbt_namefromnode, but returns the full name from the root. * * Notes: - * Unlike dns_rbt_namefromnode, the name will not point directly + * \li Unlike dns_rbt_namefromnode, the name will not point directly * to node data. Rather, dns_name_concatenate will be used to copy * the name data from each node into the 'name' argument. * * Requires: - * name != NULL - * name has a dedicated buffer. + * \li name != NULL + * \li name has a dedicated buffer. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE (possible via dns_name_concatenate) - * DNS_R_NAMETOOLONG (possible via dns_name_concatenate) + * \li ISC_R_SUCCESS + * \li ISC_R_NOSPACE (possible via dns_name_concatenate) + * \li DNS_R_NAMETOOLONG (possible via dns_name_concatenate) */ char * dns_rbt_formatnodename(dns_rbtnode_t *node, char *printname, unsigned int size); -/* +/*%< * Format the full name of a node for printing, using dns_name_format(). * * Notes: - * 'size' is the length of the printname buffer. This should be + * \li 'size' is the length of the printname buffer. This should be * DNS_NAME_FORMATSIZE or larger. * * Requires: - * node and printname are not NULL. + * \li node and printname are not NULL. * * Returns: - * The 'printname' pointer. + * \li The 'printname' pointer. */ unsigned int dns_rbt_nodecount(dns_rbt_t *rbt); -/* +/*%< * Obtain the number of nodes in the tree of trees. * * Requires: - * rbt is a valid rbt manager. + * \li rbt is a valid rbt manager. */ void dns_rbt_destroy(dns_rbt_t **rbtp); isc_result_t dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum); -/* +/*%< * Stop working with a red-black tree of trees. * If 'quantum' is zero then the entire tree will be destroyed. * If 'quantum' is non zero then up to 'quantum' nodes will be destroyed @@ -612,26 +633,26 @@ dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum); * performed on the tree of trees. * * Requires: - * *rbt is a valid rbt manager. + * \li *rbt is a valid rbt manager. * * Ensures on ISC_R_SUCCESS: - * All space allocated by the RBT library has been returned. + * \li All space allocated by the RBT library has been returned. * - * *rbt is invalidated as an rbt manager. + * \li *rbt is invalidated as an rbt manager. * * Returns: - * ISC_R_SUCCESS - * ISC_R_QUOTA if 'quantum' nodes have been destroyed. + * \li ISC_R_SUCCESS + * \li ISC_R_QUOTA if 'quantum' nodes have been destroyed. */ void dns_rbt_printall(dns_rbt_t *rbt); -/* +/*%< * Print an ASCII representation of the internal structure of the red-black * tree of trees. * * Notes: - * The name stored at each node, along with the node's color, is printed. + * \li The name stored at each node, along with the node's color, is printed. * Then the down pointer, left and right pointers are displayed * recursively in turn. NULL down pointers are silently omitted; * NULL left and right pointers are printed. @@ -643,70 +664,70 @@ dns_rbt_printall(dns_rbt_t *rbt); void dns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx); -/* +/*%< * Initialize 'chain'. * * Requires: - * 'chain' is a valid pointer. + *\li 'chain' is a valid pointer. * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. * * Ensures: - * 'chain' is suitable for use. + *\li 'chain' is suitable for use. */ void dns_rbtnodechain_reset(dns_rbtnodechain_t *chain); -/* +/*%< * Free any dynamic storage associated with 'chain', and then reinitialize * 'chain'. * * Requires: - * 'chain' is a valid pointer. + *\li 'chain' is a valid pointer. * * Ensures: - * 'chain' is suitable for use, and uses no dynamic storage. + *\li 'chain' is suitable for use, and uses no dynamic storage. */ void dns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain); -/* +/*%< * Free any dynamic storage associated with 'chain', and then invalidates it. * * Notes: - * Future calls to any dns_rbtnodechain_ function will need to call + *\li Future calls to any dns_rbtnodechain_ function will need to call * dns_rbtnodechain_init on the chain first (except, of course, * dns_rbtnodechain_init itself). * * Requires: - * 'chain' is a valid chain. + *\li 'chain' is a valid chain. * * Ensures: - * 'chain' is no longer suitable for use, and uses no dynamic storage. + *\li 'chain' is no longer suitable for use, and uses no dynamic storage. */ isc_result_t dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin, dns_rbtnode_t **node); -/* +/*%< * Provide the name, origin and node to which the chain is currently pointed. * * Notes: - * The tree need not have be locked against additions for the chain + *\li The tree need not have be locked against additions for the chain * to remain valid, however there are no guarantees if any deletion * has been made since the chain was established. * * Requires: - * 'chain' is a valid chain. + *\li 'chain' is a valid chain. * * Ensures: - * 'node', if non-NULL, is the node to which the chain was pointed + *\li 'node', if non-NULL, is the node to which the chain was pointed * by dns_rbt_findnode, dns_rbtnodechain_first or dns_rbtnodechain_last. * If none were called for the chain since it was initialized or reset, * or if the was no predecessor to the name searched for with * dns_rbt_findnode, then '*node' is NULL and ISC_R_NOTFOUND is returned. * - * 'name', if non-NULL, is the name stored at the terminal level of + *\li 'name', if non-NULL, is the name stored at the terminal level of * the chain. This is typically a single label, like the "www" of * "www.isc.org", but need not be so. At the root of the tree of trees, * if the node is "." then 'name' is ".", otherwise it is relative to ".". @@ -714,124 +735,181 @@ dns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name, * "isc.org." then the root node's stored name is "isc.org." but 'name' * will be "isc.org".) * - * 'origin', if non-NULL, is the sequence of labels in the levels + *\li 'origin', if non-NULL, is the sequence of labels in the levels * above the terminal level, such as "isc.org." in the above example. * 'origin' is always "." for the root node. * * * Returns: - * ISC_R_SUCCESS name, origin & node were successfully set. - * ISC_R_NOTFOUND The chain does not point to any node. - * <something_else> Any error return from dns_name_concatenate. + *\li #ISC_R_SUCCESS name, origin & node were successfully set. + *\li #ISC_R_NOTFOUND The chain does not point to any node. + *\li <something_else> Any error return from dns_name_concatenate. */ isc_result_t dns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, dns_name_t *name, dns_name_t *origin); -/* +/*%< * Set the chain to the lexically first node in the tree of trees. * * Notes: - * By the definition of ordering for DNS names, the root of the tree of + *\li By the definition of ordering for DNS names, the root of the tree of * trees is the very first node, since everything else in the megatree * uses it as a common suffix. * * Requires: - * 'chain' is a valid chain. - * 'rbt' is a valid rbt manager. + *\li 'chain' is a valid chain. + *\li 'rbt' is a valid rbt manager. * * Ensures: - * The chain points to the very first node of the tree. + *\li The chain points to the very first node of the tree. * - * 'name' and 'origin', if non-NULL, are set as described for + *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. Thus 'origin' will always be ".". * * Returns: - * DNS_R_NEWORIGIN The name & origin were successfully set. - * <something_else> Any error result from dns_rbtnodechain_current. + *\li #DNS_R_NEWORIGIN The name & origin were successfully set. + *\li <something_else> Any error result from dns_rbtnodechain_current. */ isc_result_t dns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt, dns_name_t *name, dns_name_t *origin); -/* +/*%< * Set the chain to the lexically last node in the tree of trees. * * Requires: - * 'chain' is a valid chain. - * 'rbt' is a valid rbt manager. + *\li 'chain' is a valid chain. + *\li 'rbt' is a valid rbt manager. * * Ensures: - * The chain points to the very last node of the tree. + *\li The chain points to the very last node of the tree. * - * 'name' and 'origin', if non-NULL, are set as described for + *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. * * Returns: - * DNS_R_NEWORIGIN The name & origin were successfully set. - * ISC_R_NOMEMORY Resource Limit: Out of Memory building chain. - * <something_else> Any error result from dns_name_concatenate. + *\li #DNS_R_NEWORIGIN The name & origin were successfully set. + *\li #ISC_R_NOMEMORY Resource Limit: Out of Memory building chain. + *\li <something_else> Any error result from dns_name_concatenate. */ isc_result_t dns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin); -/* +/*%< * Adjusts chain to point the DNSSEC predecessor of the name to which it * is currently pointed. * * Requires: - * 'chain' is a valid chain. - * 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, + *\li 'chain' is a valid chain. + *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that * dns_rbt_findnode is not guaranteed to point the chain somewhere, * since there may have been no predecessor to the searched for name. * * Ensures: - * The chain is pointed to the predecessor of its current target. + *\li The chain is pointed to the predecessor of its current target. * - * 'name' and 'origin', if non-NULL, are set as described for + *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. * - * 'origin' is only if a new origin was found. + *\li 'origin' is only if a new origin was found. * * Returns: - * ISC_R_SUCCESS The predecessor was found and 'name' was set. - * DNS_R_NEWORIGIN The predecessor was found with a different + *\li #ISC_R_SUCCESS The predecessor was found and 'name' was set. + *\li #DNS_R_NEWORIGIN The predecessor was found with a different * origin and 'name' and 'origin' were set. - * ISC_R_NOMORE There was no predecessor. - * <something_else> Any error result from dns_rbtnodechain_current. + *\li #ISC_R_NOMORE There was no predecessor. + *\li <something_else> Any error result from dns_rbtnodechain_current. */ isc_result_t dns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name, dns_name_t *origin); -/* +/*%< * Adjusts chain to point the DNSSEC successor of the name to which it * is currently pointed. * * Requires: - * 'chain' is a valid chain. - * 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, + *\li 'chain' is a valid chain. + *\li 'chain' has been pointed somewhere in the tree with dns_rbt_findnode, * dns_rbtnodechain_first or dns_rbtnodechain_last -- and remember that * dns_rbt_findnode is not guaranteed to point the chain somewhere, * since there may have been no predecessor to the searched for name. * * Ensures: - * The chain is pointed to the successor of its current target. + *\li The chain is pointed to the successor of its current target. * - * 'name' and 'origin', if non-NULL, are set as described for + *\li 'name' and 'origin', if non-NULL, are set as described for * dns_rbtnodechain_current. * - * 'origin' is only if a new origin was found. + *\li 'origin' is only if a new origin was found. * * Returns: - * ISC_R_SUCCESS The successor was found and 'name' was set. - * DNS_R_NEWORIGIN The successor was found with a different + *\li #ISC_R_SUCCESS The successor was found and 'name' was set. + *\li #DNS_R_NEWORIGIN The successor was found with a different * origin and 'name' and 'origin' were set. - * ISC_R_NOMORE There was no successor. - * <something_else> Any error result from dns_name_concatenate. + *\li #ISC_R_NOMORE There was no successor. + *\li <something_else> Any error result from dns_name_concatenate. + */ + +/* + * Wrapper macros for manipulating the rbtnode reference counter: + * Since we selectively use isc_refcount_t for the reference counter of + * a rbtnode, operations on the counter depend on the actual type of it. + * The following macros provide a common interface to these operations, + * hiding the back-end. The usage is the same as that of isc_refcount_xxx(). */ +#ifdef DNS_RBT_USEISCREFCOUNT +#define dns_rbtnode_refinit(node, n) \ + do { \ + isc_refcount_init(&(node)->references, (n)); \ + } while (0) +#define dns_rbtnode_refdestroy(node) \ + do { \ + isc_refcount_destroy(&(node)->references); \ + } while (0) +#define dns_rbtnode_refcurrent(node) \ + isc_refcount_current(&(node)->references) +#define dns_rbtnode_refincrement0(node, refs) \ + do { \ + isc_refcount_increment0(&(node)->references, (refs)); \ + } while (0) +#define dns_rbtnode_refincrement(node, refs) \ + do { \ + isc_refcount_increment(&(node)->references, (refs)); \ + } while (0) +#define dns_rbtnode_refdecrement(node, refs) \ + do { \ + isc_refcount_decrement(&(node)->references, (refs)); \ + } while (0) +#else /* DNS_RBT_USEISCREFCOUNT */ +#define dns_rbtnode_refinit(node, n) ((node)->references = (n)) +#define dns_rbtnode_refdestroy(node) (REQUIRE((node)->references == 0)) +#define dns_rbtnode_refcurrent(node) ((node)->references) +#define dns_rbtnode_refincrement0(node, refs) \ + do { \ + unsigned int *_tmp = (unsigned int *)(refs); \ + (node)->references++; \ + if ((_tmp) != NULL) \ + (*_tmp) = (node)->references; \ + } while (0) +#define dns_rbtnode_refincrement(node, refs) \ + do { \ + REQUIRE((node)->references > 0); \ + (node)->references++; \ + if ((refs) != NULL) \ + (*refs) = (node)->references; \ + } while (0) +#define dns_rbtnode_refdecrement(node, refs) \ + do { \ + REQUIRE((node)->references > 0); \ + (node)->references--; \ + if ((refs) != NULL) \ + (*refs) = (node)->references; \ + } while (0) +#endif /* DNS_RBT_USEISCREFCOUNT */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rcode.h b/contrib/bind9/lib/dns/include/dns/rcode.h index b2494f7..03c145b 100644 --- a/contrib/bind9/lib/dns/include/dns/rcode.h +++ b/contrib/bind9/lib/dns/include/dns/rcode.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rcode.h,v 1.12.206.1 2004/03/06 08:13:59 marka Exp $ */ +/* $Id: rcode.h,v 1.13.18.2 2005/04/29 00:16:18 marka Exp $ */ #ifndef DNS_RCODE_H #define DNS_RCODE_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -27,68 +29,68 @@ ISC_LANG_BEGINDECLS isc_result_t dns_rcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a DNS error value. * * Requires: - * 'rcodep' is a valid pointer. + *\li 'rcodep' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * DNS_R_UNKNOWN type is unknown + *\li #ISC_R_SUCCESS on success + *\li #DNS_R_UNKNOWN type is unknown */ isc_result_t dns_rcode_totext(dns_rcode_t rcode, isc_buffer_t *target); -/* +/*%< * Put a textual representation of error 'rcode' into 'target'. * * Requires: - * 'rcode' is a valid rcode. + *\li 'rcode' is a valid rcode. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * * Ensures: - * If the result is success: + *\li If the result is success: * The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_NOSPACE target buffer is too small */ isc_result_t dns_tsigrcode_fromtext(dns_rcode_t *rcodep, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a TSIG/TKEY error value. * * Requires: - * 'rcodep' is a valid pointer. + *\li 'rcodep' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * DNS_R_UNKNOWN type is unknown + *\li #ISC_R_SUCCESS on success + *\li #DNS_R_UNKNOWN type is unknown */ isc_result_t dns_tsigrcode_totext(dns_rcode_t rcode, isc_buffer_t *target); -/* +/*%< * Put a textual representation of TSIG/TKEY error 'rcode' into 'target'. * * Requires: - * 'rcode' is a valid TSIG/TKEY error code. + *\li 'rcode' is a valid TSIG/TKEY error code. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * * Ensures: - * If the result is success: + *\li If the result is success: * The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rdata.h b/contrib/bind9/lib/dns/include/dns/rdata.h index b006b17..a14bde7 100644 --- a/contrib/bind9/lib/dns/include/dns/rdata.h +++ b/contrib/bind9/lib/dns/include/dns/rdata.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdata.h,v 1.51.2.3.2.4 2004/03/08 02:08:01 marka Exp $ */ +/* $Id: rdata.h,v 1.60.18.3 2005/05/19 04:59:56 marka Exp $ */ #ifndef DNS_RDATA_H #define DNS_RDATA_H 1 @@ -24,9 +24,8 @@ ***** Module Info *****/ -/* - * DNS Rdata - * +/*! \file + * \brief * Provides facilities for manipulating DNS rdata, including conversions to * and from wire format and text format. * @@ -46,7 +45,7 @@ * * Implementation Notes: * - * The routines in this module are expected to be synthesized by the + *\li The routines in this module are expected to be synthesized by the * build process from a set of source files, one per rdata type. For * portability, it's probably best that the building be done by a C * program. Adding a new rdata type will be a simple matter of adding @@ -54,38 +53,37 @@ * the format of a particular rdata type is in this file. * * MP: - * Clients of this module must impose any required synchronization. + *\li Clients of this module must impose any required synchronization. * * Reliability: - * This module deals with low-level byte streams. Errors in any of + *\li This module deals with low-level byte streams. Errors in any of * the functions are likely to crash the server or corrupt memory. * - * Rdata is typed, and the caller must know what type of rdata it has. + *\li Rdata is typed, and the caller must know what type of rdata it has. * A caller that gets this wrong could crash the server. * - * The fromstruct() and tostruct() routines use a void * pointer to + *\li The fromstruct() and tostruct() routines use a void * pointer to * represent the structure. The caller must ensure that it passes a * pointer to the appropriate type, or the server could crash or memory * could be corrupted. * * Resources: - * None. + *\li None. * * Security: * - * *** WARNING *** - * + *\li *** WARNING *** * dns_rdata_fromwire() deals with raw network data. An error in * this routine could result in the failure or hijacking of the server. * * Standards: - * RFC 1035 - * Draft EDNS0 (0) - * Draft EDNS1 (0) - * Draft Binary Labels (2) - * Draft Local Compression (1) - * <Various RFCs for particular types; these will be documented in the - * sources files of the types.> + *\li RFC1035 + *\li Draft EDNS0 (0) + *\li Draft EDNS1 (0) + *\li Draft Binary Labels (2) + *\li Draft Local Compression (1) + *\li Various RFCs for particular types; these will be documented in the + * sources files of the types. * */ @@ -100,19 +98,17 @@ ISC_LANG_BEGINDECLS -/***** - ***** RData - ***** - ***** An 'rdata' is a handle to a binary region. The handle has an RR - ***** class and type, and the data in the binary region is in the format - ***** of the given class and type. - *****/ /*** *** Types ***/ -/* +/*% + ***** An 'rdata' is a handle to a binary region. The handle has an RR + ***** class and type, and the data in the binary region is in the format + ***** of the given class and type. + *****/ +/*% * Clients are strongly discouraged from using this type directly, with * the exception of the 'link' field which may be used directly for whatever * purpose the client desires. @@ -128,7 +124,7 @@ struct dns_rdata { #define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}} -#define DNS_RDATA_UPDATE 0x0001 /* update pseudo record */ +#define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record */ /* * Flags affecting rdata formatting style. Flags 0xFFFF0000 @@ -136,17 +132,19 @@ struct dns_rdata { * See additional comments at dns_rdata_tofmttext(). */ -/* Split the rdata into multiple lines to try to keep it +/*% Split the rdata into multiple lines to try to keep it within the "width". */ #define DNS_STYLEFLAG_MULTILINE 0x00000001U -/* Output explanatory comments. */ +/*% Output explanatory comments. */ #define DNS_STYLEFLAG_COMMENT 0x00000002U #define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE #define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES #define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL #define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE +#define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX +#define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL /*** *** Initialization @@ -154,7 +152,7 @@ struct dns_rdata { void dns_rdata_init(dns_rdata_t *rdata); -/* +/*%< * Make 'rdata' empty. * * Requires: @@ -163,21 +161,21 @@ dns_rdata_init(dns_rdata_t *rdata); void dns_rdata_reset(dns_rdata_t *rdata); -/* +/*%< * Make 'rdata' empty. * * Requires: - * 'rdata' is a previously initialized rdata and is not linked. + *\li 'rdata' is a previously initialized rdata and is not linked. */ void dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target); -/* +/*%< * Clone 'target' from 'src'. * * Requires: - * 'src' to be initialized. - * 'target' to be initialized. + *\li 'src' to be initialized. + *\li 'target' to be initialized. */ /*** @@ -186,20 +184,20 @@ dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target); int dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); -/* +/*%< * Determine the relative ordering under the DNSSEC order relation of * 'rdata1' and 'rdata2'. * * Requires: * - * 'rdata1' is a valid, non-empty rdata + *\li 'rdata1' is a valid, non-empty rdata * - * 'rdata2' is a valid, non-empty rdata + *\li 'rdata2' is a valid, non-empty rdata * * Returns: - * < 0 'rdata1' is less than 'rdata2' - * 0 'rdata1' is equal to 'rdata2' - * > 0 'rdata1' is greater than 'rdata2' + *\li < 0 'rdata1' is less than 'rdata2' + *\li 0 'rdata1' is equal to 'rdata2' + *\li > 0 'rdata1' is greater than 'rdata2' */ /*** @@ -209,17 +207,17 @@ dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2); void dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_region_t *r); -/* +/*%< * Make 'rdata' refer to region 'r'. * * Requires: * - * The data in 'r' is properly formatted for whatever type it is. + *\li The data in 'r' is properly formatted for whatever type it is. */ void dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r); -/* +/*%< * Make 'r' refer to 'rdata'. */ @@ -228,73 +226,70 @@ dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_buffer_t *source, dns_decompress_t *dctx, unsigned int options, isc_buffer_t *target); -/* +/*%< * Copy the possibly-compressed rdata at source into the target region. * * Notes: - * Name decompression policy is controlled by 'dctx'. + *\li Name decompression policy is controlled by 'dctx'. * * 'options' - * DNS_RDATA_DOWNCASE downcase domain names when they are copied + *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied * into target. * * Requires: * - * 'rdclass' and 'type' are valid. + *\li 'rdclass' and 'type' are valid. * - * 'source' is a valid buffer, and the active region of 'source' + *\li 'source' is a valid buffer, and the active region of 'source' * references the rdata to be processed. * - * 'target' is a valid buffer. + *\li 'target' is a valid buffer. * - * 'dctx' is a valid decompression context. + *\li 'dctx' is a valid decompression context. * - * Ensures: - * - * If result is success: - * If 'rdata' is not NULL, it is attached to the target. - * - * The conditions dns_name_fromwire() ensures for names hold + * Ensures, + * if result is success: + * \li If 'rdata' is not NULL, it is attached to the target. + * \li The conditions dns_name_fromwire() ensures for names hold * for all names in the rdata. - * - * The current location in source is advanced, and the used space + * \li The current location in source is advanced, and the used space * in target is updated. * * Result: - * Success - * <Any non-success status from dns_name_fromwire()> - * <Various 'Bad Form' class failures depending on class and type> - * Bad Form: Input too short - * Resource Limit: Not enough space + *\li Success + *\li Any non-success status from dns_name_fromwire() + *\li Various 'Bad Form' class failures depending on class and type + *\li Bad Form: Input too short + *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, isc_buffer_t *target); -/* +/*%< * Convert 'rdata' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. * * Notes: - * If the compression context allows global compression, then the + *\li If the compression context allows global compression, then the * global compression table may be updated. * * Requires: - * 'rdata' is a valid, non-empty rdata + *\li 'rdata' is a valid, non-empty rdata * - * target is a valid buffer + *\li target is a valid buffer * - * Any offsets specified in a global compression table are valid + *\li Any offsets specified in a global compression table are valid * for target. * - * Ensures: - * If the result is success: - * The used space in target is updated. + * Ensures, + * if the result is success: + * \li The used space in target is updated. * * Returns: - * Success - * <Any non-success status from dns_name_towire()> - * Resource Limit: Not enough space + *\li Success + *\li Any non-success status from dns_name_towire() + *\li Resource Limit: Not enough space */ isc_result_t @@ -302,100 +297,100 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, isc_lex_t *lexer, dns_name_t *origin, unsigned int options, isc_mem_t *mctx, isc_buffer_t *target, dns_rdatacallbacks_t *callbacks); -/* +/*%< * Convert the textual representation of a DNS rdata into uncompressed wire * form stored in the target region. Tokens constituting the text of the rdata * are taken from 'lexer'. * * Notes: - * Relative domain names in the rdata will have 'origin' appended to them. + *\li Relative domain names in the rdata will have 'origin' appended to them. * A NULL origin implies "origin == dns_rootname". * * * 'options' - * DNS_RDATA_DOWNCASE downcase domain names when they are copied + *\li DNS_RDATA_DOWNCASE downcase domain names when they are copied * into target. - * DNS_RDATA_CHECKNAMES perform checknames checks. - * DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail. If + *\li DNS_RDATA_CHECKNAMES perform checknames checks. + *\li DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail. If * not set a warning will be issued. - * DNS_RDATA_CHECKREVERSE this should set if the owner name ends + *\li DNS_RDATA_CHECKREVERSE this should set if the owner name ends * in IP6.ARPA, IP6.INT or IN-ADDR.ARPA. * * Requires: * - * 'rdclass' and 'type' are valid. + *\li 'rdclass' and 'type' are valid. * - * 'lexer' is a valid isc_lex_t. + *\li 'lexer' is a valid isc_lex_t. * - * 'mctx' is a valid isc_mem_t. + *\li 'mctx' is a valid isc_mem_t. * - * 'target' is a valid region. + *\li 'target' is a valid region. * - * 'origin' if non NULL it must be absolute. + *\li 'origin' if non NULL it must be absolute. * - * 'callbacks' to be NULL or callbacks->warn and callbacks->error be + *\li 'callbacks' to be NULL or callbacks->warn and callbacks->error be * initialized. * - * Ensures: - * If result is success: - * If 'rdata' is not NULL, it is attached to the target. - * - * The conditions dns_name_fromtext() ensures for names hold + * Ensures, + * if result is success: + *\li If 'rdata' is not NULL, it is attached to the target. + + *\li The conditions dns_name_fromtext() ensures for names hold * for all names in the rdata. - * - * The used space in target is updated. + + *\li The used space in target is updated. * * Result: - * Success - * <Translated result codes from isc_lex_gettoken> - * <Various 'Bad Form' class failures depending on class and type> - * Bad Form: Input too short - * Resource Limit: Not enough space - * Resource Limit: Not enough memory + *\li Success + *\li Translated result codes from isc_lex_gettoken + *\li Various 'Bad Form' class failures depending on class and type + *\li Bad Form: Input too short + *\li Resource Limit: Not enough space + *\li Resource Limit: Not enough memory */ isc_result_t dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target); -/* +/*%< * Convert 'rdata' into text format, storing the result in 'target'. * The text will consist of a single line, with fields separated by * single spaces. * * Notes: - * If 'origin' is not NULL, then any names in the rdata that are + *\li If 'origin' is not NULL, then any names in the rdata that are * subdomains of 'origin' will be made relative it. * - * XXX Do we *really* want to support 'origin'? I'm inclined towards "no" + *\li XXX Do we *really* want to support 'origin'? I'm inclined towards "no" * at the moment. * * Requires: * - * 'rdata' is a valid, non-empty rdata + *\li 'rdata' is a valid, non-empty rdata * - * 'origin' is NULL, or is a valid name + *\li 'origin' is NULL, or is a valid name * - * 'target' is a valid text buffer + *\li 'target' is a valid text buffer * - * Ensures: - * If the result is success: + * Ensures, + * if the result is success: * - * The used space in target is updated. + * \li The used space in target is updated. * * Returns: - * Success - * <Any non-success status from dns_name_totext()> - * Resource Limit: Not enough space + *\li Success + *\li Any non-success status from dns_name_totext() + *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, unsigned int width, char *linebreak, isc_buffer_t *target); -/* +/*%< * Like dns_rdata_totext, but do formatted output suitable for * database dumps. This is intended for use by dns_db_dump(); * library users are discouraged from calling it directly. * - * If (flags & DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay + * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay * within 'width' by breaking the text into multiple lines. * The string 'linebreak' is inserted between lines, and parentheses * are added when necessary. Because RRs contain unbreakable elements @@ -403,11 +398,11 @@ dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, * potentially large, there is no guarantee that the lines will * not exceed 'width' anyway. * - * If (flags & DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always + * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always * printed as a single line, and no parentheses are used. * The 'width' and 'linebreak' arguments are ignored. * - * If (flags & DNS_STYLEFLAG_COMMENT) != 0, output explanatory + * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory * comments next to things like the SOA timer fields. Some * comments (e.g., the SOA ones) are only printed when multiline * output is selected. @@ -416,7 +411,7 @@ dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, isc_result_t dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, dns_rdatatype_t type, void *source, isc_buffer_t *target); -/* +/*%< * Convert the C structure representation of an rdata into uncompressed wire * format in 'target'. * @@ -424,30 +419,30 @@ dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, * * Requires: * - * 'rdclass' and 'type' are valid. + *\li 'rdclass' and 'type' are valid. * - * 'source' points to a valid C struct for the class and type. + *\li 'source' points to a valid C struct for the class and type. * - * 'target' is a valid buffer. + *\li 'target' is a valid buffer. * - * All structure pointers to memory blocks should be NULL if their + *\li All structure pointers to memory blocks should be NULL if their * corresponding length values are zero. * - * Ensures: - * If result is success: - * If 'rdata' is not NULL, it is attached to the target. + * Ensures, + * if result is success: + * \li If 'rdata' is not NULL, it is attached to the target. * - * The used space in 'target' is updated. + * \li The used space in 'target' is updated. * * Result: - * Success - * <Various 'Bad Form' class failures depending on class and type> - * Resource Limit: Not enough space + *\li Success + *\li Various 'Bad Form' class failures depending on class and type + *\li Resource Limit: Not enough space */ isc_result_t dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx); -/* +/*%< * Convert an rdata into its C structure representation. * * If 'mctx' is NULL then 'rdata' must persist while 'target' is being used. @@ -456,80 +451,80 @@ dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx); * * Requires: * - * 'rdata' is a valid, non-empty rdata. + *\li 'rdata' is a valid, non-empty rdata. * - * 'target' to point to a valid pointer for the type and class. + *\li 'target' to point to a valid pointer for the type and class. * * Result: - * Success - * Resource Limit: Not enough memory + *\li Success + *\li Resource Limit: Not enough memory */ void dns_rdata_freestruct(void *source); -/* +/*%< * Free dynamic memory attached to 'source' (if any). * * Requires: * - * 'source' to point to the structure previously filled in by + *\li 'source' to point to the structure previously filled in by * dns_rdata_tostruct(). */ isc_boolean_t dns_rdatatype_ismeta(dns_rdatatype_t type); -/* +/*%< * Return true iff the rdata type 'type' is a meta-type * like ANY or AXFR. */ isc_boolean_t dns_rdatatype_issingleton(dns_rdatatype_t type); -/* +/*%< * Return true iff the rdata type 'type' is a singleton type, * like CNAME or SOA. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdataclass_ismeta(dns_rdataclass_t rdclass); -/* +/*%< * Return true iff the rdata class 'rdclass' is a meta-class * like ANY or NONE. */ isc_boolean_t dns_rdatatype_isdnssec(dns_rdatatype_t type); -/* +/*%< * Return true iff 'type' is one of the DNSSEC * rdata types that may exist alongside a CNAME record. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. */ isc_boolean_t dns_rdatatype_iszonecutauth(dns_rdatatype_t type); -/* +/*%< * Return true iff rdata of type 'type' is considered authoritative * data (not glue) in the NSEC chain when it occurs in the parent zone * at a zone cut. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdatatype_isknown(dns_rdatatype_t type); -/* +/*%< * Return true iff the rdata type 'type' is known. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. * */ @@ -537,140 +532,140 @@ dns_rdatatype_isknown(dns_rdatatype_t type); isc_result_t dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, void *arg); -/* +/*%< * Call 'add' for each name and type from 'rdata' which is subject to * additional section processing. * * Requires: * - * 'rdata' is a valid, non-empty rdata. + *\li 'rdata' is a valid, non-empty rdata. * - * 'add' is a valid dns_additionalfunc_t. + *\li 'add' is a valid dns_additionalfunc_t. * * Ensures: * - * If successful, then add() will have been called for each name + *\li If successful, then add() will have been called for each name * and type subject to additional section processing. * - * If add() returns something other than ISC_R_SUCCESS, that result + *\li If add() returns something other than #ISC_R_SUCCESS, that result * will be returned as the result of dns_rdata_additionaldata(). * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Many other results are possible if not successful. + *\li Many other results are possible if not successful. */ isc_result_t dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg); -/* +/*%< * Send 'rdata' in DNSSEC canonical form to 'digest'. * * Note: - * 'digest' may be called more than once by dns_rdata_digest(). The + *\li 'digest' may be called more than once by dns_rdata_digest(). The * concatenation of all the regions, in the order they were given * to 'digest', will be the DNSSEC canonical form of 'rdata'. * * Requires: * - * 'rdata' is a valid, non-empty rdata. + *\li 'rdata' is a valid, non-empty rdata. * - * 'digest' is a valid dns_digestfunc_t. + *\li 'digest' is a valid dns_digestfunc_t. * * Ensures: * - * If successful, then all of the rdata's data has been sent, in + *\li If successful, then all of the rdata's data has been sent, in * DNSSEC canonical form, to 'digest'. * - * If digest() returns something other than ISC_R_SUCCESS, that result + *\li If digest() returns something other than ISC_R_SUCCESS, that result * will be returned as the result of dns_rdata_digest(). * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Many other results are possible if not successful. + *\li Many other results are possible if not successful. */ isc_boolean_t dns_rdatatype_questiononly(dns_rdatatype_t type); -/* +/*%< * Return true iff rdata of type 'type' can only appear in the question * section of a properly formatted message. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdatatype_notquestion(dns_rdatatype_t type); -/* +/*%< * Return true iff rdata of type 'type' can not appear in the question * section of a properly formatted message. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. * */ isc_boolean_t dns_rdatatype_atparent(dns_rdatatype_t type); -/* +/*%< * Return true iff rdata of type 'type' should appear at the parent of * a zone cut. * * Requires: - * 'type' is a valid rdata type. + * \li 'type' is a valid rdata type. * */ unsigned int dns_rdatatype_attributes(dns_rdatatype_t rdtype); -/* +/*%< * Return attributes for the given type. * * Requires: - * 'rdtype' are known. + *\li 'rdtype' are known. * * Returns: - * a bitmask consisting of the following flags. + *\li a bitmask consisting of the following flags. */ -/* only one may exist for a name */ +/*% only one may exist for a name */ #define DNS_RDATATYPEATTR_SINGLETON 0x00000001U -/* requires no other data be present */ +/*% requires no other data be present */ #define DNS_RDATATYPEATTR_EXCLUSIVE 0x00000002U -/* Is a meta type */ +/*% Is a meta type */ #define DNS_RDATATYPEATTR_META 0x00000004U -/* Is a DNSSEC type, like RRSIG or NSEC */ +/*% Is a DNSSEC type, like RRSIG or NSEC */ #define DNS_RDATATYPEATTR_DNSSEC 0x00000008U -/* Is a zone cut authority type */ +/*% Is a zone cut authority type */ #define DNS_RDATATYPEATTR_ZONECUTAUTH 0x00000010U -/* Is reserved (unusable) */ +/*% Is reserved (unusable) */ #define DNS_RDATATYPEATTR_RESERVED 0x00000020U -/* Is an unknown type */ +/*% Is an unknown type */ #define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U -/* Is META, and can only be in a question section */ +/*% Is META, and can only be in a question section */ #define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U -/* is META, and can NOT be in a question section */ +/*% is META, and can NOT be in a question section */ #define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U -/* Is present at zone cuts in the parent, not the child */ +/*% Is present at zone cuts in the parent, not the child */ #define DNS_RDATATYPEATTR_ATPARENT 0x00000200U dns_rdatatype_t dns_rdata_covers(dns_rdata_t *rdata); -/* +/*%< * Return the rdatatype that this type covers. * * Requires: - * 'rdata' is a valid, non-empty rdata. + *\li 'rdata' is a valid, non-empty rdata. * - * 'rdata' is a type that covers other rdata types. + *\li 'rdata' is a type that covers other rdata types. * * Returns: - * The type covered. + *\li The type covered. */ isc_boolean_t diff --git a/contrib/bind9/lib/dns/include/dns/rdataclass.h b/contrib/bind9/lib/dns/include/dns/rdataclass.h index 359a2be..fc622bf 100644 --- a/contrib/bind9/lib/dns/include/dns/rdataclass.h +++ b/contrib/bind9/lib/dns/include/dns/rdataclass.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataclass.h,v 1.17.206.1 2004/03/06 08:13:59 marka Exp $ */ +/* $Id: rdataclass.h,v 1.18.18.2 2005/04/29 00:16:18 marka Exp $ */ #ifndef DNS_RDATACLASS_H #define DNS_RDATACLASS_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,49 +30,49 @@ ISC_LANG_BEGINDECLS isc_result_t dns_rdataclass_fromtext(dns_rdataclass_t *classp, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a DNS class. * * Requires: - * 'classp' is a valid pointer. + *\li 'classp' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * DNS_R_UNKNOWN class is unknown + *\li #ISC_R_SUCCESS on success + *\li #DNS_R_UNKNOWN class is unknown */ isc_result_t dns_rdataclass_totext(dns_rdataclass_t rdclass, isc_buffer_t *target); -/* +/*%< * Put a textual representation of class 'rdclass' into 'target'. * * Requires: - * 'rdclass' is a valid class. + *\li 'rdclass' is a valid class. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * - * Ensures: - * If the result is success: - * The used space in 'target' is updated. + * Ensures, + * if the result is success: + *\li The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_NOSPACE target buffer is too small */ void dns_rdataclass_format(dns_rdataclass_t rdclass, char *array, unsigned int size); -/* +/*%< * Format a human-readable representation of the class 'rdclass' * into the character array 'array', which is of size 'size'. * The resulting string is guaranteed to be null-terminated. */ #define DNS_RDATACLASS_FORMATSIZE sizeof("CLASS65535") -/* +/*%< * Minimum size of array to pass to dns_rdataclass_format(). */ diff --git a/contrib/bind9/lib/dns/include/dns/rdatalist.h b/contrib/bind9/lib/dns/include/dns/rdatalist.h index a846c89..697386f 100644 --- a/contrib/bind9/lib/dns/include/dns/rdatalist.h +++ b/contrib/bind9/lib/dns/include/dns/rdatalist.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatalist.h,v 1.13.206.1 2004/03/06 08:13:59 marka Exp $ */ +/* $Id: rdatalist.h,v 1.14.18.2 2005/04/29 00:16:19 marka Exp $ */ #ifndef DNS_RDATALIST_H #define DNS_RDATALIST_H 1 @@ -24,32 +24,31 @@ ***** Module Info *****/ -/* - * DNS Rdatalist - * +/*! \file + * \brief * A DNS rdatalist is a list of rdata of a common type and class. * * MP: - * Clients of this module must impose any required synchronization. + *\li Clients of this module must impose any required synchronization. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ #include <isc/lang.h> #include <dns/types.h> -/* +/*% * Clients may use this type directly. */ struct dns_rdatalist { @@ -65,38 +64,38 @@ ISC_LANG_BEGINDECLS void dns_rdatalist_init(dns_rdatalist_t *rdatalist); -/* +/*%< * Initialize rdatalist. * * Ensures: - * All fields of rdatalist have been initialized to their default + *\li All fields of rdatalist have been initialized to their default * values. */ isc_result_t dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist, dns_rdataset_t *rdataset); -/* +/*%< * Make 'rdataset' refer to the rdata in 'rdatalist'. * * Note: - * The caller must ensure that 'rdatalist' remains valid and unchanged + *\li The caller must ensure that 'rdatalist' remains valid and unchanged * while 'rdataset' is associated with it. * * Requires: * - * 'rdatalist' is a valid rdatalist. + *\li 'rdatalist' is a valid rdatalist. * - * 'rdataset' is a valid rdataset that is not currently associated with + *\li 'rdataset' is a valid rdataset that is not currently associated with * any rdata. * - * Ensures: - * On success, + * Ensures, + * on success, * - * 'rdataset' is associated with the rdata in rdatalist. + *\li 'rdataset' is associated with the rdata in rdatalist. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rdataset.h b/contrib/bind9/lib/dns/include/dns/rdataset.h index 12cfbde..5597591 100644 --- a/contrib/bind9/lib/dns/include/dns/rdataset.h +++ b/contrib/bind9/lib/dns/include/dns/rdataset.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.h,v 1.41.2.5.2.10 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: rdataset.h,v 1.51.18.7 2006/03/03 00:56:53 marka Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 @@ -24,9 +24,8 @@ ***** Module Info *****/ -/* - * DNS Rdataset - * +/*! \file + * \brief * A DNS rdataset is a handle that can be associated with a collection of * rdata all having a common owner name, class, and type. * @@ -34,31 +33,38 @@ * rdatasets, an implementation of the method suite (e.g. "slabbed rdata") is * required. * - * XXX <more> XXX + * XXX <more> XXX * * MP: - * Clients of this module must impose any required synchronization. + *\li Clients of this module must impose any required synchronization. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ #include <isc/lang.h> #include <isc/magic.h> +#include <isc/stdtime.h> #include <dns/types.h> ISC_LANG_BEGINDECLS +typedef enum { + dns_rdatasetadditional_fromauth, + dns_rdatasetadditional_fromcache, + dns_rdatasetadditional_fromglue +} dns_rdatasetadditional_t; + typedef struct dns_rdatasetmethods { void (*disassociate)(dns_rdataset_t *rdataset); isc_result_t (*first)(dns_rdataset_t *rdataset); @@ -74,12 +80,36 @@ typedef struct dns_rdatasetmethods { dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig); + isc_result_t (*getadditional)(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t **zonep, + dns_db_t **dbp, + dns_dbversion_t **versionp, + dns_dbnode_t **nodep, + dns_name_t *fname, + dns_message_t *msg, + isc_stdtime_t now); + isc_result_t (*setadditional)(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t *zone, + dns_db_t *db, + dns_dbversion_t *version, + dns_dbnode_t *node, + dns_name_t *fname); + isc_result_t (*putadditional)(dns_acache_t *acache, + dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype); } dns_rdatasetmethods_t; #define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R') #define DNS_RDATASET_VALID(set) ISC_MAGIC_VALID(set, DNS_RDATASET_MAGIC) -/* +/*% * Direct use of this structure by clients is strongly discouraged, except * for the 'link' field which may be used however the client wishes. The * 'private', 'current', and 'index' fields MUST NOT be changed by clients. @@ -103,14 +133,15 @@ struct dns_rdataset { * attributes */ unsigned int attributes; - /* + /*% * the counter provides the starting point in the "cyclic" order. * The value ISC_UINT32_MAX has a special meaning of "picking up a * random value." in order to take care of databases that do not * increment the counter. */ isc_uint32_t count; - /* + /*@{*/ + /*% * These are for use by the rdataset implementation, and MUST NOT * be changed by clients. */ @@ -120,35 +151,41 @@ struct dns_rdataset { unsigned int privateuint4; void * private5; void * private6; + /*@}*/ }; -/* - * _RENDERED: +/*! + * \def DNS_RDATASETATTR_RENDERED * Used by message.c to indicate that the rdataset was rendered. * - * _TTLADJUSTED: + * \def DNS_RDATASETATTR_TTLADJUSTED * Used by message.c to indicate that the rdataset's rdata had differing * TTL values, and the rdataset->ttl holds the smallest. + * + * \def DNS_RDATASETATTR_LOADORDER + * Output the RRset in load order. */ + #define DNS_RDATASETATTR_QUESTION 0x00000001 -#define DNS_RDATASETATTR_RENDERED 0x00000002 /* Used by message.c */ -#define DNS_RDATASETATTR_ANSWERED 0x00000004 /* Used by server. */ -#define DNS_RDATASETATTR_CACHE 0x00000008 /* Used by resolver. */ -#define DNS_RDATASETATTR_ANSWER 0x00000010 /* Used by resolver. */ -#define DNS_RDATASETATTR_ANSWERSIG 0x00000020 /* Used by resolver. */ -#define DNS_RDATASETATTR_EXTERNAL 0x00000040 /* Used by resolver. */ -#define DNS_RDATASETATTR_NCACHE 0x00000080 /* Used by resolver. */ -#define DNS_RDATASETATTR_CHAINING 0x00000100 /* Used by resolver. */ -#define DNS_RDATASETATTR_TTLADJUSTED 0x00000200 /* Used by message.c */ +#define DNS_RDATASETATTR_RENDERED 0x00000002 /*%< Used by message.c */ +#define DNS_RDATASETATTR_ANSWERED 0x00000004 /*%< Used by server. */ +#define DNS_RDATASETATTR_CACHE 0x00000008 /*%< Used by resolver. */ +#define DNS_RDATASETATTR_ANSWER 0x00000010 /*%< Used by resolver. */ +#define DNS_RDATASETATTR_ANSWERSIG 0x00000020 /*%< Used by resolver. */ +#define DNS_RDATASETATTR_EXTERNAL 0x00000040 /*%< Used by resolver. */ +#define DNS_RDATASETATTR_NCACHE 0x00000080 /*%< Used by resolver. */ +#define DNS_RDATASETATTR_CHAINING 0x00000100 /*%< Used by resolver. */ +#define DNS_RDATASETATTR_TTLADJUSTED 0x00000200 /*%< Used by message.c */ #define DNS_RDATASETATTR_FIXEDORDER 0x00000400 #define DNS_RDATASETATTR_RANDOMIZE 0x00000800 -#define DNS_RDATASETATTR_CHASE 0x00001000 /* Used by resolver. */ +#define DNS_RDATASETATTR_CHASE 0x00001000 /*%< Used by resolver. */ #define DNS_RDATASETATTR_NXDOMAIN 0x00002000 #define DNS_RDATASETATTR_NOQNAME 0x00004000 -#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /* Used by resolver. */ +#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */ #define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000 +#define DNS_RDATASETATTR_LOADORDER 0x00020000 -/* +/*% * _OMITDNSSEC: * Omit DNSSEC records when rendering ncache records. */ @@ -156,147 +193,147 @@ struct dns_rdataset { void dns_rdataset_init(dns_rdataset_t *rdataset); -/* +/*%< * Make 'rdataset' a valid, disassociated rdataset. * * Requires: - * 'rdataset' is not NULL. + *\li 'rdataset' is not NULL. * * Ensures: - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. */ void dns_rdataset_invalidate(dns_rdataset_t *rdataset); -/* +/*%< * Invalidate 'rdataset'. * * Requires: - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * * Ensures: - * If assertion checking is enabled, future attempts to use 'rdataset' + *\li If assertion checking is enabled, future attempts to use 'rdataset' * without initializing it will cause an assertion failure. */ void dns_rdataset_disassociate(dns_rdataset_t *rdataset); -/* +/*%< * Disassociate 'rdataset' from its rdata, allowing it to be reused. * * Notes: - * The client must ensure it has no references to rdata in the rdataset + *\li The client must ensure it has no references to rdata in the rdataset * before disassociating. * * Requires: - * 'rdataset' is a valid, associated rdataset. + *\li 'rdataset' is a valid, associated rdataset. * * Ensures: - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. */ isc_boolean_t dns_rdataset_isassociated(dns_rdataset_t *rdataset); -/* +/*%< * Is 'rdataset' associated? * * Requires: - * 'rdataset' is a valid rdataset. + *\li 'rdataset' is a valid rdataset. * * Returns: - * ISC_TRUE 'rdataset' is associated. - * ISC_FALSE 'rdataset' is not associated. + *\li #ISC_TRUE 'rdataset' is associated. + *\li #ISC_FALSE 'rdataset' is not associated. */ void dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass, dns_rdatatype_t type); -/* +/*%< * Make 'rdataset' a valid, associated, question rdataset, with a * question class of 'rdclass' and type 'type'. * * Notes: - * Question rdatasets have a class and type, but no rdata. + *\li Question rdatasets have a class and type, but no rdata. * * Requires: - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * * Ensures: - * 'rdataset' is a valid, associated, question rdataset. + *\li 'rdataset' is a valid, associated, question rdataset. */ void dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target); -/* +/*%< * Make 'target' refer to the same rdataset as 'source'. * * Requires: - * 'source' is a valid, associated rdataset. + *\li 'source' is a valid, associated rdataset. * - * 'target' is a valid, dissociated rdataset. + *\li 'target' is a valid, dissociated rdataset. * * Ensures: - * 'target' references the same rdataset as 'source'. + *\li 'target' references the same rdataset as 'source'. */ unsigned int dns_rdataset_count(dns_rdataset_t *rdataset); -/* +/*%< * Return the number of records in 'rdataset'. * * Requires: - * 'rdataset' is a valid, associated rdataset. + *\li 'rdataset' is a valid, associated rdataset. * * Returns: - * The number of records in 'rdataset'. + *\li The number of records in 'rdataset'. */ isc_result_t dns_rdataset_first(dns_rdataset_t *rdataset); -/* +/*%< * Move the rdata cursor to the first rdata in the rdataset (if any). * * Requires: - * 'rdataset' is a valid, associated rdataset. + *\li 'rdataset' is a valid, associated rdataset. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no rdata in the set. + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no rdata in the set. */ isc_result_t dns_rdataset_next(dns_rdataset_t *rdataset); -/* +/*%< * Move the rdata cursor to the next rdata in the rdataset (if any). * * Requires: - * 'rdataset' is a valid, associated rdataset. + *\li 'rdataset' is a valid, associated rdataset. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no more rdata in the set. + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no more rdata in the set. */ void dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata); -/* +/*%< * Make 'rdata' refer to the current rdata. * * Notes: * - * The data returned in 'rdata' is valid for the life of the + *\li The data returned in 'rdata' is valid for the life of the * rdataset; in particular, subsequent changes in the cursor position * do not invalidate 'rdata'. * * Requires: - * 'rdataset' is a valid, associated rdataset. + *\li 'rdataset' is a valid, associated rdataset. * - * The rdata cursor of 'rdataset' is at a valid location (i.e. the + *\li The rdata cursor of 'rdataset' is at a valid location (i.e. the * result of last call to a cursor movement command was ISC_R_SUCCESS). * * Ensures: - * 'rdata' refers to the rdata at the rdata cursor location of - * 'rdataset'. + *\li 'rdata' refers to the rdata at the rdata cursor location of + *\li 'rdataset'. */ isc_result_t @@ -305,23 +342,23 @@ dns_rdataset_totext(dns_rdataset_t *rdataset, isc_boolean_t omit_final_dot, isc_boolean_t question, isc_buffer_t *target); -/* +/*%< * Convert 'rdataset' to text format, storing the result in 'target'. * * Notes: - * The rdata cursor position will be changed. + *\li The rdata cursor position will be changed. * - * The 'question' flag should normally be ISC_FALSE. If it is - * ISC_TRUE, the TTL and rdata fields are not printed. This is + *\li The 'question' flag should normally be #ISC_FALSE. If it is + * #ISC_TRUE, the TTL and rdata fields are not printed. This is * for use when printing an rdata representing a question section. * - * This interface is deprecated; use dns_master_rdatasettottext() + *\li This interface is deprecated; use dns_master_rdatasettottext() * and/or dns_master_questiontotext() instead. * * Requires: - * 'rdataset' is a valid rdataset. + *\li 'rdataset' is a valid rdataset. * - * 'rdataset' is not empty. + *\li 'rdataset' is not empty. */ isc_result_t @@ -331,35 +368,35 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, isc_buffer_t *target, unsigned int options, unsigned int *countp); -/* +/*%< * Convert 'rdataset' to wire format, compressing names as specified * in 'cctx', and storing the result in 'target'. * * Notes: - * The rdata cursor position will be changed. + *\li The rdata cursor position will be changed. * - * The number of RRs added to target will be added to *countp. + *\li The number of RRs added to target will be added to *countp. * * Requires: - * 'rdataset' is a valid rdataset. + *\li 'rdataset' is a valid rdataset. * - * 'rdataset' is not empty. + *\li 'rdataset' is not empty. * - * 'countp' is a valid pointer. + *\li 'countp' is a valid pointer. * * Ensures: - * On a return of ISC_R_SUCCESS, 'target' contains a wire format + *\li On a return of ISC_R_SUCCESS, 'target' contains a wire format * for the data contained in 'rdataset'. Any error return leaves * the buffer unchanged. * - * *countp has been incremented by the number of RRs added to + *\li *countp has been incremented by the number of RRs added to * target. * * Returns: - * ISC_R_SUCCESS - all ok - * ISC_R_NOSPACE - 'target' doesn't have enough room + *\li #ISC_R_SUCCESS - all ok + *\li #ISC_R_NOSPACE - 'target' doesn't have enough room * - * Any error returned by dns_rdata_towire(), dns_rdataset_next(), + *\li Any error returned by dns_rdata_towire(), dns_rdataset_next(), * dns_name_towire(). */ @@ -372,13 +409,13 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset, const void *order_arg, unsigned int options, unsigned int *countp); -/* +/*%< * Like dns_rdataset_towire(), but sorting the rdatasets according to * the integer value returned by 'order' when called witih the rdataset * and 'order_arg' as arguments. * * Requires: - * All the requirements of dns_rdataset_towire(), and + *\li All the requirements of dns_rdataset_towire(), and * that order_arg is NULL if and only if order is NULL. */ @@ -392,76 +429,167 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset, unsigned int options, unsigned int *countp, void **state); -/* +/*%< * Like dns_rdataset_towiresorted() except that a partial rdataset * may be written. * * Requires: - * All the requirements of dns_rdataset_towiresorted(). + *\li All the requirements of dns_rdataset_towiresorted(). * If 'state' is non NULL then the current position in the * rdataset will be remembered if the rdataset in not * completely written and should be passed on on subsequent * calls (NOT CURRENTLY IMPLEMENTED). * * Returns: - * ISC_R_SUCCESS if all of the records were written. - * ISC_R_NOSPACE if unable to fit in all of the records. *countp + *\li #ISC_R_SUCCESS if all of the records were written. + *\li #ISC_R_NOSPACE if unable to fit in all of the records. *countp * will be updated to reflect the number of records * written. */ - isc_result_t dns_rdataset_additionaldata(dns_rdataset_t *rdataset, dns_additionaldatafunc_t add, void *arg); -/* +/*%< * For each rdata in rdataset, call 'add' for each name and type in the * rdata which is subject to additional section processing. * * Requires: * - * 'rdataset' is a valid, non-question rdataset. + *\li 'rdataset' is a valid, non-question rdataset. * - * 'add' is a valid dns_additionaldatafunc_t + *\li 'add' is a valid dns_additionaldatafunc_t * * Ensures: * - * If successful, dns_rdata_additionaldata() will have been called for + *\li If successful, dns_rdata_additionaldata() will have been called for * each rdata in 'rdataset'. * - * If a call to dns_rdata_additionaldata() is not successful, the + *\li If a call to dns_rdata_additionaldata() is not successful, the * result returned will be the result of dns_rdataset_additionaldata(). * * Returns: * - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS * - * Any error that dns_rdata_additionaldata() can return. + *\li Any error that dns_rdata_additionaldata() can return. */ isc_result_t dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig); -/* +/*%< * Return the noqname proof for this record. * * Requires: - * 'rdataset' to be valid and DNS_RDATASETATTR_NOQNAME to be set. - * 'name' to be valid. - * 'nsec' and 'nsecsig' to be valid and not associated. + *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set. + *\li 'name' to be valid. + *\li 'nsec' and 'nsecsig' to be valid and not associated. */ isc_result_t dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name); -/* +/*%< * Associate a noqname proof with this record. - * Sets DNS_RDATASETATTR_NOQNAME if successful. + * Sets #DNS_RDATASETATTR_NOQNAME if successful. * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and * the 'nsec' and 'rrsig(nsec)' ttl. * * Requires: - * 'rdataset' to be valid and DNS_RDATASETATTR_NOQNAME to be set. - * 'name' to be valid and have NSEC and RRSIG(NSEC) rdatasets. + *\li 'rdataset' to be valid and #DNS_RDATASETATTR_NOQNAME to be set. + *\li 'name' to be valid and have NSEC and RRSIG(NSEC) rdatasets. + */ + +isc_result_t +dns_rdataset_getadditional(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t **zonep, + dns_db_t **dbp, + dns_dbversion_t **versionp, + dns_dbnode_t **nodep, + dns_name_t *fname, + dns_message_t *msg, + isc_stdtime_t now); +/*%< + * Get cached additional information from the DB node for a particular + * 'rdataset.' 'type' is one of dns_rdatasetadditional_fromauth, + * dns_rdatasetadditional_fromcache, and dns_rdatasetadditional_fromglue, + * which specifies the origin of the information. 'qtype' is intended to + * be used for specifying a particular rdata type in the cached information. + * + * Requires: + * \li 'rdataset' is a valid rdataset. + * \li 'acache' can be NULL, in which case this function will simply return + * ISC_R_FAILURE. + * \li For the other pointers, see dns_acache_getentry(). + * + * Ensures: + * \li See dns_acache_getentry(). + * + * Returns: + * \li #ISC_R_SUCCESS + * \li #ISC_R_FAILURE - additional information caching is not supported. + * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional + * information for 'rdataset.' + * \li Any error that dns_acache_getentry() can return. + */ + +isc_result_t +dns_rdataset_setadditional(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t *zone, + dns_db_t *db, + dns_dbversion_t *version, + dns_dbnode_t *node, + dns_name_t *fname); +/*%< + * Set cached additional information to the DB node for a particular + * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type' + * and 'qtype'. + * + * Requires: + * \li 'rdataset' is a valid rdataset. + * \li 'acache' can be NULL, in which case this function will simply return + * ISC_R_FAILURE. + * \li For the other pointers, see dns_acache_setentry(). + * + * Ensures: + * \li See dns_acache_setentry(). + * + * Returns: + * \li #ISC_R_SUCCESS + * \li #ISC_R_FAILURE - additional information caching is not supported. + * \li #ISC_R_NOMEMORY + * \li Any error that dns_acache_setentry() can return. + */ + +isc_result_t +dns_rdataset_putadditional(dns_acache_t *acache, + dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype); +/*%< + * Discard cached additional information stored in the DB node for a particular + * 'rdataset.' See dns_rdataset_getadditional for the semantics of 'type' + * and 'qtype'. + * + * Requires: + * \li 'rdataset' is a valid rdataset. + * \li 'acache' can be NULL, in which case this function will simply return + * ISC_R_FAILURE. + * + * Ensures: + * \li See dns_acache_cancelentry(). + * + * Returns: + * \li #ISC_R_SUCCESS + * \li #ISC_R_FAILURE - additional information caching is not supported. + * \li #ISC_R_NOTFOUND - the corresponding DB node has not cached additional + * information for 'rdataset.' */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rdatasetiter.h b/contrib/bind9/lib/dns/include/dns/rdatasetiter.h index 198aebb..b2e13f8 100644 --- a/contrib/bind9/lib/dns/include/dns/rdatasetiter.h +++ b/contrib/bind9/lib/dns/include/dns/rdatasetiter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatasetiter.h,v 1.14.206.1 2004/03/06 08:13:59 marka Exp $ */ +/* $Id: rdatasetiter.h,v 1.15.18.2 2005/04/29 00:16:19 marka Exp $ */ #ifndef DNS_RDATASETITER_H #define DNS_RDATASETITER_H 1 @@ -24,9 +24,8 @@ ***** Module Info *****/ -/* - * DNS Rdataset Iterator - * +/*! \file + * \brief * The DNS Rdataset Iterator interface allows iteration of all of the * rdatasets at a node. * @@ -37,25 +36,25 @@ * It is the client's responsibility to call dns_rdataset_disassociate() * on all rdatasets returned. * - * XXX <more> XXX + * XXX more XXX * * MP: - * The iterator itself is not locked. The caller must ensure + *\li The iterator itself is not locked. The caller must ensure * synchronization. * - * The iterator methods ensure appropriate database locking. + *\li The iterator methods ensure appropriate database locking. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ /***** @@ -85,12 +84,12 @@ typedef struct dns_rdatasetitermethods { #define DNS_RDATASETITER_MAGIC ISC_MAGIC('D','N','S','i') #define DNS_RDATASETITER_VALID(i) ISC_MAGIC_VALID(i, DNS_RDATASETITER_MAGIC) -/* +/*% * This structure is actually just the common prefix of a DNS db * implementation's version of a dns_rdatasetiter_t. - * + * \brief * Direct use of this structure by clients is forbidden. DB implementations - * may change the structure. 'magic' must be DNS_RDATASETITER_MAGIC for + * may change the structure. 'magic' must be #DNS_RDATASETITER_MAGIC for * any of the dns_rdatasetiter routines to work. DB implementations must * maintain all DB rdataset iterator invariants. */ @@ -106,64 +105,64 @@ struct dns_rdatasetiter { void dns_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); -/* +/*%< * Destroy '*iteratorp'. * * Requires: * - * '*iteratorp' is a valid iterator. + *\li '*iteratorp' is a valid iterator. * * Ensures: * - * All resources used by the iterator are freed. + *\li All resources used by the iterator are freed. * - * *iteratorp == NULL. + *\li *iteratorp == NULL. */ isc_result_t dns_rdatasetiter_first(dns_rdatasetiter_t *iterator); -/* +/*%< * Move the rdataset cursor to the first rdataset at the node (if any). * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no rdatasets at the node. + *\li ISC_R_SUCCESS + *\li ISC_R_NOMORE There are no rdatasets at the node. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ isc_result_t dns_rdatasetiter_next(dns_rdatasetiter_t *iterator); -/* +/*%< * Move the rdataset cursor to the next rdataset at the node (if any). * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE There are no more rdatasets at the + *\li ISC_R_SUCCESS + *\li ISC_R_NOMORE There are no more rdatasets at the * node. * - * Other results are possible, depending on the DB implementation. + *\li Other results are possible, depending on the DB implementation. */ void dns_rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset); -/* +/*%< * Return the current rdataset. * * Requires: - * 'iterator' is a valid iterator. + *\li 'iterator' is a valid iterator. * - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * - * The rdataset cursor of 'iterator' is at a valid location (i.e. the - * result of last call to a cursor movement command was ISC_R_SUCCESS). + *\li The rdataset cursor of 'iterator' is at a valid location (i.e. the + * result of last call to a cursor movement command was #ISC_R_SUCCESS). */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rdataslab.h b/contrib/bind9/lib/dns/include/dns/rdataslab.h index a0912db..b693a71 100644 --- a/contrib/bind9/lib/dns/include/dns/rdataslab.h +++ b/contrib/bind9/lib/dns/include/dns/rdataslab.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,34 +15,33 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.h,v 1.20.2.2.2.4 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: rdataslab.h,v 1.25.18.2 2005/04/29 00:16:19 marka Exp $ */ #ifndef DNS_RDATASLAB_H #define DNS_RDATASLAB_H 1 -/* - * DNS Rdata Slab - * +/*! \file + * \brief * Implements storage of rdatasets into slabs of memory. * * MP: - * Clients of this module must impose any required synchronization. + *\li Clients of this module must impose any required synchronization. * * Reliability: - * This module deals with low-level byte streams. Errors in any of + *\li This module deals with low-level byte streams. Errors in any of * the functions are likely to crash the server or corrupt memory. * - * If the caller passes invalid memory references, these functions are + *\li If the caller passes invalid memory references, these functions are * likely to crash the server or corrupt memory. * * Resources: - * None. + *\li None. * * Security: - * None. + *\li None. * * Standards: - * None. + *\li None. */ /*** @@ -65,22 +64,22 @@ ISC_LANG_BEGINDECLS isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, unsigned int reservelen); -/* +/*%< * Slabify a rdataset. The slab area will be allocated and returned * in 'region'. * * Requires: - * 'rdataset' is valid. + *\li 'rdataset' is valid. * * Ensures: - * 'region' will have base pointing to the start of allocated memory, + *\li 'region' will have base pointing to the start of allocated memory, * with the slabified region beginning at region->base + reservelen. * region->length contains the total length allocated. * * Returns: - * ISC_R_SUCCESS - successful completion - * ISC_R_NOMEMORY - no memory. - * <XXX others> + *\li ISC_R_SUCCESS - successful completion + *\li ISC_R_NOMEMORY - no memory. + *\li XXX others */ void @@ -88,27 +87,26 @@ dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, dns_rdatatype_t covers, dns_ttl_t ttl, dns_rdataset_t *rdataset); -/* +/*%< * Construct an rdataset from a slab. * * Requires: - * 'slab' points to a slab. - * 'rdataset' is disassociated. + *\li 'slab' points to a slab. + *\li 'rdataset' is disassociated. * * Ensures: - * 'rdataset' is associated and points to a valid rdataest. + *\li 'rdataset' is associated and points to a valid rdataest. */ - unsigned int dns_rdataslab_size(unsigned char *slab, unsigned int reservelen); -/* +/*%< * Return the total size of an rdataslab. * * Requires: - * 'slab' points to a slab. + *\li 'slab' points to a slab. * * Returns: - * The number of bytes in the slab, including the reservelen. + *\li The number of bytes in the slab, including the reservelen. */ isc_result_t @@ -116,7 +114,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, unsigned int reservelen, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp); -/* +/*%< * Merge 'oslab' and 'nslab'. */ @@ -125,7 +123,7 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, unsigned int reservelen, isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rdatatype_t type, unsigned int flags, unsigned char **tslabp); -/* +/*%< * Subtract 'sslab' from 'mslab'. If 'exact' is true then all elements * of 'sslab' must exist in 'mslab'. * @@ -136,30 +134,28 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, isc_boolean_t dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, unsigned int reservelen); - -/* +/*%< * Compare two rdataslabs for equality. This does _not_ do a full * DNSSEC comparison. * * Requires: - * 'slab1' and 'slab2' point to slabs. + *\li 'slab1' and 'slab2' point to slabs. * * Returns: - * ISC_TRUE if the slabs are equal, ISC_FALSE otherwise. + *\li ISC_TRUE if the slabs are equal, ISC_FALSE otherwise. */ - isc_boolean_t dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, unsigned int reservelen, dns_rdataclass_t rdclass, dns_rdatatype_t type); -/* +/*%< * Compare two rdataslabs for DNSSEC equality. * * Requires: - * 'slab1' and 'slab2' point to slabs. + *\li 'slab1' and 'slab2' point to slabs. * * Returns: - * ISC_TRUE if the slabs are equal, ISC_FALSE otherwise. + *\li ISC_TRUE if the slabs are equal, #ISC_FALSE otherwise. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/rdatatype.h b/contrib/bind9/lib/dns/include/dns/rdatatype.h index 0fa865d..40a884d 100644 --- a/contrib/bind9/lib/dns/include/dns/rdatatype.h +++ b/contrib/bind9/lib/dns/include/dns/rdatatype.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatatype.h,v 1.17.206.1 2004/03/06 08:13:59 marka Exp $ */ +/* $Id: rdatatype.h,v 1.18.18.2 2005/04/29 00:16:20 marka Exp $ */ #ifndef DNS_RDATATYPE_H #define DNS_RDATATYPE_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,49 +30,49 @@ ISC_LANG_BEGINDECLS isc_result_t dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a DNS rdata type. * * Requires: - * 'typep' is a valid pointer. + *\li 'typep' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * DNS_R_UNKNOWN type is unknown + *\li ISC_R_SUCCESS on success + *\li DNS_R_UNKNOWN type is unknown */ isc_result_t dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target); -/* +/*%< * Put a textual representation of type 'type' into 'target'. * * Requires: - * 'type' is a valid type. + *\li 'type' is a valid type. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * - * Ensures: - * If the result is success: - * The used space in 'target' is updated. + * Ensures, + * if the result is success: + *\li The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li #ISC_R_SUCCESS on success + *\li #ISC_R_NOSPACE target buffer is too small */ void dns_rdatatype_format(dns_rdatatype_t rdtype, char *array, unsigned int size); -/* +/*%< * Format a human-readable representation of the type 'rdtype' * into the character array 'array', which is of size 'size'. * The resulting string is guaranteed to be null-terminated. */ #define DNS_RDATATYPE_FORMATSIZE sizeof("TYPE65535") -/* +/*%< * Minimum size of array to pass to dns_rdatatype_format(). * May need to be adjusted if a new RR type with a very long * name is defined. diff --git a/contrib/bind9/lib/dns/include/dns/request.h b/contrib/bind9/lib/dns/include/dns/request.h index b3e7bcd..b858a9e 100644 --- a/contrib/bind9/lib/dns/include/dns/request.h +++ b/contrib/bind9/lib/dns/include/dns/request.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.h,v 1.17.12.5 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: request.h,v 1.21.18.2 2005/04/29 00:16:20 marka Exp $ */ #ifndef DNS_REQUEST_H #define DNS_REQUEST_H 1 @@ -24,21 +24,21 @@ ***** Module Info *****/ -/* - * DNS Request +/*! \file * + * \brief * The request module provides simple request/response services useful for * sending SOA queries, DNS Notify messages, and dynamic update requests. * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. */ #include <isc/lang.h> @@ -62,102 +62,101 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6, dns_requestmgr_t **requestmgrp); -/* +/*%< * Create a request manager. * * Requires: * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. * - * 'timermgr' is a valid timer manager. + *\li 'timermgr' is a valid timer manager. * - * 'socketmgr' is a valid socket manager. + *\li 'socketmgr' is a valid socket manager. * - * 'taskmgr' is a valid task manager. + *\li 'taskmgr' is a valid task manager. * - * 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. + *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. * - * 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. + *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. * - * requestmgrp != NULL && *requestmgrp == NULL + *\li requestmgrp != NULL && *requestmgrp == NULL * * Ensures: * - * On success, *requestmgrp is a valid request manager. + *\li On success, *requestmgrp is a valid request manager. * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Any other result indicates failure. + *\li Any other result indicates failure. */ void dns_requestmgr_whenshutdown(dns_requestmgr_t *requestmgr, isc_task_t *task, isc_event_t **eventp); -/* +/*%< * Send '*eventp' to 'task' when 'requestmgr' has completed shutdown. * * Notes: * - * It is not safe to detach the last reference to 'requestmgr' until + *\li It is not safe to detach the last reference to 'requestmgr' until * shutdown is complete. * * Requires: * - * 'requestmgr' is a valid request manager. + *\li 'requestmgr' is a valid request manager. * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * *eventp is a valid event. + *\li *eventp is a valid event. * * Ensures: * - * *eventp == NULL. + *\li *eventp == NULL. */ void dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr); -/* +/*%< * Start the shutdown process for 'requestmgr'. * * Notes: * - * This call has no effect if the request manager is already shutting + *\li This call has no effect if the request manager is already shutting * down. * * Requires: * - * 'requestmgr' is a valid requestmgr. + *\li 'requestmgr' is a valid requestmgr. */ void dns_requestmgr_attach(dns_requestmgr_t *source, dns_requestmgr_t **targetp); -/* +/*%< * Attach to the request manager. dns_requestmgr_shutdown() must not * have been called on 'source' prior to calling dns_requestmgr_attach(). * * Requires: * - * 'source' is a valid requestmgr. + *\li 'source' is a valid requestmgr. * - * 'targetp' to be non NULL and '*targetp' to be NULL. + *\li 'targetp' to be non NULL and '*targetp' to be NULL. */ void dns_requestmgr_detach(dns_requestmgr_t **requestmgrp); -/* - * +/*%< * Detach from the given requestmgr. If this is the final detach * requestmgr will be destroyed. dns_requestmgr_shutdown() must * be called before the final detach. * * Requires: * - * '*requestmgrp' is a valid requestmgr. + *\li '*requestmgrp' is a valid requestmgr. * * Ensures: - * '*requestmgrp' is NULL. + *\li '*requestmgrp' is NULL. */ isc_result_t @@ -167,31 +166,32 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, unsigned int timeout, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); -/* +/*%< * Create and send a request. * * Notes: * - * 'message' will be rendered and sent to 'address'. If the - * DNS_REQUESTOPT_TCP option is set, TCP will be used. The request + *\li 'message' will be rendered and sent to 'address'. If the + * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request * will timeout after 'timeout' seconds. * - * When the request completes, successfully, due to a timeout, or + *\li When the request completes, successfully, due to a timeout, or * because it was canceled, a completion event will be sent to 'task'. * * Requires: * - * 'message' is a valid DNS message. + *\li 'message' is a valid DNS message. * - * 'address' is a valid sockaddr. + *\li 'address' is a valid sockaddr. * - * 'timeout' > 0 + *\li 'timeout' > 0 * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * requestp != NULL && *requestp == NULL + *\li requestp != NULL && *requestp == NULL */ +/*% See dns_request_createvia3() */ isc_result_t dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, @@ -200,6 +200,7 @@ dns_request_createvia(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_taskaction_t action, void *arg, dns_request_t **requestp); +/*% See dns_request_createvia3() */ isc_result_t dns_request_createvia2(dns_requestmgr_t *requestmgr, dns_message_t *message, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, @@ -216,36 +217,37 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); -/* +/*%< * Create and send a request. * * Notes: * - * 'message' will be rendered and sent to 'address'. If the - * DNS_REQUESTOPT_TCP option is set, TCP will be used. The request + *\li 'message' will be rendered and sent to 'address'. If the + * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request * will timeout after 'timeout' seconds. UDP requests will be resent * at 'udptimeout' intervals if non-zero or 'udpretries' is non-zero. * - * When the request completes, successfully, due to a timeout, or + *\li When the request completes, successfully, due to a timeout, or * because it was canceled, a completion event will be sent to 'task'. * * Requires: * - * 'message' is a valid DNS message. + *\li 'message' is a valid DNS message. * - * 'dstaddr' is a valid sockaddr. + *\li 'dstaddr' is a valid sockaddr. * - * 'srcaddr' is a valid sockaddr or NULL. + *\li 'srcaddr' is a valid sockaddr or NULL. * - * 'srcaddr' and 'dstaddr' are the same protocol family. + *\li 'srcaddr' and 'dstaddr' are the same protocol family. * - * 'timeout' > 0 + *\li 'timeout' > 0 * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * requestp != NULL && *requestp == NULL + *\li requestp != NULL && *requestp == NULL */ +/*% See dns_request_createraw3() */ isc_result_t dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, @@ -253,6 +255,7 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); +/*% See dns_request_createraw3() */ isc_result_t dns_request_createraw2(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, @@ -268,55 +271,55 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, unsigned int udptimeout, unsigned int udpretries, isc_task_t *task, isc_taskaction_t action, void *arg, dns_request_t **requestp); -/* - * Create and send a request. +/*!< + * \brief Create and send a request. * * Notes: * - * 'msgbuf' will be sent to 'destaddr' after setting the id. If the - * DNS_REQUESTOPT_TCP option is set, TCP will be used. The request + *\li 'msgbuf' will be sent to 'destaddr' after setting the id. If the + * #DNS_REQUESTOPT_TCP option is set, TCP will be used. The request * will timeout after 'timeout' seconds. UDP requests will be resent * at 'udptimeout' intervals if non-zero or if 'udpretries' is not zero. * - * When the request completes, successfully, due to a timeout, or + *\li When the request completes, successfully, due to a timeout, or * because it was canceled, a completion event will be sent to 'task'. * * Requires: * - * 'msgbuf' is a valid DNS message in compressed wire format. + *\li 'msgbuf' is a valid DNS message in compressed wire format. * - * 'destaddr' is a valid sockaddr. + *\li 'destaddr' is a valid sockaddr. * - * 'srcaddr' is a valid sockaddr or NULL. + *\li 'srcaddr' is a valid sockaddr or NULL. * - * 'srcaddr' and 'dstaddr' are the same protocol family. + *\li 'srcaddr' and 'dstaddr' are the same protocol family. * - * 'timeout' > 0 + *\li 'timeout' > 0 * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * requestp != NULL && *requestp == NULL + *\li requestp != NULL && *requestp == NULL */ void dns_request_cancel(dns_request_t *request); -/* +/*%< * Cancel 'request'. * * Requires: * - * 'request' is a valid request. + *\li 'request' is a valid request. * * Ensures: * - * If the completion event for 'request' has not yet been sent, it + *\li If the completion event for 'request' has not yet been sent, it * will be sent, and the result code will be ISC_R_CANCELED. */ isc_result_t dns_request_getresponse(dns_request_t *request, dns_message_t *message, unsigned int options); -/* +/*%< * Get the response to 'request' by filling in 'message'. * * 'options' is passed to dns_message_parse(). See dns_message_parse() @@ -324,46 +327,46 @@ dns_request_getresponse(dns_request_t *request, dns_message_t *message, * * Requires: * - * 'request' is a valid request for which the caller has received the + *\li 'request' is a valid request for which the caller has received the * completion event. * - * The result code of the completion event was ISC_R_SUCCESS. + *\li The result code of the completion event was #ISC_R_SUCCESS. * * Returns: * - * ISC_R_SUCCESS + *\li ISC_R_SUCCESS * - * Any result that dns_message_parse() can return. + *\li Any result that dns_message_parse() can return. */ isc_boolean_t dns_request_usedtcp(dns_request_t *request); -/* - * Return whether this query used TCP or not. Setting DNS_REQUESTOPT_TCP +/*%< + * Return whether this query used TCP or not. Setting #DNS_REQUESTOPT_TCP * in the call to dns_request_create() will cause the function to return - * ISC_TRUE, othewise the result is based on the query message size. + * #ISC_TRUE, othewise the result is based on the query message size. * * Requires: - * 'request' is a valid request. + *\li 'request' is a valid request. * * Returns: - * ISC_TRUE if TCP was used. - * ISC_FALSE if UDP was used. + *\li ISC_TRUE if TCP was used. + *\li ISC_FALSE if UDP was used. */ void dns_request_destroy(dns_request_t **requestp); -/* +/*%< * Destroy 'request'. * * Requires: * - * 'request' is a valid request for which the caller has received the + *\li 'request' is a valid request for which the caller has received the * completion event. * * Ensures: * - * *requestp == NULL + *\li *requestp == NULL */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/resolver.h b/contrib/bind9/lib/dns/include/dns/resolver.h index 8e3e632..4e0e6a0 100644 --- a/contrib/bind9/lib/dns/include/dns/resolver.h +++ b/contrib/bind9/lib/dns/include/dns/resolver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.34.12.9 2006/02/01 23:48:51 marka Exp $ */ +/* $Id: resolver.h,v 1.40.18.11 2006/02/01 22:39:17 marka Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -24,9 +24,9 @@ ***** Module Info *****/ -/* - * DNS Resolver +/*! \file * + * \brief * This is the BIND 9 resolver, the module responsible for resolving DNS * requests by iteratively querying authoritative servers and following * referrals. This is a "full resolver", not to be confused with @@ -35,21 +35,21 @@ * daemon the stub resolver talks to. * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * RFCs: 1034, 1035, 2181, <TBS> - * Drafts: <TBS> + *\li RFCs: 1034, 1035, 2181, TBS + *\li Drafts: TBS */ #include <isc/lang.h> @@ -60,14 +60,14 @@ ISC_LANG_BEGINDECLS -/* +/*% * A dns_fetchevent_t is sent when a 'fetch' completes. Any of 'db', * 'node', 'rdataset', and 'sigrdataset' may be bound. It is the * receiver's responsibility to detach before freeing the event. - * - * 'rdataset' and 'sigrdataset' are the values that were supplied when - * dns_resolver_createfetch() was called. They are returned to the - * caller so that they may be freed. + * \brief + * 'rdataset', 'sigrdataset', 'client' and 'id' are the values that were + * supplied when dns_resolver_createfetch() was called. They are returned + * to the caller so that they may be freed. */ typedef struct dns_fetchevent { ISC_EVENT_COMMON(struct dns_fetchevent); @@ -79,17 +79,25 @@ typedef struct dns_fetchevent { dns_rdataset_t * rdataset; dns_rdataset_t * sigrdataset; dns_fixedname_t foundname; + isc_sockaddr_t * client; + dns_messageid_t id; } dns_fetchevent_t; /* * Options that modify how a 'fetch' is done. */ -#define DNS_FETCHOPT_TCP 0x01 /* Use TCP. */ -#define DNS_FETCHOPT_UNSHARED 0x02 /* See below. */ -#define DNS_FETCHOPT_RECURSIVE 0x04 /* Set RD? */ -#define DNS_FETCHOPT_NOEDNS0 0x08 /* Do not use EDNS. */ -#define DNS_FETCHOPT_FORWARDONLY 0x10 /* Only use forwarders. */ -#define DNS_FETCHOPT_NOVALIDATE 0x20 /* Disable validation. */ +#define DNS_FETCHOPT_TCP 0x01 /*%< Use TCP. */ +#define DNS_FETCHOPT_UNSHARED 0x02 /*%< See below. */ +#define DNS_FETCHOPT_RECURSIVE 0x04 /*%< Set RD? */ +#define DNS_FETCHOPT_NOEDNS0 0x08 /*%< Do not use EDNS. */ +#define DNS_FETCHOPT_FORWARDONLY 0x10 /*%< Only use forwarders. */ +#define DNS_FETCHOPT_NOVALIDATE 0x20 /*%< Disable validation. */ +#define DNS_FETCHOPT_EDNS512 0x40 /*%< Advertise a 512 byte + UDP buffer. */ + +#define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 +#define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000 +#define DNS_FETCHOPT_EDNSVERSIONSHIFT 24 /* * XXXRTH Should this API be made semi-private? (I.e. @@ -110,114 +118,114 @@ dns_resolver_create(dns_view_t *view, dns_dispatch_t *dispatchv6, dns_resolver_t **resp); -/* +/*%< * Create a resolver. * * Notes: * - * Generally, applications should not create a resolver directly, but + *\li Generally, applications should not create a resolver directly, but * should instead call dns_view_createresolver(). * - * No options are currently defined. + *\li No options are currently defined. * * Requires: * - * 'view' is a valid view. + *\li 'view' is a valid view. * - * 'taskmgr' is a valid task manager. + *\li 'taskmgr' is a valid task manager. * - * 'ntasks' > 0. + *\li 'ntasks' > 0. * - * 'socketmgr' is a valid socket manager. + *\li 'socketmgr' is a valid socket manager. * - * 'timermgr' is a valid timer manager. + *\li 'timermgr' is a valid timer manager. * - * 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. + *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. * - * 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. + *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. * - * resp != NULL && *resp == NULL. + *\li resp != NULL && *resp == NULL. * * Returns: * - * ISC_R_SUCCESS On success. + *\li #ISC_R_SUCCESS On success. * - * Anything else Failure. + *\li Anything else Failure. */ void dns_resolver_freeze(dns_resolver_t *res); -/* +/*%< * Freeze resolver. * * Notes: * - * Certain configuration changes cannot be made after the resolver + *\li Certain configuration changes cannot be made after the resolver * is frozen. Fetches cannot be created until the resolver is frozen. * * Requires: * - * 'res' is a valid, unfrozen resolver. + *\li 'res' is a valid, unfrozen resolver. * * Ensures: * - * 'res' is frozen. + *\li 'res' is frozen. */ void dns_resolver_prime(dns_resolver_t *res); -/* +/*%< * Prime resolver. * * Notes: * - * Resolvers which have a forwarding policy other than dns_fwdpolicy_only + *\li Resolvers which have a forwarding policy other than dns_fwdpolicy_only * need to be primed with the root nameservers, otherwise the root * nameserver hints data may be used indefinitely. This function requests * that the resolver start a priming fetch, if it isn't already priming. * * Requires: * - * 'res' is a valid, frozen resolver. + *\li 'res' is a valid, frozen resolver. */ void dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task, isc_event_t **eventp); -/* +/*%< * Send '*eventp' to 'task' when 'res' has completed shutdown. * * Notes: * - * It is not safe to detach the last reference to 'res' until + *\li It is not safe to detach the last reference to 'res' until * shutdown is complete. * * Requires: * - * 'res' is a valid resolver. + *\li 'res' is a valid resolver. * - * 'task' is a valid task. + *\li 'task' is a valid task. * - * *eventp is a valid event. + *\li *eventp is a valid event. * * Ensures: * - * *eventp == NULL. + *\li *eventp == NULL. */ void dns_resolver_shutdown(dns_resolver_t *res); -/* +/*%< * Start the shutdown process for 'res'. * * Notes: * - * This call has no effect if the resolver is already shutting down. + *\li This call has no effect if the resolver is already shutting down. * * Requires: * - * 'res' is a valid resolver. + *\li 'res' is a valid resolver. */ void @@ -236,88 +244,108 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp); -/* + +isc_result_t +dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t *domain, dns_rdataset_t *nameservers, + dns_forwarders_t *forwarders, + isc_sockaddr_t *client, isc_uint16_t id, + unsigned int options, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + dns_fetch_t **fetchp); +/*%< * Recurse to answer a question. * * Notes: * - * This call starts a query for 'name', type 'type'. + *\li This call starts a query for 'name', type 'type'. * - * The 'domain' is a parent domain of 'name' for which + *\li The 'domain' is a parent domain of 'name' for which * a set of name servers 'nameservers' is known. If no * such name server information is available, set * 'domain' and 'nameservers' to NULL. * - * 'forwarders' is unimplemented, and subject to change when + *\li 'forwarders' is unimplemented, and subject to change when * we figure out how selective forwarding will work. * - * When the fetch completes (successfully or otherwise), a - * DNS_EVENT_FETCHDONE event with action 'action' and arg 'arg' will be + *\li When the fetch completes (successfully or otherwise), a + * #DNS_EVENT_FETCHDONE event with action 'action' and arg 'arg' will be * posted to 'task'. * - * The values of 'rdataset' and 'sigrdataset' will be returned in + *\li The values of 'rdataset' and 'sigrdataset' will be returned in * the FETCHDONE event. * + *\li 'client' and 'id' are used for duplicate query detection. '*client' + * must remain stable until after 'action' has been called or + * dns_resolver_cancelfetch() is called. + * * Requires: * - * 'res' is a valid resolver that has been frozen. + *\li 'res' is a valid resolver that has been frozen. * - * 'name' is a valid name. + *\li 'name' is a valid name. * - * 'type' is not a meta type other than ANY. + *\li 'type' is not a meta type other than ANY. * - * 'domain' is a valid name or NULL. + *\li 'domain' is a valid name or NULL. * - * 'nameservers' is a valid NS rdataset (whose owner name is 'domain') + *\li 'nameservers' is a valid NS rdataset (whose owner name is 'domain') * iff. 'domain' is not NULL. * - * 'forwarders' is NULL. + *\li 'forwarders' is NULL. + * + *\li 'client' is a valid sockaddr or NULL. * - * 'options' contains valid options. + *\li 'options' contains valid options. * - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * - * 'sigrdataset' is NULL, or is a valid, disassociated rdataset. + *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * - * fetchp != NULL && *fetchp == NULL. + *\li fetchp != NULL && *fetchp == NULL. * * Returns: * - * ISC_R_SUCCESS Success + *\li #ISC_R_SUCCESS Success + *\li #DNS_R_DUPLICATE + *\li #DNS_R_DROP * - * Many other values are possible, all of which indicate failure. + *\li Many other values are possible, all of which indicate failure. */ void dns_resolver_cancelfetch(dns_fetch_t *fetch); -/* +/*%< * Cancel 'fetch'. * * Notes: * - * If 'fetch' has not completed, post its FETCHDONE event with a - * result code of ISC_R_CANCELED. + *\li If 'fetch' has not completed, post its FETCHDONE event with a + * result code of #ISC_R_CANCELED. * * Requires: * - * 'fetch' is a valid fetch. + *\li 'fetch' is a valid fetch. */ void dns_resolver_destroyfetch(dns_fetch_t **fetchp); -/* +/*%< * Destroy 'fetch'. * * Requires: * - * '*fetchp' is a valid fetch. + *\li '*fetchp' is a valid fetch. * - * The caller has received the FETCHDONE event (either because the + *\li The caller has received the FETCHDONE event (either because the * fetch completed or because dns_resolver_cancelfetch() was called). * * Ensures: * - * *fetchp == NULL. + *\li *fetchp == NULL. */ dns_dispatchmgr_t * @@ -337,25 +365,25 @@ dns_resolver_taskmgr(dns_resolver_t *resolver); isc_uint32_t dns_resolver_getlamettl(dns_resolver_t *resolver); -/* +/*%< * Get the resolver's lame-ttl. zero => no lame processing. * * Requires: - * 'resolver' to be valid. + *\li 'resolver' to be valid. */ void dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl); -/* +/*%< * Set the resolver's lame-ttl. zero => no lame processing. * * Requires: - * 'resolver' to be valid. + *\li 'resolver' to be valid. */ unsigned int dns_resolver_nrunning(dns_resolver_t *resolver); -/* +/*%< * Return the number of currently running resolutions in this * resolver. This is may be less than the number of outstanding * fetches due to multiple identical fetches, or more than the @@ -366,56 +394,62 @@ dns_resolver_nrunning(dns_resolver_t *resolver); isc_result_t dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt, dns_name_t *name, in_port_t port); -/* +/*%< * Add alternate addresses to be tried in the event that the nameservers * for a zone are not available in the address families supported by the * operating system. * * Require: - * only one of 'name' or 'alt' to be valid. + * \li only one of 'name' or 'alt' to be valid. */ void dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize); -/* +/*%< * Set the EDNS UDP buffer size advertised by the server. */ isc_uint16_t dns_resolver_getudpsize(dns_resolver_t *resolver); -/* +/*%< * Get the current EDNS UDP buffer size. */ void dns_resolver_reset_algorithms(dns_resolver_t *resolver); -/* +/*%< * Clear the disabled DNSSEC algorithms. */ isc_result_t dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name, unsigned int alg); -/* +/*%< * Mark the give DNSSEC algorithm as disabled and below 'name'. * Valid algorithms are less than 256. * * Returns: - * ISC_R_SUCCESS - * ISC_R_RANGE - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_RANGE + *\li #ISC_R_NOMEMORY */ isc_boolean_t dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, unsigned int alg); -/* +/*%< * Check if the given algorithm is supported by this resolver. * This checks if the algorithm has been disabled via * dns_resolver_disable_algorithm() then the underlying * crypto libraries if not specifically disabled. */ +isc_boolean_t +dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest_type); +/*%< + * Is this digest type supported. + */ + void dns_resolver_resetmustbesecure(dns_resolver_t *resolver); @@ -426,6 +460,20 @@ dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name, isc_boolean_t dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name); +void +dns_resolver_setclientsperquery(dns_resolver_t *resolver, + isc_uint32_t min, isc_uint32_t max); + +void +dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur, + isc_uint32_t *min, isc_uint32_t *max); + +isc_boolean_t +dns_resolver_getzeronosoattl(dns_resolver_t *resolver); + +void +dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state); + ISC_LANG_ENDDECLS #endif /* DNS_RESOLVER_H */ diff --git a/contrib/bind9/lib/dns/include/dns/result.h b/contrib/bind9/lib/dns/include/dns/result.h index f1a71d9..db5481b 100644 --- a/contrib/bind9/lib/dns/include/dns/result.h +++ b/contrib/bind9/lib/dns/include/dns/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.h,v 1.81.2.7.2.13 2004/05/14 05:06:41 marka Exp $ */ +/* $Id: result.h,v 1.104.10.6 2005/06/17 02:04:32 marka Exp $ */ #ifndef DNS_RESULT_H #define DNS_RESULT_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/resultclass.h> @@ -143,8 +145,10 @@ #define DNS_R_UNKNOWNCOMMAND (ISC_RESULTCLASS_DNS + 99) #define DNS_R_MUSTBESECURE (ISC_RESULTCLASS_DNS + 100) #define DNS_R_COVERINGNSEC (ISC_RESULTCLASS_DNS + 101) +#define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102) +#define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103) -#define DNS_R_NRESULTS 102 /* Number of results */ +#define DNS_R_NRESULTS 104 /*%< Number of results */ /* * DNS wire format rcodes. @@ -165,7 +169,7 @@ #define DNS_R_NOTZONE (ISC_RESULTCLASS_DNSRCODE + 10) #define DNS_R_BADVERS (ISC_RESULTCLASS_DNSRCODE + 16) -#define DNS_R_NRCODERESULTS 17 /* Number of rcode results */ +#define DNS_R_NRCODERESULTS 17 /*%< Number of rcode results */ #define DNS_RESULT_ISRCODE(result) \ (ISC_RESULTCLASS_INCLASS(ISC_RESULTCLASS_DNSRCODE, (result))) diff --git a/contrib/bind9/lib/dns/include/dns/rootns.h b/contrib/bind9/lib/dns/include/dns/rootns.h index 02da556..a3ddc48 100644 --- a/contrib/bind9/lib/dns/include/dns/rootns.h +++ b/contrib/bind9/lib/dns/include/dns/rootns.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rootns.h,v 1.8.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: rootns.h,v 1.9.18.3 2005/04/27 05:01:38 sra Exp $ */ #ifndef DNS_ROOTNS_H #define DNS_ROOTNS_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -30,6 +32,14 @@ isc_result_t dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *filename, dns_db_t **target); +void +dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db); +/* + * Reports differences between hints and the real roots. + * + * Requires view, hints and (cache) db to be valid. + */ + ISC_LANG_ENDDECLS #endif /* DNS_ROOTNS_H */ diff --git a/contrib/bind9/lib/dns/include/dns/sdb.h b/contrib/bind9/lib/dns/include/dns/sdb.h index 5fdeace..de849f9 100644 --- a/contrib/bind9/lib/dns/include/dns/sdb.h +++ b/contrib/bind9/lib/dns/include/dns/sdb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.h,v 1.12.12.3 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: sdb.h,v 1.15.18.2 2005/04/29 00:16:21 marka Exp $ */ #ifndef DNS_SDB_H #define DNS_SDB_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * Simple database API. */ @@ -40,17 +41,17 @@ *** Types ***/ -/* +/*% * A simple database. This is an opaque type. */ typedef struct dns_sdb dns_sdb_t; -/* +/*% * A simple database lookup in progress. This is an opaque type. */ typedef struct dns_sdblookup dns_sdblookup_t; -/* +/*% * A simple database traversal in progress. This is an opaque type. */ typedef struct dns_sdballnodes dns_sdballnodes_t; @@ -96,7 +97,7 @@ isc_result_t dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, void *driverdata, unsigned int flags, isc_mem_t *mctx, dns_sdbimplementation_t **sdbimp); -/* +/*%< * Register a simple database driver for the database type 'drivername', * implemented by the functions in '*methods'. * @@ -126,7 +127,7 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, * The allnodes function, if non-NULL, fills in an opaque structure to be * used by a database iterator. This allows the zone to be transferred. * This may use a considerable amount of memory for large zones, and the - * zone transfer may not be fully RFC 1035 compliant if the zone is + * zone transfer may not be fully RFC1035 compliant if the zone is * frequently changed. * * The create function will be called for each zone configured @@ -156,19 +157,20 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, void dns_sdb_unregister(dns_sdbimplementation_t **sdbimp); -/* +/*%< * Removes the simple database driver from the list of registered database * types. There must be no active databases of this type when this function * is called. */ +/*% See dns_sdb_putradata() */ isc_result_t dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data); isc_result_t dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t type, dns_ttl_t ttl, const unsigned char *rdata, unsigned int rdlen); -/* +/*%< * Add a single resource record to the lookup structure to be * returned in the query response. dns_sdb_putrr() takes the * resource record in master file text format as a null-terminated @@ -176,6 +178,7 @@ dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t type, dns_ttl_t ttl, * uncompressed wire format. */ +/*% See dns_sdb_putnamerdata() */ isc_result_t dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data); @@ -183,7 +186,7 @@ isc_result_t dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, dns_rdatatype_t type, dns_ttl_t ttl, const void *rdata, unsigned int rdlen); -/* +/*%< * Add a single resource record to the allnodes structure to be * included in a zone transfer response, in text or wire * format as above. @@ -192,7 +195,7 @@ dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, isc_result_t dns_sdb_putsoa(dns_sdblookup_t *lookup, const char *mname, const char *rname, isc_uint32_t serial); -/* +/*%< * This function may optionally be called from the 'authority' callback * to simplify construction of the SOA record for 'zone'. It will * provide a SOA listing 'mname' as as the master server and 'rname' as diff --git a/contrib/bind9/lib/dns/include/dns/sdlz.h b/contrib/bind9/lib/dns/include/dns/sdlz.h new file mode 100644 index 0000000..13ba14a --- /dev/null +++ b/contrib/bind9/lib/dns/include/dns/sdlz.h @@ -0,0 +1,266 @@ +/* + * Portions Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +/* + * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. + * + * Permission to use, copy, modify, and 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 STICHTING NLNET + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * STICHTING NLNET 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. + * + * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was + * conceived and contributed by Rob Butler. + * + * Permission to use, copy, modify, and 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 ROB BUTLER + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * ROB BUTLER 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: sdlz.h,v 1.2.2.2 2005/09/06 03:47:19 marka Exp $ */ + +/*! \file */ + +#ifndef SDLZ_H +#define SDLZ_H 1 + +#include <dns/dlz.h> + +ISC_LANG_BEGINDECLS + +#define DNS_SDLZFLAG_THREADSAFE 0x00000001U +#define DNS_SDLZFLAG_RELATIVEOWNER 0x00000002U +#define DNS_SDLZFLAG_RELATIVERDATA 0x00000004U + + /* A simple DLZ database. */ +typedef struct dns_sdlz_db dns_sdlz_db_t; + + /* A simple DLZ database lookup in progress. */ +typedef struct dns_sdlzlookup dns_sdlzlookup_t; + + /* A simple DLZ database traversal in progress. */ +typedef struct dns_sdlzallnodes dns_sdlzallnodes_t; + + +typedef isc_result_t +(*dns_sdlzallnodesfunc_t)(const char *zone, void *driverarg, void *dbdata, + dns_sdlzallnodes_t *allnodes); + +/*%< + * Method prototype. Drivers implementing the SDLZ interface may + * supply an all nodes method. This method is called when the DNS + * server is performing a zone transfer query, after the allow zone + * transfer method has been called. This method is only called if the + * allow zone transfer method returned ISC_R_SUCCESS. This method and + * the allow zone transfer method are both required for zone transfers + * to be supported. If the driver generates data dynamically (instead + * of searching in a database for it) it should not implement this + * function as a zone transfer would be meaningless. A SDLZ driver + * does not have to implement an all nodes method. + */ + +typedef isc_result_t +(*dns_sdlzallowzonexfr_t)(void *driverarg, void *dbdata, const char *name, + const char *client); + +/*%< + * Method prototype. Drivers implementing the SDLZ interface may + * supply an allow zone transfer method. This method is called when + * the DNS server is performing a zone transfer query, before the all + * nodes method can be called. This method and the all node method + * are both required for zone transfers to be supported. If the + * driver generates data dynamically (instead of searching in a + * database for it) it should not implement this function as a zone + * transfer would be meaningless. A SDLZ driver does not have to + * implement an allow zone transfer method. + * + * This method should return ISC_R_SUCCESS if the zone is supported by + * the database and a zone transfer is allowed for the specified + * client. If the zone is supported by the database, but zone + * transfers are not allowed for the specified client this method + * should return ISC_R_NOPERM.. Lastly the method should return + * ISC_R_NOTFOUND if the zone is not supported by the database. If an + * error occurs it should return a result code indicating the type of + * error. + */ + +typedef isc_result_t +(*dns_sdlzauthorityfunc_t)(const char *zone, void *driverarg, void *dbdata, + dns_sdlzlookup_t *lookup); + +/*%< + * Method prototype. Drivers implementing the SDLZ interface may + * supply an authority method. This method is called when the DNS + * server is performing a query, after both the find zone and lookup + * methods have been called. This method is required if the lookup + * function does not supply authority information for the dns + * record. A SDLZ driver does not have to implement an authority + * method. + */ + +typedef isc_result_t +(*dns_sdlzcreate_t)(const char *dlzname, unsigned int argc, char *argv[], + void *driverarg, void **dbdata); + +/*%< + * Method prototype. Drivers implementing the SDLZ interface may + * supply a create method. This method is called when the DNS server + * is starting up and creating drivers for use later. A SDLZ driver + * does not have to implement a create method. + */ + +typedef void +(*dns_sdlzdestroy_t)(void *driverarg, void *dbdata); + +/*%< + * Method prototype. Drivers implementing the SDLZ interface may + * supply a destroy method. This method is called when the DNS server + * is shuting down and no longer needs the driver. A SDLZ driver does + * not have to implement a destroy method. + */ + +typedef isc_result_t +(*dns_sdlzfindzone_t)(void *driverarg, void *dbdata, const char *name); + +/*%< + * Method prototype. Drivers implementing the SDLZ interface MUST + * supply a find zone method. This method is called when the DNS + * server is performing a query to to determine if 'name' is a + * supported dns zone. The find zone method will be called with the + * longest possible name first, and continue to be called with + * successively shorter domain names, until any of the following + * occur: + * + * \li 1) the function returns (ISC_R_SUCCESS) indicating a zone name + * match. + * + * \li 2) a problem occurs, and the functions returns anything other than + * (ISC_R_NOTFOUND) + * + * \li 3) we run out of domain name labels. I.E. we have tried the + * shortest domain name + * + * \li 4) the number of labels in the domain name is less than min_lables + * for dns_dlzfindzone + * + * The driver's find zone method should return ISC_R_SUCCESS if the + * zone is supported by the database. Otherwise it should return + * ISC_R_NOTFOUND, if the zone is not supported. If an error occurs + * it should return a result code indicating the type of error. + */ + +typedef isc_result_t +(*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg, + void *dbdata, dns_sdlzlookup_t *lookup); + +/*%< + * 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 + * 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. + */ + +typedef struct dns_sdlzmethods { + dns_sdlzcreate_t create; + dns_sdlzdestroy_t destroy; + dns_sdlzfindzone_t findzone; + dns_sdlzlookupfunc_t lookup; + dns_sdlzauthorityfunc_t authority; + dns_sdlzallnodesfunc_t allnodes; + dns_sdlzallowzonexfr_t allowzonexfr; +} dns_sdlzmethods_t; + +isc_result_t +dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, + void *driverarg, unsigned int flags, isc_mem_t *mctx, + dns_sdlzimplementation_t **sdlzimp); +/*%< + * Register a dynamically loadable zones (dlz) driver for the database + * type 'drivername', implemented by the functions in '*methods'. + * + * sdlzimp must point to a NULL dns_sdlzimplementation_t pointer. + * That is, sdlzimp != NULL && *sdlzimp == NULL. It will be assigned + * a value that will later be used to identify the driver when + * deregistering it. + */ + +void +dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp); + +/*%< + * Removes the sdlz driver from the list of registered sdlz drivers. + * There must be no active sdlz drivers of this type when this + * function is called. + */ + +isc_result_t +dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, + const char *type, dns_ttl_t ttl, const char *data); +/*%< + * Add a single resource record to the allnodes structure to be later + * parsed into a zone transfer response. + */ + +isc_result_t +dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, + const char *data); +/*%< + * Add a single resource record to the lookup structure to be later + * parsed into a query response. + */ + +isc_result_t +dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname, + isc_uint32_t serial); +/*%< + * This function may optionally be called from the 'authority' + * callback to simplify construction of the SOA record for 'zone'. It + * will provide a SOA listing 'mname' as as the master server and + * 'rname' as the responsible person mailbox. It is the + * responsibility of the driver to increment the serial number between + * responses if necessary. All other SOA fields will have reasonable + * default values. + */ + + +ISC_LANG_ENDDECLS + +#endif /* SDLZ_H */ diff --git a/contrib/bind9/lib/dns/include/dns/secalg.h b/contrib/bind9/lib/dns/include/dns/secalg.h index 3f7a16f..0466d91 100644 --- a/contrib/bind9/lib/dns/include/dns/secalg.h +++ b/contrib/bind9/lib/dns/include/dns/secalg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: secalg.h,v 1.12.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: secalg.h,v 1.13.18.2 2005/04/29 00:16:21 marka Exp $ */ #ifndef DNS_SECALG_H #define DNS_SECALG_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,40 +30,40 @@ ISC_LANG_BEGINDECLS isc_result_t dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a DNSSEC security algorithm value. * The text may contain either a mnemonic algorithm name or a decimal algorithm * number. * * Requires: - * 'secalgp' is a valid pointer. + *\li 'secalgp' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_RANGE numeric type is out of range - * DNS_R_UNKNOWN mnemonic type is unknown + *\li ISC_R_SUCCESS on success + *\li ISC_R_RANGE numeric type is out of range + *\li DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target); -/* +/*%< * Put a textual representation of the DNSSEC security algorithm 'secalg' * into 'target'. * * Requires: - * 'secalg' is a valid secalg. + *\li 'secalg' is a valid secalg. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * - * Ensures: - * If the result is success: - * The used space in 'target' is updated. + * Ensures, + * if the result is success: + *\li The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li ISC_R_SUCCESS on success + *\li ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/secproto.h b/contrib/bind9/lib/dns/include/dns/secproto.h index da8c1dd..a6cfd5c 100644 --- a/contrib/bind9/lib/dns/include/dns/secproto.h +++ b/contrib/bind9/lib/dns/include/dns/secproto.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: secproto.h,v 1.9.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: secproto.h,v 1.10.18.2 2005/04/29 00:16:21 marka Exp $ */ #ifndef DNS_SECPROTO_H #define DNS_SECPROTO_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,40 +30,40 @@ ISC_LANG_BEGINDECLS isc_result_t dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source); -/* +/*%< * Convert the text 'source' refers to into a DNSSEC security protocol value. * The text may contain either a mnemonic protocol name or a decimal protocol * number. * * Requires: - * 'secprotop' is a valid pointer. + *\li 'secprotop' is a valid pointer. * - * 'source' is a valid text region. + *\li 'source' is a valid text region. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_RANGE numeric type is out of range - * DNS_R_UNKNOWN mnemonic type is unknown + *\li ISC_R_SUCCESS on success + *\li ISC_R_RANGE numeric type is out of range + *\li DNS_R_UNKNOWN mnemonic type is unknown */ isc_result_t dns_secproto_totext(dns_secproto_t secproto, isc_buffer_t *target); -/* +/*%< * Put a textual representation of the DNSSEC security protocol 'secproto' * into 'target'. * * Requires: - * 'secproto' is a valid secproto. + *\li 'secproto' is a valid secproto. * - * 'target' is a valid text buffer. + *\li 'target' is a valid text buffer. * - * Ensures: - * If the result is success: - * The used space in 'target' is updated. + * Ensures, + * if the result is success: + * \li The used space in 'target' is updated. * * Returns: - * ISC_R_SUCCESS on success - * ISC_R_NOSPACE target buffer is too small + *\li ISC_R_SUCCESS on success + *\li ISC_R_NOSPACE target buffer is too small */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/soa.h b/contrib/bind9/lib/dns/include/dns/soa.h index 304ae15..70c6725 100644 --- a/contrib/bind9/lib/dns/include/dns/soa.h +++ b/contrib/bind9/lib/dns/include/dns/soa.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: soa.h,v 1.2.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: soa.h,v 1.3.18.2 2005/04/29 00:16:22 marka Exp $ */ #ifndef DNS_SOA_H #define DNS_SOA_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * SOA utilities. */ diff --git a/contrib/bind9/lib/dns/include/dns/ssu.h b/contrib/bind9/lib/dns/include/dns/ssu.h index f26a039..b709030 100644 --- a/contrib/bind9/lib/dns/include/dns/ssu.h +++ b/contrib/bind9/lib/dns/include/dns/ssu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ssu.h,v 1.11.206.3 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: ssu.h,v 1.13.18.4 2006/02/16 23:51:32 marka Exp $ */ #ifndef DNS_SSU_H #define DNS_SSU_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -30,46 +32,50 @@ ISC_LANG_BEGINDECLS #define DNS_SSUMATCHTYPE_SUBDOMAIN 1 #define DNS_SSUMATCHTYPE_WILDCARD 2 #define DNS_SSUMATCHTYPE_SELF 3 +#define DNS_SSUMATCHTYPE_SELFSUB 4 +#define DNS_SSUMATCHTYPE_SELFWILD 5 +#define DNS_SSUMATCHTYPE_MAX 5 /* maximum defined value */ + isc_result_t dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table); -/* +/*%< * Creates a table that will be used to store simple-secure-update rules. * Note: all locking must be provided by the client. * * Requires: - * 'mctx' is a valid memory context - * 'table' is not NULL, and '*table' is NULL + *\li 'mctx' is a valid memory context + *\li 'table' is not NULL, and '*table' is NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li ISC_R_SUCCESS + *\li ISC_R_NOMEMORY */ void dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp); -/* +/*%< * Attach '*targetp' to 'source'. * * Requires: - * 'source' is a valid SSU table - * 'targetp' points to a NULL dns_ssutable_t *. + *\li 'source' is a valid SSU table + *\li 'targetp' points to a NULL dns_ssutable_t *. * * Ensures: - * *targetp is attached to source. + *\li *targetp is attached to source. */ void dns_ssutable_detach(dns_ssutable_t **tablep); -/* +/*%< * Detach '*tablep' from its simple-secure-update rule table. * * Requires: - * 'tablep' points to a valid dns_ssutable_t + *\li 'tablep' points to a valid dns_ssutable_t * * Ensures: - * *tablep is NULL - * If '*tablep' is the last reference to the SSU table, all + *\li *tablep is NULL + *\li If '*tablep' is the last reference to the SSU table, all * resources used by the table will be freed. */ @@ -78,78 +84,80 @@ dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, dns_name_t *identity, unsigned int matchtype, dns_name_t *name, unsigned int ntypes, dns_rdatatype_t *types); -/* +/*%< * Adds a new rule to a simple-secure-update rule table. The rule * either grants or denies update privileges of an identity (or set of * identities) to modify a name (or set of names) or certain types present * at that name. * * Notes: - * If 'matchtype' is SELF, this rule only matches if the name + *\li If 'matchtype' is SELF, this rule only matches if the name * to be updated matches the signing identity. * - * If 'ntypes' is 0, this rule applies to all types except + *\li If 'ntypes' is 0, this rule applies to all types except * NS, SOA, RRSIG, and NSEC. * - * If 'types' includes ANY, this rule applies to all types + *\li If 'types' includes ANY, this rule applies to all types * except NSEC. * * Requires: - * 'table' is a valid SSU table - * 'identity' is a valid absolute name - * 'matchtype' must be one of the defined constants. - * 'name' is a valid absolute name - * If 'ntypes' > 0, 'types' must not be NULL + *\li 'table' is a valid SSU table + *\li 'identity' is a valid absolute name + *\li 'matchtype' must be one of the defined constants. + *\li 'name' is a valid absolute name + *\li If 'ntypes' > 0, 'types' must not be NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li ISC_R_SUCCESS + *\li ISC_R_NOMEMORY */ isc_boolean_t dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, dns_name_t *name, dns_rdatatype_t type); -/* +/*%< * Checks that the attempted update of (name, type) is allowed according * to the rules specified in the simple-secure-update rule table. If * no rules are matched, access is denied. If signer is NULL, access * is denied. * * Requires: - * 'table' is a valid SSU table - * 'signer' is NULL or a valid absolute name - * 'name' is a valid absolute name + *\li 'table' is a valid SSU table + *\li 'signer' is NULL or a valid absolute name + *\li 'name' is a valid absolute name */ +/*% Accessor functions to extract rule components */ isc_boolean_t dns_ssurule_isgrant(const dns_ssurule_t *rule); +/*% Accessor functions to extract rule components */ dns_name_t * dns_ssurule_identity(const dns_ssurule_t *rule); +/*% Accessor functions to extract rule components */ unsigned int dns_ssurule_matchtype(const dns_ssurule_t *rule); +/*% Accessor functions to extract rule components */ dns_name_t * dns_ssurule_name(const dns_ssurule_t *rule); +/*% Accessor functions to extract rule components */ unsigned int dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types); -/* - * Accessor functions to extract rule components - */ isc_result_t dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule); -/* +/*%< * Initiates a rule iterator. There is no need to maintain any state. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE */ isc_result_t dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule); -/* +/*%< * Returns the next rule in the table. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMORE + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/stats.h b/contrib/bind9/lib/dns/include/dns/stats.h index db94b52..6cd95ac 100644 --- a/contrib/bind9/lib/dns/include/dns/stats.h +++ b/contrib/bind9/lib/dns/include/dns/stats.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,39 +15,43 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: stats.h,v 1.4.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: stats.h,v 1.5.18.4 2005/06/27 00:20:03 marka Exp $ */ #ifndef DNS_STATS_H #define DNS_STATS_H 1 +/*! \file */ + #include <dns/types.h> -/* +/*% * Query statistics counter types. */ typedef enum { - dns_statscounter_success = 0, /* Successful lookup */ - dns_statscounter_referral = 1, /* Referral result */ - dns_statscounter_nxrrset = 2, /* NXRRSET result */ - dns_statscounter_nxdomain = 3, /* NXDOMAIN result */ - dns_statscounter_recursion = 4, /* Recursion was used */ - dns_statscounter_failure = 5 /* Some other failure */ + dns_statscounter_success = 0, /*%< Successful lookup */ + dns_statscounter_referral = 1, /*%< Referral result */ + dns_statscounter_nxrrset = 2, /*%< NXRRSET result */ + dns_statscounter_nxdomain = 3, /*%< NXDOMAIN result */ + dns_statscounter_recursion = 4, /*%< Recursion was used */ + dns_statscounter_failure = 5, /*%< Some other failure */ + dns_statscounter_duplicate = 6, /*%< Duplicate query */ + dns_statscounter_dropped = 7 /*%< Duplicate query */ } dns_statscounter_t; -#define DNS_STATS_NCOUNTERS 6 +#define DNS_STATS_NCOUNTERS 8 LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[]; isc_result_t dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp); -/* +/*%< * Allocate an array of query statistics counters from the memory * context 'mctx'. */ void dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp); -/* +/*%< * Free an array of query statistics counters allocated from the memory * context 'mctx'. */ diff --git a/contrib/bind9/lib/dns/include/dns/tcpmsg.h b/contrib/bind9/lib/dns/include/dns/tcpmsg.h index ae1d704..075f463 100644 --- a/contrib/bind9/lib/dns/include/dns/tcpmsg.h +++ b/contrib/bind9/lib/dns/include/dns/tcpmsg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tcpmsg.h,v 1.15.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: tcpmsg.h,v 1.16.18.2 2005/04/29 00:16:22 marka Exp $ */ #ifndef DNS_TCPMSG_H #define DNS_TCPMSG_H 1 +/*! \file */ + #include <isc/buffer.h> #include <isc/lang.h> #include <isc/socket.h> @@ -45,56 +47,56 @@ ISC_LANG_BEGINDECLS void dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg); -/* +/*%< * Associate a tcp message state with a given memory context and * TCP socket. * * Requires: * - * "mctx" and "sock" be non-NULL and valid types. + *\li "mctx" and "sock" be non-NULL and valid types. * - * "sock" be a read/write TCP socket. + *\li "sock" be a read/write TCP socket. * - * "tcpmsg" be non-NULL and an uninitialized or invalidated structure. + *\li "tcpmsg" be non-NULL and an uninitialized or invalidated structure. * * Ensures: * - * "tcpmsg" is a valid structure. + *\li "tcpmsg" is a valid structure. */ void dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize); -/* +/*%< * Set the maximum packet size to "maxsize" * * Requires: * - * "tcpmsg" be valid. + *\li "tcpmsg" be valid. * - * 512 <= "maxsize" <= 65536 + *\li 512 <= "maxsize" <= 65536 */ isc_result_t dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, isc_task_t *task, isc_taskaction_t action, void *arg); -/* +/*%< * Schedule an event to be delivered when a DNS message is readable, or * when an error occurs on the socket. * * Requires: * - * "tcpmsg" be valid. + *\li "tcpmsg" be valid. * - * "task", "taskaction", and "arg" be valid. + *\li "task", "taskaction", and "arg" be valid. * * Returns: * - * ISC_R_SUCCESS -- no error - * Anything that the isc_socket_recv() call can return. XXXMLG + *\li ISC_R_SUCCESS -- no error + *\li Anything that the isc_socket_recv() call can return. XXXMLG * * Notes: * - * The event delivered is a fully generic event. It will contain no + *\li The event delivered is a fully generic event. It will contain no * actual data. The sender will be a pointer to the dns_tcpmsg_t. * The result code inside that structure should be checked to see * what the final result was. @@ -102,41 +104,41 @@ dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, void dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg); -/* +/*%< * Cancel a readmessage() call. The event will still be posted with a * CANCELED result code. * * Requires: * - * "tcpmsg" be valid. + *\li "tcpmsg" be valid. */ void dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer); -/* +/*%< * If a dns buffer is to be kept between calls, this function marks the * internal state-machine buffer as invalid, and copies all the contents * of the state into "buffer". * * Requires: * - * "tcpmsg" be valid. + *\li "tcpmsg" be valid. * - * "buffer" be non-NULL. + *\li "buffer" be non-NULL. */ void dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg); -/* +/*%< * Clean up all allocated state, and invalidate the structure. * * Requires: * - * "tcpmsg" be valid. + *\li "tcpmsg" be valid. * * Ensures: * - * "tcpmsg" is invalidated and disassociated with all memory contexts, + *\li "tcpmsg" is invalidated and disassociated with all memory contexts, * sockets, etc. */ diff --git a/contrib/bind9/lib/dns/include/dns/time.h b/contrib/bind9/lib/dns/include/dns/time.h index 0b82443..9e8f5cc 100644 --- a/contrib/bind9/lib/dns/include/dns/time.h +++ b/contrib/bind9/lib/dns/include/dns/time.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.h,v 1.9.12.3 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: time.h,v 1.11.18.2 2005/04/29 00:16:23 marka Exp $ */ #ifndef DNS_TIME_H #define DNS_TIME_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -35,7 +37,7 @@ ISC_LANG_BEGINDECLS isc_result_t dns_time64_fromtext(const char *source, isc_int64_t *target); -/* +/*%< * Convert a date and time in YYYYMMDDHHMMSS text format at 'source' * into to a 64-bit count of seconds since Jan 1 1970 0:00 GMT. * Store the count at 'target'. @@ -43,7 +45,7 @@ dns_time64_fromtext(const char *source, isc_int64_t *target); isc_result_t dns_time32_fromtext(const char *source, isc_uint32_t *target); -/* +/*%< * Like dns_time64_fromtext, but returns the second count modulo 2^32 * as per RFC2535. */ @@ -51,14 +53,14 @@ dns_time32_fromtext(const char *source, isc_uint32_t *target); isc_result_t dns_time64_totext(isc_int64_t value, isc_buffer_t *target); -/* +/*%< * Convert a 64-bit count of seconds since Jan 1 1970 0:00 GMT into * a YYYYMMDDHHMMSS text representation and append it to 'target'. */ isc_result_t dns_time32_totext(isc_uint32_t value, isc_buffer_t *target); -/* +/*%< * Like dns_time64_totext, but for a 32-bit cyclic time value. * Of those dates whose counts of seconds since Jan 1 1970 0:00 GMT * are congruent with 'value' modulo 2^32, the one closest to the diff --git a/contrib/bind9/lib/dns/include/dns/timer.h b/contrib/bind9/lib/dns/include/dns/timer.h index 36e2ac3..cd936a0 100644 --- a/contrib/bind9/lib/dns/include/dns/timer.h +++ b/contrib/bind9/lib/dns/include/dns/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: timer.h,v 1.2.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: timer.h,v 1.3.18.2 2005/04/29 00:16:23 marka Exp $ */ #ifndef DNS_TIMER_H #define DNS_TIMER_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -36,10 +38,10 @@ ISC_LANG_BEGINDECLS isc_result_t dns_timer_setidle(isc_timer_t *timer, unsigned int maxtime, unsigned int idletime, isc_boolean_t purge); -/* +/*%< * Convenience function for setting up simple, one-second-granularity * idle timers as used by zone transfers. - * + * \brief * Set the timer 'timer' to go off after 'idletime' seconds of inactivity, * or after 'maxtime' at the very latest. Events are purged iff * 'purge' is ISC_TRUE. diff --git a/contrib/bind9/lib/dns/include/dns/tkey.h b/contrib/bind9/lib/dns/include/dns/tkey.h index e5ca3b3..4e3e80a 100644 --- a/contrib/bind9/lib/dns/include/dns/tkey.h +++ b/contrib/bind9/lib/dns/include/dns/tkey.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tkey.h,v 1.18.206.1 2004/03/06 08:14:00 marka Exp $ */ +/* $Id: tkey.h,v 1.19.18.2 2005/04/29 00:16:23 marka Exp $ */ #ifndef DNS_TKEY_H #define DNS_TKEY_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -45,55 +47,55 @@ struct dns_tkeyctx { isc_result_t dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp); -/* +/*%< * Create an empty TKEY context. * * Requires: - * 'mctx' is not NULL - * 'tctx' is not NULL - * '*tctx' is NULL + *\li 'mctx' is not NULL + *\li 'tctx' is not NULL + *\li '*tctx' is NULL * * Returns - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * return codes from dns_name_fromtext() + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li return codes from dns_name_fromtext() */ void dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp); -/* +/*%< * Frees all data associated with the TKEY context * * Requires: - * 'tctx' is not NULL - * '*tctx' is not NULL + *\li 'tctx' is not NULL + *\li '*tctx' is not NULL */ isc_result_t dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, dns_tsig_keyring_t *ring); -/* +/*%< * Processes a query containing a TKEY record, adding or deleting TSIG * keys if necessary, and modifies the message to contain the response. * * Requires: - * 'msg' is a valid message - * 'tctx' is a valid TKEY context - * 'ring' is a valid TSIG keyring + *\li 'msg' is a valid message + *\li 'tctx' is a valid TKEY context + *\li 'ring' is a valid TSIG keyring * * Returns - * ISC_R_SUCCESS msg was updated (the TKEY operation succeeded, + *\li #ISC_R_SUCCESS msg was updated (the TKEY operation succeeded, * or msg now includes a TKEY with an error set) * DNS_R_FORMERR the packet was malformed (missing a TKEY * or KEY). - * other An error occurred while processing the message + *\li other An error occurred while processing the message */ isc_result_t dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, dns_name_t *algorithm, isc_buffer_t *nonce, isc_uint32_t lifetime); -/* +/*%< * Builds a query containing a TKEY that will generate a shared * secret using a Diffie-Hellman key exchange. The shared key * will be of the specified algorithm (only DNS_TSIG_HMACMD5_NAME @@ -105,61 +107,61 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name, * * * Requires: - * 'msg' is a valid message - * 'key' is a valid Diffie Hellman dst key - * 'name' is a valid name - * 'algorithm' is a valid name + *\li 'msg' is a valid message + *\li 'key' is a valid Diffie Hellman dst key + *\li 'name' is a valid name + *\li 'algorithm' is a valid name * * Returns: - * ISC_R_SUCCESS msg was successfully updated to include the + *\li #ISC_R_SUCCESS msg was successfully updated to include the * query to be sent - * other an error occurred while building the message + *\li other an error occurred while building the message */ isc_result_t dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname, void *cred, isc_uint32_t lifetime, void **context); -/* +/*%< * XXX */ isc_result_t dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key); -/* +/*%< * Builds a query containing a TKEY record that will delete the * specified shared secret from the server. * * Requires: - * 'msg' is a valid message - * 'key' is a valid TSIG key + *\li 'msg' is a valid message + *\li 'key' is a valid TSIG key * * Returns: - * ISC_R_SUCCESS msg was successfully updated to include the + *\li #ISC_R_SUCCESS msg was successfully updated to include the * query to be sent - * other an error occurred while building the message + *\li other an error occurred while building the message */ isc_result_t dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg, dst_key_t *key, isc_buffer_t *nonce, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring); -/* +/*%< * Processes a response to a query containing a TKEY that was * designed to generate a shared secret using a Diffie-Hellman key * exchange. If the query was successful, a new shared key * is created and added to the list of shared keys. * * Requires: - * 'qmsg' is a valid message (the query) - * 'rmsg' is a valid message (the response) - * 'key' is a valid Diffie Hellman dst key - * 'outkey' is either NULL or a pointer to NULL - * 'ring' is a valid keyring or NULL + *\li 'qmsg' is a valid message (the query) + *\li 'rmsg' is a valid message (the response) + *\li 'key' is a valid Diffie Hellman dst key + *\li 'outkey' is either NULL or a pointer to NULL + *\li 'ring' is a valid keyring or NULL * * Returns: - * ISC_R_SUCCESS the shared key was successfully added - * ISC_R_NOTFOUND an error occurred while looking for a + *\li #ISC_R_SUCCESS the shared key was successfully added + *\li #ISC_R_NOTFOUND an error occurred while looking for a * component of the query or response */ @@ -167,26 +169,26 @@ isc_result_t dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg, dns_name_t *gname, void *cred, void **context, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring); -/* +/*%< * XXX */ isc_result_t dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg, dns_tsig_keyring_t *ring); -/* +/*%< * Processes a response to a query containing a TKEY that was * designed to delete a shared secret. If the query was successful, * the shared key is deleted from the list of shared keys. * * Requires: - * 'qmsg' is a valid message (the query) - * 'rmsg' is a valid message (the response) - * 'ring' is not NULL + *\li 'qmsg' is a valid message (the query) + *\li 'rmsg' is a valid message (the response) + *\li 'ring' is not NULL * * Returns: - * ISC_R_SUCCESS the shared key was successfully deleted - * ISC_R_NOTFOUND an error occurred while looking for a + *\li #ISC_R_SUCCESS the shared key was successfully deleted + *\li #ISC_R_NOTFOUND an error occurred while looking for a * component of the query or response */ diff --git a/contrib/bind9/lib/dns/include/dns/tsig.h b/contrib/bind9/lib/dns/include/dns/tsig.h index 7b5b458..b3fd6cc 100644 --- a/contrib/bind9/lib/dns/include/dns/tsig.h +++ b/contrib/bind9/lib/dns/include/dns/tsig.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tsig.h,v 1.40.2.2.8.3 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: tsig.h,v 1.43.18.4 2006/01/27 23:57:44 marka Exp $ */ #ifndef DNS_TSIG_H #define DNS_TSIG_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/refcount.h> #include <isc/rwlock.h> @@ -39,8 +41,18 @@ LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapi_name; #define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_gssapims_name; #define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name - -/* +LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha1_name; +#define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name +LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha224_name; +#define DNS_TSIG_HMACSHA224_NAME dns_tsig_hmacsha224_name +LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha256_name; +#define DNS_TSIG_HMACSHA256_NAME dns_tsig_hmacsha256_name +LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha384_name; +#define DNS_TSIG_HMACSHA384_NAME dns_tsig_hmacsha384_name +LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_tsig_hmacsha512_name; +#define DNS_TSIG_HMACSHA512_NAME dns_tsig_hmacsha512_name + +/*% * Default fudge value. */ #define DNS_TSIG_FUDGE 300 @@ -53,17 +65,17 @@ struct dns_tsig_keyring { struct dns_tsigkey { /* Unlocked */ - unsigned int magic; /* Magic number. */ + unsigned int magic; /*%< Magic number. */ isc_mem_t *mctx; - dst_key_t *key; /* Key */ - dns_name_t name; /* Key name */ - dns_name_t *algorithm; /* Algorithm name */ - dns_name_t *creator; /* name that created secret */ - isc_boolean_t generated; /* was this generated? */ - isc_stdtime_t inception; /* start of validity period */ - isc_stdtime_t expire; /* end of validity period */ - dns_tsig_keyring_t *ring; /* the enclosing keyring */ - isc_refcount_t refs; /* reference counter */ + dst_key_t *key; /*%< Key */ + dns_name_t name; /*%< Key name */ + dns_name_t *algorithm; /*%< Algorithm name */ + dns_name_t *creator; /*%< name that created secret */ + isc_boolean_t generated; /*%< was this generated? */ + isc_stdtime_t inception; /*%< start of validity period */ + isc_stdtime_t expire; /*%< end of validity period */ + dns_tsig_keyring_t *ring; /*%< the enclosing keyring */ + isc_refcount_t refs; /*%< reference counter */ }; #define dns_tsigkey_identity(tsigkey) \ @@ -84,7 +96,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key); -/* +/*%< * Creates a tsig key structure and saves it in the keyring. If key is * not NULL, *key will contain a copy of the key. The keys validity * period is specified by (inception, expire), and will not expire if @@ -95,100 +107,100 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, * to generate a BADKEY response. * * Requires: - * 'name' is a valid dns_name_t - * 'algorithm' is a valid dns_name_t - * 'secret' is a valid pointer - * 'length' is an integer >= 0 - * 'key' is a valid dst key or NULL - * 'creator' points to a valid dns_name_t or is NULL - * 'mctx' is a valid memory context - * 'ring' is a valid TSIG keyring or NULL - * 'key' or '*key' must be NULL + *\li 'name' is a valid dns_name_t + *\li 'algorithm' is a valid dns_name_t + *\li 'secret' is a valid pointer + *\li 'length' is an integer >= 0 + *\li 'key' is a valid dst key or NULL + *\li 'creator' points to a valid dns_name_t or is NULL + *\li 'mctx' is a valid memory context + *\li 'ring' is a valid TSIG keyring or NULL + *\li 'key' or '*key' must be NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_EXISTS - a key with this name already exists - * ISC_R_NOTIMPLEMENTED - algorithm is not implemented - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_EXISTS - a key with this name already exists + *\li #ISC_R_NOTIMPLEMENTED - algorithm is not implemented + *\li #ISC_R_NOMEMORY */ void dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp); -/* +/*%< * Attach '*targetp' to 'source'. * * Requires: - * 'key' is a valid TSIG key + *\li 'key' is a valid TSIG key * * Ensures: - * *targetp is attached to source. + *\li *targetp is attached to source. */ void dns_tsigkey_detach(dns_tsigkey_t **keyp); -/* +/*%< * Detaches from the tsig key structure pointed to by '*key'. * * Requires: - * 'keyp' is not NULL and '*keyp' is a valid TSIG key + *\li 'keyp' is not NULL and '*keyp' is a valid TSIG key * * Ensures: - * 'keyp' points to NULL + *\li 'keyp' points to NULL */ void dns_tsigkey_setdeleted(dns_tsigkey_t *key); -/* +/*%< * Prevents this key from being used again. It will be deleted when * no references exist. * * Requires: - * 'key' is a valid TSIG key on a keyring + *\li 'key' is a valid TSIG key on a keyring */ isc_result_t dns_tsig_sign(dns_message_t *msg); -/* +/*%< * Generates a TSIG record for this message * * Requires: - * 'msg' is a valid message - * 'msg->tsigkey' is a valid TSIG key - * 'msg->tsig' is NULL + *\li 'msg' is a valid message + *\li 'msg->tsigkey' is a valid TSIG key + *\li 'msg->tsig' is NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_NOSPACE - * DNS_R_EXPECTEDTSIG + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_NOSPACE + *\li #DNS_R_EXPECTEDTSIG * - this is a response & msg->querytsig is NULL */ isc_result_t dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2); -/* +/*%< * Verifies the TSIG record in this message * * Requires: - * 'source' is a valid buffer containing the unparsed message - * 'msg' is a valid message - * 'msg->tsigkey' is a valid TSIG key if this is a response - * 'msg->tsig' is NULL - * 'msg->querytsig' is not NULL if this is a response - * 'ring1' and 'ring2' are each either a valid keyring or NULL + *\li 'source' is a valid buffer containing the unparsed message + *\li 'msg' is a valid message + *\li 'msg->tsigkey' is a valid TSIG key if this is a response + *\li 'msg->tsig' is NULL + *\li 'msg->querytsig' is not NULL if this is a response + *\li 'ring1' and 'ring2' are each either a valid keyring or NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen - * DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - * DNS_R_TSIGERRORSET - the TSIG verified but ->error was set + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected but not seen + *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected + *\li #DNS_R_TSIGERRORSET - the TSIG verified but ->error was set * and this is a query - * DNS_R_CLOCKSKEW - the TSIG failed to verify because of + *\li #DNS_R_CLOCKSKEW - the TSIG failed to verify because of * the time was out of the allowed range. - * DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify - * DNS_R_EXPECTEDRESPONSE - the message was set over TCP and + *\li #DNS_R_TSIGVERIFYFAILURE - the TSIG failed to verify + *\li #DNS_R_EXPECTEDRESPONSE - the message was set over TCP and * should have been a response, * but was not. */ @@ -196,45 +208,45 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, isc_result_t dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name, dns_name_t *algorithm, dns_tsig_keyring_t *ring); -/* +/*%< * Returns the TSIG key corresponding to this name and (possibly) * algorithm. Also increments the key's reference counter. * * Requires: - * 'tsigkey' is not NULL - * '*tsigkey' is NULL - * 'name' is a valid dns_name_t - * 'algorithm' is a valid dns_name_t or NULL - * 'ring' is a valid keyring + *\li 'tsigkey' is not NULL + *\li '*tsigkey' is NULL + *\li 'name' is a valid dns_name_t + *\li 'algorithm' is a valid dns_name_t or NULL + *\li 'ring' is a valid keyring * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTFOUND + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOTFOUND */ isc_result_t dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp); -/* +/*%< * Create an empty TSIG key ring. * * Requires: - * 'mctx' is not NULL - * 'ringp' is not NULL, and '*ringp' is NULL + *\li 'mctx' is not NULL + *\li 'ringp' is not NULL, and '*ringp' is NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ void dns_tsigkeyring_destroy(dns_tsig_keyring_t **ringp); -/* +/*%< * Destroy a TSIG key ring. * * Requires: - * 'ringp' is not NULL + *\li 'ringp' is not NULL */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/ttl.h b/contrib/bind9/lib/dns/include/dns/ttl.h index dc7167d..ad01578 100644 --- a/contrib/bind9/lib/dns/include/dns/ttl.h +++ b/contrib/bind9/lib/dns/include/dns/ttl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ttl.h,v 1.12.206.1 2004/03/06 08:14:01 marka Exp $ */ +/* $Id: ttl.h,v 1.13.18.2 2005/04/29 00:16:24 marka Exp $ */ #ifndef DNS_TTL_H #define DNS_TTL_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -36,7 +38,7 @@ ISC_LANG_BEGINDECLS isc_result_t dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target); -/* +/*%< * Output a TTL or other time interval in a human-readable form. * The time interval is given as a count of seconds in 'src'. * The text representation is appended to 'target'. @@ -47,28 +49,28 @@ dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, * in "dig", like "1 week 2 days 3 hours 4 minutes 5 seconds". * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOSPACE + * \li ISC_R_SUCCESS + * \li ISC_R_NOSPACE */ isc_result_t dns_counter_fromtext(isc_textregion_t *source, isc_uint32_t *ttl); -/* +/*%< * Converts a counter from either a plain number or a BIND 8 style value. * * Returns: - * ISC_R_SUCCESS - * DNS_R_SYNTAX + *\li ISC_R_SUCCESS + *\li DNS_R_SYNTAX */ isc_result_t dns_ttl_fromtext(isc_textregion_t *source, isc_uint32_t *ttl); -/* +/*%< * Converts a ttl from either a plain number or a BIND 8 style value. * * Returns: - * ISC_R_SUCCESS - * DNS_R_BADTTL + *\li ISC_R_SUCCESS + *\li DNS_R_BADTTL */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h index 27995de..8dcbe57 100644 --- a/contrib/bind9/lib/dns/include/dns/types.h +++ b/contrib/bind9/lib/dns/include/dns/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,21 +15,25 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.103.12.9 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: types.h,v 1.109.18.12 2006/05/02 12:55:31 shane Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 -/* +/*! \file + * \brief * Including this file gives you type declarations suitable for use in * .h files, which lets us avoid circular type reference problems. - * + * \brief * To actually use a type or get declarations of its methods, you must * include the appropriate .h file too. */ #include <isc/types.h> +typedef struct dns_acache dns_acache_t; +typedef struct dns_acacheentry dns_acacheentry_t; +typedef struct dns_acachestats dns_acachestats_t; typedef struct dns_acl dns_acl_t; typedef struct dns_aclelement dns_aclelement_t; typedef struct dns_aclenv dns_aclenv_t; @@ -50,6 +54,9 @@ typedef void dns_dbload_t; typedef void dns_dbnode_t; typedef struct dns_dbtable dns_dbtable_t; typedef void dns_dbversion_t; +typedef struct dns_dlzimplementation dns_dlzimplementation_t; +typedef struct dns_dlzdb dns_dlzdb_t; +typedef struct dns_sdlzimplementation dns_sdlzimplementation_t; typedef struct dns_decompress dns_decompress_t; typedef struct dns_dispatch dns_dispatch_t; typedef struct dns_dispatchevent dns_dispatchevent_t; @@ -136,7 +143,8 @@ typedef enum { typedef enum { dns_notifytype_no = 0, dns_notifytype_yes = 1, - dns_notifytype_explicit = 2 + dns_notifytype_explicit = 2, + dns_notifytype_masteronly = 3 } dns_notifytype_t; typedef enum { @@ -148,13 +156,19 @@ typedef enum { dns_dialuptype_passive = 5 } dns_dialuptype_t; +typedef enum { + dns_masterformat_none = 0, + dns_masterformat_text = 1, + dns_masterformat_raw = 2 +} dns_masterformat_t; + /* * These are generated by gen.c. */ #include <dns/enumtype.h> /* Provides dns_rdatatype_t. */ #include <dns/enumclass.h> /* Provides dns_rdataclass_t. */ -/* +/*% * rcodes. */ enum { @@ -190,7 +204,7 @@ enum { #define dns_rcode_badvers ((dns_rcode_t)dns_rcode_badvers) }; -/* +/*% * TSIG errors. */ enum { @@ -199,10 +213,11 @@ enum { dns_tsigerror_badtime = 18, dns_tsigerror_badmode = 19, dns_tsigerror_badname = 20, - dns_tsigerror_badalg = 21 + dns_tsigerror_badalg = 21, + dns_tsigerror_badtrunc = 22 }; -/* +/*% * Opcodes. */ enum { @@ -218,7 +233,7 @@ enum { #define dns_opcode_update ((dns_opcode_t)dns_opcode_update) }; -/* +/*% * Trust levels. Must be kept in sync with trustnames[] in masterdump.c. */ enum { @@ -226,11 +241,11 @@ enum { dns_trust_none = 0, #define dns_trust_none ((dns_trust_t)dns_trust_none) - /* Subject to DNSSEC validation but has not yet been validated */ + /*% Subject to DNSSEC validation but has not yet been validated */ dns_trust_pending = 1, #define dns_trust_pending ((dns_trust_t)dns_trust_pending) - /* Received in the additional section of a response. */ + /*% Received in the additional section of a response. */ dns_trust_additional = 2, #define dns_trust_additional ((dns_trust_t)dns_trust_additional) @@ -260,7 +275,7 @@ enum { #define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate) }; -/* +/*% * Name checking severites. */ typedef enum { @@ -294,6 +309,20 @@ typedef void (*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *); typedef int -(*dns_rdatasetorderfunc_t)(const dns_rdata_t *rdata, const void *arg); +(*dns_rdatasetorderfunc_t)(const dns_rdata_t *, const void *); + +typedef isc_boolean_t +(*dns_checkmxfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *); + +typedef isc_boolean_t +(*dns_checksrvfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *); + +typedef isc_boolean_t +(*dns_checknsfunc_t)(dns_zone_t *, dns_name_t *, dns_name_t *, + dns_rdataset_t *, dns_rdataset_t *); + +typedef isc_boolean_t +(*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *, + isc_sockaddr_t *, dns_rdataclass_t, void *); #endif /* DNS_TYPES_H */ diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h index a0d6acb..acce76e 100644 --- a/contrib/bind9/lib/dns/include/dns/validator.h +++ b/contrib/bind9/lib/dns/include/dns/validator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.h,v 1.18.12.11.6.1 2007/01/11 04:51:39 marka Exp $ */ +/* $Id: validator.h,v 1.27.18.8 2007/01/08 02:42:00 marka Exp $ */ #ifndef DNS_VALIDATOR_H #define DNS_VALIDATOR_H 1 diff --git a/contrib/bind9/lib/dns/include/dns/version.h b/contrib/bind9/lib/dns/include/dns/version.h index 28c83be..bb254534 100644 --- a/contrib/bind9/lib/dns/include/dns/version.h +++ b/contrib/bind9/lib/dns/include/dns/version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: version.h,v 1.2.224.3 2004/03/08 09:04:40 marka Exp $ */ +/* $Id: version.h,v 1.3.18.2 2005/04/29 00:16:25 marka Exp $ */ + +/*! \file */ #include <isc/platform.h> diff --git a/contrib/bind9/lib/dns/include/dns/view.h b/contrib/bind9/lib/dns/include/dns/view.h index a3cd935..ea3d4c7 100644 --- a/contrib/bind9/lib/dns/include/dns/view.h +++ b/contrib/bind9/lib/dns/include/dns/view.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.h,v 1.73.2.4.2.12 2004/03/10 02:55:58 marka Exp $ */ +/* $Id: view.h,v 1.91.18.9 2006/03/09 23:38:21 marka Exp $ */ #ifndef DNS_VIEW_H #define DNS_VIEW_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * DNS View * * A "view" is a DNS namespace, together with an optional resolver and a @@ -41,22 +42,22 @@ * to be accessed without locking. * * MP: - * Before the view is frozen, the caller must ensure synchronization. + *\li Before the view is frozen, the caller must ensure synchronization. * - * After the view is frozen, the module guarantees appropriate + *\li After the view is frozen, the module guarantees appropriate * synchronization of any data structures it creates and manipulates. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * None. + *\li None. */ #include <stdio.h> @@ -83,9 +84,11 @@ struct dns_view { dns_rdataclass_t rdclass; char * name; dns_zt_t * zonetable; + dns_dlzdb_t * dlzdatabase; dns_resolver_t * resolver; dns_adb_t * adb; dns_requestmgr_t * requestmgr; + dns_acache_t * acache; dns_cache_t * cache; dns_db_t * cachedb; dns_db_t * hints; @@ -109,6 +112,8 @@ struct dns_view { isc_boolean_t additionalfromauth; isc_boolean_t minimalresponses; isc_boolean_t enablednssec; + isc_boolean_t enablevalidation; + isc_boolean_t acceptexpired; dns_transfer_format_t transfer_format; dns_acl_t * queryacl; dns_acl_t * recursionacl; @@ -127,6 +132,7 @@ struct dns_view { isc_boolean_t checknames; dns_name_t * dlv; dns_fixedname_t dlv_fixed; + isc_uint16_t maxudp; /* * Configurable data for server use only, @@ -156,109 +162,109 @@ struct dns_view { isc_result_t dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, const char *name, dns_view_t **viewp); -/* +/*%< * Create a view. * * Notes: * - * The newly created view has no cache, no resolver, and an empty + *\li The newly created view has no cache, no resolver, and an empty * zone table. The view is not frozen. * * Requires: * - * 'mctx' is a valid memory context. + *\li 'mctx' is a valid memory context. * - * 'rdclass' is a valid class. + *\li 'rdclass' is a valid class. * - * 'name' is a valid C string. + *\li 'name' is a valid C string. * - * viewp != NULL && *viewp == NULL + *\li viewp != NULL && *viewp == NULL * * Returns: * - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY * - * Other errors are possible. + *\li Other errors are possible. */ void dns_view_attach(dns_view_t *source, dns_view_t **targetp); -/* +/*%< * Attach '*targetp' to 'source'. * * Requires: * - * 'source' is a valid, frozen view. + *\li 'source' is a valid, frozen view. * - * 'targetp' points to a NULL dns_view_t *. + *\li 'targetp' points to a NULL dns_view_t *. * * Ensures: * - * *targetp is attached to source. + *\li *targetp is attached to source. * - * While *targetp is attached, the view will not shut down. + *\li While *targetp is attached, the view will not shut down. */ void dns_view_detach(dns_view_t **viewp); -/* +/*%< * Detach '*viewp' from its view. * * Requires: * - * 'viewp' points to a valid dns_view_t * + *\li 'viewp' points to a valid dns_view_t * * * Ensures: * - * *viewp is NULL. + *\li *viewp is NULL. */ void dns_view_flushanddetach(dns_view_t **viewp); -/* +/*%< * Detach '*viewp' from its view. If this was the last reference * uncommited changed in zones will be flushed to disk. * * Requires: * - * 'viewp' points to a valid dns_view_t * + *\li 'viewp' points to a valid dns_view_t * * * Ensures: * - * *viewp is NULL. + *\li *viewp is NULL. */ void dns_view_weakattach(dns_view_t *source, dns_view_t **targetp); -/* +/*%< * Weakly attach '*targetp' to 'source'. * * Requires: * - * 'source' is a valid, frozen view. + *\li 'source' is a valid, frozen view. * - * 'targetp' points to a NULL dns_view_t *. + *\li 'targetp' points to a NULL dns_view_t *. * * Ensures: * - * *targetp is attached to source. + *\li *targetp is attached to source. * - * While *targetp is attached, the view will not be freed. + * \li While *targetp is attached, the view will not be freed. */ void dns_view_weakdetach(dns_view_t **targetp); -/* +/*%< * Detach '*viewp' from its view. * * Requires: * - * 'viewp' points to a valid dns_view_t *. + *\li 'viewp' points to a valid dns_view_t *. * * Ensures: * - * *viewp is NULL. + *\li *viewp is NULL. */ isc_result_t @@ -270,94 +276,94 @@ dns_view_createresolver(dns_view_t *view, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6); -/* +/*%< * Create a resolver and address database for the view. * * Requires: * - * 'view' is a valid, unfrozen view. + *\li 'view' is a valid, unfrozen view. * - * 'view' does not have a resolver already. + *\li 'view' does not have a resolver already. * - * The requirements of dns_resolver_create() apply to 'taskmgr', + *\li The requirements of dns_resolver_create() apply to 'taskmgr', * 'ntasks', 'socketmgr', 'timermgr', 'options', 'dispatchv4', and * 'dispatchv6'. * * Returns: * - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS * - * Any error that dns_resolver_create() can return. + *\li Any error that dns_resolver_create() can return. */ void dns_view_setcache(dns_view_t *view, dns_cache_t *cache); -/* +/*%< * Set the view's cache database. * * Requires: * - * 'view' is a valid, unfrozen view. + *\li 'view' is a valid, unfrozen view. * - * 'cache' is a valid cache. + *\li 'cache' is a valid cache. * * Ensures: * - * The cache of 'view' is 'cached. + * \li The cache of 'view' is 'cached. * - * If this is not the first call to dns_view_setcache() for this + *\li If this is not the first call to dns_view_setcache() for this * view, then previously set cache is detached. */ void dns_view_sethints(dns_view_t *view, dns_db_t *hints); -/* +/*%< * Set the view's hints database. * * Requires: * - * 'view' is a valid, unfrozen view, whose hints database has not been + *\li 'view' is a valid, unfrozen view, whose hints database has not been * set. * - * 'hints' is a valid zone database. + *\li 'hints' is a valid zone database. * * Ensures: * - * The hints database of 'view' is 'hints'. + * \li The hints database of 'view' is 'hints'. */ void dns_view_setkeyring(dns_view_t *view, dns_tsig_keyring_t *ring); -/* +/*%< * Set the view's static TSIG keys * * Requires: * - * 'view' is a valid, unfrozen view, whose static TSIG keyring has not + * \li 'view' is a valid, unfrozen view, whose static TSIG keyring has not * been set. * - * 'ring' is a valid TSIG keyring + *\li 'ring' is a valid TSIG keyring * * Ensures: * - * The static TSIG keyring of 'view' is 'ring'. + *\li The static TSIG keyring of 'view' is 'ring'. */ void dns_view_setdstport(dns_view_t *view, in_port_t dstport); -/* +/*%< * Set the view's destination port. This is the port to * which outgoing queries are sent. The default is 53, * the standard DNS port. * * Requires: * - * 'view' is a valid view. + *\li 'view' is a valid view. * - * 'dstport' is a valid TCP/UDP port number. + *\li 'dstport' is a valid TCP/UDP port number. * * Ensures: - * External name servers will be assumed to be listning + *\li External name servers will be assumed to be listning * on 'dstport'. For servers whose address has already * obtained obtained at the time of the call, the view may * continue to use the previously set port until the address @@ -367,28 +373,28 @@ dns_view_setdstport(dns_view_t *view, in_port_t dstport); isc_result_t dns_view_addzone(dns_view_t *view, dns_zone_t *zone); -/* +/*%< * Add zone 'zone' to 'view'. * * Requires: * - * 'view' is a valid, unfrozen view. + *\li 'view' is a valid, unfrozen view. * - * 'zone' is a valid zone. + *\li 'zone' is a valid zone. */ void dns_view_freeze(dns_view_t *view); -/* +/*%< * Freeze view. * * Requires: * - * 'view' is a valid, unfrozen view. + *\li 'view' is a valid, unfrozen view. * * Ensures: * - * 'view' is frozen. + *\li 'view' is frozen. */ isc_result_t @@ -396,63 +402,63 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_db_t **dbp, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/* +/*%< * Find an rdataset whose owner name is 'name', and whose type is * 'type'. * * Notes: * - * See the description of dns_db_find() for information about 'options'. - * If the caller sets DNS_DBFIND_GLUEOK, it must ensure that 'name' + *\li See the description of dns_db_find() for information about 'options'. + * If the caller sets #DNS_DBFIND_GLUEOK, it must ensure that 'name' * and 'type' are appropriate for glue retrieval. * - * If 'now' is zero, then the current time will be used. + *\li If 'now' is zero, then the current time will be used. * - * If 'use_hints' is ISC_TRUE, and the view has a hints database, then + *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then * it will be searched last. If the answer is found in the hints * database, the result code will be DNS_R_HINT. If the name is found * in the hints database but not the type, the result code will be - * DNS_R_HINTNXRRSET. + * #DNS_R_HINTNXRRSET. * - * 'foundname' must meet the requirements of dns_db_find(). + *\li 'foundname' must meet the requirements of dns_db_find(). * - * If 'sigrdataset' is not NULL, and there is a SIG rdataset which + *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which * covers 'type', then 'sigrdataset' will be bound to it. * * Requires: * - * 'view' is a valid, frozen view. + *\li 'view' is a valid, frozen view. * - * 'name' is valid name. + *\li 'name' is valid name. * - * 'type' is a valid dns_rdatatype_t, and is not a meta query type + *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type * except dns_rdatatype_any. * - * dbp == NULL || *dbp == NULL + *\li dbp == NULL || *dbp == NULL * - * nodep == NULL || *nodep == NULL. If nodep != NULL, dbp != NULL. + *\li nodep == NULL || *nodep == NULL. If nodep != NULL, dbp != NULL. * - * 'foundname' is a valid name with a dedicated buffer or NULL. + *\li 'foundname' is a valid name with a dedicated buffer or NULL. * - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * - * 'sigrdataset' is NULL, or is a valid, disassociated rdataset. + *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * * Ensures: * - * In successful cases, 'rdataset', and possibly 'sigrdataset', are + *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are * bound to the found data. * - * If dbp != NULL, it points to the database containing the data. + *\li If dbp != NULL, it points to the database containing the data. * - * If nodep != NULL, it points to the database node containing the data. + *\li If nodep != NULL, it points to the database node containing the data. * - * If foundname != NULL, it contains the full name of the found data. + *\li If foundname != NULL, it contains the full name of the found data. * * Returns: * - * Any result that dns_db_find() can return, with the exception of - * DNS_R_DELEGATION. + *\li Any result that dns_db_find() can return, with the exception of + * #DNS_R_DELEGATION. */ isc_result_t @@ -460,62 +466,63 @@ dns_view_simplefind(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/* +/*%< * Find an rdataset whose owner name is 'name', and whose type is * 'type'. * * Notes: * - * This routine is appropriate for simple, exact-match queries of the + *\li This routine is appropriate for simple, exact-match queries of the * view. 'name' must be a canonical name; there is no DNAME or CNAME * processing. * - * See the description of dns_db_find() for information about 'options'. + *\li See the description of dns_db_find() for information about 'options'. * If the caller sets DNS_DBFIND_GLUEOK, it must ensure that 'name' * and 'type' are appropriate for glue retrieval. * - * If 'now' is zero, then the current time will be used. + *\li If 'now' is zero, then the current time will be used. * - * If 'use_hints' is ISC_TRUE, and the view has a hints database, then + *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then * it will be searched last. If the answer is found in the hints * database, the result code will be DNS_R_HINT. If the name is found * in the hints database but not the type, the result code will be * DNS_R_HINTNXRRSET. * - * If 'sigrdataset' is not NULL, and there is a SIG rdataset which + *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which * covers 'type', then 'sigrdataset' will be bound to it. * * Requires: * - * 'view' is a valid, frozen view. + *\li 'view' is a valid, frozen view. * - * 'name' is valid name. + *\li 'name' is valid name. * - * 'type' is a valid dns_rdatatype_t, and is not a meta query type + *\li 'type' is a valid dns_rdatatype_t, and is not a meta query type * (e.g. dns_rdatatype_any), or dns_rdatatype_rrsig. * - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * - * 'sigrdataset' is NULL, or is a valid, disassociated rdataset. + *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * * Ensures: * - * In successful cases, 'rdataset', and possibly 'sigrdataset', are + *\li In successful cases, 'rdataset', and possibly 'sigrdataset', are * bound to the found data. * * Returns: * - * ISC_R_SUCCESS Success; result is desired type. - * DNS_R_GLUE Success; result is glue. - * DNS_R_HINT Success; result is a hint. - * DNS_R_NCACHENXDOMAIN Success; result is a ncache entry. - * DNS_R_NCACHENXRRSET Success; result is a ncache entry. - * DNS_R_NXDOMAIN The name does not exist. - * DNS_R_NXRRSET The rrset does not exist. - * ISC_R_NOTFOUND No matching data found, + *\li #ISC_R_SUCCESS Success; result is desired type. + *\li DNS_R_GLUE Success; result is glue. + *\li DNS_R_HINT Success; result is a hint. + *\li DNS_R_NCACHENXDOMAIN Success; result is a ncache entry. + *\li DNS_R_NCACHENXRRSET Success; result is a ncache entry. + *\li DNS_R_NXDOMAIN The name does not exist. + *\li DNS_R_NXRRSET The rrset does not exist. + *\li #ISC_R_NOTFOUND No matching data found, * or an error occurred. */ +/*% See dns_view_findzonecut2() */ isc_result_t dns_view_findzonecut(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, @@ -527,7 +534,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, isc_stdtime_t now, unsigned int options, isc_boolean_t use_hints, isc_boolean_t use_cache, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); -/* +/*%< * Find the best known zonecut containing 'name'. * * This uses local authority, cache, and optionally hints data. @@ -535,69 +542,69 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname, * * Notes: * - * If 'now' is zero, then the current time will be used. + *\li If 'now' is zero, then the current time will be used. * - * If 'use_hints' is ISC_TRUE, and the view has a hints database, then + *\li If 'use_hints' is ISC_TRUE, and the view has a hints database, then * it will be searched last. * - * If 'use_cache' is ISC_TRUE, and the view has a cache, then it will be + *\li If 'use_cache' is ISC_TRUE, and the view has a cache, then it will be * searched. * - * If 'sigrdataset' is not NULL, and there is a SIG rdataset which + *\li If 'sigrdataset' is not NULL, and there is a SIG rdataset which * covers 'type', then 'sigrdataset' will be bound to it. * - * If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned + *\li If the DNS_DBFIND_NOEXACT option is set, then the zonecut returned * (if any) will be the deepest known ancestor of 'name'. * * Requires: * - * 'view' is a valid, frozen view. + *\li 'view' is a valid, frozen view. * - * 'name' is valid name. + *\li 'name' is valid name. * - * 'rdataset' is a valid, disassociated rdataset. + *\li 'rdataset' is a valid, disassociated rdataset. * - * 'sigrdataset' is NULL, or is a valid, disassociated rdataset. + *\li 'sigrdataset' is NULL, or is a valid, disassociated rdataset. * * Returns: * - * ISC_R_SUCCESS Success. + *\li #ISC_R_SUCCESS Success. * - * Many other results are possible. + *\li Many other results are possible. */ isc_result_t dns_viewlist_find(dns_viewlist_t *list, const char *name, dns_rdataclass_t rdclass, dns_view_t **viewp); -/* +/*%< * Search for a view with name 'name' and class 'rdclass' in 'list'. * If found, '*viewp' is (strongly) attached to it. * * Requires: * - * 'viewp' points to a NULL dns_view_t *. + *\li 'viewp' points to a NULL dns_view_t *. * * Returns: * - * ISC_R_SUCCESS A matching view was found. - * ISC_R_NOTFOUND No matching view was found. + *\li #ISC_R_SUCCESS A matching view was found. + *\li #ISC_R_NOTFOUND No matching view was found. */ isc_result_t dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep); -/* +/*%< * Search for the zone 'name' in the zone table of 'view'. * If found, 'zonep' is (strongly) attached to it. There * are no partial matches. * * Requires: * - * 'zonep' points to a NULL dns_zone_t *. + *\li 'zonep' points to a NULL dns_zone_t *. * * Returns: - * ISC_R_SUCCESS A matching zone was found. - * ISC_R_NOTFOUND No matching zone was found. - * others An error occurred. + *\li #ISC_R_SUCCESS A matching zone was found. + *\li #ISC_R_NOTFOUND No matching zone was found. + *\li others An error occurred. */ isc_result_t @@ -605,7 +612,7 @@ dns_view_load(dns_view_t *view, isc_boolean_t stop); isc_result_t dns_view_loadnew(dns_view_t *view, isc_boolean_t stop); -/* +/*%< * Load zones attached to this view. dns_view_load() loads * all zones whose master file has changed since the last * load; dns_view_loadnew() loads only zones that have never @@ -616,29 +623,29 @@ dns_view_loadnew(dns_view_t *view, isc_boolean_t stop); * * Requires: * - * 'view' is valid. + *\li 'view' is valid. */ isc_result_t dns_view_gettsig(dns_view_t *view, dns_name_t *keyname, dns_tsigkey_t **keyp); -/* +/*%< * Find the TSIG key configured in 'view' with name 'keyname', * if any. * * Reqires: - * keyp points to a NULL dns_tsigkey_t *. + *\li keyp points to a NULL dns_tsigkey_t *. * * Returns: - * ISC_R_SUCCESS A key was found and '*keyp' now points to it. - * ISC_R_NOTFOUND No key was found. - * others An error occurred. + *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it. + *\li #ISC_R_NOTFOUND No key was found. + *\li others An error occurred. */ isc_result_t dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, dns_tsigkey_t **keyp); -/* +/*%< * Find the TSIG key configured in 'view' for the server whose * address is 'peeraddr', if any. * @@ -646,35 +653,35 @@ dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr, * keyp points to a NULL dns_tsigkey_t *. * * Returns: - * ISC_R_SUCCESS A key was found and '*keyp' now points to it. - * ISC_R_NOTFOUND No key was found. - * others An error occurred. + *\li #ISC_R_SUCCESS A key was found and '*keyp' now points to it. + *\li #ISC_R_NOTFOUND No key was found. + *\li others An error occurred. */ isc_result_t dns_view_checksig(dns_view_t *view, isc_buffer_t *source, dns_message_t *msg); -/* +/*%< * Verifies the signature of a message. * * Requires: * - * 'view' is a valid view. - * 'source' is a valid buffer containing the message - * 'msg' is a valid message + *\li 'view' is a valid view. + *\li 'source' is a valid buffer containing the message + *\li 'msg' is a valid message * * Returns: - * see dns_tsig_verify() + *\li see dns_tsig_verify() */ void dns_view_dialup(dns_view_t *view); -/* +/*%< * Perform dialup-time maintenance on the zones of 'view'. */ isc_result_t dns_view_dumpdbtostream(dns_view_t *view, FILE *fp); -/* +/*%< * Dump the current state of the view 'view' to the stream 'fp' * for purposes of analysis or debugging. * @@ -685,18 +692,18 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp); * * Requires: * - * 'view' is valid. + *\li 'view' is valid. * - * 'fp' refers to a file open for writing. + *\li 'fp' refers to a file open for writing. * * Returns: - * ISC_R_SUCCESS The cache was successfully dumped. - * others An error occurred (see dns_master_dump) + * \li ISC_R_SUCCESS The cache was successfully dumped. + * \li others An error occurred (see dns_master_dump) */ isc_result_t dns_view_flushcache(dns_view_t *view); -/* +/*%< * Flush the view's cache (and ADB). * * Requires: @@ -705,85 +712,93 @@ dns_view_flushcache(dns_view_t *view); * No other tasks are executing. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ isc_result_t dns_view_flushname(dns_view_t *view, dns_name_t *); -/* +/*%< * Flush the given name from the view's cache (and ADB). * * Requires: - * 'view' is valid. - * 'name' is valid. + *\li 'view' is valid. + *\li 'name' is valid. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS * other returns are failures. */ isc_result_t dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); -/* +/*%< * Add the given name to the delegation only table. * * * Requires: - * 'view' is valid. - * 'name' is valid. + *\li 'view' is valid. + *\li 'name' is valid. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ isc_result_t dns_view_excludedelegationonly(dns_view_t *view, dns_name_t *name); -/* +/*%< * Add the given name to be excluded from the root-delegation-only. * * * Requires: - * 'view' is valid. - * 'name' is valid. + *\li 'view' is valid. + *\li 'name' is valid. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ isc_boolean_t dns_view_isdelegationonly(dns_view_t *view, dns_name_t *name); -/* +/*%< * Check if 'name' is in the delegation only table or if * rootdelonly is set that name is not being excluded. * * Requires: - * 'view' is valid. - * 'name' is valid. + *\li 'view' is valid. + *\li 'name' is valid. * * Returns: - * ISC_TRUE if the name is is the table. - * ISC_FALSE othewise. + *\li #ISC_TRUE if the name is is the table. + *\li #ISC_FALSE othewise. */ void dns_view_setrootdelonly(dns_view_t *view, isc_boolean_t value); -/* +/*%< * Set the root delegation only flag. * * Requires: - * 'view' is valid. + *\li 'view' is valid. */ isc_boolean_t dns_view_getrootdelonly(dns_view_t *view); -/* +/*%< * Get the root delegation only flag. * * Requires: - * 'view' is valid. + *\li 'view' is valid. */ +isc_result_t +dns_view_freezezones(dns_view_t *view, isc_boolean_t freeze); +/*%< + * Freeze/thaw updates to master zones. + * + * Requires: + * \li 'view' is valid. + */ #endif /* DNS_VIEW_H */ diff --git a/contrib/bind9/lib/dns/include/dns/xfrin.h b/contrib/bind9/lib/dns/include/dns/xfrin.h index 0f5e086..fcd482e 100644 --- a/contrib/bind9/lib/dns/include/dns/xfrin.h +++ b/contrib/bind9/lib/dns/include/dns/xfrin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.h,v 1.18.136.4 2006/07/20 01:10:29 marka Exp $ */ +/* $Id: xfrin.h,v 1.20.18.5 2006/07/20 01:10:30 marka Exp $ */ #ifndef DNS_XFRIN_H #define DNS_XFRIN_H 1 @@ -24,7 +24,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * Incoming zone transfers (AXFR + IXFR). */ @@ -40,7 +41,7 @@ *** Types ***/ -/* +/*% * A transfer in progress. This is an opaque type. */ typedef struct dns_xfrin_ctx dns_xfrin_ctx_t; @@ -51,6 +52,7 @@ typedef struct dns_xfrin_ctx dns_xfrin_ctx_t; ISC_LANG_BEGINDECLS +/*% see dns_xfrin_create2() */ isc_result_t dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_sockaddr_t *masteraddr, dns_tsigkey_t *tsigkey, @@ -65,7 +67,7 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp); -/* +/*%< * Attempt to start an incoming zone transfer of 'zone' * from 'masteraddr', creating a dns_xfrin_ctx_t object to * manage it. Attach '*xfrp' to the newly created object. @@ -75,17 +77,17 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, * code as arguments when the transfer finishes. * * Requires: - * 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr + *\li 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr * or dns_rdatatype_soa (soa query followed by axfr if * serial is greater than current serial). * - * If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa, + *\li If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa, * the zone has a database. */ void dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr); -/* +/*%< * If the zone transfer 'xfr' has already finished, * do nothing. Otherwise, abort it and cause it to call * its done callback with a status of ISC_R_CANCELLED. @@ -93,14 +95,14 @@ dns_xfrin_shutdown(dns_xfrin_ctx_t *xfr); void dns_xfrin_detach(dns_xfrin_ctx_t **xfrp); -/* +/*%< * Detach a reference to a zone transfer object. * Caller to maintain external locking if required. */ void dns_xfrin_attach(dns_xfrin_ctx_t *source, dns_xfrin_ctx_t **target); -/* +/*%< * Caller to maintain external locking if required. */ diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h index 4baf36a..7cb8272 100644 --- a/contrib/bind9/lib/dns/include/dns/zone.h +++ b/contrib/bind9/lib/dns/include/dns/zone.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.106.2.7.4.18 2006/08/01 03:44:00 marka Exp $ */ +/* $Id: zone.h,v 1.126.18.19 2006/08/01 03:45:21 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 +/*! \file */ + /*** *** Imports ***/ @@ -30,6 +32,7 @@ #include <isc/lang.h> #include <isc/rwlock.h> +#include <dns/masterdump.h> #include <dns/types.h> typedef enum { @@ -39,19 +42,30 @@ typedef enum { dns_zone_stub } dns_zonetype_t; -#define DNS_ZONEOPT_SERVERS 0x00000001U /* perform server checks */ -#define DNS_ZONEOPT_PARENTS 0x00000002U /* perform parent checks */ -#define DNS_ZONEOPT_CHILDREN 0x00000004U /* perform child checks */ -#define DNS_ZONEOPT_NOTIFY 0x00000008U /* perform NOTIFY */ -#define DNS_ZONEOPT_MANYERRORS 0x00000010U /* return many errors on load */ -#define DNS_ZONEOPT_IXFRFROMDIFFS 0x00000020U /* calculate differences */ -#define DNS_ZONEOPT_NOMERGE 0x00000040U /* don't merge journal */ -#define DNS_ZONEOPT_CHECKNS 0x00000080U /* check if NS's are addresses */ -#define DNS_ZONEOPT_FATALNS 0x00000100U /* DNS_ZONEOPT_CHECKNS is fatal */ -#define DNS_ZONEOPT_MULTIMASTER 0x00000200U /* this zone has multiple masters */ -#define DNS_ZONEOPT_USEALTXFRSRC 0x00000400U /* use alternate transfer sources */ -#define DNS_ZONEOPT_CHECKNAMES 0x00000800U /* check-names */ -#define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /* fatal check-name failures */ +#define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */ +#define DNS_ZONEOPT_PARENTS 0x00000002U /*%< perform parent checks */ +#define DNS_ZONEOPT_CHILDREN 0x00000004U /*%< perform child checks */ +#define DNS_ZONEOPT_NOTIFY 0x00000008U /*%< perform NOTIFY */ +#define DNS_ZONEOPT_MANYERRORS 0x00000010U /*%< return many errors on load */ +#define DNS_ZONEOPT_IXFRFROMDIFFS 0x00000020U /*%< calculate differences */ +#define DNS_ZONEOPT_NOMERGE 0x00000040U /*%< don't merge journal */ +#define DNS_ZONEOPT_CHECKNS 0x00000080U /*%< check if NS's are addresses */ +#define DNS_ZONEOPT_FATALNS 0x00000100U /*%< DNS_ZONEOPT_CHECKNS is fatal */ +#define DNS_ZONEOPT_MULTIMASTER 0x00000200U /*%< this zone has multiple masters */ +#define DNS_ZONEOPT_USEALTXFRSRC 0x00000400U /*%< use alternate transfer sources */ +#define DNS_ZONEOPT_CHECKNAMES 0x00000800U /*%< check-names */ +#define DNS_ZONEOPT_CHECKNAMESFAIL 0x00001000U /*%< fatal check-name failures */ +#define DNS_ZONEOPT_CHECKWILDCARD 0x00002000U /*%< check for internal wildcards */ +#define DNS_ZONEOPT_CHECKMX 0x00004000U /*%< check-mx */ +#define DNS_ZONEOPT_CHECKMXFAIL 0x00008000U /*%< fatal check-mx failures */ +#define DNS_ZONEOPT_CHECKINTEGRITY 0x00010000U /*%< perform integrity checks */ +#define DNS_ZONEOPT_CHECKSIBLING 0x00020000U /*%< perform sibling glue checks */ +#define DNS_ZONEOPT_NOCHECKNS 0x00040000U /*%< disable IN NS address checks */ +#define DNS_ZONEOPT_WARNMXCNAME 0x00080000U /*%< warn on MX CNAME check */ +#define DNS_ZONEOPT_IGNOREMXCNAME 0x00100000U /*%< ignore MX CNAME check */ +#define DNS_ZONEOPT_WARNSRVCNAME 0x00200000U /*%< warn on SRV CNAME check */ +#define DNS_ZONEOPT_IGNORESRVCNAME 0x00400000U /*%< ignore SRV CNAME check */ +#define DNS_ZONEOPT_UPDATECHECKKSK 0x00800000U /*%< check dnskey KSK flag */ #ifndef NOMINUM_PUBLIC /* @@ -61,22 +75,22 @@ typedef enum { #endif /* NOMINUM_PUBLIC */ #ifndef DNS_ZONE_MINREFRESH -#define DNS_ZONE_MINREFRESH 300 /* 5 minutes */ +#define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */ #endif #ifndef DNS_ZONE_MAXREFRESH -#define DNS_ZONE_MAXREFRESH 2419200 /* 4 weeks */ +#define DNS_ZONE_MAXREFRESH 2419200 /*%< 4 weeks */ #endif #ifndef DNS_ZONE_DEFAULTREFRESH -#define DNS_ZONE_DEFAULTREFRESH 3600 /* 1 hour */ +#define DNS_ZONE_DEFAULTREFRESH 3600 /*%< 1 hour */ #endif #ifndef DNS_ZONE_MINRETRY -#define DNS_ZONE_MINRETRY 300 /* 5 minutes */ +#define DNS_ZONE_MINRETRY 300 /*%< 5 minutes */ #endif #ifndef DNS_ZONE_MAXRETRY -#define DNS_ZONE_MAXRETRY 1209600 /* 2 weeks */ +#define DNS_ZONE_MAXRETRY 1209600 /*%< 2 weeks */ #endif #ifndef DNS_ZONE_DEFAULTRETRY -#define DNS_ZONE_DEFAULTRETRY 60 /* 1 minute, subject to +#define DNS_ZONE_DEFAULTRETRY 60 /*%< 1 minute, subject to exponential backoff */ #endif @@ -93,126 +107,135 @@ ISC_LANG_BEGINDECLS isc_result_t dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx); -/* +/*%< * Creates a new empty zone and attach '*zonep' to it. * * Requires: - * 'zonep' to point to a NULL pointer. - * 'mctx' to be a valid memory context. + *\li 'zonep' to point to a NULL pointer. + *\li 'mctx' to be a valid memory context. * * Ensures: - * '*zonep' refers to a valid zone. + *\li '*zonep' refers to a valid zone. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * ISC_R_UNEXPECTED + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_UNEXPECTED */ void dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass); -/* +/*%< * Sets the class of a zone. This operation can only be performed * once on a zone. * * Require: - * 'zone' to be a valid zone. - * dns_zone_setclass() not to have been called since the zone was + *\li 'zone' to be a valid zone. + *\li dns_zone_setclass() not to have been called since the zone was * created. - * 'rdclass' != dns_rdataclass_none. + *\li 'rdclass' != dns_rdataclass_none. */ dns_rdataclass_t dns_zone_getclass(dns_zone_t *zone); -/* +/*%< * Returns the current zone class. * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type); -/* +/*%< * Sets the zone type. This operation can only be performed once on * a zone. * * Requires: - * 'zone' to be a valid zone. - * dns_zone_settype() not to have been called since the zone was + *\li 'zone' to be a valid zone. + *\li dns_zone_settype() not to have been called since the zone was * created. - * 'type' != dns_zone_none + *\li 'type' != dns_zone_none */ void dns_zone_setview(dns_zone_t *zone, dns_view_t *view); -/* +/*%< * Associate the zone with a view. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ dns_view_t * dns_zone_getview(dns_zone_t *zone); -/* +/*%< * Returns the zone's associated view. * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin); -/* +/*%< * Sets the zones origin to 'origin'. * * Require: - * 'zone' to be a valid zone. - * 'origin' to be non NULL. + *\li 'zone' to be a valid zone. + *\li 'origin' to be non NULL. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ dns_name_t * dns_zone_getorigin(dns_zone_t *zone); -/* +/*%< * Returns the value of the origin. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setfile(dns_zone_t *zone, const char *file); -/* - * Sets the name of the master file from which the zone - * loads its database to 'file'. For zones that have - * no associated master file, 'file' will be NULL. + +isc_result_t +dns_zone_setfile2(dns_zone_t *zone, const char *file, + dns_masterformat_t format); +/*%< + * Sets the name of the master file in the format of 'format' from which + * the zone loads its database to 'file'. + * + * For zones that have no associated master file, 'file' will be NULL. * * For zones with persistent databases, the file name * setting is ignored. * + * dns_zone_setfile() is a backward-compatible form of + * dns_zone_setfile2(), which always specifies the + * dns_masterformat_text (RFC1035) format. + * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * ISC_R_NOMEMORY - * ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS */ const char * dns_zone_getfile(dns_zone_t *zone); -/* +/*%< * Gets the name of the zone's master file, if any. * * Requires: - * 'zone' to be valid initialised zone. + *\li 'zone' to be valid initialised zone. * * Returns: - * Pointer to null-terminated file name, or NULL. + *\li Pointer to null-terminated file name, or NULL. */ isc_result_t @@ -220,7 +243,7 @@ dns_zone_load(dns_zone_t *zone); isc_result_t dns_zone_loadnew(dns_zone_t *zone); -/* +/*%< * Cause the database to be loaded from its backing store. * Confirm that the minimum requirements for the zone type are * met, otherwise DNS_R_BADZONE is returned. @@ -230,187 +253,216 @@ dns_zone_loadnew(dns_zone_t *zone); * and whose master file has changed since the last load. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * ISC_R_UNEXPECTED - * ISC_R_SUCCESS - * DNS_R_CONTINUE Incremental load has been queued. - * DNS_R_UPTODATE The zone has already been loaded based on + *\li #ISC_R_UNEXPECTED + *\li #ISC_R_SUCCESS + *\li DNS_R_CONTINUE Incremental load has been queued. + *\li DNS_R_UPTODATE The zone has already been loaded based on * file system timestamps. - * DNS_R_BADZONE - * Any result value from dns_db_load(). + *\li DNS_R_BADZONE + *\li Any result value from dns_db_load(). */ void dns_zone_attach(dns_zone_t *source, dns_zone_t **target); -/* +/*%< * Attach '*target' to 'source' incrementing its external * reference count. * * Require: - * 'zone' to be a valid zone. - * 'target' to be non NULL and '*target' to be NULL. + *\li 'zone' to be a valid zone. + *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_zone_detach(dns_zone_t **zonep); -/* +/*%< * Detach from a zone decrementing its external reference count. * If this was the last external reference to the zone it will be * shut down and eventually freed. * * Require: - * 'zonep' to point to a valid zone. + *\li 'zonep' to point to a valid zone. */ void dns_zone_iattach(dns_zone_t *source, dns_zone_t **target); -/* +/*%< * Attach '*target' to 'source' incrementing its internal * reference count. This is intended for use by operations * such as zone transfers that need to prevent the zone * object from being freed but not from shutting down. * * Require: - * The caller is running in the context of the zone's task. - * 'zone' to be a valid zone. - * 'target' to be non NULL and '*target' to be NULL. + *\li The caller is running in the context of the zone's task. + *\li 'zone' to be a valid zone. + *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_zone_idetach(dns_zone_t **zonep); -/* +/*%< * Detach from a zone decrementing its internal reference count. * If there are no more internal or external references to the * zone, it will be freed. * * Require: - * The caller is running in the context of the zone's task. - * 'zonep' to point to a valid zone. + *\li The caller is running in the context of the zone's task. + *\li 'zonep' to point to a valid zone. */ void dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value); -/* +/*%< * Sets ('value' == 'ISC_TRUE') / clears ('value' == 'IS_FALSE') * zone flags. Valid flag bits are DNS_ZONE_F_*. * * Requires - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp); -/* +/*%< * Attach '*dbp' to the database to if it exists otherwise * return DNS_R_NOTLOADED. * * Require: - * 'zone' to be a valid zone. - * 'dbp' to be != NULL && '*dbp' == NULL. + *\li 'zone' to be a valid zone. + *\li 'dbp' to be != NULL && '*dbp' == NULL. * * Returns: - * ISC_R_SUCCESS - * DNS_R_NOTLOADED + *\li #ISC_R_SUCCESS + *\li DNS_R_NOTLOADED */ isc_result_t dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, const char * const *dbargv); -/* +/*%< * Sets the database type to dbargv[0] and database arguments * to subsequent dbargv elements. * 'db_type' is not checked to see if it is a valid database type. * * Require: - * 'zone' to be a valid zone. - * 'database' to be non NULL. - * 'dbargc' to be >= 1 - * 'dbargv' to point to dbargc NULL-terminated strings + *\li 'zone' to be a valid zone. + *\li 'database' to be non NULL. + *\li 'dbargc' to be >= 1 + *\li 'dbargv' to point to dbargc NULL-terminated strings * * Returns: - * ISC_R_NOMEMORY - * ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + */ + +isc_result_t +dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx); +/*%< + * Returns the current dbtype. isc_mem_free() should be used + * to free 'argv' after use. + * + * Require: + *\li 'zone' to be a valid zone. + *\li 'argv' to be non NULL and *argv to be NULL. + *\li 'mctx' to be valid. + * + * Returns: + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS */ void dns_zone_markdirty(dns_zone_t *zone); -/* +/*%< * Mark a zone as 'dirty'. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_expire(dns_zone_t *zone); -/* +/*%< * Mark the zone as expired. If the zone requires dumping cause it to * be initiated. Set the refresh and retry intervals to there default * values and unload the zone. * * Require - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_refresh(dns_zone_t *zone); -/* +/*%< * Initiate zone up to date checks. The zone must already be being * managed. * * Require - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_flush(dns_zone_t *zone); -/* +/*%< * Write the zone to database if there are uncommited changes. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_dump(dns_zone_t *zone); -/* +/*%< * Write the zone to database. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd); -/* - * Write the zone to stream 'fd'. + +isc_result_t +dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, + const dns_master_style_t *style); +/*%< + * Write the zone to stream 'fd' in the specified 'format'. + * If the 'format' is dns_masterformat_text (RFC1035), 'style' also + * specifies the file style (e.g., &dns_master_style_default). + * + * dns_zone_dumptostream() is a backward-compatible form of + * dns_zone_dumptostream2(), which always uses the dns_masterformat_text + * format and the dns_master_style_default style. + * + * Note that dns_zone_dumptostream2() is the most flexible form. It + * can also provide the functionality of dns_zone_fulldumptostream(). * * Require: - * 'zone' to be a valid zone. - * 'fd' to be a stream open for writing. + *\li 'zone' to be a valid zone. + *\li 'fd' to be a stream open for writing. */ isc_result_t dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd); -/* +/*%< * The same as dns_zone_dumptostream, but dumps the zone with * different dump settings (dns_master_style_full). * * Require: - * 'zone' to be a valid zone. - * 'fd' to be a stream open for writing. + *\li 'zone' to be a valid zone. + *\li 'fd' to be a stream open for writing. */ void dns_zone_maintenance(dns_zone_t *zone); -/* +/*%< * Perform regular maintenace on the zone. This is called as a * result of a zone being managed. * * Require - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t @@ -421,108 +473,108 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count); -/* +/*%< * Set the list of master servers for the zone. * * Require: - * 'zone' to be a valid zone. - * 'masters' array of isc_sockaddr_t with port set or NULL. - * 'count' the number of masters. - * 'keynames' array of dns_name_t's for tsig keys or NULL. + *\li 'zone' to be a valid zone. + *\li 'masters' array of isc_sockaddr_t with port set or NULL. + *\li 'count' the number of masters. + *\li 'keynames' array of dns_name_t's for tsig keys or NULL. * - * dns_zone_setmasters() is just a wrapper to setmasterswithkeys(), + * \li dns_zone_setmasters() is just a wrapper to setmasterswithkeys(), * passing NULL in the keynames field. * - * If 'masters' is NULL then 'count' must be zero. + * \li If 'masters' is NULL then 'count' must be zero. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY - * Any result dns_name_dup() can return, if keynames!=NULL + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li Any result dns_name_dup() can return, if keynames!=NULL */ isc_result_t dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, isc_uint32_t count); -/* +/*%< * Set the list of additional servers to be notified when * a zone changes. To clear the list use 'count = 0'. * * Require: - * 'zone' to be a valid zone. - * 'notify' to be non-NULL if count != 0. - * 'count' to be the number of notifyees. + *\li 'zone' to be a valid zone. + *\li 'notify' to be non-NULL if count != 0. + *\li 'count' to be the number of notifyees. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ void dns_zone_unload(dns_zone_t *zone); -/* +/*%< * detach the database from the zone structure. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value); -/* +/*%< * Set given options on ('value' == ISC_TRUE) or off ('value' == - * ISC_FALSE). + * #ISC_FALSE). * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ unsigned int dns_zone_getoptions(dns_zone_t *zone); -/* +/*%< * Returns the current zone options. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val); -/* +/*%< * Set the minimum refresh time. * * Requires: - * 'zone' is valid. - * val > 0. + *\li 'zone' is valid. + *\li val > 0. */ void dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val); -/* +/*%< * Set the maximum refresh time. * * Requires: - * 'zone' is valid. - * val > 0. + *\li 'zone' is valid. + *\li val > 0. */ void dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val); -/* +/*%< * Set the minimum retry time. * * Requires: - * 'zone' is valid. - * val > 0. + *\li 'zone' is valid. + *\li val > 0. */ void dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val); -/* +/*%< * Set the maximum retry time. * * Requires: - * 'zone' is valid. + *\li 'zone' is valid. * val > 0. */ @@ -531,436 +583,454 @@ dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); isc_result_t dns_zone_setaltxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); -/* +/*%< * Set the source address to be used in IPv4 zone transfers. * * Require: - * 'zone' to be a valid zone. - * 'xfrsource' to contain the address. + *\li 'zone' to be a valid zone. + *\li 'xfrsource' to contain the address. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getxfrsource4(dns_zone_t *zone); isc_sockaddr_t * dns_zone_getaltxfrsource4(dns_zone_t *zone); -/* +/*%< * Returns the source address set by a previous dns_zone_setxfrsource4 * call, or the default of inaddr_any, port 0. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); isc_result_t dns_zone_setaltxfrsource6(dns_zone_t *zone, - const isc_sockaddr_t *xfrsource); -/* + const isc_sockaddr_t *xfrsource); +/*%< * Set the source address to be used in IPv6 zone transfers. * * Require: - * 'zone' to be a valid zone. - * 'xfrsource' to contain the address. + *\li 'zone' to be a valid zone. + *\li 'xfrsource' to contain the address. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getxfrsource6(dns_zone_t *zone); isc_sockaddr_t * dns_zone_getaltxfrsource6(dns_zone_t *zone); -/* +/*%< * Returns the source address set by a previous dns_zone_setxfrsource6 * call, or the default of in6addr_any, port 0. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); -/* +/*%< * Set the source address to be used with IPv4 NOTIFY messages. * * Require: - * 'zone' to be a valid zone. - * 'notifysrc' to contain the address. + *\li 'zone' to be a valid zone. + *\li 'notifysrc' to contain the address. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getnotifysrc4(dns_zone_t *zone); -/* +/*%< * Returns the source address set by a previous dns_zone_setnotifysrc4 * call, or the default of inaddr_any, port 0. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); -/* +/*%< * Set the source address to be used with IPv6 NOTIFY messages. * * Require: - * 'zone' to be a valid zone. - * 'notifysrc' to contain the address. + *\li 'zone' to be a valid zone. + *\li 'notifysrc' to contain the address. * * Returns: - * ISC_R_SUCCESS + *\li #ISC_R_SUCCESS */ isc_sockaddr_t * dns_zone_getnotifysrc6(dns_zone_t *zone); -/* +/*%< * Returns the source address set by a previous dns_zone_setnotifysrc6 * call, or the default of in6addr_any, port 0. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl); -/* +/*%< * Sets the notify acl list for the zone. * * Require: - * 'zone' to be a valid zone. - * 'acl' to be a valid acl. + *\li 'zone' to be a valid zone. + *\li 'acl' to be a valid acl. */ void dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl); -/* +/*%< * Sets the query acl list for the zone. * * Require: - * 'zone' to be a valid zone. - * 'acl' to be a valid acl. + *\li 'zone' to be a valid zone. + *\li 'acl' to be a valid acl. */ void dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl); -/* +/*%< * Sets the update acl list for the zone. * * Require: - * 'zone' to be a valid zone. - * 'acl' to be valid acl. + *\li 'zone' to be a valid zone. + *\li 'acl' to be valid acl. */ void dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl); -/* +/*%< * Sets the forward unsigned updates acl list for the zone. * * Require: - * 'zone' to be a valid zone. - * 'acl' to be valid acl. + *\li 'zone' to be a valid zone. + *\li 'acl' to be valid acl. */ void dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl); -/* +/*%< * Sets the transfer acl list for the zone. * * Require: - * 'zone' to be a valid zone. - * 'acl' to be valid acl. + *\li 'zone' to be a valid zone. + *\li 'acl' to be valid acl. */ dns_acl_t * dns_zone_getnotifyacl(dns_zone_t *zone); -/* +/*%< * Returns the current notify acl or NULL. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * acl a pointer to the acl. - * NULL + *\li acl a pointer to the acl. + *\li NULL */ dns_acl_t * dns_zone_getqueryacl(dns_zone_t *zone); -/* +/*%< * Returns the current query acl or NULL. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * acl a pointer to the acl. - * NULL + *\li acl a pointer to the acl. + *\li NULL */ dns_acl_t * dns_zone_getupdateacl(dns_zone_t *zone); -/* +/*%< * Returns the current update acl or NULL. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * acl a pointer to the acl. - * NULL + *\li acl a pointer to the acl. + *\li NULL */ dns_acl_t * dns_zone_getforwardacl(dns_zone_t *zone); -/* +/*%< * Returns the current forward unsigned updates acl or NULL. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * acl a pointer to the acl. - * NULL + *\li acl a pointer to the acl. + *\li NULL */ dns_acl_t * dns_zone_getxfracl(dns_zone_t *zone); -/* +/*%< * Returns the current transfer acl or NULL. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * acl a pointer to the acl. - * NULL + *\li acl a pointer to the acl. + *\li NULL */ void dns_zone_clearupdateacl(dns_zone_t *zone); -/* +/*%< * Clear the current update acl. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_clearforwardacl(dns_zone_t *zone); -/* +/*%< * Clear the current forward unsigned updates acl. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_clearnotifyacl(dns_zone_t *zone); -/* +/*%< * Clear the current notify acl. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_clearqueryacl(dns_zone_t *zone); -/* +/*%< * Clear the current query acl. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_clearxfracl(dns_zone_t *zone); -/* +/*%< * Clear the current transfer acl. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_boolean_t dns_zone_getupdatedisabled(dns_zone_t *zone); +/*%< + * Return update disabled. + */ void dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state); +/*%< + * Set update disabled. + */ + +isc_boolean_t +dns_zone_getzeronosoattl(dns_zone_t *zone); +/*%< + * Return zero-no-soa-ttl status. + */ + +void +dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state); +/*%< + * Set zero-no-soa-ttl status. + */ void dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity); -/* +/*%< * Set the severity of name checking when loading a zone. * * Require: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ dns_severity_t dns_zone_getchecknames(dns_zone_t *zone); -/* +/*%< * Return the current severity of name checking. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ void dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size); -/* +/*%< * Sets the journal size for the zone. * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_int32_t dns_zone_getjournalsize(dns_zone_t *zone); -/* +/*%< * Return the journal size as set with a previous call to * dns_zone_setjournalsize(). * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, dns_message_t *msg); -/* +/*%< * Tell the zone that it has recieved a NOTIFY message from another * server. This may cause some zone maintainence activity to occur. * * Requires: - * 'zone' to be a valid zone. - * '*from' to contain the address of the server from which 'msg' + *\li 'zone' to be a valid zone. + *\li '*from' to contain the address of the server from which 'msg' * was recieved. - * 'msg' a message with opcode NOTIFY and qr clear. + *\li 'msg' a message with opcode NOTIFY and qr clear. * * Returns: - * DNS_R_REFUSED - * DNS_R_NOTIMP - * DNS_R_FORMERR - * DNS_R_SUCCESS + *\li DNS_R_REFUSED + *\li DNS_R_NOTIMP + *\li DNS_R_FORMERR + *\li DNS_R_SUCCESS */ void dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin); -/* +/*%< * Set the maximum time (in seconds) that a zone transfer in (AXFR/IXFR) * of this zone will use before being aborted. * * Requires: - * 'zone' to be valid initialised zone. + * \li 'zone' to be valid initialised zone. */ isc_uint32_t dns_zone_getmaxxfrin(dns_zone_t *zone); -/* +/*%< * Returns the maximum transfer time for this zone. This will be * either the value set by the last call to dns_zone_setmaxxfrin() or * the default value of 1 hour. * * Requires: - * 'zone' to be valid initialised zone. + *\li 'zone' to be valid initialised zone. */ void dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout); -/* +/*%< * Set the maximum time (in seconds) that a zone transfer out (AXFR/IXFR) * of this zone will use before being aborted. * * Requires: - * 'zone' to be valid initialised zone. + * \li 'zone' to be valid initialised zone. */ isc_uint32_t dns_zone_getmaxxfrout(dns_zone_t *zone); -/* +/*%< * Returns the maximum transfer time for this zone. This will be * either the value set by the last call to dns_zone_setmaxxfrout() or * the default value of 1 hour. * * Requires: - * 'zone' to be valid initialised zone. + *\li 'zone' to be valid initialised zone. */ isc_result_t dns_zone_setjournal(dns_zone_t *zone, const char *journal); -/* +/*%< * Sets the filename used for journaling updates / IXFR transfers. * The default journal name is set by dns_zone_setfile() to be * "file.jnl". If 'journal' is NULL, the zone will have no * journal name. * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY */ char * dns_zone_getjournal(dns_zone_t *zone); -/* +/*%< * Returns the journal name associated with this zone. * If no journal has been set this will be NULL. * * Requires: - * 'zone' to be valid initialised zone. + *\li 'zone' to be valid initialised zone. */ dns_zonetype_t dns_zone_gettype(dns_zone_t *zone); -/* +/*%< * Returns the type of the zone (master/slave/etc.) * * Requires: - * 'zone' to be valid initialised zone. + *\li 'zone' to be valid initialised zone. */ void dns_zone_settask(dns_zone_t *zone, isc_task_t *task); -/* +/*%< * Give a zone a task to work with. Any current task will be detached. * * Requires: - * 'zone' to be valid. - * 'task' to be valid. + *\li 'zone' to be valid. + *\li 'task' to be valid. */ void dns_zone_gettask(dns_zone_t *zone, isc_task_t **target); -/* +/*%< * Attach '*target' to the zone's task. * * Requires: - * 'zone' to be valid initialised zone. - * 'zone' to have a task. - * 'target' to be != NULL && '*target' == NULL. + *\li 'zone' to be valid initialised zone. + *\li 'zone' to have a task. + *\li 'target' to be != NULL && '*target' == NULL. */ void dns_zone_notify(dns_zone_t *zone); -/* +/*%< * Generate notify events for this zone. * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump); -/* +/*%< * Replace the database of "zone" with a new database "db". * * If "dump" is ISC_TRUE, then the new zone contents are dumped @@ -974,11 +1044,11 @@ dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump); * journal file, and the master file dump is postponed. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. * * Returns: - * DNS_R_SUCCESS - * DNS_R_BADZONE zone failed basic consistancy checks: + * \li DNS_R_SUCCESS + * \li DNS_R_BADZONE zone failed basic consistancy checks: * * a single SOA must exist * * some NS records must exist. * Others @@ -986,111 +1056,111 @@ dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump); isc_uint32_t dns_zone_getidlein(dns_zone_t *zone); -/* +/*%< * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. * * Returns: - * number of seconds of idle time before we abort the transfer in. + * \li number of seconds of idle time before we abort the transfer in. */ void dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein); -/* - * Set the idle timeout for transfer the. - * Zero set the default value, 1 hour. +/*%< + * \li Set the idle timeout for transfer the. + * \li Zero set the default value, 1 hour. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ isc_uint32_t dns_zone_getidleout(dns_zone_t *zone); -/* +/*%< * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. * * Returns: - * number of seconds of idle time before we abort a transfer out. + * \li number of seconds of idle time before we abort a transfer out. */ void dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout); -/* - * Set the idle timeout for transfers out. - * Zero set the default value, 1 hour. +/*%< + * \li Set the idle timeout for transfers out. + * \li Zero set the default value, 1 hour. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ void dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table); -/* +/*%< * Get the simple-secure-update policy table. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ void dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table); -/* +/*%< * Set / clear the simple-secure-update policy table. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ isc_mem_t * dns_zone_getmctx(dns_zone_t *zone); -/* +/*%< * Get the memory context of a zone. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ dns_zonemgr_t * dns_zone_getmgr(dns_zone_t *zone); -/* +/*%< * If 'zone' is managed return the zone manager otherwise NULL. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ void dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval); -/* +/*%< * Set the zone's SIG validity interval. This is the length of time * for which DNSSEC signatures created as a result of dynamic updates * to secure zones will remain valid, in seconds. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ isc_uint32_t dns_zone_getsigvalidityinterval(dns_zone_t *zone); -/* +/*%< * Get the zone's SIG validity interval. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ void dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype); -/* +/*%< * Sets zone notify method to "notifytype" */ isc_result_t dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, dns_updatecallback_t callback, void *callback_arg); -/* +/*%< * Forward 'msg' to each master in turn until we get an answer or we * have exausted the list of masters. 'callback' will be called with * ISC_R_SUCCESS if we get an answer and the returned message will be @@ -1100,69 +1170,69 @@ dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg, * (callback)(callback_arg, result, answer_message); * * Require: - * 'zone' to be valid - * 'msg' to be valid. - * 'callback' to be non NULL. + *\li 'zone' to be valid + *\li 'msg' to be valid. + *\li 'callback' to be non NULL. * Returns: - * ISC_R_SUCCESS if the message has been forwarded, - * ISC_R_NOMEMORY - * Others + *\li #ISC_R_SUCCESS if the message has been forwarded, + *\li #ISC_R_NOMEMORY + *\li Others */ isc_result_t dns_zone_next(dns_zone_t *zone, dns_zone_t **next); -/* +/*%< * Find the next zone in the list of managed zones. * * Requires: - * 'zone' to be valid - * The zone manager for the indicated zone MUST be locked + *\li 'zone' to be valid + *\li The zone manager for the indicated zone MUST be locked * by the caller. This is not checked. - * 'next' be non-NULL, and '*next' be NULL. + *\li 'next' be non-NULL, and '*next' be NULL. * * Ensures: - * 'next' points to a valid zone (result ISC_R_SUCCESS) or to NULL + *\li 'next' points to a valid zone (result ISC_R_SUCCESS) or to NULL * (result ISC_R_NOMORE). */ isc_result_t dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first); -/* +/*%< * Find the first zone in the list of managed zones. * * Requires: - * 'zonemgr' to be valid - * The zone manager for the indicated zone MUST be locked + *\li 'zonemgr' to be valid + *\li The zone manager for the indicated zone MUST be locked * by the caller. This is not checked. - * 'first' be non-NULL, and '*first' be NULL + *\li 'first' be non-NULL, and '*first' be NULL * * Ensures: - * 'first' points to a valid zone (result ISC_R_SUCCESS) or to NULL + *\li 'first' points to a valid zone (result ISC_R_SUCCESS) or to NULL * (result ISC_R_NOMORE). */ isc_result_t dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory); -/* +/*%< * Sets the name of the directory where private keys used for * online signing of dynamic zones are found. * * Require: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. * * Returns: - * ISC_R_NOMEMORY - * ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS */ const char * dns_zone_getkeydirectory(dns_zone_t *zone); -/* +/*%< * Gets the name of the directory where private keys used for * online signing of dynamic zones are found. * * Requires: - * 'zone' to be valid initialised zone. + *\li 'zone' to be valid initialised zone. * * Returns: * Pointer to null-terminated file name, or NULL. @@ -1173,231 +1243,231 @@ isc_result_t dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, dns_zonemgr_t **zmgrp); -/* +/*%< * Create a zone manager. * * Requires: - * 'mctx' to be a valid memory context. - * 'taskmgr' to be a valid task manager. - * 'timermgr' to be a valid timer manager. - * 'zmgrp' to point to a NULL pointer. + *\li 'mctx' to be a valid memory context. + *\li 'taskmgr' to be a valid task manager. + *\li 'timermgr' to be a valid timer manager. + *\li 'zmgrp' to point to a NULL pointer. */ isc_result_t dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); -/* +/*%< * Bring the zone under control of a zone manager. * * Require: - * 'zmgr' to be a valid zone manager. - * 'zone' to be a valid zone. + *\li 'zmgr' to be a valid zone manager. + *\li 'zone' to be a valid zone. */ isc_result_t dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr); -/* +/*%< * Force zone maintenance of all zones managed by 'zmgr' at its * earliest conveniene. */ void dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr); -/* +/*%< * Attempt to start any stalled zone transfers. */ void dns_zonemgr_shutdown(dns_zonemgr_t *zmgr); -/* +/*%< * Shut down the zone manager. * * Requires: - * 'zmgr' to be a valid zone manager. + *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target); -/* +/*%< * Attach '*target' to 'source' incrementing its external * reference count. * * Require: - * 'zone' to be a valid zone. - * 'target' to be non NULL and '*target' to be NULL. + *\li 'zone' to be a valid zone. + *\li 'target' to be non NULL and '*target' to be NULL. */ void dns_zonemgr_detach(dns_zonemgr_t **zmgrp); -/* +/*%< * Detach from a zone manager. * * Requires: - * '*zmgrp' is a valid, non-NULL zone manager pointer. + *\li '*zmgrp' is a valid, non-NULL zone manager pointer. * * Ensures: - * '*zmgrp' is NULL. + *\li '*zmgrp' is NULL. */ void dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); -/* +/*%< * Release 'zone' from the managed by 'zmgr'. 'zmgr' is implicitly * detached from 'zone'. * * Requires: - * 'zmgr' to be a valid zone manager. - * 'zone' to be a valid zone. - * 'zmgr' == 'zone->zmgr' + *\li 'zmgr' to be a valid zone manager. + *\li 'zone' to be a valid zone. + *\li 'zmgr' == 'zone->zmgr' * * Ensures: - * 'zone->zmgr' == NULL; + *\li 'zone->zmgr' == NULL; */ void dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value); -/* +/*%< * Set the maximum number of simultaneous transfers in allowed by * the zone manager. * * Requires: - * 'zmgr' to be a valid zone manager. + *\li 'zmgr' to be a valid zone manager. */ isc_uint32_t dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr); -/* +/*%< * Return the the maximum number of simultaneous transfers in allowed. * * Requires: - * 'zmgr' to be a valid zone manager. + *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value); -/* +/*%< * Set the number of zone transfers allowed per nameserver. * * Requires: - * 'zmgr' to be a valid zone manager + *\li 'zmgr' to be a valid zone manager */ isc_uint32_t dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr); -/* +/*%< * Return the number of transfers allowed per nameserver. * * Requires: - * 'zmgr' to be a valid zone manager. + *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit); -/* +/*%< * Set the number of simultaneous file descriptors available for * reading and writing masterfiles. * * Requires: - * 'zmgr' to be a valid zone manager. - * 'iolimit' to be positive. + *\li 'zmgr' to be a valid zone manager. + *\li 'iolimit' to be positive. */ isc_uint32_t dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr); -/* +/*%< * Get the number of simultaneous file descriptors available for * reading and writing masterfiles. * * Requires: - * 'zmgr' to be a valid zone manager. + *\li 'zmgr' to be a valid zone manager. */ void dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value); -/* +/*%< * Set the number of SOA queries sent per second. * * Requires: - * 'zmgr' to be a valid zone manager + *\li 'zmgr' to be a valid zone manager */ unsigned int dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr); -/* +/*%< * Return the number of SOA queries sent per second. * * Requires: - * 'zmgr' to be a valid zone manager. + *\li 'zmgr' to be a valid zone manager. */ unsigned int dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state); -/* +/*%< * Returns the number of zones in the specified state. * * Requires: - * 'zmgr' to be a valid zone manager. - * 'state' to be a valid DNS_ZONESTATE_ constant. + *\li 'zmgr' to be a valid zone manager. + *\li 'state' to be a valid DNS_ZONESTATE_ constant. */ void dns_zone_forcereload(dns_zone_t *zone); -/* +/*%< * Force a reload of specified zone. * * Requires: - * 'zone' to be a valid zone. + *\li 'zone' to be a valid zone. */ isc_boolean_t dns_zone_isforced(dns_zone_t *zone); -/* +/*%< * Check if the zone is waiting a forced reload. * * Requires: - * 'zone' to be a valid zone. + * \li 'zone' to be a valid zone. */ isc_result_t dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on); -/* +/*%< * Make the zone keep or not keep an array of statistics * counter. * * Requires: - * zone be a valid zone. + * \li zone be a valid zone. */ isc_uint64_t * dns_zone_getstatscounters(dns_zone_t *zone); -/* +/*%< * Requires: * zone be a valid zone. * * Returns: - * A pointer to the zone's array of statistics counters, + * \li A pointer to the zone's array of statistics counters, * or NULL if it has none. */ void dns_zone_dialup(dns_zone_t *zone); -/* +/*%< * Perform dialup-time maintenance on 'zone'. */ void dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup); -/* +/*%< * Set the dialup type of 'zone' to 'dialup'. * * Requires: - * 'zone' to be valid initialised zone. - * 'dialup' to be a valid dialup type. + * \li 'zone' to be valid initialised zone. + *\li 'dialup' to be a valid dialup type. */ void dns_zone_log(dns_zone_t *zone, int level, const char *msg, ...) ISC_FORMAT_PRINTF(3, 4); -/* +/*%< * Log the message 'msg...' at 'level', including text that identifies * the message as applying to 'zone'. */ @@ -1405,19 +1475,19 @@ dns_zone_log(dns_zone_t *zone, int level, const char *msg, ...) void dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level, const char *msg, ...) ISC_FORMAT_PRINTF(4, 5); -/* +/*%< * Log the message 'msg...' at 'level', including text that identifies * the message as applying to 'zone'. */ void dns_zone_name(dns_zone_t *zone, char *buf, size_t len); -/* +/*%< * Return the name of the zone with class and view. * * Requires: - * 'zone' to be valid. - * 'buf' to be non NULL. + *\li 'zone' to be valid. + *\li 'buf' to be non NULL. */ isc_result_t @@ -1436,6 +1506,81 @@ dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata); * DNS_R_BADNAME failed rdata checks. */ +void +dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache); +/* + * Associate the zone with an additional cache. + * + * Require: + * 'zone' to be a valid zone. + * 'acache' to be a non NULL pointer. + * + * Ensures: + * 'zone' will have a reference to 'acache' + */ + +void +dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx); +/* + * Set the post load integrity callback function 'checkmx'. + * 'checkmx' will be called if the MX is not within the zone. + * + * Require: + * 'zone' to be a valid zone. + */ + +void +dns_zone_setchecksrv(dns_zone_t *zone, dns_checkmxfunc_t checksrv); +/* + * Set the post load integrity callback function 'checksrv'. + * 'checksrv' will be called if the SRV TARGET is not within the zone. + * + * Require: + * 'zone' to be a valid zone. + */ + +void +dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns); +/* + * Set the post load integrity callback function 'checkmx'. + * 'checkmx' will be called if the MX is not within the zone. + * + * Require: + * 'zone' to be a valid zone. + */ + +void +dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay); +/* + * Set the minimum delay between sets of notify messages. + * + * Requires: + * 'zone' to be valid. + */ + +isc_uint32_t +dns_zone_getnotifydelay(dns_zone_t *zone); +/* + * Get the minimum delay between sets of notify messages. + * + * Requires: + * 'zone' to be valid. + */ + +void +dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg); +/* + * Set the isself callback function and argument. + * + * isc_boolean_t + * isself(dns_view_t *myview, dns_tsigkey_t *mykey, isc_netaddr_t *srcaddr, + * isc_netaddr_t *destaddr, dns_rdataclass_t rdclass, void *arg); + * + * 'isself' returns ISC_TRUE if a non-recursive query from 'srcaddr' to + * 'destaddr' with optional key 'mykey' for class 'rdclass' would be + * delivered to 'myview'. + */ + ISC_LANG_ENDDECLS #endif /* DNS_ZONE_H */ diff --git a/contrib/bind9/lib/dns/include/dns/zonekey.h b/contrib/bind9/lib/dns/include/dns/zonekey.h index 1ac9066..ba4e076 100644 --- a/contrib/bind9/lib/dns/include/dns/zonekey.h +++ b/contrib/bind9/lib/dns/include/dns/zonekey.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zonekey.h,v 1.3.206.1 2004/03/06 08:14:01 marka Exp $ */ +/* $Id: zonekey.h,v 1.4.18.2 2005/04/29 00:16:26 marka Exp $ */ #ifndef DNS_ZONEKEY_H #define DNS_ZONEKEY_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -28,7 +30,7 @@ ISC_LANG_BEGINDECLS isc_boolean_t dns_zonekey_iszonekey(dns_rdata_t *keyrdata); -/* +/*%< * Determines if the key record contained in the rdata is a zone key. * * Requires: diff --git a/contrib/bind9/lib/dns/include/dns/zt.h b/contrib/bind9/lib/dns/include/dns/zt.h index fb43590..436ef4c 100644 --- a/contrib/bind9/lib/dns/include/dns/zt.h +++ b/contrib/bind9/lib/dns/include/dns/zt.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zt.h,v 1.27.2.2.8.1 2004/03/06 08:14:01 marka Exp $ */ +/* $Id: zt.h,v 1.30.18.3 2005/04/27 05:01:42 sra Exp $ */ #ifndef DNS_ZT_H #define DNS_ZT_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -30,101 +32,101 @@ ISC_LANG_BEGINDECLS isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **zt); -/* +/*%< * Creates a new zone table. * * Requires: - * 'mctx' to be initialized. + * \li 'mctx' to be initialized. * * Returns: - * ISC_R_SUCCESS on success. - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS on success. + * \li #ISC_R_NOMEMORY */ isc_result_t dns_zt_mount(dns_zt_t *zt, dns_zone_t *zone); -/* +/*%< * Mounts the zone on the zone table. * * Requires: - * 'zt' to be valid - * 'zone' to be valid + * \li 'zt' to be valid + * \li 'zone' to be valid * * Returns: - * ISC_R_SUCCESS - * ISC_R_EXISTS - * ISC_R_NOSPACE - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_EXISTS + * \li #ISC_R_NOSPACE + * \li #ISC_R_NOMEMORY */ isc_result_t dns_zt_unmount(dns_zt_t *zt, dns_zone_t *zone); -/* +/*%< * Unmount the given zone from the table. * * Requires: * 'zt' to be valid - * 'zone' to be valid + * \li 'zone' to be valid * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOTFOUND - * ISC_R_NOMEMORY + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOTFOUND + * \li #ISC_R_NOMEMORY */ isc_result_t dns_zt_find(dns_zt_t *zt, dns_name_t *name, unsigned int options, dns_name_t *foundname, dns_zone_t **zone); -/* +/*%< * Find the best match for 'name' in 'zt'. If foundname is non NULL * then the name of the zone found is returned. * * Notes: - * If the DNS_ZTFIND_NOEXACT is set, the best partial match (if any) + * \li If the DNS_ZTFIND_NOEXACT is set, the best partial match (if any) * to 'name' will be returned. * * Requires: - * 'zt' to be valid - * 'name' to be valid - * 'foundname' to be initialized and associated with a fixedname or NULL - * 'zone' to be non NULL and '*zone' to be NULL + * \li 'zt' to be valid + * \li 'name' to be valid + * \li 'foundname' to be initialized and associated with a fixedname or NULL + * \li 'zone' to be non NULL and '*zone' to be NULL * * Returns: - * ISC_R_SUCCESS - * DNS_R_PARTIALMATCH - * ISC_R_NOTFOUND - * ISC_R_NOSPACE + * \li #ISC_R_SUCCESS + * \li #DNS_R_PARTIALMATCH + * \li #ISC_R_NOTFOUND + * \li #ISC_R_NOSPACE */ void dns_zt_detach(dns_zt_t **ztp); -/* +/*%< * Detach the given zonetable, if the reference count goes to zero the * zonetable will be freed. In either case 'ztp' is set to NULL. * * Requires: - * '*ztp' to be valid + * \li '*ztp' to be valid */ void dns_zt_flushanddetach(dns_zt_t **ztp); -/* +/*%< * Detach the given zonetable, if the reference count goes to zero the * zonetable will be flushed and then freed. In either case 'ztp' is * set to NULL. * * Requires: - * '*ztp' to be valid + * \li '*ztp' to be valid */ void dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp); -/* +/*%< * Attach 'zt' to '*ztp'. * * Requires: - * 'zt' to be valid - * '*ztp' to be NULL + * \li 'zt' to be valid + * \li '*ztp' to be NULL */ isc_result_t @@ -132,7 +134,7 @@ dns_zt_load(dns_zt_t *zt, isc_boolean_t stop); isc_result_t dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop); -/* +/*%< * Load all zones in the table. If 'stop' is ISC_TRUE, * stop on the first error and return it. If 'stop' * is ISC_FALSE, ignore errors. @@ -142,23 +144,37 @@ dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop); * and whose master file has changed since the last load. * * Requires: - * 'zt' to be valid + * \li 'zt' to be valid + */ + +isc_result_t +dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze); +/*%< + * Freeze/thaw updates to master zones. + * Any pending updates will be flushed. + * Zones will be reloaded on thaw. */ isc_result_t dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop, isc_result_t (*action)(dns_zone_t *, void *), void *uap); -/* + +isc_result_t +dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub, + isc_result_t (*action)(dns_zone_t *, void *), void *uap); +/*%< * Apply a given 'action' to all zone zones in the table. * If 'stop' is 'ISC_TRUE' then walking the zone tree will stop if * 'action' does not return ISC_R_SUCCESS. * * Requires: - * 'zt' to be valid. - * 'action' to be non NULL. + * \li 'zt' to be valid. + * \li 'action' to be non NULL. * * Returns: - * ISC_R_SUCCESS if action was applied to all nodes. + * \li ISC_R_SUCCESS if action was applied to all nodes. If 'stop' is + * ISC_FALSE and 'sub' is non NULL then the first error (if any) + * reported by 'action' is returned in '*sub'; * any error code from 'action'. */ diff --git a/contrib/bind9/lib/dns/include/dst/Makefile.in b/contrib/bind9/lib/dns/include/dst/Makefile.in index efebfaa..deaa221 100644 --- a/contrib/bind9/lib/dns/include/dst/Makefile.in +++ b/contrib/bind9/lib/dns/include/dst/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.1.4.1 2004/12/09 04:07:19 marka Exp $ +# $Id: Makefile.in,v 1.1.6.1 2004/12/09 04:41:47 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ diff --git a/contrib/bind9/lib/dns/include/dst/dst.h b/contrib/bind9/lib/dns/include/dst/dst.h index 1629da5..8d99186 100644 --- a/contrib/bind9/lib/dns/include/dst/dst.h +++ b/contrib/bind9/lib/dns/include/dst/dst.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst.h,v 1.1.4.1 2004/12/09 04:07:19 marka Exp $ */ +/* $Id: dst.h,v 1.1.6.5 2006/01/27 23:57:44 marka Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 +/*! \file */ + #include <isc/lang.h> #include <dns/types.h> @@ -30,7 +32,7 @@ ISC_LANG_BEGINDECLS *** Types ***/ -/* +/*% * The dst_key structure is opaque. Applications should use the accessor * functions provided to retrieve key attributes. If an application needs * to set attributes, new accessor functions will be written. @@ -42,27 +44,32 @@ typedef struct dst_context dst_context_t; /* DST algorithm codes */ #define DST_ALG_UNKNOWN 0 #define DST_ALG_RSAMD5 1 -#define DST_ALG_RSA DST_ALG_RSAMD5 /* backwards compatibility */ +#define DST_ALG_RSA DST_ALG_RSAMD5 /*%< backwards compatibility */ #define DST_ALG_DH 2 #define DST_ALG_DSA 3 #define DST_ALG_ECC 4 #define DST_ALG_RSASHA1 5 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 +#define DST_ALG_HMACSHA1 161 /* XXXMPA */ +#define DST_ALG_HMACSHA224 162 /* XXXMPA */ +#define DST_ALG_HMACSHA256 163 /* XXXMPA */ +#define DST_ALG_HMACSHA384 164 /* XXXMPA */ +#define DST_ALG_HMACSHA512 165 /* XXXMPA */ #define DST_ALG_PRIVATE 254 #define DST_ALG_EXPAND 255 #define DST_MAX_ALGS 255 -/* A buffer of this size is large enough to hold any key */ +/*% A buffer of this size is large enough to hold any key */ #define DST_KEY_MAXSIZE 1280 -/* +/*% * A buffer of this size is large enough to hold the textual representation * of any key */ #define DST_KEY_MAXTEXTSIZE 2048 -/* 'Type' for dst_read_key() */ +/*% 'Type' for dst_read_key() */ #define DST_TYPE_KEY 0x1000000 /* KEY key */ #define DST_TYPE_PRIVATE 0x2000000 #define DST_TYPE_PUBLIC 0x4000000 @@ -73,239 +80,262 @@ typedef struct dst_context dst_context_t; isc_result_t dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags); -/* +/*%< * Initializes the DST subsystem. * * Requires: - * "mctx" is a valid memory context - * "ectx" is a valid entropy context + * \li "mctx" is a valid memory context + * \li "ectx" is a valid entropy context * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li ISC_R_SUCCESS + * \li ISC_R_NOMEMORY * * Ensures: - * DST is properly initialized. + * \li DST is properly initialized. */ void dst_lib_destroy(void); -/* +/*%< * Releases all resources allocated by DST. */ isc_boolean_t dst_algorithm_supported(unsigned int alg); -/* +/*%< * Checks that a given algorithm is supported by DST. * * Returns: - * ISC_TRUE - * ISC_FALSE + * \li ISC_TRUE + * \li ISC_FALSE */ isc_result_t dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp); -/* +/*%< * Creates a context to be used for a sign or verify operation. * * Requires: - * "key" is a valid key. - * "mctx" is a valid memory context. - * dctxp != NULL && *dctxp == NULL + * \li "key" is a valid key. + * \li "mctx" is a valid memory context. + * \li dctxp != NULL && *dctxp == NULL * * Returns: - * ISC_R_SUCCESS - * ISC_R_NOMEMORY + * \li ISC_R_SUCCESS + * \li ISC_R_NOMEMORY * * Ensures: - * *dctxp will contain a usable context. + * \li *dctxp will contain a usable context. */ void dst_context_destroy(dst_context_t **dctxp); -/* +/*%< * Destroys all memory associated with a context. * * Requires: - * *dctxp != NULL && *dctxp == NULL + * \li *dctxp != NULL && *dctxp == NULL * * Ensures: - * *dctxp == NULL + * \li *dctxp == NULL */ isc_result_t dst_context_adddata(dst_context_t *dctx, const isc_region_t *data); -/* +/*%< * Incrementally adds data to the context to be used in a sign or verify * operation. * * Requires: - * "dctx" is a valid context - * "data" is a valid region + * \li "dctx" is a valid context + * \li "data" is a valid region * * Returns: - * ISC_R_SUCCESS - * DST_R_SIGNFAILURE - * all other errors indicate failure + * \li ISC_R_SUCCESS + * \li DST_R_SIGNFAILURE + * \li all other errors indicate failure */ isc_result_t dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig); -/* +/*%< * Computes a signature using the data and key stored in the context. * * Requires: - * "dctx" is a valid context. - * "sig" is a valid buffer. + * \li "dctx" is a valid context. + * \li "sig" is a valid buffer. * * Returns: - * ISC_R_SUCCESS - * DST_R_VERIFYFAILURE - * all other errors indicate failure + * \li ISC_R_SUCCESS + * \li DST_R_VERIFYFAILURE + * \li all other errors indicate failure * * Ensures: - * "sig" will contain the signature + * \li "sig" will contain the signature */ isc_result_t dst_context_verify(dst_context_t *dctx, isc_region_t *sig); -/* +/*%< * Verifies the signature using the data and key stored in the context. * * Requires: - * "dctx" is a valid context. - * "sig" is a valid region. + * \li "dctx" is a valid context. + * \li "sig" is a valid region. * * Returns: - * ISC_R_SUCCESS - * all other errors indicate failure + * \li ISC_R_SUCCESS + * \li all other errors indicate failure * * Ensures: - * "sig" will contain the signature + * \li "sig" will contain the signature */ isc_result_t dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret); -/* +/*%< * Computes a shared secret from two (Diffie-Hellman) keys. * * Requires: - * "pub" is a valid key that can be used to derive a shared secret - * "priv" is a valid private key that can be used to derive a shared secret - * "secret" is a valid buffer + * \li "pub" is a valid key that can be used to derive a shared secret + * \li "priv" is a valid private key that can be used to derive a shared secret + * \li "secret" is a valid buffer * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + * \li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, secret will contain the derived shared secret. + * \li If successful, secret will contain the derived shared secret. */ isc_result_t dst_key_fromfile(dns_name_t *name, dns_keytag_t id, unsigned int alg, int type, const char *directory, isc_mem_t *mctx, dst_key_t **keyp); -/* +/*%< * Reads a key from permanent storage. The key can either be a public or * private key, and is specified by name, algorithm, and id. If a private key * is specified, the public key must also be present. If directory is NULL, * the current directory is assumed. * * Requires: - * "name" is a valid absolute dns name. - * "id" is a valid key tag identifier. - * "alg" is a supported key algorithm. - * "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union. + * \li "name" is a valid absolute dns name. + * \li "id" is a valid key tag identifier. + * \li "alg" is a supported key algorithm. + * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union. * DST_TYPE_KEY look for a KEY record otherwise DNSKEY - * "mctx" is a valid memory context. - * "keyp" is not NULL and "*keyp" is NULL. + * \li "mctx" is a valid memory context. + * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + * \li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, *keyp will contain a valid key. + * \li If successful, *keyp will contain a valid key. */ isc_result_t dst_key_fromnamedfile(const char *filename, int type, isc_mem_t *mctx, dst_key_t **keyp); -/* +/*%< * Reads a key from permanent storage. The key can either be a public or * key, and is specified by filename. If a private key is specified, the * public key must also be present. * * Requires: - * "filename" is not NULL - * "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union + * \li "filename" is not NULL + * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union * DST_TYPE_KEY look for a KEY record otherwise DNSKEY - * "mctx" is a valid memory context - * "keyp" is not NULL and "*keyp" is NULL. + * \li "mctx" is a valid memory context + * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + * \li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, *keyp will contain a valid key. + * \li If successful, *keyp will contain a valid key. + */ + + +isc_result_t +dst_key_read_public(const char *filename, int type, + isc_mem_t *mctx, dst_key_t **keyp); +/*%< + * Reads a public key from permanent storage. The key must be a public key. + * + * Requires: + * \li "filename" is not NULL + * \li "type" is DST_TYPE_KEY look for a KEY record otherwise DNSKEY + * \li "mctx" is a valid memory context + * \li "keyp" is not NULL and "*keyp" is NULL. + * + * Returns: + * \li ISC_R_SUCCESS + * \li DST_R_BADKEYTYPE if the key type is not the expected one + * \li ISC_R_UNEXPECTEDTOKEN if the file can not be parsed as a public key + * \li any other result indicates failure + * + * Ensures: + * \li If successful, *keyp will contain a valid key. */ isc_result_t dst_key_tofile(const dst_key_t *key, int type, const char *directory); -/* +/*%< * Writes a key to permanent storage. The key can either be a public or * private key. Public keys are written in DNS format and private keys * are written as a set of base64 encoded values. If directory is NULL, * the current directory is assumed. * * Requires: - * "key" is a valid key. - * "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union + * \li "key" is a valid key. + * \li "type" is DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or the bitwise union * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + * \li ISC_R_SUCCESS + * \li any other result indicates failure */ isc_result_t dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); -/* +/*%< * Converts a DNS KEY record into a DST key. * * Requires: - * "name" is a valid absolute dns name. - * "source" is a valid buffer. There must be at least 4 bytes available. - * "mctx" is a valid memory context. - * "keyp" is not NULL and "*keyp" is NULL. + * \li "name" is a valid absolute dns name. + * \li "source" is a valid buffer. There must be at least 4 bytes available. + * \li "mctx" is a valid memory context. + * \li "keyp" is not NULL and "*keyp" is NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + * \li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, *keyp will contain a valid key, and the consumed + * \li If successful, *keyp will contain a valid key, and the consumed * pointer in data will be advanced. */ isc_result_t dst_key_todns(const dst_key_t *key, isc_buffer_t *target); -/* +/*%< * Converts a DST key into a DNS KEY record. * * Requires: - * "key" is a valid key. - * "target" is a valid buffer. There must be at least 4 bytes unused. + * \li "key" is a valid key. + * \li "target" is a valid buffer. There must be at least 4 bytes unused. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + * \li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, the used pointer in 'target' is advanced by at least 4. + * \li If successful, the used pointer in 'target' is advanced by at least 4. */ isc_result_t @@ -313,80 +343,80 @@ dst_key_frombuffer(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp); -/* +/*%< * Converts a buffer containing DNS KEY RDATA into a DST key. * * Requires: - * "name" is a valid absolute dns name. - * "alg" is a supported key algorithm. - * "source" is a valid buffer. - * "mctx" is a valid memory context. - * "keyp" is not NULL and "*keyp" is NULL. + *\li "name" is a valid absolute dns name. + *\li "alg" is a supported key algorithm. + *\li "source" is a valid buffer. + *\li "mctx" is a valid memory context. + *\li "keyp" is not NULL and "*keyp" is NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + *\li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, *keyp will contain a valid key, and the consumed + *\li If successful, *keyp will contain a valid key, and the consumed * pointer in source will be advanced. */ isc_result_t dst_key_tobuffer(const dst_key_t *key, isc_buffer_t *target); -/* +/*%< * Converts a DST key into DNS KEY RDATA format. * * Requires: - * "key" is a valid key. - * "target" is a valid buffer. + *\li "key" is a valid key. + *\li "target" is a valid buffer. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + *\li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, the used pointer in 'target' is advanced. + *\li If successful, the used pointer in 'target' is advanced. */ isc_result_t dst_key_privatefrombuffer(dst_key_t *key, isc_buffer_t *buffer); -/* +/*%< * Converts a public key into a private key, reading the private key * information from the buffer. The buffer should contain the same data * as the .private key file would. * * Requires: - * "key" is a valid public key. - * "buffer" is not NULL. + *\li "key" is a valid public key. + *\li "buffer" is not NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + *\li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, key will contain a valid private key. + *\li If successful, key will contain a valid private key. */ isc_result_t dst_key_fromgssapi(dns_name_t *name, void *opaque, isc_mem_t *mctx, dst_key_t **keyp); -/* +/*%< * Converts a GSSAPI opaque context id into a DST key. * * Requires: - * "name" is a valid absolute dns name. - * "opaque" is a GSSAPI context id. - * "mctx" is a valid memory context. - * "keyp" is not NULL and "*keyp" is NULL. + *\li "name" is a valid absolute dns name. + *\li "opaque" is a GSSAPI context id. + *\li "mctx" is a valid memory context. + *\li "keyp" is not NULL and "*keyp" is NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + *\li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, *keyp will contain a valid key and be responsible for + *\li If successful, *keyp will contain a valid key and be responsible for * the context id. */ @@ -396,9 +426,10 @@ dst_key_generate(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp); -/* +/*%< * Generate a DST key (or keypair) with the supplied parameters. The * interpretation of the "param" field depends on the algorithm: + * \code * RSA: exponent * 0 use exponent 3 * !0 use Fermat4 (2^16 + 1) @@ -410,66 +441,67 @@ dst_key_generate(dns_name_t *name, unsigned int alg, * HMACMD5: entropy * 0 default - require good entropy * !0 lack of good entropy is ok + *\endcode * * Requires: - * "name" is a valid absolute dns name. - * "keyp" is not NULL and "*keyp" is NULL. + *\li "name" is a valid absolute dns name. + *\li "keyp" is not NULL and "*keyp" is NULL. * * Returns: - * ISC_R_SUCCESS - * any other result indicates failure + *\li ISC_R_SUCCESS + * \li any other result indicates failure * * Ensures: - * If successful, *keyp will contain a valid key. + *\li If successful, *keyp will contain a valid key. */ isc_boolean_t dst_key_compare(const dst_key_t *key1, const dst_key_t *key2); -/* +/*%< * Compares two DST keys. * * Requires: - * "key1" is a valid key. - * "key2" is a valid key. + *\li "key1" is a valid key. + *\li "key2" is a valid key. * * Returns: - * ISC_TRUE - * ISC_FALSE + *\li ISC_TRUE + * \li ISC_FALSE */ isc_boolean_t dst_key_paramcompare(const dst_key_t *key1, const dst_key_t *key2); -/* +/*%< * Compares the parameters of two DST keys. This is used to determine if * two (Diffie-Hellman) keys can be used to derive a shared secret. * * Requires: - * "key1" is a valid key. - * "key2" is a valid key. + *\li "key1" is a valid key. + *\li "key2" is a valid key. * * Returns: - * ISC_TRUE - * ISC_FALSE + *\li ISC_TRUE + * \li ISC_FALSE */ void dst_key_free(dst_key_t **keyp); -/* +/*%< * Release all memory associated with the key. * * Requires: - * "keyp" is not NULL and "*keyp" is a valid key. + *\li "keyp" is not NULL and "*keyp" is a valid key. * * Ensures: - * All memory associated with "*keyp" will be freed. - * *keyp == NULL + *\li All memory associated with "*keyp" will be freed. + *\li *keyp == NULL */ -/* +/*%< * Accessor functions to obtain key fields. * * Require: - * "key" is a valid key. + *\li "key" is a valid key. */ dns_name_t * dst_key_name(const dst_key_t *key); @@ -504,65 +536,83 @@ dst_key_isnullkey(const dst_key_t *key); isc_result_t dst_key_buildfilename(const dst_key_t *key, int type, const char *directory, isc_buffer_t *out); -/* +/*%< * Generates the filename used by dst to store the specified key. * If directory is NULL, the current directory is assumed. * * Requires: - * "key" is a valid key - * "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or 0 for no suffix. - * "out" is a valid buffer + *\li "key" is a valid key + *\li "type" is either DST_TYPE_PUBLIC, DST_TYPE_PRIVATE, or 0 for no suffix. + *\li "out" is a valid buffer * * Ensures: - * the file name will be written to "out", and the used pointer will + *\li the file name will be written to "out", and the used pointer will * be advanced. */ isc_result_t dst_key_sigsize(const dst_key_t *key, unsigned int *n); -/* +/*%< * Computes the size of a signature generated by the given key. * * Requires: - * "key" is a valid key. - * "n" is not NULL + *\li "key" is a valid key. + *\li "n" is not NULL * * Returns: - * ISC_R_SUCCESS - * DST_R_UNSUPPORTEDALG + *\li #ISC_R_SUCCESS + *\li DST_R_UNSUPPORTEDALG * * Ensures: - * "n" stores the size of a generated signature + *\li "n" stores the size of a generated signature */ isc_result_t dst_key_secretsize(const dst_key_t *key, unsigned int *n); -/* +/*%< * Computes the size of a shared secret generated by the given key. * * Requires: - * "key" is a valid key. - * "n" is not NULL + *\li "key" is a valid key. + *\li "n" is not NULL * * Returns: - * ISC_R_SUCCESS - * DST_R_UNSUPPORTEDALG + *\li #ISC_R_SUCCESS + *\li DST_R_UNSUPPORTEDALG * * Ensures: - * "n" stores the size of a generated shared secret + *\li "n" stores the size of a generated shared secret */ isc_uint16_t dst_region_computeid(const isc_region_t *source, unsigned int alg); -/* +/*%< * Computes the key id of the key stored in the provided region with the * given algorithm. * * Requires: - * "source" contains a valid, non-NULL region. + *\li "source" contains a valid, non-NULL region. * * Returns: - * the key id + *\li the key id + */ + +isc_uint16_t +dst_key_getbits(const dst_key_t *key); +/* + * Get the number of digest bits required (0 == MAX). + * + * Requires: + * "key" is a valid key. + */ + +void +dst_key_setbits(dst_key_t *key, isc_uint16_t bits); +/* + * Set the number of digest bits required (0 == MAX). + * + * Requires: + * "key" is a valid key. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dst/gssapi.h b/contrib/bind9/lib/dns/include/dst/gssapi.h index 1d74656..e30fb0c 100644 --- a/contrib/bind9/lib/dns/include/dst/gssapi.h +++ b/contrib/bind9/lib/dns/include/dst/gssapi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gssapi.h,v 1.1.4.1 2004/12/09 04:07:20 marka Exp $ */ +/* $Id: gssapi.h,v 1.1.6.3 2005/04/29 00:16:28 marka Exp $ */ #ifndef DST_GSSAPI_H #define DST_GSSAPI_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/types.h> diff --git a/contrib/bind9/lib/dns/include/dst/lib.h b/contrib/bind9/lib/dns/include/dst/lib.h index 7a8e73e..bd71261 100644 --- a/contrib/bind9/lib/dns/include/dst/lib.h +++ b/contrib/bind9/lib/dns/include/dst/lib.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lib.h,v 1.1.4.1 2004/12/09 04:07:20 marka Exp $ */ +/* $Id: lib.h,v 1.1.6.3 2005/04/29 00:16:29 marka Exp $ */ #ifndef DST_LIB_H #define DST_LIB_H 1 +/*! \file */ + #include <isc/types.h> #include <isc/lang.h> diff --git a/contrib/bind9/lib/dns/include/dst/result.h b/contrib/bind9/lib/dns/include/dst/result.h index 015e086..aa03b73 100644 --- a/contrib/bind9/lib/dns/include/dst/result.h +++ b/contrib/bind9/lib/dns/include/dst/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.h,v 1.1.4.1 2004/12/09 04:07:20 marka Exp $ */ +/* $Id: result.h,v 1.1.6.3 2005/04/29 00:16:29 marka Exp $ */ #ifndef DST_RESULT_H #define DST_RESULT_H 1 +/*! \file */ + #include <isc/lang.h> #include <isc/resultclass.h> diff --git a/contrib/bind9/lib/dns/journal.c b/contrib/bind9/lib/dns/journal.c index 536416d..1f208c8 100644 --- a/contrib/bind9/lib/dns/journal.c +++ b/contrib/bind9/lib/dns/journal.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: journal.c,v 1.77.2.1.10.13 2005/11/03 23:08:41 marka Exp $ */ +/* $Id: journal.c,v 1.86.18.8 2005/11/03 23:02:23 marka Exp $ */ #include <config.h> @@ -40,7 +40,44 @@ #include <dns/result.h> #include <dns/soa.h> -/* +/*! \file + * \brief Journalling. + * + * A journal file consists of + * + * \li A fixed-size header of type journal_rawheader_t. + * + * \li The index. This is an unordered array of index entries + * of type journal_rawpos_t giving the locations + * of some arbitrary subset of the journal's addressable + * transactions. The index entries are used as hints to + * speed up the process of locating a transaction with a given + * serial number. Unused index entries have an "offset" + * field of zero. The size of the index can vary between + * journal files, but does not change during the lifetime + * of a file. The size can be zero. + * + * \li The journal data. This consists of one or more transactions. + * Each transaction begins with a transaction header of type + * journal_rawxhdr_t. The transaction header is followed by a + * sequence of RRs, similar in structure to an IXFR difference + * sequence (RFC1995). That is, the pre-transaction SOA, + * zero or more other deleted RRs, the post-transaction SOA, + * and zero or more other added RRs. Unlike in IXFR, each RR + * is prefixed with a 32-bit length. + * + * The journal data part grows as new transactions are + * appended to the file. Only those transactions + * whose serial number is current-(2^31-1) to current + * are considered "addressable" and may be pointed + * to from the header or index. They may be preceded + * by old transactions that are no longer addressable, + * and they may be followed by transactions that were + * appended to the journal but never committed by updating + * the "end" position in the header. The latter will + * be overwritten when new transactions are added. + */ +/*% * When true, accept IXFR difference sequences where the * SOA serial number does not change (BIND 8 sends such * sequences). @@ -58,7 +95,7 @@ static isc_boolean_t bind8_compat = ISC_TRUE; /* XXX config */ #define JOURNAL_DEBUG_LOGARGS(n) \ JOURNAL_COMMON_LOGARGS, ISC_LOG_DEBUG(n) -/* +/*% * It would be non-sensical (or at least obtuse) to use FAIL() with an * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". @@ -134,55 +171,16 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, return (result); } -/**************************************************************************/ -/* - * Journalling. - */ +/* Journalling */ -/* - * A journal file consists of - * - * - A fixed-size header of type journal_rawheader_t. - * - * - The index. This is an unordered array of index entries - * of type journal_rawpos_t giving the locations - * of some arbitrary subset of the journal's addressable - * transactions. The index entries are used as hints to - * speed up the process of locating a transaction with a given - * serial number. Unused index entries have an "offset" - * field of zero. The size of the index can vary between - * journal files, but does not change during the lifetime - * of a file. The size can be zero. - * - * - The journal data. This consists of one or more transactions. - * Each transaction begins with a transaction header of type - * journal_rawxhdr_t. The transaction header is followed by a - * sequence of RRs, similar in structure to an IXFR difference - * sequence (RFC1995). That is, the pre-transaction SOA, - * zero or more other deleted RRs, the post-transaction SOA, - * and zero or more other added RRs. Unlike in IXFR, each RR - * is prefixed with a 32-bit length. - * - * The journal data part grows as new transactions are - * appended to the file. Only those transactions - * whose serial number is current-(2^31-1) to current - * are considered "addressable" and may be pointed - * to from the header or index. They may be preceded - * by old transactions that are no longer addressable, - * and they may be followed by transactions that were - * appended to the journal but never committed by updating - * the "end" position in the header. The latter will - * be overwritten when new transactions are added. - */ - -/* +/*% * On-disk representation of a "pointer" to a journal entry. * These are used in the journal header to locate the beginning * and end of the journal, and in the journal index to locate * other transactions. */ typedef struct { - unsigned char serial[4]; /* SOA serial before update. */ + unsigned char serial[4]; /*%< SOA serial before update. */ /* * XXXRTH Should offset be 8 bytes? * XXXDCL ... probably, since isc_offset_t is 8 bytes on many OSs. @@ -190,54 +188,54 @@ typedef struct { * platforms as long as we are using fseek() rather * than lseek(). */ - unsigned char offset[4]; /* Offset from beginning of file. */ + unsigned char offset[4]; /*%< Offset from beginning of file. */ } journal_rawpos_t; -/* - * The on-disk representation of the journal header. - * All numbers are stored in big-endian order. - */ -/* +/*% * The header is of a fixed size, with some spare room for future * extensions. */ #define JOURNAL_HEADER_SIZE 64 /* Bytes. */ +/*% + * The on-disk representation of the journal header. + * All numbers are stored in big-endian order. + */ typedef union { struct { - /* File format version ID. */ + /*% File format version ID. */ unsigned char format[16]; - /* Position of the first addressable transaction */ + /*% Position of the first addressable transaction */ journal_rawpos_t begin; - /* Position of the next (yet nonexistent) transaction. */ + /*% Position of the next (yet nonexistent) transaction. */ journal_rawpos_t end; - /* Number of index entries following the header. */ + /*% Number of index entries following the header. */ unsigned char index_size[4]; } h; /* Pad the header to a fixed size. */ unsigned char pad[JOURNAL_HEADER_SIZE]; } journal_rawheader_t; -/* +/*% * The on-disk representation of the transaction header. * There is one of these at the beginning of each transaction. */ typedef struct { - unsigned char size[4]; /* In bytes, excluding header. */ - unsigned char serial0[4]; /* SOA serial before update. */ - unsigned char serial1[4]; /* SOA serial after update. */ + unsigned char size[4]; /*%< In bytes, excluding header. */ + unsigned char serial0[4]; /*%< SOA serial before update. */ + unsigned char serial1[4]; /*%< SOA serial after update. */ } journal_rawxhdr_t; -/* +/*% * The on-disk representation of the RR header. * There is one of these at the beginning of each RR. */ typedef struct { - unsigned char size[4]; /* In bytes, excluding header. */ + unsigned char size[4]; /*%< In bytes, excluding header. */ } journal_rawrrhdr_t; -/* +/*% * The in-core representation of the journal header. */ typedef struct { @@ -255,7 +253,7 @@ typedef struct { isc_uint32_t index_size; } journal_header_t; -/* +/*% * The in-core representation of the transaction header. */ @@ -265,7 +263,7 @@ typedef struct { isc_uint32_t serial1; } journal_xhdr_t; -/* +/*% * The in-core representation of the RR header. */ typedef struct { @@ -273,7 +271,7 @@ typedef struct { } journal_rrhdr_t; -/* +/*% * Initial contents to store in the header of a newly created * journal file. * @@ -297,40 +295,38 @@ typedef enum { } journal_state_t; struct dns_journal { - unsigned int magic; /* JOUR */ - isc_mem_t *mctx; /* Memory context */ + unsigned int magic; /*%< JOUR */ + isc_mem_t *mctx; /*%< Memory context */ journal_state_t state; - const char *filename; /* Journal file name */ - FILE * fp; /* File handle */ - isc_offset_t offset; /* Current file offset */ - journal_header_t header; /* In-core journal header */ - unsigned char *rawindex; /* In-core buffer for journal - index in on-disk format */ - journal_pos_t *index; /* In-core journal index */ - - /* Current transaction state (when writing). */ + const char *filename; /*%< Journal file name */ + FILE * fp; /*%< File handle */ + isc_offset_t offset; /*%< Current file offset */ + journal_header_t header; /*%< In-core journal header */ + unsigned char *rawindex; /*%< In-core buffer for journal index in on-disk format */ + journal_pos_t *index; /*%< In-core journal index */ + + /*% Current transaction state (when writing). */ struct { - unsigned int n_soa; /* Number of SOAs seen */ - journal_pos_t pos[2]; /* Begin/end position */ + unsigned int n_soa; /*%< Number of SOAs seen */ + journal_pos_t pos[2]; /*%< Begin/end position */ } x; - /* Iteration state (when reading). */ + /*% Iteration state (when reading). */ struct { /* These define the part of the journal we iterate over. */ - journal_pos_t bpos; /* Position before first, */ - journal_pos_t epos; /* and after last - transaction */ + journal_pos_t bpos; /*%< Position before first, */ + journal_pos_t epos; /*%< and after last transaction */ /* The rest is iterator state. */ - isc_uint32_t current_serial; /* Current SOA serial */ - isc_buffer_t source; /* Data from disk */ - isc_buffer_t target; /* Data from _fromwire check */ - dns_decompress_t dctx; /* Dummy decompression ctx */ - dns_name_t name; /* Current domain name */ - dns_rdata_t rdata; /* Current rdata */ - isc_uint32_t ttl; /* Current TTL */ - unsigned int xsize; /* Size of transaction data */ - unsigned int xpos; /* Current position in it */ - isc_result_t result; /* Result of last call */ + isc_uint32_t current_serial; /*%< Current SOA serial */ + isc_buffer_t source; /*%< Data from disk */ + isc_buffer_t target; /*%< Data from _fromwire check */ + dns_decompress_t dctx; /*%< Dummy decompression ctx */ + dns_name_t name; /*%< Current domain name */ + dns_rdata_t rdata; /*%< Current rdata */ + isc_uint32_t ttl; /*%< Current TTL */ + unsigned int xsize; /*%< Size of transaction data */ + unsigned int xpos; /*%< Current position in it */ + isc_result_t result; /*%< Result of last call */ } it; }; diff --git a/contrib/bind9/lib/dns/key.c b/contrib/bind9/lib/dns/key.c index 97d970e..b0f2c0a 100644 --- a/contrib/bind9/lib/dns/key.c +++ b/contrib/bind9/lib/dns/key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: key.c,v 1.1.4.3 2005/06/09 23:54:29 marka Exp $ */ +/* $Id: key.c,v 1.1.6.6 2006/01/27 23:57:44 marka Exp $ */ #include <config.h> @@ -125,3 +125,23 @@ dst_key_isnullkey(const dst_key_t *key) { return (ISC_FALSE); return (ISC_TRUE); } + +void +dst_key_setbits(dst_key_t *key, isc_uint16_t bits) { + unsigned int maxbits; + REQUIRE(VALID_KEY(key)); + if (bits != 0) { + RUNTIME_CHECK(dst_key_sigsize(key, &maxbits) == ISC_R_SUCCESS); + maxbits *= 8; + REQUIRE(bits <= maxbits); + } + key->key_bits = bits; +} + +isc_uint16_t +dst_key_getbits(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_bits); +} + +/*! \file */ diff --git a/contrib/bind9/lib/dns/keytable.c b/contrib/bind9/lib/dns/keytable.c index 7f3e3cf..ec0f8e4 100644 --- a/contrib/bind9/lib/dns/keytable.c +++ b/contrib/bind9/lib/dns/keytable.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keytable.c,v 1.26.12.5 2006/01/06 00:01:42 marka Exp $ */ +/* $Id: keytable.c,v 1.28.18.4 2005/12/05 00:00:03 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -87,22 +89,12 @@ dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) { goto cleanup_keytable; result = isc_mutex_init(&keytable->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_rbt; - } result = isc_rwlock_init(&keytable->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_rwlock_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_lock; - } keytable->mctx = mctx; keytable->active_nodes = 0; diff --git a/contrib/bind9/lib/dns/lib.c b/contrib/bind9/lib/dns/lib.c index 4449067..423908a 100644 --- a/contrib/bind9/lib/dns/lib.c +++ b/contrib/bind9/lib/dns/lib.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lib.c,v 1.9.12.3 2004/03/08 09:04:30 marka Exp $ */ +/* $Id: lib.c,v 1.11.18.3 2005/08/15 01:46:50 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -31,6 +33,7 @@ *** Globals ***/ +LIBDNS_EXTERNAL_DATA unsigned int dns_pps = 0U; LIBDNS_EXTERNAL_DATA isc_msgcat_t * dns_msgcat = NULL; diff --git a/contrib/bind9/lib/dns/log.c b/contrib/bind9/lib/dns/log.c index d240767..939ea36 100644 --- a/contrib/bind9/lib/dns/log.c +++ b/contrib/bind9/lib/dns/log.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: log.c,v 1.33.2.2.10.3 2004/03/06 08:13:39 marka Exp $ */ +/* $Id: log.c,v 1.36.18.4 2005/09/05 00:18:24 marka Exp $ */ + +/*! \file */ /* Principal Authors: DCL */ @@ -25,7 +27,7 @@ #include <dns/log.h> -/* +/*% * When adding a new category, be sure to add the appropriate * #define to <dns/log.h>. */ @@ -44,7 +46,7 @@ LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = { { NULL, 0 } }; -/* +/*% * When adding a new module, be sure to add the appropriate * #define to <dns/log.h>. */ @@ -74,6 +76,8 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = { { "dns/sdb", 0 }, { "dns/diff", 0 }, { "dns/hints", 0 }, + { "dns/acache", 0 }, + { "dns/dlz", 0 }, { NULL, 0 } }; diff --git a/contrib/bind9/lib/dns/lookup.c b/contrib/bind9/lib/dns/lookup.c index 1cf5721..642a434 100644 --- a/contrib/bind9/lib/dns/lookup.c +++ b/contrib/bind9/lib/dns/lookup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lookup.c,v 1.9.12.7 2006/01/04 23:50:20 marka Exp $ */ +/* $Id: lookup.c,v 1.14.18.4 2005/11/30 03:44:39 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/master.c b/contrib/bind9/lib/dns/master.c index 7a2dab3..8eb1f2d 100644 --- a/contrib/bind9/lib/dns/master.c +++ b/contrib/bind9/lib/dns/master.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.c,v 1.122.2.8.2.14 2004/05/05 01:32:16 marka Exp $ */ +/* $Id: master.c,v 1.148.18.13 2006/12/07 23:57:58 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -25,6 +27,7 @@ #include <isc/mem.h> #include <isc/print.h> #include <isc/serial.h> +#include <isc/stdio.h> #include <isc/stdtime.h> #include <isc/string.h> #include <isc/task.h> @@ -46,33 +49,34 @@ #include <dns/time.h> #include <dns/ttl.h> -/* - * Grow the number of dns_rdatalist_t (RDLSZ) and dns_rdata_t (RDSZ) structures +/*! + * Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ) structures * by these sizes when we need to. * - * RDLSZ reflects the number of different types with the same name expected. + */ +/*% RDLSZ reflects the number of different types with the same name expected. */ +#define RDLSZ 32 +/*% * RDSZ reflects the number of rdata expected at a give name that can fit into * 64k. */ - -#define RDLSZ 32 #define RDSZ 512 #define NBUFS 4 #define MAXWIRESZ 255 -/* +/*% * Target buffer size and minimum target size. * MINTSIZ must be big enough to hold the largest rdata record. - * + * \brief * TSIZ >= MINTSIZ */ #define TSIZ (128*1024) -/* +/*% * max message size - header - root - type - class - ttl - rdlen */ #define MINTSIZ (65535 - 12 - 1 - 2 - 2 - 4 - 2) -/* +/*% * Size for tokens in the presentation format, * The largest tokens are the base64 blocks in KEY and CERT records, * Largest key allowed is about 1372 bytes but @@ -87,19 +91,28 @@ typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t; typedef struct dns_incctx dns_incctx_t; -/* +/*% * Master file load state. */ struct dns_loadctx { unsigned int magic; isc_mem_t *mctx; - isc_lex_t *lex; - isc_boolean_t keep_lex; + dns_masterformat_t format; + dns_rdatacallbacks_t *callbacks; isc_task_t *task; dns_loaddonefunc_t done; void *done_arg; + + /* Common methods */ + isc_result_t (*openfile)(dns_loadctx_t *lctx, + const char *filename); + isc_result_t (*load)(dns_loadctx_t *lctx); + + /* Members specific to the text format: */ + isc_lex_t *lex; + isc_boolean_t keep_lex; unsigned int options; isc_boolean_t ttl_known; isc_boolean_t default_ttl_known; @@ -111,9 +124,14 @@ struct dns_loadctx { isc_uint32_t default_ttl; dns_rdataclass_t zclass; dns_fixedname_t fixed_top; - dns_name_t *top; /* top of zone */ + dns_name_t *top; /*%< top of zone */ + + /* Members specific to the raw format: */ + FILE *f; + isc_boolean_t first; + /* Which fixed buffers we are using? */ - unsigned int loop_cnt; /* records per quantum, + unsigned int loop_cnt; /*% records per quantum, * 0 => all. */ isc_boolean_t canceled; isc_mutex_t lock; @@ -144,6 +162,18 @@ struct dns_incctx { #define DNS_AS_STR(t) ((t).value.as_textregion.base) static isc_result_t +openfile_text(dns_loadctx_t *lctx, const char *master_file); + +static isc_result_t +openfile_raw(dns_loadctx_t *lctx, const char *master_file); + +static isc_result_t +load_text(dns_loadctx_t *lctx); + +static isc_result_t +load_raw(dns_loadctx_t *lctx); + +static isc_result_t pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx); static isc_result_t @@ -405,6 +435,7 @@ incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) { static void loadctx_destroy(dns_loadctx_t *lctx) { isc_mem_t *mctx; + isc_result_t result; REQUIRE(DNS_LCTX_VALID(lctx)); @@ -412,6 +443,15 @@ loadctx_destroy(dns_loadctx_t *lctx) { if (lctx->inc != NULL) incctx_destroy(lctx->mctx, lctx->inc); + if (lctx->f != NULL) { + result = isc_stdio_close(lctx->f); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_close() failed: %s", + isc_result_totext(result)); + } + } + /* isc_lex_destroy() will close all open streams */ if (lctx->lex != NULL && !lctx->keep_lex) isc_lex_destroy(&lctx->lex); @@ -461,7 +501,8 @@ incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) { } static isc_result_t -loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, +loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, + unsigned int options, dns_name_t *top, dns_rdataclass_t zclass, dns_name_t *origin, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, isc_lex_t *lex, @@ -489,10 +530,7 @@ loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, result = isc_mutex_init(&lctx->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, lctx, sizeof(*lctx)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); + return (result); } lctx->inc = NULL; @@ -500,6 +538,20 @@ loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, if (result != ISC_R_SUCCESS) goto cleanup_ctx; + lctx->format = format; + switch (format) { + default: + INSIST(0); + case dns_masterformat_text: + lctx->openfile = openfile_text; + lctx->load = load_text; + break; + case dns_masterformat_raw: + lctx->openfile = openfile_raw; + lctx->load = load_raw; + break; + } + if (lex != NULL) { lctx->lex = lex; lctx->keep_lex = ISC_TRUE; @@ -534,6 +586,9 @@ loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, dns_name_toregion(top, &r); dns_name_fromregion(lctx->top, &r); + lctx->f = NULL; + lctx->first = ISC_TRUE; + lctx->loop_cnt = (done != NULL) ? 100 : 0; lctx->callbacks = callbacks; lctx->task = NULL; @@ -640,6 +695,25 @@ genname(char *name, int it, char *buffer, size_t length) { } static isc_result_t +openfile_text(dns_loadctx_t *lctx, const char *master_file) { + return (isc_lex_openfile(lctx->lex, master_file)); +} + +static isc_result_t +openfile_raw(dns_loadctx_t *lctx, const char *master_file) { + isc_result_t result; + + result = isc_stdio_open(master_file, "r", &lctx->f); + if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_open() failed: %s", + isc_result_totext(result)); + } + + return (result); +} + +static isc_result_t generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs, const char *source, unsigned int line) { @@ -711,6 +785,7 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs, case dns_rdatatype_a: case dns_rdatatype_aaaa: if (lctx->zclass == dns_rdataclass_in || + lctx->zclass == dns_rdataclass_ch || lctx->zclass == dns_rdataclass_hs) break; /* FALLTHROUGH */ @@ -862,8 +937,25 @@ check_ns(dns_loadctx_t *lctx, isc_token_t *token, const char *source, return (result); } +static void +check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line, + dns_rdatacallbacks_t *callbacks) +{ + dns_name_t *name; + + name = (ictx->glue != NULL) ? ictx->glue : ictx->current; + if (dns_name_internalwildcard(name)) { + char namebuf[DNS_NAME_FORMATSIZE]; + + dns_name_format(name, namebuf, sizeof(namebuf)); + (*callbacks->warn)(callbacks, "%s:%lu: warning: ownername " + "'%s' contains an non-terminal wildcard", + source, line, namebuf); + } +} + static isc_result_t -load(dns_loadctx_t *lctx) { +load_text(dns_loadctx_t *lctx) { dns_rdataclass_t rdclass; dns_rdatatype_t type, covers; isc_uint32_t ttl_offset = 0; @@ -939,11 +1031,16 @@ load(dns_loadctx_t *lctx) { options |= DNS_RDATA_CHECKNAMES; if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) options |= DNS_RDATA_CHECKNAMESFAIL; + if ((lctx->options & DNS_MASTER_CHECKMX) != 0) + options |= DNS_RDATA_CHECKMX; + if ((lctx->options & DNS_MASTER_CHECKMXFAIL) != 0) + options |= DNS_RDATA_CHECKMXFAIL; source = isc_lex_getsourcename(lctx->lex); do { initialws = ISC_FALSE; line = isc_lex_getsourceline(lctx->lex); - GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS, &token, ISC_TRUE); + GETTOKEN(lctx->lex, ISC_LEXOPT_INITIALWS | ISC_LEXOPT_QSTRING, + &token, ISC_TRUE); line = isc_lex_getsourceline(lctx->lex); if (token.type == isc_tokentype_eof) { @@ -979,7 +1076,8 @@ load(dns_loadctx_t *lctx) { * Still working on the same name. */ initialws = ISC_TRUE; - } else if (token.type == isc_tokentype_string) { + } else if (token.type == isc_tokentype_string || + token.type == isc_tokentype_qstring) { /* * "$" Support. @@ -1117,6 +1215,7 @@ load(dns_loadctx_t *lctx) { isc_mem_free(mctx, gtype); if (rhs != NULL) isc_mem_free(mctx, rhs); + range = lhs = gtype = rhs = NULL; /* RANGE */ GETTOKEN(lctx->lex, 0, &token, ISC_FALSE); range = isc_mem_strdup(mctx, @@ -1346,6 +1445,14 @@ load(dns_loadctx_t *lctx) { isc_buffer_init(&target, target_mem, target_size); } + /* + * Check for internal wildcards. + */ + if ((lctx->options & DNS_MASTER_CHECKWILDCARD) + != 0) + check_wildcard(ictx, source, line, + callbacks); + } if ((lctx->options & DNS_MASTER_ZONE) != 0 && (lctx->options & DNS_MASTER_SLAVE) == 0 && @@ -1508,7 +1615,7 @@ load(dns_loadctx_t *lctx) { current_has_delegation = ISC_TRUE; /* - * RFC 1123: MD and MF are not allowed to be loaded from + * RFC1123: MD and MF are not allowed to be loaded from * master files. */ if ((lctx->options & DNS_MASTER_ZONE) != 0 && @@ -1571,7 +1678,7 @@ load(dns_loadctx_t *lctx) { isc_boolean_t ok; dns_name_t *name; - name = (ictx->glue != NULL) ? ictx-> glue : + name = (ictx->glue != NULL) ? ictx->glue : ictx->current; ok = dns_rdata_checkowner(name, lctx->zclass, type, ISC_TRUE); @@ -1686,7 +1793,7 @@ load(dns_loadctx_t *lctx) { } else if (!explicit_ttl && lctx->warn_1035) { (*callbacks->warn)(callbacks, "%s:%lu: " - "using RFC 1035 TTL semantics", + "using RFC1035 TTL semantics", source, line); lctx->warn_1035 = ISC_FALSE; } @@ -1879,7 +1986,7 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { new->drop = ictx->drop; } - result = isc_lex_openfile(lctx->lex, master_file); + result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; new->parent = ictx; @@ -1892,25 +1999,352 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { return (result); } +static inline isc_result_t +read_and_check(isc_boolean_t do_read, isc_buffer_t *buffer, + size_t len, FILE *f) +{ + isc_result_t result; + + if (do_read) { + INSIST(isc_buffer_availablelength(buffer) >= len); + result = isc_stdio_read(isc_buffer_used(buffer), 1, len, + f, NULL); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_add(buffer, len); + } else if (isc_buffer_remaininglength(buffer) < len) + return (ISC_R_RANGE); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +load_raw(dns_loadctx_t *lctx) { + isc_result_t result = ISC_R_SUCCESS; + isc_boolean_t done = ISC_FALSE; + unsigned int loop_cnt = 0; + dns_rdatacallbacks_t *callbacks; + unsigned char namebuf[DNS_NAME_MAXWIRE]; + isc_region_t r; + dns_name_t name; + rdatalist_head_t head, dummy; + dns_rdatalist_t rdatalist; + isc_mem_t *mctx = lctx->mctx; + dns_rdata_t *rdata = NULL; + unsigned int rdata_size = 0; + int target_size = TSIZ; + isc_buffer_t target; + unsigned char *target_mem = NULL; + + REQUIRE(DNS_LCTX_VALID(lctx)); + callbacks = lctx->callbacks; + + if (lctx->first) { + dns_masterrawheader_t header; + isc_uint32_t format, version, dumptime; + size_t hdrlen = sizeof(format) + sizeof(version) + + sizeof(dumptime); + + INSIST(hdrlen <= sizeof(header)); + isc_buffer_init(&target, &header, sizeof(header)); + + result = isc_stdio_read(&header, 1, hdrlen, lctx->f, NULL); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_read failed: %s", + isc_result_totext(result)); + return (result); + } + isc_buffer_add(&target, hdrlen); + format = isc_buffer_getuint32(&target); + if (format != dns_masterformat_raw) { + (*callbacks->error)(callbacks, + "dns_master_load: " + "file format mismatch"); + return (ISC_R_NOTIMPLEMENTED); + } + + version = isc_buffer_getuint32(&target); + if (version > DNS_RAWFORMAT_VERSION) { + (*callbacks->error)(callbacks, + "dns_master_load: " + "unsupported file format version"); + return (ISC_R_NOTIMPLEMENTED); + } + + /* Empty read: currently, we do not use dumptime */ + dumptime = isc_buffer_getuint32(&target); + + lctx->first = ISC_FALSE; + } + + ISC_LIST_INIT(head); + ISC_LIST_INIT(dummy); + dns_rdatalist_init(&rdatalist); + + /* + * Allocate target_size of buffer space. This is greater than twice + * the maximum individual RR data size. + */ + target_mem = isc_mem_get(mctx, target_size); + if (target_mem == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + isc_buffer_init(&target, target_mem, target_size); + + /* + * In the following loop, we regard any error fatal regardless of + * whether "MANYERRORS" is set in the context option. This is because + * normal errors should already have been checked at creation time. + * Besides, it is very unlikely that we can recover from an error + * in this format, and so trying to continue parsing erroneous data + * does not really make sense. + */ + for (loop_cnt = 0; + (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); + loop_cnt++) { + unsigned int i, rdcount, consumed_name; + isc_uint16_t namelen; + isc_uint32_t totallen; + size_t minlen, readlen; + isc_boolean_t sequential_read = ISC_FALSE; + + /* Read the data length */ + isc_buffer_clear(&target); + INSIST(isc_buffer_availablelength(&target) >= + sizeof(totallen)); + result = isc_stdio_read(target.base, 1, sizeof(totallen), + lctx->f, NULL); + if (result == ISC_R_EOF) { + result = ISC_R_SUCCESS; + done = ISC_TRUE; + break; + } + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_add(&target, sizeof(totallen)); + totallen = isc_buffer_getuint32(&target); + /* + * Validation: the input data must at least contain the common + * header. + */ + minlen = sizeof(totallen) + sizeof(isc_uint16_t) + + sizeof(isc_uint16_t) + sizeof(isc_uint16_t) + + sizeof(isc_uint32_t) + sizeof(isc_uint32_t); + if (totallen < minlen) { + result = ISC_R_RANGE; + goto cleanup; + } + totallen -= sizeof(totallen); + + isc_buffer_clear(&target); + if (totallen > isc_buffer_availablelength(&target)) { + /* + * The default buffer size should typically be large + * enough to store the entire RRset. We could try to + * allocate enough space if this is not the case, but + * it might cause a hazardous result when "totallen" + * is forged. Thus, we'd rather take an inefficient + * but robust approach in this atypical case: read + * data step by step, and commit partial data when + * necessary. Note that the buffer must be large + * enough to store the "header part", owner name, and + * at least one rdata (however large it is). + */ + sequential_read = ISC_TRUE; + readlen = minlen - sizeof(totallen); + } else { + /* + * Typical case. We can read the whole RRset at once + * with the default buffer. + */ + readlen = totallen; + } + result = isc_stdio_read(target.base, 1, readlen, + lctx->f, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_add(&target, readlen); + + /* Construct RRset headers */ + rdatalist.rdclass = isc_buffer_getuint16(&target); + rdatalist.type = isc_buffer_getuint16(&target); + rdatalist.covers = isc_buffer_getuint16(&target); + rdatalist.ttl = isc_buffer_getuint32(&target); + rdcount = isc_buffer_getuint32(&target); + if (rdcount == 0) { + result = ISC_R_RANGE; + goto cleanup; + } + INSIST(isc_buffer_consumedlength(&target) <= readlen); + + /* Owner name: length followed by name */ + result = read_and_check(sequential_read, &target, + sizeof(namelen), lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + namelen = isc_buffer_getuint16(&target); + if (namelen > sizeof(namebuf)) { + result = ISC_R_RANGE; + goto cleanup; + } + + result = read_and_check(sequential_read, &target, namelen, + lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_setactive(&target, (unsigned int)namelen); + isc_buffer_activeregion(&target, &r); + dns_name_init(&name, NULL); + dns_name_fromregion(&name, &r); + isc_buffer_forward(&target, (unsigned int)namelen); + consumed_name = isc_buffer_consumedlength(&target); + + /* Rdata contents. */ + if (rdcount > rdata_size) { + dns_rdata_t *new_rdata = NULL; + + new_rdata = grow_rdata(rdata_size + RDSZ, rdata, + rdata_size, &head, + &dummy, mctx); + if (new_rdata == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + rdata_size += RDSZ; + rdata = new_rdata; + } + + continue_read: + for (i = 0; i < rdcount; i++) { + isc_uint16_t rdlen; + + dns_rdata_init(&rdata[i]); + + if (sequential_read && + isc_buffer_availablelength(&target) < MINTSIZ) { + unsigned int j; + + INSIST(i > 0); /* detect an infinite loop */ + + /* Partial Commit. */ + ISC_LIST_APPEND(head, &rdatalist, link); + result = commit(callbacks, lctx, &head, &name, + NULL, 0); + for (j = 0; j < i; j++) { + ISC_LIST_UNLINK(rdatalist.rdata, + &rdata[j], link); + dns_rdata_reset(&rdata[j]); + } + if (result != ISC_R_SUCCESS) + goto cleanup; + + /* Rewind the buffer and continue */ + isc_buffer_clear(&target); + isc_buffer_add(&target, consumed_name); + isc_buffer_forward(&target, consumed_name); + + rdcount -= i; + i = 0; + + goto continue_read; + } + + /* rdata length */ + result = read_and_check(sequential_read, &target, + sizeof(rdlen), lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + rdlen = isc_buffer_getuint16(&target); + + /* rdata */ + result = read_and_check(sequential_read, &target, + rdlen, lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_setactive(&target, (unsigned int)rdlen); + isc_buffer_activeregion(&target, &r); + isc_buffer_forward(&target, (unsigned int)rdlen); + dns_rdata_fromregion(&rdata[i], rdatalist.rdclass, + rdatalist.type, &r); + + ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); + } + + /* + * Sanity check. Still having remaining space is not + * necessarily critical, but it very likely indicates broken + * or malformed data. + */ + if (isc_buffer_remaininglength(&target) != 0) { + result = ISC_R_RANGE; + goto cleanup; + } + + ISC_LIST_APPEND(head, &rdatalist, link); + + /* Commit this RRset. rdatalist will be unlinked. */ + result = commit(callbacks, lctx, &head, &name, NULL, 0); + + for (i = 0; i < rdcount; i++) { + ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); + dns_rdata_reset(&rdata[i]); + } + + if (result != ISC_R_SUCCESS) + goto cleanup; + } + + if (!done) { + INSIST(lctx->done != NULL && lctx->task != NULL); + result = DNS_R_CONTINUE; + } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) + result = lctx->result; + + cleanup: + if (rdata != NULL) + isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); + if (target_mem != NULL) + isc_mem_put(mctx, target_mem, target_size); + if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) { + (*callbacks->error)(callbacks, "dns_master_load: %s", + dns_result_totext(result)); + } + + return (result); +} + isc_result_t dns_master_loadfile(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) { + return (dns_master_loadfile2(master_file, top, origin, zclass, options, + callbacks, mctx, dns_masterformat_text)); +} + +isc_result_t +dns_master_loadfile2(const char *master_file, dns_name_t *top, + dns_name_t *origin, + dns_rdataclass_t zclass, unsigned int options, + dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, + dns_masterformat_t format) +{ dns_loadctx_t *lctx = NULL; isc_result_t result; - result = loadctx_create(mctx, options, top, zclass, origin, + result = loadctx_create(format, mctx, options, top, zclass, origin, callbacks, NULL, NULL, NULL, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); - result = isc_lex_openfile(lctx->lex, master_file); + result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: @@ -1926,18 +2360,32 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) { + return (dns_master_loadfileinc2(master_file, top, origin, zclass, + options, callbacks, task, done, + done_arg, lctxp, mctx, + dns_masterformat_text)); +} + +isc_result_t +dns_master_loadfileinc2(const char *master_file, dns_name_t *top, + dns_name_t *origin, dns_rdataclass_t zclass, + unsigned int options, dns_rdatacallbacks_t *callbacks, + isc_task_t *task, dns_loaddonefunc_t done, + void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx, + dns_masterformat_t format) +{ dns_loadctx_t *lctx = NULL; isc_result_t result; - + REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, + result = loadctx_create(format, mctx, options, top, zclass, origin, callbacks, task, done, done_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); - result = isc_lex_openfile(lctx->lex, master_file); + result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1963,8 +2411,9 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, REQUIRE(stream != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, NULL, NULL, NULL, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, NULL, NULL, NULL, + NULL, &lctx); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1972,7 +2421,7 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, if (result != ISC_R_SUCCESS) goto cleanup; - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: @@ -1995,8 +2444,9 @@ dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, task, done, done_arg, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, task, done, + done_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) goto cleanup; @@ -2027,8 +2477,9 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, REQUIRE(buffer != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, NULL, NULL, NULL, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, NULL, NULL, NULL, + NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); @@ -2036,7 +2487,7 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, if (result != ISC_R_SUCCESS) goto cleanup; - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: @@ -2060,8 +2511,9 @@ dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top, REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, task, done, done_arg, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, task, done, + done_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); @@ -2092,12 +2544,13 @@ dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, REQUIRE(lex != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, NULL, NULL, NULL, lex, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, NULL, NULL, NULL, + lex, &lctx); if (result != ISC_R_SUCCESS) return (result); - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); dns_loadctx_detach(&lctx); @@ -2119,8 +2572,9 @@ dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, task, done, done_arg, lex, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, task, done, + done_arg, lex, &lctx); if (result != ISC_R_SUCCESS) return (result); @@ -2281,9 +2735,15 @@ commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx, } else if (result != ISC_R_SUCCESS) { dns_name_format(owner, namebuf, sizeof(namebuf)); - (*error)(callbacks, "%s: %s:%lu: %s: %s", - "dns_master_load", source, line, - namebuf, dns_result_totext(result)); + if (source != NULL) { + (*error)(callbacks, "%s: %s:%lu: %s: %s", + "dns_master_load", source, line, + namebuf, dns_result_totext(result)); + } else { + (*error)(callbacks, "%s: %s: %s", + "dns_master_load", namebuf, + dns_result_totext(result)); + } } if (MANYERRS(lctx, result)) SETRESULT(lctx, result); @@ -2342,7 +2802,7 @@ load_quantum(isc_task_t *task, isc_event_t *event) { if (lctx->canceled) result = ISC_R_CANCELED; else - result = load(lctx); + result = (lctx->load)(lctx); if (result == DNS_R_CONTINUE) { event->ev_arg = lctx; isc_task_send(task, &event); diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c index 0f4716d..03716e2 100644 --- a/contrib/bind9/lib/dns/masterdump.c +++ b/contrib/bind9/lib/dns/masterdump.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.c,v 1.56.2.5.2.15 2006/03/10 00:17:21 marka Exp $ */ +/* $Id: masterdump.c,v 1.73.18.14 2006/08/08 06:39:36 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -29,13 +31,16 @@ #include <isc/stdio.h> #include <isc/string.h> #include <isc/task.h> +#include <isc/time.h> #include <isc/util.h> #include <dns/db.h> #include <dns/dbiterator.h> #include <dns/events.h> #include <dns/fixedname.h> +#include <dns/lib.h> #include <dns/log.h> +#include <dns/master.h> #include <dns/masterdump.h> #include <dns/rdata.h> #include <dns/rdataclass.h> @@ -65,7 +70,7 @@ struct dns_master_style { unsigned int tab_width; }; -/* +/*% * The maximum length of the newline+indentation that is output * when inserting a line break in an RR. This effectively puts an * upper limits on the value of "rdata_column", because if it is @@ -73,7 +78,7 @@ struct dns_master_style { */ #define DNS_TOTEXT_LINEBREAK_MAXLEN 100 -/* +/*% * Context structure for a masterfile dump in progress. */ typedef struct dns_totext_ctx { @@ -134,7 +139,7 @@ dns_master_style_simple = { 24, 32, 32, 40, 80, 8 }; -/* +/*% * A style suitable for dns_rdataset_totext(). */ LIBDNS_EXTERNAL_DATA const dns_master_style_t @@ -171,11 +176,16 @@ struct dns_dumpctx { /* dns_master_dumpinc() */ char *file; char *tmpfile; + dns_masterformat_t format; + isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name, + dns_rdatasetiter_t *rdsiter, + dns_totext_ctx_t *ctx, + isc_buffer_t *buffer, FILE *f); }; #define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) -/* +/*% * Output tabs and spaces to go from column '*current' to * column 'to', and update '*current' to reflect the new * current column. @@ -348,6 +358,7 @@ rdataset_totext(dns_rdataset_t *rdataset, REQUIRE(DNS_RDATASET_VALID(rdataset)); + rdataset->attributes |= DNS_RDATASETATTR_LOADORDER; result = dns_rdataset_first(rdataset); REQUIRE(result == ISC_R_SUCCESS); @@ -774,9 +785,9 @@ static const char *trustnames[] = { }; static isc_result_t -dump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, - dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f) +dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name, + dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, + isc_buffer_t *buffer, FILE *f) { isc_result_t itresult, dumpresult; isc_region_t r; @@ -848,6 +859,146 @@ dump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, return (itresult); } +/* + * Dump given RRsets in the "raw" format. + */ +static isc_result_t +dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset, + isc_buffer_t *buffer, FILE *f) +{ + isc_result_t result; + isc_uint32_t totallen; + isc_uint16_t dlen; + isc_region_t r, r_hdr; + + REQUIRE(buffer->length > 0); + REQUIRE(DNS_RDATASET_VALID(rdataset)); + + restart: + totallen = 0; + result = dns_rdataset_first(rdataset); + REQUIRE(result == ISC_R_SUCCESS); + + isc_buffer_clear(buffer); + + /* + * Common header and owner name (length followed by name) + * These fields should be in a moderate length, so we assume we + * can store all of them in the initial buffer. + */ + isc_buffer_availableregion(buffer, &r_hdr); + INSIST(r_hdr.length >= sizeof(dns_masterrawrdataset_t)); + isc_buffer_putuint32(buffer, totallen); /* XXX: leave space */ + isc_buffer_putuint16(buffer, rdataset->rdclass); /* 16-bit class */ + isc_buffer_putuint16(buffer, rdataset->type); /* 16-bit type */ + isc_buffer_putuint16(buffer, rdataset->covers); /* same as type */ + isc_buffer_putuint32(buffer, rdataset->ttl); /* 32-bit TTL */ + isc_buffer_putuint32(buffer, dns_rdataset_count(rdataset)); + totallen = isc_buffer_usedlength(buffer); + INSIST(totallen <= sizeof(dns_masterrawrdataset_t)); + + dns_name_toregion(name, &r); + INSIST(isc_buffer_availablelength(buffer) >= + (sizeof(dlen) + r.length)); + dlen = (isc_uint16_t)r.length; + isc_buffer_putuint16(buffer, dlen); + isc_buffer_copyregion(buffer, &r); + totallen += sizeof(dlen) + r.length; + + do { + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_region_t r; + + dns_rdataset_current(rdataset, &rdata); + dns_rdata_toregion(&rdata, &r); + INSIST(r.length <= 0xffffU); + dlen = (isc_uint16_t)r.length; + + /* + * Copy the rdata into the buffer. If the buffer is too small, + * grow it. This should be rare, so we'll simply restart the + * entire procedure (or should we copy the old data and + * continue?). + */ + if (isc_buffer_availablelength(buffer) < + sizeof(dlen) + r.length) { + int newlength; + void *newmem; + + newlength = buffer->length * 2; + newmem = isc_mem_get(mctx, newlength); + if (newmem == NULL) + return (ISC_R_NOMEMORY); + isc_mem_put(mctx, buffer->base, buffer->length); + isc_buffer_init(buffer, newmem, newlength); + goto restart; + } + isc_buffer_putuint16(buffer, dlen); + isc_buffer_copyregion(buffer, &r); + totallen += sizeof(dlen) + r.length; + + result = dns_rdataset_next(rdataset); + } while (result == ISC_R_SUCCESS); + + if (result != ISC_R_NOMORE) + return (result); + + /* + * Fill in the total length field. + * XXX: this is a bit tricky. Since we have already "used" the space + * for the total length in the buffer, we first remember the entire + * buffer length in the region, "rewind", and then write the value. + */ + isc_buffer_usedregion(buffer, &r); + isc_buffer_clear(buffer); + isc_buffer_putuint32(buffer, totallen); + INSIST(isc_buffer_usedlength(buffer) < totallen); + + /* + * Write the buffer contents to the raw master file. + */ + result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL); + + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "raw master file write failed: %s", + isc_result_totext(result)); + return (result); + } + + return (result); +} + +static isc_result_t +dump_rdatasets_raw(isc_mem_t *mctx, dns_name_t *name, + dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, + isc_buffer_t *buffer, FILE *f) +{ + isc_result_t result; + dns_rdataset_t rdataset; + + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + + dns_rdataset_init(&rdataset); + dns_rdatasetiter_current(rdsiter, &rdataset); + + if (rdataset.type == 0 && + (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) { + /* Omit negative cache entries */ + } else { + result = dump_rdataset_raw(mctx, name, &rdataset, + buffer, f); + } + dns_rdataset_disassociate(&rdataset); + } + + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + + return (result); +} /* * Initial size of text conversion buffer. The buffer is used @@ -856,7 +1007,7 @@ dump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, * * When converting rdatasets, it is dynamically resized, but * when converting origins, timestamps, etc it is not. Therefore, - * the initial size must large enough to hold the longest possible + * the initial size must large enough to hold the longest possible * text representation of any domain name (for $ORIGIN). */ static const int initial_buffer_length = 1200; @@ -1021,7 +1172,8 @@ task_send(dns_dumpctx_t *dctx) { static isc_result_t dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp) + const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp, + dns_masterformat_t format) { dns_dumpctx_t *dctx; isc_result_t result; @@ -1044,6 +1196,19 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dctx->canceled = ISC_FALSE; dctx->file = NULL; dctx->tmpfile = NULL; + dctx->format = format; + + switch (format) { + case dns_masterformat_text: + dctx->dumpsets = dump_rdatasets_text; + break; + case dns_masterformat_raw: + dctx->dumpsets = dump_rdatasets_raw; + break; + default: + INSIST(0); + break; + } result = totext_ctx_init(style, &dctx->tctx); if (result != ISC_R_SUCCESS) { @@ -1057,8 +1222,11 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dctx->do_date = dns_db_iscache(dctx->db); - relative = ((dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) ? - ISC_TRUE : ISC_FALSE; + if (dctx->format == dns_masterformat_text && + (dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) { + relative = ISC_TRUE; + } else + relative = ISC_FALSE; result = dns_db_createiterator(dctx->db, relative, &dctx->dbiter); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1095,6 +1263,9 @@ dumptostreaminc(dns_dumpctx_t *dctx) { dns_name_t *name; dns_fixedname_t fixname; unsigned int nodes; + dns_masterrawheader_t rawheader; + isc_uint32_t now32; + isc_time_t start; bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); if (bufmem == NULL) @@ -1106,26 +1277,68 @@ dumptostreaminc(dns_dumpctx_t *dctx) { name = dns_fixedname_name(&fixname); if (dctx->first) { - /* - * If the database has cache semantics, output an RFC2540 - * $DATE directive so that the TTLs can be adjusted when - * it is reloaded. For zones it is not really needed, and - * it would make the file incompatible with pre-RFC2540 - * software, so we omit it in the zone case. - */ - if (dctx->do_date) { - result = dns_time32_totext(dctx->now, &buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_usedregion(&buffer, &r); - fprintf(dctx->f, "$DATE %.*s\n", - (int) r.length, (char *) r.base); + switch (dctx->format) { + case dns_masterformat_text: + /* + * If the database has cache semantics, output an + * RFC2540 $DATE directive so that the TTLs can be + * adjusted when it is reloaded. For zones it is not + * really needed, and it would make the file + * incompatible with pre-RFC2540 software, so we omit + * it in the zone case. + */ + if (dctx->do_date) { + result = dns_time32_totext(dctx->now, &buffer); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_buffer_usedregion(&buffer, &r); + fprintf(dctx->f, "$DATE %.*s\n", + (int) r.length, (char *) r.base); + } + break; + case dns_masterformat_raw: + r.base = (unsigned char *)&rawheader; + r.length = sizeof(rawheader); + isc_buffer_region(&buffer, &r); + isc_buffer_putuint32(&buffer, dns_masterformat_raw); + isc_buffer_putuint32(&buffer, DNS_RAWFORMAT_VERSION); + if (sizeof(now32) != sizeof(dctx->now)) { + /* + * We assume isc_stdtime_t is a 32-bit integer, + * which should be the case on most cases. + * If it turns out to be uncommon, we'll need + * to bump the version number and revise the + * header format. + */ + isc_log_write(dns_lctx, + ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, + ISC_LOG_INFO, + "dumping master file in raw " + "format: stdtime is not 32bits"); + now32 = 0; + } else + now32 = dctx->now; + isc_buffer_putuint32(&buffer, now32); + INSIST(isc_buffer_usedlength(&buffer) <= + sizeof(rawheader)); + result = isc_stdio_write(buffer.base, 1, + isc_buffer_usedlength(&buffer), + dctx->f, NULL); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_clear(&buffer); + break; + default: + INSIST(0); } + result = dns_dbiterator_first(dctx->dbiter); dctx->first = ISC_FALSE; } else result = ISC_R_SUCCESS; nodes = dctx->nodes; + isc_time_now(&start); while (result == ISC_R_SUCCESS && (dctx->nodes == 0 || nodes--)) { dns_rdatasetiter_t *rdsiter = NULL; dns_dbnode_t *node = NULL; @@ -1148,8 +1361,8 @@ dumptostreaminc(dns_dumpctx_t *dctx) { dns_db_detachnode(dctx->db, &node); goto fail; } - result = dump_rdatasets(dctx->mctx, name, rdsiter, &dctx->tctx, - &buffer, dctx->f); + result = (dctx->dumpsets)(dctx->mctx, name, rdsiter, + &dctx->tctx, &buffer, dctx->f); dns_rdatasetiter_destroy(&rdsiter); if (result != ISC_R_SUCCESS) { dns_db_detachnode(dctx->db, &node); @@ -1159,7 +1372,46 @@ dumptostreaminc(dns_dumpctx_t *dctx) { result = dns_dbiterator_next(dctx->dbiter); } + /* + * Work out how many nodes can be written in the time between + * two requests to the nameserver. Smooth the resulting number and + * use it as a estimate for the number of nodes to be written in the + * next iteration. + */ if (dctx->nodes != 0 && result == ISC_R_SUCCESS) { + unsigned int pps = dns_pps; /* packets per second */ + unsigned int interval; + isc_uint64_t usecs; + isc_time_t end; + + isc_time_now(&end); + if (pps < 100) + pps = 100; + interval = 1000000 / pps; /* interval in usecs */ + if (interval == 0) + interval = 1; + usecs = isc_time_microdiff(&end, &start); + if (usecs == 0) { + dctx->nodes = dctx->nodes * 2; + if (dctx->nodes > 1000) + dctx->nodes = 1000; + } else { + nodes = dctx->nodes * interval; + nodes /= (unsigned int)usecs; + if (nodes == 0) + nodes = 1; + else if (nodes > 1000) + nodes = 1000; + + /* Smooth and assign. */ + dctx->nodes = (nodes + dctx->nodes * 7) / 8; + + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, + ISC_LOG_DEBUG(1), + "dumptostreaminc(%p) new nodes -> %d\n", + dctx, dctx->nodes); + } result = dns_dbiterator_pause(dctx->dbiter); RUNTIME_CHECK(result == ISC_R_SUCCESS); result = DNS_R_CONTINUE; @@ -1185,7 +1437,8 @@ dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, REQUIRE(f != NULL); REQUIRE(done != NULL); - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, + dns_masterformat_text); if (result != ISC_R_SUCCESS) return (result); isc_task_attach(task, &dctx->task); @@ -1212,10 +1465,20 @@ dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, const dns_master_style_t *style, FILE *f) { + return (dns_master_dumptostream2(mctx, db, version, style, + dns_masterformat_text, f)); +} + +isc_result_t +dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, + dns_masterformat_t format, FILE *f) +{ dns_dumpctx_t *dctx = NULL; isc_result_t result; - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, format); if (result != ISC_R_SUCCESS) return (result); @@ -1264,6 +1527,17 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp) { + return (dns_master_dumpinc2(mctx, db, version, style, filename, task, + done, done_arg, dctxp, + dns_masterformat_text)); +} + +isc_result_t +dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, + dns_dumpctx_t **dctxp, dns_masterformat_t format) +{ FILE *f = NULL; isc_result_t result; char *tempname = NULL; @@ -1278,7 +1552,7 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, if (result != ISC_R_SUCCESS) goto cleanup; - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, format); if (result != ISC_R_SUCCESS) { (void)isc_stdio_close(f); (void)isc_file_remove(tempname); @@ -1314,6 +1588,15 @@ isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename) { + return (dns_master_dump2(mctx, db, version, style, filename, + dns_masterformat_text)); +} + +isc_result_t +dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + dns_masterformat_t format) +{ FILE *f = NULL; isc_result_t result; char *tempname; @@ -1323,7 +1606,7 @@ dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, if (result != ISC_R_SUCCESS) return (result); - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, format); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1340,6 +1623,7 @@ dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, /* * Dump a database node into a master file. + * XXX: this function assumes the text format. */ isc_result_t dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, @@ -1373,7 +1657,7 @@ dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, result = dns_db_allrdatasets(db, node, version, now, &rdsiter); if (result != ISC_R_SUCCESS) goto failure; - result = dump_rdatasets(mctx, name, rdsiter, &ctx, &buffer, f); + result = dump_rdatasets_text(mctx, name, rdsiter, &ctx, &buffer, f); if (result != ISC_R_SUCCESS) goto failure; dns_rdatasetiter_destroy(&rdsiter); @@ -1452,4 +1736,3 @@ dns_master_styledestroy(dns_master_style_t **stylep, isc_mem_t *mctx) { *stylep = NULL; isc_mem_put(mctx, style, sizeof(*style)); } - diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c index 3387543..a4a1f87 100644 --- a/contrib/bind9/lib/dns/message.c +++ b/contrib/bind9/lib/dns/message.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.c,v 1.194.2.10.2.24 2006/02/28 06:32:54 marka Exp $ */ +/* $Id: message.c,v 1.222.18.10 2006/03/02 23:19:20 marka Exp $ */ + +/*! \file */ /*** *** Imports @@ -63,7 +65,7 @@ #define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \ && ((s) < DNS_PSEUDOSECTION_MAX)) -/* +/*% * This is the size of each individual scratchpad buffer, and the numbers * of various block allocations used within the server. * XXXMLG These should come from a config setting. @@ -75,7 +77,7 @@ #define RDATALIST_COUNT 8 #define RDATASET_COUNT RDATALIST_COUNT -/* +/*% * Text representation of the different items, for message_totext * functions. */ @@ -133,7 +135,7 @@ static const char *rcodetext[] = { }; -/* +/*% * "helper" type, which consists of a block of some type, and is linkable. * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer * size, or the allocated elements will not be alligned correctly. @@ -1441,7 +1443,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, /* * Minimize TTLs. * - * Section 5.2 of RFC 2181 says we should drop + * Section 5.2 of RFC2181 says we should drop * nonauthoritative rrsets where the TTLs differ, but we * currently treat them the as if they were authoritative and * minimize them. @@ -2282,6 +2284,18 @@ dns_message_addname(dns_message_t *msg, dns_name_t *name, ISC_LIST_APPEND(msg->sections[section], name, link); } +void +dns_message_removename(dns_message_t *msg, dns_name_t *name, + dns_section_t section) +{ + REQUIRE(msg != NULL); + REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER); + REQUIRE(name != NULL); + REQUIRE(VALID_NAMED_SECTION(section)); + + ISC_LIST_UNLINK(msg->sections[section], name, link); +} + isc_result_t dns_message_gettempname(dns_message_t *msg, dns_name_t **item) { REQUIRE(DNS_MESSAGE_VALID(msg)); diff --git a/contrib/bind9/lib/dns/name.c b/contrib/bind9/lib/dns/name.c index 1a257de..7f5d4e9 100644 --- a/contrib/bind9/lib/dns/name.c +++ b/contrib/bind9/lib/dns/name.c @@ -15,17 +15,22 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.127.2.7.2.16 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: name.c,v 1.144.18.16 2006/12/07 07:03:10 marka Exp $ */ + +/*! \file */ #include <config.h> #include <ctype.h> +#include <stdlib.h> #include <isc/buffer.h> #include <isc/hash.h> #include <isc/mem.h> +#include <isc/once.h> #include <isc/print.h> #include <isc/string.h> +#include <isc/thread.h> #include <isc/util.h> #include <dns/compress.h> @@ -122,7 +127,7 @@ static unsigned char maptolower[] = { set_offsets(name, var, NULL); \ } -/* +/*% * Note: If additional attributes are added that should not be set for * empty names, MAKE_EMPTY() must be changed so it clears them. */ @@ -134,7 +139,7 @@ do { \ name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \ } while (0); -/* +/*% * A name is "bindable" if it can be set to point to a new value, i.e. * name->ndata and name->length may be changed. */ @@ -142,7 +147,7 @@ do { \ ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \ == 0) -/* +/*% * Note that the name data must be a char array, not a string * literal, to avoid compiler warnings about discarding * the const attribute of a string. @@ -182,6 +187,19 @@ LIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild; unsigned int dns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive); +/* + * dns_name_t to text post-conversion procedure. + */ +#ifdef ISC_PLATFORM_USETHREADS +static int thread_key_initialized = 0; +static isc_mutex_t thread_key_mutex; +static isc_mem_t *thread_key_mctx = NULL; +static isc_thread_key_t totext_filter_proc_key; +static isc_once_t once = ISC_ONCE_INIT; +#else +static dns_name_totextfilter_t totext_filter_proc = NULL; +#endif + static void set_offsets(const dns_name_t *name, unsigned char *offsets, dns_name_t *set_name); @@ -385,6 +403,41 @@ dns_name_iswildcard(const dns_name_t *name) { return (ISC_FALSE); } +isc_boolean_t +dns_name_internalwildcard(const dns_name_t *name) { + unsigned char *ndata; + unsigned int count; + unsigned int label; + + /* + * Does 'name' contain a internal wildcard? + */ + + REQUIRE(VALID_NAME(name)); + REQUIRE(name->labels > 0); + + /* + * Skip first label. + */ + ndata = name->ndata; + count = *ndata++; + INSIST(count <= 63); + ndata += count; + label = 1; + /* + * Check all but the last of the remaining labels. + */ + while (label + 1 < name->labels) { + count = *ndata++; + INSIST(count <= 63); + if (count == 1 && *ndata == '*') + return (ISC_TRUE); + ndata += count; + label++; + } + return (ISC_FALSE); +} + static inline unsigned int name_hash(dns_name_t *name, isc_boolean_t case_sensitive) { unsigned int length; @@ -664,6 +717,35 @@ dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { return (ISC_TRUE); } +isc_boolean_t +dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) { + + /* + * Are 'name1' and 'name2' equal? + * + * Note: It makes no sense for one of the names to be relative and the + * other absolute. If both names are relative, then to be meaningfully + * compared the caller must ensure that they are both relative to the + * same domain. + */ + + REQUIRE(VALID_NAME(name1)); + REQUIRE(VALID_NAME(name2)); + /* + * Either name1 is absolute and name2 is absolute, or neither is. + */ + REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == + (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); + + if (name1->length != name2->length) + return (ISC_FALSE); + + if (memcmp(name1->ndata, name2->ndata, name1->length) != 0) + return (ISC_FALSE); + + return (ISC_TRUE); +} + int dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) { unsigned int l1, l2, l, count1, count2, count; @@ -1189,6 +1271,54 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source, return (ISC_R_SUCCESS); } +#ifdef ISC_PLATFORM_USETHREADS +static void +free_specific(void *arg) { + dns_name_totextfilter_t *mem = arg; + isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); + /* Stop use being called again. */ + (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL); +} + +static void +thread_key_mutex_init(void) { + RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS); +} + +static isc_result_t +totext_filter_proc_key_init(void) { + isc_result_t result; + + /* + * We need the call to isc_once_do() to support profiled mutex + * otherwise thread_key_mutex could be initialized at compile time. + */ + result = isc_once_do(&once, thread_key_mutex_init); + if (result != ISC_R_SUCCESS) + return (result); + + if (!thread_key_initialized) { + LOCK(&thread_key_mutex); + if (thread_key_mctx == NULL) + result = isc_mem_create2(0, 0, &thread_key_mctx, 0); + if (result != ISC_R_SUCCESS) + goto unlock; + isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE); + + if (!thread_key_initialized && + isc_thread_key_create(&totext_filter_proc_key, + free_specific) != 0) { + result = ISC_R_FAILURE; + isc_mem_detach(&thread_key_mctx); + } else + thread_key_initialized = 1; + unlock: + UNLOCK(&thread_key_mutex); + } + return (result); +} +#endif + isc_result_t dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_t *target) @@ -1200,6 +1330,12 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, unsigned int trem, count; unsigned int labels; isc_boolean_t saw_root = ISC_FALSE; + unsigned int oused = target->used; +#ifdef ISC_PLATFORM_USETHREADS + dns_name_totextfilter_t *mem; + dns_name_totextfilter_t totext_filter_proc = NULL; + isc_result_t result; +#endif /* * This function assumes the name is in proper uncompressed @@ -1208,6 +1344,11 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, REQUIRE(VALID_NAME(name)); REQUIRE(ISC_BUFFER_VALID(target)); +#ifdef ISC_PLATFORM_USETHREADS + result = totext_filter_proc_key_init(); + if (result != ISC_R_SUCCESS) + return (result); +#endif ndata = name->ndata; nlen = name->length; labels = name->labels; @@ -1339,6 +1480,14 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot, isc_buffer_add(target, tlen - trem); +#ifdef ISC_PLATFORM_USETHREADS + mem = isc_thread_key_getspecific(totext_filter_proc_key); + if (mem != NULL) + totext_filter_proc = *mem; +#endif + if (totext_filter_proc != NULL) + return ((*totext_filter_proc)(target, oused, saw_root)); + return (ISC_R_SUCCESS); } @@ -1573,7 +1722,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, { unsigned char *cdata, *ndata; unsigned int cused; /* Bytes of compressed name data used */ - unsigned int hops, nused, labels, n, nmax; + unsigned int nused, labels, n, nmax; unsigned int current, new_current, biggest_pointer; isc_boolean_t done; fw_state state = fw_start; @@ -1581,10 +1730,12 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, unsigned char *offsets; dns_offsets_t odata; isc_boolean_t downcase; + isc_boolean_t seen_pointer; /* * Copy the possibly-compressed name at source into target, - * decompressing it. + * decompressing it. Loop prevention is performed by checking + * the new pointer against biggest_pointer. */ REQUIRE(VALID_NAME(name)); @@ -1618,11 +1769,11 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, * Set up. */ labels = 0; - hops = 0; done = ISC_FALSE; ndata = isc_buffer_used(target); nused = 0; + seen_pointer = ISC_FALSE; /* * Find the maximum number of uncompressed target name @@ -1648,7 +1799,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, while (current < source->active && !done) { c = *cdata++; current++; - if (hops == 0) + if (!seen_pointer) cused++; switch (state) { @@ -1704,11 +1855,8 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, return (DNS_R_BADPOINTER); biggest_pointer = new_current; current = new_current; - cdata = (unsigned char *)source->base + - current; - hops++; - if (hops > DNS_POINTER_MAXHOPS) - return (DNS_R_TOOMANYHOPS); + cdata = (unsigned char *)source->base + current; + seen_pointer = ISC_TRUE; state = fw_start; break; default: @@ -1744,7 +1892,6 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, * big enough buffer. */ return (ISC_R_NOSPACE); - } isc_result_t @@ -2124,6 +2271,49 @@ dns_name_print(dns_name_t *name, FILE *stream) { return (ISC_R_SUCCESS); } +isc_result_t +dns_name_settotextfilter(dns_name_totextfilter_t proc) { +#ifdef ISC_PLATFORM_USETHREADS + isc_result_t result; + dns_name_totextfilter_t *mem; + int res; + + result = totext_filter_proc_key_init(); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * If we already have been here set / clear as appropriate. + * Otherwise allocate memory. + */ + mem = isc_thread_key_getspecific(totext_filter_proc_key); + if (mem != NULL && proc != NULL) { + *mem = proc; + return (ISC_R_SUCCESS); + } + if (proc == NULL) { + isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); + res = isc_thread_key_setspecific(totext_filter_proc_key, NULL); + if (res != 0) + result = ISC_R_UNEXPECTED; + return (result); + } + + mem = isc_mem_get(thread_key_mctx, sizeof(*mem)); + if (mem == NULL) + return (ISC_R_NOMEMORY); + *mem = proc; + if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) { + isc_mem_put(thread_key_mctx, mem, sizeof(*mem)); + result = ISC_R_UNEXPECTED; + } + return (result); +#else + totext_filter_proc = proc; + return (ISC_R_SUCCESS); +#endif +} + void dns_name_format(dns_name_t *name, char *cp, unsigned int size) { isc_result_t result; @@ -2198,3 +2388,19 @@ dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) { return (ISC_R_SUCCESS); } +void +dns_name_destroy(void) { +#ifdef ISC_PLATFORM_USETHREADS + RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init) + == ISC_R_SUCCESS); + + LOCK(&thread_key_mutex); + if (thread_key_initialized) { + isc_mem_detach(&thread_key_mctx); + isc_thread_key_delete(totext_filter_proc_key); + thread_key_initialized = 0; + } + UNLOCK(&thread_key_mutex); + +#endif +} diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c index dddde60..1fdc5c8 100644 --- a/contrib/bind9/lib/dns/ncache.c +++ b/contrib/bind9/lib/dns/ncache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.c,v 1.24.2.4.2.7 2004/03/08 02:07:54 marka Exp $ */ +/* $Id: ncache.c,v 1.36.18.3 2005/04/29 00:15:59 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -184,7 +186,7 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, * * We trust that the caller wants negative caching, so this * means we have a "type 3 nxdomain" or "type 3 nodata" - * response (see RFC 2308 for details). + * response (see RFC2308 for details). * * We will now build a suitable negative cache rdataset that * will cause zero bytes to be emitted when converted to @@ -208,7 +210,7 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, isc_buffer_putuint16(&buffer, 0); isc_buffer_putuint16(&buffer, 0); /* - * RFC 2308, section 5, says that negative answers without + * RFC2308, section 5, says that negative answers without * SOAs should not be cached. */ ttl = 0; @@ -473,6 +475,9 @@ static dns_rdatasetmethods_t rdataset_methods = { rdataset_clone, rdataset_count, NULL, + NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind9/lib/dns/nsec.c b/contrib/bind9/lib/dns/nsec.c index c259706..c1de67e 100644 --- a/contrib/bind9/lib/dns/nsec.c +++ b/contrib/bind9/lib/dns/nsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsec.c,v 1.5.2.1 2004/03/08 02:07:55 marka Exp $ */ +/* $Id: nsec.c,v 1.5.20.2 2005/04/29 00:15:59 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/openssl_link.c b/contrib/bind9/lib/dns/openssl_link.c index 525905c..fda610a 100644 --- a/contrib/bind9/lib/dns/openssl_link.c +++ b/contrib/bind9/lib/dns/openssl_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,7 +18,7 @@ /* * Principal Author: Brian Wellington - * $Id: openssl_link.c,v 1.1.4.3 2006/05/23 23:51:03 marka Exp $ + * $Id: openssl_link.c,v 1.1.6.9 2006/05/23 23:51:04 marka Exp $ */ #ifdef OPENSSL @@ -37,6 +37,8 @@ #include <openssl/err.h> #include <openssl/rand.h> +#include <openssl/evp.h> +#include <openssl/conf.h> #include <openssl/crypto.h> #if defined(CRYPTO_LOCK_ENGINE) && (OPENSSL_VERSION_NUMBER != 0x00907000L) @@ -132,6 +134,11 @@ isc_result_t dst__openssl_init() { isc_result_t result; +#ifdef DNS_CRYPTO_LEAKS + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); +#endif CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free); nlocks = CRYPTO_num_locks(); locks = mem_alloc(sizeof(isc_mutex_t) * nlocks); @@ -179,6 +186,33 @@ dst__openssl_init() { void dst__openssl_destroy() { + + /* + * Sequence taken from apps_shutdown() in <apps/apps.h>. + */ +#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) + CONF_modules_unload(1); +#endif + EVP_cleanup(); +#if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L + ENGINE_cleanup(); +#endif +#if (OPENSSL_VERSION_NUMBER >= 0x00907000L) + CRYPTO_cleanup_all_ex_data(); +#endif + ERR_clear_error(); + ERR_free_strings(); + ERR_remove_state(0); + +#ifdef DNS_CRYPTO_LEAKS + CRYPTO_mem_leaks_fp(stderr); +#endif + +#if 0 + /* + * The old error sequence that leaked. Remove for 9.4.1 if + * there are no issues by then. + */ ERR_clear_error(); #ifdef USE_ENGINE if (e != NULL) { @@ -186,12 +220,17 @@ dst__openssl_destroy() { e = NULL; } #endif +#endif if (locks != NULL) { DESTROYMUTEXBLOCK(locks, nlocks); mem_free(locks); } - if (rm != NULL) + if (rm != NULL) { +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + RAND_cleanup(); +#endif mem_free(rm); + } } isc_result_t @@ -217,3 +256,4 @@ dst__openssl_toresult(isc_result_t fallback) { EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ +/*! \file */ diff --git a/contrib/bind9/lib/dns/openssldh_link.c b/contrib/bind9/lib/dns/openssldh_link.c index 74ba39a..6f2e987 100644 --- a/contrib/bind9/lib/dns/openssldh_link.c +++ b/contrib/bind9/lib/dns/openssldh_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,7 +18,7 @@ /* * Principal Author: Brian Wellington - * $Id: openssldh_link.c,v 1.1.4.3 2006/03/02 00:37:20 marka Exp $ + * $Id: openssldh_link.c,v 1.1.6.9 2007/01/08 02:52:39 marka Exp $ */ #ifdef OPENSSL @@ -138,81 +138,11 @@ openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } -#ifndef HAVE_DH_GENERATE_PARAMETERS -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -static DH * -DH_generate_parameters(int prime_len, int generator, - void (*callback)(int,int,void *), void *cb_arg) -{ - BN_GENCB cb; - DH *dh = NULL; - - dh = DH_new(); - if (dh != NULL) { - BN_GENCB_set_old(&cb, callback, cb_arg); - - if (DH_generate_parameters_ex(dh, prime_len, generator, &cb)) - return (dh); - DH_free(dh); - } - return (NULL); -} -#endif - static isc_result_t openssldh_generate(dst_key_t *key, int generator) { +#if OPENSSL_VERSION_NUMBER > 0x00908000L + BN_GENCB cb; +#endif DH *dh = NULL; if (generator == 0) { @@ -222,7 +152,7 @@ openssldh_generate(dst_key_t *key, int generator) { { dh = DH_new(); if (dh == NULL) - return (ISC_R_NOMEMORY); + return (dst__openssl_toresult(ISC_R_NOMEMORY)); if (key->key_size == 768) dh->p = &bn768; else if (key->key_size == 1024) @@ -230,14 +160,28 @@ openssldh_generate(dst_key_t *key, int generator) { else dh->p = &bn1536; dh->g = &bn2; - } - else + } else generator = 2; } - if (generator != 0) + if (generator != 0) { +#if OPENSSL_VERSION_NUMBER > 0x00908000L + dh = DH_new(); + if (dh == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + + BN_GENCB_set_old(&cb, NULL, NULL); + + if (!DH_generate_parameters_ex(dh, key->key_size, generator, + &cb)) { + DH_free(dh); + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + } +#else dh = DH_generate_parameters(key->key_size, generator, NULL, NULL); +#endif + } if (dh == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); @@ -358,7 +302,7 @@ openssldh_fromdns(dst_key_t *key, isc_buffer_t *data) { dh = DH_new(); if (dh == NULL) - return (ISC_R_NOMEMORY); + return (dst__openssl_toresult(ISC_R_NOMEMORY)); dh->flags &= ~DH_FLAG_CACHE_MONT_P; /* @@ -637,11 +581,11 @@ openssldh_cleanup(void) { } static dst_func_t openssldh_functions = { - NULL, /* createctx */ - NULL, /* destroyctx */ - NULL, /* adddata */ - NULL, /* openssldh_sign */ - NULL, /* openssldh_verify */ + NULL, /*%< createctx */ + NULL, /*%< destroyctx */ + NULL, /*%< adddata */ + NULL, /*%< openssldh_sign */ + NULL, /*%< openssldh_verify */ openssldh_computesecret, openssldh_compare, openssldh_paramcompare, @@ -679,3 +623,4 @@ dst__openssldh_init(dst_func_t **funcp) { EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ +/*! \file */ diff --git a/contrib/bind9/lib/dns/openssldsa_link.c b/contrib/bind9/lib/dns/openssldsa_link.c index 267bfe8..64e6159 100644 --- a/contrib/bind9/lib/dns/openssldsa_link.c +++ b/contrib/bind9/lib/dns/openssldsa_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -16,7 +16,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: openssldsa_link.c,v 1.1.4.3 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: openssldsa_link.c,v 1.1.6.8 2007/01/08 03:03:48 marka Exp $ */ #ifdef OPENSSL @@ -124,7 +124,7 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) { if (sig->length < 2 * ISC_SHA1_DIGESTLENGTH + 1) return (DST_R_VERIFYFAILURE); - cp++; /* Skip T */ + cp++; /*%< Skip T */ dsasig = DSA_SIG_new(); dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL); cp += ISC_SHA1_DIGESTLENGTH; @@ -169,85 +169,11 @@ openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } -#ifndef HAVE_DSA_GENERATE_PARAMETERS -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -static DSA * -DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, - void (*callback)(int, int, void *), - void *cb_arg) -{ - BN_GENCB cb; - DSA *dsa; - - dsa = DSA_new(); - if (dsa != NULL) { - - BN_GENCB_set_old(&cb, callback, cb_arg); - - if (DSA_generate_parameters_ex(dsa, bits, seed_in, seed_len, - counter_ret, h_ret, &cb)) - return (dsa); - DSA_free(dsa); - } - return (NULL); -} -#endif - static isc_result_t openssldsa_generate(dst_key_t *key, int unused) { +#if OPENSSL_VERSION_NUMBER > 0x00908000L + BN_GENCB cb; +#endif DSA *dsa; unsigned char rand_array[ISC_SHA1_DIGESTLENGTH]; isc_result_t result; @@ -259,12 +185,27 @@ openssldsa_generate(dst_key_t *key, int unused) { if (result != ISC_R_SUCCESS) return (result); +#if OPENSSL_VERSION_NUMBER > 0x00908000L + dsa = DSA_new(); + if (dsa == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + + BN_GENCB_set_old(&cb, NULL, NULL); + + if (!DSA_generate_parameters_ex(dsa, key->key_size, rand_array, + ISC_SHA1_DIGESTLENGTH, NULL, NULL, + &cb)) + { + DSA_free(dsa); + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + } +#else dsa = DSA_generate_parameters(key->key_size, rand_array, ISC_SHA1_DIGESTLENGTH, NULL, NULL, NULL, NULL); - if (dsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); +#endif if (DSA_generate_key(dsa) == 0) { DSA_free(dsa); @@ -490,9 +431,9 @@ static dst_func_t openssldsa_functions = { openssldsa_adddata, openssldsa_sign, openssldsa_verify, - NULL, /* computesecret */ + NULL, /*%< computesecret */ openssldsa_compare, - NULL, /* paramcompare */ + NULL, /*%< paramcompare */ openssldsa_generate, openssldsa_isprivate, openssldsa_destroy, @@ -500,7 +441,7 @@ static dst_func_t openssldsa_functions = { openssldsa_fromdns, openssldsa_tofile, openssldsa_parse, - NULL, /* cleanup */ + NULL, /*%< cleanup */ }; isc_result_t @@ -518,3 +459,4 @@ dst__openssldsa_init(dst_func_t **funcp) { EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ +/*! \file */ diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c index c33913c..2609df6 100644 --- a/contrib/bind9/lib/dns/opensslrsa_link.c +++ b/contrib/bind9/lib/dns/opensslrsa_link.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -17,7 +17,7 @@ /* * Principal Author: Brian Wellington - * $Id: opensslrsa_link.c,v 1.1.4.9 2006/11/07 21:28:40 marka Exp $ + * $Id: opensslrsa_link.c,v 1.1.6.11 2006/11/07 21:28:49 marka Exp $ */ #ifdef OPENSSL @@ -50,7 +50,7 @@ #ifdef WIN32 #if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \ OPENSSL_VERSION_NUMBER < 0x00908000L) || \ - OPENSSL_VERSION_NUMBER >= 0x0090804fL) + OPENSSL_VERSION_NUMBER >= 0x0090804fL) #error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater. #endif #endif @@ -367,7 +367,7 @@ opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) { e_bytes = BN_num_bytes(rsa->e); mod_bytes = BN_num_bytes(rsa->n); - if (e_bytes < 256) { /* key exponent is <= 2040 bits */ + if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ if (r.length < 1) return (ISC_R_NOSPACE); isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); @@ -403,7 +403,7 @@ opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { rsa = RSA_new(); if (rsa == NULL) - return (ISC_R_NOMEMORY); + return (dst__openssl_toresult(ISC_R_NOMEMORY)); SET_FLAGS(rsa); if (r.length < 1) { @@ -598,9 +598,9 @@ static dst_func_t opensslrsa_functions = { opensslrsa_adddata, opensslrsa_sign, opensslrsa_verify, - NULL, /* computesecret */ + NULL, /*%< computesecret */ opensslrsa_compare, - NULL, /* paramcompare */ + NULL, /*%< paramcompare */ opensslrsa_generate, opensslrsa_isprivate, opensslrsa_destroy, @@ -608,7 +608,7 @@ static dst_func_t opensslrsa_functions = { opensslrsa_fromdns, opensslrsa_tofile, opensslrsa_parse, - NULL, /* cleanup */ + NULL, /*%< cleanup */ }; isc_result_t @@ -626,3 +626,4 @@ dst__opensslrsa_init(dst_func_t **funcp) { EMPTY_TRANSLATION_UNIT #endif /* OPENSSL */ +/*! \file */ diff --git a/contrib/bind9/lib/dns/order.c b/contrib/bind9/lib/dns/order.c index f09afed..1d216b7 100644 --- a/contrib/bind9/lib/dns/order.c +++ b/contrib/bind9/lib/dns/order.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: order.c,v 1.4.202.4 2004/03/08 09:04:30 marka Exp $ */ +/* $Id: order.c,v 1.5.18.3 2005/07/12 01:22:21 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -53,6 +55,8 @@ struct dns_order { isc_result_t dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) { dns_order_t *order; + isc_result_t result; + REQUIRE(orderp != NULL && *orderp == NULL); order = isc_mem_get(mctx, sizeof(*order)); @@ -60,7 +64,13 @@ dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) { return (ISC_R_NOMEMORY); ISC_LIST_INIT(order->ents); - isc_refcount_init(&order->references, 1); /* Implicit attach. */ + + /* Implicit attach. */ + result = isc_refcount_init(&order->references, 1); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, order, sizeof(*order)); + return (result); + } order->mctx = NULL; isc_mem_attach(mctx, &order->mctx); diff --git a/contrib/bind9/lib/dns/peer.c b/contrib/bind9/lib/dns/peer.c index 8b6ccdb..7d878b5 100644 --- a/contrib/bind9/lib/dns/peer.c +++ b/contrib/bind9/lib/dns/peer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.c,v 1.14.2.1.10.6 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: peer.c,v 1.19.18.8 2006/02/28 03:10:48 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -29,7 +31,7 @@ #include <dns/name.h> #include <dns/peer.h> -/* +/*% * Bit positions in the dns_peer_t structure flags field */ #define BOGUS_BIT 0 @@ -38,6 +40,8 @@ #define PROVIDE_IXFR_BIT 3 #define REQUEST_IXFR_BIT 4 #define SUPPORT_EDNS_BIT 5 +#define SERVER_UDPSIZE_BIT 6 +#define SERVER_MAXUDP_BIT 7 static void peerlist_delete(dns_peerlist_t **list); @@ -65,7 +69,6 @@ dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { return (ISC_R_SUCCESS); } - void dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { REQUIRE(DNS_PEERLIST_VALID(source)); @@ -130,7 +133,20 @@ dns_peerlist_addpeer(dns_peerlist_t *peers, dns_peer_t *peer) { dns_peer_attach(peer, &p); - ISC_LIST_APPEND(peers->elements, peer, next); + /* + * More specifics to front of list. + */ + for (p = ISC_LIST_HEAD(peers->elements); + p != NULL; + p = ISC_LIST_NEXT(p, next)) + if (p->prefixlen < peer->prefixlen) + break; + + if (p != NULL) + ISC_LIST_INSERTBEFORE(peers->elements, p, peer, next); + else + ISC_LIST_APPEND(peers->elements, peer, next); + } isc_result_t @@ -145,7 +161,8 @@ dns_peerlist_peerbyaddr(dns_peerlist_t *servers, server = ISC_LIST_HEAD(servers->elements); while (server != NULL) { - if (isc_netaddr_equal(addr, &server->address)) + if (isc_netaddr_eqprefix(addr, &server->address, + server->prefixlen)) break; server = ISC_LIST_NEXT(server, next); @@ -176,6 +193,27 @@ dns_peerlist_currpeer(dns_peerlist_t *peers, dns_peer_t **retval) { isc_result_t dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { + unsigned int prefixlen = 0; + + REQUIRE(peerptr != NULL); + switch(addr->family) { + case AF_INET: + prefixlen = 32; + break; + case AF_INET6: + prefixlen = 128; + break; + default: + INSIST(0); + } + + return (dns_peer_newprefix(mem, addr, prefixlen, peerptr)); +} + +isc_result_t +dns_peer_newprefix(isc_mem_t *mem, isc_netaddr_t *addr, unsigned int prefixlen, + dns_peer_t **peerptr) +{ dns_peer_t *peer; REQUIRE(peerptr != NULL); @@ -186,6 +224,7 @@ dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { peer->magic = DNS_PEER_MAGIC; peer->address = *addr; + peer->prefixlen = prefixlen; peer->mem = mem; peer->bogus = ISC_FALSE; peer->transfer_format = dns_one_answer; @@ -195,6 +234,8 @@ dns_peer_new(isc_mem_t *mem, isc_netaddr_t *addr, dns_peer_t **peerptr) { peer->key = NULL; peer->refs = 1; peer->transfer_source = NULL; + peer->notify_source = NULL; + peer->query_source = NULL; memset(&peer->bitflags, 0x0, sizeof(peer->bitflags)); @@ -522,3 +563,123 @@ dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { *transfer_source = *peer->transfer_source; return (ISC_R_SUCCESS); } + +isc_result_t +dns_peer_setnotifysource(dns_peer_t *peer, + const isc_sockaddr_t *notify_source) +{ + REQUIRE(DNS_PEER_VALID(peer)); + + if (peer->notify_source != NULL) { + isc_mem_put(peer->mem, peer->notify_source, + sizeof(*peer->notify_source)); + peer->notify_source = NULL; + } + if (notify_source != NULL) { + peer->notify_source = isc_mem_get(peer->mem, + sizeof(*peer->notify_source)); + if (peer->notify_source == NULL) + return (ISC_R_NOMEMORY); + + *peer->notify_source = *notify_source; + } + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getnotifysource(dns_peer_t *peer, isc_sockaddr_t *notify_source) { + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(notify_source != NULL); + + if (peer->notify_source == NULL) + return (ISC_R_NOTFOUND); + *notify_source = *peer->notify_source; + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_setquerysource(dns_peer_t *peer, const isc_sockaddr_t *query_source) { + REQUIRE(DNS_PEER_VALID(peer)); + + if (peer->query_source != NULL) { + isc_mem_put(peer->mem, peer->query_source, + sizeof(*peer->query_source)); + peer->query_source = NULL; + } + if (query_source != NULL) { + peer->query_source = isc_mem_get(peer->mem, + sizeof(*peer->query_source)); + if (peer->query_source == NULL) + return (ISC_R_NOMEMORY); + + *peer->query_source = *query_source; + } + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getquerysource(dns_peer_t *peer, isc_sockaddr_t *query_source) { + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(query_source != NULL); + + if (peer->query_source == NULL) + return (ISC_R_NOTFOUND); + *query_source = *peer->query_source; + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_setudpsize(dns_peer_t *peer, isc_uint16_t udpsize) { + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags); + + peer->udpsize = udpsize; + DNS_BIT_SET(SERVER_UDPSIZE_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getudpsize(dns_peer_t *peer, isc_uint16_t *udpsize) { + + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(udpsize != NULL); + + if (DNS_BIT_CHECK(SERVER_UDPSIZE_BIT, &peer->bitflags)) { + *udpsize = peer->udpsize; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} + +isc_result_t +dns_peer_setmaxudp(dns_peer_t *peer, isc_uint16_t maxudp) { + isc_boolean_t existed; + + REQUIRE(DNS_PEER_VALID(peer)); + + existed = DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags); + + peer->maxudp = maxudp; + DNS_BIT_SET(SERVER_MAXUDP_BIT, &peer->bitflags); + + return (existed ? ISC_R_EXISTS : ISC_R_SUCCESS); +} + +isc_result_t +dns_peer_getmaxudp(dns_peer_t *peer, isc_uint16_t *maxudp) { + + REQUIRE(DNS_PEER_VALID(peer)); + REQUIRE(maxudp != NULL); + + if (DNS_BIT_CHECK(SERVER_MAXUDP_BIT, &peer->bitflags)) { + *maxudp = peer->maxudp; + return (ISC_R_SUCCESS); + } else { + return (ISC_R_NOTFOUND); + } +} diff --git a/contrib/bind9/lib/dns/portlist.c b/contrib/bind9/lib/dns/portlist.c index f65910b..7e76171 100644 --- a/contrib/bind9/lib/dns/portlist.c +++ b/contrib/bind9/lib/dns/portlist.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: portlist.c,v 1.3.72.6 2006/08/25 05:25:50 marka Exp $ */ +/* $Id: portlist.c,v 1.6.18.5 2006/08/25 05:25:51 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -81,12 +83,14 @@ dns_portlist_create(isc_mem_t *mctx, dns_portlist_t **portlistp) { result = isc_mutex_init(&portlist->lock); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, portlist, sizeof(*portlist)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); + return (result); + } + result = isc_refcount_init(&portlist->refcount, 1); + if (result != ISC_R_SUCCESS) { + DESTROYLOCK(&portlist->lock); + isc_mem_put(mctx, portlist, sizeof(*portlist)); + return (result); } - isc_refcount_init(&portlist->refcount, 1); portlist->list = NULL; portlist->allocated = 0; portlist->active = 0; diff --git a/contrib/bind9/lib/dns/rbt.c b/contrib/bind9/lib/dns/rbt.c index ecff783..b8db99a 100644 --- a/contrib/bind9/lib/dns/rbt.c +++ b/contrib/bind9/lib/dns/rbt.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbt.c,v 1.115.2.2.2.13 2005/06/18 01:03:24 marka Exp $ */ +/* $Id: rbt.c,v 1.128.18.7 2005/10/13 01:26:06 marka Exp $ */ + +/*! \file */ /* Principal Authors: DCL */ @@ -24,10 +26,11 @@ #include <isc/mem.h> #include <isc/platform.h> #include <isc/print.h> +#include <isc/refcount.h> #include <isc/string.h> #include <isc/util.h> -/* +/*% * This define is so dns/name.h (included by dns/fixedname.h) uses more * efficient macro calls instead of functions for a few operations. */ @@ -52,7 +55,7 @@ #ifdef RBT_MEM_TEST #undef RBT_HASH_SIZE -#define RBT_HASH_SIZE 2 /* To give the reallocation code a workout. */ +#define RBT_HASH_SIZE 2 /*%< To give the reallocation code a workout. */ #endif struct dns_rbt { @@ -69,7 +72,7 @@ struct dns_rbt { #define RED 0 #define BLACK 1 -/* +/*% * Elements of the rbtnode structure. */ #define PARENT(node) ((node)->parent) @@ -87,16 +90,15 @@ struct dns_rbt { #define IS_ROOT(node) ISC_TF((node)->is_root == 1) #define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1) -/* +/*% * Structure elements from the rbtdb.c, not * used as part of the rbt.c algorithms. */ #define DIRTY(node) ((node)->dirty) #define WILD(node) ((node)->wild) #define LOCKNUM(node) ((node)->locknum) -#define REFS(node) ((node)->references) -/* +/*% * The variable length stuff stored after the node. */ #define NAME(node) ((unsigned char *)((node) + 1)) @@ -105,7 +107,7 @@ struct dns_rbt { #define NODE_SIZE(node) (sizeof(*node) + \ NAMELEN(node) + OFFSETLEN(node) + PADBYTES(node)) -/* +/*% * Color management. */ #define IS_RED(node) ((node) != NULL && (node)->color == RED) @@ -113,7 +115,7 @@ struct dns_rbt { #define MAKE_RED(node) ((node)->color = RED) #define MAKE_BLACK(node) ((node)->color = BLACK) -/* +/*% * Chain management. * * The "ancestors" member of chains were removed, with their job now @@ -123,7 +125,7 @@ struct dns_rbt { #define ADD_LEVEL(chain, node) \ (chain)->levels[(chain)->level_count++] = (node) -/* +/*% * The following macros directly access normally private name variables. * These macros are used to avoid a lot of function calls in the critical * path of the tree traversal code. @@ -1310,6 +1312,7 @@ dns_rbt_deletenode(dns_rbt_t *rbt, dns_rbtnode_t *node, isc_boolean_t recurse) #if DNS_RBT_USEMAGIC node->magic = 0; #endif + dns_rbtnode_refdestroy(node); isc_mem_put(rbt->mctx, node, NODE_SIZE(node)); rbt->nodecount--; @@ -1434,9 +1437,9 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) { #endif LOCKNUM(node) = 0; - REFS(node) = 0; WILD(node) = 0; DIRTY(node) = 0; + dns_rbtnode_refinit(node, 0); node->find_callback = 0; MAKE_BLACK(node); diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c index 8930d35..cd25608 100644 --- a/contrib/bind9/lib/dns/rbtdb.c +++ b/contrib/bind9/lib/dns/rbtdb.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.168.2.11.2.26 2006/03/02 23:18:20 marka Exp $ */ +/* $Id: rbtdb.c,v 1.196.18.41 2006/10/26 06:04:29 marka Exp $ */ + +/*! \file */ /* * Principal Author: Bob Halley @@ -32,12 +34,15 @@ #include <isc/rwlock.h> #include <isc/string.h> #include <isc/task.h> +#include <isc/time.h> #include <isc/util.h> +#include <dns/acache.h> #include <dns/db.h> #include <dns/dbiterator.h> #include <dns/events.h> #include <dns/fixedname.h> +#include <dns/lib.h> #include <dns/log.h> #include <dns/masterdump.h> #include <dns/rbt.h> @@ -46,6 +51,8 @@ #include <dns/rdatasetiter.h> #include <dns/rdataslab.h> #include <dns/result.h> +#include <dns/view.h> +#include <dns/zone.h> #include <dns/zonekey.h> #ifdef DNS_RBTDB_VERSION64 @@ -60,7 +67,7 @@ #define RBTDB_MAGIC ISC_MAGIC('R', 'B', 'D', '4') #endif -/* +/*% * Note that "impmagic" is not the first four bytes of the struct, so * ISC_MAGIC_VALID cannot be used. */ @@ -69,7 +76,7 @@ #ifdef DNS_RBTDB_VERSION64 typedef isc_uint64_t rbtdb_serial_t; -/* +/*% * Make casting easier in symbolic debuggers by using different names * for the 64 bit version. */ @@ -98,6 +105,81 @@ typedef isc_uint32_t rbtdb_rdatatype_t; RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any) /* + * We use rwlock for DB lock only when ISC_RWLOCK_USEATOMIC is non 0. + * Using rwlock is effective with regard to lookup performance only when + * it is implemented in an efficient way. + * Otherwise, it is generally wise to stick to the simple locking since rwlock + * would require more memory or can even make lookups slower due to its own + * overhead (when it internally calls mutex locks). + */ +#ifdef ISC_RWLOCK_USEATOMIC +#define DNS_RBTDB_USERWLOCK 1 +#else +#define DNS_RBTDB_USERWLOCK 0 +#endif + +#if DNS_RBTDB_USERWLOCK +#define RBTDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) +#define RBTDB_DESTROYLOCK(l) isc_rwlock_destroy(l) +#define RBTDB_LOCK(l, t) RWLOCK((l), (t)) +#define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t)) +#else +#define RBTDB_INITLOCK(l) isc_mutex_init(l) +#define RBTDB_DESTROYLOCK(l) DESTROYLOCK(l) +#define RBTDB_LOCK(l, t) LOCK(l) +#define RBTDB_UNLOCK(l, t) UNLOCK(l) +#endif + +/* + * Since node locking is sensitive to both performance and memory footprint, + * we need some trick here. If we have both high-performance rwlock and + * high performance and small-memory reference counters, we use rwlock for + * node lock and isc_refcount for node references. In this case, we don't have + * to protect the access to the counters by locks. + * Otherwise, we simply use ordinary mutex lock for node locking, and use + * simple integers as reference counters which is protected by the lock. + * In most cases, we can simply use wrapper macros such as NODE_LOCK and + * NODE_UNLOCK. In some other cases, however, we need to protect reference + * counters first and then protect other parts of a node as read-only data. + * Special additional macros, NODE_STRONGLOCK(), NODE_WEAKLOCK(), etc, are also + * provided for these special cases. When we can use the efficient backend + * routines, we should only protect the "other members" by NODE_WEAKLOCK(read). + * Otherwise, we should use NODE_STRONGLOCK() to protect the entire critical + * section including the access to the reference counter. + * Note that we cannot use NODE_LOCK()/NODE_UNLOCK() wherever the protected + * section is also protected by NODE_STRONGLOCK(). + */ +#if defined(ISC_RWLOCK_USEATOMIC) && defined(DNS_RBT_USEISCREFCOUNT) +typedef isc_rwlock_t nodelock_t; + +#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0) +#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l) +#define NODE_LOCK(l, t) RWLOCK((l), (t)) +#define NODE_UNLOCK(l, t) RWUNLOCK((l), (t)) +#define NODE_TRYUPGRADE(l) isc_rwlock_tryupgrade(l) + +#define NODE_STRONGLOCK(l) ((void)0) +#define NODE_STRONGUNLOCK(l) ((void)0) +#define NODE_WEAKLOCK(l, t) NODE_LOCK(l, t) +#define NODE_WEAKUNLOCK(l, t) NODE_UNLOCK(l, t) +#define NODE_WEAKDOWNGRADE(l) isc_rwlock_downgrade(l) +#else +typedef isc_mutex_t nodelock_t; + +#define NODE_INITLOCK(l) isc_mutex_init(l) +#define NODE_DESTROYLOCK(l) DESTROYLOCK(l) +#define NODE_LOCK(l, t) LOCK(l) +#define NODE_UNLOCK(l, t) UNLOCK(l) +#define NODE_TRYUPGRADE(l) ISC_R_SUCCESS + +#define NODE_STRONGLOCK(l) LOCK(l) +#define NODE_STRONGUNLOCK(l) UNLOCK(l) +#define NODE_WEAKLOCK(l, t) ((void)0) +#define NODE_WEAKUNLOCK(l, t) ((void)0) +#define NODE_WEAKDOWNGRADE(l) ((void)0) +#endif + +/* * Allow clients with a virtual time of upto 5 minutes in the past to see * records that would have otherwise have expired. */ @@ -109,8 +191,10 @@ struct noqname { void * nsecsig; }; +typedef struct acachectl acachectl_t; + typedef struct rdatasetheader { - /* + /*% * Locked by the owning node's lock. */ rbtdb_serial_t serial; @@ -119,13 +203,13 @@ typedef struct rdatasetheader { isc_uint16_t attributes; dns_trust_t trust; struct noqname *noqname; - /* + /*%< * We don't use the LIST macros, because the LIST structure has * both head and tail pointers, and is doubly linked. */ struct rdatasetheader *next; - /* + /*%< * If this is the top header for an rdataset, 'next' points * to the top header for the next rdataset (i.e., the next type). * Otherwise, it points up to the header whose down pointer points @@ -133,19 +217,22 @@ typedef struct rdatasetheader { */ struct rdatasetheader *down; - /* + /*%< * Points to the header for the next older version of * this rdataset. */ isc_uint32_t count; - /* + /*%< * Monotonously increased every time this rdataset is bound so that * it is used as the base of the starting point in DNS responses * when the "cyclic" rrset-order is required. Since the ordering * should not be so crucial, no lock is set for the counter for * performance reasons. */ + + acachectl_t *additional_auth; + acachectl_t *additional_glue; } rdatasetheader_t; #define RDATASET_ATTR_NONEXISTENT 0x0001 @@ -154,6 +241,19 @@ typedef struct rdatasetheader { #define RDATASET_ATTR_RETAIN 0x0008 #define RDATASET_ATTR_NXDOMAIN 0x0010 +typedef struct acache_cbarg { + dns_rdatasetadditional_t type; + unsigned int count; + dns_db_t *db; + dns_dbnode_t *node; + rdatasetheader_t *header; +} acache_cbarg_t; + +struct acachectl { + dns_acacheentry_t *entry; + acache_cbarg_t *cbarg; +}; + /* * XXX * When the cache will pre-expire data (due to memory low or other @@ -175,12 +275,14 @@ typedef struct rdatasetheader { #define NXDOMAIN(header) \ (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) -#define DEFAULT_NODE_LOCK_COUNT 7 /* Should be prime. */ +#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */ +#define DEFAULT_CACHE_NODE_LOCK_COUNT 1009 /*%< Should be prime. */ typedef struct { - isc_mutex_t lock; + nodelock_t lock; + /* Protected in the refcount routines. */ + isc_refcount_t references; /* Locked by lock. */ - unsigned int references; isc_boolean_t exiting; } rbtdb_nodelock_t; @@ -195,9 +297,14 @@ typedef ISC_LIST(rbtdb_changed_t) rbtdb_changedlist_t; typedef struct rbtdb_version { /* Not locked */ rbtdb_serial_t serial; + /* + * Protected in the refcount routines. + * XXXJT: should we change the lock policy based on the refcount + * performance? + */ + isc_refcount_t references; /* Locked by database lock. */ isc_boolean_t writer; - unsigned int references; isc_boolean_t commit_ok; rbtdb_changedlist_t changed_list; ISC_LINK(struct rbtdb_version) link; @@ -208,7 +315,11 @@ typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t; typedef struct { /* Unlocked. */ dns_db_t common; +#if DNS_RBTDB_USERWLOCK + isc_rwlock_t lock; +#else isc_mutex_t lock; +#endif isc_rwlock_t tree_lock; unsigned int node_lock_count; rbtdb_nodelock_t * node_locks; @@ -225,15 +336,20 @@ typedef struct { rbtdb_versionlist_t open_versions; isc_boolean_t overmem; isc_task_t * task; + dns_dbnode_t *soanode; + dns_dbnode_t *nsnode; /* Locked by tree_lock. */ dns_rbt_t * tree; isc_boolean_t secure; + + /* Unlocked */ + unsigned int quantum; } dns_rbtdb_t; #define RBTDB_ATTR_LOADED 0x01 #define RBTDB_ATTR_LOADING 0x02 -/* +/*% * Search Context */ typedef struct { @@ -252,7 +368,7 @@ typedef struct { isc_stdtime_t now; } rbtdb_search_t; -/* +/*% * Load Context */ typedef struct { @@ -270,6 +386,30 @@ static isc_result_t rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataset_t *nsecsig); +static isc_result_t rdataset_getadditional(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t **zonep, + dns_db_t **dbp, + dns_dbversion_t **versionp, + dns_dbnode_t **nodep, + dns_name_t *fname, + dns_message_t *msg, + isc_stdtime_t now); +static isc_result_t rdataset_setadditional(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t *zone, + dns_db_t *db, + dns_dbversion_t *version, + dns_dbnode_t *node, + dns_name_t *fname); +static isc_result_t rdataset_putadditional(dns_acache_t *acache, + dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype); static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, @@ -279,7 +419,10 @@ static dns_rdatasetmethods_t rdataset_methods = { rdataset_clone, rdataset_count, NULL, - rdataset_getnoqname + rdataset_getnoqname, + rdataset_getadditional, + rdataset_setadditional, + rdataset_putadditional }; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); @@ -403,25 +546,87 @@ free_rbtdb_callback(isc_task_t *task, isc_event_t *event) { free_rbtdb(rbtdb, ISC_TRUE, event); } +/*% + * Work out how many nodes can be deleted in the time between two + * requests to the nameserver. Smooth the resulting number and use it + * as a estimate for the number of nodes to be deleted in the next + * iteration. + */ +static unsigned int +adjust_quantum(unsigned int old, isc_time_t *start) { + unsigned int pps = dns_pps; /* packets per second */ + unsigned int interval; + isc_uint64_t usecs; + isc_time_t end; + unsigned int new; + + if (pps < 100) + pps = 100; + isc_time_now(&end); + + interval = 1000000 / pps; /* interval in usec */ + if (interval == 0) + interval = 1; + usecs = isc_time_microdiff(&end, start); + if (usecs == 0) { + /* + * We were unable to measure the amount of time taken. + * Double the nodes deleted next time. + */ + old *= 2; + if (old > 1000) + old = 1000; + return (old); + } + new = old * interval; + new /= (unsigned int)usecs; + if (new == 0) + new = 1; + else if (new > 1000) + new = 1000; + + /* Smooth */ + new = (new + old * 3) / 4; + + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, + ISC_LOG_DEBUG(1), "adjust_quantum -> %d", new); + + return (new); +} + static void free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) { unsigned int i; isc_ondestroy_t ondest; isc_result_t result; char buf[DNS_NAME_FORMATSIZE]; + isc_time_t start; - REQUIRE(EMPTY(rbtdb->open_versions)); + REQUIRE(rbtdb->current_version != NULL || EMPTY(rbtdb->open_versions)); REQUIRE(rbtdb->future_version == NULL); - if (rbtdb->current_version != NULL) + if (rbtdb->current_version != NULL) { + unsigned int refs; + + isc_refcount_decrement(&rbtdb->current_version->references, + &refs); + INSIST(refs == 0); + UNLINK(rbtdb->open_versions, rbtdb->current_version, link); + isc_refcount_destroy(&rbtdb->current_version->references); isc_mem_put(rbtdb->common.mctx, rbtdb->current_version, sizeof(rbtdb_version_t)); + } + if (event == NULL) + rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0; again: if (rbtdb->tree != NULL) { - result = dns_rbt_destroy2(&rbtdb->tree, - (rbtdb->task != NULL) ? 1000 : 0); + isc_time_now(&start); + result = dns_rbt_destroy2(&rbtdb->tree, rbtdb->quantum); if (result == ISC_R_QUOTA) { INSIST(rbtdb->task != NULL); + if (rbtdb->quantum != 0) + rbtdb->quantum = adjust_quantum(rbtdb->quantum, + &start); if (event == NULL) event = isc_event_allocate(rbtdb->common.mctx, NULL, @@ -450,15 +655,17 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) { } if (dns_name_dynamic(&rbtdb->common.origin)) dns_name_free(&rbtdb->common.origin, rbtdb->common.mctx); - for (i = 0; i < rbtdb->node_lock_count; i++) - DESTROYLOCK(&rbtdb->node_locks[i].lock); + for (i = 0; i < rbtdb->node_lock_count; i++) { + isc_refcount_destroy(&rbtdb->node_locks[i].references); + NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); + } isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks, rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); isc_rwlock_destroy(&rbtdb->tree_lock); isc_refcount_destroy(&rbtdb->references); if (rbtdb->task != NULL) isc_task_detach(&rbtdb->task); - DESTROYLOCK(&rbtdb->lock); + RBTDB_DESTROYLOCK(&rbtdb->lock); rbtdb->common.magic = 0; rbtdb->common.impmagic = 0; ondest = rbtdb->common.ondest; @@ -474,24 +681,31 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) { /* XXX check for open versions here */ + if (rbtdb->soanode != NULL) + dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->soanode); + if (rbtdb->nsnode != NULL) + dns_db_detachnode((dns_db_t *)rbtdb, &rbtdb->nsnode); + /* * Even though there are no external direct references, there still * may be nodes in use. */ for (i = 0; i < rbtdb->node_lock_count; i++) { - LOCK(&rbtdb->node_locks[i].lock); + NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); rbtdb->node_locks[i].exiting = ISC_TRUE; - if (rbtdb->node_locks[i].references == 0) + NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); + if (isc_refcount_current(&rbtdb->node_locks[i].references) + == 0) { inactive++; - UNLOCK(&rbtdb->node_locks[i].lock); + } } if (inactive != 0) { - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); rbtdb->active -= inactive; if (rbtdb->active == 0) want_free = ISC_TRUE; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (want_free) { char buf[DNS_NAME_FORMATSIZE]; if (dns_name_dynamic(&rbtdb->common.origin)) @@ -526,15 +740,14 @@ static void currentversion(dns_db_t *db, dns_dbversion_t **versionp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_version_t *version; + unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); version = rbtdb->current_version; - if (version->references == 0) - PREPEND(rbtdb->open_versions, version, link); - version->references++; - UNLOCK(&rbtdb->lock); + isc_refcount_increment(&version->references, &refs); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); *versionp = (dns_dbversion_t *)version; } @@ -543,13 +756,18 @@ static inline rbtdb_version_t * allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial, unsigned int references, isc_boolean_t writer) { + isc_result_t result; rbtdb_version_t *version; version = isc_mem_get(mctx, sizeof(*version)); if (version == NULL) return (NULL); version->serial = serial; - version->references = references; + result = isc_refcount_init(&version->references, references); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, version, sizeof(*version)); + return (NULL); + } version->writer = writer; version->commit_ok = ISC_FALSE; ISC_LIST_INIT(version->changed_list); @@ -567,7 +785,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) { REQUIRE(versionp != NULL && *versionp == NULL); REQUIRE(rbtdb->future_version == NULL); - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); RUNTIME_CHECK(rbtdb->next_serial != 0); /* XXX Error? */ version = allocate_version(rbtdb->common.mctx, rbtdb->next_serial, 1, ISC_TRUE); @@ -576,7 +794,7 @@ newversion(dns_db_t *db, dns_dbversion_t **versionp) { rbtdb->next_serial++; rbtdb->future_version = version; } - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (version == NULL) return (ISC_R_NOMEMORY); @@ -592,16 +810,12 @@ attachversion(dns_db_t *db, dns_dbversion_t *source, { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; rbtdb_version_t *rbtversion = source; + unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); - LOCK(&rbtdb->lock); - - INSIST(rbtversion->references > 0); - rbtversion->references++; - INSIST(rbtversion->references != 0); - - UNLOCK(&rbtdb->lock); + isc_refcount_increment(&rbtversion->references, &refs); + INSIST(refs > 1); *targetp = rbtversion; } @@ -611,32 +825,62 @@ add_changed(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, dns_rbtnode_t *node) { rbtdb_changed_t *changed; + unsigned int refs; /* - * Caller must be holding the node lock. + * Caller must be holding the node lock if its reference must be + * protected by the lock. */ changed = isc_mem_get(rbtdb->common.mctx, sizeof(*changed)); - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); REQUIRE(version->writer); if (changed != NULL) { - INSIST(node->references > 0); - node->references++; - INSIST(node->references != 0); + dns_rbtnode_refincrement(node, &refs); + INSIST(refs != 0); changed->node = node; changed->dirty = ISC_FALSE; ISC_LIST_INITANDAPPEND(version->changed_list, changed, link); } else version->commit_ok = ISC_FALSE; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); return (changed); } +static void +free_acachearray(isc_mem_t *mctx, rdatasetheader_t *header, + acachectl_t *array) +{ + unsigned int count; + unsigned int i; + unsigned char *raw; /* RDATASLAB */ + + /* + * The caller must be holding the corresponding node lock. + */ + + if (array == NULL) + return; + + raw = (unsigned char *)header + sizeof(*header); + count = raw[0] * 256 + raw[1]; + + /* + * Sanity check: since an additional cache entry has a reference to + * the original DB node (in the callback arg), there should be no + * acache entries when the node can be freed. + */ + for (i = 0; i < count; i++) + INSIST(array[i].entry == NULL && array[i].cbarg == NULL); + + isc_mem_put(mctx, array, count * sizeof(acachectl_t)); +} + static inline void free_noqname(isc_mem_t *mctx, struct noqname **noqname) { @@ -658,7 +902,10 @@ free_rdataset(isc_mem_t *mctx, rdatasetheader_t *rdataset) { if (rdataset->noqname != NULL) free_noqname(mctx, &rdataset->noqname); - + + free_acachearray(mctx, rdataset, rdataset->additional_auth); + free_acachearray(mctx, rdataset, rdataset->additional_glue); + if ((rdataset->attributes & RDATASET_ATTR_NONEXISTENT) != 0) size = sizeof(*rdataset); else @@ -700,8 +947,19 @@ rollback_node(dns_rbtnode_t *node, rbtdb_serial_t serial) { } static inline void +clean_stale_headers(isc_mem_t *mctx, rdatasetheader_t *top) { + rdatasetheader_t *d, *down_next; + + for (d = top->down; d != NULL; d = down_next) { + down_next = d->down; + free_rdataset(mctx, d); + } + top->down = NULL; +} + +static inline void clean_cache_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { - rdatasetheader_t *current, *dcurrent, *top_prev, *top_next, *down_next; + rdatasetheader_t *current, *top_prev, *top_next; isc_mem_t *mctx = rbtdb->common.mctx; /* @@ -711,15 +969,7 @@ clean_cache_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { top_prev = NULL; for (current = node->data; current != NULL; current = top_next) { top_next = current->next; - dcurrent = current->down; - if (dcurrent != NULL) { - do { - down_next = dcurrent->down; - free_rdataset(mctx, dcurrent); - dcurrent = down_next; - } while (dcurrent != NULL); - current->down = NULL; - } + clean_stale_headers(mctx, current); /* * If current is nonexistent or stale, we can clean it up. */ @@ -862,31 +1112,72 @@ clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, node->dirty = 0; } +/* + * Caller must be holding the node lock if its reference must be protected + * by the lock. + */ static inline void new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { - if (node->references == 0) { - rbtdb->node_locks[node->locknum].references++; - INSIST(rbtdb->node_locks[node->locknum].references != 0); + unsigned int lockrefs, noderefs; + isc_refcount_t *lockref; + + dns_rbtnode_refincrement0(node, &noderefs); + if (noderefs == 1) { /* this is the first reference to the node */ + lockref = &rbtdb->node_locks[node->locknum].references; + isc_refcount_increment0(lockref, &lockrefs); + INSIST(lockrefs != 0); } - node->references++; - INSIST(node->references != 0); + INSIST(noderefs != 0); } -static void -no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, - rbtdb_serial_t least_serial, isc_rwlocktype_t lock) +/* + * Caller must be holding the node lock; either the "strong", read or write + * lock. Note that the lock must be held even when node references are + * atomically modified; in that case the decrement operation itself does not + * have to be protected, but we must avoid a race condition where multiple + * threads are decreasing the reference to zero simultaneously and at least + * one of them is going to free the node. + * This function returns ISC_TRUE if and only if the node reference decreases + * to zero. + */ +static isc_boolean_t +decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, + rbtdb_serial_t least_serial, + isc_rwlocktype_t nlock, isc_rwlocktype_t tlock) { isc_result_t result; isc_boolean_t write_locked; - unsigned int locknum; - - /* - * Caller must be holding the node lock. - */ + rbtdb_nodelock_t *nodelock; + unsigned int refs, nrefs; + + nodelock = &rbtdb->node_locks[node->locknum]; + + /* Handle easy and typical case first. */ + if (!node->dirty && (node->data != NULL || node->down != NULL)) { + dns_rbtnode_refdecrement(node, &nrefs); + INSIST((int)nrefs >= 0); + if (nrefs == 0) { + isc_refcount_decrement(&nodelock->references, &refs); + INSIST((int)refs >= 0); + } + return ((nrefs == 0) ? ISC_TRUE : ISC_FALSE); + } - REQUIRE(node->references == 0); + /* Upgrade the lock? */ + if (nlock == isc_rwlocktype_read) { + NODE_WEAKUNLOCK(&nodelock->lock, isc_rwlocktype_read); + NODE_WEAKLOCK(&nodelock->lock, isc_rwlocktype_write); + } + dns_rbtnode_refdecrement(node, &nrefs); + INSIST((int)nrefs >= 0); + if (nrefs > 0) { + /* Restore the lock? */ + if (nlock == isc_rwlocktype_read) + NODE_WEAKDOWNGRADE(&nodelock->lock); + return (ISC_FALSE); + } - if (node->dirty) { + if (node->dirty && dns_rbtnode_refcurrent(node) == 0) { if (IS_CACHE(rbtdb)) clean_cache_node(rbtdb, node); else { @@ -895,35 +1186,38 @@ no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, * Caller doesn't know the least serial. * Get it. */ - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); least_serial = rbtdb->least_serial; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, + isc_rwlocktype_read); } clean_zone_node(rbtdb, node, least_serial); } } - locknum = node->locknum; - - INSIST(rbtdb->node_locks[locknum].references > 0); - rbtdb->node_locks[locknum].references--; + isc_refcount_decrement(&nodelock->references, &refs); + INSIST((int)refs >= 0); /* * XXXDCL should this only be done for cache zones? */ - if (node->data != NULL || node->down != NULL) - return; + if (node->data != NULL || node->down != NULL) { + /* Restore the lock? */ + if (nlock == isc_rwlocktype_read) + NODE_WEAKDOWNGRADE(&nodelock->lock); + return (ISC_TRUE); + } /* * XXXDCL need to add a deferred delete method for ISC_R_LOCKBUSY. */ - if (lock != isc_rwlocktype_write) { + if (tlock != isc_rwlocktype_write) { /* * Locking hierarchy notwithstanding, we don't need to free * the node lock before acquiring the tree write lock because * we only do a trylock. */ - if (lock == isc_rwlocktype_read) + if (tlock == isc_rwlocktype_read) result = isc_rwlock_tryupgrade(&rbtdb->tree_lock); else result = isc_rwlock_trylock(&rbtdb->tree_lock, @@ -935,13 +1229,21 @@ no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, } else write_locked = ISC_TRUE; - if (write_locked) { + if (write_locked && dns_rbtnode_refcurrent(node) == 0) { + /* + * We can now delete the node if the reference counter is + * zero. This should be typically the case, but a different + * thread may still gain a (new) reference just before the + * current thread locks the tree (e.g., in findnode()). + */ + if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { char printname[DNS_NAME_FORMATSIZE]; isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_DEBUG(1), - "no_references: delete from rbt: %p %s", + "decrement_reference: " + "delete from rbt: %p %s", node, dns_rbt_formatnodename(node, printname, sizeof(printname))); @@ -951,20 +1253,27 @@ no_references(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, - "no_references: dns_rbt_deletenode: %s", + "decrement_reference: " + "dns_rbt_deletenode: %s", isc_result_totext(result)); } + /* Restore the lock? */ + if (nlock == isc_rwlocktype_read) + NODE_WEAKDOWNGRADE(&nodelock->lock); + /* * Relock a read lock, or unlock the write lock if no lock was held. */ - if (lock == isc_rwlocktype_none) + if (tlock == isc_rwlocktype_none) if (write_locked) RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); - if (lock == isc_rwlocktype_read) + if (tlock == isc_rwlocktype_read) if (write_locked) isc_rwlock_downgrade(&rbtdb->tree_lock); + + return (ISC_TRUE); } static inline void @@ -1061,7 +1370,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { rbtdb_changed_t *changed, *next_changed; rbtdb_serial_t serial, least_serial; dns_rbtnode_t *rbtnode; - isc_mutex_t *lock; + unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); version = (rbtdb_version_t *)*versionp; @@ -1069,113 +1378,146 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { cleanup_version = NULL; ISC_LIST_INIT(cleanup_list); - LOCK(&rbtdb->lock); - INSIST(version->references > 0); - INSIST(!version->writer || !(commit && version->references > 1)); - version->references--; + isc_refcount_decrement(&version->references, &refs); + if (refs > 0) { /* typical and easy case first */ + if (commit) { + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read); + INSIST(!version->writer); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read); + } + goto end; + } + + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); serial = version->serial; - if (version->references == 0) { - if (version->writer) { - if (commit) { - INSIST(version->commit_ok); - INSIST(version == rbtdb->future_version); - if (EMPTY(rbtdb->open_versions)) { - /* - * We're going to become the least open - * version. - */ - make_least_version(rbtdb, version, - &cleanup_list); - } else { - /* - * Some other open version is the - * least version. We can't cleanup - * records that were changed in this - * version because the older versions - * may still be in use by an open - * version. - * - * We can, however, discard the - * changed records for things that - * we've added that didn't exist in - * prior versions. - */ - cleanup_nondirty(version, - &cleanup_list); - } - /* - * If the (soon to be former) current version - * isn't being used by anyone, we can clean - * it up. - */ - if (rbtdb->current_version->references == 0) { - cleanup_version = - rbtdb->current_version; - APPENDLIST(version->changed_list, - cleanup_version->changed_list, - link); - } + if (version->writer) { + if (commit) { + unsigned cur_ref; + rbtdb_version_t *cur_version; + + INSIST(version->commit_ok); + INSIST(version == rbtdb->future_version); + /* + * The current version is going to be replaced. + * Release the (likely last) reference to it from the + * DB itself and unlink it from the open list. + */ + cur_version = rbtdb->current_version; + isc_refcount_decrement(&cur_version->references, + &cur_ref); + if (cur_ref == 0) { + if (cur_version->serial == rbtdb->least_serial) + INSIST(EMPTY(cur_version->changed_list)); + UNLINK(rbtdb->open_versions, + cur_version, link); + } + if (EMPTY(rbtdb->open_versions)) { /* - * Become the current version. + * We're going to become the least open + * version. */ - version->writer = ISC_FALSE; - rbtdb->current_version = version; - rbtdb->current_serial = version->serial; - rbtdb->future_version = NULL; + make_least_version(rbtdb, version, + &cleanup_list); } else { /* - * We're rolling back this transaction. + * Some other open version is the + * least version. We can't cleanup + * records that were changed in this + * version because the older versions + * may still be in use by an open + * version. + * + * We can, however, discard the + * changed records for things that + * we've added that didn't exist in + * prior versions. */ - cleanup_list = version->changed_list; - ISC_LIST_INIT(version->changed_list); - rollback = ISC_TRUE; - cleanup_version = version; - rbtdb->future_version = NULL; + cleanup_nondirty(version, &cleanup_list); } + /* + * If the (soon to be former) current version + * isn't being used by anyone, we can clean + * it up. + */ + if (cur_ref == 0) { + cleanup_version = cur_version; + APPENDLIST(version->changed_list, + cleanup_version->changed_list, + link); + } + /* + * Become the current version. + */ + version->writer = ISC_FALSE; + rbtdb->current_version = version; + rbtdb->current_serial = version->serial; + rbtdb->future_version = NULL; + + /* + * Keep the current version in the open list, and + * gain a reference for the DB itself (see the DB + * creation function below). This must be the only + * case where we need to increment the counter from + * zero and need to use isc_refcount_increment0(). + */ + isc_refcount_increment0(&version->references, + &cur_ref); + INSIST(cur_ref == 1); + PREPEND(rbtdb->open_versions, + rbtdb->current_version, link); } else { - if (version != rbtdb->current_version) { - /* - * There are no external or internal references - * to this version and it can be cleaned up. - */ - cleanup_version = version; + /* + * We're rolling back this transaction. + */ + cleanup_list = version->changed_list; + ISC_LIST_INIT(version->changed_list); + rollback = ISC_TRUE; + cleanup_version = version; + rbtdb->future_version = NULL; + } + } else { + if (version != rbtdb->current_version) { + /* + * There are no external or internal references + * to this version and it can be cleaned up. + */ + cleanup_version = version; + /* + * Find the version with the least serial + * number greater than ours. + */ + least_greater = PREV(version, link); + if (least_greater == NULL) + least_greater = rbtdb->current_version; + + INSIST(version->serial < least_greater->serial); + /* + * Is this the least open version? + */ + if (version->serial == rbtdb->least_serial) { /* - * Find the version with the least serial - * number greater than ours. + * Yes. Install the new least open + * version. */ - least_greater = PREV(version, link); - if (least_greater == NULL) - least_greater = rbtdb->current_version; - - INSIST(version->serial < least_greater->serial); + make_least_version(rbtdb, + least_greater, + &cleanup_list); + } else { /* - * Is this the least open version? + * Add any unexecuted cleanups to + * those of the least greater version. */ - if (version->serial == rbtdb->least_serial) { - /* - * Yes. Install the new least open - * version. - */ - make_least_version(rbtdb, - least_greater, - &cleanup_list); - } else { - /* - * Add any unexecuted cleanups to - * those of the least greater version. - */ - APPENDLIST(least_greater->changed_list, - version->changed_list, - link); - } - } else if (version->serial == rbtdb->least_serial) - INSIST(EMPTY(version->changed_list)); - UNLINK(rbtdb->open_versions, version, link); - } + APPENDLIST(least_greater->changed_list, + version->changed_list, + link); + } + } else if (version->serial == rbtdb->least_serial) + INSIST(EMPTY(version->changed_list)); + UNLINK(rbtdb->open_versions, version, link); } least_serial = rbtdb->least_serial; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); /* * Update the zone's secure status. @@ -1193,28 +1535,26 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { for (changed = HEAD(cleanup_list); changed != NULL; changed = next_changed) { + nodelock_t *lock; + next_changed = NEXT(changed, link); rbtnode = changed->node; lock = &rbtdb->node_locks[rbtnode->locknum].lock; - LOCK(lock); - - INSIST(rbtnode->references > 0); - rbtnode->references--; + NODE_LOCK(lock, isc_rwlocktype_write); if (rollback) rollback_node(rbtnode, serial); - - if (rbtnode->references == 0) - no_references(rbtdb, rbtnode, least_serial, - isc_rwlocktype_none); - - UNLOCK(lock); + decrement_reference(rbtdb, rbtnode, least_serial, + isc_rwlocktype_write, + isc_rwlocktype_none); + NODE_UNLOCK(lock, isc_rwlocktype_write); isc_mem_put(rbtdb->common.mctx, changed, sizeof(*changed)); } } + end: *versionp = NULL; } @@ -1287,7 +1627,6 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *node = NULL; dns_name_t nodename; - unsigned int locknum; isc_result_t result; isc_rwlocktype_t locktype = isc_rwlocktype_read; @@ -1334,10 +1673,9 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, return (result); } } - locknum = node->locknum; - LOCK(&rbtdb->node_locks[locknum].lock); + NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); new_reference(rbtdb, node); - UNLOCK(&rbtdb->node_locks[locknum].lock); + NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); RWUNLOCK(&rbtdb->tree_lock, locktype); *nodep = (dns_dbnode_t *)node; @@ -1366,7 +1704,8 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { result = DNS_R_CONTINUE; onode = search->rbtdb->origin_node; - LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); /* * Look for an NS or DNAME rdataset active in our version. @@ -1477,7 +1816,8 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { search->wild = ISC_TRUE; } - UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); return (result); } @@ -1487,10 +1827,14 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header, isc_stdtime_t now, dns_rdataset_t *rdataset) { - unsigned char *raw; + unsigned char *raw; /* RDATASLAB */ /* - * Caller must be holding the node lock. + * Caller must be holding the node reader lock. + * XXXJT: technically, we need a writer lock, since we'll increment + * the header count below. However, since the actual counter value + * doesn't matter, we prioritize performance here. (We may want to + * use atomic increment when available). */ if (rdataset == NULL) @@ -1570,14 +1914,16 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep, search->need_cleanup = ISC_FALSE; } if (rdataset != NULL) { - LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); bind_rdataset(search->rbtdb, node, search->zonecut_rdataset, search->now, rdataset); if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL) bind_rdataset(search->rbtdb, node, search->zonecut_sigrdataset, search->now, sigrdataset); - UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); } if (type == dns_rdatatype_dname) @@ -1589,7 +1935,7 @@ static inline isc_boolean_t valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type, dns_rbtnode_t *node) { - unsigned char *raw; + unsigned char *raw; /* RDATASLAB */ unsigned int count, size; dns_name_t ns_name; isc_boolean_t valid = ISC_FALSE; @@ -1618,12 +1964,12 @@ valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type, header = search->zonecut_rdataset; raw = (unsigned char *)header + sizeof(*header); count = raw[0] * 256 + raw[1]; - raw += 2; + raw += 2 + (4 * count); while (count > 0) { count--; size = raw[0] * 256 + raw[1]; - raw += 2; + raw += 4; region.base = raw; region.length = size; raw += size; @@ -1672,7 +2018,8 @@ activeempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain, origin, &node); if (result != ISC_R_SUCCESS) break; - LOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); for (header = node->data; header != NULL; header = header->next) { @@ -1680,7 +2027,8 @@ activeempty(rbtdb_search_t *search, dns_rbtnodechain_t *chain, !IGNORE(header) && EXISTS(header)) break; } - UNLOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); if (header != NULL) break; result = dns_rbtnodechain_next(chain, NULL, NULL); @@ -1737,7 +2085,8 @@ activeemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) { origin, &node); if (result != ISC_R_SUCCESS) break; - LOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); for (header = node->data; header != NULL; header = header->next) { @@ -1745,7 +2094,8 @@ activeemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) { !IGNORE(header) && EXISTS(header)) break; } - UNLOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); if (header != NULL) break; result = dns_rbtnodechain_prev(&chain, NULL, NULL); @@ -1762,7 +2112,8 @@ activeemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) { origin, &node); if (result != ISC_R_SUCCESS) break; - LOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); for (header = node->data; header != NULL; header = header->next) { @@ -1770,7 +2121,8 @@ activeemtpynode(rbtdb_search_t *search, dns_name_t *qname, dns_name_t *wname) { !IGNORE(header) && EXISTS(header)) break; } - UNLOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); if (header != NULL) break; result = dns_rbtnodechain_next(&chain, NULL, NULL); @@ -1838,7 +2190,8 @@ find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep, done = ISC_FALSE; node = *nodep; do { - LOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); /* * First we try to figure out if this node is active in @@ -1863,7 +2216,8 @@ find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep, else wild = ISC_FALSE; - UNLOCK(&(rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); if (wild) { /* @@ -1896,33 +2250,38 @@ find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result == ISC_R_SUCCESS) { - /* - * We have found the wildcard node. If it - * is active in the search's version, we're - * done. - */ - LOCK(&(rbtdb->node_locks[wnode->locknum].lock)); - for (header = wnode->data; - header != NULL; - header = header->next) { - if (header->serial <= search->serial && - !IGNORE(header) && EXISTS(header)) - break; - } - UNLOCK(&(rbtdb->node_locks[wnode->locknum].lock)); - if (header != NULL || - activeempty(search, &wchain, wname)) { - if (activeemtpynode(search, qname, wname)) + nodelock_t *lock; + + /* + * We have found the wildcard node. If it + * is active in the search's version, we're + * done. + */ + lock = &rbtdb->node_locks[wnode->locknum].lock; + NODE_LOCK(lock, isc_rwlocktype_read); + for (header = wnode->data; + header != NULL; + header = header->next) { + if (header->serial <= search->serial && + !IGNORE(header) && EXISTS(header)) + break; + } + NODE_UNLOCK(lock, isc_rwlocktype_read); + if (header != NULL || + activeempty(search, &wchain, wname)) { + if (activeemtpynode(search, qname, + wname)) { return (ISC_R_NOTFOUND); - /* - * The wildcard node is active! - * - * Note: result is still ISC_R_SUCCESS - * so we don't have to set it. - */ - *nodep = wnode; - break; - } + } + /* + * The wildcard node is active! + * + * Note: result is still ISC_R_SUCCESS + * so we don't have to set it. + */ + *nodep = wnode; + break; + } } else if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) { /* @@ -1974,7 +2333,8 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, origin, &node); if (result != ISC_R_SUCCESS) return (result); - LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); found = NULL; foundsig = NULL; empty_node = ISC_TRUE; @@ -2074,7 +2434,8 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep, result = dns_rbtnodechain_prev(&search->chain, NULL, NULL); } - UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); } while (empty_node && result == ISC_R_SUCCESS); /* @@ -2103,12 +2464,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, isc_boolean_t at_zonecut = ISC_FALSE; isc_boolean_t wild; isc_boolean_t empty_node; - isc_mutex_t *lock; rdatasetheader_t *header, *header_next, *found, *nsecheader; rdatasetheader_t *foundsig, *cnamesig, *nsecsig; rbtdb_rdatatype_t sigtype; isc_boolean_t active; dns_rbtnodechain_t chain; + nodelock_t *lock; search.rbtdb = (dns_rbtdb_t *)db; @@ -2243,7 +2604,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * We now go looking for rdata... */ - LOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_LOCK(&(search.rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); found = NULL; foundsig = NULL; @@ -2391,7 +2753,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * we really have a partial match. */ if (!wild) { - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + lock = &search.rbtdb->node_locks[node->locknum].lock; + NODE_UNLOCK(lock, isc_rwlocktype_read); goto partial_match; } } @@ -2401,16 +2764,17 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, */ if (found == NULL) { if (search.zonecut != NULL) { - /* - * We were trying to find glue at a node beneath a - * zone cut, but didn't. - * - * Return the delegation. - */ - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); - result = setup_delegation(&search, nodep, foundname, - rdataset, sigrdataset); - goto tree_exit; + /* + * We were trying to find glue at a node beneath a + * zone cut, but didn't. + * + * Return the delegation. + */ + lock = &search.rbtdb->node_locks[node->locknum].lock; + NODE_UNLOCK(lock, isc_rwlocktype_read); + result = setup_delegation(&search, nodep, foundname, + rdataset, sigrdataset); + goto tree_exit; } /* * The desired type doesn't exist. @@ -2426,11 +2790,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, result = DNS_R_BADDB; goto node_exit; } - - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + + lock = &search.rbtdb->node_locks[node->locknum].lock; + NODE_UNLOCK(lock, isc_rwlocktype_read); result = find_closest_nsec(&search, nodep, foundname, - rdataset, sigrdataset, - search.rbtdb->secure); + rdataset, sigrdataset, + search.rbtdb->secure); if (result == ISC_R_SUCCESS) result = DNS_R_EMPTYWILD; goto tree_exit; @@ -2508,9 +2873,10 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, if (result == DNS_R_GLUE && (search.options & DNS_DBFIND_VALIDATEGLUE) != 0 && !valid_glue(&search, foundname, type, node)) { - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); - result = setup_delegation(&search, nodep, foundname, - rdataset, sigrdataset); + lock = &search.rbtdb->node_locks[node->locknum].lock; + NODE_UNLOCK(lock, isc_rwlocktype_read); + result = setup_delegation(&search, nodep, foundname, + rdataset, sigrdataset); goto tree_exit; } } else { @@ -2539,7 +2905,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, foundname->attributes |= DNS_NAMEATTR_WILDCARD; node_exit: - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock), + isc_rwlocktype_read); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); @@ -2552,14 +2919,10 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, node = search.zonecut; lock = &(search.rbtdb->node_locks[node->locknum].lock); - LOCK(lock); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) - no_references(search.rbtdb, node, 0, - isc_rwlocktype_none); - - UNLOCK(lock); + NODE_LOCK(lock, isc_rwlocktype_read); + decrement_reference(search.rbtdb, node, 0, + isc_rwlocktype_read, isc_rwlocktype_none); + NODE_UNLOCK(lock, isc_rwlocktype_read); } if (close_version) @@ -2596,6 +2959,8 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *dname_header, *sigdname_header; isc_result_t result; + nodelock_t *lock; + isc_rwlocktype_t locktype; /* XXX comment */ @@ -2606,7 +2971,9 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { */ UNUSED(name); - LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + lock = &(search->rbtdb->node_locks[node->locknum].lock); + locktype = isc_rwlocktype_read; + NODE_LOCK(lock, locktype); /* * Look for a DNAME or RRSIG DNAME rdataset. @@ -2624,21 +2991,47 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { * the node as dirty, so it will get cleaned * up later. */ - if (node->references == 0) { - INSIST(header->down == NULL); - if (header_prev != NULL) - header_prev->next = - header->next; - else - node->data = header->next; - free_rdataset(search->rbtdb->common.mctx, - header); - } else { - header->attributes |= - RDATASET_ATTR_STALE; - node->dirty = 1; + if ((header->ttl <= search->now - RBTDB_VIRTUAL) && + (locktype == isc_rwlocktype_write || + NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { + /* + * We update the node's status only when we + * can get write access; otherwise, we leave + * others to this work. Periodical cleaning + * will eventually take the job as the last + * resort. + * We won't downgrade the lock, since other + * rdatasets are probably stale, too. + */ + locktype = isc_rwlocktype_write; + + if (dns_rbtnode_refcurrent(node) == 0) { + isc_mem_t *mctx; + + /* + * header->down can be non-NULL if the + * refcount has just decremented to 0 + * but decrement_reference() has not + * performed clean_cache_node(), in + * which case we need to purge the + * stale headers first. + */ + mctx = search->rbtdb->common.mctx; + clean_stale_headers(mctx, header); + if (header_prev != NULL) + header_prev->next = + header->next; + else + node->data = header->next; + free_rdataset(mctx, header); + } else { + header->attributes |= + RDATASET_ATTR_STALE; + node->dirty = 1; + header_prev = header; + } + } else header_prev = header; - } } else if (header->type == dns_rdatatype_dname && EXISTS(header)) { dname_header = header; @@ -2667,7 +3060,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) { } else result = DNS_R_CONTINUE; - UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); return (result); } @@ -2685,6 +3078,8 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node, dns_name_t name; dns_rbtdb_t *rbtdb; isc_boolean_t done; + nodelock_t *lock; + isc_rwlocktype_t locktype; /* * Caller must be holding the tree lock. @@ -2694,7 +3089,9 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node, i = search->chain.level_matches; done = ISC_FALSE; do { - LOCK(&(rbtdb->node_locks[node->locknum].lock)); + locktype = isc_rwlocktype_read; + lock = &rbtdb->node_locks[node->locknum].lock; + NODE_LOCK(lock, locktype); /* * Look for NS and RRSIG NS rdatasets. @@ -2714,21 +3111,37 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node, * the node as dirty, so it will get cleaned * up later. */ - if (node->references == 0) { - INSIST(header->down == NULL); - if (header_prev != NULL) - header_prev->next = - header->next; - else - node->data = header->next; - free_rdataset(rbtdb->common.mctx, - header); - } else { - header->attributes |= - RDATASET_ATTR_STALE; - node->dirty = 1; + if ((header->ttl <= search->now - + RBTDB_VIRTUAL) && + (locktype == isc_rwlocktype_write || + NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { + /* + * We update the node's status only + * when we can get write access. + */ + locktype = isc_rwlocktype_write; + + if (dns_rbtnode_refcurrent(node) + == 0) { + isc_mem_t *m; + + m = search->rbtdb->common.mctx; + clean_stale_headers(m, header); + if (header_prev != NULL) + header_prev->next = + header->next; + else + node->data = + header->next; + free_rdataset(m, header); + } else { + header->attributes |= + RDATASET_ATTR_STALE; + node->dirty = 1; + header_prev = header; + } + } else header_prev = header; - } } else if (EXISTS(header)) { /* * We've found an extant rdataset. See if @@ -2792,7 +3205,7 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node, } node_exit: - UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); if (found == NULL && i > 0) { i--; @@ -2818,6 +3231,8 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, dns_fixedname_t fname, forigin; dns_name_t *name, *origin; rbtdb_rdatatype_t matchtype, sigmatchtype; + nodelock_t *lock; + isc_rwlocktype_t locktype; matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0); sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, @@ -2833,7 +3248,9 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, origin, &node); if (result != ISC_R_SUCCESS) return (result); - LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + locktype = isc_rwlocktype_read; + lock = &(search->rbtdb->node_locks[node->locknum].lock); + NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; empty_node = ISC_TRUE; @@ -2850,23 +3267,35 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, * node as dirty, so it will get cleaned up * later. */ - if (header->ttl > search->now - RBTDB_VIRTUAL) - header_prev = header; - else if (node->references == 0) { - INSIST(header->down == NULL); - if (header_prev != NULL) - header_prev->next = - header->next; - else - node->data = header->next; - free_rdataset(search->rbtdb->common.mctx, - header); - } else { - header->attributes |= - RDATASET_ATTR_STALE; - node->dirty = 1; + if ((header->ttl <= now - RBTDB_VIRTUAL) && + (locktype == isc_rwlocktype_write || + NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { + /* + * We update the node's status only + * when we can get write access. + */ + locktype = isc_rwlocktype_write; + + if (dns_rbtnode_refcurrent(node) + == 0) { + isc_mem_t *m; + + m = search->rbtdb->common.mctx; + clean_stale_headers(m, header); + if (header_prev != NULL) + header_prev->next = + header->next; + else + node->data = header->next; + free_rdataset(m, header); + } else { + header->attributes |= + RDATASET_ATTR_STALE; + node->dirty = 1; + header_prev = header; + } + } else header_prev = header; - } continue; } if (NONEXISTENT(header) || NXDOMAIN(header)) { @@ -2899,7 +3328,7 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep, result = dns_rbtnodechain_prev(&search->chain, NULL, NULL); unlock_node: - UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); } while (empty_node && result == ISC_R_SUCCESS); return (result); } @@ -2915,7 +3344,8 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, rbtdb_search_t search; isc_boolean_t cname_ok = ISC_TRUE; isc_boolean_t empty_node; - isc_mutex_t *lock; + nodelock_t *lock; + isc_rwlocktype_t locktype; rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *found, *nsheader; rdatasetheader_t *foundsig, *nssig, *cnamesig; @@ -2989,7 +3419,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * We now go looking for rdata... */ - LOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + lock = &(search.rbtdb->node_locks[node->locknum].lock); + locktype = isc_rwlocktype_read; + NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; @@ -3009,21 +3441,34 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * mark it as stale, and the node as dirty, so it will * get cleaned up later. */ - if (header->ttl > now - RBTDB_VIRTUAL) - header_prev = header; - else if (node->references == 0) { - INSIST(header->down == NULL); - if (header_prev != NULL) - header_prev->next = header->next; - else - node->data = header->next; - free_rdataset(search.rbtdb->common.mctx, - header); - } else { - header->attributes |= RDATASET_ATTR_STALE; - node->dirty = 1; + if ((header->ttl <= now - RBTDB_VIRTUAL) && + (locktype == isc_rwlocktype_write || + NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { + /* + * We update the node's status only when we + * can get write access. + */ + locktype = isc_rwlocktype_write; + + if (dns_rbtnode_refcurrent(node) == 0) { + isc_mem_t *mctx; + + mctx = search.rbtdb->common.mctx; + clean_stale_headers(mctx, header); + if (header_prev != NULL) + header_prev->next = + header->next; + else + node->data = header->next; + free_rdataset(mctx, header); + } else { + header->attributes |= + RDATASET_ATTR_STALE; + node->dirty = 1; + header_prev = header; + } + } else header_prev = header; - } } else if (EXISTS(header)) { /* * We now know that there is at least one active @@ -3103,7 +3548,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * extant rdatasets. That means that this node doesn't * meaningfully exist, and that we really have a partial match. */ - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); goto find_ns; } @@ -3136,7 +3581,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, /* * Go find the deepest zone cut. */ - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); goto find_ns; } @@ -3183,7 +3628,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, } node_exit: - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); @@ -3196,13 +3641,10 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, node = search.zonecut; lock = &(search.rbtdb->node_locks[node->locknum].lock); - LOCK(lock); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) - no_references(search.rbtdb, node, 0, - isc_rwlocktype_none); - UNLOCK(lock); + NODE_LOCK(lock, isc_rwlocktype_read); + decrement_reference(search.rbtdb, node, 0, + isc_rwlocktype_read, isc_rwlocktype_none); + NODE_UNLOCK(lock, isc_rwlocktype_read); } dns_rbtnodechain_reset(&search.chain); @@ -3217,11 +3659,13 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_rbtnode_t *node = NULL; + nodelock_t *lock; isc_result_t result; rbtdb_search_t search; rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *found, *foundsig; unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA; + isc_rwlocktype_t locktype; search.rbtdb = (dns_rbtdb_t *)db; @@ -3264,7 +3708,9 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, * We now go looking for an NS rdataset at the node. */ - LOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + lock = &(search.rbtdb->node_locks[node->locknum].lock); + locktype = isc_rwlocktype_read; + NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; @@ -3278,21 +3724,34 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, * mark it as stale, and the node as dirty, so it will * get cleaned up later. */ - if (header->ttl > now - RBTDB_VIRTUAL) - header_prev = header; - else if (node->references == 0) { - INSIST(header->down == NULL); - if (header_prev != NULL) - header_prev->next = header->next; - else - node->data = header->next; - free_rdataset(search.rbtdb->common.mctx, - header); - } else { - header->attributes |= RDATASET_ATTR_STALE; - node->dirty = 1; + if ((header->ttl <= now - RBTDB_VIRTUAL) && + (locktype == isc_rwlocktype_write || + NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { + /* + * We update the node's status only when we + * can get write access. + */ + locktype = isc_rwlocktype_write; + + if (dns_rbtnode_refcurrent(node) == 0) { + isc_mem_t *mctx; + + mctx = search.rbtdb->common.mctx; + clean_stale_headers(mctx, header); + if (header_prev != NULL) + header_prev->next = + header->next; + else + node->data = header->next; + free_rdataset(mctx, header); + } else { + header->attributes |= + RDATASET_ATTR_STALE; + node->dirty = 1; + header_prev = header; + } + } else header_prev = header; - } } else if (EXISTS(header)) { /* * If we found a type we were looking for, remember @@ -3321,7 +3780,7 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, /* * No NS records here. */ - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); goto find_ns; } @@ -3335,7 +3794,7 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, bind_rdataset(search.rbtdb, node, foundsig, search.now, sigrdataset); - UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); + NODE_UNLOCK(lock, locktype); tree_exit: RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read); @@ -3354,15 +3813,15 @@ static void attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *node = (dns_rbtnode_t *)source; + unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(targetp != NULL && *targetp == NULL); - LOCK(&rbtdb->node_locks[node->locknum].lock); - INSIST(node->references > 0); - node->references++; - INSIST(node->references != 0); /* Catch overflow. */ - UNLOCK(&rbtdb->node_locks[node->locknum].lock); + NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); + dns_rbtnode_refincrement(node, &refs); + INSIST(refs != 0); + NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); *targetp = source; } @@ -3373,35 +3832,34 @@ detachnode(dns_db_t *db, dns_dbnode_t **targetp) { dns_rbtnode_t *node; isc_boolean_t want_free = ISC_FALSE; isc_boolean_t inactive = ISC_FALSE; - unsigned int locknum; + rbtdb_nodelock_t *nodelock; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(targetp != NULL && *targetp != NULL); node = (dns_rbtnode_t *)(*targetp); - locknum = node->locknum; + nodelock = &rbtdb->node_locks[node->locknum]; - LOCK(&rbtdb->node_locks[locknum].lock); + NODE_LOCK(&nodelock->lock, isc_rwlocktype_read); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) { - no_references(rbtdb, node, 0, isc_rwlocktype_none); - if (rbtdb->node_locks[locknum].references == 0 && - rbtdb->node_locks[locknum].exiting) + if (decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, + isc_rwlocktype_none)) { + if (isc_refcount_current(&nodelock->references) == 0 && + nodelock->exiting) { inactive = ISC_TRUE; + } } - UNLOCK(&rbtdb->node_locks[locknum].lock); + NODE_UNLOCK(&nodelock->lock, isc_rwlocktype_read); *targetp = NULL; if (inactive) { - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); rbtdb->active--; if (rbtdb->active == 0) want_free = ISC_TRUE; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); if (want_free) { char buf[DNS_NAME_FORMATSIZE]; if (dns_name_dynamic(&rbtdb->common.origin)) @@ -3465,14 +3923,19 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { sizeof(printname))); } - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + /* + * We may not need write access, but this code path is not performance + * sensitive, so it should be okay to always lock as a writer. + */ + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); for (header = rbtnode->data; header != NULL; header = header->next) if (header->ttl <= now - RBTDB_VIRTUAL) { /* - * We don't check if rbtnode->references == 0 and try + * We don't check if refcurrent(rbtnode) == 0 and try * to free like we do in cache_find(), because - * rbtnode->references must be non-zero. This is so + * refcurrent(rbtnode) must be non-zero. This is so * because 'node' is an argument to the function. */ header->attributes |= RDATASET_ATTR_STALE; @@ -3496,7 +3959,8 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { isc_log_write(dns_lctx, category, module, level, "overmem cache: saved %s", printname); - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); return (ISC_R_SUCCESS); } @@ -3518,10 +3982,12 @@ printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { REQUIRE(VALID_RBTDB(rbtdb)); - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); fprintf(out, "node %p, %u references, locknum = %u\n", - rbtnode, rbtnode->references, rbtnode->locknum); + rbtnode, dns_rbtnode_refcurrent(rbtnode), + rbtnode->locknum); if (rbtnode->data != NULL) { rdatasetheader_t *current, *top_next; @@ -3547,7 +4013,8 @@ printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { } else fprintf(out, "(empty)\n"); - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); } static isc_result_t @@ -3608,7 +4075,8 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, serial = rbtversion->serial; now = 0; - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); found = NULL; foundsig = NULL; @@ -3656,7 +4124,8 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, sigrdataset); } - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); if (close_version) closeversion(db, (dns_dbversion_t **) (void *)(&rbtversion), @@ -3679,6 +4148,8 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, rdatasetheader_t *header, *header_next, *found, *foundsig; rbtdb_rdatatype_t matchtype, sigmatchtype, negtype; isc_result_t result; + nodelock_t *lock; + isc_rwlocktype_t locktype; REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(type != dns_rdatatype_any); @@ -3690,7 +4161,9 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, if (now == 0) isc_stdtime_get(&now); - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + lock = &rbtdb->node_locks[rbtnode->locknum].lock; + locktype = isc_rwlocktype_read; + NODE_LOCK(lock, locktype); found = NULL; foundsig = NULL; @@ -3704,13 +4177,22 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, for (header = rbtnode->data; header != NULL; header = header_next) { header_next = header->next; if (header->ttl <= now) { - /* - * We don't check if rbtnode->references == 0 and try - * to free like we do in cache_find(), because - * rbtnode->references must be non-zero. This is so - * because 'node' is an argument to the function. - */ - if (header->ttl <= now - RBTDB_VIRTUAL) { + if ((header->ttl <= now - RBTDB_VIRTUAL) && + (locktype == isc_rwlocktype_write || + NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS)) { + /* + * We update the node's status only when we + * can get write access. + */ + locktype = isc_rwlocktype_write; + + /* + * We don't check if refcurrent(rbtnode) == 0 + * and try to free like we do in cache_find(), + * because refcurrent(rbtnode) must be + * non-zero. This is so because 'node' is an + * argument to the function. + */ header->attributes |= RDATASET_ATTR_STALE; rbtnode->dirty = 1; } @@ -3731,7 +4213,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, sigrdataset); } - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(lock, locktype); if (found == NULL) return (ISC_R_NOTFOUND); @@ -3757,6 +4239,7 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rbtdb_version_t *rbtversion = version; rbtdb_rdatasetiter_t *iterator; + unsigned int refs; REQUIRE(VALID_RBTDB(rbtdb)); @@ -3770,11 +4253,11 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, currentversion(db, (dns_dbversion_t **) (void *)(&rbtversion)); else { - LOCK(&rbtdb->lock); - INSIST(rbtversion->references > 0); - rbtversion->references++; - INSIST(rbtversion->references != 0); - UNLOCK(&rbtdb->lock); + unsigned int refs; + + isc_refcount_increment(&rbtversion->references, + &refs); + INSIST(refs > 1); } } else { if (now == 0) @@ -3789,14 +4272,14 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, iterator->common.version = (dns_dbversion_t *)rbtversion; iterator->common.now = now; - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_STRONGLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + + dns_rbtnode_refincrement(rbtnode, &refs); + INSIST(refs != 0); - INSIST(rbtnode->references > 0); - rbtnode->references++; - INSIST(rbtnode->references != 0); iterator->current = NULL; - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_STRONGUNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); *iteratorp = (dns_rdatasetiter_t *)iterator; @@ -3987,6 +4470,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, * The NXDOMAIN/NODATA(QTYPE=ANY) * is more trusted. */ + free_rdataset(rbtdb->common.mctx, newheader); if (addedrdataset != NULL) @@ -4343,6 +4827,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->noqname = NULL; newheader->count = 0; newheader->trust = rdataset->trust; + newheader->additional_auth = NULL; + newheader->additional_glue = NULL; if (rbtversion != NULL) { newheader->serial = rbtversion->serial; now = 0; @@ -4371,14 +4857,16 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, } else delegating = ISC_FALSE; - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); result = add(rbtdb, rbtnode, rbtversion, newheader, options, ISC_FALSE, addedrdataset, now); if (result == ISC_R_SUCCESS && delegating) rbtnode->find_callback = 1; - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); if (delegating) RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); @@ -4423,13 +4911,17 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->trust = 0; newheader->noqname = NULL; newheader->count = 0; + newheader->additional_auth = NULL; + newheader->additional_glue = NULL; - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); changed = add_changed(rbtdb, rbtversion, rbtnode); if (changed == NULL) { free_rdataset(rbtdb->common.mctx, newheader); - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); return (ISC_R_NOMEMORY); } @@ -4476,6 +4968,13 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * header, not newheader. */ newheader->serial = rbtversion->serial; + /* + * XXXJT: dns_rdataslab_subtract() copied the pointers + * to additional info. We need to clear these fields + * to avoid having duplicated references. + */ + newheader->additional_auth = NULL; + newheader->additional_glue = NULL; } else if (result == DNS_R_NXRRSET) { /* * This subtraction would remove all of the rdata; @@ -4495,6 +4994,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->serial = rbtversion->serial; newheader->noqname = NULL; newheader->count = 0; + newheader->additional_auth = NULL; + newheader->additional_glue = NULL; } else { free_rdataset(rbtdb->common.mctx, newheader); goto unlock; @@ -4530,7 +5031,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, bind_rdataset(rbtdb, rbtnode, newheader, 0, newrdataset); unlock: - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); /* * Update the zone's secure status. If version is non-NULL @@ -4567,18 +5069,22 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, newheader->attributes = RDATASET_ATTR_NONEXISTENT; newheader->trust = 0; newheader->noqname = NULL; + newheader->additional_auth = NULL; + newheader->additional_glue = NULL; if (rbtversion != NULL) newheader->serial = rbtversion->serial; else newheader->serial = 0; newheader->count = 0; - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); result = add(rbtdb, rbtnode, rbtversion, newheader, DNS_DBADD_FORCE, ISC_FALSE, NULL, 0); - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); /* * Update the zone's secure status. If version is non-NULL @@ -4656,6 +5162,8 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) { newheader->serial = 1; newheader->noqname = NULL; newheader->count = 0; + newheader->additional_auth = NULL; + newheader->additional_glue = NULL; result = add(rbtdb, node, rbtdb->current_version, newheader, DNS_DBADD_MERGE, ISC_TRUE, NULL, 0); @@ -4687,13 +5195,13 @@ beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { else loadctx->now = 0; - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); REQUIRE((rbtdb->attributes & (RBTDB_ATTR_LOADED|RBTDB_ATTR_LOADING)) == 0); rbtdb->attributes |= RBTDB_ATTR_LOADING; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); *addp = loading_addrdataset; *dbloadp = loadctx; @@ -4711,7 +5219,7 @@ endload(dns_db_t *db, dns_dbload_t **dbloadp) { loadctx = *dbloadp; REQUIRE(loadctx->rbtdb == rbtdb); - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADING) != 0); REQUIRE((rbtdb->attributes & RBTDB_ATTR_LOADED) == 0); @@ -4719,7 +5227,7 @@ endload(dns_db_t *db, dns_dbload_t **dbloadp) { rbtdb->attributes &= ~RBTDB_ATTR_LOADING; rbtdb->attributes |= RBTDB_ATTR_LOADED; - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); /* * If there's a KEY rdataset at the zone origin containing a @@ -4736,16 +5244,17 @@ endload(dns_db_t *db, dns_dbload_t **dbloadp) { } static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { +dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) { dns_rbtdb_t *rbtdb; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); - return (dns_master_dump(rbtdb->common.mctx, db, version, - &dns_master_style_default, - filename)); + return (dns_master_dump2(rbtdb->common.mctx, db, version, + &dns_master_style_default, + filename, masterformat)); } static void @@ -4799,12 +5308,12 @@ settask(dns_db_t *db, isc_task_t *task) { REQUIRE(VALID_RBTDB(rbtdb)); - LOCK(&rbtdb->lock); + RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write); if (rbtdb->task != NULL) isc_task_detach(&rbtdb->task); if (task != NULL) isc_task_attach(task, &rbtdb->task); - UNLOCK(&rbtdb->lock); + RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write); } static isc_boolean_t @@ -4813,6 +5322,31 @@ ispersistent(dns_db_t *db) { return (ISC_FALSE); } +static isc_result_t +getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) { + dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; + dns_rbtnode_t *onode; + isc_result_t result = ISC_R_SUCCESS; + + REQUIRE(VALID_RBTDB(rbtdb)); + REQUIRE(nodep != NULL && *nodep == NULL); + + /* Note that the access to origin_node doesn't require a DB lock */ + onode = (dns_rbtnode_t *)rbtdb->origin_node; + if (onode != NULL) { + NODE_STRONGLOCK(&rbtdb->node_locks[onode->locknum].lock); + new_reference(rbtdb, onode); + NODE_STRONGUNLOCK(&rbtdb->node_locks[onode->locknum].lock); + + *nodep = rbtdb->origin_node; + } else { + INSIST(!IS_CACHE(rbtdb)); + result = ISC_R_NOTFOUND; + } + + return (result); +} + static dns_dbmethods_t zone_methods = { attach, detach, @@ -4840,7 +5374,8 @@ static dns_dbmethods_t zone_methods = { nodecount, ispersistent, overmem, - settask + settask, + getoriginnode }; static dns_dbmethods_t cache_methods = { @@ -4870,7 +5405,8 @@ static dns_dbmethods_t cache_methods = { nodecount, ispersistent, overmem, - settask + settask, + getoriginnode }; isc_result_t @@ -4896,6 +5432,7 @@ dns_rbtdb_create rbtdb = isc_mem_get(mctx, sizeof(*rbtdb)); if (rbtdb == NULL) return (ISC_R_NOMEMORY); + memset(rbtdb, '\0', sizeof(*rbtdb)); dns_name_init(&rbtdb->common.origin, NULL); rbtdb->common.attributes = 0; @@ -4910,55 +5447,48 @@ dns_rbtdb_create rbtdb->common.rdclass = rdclass; rbtdb->common.mctx = NULL; - result = isc_mutex_init(&rbtdb->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, rbtdb, sizeof(*rbtdb)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } + result = RBTDB_INITLOCK(&rbtdb->lock); + if (result != ISC_R_SUCCESS) + goto cleanup_rbtdb; result = isc_rwlock_init(&rbtdb->tree_lock, 0, 0); - if (result != ISC_R_SUCCESS) { - DESTROYLOCK(&rbtdb->lock); - isc_mem_put(mctx, rbtdb, sizeof(*rbtdb)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_rwlock_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } + if (result != ISC_R_SUCCESS) + goto cleanup_lock; + if (rbtdb->node_lock_count == 0) { + if (IS_CACHE(rbtdb)) + rbtdb->node_lock_count = DEFAULT_CACHE_NODE_LOCK_COUNT; + else + rbtdb->node_lock_count = DEFAULT_NODE_LOCK_COUNT; + } INSIST(rbtdb->node_lock_count < (1 << DNS_RBT_LOCKLENGTH)); - - if (rbtdb->node_lock_count == 0) - rbtdb->node_lock_count = DEFAULT_NODE_LOCK_COUNT; rbtdb->node_locks = isc_mem_get(mctx, rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); + if (rbtdb->node_locks == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup_tree_lock; + } + rbtdb->active = rbtdb->node_lock_count; + for (i = 0; i < (int)(rbtdb->node_lock_count); i++) { - result = isc_mutex_init(&rbtdb->node_locks[i].lock); + result = NODE_INITLOCK(&rbtdb->node_locks[i].lock); + if (result == ISC_R_SUCCESS) { + result = isc_refcount_init(&rbtdb->node_locks[i].references, 0); + if (result != ISC_R_SUCCESS) + NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); + } if (result != ISC_R_SUCCESS) { - i--; - while (i >= 0) { - DESTROYLOCK(&rbtdb->node_locks[i].lock); - i--; + while (i-- > 0) { + NODE_DESTROYLOCK(&rbtdb->node_locks[i].lock); + isc_refcount_decrement(&rbtdb->node_locks[i].references, NULL); + isc_refcount_destroy(&rbtdb->node_locks[i].references); } - isc_mem_put(mctx, rbtdb->node_locks, - rbtdb->node_lock_count * - sizeof(rbtdb_nodelock_t)); - isc_rwlock_destroy(&rbtdb->tree_lock); - DESTROYLOCK(&rbtdb->lock); - isc_mem_put(mctx, rbtdb, sizeof(*rbtdb)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); + goto cleanup_node_locks; } - rbtdb->node_locks[i].references = 0; rbtdb->node_locks[i].exiting = ISC_FALSE; } - + /* * Attach to the mctx. The database will persist so long as there * are references to it, and attaching to the mctx ensures that our @@ -5001,7 +5531,7 @@ dns_rbtdb_create * the top-of-zone node can never be deleted, nor can its address * change. */ - if (! IS_CACHE(rbtdb)) { + if (!IS_CACHE(rbtdb)) { rbtdb->origin_node = NULL; result = dns_rbt_addnode(rbtdb->tree, &rbtdb->common.origin, &rbtdb->origin_node); @@ -5029,7 +5559,11 @@ dns_rbtdb_create /* * Misc. Initialization. */ - isc_refcount_init(&rbtdb->references, 1); + result = isc_refcount_init(&rbtdb->references, 1); + if (result != ISC_R_SUCCESS) { + free_rbtdb(rbtdb, ISC_FALSE, NULL); + return (result); + } rbtdb->attributes = 0; rbtdb->secure = ISC_FALSE; rbtdb->overmem = ISC_FALSE; @@ -5041,13 +5575,20 @@ dns_rbtdb_create rbtdb->current_serial = 1; rbtdb->least_serial = 1; rbtdb->next_serial = 2; - rbtdb->current_version = allocate_version(mctx, 1, 0, ISC_FALSE); + rbtdb->current_version = allocate_version(mctx, 1, 1, ISC_FALSE); if (rbtdb->current_version == NULL) { + isc_refcount_decrement(&rbtdb->references, NULL); + isc_refcount_destroy(&rbtdb->references); free_rbtdb(rbtdb, ISC_FALSE, NULL); return (ISC_R_NOMEMORY); } rbtdb->future_version = NULL; ISC_LIST_INIT(rbtdb->open_versions); + /* + * Keep the current version in the open list so that list operation + * won't happen in normal lookup operations. + */ + PREPEND(rbtdb->open_versions, rbtdb->current_version, link); rbtdb->common.magic = DNS_DB_MAGIC; rbtdb->common.impmagic = RBTDB_MAGIC; @@ -5055,6 +5596,20 @@ dns_rbtdb_create *dbp = (dns_db_t *)rbtdb; return (ISC_R_SUCCESS); + + cleanup_node_locks: + isc_mem_put(mctx, rbtdb->node_locks, + rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t)); + + cleanup_tree_lock: + isc_rwlock_destroy(&rbtdb->tree_lock); + + cleanup_lock: + RBTDB_DESTROYLOCK(&rbtdb->lock); + + cleanup_rbtdb: + isc_mem_put(mctx, rbtdb, sizeof(*rbtdb)); + return (result); } @@ -5072,7 +5627,7 @@ rdataset_disassociate(dns_rdataset_t *rdataset) { static isc_result_t rdataset_first(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; + unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int count; count = raw[0] * 256 + raw[1]; @@ -5080,11 +5635,20 @@ rdataset_first(dns_rdataset_t *rdataset) { rdataset->private5 = NULL; return (ISC_R_NOMORE); } - raw += 2; + + if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) + raw += 2 + (4 * count); + else + raw += 2; + /* - * The privateuint4 field is the number of rdata beyond the cursor - * position, so we decrement the total count by one before storing - * it. + * The privateuint4 field is the number of rdata beyond the + * cursor position, so we decrement the total count by one + * before storing it. + * + * If DNS_RDATASETATTR_LOADORDER is not set 'raw' points to the + * first record. If DNS_RDATASETATTR_LOADORDER is set 'raw' points + * to the first entry in the offset table. */ count--; rdataset->privateuint4 = count; @@ -5097,30 +5661,47 @@ static isc_result_t rdataset_next(dns_rdataset_t *rdataset) { unsigned int count; unsigned int length; - unsigned char *raw; + unsigned char *raw; /* RDATASLAB */ count = rdataset->privateuint4; if (count == 0) return (ISC_R_NOMORE); count--; rdataset->privateuint4 = count; + + /* + * Skip forward one record (length + 4) or one offset (4). + */ raw = rdataset->private5; - length = raw[0] * 256 + raw[1]; - raw += length + 2; - rdataset->private5 = raw; + if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0) { + length = raw[0] * 256 + raw[1]; + raw += length; + } + rdataset->private5 = raw + 4; return (ISC_R_SUCCESS); } static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { - unsigned char *raw = rdataset->private5; + unsigned char *raw = rdataset->private5; /* RDATASLAB */ + unsigned int offset; isc_region_t r; REQUIRE(raw != NULL); + /* + * Find the start of the record if not already in private5 + * then skip the length and order fields. + */ + if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) != 0) { + offset = (raw[0] << 24) + (raw[1] << 16) + + (raw[2] << 8) + raw[3]; + raw = rdataset->private3; + raw += offset; + } r.length = raw[0] * 256 + raw[1]; - raw += 2; + raw += 4; r.base = raw; dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); } @@ -5143,7 +5724,7 @@ rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { static unsigned int rdataset_count(dns_rdataset_t *rdataset) { - unsigned char *raw = rdataset->private3; + unsigned char *raw = rdataset->private3; /* RDATASLAB */ unsigned int count; count = raw[0] * 256 + raw[1]; @@ -5233,7 +5814,8 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) { now = 0; } - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); for (header = rbtnode->data; header != NULL; header = top_next) { top_next = header->next; @@ -5260,7 +5842,8 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) { break; } - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); rbtiterator->current = header; @@ -5294,7 +5877,8 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { now = 0; } - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); type = header->type; rdtype = RBTDB_RDATATYPE_BASE(header->type); @@ -5335,7 +5919,8 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { } } - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); rbtiterator->current = header; @@ -5355,12 +5940,14 @@ rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { header = rbtiterator->current; REQUIRE(header != NULL); - LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); bind_rdataset(rbtdb, rbtnode, header, rbtiterator->common.now, rdataset); - UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_read); } @@ -5377,26 +5964,25 @@ reference_iter_node(rbtdb_dbiterator_t *rbtdbiter) { return; INSIST(rbtdbiter->tree_locked != isc_rwlocktype_none); - LOCK(&rbtdb->node_locks[node->locknum].lock); + NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); new_reference(rbtdb, node); - UNLOCK(&rbtdb->node_locks[node->locknum].lock); + NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); } static inline void dereference_iter_node(rbtdb_dbiterator_t *rbtdbiter) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; dns_rbtnode_t *node = rbtdbiter->node; - isc_mutex_t *lock; + nodelock_t *lock; if (node == NULL) return; lock = &rbtdb->node_locks[node->locknum].lock; - LOCK(lock); - INSIST(rbtdbiter->node->references > 0); - if (--node->references == 0) - no_references(rbtdb, node, 0, rbtdbiter->tree_locked); - UNLOCK(lock); + NODE_LOCK(lock, isc_rwlocktype_read); + decrement_reference(rbtdb, node, 0, isc_rwlocktype_read, + rbtdbiter->tree_locked); + NODE_UNLOCK(lock, isc_rwlocktype_read); rbtdbiter->node = NULL; } @@ -5406,7 +5992,7 @@ flush_deletions(rbtdb_dbiterator_t *rbtdbiter) { dns_rbtnode_t *node; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db; isc_boolean_t was_read_locked = ISC_FALSE; - isc_mutex_t *lock; + nodelock_t *lock; int i; if (rbtdbiter->delete != 0) { @@ -5433,13 +6019,11 @@ flush_deletions(rbtdb_dbiterator_t *rbtdbiter) { node = rbtdbiter->deletions[i]; lock = &rbtdb->node_locks[node->locknum].lock; - LOCK(lock); - INSIST(node->references > 0); - node->references--; - if (node->references == 0) - no_references(rbtdb, node, 0, - rbtdbiter->tree_locked); - UNLOCK(lock); + NODE_LOCK(lock, isc_rwlocktype_read); + decrement_reference(rbtdb, node, 0, + isc_rwlocktype_read, + rbtdbiter->tree_locked); + NODE_UNLOCK(lock, isc_rwlocktype_read); } rbtdbiter->delete = 0; @@ -5707,9 +6291,9 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, } else result = ISC_R_SUCCESS; - LOCK(&rbtdb->node_locks[node->locknum].lock); + NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); new_reference(rbtdb, node); - UNLOCK(&rbtdb->node_locks[node->locknum].lock); + NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); *nodep = rbtdbiter->node; @@ -5730,10 +6314,13 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, * expirenode() currently always returns success. */ if (expire_result == ISC_R_SUCCESS && node->down == NULL) { + unsigned int refs; + rbtdbiter->deletions[rbtdbiter->delete++] = node; - LOCK(&rbtdb->node_locks[node->locknum].lock); - node->references++; - UNLOCK(&rbtdb->node_locks[node->locknum].lock); + NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); + dns_rbtnode_refincrement(node, &refs); + INSIST(refs != 0); + NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); } } @@ -5775,3 +6362,356 @@ dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { return (dns_name_copy(origin, name, NULL)); } + +/*% + * Additional cache routines. + */ +static isc_result_t +rdataset_getadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, dns_acache_t *acache, + dns_zone_t **zonep, dns_db_t **dbp, + dns_dbversion_t **versionp, dns_dbnode_t **nodep, + dns_name_t *fname, dns_message_t *msg, + isc_stdtime_t now) +{ + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + unsigned char *raw = rdataset->private3; /* RDATASLAB */ + unsigned int current_count = rdataset->privateuint4; + unsigned int count; + rdatasetheader_t *header; + nodelock_t *nodelock; + unsigned int total_count; + acachectl_t *acarray; + dns_acacheentry_t *entry; + isc_result_t result; + + UNUSED(qtype); /* we do not use this value at least for now */ + UNUSED(acache); + + header = (struct rdatasetheader *)(raw - sizeof(*header)); + + total_count = raw[0] * 256 + raw[1]; + INSIST(total_count > current_count); + count = total_count - current_count - 1; + + acarray = NULL; + + nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; + NODE_LOCK(nodelock, isc_rwlocktype_read); + + switch (type) { + case dns_rdatasetadditional_fromauth: + acarray = header->additional_auth; + break; + case dns_rdatasetadditional_fromcache: + acarray = NULL; + break; + case dns_rdatasetadditional_fromglue: + acarray = header->additional_glue; + break; + default: + INSIST(0); + } + + if (acarray == NULL) { + if (type != dns_rdatasetadditional_fromcache) + dns_acache_countquerymiss(acache); + NODE_UNLOCK(nodelock, isc_rwlocktype_read); + return (ISC_R_NOTFOUND); + } + + if (acarray[count].entry == NULL) { + dns_acache_countquerymiss(acache); + NODE_UNLOCK(nodelock, isc_rwlocktype_read); + return (ISC_R_NOTFOUND); + } + + entry = NULL; + dns_acache_attachentry(acarray[count].entry, &entry); + + NODE_UNLOCK(nodelock, isc_rwlocktype_read); + + result = dns_acache_getentry(entry, zonep, dbp, versionp, + nodep, fname, msg, now); + + dns_acache_detachentry(&entry); + + return (result); +} + +static void +acache_callback(dns_acacheentry_t *entry, void **arg) { + dns_rbtdb_t *rbtdb; + dns_rbtnode_t *rbtnode; + nodelock_t *nodelock; + acachectl_t *acarray = NULL; + acache_cbarg_t *cbarg; + unsigned int count; + + REQUIRE(arg != NULL); + cbarg = *arg; + + /* + * The caller must hold the entry lock. + */ + + rbtdb = (dns_rbtdb_t *)cbarg->db; + rbtnode = (dns_rbtnode_t *)cbarg->node; + + nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; + NODE_LOCK(nodelock, isc_rwlocktype_write); + + switch (cbarg->type) { + case dns_rdatasetadditional_fromauth: + acarray = cbarg->header->additional_auth; + break; + case dns_rdatasetadditional_fromglue: + acarray = cbarg->header->additional_glue; + break; + default: + INSIST(0); + } + + count = cbarg->count; + if (acarray[count].entry == entry) + acarray[count].entry = NULL; + INSIST(acarray[count].cbarg != NULL); + isc_mem_put(rbtdb->common.mctx, acarray[count].cbarg, + sizeof(acache_cbarg_t)); + acarray[count].cbarg = NULL; + + dns_acache_detachentry(&entry); + + NODE_UNLOCK(nodelock, isc_rwlocktype_write); + + dns_db_detachnode((dns_db_t *)rbtdb, (dns_dbnode_t **)(void*)&rbtnode); + dns_db_detach((dns_db_t **)(void*)&rbtdb); + + *arg = NULL; +} + +static void +acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry, + acache_cbarg_t **cbargp) +{ + acache_cbarg_t *cbarg; + + REQUIRE(mctx != NULL); + REQUIRE(entry != NULL); + REQUIRE(cbargp != NULL && *cbargp != NULL); + + cbarg = *cbargp; + + dns_acache_cancelentry(entry); + dns_db_detachnode(cbarg->db, &cbarg->node); + dns_db_detach(&cbarg->db); + + isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t)); + + *cbargp = NULL; +} + +static isc_result_t +rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, dns_acache_t *acache, + dns_zone_t *zone, dns_db_t *db, + dns_dbversion_t *version, dns_dbnode_t *node, + dns_name_t *fname) +{ + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + unsigned char *raw = rdataset->private3; /* RDATASLAB */ + unsigned int current_count = rdataset->privateuint4; + rdatasetheader_t *header; + unsigned int total_count, count; + nodelock_t *nodelock; + isc_result_t result; + acachectl_t *acarray; + dns_acacheentry_t *newentry, *oldentry = NULL; + acache_cbarg_t *newcbarg, *oldcbarg = NULL; + + UNUSED(qtype); + + if (type == dns_rdatasetadditional_fromcache) + return (ISC_R_SUCCESS); + + header = (struct rdatasetheader *)(raw - sizeof(*header)); + + total_count = raw[0] * 256 + raw[1]; + INSIST(total_count > current_count); + count = total_count - current_count - 1; /* should be private data */ + + newcbarg = isc_mem_get(rbtdb->common.mctx, sizeof(*newcbarg)); + if (newcbarg == NULL) + return (ISC_R_NOMEMORY); + newcbarg->type = type; + newcbarg->count = count; + newcbarg->header = header; + newcbarg->db = NULL; + dns_db_attach((dns_db_t *)rbtdb, &newcbarg->db); + newcbarg->node = NULL; + dns_db_attachnode((dns_db_t *)rbtdb, (dns_dbnode_t *)rbtnode, + &newcbarg->node); + newentry = NULL; + result = dns_acache_createentry(acache, (dns_db_t *)rbtdb, + acache_callback, newcbarg, &newentry); + if (result != ISC_R_SUCCESS) + goto fail; + /* Set cache data in the new entry. */ + result = dns_acache_setentry(acache, newentry, zone, db, + version, node, fname); + if (result != ISC_R_SUCCESS) + goto fail; + + nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; + NODE_LOCK(nodelock, isc_rwlocktype_write); + + acarray = NULL; + switch (type) { + case dns_rdatasetadditional_fromauth: + acarray = header->additional_auth; + break; + case dns_rdatasetadditional_fromglue: + acarray = header->additional_glue; + break; + default: + INSIST(0); + } + + if (acarray == NULL) { + unsigned int i; + + acarray = isc_mem_get(rbtdb->common.mctx, total_count * + sizeof(acachectl_t)); + + if (acarray == NULL) { + NODE_UNLOCK(nodelock, isc_rwlocktype_write); + goto fail; + } + + for (i = 0; i < total_count; i++) { + acarray[i].entry = NULL; + acarray[i].cbarg = NULL; + } + } + switch (type) { + case dns_rdatasetadditional_fromauth: + header->additional_auth = acarray; + break; + case dns_rdatasetadditional_fromglue: + header->additional_glue = acarray; + break; + default: + INSIST(0); + } + + if (acarray[count].entry != NULL) { + /* + * Swap the entry. Delay cleaning-up the old entry since + * it would require a node lock. + */ + oldentry = acarray[count].entry; + INSIST(acarray[count].cbarg != NULL); + oldcbarg = acarray[count].cbarg; + } + acarray[count].entry = newentry; + acarray[count].cbarg = newcbarg; + + NODE_UNLOCK(nodelock, isc_rwlocktype_write); + + if (oldentry != NULL) { + if (oldcbarg != NULL) + acache_cancelentry(rbtdb->common.mctx, oldentry, + &oldcbarg); + dns_acache_detachentry(&oldentry); + } + + return (ISC_R_SUCCESS); + + fail: + if (newcbarg != NULL) { + if (newentry != NULL) { + acache_cancelentry(rbtdb->common.mctx, newentry, + &newcbarg); + dns_acache_detachentry(&newentry); + } else { + dns_db_detachnode((dns_db_t *)rbtdb, &newcbarg->node); + dns_db_detach(&newcbarg->db); + isc_mem_put(rbtdb->common.mctx, newcbarg, + sizeof(*newcbarg)); + } + } + + return (result); +} + +static isc_result_t +rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, dns_rdatatype_t qtype) +{ + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + unsigned char *raw = rdataset->private3; /* RDATASLAB */ + unsigned int current_count = rdataset->privateuint4; + rdatasetheader_t *header; + nodelock_t *nodelock; + unsigned int total_count, count; + acachectl_t *acarray; + dns_acacheentry_t *entry; + acache_cbarg_t *cbarg; + + UNUSED(qtype); /* we do not use this value at least for now */ + UNUSED(acache); + + if (type == dns_rdatasetadditional_fromcache) + return (ISC_R_SUCCESS); + + header = (struct rdatasetheader *)(raw - sizeof(*header)); + + total_count = raw[0] * 256 + raw[1]; + INSIST(total_count > current_count); + count = total_count - current_count - 1; + + acarray = NULL; + entry = NULL; + + nodelock = &rbtdb->node_locks[rbtnode->locknum].lock; + NODE_LOCK(nodelock, isc_rwlocktype_write); + + switch (type) { + case dns_rdatasetadditional_fromauth: + acarray = header->additional_auth; + break; + case dns_rdatasetadditional_fromglue: + acarray = header->additional_glue; + break; + default: + INSIST(0); + } + + if (acarray == NULL) { + NODE_UNLOCK(nodelock, isc_rwlocktype_write); + return (ISC_R_NOTFOUND); + } + + entry = acarray[count].entry; + if (entry == NULL) { + NODE_UNLOCK(nodelock, isc_rwlocktype_write); + return (ISC_R_NOTFOUND); + } + + acarray[count].entry = NULL; + cbarg = acarray[count].cbarg; + acarray[count].cbarg = NULL; + + NODE_UNLOCK(nodelock, isc_rwlocktype_write); + + if (entry != NULL) { + if (cbarg != NULL) + acache_cancelentry(rbtdb->common.mctx, entry, &cbarg); + dns_acache_detachentry(&entry); + } + + return (ISC_R_SUCCESS); +} diff --git a/contrib/bind9/lib/dns/rbtdb.h b/contrib/bind9/lib/dns/rbtdb.h index 086b75e..f9fb50b 100644 --- a/contrib/bind9/lib/dns/rbtdb.h +++ b/contrib/bind9/lib/dns/rbtdb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.h,v 1.13.206.1 2004/03/06 08:13:42 marka Exp $ */ +/* $Id: rbtdb.h,v 1.14.18.2 2005/04/29 00:16:02 marka Exp $ */ #ifndef DNS_RBTDB_H #define DNS_RBTDB_H 1 @@ -27,7 +27,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * DNS Red-Black Tree DB Implementation */ diff --git a/contrib/bind9/lib/dns/rbtdb64.c b/contrib/bind9/lib/dns/rbtdb64.c index f41ab37..773fe91 100644 --- a/contrib/bind9/lib/dns/rbtdb64.c +++ b/contrib/bind9/lib/dns/rbtdb64.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb64.c,v 1.6.206.1 2004/03/06 08:13:42 marka Exp $ */ +/* $Id: rbtdb64.c,v 1.7.18.2 2005/04/29 00:16:02 marka Exp $ */ + +/*! \file */ #define DNS_RBTDB_VERSION64 1 #include "rbtdb.c" diff --git a/contrib/bind9/lib/dns/rbtdb64.h b/contrib/bind9/lib/dns/rbtdb64.h index 5d426b5..e2de45c 100644 --- a/contrib/bind9/lib/dns/rbtdb64.h +++ b/contrib/bind9/lib/dns/rbtdb64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb64.h,v 1.12.206.1 2004/03/06 08:13:43 marka Exp $ */ +/* $Id: rbtdb64.h,v 1.13.18.2 2005/04/29 00:16:02 marka Exp $ */ #ifndef DNS_RBTDB64_H #define DNS_RBTDB64_H 1 @@ -26,7 +26,8 @@ ***** Module Info *****/ -/* +/*! \file + * \brief * DNS Red-Black Tree DB Implementation with 64-bit version numbers */ diff --git a/contrib/bind9/lib/dns/rcode.c b/contrib/bind9/lib/dns/rcode.c index 337f649..f61aa35 100644 --- a/contrib/bind9/lib/dns/rcode.c +++ b/contrib/bind9/lib/dns/rcode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rcode.c,v 1.1.4.1 2004/03/12 10:31:25 marka Exp $ */ +/* $Id: rcode.c,v 1.2.18.2 2006/01/27 23:57:44 marka Exp $ */ #include <config.h> #include <ctype.h> @@ -76,6 +76,7 @@ { dns_tsigerror_badmode, "BADMODE", 0}, \ { dns_tsigerror_badname, "BADNAME", 0}, \ { dns_tsigerror_badalg, "BADALG", 0}, \ + { dns_tsigerror_badtrunc, "BADTRUNC", 0}, \ { 0, NULL, 0 } /* RFC2538 section 2.1 */ diff --git a/contrib/bind9/lib/dns/rdata.c b/contrib/bind9/lib/dns/rdata.c index bcd0e150..5641777 100644 --- a/contrib/bind9/lib/dns/rdata.c +++ b/contrib/bind9/lib/dns/rdata.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdata.c,v 1.147.2.11.2.22 2006/07/21 02:05:56 marka Exp $ */ +/* $Id: rdata.c,v 1.184.18.9 2006/07/21 02:05:57 marka Exp $ */ + +/*! \file */ #include <config.h> #include <ctype.h> @@ -100,16 +102,16 @@ #define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad -/* +/*% * Context structure for the totext_ functions. * Contains formatting options for rdata-to-text * conversion. */ typedef struct dns_rdata_textctx { - dns_name_t *origin; /* Current origin, or NULL. */ - unsigned int flags; /* DNS_STYLEFLAG_* */ - unsigned int width; /* Width of rdata column. */ - const char *linebreak; /* Line break string. */ + dns_name_t *origin; /*%< Current origin, or NULL. */ + unsigned int flags; /*%< DNS_STYLEFLAG_* */ + unsigned int width; /*%< Width of rdata column. */ + const char *linebreak; /*%< Line break string. */ } dns_rdata_textctx_t; static isc_result_t @@ -195,6 +197,10 @@ static void warn_badname(dns_name_t *name, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks); +static void +warn_badmx(isc_token_t *token, isc_lex_t *lexer, + dns_rdatacallbacks_t *callbacks); + static inline int getquad(const void *src, struct in_addr *dst, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) @@ -1581,6 +1587,22 @@ fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { } static void +warn_badmx(isc_token_t *token, isc_lex_t *lexer, + dns_rdatacallbacks_t *callbacks) +{ + const char *file; + unsigned long line; + + if (lexer != NULL) { + file = isc_lex_getsourcename(lexer); + line = isc_lex_getsourceline(lexer); + (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s", + file, line, DNS_AS_STR(*token), + dns_result_totext(DNS_R_MXISADDRESS)); + } +} + +static void warn_badname(dns_name_t *name, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { diff --git a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c index c9b52c7..4fdadd3 100644 --- a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c +++ b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tsig_250.c,v 1.52.2.1.2.8 2005/03/20 22:34:01 marka Exp $ */ +/* $Id: tsig_250.c,v 1.59.18.2 2005/03/20 22:34:32 marka Exp $ */ /* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */ diff --git a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h index 7b5ccc2..b84a715 100644 --- a/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h +++ b/contrib/bind9/lib/dns/rdata/any_255/tsig_250.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,13 +15,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tsig_250.h,v 1.20.206.1 2004/03/06 08:14:02 marka Exp $ */ - -/* RFC 2845 */ +/* $Id: tsig_250.h,v 1.21.18.2 2005/04/29 00:16:29 marka Exp $ */ #ifndef ANY_255_TSIG_250_H #define ANY_255_TSIG_250_H 1 +/*% RFC2845 */ typedef struct dns_rdata_any_tsig { dns_rdatacommon_t common; isc_mem_t * mctx; diff --git a/contrib/bind9/lib/dns/rdata/ch_3/a_1.c b/contrib/bind9/lib/dns/rdata/ch_3/a_1.c new file mode 100644 index 0000000..6a9b70c --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/ch_3/a_1.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: a_1.c,v 1.2.2.3 2005/08/23 04:10:09 marka Exp $ */ + +/* by Bjorn.Victor@it.uu.se, 2005-05-07 */ +/* Based on generic/soa_6.c and generic/mx_15.c */ + +#ifndef RDATA_CH_3_A_1_C +#define RDATA_CH_3_A_1_C + +#include <isc/net.h> + +#define RRTYPE_A_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_ch_a(ARGS_FROMTEXT) { + isc_token_t token; + dns_name_t name; + isc_buffer_t buffer; + + REQUIRE(type == 1); + REQUIRE(rdclass == dns_rdataclass_ch); /* 3 */ + + UNUSED(type); + UNUSED(callbacks); + + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + + /* get domain name */ + dns_name_init(&name, NULL); + buffer_fromregion(&buffer, &token.value.as_region); + origin = (origin != NULL) ? origin : dns_rootname; + RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); + if ((options & DNS_RDATA_CHECKNAMES) != 0 && + (options & DNS_RDATA_CHECKREVERSE) != 0) { + isc_boolean_t ok; + ok = dns_name_ishostname(&name, ISC_FALSE); + if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) + RETTOK(DNS_R_BADNAME); + if (!ok && callbacks != NULL) + warn_badname(&name, lexer, callbacks); + } + + /* 16-bit octal address */ + RETERR(isc_lex_getoctaltoken(lexer, &token, ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + return (uint16_tobuffer(token.value.as_ulong, target)); +} + +static inline isc_result_t +totext_ch_a(ARGS_TOTEXT) { + isc_region_t region; + dns_name_t name; + dns_name_t prefix; + isc_boolean_t sub; + char buf[sizeof("0177777")]; + isc_uint16_t addr; + + REQUIRE(rdata->type == 1); + REQUIRE(rdata->rdclass == dns_rdataclass_ch); /* 3 */ + REQUIRE(rdata->length != 0); + + dns_name_init(&name, NULL); + dns_name_init(&prefix, NULL); + + dns_rdata_toregion(rdata, ®ion); + dns_name_fromregion(&name, ®ion); + isc_region_consume(®ion, name_length(&name)); + addr = uint16_fromregion(®ion); + + sub = name_prefix(&name, tctx->origin, &prefix); + RETERR(dns_name_totext(&prefix, sub, target)); + + sprintf(buf, "%o", addr); /* note octal */ + RETERR(str_totext(" ", target)); + return (str_totext(buf, target)); +} + +static inline isc_result_t +fromwire_ch_a(ARGS_FROMWIRE) { + isc_region_t sregion; + isc_region_t tregion; + dns_name_t name; + + REQUIRE(type == 1); + REQUIRE(rdclass == dns_rdataclass_ch); + + UNUSED(type); + UNUSED(rdclass); + + dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); + + dns_name_init(&name, NULL); + + RETERR(dns_name_fromwire(&name, source, dctx, options, target)); + + isc_buffer_activeregion(source, &sregion); + isc_buffer_availableregion(target, &tregion); + if (sregion.length < 2) + return (ISC_R_UNEXPECTEDEND); + if (tregion.length < 2) + return (ISC_R_NOSPACE); + + memcpy(tregion.base, sregion.base, 2); + isc_buffer_forward(source, 2); + isc_buffer_add(target, 2); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +towire_ch_a(ARGS_TOWIRE) { + dns_name_t name; + dns_offsets_t offsets; + isc_region_t sregion; + isc_region_t tregion; + + REQUIRE(rdata->type == 1); + REQUIRE(rdata->rdclass == dns_rdataclass_ch); + REQUIRE(rdata->length != 0); + + dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); + + dns_name_init(&name, offsets); + + dns_rdata_toregion(rdata, &sregion); + + dns_name_fromregion(&name, &sregion); + isc_region_consume(&sregion, name_length(&name)); + RETERR(dns_name_towire(&name, cctx, target)); + + isc_buffer_availableregion(target, &tregion); + if (tregion.length < 2) + return (ISC_R_NOSPACE); + + memcpy(tregion.base, sregion.base, 2); + isc_buffer_add(target, 2); + return (ISC_R_SUCCESS); +} + +static inline int +compare_ch_a(ARGS_COMPARE) { + dns_name_t name1; + dns_name_t name2; + isc_region_t region1; + isc_region_t region2; + int order; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 1); + REQUIRE(rdata1->rdclass == dns_rdataclass_ch); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + dns_name_init(&name1, NULL); + dns_name_init(&name2, NULL); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + + dns_name_fromregion(&name1, ®ion1); + dns_name_fromregion(&name2, ®ion2); + isc_region_consume(®ion1, name_length(&name1)); + isc_region_consume(®ion2, name_length(&name2)); + + order = dns_name_rdatacompare(&name1, &name2); + if (order != 0) + return (order); + + order = memcmp(rdata1->data, rdata2->data, 2); + if (order != 0) + order = (order < 0) ? -1 : 1; + return (order); +} + +static inline isc_result_t +fromstruct_ch_a(ARGS_FROMSTRUCT) { + dns_rdata_ch_a_t *a = source; + isc_region_t region; + + REQUIRE(type == 1); + REQUIRE(source != NULL); + REQUIRE(a->common.rdtype == type); + REQUIRE(a->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + dns_name_toregion(&a->ch_addr_dom, ®ion); + RETERR(isc_buffer_copyregion(target, ®ion)); + + return (uint16_tobuffer(ntohs(a->ch_addr), target)); +} + +static inline isc_result_t +tostruct_ch_a(ARGS_TOSTRUCT) { + dns_rdata_ch_a_t *a = target; + isc_region_t region; + dns_name_t name; + + REQUIRE(rdata->type == 1); + REQUIRE(rdata->rdclass == dns_rdataclass_ch); + REQUIRE(rdata->length != 0); + + a->common.rdclass = rdata->rdclass; + a->common.rdtype = rdata->type; + ISC_LINK_INIT(&a->common, link); + + dns_rdata_toregion(rdata, ®ion); + + dns_name_init(&name, NULL); + dns_name_fromregion(&name, ®ion); + isc_region_consume(®ion, name_length(&name)); + + dns_name_init(&a->ch_addr_dom, NULL); + RETERR(name_duporclone(&name, mctx, &a->ch_addr_dom)); + a->ch_addr = htons(uint16_fromregion(®ion)); + a->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_ch_a(ARGS_FREESTRUCT) { + dns_rdata_ch_a_t *a = source; + + REQUIRE(source != NULL); + REQUIRE(a->common.rdtype == 1); + + if (a->mctx == NULL) + return; + + dns_name_free(&a->ch_addr_dom, a->mctx); + a->mctx = NULL; +} + +static inline isc_result_t +additionaldata_ch_a(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 1); + REQUIRE(rdata->rdclass == dns_rdataclass_ch); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_ch_a(ARGS_DIGEST) { + isc_region_t r; + + dns_name_t name; + + REQUIRE(rdata->type == 1); + REQUIRE(rdata->rdclass == dns_rdataclass_ch); + + dns_rdata_toregion(rdata, &r); + dns_name_init(&name, NULL); + dns_name_fromregion(&name, &r); + isc_region_consume(&r, name_length(&name)); + RETERR(dns_name_digest(&name, digest, arg)); + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_ch_a(ARGS_CHECKOWNER) { + + REQUIRE(type == 1); + REQUIRE(rdclass == dns_rdataclass_ch); + + UNUSED(type); + + return (dns_name_ishostname(name, wildcard)); +} + +static inline isc_boolean_t +checknames_ch_a(ARGS_CHECKNAMES) { + isc_region_t region; + dns_name_t name; + + REQUIRE(rdata->type == 1); + REQUIRE(rdata->rdclass == dns_rdataclass_ch); + + UNUSED(owner); + + dns_rdata_toregion(rdata, ®ion); + dns_name_init(&name, NULL); + dns_name_fromregion(&name, ®ion); + if (!dns_name_ishostname(&name, ISC_FALSE)) { + if (bad != NULL) + dns_name_clone(&name, bad); + return (ISC_FALSE); + } + + return (ISC_TRUE); +} + +#endif /* RDATA_CH_3_A_1_C */ diff --git a/contrib/bind9/lib/dns/rdata/ch_3/a_1.h b/contrib/bind9/lib/dns/rdata/ch_3/a_1.h new file mode 100644 index 0000000..9f67977 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/ch_3/a_1.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: a_1.h,v 1.2.2.2 2005/06/05 00:02:22 marka Exp $ */ + +/* by Bjorn.Victor@it.uu.se, 2005-05-07 */ +/* Based on generic/mx_15.h */ + +#ifndef CH_3_A_1_H +#define CH_3_A_1_H 1 + +typedef isc_uint16_t ch_addr_t; + +typedef struct dns_rdata_ch_a { + dns_rdatacommon_t common; + isc_mem_t *mctx; + dns_name_t ch_addr_dom; /* ch-addr domain for back mapping */ + ch_addr_t ch_addr; /* chaos address (16 bit) network order */ +} dns_rdata_ch_a_t; + +#endif /* CH_3_A_1_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c b/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c index f46844a..24a63e6 100644 --- a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c +++ b/contrib/bind9/lib/dns/rdata/generic/afsdb_18.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: afsdb_18.c,v 1.39.2.1.2.3 2004/03/06 08:14:03 marka Exp $ */ +/* $Id: afsdb_18.c,v 1.43.18.2 2005/04/29 00:16:30 marka Exp $ */ /* Reviewed: Wed Mar 15 14:59:00 PST 2000 by explorer */ -/* RFC 1183 */ +/* RFC1183 */ #ifndef RDATA_GENERIC_AFSDB_18_C #define RDATA_GENERIC_AFSDB_18_C diff --git a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h b/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h index 3f89f9d..1532da1 100644 --- a/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h +++ b/contrib/bind9/lib/dns/rdata/generic/afsdb_18.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_AFSDB_18_H #define GENERIC_AFSDB_18_H 1 -/* $Id: afsdb_18.h,v 1.15.206.1 2004/03/06 08:14:03 marka Exp $ */ +/* $Id: afsdb_18.h,v 1.16.18.2 2005/04/29 00:16:30 marka Exp $ */ -/* RFC 1183 */ +/*! + * \brief Per RFC1183 */ typedef struct dns_rdata_afsdb { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/cert_37.c b/contrib/bind9/lib/dns/rdata/generic/cert_37.c index 81a1aa7..c6ba3a8 100644 --- a/contrib/bind9/lib/dns/rdata/generic/cert_37.c +++ b/contrib/bind9/lib/dns/rdata/generic/cert_37.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cert_37.c,v 1.40.2.1.2.5 2004/03/08 09:04:40 marka Exp $ */ +/* $Id: cert_37.c,v 1.46.18.2 2005/04/29 00:16:30 marka Exp $ */ /* Reviewed: Wed Mar 15 21:14:32 EST 2000 by tale */ -/* RFC 2538 */ +/* RFC2538 */ #ifndef RDATA_GENERIC_CERT_37_C #define RDATA_GENERIC_CERT_37_C diff --git a/contrib/bind9/lib/dns/rdata/generic/cert_37.h b/contrib/bind9/lib/dns/rdata/generic/cert_37.h index 01ae265..2af25b7 100644 --- a/contrib/bind9/lib/dns/rdata/generic/cert_37.h +++ b/contrib/bind9/lib/dns/rdata/generic/cert_37.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,12 +15,12 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cert_37.h,v 1.15.206.1 2004/03/06 08:14:03 marka Exp $ */ +/* $Id: cert_37.h,v 1.16.18.2 2005/04/29 00:16:31 marka Exp $ */ -/* RFC 2538 */ #ifndef GENERIC_CERT_37_H #define GENERIC_CERT_37_H 1 +/*% RFC2538 */ typedef struct dns_rdata_cert { dns_rdatacommon_t common; isc_mem_t *mctx; diff --git a/contrib/bind9/lib/dns/rdata/generic/cname_5.c b/contrib/bind9/lib/dns/rdata/generic/cname_5.c index 0ce7aa2..6ea1db1 100644 --- a/contrib/bind9/lib/dns/rdata/generic/cname_5.c +++ b/contrib/bind9/lib/dns/rdata/generic/cname_5.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cname_5.c,v 1.43.206.2 2004/03/06 08:14:03 marka Exp $ */ +/* $Id: cname_5.c,v 1.45 2004/03/05 05:10:10 marka Exp $ */ /* reviewed: Wed Mar 15 16:48:45 PST 2000 by brister */ diff --git a/contrib/bind9/lib/dns/rdata/generic/cname_5.h b/contrib/bind9/lib/dns/rdata/generic/cname_5.h index 2efee44..dc24383 100644 --- a/contrib/bind9/lib/dns/rdata/generic/cname_5.h +++ b/contrib/bind9/lib/dns/rdata/generic/cname_5.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cname_5.h,v 1.23.206.1 2004/03/06 08:14:04 marka Exp $ */ +/* $Id: cname_5.h,v 1.24 2004/03/05 05:10:10 marka Exp $ */ #ifndef GENERIC_CNAME_5_H #define GENERIC_CNAME_5_H 1 diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c index b28435c..fa22580 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c +++ b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlv_32769.c,v 1.2.4.2 2006/02/19 06:50:46 marka Exp $ */ +/* $Id: dlv_32769.c,v 1.2.2.2 2006/02/19 06:50:47 marka Exp $ */ /* draft-ietf-dnsext-delegation-signer-05.txt */ diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h index 08a9b1d..bd03c73 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h +++ b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlv_32769.h,v 1.2.4.2 2006/02/19 06:50:46 marka Exp $ */ +/* $Id: dlv_32769.h,v 1.2.2.2 2006/02/19 06:50:47 marka Exp $ */ /* draft-ietf-dnsext-delegation-signer-05.txt */ #ifndef GENERIC_DLV_32769_H diff --git a/contrib/bind9/lib/dns/rdata/generic/dname_39.c b/contrib/bind9/lib/dns/rdata/generic/dname_39.c index b532f2e..ed3133c 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dname_39.c +++ b/contrib/bind9/lib/dns/rdata/generic/dname_39.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dname_39.c,v 1.34.206.2 2004/03/06 08:14:04 marka Exp $ */ +/* $Id: dname_39.c,v 1.36 2004/03/05 05:10:10 marka Exp $ */ /* Reviewed: Wed Mar 15 16:52:38 PST 2000 by explorer */ diff --git a/contrib/bind9/lib/dns/rdata/generic/dname_39.h b/contrib/bind9/lib/dns/rdata/generic/dname_39.h index a1b2192..93ec709 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dname_39.h +++ b/contrib/bind9/lib/dns/rdata/generic/dname_39.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_DNAME_39_H #define GENERIC_DNAME_39_H 1 -/* $Id: dname_39.h,v 1.16.206.1 2004/03/06 08:14:04 marka Exp $ */ +/* $Id: dname_39.h,v 1.17.18.2 2005/04/29 00:16:31 marka Exp $ */ -/* RFC2672 */ +/*! + * \brief per RFC2672 */ typedef struct dns_rdata_dname { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c b/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c index 5cf58d5..5a4e453 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c +++ b/contrib/bind9/lib/dns/rdata/generic/dnskey_48.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,13 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnskey_48.c,v 1.4.2.1 2004/03/08 02:08:02 marka Exp $ */ +/* $Id: dnskey_48.c,v 1.4.20.2 2005/04/29 00:16:31 marka Exp $ */ /* * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. */ -/* RFC 2535 */ +/* RFC2535 */ #ifndef RDATA_GENERIC_DNSKEY_48_C #define RDATA_GENERIC_DNSKEY_48_C diff --git a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h b/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h index 4dd71d2..9b3d262 100644 --- a/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h +++ b/contrib/bind9/lib/dns/rdata/generic/dnskey_48.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_DNSKEY_48_H #define GENERIC_DNSKEY_48_H 1 -/* $Id: dnskey_48.h,v 1.3.2.1 2004/03/08 02:08:02 marka Exp $ */ +/* $Id: dnskey_48.h,v 1.3.20.2 2005/04/29 00:16:32 marka Exp $ */ -/* RFC 2535 */ +/*! + * \brief per RFC2535 */ typedef struct dns_rdata_dnskey { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/ds_43.c b/contrib/bind9/lib/dns/rdata/generic/ds_43.c index 0206b6f..b9a3a3e 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ds_43.c +++ b/contrib/bind9/lib/dns/rdata/generic/ds_43.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds_43.c,v 1.6.2.4 2005/09/06 07:29:31 marka Exp $ */ +/* $Id: ds_43.c,v 1.7.18.2 2005/09/06 07:29:32 marka Exp $ */ /* draft-ietf-dnsext-delegation-signer-05.txt */ diff --git a/contrib/bind9/lib/dns/rdata/generic/ds_43.h b/contrib/bind9/lib/dns/rdata/generic/ds_43.h index cd4a5ca..dae7bef 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ds_43.h +++ b/contrib/bind9/lib/dns/rdata/generic/ds_43.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,12 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds_43.h,v 1.3.2.1 2004/03/08 02:08:03 marka Exp $ */ +/* $Id: ds_43.h,v 1.3.20.2 2005/04/29 00:16:32 marka Exp $ */ -/* draft-ietf-dnsext-delegation-signer-05.txt */ #ifndef GENERIC_DS_43_H #define GENERIC_DS_43_H 1 +/*! + * \brief per draft-ietf-dnsext-delegation-signer-05.txt */ typedef struct dns_rdata_ds { dns_rdatacommon_t common; isc_mem_t *mctx; diff --git a/contrib/bind9/lib/dns/rdata/generic/gpos_27.c b/contrib/bind9/lib/dns/rdata/generic/gpos_27.c index 1768f17..9b37905 100644 --- a/contrib/bind9/lib/dns/rdata/generic/gpos_27.c +++ b/contrib/bind9/lib/dns/rdata/generic/gpos_27.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gpos_27.c,v 1.32.12.5 2004/03/08 09:04:40 marka Exp $ */ +/* $Id: gpos_27.c,v 1.37.18.2 2005/04/29 00:16:32 marka Exp $ */ /* reviewed: Wed Mar 15 16:48:45 PST 2000 by brister */ -/* RFC 1712 */ +/* RFC1712 */ #ifndef RDATA_GENERIC_GPOS_27_C #define RDATA_GENERIC_GPOS_27_C diff --git a/contrib/bind9/lib/dns/rdata/generic/gpos_27.h b/contrib/bind9/lib/dns/rdata/generic/gpos_27.h index 6f9ed37..4949bde 100644 --- a/contrib/bind9/lib/dns/rdata/generic/gpos_27.h +++ b/contrib/bind9/lib/dns/rdata/generic/gpos_27.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_GPOS_27_H #define GENERIC_GPOS_27_H 1 -/* $Id: gpos_27.h,v 1.12.206.1 2004/03/06 08:14:04 marka Exp $ */ +/* $Id: gpos_27.h,v 1.13.18.2 2005/04/29 00:16:32 marka Exp $ */ -/* RFC 1712 */ +/*! + * \brief per RFC1712 */ typedef struct dns_rdata_gpos { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c b/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c index e432ce5..70c433c 100644 --- a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c +++ b/contrib/bind9/lib/dns/rdata/generic/hinfo_13.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: hinfo_13.c,v 1.37.12.5 2004/03/08 09:04:40 marka Exp $ */ +/* $Id: hinfo_13.c,v 1.42 2004/03/05 05:10:11 marka Exp $ */ /* * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. diff --git a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h b/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h index 61cbdd7..e542c48 100644 --- a/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h +++ b/contrib/bind9/lib/dns/rdata/generic/hinfo_13.h @@ -18,7 +18,7 @@ #ifndef GENERIC_HINFO_13_H #define GENERIC_HINFO_13_H 1 -/* $Id: hinfo_13.h,v 1.22.206.1 2004/03/06 08:14:05 marka Exp $ */ +/* $Id: hinfo_13.h,v 1.23 2004/03/05 05:10:12 marka Exp $ */ typedef struct dns_rdata_hinfo { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c new file mode 100644 index 0000000..3c3736e --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: ipseckey_45.c,v 1.2.2.1 2005/07/07 03:17:36 marka Exp $ */ + +#ifndef RDATA_GENERIC_IPSECKEY_45_C +#define RDATA_GENERIC_IPSECKEY_45_C + +#include <string.h> + +#include <isc/net.h> + +#define RRTYPE_IPSECKEY_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_ipseckey(ARGS_FROMTEXT) { + isc_token_t token; + dns_name_t name; + isc_buffer_t buffer; + unsigned int gateway; + struct in_addr addr; + unsigned char addr6[16]; + isc_region_t region; + + REQUIRE(type == 45); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(callbacks); + + /* + * Precedence. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffU) + RETTOK(ISC_R_RANGE); + RETERR(uint8_tobuffer(token.value.as_ulong, target)); + + /* + * Gateway type. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0x3U) + RETTOK(ISC_R_RANGE); + RETERR(uint8_tobuffer(token.value.as_ulong, target)); + gateway = token.value.as_ulong; + + /* + * Algorithm. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffU) + RETTOK(ISC_R_RANGE); + RETERR(uint8_tobuffer(token.value.as_ulong, target)); + + /* + * Gateway. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + ISC_FALSE)); + + switch (gateway) { + case 0: + if (strcmp(DNS_AS_STR(token), ".") != 0) + RETTOK(DNS_R_SYNTAX); + break; + + case 1: + if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1) + RETTOK(DNS_R_BADDOTTEDQUAD); + isc_buffer_availableregion(target, ®ion); + if (region.length < 4) + return (ISC_R_NOSPACE); + memcpy(region.base, &addr, 4); + isc_buffer_add(target, 4); + break; + + case 2: + if (inet_pton(AF_INET6, DNS_AS_STR(token), addr6) != 1) + RETTOK(DNS_R_BADAAAA); + isc_buffer_availableregion(target, ®ion); + if (region.length < 16) + return (ISC_R_NOSPACE); + memcpy(region.base, addr6, 16); + isc_buffer_add(target, 16); + break; + + case 3: + dns_name_init(&name, NULL); + buffer_fromregion(&buffer, &token.value.as_region); + origin = (origin != NULL) ? origin : dns_rootname; + RETTOK(dns_name_fromtext(&name, &buffer, origin, + options, target)); + break; + } + + /* + * Public key. + */ + return (isc_base64_tobuffer(lexer, target, -1)); +} + +static inline isc_result_t +totext_ipseckey(ARGS_TOTEXT) { + isc_region_t region; + dns_name_t name; + dns_name_t prefix; + isc_boolean_t sub; + char buf[sizeof("255 ")]; + unsigned short num; + unsigned short gateway; + + REQUIRE(rdata->type == 45); + REQUIRE(rdata->length >= 3); + + dns_name_init(&name, NULL); + dns_name_init(&prefix, NULL); + + if (rdata->data[1] > 3U) + return (ISC_R_NOTIMPLEMENTED); + + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext("( ", target)); + + /* + * Precendence. + */ + dns_rdata_toregion(rdata, ®ion); + num = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + sprintf(buf, "%u ", num); + RETERR(str_totext(buf, target)); + + /* + * Gateway type. + */ + gateway = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + sprintf(buf, "%u ", gateway); + RETERR(str_totext(buf, target)); + + /* + * Algorithm. + */ + num = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + sprintf(buf, "%u ", num); + RETERR(str_totext(buf, target)); + + /* + * Gateway. + */ + switch (gateway) { + case 0: + RETERR(str_totext(".", target)); + break; + + case 1: + RETERR(inet_totext(AF_INET, ®ion, target)); + isc_region_consume(®ion, 4); + break; + + case 2: + RETERR(inet_totext(AF_INET6, ®ion, target)); + isc_region_consume(®ion, 16); + break; + + case 3: + dns_name_fromregion(&name, ®ion); + sub = name_prefix(&name, tctx->origin, &prefix); + RETERR(dns_name_totext(&prefix, sub, target)); + isc_region_consume(®ion, name_length(&name)); + break; + } + + /* + * Key. + */ + if (region.length > 0U) { + RETERR(str_totext(tctx->linebreak, target)); + RETERR(isc_base64_totext(®ion, tctx->width - 2, + tctx->linebreak, target)); + } + + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" )", target)); + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +fromwire_ipseckey(ARGS_FROMWIRE) { + dns_name_t name; + isc_region_t region; + + REQUIRE(type == 45); + + UNUSED(type); + UNUSED(rdclass); + + dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); + + dns_name_init(&name, NULL); + + isc_buffer_activeregion(source, ®ion); + if (region.length < 3) + return (ISC_R_UNEXPECTEDEND); + + switch (region.base[1]) { + case 0: + isc_buffer_forward(source, region.length); + return (mem_tobuffer(target, region.base, region.length)); + + case 1: + if (region.length < 7) + return (ISC_R_UNEXPECTEDEND); + isc_buffer_forward(source, region.length); + return (mem_tobuffer(target, region.base, region.length)); + + case 2: + if (region.length < 19) + return (ISC_R_UNEXPECTEDEND); + isc_buffer_forward(source, region.length); + return (mem_tobuffer(target, region.base, region.length)); + + case 3: + RETERR(mem_tobuffer(target, region.base, 3)); + isc_buffer_forward(source, 3); + RETERR(dns_name_fromwire(&name, source, dctx, options, target)); + isc_buffer_activeregion(source, ®ion); + return(mem_tobuffer(target, region.base, region.length)); + + default: + return (ISC_R_NOTIMPLEMENTED); + } +} + +static inline isc_result_t +towire_ipseckey(ARGS_TOWIRE) { + isc_region_t region; + + REQUIRE(rdata->type == 45); + REQUIRE(rdata->length != 0); + + UNUSED(cctx); + + dns_rdata_toregion(rdata, ®ion); + return (mem_tobuffer(target, region.base, region.length)); +} + +static inline int +compare_ipseckey(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 45); + REQUIRE(rdata1->length >= 3); + REQUIRE(rdata2->length >= 3); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + + return (isc_region_compare(®ion1, ®ion2)); +} + +static inline isc_result_t +fromstruct_ipseckey(ARGS_FROMSTRUCT) { + dns_rdata_ipseckey_t *ipseckey = source; + isc_region_t region; + isc_uint32_t n; + + REQUIRE(type == 45); + REQUIRE(source != NULL); + REQUIRE(ipseckey->common.rdtype == type); + REQUIRE(ipseckey->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + if (ipseckey->gateway_type > 3U) + return (ISC_R_NOTIMPLEMENTED); + + RETERR(uint8_tobuffer(ipseckey->precedence, target)); + RETERR(uint8_tobuffer(ipseckey->gateway_type, target)); + RETERR(uint8_tobuffer(ipseckey->algorithm, target)); + + switch (ipseckey->gateway_type) { + case 0: + break; + + case 1: + n = ntohl(ipseckey->in_addr.s_addr); + RETERR(uint32_tobuffer(n, target)); + break; + + case 2: + RETERR(mem_tobuffer(target, ipseckey->in6_addr.s6_addr, 16)); + break; + + case 3: + dns_name_toregion(&ipseckey->gateway, ®ion); + RETERR(isc_buffer_copyregion(target, ®ion)); + break; + } + + return (mem_tobuffer(target, ipseckey->key, ipseckey->keylength)); +} + +static inline isc_result_t +tostruct_ipseckey(ARGS_TOSTRUCT) { + isc_region_t region; + dns_rdata_ipseckey_t *ipseckey = target; + dns_name_t name; + isc_uint32_t n; + + REQUIRE(rdata->type == 45); + REQUIRE(target != NULL); + REQUIRE(rdata->length >= 3); + + if (rdata->data[1] > 3U) + return (ISC_R_NOTIMPLEMENTED); + + ipseckey->common.rdclass = rdata->rdclass; + ipseckey->common.rdtype = rdata->type; + ISC_LINK_INIT(&ipseckey->common, link); + + dns_name_init(&name, NULL); + dns_rdata_toregion(rdata, ®ion); + + ipseckey->precedence = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + + ipseckey->gateway_type = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + + ipseckey->algorithm = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + + switch (ipseckey->gateway_type) { + case 0: + break; + + case 1: + n = uint32_fromregion(®ion); + ipseckey->in_addr.s_addr = htonl(n); + isc_region_consume(®ion, 4); + break; + + case 2: + memcpy(ipseckey->in6_addr.s6_addr, region.base, 16); + isc_region_consume(®ion, 16); + break; + + case 3: + dns_name_init(&ipseckey->gateway, NULL); + dns_name_fromregion(&name, ®ion); + RETERR(name_duporclone(&name, mctx, &ipseckey->gateway)); + isc_region_consume(®ion, name_length(&name)); + break; + } + + ipseckey->keylength = region.length; + if (ipseckey->keylength != 0U) { + ipseckey->key = mem_maybedup(mctx, region.base, + ipseckey->keylength); + if (ipseckey->key == NULL) { + if (ipseckey->gateway_type == 3) + dns_name_free(&ipseckey->gateway, + ipseckey->mctx); + return (ISC_R_NOMEMORY); + } + } else + ipseckey->key = NULL; + + ipseckey->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_ipseckey(ARGS_FREESTRUCT) { + dns_rdata_ipseckey_t *ipseckey = source; + + REQUIRE(source != NULL); + REQUIRE(ipseckey->common.rdtype == 45); + + if (ipseckey->mctx == NULL) + return; + + if (ipseckey->gateway_type == 3) + dns_name_free(&ipseckey->gateway, ipseckey->mctx); + + if (ipseckey->key != NULL) + isc_mem_free(ipseckey->mctx, ipseckey->key); + + ipseckey->mctx = NULL; +} + +static inline isc_result_t +additionaldata_ipseckey(ARGS_ADDLDATA) { + + REQUIRE(rdata->type == 45); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_ipseckey(ARGS_DIGEST) { + isc_region_t region; + + REQUIRE(rdata->type == 45); + + dns_rdata_toregion(rdata, ®ion); + return ((digest)(arg, ®ion)); +} + +static inline isc_boolean_t +checkowner_ipseckey(ARGS_CHECKOWNER) { + + REQUIRE(type == 45); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_ipseckey(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 45); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +#endif /* RDATA_GENERIC_IPSECKEY_45_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h new file mode 100644 index 0000000..b766fa0 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and 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: ipseckey_45.h,v 1.2.2.1 2005/07/07 03:17:36 marka Exp $ */ + +#ifndef GENERIC_IPSECKEY_45_H +#define GENERIC_IPSECKEY_45_H 1 + +typedef struct dns_rdata_ipseckey { + dns_rdatacommon_t common; + isc_mem_t *mctx; + isc_uint8_t precedence; + isc_uint8_t gateway_type; + isc_uint8_t algorithm; + struct in_addr in_addr; /* gateway type 1 */ + struct in6_addr in6_addr; /* gateway type 2 */ + dns_name_t gateway; /* gateway type 3 */ + unsigned char *key; + isc_uint16_t keylength; +} dns_rdata_ipseckey_t; + +#endif /* GENERIC_IPSECKEY_45_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/isdn_20.c b/contrib/bind9/lib/dns/rdata/generic/isdn_20.c index cc14157..1813759 100644 --- a/contrib/bind9/lib/dns/rdata/generic/isdn_20.c +++ b/contrib/bind9/lib/dns/rdata/generic/isdn_20.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: isdn_20.c,v 1.30.12.4 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: isdn_20.c,v 1.34.18.2 2005/04/29 00:16:33 marka Exp $ */ /* Reviewed: Wed Mar 15 16:53:11 PST 2000 by bwelling */ -/* RFC 1183 */ +/* RFC1183 */ #ifndef RDATA_GENERIC_ISDN_20_C #define RDATA_GENERIC_ISDN_20_C diff --git a/contrib/bind9/lib/dns/rdata/generic/isdn_20.h b/contrib/bind9/lib/dns/rdata/generic/isdn_20.h index 3a63971..6a51317 100644 --- a/contrib/bind9/lib/dns/rdata/generic/isdn_20.h +++ b/contrib/bind9/lib/dns/rdata/generic/isdn_20.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_ISDN_20_H #define GENERIC_ISDN_20_H 1 -/* $Id: isdn_20.h,v 1.13.206.1 2004/03/06 08:14:05 marka Exp $ */ +/* $Id: isdn_20.h,v 1.14.18.2 2005/04/29 00:16:33 marka Exp $ */ -/* RFC 1183 */ +/*! + * \brief Per RFC1183 */ typedef struct dns_rdata_isdn { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/key_25.c b/contrib/bind9/lib/dns/rdata/generic/key_25.c index defbe6d..24dc10f 100644 --- a/contrib/bind9/lib/dns/rdata/generic/key_25.c +++ b/contrib/bind9/lib/dns/rdata/generic/key_25.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,13 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: key_25.c,v 1.41.12.7 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: key_25.c,v 1.47.18.2 2005/04/29 00:16:33 marka Exp $ */ /* * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. */ -/* RFC 2535 */ +/* RFC2535 */ #ifndef RDATA_GENERIC_KEY_25_C #define RDATA_GENERIC_KEY_25_C diff --git a/contrib/bind9/lib/dns/rdata/generic/key_25.h b/contrib/bind9/lib/dns/rdata/generic/key_25.h index e192a1b..03400db 100644 --- a/contrib/bind9/lib/dns/rdata/generic/key_25.h +++ b/contrib/bind9/lib/dns/rdata/generic/key_25.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_KEY_25_H #define GENERIC_KEY_25_H 1 -/* $Id: key_25.h,v 1.14.206.1 2004/03/06 08:14:06 marka Exp $ */ +/* $Id: key_25.h,v 1.15.18.2 2005/04/29 00:16:33 marka Exp $ */ -/* RFC 2535 */ +/*! + * \brief Per RFC2535 */ typedef struct dns_rdata_key_t { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/loc_29.c b/contrib/bind9/lib/dns/rdata/generic/loc_29.c index 28003ab..c93ac90 100644 --- a/contrib/bind9/lib/dns/rdata/generic/loc_29.c +++ b/contrib/bind9/lib/dns/rdata/generic/loc_29.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: loc_29.c,v 1.30.2.3.2.6 2004/03/06 08:14:06 marka Exp $ */ +/* $Id: loc_29.c,v 1.41.18.2 2005/04/29 00:16:34 marka Exp $ */ /* Reviewed: Wed Mar 15 18:13:09 PST 2000 by explorer */ -/* RFC 1876 */ +/* RFC1876 */ #ifndef RDATA_GENERIC_LOC_29_C #define RDATA_GENERIC_LOC_29_C diff --git a/contrib/bind9/lib/dns/rdata/generic/loc_29.h b/contrib/bind9/lib/dns/rdata/generic/loc_29.h index cdca67b..d8eae16 100644 --- a/contrib/bind9/lib/dns/rdata/generic/loc_29.h +++ b/contrib/bind9/lib/dns/rdata/generic/loc_29.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_LOC_29_H #define GENERIC_LOC_29_H 1 -/* $Id: loc_29.h,v 1.14.206.1 2004/03/06 08:14:06 marka Exp $ */ +/* $Id: loc_29.h,v 1.15.18.2 2005/04/29 00:16:34 marka Exp $ */ -/* RFC 1876 */ +/*! + * \brief Per RFC1876 */ typedef struct dns_rdata_loc_0 { isc_uint8_t version; /* must be first and zero */ diff --git a/contrib/bind9/lib/dns/rdata/generic/mb_7.c b/contrib/bind9/lib/dns/rdata/generic/mb_7.c index 2562707..94c622d 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mb_7.c +++ b/contrib/bind9/lib/dns/rdata/generic/mb_7.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mb_7.c,v 1.41.206.2 2004/03/06 08:14:06 marka Exp $ */ +/* $Id: mb_7.c,v 1.43 2004/03/05 05:10:13 marka Exp $ */ /* Reviewed: Wed Mar 15 17:31:26 PST 2000 by bwelling */ diff --git a/contrib/bind9/lib/dns/rdata/generic/mb_7.h b/contrib/bind9/lib/dns/rdata/generic/mb_7.h index 115ab49..f6a8b35 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mb_7.h +++ b/contrib/bind9/lib/dns/rdata/generic/mb_7.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MB_7_H #define GENERIC_MB_7_H 1 -/* $Id: mb_7.h,v 1.22.206.1 2004/03/06 08:14:06 marka Exp $ */ +/* $Id: mb_7.h,v 1.23.18.2 2005/04/29 00:16:34 marka Exp $ */ typedef struct dns_rdata_mb { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/md_3.c b/contrib/bind9/lib/dns/rdata/generic/md_3.c index 7488d84..75e4970 100644 --- a/contrib/bind9/lib/dns/rdata/generic/md_3.c +++ b/contrib/bind9/lib/dns/rdata/generic/md_3.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: md_3.c,v 1.43.206.2 2004/03/06 08:14:07 marka Exp $ */ +/* $Id: md_3.c,v 1.45 2004/03/05 05:10:13 marka Exp $ */ /* Reviewed: Wed Mar 15 17:48:20 PST 2000 by bwelling */ diff --git a/contrib/bind9/lib/dns/rdata/generic/md_3.h b/contrib/bind9/lib/dns/rdata/generic/md_3.h index 8662829..578ce66 100644 --- a/contrib/bind9/lib/dns/rdata/generic/md_3.h +++ b/contrib/bind9/lib/dns/rdata/generic/md_3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MD_3_H #define GENERIC_MD_3_H 1 -/* $Id: md_3.h,v 1.23.206.1 2004/03/06 08:14:07 marka Exp $ */ +/* $Id: md_3.h,v 1.24.18.2 2005/04/29 00:16:35 marka Exp $ */ typedef struct dns_rdata_md { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/mf_4.c b/contrib/bind9/lib/dns/rdata/generic/mf_4.c index b6c72d9..362d300 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mf_4.c +++ b/contrib/bind9/lib/dns/rdata/generic/mf_4.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mf_4.c,v 1.41.206.2 2004/03/06 08:14:07 marka Exp $ */ +/* $Id: mf_4.c,v 1.43 2004/03/05 05:10:14 marka Exp $ */ /* reviewed: Wed Mar 15 17:47:33 PST 2000 by brister */ diff --git a/contrib/bind9/lib/dns/rdata/generic/mf_4.h b/contrib/bind9/lib/dns/rdata/generic/mf_4.h index adb8254..2be0eec 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mf_4.h +++ b/contrib/bind9/lib/dns/rdata/generic/mf_4.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MF_4_H #define GENERIC_MF_4_H 1 -/* $Id: mf_4.h,v 1.21.206.1 2004/03/06 08:14:07 marka Exp $ */ +/* $Id: mf_4.h,v 1.22.18.2 2005/04/29 00:16:35 marka Exp $ */ typedef struct dns_rdata_mf { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/mg_8.c b/contrib/bind9/lib/dns/rdata/generic/mg_8.c index 26eac8dd..602d820 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mg_8.c +++ b/contrib/bind9/lib/dns/rdata/generic/mg_8.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mg_8.c,v 1.39.206.2 2004/03/06 08:14:07 marka Exp $ */ +/* $Id: mg_8.c,v 1.41 2004/03/05 05:10:14 marka Exp $ */ /* reviewed: Wed Mar 15 17:49:21 PST 2000 by brister */ diff --git a/contrib/bind9/lib/dns/rdata/generic/mg_8.h b/contrib/bind9/lib/dns/rdata/generic/mg_8.h index b45c2bf..5679c17 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mg_8.h +++ b/contrib/bind9/lib/dns/rdata/generic/mg_8.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MG_8_H #define GENERIC_MG_8_H 1 -/* $Id: mg_8.h,v 1.21.206.1 2004/03/06 08:14:07 marka Exp $ */ +/* $Id: mg_8.h,v 1.22.18.2 2005/04/29 00:16:35 marka Exp $ */ typedef struct dns_rdata_mg { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/minfo_14.c b/contrib/bind9/lib/dns/rdata/generic/minfo_14.c index a3c4a9c..b757480 100644 --- a/contrib/bind9/lib/dns/rdata/generic/minfo_14.c +++ b/contrib/bind9/lib/dns/rdata/generic/minfo_14.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: minfo_14.c,v 1.40.12.4 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: minfo_14.c,v 1.43 2004/03/05 05:10:14 marka Exp $ */ /* reviewed: Wed Mar 15 17:45:32 PST 2000 by brister */ diff --git a/contrib/bind9/lib/dns/rdata/generic/minfo_14.h b/contrib/bind9/lib/dns/rdata/generic/minfo_14.h index 84078b9..754fe20 100644 --- a/contrib/bind9/lib/dns/rdata/generic/minfo_14.h +++ b/contrib/bind9/lib/dns/rdata/generic/minfo_14.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MINFO_14_H #define GENERIC_MINFO_14_H 1 -/* $Id: minfo_14.h,v 1.22.206.1 2004/03/06 08:14:08 marka Exp $ */ +/* $Id: minfo_14.h,v 1.23.18.2 2005/04/29 00:16:35 marka Exp $ */ typedef struct dns_rdata_minfo { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/mr_9.c b/contrib/bind9/lib/dns/rdata/generic/mr_9.c index 30da6cb..ab4c6e0 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mr_9.c +++ b/contrib/bind9/lib/dns/rdata/generic/mr_9.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mr_9.c,v 1.38.206.2 2004/03/06 08:14:08 marka Exp $ */ +/* $Id: mr_9.c,v 1.40 2004/03/05 05:10:15 marka Exp $ */ /* Reviewed: Wed Mar 15 21:30:35 EST 2000 by tale */ diff --git a/contrib/bind9/lib/dns/rdata/generic/mr_9.h b/contrib/bind9/lib/dns/rdata/generic/mr_9.h index ba6e154..e255d70 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mr_9.h +++ b/contrib/bind9/lib/dns/rdata/generic/mr_9.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MR_9_H #define GENERIC_MR_9_H 1 -/* $Id: mr_9.h,v 1.21.206.1 2004/03/06 08:14:08 marka Exp $ */ +/* $Id: mr_9.h,v 1.22.18.2 2005/04/29 00:16:36 marka Exp $ */ typedef struct dns_rdata_mr { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/mx_15.c b/contrib/bind9/lib/dns/rdata/generic/mx_15.c index 794249c..fd77ec8 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mx_15.c +++ b/contrib/bind9/lib/dns/rdata/generic/mx_15.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,15 +15,37 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mx_15.c,v 1.48.2.1.2.3 2004/03/06 08:14:08 marka Exp $ */ +/* $Id: mx_15.c,v 1.52.18.2 2005/05/20 01:10:11 marka Exp $ */ /* reviewed: Wed Mar 15 18:05:46 PST 2000 by brister */ #ifndef RDATA_GENERIC_MX_15_C #define RDATA_GENERIC_MX_15_C +#include <string.h> + +#include <isc/net.h> + #define RRTYPE_MX_ATTRIBUTES (0) +static isc_boolean_t +check_mx(isc_token_t *token) { + char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123.")]; + struct in_addr addr; + struct in6_addr addr6; + + if (strlcpy(tmp, DNS_AS_STR(*token), sizeof(tmp)) >= sizeof(tmp)) + return (ISC_TRUE); + + if (tmp[strlen(tmp) - 1] == '.') + tmp[strlen(tmp) - 1] = '\0'; + if (inet_aton(tmp, &addr) == 1 || + inet_pton(AF_INET6, tmp, &addr6) == 1) + return (ISC_FALSE); + + return (ISC_TRUE); +} + static inline isc_result_t fromtext_mx(ARGS_FROMTEXT) { isc_token_t token; @@ -45,6 +67,15 @@ fromtext_mx(ARGS_FROMTEXT) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); + + ok = ISC_TRUE; + if ((options & DNS_RDATA_CHECKMX) != 0) + ok = check_mx(&token); + if (!ok && (options & DNS_RDATA_CHECKMXFAIL) != 0) + RETTOK(DNS_R_MXISADDRESS); + if (!ok && callbacks != NULL) + warn_badmx(&token, lexer, callbacks); + dns_name_init(&name, NULL); buffer_fromregion(&buffer, &token.value.as_region); origin = (origin != NULL) ? origin : dns_rootname; diff --git a/contrib/bind9/lib/dns/rdata/generic/mx_15.h b/contrib/bind9/lib/dns/rdata/generic/mx_15.h index 01225fa..4d81b90 100644 --- a/contrib/bind9/lib/dns/rdata/generic/mx_15.h +++ b/contrib/bind9/lib/dns/rdata/generic/mx_15.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_MX_15_H #define GENERIC_MX_15_H 1 -/* $Id: mx_15.h,v 1.24.206.1 2004/03/06 08:14:09 marka Exp $ */ +/* $Id: mx_15.h,v 1.25.18.2 2005/04/29 00:16:36 marka Exp $ */ typedef struct dns_rdata_mx { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/ns_2.c b/contrib/bind9/lib/dns/rdata/generic/ns_2.c index bf32d63..2379433 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ns_2.c +++ b/contrib/bind9/lib/dns/rdata/generic/ns_2.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ns_2.c,v 1.42.206.2 2004/03/06 08:14:09 marka Exp $ */ +/* $Id: ns_2.c,v 1.44 2004/03/05 05:10:15 marka Exp $ */ /* Reviewed: Wed Mar 15 18:15:00 PST 2000 by bwelling */ diff --git a/contrib/bind9/lib/dns/rdata/generic/ns_2.h b/contrib/bind9/lib/dns/rdata/generic/ns_2.h index 2bef1f8..ec8e771 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ns_2.h +++ b/contrib/bind9/lib/dns/rdata/generic/ns_2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_NS_2_H #define GENERIC_NS_2_H 1 -/* $Id: ns_2.h,v 1.22.206.1 2004/03/06 08:14:09 marka Exp $ */ +/* $Id: ns_2.h,v 1.23.18.2 2005/04/29 00:16:37 marka Exp $ */ typedef struct dns_rdata_ns { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec_47.c b/contrib/bind9/lib/dns/rdata/generic/nsec_47.c index 74b7806..f3e56ca 100644 --- a/contrib/bind9/lib/dns/rdata/generic/nsec_47.c +++ b/contrib/bind9/lib/dns/rdata/generic/nsec_47.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsec_47.c,v 1.7.2.1 2004/03/08 02:08:03 marka Exp $ */ +/* $Id: nsec_47.c,v 1.7 2004/03/05 05:10:15 marka Exp $ */ /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */ diff --git a/contrib/bind9/lib/dns/rdata/generic/nsec_47.h b/contrib/bind9/lib/dns/rdata/generic/nsec_47.h index d76a25c..ff03483 100644 --- a/contrib/bind9/lib/dns/rdata/generic/nsec_47.h +++ b/contrib/bind9/lib/dns/rdata/generic/nsec_47.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_NSEC_47_H #define GENERIC_NSEC_47_H 1 -/* $Id: nsec_47.h,v 1.4.2.1 2004/03/08 02:08:03 marka Exp $ */ +/* $Id: nsec_47.h,v 1.4.20.2 2005/04/29 00:16:37 marka Exp $ */ -/* draft-ietf-dnsext-nsec-rdata-01.txt */ +/*! + * \brief Per draft-ietf-dnsext-nsec-rdata-01.txt */ typedef struct dns_rdata_nsec { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/null_10.c b/contrib/bind9/lib/dns/rdata/generic/null_10.c index 492044d..a6f8f9f4 100644 --- a/contrib/bind9/lib/dns/rdata/generic/null_10.c +++ b/contrib/bind9/lib/dns/rdata/generic/null_10.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: null_10.c,v 1.35.2.1.10.4 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: null_10.c,v 1.40 2004/03/05 05:10:16 marka Exp $ */ /* Reviewed: Thu Mar 16 13:57:50 PST 2000 by explorer */ diff --git a/contrib/bind9/lib/dns/rdata/generic/null_10.h b/contrib/bind9/lib/dns/rdata/generic/null_10.h index 44a9e8f..5afb1ae 100644 --- a/contrib/bind9/lib/dns/rdata/generic/null_10.h +++ b/contrib/bind9/lib/dns/rdata/generic/null_10.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_NULL_10_H #define GENERIC_NULL_10_H 1 -/* $Id: null_10.h,v 1.20.206.1 2004/03/06 08:14:09 marka Exp $ */ +/* $Id: null_10.h,v 1.21.18.2 2005/04/29 00:16:37 marka Exp $ */ typedef struct dns_rdata_null { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/nxt_30.c b/contrib/bind9/lib/dns/rdata/generic/nxt_30.c index e4dba7f..b7358e0 100644 --- a/contrib/bind9/lib/dns/rdata/generic/nxt_30.c +++ b/contrib/bind9/lib/dns/rdata/generic/nxt_30.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nxt_30.c,v 1.49.2.2.2.9 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: nxt_30.c,v 1.59.18.2 2005/04/29 00:16:38 marka Exp $ */ /* reviewed: Wed Mar 15 18:21:15 PST 2000 by brister */ -/* RFC 2535 */ +/* RFC2535 */ #ifndef RDATA_GENERIC_NXT_30_C #define RDATA_GENERIC_NXT_30_C diff --git a/contrib/bind9/lib/dns/rdata/generic/nxt_30.h b/contrib/bind9/lib/dns/rdata/generic/nxt_30.h index 540135f..3700fb1 100644 --- a/contrib/bind9/lib/dns/rdata/generic/nxt_30.h +++ b/contrib/bind9/lib/dns/rdata/generic/nxt_30.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_NXT_30_H #define GENERIC_NXT_30_H 1 -/* $Id: nxt_30.h,v 1.18.12.3 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: nxt_30.h,v 1.21.18.2 2005/04/29 00:16:38 marka Exp $ */ -/* RFC 2535 */ +/*! + * \brief RFC2535 */ typedef struct dns_rdata_nxt { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/opt_41.c b/contrib/bind9/lib/dns/rdata/generic/opt_41.c index ac74a28..e8f4816 100644 --- a/contrib/bind9/lib/dns/rdata/generic/opt_41.c +++ b/contrib/bind9/lib/dns/rdata/generic/opt_41.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: opt_41.c,v 1.25.12.4 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: opt_41.c,v 1.29.18.2 2005/04/29 00:16:38 marka Exp $ */ /* Reviewed: Thu Mar 16 14:06:44 PST 2000 by gson */ -/* RFC 2671 */ +/* RFC2671 */ #ifndef RDATA_GENERIC_OPT_41_C #define RDATA_GENERIC_OPT_41_C diff --git a/contrib/bind9/lib/dns/rdata/generic/opt_41.h b/contrib/bind9/lib/dns/rdata/generic/opt_41.h index c70ad90..827936e 100644 --- a/contrib/bind9/lib/dns/rdata/generic/opt_41.h +++ b/contrib/bind9/lib/dns/rdata/generic/opt_41.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_OPT_41_H #define GENERIC_OPT_41_H 1 -/* $Id: opt_41.h,v 1.13.206.1 2004/03/06 08:14:10 marka Exp $ */ +/* $Id: opt_41.h,v 1.14.18.2 2005/04/29 00:16:38 marka Exp $ */ -/* RFC 2671 */ +/*! + * \brief Per RFC2671 */ typedef struct dns_rdata_opt_opcode { isc_uint16_t opcode; diff --git a/contrib/bind9/lib/dns/rdata/generic/proforma.c b/contrib/bind9/lib/dns/rdata/generic/proforma.c index 21c6577..bf8b2fd 100644 --- a/contrib/bind9/lib/dns/rdata/generic/proforma.c +++ b/contrib/bind9/lib/dns/rdata/generic/proforma.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: proforma.c,v 1.30.12.4 2004/03/08 09:04:41 marka Exp $ */ +/* $Id: proforma.c,v 1.34 2004/03/05 05:10:17 marka Exp $ */ #ifndef RDATA_GENERIC_#_#_C #define RDATA_GENERIC_#_#_C diff --git a/contrib/bind9/lib/dns/rdata/generic/proforma.h b/contrib/bind9/lib/dns/rdata/generic/proforma.h index 5d5090e..89d1606 100644 --- a/contrib/bind9/lib/dns/rdata/generic/proforma.h +++ b/contrib/bind9/lib/dns/rdata/generic/proforma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_PROFORMA_H #define GENERIC_PROFORMA_H 1 -/* $Id: proforma.h,v 1.18.206.1 2004/03/06 08:14:11 marka Exp $ */ +/* $Id: proforma.h,v 1.19.18.2 2005/04/29 00:16:39 marka Exp $ */ typedef struct dns_rdata_# { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/ptr_12.c b/contrib/bind9/lib/dns/rdata/generic/ptr_12.c index 9be93b3..16d5706 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ptr_12.c +++ b/contrib/bind9/lib/dns/rdata/generic/ptr_12.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ptr_12.c,v 1.39.206.2 2004/03/06 08:14:11 marka Exp $ */ +/* $Id: ptr_12.c,v 1.41 2004/03/05 05:10:17 marka Exp $ */ /* Reviewed: Thu Mar 16 14:05:12 PST 2000 by explorer */ diff --git a/contrib/bind9/lib/dns/rdata/generic/ptr_12.h b/contrib/bind9/lib/dns/rdata/generic/ptr_12.h index 53e7920..4eb8fa7 100644 --- a/contrib/bind9/lib/dns/rdata/generic/ptr_12.h +++ b/contrib/bind9/lib/dns/rdata/generic/ptr_12.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_PTR_12_H #define GENERIC_PTR_12_H 1 -/* $Id: ptr_12.h,v 1.22.206.1 2004/03/06 08:14:11 marka Exp $ */ +/* $Id: ptr_12.h,v 1.23.18.2 2005/04/29 00:16:39 marka Exp $ */ typedef struct dns_rdata_ptr { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/rp_17.c b/contrib/bind9/lib/dns/rdata/generic/rp_17.c index 27e02ee..b153643 100644 --- a/contrib/bind9/lib/dns/rdata/generic/rp_17.c +++ b/contrib/bind9/lib/dns/rdata/generic/rp_17.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rp_17.c,v 1.35.12.4 2004/03/08 09:04:42 marka Exp $ */ +/* $Id: rp_17.c,v 1.38.18.2 2005/04/29 00:16:39 marka Exp $ */ -/* RFC 1183 */ +/* RFC1183 */ #ifndef RDATA_GENERIC_RP_17_C #define RDATA_GENERIC_RP_17_C diff --git a/contrib/bind9/lib/dns/rdata/generic/rp_17.h b/contrib/bind9/lib/dns/rdata/generic/rp_17.h index a88b9c0..533c7e7 100644 --- a/contrib/bind9/lib/dns/rdata/generic/rp_17.h +++ b/contrib/bind9/lib/dns/rdata/generic/rp_17.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_RP_17_H #define GENERIC_RP_17_H 1 -/* $Id: rp_17.h,v 1.16.206.1 2004/03/06 08:14:11 marka Exp $ */ +/* $Id: rp_17.h,v 1.17.18.2 2005/04/29 00:16:39 marka Exp $ */ -/* RFC 1183 */ +/*! + * \brief Per RFC1183 */ typedef struct dns_rdata_rp { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c b/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c index ad43295..6561f28 100644 --- a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c +++ b/contrib/bind9/lib/dns/rdata/generic/rrsig_46.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rrsig_46.c,v 1.4.2.3 2004/06/24 00:58:06 marka Exp $ */ +/* $Id: rrsig_46.c,v 1.5.18.3 2005/04/29 00:16:39 marka Exp $ */ /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */ -/* RFC 2535 */ +/* RFC2535 */ #ifndef RDATA_GENERIC_RRSIG_46_C #define RDATA_GENERIC_RRSIG_46_C diff --git a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h b/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h index 148604b..b8b35a2 100644 --- a/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h +++ b/contrib/bind9/lib/dns/rdata/generic/rrsig_46.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_DNSSIG_46_H #define GENERIC_DNSSIG_46_H 1 -/* $Id: rrsig_46.h,v 1.3.2.1 2004/03/08 02:08:04 marka Exp $ */ +/* $Id: rrsig_46.h,v 1.3.20.2 2005/04/29 00:16:39 marka Exp $ */ -/* RFC 2535 */ +/*! + * \brief Per RFC2535 */ typedef struct dns_rdata_rrsig { dns_rdatacommon_t common; isc_mem_t * mctx; diff --git a/contrib/bind9/lib/dns/rdata/generic/rt_21.c b/contrib/bind9/lib/dns/rdata/generic/rt_21.c index daf9756..6977e98 100644 --- a/contrib/bind9/lib/dns/rdata/generic/rt_21.c +++ b/contrib/bind9/lib/dns/rdata/generic/rt_21.c @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rt_21.c,v 1.37.2.1.2.5 2005/03/17 03:58:31 marka Exp $ */ +/* $Id: rt_21.c,v 1.41.18.3 2005/04/27 05:01:52 sra Exp $ */ /* reviewed: Thu Mar 16 15:02:31 PST 2000 by brister */ -/* RFC 1183 */ +/* RFC1183 */ #ifndef RDATA_GENERIC_RT_21_C #define RDATA_GENERIC_RT_21_C diff --git a/contrib/bind9/lib/dns/rdata/generic/rt_21.h b/contrib/bind9/lib/dns/rdata/generic/rt_21.h index 32b0352..b8ec969 100644 --- a/contrib/bind9/lib/dns/rdata/generic/rt_21.h +++ b/contrib/bind9/lib/dns/rdata/generic/rt_21.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_RT_21_H #define GENERIC_RT_21_H 1 -/* $Id: rt_21.h,v 1.16.206.1 2004/03/06 08:14:12 marka Exp $ */ +/* $Id: rt_21.h,v 1.17.18.2 2005/04/29 00:16:40 marka Exp $ */ -/* RFC 1183 */ +/*! + * \brief Per RFC1183 */ typedef struct dns_rdata_rt { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/sig_24.c b/contrib/bind9/lib/dns/rdata/generic/sig_24.c index 39cb064..9842953 100644 --- a/contrib/bind9/lib/dns/rdata/generic/sig_24.c +++ b/contrib/bind9/lib/dns/rdata/generic/sig_24.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sig_24.c,v 1.54.2.1.2.7 2004/03/08 09:04:42 marka Exp $ */ +/* $Id: sig_24.c,v 1.62.18.2 2005/04/29 00:16:40 marka Exp $ */ /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */ -/* RFC 2535 */ +/* RFC2535 */ #ifndef RDATA_GENERIC_SIG_24_C #define RDATA_GENERIC_SIG_24_C diff --git a/contrib/bind9/lib/dns/rdata/generic/sig_24.h b/contrib/bind9/lib/dns/rdata/generic/sig_24.h index 28bcac2..96ed767 100644 --- a/contrib/bind9/lib/dns/rdata/generic/sig_24.h +++ b/contrib/bind9/lib/dns/rdata/generic/sig_24.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_SIG_24_H #define GENERIC_SIG_24_H 1 -/* $Id: sig_24.h,v 1.21.206.1 2004/03/06 08:14:12 marka Exp $ */ +/* $Id: sig_24.h,v 1.22.18.2 2005/04/29 00:16:40 marka Exp $ */ -/* RFC 2535 */ +/*! + * \brief Per RFC2535 */ typedef struct dns_rdata_sig_t { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/soa_6.c b/contrib/bind9/lib/dns/rdata/generic/soa_6.c index 7eeb36e..8de678c 100644 --- a/contrib/bind9/lib/dns/rdata/generic/soa_6.c +++ b/contrib/bind9/lib/dns/rdata/generic/soa_6.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: soa_6.c,v 1.53.12.6 2004/03/08 09:04:42 marka Exp $ */ +/* $Id: soa_6.c,v 1.59 2004/03/05 05:10:18 marka Exp $ */ /* Reviewed: Thu Mar 16 15:18:32 PST 2000 by explorer */ diff --git a/contrib/bind9/lib/dns/rdata/generic/soa_6.h b/contrib/bind9/lib/dns/rdata/generic/soa_6.h index eca6dfd..4211786 100644 --- a/contrib/bind9/lib/dns/rdata/generic/soa_6.h +++ b/contrib/bind9/lib/dns/rdata/generic/soa_6.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,21 +15,22 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_SOA_6_H #define GENERIC_SOA_6_H 1 -/* $Id: soa_6.h,v 1.27.206.1 2004/03/06 08:14:12 marka Exp $ */ +/* $Id: soa_6.h,v 1.28.18.2 2005/04/29 00:16:40 marka Exp $ */ typedef struct dns_rdata_soa { dns_rdatacommon_t common; isc_mem_t *mctx; dns_name_t origin; dns_name_t contact; - isc_uint32_t serial; /* host order */ - isc_uint32_t refresh; /* host order */ - isc_uint32_t retry; /* host order */ - isc_uint32_t expire; /* host order */ - isc_uint32_t minimum; /* host order */ + isc_uint32_t serial; /*%< host order */ + isc_uint32_t refresh; /*%< host order */ + isc_uint32_t retry; /*%< host order */ + isc_uint32_t expire; /*%< host order */ + isc_uint32_t minimum; /*%< host order */ } dns_rdata_soa_t; diff --git a/contrib/bind9/lib/dns/rdata/generic/spf_99.c b/contrib/bind9/lib/dns/rdata/generic/spf_99.c new file mode 100644 index 0000000..b65f580 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/spf_99.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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: spf_99.c,v 1.1.2.2 2005/07/16 00:40:54 marka Exp $ */ + +/* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */ + +#ifndef RDATA_GENERIC_SPF_99_C +#define RDATA_GENERIC_SPF_99_C + +#define RRTYPE_SPF_ATTRIBUTES (0) + +static inline isc_result_t +fromtext_spf(ARGS_FROMTEXT) { + isc_token_t token; + int strings; + + REQUIRE(type == 99); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + strings = 0; + for (;;) { + RETERR(isc_lex_getmastertoken(lexer, &token, + isc_tokentype_qstring, + ISC_TRUE)); + if (token.type != isc_tokentype_qstring && + token.type != isc_tokentype_string) + break; + RETTOK(txt_fromtext(&token.value.as_textregion, target)); + strings++; + } + /* Let upper layer handle eol/eof. */ + isc_lex_ungettoken(lexer, &token); + return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS); +} + +static inline isc_result_t +totext_spf(ARGS_TOTEXT) { + isc_region_t region; + + UNUSED(tctx); + + REQUIRE(rdata->type == 99); + + dns_rdata_toregion(rdata, ®ion); + + while (region.length > 0) { + RETERR(txt_totext(®ion, target)); + if (region.length > 0) + RETERR(str_totext(" ", target)); + } + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +fromwire_spf(ARGS_FROMWIRE) { + isc_result_t result; + + REQUIRE(type == 99); + + UNUSED(type); + UNUSED(dctx); + UNUSED(rdclass); + UNUSED(options); + + do { + result = txt_fromwire(source, target); + if (result != ISC_R_SUCCESS) + return (result); + } while (!buffer_empty(source)); + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +towire_spf(ARGS_TOWIRE) { + isc_region_t region; + + REQUIRE(rdata->type == 99); + + UNUSED(cctx); + + isc_buffer_availableregion(target, ®ion); + if (region.length < rdata->length) + return (ISC_R_NOSPACE); + + memcpy(region.base, rdata->data, rdata->length); + isc_buffer_add(target, rdata->length); + return (ISC_R_SUCCESS); +} + +static inline int +compare_spf(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 99); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (isc_region_compare(&r1, &r2)); +} + +static inline isc_result_t +fromstruct_spf(ARGS_FROMSTRUCT) { + dns_rdata_spf_t *txt = source; + isc_region_t region; + isc_uint8_t length; + + REQUIRE(type == 99); + REQUIRE(source != NULL); + REQUIRE(txt->common.rdtype == type); + REQUIRE(txt->common.rdclass == rdclass); + REQUIRE(txt->txt != NULL && txt->txt_len != 0); + + UNUSED(type); + UNUSED(rdclass); + + region.base = txt->txt; + region.length = txt->txt_len; + while (region.length > 0) { + length = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + if (region.length <= length) + return (ISC_R_UNEXPECTEDEND); + isc_region_consume(®ion, length); + } + + return (mem_tobuffer(target, txt->txt, txt->txt_len)); +} + +static inline isc_result_t +tostruct_spf(ARGS_TOSTRUCT) { + dns_rdata_spf_t *txt = target; + isc_region_t r; + + REQUIRE(rdata->type == 99); + REQUIRE(target != NULL); + + txt->common.rdclass = rdata->rdclass; + txt->common.rdtype = rdata->type; + ISC_LINK_INIT(&txt->common, link); + + dns_rdata_toregion(rdata, &r); + txt->txt_len = r.length; + txt->txt = mem_maybedup(mctx, r.base, r.length); + if (txt->txt == NULL) + return (ISC_R_NOMEMORY); + + txt->offset = 0; + txt->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_spf(ARGS_FREESTRUCT) { + dns_rdata_spf_t *txt = source; + + REQUIRE(source != NULL); + REQUIRE(txt->common.rdtype == 99); + + if (txt->mctx == NULL) + return; + + if (txt->txt != NULL) + isc_mem_free(txt->mctx, txt->txt); + txt->mctx = NULL; +} + +static inline isc_result_t +additionaldata_spf(ARGS_ADDLDATA) { + REQUIRE(rdata->type == 99); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_spf(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 99); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_spf(ARGS_CHECKOWNER) { + + REQUIRE(type == 99); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_spf(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 99); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +#endif /* RDATA_GENERIC_SPF_99_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/spf_99.h b/contrib/bind9/lib/dns/rdata/generic/spf_99.h new file mode 100644 index 0000000..afe77ec --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/spf_99.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +#ifndef GENERIC_SPF_99_H +#define GENERIC_SPF_99_H 1 + +/* $Id: spf_99.h,v 1.1.2.2 2005/07/16 00:40:54 marka Exp $ */ + +typedef struct dns_rdata_spf_string { + isc_uint8_t length; + unsigned char *data; +} dns_rdata_spf_string_t; + +typedef struct dns_rdata_spf { + dns_rdatacommon_t common; + isc_mem_t *mctx; + unsigned char *txt; + isc_uint16_t txt_len; + /* private */ + isc_uint16_t offset; +} dns_rdata_spf_t; + +/* + * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done + * via rdatastructpre.h and rdatastructsuf.h. + */ + +isc_result_t +dns_rdata_spf_first(dns_rdata_spf_t *); + +isc_result_t +dns_rdata_spf_next(dns_rdata_spf_t *); + +isc_result_t +dns_rdata_spf_current(dns_rdata_spf_t *, dns_rdata_spf_string_t *); + +#endif /* GENERIC_SPF_99_H */ diff --git a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c index eabf056..64b51c7 100644 --- a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c +++ b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sshfp_44.c,v 1.1.8.3 2004/03/06 08:14:13 marka Exp $ */ +/* $Id: sshfp_44.c,v 1.3.18.1 2006/03/10 04:04:32 marka Exp $ */ -/* draft-ietf-secsh-dns-05.txt */ +/* RFC 4255 */ #ifndef RDATA_GENERIC_SSHFP_44_C #define RDATA_GENERIC_SSHFP_44_C diff --git a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h index ccdefd4..513eeac 100644 --- a/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h +++ b/contrib/bind9/lib/dns/rdata/generic/sshfp_44.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sshfp_44.h,v 1.1.8.2 2004/03/06 08:14:13 marka Exp $ */ +/* $Id: sshfp_44.h,v 1.2.18.3 2006/03/10 04:04:32 marka Exp $ */ -/* draft-ietf-secsh-dns-05.txt */ +/*! + * \brief Per RFC 4255 */ #ifndef GENERIC_SSHFP_44_H #define GENERIC_SSHFP_44_H 1 diff --git a/contrib/bind9/lib/dns/rdata/generic/tkey_249.c b/contrib/bind9/lib/dns/rdata/generic/tkey_249.c index da63167..cee16ab 100644 --- a/contrib/bind9/lib/dns/rdata/generic/tkey_249.c +++ b/contrib/bind9/lib/dns/rdata/generic/tkey_249.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tkey_249.c,v 1.48.2.1.2.6 2004/03/08 09:04:42 marka Exp $ */ +/* $Id: tkey_249.c,v 1.55 2004/03/05 05:10:18 marka Exp $ */ /* * Reviewed: Thu Mar 16 17:35:30 PST 2000 by halley. diff --git a/contrib/bind9/lib/dns/rdata/generic/tkey_249.h b/contrib/bind9/lib/dns/rdata/generic/tkey_249.h index 8e0081c..c1d2f06 100644 --- a/contrib/bind9/lib/dns/rdata/generic/tkey_249.h +++ b/contrib/bind9/lib/dns/rdata/generic/tkey_249.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_TKEY_249_H #define GENERIC_TKEY_249_H 1 -/* $Id: tkey_249.h,v 1.18.206.2 2004/03/06 08:14:13 marka Exp $ */ +/* $Id: tkey_249.h,v 1.20.18.2 2005/04/29 00:16:40 marka Exp $ */ -/* draft-ietf-dnsind-tkey-00.txt */ +/*! + * \brief Per draft-ietf-dnsind-tkey-00.txt */ typedef struct dns_rdata_tkey { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/txt_16.c b/contrib/bind9/lib/dns/rdata/generic/txt_16.c index 631d7af..fa3ffef 100644 --- a/contrib/bind9/lib/dns/rdata/generic/txt_16.c +++ b/contrib/bind9/lib/dns/rdata/generic/txt_16.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: txt_16.c,v 1.37.12.4 2004/03/08 09:04:42 marka Exp $ */ +/* $Id: txt_16.c,v 1.41 2004/03/05 05:10:18 marka Exp $ */ /* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */ diff --git a/contrib/bind9/lib/dns/rdata/generic/txt_16.h b/contrib/bind9/lib/dns/rdata/generic/txt_16.h index db5019c..57d986a 100644 --- a/contrib/bind9/lib/dns/rdata/generic/txt_16.h +++ b/contrib/bind9/lib/dns/rdata/generic/txt_16.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_TXT_16_H #define GENERIC_TXT_16_H 1 -/* $Id: txt_16.h,v 1.23.206.1 2004/03/06 08:14:14 marka Exp $ */ +/* $Id: txt_16.h,v 1.24.18.2 2005/04/29 00:16:40 marka Exp $ */ typedef struct dns_rdata_txt_string { isc_uint8_t length; diff --git a/contrib/bind9/lib/dns/rdata/generic/unspec_103.c b/contrib/bind9/lib/dns/rdata/generic/unspec_103.c index 157e9a1..f316ad9 100644 --- a/contrib/bind9/lib/dns/rdata/generic/unspec_103.c +++ b/contrib/bind9/lib/dns/rdata/generic/unspec_103.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: unspec_103.c,v 1.28.2.1.10.4 2004/03/08 09:04:43 marka Exp $ */ +/* $Id: unspec_103.c,v 1.33 2004/03/05 05:10:18 marka Exp $ */ #ifndef RDATA_GENERIC_UNSPEC_103_C #define RDATA_GENERIC_UNSPEC_103_C diff --git a/contrib/bind9/lib/dns/rdata/generic/unspec_103.h b/contrib/bind9/lib/dns/rdata/generic/unspec_103.h index 021e308..6575c1a 100644 --- a/contrib/bind9/lib/dns/rdata/generic/unspec_103.h +++ b/contrib/bind9/lib/dns/rdata/generic/unspec_103.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef GENERIC_UNSPEC_103_H #define GENERIC_UNSPEC_103_H 1 -/* $Id: unspec_103.h,v 1.12.206.1 2004/03/06 08:14:14 marka Exp $ */ +/* $Id: unspec_103.h,v 1.13.18.2 2005/04/29 00:16:40 marka Exp $ */ typedef struct dns_rdata_unspec_t { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/generic/x25_19.c b/contrib/bind9/lib/dns/rdata/generic/x25_19.c index 2f123ad..1199195 100644 --- a/contrib/bind9/lib/dns/rdata/generic/x25_19.c +++ b/contrib/bind9/lib/dns/rdata/generic/x25_19.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: x25_19.c,v 1.31.12.4 2004/03/08 09:04:43 marka Exp $ */ +/* $Id: x25_19.c,v 1.35.18.2 2005/04/29 00:16:40 marka Exp $ */ /* Reviewed: Thu Mar 16 16:15:57 PST 2000 by bwelling */ -/* RFC 1183 */ +/* RFC1183 */ #ifndef RDATA_GENERIC_X25_19_C #define RDATA_GENERIC_X25_19_C diff --git a/contrib/bind9/lib/dns/rdata/generic/x25_19.h b/contrib/bind9/lib/dns/rdata/generic/x25_19.h index bcb74cf..32320d0 100644 --- a/contrib/bind9/lib/dns/rdata/generic/x25_19.h +++ b/contrib/bind9/lib/dns/rdata/generic/x25_19.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef GENERIC_X25_19_H #define GENERIC_X25_19_H 1 -/* $Id: x25_19.h,v 1.13.206.1 2004/03/06 08:14:14 marka Exp $ */ +/* $Id: x25_19.h,v 1.14.18.2 2005/04/29 00:16:40 marka Exp $ */ -/* RFC 1183 */ +/*! + * \brief Per RFC1183 */ typedef struct dns_rdata_x25 { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/hs_4/a_1.c b/contrib/bind9/lib/dns/rdata/hs_4/a_1.c index 07d6adc..5d3ddae 100644 --- a/contrib/bind9/lib/dns/rdata/hs_4/a_1.c +++ b/contrib/bind9/lib/dns/rdata/hs_4/a_1.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: a_1.c,v 1.25.12.4 2004/03/08 09:04:43 marka Exp $ */ +/* $Id: a_1.c,v 1.29 2004/03/05 05:10:20 marka Exp $ */ /* reviewed: Thu Mar 16 15:58:36 PST 2000 by brister */ diff --git a/contrib/bind9/lib/dns/rdata/hs_4/a_1.h b/contrib/bind9/lib/dns/rdata/hs_4/a_1.h index c06c648..59f54b5 100644 --- a/contrib/bind9/lib/dns/rdata/hs_4/a_1.h +++ b/contrib/bind9/lib/dns/rdata/hs_4/a_1.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef HS_4_A_1_H #define HS_4_A_1_H 1 -/* $Id: a_1.h,v 1.7.206.1 2004/03/06 08:14:15 marka Exp $ */ +/* $Id: a_1.h,v 1.8.18.2 2005/04/29 00:16:41 marka Exp $ */ typedef struct dns_rdata_hs_a { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/a6_38.c b/contrib/bind9/lib/dns/rdata/in_1/a6_38.c index ded70c1..50017e1 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/a6_38.c +++ b/contrib/bind9/lib/dns/rdata/in_1/a6_38.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: a6_38.c,v 1.46.2.1.2.5 2004/03/08 09:04:43 marka Exp $ */ +/* $Id: a6_38.c,v 1.52 2004/03/05 05:10:23 marka Exp $ */ /* RFC2874 */ diff --git a/contrib/bind9/lib/dns/rdata/in_1/a6_38.h b/contrib/bind9/lib/dns/rdata/in_1/a6_38.h index 9134ced..bb15dad 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/a6_38.h +++ b/contrib/bind9/lib/dns/rdata/in_1/a6_38.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_A6_38_H #define IN_1_A6_38_H 1 -/* $Id: a6_38.h,v 1.19.206.1 2004/03/06 08:14:15 marka Exp $ */ +/* $Id: a6_38.h,v 1.20.18.2 2005/04/29 00:16:41 marka Exp $ */ -/* RFC2874 */ +/*! + * \brief Per RFC2874 */ typedef struct dns_rdata_in_a6 { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/a_1.c b/contrib/bind9/lib/dns/rdata/in_1/a_1.c index 30165c9..e8cb8ce 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/a_1.c +++ b/contrib/bind9/lib/dns/rdata/in_1/a_1.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: a_1.c,v 1.46.12.5 2004/03/08 09:04:43 marka Exp $ */ +/* $Id: a_1.c,v 1.51 2004/03/05 05:10:23 marka Exp $ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ diff --git a/contrib/bind9/lib/dns/rdata/in_1/a_1.h b/contrib/bind9/lib/dns/rdata/in_1/a_1.h index 34d7469..d92a973 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/a_1.h +++ b/contrib/bind9/lib/dns/rdata/in_1/a_1.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef IN_1_A_1_H #define IN_1_A_1_H 1 -/* $Id: a_1.h,v 1.23.206.1 2004/03/06 08:14:16 marka Exp $ */ +/* $Id: a_1.h,v 1.24.18.2 2005/04/29 00:16:41 marka Exp $ */ typedef struct dns_rdata_in_a { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c b/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c index 489fe01..1dd32cf 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c +++ b/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: aaaa_28.c,v 1.36.12.5 2004/03/08 09:04:44 marka Exp $ */ +/* $Id: aaaa_28.c,v 1.41.18.2 2005/04/29 00:16:41 marka Exp $ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ -/* RFC 1886 */ +/* RFC1886 */ #ifndef RDATA_IN_1_AAAA_28_C #define RDATA_IN_1_AAAA_28_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h b/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h index e8a9319..31ad6a6 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h +++ b/contrib/bind9/lib/dns/rdata/in_1/aaaa_28.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_AAAA_28_H #define IN_1_AAAA_28_H 1 -/* $Id: aaaa_28.h,v 1.16.206.1 2004/03/06 08:14:16 marka Exp $ */ +/* $Id: aaaa_28.h,v 1.17.18.2 2005/04/29 00:16:42 marka Exp $ */ -/* RFC 1886 */ +/*! + * \brief Per RFC1886 */ typedef struct dns_rdata_in_aaaa { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/apl_42.c b/contrib/bind9/lib/dns/rdata/in_1/apl_42.c index ac39569..42b2e7f 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/apl_42.c +++ b/contrib/bind9/lib/dns/rdata/in_1/apl_42.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: apl_42.c,v 1.4.200.8 2004/03/16 12:38:15 marka Exp $ */ +/* $Id: apl_42.c,v 1.8.18.2 2005/04/29 00:16:42 marka Exp $ */ -/* RFC 3123 */ +/* RFC3123 */ #ifndef RDATA_IN_1_APL_42_C #define RDATA_IN_1_APL_42_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/apl_42.h b/contrib/bind9/lib/dns/rdata/in_1/apl_42.h index 83309a6..d434ace 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/apl_42.h +++ b/contrib/bind9/lib/dns/rdata/in_1/apl_42.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,10 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* */ #ifndef IN_1_APL_42_H #define IN_1_APL_42_H 1 -/* $Id: apl_42.h,v 1.1.202.3 2004/03/08 09:04:44 marka Exp $ */ +/* $Id: apl_42.h,v 1.2.18.2 2005/04/29 00:16:42 marka Exp $ */ typedef struct dns_rdata_apl_ent { isc_boolean_t negative; diff --git a/contrib/bind9/lib/dns/rdata/in_1/kx_36.c b/contrib/bind9/lib/dns/rdata/in_1/kx_36.c index fee1e3d..8a64aac 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/kx_36.c +++ b/contrib/bind9/lib/dns/rdata/in_1/kx_36.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: kx_36.c,v 1.37.2.1.2.3 2004/03/06 08:14:17 marka Exp $ */ +/* $Id: kx_36.c,v 1.41.18.2 2005/04/29 00:16:42 marka Exp $ */ /* Reviewed: Thu Mar 16 17:24:54 PST 2000 by explorer */ -/* RFC 2230 */ +/* RFC2230 */ #ifndef RDATA_IN_1_KX_36_C #define RDATA_IN_1_KX_36_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/kx_36.h b/contrib/bind9/lib/dns/rdata/in_1/kx_36.h index 5ac328d..c44883d 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/kx_36.h +++ b/contrib/bind9/lib/dns/rdata/in_1/kx_36.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_KX_36_H #define IN_1_KX_36_H 1 -/* $Id: kx_36.h,v 1.15.206.1 2004/03/06 08:14:17 marka Exp $ */ +/* $Id: kx_36.h,v 1.16.18.2 2005/04/29 00:16:42 marka Exp $ */ -/* RFC 2230 */ +/*! + * \brief Per RFC2230 */ typedef struct dns_rdata_in_kx { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c b/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c index f3c93c7..0e5961a 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c +++ b/contrib/bind9/lib/dns/rdata/in_1/naptr_35.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: naptr_35.c,v 1.43.2.1.2.3 2004/03/06 08:14:17 marka Exp $ */ +/* $Id: naptr_35.c,v 1.47.18.2 2005/04/29 00:16:42 marka Exp $ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ -/* RFC 2915 */ +/* RFC2915 */ #ifndef RDATA_IN_1_NAPTR_35_C #define RDATA_IN_1_NAPTR_35_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/naptr_35.h b/contrib/bind9/lib/dns/rdata/in_1/naptr_35.h index b1deb2ce..2578b48 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/naptr_35.h +++ b/contrib/bind9/lib/dns/rdata/in_1/naptr_35.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_NAPTR_35_H #define IN_1_NAPTR_35_H 1 -/* $Id: naptr_35.h,v 1.18.206.1 2004/03/06 08:14:17 marka Exp $ */ +/* $Id: naptr_35.h,v 1.19.18.2 2005/04/29 00:16:42 marka Exp $ */ -/* RFC 2915 */ +/*! + * \brief Per RFC2915 */ typedef struct dns_rdata_in_naptr { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c b/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c index 0fa0fb2..1a65cbe 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c +++ b/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsap-ptr_23.c,v 1.32.206.2 2004/03/06 08:14:17 marka Exp $ */ +/* $Id: nsap-ptr_23.c,v 1.34.18.2 2005/04/29 00:16:42 marka Exp $ */ /* Reviewed: Fri Mar 17 10:16:02 PST 2000 by gson */ -/* RFC 1348. Obsoleted in RFC 1706 - use PTR instead. */ +/* RFC1348. Obsoleted in RFC 1706 - use PTR instead. */ #ifndef RDATA_IN_1_NSAP_PTR_23_C #define RDATA_IN_1_NSAP_PTR_23_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h b/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h index 9bf3c65..bd8e025 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h +++ b/contrib/bind9/lib/dns/rdata/in_1/nsap-ptr_23.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_NSAP_PTR_23_H #define IN_1_NSAP_PTR_23_H 1 -/* $Id: nsap-ptr_23.h,v 1.14.206.1 2004/03/06 08:14:18 marka Exp $ */ +/* $Id: nsap-ptr_23.h,v 1.15.18.2 2005/04/29 00:16:43 marka Exp $ */ -/* RFC 1348. Obsoleted in RFC 1706 - use PTR instead. */ +/*! + * \brief Per RFC1348. Obsoleted in RFC 1706 - use PTR instead. */ typedef struct dns_rdata_in_nsap_ptr { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c index 594b97f..a348a30 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c +++ b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsap_22.c,v 1.33.12.5 2004/03/08 09:04:44 marka Exp $ */ +/* $Id: nsap_22.c,v 1.38.18.2 2005/04/29 00:16:43 marka Exp $ */ /* Reviewed: Fri Mar 17 10:41:07 PST 2000 by gson */ -/* RFC 1706 */ +/* RFC1706 */ #ifndef RDATA_IN_1_NSAP_22_C #define RDATA_IN_1_NSAP_22_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h index 6467433..583fbac 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h +++ b/contrib/bind9/lib/dns/rdata/in_1/nsap_22.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_NSAP_22_H #define IN_1_NSAP_22_H 1 -/* $Id: nsap_22.h,v 1.13.206.1 2004/03/06 08:14:18 marka Exp $ */ +/* $Id: nsap_22.h,v 1.14.18.2 2005/04/29 00:16:43 marka Exp $ */ -/* RFC 1706 */ +/*! + * \brief Per RFC1706 */ typedef struct dns_rdata_in_nsap { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/px_26.c b/contrib/bind9/lib/dns/rdata/in_1/px_26.c index 66214dd..3df9b99 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/px_26.c +++ b/contrib/bind9/lib/dns/rdata/in_1/px_26.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: px_26.c,v 1.34.2.1.2.4 2004/03/06 08:14:18 marka Exp $ */ +/* $Id: px_26.c,v 1.39.18.2 2005/04/29 00:16:43 marka Exp $ */ /* Reviewed: Mon Mar 20 10:44:27 PST 2000 */ -/* RFC 2163 */ +/* RFC2163 */ #ifndef RDATA_IN_1_PX_26_C #define RDATA_IN_1_PX_26_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/px_26.h b/contrib/bind9/lib/dns/rdata/in_1/px_26.h index 79d4b18..a38d5f81 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/px_26.h +++ b/contrib/bind9/lib/dns/rdata/in_1/px_26.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,9 +18,10 @@ #ifndef IN_1_PX_26_H #define IN_1_PX_26_H 1 -/* $Id: px_26.h,v 1.14.206.1 2004/03/06 08:14:18 marka Exp $ */ +/* $Id: px_26.h,v 1.15.18.2 2005/04/29 00:16:43 marka Exp $ */ -/* RFC 2163 */ +/*! + * \brief Per RFC2163 */ typedef struct dns_rdata_in_px { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/srv_33.c b/contrib/bind9/lib/dns/rdata/in_1/srv_33.c index 7bcba1b..2925a77 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/srv_33.c +++ b/contrib/bind9/lib/dns/rdata/in_1/srv_33.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: srv_33.c,v 1.36.2.1.2.4 2004/03/06 08:14:18 marka Exp $ */ +/* $Id: srv_33.c,v 1.41.18.2 2005/04/29 00:16:43 marka Exp $ */ /* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */ -/* RFC 2782 */ +/* RFC2782 */ #ifndef RDATA_IN_1_SRV_33_C #define RDATA_IN_1_SRV_33_C diff --git a/contrib/bind9/lib/dns/rdata/in_1/srv_33.h b/contrib/bind9/lib/dns/rdata/in_1/srv_33.h index 91dbf37..7d9fef6 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/srv_33.h +++ b/contrib/bind9/lib/dns/rdata/in_1/srv_33.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -18,11 +18,12 @@ #ifndef IN_1_SRV_33_H #define IN_1_SRV_33_H 1 -/* $Id: srv_33.h,v 1.14.206.1 2004/03/06 08:14:19 marka Exp $ */ +/* $Id: srv_33.h,v 1.15.18.2 2005/04/29 00:16:43 marka Exp $ */ /* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */ -/* RFC 2782 */ +/*! + * \brief Per RFC2782 */ typedef struct dns_rdata_in_srv { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/in_1/wks_11.c b/contrib/bind9/lib/dns/rdata/in_1/wks_11.c index c278686..749b8fd 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/wks_11.c +++ b/contrib/bind9/lib/dns/rdata/in_1/wks_11.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: wks_11.c,v 1.44.12.8 2004/09/16 01:00:58 marka Exp $ */ +/* $Id: wks_11.c,v 1.51.18.1 2004/09/16 01:02:19 marka Exp $ */ /* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */ diff --git a/contrib/bind9/lib/dns/rdata/in_1/wks_11.h b/contrib/bind9/lib/dns/rdata/in_1/wks_11.h index e734281..a0093b9 100644 --- a/contrib/bind9/lib/dns/rdata/in_1/wks_11.h +++ b/contrib/bind9/lib/dns/rdata/in_1/wks_11.h @@ -18,7 +18,7 @@ #ifndef IN_1_WKS_11_H #define IN_1_WKS_11_H 1 -/* $Id: wks_11.h,v 1.19.206.1 2004/03/06 08:14:19 marka Exp $ */ +/* $Id: wks_11.h,v 1.20 2004/03/05 05:10:25 marka Exp $ */ typedef struct dns_rdata_in_wks { dns_rdatacommon_t common; diff --git a/contrib/bind9/lib/dns/rdata/rdatastructpre.h b/contrib/bind9/lib/dns/rdata/rdatastructpre.h index 19af8b4..d641ef5 100644 --- a/contrib/bind9/lib/dns/rdata/rdatastructpre.h +++ b/contrib/bind9/lib/dns/rdata/rdatastructpre.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatastructpre.h,v 1.13.206.1 2004/03/06 08:14:02 marka Exp $ */ +/* $Id: rdatastructpre.h,v 1.14 2004/03/05 05:10:04 marka Exp $ */ #ifndef DNS_RDATASTRUCT_H #define DNS_RDATASTRUCT_H 1 diff --git a/contrib/bind9/lib/dns/rdata/rdatastructsuf.h b/contrib/bind9/lib/dns/rdata/rdatastructsuf.h index 3eabff2..1ab1b0a 100644 --- a/contrib/bind9/lib/dns/rdata/rdatastructsuf.h +++ b/contrib/bind9/lib/dns/rdata/rdatastructsuf.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatastructsuf.h,v 1.7.206.1 2004/03/06 08:14:02 marka Exp $ */ +/* $Id: rdatastructsuf.h,v 1.8 2004/03/05 05:10:04 marka Exp $ */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/rdatalist.c b/contrib/bind9/lib/dns/rdatalist.c index baa62e5..7229fa3 100644 --- a/contrib/bind9/lib/dns/rdatalist.c +++ b/contrib/bind9/lib/dns/rdatalist.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatalist.c,v 1.25.2.2.2.2 2004/03/08 02:07:56 marka Exp $ */ +/* $Id: rdatalist.c,v 1.28.18.3 2005/04/29 00:16:02 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -38,7 +40,10 @@ static dns_rdatasetmethods_t methods = { isc__rdatalist_clone, isc__rdatalist_count, isc__rdatalist_addnoqname, - isc__rdatalist_getnoqname + isc__rdatalist_getnoqname, + NULL, + NULL, + NULL }; void diff --git a/contrib/bind9/lib/dns/rdatalist_p.h b/contrib/bind9/lib/dns/rdatalist_p.h index 3a7b52c..d697fec 100644 --- a/contrib/bind9/lib/dns/rdatalist_p.h +++ b/contrib/bind9/lib/dns/rdatalist_p.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,11 +15,13 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatalist_p.h,v 1.3.206.2 2004/03/08 02:07:56 marka Exp $ */ +/* $Id: rdatalist_p.h,v 1.5.18.2 2005/04/29 00:16:03 marka Exp $ */ #ifndef DNS_RDATALIST_P_H #define DNS_RDATALIST_P_H +/*! \file */ + #include <isc/result.h> #include <dns/types.h> diff --git a/contrib/bind9/lib/dns/rdataset.c b/contrib/bind9/lib/dns/rdataset.c index 8af71c3..c86b3c5 100644 --- a/contrib/bind9/lib/dns/rdataset.c +++ b/contrib/bind9/lib/dns/rdataset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.c,v 1.58.2.2.2.12 2006/03/02 00:37:20 marka Exp $ */ +/* $Id: rdataset.c,v 1.72.18.5 2006/03/02 00:37:21 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -174,6 +176,9 @@ static dns_rdatasetmethods_t question_methods = { question_clone, question_count, NULL, + NULL, + NULL, + NULL, NULL }; @@ -624,3 +629,81 @@ dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, return (ISC_R_NOTIMPLEMENTED); return((rdataset->methods->getnoqname)(rdataset, name, nsec, nsecsig)); } + +/* + * Additional cache stuff + */ +isc_result_t +dns_rdataset_getadditional(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t **zonep, + dns_db_t **dbp, + dns_dbversion_t **versionp, + dns_dbnode_t **nodep, + dns_name_t *fname, + dns_message_t *msg, + isc_stdtime_t now) +{ + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + REQUIRE(zonep == NULL || *zonep == NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + REQUIRE(versionp != NULL && *versionp == NULL); + REQUIRE(nodep != NULL && *nodep == NULL); + REQUIRE(fname != NULL); + REQUIRE(msg != NULL); + + if (acache != NULL && rdataset->methods->getadditional != NULL) { + return ((rdataset->methods->getadditional)(rdataset, type, + qtype, acache, + zonep, dbp, + versionp, nodep, + fname, msg, now)); + } + + return (ISC_R_FAILURE); +} + +isc_result_t +dns_rdataset_setadditional(dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype, + dns_acache_t *acache, + dns_zone_t *zone, + dns_db_t *db, + dns_dbversion_t *version, + dns_dbnode_t *node, + dns_name_t *fname) +{ + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (acache != NULL && rdataset->methods->setadditional != NULL) { + return ((rdataset->methods->setadditional)(rdataset, type, + qtype, acache, zone, + db, version, + node, fname)); + } + + return (ISC_R_FAILURE); +} + +isc_result_t +dns_rdataset_putadditional(dns_acache_t *acache, + dns_rdataset_t *rdataset, + dns_rdatasetadditional_t type, + dns_rdatatype_t qtype) +{ + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (acache != NULL && rdataset->methods->putadditional != NULL) { + return ((rdataset->methods->putadditional)(acache, rdataset, + type, qtype)); + } + + return (ISC_R_FAILURE); +} + diff --git a/contrib/bind9/lib/dns/rdatasetiter.c b/contrib/bind9/lib/dns/rdatasetiter.c index f3b0f8b..8089e04 100644 --- a/contrib/bind9/lib/dns/rdatasetiter.c +++ b/contrib/bind9/lib/dns/rdatasetiter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatasetiter.c,v 1.11.206.1 2004/03/06 08:13:44 marka Exp $ */ +/* $Id: rdatasetiter.c,v 1.12.18.2 2005/04/29 00:16:03 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/rdataslab.c b/contrib/bind9/lib/dns/rdataslab.c index 0604cd5..3b5ab2d 100644 --- a/contrib/bind9/lib/dns/rdataslab.c +++ b/contrib/bind9/lib/dns/rdataslab.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.c,v 1.29.2.2.2.6 2004/03/08 09:04:31 marka Exp $ */ +/* $Id: rdataslab.c,v 1.35.18.5 2006/03/05 23:58:51 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -31,25 +33,95 @@ #include <dns/rdataset.h> #include <dns/rdataslab.h> -/* Note: the "const void *" are just to make qsort happy. */ +/* + * The rdataslab structure allows iteration to occur in both load order + * and DNSSEC order. The structure is as follows: + * + * header (reservelen bytes) + * record count (2 bytes) + * offset table (4 x record count bytes in load order) + * data records + * data length (2 bytes) + * order (2 bytes) + * data (data length bytes) + * + * Offsets are from the end of the header. + * + * Load order traversal is performed by walking the offset table to find + * the start of the record. + * + * DNSSEC order traversal is performed by walking the data records. + * + * The order is stored with record to allow for efficient reconstuction of + * of the offset table following a merge or subtraction. + * + * The iterator methods here currently only support DNSSEC order iteration. + * + * The iterator methods in rbtdb support both load order and DNSSEC order + * iteration. + * + * WARNING: + * rbtdb.c directly interacts with the slab's raw structures. If the + * structure changes then rbtdb.c also needs to be updated to reflect + * the changes. See the areas tagged with "RDATASLAB". + */ + +struct xrdata { + dns_rdata_t rdata; + unsigned int order; +}; + +/*% Note: the "const void *" are just to make qsort happy. */ static int compare_rdata(const void *p1, const void *p2) { - const dns_rdata_t *rdata1 = p1; - const dns_rdata_t *rdata2 = p2; - return (dns_rdata_compare(rdata1, rdata2)); + const struct xrdata *x1 = p1; + const struct xrdata *x2 = p2; + return (dns_rdata_compare(&x1->rdata, &x2->rdata)); +} + +static void +fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable, + unsigned length) +{ + unsigned int i, j; + unsigned char *raw; + + for (i = 0, j = 0; i < length; i++) { + + if (offsettable[i] == 0) + continue; + + /* + * Fill in offset table. + */ + raw = &offsetbase[j*4 + 2]; + *raw++ = (offsettable[i] & 0xff000000) >> 24; + *raw++ = (offsettable[i] & 0xff0000) >> 16; + *raw++ = (offsettable[i] & 0xff00) >> 8; + *raw = offsettable[i] & 0xff; + + /* + * Fill in table index. + */ + raw = offsetbase + offsettable[i] + 2; + *raw++ = (j & 0xff00) >> 8; + *raw = j++ & 0xff; + } } isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, unsigned int reservelen) { - dns_rdata_t *rdatas; + struct xrdata *x; unsigned char *rawbuf; + unsigned char *offsetbase; unsigned int buflen; isc_result_t result; unsigned int nitems; unsigned int nalloc; unsigned int i; + unsigned int *offsettable; buflen = reservelen + 2; @@ -58,8 +130,11 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, if (nitems == 0) return (ISC_R_FAILURE); - rdatas = isc_mem_get(mctx, nalloc * sizeof(dns_rdata_t)); - if (rdatas == NULL) + if (nalloc > 0xffff) + return (ISC_R_NOSPACE); + + x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata)); + if (x == NULL) return (ISC_R_NOMEMORY); /* @@ -70,8 +145,9 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, goto free_rdatas; for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) { INSIST(result == ISC_R_SUCCESS); - dns_rdata_init(&rdatas[i]); - dns_rdataset_current(rdataset, &rdatas[i]); + dns_rdata_init(&x[i].rdata); + dns_rdataset_current(rdataset, &x[i].rdata); + x[i].order = i; result = dns_rdataset_next(rdataset); } if (result != ISC_R_NOMORE) @@ -85,7 +161,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, goto free_rdatas; } - qsort(rdatas, nalloc, sizeof(dns_rdata_t), compare_rdata); + /* + * Put into DNSSEC order. + */ + qsort(x, nalloc, sizeof(struct xrdata), compare_rdata); /* * Remove duplicates and compute the total storage required. @@ -93,20 +172,27 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, * If an rdata is not a duplicate, accumulate the storage size * required for the rdata. We do not store the class, type, etc, * just the rdata, so our overhead is 2 bytes for the number of - * records, and 2 for each rdata length, and then the rdata itself. + * records, and 8 for each rdata, (length(2), offset(4) and order(2)) + * and then the rdata itself. */ for (i = 1; i < nalloc; i++) { - if (compare_rdata(&rdatas[i-1], &rdatas[i]) == 0) { - rdatas[i-1].data = NULL; - rdatas[i-1].length = 0; + if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) { + x[i-1].rdata.data = NULL; + x[i-1].rdata.length = 0; + /* + * Preserve the least order so A, B, A -> A, B + * after duplicate removal. + */ + if (x[i-1].order < x[i].order) + x[i].order = x[i-1].order; nitems--; } else - buflen += (2 + rdatas[i-1].length); + buflen += (8 + x[i-1].rdata.length); } /* * Don't forget the last item! */ - buflen += (2 + rdatas[i-1].length); + buflen += (8 + x[i-1].rdata.length); /* * Ensure that singleton types are actually singletons. @@ -129,26 +215,47 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, result = ISC_R_NOMEMORY; goto free_rdatas; } + + /* Allocate temporary offset table. */ + offsettable = isc_mem_get(mctx, nalloc * sizeof(unsigned int)); + if (offsettable == NULL) { + isc_mem_put(mctx, rawbuf, buflen); + result = ISC_R_NOMEMORY; + goto free_rdatas; + } + memset(offsettable, 0, nalloc * sizeof(unsigned int)); region->base = rawbuf; region->length = buflen; rawbuf += reservelen; + offsetbase = rawbuf; *rawbuf++ = (nitems & 0xff00) >> 8; *rawbuf++ = (nitems & 0x00ff); + + /* Skip load order table. Filled in later. */ + rawbuf += nitems * 4; + for (i = 0; i < nalloc; i++) { - if (rdatas[i].data == NULL) + if (x[i].rdata.data == NULL) continue; - *rawbuf++ = (rdatas[i].length & 0xff00) >> 8; - *rawbuf++ = (rdatas[i].length & 0x00ff); - memcpy(rawbuf, rdatas[i].data, rdatas[i].length); - rawbuf += rdatas[i].length; + offsettable[x[i].order] = rawbuf - offsetbase; + *rawbuf++ = (x[i].rdata.length & 0xff00) >> 8; + *rawbuf++ = (x[i].rdata.length & 0x00ff); + rawbuf += 2; /* filled in later */ + memcpy(rawbuf, x[i].rdata.data, x[i].rdata.length); + rawbuf += x[i].rdata.length; } + + fillin_offsets(offsetbase, offsettable, nalloc); + + isc_mem_put(mctx, offsettable, nalloc * sizeof(unsigned int)); + result = ISC_R_SUCCESS; free_rdatas: - isc_mem_put(mctx, rdatas, nalloc * sizeof(dns_rdata_t)); + isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata)); return (result); } @@ -167,7 +274,7 @@ rdataset_first(dns_rdataset_t *rdataset) { rdataset->private5 = NULL; return (ISC_R_NOMORE); } - raw += 2; + raw += 2 + (4 * count); /* * The privateuint4 field is the number of rdata beyond the cursor * position, so we decrement the total count by one before storing @@ -193,7 +300,7 @@ rdataset_next(dns_rdataset_t *rdataset) { rdataset->privateuint4 = count; raw = rdataset->private5; length = raw[0] * 256 + raw[1]; - raw += length + 2; + raw += length + 4; rdataset->private5 = raw; return (ISC_R_SUCCESS); @@ -207,7 +314,7 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { REQUIRE(raw != NULL); r.length = raw[0] * 256 + raw[1]; - raw += 2; + raw += 4; r.base = raw; dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); } @@ -241,6 +348,9 @@ static dns_rdatasetmethods_t rdataset_methods = { rdataset_clone, rdataset_count, NULL, + NULL, + NULL, + NULL, NULL }; @@ -280,11 +390,12 @@ dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) { current = slab + reservelen; count = *current++ * 256; count += *current++; + current += (4 * count); while (count > 0) { count--; length = *current++ * 256; length += *current++; - current += length; + current += length + 2; } return ((unsigned int)(current - slab)); @@ -306,6 +417,7 @@ rdata_from_slab(unsigned char **current, region.length = *tcurrent++ * 256; region.length += *tcurrent++; + tcurrent += 2; region.base = tcurrent; tcurrent += region.length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); @@ -325,15 +437,22 @@ rdata_in_slab(unsigned char *slab, unsigned int reservelen, unsigned int count, i; unsigned char *current; dns_rdata_t trdata = DNS_RDATA_INIT; + int n; current = slab + reservelen; count = *current++ * 256; count += *current++; + current += (4 * count); + for (i = 0; i < count; i++) { rdata_from_slab(¤t, rdclass, type, &trdata); - if (dns_rdata_compare(&trdata, rdata) == 0) + + n = dns_rdata_compare(&trdata, rdata); + if (n == 0) return (ISC_TRUE); + if (n > 0) /* In DNSSEC order. */ + break; dns_rdata_reset(&trdata); } return (ISC_FALSE); @@ -354,6 +473,11 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, unsigned int oadded = 0; unsigned int nadded = 0; unsigned int nncount = 0; + unsigned int oncount; + unsigned int norder = 0; + unsigned int oorder = 0; + unsigned char *offsetbase; + unsigned int *offsettable; /* * XXX Need parameter to allow "delete rdatasets in nslab" merge, @@ -366,12 +490,16 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, ocurrent = oslab + reservelen; ocount = *ocurrent++ * 256; ocount += *ocurrent++; + ocurrent += (4 * ocount); ostart = ocurrent; ncurrent = nslab + reservelen; ncount = *ncurrent++ * 256; ncount += *ncurrent++; + ncurrent += (4 * ncount); INSIST(ocount > 0 && ncount > 0); + oncount = ncount; + /* * Yes, this is inefficient! */ @@ -383,8 +511,8 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, for (count = 0; count < ocount; count++) { length = *ocurrent++ * 256; length += *ocurrent++; - olength += length + 2; - ocurrent += length; + olength += length + 8; + ocurrent += length + 2; } /* @@ -400,6 +528,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, do { nregion.length = *ncurrent++ * 256; nregion.length += *ncurrent++; + ncurrent += 2; nregion.base = ncurrent; dns_rdata_init(&nrdata); dns_rdata_fromregion(&nrdata, rdclass, type, &nregion); @@ -408,7 +537,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, /* * This rdata isn't in the old slab. */ - tlength += nregion.length + 2; + tlength += nregion.length + 8; tcount++; nncount++; added_something = ISC_TRUE; @@ -436,6 +565,9 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, return (DNS_R_SINGLETON); } + if (tcount > 0xffff) + return (ISC_R_NOSPACE); + /* * Copy the reserved area from the new slab. */ @@ -444,6 +576,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, return (ISC_R_NOMEMORY); memcpy(tstart, nslab, reservelen); tcurrent = tstart + reservelen; + offsetbase = tcurrent; /* * Write the new count. @@ -452,16 +585,35 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, *tcurrent++ = (tcount & 0x00ff); /* + * Skip offset table. + */ + tcurrent += (tcount * 4); + + offsettable = isc_mem_get(mctx, + (ocount + oncount) * sizeof(unsigned int)); + if (offsettable == NULL) { + isc_mem_put(mctx, tstart, tlength); + return (ISC_R_NOMEMORY); + } + memset(offsettable, 0, (ocount + oncount) * sizeof(unsigned int)); + + /* * Merge the two slabs. */ ocurrent = ostart; INSIST(ocount != 0); + oorder = ocurrent[2] * 256 + ocurrent[3]; + INSIST(oorder < ocount); rdata_from_slab(&ocurrent, rdclass, type, &ordata); ncurrent = nslab + reservelen + 2; + ncurrent += (4 * oncount); + if (ncount > 0) { do { dns_rdata_reset(&nrdata); + norder = ncurrent[2] * 256 + ncurrent[3]; + INSIST(norder < oncount); rdata_from_slab(&ncurrent, rdclass, type, &nrdata); } while (rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata)); @@ -476,27 +628,35 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, else fromold = ISC_TF(compare_rdata(&ordata, &nrdata) < 0); if (fromold) { + offsettable[oorder] = tcurrent - offsetbase; length = ordata.length; *tcurrent++ = (length & 0xff00) >> 8; *tcurrent++ = (length & 0x00ff); + tcurrent += 2; /* fill in later */ memcpy(tcurrent, ordata.data, length); tcurrent += length; oadded++; if (oadded < ocount) { dns_rdata_reset(&ordata); + oorder = ocurrent[2] * 256 + ocurrent[3]; + INSIST(oorder < ocount); rdata_from_slab(&ocurrent, rdclass, type, &ordata); } } else { + offsettable[ocount + norder] = tcurrent - offsetbase; length = nrdata.length; *tcurrent++ = (length & 0xff00) >> 8; *tcurrent++ = (length & 0x00ff); + tcurrent += 2; /* fill in later */ memcpy(tcurrent, nrdata.data, length); tcurrent += length; nadded++; if (nadded < ncount) { do { dns_rdata_reset(&nrdata); + norder = ncurrent[2] * 256 + ncurrent[3]; + INSIST(norder < oncount); rdata_from_slab(&ncurrent, rdclass, type, &nrdata); } while (rdata_in_slab(oslab, reservelen, @@ -506,6 +666,11 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, } } + fillin_offsets(offsetbase, offsettable, ocount + oncount); + + isc_mem_put(mctx, offsettable, + (ocount + oncount) * sizeof(unsigned int)); + INSIST(tcurrent == tstart + tlength); *tslabp = tstart; @@ -520,9 +685,12 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, unsigned int flags, unsigned char **tslabp) { unsigned char *mcurrent, *sstart, *scurrent, *tstart, *tcurrent; - unsigned int mcount, scount, rcount ,count, tlength, tcount; + unsigned int mcount, scount, rcount ,count, tlength, tcount, i; dns_rdata_t srdata = DNS_RDATA_INIT; dns_rdata_t mrdata = DNS_RDATA_INIT; + unsigned char *offsetbase; + unsigned int *offsettable; + unsigned int order; REQUIRE(tslabp != NULL && *tslabp == NULL); REQUIRE(mslab != NULL && sslab != NULL); @@ -533,7 +701,6 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, scurrent = sslab + reservelen; scount = *scurrent++ * 256; scount += *scurrent++; - sstart = scurrent; INSIST(mcount > 0 && scount > 0); /* @@ -547,11 +714,15 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, tcount = 0; rcount = 0; + mcurrent += 4 * mcount; + scurrent += 4 * scount; + sstart = scurrent; + /* * Add in the length of rdata in the mslab that aren't in * the sslab. */ - do { + for (i = 0; i < mcount; i++) { unsigned char *mrdatabegin = mcurrent; rdata_from_slab(&mcurrent, rdclass, type, &mrdata); scurrent = sstart; @@ -570,9 +741,10 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, tcount++; } else rcount++; - mcount--; dns_rdata_reset(&mrdata); - } while (mcount > 0); + } + + tlength += (4 * tcount); /* * Check that all the records originally existed. The numeric @@ -601,6 +773,14 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, return (ISC_R_NOMEMORY); memcpy(tstart, mslab, reservelen); tcurrent = tstart + reservelen; + offsetbase = tcurrent; + + offsettable = isc_mem_get(mctx, mcount * sizeof(unsigned int)); + if (offsettable == NULL) { + isc_mem_put(mctx, tstart, tlength); + return (ISC_R_NOMEMORY); + } + memset(offsettable, 0, mcount * sizeof(unsigned int)); /* * Write the new count. @@ -608,14 +788,19 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, *tcurrent++ = (tcount & 0xff00) >> 8; *tcurrent++ = (tcount & 0x00ff); + tcurrent += (4 * tcount); + /* * Copy the parts of mslab not in sslab. */ mcurrent = mslab + reservelen; mcount = *mcurrent++ * 256; mcount += *mcurrent++; - do { + mcurrent += (4 * mcount); + for (i = 0; i < mcount; i++) { unsigned char *mrdatabegin = mcurrent; + order = mcurrent[2] * 256 + mcurrent[3]; + INSIST(order < mcount); rdata_from_slab(&mcurrent, rdclass, type, &mrdata); scurrent = sstart; for (count = 0; count < scount; count++) { @@ -630,12 +815,16 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab, * copied to the tslab. */ unsigned int length = mcurrent - mrdatabegin; + offsettable[order] = tcurrent - offsetbase; memcpy(tcurrent, mrdatabegin, length); tcurrent += length; } dns_rdata_reset(&mrdata); - mcount--; - } while (mcount > 0); + } + + fillin_offsets(offsetbase, offsettable, mcount); + + isc_mem_put(mctx, offsettable, mcount * sizeof(unsigned int)); INSIST(tcurrent == tstart + tlength); @@ -663,6 +852,9 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, if (count1 != count2) return (ISC_FALSE); + current1 += (4 * count1); + current2 += (4 * count2); + while (count1 > 0) { length1 = *current1++ * 256; length1 += *current1++; @@ -670,6 +862,9 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2, length2 = *current2++ * 256; length2 += *current2++; + current1 += 2; + current2 += 2; + if (length1 != length2 || memcmp(current1, current2, length1) != 0) return (ISC_FALSE); @@ -703,6 +898,9 @@ dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2, if (count1 != count2) return (ISC_FALSE); + current1 += (4 * count1); + current2 += (4 * count2); + while (count1-- > 0) { rdata_from_slab(¤t1, rdclass, type, &rdata1); rdata_from_slab(¤t2, rdclass, type, &rdata2); diff --git a/contrib/bind9/lib/dns/request.c b/contrib/bind9/lib/dns/request.c index c325fd4..be8f93d 100644 --- a/contrib/bind9/lib/dns/request.c +++ b/contrib/bind9/lib/dns/request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.c,v 1.64.2.1.10.9 2006/08/21 00:50:48 marka Exp $ */ +/* $Id: request.c,v 1.72.18.5 2006/08/21 00:40:53 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -91,10 +93,10 @@ struct dns_request { #define DNS_REQUEST_F_CONNECTING 0x0001 #define DNS_REQUEST_F_SENDING 0x0002 -#define DNS_REQUEST_F_CANCELED 0x0004 /* ctlevent received, or otherwise +#define DNS_REQUEST_F_CANCELED 0x0004 /*%< ctlevent received, or otherwise synchronously canceled */ -#define DNS_REQUEST_F_TIMEDOUT 0x0008 /* cancelled due to a timeout */ -#define DNS_REQUEST_F_TCP 0x0010 /* This request used TCP */ +#define DNS_REQUEST_F_TIMEDOUT 0x0008 /*%< cancelled due to a timeout */ +#define DNS_REQUEST_F_TCP 0x0010 /*%< This request used TCP */ #define DNS_REQUEST_CANCELED(r) \ (((r)->flags & DNS_REQUEST_F_CANCELED) != 0) #define DNS_REQUEST_CONNECTING(r) \ diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c index a56fecf..7312841 100644 --- a/contrib/bind9/lib/dns/resolver.c +++ b/contrib/bind9/lib/dns/resolver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.218.2.18.4.64.4.2 2007/01/11 05:05:10 marka Exp $ */ +/* $Id: resolver.c,v 1.284.18.57 2007/02/14 23:41:01 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -99,12 +101,12 @@ #define QTRACE(m) #endif -/* +/*% * Maximum EDNS0 input packet size. */ #define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */ -/* +/*% * This defines the maximum number of timeouts we will permit before we * disable EDNS0 on the query. */ @@ -146,13 +148,13 @@ typedef struct query { #define RESQUERY_SENDING(q) ((q)->sends > 0) typedef enum { - fetchstate_init = 0, /* Start event has not run yet. */ + fetchstate_init = 0, /*%< Start event has not run yet. */ fetchstate_active, - fetchstate_done /* FETCHDONE events posted. */ + fetchstate_done /*%< FETCHDONE events posted. */ } fetchstate; struct fetchctx { - /* Not locked. */ + /*% Not locked. */ unsigned int magic; dns_resolver_t * res; dns_name_t name; @@ -160,15 +162,16 @@ struct fetchctx { unsigned int options; unsigned int bucketnum; char * info; - /* Locked by appropriate bucket lock. */ + /*% Locked by appropriate bucket lock. */ fetchstate state; isc_boolean_t want_shutdown; isc_boolean_t cloned; + isc_boolean_t spilled; unsigned int references; isc_event_t control_event; ISC_LINK(struct fetchctx) link; ISC_LIST(dns_fetchevent_t) events; - /* Locked by task event serialization. */ + /*% Locked by task event serialization. */ dns_name_t domain; dns_rdataset_t nameservers; unsigned int attributes; @@ -187,16 +190,18 @@ struct fetchctx { isc_sockaddrlist_t forwarders; dns_fwdpolicy_t fwdpolicy; isc_sockaddrlist_t bad; + isc_sockaddrlist_t edns; + isc_sockaddrlist_t edns512; ISC_LIST(dns_validator_t) validators; dns_db_t * cache; dns_adb_t * adb; - /* + /*% * The number of events we're waiting for. */ unsigned int pending; - /* + /*% * The number of times we've "restarted" the current * nameserver set. This acts as a failsafe to prevent * us from pounding constantly on a particular set of @@ -206,13 +211,13 @@ struct fetchctx { */ unsigned int restarts; - /* + /*% * The number of timeouts that have occurred since we * last successfully received a response packet. This * is used for EDNS0 black hole detection. */ unsigned int timeouts; - /* + /*% * Look aside state for DS lookups. */ dns_name_t nsname; @@ -270,6 +275,7 @@ typedef struct fctxbucket { isc_mutex_t lock; ISC_LIST(fetchctx_t) fctxs; isc_boolean_t exiting; + isc_mem_t * mctx; } fctxbucket_t; typedef struct alternate { @@ -314,12 +320,17 @@ struct dns_resolver { isc_rwlock_t mbslock; #endif dns_rbt_t * mustbesecure; + unsigned int spillatmax; + unsigned int spillatmin; + isc_timer_t * spillattimer; + isc_boolean_t zero_no_soa_ttl; /* Locked by lock. */ unsigned int references; isc_boolean_t exiting; isc_eventlist_t whenshutdown; unsigned int activebuckets; isc_boolean_t priming; + unsigned int spillat; /* Locked by primelock. */ dns_fetch_t * primefetch; /* Locked by nlock. */ @@ -329,7 +340,7 @@ struct dns_resolver { #define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!') #define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC) -/* +/*% * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0, * which we also use as an addrinfo flag. */ @@ -368,7 +379,8 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, dns_valarg_t *valarg; isc_result_t result; - valarg = isc_mem_get(fctx->res->mctx, sizeof(*valarg)); + valarg = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, + sizeof(*valarg)); if (valarg == NULL) return (ISC_R_NOMEMORY); @@ -385,7 +397,8 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, if (result == ISC_R_SUCCESS) ISC_LIST_APPEND(fctx->validators, validator, link); else - isc_mem_put(fctx->res->mctx, valarg, sizeof(*valarg)); + isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx, + valarg, sizeof(*valarg)); return (result); } @@ -571,8 +584,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp, * slow. We don't know. Increase the RTT. */ INSIST(no_response); - rtt = query->addrinfo->srtt + - (200000 * fctx->restarts); + rtt = query->addrinfo->srtt + 200000; if (rtt > 10000000) rtt = 10000000; /* @@ -755,6 +767,9 @@ static inline void fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { dns_fetchevent_t *event, *next_event; isc_task_t *task; + unsigned int count = 0; + isc_interval_t i; + isc_boolean_t logit = ISC_FALSE; /* * Caller must be holding the appropriate bucket lock. @@ -780,6 +795,31 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result) { fctx->type == dns_rdatatype_sig); isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); + count++; + } + + if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 && + fctx->spilled && + (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) { + LOCK(&fctx->res->lock); + if (count == fctx->res->spillat && !fctx->res->exiting) { + fctx->res->spillat += 5; + if (fctx->res->spillat > fctx->res->spillatmax && + fctx->res->spillatmax != 0) + fctx->res->spillat = fctx->res->spillatmax; + isc_interval_set(&i, 20 * 60, 0); + result = isc_timer_reset(fctx->res->spillattimer, + isc_timertype_ticker, NULL, + &i, ISC_TRUE); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + logit = ISC_TRUE; + } + UNLOCK(&fctx->res->lock); + if (logit) + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, + "clients-per-query increased to %u", + count + 1); } } @@ -884,7 +924,8 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) { } static inline isc_result_t -fctx_addopt(dns_message_t *message, dns_resolver_t *res) { +fctx_addopt(dns_message_t *message, unsigned int version, isc_uint16_t udpsize) +{ dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; @@ -910,12 +951,13 @@ fctx_addopt(dns_message_t *message, dns_resolver_t *res) { /* * Set Maximum UDP buffer size. */ - rdatalist->rdclass = res->udpsize; + rdatalist->rdclass = udpsize; /* - * Set EXTENDED-RCODE, VERSION, and Z to 0, and the DO bit to 1. + * Set EXTENDED-RCODE and Z to 0, DO to 1. */ - rdatalist->ttl = DNS_MESSAGEEXTFLAG_DO; + rdatalist->ttl = (version << 16); + rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO; /* * No EDNS options. @@ -936,34 +978,37 @@ fctx_addopt(dns_message_t *message, dns_resolver_t *res) { static inline void fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) { unsigned int seconds; + unsigned int us; /* - * We retry every 2 seconds the first two times through the address + * We retry every .5 seconds the first two times through the address * list, and then we do exponential back-off. */ if (fctx->restarts < 3) - seconds = 2; + us = 500000; else - seconds = (2 << (fctx->restarts - 1)); + us = (500000 << (fctx->restarts - 2)); /* - * Double the round-trip time and convert to seconds. + * Double the round-trip time. */ - rtt /= 500000; + rtt *= 2; /* * Always wait for at least the doubled round-trip time. */ - if (seconds < rtt) - seconds = rtt; + if (us < rtt) + us = rtt; /* - * But don't ever wait for more than 30 seconds. + * But don't ever wait for more than 10 seconds. */ - if (seconds > 30) - seconds = 30; + if (us > 10000000) + us = 10000000; - isc_interval_set(&fctx->interval, seconds, 0); + seconds = us / 1000000; + us -= seconds * 1000000; + isc_interval_set(&fctx->interval, seconds, us * 1000); } static isc_result_t @@ -974,6 +1019,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_task_t *task; isc_result_t result; resquery_t *query; + isc_sockaddr_t addr; + isc_boolean_t have_addr = ISC_FALSE; FCTXTRACE("query"); @@ -989,12 +1036,13 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE); - query = isc_mem_get(res->mctx, sizeof(*query)); + query = isc_mem_get(res->buckets[fctx->bucketnum].mctx, + sizeof(*query)); if (query == NULL) { result = ISC_R_NOMEMORY; goto stop_idle_timer; } - query->mctx = res->mctx; + query->mctx = res->buckets[fctx->bucketnum].mctx; query->options = options; query->attributes = 0; query->sends = 0; @@ -1014,28 +1062,42 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, query->dispatchmgr = res->dispatchmgr; query->dispatch = NULL; query->tcpsocket = NULL; + if (res->view->peers != NULL) { + dns_peer_t *peer = NULL; + isc_netaddr_t dstip; + isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr); + result = dns_peerlist_peerbyaddr(res->view->peers, + &dstip, &peer); + if (result == ISC_R_SUCCESS) { + result = dns_peer_getquerysource(peer, &addr); + if (result == ISC_R_SUCCESS) + have_addr = ISC_TRUE; + } + } + if ((query->options & DNS_FETCHOPT_TCP) != 0) { - isc_sockaddr_t addr; int pf; pf = isc_sockaddr_pf(&addrinfo->sockaddr); - - switch (pf) { - case PF_INET: - result = dns_dispatch_getlocaladdress(res->dispatchv4, - &addr); - break; - case PF_INET6: - result = dns_dispatch_getlocaladdress(res->dispatchv6, - &addr); - break; - default: - result = ISC_R_NOTIMPLEMENTED; - break; + if (!have_addr) { + switch (pf) { + case PF_INET: + result = + dns_dispatch_getlocaladdress(res->dispatchv4, + &addr); + break; + case PF_INET6: + result = + dns_dispatch_getlocaladdress(res->dispatchv6, + &addr); + break; + default: + result = ISC_R_NOTIMPLEMENTED; + break; + } + if (result != ISC_R_SUCCESS) + goto cleanup_query; } - if (result != ISC_R_SUCCESS) - goto cleanup_query; - isc_sockaddr_setport(&addr, 0); result = isc_socket_create(res->socketmgr, pf, @@ -1054,16 +1116,46 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, * A dispatch will be created once the connect succeeds. */ } else { - switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { - case PF_INET: - dns_dispatch_attach(res->dispatchv4, &query->dispatch); - break; - case PF_INET6: - dns_dispatch_attach(res->dispatchv6, &query->dispatch); - break; - default: - result = ISC_R_NOTIMPLEMENTED; - goto cleanup_query; + if (have_addr) { + unsigned int attrs, attrmask; + attrs = DNS_DISPATCHATTR_UDP; + switch (isc_sockaddr_pf(&addr)) { + case AF_INET: + attrs |= DNS_DISPATCHATTR_IPV4; + break; + case AF_INET6: + attrs |= DNS_DISPATCHATTR_IPV6; + break; + default: + result = ISC_R_NOTIMPLEMENTED; + goto cleanup_query; + } + attrmask = DNS_DISPATCHATTR_UDP; + attrmask |= DNS_DISPATCHATTR_TCP; + attrmask |= DNS_DISPATCHATTR_IPV4; + attrmask |= DNS_DISPATCHATTR_IPV6; + result = dns_dispatch_getudp(res->dispatchmgr, + res->socketmgr, + res->taskmgr, &addr, + 4096, 1000, 32768, 16411, + 16433, attrs, attrmask, + &query->dispatch); + if (result != ISC_R_SUCCESS) + goto cleanup_query; + } else { + switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { + case PF_INET: + dns_dispatch_attach(res->dispatchv4, + &query->dispatch); + break; + case PF_INET6: + dns_dispatch_attach(res->dispatchv6, + &query->dispatch); + break; + default: + result = ISC_R_NOTIMPLEMENTED; + goto cleanup_query; + } } /* * We should always have a valid dispatcher here. If we @@ -1115,7 +1207,8 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, cleanup_query: query->magic = 0; - isc_mem_put(res->mctx, query, sizeof(*query)); + isc_mem_put(res->buckets[fctx->bucketnum].mctx, + query, sizeof(*query)); stop_idle_timer: RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS); @@ -1123,6 +1216,66 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, return (result); } +static isc_boolean_t +triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { + isc_sockaddr_t *sa; + + for (sa = ISC_LIST_HEAD(fctx->edns); + sa != NULL; + sa = ISC_LIST_NEXT(sa, link)) { + if (isc_sockaddr_equal(sa, address)) + return (ISC_TRUE); + } + + return (ISC_FALSE); +} + +static void +add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { + isc_sockaddr_t *sa; + + if (triededns(fctx, address)) + return; + + sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, + sizeof(*sa)); + if (sa == NULL) + return; + + *sa = *address; + ISC_LIST_INITANDAPPEND(fctx->edns, sa, link); +} + +static isc_boolean_t +triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { + isc_sockaddr_t *sa; + + for (sa = ISC_LIST_HEAD(fctx->edns512); + sa != NULL; + sa = ISC_LIST_NEXT(sa, link)) { + if (isc_sockaddr_equal(sa, address)) + return (ISC_TRUE); + } + + return (ISC_FALSE); +} + +static void +add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { + isc_sockaddr_t *sa; + + if (triededns512(fctx, address)) + return; + + sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, + sizeof(*sa)); + if (sa == NULL) + return; + + *sa = *address; + ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link); +} + static isc_result_t resquery_send(resquery_t *query) { fetchctx_t *fctx; @@ -1211,7 +1364,9 @@ resquery_send(resquery_t *query) { * Set CD if the client says don't validate or the question is * under a secure entry point. */ - if ((query->options & DNS_FETCHOPT_NOVALIDATE) == 0) { + if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) { + fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; + } else if (res->view->enablevalidation) { result = dns_keytable_issecuredomain(res->view->secroots, &fctx->name, &secure_domain); @@ -1221,8 +1376,7 @@ resquery_send(resquery_t *query) { secure_domain = ISC_TRUE; if (secure_domain) fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; - } else - fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD; + } /* * We don't have to set opcode because it defaults to query. @@ -1271,15 +1425,35 @@ resquery_send(resquery_t *query) { * Use EDNS0, unless the caller doesn't want it, or we know that * the remote server doesn't like it. */ - if (fctx->timeouts >= MAX_EDNS0_TIMEOUTS && + + if ((triededns512(fctx, &query->addrinfo->sockaddr) || + fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { query->options |= DNS_FETCHOPT_NOEDNS0; FCTXTRACE("too many timeouts, disabling EDNS0"); + } else if ((triededns(fctx, &query->addrinfo->sockaddr) || + fctx->timeouts >= MAX_EDNS0_TIMEOUTS) && + (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { + query->options |= DNS_FETCHOPT_EDNS512; + FCTXTRACE("too many timeouts, setting EDNS size to 512"); } if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) { - result = fctx_addopt(fctx->qmessage, res); + unsigned int version = 0; /* Default version. */ + unsigned int flags; + isc_uint16_t udpsize = res->udpsize; + + flags = query->addrinfo->flags; + if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) { + version = flags & DNS_FETCHOPT_EDNSVERSIONMASK; + version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT; + } + if ((query->options & DNS_FETCHOPT_EDNS512) != 0) + udpsize = 512; + else if (peer != NULL) + (void)dns_peer_getudpsize(peer, &udpsize); + result = fctx_addopt(fctx->qmessage, version, udpsize); if (result != ISC_R_SUCCESS) { /* * We couldn't add the OPT, but we'll press on. @@ -1306,6 +1480,12 @@ resquery_send(resquery_t *query) { goto cleanup_message; } + if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) + add_triededns(fctx, &query->addrinfo->sockaddr); + + if ((query->options & DNS_FETCHOPT_EDNS512) != 0) + add_triededns512(fctx, &query->addrinfo->sockaddr); + /* * Clear CD if EDNS is not in use. */ @@ -1680,7 +1860,8 @@ add_bad(fetchctx_t *fctx, isc_sockaddr_t *address, isc_result_t reason) { FCTXTRACE("add_bad"); - sa = isc_mem_get(fctx->res->mctx, sizeof(*sa)); + sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, + sizeof(*sa)); if (sa == NULL) return; *sa = *address; @@ -1795,7 +1976,7 @@ sort_finds(fetchctx_t *fctx) { static void findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, unsigned int options, unsigned int flags, isc_stdtime_t now, - isc_boolean_t *pruned, isc_boolean_t *need_alternate) + isc_boolean_t *need_alternate) { dns_adbaddrinfo_t *ai; dns_adbfind_t *find; @@ -1824,7 +2005,8 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, result = dns_adb_createfind(fctx->adb, res->buckets[fctx->bucketnum].task, fctx_finddone, fctx, name, - &fctx->domain, options, now, NULL, + &fctx->name, fctx->type, + options, now, NULL, res->view->dstport, &find); if (result != ISC_R_SUCCESS) { if (result == DNS_R_ALIAS) { @@ -1887,18 +2069,6 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, (res->dispatchv6 == NULL && find->result_v4 == DNS_R_NXRRSET))) *need_alternate = ISC_TRUE; - /* - * And ADB isn't going to send us any events - * either. This find loses. - */ - if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0) { - /* - * The ADB pruned lame servers for - * this name. Remember that in case - * we get desperate later on. - */ - *pruned = ISC_TRUE; - } dns_adb_destroyfind(&find); } } @@ -1913,7 +2083,7 @@ fctx_getaddresses(fetchctx_t *fctx) { unsigned int stdoptions; isc_sockaddr_t *sa; dns_adbaddrinfo_t *ai; - isc_boolean_t pruned, all_bad; + isc_boolean_t all_bad; dns_rdata_ns_t ns; isc_boolean_t need_alternate = ISC_FALSE; @@ -1929,7 +2099,6 @@ fctx_getaddresses(fetchctx_t *fctx) { } res = fctx->res; - pruned = ISC_FALSE; stdoptions = 0; /* Keep compiler happy. */ /* @@ -2021,7 +2190,6 @@ fctx_getaddresses(fetchctx_t *fctx) { stdoptions |= DNS_ADBFIND_INET6; isc_stdtime_get(&now); - restart: INSIST(ISC_LIST_EMPTY(fctx->finds)); INSIST(ISC_LIST_EMPTY(fctx->altfinds)); @@ -2038,7 +2206,7 @@ fctx_getaddresses(fetchctx_t *fctx) { continue; findname(fctx, &ns.name, 0, stdoptions, 0, now, - &pruned, &need_alternate); + &need_alternate); dns_rdata_reset(&rdata); dns_rdata_freestruct(&ns); } @@ -2058,7 +2226,7 @@ fctx_getaddresses(fetchctx_t *fctx) { if (!a->isaddress) { findname(fctx, &a->_u._n.name, a->_u._n.port, stdoptions, FCTX_ADDRINFO_FORWARDER, - now, &pruned, NULL); + now, NULL); continue; } if (isc_sockaddr_pf(&a->_u.addr) != family) @@ -2101,18 +2269,6 @@ fctx_getaddresses(fetchctx_t *fctx) { * yet. Tell the caller to wait for an answer. */ result = DNS_R_WAIT; - } else if (pruned) { - /* - * Some addresses were removed by lame pruning. - * Turn pruning off and try again. - */ - FCTXTRACE("restarting with returnlame"); - INSIST((stdoptions & DNS_ADBFIND_RETURNLAME) == 0); - stdoptions |= DNS_ADBFIND_RETURNLAME; - pruned = ISC_FALSE; - fctx_cleanupaltfinds(fctx); - fctx_cleanupfinds(fctx); - goto restart; } else { /* * We've lost completely. We don't know any @@ -2427,21 +2583,37 @@ fctx_destroy(fetchctx_t *fctx) { sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->bad, sa, link); - isc_mem_put(res->mctx, sa, sizeof(*sa)); + isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); + } + + for (sa = ISC_LIST_HEAD(fctx->edns); + sa != NULL; + sa = next_sa) { + next_sa = ISC_LIST_NEXT(sa, link); + ISC_LIST_UNLINK(fctx->edns, sa, link); + isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); + } + + for (sa = ISC_LIST_HEAD(fctx->edns512); + sa != NULL; + sa = next_sa) { + next_sa = ISC_LIST_NEXT(sa, link); + ISC_LIST_UNLINK(fctx->edns512, sa, link); + isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); } isc_timer_detach(&fctx->timer); dns_message_destroy(&fctx->rmessage); dns_message_destroy(&fctx->qmessage); if (dns_name_countlabels(&fctx->domain) > 0) - dns_name_free(&fctx->domain, res->mctx); + dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); - dns_name_free(&fctx->name, res->mctx); + dns_name_free(&fctx->name, res->buckets[bucketnum].mctx); dns_db_detach(&fctx->cache); dns_adb_detach(&fctx->adb); - isc_mem_free(res->mctx, fctx->info); - isc_mem_put(res->mctx, fctx, sizeof(*fctx)); + isc_mem_free(res->buckets[bucketnum].mctx, fctx->info); + isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx)); LOCK(&res->nlock); res->nfctx--; @@ -2670,8 +2842,9 @@ fctx_start(isc_task_t *task, isc_event_t *event) { */ static inline isc_result_t -fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_taskaction_t action, - void *arg, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, +fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client, + dns_messageid_t id, isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t *fetch) { isc_task_t *clone; @@ -2687,8 +2860,7 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_taskaction_t action, clone = NULL; isc_task_attach(task, &clone); event = (dns_fetchevent_t *) - isc_event_allocate(fctx->res->mctx, clone, - DNS_EVENT_FETCHDONE, + isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE, action, arg, sizeof(*event)); if (event == NULL) { isc_task_detach(&clone); @@ -2701,6 +2873,8 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_taskaction_t action, event->rdataset = rdataset; event->sigrdataset = sigrdataset; event->fetch = fetch; + event->client = client; + event->id = id; dns_fixedname_init(&event->foundname); /* @@ -2739,21 +2913,21 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, */ REQUIRE(fctxp != NULL && *fctxp == NULL); - fctx = isc_mem_get(res->mctx, sizeof(*fctx)); + fctx = isc_mem_get(res->buckets[bucketnum].mctx, sizeof(*fctx)); if (fctx == NULL) return (ISC_R_NOMEMORY); dns_name_format(name, buf, sizeof(buf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); strcat(buf, "/"); /* checked */ strcat(buf, typebuf); /* checked */ - fctx->info = isc_mem_strdup(res->mctx, buf); + fctx->info = isc_mem_strdup(res->buckets[bucketnum].mctx, buf); if (fctx->info == NULL) { result = ISC_R_NOMEMORY; goto cleanup_fetch; } FCTXTRACE("create"); dns_name_init(&fctx->name, NULL); - result = dns_name_dup(name, res->mctx, &fctx->name); + result = dns_name_dup(name, res->buckets[bucketnum].mctx, &fctx->name); if (result != ISC_R_SUCCESS) goto cleanup_info; dns_name_init(&fctx->domain, NULL); @@ -2780,6 +2954,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, ISC_LIST_INIT(fctx->forwarders); fctx->fwdpolicy = dns_fwdpolicy_none; ISC_LIST_INIT(fctx->bad); + ISC_LIST_INIT(fctx->edns); + ISC_LIST_INIT(fctx->edns512); ISC_LIST_INIT(fctx->validators); fctx->find = NULL; fctx->altfind = NULL; @@ -2787,6 +2963,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, fctx->restarts = 0; fctx->timeouts = 0; fctx->attributes = 0; + fctx->spilled = ISC_FALSE; fctx->nqueries = 0; dns_name_init(&fctx->nsname, NULL); @@ -2829,7 +3006,9 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, NULL); if (result != ISC_R_SUCCESS) goto cleanup_name; - result = dns_name_dup(domain, res->mctx, &fctx->domain); + result = dns_name_dup(domain, + res->buckets[bucketnum].mctx, + &fctx->domain); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&fctx->nameservers); goto cleanup_name; @@ -2838,12 +3017,16 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, /* * We're in forward-only mode. Set the query domain. */ - result = dns_name_dup(domain, res->mctx, &fctx->domain); + result = dns_name_dup(domain, + res->buckets[bucketnum].mctx, + &fctx->domain); if (result != ISC_R_SUCCESS) goto cleanup_name; } } else { - result = dns_name_dup(domain, res->mctx, &fctx->domain); + result = dns_name_dup(domain, + res->buckets[bucketnum].mctx, + &fctx->domain); if (result != ISC_R_SUCCESS) goto cleanup_name; dns_rdataset_clone(nameservers, &fctx->nameservers); @@ -2852,14 +3035,16 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain)); fctx->qmessage = NULL; - result = dns_message_create(res->mctx, DNS_MESSAGE_INTENTRENDER, + result = dns_message_create(res->buckets[bucketnum].mctx, + DNS_MESSAGE_INTENTRENDER, &fctx->qmessage); if (result != ISC_R_SUCCESS) goto cleanup_domain; fctx->rmessage = NULL; - result = dns_message_create(res->mctx, DNS_MESSAGE_INTENTPARSE, + result = dns_message_create(res->buckets[bucketnum].mctx, + DNS_MESSAGE_INTENTPARSE, &fctx->rmessage); if (result != ISC_R_SUCCESS) @@ -2932,18 +3117,18 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, cleanup_domain: if (dns_name_countlabels(&fctx->domain) > 0) - dns_name_free(&fctx->domain, res->mctx); + dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); cleanup_name: - dns_name_free(&fctx->name, res->mctx); + dns_name_free(&fctx->name, res->buckets[bucketnum].mctx); cleanup_info: - isc_mem_free(res->mctx, fctx->info); + isc_mem_free(res->buckets[bucketnum].mctx, fctx->info); cleanup_fetch: - isc_mem_put(res->mctx, fctx, sizeof(*fctx)); + isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx)); return (result); } @@ -3180,7 +3365,8 @@ validated(isc_task_t *task, isc_event_t *event) { * destroy the fctx if necessary. */ dns_validator_destroy(&vevent->validator); - isc_mem_put(fctx->res->mctx, valarg, sizeof(*valarg)); + isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx, + valarg, sizeof(*valarg)); negative = ISC_TF(vevent->rdataset == NULL); @@ -3290,7 +3476,8 @@ validated(isc_task_t *task, isc_event_t *event) { */ ttl = fctx->res->view->maxncachettl; if (fctx->type == dns_rdatatype_soa && - covers == dns_rdatatype_any) + covers == dns_rdatatype_any && + fctx->res->zero_no_soa_ttl) ttl = 0; result = ncache_adderesult(fctx->rmessage, fctx->cache, node, @@ -3471,14 +3658,16 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, /* * Is DNSSEC validation required for this name? */ - result = dns_keytable_issecuredomain(res->view->secroots, name, - &secure_domain); - if (result != ISC_R_SUCCESS) - return (result); + if (res->view->enablevalidation) { + result = dns_keytable_issecuredomain(res->view->secroots, name, + &secure_domain); + if (result != ISC_R_SUCCESS) + return (result); - if (!secure_domain && res->view->dlv != NULL) { - valoptions = DNS_VALIDATOR_DLV; - secure_domain = ISC_TRUE; + if (!secure_domain && res->view->dlv != NULL) { + valoptions = DNS_VALIDATOR_DLV; + secure_domain = ISC_TRUE; + } } if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) @@ -3899,14 +4088,16 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, /* * Is DNSSEC validation required for this name? */ - result = dns_keytable_issecuredomain(res->view->secroots, name, - &secure_domain); - if (result != ISC_R_SUCCESS) - return (result); + if (fctx->res->view->enablevalidation) { + result = dns_keytable_issecuredomain(res->view->secroots, name, + &secure_domain); + if (result != ISC_R_SUCCESS) + return (result); - if (!secure_domain && res->view->dlv != NULL) { - valoptions = DNS_VALIDATOR_DLV; - secure_domain = ISC_TRUE; + if (!secure_domain && res->view->dlv != NULL) { + valoptions = DNS_VALIDATOR_DLV; + secure_domain = ISC_TRUE; + } } if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0) @@ -4211,7 +4402,7 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, dns_message_t *message; dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name; dns_rdataset_t *rdataset, *ns_rdataset; - isc_boolean_t done, aa, negative_response; + isc_boolean_t aa, negative_response; dns_rdatatype_t type; dns_section_t section = bind8_ns_resp ? DNS_SECTION_ANSWER : DNS_SECTION_AUTHORITY; @@ -4270,13 +4461,12 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, /* * Process the authority section. */ - done = ISC_FALSE; ns_name = NULL; ns_rdataset = NULL; soa_name = NULL; ds_name = NULL; result = dns_message_firstname(message, section); - while (!done && result == ISC_R_SUCCESS) { + while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, section, &name); if (dns_name_issubdomain(name, &fctx->domain)) { @@ -4338,15 +4528,29 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, dns_trust_additional; } } - /* - * A negative response has a SOA record (Type 2) - * and a optional NS RRset (Type 1) or it has neither - * a SOA or a NS RRset (Type 3, handled above) or - * rcode is NXDOMAIN (handled above) in which case - * the NS RRset is allowed (Type 4). - */ - if (soa_name != NULL) - negative_response = ISC_TRUE; + } + result = dns_message_nextname(message, section); + if (result == ISC_R_NOMORE) + break; + else if (result != ISC_R_SUCCESS) + return (result); + } + + /* + * A negative response has a SOA record (Type 2) + * and a optional NS RRset (Type 1) or it has neither + * a SOA or a NS RRset (Type 3, handled above) or + * rcode is NXDOMAIN (handled above) in which case + * the NS RRset is allowed (Type 4). + */ + if (soa_name != NULL) + negative_response = ISC_TRUE; + + result = dns_message_firstname(message, section); + while (result == ISC_R_SUCCESS) { + name = NULL; + dns_message_currentname(message, section, &name); + if (dns_name_issubdomain(name, &fctx->domain)) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { @@ -4501,11 +4705,14 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, * if so we should bail out. */ INSIST(dns_name_countlabels(&fctx->domain) > 0); - dns_name_free(&fctx->domain, fctx->res->mctx); + dns_name_free(&fctx->domain, + fctx->res->buckets[fctx->bucketnum].mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(ns_name, fctx->res->mctx, &fctx->domain); + result = dns_name_dup(ns_name, + fctx->res->buckets[fctx->bucketnum].mctx, + &fctx->domain); if (result != ISC_R_SUCCESS) return (result); fctx->attributes |= FCTX_ATTR_WANTCACHE; @@ -4960,9 +5167,11 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_rdataset_clone(fevent->rdataset, &fctx->nameservers); - dns_name_free(&fctx->domain, fctx->res->mctx); + dns_name_free(&fctx->domain, + fctx->res->buckets[bucketnum].mctx); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(&fctx->nsname, fctx->res->mctx, + result = dns_name_dup(&fctx->nsname, + fctx->res->buckets[bucketnum].mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL); @@ -5386,6 +5595,28 @@ resquery_response(isc_task_t *task, isc_event_t *event) { * for this fetch. */ result = DNS_R_YXDOMAIN; + } else if (message->rcode == dns_rcode_badvers) { + dns_rdataset_t *opt; + unsigned int flags, mask; + unsigned int version; + + resend = ISC_TRUE; + opt = dns_message_getopt(message); + version = (opt->ttl >> 16) & 0xff; + flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) | + DNS_FETCHOPT_EDNSVERSIONSET; + mask = DNS_FETCHOPT_EDNSVERSIONMASK | + DNS_FETCHOPT_EDNSVERSIONSET; + switch (version) { + case 0: + dns_adb_changeflags(fctx->adb, query->addrinfo, + flags, mask); + break; + default: + broken_server = DNS_R_BADVERS; + keep_trying = ISC_TRUE; + break; + } } else { /* * XXXRTH log. @@ -5415,7 +5646,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { is_lame(fctx)) { log_lame(fctx, query->addrinfo); result = dns_adb_marklame(fctx->adb, query->addrinfo, - &fctx->domain, + &fctx->name, fctx->type, now + fctx->res->lame_ttl); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, @@ -5637,9 +5868,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) { fctx_done(fctx, DNS_R_SERVFAIL); return; } - dns_name_free(&fctx->domain, fctx->res->mctx); + dns_name_free(&fctx->domain, + fctx->res->buckets[fctx->bucketnum].mctx); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(fname, fctx->res->mctx, + result = dns_name_dup(fname, + fctx->res->buckets[fctx->bucketnum].mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL); @@ -5737,6 +5970,7 @@ destroy(dns_resolver_t *res) { isc_task_shutdown(res->buckets[i].task); isc_task_detach(&res->buckets[i].task); DESTROYLOCK(&res->buckets[i].lock); + isc_mem_detach(&res->buckets[i].mctx); } isc_mem_put(res->mctx, res->buckets, res->nbuckets * sizeof(fctxbucket_t)); @@ -5758,6 +5992,7 @@ destroy(dns_resolver_t *res) { #if USE_MBSLOCK isc_rwlock_destroy(&res->mbslock); #endif + isc_timer_detach(&res->spillattimer); res->magic = 0; isc_mem_put(res->mctx, res, sizeof(*res)); } @@ -5796,11 +6031,44 @@ empty_bucket(dns_resolver_t *res) { UNLOCK(&res->lock); } +static void +spillattimer_countdown(isc_task_t *task, isc_event_t *event) { + dns_resolver_t *res = event->ev_arg; + isc_result_t result; + unsigned int count; + isc_boolean_t logit = ISC_FALSE; + + REQUIRE(VALID_RESOLVER(res)); + + UNUSED(task); + + LOCK(&res->lock); + INSIST(!res->exiting); + if (res->spillat > res->spillatmin) { + res->spillat--; + logit = ISC_TRUE; + } + if (res->spillat <= res->spillatmin) { + result = isc_timer_reset(res->spillattimer, + isc_timertype_inactive, NULL, + NULL, ISC_TRUE); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + } + count = res->spillat; + UNLOCK(&res->lock); + if (logit) + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, + "clients-per-query decreased to %u", count); + + isc_event_free(&event); +} + isc_result_t dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr, unsigned int ntasks, isc_socketmgr_t *socketmgr, - isc_timermgr_t *timermgr, + isc_timermgr_t *timermgr, unsigned int options, dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4, @@ -5810,6 +6078,7 @@ dns_resolver_create(dns_view_t *view, dns_resolver_t *res; isc_result_t result = ISC_R_SUCCESS; unsigned int i, buckets_created = 0; + isc_task_t *task = NULL; char name[16]; /* @@ -5839,6 +6108,10 @@ dns_resolver_create(dns_view_t *view, res->udpsize = RECV_BUFFER_SIZE; res->algorithms = NULL; res->mustbesecure = NULL; + res->spillatmin = res->spillat = 10; + res->spillatmax = 100; + res->spillattimer = NULL; + res->zero_no_soa_ttl = ISC_FALSE; res->nbuckets = ntasks; res->activebuckets = ntasks; @@ -5858,6 +6131,13 @@ dns_resolver_create(dns_view_t *view, DESTROYLOCK(&res->buckets[i].lock); goto cleanup_buckets; } + res->buckets[i].mctx = NULL; + result = isc_mem_create(0, 0, &res->buckets[i].mctx); + if (result != ISC_R_SUCCESS) { + isc_task_detach(&res->buckets[i].task); + DESTROYLOCK(&res->buckets[i].lock); + goto cleanup_buckets; + } snprintf(name, sizeof(name), "res%u", i); isc_task_setname(res->buckets[i].task, name, res); ISC_LIST_INIT(res->buckets[i].fctxs); @@ -5892,10 +6172,22 @@ dns_resolver_create(dns_view_t *view, if (result != ISC_R_SUCCESS) goto cleanup_nlock; + task = NULL; + result = isc_task_create(taskmgr, 0, &task); + if (result != ISC_R_SUCCESS) + goto cleanup_primelock; + + result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL, + task, spillattimer_countdown, res, + &res->spillattimer); + isc_task_detach(&task); + if (result != ISC_R_SUCCESS) + goto cleanup_primelock; + #if USE_ALGLOCK result = isc_rwlock_init(&res->alglock, 0, 0); if (result != ISC_R_SUCCESS) - goto cleanup_primelock; + goto cleanup_spillattimer; #endif #if USE_MBSLOCK result = isc_rwlock_init(&res->mbslock, 0, 0); @@ -5916,9 +6208,12 @@ dns_resolver_create(dns_view_t *view, #endif #endif #if USE_ALGLOCK || USE_MBSLOCK + cleanup_spillattimer: + isc_timer_detach(&res->spillattimer); +#endif + cleanup_primelock: DESTROYLOCK(&res->primelock); -#endif cleanup_nlock: DESTROYLOCK(&res->nlock); @@ -5934,6 +6229,7 @@ dns_resolver_create(dns_view_t *view, cleanup_buckets: for (i = 0; i < buckets_created; i++) { + isc_mem_detach(&res->buckets[i].mctx); DESTROYLOCK(&res->buckets[i].lock); isc_task_shutdown(res->buckets[i].task); isc_task_detach(&res->buckets[i].task); @@ -5952,6 +6248,7 @@ prime_done(isc_task_t *task, isc_event_t *event) { dns_resolver_t *res; dns_fetchevent_t *fevent; dns_fetch_t *fetch; + dns_db_t *db = NULL; REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); fevent = (dns_fetchevent_t *)event; @@ -5970,6 +6267,13 @@ prime_done(isc_task_t *task, isc_event_t *event) { UNLOCK(&res->primelock); UNLOCK(&res->lock); + + if (fevent->result == ISC_R_SUCCESS && + res->view->cache != NULL && res->view->hints != NULL) { + dns_cache_attachdb(res->view->cache, &db); + dns_root_checkhints(res->view, res->view->hints, db); + dns_db_detach(&db); + } if (fevent->node != NULL) dns_db_detachnode(fevent->db, &fevent->node); @@ -6111,6 +6415,7 @@ dns_resolver_shutdown(dns_resolver_t *res) { unsigned int i; fetchctx_t *fctx; isc_socket_t *sock; + isc_result_t result; REQUIRE(VALID_RESOLVER(res)); @@ -6147,6 +6452,10 @@ dns_resolver_shutdown(dns_resolver_t *res) { } if (res->activebuckets == 0) send_shutdown_events(res); + result = isc_timer_reset(res->spillattimer, + isc_timertype_inactive, NULL, + NULL, ISC_TRUE); + RUNTIME_CHECK(result == ISC_R_SUCCESS); } UNLOCK(&res->lock); @@ -6217,12 +6526,32 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { + return (dns_resolver_createfetch2(res, name, type, domain, + nameservers, forwarders, NULL, 0, + options, task, action, arg, + rdataset, sigrdataset, fetchp)); +} + +isc_result_t +dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t *domain, dns_rdataset_t *nameservers, + dns_forwarders_t *forwarders, + isc_sockaddr_t *client, dns_messageid_t id, + unsigned int options, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + dns_fetch_t **fetchp) +{ dns_fetch_t *fetch; fetchctx_t *fctx = NULL; - isc_result_t result; + isc_result_t result = ISC_R_SUCCESS; unsigned int bucketnum; isc_boolean_t new_fctx = ISC_FALSE; isc_event_t *event; + unsigned int count = 0; + unsigned int spillat; UNUSED(forwarders); @@ -6249,8 +6578,11 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, if (fetch == NULL) return (ISC_R_NOMEMORY); - bucketnum = dns_name_hash(name, ISC_FALSE) % res->nbuckets; + bucketnum = dns_name_fullhash(name, ISC_FALSE) % res->nbuckets; + LOCK(&res->lock); + spillat = res->spillat; + UNLOCK(&res->lock); LOCK(&res->buckets[bucketnum].lock); if (res->buckets[bucketnum].exiting) { @@ -6266,6 +6598,31 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, break; } } + + /* + * Is this a duplicate? + */ + if (fctx != NULL && client != NULL) { + dns_fetchevent_t *fevent; + for (fevent = ISC_LIST_HEAD(fctx->events); + fevent != NULL; + fevent = ISC_LIST_NEXT(fevent, ev_link)) { + if (fevent->client != NULL && fevent->id == id && + isc_sockaddr_equal(fevent->client, client)) { + result = DNS_R_DUPLICATE; + goto unlock; + } + count++; + } + } + if (count >= res->spillatmin && res->spillatmin != 0) { + if (count >= spillat) + fctx->spilled = ISC_TRUE; + if (fctx->spilled) { + result = DNS_R_DROP; + goto unlock; + } + } /* * If we didn't have a fetch, would attach to a done fetch, this @@ -6285,7 +6642,7 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, new_fctx = ISC_TRUE; } - result = fctx_join(fctx, task, action, arg, + result = fctx_join(fctx, task, client, id, action, arg, rdataset, sigrdataset, fetch); if (new_fctx) { if (result == ISC_R_SUCCESS) { @@ -6641,6 +6998,13 @@ dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name, return (dst_algorithm_supported(alg)); } +isc_boolean_t +dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest) { + + UNUSED(resolver); + return (dns_ds_digest_supported(digest)); +} + void dns_resolver_resetmustbesecure(dns_resolver_t *resolver) { @@ -6706,3 +7070,45 @@ dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) { #endif return (value); } + +void +dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur, + isc_uint32_t *min, isc_uint32_t *max) +{ + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (cur != NULL) + *cur = resolver->spillat; + if (min != NULL) + *min = resolver->spillatmin; + if (max != NULL) + *max = resolver->spillatmax; + UNLOCK(&resolver->lock); +} + +void +dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min, + isc_uint32_t max) +{ + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + resolver->spillatmin = resolver->spillat = min; + resolver->spillatmax = max; + UNLOCK(&resolver->lock); +} + +isc_boolean_t +dns_resolver_getzeronosoattl(dns_resolver_t *resolver) { + REQUIRE(VALID_RESOLVER(resolver)); + + return (resolver->zero_no_soa_ttl); +} + +void +dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) { + REQUIRE(VALID_RESOLVER(resolver)); + + resolver->zero_no_soa_ttl = state; +} diff --git a/contrib/bind9/lib/dns/result.c b/contrib/bind9/lib/dns/result.c index eb8308a..fdb58e0 100644 --- a/contrib/bind9/lib/dns/result.c +++ b/contrib/bind9/lib/dns/result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.c,v 1.90.2.9.2.13 2004/05/14 05:06:39 marka Exp $ */ +/* $Id: result.c,v 1.115.10.7 2005/06/17 02:04:31 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -26,155 +28,157 @@ #include <dns/lib.h> static const char *text[DNS_R_NRESULTS] = { - "label too long", /* 0 DNS_R_LABELTOOLONG */ - "bad escape", /* 1 DNS_R_BADESCAPE */ - /* + "label too long", /*%< 0 DNS_R_LABELTOOLONG */ + "bad escape", /*%< 1 DNS_R_BADESCAPE */ + /*! * Note that DNS_R_BADBITSTRING and DNS_R_BITSTRINGTOOLONG are * deprecated. */ - "bad bitstring", /* 2 DNS_R_BADBITSTRING */ - "bitstring too long", /* 3 DNS_R_BITSTRINGTOOLONG */ - "empty label", /* 4 DNS_R_EMPTYLABEL */ - - "bad dotted quad", /* 5 DNS_R_BADDOTTEDQUAD */ - "invalid NS owner name (wildcard)", /* 6 DNS_R_INVALIDNS */ - "unknown class/type", /* 7 DNS_R_UNKNOWN */ - "bad label type", /* 8 DNS_R_BADLABELTYPE */ - "bad compression pointer", /* 9 DNS_R_BADPOINTER */ - - "too many hops", /* 10 DNS_R_TOOMANYHOPS */ - "disallowed (by application policy)", /* 11 DNS_R_DISALLOWED */ - "extra input text", /* 12 DNS_R_EXTRATOKEN */ - "extra input data", /* 13 DNS_R_EXTRADATA */ - "text too long", /* 14 DNS_R_TEXTTOOLONG */ - - "not at top of zone", /* 15 DNS_R_NOTZONETOP */ - "syntax error", /* 16 DNS_R_SYNTAX */ - "bad checksum", /* 17 DNS_R_BADCKSUM */ - "bad IPv6 address", /* 18 DNS_R_BADAAAA */ - "no owner", /* 19 DNS_R_NOOWNER */ - - "no ttl", /* 20 DNS_R_NOTTL */ - "bad class", /* 21 DNS_R_BADCLASS */ - "name too long", /* 22 DNS_R_NAMETOOLONG */ - "partial match", /* 23 DNS_R_PARTIALMATCH */ - "new origin", /* 24 DNS_R_NEWORIGIN */ - - "unchanged", /* 25 DNS_R_UNCHANGED */ - "bad ttl", /* 26 DNS_R_BADTTL */ - "more data needed/to be rendered", /* 27 DNS_R_NOREDATA */ - "continue", /* 28 DNS_R_CONTINUE */ - "delegation", /* 29 DNS_R_DELEGATION */ - - "glue", /* 30 DNS_R_GLUE */ - "dname", /* 31 DNS_R_DNAME */ - "cname", /* 32 DNS_R_CNAME */ - "bad database", /* 33 DNS_R_BADDB */ - "zonecut", /* 34 DNS_R_ZONECUT */ - - "bad zone", /* 35 DNS_R_BADZONE */ - "more data", /* 36 DNS_R_MOREDATA */ - "up to date", /* 37 DNS_R_UPTODATE */ - "tsig verify failure", /* 38 DNS_R_TSIGVERIFYFAILURE */ - "tsig indicates error", /* 39 DNS_R_TSIGERRORSET */ - - "RRSIG failed to verify", /* 40 DNS_R_SIGINVALID */ - "RRSIG has expired", /* 41 DNS_R_SIGEXPIRED */ - "RRSIG validity period has not begun", /* 42 DNS_R_SIGFUTURE */ - "key is unauthorized to sign data", /* 43 DNS_R_KEYUNAUTHORIZED */ - "invalid time", /* 44 DNS_R_INVALIDTIME */ - - "expected a TSIG or SIG(0)", /* 45 DNS_R_EXPECTEDTSIG */ - "did not expect a TSIG or SIG(0)", /* 46 DNS_R_UNEXPECTEDTSIG */ - "TKEY is unacceptable", /* 47 DNS_R_INVALIDTKEY */ - "hint", /* 48 DNS_R_HINT */ - "drop", /* 49 DNS_R_DROP */ - - "zone not loaded", /* 50 DNS_R_NOTLOADED */ - "ncache nxdomain", /* 51 DNS_R_NCACHENXDOMAIN */ - "ncache nxrrset", /* 52 DNS_R_NCACHENXRRSET */ - "wait", /* 53 DNS_R_WAIT */ - "not verified yet", /* 54 DNS_R_NOTVERIFIEDYET */ - - "no identity", /* 55 DNS_R_NOIDENTITY */ - "no journal", /* 56 DNS_R_NOJOURNAL */ - "alias", /* 57 DNS_R_ALIAS */ - "use TCP", /* 58 DNS_R_USETCP */ - "no valid RRSIG", /* 59 DNS_R_NOVALIDSIG */ - - "no valid NSEC", /* 60 DNS_R_NOVALIDNSEC */ - "not insecure", /* 61 DNS_R_NOTINSECURE */ - "unknown service", /* 62 DNS_R_UNKNOWNSERVICE */ - "recoverable error occurred", /* 63 DNS_R_RECOVERABLE */ - "unknown opt attribute record", /* 64 DNS_R_UNKNOWNOPT */ - - "unexpected message id", /* 65 DNS_R_UNEXPECTEDID */ - "seen include file", /* 66 DNS_R_SEENINCLUDE */ - "not exact", /* 67 DNS_R_NOTEXACT */ - "address blackholed", /* 68 DNS_R_BLACKHOLED */ - "bad algorithm", /* 69 DNS_R_BADALG */ - - "invalid use of a meta type", /* 70 DNS_R_METATYPE */ - "CNAME and other data", /* 71 DNS_R_CNAMEANDOTHER */ - "multiple RRs of singleton type", /* 72 DNS_R_SINGLETON */ - "hint nxrrset", /* 73 DNS_R_HINTNXRRSET */ - "no master file configured", /* 74 DNS_R_NOMASTERFILE */ - - "unknown protocol", /* 75 DNS_R_UNKNOWNPROTO */ - "clocks are unsynchronized", /* 76 DNS_R_CLOCKSKEW */ - "IXFR failed", /* 77 DNS_R_BADIXFR */ - "not authoritative", /* 78 DNS_R_NOTAUTHORITATIVE */ - "no valid KEY", /* 79 DNS_R_NOVALIDKEY */ - - "obsolete", /* 80 DNS_R_OBSOLETE */ - "already frozen", /* 81 DNS_R_FROZEN */ - "unknown flag", /* 82 DNS_R_UNKNOWNFLAG */ - "expected a response", /* 83 DNS_R_EXPECTEDRESPONSE */ - "no valid DS", /* 84 DNS_R_NOVALIDDS */ - - "NS is an address", /* 85 DNS_R_NSISADDRESS */ - "received FORMERR", /* 86 DNS_R_REMOTEFORMERR */ - "truncated TCP response", /* 87 DNS_R_TRUNCATEDTCP */ - "lame server detected", /* 88 DNS_R_LAME */ - "unexpected RCODE", /* 89 DNS_R_UNEXPECTEDRCODE */ - - "unexpected OPCODE", /* 90 DNS_R_UNEXPECTEDOPCODE */ - "chase DS servers", /* 91 DNS_R_CHASEDSSERVERS */ - "empty name", /* 92 DNS_R_EMPTYNAME */ - "empty wild", /* 93 DNS_R_EMPTYWILD */ - "bad bitmap", /* 94 DNS_R_BADBITMAP */ - - "from wildcard", /* 95 DNS_R_FROMWILDCARD */ - "bad owner name (check-names)", /* 96 DNS_R_BADOWNERNAME */ - "bad name (check-names)", /* 97 DNS_R_BADNAME */ - "dynamic zone", /* 98 DNS_R_DYNAMIC */ - "unknown command", /* 99 DNS_R_UNKNOWNCOMMAND */ - - "must-be-secure", /* 100 DNS_R_MUSTBESECURE */ - "covering NSEC record returned" /* 101 DNS_R_COVERINGNSEC */ + "bad bitstring", /*%< 2 DNS_R_BADBITSTRING */ + "bitstring too long", /*%< 3 DNS_R_BITSTRINGTOOLONG */ + "empty label", /*%< 4 DNS_R_EMPTYLABEL */ + + "bad dotted quad", /*%< 5 DNS_R_BADDOTTEDQUAD */ + "invalid NS owner name (wildcard)", /*%< 6 DNS_R_INVALIDNS */ + "unknown class/type", /*%< 7 DNS_R_UNKNOWN */ + "bad label type", /*%< 8 DNS_R_BADLABELTYPE */ + "bad compression pointer", /*%< 9 DNS_R_BADPOINTER */ + + "too many hops", /*%< 10 DNS_R_TOOMANYHOPS */ + "disallowed (by application policy)", /*%< 11 DNS_R_DISALLOWED */ + "extra input text", /*%< 12 DNS_R_EXTRATOKEN */ + "extra input data", /*%< 13 DNS_R_EXTRADATA */ + "text too long", /*%< 14 DNS_R_TEXTTOOLONG */ + + "not at top of zone", /*%< 15 DNS_R_NOTZONETOP */ + "syntax error", /*%< 16 DNS_R_SYNTAX */ + "bad checksum", /*%< 17 DNS_R_BADCKSUM */ + "bad IPv6 address", /*%< 18 DNS_R_BADAAAA */ + "no owner", /*%< 19 DNS_R_NOOWNER */ + + "no ttl", /*%< 20 DNS_R_NOTTL */ + "bad class", /*%< 21 DNS_R_BADCLASS */ + "name too long", /*%< 22 DNS_R_NAMETOOLONG */ + "partial match", /*%< 23 DNS_R_PARTIALMATCH */ + "new origin", /*%< 24 DNS_R_NEWORIGIN */ + + "unchanged", /*%< 25 DNS_R_UNCHANGED */ + "bad ttl", /*%< 26 DNS_R_BADTTL */ + "more data needed/to be rendered", /*%< 27 DNS_R_NOREDATA */ + "continue", /*%< 28 DNS_R_CONTINUE */ + "delegation", /*%< 29 DNS_R_DELEGATION */ + + "glue", /*%< 30 DNS_R_GLUE */ + "dname", /*%< 31 DNS_R_DNAME */ + "cname", /*%< 32 DNS_R_CNAME */ + "bad database", /*%< 33 DNS_R_BADDB */ + "zonecut", /*%< 34 DNS_R_ZONECUT */ + + "bad zone", /*%< 35 DNS_R_BADZONE */ + "more data", /*%< 36 DNS_R_MOREDATA */ + "up to date", /*%< 37 DNS_R_UPTODATE */ + "tsig verify failure", /*%< 38 DNS_R_TSIGVERIFYFAILURE */ + "tsig indicates error", /*%< 39 DNS_R_TSIGERRORSET */ + + "RRSIG failed to verify", /*%< 40 DNS_R_SIGINVALID */ + "RRSIG has expired", /*%< 41 DNS_R_SIGEXPIRED */ + "RRSIG validity period has not begun", /*%< 42 DNS_R_SIGFUTURE */ + "key is unauthorized to sign data", /*%< 43 DNS_R_KEYUNAUTHORIZED */ + "invalid time", /*%< 44 DNS_R_INVALIDTIME */ + + "expected a TSIG or SIG(0)", /*%< 45 DNS_R_EXPECTEDTSIG */ + "did not expect a TSIG or SIG(0)", /*%< 46 DNS_R_UNEXPECTEDTSIG */ + "TKEY is unacceptable", /*%< 47 DNS_R_INVALIDTKEY */ + "hint", /*%< 48 DNS_R_HINT */ + "drop", /*%< 49 DNS_R_DROP */ + + "zone not loaded", /*%< 50 DNS_R_NOTLOADED */ + "ncache nxdomain", /*%< 51 DNS_R_NCACHENXDOMAIN */ + "ncache nxrrset", /*%< 52 DNS_R_NCACHENXRRSET */ + "wait", /*%< 53 DNS_R_WAIT */ + "not verified yet", /*%< 54 DNS_R_NOTVERIFIEDYET */ + + "no identity", /*%< 55 DNS_R_NOIDENTITY */ + "no journal", /*%< 56 DNS_R_NOJOURNAL */ + "alias", /*%< 57 DNS_R_ALIAS */ + "use TCP", /*%< 58 DNS_R_USETCP */ + "no valid RRSIG", /*%< 59 DNS_R_NOVALIDSIG */ + + "no valid NSEC", /*%< 60 DNS_R_NOVALIDNSEC */ + "not insecure", /*%< 61 DNS_R_NOTINSECURE */ + "unknown service", /*%< 62 DNS_R_UNKNOWNSERVICE */ + "recoverable error occurred", /*%< 63 DNS_R_RECOVERABLE */ + "unknown opt attribute record", /*%< 64 DNS_R_UNKNOWNOPT */ + + "unexpected message id", /*%< 65 DNS_R_UNEXPECTEDID */ + "seen include file", /*%< 66 DNS_R_SEENINCLUDE */ + "not exact", /*%< 67 DNS_R_NOTEXACT */ + "address blackholed", /*%< 68 DNS_R_BLACKHOLED */ + "bad algorithm", /*%< 69 DNS_R_BADALG */ + + "invalid use of a meta type", /*%< 70 DNS_R_METATYPE */ + "CNAME and other data", /*%< 71 DNS_R_CNAMEANDOTHER */ + "multiple RRs of singleton type", /*%< 72 DNS_R_SINGLETON */ + "hint nxrrset", /*%< 73 DNS_R_HINTNXRRSET */ + "no master file configured", /*%< 74 DNS_R_NOMASTERFILE */ + + "unknown protocol", /*%< 75 DNS_R_UNKNOWNPROTO */ + "clocks are unsynchronized", /*%< 76 DNS_R_CLOCKSKEW */ + "IXFR failed", /*%< 77 DNS_R_BADIXFR */ + "not authoritative", /*%< 78 DNS_R_NOTAUTHORITATIVE */ + "no valid KEY", /*%< 79 DNS_R_NOVALIDKEY */ + + "obsolete", /*%< 80 DNS_R_OBSOLETE */ + "already frozen", /*%< 81 DNS_R_FROZEN */ + "unknown flag", /*%< 82 DNS_R_UNKNOWNFLAG */ + "expected a response", /*%< 83 DNS_R_EXPECTEDRESPONSE */ + "no valid DS", /*%< 84 DNS_R_NOVALIDDS */ + + "NS is an address", /*%< 85 DNS_R_NSISADDRESS */ + "received FORMERR", /*%< 86 DNS_R_REMOTEFORMERR */ + "truncated TCP response", /*%< 87 DNS_R_TRUNCATEDTCP */ + "lame server detected", /*%< 88 DNS_R_LAME */ + "unexpected RCODE", /*%< 89 DNS_R_UNEXPECTEDRCODE */ + + "unexpected OPCODE", /*%< 90 DNS_R_UNEXPECTEDOPCODE */ + "chase DS servers", /*%< 91 DNS_R_CHASEDSSERVERS */ + "empty name", /*%< 92 DNS_R_EMPTYNAME */ + "empty wild", /*%< 93 DNS_R_EMPTYWILD */ + "bad bitmap", /*%< 94 DNS_R_BADBITMAP */ + + "from wildcard", /*%< 95 DNS_R_FROMWILDCARD */ + "bad owner name (check-names)", /*%< 96 DNS_R_BADOWNERNAME */ + "bad name (check-names)", /*%< 97 DNS_R_BADNAME */ + "dynamic zone", /*%< 98 DNS_R_DYNAMIC */ + "unknown command", /*%< 99 DNS_R_UNKNOWNCOMMAND */ + + "must-be-secure", /*%< 100 DNS_R_MUSTBESECURE */ + "covering NSEC record returned", /*%< 101 DNS_R_COVERINGNSEC */ + "MX is an address", /*%< 102 DNS_R_MXISADDRESS */ + "duplicate query" /*%< 103 DNS_R_DUPLICATE */ }; static const char *rcode_text[DNS_R_NRCODERESULTS] = { - "NOERROR", /* 0 DNS_R_NOEROR */ - "FORMERR", /* 1 DNS_R_FORMERR */ - "SERVFAIL", /* 2 DNS_R_SERVFAIL */ - "NXDOMAIN", /* 3 DNS_R_NXDOMAIN */ - "NOTIMP", /* 4 DNS_R_NOTIMP */ - - "REFUSED", /* 5 DNS_R_REFUSED */ - "YXDOMAIN", /* 6 DNS_R_YXDOMAIN */ - "YXRRSET", /* 7 DNS_R_YXRRSET */ - "NXRRSET", /* 8 DNS_R_NXRRSET */ - "NOTAUTH", /* 9 DNS_R_NOTAUTH */ - - "NOTZONE", /* 10 DNS_R_NOTZONE */ - "<rcode 11>", /* 11 has no macro */ - "<rcode 12>", /* 12 has no macro */ - "<rcode 13>", /* 13 has no macro */ - "<rcode 14>", /* 14 has no macro */ - - "<rcode 15>", /* 15 has no macro */ - "BADVERS", /* 16 DNS_R_BADVERS */ + "NOERROR", /*%< 0 DNS_R_NOEROR */ + "FORMERR", /*%< 1 DNS_R_FORMERR */ + "SERVFAIL", /*%< 2 DNS_R_SERVFAIL */ + "NXDOMAIN", /*%< 3 DNS_R_NXDOMAIN */ + "NOTIMP", /*%< 4 DNS_R_NOTIMP */ + + "REFUSED", /*%< 5 DNS_R_REFUSED */ + "YXDOMAIN", /*%< 6 DNS_R_YXDOMAIN */ + "YXRRSET", /*%< 7 DNS_R_YXRRSET */ + "NXRRSET", /*%< 8 DNS_R_NXRRSET */ + "NOTAUTH", /*%< 9 DNS_R_NOTAUTH */ + + "NOTZONE", /*%< 10 DNS_R_NOTZONE */ + "<rcode 11>", /*%< 11 has no macro */ + "<rcode 12>", /*%< 12 has no macro */ + "<rcode 13>", /*%< 13 has no macro */ + "<rcode 14>", /*%< 14 has no macro */ + + "<rcode 15>", /*%< 15 has no macro */ + "BADVERS", /*%< 16 DNS_R_BADVERS */ }; #define DNS_RESULT_RESULTSET 2 diff --git a/contrib/bind9/lib/dns/rootns.c b/contrib/bind9/lib/dns/rootns.c index 9e9c940..1c038a4 100644 --- a/contrib/bind9/lib/dns/rootns.c +++ b/contrib/bind9/lib/dns/rootns.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rootns.c,v 1.20.2.3.2.5 2004/03/08 09:04:32 marka Exp $ */ +/* $Id: rootns.c,v 1.26.18.3 2005/04/27 05:01:26 sra Exp $ */ + +/*! \file */ #include <config.h> @@ -26,15 +28,18 @@ #include <dns/callbacks.h> #include <dns/db.h> #include <dns/dbiterator.h> -#include <dns/log.h> #include <dns/fixedname.h> +#include <dns/log.h> #include <dns/master.h> #include <dns/rdata.h> -#include <dns/rdatasetiter.h> +#include <dns/rdata.h> #include <dns/rdataset.h> +#include <dns/rdatasetiter.h> #include <dns/rdatastruct.h> +#include <dns/rdatatype.h> #include <dns/result.h> #include <dns/rootns.h> +#include <dns/view.h> static char root_ns[] = ";\n" @@ -245,3 +250,265 @@ dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, return (result); } + +static void +report(dns_view_t *view, dns_name_t *name, isc_boolean_t missing, + dns_rdata_t *rdata) +{ + const char *viewname = "", *sep = ""; + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + char databuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")]; + isc_buffer_t buffer; + isc_result_t result; + + if (strcmp(view->name, "_bind") != 0 && + strcmp(view->name, "_default") != 0) { + viewname = view->name; + sep = ": view "; + } + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf)); + isc_buffer_init(&buffer, databuf, sizeof(databuf) - 1); + result = dns_rdata_totext(rdata, NULL, &buffer); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + databuf[isc_buffer_usedlength(&buffer)] = '\0'; + + if (missing) + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, + "checkhints%s%s: %s/%s (%s) missing from hints", + sep, viewname, namebuf, typebuf, databuf); + else + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, + "checkhints%s%s: %s/%s (%s) extra record " + "in hints", sep, viewname, namebuf, typebuf, + databuf); +} + +static isc_boolean_t +inrrset(dns_rdataset_t *rrset, dns_rdata_t *rdata) { + isc_result_t result; + dns_rdata_t current = DNS_RDATA_INIT; + + result = dns_rdataset_first(rrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(rrset, ¤t); + if (dns_rdata_compare(rdata, ¤t) == 0) + return (ISC_TRUE); + dns_rdata_reset(¤t); + result = dns_rdataset_next(rrset); + } + return (ISC_FALSE); +} + +/* + * Check that the address RRsets match. + * + * Note we don't complain about missing glue records. + */ + +static void +check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db, + dns_name_t *name, isc_stdtime_t now) +{ + isc_result_t hresult, rresult, result; + dns_rdataset_t hintrrset, rootrrset; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_name_t *foundname; + dns_fixedname_t fixed; + + dns_rdataset_init(&hintrrset); + dns_rdataset_init(&rootrrset); + dns_fixedname_init(&fixed); + foundname = dns_fixedname_name(&fixed); + + hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0, + now, NULL, foundname, &hintrrset, NULL); + rresult = dns_db_find(db, name, NULL, dns_rdatatype_a, + DNS_DBFIND_GLUEOK, now, NULL, foundname, + &rootrrset, NULL); + if (hresult == ISC_R_SUCCESS && + (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { + result = dns_rdataset_first(&rootrrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rootrrset, &rdata); + if (!inrrset(&hintrrset, &rdata)) + report(view, name, ISC_TRUE, &rdata); + result = dns_rdataset_next(&rootrrset); + } + result = dns_rdataset_first(&hintrrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&hintrrset, &rdata); + if (!inrrset(&rootrrset, &rdata)) + report(view, name, ISC_FALSE, &rdata); + result = dns_rdataset_next(&hintrrset); + } + } + if (hresult == ISC_R_NOTFOUND && + (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { + result = dns_rdataset_first(&rootrrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rootrrset, &rdata); + report(view, name, ISC_TRUE, &rdata); + result = dns_rdataset_next(&rootrrset); + } + } + if (dns_rdataset_isassociated(&rootrrset)) + dns_rdataset_disassociate(&rootrrset); + if (dns_rdataset_isassociated(&hintrrset)) + dns_rdataset_disassociate(&hintrrset); + + /* + * Check AAAA records. + */ + hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0, + now, NULL, foundname, &hintrrset, NULL); + rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, + DNS_DBFIND_GLUEOK, now, NULL, foundname, + &rootrrset, NULL); + if (hresult == ISC_R_SUCCESS && + (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { + result = dns_rdataset_first(&rootrrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rootrrset, &rdata); + if (!inrrset(&hintrrset, &rdata)) + report(view, name, ISC_TRUE, &rdata); + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rootrrset); + } + result = dns_rdataset_first(&hintrrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&hintrrset, &rdata); + if (!inrrset(&rootrrset, &rdata)) + report(view, name, ISC_FALSE, &rdata); + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&hintrrset); + } + } + if (hresult == ISC_R_NOTFOUND && + (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) { + result = dns_rdataset_first(&rootrrset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rootrrset, &rdata); + report(view, name, ISC_TRUE, &rdata); + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rootrrset); + } + } + if (dns_rdataset_isassociated(&rootrrset)) + dns_rdataset_disassociate(&rootrrset); + if (dns_rdataset_isassociated(&hintrrset)) + dns_rdataset_disassociate(&hintrrset); +} + +void +dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) { + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_ns_t ns; + dns_rdataset_t hintns, rootns; + const char *viewname = "", *sep = ""; + isc_stdtime_t now; + dns_name_t *name; + dns_fixedname_t fixed; + + REQUIRE(hints != NULL); + REQUIRE(db != NULL); + REQUIRE(view != NULL); + + isc_stdtime_get(&now); + + if (strcmp(view->name, "_bind") != 0 && + strcmp(view->name, "_default") != 0) { + viewname = view->name; + sep = ": view "; + } + + dns_rdataset_init(&hintns); + dns_rdataset_init(&rootns); + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + + result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0, + now, NULL, name, &hintns, NULL); + if (result != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, + "checkhints%s%s: unable to get root NS rrset " + "from hints: %s", sep, viewname, + dns_result_totext(result)); + goto cleanup; + } + + result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0, + now, NULL, name, &rootns, NULL); + if (result != ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, + "checkhints%s%s: unable to get root NS rrset " + "from cache: %s", sep, viewname, + dns_result_totext(result)); + goto cleanup; + } + + /* + * Look for missing root NS names. + */ + result = dns_rdataset_first(&rootns); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rootns, &rdata); + result = dns_rdata_tostruct(&rdata, &ns, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + result = in_rootns(&hintns, &ns.name); + if (result != ISC_R_SUCCESS) { + char namebuf[DNS_NAME_FORMATSIZE]; + /* missing from hints */ + dns_name_format(&ns.name, namebuf, sizeof(namebuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, + "checkhints%s%s: unable to find root " + "NS '%s' in hints", sep, viewname, + namebuf); + } else + check_address_records(view, hints, db, &ns.name, now); + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rootns); + } + if (result != ISC_R_NOMORE) { + goto cleanup; + } + + /* + * Look for extra root NS names. + */ + result = dns_rdataset_first(&hintns); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&hintns, &rdata); + result = dns_rdata_tostruct(&rdata, &ns, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + result = in_rootns(&rootns, &ns.name); + if (result != ISC_R_SUCCESS) { + char namebuf[DNS_NAME_FORMATSIZE]; + /* extra entry in hints */ + dns_name_format(&ns.name, namebuf, sizeof(namebuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_HINTS, ISC_LOG_WARNING, + "checkhints%s%s: extra NS '%s' in hints", + sep, viewname, namebuf); + } + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&hintns); + } + if (result != ISC_R_NOMORE) { + goto cleanup; + } + + cleanup: + if (dns_rdataset_isassociated(&rootns)) + dns_rdataset_disassociate(&rootns); + if (dns_rdataset_isassociated(&hintns)) + dns_rdataset_disassociate(&hintns); +} diff --git a/contrib/bind9/lib/dns/sdb.c b/contrib/bind9/lib/dns/sdb.c index ef22418..79ddef2 100644 --- a/contrib/bind9/lib/dns/sdb.c +++ b/contrib/bind9/lib/dns/sdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.35.12.8 2004/07/22 04:01:58 marka Exp $ */ +/* $Id: sdb.c,v 1.45.18.10 2006/12/07 23:57:58 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -99,7 +101,7 @@ typedef struct sdb_rdatasetiter { #define SDB_MAGIC ISC_MAGIC('S', 'D', 'B', '-') -/* +/*% * Note that "impmagic" is not the first four bytes of the struct, so * ISC_MAGIC_VALID cannot be used. */ @@ -110,7 +112,7 @@ typedef struct sdb_rdatasetiter { #define VALID_SDBLOOKUP(sdbl) ISC_MAGIC_VALID(sdbl, SDBLOOKUP_MAGIC) #define VALID_SDBNODE(sdbn) VALID_SDBLOOKUP(sdbn) -/* These values are taken from RFC 1537 */ +/* These values are taken from RFC1537 */ #define SDB_DEFAULT_REFRESH (60 * 60 * 8) #define SDB_DEFAULT_RETRY (60 * 60 * 2) #define SDB_DEFAULT_EXPIRE (60 * 60 * 24 * 7) @@ -225,12 +227,8 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, imp->mctx = NULL; isc_mem_attach(mctx, &imp->mctx); result = isc_mutex_init(&imp->driverlock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); + if (result != ISC_R_SUCCESS) goto cleanup_mctx; - } imp->dbimp = NULL; result = dns_db_register(drivername, dns_sdb_create, imp, mctx, @@ -269,10 +267,11 @@ dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) { static inline unsigned int initial_size(unsigned int len) { unsigned int size; - for (size = 64; size < (64 * 1024); size *= 2) + + for (size = 1024; size < (64 * 1024); size *= 2) if (len < size) return (size); - return (64 * 1024); + return (65535); } isc_result_t @@ -383,6 +382,8 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, if (result != ISC_R_SUCCESS) goto failure; + if (size >= 65535) + size = 65535; p = isc_mem_get(mctx, size); if (p == NULL) { result = ISC_R_NOMEMORY; @@ -398,6 +399,11 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, if (result != ISC_R_NOSPACE) break; + /* + * Is the RR too big? + */ + if (size >= 65535) + break; isc_mem_put(mctx, p, size); p = NULL; size *= 2; @@ -599,10 +605,12 @@ endload(dns_db_t *db, dns_dbload_t **dbloadp) { } static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { +dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) { UNUSED(db); UNUSED(version); UNUSED(filename); + UNUSED(masterformat); return (ISC_R_NOTIMPLEMENTED); } @@ -664,11 +672,8 @@ createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) { node->name = NULL; result = isc_mutex_init(&node->lock); if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); isc_mem_put(sdb->common.mctx, node, sizeof(dns_sdbnode_t)); - return (ISC_R_UNEXPECTED); + return (result); } dns_rdatacallbacks_init(&node->callbacks); node->references = 1; @@ -930,7 +935,8 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, xresult = dns_name_copy(xname, foundname, NULL); if (xresult != ISC_R_SUCCESS) { - destroynode(node); + if (node != NULL) + destroynode(node); if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); return (DNS_R_BADDB); @@ -1234,7 +1240,8 @@ static dns_dbmethods_t sdb_methods = { nodecount, ispersistent, overmem, - settask + settask, + NULL }; static isc_result_t @@ -1270,13 +1277,8 @@ dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, dns_dbtype_t type, isc_mem_attach(mctx, &sdb->common.mctx); result = isc_mutex_init(&sdb->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_mctx; - } result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin); if (result != ISC_R_SUCCESS) @@ -1361,7 +1363,10 @@ static dns_rdatasetmethods_t methods = { rdataset_clone, isc__rdatalist_count, isc__rdatalist_addnoqname, - isc__rdatalist_getnoqname + isc__rdatalist_getnoqname, + NULL, + NULL, + NULL }; static void diff --git a/contrib/bind9/lib/dns/sdlz.c b/contrib/bind9/lib/dns/sdlz.c new file mode 100644 index 0000000..2c6ba8d --- /dev/null +++ b/contrib/bind9/lib/dns/sdlz.c @@ -0,0 +1,1781 @@ +/* + * Portions Copyright (C) 2005-2007 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and 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. + */ + +/* + * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl. + * + * Permission to use, copy, modify, and 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 STICHTING NLNET + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * STICHTING NLNET 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. + * + * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was + * conceived and contributed by Rob Butler. + * + * Permission to use, copy, modify, and 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 ROB BUTLER + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * ROB BUTLER 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: sdlz.c,v 1.2.2.9 2007/02/14 23:45:43 marka Exp $ */ + +/*! \file */ + +#include <config.h> +#include <string.h> + +#include <isc/buffer.h> +#include <isc/lex.h> +#include <isc/log.h> +#include <isc/rwlock.h> +#include <isc/string.h> +#include <isc/util.h> +#include <isc/magic.h> +#include <isc/mem.h> +#include <isc/once.h> +#include <isc/print.h> +#include <isc/region.h> + +#include <dns/callbacks.h> +#include <dns/db.h> +#include <dns/dbiterator.h> +#include <dns/dlz.h> +#include <dns/fixedname.h> +#include <dns/log.h> +#include <dns/rdata.h> +#include <dns/rdatalist.h> +#include <dns/rdataset.h> +#include <dns/rdatasetiter.h> +#include <dns/rdatatype.h> +#include <dns/result.h> +#include <dns/master.h> +#include <dns/sdlz.h> +#include <dns/types.h> + +#include "rdatalist_p.h" + +/* + * Private Types + */ + +struct dns_sdlzimplementation { + const dns_sdlzmethods_t *methods; + isc_mem_t *mctx; + void *driverarg; + unsigned int flags; + isc_mutex_t driverlock; + dns_dlzimplementation_t *dlz_imp; +}; + +struct dns_sdlz_db { + /* Unlocked */ + dns_db_t common; + void *dbdata; + dns_sdlzimplementation_t *dlzimp; + isc_mutex_t refcnt_lock; + /* Locked */ + unsigned int references; +}; + +struct dns_sdlzlookup { + /* Unlocked */ + unsigned int magic; + dns_sdlz_db_t *sdlz; + ISC_LIST(dns_rdatalist_t) lists; + ISC_LIST(isc_buffer_t) buffers; + dns_name_t *name; + ISC_LINK(dns_sdlzlookup_t) link; + isc_mutex_t lock; + dns_rdatacallbacks_t callbacks; + /* Locked */ + unsigned int references; +}; + +typedef struct dns_sdlzlookup dns_sdlznode_t; + +struct dns_sdlzallnodes { + dns_dbiterator_t common; + ISC_LIST(dns_sdlznode_t) nodelist; + dns_sdlznode_t *current; + dns_sdlznode_t *origin; +}; + +typedef dns_sdlzallnodes_t sdlz_dbiterator_t; + +typedef struct sdlz_rdatasetiter { + dns_rdatasetiter_t common; + dns_rdatalist_t *current; +} sdlz_rdatasetiter_t; + + +#define SDLZDB_MAGIC ISC_MAGIC('D', 'L', 'Z', 'S') + +/* + * Note that "impmagic" is not the first four bytes of the struct, so + * ISC_MAGIC_VALID cannot be used. + */ + +#define VALID_SDLZDB(sdlzdb) ((sdlzdb) != NULL && \ + (sdlzdb)->common.impmagic == SDLZDB_MAGIC) + +#define SDLZLOOKUP_MAGIC ISC_MAGIC('D','L','Z','L') +#define VALID_SDLZLOOKUP(sdlzl) ISC_MAGIC_VALID(sdlzl, SDLZLOOKUP_MAGIC) +#define VALID_SDLZNODE(sdlzn) VALID_SDLZLOOKUP(sdlzn) + +/* These values are taken from RFC 1537 */ +#define SDLZ_DEFAULT_REFRESH (60 * 60 * 8) +#define SDLZ_DEFAULT_RETRY (60 * 60 * 2) +#define SDLZ_DEFAULT_EXPIRE (60 * 60 * 24 * 7) +#define SDLZ_DEFAULT_MINIMUM (60 * 60 * 24) + +/* This is a reasonable value */ +#define SDLZ_DEFAULT_TTL (60 * 60 * 24) + +static int dummy; + +#define MAYBE_LOCK(imp) \ + do { \ + unsigned int flags = imp->flags; \ + if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \ + LOCK(&imp->driverlock); \ + } while (0) + +#define MAYBE_UNLOCK(imp) \ + do { \ + unsigned int flags = imp->flags; \ + if ((flags & DNS_SDLZFLAG_THREADSAFE) == 0) \ + UNLOCK(&imp->driverlock); \ + } while (0) + +/* + * Forward references. Try to keep these to a minimum. + */ + +static void list_tordataset(dns_rdatalist_t *rdatalist, + dns_db_t *db, dns_dbnode_t *node, + dns_rdataset_t *rdataset); + +static void detachnode(dns_db_t *db, dns_dbnode_t **targetp); + +static void dbiterator_destroy(dns_dbiterator_t **iteratorp); +static isc_result_t dbiterator_first(dns_dbiterator_t *iterator); +static isc_result_t dbiterator_last(dns_dbiterator_t *iterator); +static isc_result_t dbiterator_seek(dns_dbiterator_t *iterator, + dns_name_t *name); +static isc_result_t dbiterator_prev(dns_dbiterator_t *iterator); +static isc_result_t dbiterator_next(dns_dbiterator_t *iterator); +static isc_result_t dbiterator_current(dns_dbiterator_t *iterator, + dns_dbnode_t **nodep, + dns_name_t *name); +static isc_result_t dbiterator_pause(dns_dbiterator_t *iterator); +static isc_result_t dbiterator_origin(dns_dbiterator_t *iterator, + dns_name_t *name); + +static dns_dbiteratormethods_t dbiterator_methods = { + dbiterator_destroy, + dbiterator_first, + dbiterator_last, + dbiterator_seek, + dbiterator_prev, + dbiterator_next, + dbiterator_current, + dbiterator_pause, + dbiterator_origin +}; + +/* + * Utility functions + */ + +/*% Converts the input string to lowercase, in place. */ + +static void +dns_sdlz_tolower(char *str) { + + unsigned int len = strlen(str); + unsigned int i; + + for (i = 0; i < len; i++) { + if (str[i] >= 'A' && str[i] <= 'Z') + str[i] += 32; + } + +} + +static inline unsigned int +initial_size(const char *data) { + unsigned int len = (strlen(data) / 64) + 1; + return (len * 64 + 64); +} + +/* + * Rdataset Iterator Methods. These methods were "borrowed" from the SDB + * driver interface. See the SDB driver interface documentation for more info. + */ + +static void +rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) { + sdlz_rdatasetiter_t *sdlziterator = + (sdlz_rdatasetiter_t *)(*iteratorp); + + detachnode(sdlziterator->common.db, &sdlziterator->common.node); + isc_mem_put(sdlziterator->common.db->mctx, sdlziterator, + sizeof(sdlz_rdatasetiter_t)); + *iteratorp = NULL; +} + +static isc_result_t +rdatasetiter_first(dns_rdatasetiter_t *iterator) { + sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; + dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)iterator->node; + + if (ISC_LIST_EMPTY(sdlznode->lists)) + return (ISC_R_NOMORE); + sdlziterator->current = ISC_LIST_HEAD(sdlznode->lists); + return (ISC_R_SUCCESS); +} + +static isc_result_t +rdatasetiter_next(dns_rdatasetiter_t *iterator) { + sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; + + sdlziterator->current = ISC_LIST_NEXT(sdlziterator->current, link); + if (sdlziterator->current == NULL) + return (ISC_R_NOMORE); + else + return (ISC_R_SUCCESS); +} + +static void +rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) { + sdlz_rdatasetiter_t *sdlziterator = (sdlz_rdatasetiter_t *)iterator; + + list_tordataset(sdlziterator->current, iterator->db, iterator->node, + rdataset); +} + +static dns_rdatasetitermethods_t rdatasetiter_methods = { + rdatasetiter_destroy, + rdatasetiter_first, + rdatasetiter_next, + rdatasetiter_current +}; + +/* + * DB routines. These methods were "borrowed" from the SDB driver interface. + * See the SDB driver interface documentation for more info. + */ + +static void +attach(dns_db_t *source, dns_db_t **targetp) { + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *) source; + + REQUIRE(VALID_SDLZDB(sdlz)); + + LOCK(&sdlz->refcnt_lock); + REQUIRE(sdlz->references > 0); + sdlz->references++; + UNLOCK(&sdlz->refcnt_lock); + + *targetp = source; +} + +static void +destroy(dns_sdlz_db_t *sdlz) { + isc_mem_t *mctx; + mctx = sdlz->common.mctx; + + sdlz->common.magic = 0; + sdlz->common.impmagic = 0; + + isc_mutex_destroy(&sdlz->refcnt_lock); + + dns_name_free(&sdlz->common.origin, mctx); + + isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t)); + isc_mem_detach(&mctx); +} + +static void +detach(dns_db_t **dbp) { + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp); + isc_boolean_t need_destroy = ISC_FALSE; + + REQUIRE(VALID_SDLZDB(sdlz)); + LOCK(&sdlz->refcnt_lock); + REQUIRE(sdlz->references > 0); + sdlz->references--; + if (sdlz->references == 0) + need_destroy = ISC_TRUE; + UNLOCK(&sdlz->refcnt_lock); + + if (need_destroy) + destroy(sdlz); + + *dbp = NULL; +} + +static isc_result_t +beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { + UNUSED(db); + UNUSED(addp); + UNUSED(dbloadp); + return (ISC_R_NOTIMPLEMENTED); +} + +static isc_result_t +endload(dns_db_t *db, dns_dbload_t **dbloadp) { + UNUSED(db); + UNUSED(dbloadp); + return (ISC_R_NOTIMPLEMENTED); +} + +static isc_result_t +dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) +{ + UNUSED(db); + UNUSED(version); + UNUSED(filename); + UNUSED(masterformat); + return (ISC_R_NOTIMPLEMENTED); +} + +static void +currentversion(dns_db_t *db, dns_dbversion_t **versionp) { + REQUIRE(versionp != NULL && *versionp == NULL); + + UNUSED(db); + + *versionp = (void *) &dummy; + return; +} + +static isc_result_t +newversion(dns_db_t *db, dns_dbversion_t **versionp) { + UNUSED(db); + UNUSED(versionp); + + return (ISC_R_NOTIMPLEMENTED); +} + +static void +attachversion(dns_db_t *db, dns_dbversion_t *source, + dns_dbversion_t **targetp) +{ + REQUIRE(source != NULL && source == (void *) &dummy); + + UNUSED(db); + UNUSED(source); + UNUSED(targetp); + *targetp = source; +} + +static void +closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { + REQUIRE(versionp != NULL && *versionp == (void *) &dummy); + REQUIRE(commit == ISC_FALSE); + + UNUSED(db); + UNUSED(commit); + + *versionp = NULL; +} + +static isc_result_t +createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) { + dns_sdlznode_t *node; + isc_result_t result; + + node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t)); + if (node == NULL) + return (ISC_R_NOMEMORY); + + node->sdlz = NULL; + attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz); + ISC_LIST_INIT(node->lists); + ISC_LIST_INIT(node->buffers); + ISC_LINK_INIT(node, link); + node->name = NULL; + result = isc_mutex_init(&node->lock); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_mutex_init() failed: %s", + isc_result_totext(result)); + isc_mem_put(sdlz->common.mctx, node, sizeof(dns_sdlznode_t)); + return (ISC_R_UNEXPECTED); + } + dns_rdatacallbacks_init(&node->callbacks); + node->references = 1; + node->magic = SDLZLOOKUP_MAGIC; + + *nodep = node; + return (ISC_R_SUCCESS); +} + +static void +destroynode(dns_sdlznode_t *node) { + dns_rdatalist_t *list; + dns_rdata_t *rdata; + isc_buffer_t *b; + dns_sdlz_db_t *sdlz; + dns_db_t *db; + isc_mem_t *mctx; + + sdlz = node->sdlz; + mctx = sdlz->common.mctx; + + while (!ISC_LIST_EMPTY(node->lists)) { + list = ISC_LIST_HEAD(node->lists); + while (!ISC_LIST_EMPTY(list->rdata)) { + rdata = ISC_LIST_HEAD(list->rdata); + ISC_LIST_UNLINK(list->rdata, rdata, link); + isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); + } + ISC_LIST_UNLINK(node->lists, list, link); + isc_mem_put(mctx, list, sizeof(dns_rdatalist_t)); + } + + while (!ISC_LIST_EMPTY(node->buffers)) { + b = ISC_LIST_HEAD(node->buffers); + ISC_LIST_UNLINK(node->buffers, b, link); + isc_buffer_free(&b); + } + + if (node->name != NULL) { + dns_name_free(node->name, mctx); + isc_mem_put(mctx, node->name, sizeof(dns_name_t)); + } + DESTROYLOCK(&node->lock); + node->magic = 0; + isc_mem_put(mctx, node, sizeof(dns_sdlznode_t)); + db = &sdlz->common; + detach(&db); +} + +static isc_result_t +findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_dbnode_t **nodep) +{ + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; + dns_sdlznode_t *node = NULL; + isc_result_t result; + isc_buffer_t b; + char namestr[DNS_NAME_MAXTEXT + 1]; + isc_buffer_t b2; + char zonestr[DNS_NAME_MAXTEXT + 1]; + isc_boolean_t isorigin; + dns_sdlzauthorityfunc_t authority; + + REQUIRE(VALID_SDLZDB(sdlz)); + REQUIRE(create == ISC_FALSE); + REQUIRE(nodep != NULL && *nodep == NULL); + + UNUSED(name); + UNUSED(create); + + isc_buffer_init(&b, namestr, sizeof(namestr)); + if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVEOWNER) != 0) { + dns_name_t relname; + unsigned int labels; + + labels = dns_name_countlabels(name) - + dns_name_countlabels(&db->origin); + dns_name_init(&relname, NULL); + dns_name_getlabelsequence(name, 0, labels, &relname); + result = dns_name_totext(&relname, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + } else { + result = dns_name_totext(name, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + } + isc_buffer_putuint8(&b, 0); + + isc_buffer_init(&b2, zonestr, sizeof(zonestr)); + result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b2); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_putuint8(&b2, 0); + + result = createnode(sdlz, &node); + if (result != ISC_R_SUCCESS) + return (result); + + isorigin = dns_name_equal(name, &sdlz->common.origin); + + /* make sure strings are always lowercase */ + dns_sdlz_tolower(zonestr); + dns_sdlz_tolower(namestr); + + MAYBE_LOCK(sdlz->dlzimp); + + /* try to lookup the host (namestr) */ + result = sdlz->dlzimp->methods->lookup(zonestr, namestr, + sdlz->dlzimp->driverarg, + sdlz->dbdata, node); + + /* + * if the host (namestr) was not found, try to lookup a + * "wildcard" host. + */ + if (result != ISC_R_SUCCESS) { + result = sdlz->dlzimp->methods->lookup(zonestr, "*", + sdlz->dlzimp->driverarg, + sdlz->dbdata, node); + } + + MAYBE_UNLOCK(sdlz->dlzimp); + + if (result != ISC_R_SUCCESS && !isorigin) { + destroynode(node); + return (result); + } + + if (isorigin && sdlz->dlzimp->methods->authority != NULL) { + MAYBE_LOCK(sdlz->dlzimp); + authority = sdlz->dlzimp->methods->authority; + result = (*authority)(zonestr, sdlz->dlzimp->driverarg, + sdlz->dbdata, node); + MAYBE_UNLOCK(sdlz->dlzimp); + if (result != ISC_R_SUCCESS && + result != ISC_R_NOTIMPLEMENTED) { + destroynode(node); + return (result); + } + } + + *nodep = node; + return (ISC_R_SUCCESS); +} + +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) +{ + UNUSED(db); + UNUSED(name); + UNUSED(options); + UNUSED(now); + UNUSED(nodep); + UNUSED(foundname); + UNUSED(rdataset); + UNUSED(sigrdataset); + + return (ISC_R_NOTIMPLEMENTED); +} + +static void +attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) { + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; + dns_sdlznode_t *node = (dns_sdlznode_t *)source; + + REQUIRE(VALID_SDLZDB(sdlz)); + + UNUSED(sdlz); + + LOCK(&node->lock); + INSIST(node->references > 0); + node->references++; + INSIST(node->references != 0); /* Catch overflow. */ + UNLOCK(&node->lock); + + *targetp = source; +} + +static void +detachnode(dns_db_t *db, dns_dbnode_t **targetp) { + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; + dns_sdlznode_t *node; + isc_boolean_t need_destroy = ISC_FALSE; + + REQUIRE(VALID_SDLZDB(sdlz)); + REQUIRE(targetp != NULL && *targetp != NULL); + + UNUSED(sdlz); + + node = (dns_sdlznode_t *)(*targetp); + + LOCK(&node->lock); + INSIST(node->references > 0); + node->references--; + if (node->references == 0) + need_destroy = ISC_TRUE; + UNLOCK(&node->lock); + + if (need_destroy) + destroynode(node); + + *targetp = NULL; +} + +static isc_result_t +expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { + UNUSED(db); + UNUSED(node); + UNUSED(now); + INSIST(0); + return (ISC_R_UNEXPECTED); +} + +static void +printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) { + UNUSED(db); + UNUSED(node); + UNUSED(out); + return; +} + +static isc_result_t +createiterator(dns_db_t *db, isc_boolean_t relative_names, + dns_dbiterator_t **iteratorp) +{ + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; + sdlz_dbiterator_t *sdlziter; + isc_result_t result; + isc_buffer_t b; + char zonestr[DNS_NAME_MAXTEXT + 1]; + + REQUIRE(VALID_SDLZDB(sdlz)); + + if (sdlz->dlzimp->methods->allnodes == NULL) + return (ISC_R_NOTIMPLEMENTED); + + isc_buffer_init(&b, zonestr, sizeof(zonestr)); + result = dns_name_totext(&sdlz->common.origin, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_putuint8(&b, 0); + + sdlziter = isc_mem_get(sdlz->common.mctx, sizeof(sdlz_dbiterator_t)); + if (sdlziter == NULL) + return (ISC_R_NOMEMORY); + + sdlziter->common.methods = &dbiterator_methods; + sdlziter->common.db = NULL; + dns_db_attach(db, &sdlziter->common.db); + sdlziter->common.relative_names = relative_names; + sdlziter->common.magic = DNS_DBITERATOR_MAGIC; + ISC_LIST_INIT(sdlziter->nodelist); + sdlziter->current = NULL; + sdlziter->origin = NULL; + + /* make sure strings are always lowercase */ + dns_sdlz_tolower(zonestr); + + MAYBE_LOCK(sdlz->dlzimp); + result = sdlz->dlzimp->methods->allnodes(zonestr, + sdlz->dlzimp->driverarg, + sdlz->dbdata, sdlziter); + MAYBE_UNLOCK(sdlz->dlzimp); + if (result != ISC_R_SUCCESS) { + dns_dbiterator_t *iter = &sdlziter->common; + dbiterator_destroy(&iter); + return (result); + } + + if (sdlziter->origin != NULL) { + ISC_LIST_UNLINK(sdlziter->nodelist, sdlziter->origin, link); + ISC_LIST_PREPEND(sdlziter->nodelist, sdlziter->origin, link); + } + + *iteratorp = (dns_dbiterator_t *)sdlziter; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +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) +{ + dns_rdatalist_t *list; + dns_sdlznode_t *sdlznode = (dns_sdlznode_t *)node; + + REQUIRE(VALID_SDLZNODE(node)); + + UNUSED(db); + UNUSED(version); + UNUSED(covers); + UNUSED(now); + UNUSED(sigrdataset); + + if (type == dns_rdatatype_sig || type == dns_rdatatype_rrsig) + return (ISC_R_NOTIMPLEMENTED); + + list = ISC_LIST_HEAD(sdlznode->lists); + while (list != NULL) { + if (list->type == type) + break; + list = ISC_LIST_NEXT(list, link); + } + if (list == NULL) + return (ISC_R_NOTFOUND); + + list_tordataset(list, db, node, rdataset); + + return (ISC_R_SUCCESS); +} + +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) +{ + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; + dns_dbnode_t *node = NULL; + dns_fixedname_t fname; + dns_rdataset_t xrdataset; + dns_name_t *xname; + unsigned int nlabels, olabels; + isc_result_t result; + unsigned int i; + + REQUIRE(VALID_SDLZDB(sdlz)); + REQUIRE(nodep == NULL || *nodep == NULL); + REQUIRE(version == NULL || version == (void *) &dummy); + + UNUSED(options); + UNUSED(sdlz); + + if (!dns_name_issubdomain(name, &db->origin)) + return (DNS_R_NXDOMAIN); + + olabels = dns_name_countlabels(&db->origin); + nlabels = dns_name_countlabels(name); + + dns_fixedname_init(&fname); + xname = dns_fixedname_name(&fname); + + if (rdataset == NULL) { + dns_rdataset_init(&xrdataset); + rdataset = &xrdataset; + } + + result = DNS_R_NXDOMAIN; + + for (i = olabels; i <= nlabels; i++) { + /* + * Unless this is an explicit lookup at the origin, don't + * look at the origin. + */ + if (i == olabels && i != nlabels) + continue; + + /* + * Look up the next label. + */ + dns_name_getlabelsequence(name, nlabels - i, i, xname); + result = findnode(db, xname, ISC_FALSE, &node); + if (result != ISC_R_SUCCESS) { + result = DNS_R_NXDOMAIN; + continue; + } + + /* + * Look for a DNAME at the current label, unless this is + * the qname. + */ + if (i < nlabels) { + result = findrdataset(db, node, version, + dns_rdatatype_dname, + 0, now, rdataset, sigrdataset); + if (result == ISC_R_SUCCESS) { + result = DNS_R_DNAME; + break; + } + } + + /* + * Look for an NS at the current label, unless this is the + * origin or glue is ok. + */ + if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { + result = findrdataset(db, node, version, + dns_rdatatype_ns, + 0, now, rdataset, sigrdataset); + if (result == ISC_R_SUCCESS) { + if (i == nlabels && type == dns_rdatatype_any) + { + result = DNS_R_ZONECUT; + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL) + dns_rdataset_disassociate + (sigrdataset); + } else + result = DNS_R_DELEGATION; + break; + } + } + + /* + * If the current name is not the qname, add another label + * and try again. + */ + if (i < nlabels) { + destroynode(node); + node = NULL; + continue; + } + + /* + * If we're looking for ANY, we're done. + */ + if (type == dns_rdatatype_any) { + result = ISC_R_SUCCESS; + break; + } + + /* + * Look for the qtype. + */ + result = findrdataset(db, node, version, type, + 0, now, rdataset, sigrdataset); + if (result == ISC_R_SUCCESS) + break; + + /* + * Look for a CNAME + */ + if (type != dns_rdatatype_cname) { + result = findrdataset(db, node, version, + dns_rdatatype_cname, + 0, now, rdataset, sigrdataset); + if (result == ISC_R_SUCCESS) { + result = DNS_R_CNAME; + break; + } + } + + result = DNS_R_NXRRSET; + break; + } + + if (rdataset == &xrdataset && dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + + if (foundname != NULL) { + isc_result_t xresult; + + xresult = dns_name_copy(xname, foundname, NULL); + if (xresult != ISC_R_SUCCESS) { + if (node != NULL) + destroynode(node); + if (dns_rdataset_isassociated(rdataset)) + dns_rdataset_disassociate(rdataset); + return (DNS_R_BADDB); + } + } + + if (nodep != NULL) + *nodep = node; + else if (node != NULL) + detachnode(db, &node); + + return (result); +} + +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) +{ + sdlz_rdatasetiter_t *iterator; + + REQUIRE(version == NULL || version == &dummy); + + UNUSED(version); + UNUSED(now); + + iterator = isc_mem_get(db->mctx, sizeof(sdlz_rdatasetiter_t)); + if (iterator == NULL) + return (ISC_R_NOMEMORY); + + iterator->common.magic = DNS_RDATASETITER_MAGIC; + iterator->common.methods = &rdatasetiter_methods; + iterator->common.db = db; + iterator->common.node = NULL; + attachnode(db, node, &iterator->common.node); + iterator->common.version = version; + iterator->common.now = now; + + *iteratorp = (dns_rdatasetiter_t *)iterator; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options, + dns_rdataset_t *addedrdataset) +{ + UNUSED(db); + UNUSED(node); + UNUSED(version); + UNUSED(now); + UNUSED(rdataset); + UNUSED(options); + UNUSED(addedrdataset); + + return (ISC_R_NOTIMPLEMENTED); +} + +static isc_result_t +subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + dns_rdataset_t *rdataset, unsigned int options, + dns_rdataset_t *newrdataset) +{ + UNUSED(db); + UNUSED(node); + UNUSED(version); + UNUSED(rdataset); + UNUSED(options); + UNUSED(newrdataset); + + return (ISC_R_NOTIMPLEMENTED); +} + +static isc_result_t +deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + dns_rdatatype_t type, dns_rdatatype_t covers) +{ + UNUSED(db); + UNUSED(node); + UNUSED(version); + UNUSED(type); + UNUSED(covers); + + return (ISC_R_NOTIMPLEMENTED); +} + +static isc_boolean_t +issecure(dns_db_t *db) { + UNUSED(db); + + return (ISC_FALSE); +} + +static unsigned int +nodecount(dns_db_t *db) { + UNUSED(db); + + return (0); +} + +static isc_boolean_t +ispersistent(dns_db_t *db) { + UNUSED(db); + return (ISC_TRUE); +} + +static void +overmem(dns_db_t *db, isc_boolean_t overmem) { + UNUSED(db); + UNUSED(overmem); +} + +static void +settask(dns_db_t *db, isc_task_t *task) { + UNUSED(db); + UNUSED(task); +} + + +static dns_dbmethods_t sdlzdb_methods = { + attach, + detach, + beginload, + endload, + dump, + currentversion, + newversion, + attachversion, + closeversion, + findnode, + find, + findzonecut, + attachnode, + detachnode, + expirenode, + printnode, + createiterator, + findrdataset, + allrdatasets, + addrdataset, + subtractrdataset, + deleterdataset, + issecure, + nodecount, + ispersistent, + overmem, + settask, + NULL, +}; + +/* + * Database Iterator Methods. These methods were "borrowed" from the SDB + * driver interface. See the SDB driver interface documentation for more info. + */ + +static void +dbiterator_destroy(dns_dbiterator_t **iteratorp) { + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)(*iteratorp); + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)sdlziter->common.db; + + while (!ISC_LIST_EMPTY(sdlziter->nodelist)) { + dns_sdlznode_t *node; + node = ISC_LIST_HEAD(sdlziter->nodelist); + ISC_LIST_UNLINK(sdlziter->nodelist, node, link); + destroynode(node); + } + + dns_db_detach(&sdlziter->common.db); + isc_mem_put(sdlz->common.mctx, sdlziter, sizeof(sdlz_dbiterator_t)); + + *iteratorp = NULL; +} + +static isc_result_t +dbiterator_first(dns_dbiterator_t *iterator) { + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; + + sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); + if (sdlziter->current == NULL) + return (ISC_R_NOMORE); + else + return (ISC_R_SUCCESS); +} + +static isc_result_t +dbiterator_last(dns_dbiterator_t *iterator) { + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; + + sdlziter->current = ISC_LIST_TAIL(sdlziter->nodelist); + if (sdlziter->current == NULL) + return (ISC_R_NOMORE); + else + return (ISC_R_SUCCESS); +} + +static isc_result_t +dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) { + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; + + sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist); + while (sdlziter->current != NULL) + if (dns_name_equal(sdlziter->current->name, name)) + return (ISC_R_SUCCESS); + return (ISC_R_NOTFOUND); +} + +static isc_result_t +dbiterator_prev(dns_dbiterator_t *iterator) { + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; + + sdlziter->current = ISC_LIST_PREV(sdlziter->current, link); + if (sdlziter->current == NULL) + return (ISC_R_NOMORE); + else + return (ISC_R_SUCCESS); +} + +static isc_result_t +dbiterator_next(dns_dbiterator_t *iterator) { + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; + + sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link); + if (sdlziter->current == NULL) + return (ISC_R_NOMORE); + else + return (ISC_R_SUCCESS); +} + +static isc_result_t +dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep, + dns_name_t *name) +{ + sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator; + + attachnode(iterator->db, sdlziter->current, nodep); + if (name != NULL) + return (dns_name_copy(sdlziter->current->name, name, NULL)); + return (ISC_R_SUCCESS); +} + +static isc_result_t +dbiterator_pause(dns_dbiterator_t *iterator) { + UNUSED(iterator); + return (ISC_R_SUCCESS); +} + +static isc_result_t +dbiterator_origin(dns_dbiterator_t *iterator, dns_name_t *name) { + UNUSED(iterator); + return (dns_name_copy(dns_rootname, name, NULL)); +} + +/* + * Rdataset Methods. These methods were "borrowed" from the SDB driver + * interface. See the SDB driver interface documentation for more info. + */ + +static void +disassociate(dns_rdataset_t *rdataset) { + dns_dbnode_t *node = rdataset->private5; + dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node; + dns_db_t *db = (dns_db_t *) sdlznode->sdlz; + + detachnode(db, &node); + isc__rdatalist_disassociate(rdataset); +} + +static void +rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { + dns_dbnode_t *node = source->private5; + dns_sdlznode_t *sdlznode = (dns_sdlznode_t *) node; + dns_db_t *db = (dns_db_t *) sdlznode->sdlz; + dns_dbnode_t *tempdb = NULL; + + isc__rdatalist_clone(source, target); + attachnode(db, node, &tempdb); + source->private5 = tempdb; +} + +static dns_rdatasetmethods_t rdataset_methods = { + disassociate, + isc__rdatalist_first, + isc__rdatalist_next, + isc__rdatalist_current, + rdataset_clone, + isc__rdatalist_count, + isc__rdatalist_addnoqname, + isc__rdatalist_getnoqname, + NULL, + NULL, + NULL +}; + +static void +list_tordataset(dns_rdatalist_t *rdatalist, + dns_db_t *db, dns_dbnode_t *node, + dns_rdataset_t *rdataset) +{ + /* + * The sdlz rdataset is an rdatalist with some additions. + * - private1 & private2 are used by the rdatalist. + * - private3 & private 4 are unused. + * - private5 is the node. + */ + + /* This should never fail. */ + RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == + ISC_R_SUCCESS); + + rdataset->methods = &rdataset_methods; + dns_db_attachnode(db, node, &rdataset->private5); +} + +/* + * SDLZ core methods. This is the core of the new DLZ functionality. + */ + +/*% + * Build a 'bind' database driver structure to be returned by + * either the find zone or the allow zone transfer method. + * This method is only available in this source file, it is + * not made available anywhere else. + */ + +static isc_result_t +dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata, + dns_name_t *name, dns_rdataclass_t rdclass, dns_db_t **dbp) +{ + isc_result_t result; + dns_sdlz_db_t *sdlzdb; + dns_sdlzimplementation_t *imp; + + /* check that things are as we expect */ + REQUIRE(dbp != NULL && *dbp == NULL); + REQUIRE(name != NULL); + + imp = (dns_sdlzimplementation_t *) driverarg; + + /* allocate and zero memory for driver structure */ + sdlzdb = isc_mem_get(mctx, sizeof(dns_sdlz_db_t)); + if (sdlzdb == NULL) + return (ISC_R_NOMEMORY); + memset(sdlzdb, 0, sizeof(dns_sdlz_db_t)); + + /* initialize and set origin */ + dns_name_init(&sdlzdb->common.origin, NULL); + result = dns_name_dupwithoffsets(name, mctx, &sdlzdb->common.origin); + if (result != ISC_R_SUCCESS) + goto mem_cleanup; + + /* initialize the reference count mutex */ + result = isc_mutex_init(&sdlzdb->refcnt_lock); + if (result != ISC_R_SUCCESS) + goto name_cleanup; + + /* set the rest of the database structure attributes */ + sdlzdb->dlzimp = imp; + sdlzdb->common.methods = &sdlzdb_methods; + sdlzdb->common.attributes = 0; + sdlzdb->common.rdclass = rdclass; + sdlzdb->common.mctx = NULL; + sdlzdb->dbdata = dbdata; + sdlzdb->references = 1; + + /* attach to the memory context */ + isc_mem_attach(mctx, &sdlzdb->common.mctx); + + /* mark structure as valid */ + sdlzdb->common.magic = DNS_DB_MAGIC; + sdlzdb->common.impmagic = SDLZDB_MAGIC; + *dbp = (dns_db_t *) sdlzdb; + + return (result); + + /* + * reference count mutex could not be initialized, clean up + * name memory + */ + name_cleanup: + dns_name_free(&sdlzdb->common.origin, mctx); + mem_cleanup: + isc_mem_put(mctx, sdlzdb, sizeof(dns_sdlz_db_t)); + return (result); +} + +static isc_result_t +dns_sdlzallowzonexfr(void *driverarg, void *dbdata, isc_mem_t *mctx, + dns_rdataclass_t rdclass, dns_name_t *name, + isc_sockaddr_t *clientaddr, dns_db_t **dbp) +{ + isc_buffer_t b; + isc_buffer_t b2; + char namestr[DNS_NAME_MAXTEXT + 1]; + char clientstr[(sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255") + + 1]; + isc_netaddr_t netaddr; + isc_result_t result; + dns_sdlzimplementation_t *imp; + + /* + * Perform checks to make sure data is as we expect it to be. + */ + REQUIRE(driverarg != NULL); + REQUIRE(name != NULL); + REQUIRE(clientaddr != NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + + imp = (dns_sdlzimplementation_t *) driverarg; + + /* Convert DNS name to ascii text */ + isc_buffer_init(&b, namestr, sizeof(namestr)); + result = dns_name_totext(name, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_putuint8(&b, 0); + + /* convert client address to ascii text */ + isc_buffer_init(&b2, clientstr, sizeof(clientstr)); + isc_netaddr_fromsockaddr(&netaddr, clientaddr); + result = isc_netaddr_totext(&netaddr, &b2); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_putuint8(&b2, 0); + + /* make sure strings are always lowercase */ + dns_sdlz_tolower(namestr); + dns_sdlz_tolower(clientstr); + + /* Call SDLZ driver's find zone method */ + if (imp->methods->allowzonexfr != NULL) { + MAYBE_LOCK(imp); + result = imp->methods->allowzonexfr(imp->driverarg, dbdata, + namestr, clientstr); + MAYBE_UNLOCK(imp); + /* + * if zone is supported and transfers allowed build a 'bind' + * database driver + */ + if (result == ISC_R_SUCCESS) + result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, + name, rdclass, dbp); + return (result); + } + + return (ISC_R_NOTIMPLEMENTED); +} + +static isc_result_t +dns_sdlzcreate(isc_mem_t *mctx, const char *dlzname, unsigned int argc, + char *argv[], void *driverarg, void **dbdata) +{ + dns_sdlzimplementation_t *imp; + isc_result_t result = ISC_R_NOTFOUND; + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Loading SDLZ driver."); + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(driverarg != NULL); + REQUIRE(dlzname != NULL); + REQUIRE(dbdata != NULL); + UNUSED(mctx); + + imp = driverarg; + + /* If the create method exists, call it. */ + if (imp->methods->create != NULL) { + MAYBE_LOCK(imp); + result = imp->methods->create(dlzname, argc, argv, + imp->driverarg, dbdata); + MAYBE_UNLOCK(imp); + } + + /* Write debugging message to log */ + if (result == ISC_R_SUCCESS) { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "SDLZ driver loaded successfully."); + } else { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, + "SDLZ driver failed to load."); + } + + return (result); +} + +static void +dns_sdlzdestroy(void *driverdata, void **dbdata) +{ + + dns_sdlzimplementation_t *imp; + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Unloading SDLZ driver."); + + imp = driverdata; + + /* If the destroy method exists, call it. */ + if (imp->methods->destroy != NULL) { + MAYBE_LOCK(imp); + imp->methods->destroy(imp->driverarg, dbdata); + MAYBE_UNLOCK(imp); + } +} + +static isc_result_t +dns_sdlzfindzone(void *driverarg, void *dbdata, isc_mem_t *mctx, + dns_rdataclass_t rdclass, dns_name_t *name, dns_db_t **dbp) +{ + isc_buffer_t b; + char namestr[DNS_NAME_MAXTEXT + 1]; + isc_result_t result; + dns_sdlzimplementation_t *imp; + + /* + * Perform checks to make sure data is as we expect it to be. + */ + REQUIRE(driverarg != NULL); + REQUIRE(name != NULL); + REQUIRE(dbp != NULL && *dbp == NULL); + + imp = (dns_sdlzimplementation_t *) driverarg; + + /* Convert DNS name to ascii text */ + isc_buffer_init(&b, namestr, sizeof(namestr)); + result = dns_name_totext(name, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_putuint8(&b, 0); + + /* make sure strings are always lowercase */ + dns_sdlz_tolower(namestr); + + /* Call SDLZ driver's find zone method */ + MAYBE_LOCK(imp); + result = imp->methods->findzone(imp->driverarg, dbdata, namestr); + MAYBE_UNLOCK(imp); + + /* + * if zone is supported build a 'bind' database driver + * structure to return + */ + if (result == ISC_R_SUCCESS) + result = dns_sdlzcreateDBP(mctx, driverarg, dbdata, name, + rdclass, dbp); + + return (result); +} + +static dns_dlzmethods_t sdlzmethods = { + dns_sdlzcreate, + dns_sdlzdestroy, + dns_sdlzfindzone, + dns_sdlzallowzonexfr +}; + +/* + * Public functions. + */ + +isc_result_t +dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl, + const char *data) +{ + dns_rdatalist_t *rdatalist; + dns_rdata_t *rdata; + dns_rdatatype_t typeval; + isc_consttextregion_t r; + isc_buffer_t b; + isc_buffer_t *rdatabuf = NULL; + isc_lex_t *lex; + isc_result_t result; + unsigned int size; + isc_mem_t *mctx; + dns_name_t *origin; + + REQUIRE(VALID_SDLZLOOKUP(lookup)); + REQUIRE(type != NULL); + REQUIRE(data != NULL); + + mctx = lookup->sdlz->common.mctx; + + r.base = type; + r.length = strlen(type); + result = dns_rdatatype_fromtext(&typeval, (void *) &r); + if (result != ISC_R_SUCCESS) + return (result); + + rdatalist = ISC_LIST_HEAD(lookup->lists); + while (rdatalist != NULL) { + if (rdatalist->type == typeval) + break; + rdatalist = ISC_LIST_NEXT(rdatalist, link); + } + + if (rdatalist == NULL) { + rdatalist = isc_mem_get(mctx, sizeof(dns_rdatalist_t)); + if (rdatalist == NULL) + return (ISC_R_NOMEMORY); + rdatalist->rdclass = lookup->sdlz->common.rdclass; + rdatalist->type = typeval; + rdatalist->covers = 0; + rdatalist->ttl = ttl; + ISC_LIST_INIT(rdatalist->rdata); + ISC_LINK_INIT(rdatalist, link); + ISC_LIST_APPEND(lookup->lists, rdatalist, link); + } else + if (rdatalist->ttl != ttl) + return (DNS_R_BADTTL); + + rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); + if (rdata == NULL) + return (ISC_R_NOMEMORY); + dns_rdata_init(rdata); + + if ((lookup->sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) + origin = &lookup->sdlz->common.origin; + else + origin = dns_rootname; + + lex = NULL; + result = isc_lex_create(mctx, 64, &lex); + if (result != ISC_R_SUCCESS) + goto failure; + + size = initial_size(data); + do { + isc_buffer_init(&b, data, strlen(data)); + isc_buffer_add(&b, strlen(data)); + + result = isc_lex_openbuffer(lex, &b); + if (result != ISC_R_SUCCESS) + goto failure; + + rdatabuf = NULL; + result = isc_buffer_allocate(mctx, &rdatabuf, size); + if (result != ISC_R_SUCCESS) + goto failure; + + result = dns_rdata_fromtext(rdata, rdatalist->rdclass, + rdatalist->type, lex, + origin, ISC_FALSE, + mctx, rdatabuf, + &lookup->callbacks); + if (result != ISC_R_SUCCESS) + isc_buffer_free(&rdatabuf); + size *= 2; + } while (result == ISC_R_NOSPACE); + + if (result != ISC_R_SUCCESS) + goto failure; + + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); + + if (lex != NULL) + isc_lex_destroy(&lex); + + return (ISC_R_SUCCESS); + + failure: + if (rdatabuf != NULL) + isc_buffer_free(&rdatabuf); + if (lex != NULL) + isc_lex_destroy(&lex); + isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); + + return (result); +} + +isc_result_t +dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name, + const char *type, dns_ttl_t ttl, const char *data) +{ + dns_name_t *newname, *origin; + dns_fixedname_t fnewname; + dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)allnodes->common.db; + dns_sdlznode_t *sdlznode; + isc_mem_t *mctx = sdlz->common.mctx; + isc_buffer_t b; + isc_result_t result; + + dns_fixedname_init(&fnewname); + newname = dns_fixedname_name(&fnewname); + + if ((sdlz->dlzimp->flags & DNS_SDLZFLAG_RELATIVERDATA) != 0) + origin = &sdlz->common.origin; + else + origin = dns_rootname; + isc_buffer_init(&b, name, strlen(name)); + isc_buffer_add(&b, strlen(name)); + + result = dns_name_fromtext(newname, &b, origin, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) + return (result); + + if (allnodes->common.relative_names) { + /* All names are relative to the root */ + unsigned int nlabels = dns_name_countlabels(newname); + dns_name_getlabelsequence(newname, 0, nlabels - 1, newname); + } + + sdlznode = ISC_LIST_HEAD(allnodes->nodelist); + if (sdlznode == NULL || !dns_name_equal(sdlznode->name, newname)) { + sdlznode = NULL; + result = createnode(sdlz, &sdlznode); + if (result != ISC_R_SUCCESS) + return (result); + sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t)); + if (sdlznode->name == NULL) { + destroynode(sdlznode); + return (ISC_R_NOMEMORY); + } + dns_name_init(sdlznode->name, NULL); + result = dns_name_dup(newname, mctx, sdlznode->name); + if (result != ISC_R_SUCCESS) { + isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t)); + destroynode(sdlznode); + return (result); + } + ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link); + if (allnodes->origin == NULL && + dns_name_equal(newname, &sdlz->common.origin)) + allnodes->origin = sdlznode; + } + return (dns_sdlz_putrr(sdlznode, type, ttl, data)); + +} + +isc_result_t +dns_sdlz_putsoa(dns_sdlzlookup_t *lookup, const char *mname, const char *rname, + isc_uint32_t serial) +{ + char str[2 * DNS_NAME_MAXTEXT + 5 * (sizeof("2147483647")) + 7]; + int n; + + REQUIRE(mname != NULL); + REQUIRE(rname != NULL); + + n = snprintf(str, sizeof str, "%s %s %u %u %u %u %u", + mname, rname, serial, + SDLZ_DEFAULT_REFRESH, SDLZ_DEFAULT_RETRY, + SDLZ_DEFAULT_EXPIRE, SDLZ_DEFAULT_MINIMUM); + if (n >= (int)sizeof(str) || n < 0) + return (ISC_R_NOSPACE); + return (dns_sdlz_putrr(lookup, "SOA", SDLZ_DEFAULT_TTL, str)); +} + +isc_result_t +dns_sdlzregister(const char *drivername, const dns_sdlzmethods_t *methods, + void *driverarg, unsigned int flags, isc_mem_t *mctx, + dns_sdlzimplementation_t **sdlzimp) +{ + + dns_sdlzimplementation_t *imp; + isc_result_t result; + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(drivername != NULL); + REQUIRE(methods != NULL); + REQUIRE(methods->findzone != NULL); + REQUIRE(methods->lookup != NULL); + REQUIRE(mctx != NULL); + REQUIRE(sdlzimp != NULL && *sdlzimp == NULL); + REQUIRE((flags & ~(DNS_SDLZFLAG_RELATIVEOWNER | + DNS_SDLZFLAG_RELATIVERDATA | + DNS_SDLZFLAG_THREADSAFE)) == 0); + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Registering SDLZ driver '%s'", drivername); + + /* + * Allocate memory for a sdlz_implementation object. Error if + * we cannot. + */ + imp = isc_mem_get(mctx, sizeof(dns_sdlzimplementation_t)); + if (imp == NULL) + return (ISC_R_NOMEMORY); + + /* Make sure memory region is set to all 0's */ + memset(imp, 0, sizeof(dns_sdlzimplementation_t)); + + /* Store the data passed into this method */ + imp->methods = methods; + imp->driverarg = driverarg; + imp->flags = flags; + imp->mctx = NULL; + + /* attach the new sdlz_implementation object to a memory context */ + isc_mem_attach(mctx, &imp->mctx); + + /* + * initialize the driver lock, error if we cannot + * (used if a driver does not support multiple threads) + */ + result = isc_mutex_init(&imp->driverlock); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_mutex_init() failed: %s", + isc_result_totext(result)); + goto cleanup_mctx; + } + + imp->dlz_imp = NULL; + + /* + * register the DLZ driver. Pass in our "extra" sdlz information as + * a driverarg. (that's why we stored the passed in driver arg in our + * sdlz_implementation structure) Also, store the dlz_implementation + * structure in our sdlz_implementation. + */ + result = dns_dlzregister(drivername, &sdlzmethods, imp, mctx, + &imp->dlz_imp); + + /* if registration fails, cleanup and get outta here. */ + if (result != ISC_R_SUCCESS) + goto cleanup_mutex; + + *sdlzimp = imp; + + return (ISC_R_SUCCESS); + + cleanup_mutex: + /* destroy the driver lock, we don't need it anymore */ + DESTROYLOCK(&imp->driverlock); + + cleanup_mctx: + /* + * return the memory back to the available memory pool and + * remove it from the memory context. + */ + isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); + isc_mem_detach(&mctx); + return (result); +} + +void +dns_sdlzunregister(dns_sdlzimplementation_t **sdlzimp) { + dns_sdlzimplementation_t *imp; + isc_mem_t *mctx; + + /* Write debugging message to log */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, + DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), + "Unregistering SDLZ driver."); + + /* + * Performs checks to make sure data is as we expect it to be. + */ + REQUIRE(sdlzimp != NULL && *sdlzimp != NULL); + + imp = *sdlzimp; + + /* Unregister the DLZ driver implementation */ + dns_dlzunregister(&imp->dlz_imp); + + /* destroy the driver lock, we don't need it anymore */ + DESTROYLOCK(&imp->driverlock); + + mctx = imp->mctx; + + /* + * return the memory back to the available memory pool and + * remove it from the memory context. + */ + isc_mem_put(mctx, imp, sizeof(dns_sdlzimplementation_t)); + isc_mem_detach(&mctx); + + *sdlzimp = NULL; +} diff --git a/contrib/bind9/lib/dns/soa.c b/contrib/bind9/lib/dns/soa.c index c0e0518..20198c0 100644 --- a/contrib/bind9/lib/dns/soa.c +++ b/contrib/bind9/lib/dns/soa.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: soa.c,v 1.3.206.1 2004/03/06 08:13:45 marka Exp $ */ +/* $Id: soa.c,v 1.4.18.2 2005/04/29 00:16:05 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/ssu.c b/contrib/bind9/lib/dns/ssu.c index a9ecdce..fa3011c 100644 --- a/contrib/bind9/lib/dns/ssu.c +++ b/contrib/bind9/lib/dns/ssu.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,8 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/*! \file */ /* - * $Id: ssu.c,v 1.22.206.3 2004/03/08 09:04:32 marka Exp $ + * $Id: ssu.c,v 1.24.18.4 2006/02/16 23:51:32 marka Exp $ * Principal Author: Brian Wellington */ @@ -24,9 +25,11 @@ #include <isc/magic.h> #include <isc/mem.h> +#include <isc/result.h> #include <isc/string.h> /* Required for HP/UX (and others?) */ #include <isc/util.h> +#include <dns/fixedname.h> #include <dns/name.h> #include <dns/ssu.h> @@ -38,13 +41,13 @@ struct dns_ssurule { unsigned int magic; - isc_boolean_t grant; /* is this a grant or a deny? */ - unsigned int matchtype; /* which type of pattern match? */ - dns_name_t *identity; /* the identity to match */ - dns_name_t *name; /* the name being updated */ - unsigned int ntypes; /* number of data types covered */ - dns_rdatatype_t *types; /* the data types. Can include ANY, */ - /* defaults to all but SIG,SOA,NS if NULL*/ + isc_boolean_t grant; /*%< is this a grant or a deny? */ + unsigned int matchtype; /*%< which type of pattern match? */ + dns_name_t *identity; /*%< the identity to match */ + dns_name_t *name; /*%< the name being updated */ + unsigned int ntypes; /*%< number of data types covered */ + dns_rdatatype_t *types; /*%< the data types. Can include ANY, */ + /*%< defaults to all but SIG,SOA,NS if NULL */ ISC_LINK(dns_ssurule_t) link; }; @@ -160,7 +163,7 @@ dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, REQUIRE(VALID_SSUTABLE(table)); REQUIRE(dns_name_isabsolute(identity)); REQUIRE(dns_name_isabsolute(name)); - REQUIRE(matchtype <= DNS_SSUMATCHTYPE_SELF); + REQUIRE(matchtype <= DNS_SSUMATCHTYPE_MAX); if (matchtype == DNS_SSUMATCHTYPE_WILDCARD) REQUIRE(dns_name_iswildcard(name)); if (ntypes > 0) @@ -208,8 +211,7 @@ dns_ssutable_addrule(dns_ssutable_t *table, isc_boolean_t grant, goto failure; } memcpy(rule->types, types, ntypes * sizeof(dns_rdatatype_t)); - } - else + } else rule->types = NULL; rule->magic = SSURULEMAGIC; @@ -249,6 +251,9 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, { dns_ssurule_t *rule; unsigned int i; + dns_fixedname_t fixed; + dns_name_t *wildcard; + isc_result_t result; REQUIRE(VALID_SSUTABLE(table)); REQUIRE(signer == NULL || dns_name_isabsolute(signer)); @@ -265,35 +270,39 @@ dns_ssutable_checkrules(dns_ssutable_t *table, dns_name_t *signer, if (dns_name_iswildcard(rule->identity)) { if (!dns_name_matcheswildcard(signer, rule->identity)) continue; - } - else { - if (!dns_name_equal(signer, rule->identity)) + } else if (!dns_name_equal(signer, rule->identity)) continue; - } if (rule->matchtype == DNS_SSUMATCHTYPE_NAME) { if (!dns_name_equal(name, rule->name)) continue; - } - else if (rule->matchtype == DNS_SSUMATCHTYPE_SUBDOMAIN) { + } else if (rule->matchtype == DNS_SSUMATCHTYPE_SUBDOMAIN) { if (!dns_name_issubdomain(name, rule->name)) continue; - } - else if (rule->matchtype == DNS_SSUMATCHTYPE_WILDCARD) { + } else if (rule->matchtype == DNS_SSUMATCHTYPE_WILDCARD) { if (!dns_name_matcheswildcard(name, rule->name)) continue; - - } - else if (rule->matchtype == DNS_SSUMATCHTYPE_SELF) { + } else if (rule->matchtype == DNS_SSUMATCHTYPE_SELF) { if (!dns_name_equal(signer, name)) continue; + } else if (rule->matchtype == DNS_SSUMATCHTYPE_SELFSUB) { + if (!dns_name_issubdomain(name, signer)) + continue; + } else if (rule->matchtype == DNS_SSUMATCHTYPE_SELFWILD) { + dns_fixedname_init(&fixed); + wildcard = dns_fixedname_name(&fixed); + result = dns_name_concatenate(dns_wildcardname, signer, + wildcard, NULL); + if (result != ISC_R_SUCCESS) + continue; + if (!dns_name_matcheswildcard(name, wildcard)) + continue; } if (rule->ntypes == 0) { if (!isusertype(type)) continue; - } - else { + } else { for (i = 0; i < rule->ntypes; i++) { if (rule->types[i] == dns_rdatatype_any || rule->types[i] == type) diff --git a/contrib/bind9/lib/dns/stats.c b/contrib/bind9/lib/dns/stats.c index aefcbe0..660046f 100644 --- a/contrib/bind9/lib/dns/stats.c +++ b/contrib/bind9/lib/dns/stats.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: stats.c,v 1.5.206.1 2004/03/06 08:13:46 marka Exp $ */ +/* $Id: stats.c,v 1.6.18.4 2005/06/27 00:20:02 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -30,7 +32,9 @@ LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] = "nxrrset", "nxdomain", "recursion", - "failure" + "failure", + "duplicate", + "dropped" }; isc_result_t diff --git a/contrib/bind9/lib/dns/tcpmsg.c b/contrib/bind9/lib/dns/tcpmsg.c index a0fddcd..018c4ce 100644 --- a/contrib/bind9/lib/dns/tcpmsg.c +++ b/contrib/bind9/lib/dns/tcpmsg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tcpmsg.c,v 1.24.206.3 2006/08/10 23:59:28 marka Exp $ */ +/* $Id: tcpmsg.c,v 1.25.18.4 2006/08/10 23:59:29 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/time.c b/contrib/bind9/lib/dns/time.c index 770f021..b4e7bee 100644 --- a/contrib/bind9/lib/dns/time.c +++ b/contrib/bind9/lib/dns/time.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: time.c,v 1.18.2.4.2.8 2004/08/28 06:25:20 marka Exp $ */ +/* $Id: time.c,v 1.26.18.3 2005/04/29 00:16:06 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/timer.c b/contrib/bind9/lib/dns/timer.c index b364f54..b225722 100644 --- a/contrib/bind9/lib/dns/timer.c +++ b/contrib/bind9/lib/dns/timer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: timer.c,v 1.2.206.1 2004/03/06 08:13:46 marka Exp $ */ +/* $Id: timer.c,v 1.3.18.2 2005/04/29 00:16:06 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/tkey.c b/contrib/bind9/lib/dns/tkey.c index ca793d2..e4dbdc7 100644 --- a/contrib/bind9/lib/dns/tkey.c +++ b/contrib/bind9/lib/dns/tkey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,9 +16,9 @@ */ /* - * $Id: tkey.c,v 1.71.2.1.10.9 2006/01/04 23:50:20 marka Exp $ + * $Id: tkey.c,v 1.76.18.5 2005/11/30 03:44:39 marka Exp $ */ - +/*! \file */ #include <config.h> #include <isc/buffer.h> diff --git a/contrib/bind9/lib/dns/tsig.c b/contrib/bind9/lib/dns/tsig.c index 9bdde06..c5107b5 100644 --- a/contrib/bind9/lib/dns/tsig.c +++ b/contrib/bind9/lib/dns/tsig.c @@ -16,9 +16,9 @@ */ /* - * $Id: tsig.c,v 1.112.2.3.8.10 2006/05/02 04:21:42 marka Exp $ + * $Id: tsig.c,v 1.117.18.9 2006/05/02 04:23:12 marka Exp $ */ - +/*! \file */ #include <config.h> #include <stdlib.h> @@ -48,6 +48,11 @@ #define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR) #define algname_is_allocated(algname) \ ((algname) != dns_tsig_hmacmd5_name && \ + (algname) != dns_tsig_hmacsha1_name && \ + (algname) != dns_tsig_hmacsha224_name && \ + (algname) != dns_tsig_hmacsha256_name && \ + (algname) != dns_tsig_hmacsha384_name && \ + (algname) != dns_tsig_hmacsha512_name && \ (algname) != dns_tsig_gssapi_name && \ (algname) != dns_tsig_gssapims_name) @@ -96,6 +101,76 @@ static dns_name_t gsstsigms = { LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_gssapims_name = &gsstsigms; +static unsigned char hmacsha1_ndata[] = "\011hmac-sha1"; +static unsigned char hmacsha1_offsets[] = { 0, 10 }; + +static dns_name_t hmacsha1 = { + DNS_NAME_MAGIC, + hmacsha1_ndata, 11, 2, + DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, + hmacsha1_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} +}; + +LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1; + +static unsigned char hmacsha224_ndata[] = "\013hmac-sha224"; +static unsigned char hmacsha224_offsets[] = { 0, 12 }; + +static dns_name_t hmacsha224 = { + DNS_NAME_MAGIC, + hmacsha224_ndata, 13, 2, + DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, + hmacsha224_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} +}; + +LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224; + +static unsigned char hmacsha256_ndata[] = "\013hmac-sha256"; +static unsigned char hmacsha256_offsets[] = { 0, 12 }; + +static dns_name_t hmacsha256 = { + DNS_NAME_MAGIC, + hmacsha256_ndata, 13, 2, + DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, + hmacsha256_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} +}; + +LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256; + +static unsigned char hmacsha384_ndata[] = "\013hmac-sha384"; +static unsigned char hmacsha384_offsets[] = { 0, 12 }; + +static dns_name_t hmacsha384 = { + DNS_NAME_MAGIC, + hmacsha384_ndata, 13, 2, + DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, + hmacsha384_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} +}; + +LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384; + +static unsigned char hmacsha512_ndata[] = "\013hmac-sha512"; +static unsigned char hmacsha512_offsets[] = { 0, 12 }; + +static dns_name_t hmacsha512 = { + DNS_NAME_MAGIC, + hmacsha512_ndata, 13, 2, + DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, + hmacsha512_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} +}; + +LIBDNS_EXTERNAL_DATA dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512; + static isc_result_t tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg); @@ -137,6 +212,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, REQUIRE(name != NULL); REQUIRE(algorithm != NULL); REQUIRE(mctx != NULL); + REQUIRE(key != NULL || ring != NULL); tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t)); if (tkey == NULL) @@ -154,6 +230,40 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, ret = DNS_R_BADALG; goto cleanup_name; } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { + tkey->algorithm = DNS_TSIG_HMACSHA1_NAME; + if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) { + ret = DNS_R_BADALG; + goto cleanup_name; + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { + tkey->algorithm = DNS_TSIG_HMACSHA224_NAME; + if (dstkey != NULL && + dst_key_alg(dstkey) != DST_ALG_HMACSHA224) { + ret = DNS_R_BADALG; + goto cleanup_name; + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { + tkey->algorithm = DNS_TSIG_HMACSHA256_NAME; + if (dstkey != NULL && + dst_key_alg(dstkey) != DST_ALG_HMACSHA256) { + ret = DNS_R_BADALG; + goto cleanup_name; + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { + tkey->algorithm = DNS_TSIG_HMACSHA384_NAME; + if (dstkey != NULL && + dst_key_alg(dstkey) != DST_ALG_HMACSHA384) { + ret = DNS_R_BADALG; + goto cleanup_name; + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { + tkey->algorithm = DNS_TSIG_HMACSHA512_NAME; + if (dstkey != NULL && + dst_key_alg(dstkey) != DST_ALG_HMACSHA512) { + ret = DNS_R_BADALG; + goto cleanup_name; + } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPI_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { @@ -202,20 +312,14 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, tkey->key = dstkey; tkey->ring = ring; - if (ring != NULL) { - RWLOCK(&ring->lock, isc_rwlocktype_write); - ret = dns_rbt_addname(ring->keys, name, tkey); - if (ret != ISC_R_SUCCESS) { - RWUNLOCK(&ring->lock, isc_rwlocktype_write); - goto cleanup_algorithm; - } - refs++; - RWUNLOCK(&ring->lock, isc_rwlocktype_write); - } - if (key != NULL) refs++; - isc_refcount_init(&tkey->refs, refs); + if (ring != NULL) + refs++; + ret = isc_refcount_init(&tkey->refs, refs); + if (ret != ISC_R_SUCCESS) + goto cleanup_creator; + tkey->generated = generated; tkey->inception = inception; tkey->expire = expire; @@ -223,6 +327,16 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, tkey->magic = TSIG_MAGIC; + if (ring != NULL) { + RWLOCK(&ring->lock, isc_rwlocktype_write); + ret = dns_rbt_addname(ring->keys, name, tkey); + if (ret != ISC_R_SUCCESS) { + RWUNLOCK(&ring->lock, isc_rwlocktype_write); + goto cleanup_refs; + } + RWUNLOCK(&ring->lock, isc_rwlocktype_write); + } + if (dstkey != NULL && dst_key_size(dstkey) < 64) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); @@ -236,6 +350,16 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, return (ISC_R_SUCCESS); + cleanup_refs: + tkey->magic = 0; + while (refs-- > 0) + isc_refcount_decrement(&tkey->refs, NULL); + isc_refcount_destroy(&tkey->refs); + cleanup_creator: + if (tkey->creator != NULL) { + dns_name_free(tkey->creator, mctx); + isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); + } cleanup_algorithm: if (algname_is_allocated(tkey->algorithm)) { if (dns_name_dynamic(tkey->algorithm)) @@ -264,22 +388,93 @@ dns_tsigkey_create(dns_name_t *name, dns_name_t *algorithm, if (length > 0) REQUIRE(secret != NULL); - if (!dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME) && length > 0) + if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { + if (secret != NULL) { + isc_buffer_t b; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + result = dst_key_frombuffer(name, DST_ALG_HMACMD5, + DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, + dns_rdataclass_in, + &b, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (result); + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { + if (secret != NULL) { + isc_buffer_t b; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + result = dst_key_frombuffer(name, DST_ALG_HMACSHA1, + DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, + dns_rdataclass_in, + &b, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (result); + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { + if (secret != NULL) { + isc_buffer_t b; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + result = dst_key_frombuffer(name, DST_ALG_HMACSHA224, + DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, + dns_rdataclass_in, + &b, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (result); + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { + if (secret != NULL) { + isc_buffer_t b; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + result = dst_key_frombuffer(name, DST_ALG_HMACSHA256, + DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, + dns_rdataclass_in, + &b, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (result); + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { + if (secret != NULL) { + isc_buffer_t b; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + result = dst_key_frombuffer(name, DST_ALG_HMACSHA384, + DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, + dns_rdataclass_in, + &b, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (result); + } + } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { + if (secret != NULL) { + isc_buffer_t b; + + isc_buffer_init(&b, secret, length); + isc_buffer_add(&b, length); + result = dst_key_frombuffer(name, DST_ALG_HMACSHA512, + DNS_KEYOWNER_ENTITY, + DNS_KEYPROTO_DNSSEC, + dns_rdataclass_in, + &b, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (result); + } + } else if (length > 0) return (DNS_R_BADALG); - if (secret != NULL) { - isc_buffer_t b; - - isc_buffer_init(&b, secret, length); - isc_buffer_add(&b, length); - result = dst_key_frombuffer(name, DST_ALG_HMACMD5, - DNS_KEYOWNER_ENTITY, - DNS_KEYPROTO_DNSSEC, - dns_rdataclass_in, - &b, mctx, &dstkey); - if (result != ISC_R_SUCCESS) - return (result); - } result = dns_tsigkey_createfromkey(name, algorithm, dstkey, generated, creator, inception, expire, mctx, ring, key); @@ -423,6 +618,7 @@ dns_tsig_sign(dns_message_t *msg) { if (key->key != NULL && tsig.error != dns_tsigerror_badsig) { unsigned char header[DNS_MESSAGE_HEADERLEN]; isc_buffer_t headerbuf; + isc_uint16_t digestbits; ret = dst_context_create(key->key, mctx, &ctx); if (ret != ISC_R_SUCCESS) @@ -549,7 +745,16 @@ dns_tsig_sign(dns_message_t *msg) { if (ret != ISC_R_SUCCESS) goto cleanup_signature; dst_context_destroy(&ctx); - tsig.siglen = isc_buffer_usedlength(&sigbuf); + digestbits = dst_key_getbits(key->key); + if (digestbits != 0) { + unsigned int bytes = (digestbits + 1) / 8; + if (is_response(msg) && bytes < querytsig.siglen) + bytes = querytsig.siglen; + if (bytes > isc_buffer_usedlength(&sigbuf)) + bytes = isc_buffer_usedlength(&sigbuf); + tsig.siglen = bytes; + } else + tsig.siglen = isc_buffer_usedlength(&sigbuf); } else { tsig.siglen = 0; tsig.signature = NULL; @@ -640,6 +845,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, dst_context_t *ctx = NULL; isc_mem_t *mctx; isc_uint16_t addcount, id; + unsigned int siglen; + unsigned int alg; REQUIRE(source != NULL); REQUIRE(DNS_MESSAGE_VALID(msg)); @@ -752,6 +959,42 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, return (DNS_R_CLOCKSKEW); } + /* + * Check digest length. + */ + alg = dst_key_alg(key); + ret = dst_key_sigsize(key, &siglen); + if (ret != ISC_R_SUCCESS) + return (ret); + if (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 || + alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || + alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512) { + isc_uint16_t digestbits = dst_key_getbits(key); + if (tsig.siglen > siglen) { + tsig_log(msg->tsigkey, 2, "signature length to big"); + return (DNS_R_FORMERR); + } + if (tsig.siglen > 0 && + (tsig.siglen < 10 || tsig.siglen < ((siglen + 1) / 2))) { + tsig_log(msg->tsigkey, 2, + "signature length below minimum"); + return (DNS_R_FORMERR); + } + if (tsig.siglen > 0 && digestbits != 0 && + tsig.siglen < ((digestbits + 1) / 8)) { + msg->tsigstatus = dns_tsigerror_badtrunc; + tsig_log(msg->tsigkey, 2, + "truncated signature length too small"); + return (DNS_R_TSIGVERIFYFAILURE); + } + if (tsig.siglen > 0 && digestbits == 0 && + tsig.siglen < siglen) { + msg->tsigstatus = dns_tsigerror_badtrunc; + tsig_log(msg->tsigkey, 2, "signature length too small"); + return (DNS_R_TSIGVERIFYFAILURE); + } + } + if (tsig.siglen > 0) { sig_r.base = tsig.signature; sig_r.length = tsig.siglen; @@ -1186,12 +1429,8 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) { return (ISC_R_NOMEMORY); result = isc_rwlock_init(&ring->lock, 0, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_rwlock_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } + if (result != ISC_R_SUCCESS) + return (result); ring->keys = NULL; result = dns_rbt_create(mctx, free_tsignode, NULL, &ring->keys); diff --git a/contrib/bind9/lib/dns/ttl.c b/contrib/bind9/lib/dns/ttl.c index 1dad0fb..39d2ac3 100644 --- a/contrib/bind9/lib/dns/ttl.c +++ b/contrib/bind9/lib/dns/ttl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ttl.c,v 1.21.12.5 2004/03/08 09:04:32 marka Exp $ */ +/* $Id: ttl.c,v 1.25.18.2 2005/04/29 00:16:07 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index 571ad79..a92d647 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.91.2.5.8.27.6.1 2007/01/11 04:51:39 marka Exp $ */ +/* $Id: validator.c,v 1.119.18.29 2007/01/08 02:41:59 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -69,9 +71,9 @@ * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep -> * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure * - * \li When called without a rdataset and with DNS_VALIDATOR_DLV: - * validator_start -> startfinddlvsep -> dlv_validator_start -> - * validator_start -> nsecvalidate -> proveunsecure + * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate() + * to always validate the authority section even when it does not contain + * signatures. * * validator_start: determines what type of validation to do. * validate: attempts to perform a positive validation. @@ -90,7 +92,6 @@ * have attempted a verify. */ #define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */ #define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */ -#define VALATTR_AUTHNONPENDING 0x0040 /*%< Tidy up pending auth. */ /*! * NSEC proofs to be looked for. @@ -155,18 +156,11 @@ dlv_validator_start(dns_validator_t *val); static isc_result_t finddlvsep(dns_validator_t *val, isc_boolean_t resume); -static void -auth_nonpending(dns_message_t *message); - static isc_result_t startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure); /*% * Mark the RRsets as a answer. - * - * If VALATTR_AUTHNONPENDING is set then this is a negative answer - * in a insecure zone. We need to mark any pending RRsets as - * dns_trust_authauthority answers (this is deferred from resolver.c). */ static inline void markanswer(dns_validator_t *val) { @@ -175,9 +169,6 @@ markanswer(dns_validator_t *val) { val->event->rdataset->trust = dns_trust_answer; if (val->event->sigrdataset != NULL) val->event->sigrdataset->trust = dns_trust_answer; - if (val->event->message != NULL && - (val->attributes & VALATTR_AUTHNONPENDING) != 0) - auth_nonpending(val->event->message); } static void @@ -217,31 +208,6 @@ exit_check(dns_validator_t *val) { } /*% - * Mark pending answers in the authority section as dns_trust_authauthority. - */ -static void -auth_nonpending(dns_message_t *message) { - isc_result_t result; - dns_name_t *name; - dns_rdataset_t *rdataset; - - for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); - result == ISC_R_SUCCESS; - result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) - { - name = NULL; - dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); - for (rdataset = ISC_LIST_HEAD(name->list); - rdataset != NULL; - rdataset = ISC_LIST_NEXT(rdataset, link)) - { - if (rdataset->trust == dns_trust_pending) - rdataset->trust = dns_trust_authauthority; - } - } -} - -/*% * Look in the NSEC record returned from a DS query to see if there is * a NS RRset at this name. If it is found we are at a delegation point. */ @@ -613,6 +579,8 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, unsigned int olabels, nlabels, labels; dns_rdata_nsec_t nsec; isc_boolean_t atparent; + isc_boolean_t ns; + isc_boolean_t soa; REQUIRE(exists != NULL); REQUIRE(data != NULL); @@ -644,9 +612,9 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, * The names are the same. */ atparent = dns_rdatatype_atparent(val->event->type); - if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) && - !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) - { + ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); + soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa); + if (ns && !soa) { if (!atparent) { /* * This NSEC record is from somewhere higher in @@ -657,7 +625,7 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, "ignoring parent nsec"); return (ISC_R_IGNORE); } - } else if (atparent) { + } else if (atparent && ns && soa) { /* * This NSEC record is from the child. * It can not be legitimately used here. @@ -666,12 +634,20 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, "ignoring child nsec"); return (ISC_R_IGNORE); } - *exists = ISC_TRUE; - *data = dns_nsec_typepresent(&rdata, val->event->type); - validator_log(val, ISC_LOG_DEBUG(3), - "nsec proves name exists (owner) data=%d", - *data); - return (ISC_R_SUCCESS); + if (val->event->type == dns_rdatatype_cname || + val->event->type == dns_rdatatype_nxt || + val->event->type == dns_rdatatype_nsec || + val->event->type == dns_rdatatype_key || + !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) { + *exists = ISC_TRUE; + *data = dns_nsec_typepresent(&rdata, val->event->type); + validator_log(val, ISC_LOG_DEBUG(3), + "nsec proves name exists (owner) data=%d", + *data); + return (ISC_R_SUCCESS); + } + validator_log(val, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists"); + return (ISC_R_IGNORE); } if (relation == dns_namereln_subdomain && @@ -731,6 +707,7 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, result = dns_name_concatenate(dns_wildcardname, &common, wild, NULL); if (result != ISC_R_SUCCESS) { + dns_rdata_freestruct(&nsec); validator_log(val, ISC_LOG_DEBUG(3), "failure generating wildcard name"); return (result); @@ -784,6 +761,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) { } } else { dns_name_t **proofs = val->event->proofs; + dns_name_t *wild = dns_fixedname_name(&val->wild); if (rdataset->trust == dns_trust_secure) val->seensig = ISC_TRUE; @@ -795,10 +773,9 @@ authvalidated(isc_task_t *task, isc_event_t *event) { (val->attributes & VALATTR_FOUNDNODATA) == 0 && (val->attributes & VALATTR_FOUNDNOQNAME) == 0 && nsecnoexistnodata(val, val->event->name, devent->name, - rdataset, &exists, &data, - dns_fixedname_name(&val->wild)) + rdataset, &exists, &data, wild) == ISC_R_SUCCESS) - { + { if (exists && !data) { val->attributes |= VALATTR_FOUNDNODATA; if (NEEDNODATA(val)) @@ -1285,15 +1262,27 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, { isc_result_t result; dns_fixedname_t fixed; + isc_boolean_t ignore = ISC_FALSE; val->attributes |= VALATTR_TRIEDVERIFY; dns_fixedname_init(&fixed); + again: result = dns_dnssec_verify2(val->event->name, val->event->rdataset, - key, ISC_FALSE, val->view->mctx, rdata, + key, ignore, val->view->mctx, rdata, dns_fixedname_name(&fixed)); - validator_log(val, ISC_LOG_DEBUG(3), - "verify rdataset (keyid=%u): %s", - keyid, isc_result_totext(result)); + if (result == DNS_R_SIGEXPIRED && val->view->acceptexpired) { + ignore = ISC_TRUE; + goto again; + } + if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD)) + validator_log(val, ISC_LOG_INFO, + "accepted expired %sRRSIG (keyid=%u)", + (result == DNS_R_FROMWILDCARD) ? + "wildcard " : "", keyid); + else + validator_log(val, ISC_LOG_DEBUG(3), + "verify rdataset (keyid=%u): %s", + keyid, isc_result_totext(result)); if (result == DNS_R_FROMWILDCARD) { if (!dns_name_equal(val->event->name, dns_fixedname_name(&fixed))) @@ -1485,6 +1474,7 @@ dlv_validatezonekey(dns_validator_t *val) { isc_boolean_t supported_algorithm; isc_result_t result; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; + isc_uint8_t digest_type; validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey"); @@ -1495,6 +1485,31 @@ dlv_validatezonekey(dns_validator_t *val) { */ supported_algorithm = ISC_FALSE; + /* + * If DNS_DSDIGEST_SHA256 is present we are required to prefer + * it over DNS_DSDIGEST_SHA1. This in practice means that we + * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 + * is present. + */ + digest_type = DNS_DSDIGEST_SHA1; + for (result = dns_rdataset_first(&val->dlv); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&val->dlv)) { + dns_rdata_reset(&dlvrdata); + dns_rdataset_current(&val->dlv, &dlvrdata); + dns_rdata_tostruct(&dlvrdata, &dlv, NULL); + + if (!dns_resolver_algorithm_supported(val->view->resolver, + val->event->name, + dlv.algorithm)) + continue; + + if (dlv.digest_type == DNS_DSDIGEST_SHA256) { + digest_type = DNS_DSDIGEST_SHA256; + break; + } + } + for (result = dns_rdataset_first(&val->dlv); result == ISC_R_SUCCESS; result = dns_rdataset_next(&val->dlv)) @@ -1503,8 +1518,14 @@ dlv_validatezonekey(dns_validator_t *val) { dns_rdataset_current(&val->dlv, &dlvrdata); (void)dns_rdata_tostruct(&dlvrdata, &dlv, NULL); - if (dlv.digest_type != DNS_DSDIGEST_SHA1 || - !dns_resolver_algorithm_supported(val->view->resolver, + if (!dns_resolver_digest_supported(val->view->resolver, + dlv.digest_type)) + continue; + + if (dlv.digest_type != digest_type) + continue; + + if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, dlv.algorithm)) continue; @@ -1627,6 +1648,7 @@ validatezonekey(dns_validator_t *val) { dst_key_t *dstkey; isc_boolean_t supported_algorithm; isc_boolean_t atsep = ISC_FALSE; + isc_uint8_t digest_type; /* * Caller must be holding the validator lock. @@ -1796,6 +1818,31 @@ validatezonekey(dns_validator_t *val) { supported_algorithm = ISC_FALSE; + /* + * If DNS_DSDIGEST_SHA256 is present we are required to prefer + * it over DNS_DSDIGEST_SHA1. This in practice means that we + * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 + * is present. + */ + digest_type = DNS_DSDIGEST_SHA1; + for (result = dns_rdataset_first(val->dsset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(val->dsset)) { + dns_rdata_reset(&dsrdata); + dns_rdataset_current(val->dsset, &dsrdata); + dns_rdata_tostruct(&dsrdata, &ds, NULL); + + if (!dns_resolver_algorithm_supported(val->view->resolver, + val->event->name, + ds.algorithm)) + continue; + + if (ds.digest_type == DNS_DSDIGEST_SHA256) { + digest_type = DNS_DSDIGEST_SHA256; + break; + } + } + for (result = dns_rdataset_first(val->dsset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->dsset)) @@ -1804,8 +1851,13 @@ validatezonekey(dns_validator_t *val) { dns_rdataset_current(val->dsset, &dsrdata); (void)dns_rdata_tostruct(&dsrdata, &ds, NULL); - if (ds.digest_type != DNS_DSDIGEST_SHA1) + if (!dns_resolver_digest_supported(val->view->resolver, + ds.digest_type)) continue; + + if (ds.digest_type != digest_type) + continue; + if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, ds.algorithm)) @@ -2044,12 +2096,6 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { if (rdataset->type == dns_rdatatype_rrsig) continue; - if (rdataset->type == dns_rdatatype_soa) { - val->soaset = rdataset; - val->soaname = name; - } else if (rdataset->type == dns_rdatatype_nsec) - val->nsecset = rdataset; - for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, @@ -2059,8 +2105,6 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { sigrdataset->covers == rdataset->type) break; } - if (sigrdataset == NULL) - continue; /* * If a signed zone is missing the zone key, bad * things could happen. A query for data in the zone @@ -2149,7 +2193,6 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) not found"); - val->attributes |= VALATTR_AUTHNONPENDING; val->attributes |= VALATTR_INSECURITY; return (proveunsecure(val, ISC_FALSE)); } @@ -2166,7 +2209,8 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdataset_current(rdataset, &dsrdata); (void)dns_rdata_tostruct(&dsrdata, &ds, NULL); - if (ds.digest_type == DNS_DSDIGEST_SHA1 && + if (dns_resolver_digest_supported(val->view->resolver, + ds.digest_type) && dns_resolver_algorithm_supported(val->view->resolver, name, ds.algorithm)) { dns_rdata_reset(&dsrdata); @@ -2506,11 +2550,21 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { namebuf); result = view_find(val, tname, dns_rdatatype_ds); + if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) { /* * There is no DS. If this is a delegation, * we maybe done. */ + if (val->frdataset.trust == dns_trust_pending) { + result = create_fetch(val, tname, + dns_rdatatype_ds, + dsfetched2, + "proveunsecure"); + if (result != ISC_R_SUCCESS) + goto out; + return (DNS_R_WAIT); + } if (val->frdataset.trust < dns_trust_secure) { /* * This shouldn't happen, since the negative @@ -2675,7 +2729,8 @@ validator_start(isc_task_t *task, isc_event_t *event) { LOCK(&val->lock); - if ((val->options & DNS_VALIDATOR_DLV) != 0) { + if ((val->options & DNS_VALIDATOR_DLV) != 0 && + val->event->rdataset != NULL) { validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV"); result = startfinddlvsep(val, dns_rootname); } else if (val->event->rdataset != NULL && @@ -2812,9 +2867,6 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, val->keyset = NULL; val->dsset = NULL; dns_rdataset_init(&val->dlv); - val->soaset = NULL; - val->nsecset = NULL; - val->soaname = NULL; val->seensig = ISC_FALSE; val->havedlvsep = ISC_FALSE; val->depth = 0; diff --git a/contrib/bind9/lib/dns/version.c b/contrib/bind9/lib/dns/version.c index 6b043ab..1c03774 100644 --- a/contrib/bind9/lib/dns/version.c +++ b/contrib/bind9/lib/dns/version.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: version.c,v 1.9.12.3 2004/03/08 09:04:33 marka Exp $ */ +/* $Id: version.c,v 1.11.18.2 2005/04/29 00:16:07 marka Exp $ */ + +/*! \file */ #include <dns/version.h> diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c index ac7af61..4938597 100644 --- a/contrib/bind9/lib/dns/view.c +++ b/contrib/bind9/lib/dns/view.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.103.2.5.2.14 2004/03/10 02:55:58 marka Exp $ */ +/* $Id: view.c,v 1.126.18.11 2006/03/09 23:38:21 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -24,10 +26,12 @@ #include <isc/string.h> /* Required for HP/UX (and others?) */ #include <isc/util.h> +#include <dns/acache.h> #include <dns/acl.h> #include <dns/adb.h> #include <dns/cache.h> #include <dns/db.h> +#include <dns/dlz.h> #include <dns/events.h> #include <dns/forward.h> #include <dns/keytable.h> @@ -76,13 +80,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, goto cleanup_view; } result = isc_mutex_init(&view->lock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_name; - } + view->zonetable = NULL; result = dns_zt_create(mctx, rdclass, &view->zonetable); if (result != ISC_R_SUCCESS) { @@ -120,8 +120,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, goto cleanup_trustedkeys; } + view->acache = NULL; view->cache = NULL; view->cachedb = NULL; + view->dlzdatabase = NULL; view->hints = NULL; view->resolver = NULL; view->adb = NULL; @@ -130,7 +132,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->rdclass = rdclass; view->frozen = ISC_FALSE; view->task = NULL; - isc_refcount_init(&view->references, 1); + result = isc_refcount_init(&view->references, 1); + if (result != ISC_R_SUCCESS) + goto cleanup_fwdtable; view->weakrefs = 0; view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| DNS_VIEWATTR_REQSHUTDOWN); @@ -141,7 +145,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->matchrecursiveonly = ISC_FALSE; result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); if (result != ISC_R_SUCCESS) - goto cleanup_fwdtable; + goto cleanup_references; view->peers = NULL; view->order = NULL; view->delonly = NULL; @@ -156,6 +160,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->additionalfromcache = ISC_TRUE; view->additionalfromauth = ISC_TRUE; view->enablednssec = ISC_TRUE; + view->enablevalidation = ISC_TRUE; + view->acceptexpired = ISC_FALSE; view->minimalresponses = ISC_FALSE; view->transfer_format = dns_one_answer; view->queryacl = NULL; @@ -169,6 +175,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->preferred_glue = 0; view->flush = ISC_FALSE; view->dlv = NULL; + view->maxudp = 0; dns_fixedname_init(&view->dlv_fixed); result = dns_order_create(view->mctx, &view->order); @@ -208,6 +215,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, cleanup_dynkeys: dns_tsigkeyring_destroy(&view->dynamickeys); + cleanup_references: + isc_refcount_destroy(&view->references); + cleanup_fwdtable: dns_fwdtable_destroy(&view->fwdtable); @@ -253,12 +263,19 @@ destroy(dns_view_t *view) { dns_adb_detach(&view->adb); if (view->resolver != NULL) dns_resolver_detach(&view->resolver); + if (view->acache != NULL) { + if (view->cachedb != NULL) + dns_acache_putdb(view->acache, view->cachedb); + dns_acache_detach(&view->acache); + } if (view->requestmgr != NULL) dns_requestmgr_detach(&view->requestmgr); if (view->task != NULL) isc_task_detach(&view->task); if (view->hints != NULL) dns_db_detach(&view->hints); + if (view->dlzdatabase != NULL) + dns_dlzdestroy(&view->dlzdatabase); if (view->cachedb != NULL) dns_db_detach(&view->cachedb); if (view->cache != NULL) @@ -365,6 +382,8 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { dns_adb_shutdown(view->adb); if (!REQSHUTDOWN(view)) dns_requestmgr_shutdown(view->requestmgr); + if (view->acache != NULL) + dns_acache_shutdown(view->acache); if (view->flush) dns_zt_flushanddetach(&view->zonetable); else @@ -585,12 +604,17 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache) { REQUIRE(!view->frozen); if (view->cache != NULL) { + if (view->acache != NULL) + dns_acache_putdb(view->acache, view->cachedb); dns_db_detach(&view->cachedb); dns_cache_detach(&view->cache); } dns_cache_attach(cache, &view->cache); dns_cache_attachdb(cache, &view->cachedb); INSIST(DNS_DB_VALID(view->cachedb)); + + if (view->acache != NULL) + dns_acache_setdb(view->acache, view->cachedb); } void @@ -1198,8 +1222,12 @@ dns_view_flushcache(dns_view_t *view) { result = dns_cache_flush(view->cache); if (result != ISC_R_SUCCESS) return (result); + if (view->acache != NULL) + dns_acache_putdb(view->acache, view->cachedb); dns_db_detach(&view->cachedb); dns_cache_attachdb(view->cache, &view->cachedb); + if (view->acache != NULL) + dns_acache_setdb(view->acache, view->cachedb); dns_adb_flush(view->adb); return (ISC_R_SUCCESS); @@ -1330,3 +1358,9 @@ dns_view_getrootdelonly(dns_view_t *view) { REQUIRE(DNS_VIEW_VALID(view)); return (view->rootdelonly); } + +isc_result_t +dns_view_freezezones(dns_view_t *view, isc_boolean_t value) { + REQUIRE(DNS_VIEW_VALID(view)); + return (dns_zt_freezezones(view->zonetable, value)); +} diff --git a/contrib/bind9/lib/dns/xfrin.c b/contrib/bind9/lib/dns/xfrin.c index fdeed14..bec8501 100644 --- a/contrib/bind9/lib/dns/xfrin.c +++ b/contrib/bind9/lib/dns/xfrin.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.124.2.4.2.16 2006/07/19 01:04:24 marka Exp $ */ +/* $Id: xfrin.c,v 1.135.18.11 2006/07/19 00:58:01 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -51,7 +53,7 @@ * Incoming AXFR and IXFR. */ -/* +/*% * It would be non-sensical (or at least obtuse) to use FAIL() with an * ISC_R_SUCCESS code, but the test is there to keep the Solaris compiler * from complaining about "end-of-loop code not reached". @@ -66,7 +68,7 @@ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) -/* +/*% * The states of the *XFR state machine. We handle both IXFR and AXFR * with a single integrated state machine because they cannot be distinguished * immediately - an AXFR response to an IXFR request can only be detected @@ -85,7 +87,7 @@ typedef enum { XFRST_END } xfrin_state_t; -/* +/*% * Incoming zone transfer context. */ @@ -100,18 +102,18 @@ struct dns_xfrin_ctx { isc_timer_t *timer; isc_socketmgr_t *socketmgr; - int connects; /* Connect in progress */ - int sends; /* Send in progress */ - int recvs; /* Receive in progress */ + int connects; /*%< Connect in progress */ + int sends; /*%< Send in progress */ + int recvs; /*%< Receive in progress */ isc_boolean_t shuttingdown; - dns_name_t name; /* Name of zone to transfer */ + dns_name_t name; /*%< Name of zone to transfer */ dns_rdataclass_t rdclass; isc_boolean_t checkid; dns_messageid_t id; - /* + /*% * Requested transfer type (dns_rdatatype_axfr or * dns_rdatatype_ixfr). The actual transfer type * may differ due to IXFR->AXFR fallback. @@ -122,32 +124,32 @@ struct dns_xfrin_ctx { isc_sockaddr_t sourceaddr; isc_socket_t *socket; - /* Buffer for IXFR/AXFR request message */ + /*% Buffer for IXFR/AXFR request message */ isc_buffer_t qbuffer; unsigned char qbuffer_data[512]; - /* Incoming reply TCP message */ + /*% Incoming reply TCP message */ dns_tcpmsg_t tcpmsg; isc_boolean_t tcpmsg_valid; dns_db_t *db; dns_dbversion_t *ver; - dns_diff_t diff; /* Pending database changes */ - int difflen; /* Number of pending tuples */ + dns_diff_t diff; /*%< Pending database changes */ + int difflen; /*%< Number of pending tuples */ xfrin_state_t state; isc_uint32_t end_serial; isc_boolean_t is_ixfr; - unsigned int nmsg; /* Number of messages recvd */ + unsigned int nmsg; /*%< Number of messages recvd */ - dns_tsigkey_t *tsigkey; /* Key used to create TSIG */ - isc_buffer_t *lasttsig; /* The last TSIG */ - dst_context_t *tsigctx; /* TSIG verification context */ - unsigned int sincetsig; /* recvd since the last TSIG */ + dns_tsigkey_t *tsigkey; /*%< Key used to create TSIG */ + isc_buffer_t *lasttsig; /*%< The last TSIG */ + dst_context_t *tsigctx; /*%< TSIG verification context */ + unsigned int sincetsig; /*%< recvd since the last TSIG */ dns_xfrindone_t done; - /* + /*% * AXFR- and IXFR-specific data. Only one is used at a time * according to the is_ixfr flag, so this could be a union, * but keeping them separate makes it a bit simpler to clean @@ -224,14 +226,14 @@ static isc_result_t render(dns_message_t *msg, isc_mem_t *mctx, isc_buffer_t *buf); static void -xfrin_logv(int level, dns_name_t *zonename, dns_rdataclass_t rdclass, - isc_sockaddr_t *masteraddr, const char *fmt, va_list ap) - ISC_FORMAT_PRINTF(5, 0); +xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr, + const char *fmt, va_list ap) + ISC_FORMAT_PRINTF(4, 0); static void -xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass, - isc_sockaddr_t *masteraddr, const char *fmt, ...) - ISC_FORMAT_PRINTF(5, 6); +xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr, + const char *fmt, ...) + ISC_FORMAT_PRINTF(4, 5); static void xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) @@ -457,7 +459,7 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, FAIL(DNS_R_FORMERR); } /* - * Remember the serial number in the intial SOA. + * Remember the serial number in the initial SOA. * We need it to recognize the end of an IXFR. */ xfr->end_serial = dns_soa_getserial(rdata); @@ -631,9 +633,12 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, failure: if (db != NULL) dns_db_detach(&db); - if (result != ISC_R_SUCCESS) - xfrin_log1(ISC_LOG_ERROR, zonename, dns_zone_getclass(zone), - masteraddr, "zone transfer setup failed"); + if (result != ISC_R_SUCCESS) { + char zonetext[DNS_NAME_MAXTEXT+32]; + dns_zone_name(zone, zonetext, sizeof(zonetext)); + xfrin_log1(ISC_LOG_ERROR, zonetext, masteraddr, + "zone transfer setup failed"); + } return (result); } @@ -1400,23 +1405,19 @@ maybe_free(dns_xfrin_ctx_t *xfr) { * transfer of <zone> from <address>: <message> */ static void -xfrin_logv(int level, dns_name_t *zonename, dns_rdataclass_t rdclass, - isc_sockaddr_t *masteraddr, const char *fmt, va_list ap) +xfrin_logv(int level, const char *zonetext, isc_sockaddr_t *masteraddr, + const char *fmt, va_list ap) { - char zntext[DNS_NAME_FORMATSIZE]; char mastertext[ISC_SOCKADDR_FORMATSIZE]; - char classtext[DNS_RDATACLASS_FORMATSIZE]; char msgtext[2048]; - dns_name_format(zonename, zntext, sizeof(zntext)); - dns_rdataclass_format(rdclass, classtext, sizeof(classtext)); isc_sockaddr_format(masteraddr, mastertext, sizeof(mastertext)); vsnprintf(msgtext, sizeof(msgtext), fmt, ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_XFER_IN, DNS_LOGMODULE_XFER_IN, level, - "transfer of '%s/%s' from %s: %s", - zntext, classtext, mastertext, msgtext); + "transfer of '%s' from %s: %s", + zonetext, mastertext, msgtext); } /* @@ -1424,8 +1425,8 @@ xfrin_logv(int level, dns_name_t *zonename, dns_rdataclass_t rdclass, */ static void -xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass, - isc_sockaddr_t *masteraddr, const char *fmt, ...) +xfrin_log1(int level, const char *zonetext, isc_sockaddr_t *masteraddr, + const char *fmt, ...) { va_list ap; @@ -1433,7 +1434,7 @@ xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass, return; va_start(ap, fmt); - xfrin_logv(level, zonename, rdclass, masteraddr, fmt, ap); + xfrin_logv(level, zonetext, masteraddr, fmt, ap); va_end(ap); } @@ -1445,11 +1446,14 @@ static void xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...) { va_list ap; + char zonetext[DNS_NAME_MAXTEXT+32]; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; + dns_zone_name(xfr->zone, zonetext, sizeof(zonetext)); + va_start(ap, fmt); - xfrin_logv(level, &xfr->name, xfr->rdclass, &xfr->masteraddr, fmt, ap); + xfrin_logv(level, zonetext, &xfr->masteraddr, fmt, ap); va_end(ap); } diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c index d2a47b0..5a73796 100644 --- a/contrib/bind9/lib/dns/zone.c +++ b/contrib/bind9/lib/dns/zone.c @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.333.2.23.2.65 2006/07/19 01:04:24 marka Exp $ */ +/* $Id: zone.c,v 1.410.18.47 2006/12/07 06:21:16 marka Exp $ */ + +/*! \file */ #include <config.h> @@ -25,16 +27,19 @@ #include <isc/random.h> #include <isc/ratelimiter.h> #include <isc/refcount.h> +#include <isc/rwlock.h> #include <isc/serial.h> #include <isc/string.h> #include <isc/taskpool.h> #include <isc/timer.h> #include <isc/util.h> +#include <dns/acache.h> #include <dns/acl.h> #include <dns/adb.h> #include <dns/callbacks.h> #include <dns/db.h> +#include <dns/dbiterator.h> #include <dns/events.h> #include <dns/journal.h> #include <dns/log.h> @@ -79,7 +84,7 @@ #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O') #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC) -/* +/*% * Ensure 'a' is at least 'min' but not more than 'max'. */ #define RANGE(a, min, max) \ @@ -88,16 +93,16 @@ /* * Default values. */ -#define DNS_DEFAULT_IDLEIN 3600 /* 1 hour */ -#define DNS_DEFAULT_IDLEOUT 3600 /* 1 hour */ -#define MAX_XFER_TIME (2*3600) /* Documented default is 2 hours */ +#define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */ +#define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */ +#define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */ #ifndef DNS_MAX_EXPIRE -#define DNS_MAX_EXPIRE 14515200 /* 24 weeks */ +#define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */ #endif #ifndef DNS_DUMP_DELAY -#define DNS_DUMP_DELAY 900 /* 15 minutes */ +#define DNS_DUMP_DELAY 900 /*%< 15 minutes */ #endif typedef struct dns_notify dns_notify_t; @@ -123,6 +128,18 @@ typedef ISC_LIST(dns_io_t) dns_iolist_t; #define LOCKED_ZONE(z) ISC_TRUE #endif +#ifdef ISC_RWLOCK_USEATOMIC +#define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0) +#define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l) +#define ZONEDB_LOCK(l, t) RWLOCK((l), (t)) +#define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t)) +#else +#define ZONEDB_INITLOCK(l) isc_mutex_init(l) +#define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l) +#define ZONEDB_LOCK(l, t) LOCK(l) +#define ZONEDB_UNLOCK(l, t) UNLOCK(l) +#endif + struct dns_zone { /* Unlocked */ unsigned int magic; @@ -133,14 +150,21 @@ struct dns_zone { isc_mem_t *mctx; isc_refcount_t erefs; +#ifdef ISC_RWLOCK_USEATOMIC + isc_rwlock_t dblock; +#else + isc_mutex_t dblock; +#endif + dns_db_t *db; /* Locked by dblock */ + /* Locked */ - dns_db_t *db; dns_zonemgr_t *zmgr; ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ isc_timer_t *timer; unsigned int irefs; dns_name_t origin; char *masterfile; + dns_masterformat_t masterformat; char *journal; isc_int32_t journalsize; dns_rdataclass_t rdclass; @@ -153,6 +177,7 @@ struct dns_zone { isc_time_t refreshtime; isc_time_t dumptime; isc_time_t loadtime; + isc_time_t notifytime; isc_uint32_t serial; isc_uint32_t refresh; isc_uint32_t retry; @@ -176,13 +201,13 @@ struct dns_zone { unsigned int notifycnt; isc_sockaddr_t notifyfrom; isc_task_t *task; - isc_sockaddr_t notifysrc4; - isc_sockaddr_t notifysrc6; - isc_sockaddr_t xfrsource4; - isc_sockaddr_t xfrsource6; - isc_sockaddr_t altxfrsource4; - isc_sockaddr_t altxfrsource6; - isc_sockaddr_t sourceaddr; + isc_sockaddr_t notifysrc4; + isc_sockaddr_t notifysrc6; + isc_sockaddr_t xfrsource4; + isc_sockaddr_t xfrsource6; + isc_sockaddr_t altxfrsource4; + isc_sockaddr_t altxfrsource6; + isc_sockaddr_t sourceaddr; dns_xfrin_ctx_t *xfr; /* task locked */ dns_tsigkey_t *tsigkey; /* key used for xfr */ /* Access Control Lists */ @@ -192,6 +217,7 @@ struct dns_zone { dns_acl_t *query_acl; dns_acl_t *xfr_acl; isc_boolean_t update_disabled; + isc_boolean_t zero_no_soa_ttl; dns_severity_t check_names; ISC_LIST(dns_notify_t) notifies; dns_request_t *request; @@ -207,7 +233,11 @@ struct dns_zone { dns_ssutable_t *ssutable; isc_uint32_t sigvalidityinterval; dns_view_t *view; - /* + dns_acache_t *acache; + dns_checkmxfunc_t checkmx; + dns_checksrvfunc_t checksrv; + dns_checknsfunc_t checkns; + /*% * Zones in certain states such as "waiting for zone transfer" * or "zone transfer in progress" are kept on per-state linked lists * in the zone manager using the 'statelink' field. The 'statelist' @@ -216,10 +246,13 @@ struct dns_zone { */ ISC_LINK(dns_zone_t) statelink; dns_zonelist_t *statelist; - /* + /*% * Optional per-zone statistics counters (NULL if not present). */ - isc_uint64_t *counters; + isc_uint64_t *counters; + isc_uint32_t notifydelay; + dns_isselffunc_t isself; + void *isselfarg; }; #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) @@ -232,35 +265,35 @@ struct dns_zone { (z)->flags &= ~(f); \ } while (0) /* XXX MPA these may need to go back into zone.h */ -#define DNS_ZONEFLG_REFRESH 0x00000001U /* refresh check in progress */ -#define DNS_ZONEFLG_NEEDDUMP 0x00000002U /* zone need consolidation */ -#define DNS_ZONEFLG_USEVC 0x00000004U /* use tcp for refresh query */ -#define DNS_ZONEFLG_DUMPING 0x00000008U /* a dump is in progress */ -#define DNS_ZONEFLG_HASINCLUDE 0x00000010U /* $INCLUDE in zone file */ -#define DNS_ZONEFLG_LOADED 0x00000020U /* database has loaded */ -#define DNS_ZONEFLG_EXITING 0x00000040U /* zone is being destroyed */ -#define DNS_ZONEFLG_EXPIRED 0x00000080U /* zone has expired */ -#define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /* refresh check needed */ -#define DNS_ZONEFLG_UPTODATE 0x00000200U /* zone contents are +#define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */ +#define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */ +#define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */ +#define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */ +#define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */ +#define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */ +#define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */ +#define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */ +#define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */ +#define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are * uptodate */ -#define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /* need to send out notify +#define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify * messages */ -#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /* generate a journal diff on +#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on * reload */ -#define DNS_ZONEFLG_NOMASTERS 0x00001000U /* an attempt to refresh a +#define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a * zone with no masters * occured */ -#define DNS_ZONEFLG_LOADING 0x00002000U /* load from disk in progress*/ -#define DNS_ZONEFLG_HAVETIMERS 0x00004000U /* timer values have been set +#define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/ +#define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set * from SOA (if not set, we * are still using * default timer values) */ -#define DNS_ZONEFLG_FORCEXFER 0x00008000U /* Force a zone xfer */ +#define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */ #define DNS_ZONEFLG_NOREFRESH 0x00010000U #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U #define DNS_ZONEFLG_DIALREFRESH 0x00040000U #define DNS_ZONEFLG_SHUTDOWN 0x00080000U -#define DNS_ZONEFLAG_NOIXFR 0x00100000U /* IXFR failed, force AXFR */ +#define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */ #define DNS_ZONEFLG_FLUSH 0x00200000U #define DNS_ZONEFLG_NOEDNS 0x00400000U #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U @@ -301,7 +334,7 @@ struct dns_zonemgr { dns_iolist_t low; }; -/* +/*% * Hold notify state. */ struct dns_notify { @@ -318,7 +351,7 @@ struct dns_notify { #define DNS_NOTIFY_NOSOA 0x0001U -/* +/*% * dns_stub holds state while performing a 'stub' transfer. * 'db' is the zone's 'db' or a new one if this is the initial * transfer. @@ -332,7 +365,7 @@ struct dns_stub { dns_dbversion_t *version; }; -/* +/*% * Hold load state. */ struct dns_load { @@ -344,7 +377,7 @@ struct dns_load { dns_rdatacallbacks_t callbacks; }; -/* +/*% * Hold forward state. */ struct dns_forward { @@ -359,7 +392,7 @@ struct dns_forward { void *callback_arg; }; -/* +/*% * Hold IO request state. */ struct dns_io { @@ -386,6 +419,8 @@ static void zone_iattach(dns_zone_t *source, dns_zone_t **target); static void zone_idetach(dns_zone_t **zonep); static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump); +static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db); +static inline void zone_detachdb(dns_zone_t *zone); static isc_result_t default_journal(dns_zone_t *zone); static void zone_xfrdone(dns_zone_t *zone, isc_result_t result); static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, @@ -430,17 +465,18 @@ static void zonemgr_putio(dns_io_t **iop); static void zonemgr_cancelio(dns_io_t *io); static isc_result_t -zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount, +zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, - isc_uint32_t *expire, isc_uint32_t *minimum); + isc_uint32_t *expire, isc_uint32_t *minimum, + unsigned int *errors); static void zone_freedbargs(dns_zone_t *zone); static void forward_callback(isc_task_t *task, isc_event_t *event); static void zone_saveunique(dns_zone_t *zone, const char *path, const char *templat); static void zone_maintenance(dns_zone_t *zone); -static void zone_notify(dns_zone_t *zone); +static void zone_notify(dns_zone_t *zone, isc_time_t *now); static void dump_done(void *arg, isc_result_t result); #define ENTER zone_debuglog(zone, me, 1, "enter") @@ -484,36 +520,41 @@ isc_result_t dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { isc_result_t result; dns_zone_t *zone; + isc_time_t now; REQUIRE(zonep != NULL && *zonep == NULL); REQUIRE(mctx != NULL); + TIME_NOW(&now); zone = isc_mem_get(mctx, sizeof(*zone)); if (zone == NULL) return (ISC_R_NOMEMORY); + zone->mctx = NULL; + isc_mem_attach(mctx, &zone->mctx); + result = isc_mutex_init(&zone->lock); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, zone, sizeof(*zone)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); - return (ISC_R_UNEXPECTED); - } + if (result != ISC_R_SUCCESS) + goto free_zone; + + result = ZONEDB_INITLOCK(&zone->dblock); + if (result != ISC_R_SUCCESS) + goto free_mutex; /* XXX MPA check that all elements are initialised */ - zone->mctx = NULL; #ifdef DNS_ZONE_CHECKLOCK zone->locked = ISC_FALSE; #endif - isc_mem_attach(mctx, &zone->mctx); zone->db = NULL; zone->zmgr = NULL; ISC_LINK_INIT(zone, link); - isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ + result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ + if (result != ISC_R_SUCCESS) + goto free_dblock; zone->irefs = 0; dns_name_init(&zone->origin, NULL); zone->masterfile = NULL; + zone->masterformat = dns_masterformat_none; zone->keydirectory = NULL; zone->journalsize = -1; zone->journal = NULL; @@ -527,6 +568,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { isc_time_settoepoch(&zone->refreshtime); isc_time_settoepoch(&zone->dumptime); isc_time_settoepoch(&zone->loadtime); + zone->notifytime = now; zone->serial = 0; zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; @@ -551,6 +593,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->query_acl = NULL; zone->xfr_acl = NULL; zone->update_disabled = ISC_FALSE; + zone->zero_no_soa_ttl = ISC_TRUE; zone->check_names = dns_severity_ignore; zone->request = NULL; zone->lctx = NULL; @@ -574,16 +617,23 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->ssutable = NULL; zone->sigvalidityinterval = 30 * 24 * 3600; zone->view = NULL; + zone->acache = NULL; + zone->checkmx = NULL; + zone->checksrv = NULL; + zone->checkns = NULL; ISC_LINK_INIT(zone, statelink); zone->statelist = NULL; zone->counters = NULL; + zone->notifydelay = 5; + zone->isself = NULL; + zone->isselfarg = NULL; zone->magic = ZONE_MAGIC; /* Must be after magic is set. */ result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default); if (result != ISC_R_SUCCESS) - goto free_mutex; + goto free_erefs; ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, @@ -591,8 +641,17 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { *zonep = zone; return (ISC_R_SUCCESS); + free_erefs: + isc_refcount_decrement(&zone->erefs, NULL); + isc_refcount_destroy(&zone->erefs); + + free_dblock: + ZONEDB_DESTROYLOCK(&zone->dblock); + free_mutex: DESTROYLOCK(&zone->lock); + + free_zone: isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone)); return (result); } @@ -639,7 +698,9 @@ zone_free(dns_zone_t *zone) { if (zone->counters != NULL) dns_stats_freecounters(zone->mctx, &zone->counters); if (zone->db != NULL) - dns_db_detach(&zone->db); + zone_detachdb(zone); + if (zone->acache != NULL) + dns_acache_detach(&zone->acache); zone_freedbargs(zone); RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0) == ISC_R_SUCCESS); @@ -662,6 +723,7 @@ zone_free(dns_zone_t *zone) { dns_ssutable_detach(&zone->ssutable); /* last stuff */ + ZONEDB_DESTROYLOCK(&zone->dblock); DESTROYLOCK(&zone->lock); isc_refcount_destroy(&zone->erefs); zone->magic = 0; @@ -739,6 +801,39 @@ zone_freedbargs(dns_zone_t *zone) { } isc_result_t +dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) { + size_t size = 0; + unsigned int i; + isc_result_t result = ISC_R_SUCCESS; + void *mem; + char **tmp, *tmp2; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(argv != NULL && *argv == NULL); + + LOCK_ZONE(zone); + size = (zone->db_argc + 1) * sizeof(char *); + for (i = 0; i < zone->db_argc; i++) + size += strlen(zone->db_argv[i]) + 1; + mem = isc_mem_allocate(mctx, size); + if (mem != NULL) { + tmp = mem; + tmp2 = mem; + tmp2 += (zone->db_argc + 1) * sizeof(char *); + for (i = 0; i < zone->db_argc; i++) { + *tmp++ = tmp2; + strcpy(tmp2, zone->db_argv[i]); + tmp2 += strlen(tmp2) + 1; + } + *tmp = NULL; + } else + result = ISC_R_NOMEMORY; + UNLOCK_ZONE(zone); + *argv = mem; + return (result); +} + +isc_result_t dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc, const char * const *dbargv) { isc_result_t result = ISC_R_SUCCESS; @@ -822,6 +917,35 @@ dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { return (result); } +void +dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) { + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(acache != NULL); + + LOCK_ZONE(zone); + if (zone->acache != NULL) + dns_acache_detach(&zone->acache); + dns_acache_attach(acache, &zone->acache); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { + isc_result_t result; + + /* + * If the zone reuses an existing DB, the DB needs to be + * set in the acache explicitly. We can safely ignore the + * case where the DB is already set. If other error happens, + * the acache will not work effectively. + */ + result = dns_acache_setdb(acache, zone->db); + if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "dns_acache_setdb() failed: %s", + isc_result_totext(result)); + } + } + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + UNLOCK_ZONE(zone); +} static isc_result_t dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { @@ -844,14 +968,22 @@ dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { isc_result_t dns_zone_setfile(dns_zone_t *zone, const char *file) { + return (dns_zone_setfile2(zone, file, dns_masterformat_text)); +} + +isc_result_t +dns_zone_setfile2(dns_zone_t *zone, const char *file, + dns_masterformat_t format) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->masterfile, file); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { + zone->masterformat = format; result = default_journal(zone); + } UNLOCK_ZONE(zone); return (result); @@ -979,31 +1111,42 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } + + /* + * Store the current time before the zone is loaded, so that if the + * file changes between the time of the load and the time that + * zone->loadtime is set, then the file will still be reloaded + * the next time dns_zone_load is called. + */ + TIME_NOW(&loadtime); + /* * Don't do the load if the file that stores the zone is older * than the last time the zone was loaded. If the zone has not * been loaded yet, zone->loadtime will be the epoch. */ - if (zone->masterfile != NULL && ! isc_time_isepoch(&zone->loadtime)) { + if (zone->masterfile != NULL) { /* * The file is already loaded. If we are just doing a * "rndc reconfig", we are done. */ - if ((flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { + if (!isc_time_isepoch(&zone->loadtime) && + (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } - if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE)) { - result = isc_file_getmodtime(zone->masterfile, - &filetime); - if (result == ISC_R_SUCCESS && + + result = isc_file_getmodtime(zone->masterfile, &filetime); + if (result == ISC_R_SUCCESS) { + if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && isc_time_compare(&filetime, &zone->loadtime) <= 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), - "skipping load: master file older " - "than last load"); + "skipping load: master file " + "older than last load"); result = DNS_R_UPTODATE; goto cleanup; } + loadtime = filetime; } } @@ -1024,9 +1167,10 @@ zone_load(dns_zone_t *zone, unsigned int flags) { strcmp(zone->db_argv[0], "rbt64") == 0)) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { - if (zone->masterfile != NULL) + if (zone->masterfile != NULL) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); + } zone->refreshtime = now; if (zone->task != NULL) zone_settimer(zone, &now); @@ -1037,14 +1181,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load"); - /* - * Store the current time before the zone is loaded, so that if the - * file changes between the time of the load and the time that - * zone->loadtime is set, then the file will still be reloaded - * the next time dns_zone_load is called. - */ - TIME_NOW(&loadtime); - result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, (zone->type == dns_zone_stub) ? dns_dbtype_stub : dns_dbtype_zone, @@ -1125,14 +1261,21 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; - result = dns_master_loadfileinc(load->zone->masterfile, - dns_db_origin(load->db), - dns_db_origin(load->db), - load->zone->rdclass, - options, - &load->callbacks, task, - zone_loaddone, load, - &load->zone->lctx, load->zone->mctx); + if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMX)) + options |= DNS_MASTER_CHECKMX; + if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKMXFAIL)) + options |= DNS_MASTER_CHECKMXFAIL; + if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD)) + options |= DNS_MASTER_CHECKWILDCARD; + result = dns_master_loadfileinc2(load->zone->masterfile, + dns_db_origin(load->db), + dns_db_origin(load->db), + load->zone->rdclass, + options, + &load->callbacks, task, + zone_loaddone, load, + &load->zone->lctx, load->zone->mctx, + load->zone->masterformat); if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && result != DNS_R_SEENINCLUDE) goto fail; @@ -1160,12 +1303,14 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { goto fail; LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); dns_db_currentversion(zone->db, &version); - result = dns_master_dumpinc(zone->mctx, zone->db, version, - &dns_master_style_default, - zone->masterfile, zone->task, - dump_done, zone, &zone->dctx); + result = dns_master_dumpinc2(zone->mctx, zone->db, version, + &dns_master_style_default, + zone->masterfile, zone->task, dump_done, + zone, &zone->dctx, zone->masterformat); dns_db_closeversion(zone->db, &version, ISC_FALSE); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); if (result != DNS_R_CONTINUE) goto fail; @@ -1195,6 +1340,12 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { options |= DNS_MASTER_CHECKNAMES; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) options |= DNS_MASTER_CHECKNAMESFAIL; + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) + options |= DNS_MASTER_CHECKMX; + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) + options |= DNS_MASTER_CHECKMXFAIL; + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) + options |= DNS_MASTER_CHECKWILDCARD; if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) { load = isc_mem_get(zone->mctx, sizeof(*load)); @@ -1236,9 +1387,10 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { &callbacks.add_private); if (result != ISC_R_SUCCESS) return (result); - result = dns_master_loadfile(zone->masterfile, &zone->origin, - &zone->origin, zone->rdclass, - options, &callbacks, zone->mctx); + result = dns_master_loadfile2(zone->masterfile, &zone->origin, + &zone->origin, zone->rdclass, + options, &callbacks, zone->mctx, + zone->masterformat); tresult = dns_db_endload(db, &callbacks.add_private); if (result == ISC_R_SUCCESS) result = tresult; @@ -1255,12 +1407,487 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { return (result); } +static isc_boolean_t +zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, + dns_name_t *owner) +{ + isc_result_t result; + char ownerbuf[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; + char altbuf[DNS_NAME_FORMATSIZE]; + dns_fixedname_t fixed; + dns_name_t *foundname; + int level; + + /* + * Outside of zone. + */ + if (!dns_name_issubdomain(name, &zone->origin)) { + if (zone->checkmx != NULL) + return ((zone->checkmx)(zone, name, owner)); + return (ISC_TRUE); + } + + if (zone->type == dns_zone_master) + level = ISC_LOG_ERROR; + else + level = ISC_LOG_WARNING; + + dns_fixedname_init(&fixed); + foundname = dns_fixedname_name(&fixed); + + result = dns_db_find(db, name, NULL, dns_rdatatype_a, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + + if (result == DNS_R_NXRRSET) { + result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + } + + dns_name_format(owner, ownerbuf, sizeof ownerbuf); + dns_name_format(name, namebuf, sizeof namebuf); + if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || + result == DNS_R_EMPTYNAME) { + dns_zone_log(zone, level, + "%s/MX '%s' has no address records (A or AAAA)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); + } + + if (result == DNS_R_CNAME) { + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) + dns_zone_log(zone, level, + "%s/MX '%s' is a CNAME (illegal)", + ownerbuf, namebuf); + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); + } + + if (result == DNS_R_DNAME) { + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) { + dns_name_format(foundname, altbuf, sizeof altbuf); + dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME" + " '%s' (illegal)", ownerbuf, namebuf, + altbuf); + } + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); + } + + if (zone->checkmx != NULL && result == DNS_R_DELEGATION) + return ((zone->checkmx)(zone, name, owner)); + + return (ISC_TRUE); +} + +static isc_boolean_t +zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, + dns_name_t *owner) +{ + isc_result_t result; + char ownerbuf[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; + char altbuf[DNS_NAME_FORMATSIZE]; + dns_fixedname_t fixed; + dns_name_t *foundname; + int level; + + /* + * "." means the services does not exist. + */ + if (dns_name_equal(name, dns_rootname)) + return (ISC_TRUE); + + /* + * Outside of zone. + */ + if (!dns_name_issubdomain(name, &zone->origin)) { + if (zone->checksrv != NULL) + return ((zone->checksrv)(zone, name, owner)); + return (ISC_TRUE); + } + + if (zone->type == dns_zone_master) + level = ISC_LOG_ERROR; + else + level = ISC_LOG_WARNING; + + dns_fixedname_init(&fixed); + foundname = dns_fixedname_name(&fixed); + + result = dns_db_find(db, name, NULL, dns_rdatatype_a, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + + if (result == DNS_R_NXRRSET) { + result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + } + + dns_name_format(owner, ownerbuf, sizeof ownerbuf); + dns_name_format(name, namebuf, sizeof namebuf); + if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || + result == DNS_R_EMPTYNAME) { + dns_zone_log(zone, level, + "%s/SRV '%s' has no address records (A or AAAA)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0. */ + return (ISC_TRUE); + } + + if (result == DNS_R_CNAME) { + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) + dns_zone_log(zone, level, + "%s/SRV '%s' is a CNAME (illegal)", + ownerbuf, namebuf); + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); + } + + if (result == DNS_R_DNAME) { + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) + level = ISC_LOG_WARNING; + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) { + dns_name_format(foundname, altbuf, sizeof altbuf); + dns_zone_log(zone, level, "%s/SRV '%s' is below a " + "DNAME '%s' (illegal)", ownerbuf, namebuf, + altbuf); + } + return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE); + } + + if (zone->checksrv != NULL && result == DNS_R_DELEGATION) + return ((zone->checksrv)(zone, name, owner)); + + return (ISC_TRUE); +} + +static isc_boolean_t +zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name, + dns_name_t *owner) +{ + isc_boolean_t answer = ISC_TRUE; + isc_result_t result, tresult; + char ownerbuf[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; + char altbuf[DNS_NAME_FORMATSIZE]; + dns_fixedname_t fixed; + dns_name_t *foundname; + dns_rdataset_t a; + dns_rdataset_t aaaa; + int level; + + /* + * Outside of zone. + */ + if (!dns_name_issubdomain(name, &zone->origin)) { + if (zone->checkns != NULL) + return ((zone->checkns)(zone, name, owner, NULL, NULL)); + return (ISC_TRUE); + } + + if (zone->type == dns_zone_master) + level = ISC_LOG_ERROR; + else + level = ISC_LOG_WARNING; + + dns_fixedname_init(&fixed); + foundname = dns_fixedname_name(&fixed); + dns_rdataset_init(&a); + dns_rdataset_init(&aaaa); + + result = dns_db_find(db, name, NULL, dns_rdatatype_a, + DNS_DBFIND_GLUEOK, 0, NULL, + foundname, &a, NULL); + + if (result == ISC_R_SUCCESS) { + dns_rdataset_disassociate(&a); + return (ISC_TRUE); + } else if (result == DNS_R_DELEGATION) + dns_rdataset_disassociate(&a); + + if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION || + result == DNS_R_GLUE) { + tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, + DNS_DBFIND_GLUEOK, 0, NULL, + foundname, &aaaa, NULL); + if (tresult == ISC_R_SUCCESS) { + dns_rdataset_disassociate(&aaaa); + return (ISC_TRUE); + } + if (tresult == DNS_R_DELEGATION) + dns_rdataset_disassociate(&aaaa); + if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) { + /* + * Check glue against child zone. + */ + if (zone->checkns != NULL) + answer = (zone->checkns)(zone, name, owner, + &a, &aaaa); + if (dns_rdataset_isassociated(&a)) + dns_rdataset_disassociate(&a); + if (dns_rdataset_isassociated(&aaaa)) + dns_rdataset_disassociate(&aaaa); + return (answer); + } + } else + tresult = result; + + dns_name_format(owner, ownerbuf, sizeof ownerbuf); + dns_name_format(name, namebuf, sizeof namebuf); + if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || + result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) { + const char *what; + if (dns_name_issubdomain(name, owner)) + what = "REQUIRED GLUE "; + else if (result == DNS_R_DELEGATION) + what = "SIBLING GLUE "; + else + what = ""; + + if (result != DNS_R_DELEGATION || + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) { + dns_zone_log(zone, level, "%s/NS '%s' has no %s" + "address records (A or AAAA)", + ownerbuf, namebuf, what); + /* + * Log missing address record. + */ + if (result == DNS_R_DELEGATION && zone->checkns != NULL) + (void)(zone->checkns)(zone, name, owner, + &a, &aaaa); + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ + } + } else if (result == DNS_R_CNAME) { + dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)", + ownerbuf, namebuf); + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ + } else if (result == DNS_R_DNAME) { + dns_name_format(foundname, altbuf, sizeof altbuf); + dns_zone_log(zone, level, + "%s/NS '%s' is below a DNAME '%s' (illegal)", + ownerbuf, namebuf, altbuf); + /* XXX950 make fatal for 9.5.0. */ + /* answer = ISC_FALSE; */ + } + + if (dns_rdataset_isassociated(&a)) + dns_rdataset_disassociate(&a); + if (dns_rdataset_isassociated(&aaaa)) + dns_rdataset_disassociate(&aaaa); + return (answer); +} + +static isc_boolean_t +integrity_checks(dns_zone_t *zone, dns_db_t *db) { + dns_dbiterator_t *dbiterator = NULL; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_fixedname_t fixed; + dns_fixedname_t fixedbottom; + dns_rdata_mx_t mx; + dns_rdata_ns_t ns; + dns_rdata_in_srv_t srv; + dns_rdata_t rdata; + dns_name_t *name; + dns_name_t *bottom; + isc_result_t result; + isc_boolean_t ok = ISC_TRUE; + + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + dns_fixedname_init(&fixedbottom); + bottom = dns_fixedname_name(&fixedbottom); + dns_rdataset_init(&rdataset); + dns_rdata_init(&rdata); + + result = dns_db_createiterator(db, ISC_FALSE, &dbiterator); + if (result != ISC_R_SUCCESS) + return (ISC_TRUE); + + result = dns_dbiterator_first(dbiterator); + while (result == ISC_R_SUCCESS) { + result = dns_dbiterator_current(dbiterator, &node, name); + if (result != ISC_R_SUCCESS) + goto cleanup; + + /* + * Is this name visible in the zone? + */ + if (!dns_name_issubdomain(name, &zone->origin) || + (dns_name_countlabels(bottom) > 0 && + dns_name_issubdomain(name, bottom))) + goto next; + + /* + * Don't check the NS records at the origin. + */ + if (dns_name_equal(name, &zone->origin)) + goto checkmx; + + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto checkmx; + /* + * Remember bottom of zone. + */ + dns_name_copy(name, bottom, NULL); + + result = dns_rdataset_first(&rdataset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &ns, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (!zone_check_glue(zone, db, &ns.name, name)) + ok = ISC_FALSE; + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + + checkmx: + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto checksrv; + result = dns_rdataset_first(&rdataset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &mx, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (!zone_check_mx(zone, db, &mx.mx, name)) + ok = ISC_FALSE; + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + + checksrv: + if (zone->rdclass != dns_rdataclass_in) + goto next; + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto next; + result = dns_rdataset_first(&rdataset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &srv, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (!zone_check_srv(zone, db, &srv.target, name)) + ok = ISC_FALSE; + dns_rdata_reset(&rdata); + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + + next: + dns_db_detachnode(db, &node); + result = dns_dbiterator_next(dbiterator); + } + + cleanup: + if (node != NULL) + dns_db_detachnode(db, &node); + dns_dbiterator_destroy(&dbiterator); + + return (ok); +} + +/* + * OpenSSL verification of RSA keys with exponent 3 is known to be + * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn + * if they are in use. + */ +static void +zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) { + dns_dbnode_t *node = NULL; + dns_dbversion_t *version = NULL; + dns_rdata_dnskey_t dnskey; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_t rdataset; + isc_result_t result; + isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE; + const char *algorithm; + + result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); + if (result != ISC_R_SUCCESS) + goto cleanup; + + dns_db_currentversion(db, &version); + dns_rdataset_init(&rdataset); + result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey, + dns_rdatatype_none, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) + { + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &dnskey, NULL); + INSIST(result == ISC_R_SUCCESS); + + if ((dnskey.algorithm == DST_ALG_RSASHA1 || + dnskey.algorithm == DST_ALG_RSAMD5) && + dnskey.datalen > 1 && dnskey.data[0] == 1 && + dnskey.data[1] == 3) + { + if (dnskey.algorithm == DST_ALG_RSASHA1) { + logit = !foundrsa; + foundrsa = ISC_TRUE; + algorithm = "RSASHA1"; + } else { + logit = !foundmd5; + foundmd5 = ISC_TRUE; + algorithm = "RSAMD5"; + } + if (logit) + dns_zone_log(zone, ISC_LOG_WARNING, + "weak %s (%u) key found " + "(exponent=3)", algorithm, + dnskey.algorithm); + if (foundrsa && foundmd5) + break; + } + dns_rdata_reset(&rdata); + } + dns_rdataset_disassociate(&rdataset); + + cleanup: + if (node != NULL) + dns_db_detachnode(db, &node); + if (version != NULL) + dns_db_closeversion(db, &version, ISC_FALSE); + +} + static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, isc_result_t result) { unsigned int soacount = 0; unsigned int nscount = 0; + unsigned int errors = 0; isc_uint32_t serial, refresh, retry, expire, minimum; isc_time_t now; isc_boolean_t needdump = ISC_FALSE; @@ -1281,12 +1908,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, "no master file"); else if (result != DNS_R_NOMASTERFILE) dns_zone_log(zone, ISC_LOG_ERROR, - "loading master file %s: %s", + "loading from master file %s " + "failed: %s", zone->masterfile, dns_result_totext(result)); } else dns_zone_log(zone, ISC_LOG_ERROR, - "loading master file %s: %s", + "loading from master file %s failed: %s", zone->masterfile, dns_result_totext(result)); goto cleanup; @@ -1337,14 +1965,12 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded"); /* - * Obtain ns and soa counts for top of zone. + * Obtain ns, soa and cname counts for top of zone. */ - nscount = 0; - soacount = 0; INSIST(db != NULL); - result = zone_get_from_db(db, &zone->origin, &nscount, - &soacount, &serial, &refresh, &retry, - &expire, &minimum); + result = zone_get_from_db(zone, db, &nscount, &soacount, &serial, + &refresh, &retry, &expire, &minimum, + &errors); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "could not find NS and/or SOA records"); @@ -1371,6 +1997,17 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } if (result != ISC_R_SUCCESS) goto cleanup; + if (zone->type == dns_zone_master && errors != 0) { + result = DNS_R_BADZONE; + goto cleanup; + } + if (zone->type == dns_zone_master && + DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) && + !integrity_checks(zone, db)) { + result = DNS_R_BADZONE; + goto cleanup; + } + if (zone->db != NULL) { /* * This is checked in zone_replacedb() for slave zones @@ -1397,7 +2034,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, "zone serial has gone backwards"); else if (serial == zone->serial && !hasinclude) dns_zone_log(zone, ISC_LOG_ERROR, - "zone serial unchanged"); + "zone serial unchanged. " + "zone may fail to transfer " + "to slaves."); } zone->serial = serial; zone->refresh = RANGE(refresh, @@ -1440,6 +2079,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, goto cleanup; } + /* + * Check for weak DNSKEY's. + */ + if (zone->type == dns_zone_master) + zone_check_dnskeys(zone, db); #if 0 /* destroy notification example. */ @@ -1453,12 +2097,15 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } #endif + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db != NULL) { result = zone_replacedb(zone, db, ISC_FALSE); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); if (result != ISC_R_SUCCESS) goto cleanup; } else { - dns_db_attach(db, &zone->db); + zone_attachdb(zone, db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); } @@ -1509,36 +2156,111 @@ exit_check(dns_zone_t *zone) { return (ISC_FALSE); } +static isc_boolean_t +zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_name_t *name) { + isc_result_t result; + char namebuf[DNS_NAME_FORMATSIZE]; + char altbuf[DNS_NAME_FORMATSIZE]; + dns_fixedname_t fixed; + dns_name_t *foundname; + int level; + + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) + return (ISC_TRUE); + + if (zone->type == dns_zone_master) + level = ISC_LOG_ERROR; + else + level = ISC_LOG_WARNING; + + dns_fixedname_init(&fixed); + foundname = dns_fixedname_name(&fixed); + + result = dns_db_find(db, name, NULL, dns_rdatatype_a, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + + if (result == DNS_R_NXRRSET) { + result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, + 0, 0, NULL, foundname, NULL, NULL); + if (result == ISC_R_SUCCESS) + return (ISC_TRUE); + } + + dns_name_format(name, namebuf, sizeof namebuf); + if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN || + result == DNS_R_EMPTYNAME) { + dns_zone_log(zone, level, + "NS '%s' has no address records (A or AAAA)", + namebuf); + /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ + return (ISC_TRUE); + } + + if (result == DNS_R_CNAME) { + dns_zone_log(zone, level, "NS '%s' is a CNAME (illegal)", + namebuf); + /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ + return (ISC_TRUE); + } + + if (result == DNS_R_DNAME) { + dns_name_format(foundname, altbuf, sizeof altbuf); + dns_zone_log(zone, level, + "NS '%s' is below a DNAME '%s' (illegal)", + namebuf, altbuf); + /* XXX950 Make fatal ISC_FALSE for 9.5.0. */ + return (ISC_TRUE); + } + + return (ISC_TRUE); +} + static isc_result_t -zone_count_ns_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, - unsigned int *nscount) +zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, + dns_dbversion_t *version, unsigned int *nscount, + unsigned int *errors) { isc_result_t result; - unsigned int count; + unsigned int count = 0; + unsigned int ecount = 0; dns_rdataset_t rdataset; - - REQUIRE(nscount != NULL); + dns_rdata_t rdata; + dns_rdata_ns_t ns; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, dns_rdatatype_none, 0, &rdataset, NULL); - if (result == ISC_R_NOTFOUND) { - *nscount = 0; - result = ISC_R_SUCCESS; - goto invalidate_rdataset; - } + if (result == ISC_R_NOTFOUND) + goto success; if (result != ISC_R_SUCCESS) goto invalidate_rdataset; - count = 0; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { + if (errors != NULL && zone->rdclass == dns_rdataclass_in && + (zone->type == dns_zone_master || + zone->type == dns_zone_slave)) { + dns_rdata_init(&rdata); + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &ns, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (dns_name_issubdomain(&ns.name, &zone->origin) && + !zone_check_ns(zone, db, &ns.name)) + ecount++; + } count++; result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); - *nscount = count; + success: + if (nscount != NULL) + *nscount = count; + if (errors != NULL) + *errors = ecount; + result = ISC_R_SUCCESS; invalidate_rdataset: @@ -1626,10 +2348,11 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, * zone must be locked. */ static isc_result_t -zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount, +zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount, unsigned int *soacount, isc_uint32_t *serial, isc_uint32_t *refresh, isc_uint32_t *retry, - isc_uint32_t *expire, isc_uint32_t *minimum) + isc_uint32_t *expire, isc_uint32_t *minimum, + unsigned int *errors) { dns_dbversion_t *version; isc_result_t result; @@ -1637,20 +2360,21 @@ zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount, dns_dbnode_t *node; REQUIRE(db != NULL); - REQUIRE(origin != NULL); + REQUIRE(zone != NULL); version = NULL; dns_db_currentversion(db, &version); node = NULL; - result = dns_db_findnode(db, origin, ISC_FALSE, &node); + result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) { answer = result; goto closeversion; } - if (nscount != NULL) { - result = zone_count_ns_rr(db, node, version, nscount); + if (nscount != NULL || errors != NULL) { + result = zone_count_ns_rr(zone, db, node, version, + nscount, errors); if (result != ISC_R_SUCCESS) answer = result; } @@ -1979,6 +2703,37 @@ dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, return (result); } +static isc_boolean_t +same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new, + isc_uint32_t count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + if (!isc_sockaddr_equal(&old[i], &new[i])) + return (ISC_FALSE); + return (ISC_TRUE); +} + +static isc_boolean_t +same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) { + unsigned int i; + + if (old == NULL && new == NULL) + return (ISC_TRUE); + if (old == NULL || new == NULL) + return (ISC_FALSE); + + for (i = 0; i < count; i++) { + if (old[i] == NULL && new[i] == NULL) + continue; + if (old[i] == NULL || new[i] == NULL || + !dns_name_equal(old[i], new[i])) + return (ISC_FALSE); + } + return (ISC_TRUE); +} + isc_result_t dns_zone_setmasterswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters, @@ -1998,6 +2753,19 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, } LOCK_ZONE(zone); + /* + * The refresh code assumes that 'masters' wouldn't change under it. + * If it will change then kill off any current refresh in progress + * and update the masters info. If it won't change then we can just + * unlock and exit. + */ + if (count != zone->masterscnt || + !same_masters(zone->masters, masters, count) || + !same_keynames(zone->masterkeynames, keynames, count)) { + if (zone->request != NULL) + dns_request_cancel(zone->request); + } else + goto unlock; if (zone->masters != NULL) { isc_mem_put(zone->mctx, zone->masters, zone->masterscnt * sizeof(*new)); @@ -2115,12 +2883,12 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) { REQUIRE(DNS_ZONE_VALID(zone)); - LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db == NULL) result = DNS_R_NOTLOADED; else dns_db_attach(zone->db, dpb); - UNLOCK_ZONE(zone); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); return (result); } @@ -2245,8 +3013,9 @@ zone_maintenance(dns_zone_t *zone) { switch (zone->type) { case dns_zone_master: case dns_zone_slave: - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) - zone_notify(zone); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && + isc_time_compare(&now, &zone->notifytime) >= 0) + zone_notify(zone, &now); break; default: break; @@ -2498,6 +3267,7 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { isc_boolean_t again; dns_db_t *db = NULL; char *masterfile = NULL; + dns_masterformat_t masterformat = dns_masterformat_none; /* * 'compact' MUST only be set if we are task locked. @@ -2507,11 +3277,15 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { ENTER; redo: - LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); - if (zone->masterfile != NULL) + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + LOCK_ZONE(zone); + if (zone->masterfile != NULL) { masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); + masterformat = zone->masterformat; + } UNLOCK_ZONE(zone); if (db == NULL) { result = DNS_R_NOTLOADED; @@ -2536,9 +3310,9 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { UNLOCK_ZONE(zone); } else { dns_db_currentversion(db, &version); - result = dns_master_dump(zone->mctx, db, version, - &dns_master_style_default, - masterfile); + result = dns_master_dump2(zone->mctx, db, version, + &dns_master_style_default, + masterfile, masterformat); dns_db_closeversion(db, &version, ISC_FALSE); } fail: @@ -2576,35 +3350,46 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { } static isc_result_t -dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style) { +dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, + dns_masterformat_t format) +{ isc_result_t result; dns_dbversion_t *version = NULL; dns_db_t *db = NULL; REQUIRE(DNS_ZONE_VALID(zone)); - LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_attach(zone->db, &db); - UNLOCK_ZONE(zone); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (db == NULL) return (DNS_R_NOTLOADED); dns_db_currentversion(db, &version); - result = dns_master_dumptostream(zone->mctx, db, version, style, fd); + result = dns_master_dumptostream2(zone->mctx, db, version, style, + format, fd); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); return (result); } isc_result_t +dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, + const dns_master_style_t *style) { + return dumptostream(zone, fd, style, format); +} + +isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { - return dumptostream(zone, fd, &dns_master_style_default); + return dumptostream(zone, fd, &dns_master_style_default, + dns_masterformat_text); } isc_result_t dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { - return dumptostream(zone, fd, &dns_master_style_full); + return dumptostream(zone, fd, &dns_master_style_full, + dns_masterformat_text); } void @@ -2645,7 +3430,9 @@ zone_unload(dns_zone_t *zone) { REQUIRE(LOCKED_ZONE(zone)); - dns_db_detach(&zone->db); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); + zone_detachdb(zone); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP); } @@ -2700,6 +3487,46 @@ notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) { return (ISC_FALSE); } +static isc_boolean_t +notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) { + dns_tsigkey_t *key = NULL; + isc_sockaddr_t src; + isc_sockaddr_t any; + isc_boolean_t isself; + isc_netaddr_t dstaddr; + + if (zone->view == NULL || zone->isself == NULL) + return (ISC_FALSE); + + switch (isc_sockaddr_pf(dst)) { + case PF_INET: + src = zone->notifysrc4; + isc_sockaddr_any(&any); + break; + case PF_INET6: + src = zone->notifysrc6; + isc_sockaddr_any6(&any); + break; + default: + return (ISC_FALSE); + } + + /* + * When sending from any the kernel will assign a source address + * that matches the destination address. + */ + if (isc_sockaddr_eqaddr(&any, &src)) + src = *dst; + + isc_netaddr_fromsockaddr(&dstaddr, dst); + (void)dns_view_getpeertsig(zone->view, &dstaddr, &key); + isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass, + zone->isselfarg); + if (key != NULL) + dns_tsigkey_detach(&key); + return (isself); +} + static void notify_destroy(dns_notify_t *notify, isc_boolean_t locked) { isc_mem_t *mctx; @@ -2800,7 +3627,7 @@ notify_find_address(dns_notify_t *notify) { result = dns_adb_createfind(notify->zone->view->adb, notify->zone->task, process_adb_event, notify, - ¬ify->ns, dns_rootname, + ¬ify->ns, dns_rootname, 0, options, 0, NULL, notify->zone->view->dstport, ¬ify->find); @@ -2853,6 +3680,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t src; int timeout; + isc_boolean_t have_notifysource = ISC_FALSE; notify = event->ev_arg; REQUIRE(DNS_NOTIFY_VALID(notify)); @@ -2880,7 +3708,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { */ if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 && IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) { - isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); + isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); notify_log(notify->zone, ISC_LOG_DEBUG(3), "notify: ignoring IPv6 mapped IPV4 address: %s", addrbuf); @@ -2898,12 +3726,24 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", addrbuf); + if (notify->zone->view->peers != NULL) { + dns_peer_t *peer = NULL; + result = dns_peerlist_peerbyaddr(notify->zone->view->peers, + &dstip, &peer); + if (result == ISC_R_SUCCESS) { + result = dns_peer_getnotifysource(peer, &src); + if (result == ISC_R_SUCCESS) + have_notifysource = ISC_TRUE; + } + } switch (isc_sockaddr_pf(¬ify->dst)) { case PF_INET: - src = notify->zone->notifysrc4; + if (!have_notifysource) + src = notify->zone->notifysrc4; break; case PF_INET6: - src = notify->zone->notifysrc6; + if (!have_notifysource) + src = notify->zone->notifysrc6; break; default: result = ISC_R_NOTIMPLEMENTED; @@ -2947,6 +3787,8 @@ notify_send(dns_notify_t *notify) { dst = ai->sockaddr; if (notify_isqueued(notify->zone, NULL, &dst)) continue; + if (notify_isself(notify->zone, &dst)) + continue; new = NULL; result = notify_create(notify->mctx, (notify->flags & DNS_NOTIFY_NOSOA), @@ -2982,8 +3824,9 @@ dns_zone_notify(dns_zone_t *zone) { } static void -zone_notify(dns_zone_t *zone) { +zone_notify(dns_zone_t *zone, isc_time_t *now) { dns_dbnode_t *node = NULL; + dns_db_t *zonedb = NULL; dns_dbversion_t *version = NULL; dns_name_t *origin = NULL; dns_name_t master; @@ -3001,13 +3844,13 @@ zone_notify(dns_zone_t *zone) { dns_notifytype_t notifytype; unsigned int flags = 0; isc_boolean_t loggednotify = ISC_FALSE; - dns_db_t *db = NULL; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); notifytype = zone->notifytype; + DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime); UNLOCK_ZONE(zone); if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) @@ -3016,11 +3859,8 @@ zone_notify(dns_zone_t *zone) { if (notifytype == dns_notifytype_no) return; - LOCK_ZONE(zone); - if (zone->db != NULL) - dns_db_attach(zone->db, &db); - UNLOCK_ZONE(zone); - if (db == NULL) + if (notifytype == dns_notifytype_masteronly && + zone->type != dns_zone_master) return; origin = &zone->origin; @@ -3035,13 +3875,19 @@ zone_notify(dns_zone_t *zone) { /* * Get SOA RRset. */ - dns_db_currentversion(db, &version); - result = dns_db_findnode(db, origin, ISC_FALSE, &node); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) + dns_db_attach(zone->db, &zonedb); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (zonedb == NULL) + return; + dns_db_currentversion(zonedb, &version); + result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto cleanup1; dns_rdataset_init(&soardset); - result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, + result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, dns_rdatatype_none, 0, &soardset, NULL); if (result != ISC_R_SUCCESS) goto cleanup2; @@ -3098,7 +3944,7 @@ zone_notify(dns_zone_t *zone) { */ dns_rdataset_init(&nsrdset); - result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns, + result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns, dns_rdatatype_none, 0, &nsrdset, NULL); if (result != ISC_R_SUCCESS) goto cleanup3; @@ -3155,10 +4001,10 @@ zone_notify(dns_zone_t *zone) { if (dns_name_dynamic(&master)) dns_name_free(&master, zone->mctx); cleanup2: - dns_db_detachnode(db, &node); + dns_db_detachnode(zonedb, &node); cleanup1: - dns_db_closeversion(db, &version, ISC_FALSE); - dns_db_detach(&db); + dns_db_closeversion(zonedb, &version, ISC_FALSE); + dns_db_detach(&zonedb); } /*** @@ -3406,10 +4252,10 @@ stub_callback(isc_task_t *task, isc_event_t *event) { * Tidy up. */ dns_db_closeversion(stub->db, &stub->version, ISC_TRUE); - LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db == NULL) - dns_db_attach(stub->db, &zone->db); - UNLOCK_ZONE(zone); + zone_attachdb(zone, stub->db); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); dns_db_detach(&stub->db); if (zone->masterfile != NULL) { @@ -3955,7 +4801,7 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, } static isc_result_t -add_opt(dns_message_t *message) { +add_opt(dns_message_t *message, isc_uint16_t udpsize) { dns_rdataset_t *rdataset = NULL; dns_rdatalist_t *rdatalist = NULL; dns_rdata_t *rdata = NULL; @@ -3978,7 +4824,7 @@ add_opt(dns_message_t *message) { /* * Set Maximum UDP buffer size. */ - rdatalist->rdclass = SEND_BUFFER_SIZE; + rdatalist->rdclass = udpsize; /* * Set EXTENDED-RCODE, VERSION, DO and Z to 0. @@ -4025,6 +4871,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { isc_boolean_t cancel = ISC_TRUE; int timeout; isc_boolean_t have_xfrsource; + isc_uint16_t udpsize = SEND_BUFFER_SIZE; REQUIRE(DNS_ZONE_VALID(zone)); @@ -4068,7 +4915,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(keyname, namebuf, sizeof(namebuf)); dns_zone_log(zone, ISC_LOG_ERROR, - "unable to find key: %s", namebuf); + "unable to find key: %s", namebuf); } } if (key == NULL) @@ -4088,6 +4935,10 @@ soa_query(isc_task_t *task, isc_event_t *event) { &zone->sourceaddr); if (result == ISC_R_SUCCESS) have_xfrsource = ISC_TRUE; + if (zone->view->resolver != NULL) + udpsize = + dns_resolver_getudpsize(zone->view->resolver); + (void)dns_peer_getudpsize(peer, &udpsize); } } @@ -4119,7 +4970,7 @@ soa_query(isc_task_t *task, isc_event_t *event) { DNS_REQUESTOPT_TCP : 0; if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { - result = add_opt(message); + result = add_opt(message, udpsize); if (result != ISC_R_SUCCESS) zone_debuglog(zone, me, 1, "unable to add opt record: %s", @@ -4184,6 +5035,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { dns_dbnode_t *node = NULL; int timeout; isc_boolean_t have_xfrsource = ISC_FALSE; + isc_uint16_t udpsize = SEND_BUFFER_SIZE; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE((soardataset != NULL && stub == NULL) || @@ -4213,9 +5065,13 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { * new one and attach it to the zone once we have the NS * RRset and glue. */ - if (zone->db != NULL) + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { dns_db_attach(zone->db, &stub->db); - else { + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + } else { + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + INSIST(zone->db_argc >= 1); result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_stub, @@ -4284,7 +5140,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(keyname, namebuf, sizeof(namebuf)); dns_zone_log(zone, ISC_LOG_ERROR, - "unable to find key: %s", namebuf); + "unable to find key: %s", namebuf); } } if (key == NULL) @@ -4303,11 +5159,15 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { &zone->sourceaddr); if (result == ISC_R_SUCCESS) have_xfrsource = ISC_TRUE; + if (zone->view->resolver != NULL) + udpsize = + dns_resolver_getudpsize(zone->view->resolver); + (void)dns_peer_getudpsize(peer, &udpsize); } } if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { - result = add_opt(message); + result = add_opt(message, udpsize); if (result != ISC_R_SUCCESS) zone_debuglog(zone, me, 1, "unable to add opt record: %s", @@ -4367,7 +5227,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { if (message != NULL) dns_message_destroy(&message); unlock: - if (key != NULL) + if (key != NULL) dns_tsigkey_detach(&key); UNLOCK_ZONE(zone); return; @@ -4495,7 +5355,7 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) { switch (zone->type) { case dns_zone_master: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) - next = *now; + next = zone->notifytime; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { INSIST(!isc_time_isepoch(&zone->dumptime)); @@ -4507,7 +5367,7 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) { case dns_zone_slave: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) - next = *now; + next = zone->notifytime; /*FALLTHROUGH*/ case dns_zone_stub: @@ -4582,6 +5442,7 @@ static isc_result_t notify_createmessage(dns_zone_t *zone, unsigned int flags, dns_message_t **messagep) { + dns_db_t *zonedb = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_message_t *message = NULL; @@ -4647,15 +5508,20 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags, if (result != ISC_R_SUCCESS) goto soa_cleanup; + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */ + dns_db_attach(zone->db, &zonedb); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + dns_name_init(tempname, NULL); dns_name_clone(&zone->origin, tempname); - dns_db_currentversion(zone->db, &version); - result = dns_db_findnode(zone->db, tempname, ISC_FALSE, &node); + dns_db_currentversion(zonedb, &version); + result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node); if (result != ISC_R_SUCCESS) goto soa_cleanup; dns_rdataset_init(&rdataset); - result = dns_db_findrdataset(zone->db, node, version, + result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa, dns_rdatatype_none, 0, &rdataset, NULL); @@ -4699,9 +5565,11 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags, soa_cleanup: if (node != NULL) - dns_db_detachnode(zone->db, &node); + dns_db_detachnode(zonedb, &node); if (version != NULL) - dns_db_closeversion(zone->db, &version, ISC_FALSE); + dns_db_closeversion(zonedb, &version, ISC_FALSE); + if (zonedb != NULL) + dns_db_detach(&zonedb); if (tempname != NULL) dns_message_puttempname(message, &tempname); if (temprdata != NULL) @@ -4744,7 +5612,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, * If type != T_SOA return DNS_R_REFUSED. We don't yet support * ROLLOVER. * - * SOA: RFC 1996 + * SOA: RFC1996 * Check that 'from' is a valid notify source, (zone->masters). * Return DNS_R_REFUSED if not. * @@ -5046,6 +5914,19 @@ dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) { zone->update_disabled = state; } +isc_boolean_t +dns_zone_getzeronosoattl(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + return (zone->zero_no_soa_ttl); + +} + +void +dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) { + REQUIRE(DNS_ZONE_VALID(zone)); + zone->zero_no_soa_ttl = state; +} + void dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) { @@ -5244,7 +6125,8 @@ dns_zone_getmaxxfrout(dns_zone_t *zone) { return (zone->maxxfrout); } -dns_zonetype_t dns_zone_gettype(dns_zone_t *zone) { +dns_zonetype_t +dns_zone_gettype(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); return (zone->type); @@ -5265,8 +6147,10 @@ dns_zone_settask(dns_zone_t *zone, isc_task_t *task) { if (zone->task != NULL) isc_task_detach(&zone->task); isc_task_attach(task, &zone->task); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) dns_db_settask(zone->db, zone->task); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); } @@ -5371,7 +6255,9 @@ dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); result = zone_replacedb(zone, db, dump); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); UNLOCK_ZONE(zone); return (result); } @@ -5384,13 +6270,13 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { unsigned int nscount = 0; /* - * 'zone' locked by caller. + * 'zone' and 'zonedb' locked by caller. */ REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); - result = zone_get_from_db(db, &zone->origin, &nscount, &soacount, - NULL, NULL, NULL, NULL, NULL); + result = zone_get_from_db(zone, db, &nscount, &soacount, + NULL, NULL, NULL, NULL, NULL, NULL); if (result == ISC_R_SUCCESS) { if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -5478,7 +6364,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "dumping new zone version"); - result = dns_db_dump(db, ver, zone->masterfile); + result = dns_db_dump2(db, ver, zone->masterfile, + zone->masterformat); if (result != ISC_R_SUCCESS) goto fail; @@ -5518,8 +6405,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { "replacing zone database"); if (zone->db != NULL) - dns_db_detach(&zone->db); - dns_db_attach(db, &zone->db); + zone_detachdb(zone); + zone_attachdb(zone, db); dns_db_settask(zone->db, zone->task); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); return (ISC_R_SUCCESS); @@ -5529,6 +6416,33 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { return (result); } +/* The caller must hold the dblock as a writer. */ +static inline void +zone_attachdb(dns_zone_t *zone, dns_db_t *db) { + REQUIRE(zone->db == NULL && db != NULL); + + dns_db_attach(db, &zone->db); + if (zone->acache != NULL) { + isc_result_t result; + result = dns_acache_setdb(zone->acache, db); + if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "dns_acache_setdb() failed: %s", + isc_result_totext(result)); + } + } +} + +/* The caller must hold the dblock as a writer. */ +static inline void +zone_detachdb(dns_zone_t *zone) { + REQUIRE(zone->db != NULL); + + if (zone->acache != NULL) + (void)dns_acache_putdb(zone->acache, zone->db); + dns_db_detach(&zone->db); +} + static void zone_xfrdone(dns_zone_t *zone, isc_result_t result) { isc_time_t now; @@ -5559,8 +6473,11 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { /* * Has the zone expired underneath us? */ - if (zone->db == NULL) + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db == NULL) { + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); goto same_master; + } /* * Update the zone structure's data from the actual @@ -5569,9 +6486,10 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { nscount = 0; soacount = 0; INSIST(zone->db != NULL); - result = zone_get_from_db(zone->db, &zone->origin, &nscount, + result = zone_get_from_db(zone, zone->db, &nscount, &soacount, &serial, &refresh, - &retry, &expire, &minimum); + &retry, &expire, &minimum, NULL); + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); if (result == ISC_R_SUCCESS) { if (soacount != 1) dns_zone_log(zone, ISC_LOG_ERROR, @@ -6217,13 +7135,9 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, ISC_LIST_INIT(zmgr->waiting_for_xfrin); ISC_LIST_INIT(zmgr->xfrin_in_progress); result = isc_rwlock_init(&zmgr->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_rwlock_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto free_mem; - } + zmgr->transfersin = 10; zmgr->transfersperns = 2; @@ -6254,12 +7168,9 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, ISC_LIST_INIT(zmgr->low); result = isc_mutex_init(&zmgr->iolock); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_mutex_init() failed: %s", - isc_result_totext(result)); + if (result != ISC_R_SUCCESS) goto free_rl; - } + zmgr->magic = ZONEMGR_MAGIC; *zmgrp = zmgr; @@ -6955,6 +7866,7 @@ dns_zone_getkeydirectory(dns_zone_t *zone) { return (zone->keydirectory); } + unsigned int dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) { dns_zone_t *zone; @@ -7046,3 +7958,47 @@ dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { return (ISC_R_SUCCESS); } + +void +dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) { + REQUIRE(DNS_ZONE_VALID(zone)); + zone->checkmx = checkmx; +} + +void +dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) { + REQUIRE(DNS_ZONE_VALID(zone)); + zone->checksrv = checksrv; +} + +void +dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) { + REQUIRE(DNS_ZONE_VALID(zone)); + zone->checkns = checkns; +} + +void +dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) { + REQUIRE(DNS_ZONE_VALID(zone)); + + LOCK_ZONE(zone); + zone->isself = isself; + zone->isselfarg = arg; + UNLOCK_ZONE(zone); +} + +void +dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) { + REQUIRE(DNS_ZONE_VALID(zone)); + + LOCK_ZONE(zone); + zone->notifydelay = delay; + UNLOCK_ZONE(zone); +} + +isc_uint32_t +dns_zone_getnotifydelay(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + + return (zone->notifydelay); +} diff --git a/contrib/bind9/lib/dns/zonekey.c b/contrib/bind9/lib/dns/zonekey.c index dc7ae0f..0ed63bb 100644 --- a/contrib/bind9/lib/dns/zonekey.c +++ b/contrib/bind9/lib/dns/zonekey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zonekey.c,v 1.3.206.3 2004/03/08 09:04:33 marka Exp $ */ +/* $Id: zonekey.c,v 1.5.18.2 2005/04/29 00:16:08 marka Exp $ */ + +/*! \file */ #include <config.h> diff --git a/contrib/bind9/lib/dns/zt.c b/contrib/bind9/lib/dns/zt.c index 7aa6a9f..4cb8f3f 100644 --- a/contrib/bind9/lib/dns/zt.c +++ b/contrib/bind9/lib/dns/zt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,16 +15,24 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zt.c,v 1.33.12.6 2004/03/08 21:06:28 marka Exp $ */ +/* $Id: zt.c,v 1.38.18.5 2005/11/30 03:44:39 marka Exp $ */ + +/*! \file */ #include <config.h> +#include <isc/file.h> #include <isc/magic.h> #include <isc/mem.h> +#include <isc/string.h> #include <isc/util.h> +#include <dns/log.h> +#include <dns/name.h> #include <dns/rbt.h> +#include <dns/rdataclass.h> #include <dns/result.h> +#include <dns/view.h> #include <dns/zone.h> #include <dns/zt.h> @@ -51,6 +59,9 @@ load(dns_zone_t *zone, void *uap); static isc_result_t loadnew(dns_zone_t *zone, void *uap); +static isc_result_t +freezezones(dns_zone_t *zone, void *uap); + isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) { dns_zt_t *zt; @@ -68,13 +79,8 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) { goto cleanup_zt; result = isc_rwlock_init(&zt->rwlock, 0, 0); - if (result != ISC_R_SUCCESS) { - UNEXPECTED_ERROR(__FILE__, __LINE__, - "isc_rwlock_init() failed: %s", - isc_result_totext(result)); - result = ISC_R_UNEXPECTED; + if (result != ISC_R_SUCCESS) goto cleanup_rbt; - } zt->mctx = mctx; zt->references = 1; @@ -266,12 +272,90 @@ loadnew(dns_zone_t *zone, void *uap) { } isc_result_t +dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze) { + isc_result_t result, tresult; + + REQUIRE(VALID_ZT(zt)); + + RWLOCK(&zt->rwlock, isc_rwlocktype_read); + result = dns_zt_apply2(zt, ISC_FALSE, &tresult, freezezones, &freeze); + RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); + return ((result == ISC_R_SUCCESS) ? tresult : result); +} + +static isc_result_t +freezezones(dns_zone_t *zone, void *uap) { + isc_boolean_t freeze = *(isc_boolean_t *)uap; + isc_boolean_t frozen; + isc_result_t result = ISC_R_SUCCESS; + char classstr[DNS_RDATACLASS_FORMATSIZE]; + char zonename[DNS_NAME_FORMATSIZE]; + dns_view_t *view; + char *journal; + const char *vname; + const char *sep; + int level; + + if (dns_zone_gettype(zone) != dns_zone_master) + return (ISC_R_SUCCESS); + + frozen = dns_zone_getupdatedisabled(zone); + if (freeze) { + if (frozen) + result = DNS_R_FROZEN; + if (result == ISC_R_SUCCESS) + result = dns_zone_flush(zone); + if (result == ISC_R_SUCCESS) { + journal = dns_zone_getjournal(zone); + if (journal != NULL) + (void)isc_file_remove(journal); + } + } else { + if (frozen) { + result = dns_zone_load(zone); + if (result == DNS_R_CONTINUE || + result == DNS_R_UPTODATE) + result = ISC_R_SUCCESS; + } + } + if (result == ISC_R_SUCCESS) + dns_zone_setupdatedisabled(zone, freeze); + view = dns_zone_getview(zone); + if (strcmp(view->name, "_bind") == 0 || + strcmp(view->name, "_default") == 0) + { + vname = ""; + sep = ""; + } else { + vname = view->name; + sep = " "; + } + dns_rdataclass_format(dns_zone_getclass(zone), classstr, + sizeof(classstr)); + dns_name_format(dns_zone_getorigin(zone), zonename, sizeof(zonename)); + level = (result != ISC_R_SUCCESS) ? ISC_LOG_ERROR : ISC_LOG_DEBUG(1); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, + level, "%s zone '%s/%s'%s%s: %s", + freeze ? "freezing" : "thawing", + zonename, classstr, sep, vname, + isc_result_totext(result)); + return (result); +} + +isc_result_t dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop, isc_result_t (*action)(dns_zone_t *, void *), void *uap) { + return (dns_zt_apply2(zt, stop, NULL, action, uap)); +} + +isc_result_t +dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub, + isc_result_t (*action)(dns_zone_t *, void *), void *uap) +{ dns_rbtnode_t *node; dns_rbtnodechain_t chain; - isc_result_t result; + isc_result_t result, tresult = ISC_R_SUCCESS; dns_zone_t *zone; REQUIRE(VALID_ZT(zt)); @@ -292,8 +376,12 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop, zone = node->data; if (zone != NULL) result = (action)(zone, uap); - if (result != ISC_R_SUCCESS && stop) + if (result != ISC_R_SUCCESS && stop) { + tresult = result; goto cleanup; /* don't break */ + } else if (result != ISC_R_SUCCESS && + tresult == ISC_R_SUCCESS) + tresult = result; } result = dns_rbtnodechain_next(&chain, NULL, NULL); } @@ -302,6 +390,8 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop, cleanup: dns_rbtnodechain_invalidate(&chain); + if (sub != NULL) + *sub = tresult; return (result); } |