ncache.c revision a8da00ef95ba37b9d071c2b8db1a0c967e060106
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley/*
523ad879ce1abb51cae579a6393da0e0436fe8dfTinderbox User * Copyright (C) 2004, 2005, 2007, 2008, 2010-2014 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1999-2003 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * purpose with or without fee is hereby granted, provided that the above
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
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.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id$ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley#include <config.h>
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
f1788d67add6bf3d301e91b3f54fa3c90a87328eBrian Wellington#include <isc/buffer.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley#include <dns/db.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dns/message.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dns/ncache.h>
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley#include <dns/rdata.h>
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley#include <dns/rdatalist.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <dns/rdataset.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <dns/rdatastruct.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define DNS_NCACHE_RDATA 20U
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley/*
c1ee8bb4ba3e9ab1463403ed685729631de406b1Mark Andrews * The format of an ncache rdata is a sequence of zero or more records of
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * the following format:
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley *
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * owner name
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * type
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * trust
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * rdata count
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * rdata length These two occur 'rdata count'
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * rdata times.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley *
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrewsstatic isc_result_t
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrewsaddoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews isc_boolean_t optout, isc_boolean_t secure,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews dns_rdataset_t *addedrdataset);
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleystatic inline isc_result_t
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleycopy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_result_t result;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley unsigned int count;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_region_t ar, r;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley /*
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Copy the rdataset count to the buffer.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(buffer, &ar);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley if (ar.length < 2)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley return (ISC_R_NOSPACE);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley count = dns_rdataset_count(rdataset);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley INSIST(count <= 65535);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_buffer_putuint16(buffer, (isc_uint16_t)count);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley result = dns_rdataset_first(rdataset);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley while (result == ISC_R_SUCCESS) {
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_rdataset_current(rdataset, &rdata);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_rdata_toregion(&rdata, &r);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley INSIST(r.length <= 65535);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(buffer, &ar);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley if (ar.length < 2)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley return (ISC_R_NOSPACE);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley /*
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Copy the rdata length to the buffer.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley /*
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * Copy the rdata to the buffer.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley result = isc_buffer_copyregion(buffer, &r);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley if (result != ISC_R_SUCCESS)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley return (result);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews dns_rdata_reset(&rdata);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley result = dns_rdataset_next(rdataset);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley }
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley if (result != ISC_R_NOMORE)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley return (result);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley return (ISC_R_SUCCESS);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley}
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleyisc_result_t
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleydns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
7cd4c3ddd1baf5f2b204562fdba3da37c716cc78Andreas Gustafsson dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_rdataset_t *addedrdataset)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews return (addoptout(message, cache, node, covers, now, maxttl,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews ISC_FALSE, ISC_FALSE, addedrdataset));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_dbnode_t *node, dns_rdatatype_t covers,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_stdtime_t now, dns_ttl_t maxttl,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_boolean_t optout, dns_rdataset_t *addedrdataset)
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews{
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews return (addoptout(message, cache, node, covers, now, maxttl,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews optout, ISC_TRUE, addedrdataset));
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews}
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrewsstatic isc_result_t
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrewsaddoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews isc_boolean_t optout, isc_boolean_t secure,
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews dns_rdataset_t *addedrdataset)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley{
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_result_t result;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_buffer_t buffer;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley isc_region_t r;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_rdataset_t *rdataset;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_rdatatype_t type;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_name_t *name;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_ttl_t ttl;
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley dns_trust_t trust;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_t rdata[DNS_NCACHE_RDATA];
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley dns_rdataset_t ncrdataset;
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley dns_rdatalist_t ncrdatalist;
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley unsigned char data[4096];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int next = 0;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Convert the authority data from 'message' into a negative cache
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * rdataset, and store it in 'cache' at 'node'.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley REQUIRE(message != NULL);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley /*
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * We assume that all data in the authority section has been
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley * validated by the caller.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Initialize the list.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdatalist.rdclass = dns_db_class(cache);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdatalist.type = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdatalist.covers = covers;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdatalist.ttl = maxttl;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ISC_LIST_INIT(ncrdatalist.rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ISC_LINK_INIT(&ncrdatalist, link);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Build an ncache rdatas into buffer.
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley */
7cd4c3ddd1baf5f2b204562fdba3da37c716cc78Andreas Gustafsson ttl = maxttl;
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley trust = 0xffff;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&buffer, data, sizeof(data));
4607e7a9b8dfb1b41c70e51c2b603daaf22cf302Mark Andrews if (message->counts[DNS_SECTION_AUTHORITY])
4607e7a9b8dfb1b41c70e51c2b603daaf22cf302Mark Andrews result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
4607e7a9b8dfb1b41c70e51c2b603daaf22cf302Mark Andrews else
4607e7a9b8dfb1b41c70e51c2b603daaf22cf302Mark Andrews result = ISC_R_NOMORE;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley while (result == ISC_R_SUCCESS) {
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley name = NULL;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_message_currentname(message, DNS_SECTION_AUTHORITY,
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley &name);
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley for (rdataset = ISC_LIST_HEAD(name->list);
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley rdataset != NULL;
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley rdataset = ISC_LIST_NEXT(rdataset, link)) {
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley if ((rdataset->attributes &
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley DNS_RDATASETATTR_NCACHE) == 0)
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley continue;
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley type = rdataset->type;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (type == dns_rdatatype_rrsig)
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley type = rdataset->covers;
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley if (type == dns_rdatatype_soa ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews type == dns_rdatatype_nsec ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews type == dns_rdatatype_nsec3) {
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley if (ttl > rdataset->ttl)
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley ttl = rdataset->ttl;
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley if (trust > rdataset->trust)
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley trust = rdataset->trust;
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley /*
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley * Copy the owner name to the buffer.
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley */
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley dns_name_toregion(name, &r);
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley result = isc_buffer_copyregion(&buffer,
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley &r);
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley if (result != ISC_R_SUCCESS)
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley return (result);
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley /*
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley * Copy the type to the buffer.
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_buffer_availableregion(&buffer,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence &r);
fbe2cff19f5cddc67b967764ad95038dfcafc85aEvan Hunt if (r.length < 3)
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley return (ISC_R_NOSPACE);
b5fff54fe9335b20c02d749831fc0eaeda97198fBrian Wellington isc_buffer_putuint16(&buffer,
b5fff54fe9335b20c02d749831fc0eaeda97198fBrian Wellington rdataset->type);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_putuint8(&buffer,
32f985bcf464816d3a8700185afdebb122cb4cecMark Andrews (unsigned char)rdataset->trust);
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley /*
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley * Copy the rdataset into the buffer.
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley */
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley result = copy_rdataset(rdataset,
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley &buffer);
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley if (result != ISC_R_SUCCESS)
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (next >= DNS_NCACHE_RDATA)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOSPACE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_init(&rdata[next]);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_remainingregion(&buffer, &r);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdata[next].data = r.base;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdata[next].length = r.length;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdata[next].rdclass =
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdatalist.rdclass;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdata[next].type = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdata[next].flags = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ISC_LIST_APPEND(ncrdatalist.rdata,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews &rdata[next], link);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_forward(&buffer, r.length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews next++;
e0df061f35a26d2bbd0986aa889f88b3710b32d4Bob Halley }
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley }
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley }
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley }
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley if (result != ISC_R_NOMORE)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley return (result);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley if (trust == 0xffff) {
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley message->counts[DNS_SECTION_ANSWER] == 0) {
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley /*
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley * The response has aa set and we haven't followed
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley * any CNAME or DNAME chains.
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley */
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley trust = dns_trust_authauthority;
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley } else
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley trust = dns_trust_additional;
c1ee8bb4ba3e9ab1463403ed685729631de406b1Mark Andrews ttl = 0;
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley }
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley INSIST(trust != 0xffff);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdatalist.ttl = ttl;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley dns_rdataset_init(&ncrdataset);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson == ISC_R_SUCCESS);
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews if (!secure && trust > dns_trust_answer)
48019314431389cca5f8eba7ee9aa5bc08a67f4eMark Andrews trust = dns_trust_answer;
66b2f0d4bfa342770aa5e26a005a0c0ec5071231Bob Halley ncrdataset.trust = trust;
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews if (message->rcode == dns_rcode_nxdomain)
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (optout)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
55254a46f91419b92eee0d20dfb958e8dd52526cBob Halley return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
08af8bf5ade4131fe44926ad04fd489e64a620bbBob Halley 0, addedrdataset));
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley}
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleyisc_result_t
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halleydns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
b2ca6fd3a8293440b4d263723525396059cf2400Brian Wellington isc_buffer_t *target, unsigned int options,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington unsigned int *countp)
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley{
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_result_t result;
8569ab045a4cf6ecd1b5a3354ddb1c93ef34ea57Brian Wellington isc_region_t remaining, tavailable;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_t source, savedbuffer, rdlen;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley dns_name_t name;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley dns_rdatatype_t type;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley unsigned int i, rcount, count;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Convert the negative caching rdataset 'rdataset' to wire format,
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * compressing names as specified in 'cctx', and storing the result in
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * 'target'.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
569d094440399b000e059d4cb3434391c2c4d330Michael Graff REQUIRE(rdataset != NULL);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley REQUIRE(rdataset->type == 0);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley savedbuffer = *target;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley count = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rdataset_first(rdataset);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (result == ISC_R_SUCCESS) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_current(rdataset, &rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_init(&source, rdata.data, rdata.length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_add(&source, rdata.length);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley dns_name_init(&name, NULL);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(&source, &remaining);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley dns_name_fromregion(&name, &remaining);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley INSIST(remaining.length >= name.length);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_forward(&source, name.length);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley remaining.length -= name.length;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length >= 5);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley type = isc_buffer_getuint16(&source);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_forward(&source, 1);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rcount = isc_buffer_getuint16(&source);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley for (i = 0; i < rcount; i++) {
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Get the length of this rdata and set up an
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * rdata structure for it.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(&source, &remaining);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley INSIST(remaining.length >= 2);
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews dns_rdata_reset(&rdata);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rdata.length = isc_buffer_getuint16(&source);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(&source, &remaining);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rdata.data = remaining.base;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rdata.type = type;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rdata.rdclass = rdataset->rdclass;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley INSIST(remaining.length >= rdata.length);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_forward(&source, rdata.length);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
b2ca6fd3a8293440b4d263723525396059cf2400Brian Wellington if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
b2ca6fd3a8293440b4d263723525396059cf2400Brian Wellington dns_rdatatype_isdnssec(type))
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington continue;
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Write the name.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley result = dns_name_towire(&name, cctx, target);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley goto rollback;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * See if we have space for type, class, ttl, and
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * rdata length. Write the type, class, and ttl.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
8569ab045a4cf6ecd1b5a3354ddb1c93ef34ea57Brian Wellington isc_buffer_availableregion(target, &tavailable);
8569ab045a4cf6ecd1b5a3354ddb1c93ef34ea57Brian Wellington if (tavailable.length < 10) {
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley result = ISC_R_NOSPACE;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley goto rollback;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley }
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_putuint16(target, type);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_putuint16(target, rdataset->rdclass);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_putuint32(target, rdataset->ttl);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Save space for rdata length.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rdlen = *target;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_add(target, 2);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Write the rdata.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley result = dns_rdata_towire(&rdata, cctx, target);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley goto rollback;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley /*
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * Set the rdata length field to the compressed
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley * length.
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley */
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence INSIST((target->used >= rdlen.used + 2) &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence (target->used - rdlen.used - 2 < 65536));
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley isc_buffer_putuint16(&rdlen,
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence (isc_uint16_t)(target->used -
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence rdlen.used - 2));
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley count++;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(isc_buffer_remaininglength(&source) == 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews result = dns_rdataset_next(rdataset);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_reset(&rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_NOMORE)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews goto rollback;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley *countp = count;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley return (ISC_R_SUCCESS);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley rollback:
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence INSIST(savedbuffer.used < 65536);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley *countp = 0;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley *target = savedbuffer;
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley
948eabe2a254a8a278ef6325f3790e75329ee656Bob Halley return (result);
4e142a5bccd2944174ad9ae58d86cf03e170054dBob Halley}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic void
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrdataset_disassociate(dns_rdataset_t *rdataset) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews UNUSED(rdataset);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic isc_result_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrdataset_first(dns_rdataset_t *rdataset) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned char *raw = rdataset->private3;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int count;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews count = raw[0] * 256 + raw[1];
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (count == 0) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private5 = NULL;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_NOMORE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews raw += 2;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews /*
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews * The privateuint4 field is the number of rdata beyond the cursor
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * position, so we decrement the total count by one before storing
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * it.
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews count--;
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews rdataset->privateuint4 = count;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private5 = raw;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_SUCCESS);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic isc_result_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrdataset_next(dns_rdataset_t *rdataset) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int count;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int length;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned char *raw;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews count = rdataset->privateuint4;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (count == 0)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_NOMORE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews count--;
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews rdataset->privateuint4 = count;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews raw = rdataset->private5;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews length = raw[0] * 256 + raw[1];
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews raw += length + 2;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private5 = raw;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_SUCCESS);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic void
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned char *raw = rdataset->private5;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_region_t r;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews REQUIRE(raw != NULL);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews r.length = raw[0] * 256 + raw[1];
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews raw += 2;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews r.base = raw;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic void
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews *target = *source;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Reset iterator state.
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews target->privateuint4 = 0;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews target->private5 = NULL;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic unsigned int
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsrdataset_count(dns_rdataset_t *rdataset) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned char *raw = rdataset->private3;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int count;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews count = raw[0] * 256 + raw[1];
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (count);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic void
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsrdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unsigned char *raw = rdataset->private3;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
32f985bcf464816d3a8700185afdebb122cb4cecMark Andrews raw[-1] = (unsigned char)trust;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews}
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsstatic dns_rdatasetmethods_t rdataset_methods = {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset_disassociate,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset_first,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset_next,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset_current,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset_clone,
7ac0df532272d803c3f72ff7a109587e92622f5aMark Andrews rdataset_count,
7ac0df532272d803c3f72ff7a109587e92622f5aMark Andrews NULL,
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉 NULL,
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉 NULL,
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉 NULL,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews NULL,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews NULL,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews NULL,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset_settrust,
092d3b76db6b93b8029bd7d083e74fc80fb41858Mark Andrews NULL,
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrews NULL,
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrews NULL,
7ac0df532272d803c3f72ff7a109587e92622f5aMark Andrews NULL
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews};
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsisc_result_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsdns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdatatype_t type, dns_rdataset_t *rdataset)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews{
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_result_t result;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_region_t remaining;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_buffer_t source;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_name_t tname;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_rdatatype_t ttype;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_trust_t trust = dns_trust_none;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t clone;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews REQUIRE(ncacherdataset != NULL);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews REQUIRE(ncacherdataset->type == 0);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews REQUIRE(name != NULL);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews REQUIRE(!dns_rdataset_isassociated(rdataset));
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews REQUIRE(type != dns_rdatatype_rrsig);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_init(&clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_clone(ncacherdataset, &clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_first(&clone);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (result == ISC_R_SUCCESS) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_current(&clone, &rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_init(&source, rdata.data, rdata.length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_add(&source, rdata.length);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_name_init(&tname, NULL);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_buffer_remainingregion(&source, &remaining);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews dns_name_fromregion(&tname, &remaining);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews INSIST(remaining.length >= tname.length);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_buffer_forward(&source, tname.length);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews remaining.length -= tname.length;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length >= 3);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews ttype = isc_buffer_getuint16(&source);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (ttype == type && dns_name_equal(&tname, name)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews trust = isc_buffer_getuint8(&source);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(trust <= dns_trust_ultimate);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_buffer_remainingregion(&source, &remaining);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews break;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_next(&clone);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_reset(&rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&clone);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result == ISC_R_NOMORE)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_NOTFOUND);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (result != ISC_R_SUCCESS)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (result);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(remaining.length != 0);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->methods = &rdataset_methods;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->rdclass = ncacherdataset->rdclass;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->type = type;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->covers = 0;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->ttl = ncacherdataset->ttl;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->trust = trust;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->private1 = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->private2 = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->private3 = remaining.base;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Reset iterator state.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->privateuint4 = 0;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->private5 = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->private6 = NULL;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (ISC_R_SUCCESS);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews}
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsisc_result_t
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsdns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater dns_rdatatype_t covers, dns_rdataset_t *rdataset)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews{
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_t tname;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_rrsig_t rrsig;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_t clone;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdatatype_t type;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_trust_t trust = dns_trust_none;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_t source;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_region_t remaining, sigregion;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_result_t result;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unsigned char *raw;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unsigned int count;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(ncacherdataset != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(ncacherdataset->type == 0);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(name != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(!dns_rdataset_isassociated(rdataset));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_init(&clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_clone(ncacherdataset, &clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_first(&clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews while (result == ISC_R_SUCCESS) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_current(&clone, &rdata);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_init(&source, rdata.data, rdata.length);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_add(&source, rdata.length);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_init(&tname, NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_remainingregion(&source, &remaining);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_name_fromregion(&tname, &remaining);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length >= tname.length);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_forward(&source, tname.length);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews remaining.length -= tname.length;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews remaining.base += tname.length;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length >= 2);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews type = isc_buffer_getuint16(&source);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews remaining.length -= 2;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews remaining.base += 2;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (type != dns_rdatatype_rrsig ||
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews !dns_name_equal(&tname, name)) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_next(&clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_reset(&rdata);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews continue;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length >= 1);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews trust = isc_buffer_getuint8(&source);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(trust <= dns_trust_ultimate);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews remaining.length -= 1;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews remaining.base += 1;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews raw = remaining.base;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews count = raw[0] * 256 + raw[1];
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(count > 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews raw += 2;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews sigregion.length = raw[0] * 256 + raw[1];
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews raw += 2;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews sigregion.base = raw;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_reset(&rdata);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_fromregion(&rdata, rdataset->rdclass,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdatatype_rrsig, &sigregion);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (rrsig.covered == covers) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews isc_buffer_remainingregion(&source, &remaining);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews break;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews result = dns_rdataset_next(&clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdata_reset(&rdata);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews }
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_rdataset_disassociate(&clone);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result == ISC_R_NOMORE)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (ISC_R_NOTFOUND);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (result != ISC_R_SUCCESS)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (result);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length != 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->methods = &rdataset_methods;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->rdclass = ncacherdataset->rdclass;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->type = dns_rdatatype_rrsig;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->covers = covers;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->ttl = ncacherdataset->ttl;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->trust = trust;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private1 = NULL;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private2 = NULL;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private3 = remaining.base;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Reset iterator state.
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
80b782f356f0692c11b4e52e8dd46ec41704e5a2Mark Andrews rdataset->privateuint4 = 0;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews rdataset->private5 = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->private6 = NULL;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_R_SUCCESS);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_t *rdataset)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dns_trust_t trust;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_region_t remaining, sigregion;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_t source;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t tname;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdatatype_t type;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int count;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_rrsig_t rrsig;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char *raw;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(ncacherdataset != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(ncacherdataset->type == 0);
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(found != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(!dns_rdataset_isassociated(rdataset));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdataset_current(ncacherdataset, &rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_init(&source, rdata.data, rdata.length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_add(&source, rdata.length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_init(&tname, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_remainingregion(&source, &remaining);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_fromregion(found, &remaining);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(remaining.length >= found->length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_forward(&source, found->length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews remaining.length -= found->length;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(remaining.length >= 5);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews type = isc_buffer_getuint16(&source);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews trust = isc_buffer_getuint8(&source);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INSIST(trust <= dns_trust_ultimate);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_remainingregion(&source, &remaining);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->methods = &rdataset_methods;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->rdclass = ncacherdataset->rdclass;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->type = type;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (type == dns_rdatatype_rrsig) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Extract covers from RRSIG.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews raw = remaining.base;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count = raw[0] * 256 + raw[1];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(count > 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews raw += 2;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews sigregion.length = raw[0] * 256 + raw[1];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews raw += 2;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews sigregion.base = raw;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_reset(&rdata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_rdata_fromregion(&rdata, rdataset->rdclass,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->type, &sigregion);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->covers = rrsig.covered;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->covers = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->ttl = ncacherdataset->ttl;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews rdataset->trust = trust;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->private1 = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->private2 = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->private3 = remaining.base;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Reset iterator state.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->privateuint4 = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->private5 = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews rdataset->private6 = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}