summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/dns/ncache.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns/ncache.c')
-rw-r--r--contrib/bind9/lib/dns/ncache.c559
1 files changed, 0 insertions, 559 deletions
diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c
deleted file mode 100644
index 1fdc5c8..0000000
--- a/contrib/bind9/lib/dns/ncache.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * 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
- * 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: ncache.c,v 1.36.18.3 2005/04/29 00:15:59 marka Exp $ */
-
-/*! \file */
-
-#include <config.h>
-
-#include <isc/buffer.h>
-#include <isc/util.h>
-
-#include <dns/db.h>
-#include <dns/message.h>
-#include <dns/ncache.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
-#include <dns/rdataset.h>
-
-/*
- * The format of an ncache rdata is a sequence of one or more records of
- * the following format:
- *
- * owner name
- * type
- * rdata count
- * rdata length These two occur 'rdata count'
- * rdata times.
- *
- */
-
-static inline isc_result_t
-copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
- isc_result_t result;
- unsigned int count;
- isc_region_t ar, r;
- dns_rdata_t rdata = DNS_RDATA_INIT;
-
- /*
- * Copy the rdataset count to the buffer.
- */
- isc_buffer_availableregion(buffer, &ar);
- if (ar.length < 2)
- return (ISC_R_NOSPACE);
- count = dns_rdataset_count(rdataset);
- INSIST(count <= 65535);
- isc_buffer_putuint16(buffer, (isc_uint16_t)count);
-
- result = dns_rdataset_first(rdataset);
- while (result == ISC_R_SUCCESS) {
- dns_rdataset_current(rdataset, &rdata);
- dns_rdata_toregion(&rdata, &r);
- INSIST(r.length <= 65535);
- isc_buffer_availableregion(buffer, &ar);
- if (ar.length < 2)
- return (ISC_R_NOSPACE);
- /*
- * Copy the rdata length to the buffer.
- */
- isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
- /*
- * Copy the rdata to the buffer.
- */
- result = isc_buffer_copyregion(buffer, &r);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(rdataset);
- }
- if (result != ISC_R_NOMORE)
- return (result);
-
- return (ISC_R_SUCCESS);
-}
-
-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)
-{
- isc_result_t result;
- isc_buffer_t buffer;
- isc_region_t r;
- dns_rdataset_t *rdataset;
- dns_rdatatype_t type;
- dns_name_t *name;
- dns_ttl_t ttl;
- dns_trust_t trust;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_t ncrdataset;
- dns_rdatalist_t ncrdatalist;
- unsigned char data[4096];
-
- /*
- * Convert the authority data from 'message' into a negative cache
- * rdataset, and store it in 'cache' at 'node'.
- */
-
- REQUIRE(message != NULL);
-
- /*
- * We assume that all data in the authority section has been
- * validated by the caller.
- */
-
- /*
- * First, build an ncache rdata in buffer.
- */
- ttl = maxttl;
- trust = 0xffff;
- isc_buffer_init(&buffer, data, sizeof(data));
- if (message->counts[DNS_SECTION_AUTHORITY])
- result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
- else
- result = ISC_R_NOMORE;
- while (result == ISC_R_SUCCESS) {
- name = NULL;
- dns_message_currentname(message, DNS_SECTION_AUTHORITY,
- &name);
- if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
- for (rdataset = ISC_LIST_HEAD(name->list);
- rdataset != NULL;
- rdataset = ISC_LIST_NEXT(rdataset, link)) {
- if ((rdataset->attributes &
- DNS_RDATASETATTR_NCACHE) == 0)
- continue;
- type = rdataset->type;
- if (type == dns_rdatatype_rrsig)
- type = rdataset->covers;
- if (type == dns_rdatatype_soa ||
- type == dns_rdatatype_nsec) {
- if (ttl > rdataset->ttl)
- ttl = rdataset->ttl;
- if (trust > rdataset->trust)
- trust = rdataset->trust;
- /*
- * Copy the owner name to the buffer.
- */
- dns_name_toregion(name, &r);
- result = isc_buffer_copyregion(&buffer,
- &r);
- if (result != ISC_R_SUCCESS)
- return (result);
- /*
- * Copy the type to the buffer.
- */
- isc_buffer_availableregion(&buffer,
- &r);
- if (r.length < 2)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(&buffer,
- rdataset->type);
- /*
- * Copy the rdataset into the buffer.
- */
- result = copy_rdataset(rdataset,
- &buffer);
- if (result != ISC_R_SUCCESS)
- return (result);
- }
- }
- }
- result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
- }
- if (result != ISC_R_NOMORE)
- return (result);
-
- if (trust == 0xffff) {
- /*
- * We didn't find any authority data from which to create a
- * negative cache rdataset. In particular, we have no SOA.
- *
- * We trust that the caller wants negative caching, so this
- * means we have a "type 3 nxdomain" or "type 3 nodata"
- * 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
- * wire format.
- */
-
- /*
- * The ownername must exist, but it doesn't matter what value
- * it has. We use the root name.
- */
- dns_name_toregion(dns_rootname, &r);
- result = isc_buffer_copyregion(&buffer, &r);
- if (result != ISC_R_SUCCESS)
- return (result);
- /*
- * Copy the type and a zero rdata count to the buffer.
- */
- isc_buffer_availableregion(&buffer, &r);
- if (r.length < 4)
- return (ISC_R_NOSPACE);
- isc_buffer_putuint16(&buffer, 0);
- isc_buffer_putuint16(&buffer, 0);
- /*
- * RFC2308, section 5, says that negative answers without
- * SOAs should not be cached.
- */
- ttl = 0;
- /*
- * Set trust.
- */
- if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
- message->counts[DNS_SECTION_ANSWER] == 0) {
- /*
- * The response has aa set and we haven't followed
- * any CNAME or DNAME chains.
- */
- trust = dns_trust_authauthority;
- } else
- trust = dns_trust_additional;
- }
-
- /*
- * Now add it to the cache.
- */
- INSIST(trust != 0xffff);
- isc_buffer_usedregion(&buffer, &r);
- rdata.data = r.base;
- rdata.length = r.length;
- rdata.rdclass = dns_db_class(cache);
- rdata.type = 0;
- rdata.flags = 0;
-
- ncrdatalist.rdclass = rdata.rdclass;
- ncrdatalist.type = 0;
- ncrdatalist.covers = covers;
- ncrdatalist.ttl = ttl;
- ISC_LIST_INIT(ncrdatalist.rdata);
- ISC_LINK_INIT(&ncrdatalist, link);
-
- ISC_LIST_APPEND(ncrdatalist.rdata, &rdata, link);
-
- dns_rdataset_init(&ncrdataset);
- RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
- == ISC_R_SUCCESS);
- ncrdataset.trust = trust;
- if (message->rcode == dns_rcode_nxdomain)
- ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
-
- return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
- 0, addedrdataset));
-}
-
-isc_result_t
-dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
- isc_buffer_t *target, unsigned int options,
- unsigned int *countp)
-{
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- isc_region_t remaining, tavailable;
- isc_buffer_t source, savedbuffer, rdlen;
- dns_name_t name;
- dns_rdatatype_t type;
- unsigned int i, rcount, count;
-
- /*
- * Convert the negative caching rdataset 'rdataset' to wire format,
- * compressing names as specified in 'cctx', and storing the result in
- * 'target'.
- */
-
- REQUIRE(rdataset != NULL);
- REQUIRE(rdataset->type == 0);
-
- result = dns_rdataset_first(rdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(rdataset, &rdata);
- INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE);
- isc_buffer_init(&source, rdata.data, rdata.length);
- isc_buffer_add(&source, rdata.length);
-
- savedbuffer = *target;
-
- count = 0;
- do {
- dns_name_init(&name, NULL);
- isc_buffer_remainingregion(&source, &remaining);
- dns_name_fromregion(&name, &remaining);
- INSIST(remaining.length >= name.length);
- isc_buffer_forward(&source, name.length);
- remaining.length -= name.length;
-
- INSIST(remaining.length >= 4);
- type = isc_buffer_getuint16(&source);
- rcount = isc_buffer_getuint16(&source);
-
- for (i = 0; i < rcount; i++) {
- /*
- * Get the length of this rdata and set up an
- * rdata structure for it.
- */
- isc_buffer_remainingregion(&source, &remaining);
- INSIST(remaining.length >= 2);
- dns_rdata_reset(&rdata);
- rdata.length = isc_buffer_getuint16(&source);
- isc_buffer_remainingregion(&source, &remaining);
- rdata.data = remaining.base;
- rdata.type = type;
- rdata.rdclass = rdataset->rdclass;
- INSIST(remaining.length >= rdata.length);
- isc_buffer_forward(&source, rdata.length);
-
- if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
- dns_rdatatype_isdnssec(type))
- continue;
-
- /*
- * Write the name.
- */
- dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
- result = dns_name_towire(&name, cctx, target);
- if (result != ISC_R_SUCCESS)
- goto rollback;
-
- /*
- * See if we have space for type, class, ttl, and
- * rdata length. Write the type, class, and ttl.
- */
- isc_buffer_availableregion(target, &tavailable);
- if (tavailable.length < 10) {
- result = ISC_R_NOSPACE;
- goto rollback;
- }
- isc_buffer_putuint16(target, type);
- isc_buffer_putuint16(target, rdataset->rdclass);
- isc_buffer_putuint32(target, rdataset->ttl);
-
- /*
- * Save space for rdata length.
- */
- rdlen = *target;
- isc_buffer_add(target, 2);
-
- /*
- * Write the rdata.
- */
- result = dns_rdata_towire(&rdata, cctx, target);
- if (result != ISC_R_SUCCESS)
- goto rollback;
-
- /*
- * Set the rdata length field to the compressed
- * length.
- */
- INSIST((target->used >= rdlen.used + 2) &&
- (target->used - rdlen.used - 2 < 65536));
- isc_buffer_putuint16(&rdlen,
- (isc_uint16_t)(target->used -
- rdlen.used - 2));
-
- count++;
- }
- isc_buffer_remainingregion(&source, &remaining);
- } while (remaining.length > 0);
-
- *countp = count;
-
- return (ISC_R_SUCCESS);
-
- rollback:
- INSIST(savedbuffer.used < 65536);
- dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
- *countp = 0;
- *target = savedbuffer;
-
- return (result);
-}
-
-static void
-rdataset_disassociate(dns_rdataset_t *rdataset) {
- UNUSED(rdataset);
-}
-
-static isc_result_t
-rdataset_first(dns_rdataset_t *rdataset) {
- unsigned char *raw = rdataset->private3;
- unsigned int count;
-
- count = raw[0] * 256 + raw[1];
- if (count == 0) {
- rdataset->private5 = NULL;
- return (ISC_R_NOMORE);
- }
- 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.
- */
- count--;
- rdataset->privateuint4 = count;
- rdataset->private5 = raw;
-
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-rdataset_next(dns_rdataset_t *rdataset) {
- unsigned int count;
- unsigned int length;
- unsigned char *raw;
-
- count = rdataset->privateuint4;
- if (count == 0)
- return (ISC_R_NOMORE);
- count--;
- rdataset->privateuint4 = count;
- raw = rdataset->private5;
- length = raw[0] * 256 + raw[1];
- raw += length + 2;
- rdataset->private5 = raw;
-
- return (ISC_R_SUCCESS);
-}
-
-static void
-rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
- unsigned char *raw = rdataset->private5;
- isc_region_t r;
-
- REQUIRE(raw != NULL);
-
- r.length = raw[0] * 256 + raw[1];
- raw += 2;
- r.base = raw;
- dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
-}
-
-static void
-rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
- *target = *source;
-
- /*
- * Reset iterator state.
- */
- target->privateuint4 = 0;
- target->private5 = NULL;
-}
-
-static unsigned int
-rdataset_count(dns_rdataset_t *rdataset) {
- unsigned char *raw = rdataset->private3;
- unsigned int count;
-
- count = raw[0] * 256 + raw[1];
-
- return (count);
-}
-
-static dns_rdatasetmethods_t rdataset_methods = {
- rdataset_disassociate,
- rdataset_first,
- rdataset_next,
- rdataset_current,
- rdataset_clone,
- rdataset_count,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-isc_result_t
-dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
- dns_rdatatype_t type, dns_rdataset_t *rdataset)
-{
- isc_result_t result;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t remaining;
- isc_buffer_t source;
- dns_name_t tname;
- dns_rdatatype_t ttype;
- unsigned int i, rcount;
- isc_uint16_t length;
-
- REQUIRE(ncacherdataset != NULL);
- REQUIRE(ncacherdataset->type == 0);
- REQUIRE(name != NULL);
- REQUIRE(!dns_rdataset_isassociated(rdataset));
- REQUIRE(type != dns_rdatatype_rrsig);
-
- result = dns_rdataset_first(ncacherdataset);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_rdataset_current(ncacherdataset, &rdata);
- INSIST(dns_rdataset_next(ncacherdataset) == ISC_R_NOMORE);
- isc_buffer_init(&source, rdata.data, rdata.length);
- isc_buffer_add(&source, rdata.length);
-
- do {
- dns_name_init(&tname, NULL);
- isc_buffer_remainingregion(&source, &remaining);
- dns_name_fromregion(&tname, &remaining);
- INSIST(remaining.length >= tname.length);
- isc_buffer_forward(&source, tname.length);
- remaining.length -= tname.length;
-
- INSIST(remaining.length >= 4);
- ttype = isc_buffer_getuint16(&source);
-
- if (ttype == type && dns_name_equal(&tname, name)) {
- isc_buffer_remainingregion(&source, &remaining);
- break;
- }
-
- rcount = isc_buffer_getuint16(&source);
- for (i = 0; i < rcount; i++) {
- isc_buffer_remainingregion(&source, &remaining);
- INSIST(remaining.length >= 2);
- length = isc_buffer_getuint16(&source);
- isc_buffer_remainingregion(&source, &remaining);
- INSIST(remaining.length >= length);
- isc_buffer_forward(&source, length);
- }
- isc_buffer_remainingregion(&source, &remaining);
- } while (remaining.length > 0);
-
- if (remaining.length == 0)
- return (ISC_R_NOTFOUND);
-
- rdataset->methods = &rdataset_methods;
- rdataset->rdclass = ncacherdataset->rdclass;
- rdataset->type = type;
- rdataset->covers = 0;
- rdataset->ttl = ncacherdataset->ttl;
- rdataset->trust = ncacherdataset->trust;
- rdataset->private1 = NULL;
- rdataset->private2 = NULL;
-
- rdataset->private3 = remaining.base;
-
- /*
- * Reset iterator state.
- */
- rdataset->privateuint4 = 0;
- rdataset->private5 = NULL;
- return (ISC_R_SUCCESS);
-}
OpenPOWER on IntegriCloud