ncache.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
28d9fd53819cc163629c867466b20d8ebcae8842David Lawrence * Copyright (C) 1999-2005, 2007, 2008, 2010-2016 Internet Systems Consortium, Inc. ("ISC")
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/.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * The format of an ncache rdata is a sequence of zero or more records of
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * the following format:
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * owner name
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff * rdata count
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff * rdata length These two occur 'rdata count'
3d5cad69ec20157912e95cf3b79316dfb0a314f3Mark Andrews * rdata times.
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,
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrewscopy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int count;
90880946803188d7c6b3ca7dea69761eb21241c2Mark Andrews * Copy the rdataset count to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_putuint16(buffer, (isc_uint16_t)count);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the rdata length to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_buffer_putuint16(buffer, (isc_uint16_t)r.length);
9f139761ca06977d1db8051842efc620c15b8199Andreas Gustafsson * Copy the rdata to the buffer.
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 return (addoptout(message, cache, node, covers, now, maxttl,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewsdns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson dns_dbnode_t *node, dns_rdatatype_t covers,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews isc_boolean_t optout, dns_rdataset_t *addedrdataset)
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington return (addoptout(message, cache, node, covers, now, maxttl,
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,
9ce72fc748cc7c2b738147f9736e00a96474be1bBrian Wellington unsigned int next = 0;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Convert the authority data from 'message' into a negative cache
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson * rdataset, and store it in 'cache' at 'node'.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * We assume that all data in the authority section has been
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * validated by the caller.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Initialize the list.
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews * Build an ncache rdatas into buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff dns_message_currentname(message, DNS_SECTION_AUTHORITY,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the owner name to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the type to the buffer.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Copy the rdataset into the buffer.
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 &&
e6c22f37d8df55a9f66b479a22717e179bcf79a3Andreas Gustafsson message->counts[DNS_SECTION_ANSWER] == 0) {
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews * The response has aa set and we haven't followed
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews * any CNAME or DNAME chains.
deaaf94332abbfdb3aff53675546acfed16e5eb6Mark Andrews RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT;
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset,
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrewsdns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
373ce67419680a398ba3dc51a14a486caaf0afb0Mark Andrews unsigned int *countp)
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews * Convert the negative caching rdataset 'rdataset' to wire format,
05f90cac85760b4edef2962209df49ea019c180fMark Andrews * compressing names as specified in 'cctx', and storing the result in
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
8dd2e6e7c1328ba00d734ce939777e06d9a15493Michael Graff isc_buffer_init(&source, rdata.data, rdata.length);
05f90cac85760b4edef2962209df49ea019c180fMark Andrews isc_buffer_remainingregion(&source, &remaining);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews for (i = 0; i < rcount; i++) {
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews * Get the length of this rdata and set up an
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews * rdata structure for it.
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews isc_buffer_remainingregion(&source, &remaining);
a560a0bfb2fd48ddd1900f61a655397a5c4f7343Mark Andrews isc_buffer_remainingregion(&source, &remaining);
9281e7aa775026dc47c01745fdcc438645146877Mark Andrews if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews * Write the name.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
206c71aae4cca0c94d67e271196b6658d293886bMark Andrews * See if we have space for type, class, ttl, and
206c71aae4cca0c94d67e271196b6658d293886bMark Andrews * rdata length. Write the type, class, and ttl.
05f90cac85760b4edef2962209df49ea019c180fMark Andrews isc_buffer_availableregion(target, &tavailable);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_putuint16(target, rdataset->rdclass);
90f9d00f087ddb4442d1ebf628c1bcaff18226a0Andreas Gustafsson isc_buffer_putuint32(target, rdataset->ttl);
d981ca645597116d227a48bf37cc5edc061c854dBob Halley * Save space for rdata length.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * Write the rdata.
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley * Set the rdata length field to the compressed
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley INSIST(isc_buffer_remaininglength(&source) == 0);
goto rollback;
return (ISC_R_SUCCESS);
*countp = 0;
return (result);
static isc_result_t
unsigned int count;
if (count == 0) {
return (ISC_R_NOMORE);
count--;
return (ISC_R_SUCCESS);
static isc_result_t
unsigned int count;
unsigned int length;
unsigned char *raw;
if (count == 0)
return (ISC_R_NOMORE);
count--;
return (ISC_R_SUCCESS);
isc_region_t r;
unsigned int count;
return (count);
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
return (ISC_R_NOTFOUND);
return (result);
return (ISC_R_SUCCESS);
unsigned char *raw;
unsigned int count;
return (ISC_R_NOTFOUND);
return (result);
return (ISC_R_SUCCESS);
unsigned int count;
unsigned char *raw;