ncache.c revision 29d52c001ff976561669375cf0c866b815a90c49
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2004, 2005, 2007, 2008, 2010-2015 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 1999-2003 Internet Software Consortium.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Permission to use, copy, modify, and/or distribute this software for any
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15a44745412679c30a6d022733925af70a38b715David Lawrence * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15a44745412679c30a6d022733925af70a38b715David Lawrence * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15a44745412679c30a6d022733925af70a38b715David Lawrence * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15a44745412679c30a6d022733925af70a38b715David Lawrence * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PERFORMANCE OF THIS SOFTWARE.
55bf97a1b4b7f78b669b1179df1422cb9789c484Michael Sawyer * The format of an ncache rdata is a sequence of zero or more records of
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * the following format:
55bf97a1b4b7f78b669b1179df1422cb9789c484Michael Sawyer * rdata count
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer * rdata length These two occur 'rdata count'
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * rdata times.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyeraddoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
056aaae3e2399b2c1df8f82be52d9bd43ceda50cMichael Sawyer dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyercopy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer unsigned int count;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Copy the rdataset count to the buffer.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(buffer, (isc_uint16_t)count);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Copy the rdata length to the buffer.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Copy the rdata to the buffer.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyerdns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer return (addoptout(message, cache, node, covers, now, maxttl,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_boolean_t optout, dns_rdataset_t *addedrdataset)
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington return (addoptout(message, cache, node, covers, now, maxttl,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyeraddoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington unsigned int next = 0;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Convert the authority data from 'message' into a negative cache
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * rdataset, and store it in 'cache' at 'node'.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * We assume that all data in the authority section has been
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington * validated by the caller.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Initialize the list.
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington * Build an ncache rdatas into buffer.
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington isc_buffer_init(&buffer, data, sizeof(data));
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington if (message->counts[DNS_SECTION_AUTHORITY])
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer dns_message_currentname(message, DNS_SECTION_AUTHORITY,
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson for (rdataset = ISC_LIST_HEAD(name->list);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson rdataset = ISC_LIST_NEXT(rdataset, link)) {
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Copy the owner name to the buffer.
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * Copy the type to the buffer.
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Copy the rdataset into the buffer.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson message->counts[DNS_SECTION_ANSWER] == 0) {
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson * The response has aa set and we haven't followed
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * any CNAME or DNAME chains.
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson if (message->rcode == dns_rcode_nxdomain)
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned int *countp)
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * Convert the negative caching rdataset 'rdataset' to wire format,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * compressing names as specified in 'cctx', and storing the result in
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_init(&source, rdata.data, rdata.length);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews isc_buffer_remainingregion(&source, &remaining);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson for (i = 0; i < rcount; i++) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * Get the length of this rdata and set up an
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson * rdata structure for it.
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer isc_buffer_remainingregion(&source, &remaining);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer rdata.length = isc_buffer_getuint16(&source);
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson isc_buffer_remainingregion(&source, &remaining);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * Write the name.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer result = dns_name_towire(&name, cctx, target);
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson * See if we have space for type, class, ttl, and
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson * rdata length. Write the type, class, and ttl.
ee4429e13e08f30c366cdc5d10585388b8a9f212Michael Sawyer isc_buffer_availableregion(target, &tavailable);
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson isc_buffer_putuint16(target, rdataset->rdclass);
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson isc_buffer_putuint32(target, rdataset->ttl);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer * Save space for rdata length.
93988fb202645e5d06b337b8e3e20765a467149dAndreas Gustafsson * Write the rdata.
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer result = dns_rdata_towire(&rdata, cctx, target);
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson * Set the rdata length field to the compressed
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson INSIST((target->used >= rdlen.used + 2) &&
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson (target->used - rdlen.used - 2 < 65536));
7ddb4c86a95ab721a70d406821352ce7b730a1bdAndreas Gustafsson INSIST(isc_buffer_remaininglength(&source) == 0);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerrdataset_disassociate(dns_rdataset_t *rdataset) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyer unsigned int count;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer * The privateuint4 field is the number of rdata beyond the cursor
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * position, so we decrement the total count by one before storing
3291587f23b940c986f41cf37b2e531f618ec2bdMichael Sawyer unsigned int count;
3291587f23b940c986f41cf37b2e531f618ec2bdMichael Sawyer unsigned int length;
3291587f23b940c986f41cf37b2e531f618ec2bdMichael Sawyer unsigned char *raw;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerrdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyerrdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Reset iterator state.
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerstatic unsigned int
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned int count;
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerrdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
844eaa56d6d647b38b2a5cf08f7ea5ab7b752690Michael Sawyerstatic dns_rdatasetmethods_t rdataset_methods = {
d821f1cd7e97552401296e880e7518c98c9ebea1Michael Sawyerdns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson dns_rdatatype_t type, dns_rdataset_t *rdataset)
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer REQUIRE(!dns_rdataset_isassociated(rdataset));
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer isc_buffer_init(&source, rdata.data, rdata.length);
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer isc_buffer_remainingregion(&source, &remaining);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer if (ttype == type && dns_name_equal(&tname, name)) {
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer isc_buffer_remainingregion(&source, &remaining);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Reset iterator state.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
e42c402595802edceafbd3e5338dda011fbbcdb6Michael Sawyer dns_rdatatype_t covers, dns_rdataset_t *rdataset)
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned char *raw;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer unsigned int count;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE(!dns_rdataset_isassociated(rdataset));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&source, rdata.data, rdata.length);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_remainingregion(&source, &remaining);
5d20773abcdf9ff3afe14a349413174f94594188Michael Sawyer dns_rdata_fromregion(&rdata, rdataset->rdclass,
37e6e0ca1337351642798b1a6aa24ae40bf86399Andreas Gustafsson (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
aa6054ec74819f754bcf19442ca9b39d948171adMichael Sawyer isc_buffer_remainingregion(&source, &remaining);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Reset iterator state.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyerdns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer unsigned int count;
cefd68008fbba3488a077052ae62aa12b6de502bMichael Sawyer unsigned char *raw;
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
b266f8fc42702debc6bd89365273223fa89cd8ddBrian Wellington REQUIRE(!dns_rdataset_isassociated(rdataset));
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdataset_current(ncacherdataset, &rdata);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_init(&source, rdata.data, rdata.length);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_remainingregion(&source, &remaining);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer isc_buffer_remainingregion(&source, &remaining);
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer * Extract covers from RRSIG.
6fe03d6c83ec02d4494edc870f5e892d419b6885Michael Sawyer dns_rdata_fromregion(&rdata, rdataset->rdclass,
07a926724c0a91d85b85a94441938d0094e88cffMark Andrews (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
5f01e77fc23fe9665fa2b8acd0a0c5bfbf61d61dBrian Wellington * Reset iterator state.