ncache.c revision fbe2cff19f5cddc67b967764ad95038dfcafc85a
1b5a34533410ff4eaff0e5b5b110221a97e29cfcAutomatic Updater * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1999-2003 Internet Software Consortium.
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * purpose with or without fee is hereby granted, provided that the above
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
557bcc2092642b2d4668c9b08872c9f2bb88bddbMark Andrews/* $Id: ncache.c,v 1.53 2011/05/26 23:11:15 each Exp $ */
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington * The format of an ncache rdata is a sequence of zero or more records of
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * the following format:
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * rdata count
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * rdata length These two occur 'rdata count'
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * rdata times.
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellingtoncopy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington * Copy the rdataset count to the buffer.
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington isc_buffer_putuint16(buffer, (isc_uint16_t)count);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Copy the rdata length to the buffer.
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Copy the rdata to the buffer.
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington result = isc_buffer_copyregion(buffer, &r);
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellingtondns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington return (dns_ncache_addoptout(message, cache, node, covers, now, maxttl,
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeindns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
571688b02f955f6304649866e768b1f81739cbedBrian Wellington dns_dbnode_t *node, dns_rdatatype_t covers,
571688b02f955f6304649866e768b1f81739cbedBrian Wellington isc_boolean_t optout, dns_rdataset_t *addedrdataset)
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington unsigned int next = 0;
557bcc2092642b2d4668c9b08872c9f2bb88bddbMark Andrews * Convert the authority data from 'message' into a negative cache
557bcc2092642b2d4668c9b08872c9f2bb88bddbMark Andrews * rdataset, and store it in 'cache' at 'node'.
23f64ea0dcd7f5b7094ae6ade2a002fb7dde1466Brian Wellington * We assume that all data in the authority section has been
e2fd12f3a020ca8c5de168a44fb72e339cdaa3e9Brian Wellington * validated by the caller.
23f64ea0dcd7f5b7094ae6ade2a002fb7dde1466Brian Wellington * Initialize the list.
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington * Build an ncache rdatas into buffer.
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_init(&buffer, data, sizeof(data));
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington if (message->counts[DNS_SECTION_AUTHORITY])
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington dns_message_currentname(message, DNS_SECTION_AUTHORITY,
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington rdataset = ISC_LIST_NEXT(rdataset, link)) {
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington * Copy the owner name to the buffer.
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington * Copy the type to the buffer.
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington * Copy the rdataset into the buffer.
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington message->counts[DNS_SECTION_ANSWER] == 0) {
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington * The response has aa set and we haven't followed
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington * any CNAME or DNAME chains.
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
e2fd12f3a020ca8c5de168a44fb72e339cdaa3e9Brian Wellington ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
e2fd12f3a020ca8c5de168a44fb72e339cdaa3e9Brian Wellington ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
e2fd12f3a020ca8c5de168a44fb72e339cdaa3e9Brian Wellington return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
77ac297199fc44809d9628558223627c10ae3f31Brian Wellingtondns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington isc_buffer_t *target, unsigned int options,
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington unsigned int *countp)
77ac297199fc44809d9628558223627c10ae3f31Brian Wellington * Convert the negative caching rdataset 'rdataset' to wire format,
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * compressing names as specified in 'cctx', and storing the result in
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson isc_buffer_init(&source, rdata.data, rdata.length);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington for (i = 0; i < rcount; i++) {
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Get the length of this rdata and set up an
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * rdata structure for it.
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington rdata.length = isc_buffer_getuint16(&source);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Write the name.
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson result = dns_name_towire(&name, cctx, target);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson * See if we have space for type, class, ttl, and
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson * rdata length. Write the type, class, and ttl.
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson isc_buffer_availableregion(target, &tavailable);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson isc_buffer_putuint16(target, rdataset->rdclass);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson isc_buffer_putuint32(target, rdataset->ttl);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson * Save space for rdata length.
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson * Write the rdata.
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson result = dns_rdata_towire(&rdata, cctx, target);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson * Set the rdata length field to the compressed
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson INSIST((target->used >= rdlen.used + 2) &&
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson (target->used - rdlen.used - 2 < 65536));
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson INSIST(isc_buffer_remaininglength(&source) == 0);
a4c351fcef77fb332e3cb20253fb96556a414a17Brian Wellington dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafssonrdataset_disassociate(dns_rdataset_t *rdataset) {
6b79e960e6ba2991aeb02a6c39af255ab7f06d99Mark Andrews unsigned int count;
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson * The privateuint4 field is the number of rdata beyond the cursor
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * position, so we decrement the total count by one before storing
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington unsigned char *raw;
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellingtonrdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellingtonrdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington * Reset iterator state.
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellingtonstatic unsigned int
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellingtonrdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellingtonstatic dns_rdatasetmethods_t rdataset_methods = {
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafssondns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson dns_rdatatype_t type, dns_rdataset_t *rdataset)
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson REQUIRE(!dns_rdataset_isassociated(rdataset));
307ba34fa07db768c3a899844f248a2c1d7dcc7fAndreas Gustafsson dns_rdataset_clone(ncacherdataset, &clone);
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington isc_buffer_init(&source, rdata.data, rdata.length);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson if (ttype == type && dns_name_equal(&tname, name)) {
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington rdataset->rdclass = ncacherdataset->rdclass;
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Reset iterator state.
e2fd12f3a020ca8c5de168a44fb72e339cdaa3e9Brian Wellingtondns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
e2fd12f3a020ca8c5de168a44fb72e339cdaa3e9Brian Wellington dns_rdatatype_t covers, dns_rdataset_t *rdataset)
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington unsigned char *raw;
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington REQUIRE(!dns_rdataset_isassociated(rdataset));
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington dns_rdataset_clone(ncacherdataset, &clone);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_init(&source, rdata.data, rdata.length);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington dns_rdata_fromregion(&rdata, rdataset->rdclass,
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington rdataset->rdclass = ncacherdataset->rdclass;
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Reset iterator state.
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellingtondns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington unsigned char *raw;
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington REQUIRE(!dns_rdataset_isassociated(rdataset));
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington dns_rdataset_current(ncacherdataset, &rdata);
229ce407c359b0b641759ba1fc4a5fa2054a44daBrian Wellington isc_buffer_init(&source, rdata.data, rdata.length);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_remainingregion(&source, &remaining);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington isc_buffer_forward(&source, found->length);
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington isc_buffer_remainingregion(&source, &remaining);
60b90a37f41ab7607762d0e9791e79bd19eae4f4Brian Wellington rdataset->rdclass = ncacherdataset->rdclass;
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Extract covers from RRSIG.
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington dns_rdata_fromregion(&rdata, rdataset->rdclass,
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
033ba09d6df0ac92a736a480b9c3b164b61dccb2Brian Wellington * Reset iterator state.