ncache.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews/*
28d9fd53819cc163629c867466b20d8ebcae8842David Lawrence * Copyright (C) 1999-2005, 2007, 2008, 2010-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence */
15a44745412679c30a6d022733925af70a38b715David Lawrence
15a44745412679c30a6d022733925af70a38b715David Lawrence/* $Id$ */
15a44745412679c30a6d022733925af70a38b715David Lawrence
15a44745412679c30a6d022733925af70a38b715David Lawrence/*! \file */
15a44745412679c30a6d022733925af70a38b715David Lawrence
15a44745412679c30a6d022733925af70a38b715David Lawrence#include <config.h>
15a44745412679c30a6d022733925af70a38b715David Lawrence
15a44745412679c30a6d022733925af70a38b715David Lawrence#include <isc/buffer.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <isc/util.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews#include <dns/db.h>
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff#include <dns/message.h>
f31f0b63cbe841720f154c570bcdede9d79e64b8Michael Graff#include <dns/ncache.h>
3761c433912beabe43abeed2c3513b6201c59f64Mark Andrews#include <dns/rdata.h>
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews#include <dns/rdatalist.h>
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews#include <dns/rdataset.h>
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#include <dns/rdatastruct.h>
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff
6324997211a5e2d82528dcde98e8981190a35faeMichael Graff#define DNS_NCACHE_RDATA 20U
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence/*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * The format of an ncache rdata is a sequence of zero or more records of
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * the following format:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews *
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * owner name
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews * type
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * trust
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff * rdata count
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff * rdata length These two occur 'rdata count'
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * rdata times.
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews *
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrewsstatic isc_result_t
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrewsaddoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t optout, isc_boolean_t secure,
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews dns_rdataset_t *addedrdataset);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrewsstatic inline isc_result_t
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrewscopy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews isc_result_t result;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int count;
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff isc_region_t ar, r;
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews /*
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews * Copy the rdataset count to the buffer.
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff */
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews isc_buffer_availableregion(buffer, &ar);
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews if (ar.length < 2)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOSPACE);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson count = dns_rdataset_count(rdataset);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff INSIST(count <= 65535);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_putuint16(buffer, (isc_uint16_t)count);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence result = dns_rdataset_first(rdataset);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson while (result == ISC_R_SUCCESS) {
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff dns_rdataset_current(rdataset, &rdata);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdata_toregion(&rdata, &r);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff INSIST(r.length <= 65535);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_availableregion(buffer, &ar);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (ar.length < 2)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the rdata length to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington /*
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson * Copy the rdata to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews result = isc_buffer_copyregion(buffer, &r);
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews if (result != ISC_R_SUCCESS)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson dns_rdata_reset(&rdata);
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson result = dns_rdataset_next(rdataset);
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_NOMORE)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_SUCCESS);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsisc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdataset_t *addedrdataset)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews{
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (addoptout(message, cache, node, covers, now, maxttl,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson ISC_FALSE, ISC_FALSE, addedrdataset));
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews}
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrewsisc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_dbnode_t *node, dns_rdatatype_t covers,
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews isc_stdtime_t now, dns_ttl_t maxttl,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t optout, dns_rdataset_t *addedrdataset)
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington{
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington return (addoptout(message, cache, node, covers, now, maxttl,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson optout, ISC_TRUE, addedrdataset));
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsstatic isc_result_t
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsaddoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t optout, isc_boolean_t secure,
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff dns_rdataset_t *addedrdataset)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson{
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson isc_result_t result;
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews isc_buffer_t buffer;
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson isc_region_t r;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdataset_t *rdataset;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdatatype_t type;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_name_t *name;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_ttl_t ttl;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_trust_t trust;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdata_t rdata[DNS_NCACHE_RDATA];
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff dns_rdataset_t ncrdataset;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_rdatalist_t ncrdatalist;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson unsigned char data[4096];
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington unsigned int next = 0;
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Convert the authority data from 'message' into a negative cache
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * rdataset, and store it in 'cache' at 'node'.
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington */
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson REQUIRE(message != NULL);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * We assume that all data in the authority section has been
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * validated by the caller.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Initialize the list.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews dns_rdatalist_init(&ncrdatalist);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff ncrdatalist.rdclass = dns_db_class(cache);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ncrdatalist.covers = covers;
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff ncrdatalist.ttl = maxttl;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson /*
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews * Build an ncache rdatas into buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ttl = maxttl;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews trust = 0xffff;
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews isc_buffer_init(&buffer, data, sizeof(data));
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews if (message->counts[DNS_SECTION_AUTHORITY])
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence else
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = ISC_R_NOMORE;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (result == ISC_R_SUCCESS) {
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews name = NULL;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff dns_message_currentname(message, DNS_SECTION_AUTHORITY,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &name);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews for (rdataset = ISC_LIST_HEAD(name->list);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdataset != NULL;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdataset = ISC_LIST_NEXT(rdataset, link)) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if ((rdataset->attributes &
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff DNS_RDATASETATTR_NCACHE) == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff continue;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews type = rdataset->type;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (type == dns_rdatatype_rrsig)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff type = rdataset->covers;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (type == dns_rdatatype_soa ||
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews type == dns_rdatatype_nsec ||
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews type == dns_rdatatype_nsec3) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (ttl > rdataset->ttl)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ttl = rdataset->ttl;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (trust > rdataset->trust)
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews trust = rdataset->trust;
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the owner name to the buffer.
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson */
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews dns_name_toregion(name, &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = isc_buffer_copyregion(&buffer,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_SUCCESS)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the type to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews isc_buffer_availableregion(&buffer,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (r.length < 3)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOSPACE);
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews isc_buffer_putuint16(&buffer,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdataset->type);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_putuint8(&buffer,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews (unsigned char)rdataset->trust);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff /*
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the rdataset into the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = copy_rdataset(rdataset,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff &buffer);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_SUCCESS)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (next >= DNS_NCACHE_RDATA)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (ISC_R_NOSPACE);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdata_init(&rdata[next]);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_remainingregion(&buffer, &r);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata[next].data = r.base;
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson rdata[next].length = r.length;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata[next].rdclass =
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews ncrdatalist.rdclass;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley rdata[next].type = 0;
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews rdata[next].flags = 0;
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews ISC_LIST_APPEND(ncrdatalist.rdata,
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews &rdata[next], link);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_forward(&buffer, r.length);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews next++;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (result != ISC_R_NOMORE)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return (result);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson if (trust == 0xffff) {
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson message->counts[DNS_SECTION_ANSWER] == 0) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews * The response has aa set and we haven't followed
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews * any CNAME or DNAME chains.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews trust = dns_trust_authauthority;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews } else
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews trust = dns_trust_additional;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ttl = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews }
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson INSIST(trust != 0xffff);
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson ncrdatalist.ttl = ttl;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews dns_rdataset_init(&ncrdataset);
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews == ISC_R_SUCCESS);
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews if (!secure && trust > dns_trust_answer)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews trust = dns_trust_answer;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews ncrdataset.trust = trust;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (message->rcode == dns_rcode_nxdomain)
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews if (optout)
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews 0, addedrdataset));
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews}
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrewsisc_result_t
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrewsdns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews isc_buffer_t *target, unsigned int options,
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews unsigned int *countp)
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews{
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews isc_result_t result;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews isc_region_t remaining, tavailable;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews isc_buffer_t source, savedbuffer, rdlen;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_name_t name;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews dns_rdatatype_t type;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff unsigned int i, rcount, count;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews /*
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews * Convert the negative caching rdataset 'rdataset' to wire format,
05f90cac85760b4edef2962209df49ea019c180fMark Andrews * compressing names as specified in 'cctx', and storing the result in
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews * 'target'.
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff */
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews REQUIRE(rdataset != NULL);
b589e90689c6e87bf9608424ca8d99571c18bc61Mark Andrews REQUIRE(rdataset->type == 0);
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews savedbuffer = *target;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews count = 0;
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews
05f90cac85760b4edef2962209df49ea019c180fMark Andrews result = dns_rdataset_first(rdataset);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews while (result == ISC_R_SUCCESS) {
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff dns_rdataset_current(rdataset, &rdata);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff isc_buffer_init(&source, rdata.data, rdata.length);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews isc_buffer_add(&source, rdata.length);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews dns_name_init(&name, NULL);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews isc_buffer_remainingregion(&source, &remaining);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews dns_name_fromregion(&name, &remaining);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews INSIST(remaining.length >= name.length);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews isc_buffer_forward(&source, name.length);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews remaining.length -= name.length;
05f90cac85760b4edef2962209df49ea019c180fMark Andrews
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews INSIST(remaining.length >= 5);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews type = isc_buffer_getuint16(&source);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews isc_buffer_forward(&source, 1);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews rcount = isc_buffer_getuint16(&source);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews for (i = 0; i < rcount; i++) {
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff /*
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews * Get the length of this rdata and set up an
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews * rdata structure for it.
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff */
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews isc_buffer_remainingregion(&source, &remaining);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews INSIST(remaining.length >= 2);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff dns_rdata_reset(&rdata);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews rdata.length = isc_buffer_getuint16(&source);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews isc_buffer_remainingregion(&source, &remaining);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff rdata.data = remaining.base;
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews rdata.type = type;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews rdata.rdclass = rdataset->rdclass;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews INSIST(remaining.length >= rdata.length);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff isc_buffer_forward(&source, rdata.length);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews dns_rdatatype_isdnssec(type))
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews continue;
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /*
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews * Write the name.
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews result = dns_name_towire(&name, cctx, target);
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews if (result != ISC_R_SUCCESS)
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews goto rollback;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff /*
206c71aae4cca0c94d67e271196b6658d293886bMark Andrews * See if we have space for type, class, ttl, and
206c71aae4cca0c94d67e271196b6658d293886bMark Andrews * rdata length. Write the type, class, and ttl.
206c71aae4cca0c94d67e271196b6658d293886bMark Andrews */
05f90cac85760b4edef2962209df49ea019c180fMark Andrews isc_buffer_availableregion(target, &tavailable);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews if (tavailable.length < 10) {
05f90cac85760b4edef2962209df49ea019c180fMark Andrews result = ISC_R_NOSPACE;
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews goto rollback;
d981ca645597116d227a48bf37cc5edc061c854dBob Halley }
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_buffer_putuint16(target, type);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_putuint16(target, rdataset->rdclass);
90f9d00f087ddb4442d1ebf628c1bcaff18226a0Andreas Gustafsson isc_buffer_putuint32(target, rdataset->ttl);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff /*
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * Save space for rdata length.
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff */
d981ca645597116d227a48bf37cc5edc061c854dBob Halley rdlen = *target;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff isc_buffer_add(target, 2);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley
d981ca645597116d227a48bf37cc5edc061c854dBob Halley /*
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * Write the rdata.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence */
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley result = dns_rdata_towire(&rdata, cctx, target);
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley if (result != ISC_R_SUCCESS)
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley goto rollback;
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley /*
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * Set the rdata length field to the compressed
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff * length.
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley */
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley INSIST((target->used >= rdlen.used + 2) &&
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff (target->used - rdlen.used - 2 < 65536));
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley isc_buffer_putuint16(&rdlen,
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff (isc_uint16_t)(target->used -
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley rdlen.used - 2));
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff count++;
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley }
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley INSIST(isc_buffer_remaininglength(&source) == 0);
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley result = dns_rdataset_next(rdataset);
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley dns_rdata_reset(&rdata);
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley }
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews if (result != ISC_R_NOMORE)
goto rollback;
*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 void
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
unsigned char *raw = rdataset->private3;
raw[-1] = (unsigned char)trust;
}
static dns_rdatasetmethods_t rdataset_methods = {
rdataset_disassociate,
rdataset_first,
rdataset_next,
rdataset_current,
rdataset_clone,
rdataset_count,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
rdataset_settrust,
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;
dns_trust_t trust = dns_trust_none;
dns_rdataset_t clone;
REQUIRE(ncacherdataset != NULL);
REQUIRE(ncacherdataset->type == 0);
REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
REQUIRE(name != NULL);
REQUIRE(!dns_rdataset_isassociated(rdataset));
REQUIRE(type != dns_rdatatype_rrsig);
dns_rdataset_init(&clone);
dns_rdataset_clone(ncacherdataset, &clone);
result = dns_rdataset_first(&clone);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&clone, &rdata);
isc_buffer_init(&source, rdata.data, rdata.length);
isc_buffer_add(&source, rdata.length);
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 >= 3);
ttype = isc_buffer_getuint16(&source);
if (ttype == type && dns_name_equal(&tname, name)) {
trust = isc_buffer_getuint8(&source);
INSIST(trust <= dns_trust_ultimate);
isc_buffer_remainingregion(&source, &remaining);
break;
}
result = dns_rdataset_next(&clone);
dns_rdata_reset(&rdata);
}
dns_rdataset_disassociate(&clone);
if (result == ISC_R_NOMORE)
return (ISC_R_NOTFOUND);
if (result != ISC_R_SUCCESS)
return (result);
INSIST(remaining.length != 0);
rdataset->methods = &rdataset_methods;
rdataset->rdclass = ncacherdataset->rdclass;
rdataset->type = type;
rdataset->covers = 0;
rdataset->ttl = ncacherdataset->ttl;
rdataset->trust = trust;
rdataset->private1 = NULL;
rdataset->private2 = NULL;
rdataset->private3 = remaining.base;
/*
* Reset iterator state.
*/
rdataset->privateuint4 = 0;
rdataset->private5 = NULL;
rdataset->private6 = NULL;
return (ISC_R_SUCCESS);
}
isc_result_t
dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
dns_rdatatype_t covers, dns_rdataset_t *rdataset)
{
dns_name_t tname;
dns_rdata_rrsig_t rrsig;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_t clone;
dns_rdatatype_t type;
dns_trust_t trust = dns_trust_none;
isc_buffer_t source;
isc_region_t remaining, sigregion;
isc_result_t result;
unsigned char *raw;
unsigned int count;
REQUIRE(ncacherdataset != NULL);
REQUIRE(ncacherdataset->type == 0);
REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
REQUIRE(name != NULL);
REQUIRE(!dns_rdataset_isassociated(rdataset));
dns_rdataset_init(&clone);
dns_rdataset_clone(ncacherdataset, &clone);
result = dns_rdataset_first(&clone);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&clone, &rdata);
isc_buffer_init(&source, rdata.data, rdata.length);
isc_buffer_add(&source, rdata.length);
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);
isc_region_consume(&remaining, tname.length);
INSIST(remaining.length >= 2);
type = isc_buffer_getuint16(&source);
isc_region_consume(&remaining, 2);
if (type != dns_rdatatype_rrsig ||
!dns_name_equal(&tname, name)) {
result = dns_rdataset_next(&clone);
dns_rdata_reset(&rdata);
continue;
}
INSIST(remaining.length >= 1);
trust = isc_buffer_getuint8(&source);
INSIST(trust <= dns_trust_ultimate);
isc_region_consume(&remaining, 1);
raw = remaining.base;
count = raw[0] * 256 + raw[1];
INSIST(count > 0);
raw += 2;
sigregion.length = raw[0] * 256 + raw[1];
raw += 2;
sigregion.base = raw;
dns_rdata_reset(&rdata);
dns_rdata_fromregion(&rdata, rdataset->rdclass,
dns_rdatatype_rrsig, &sigregion);
(void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
if (rrsig.covered == covers) {
isc_buffer_remainingregion(&source, &remaining);
break;
}
result = dns_rdataset_next(&clone);
dns_rdata_reset(&rdata);
}
dns_rdataset_disassociate(&clone);
if (result == ISC_R_NOMORE)
return (ISC_R_NOTFOUND);
if (result != ISC_R_SUCCESS)
return (result);
INSIST(remaining.length != 0);
rdataset->methods = &rdataset_methods;
rdataset->rdclass = ncacherdataset->rdclass;
rdataset->type = dns_rdatatype_rrsig;
rdataset->covers = covers;
rdataset->ttl = ncacherdataset->ttl;
rdataset->trust = trust;
rdataset->private1 = NULL;
rdataset->private2 = NULL;
rdataset->private3 = remaining.base;
/*
* Reset iterator state.
*/
rdataset->privateuint4 = 0;
rdataset->private5 = NULL;
rdataset->private6 = NULL;
return (ISC_R_SUCCESS);
}
void
dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
dns_rdataset_t *rdataset)
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_trust_t trust;
isc_region_t remaining, sigregion;
isc_buffer_t source;
dns_name_t tname;
dns_rdatatype_t type;
unsigned int count;
dns_rdata_rrsig_t rrsig;
unsigned char *raw;
REQUIRE(ncacherdataset != NULL);
REQUIRE(ncacherdataset->type == 0);
REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
REQUIRE(found != NULL);
REQUIRE(!dns_rdataset_isassociated(rdataset));
dns_rdataset_current(ncacherdataset, &rdata);
isc_buffer_init(&source, rdata.data, rdata.length);
isc_buffer_add(&source, rdata.length);
dns_name_init(&tname, NULL);
isc_buffer_remainingregion(&source, &remaining);
dns_name_fromregion(found, &remaining);
INSIST(remaining.length >= found->length);
isc_buffer_forward(&source, found->length);
remaining.length -= found->length;
INSIST(remaining.length >= 5);
type = isc_buffer_getuint16(&source);
trust = isc_buffer_getuint8(&source);
INSIST(trust <= dns_trust_ultimate);
isc_buffer_remainingregion(&source, &remaining);
rdataset->methods = &rdataset_methods;
rdataset->rdclass = ncacherdataset->rdclass;
rdataset->type = type;
if (type == dns_rdatatype_rrsig) {
/*
* Extract covers from RRSIG.
*/
raw = remaining.base;
count = raw[0] * 256 + raw[1];
INSIST(count > 0);
raw += 2;
sigregion.length = raw[0] * 256 + raw[1];
raw += 2;
sigregion.base = raw;
dns_rdata_reset(&rdata);
dns_rdata_fromregion(&rdata, rdataset->rdclass,
rdataset->type, &sigregion);
(void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
rdataset->covers = rrsig.covered;
} else
rdataset->covers = 0;
rdataset->ttl = ncacherdataset->ttl;
rdataset->trust = trust;
rdataset->private1 = NULL;
rdataset->private2 = NULL;
rdataset->private3 = remaining.base;
/*
* Reset iterator state.
*/
rdataset->privateuint4 = 0;
rdataset->private5 = NULL;
rdataset->private6 = NULL;
}