rdataset.c revision ca67883a666bdf314d3da958d5195e7215b1f797
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Copyright (C) 1999 Internet Software Consortium.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy *
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Permission to use, copy, modify, and distribute this software for any
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * purpose with or without fee is hereby granted, provided that the above
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * copyright notice and this permission notice appear in all copies.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy *
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * SOFTWARE.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <config.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <stddef.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <string.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <isc/assertions.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <dns/rdata.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <dns/rdataclass.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <dns/rdatatype.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <dns/rdataset.h>
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy#include <dns/compress.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyvoid
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedydns_rdataset_init(dns_rdataset_t *rdataset) {
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy /*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Make 'rdataset' a valid, disassociated rdataset.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy REQUIRE(rdataset != NULL);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->magic = DNS_RDATASET_MAGIC;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->methods = NULL;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy ISC_LINK_INIT(rdataset, link);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->rdclass = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->type = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->ttl = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->trust = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->attributes = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->private1 = NULL;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->private2 = NULL;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->private3 = NULL;
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy rdataset->private4 = NULL;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->private5 = NULL;
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy}
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyvoid
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedydns_rdataset_invalidate(dns_rdataset_t *rdataset) {
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy /*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Invalidate 'rdataset'.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy REQUIRE(DNS_RDATASET_VALID(rdataset));
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy REQUIRE(rdataset->methods == NULL);
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy rdataset->magic = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy ISC_LINK_INIT(rdataset, link);
rdataset->rdclass = 0;
rdataset->type = 0;
rdataset->ttl = 0;
rdataset->trust = 0;
rdataset->attributes = 0;
rdataset->private1 = NULL;
rdataset->private2 = NULL;
rdataset->private3 = NULL;
rdataset->private4 = NULL;
rdataset->private5 = NULL;
}
void
dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
/*
* Disassociate 'rdataset' from its rdata, allowing it to be reused.
*/
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL);
(rdataset->methods->disassociate)(rdataset);
rdataset->methods = NULL;
ISC_LINK_INIT(rdataset, link);
rdataset->rdclass = 0;
rdataset->type = 0;
rdataset->ttl = 0;
rdataset->trust = 0;
rdataset->attributes = 0;
rdataset->private1 = NULL;
rdataset->private2 = NULL;
rdataset->private3 = NULL;
rdataset->private4 = NULL;
rdataset->private5 = NULL;
}
dns_result_t
dns_rdataset_first(dns_rdataset_t *rdataset) {
/*
* Move the rdata cursor to the first rdata in the rdataset (if any).
*/
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL);
return ((rdataset->methods->first)(rdataset));
}
dns_result_t
dns_rdataset_next(dns_rdataset_t *rdataset) {
/*
* Move the rdata cursor to the next rdata in the rdataset (if any).
*/
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL);
return ((rdataset->methods->next)(rdataset));
}
void
dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
/*
* Make 'rdata' refer to the current rdata.
*/
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL);
(rdataset->methods->current)(rdataset, rdata);
}
dns_result_t
dns_rdataset_towire(dns_rdataset_t *rdataset,
dns_name_t *owner_name,
dns_compress_t *cctx,
isc_boolean_t no_rdata_or_ttl,
isc_buffer_t *target,
unsigned int *countp)
{
dns_rdata_t rdata;
isc_region_t r;
dns_result_t result;
unsigned int count;
isc_buffer_t st;
isc_buffer_t rdlen;
unsigned int headlen;
/*
* Convert 'rdataset' to wire format, compressing names as specified
* in cctx, and storing the result in 'target'.
*/
REQUIRE(DNS_RDATASET_VALID(rdataset));
result = dns_rdataset_first(rdataset);
if (no_rdata_or_ttl) {
REQUIRE(result == DNS_R_NOMORE);
} else {
REQUIRE(result == DNS_R_SUCCESS);
}
REQUIRE(countp != NULL);
count = 0;
do {
/*
* copy out the name, type, class, ttl.
*/
if (dns_compress_getedns(cctx) >= 1)
dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL);
else
dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
st = *target;
result = dns_name_towire(owner_name, cctx, target);
if (result != DNS_R_SUCCESS) {
dns_compress_rollback(cctx, st.used);
*countp += count;
*target = st;
return (result);
}
headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
if (!no_rdata_or_ttl)
headlen += sizeof(dns_ttl_t)
+ 2; /* XXX 2 for rdata len */
isc_buffer_available(target, &r);
if (r.length < headlen) {
dns_compress_rollback(cctx, st.used);
*countp += count;
*target = st;
return (DNS_R_NOSPACE);
}
isc_buffer_putuint16(target, rdataset->type);
isc_buffer_putuint16(target, rdataset->rdclass);
if (!no_rdata_or_ttl) {
isc_buffer_putuint32(target, rdataset->ttl);
/*
* Save space for rdlen.
*/
rdlen = *target;
isc_buffer_add(target, 2);
/*
* copy out the rdata
*/
dns_rdataset_current(rdataset, &rdata);
result = dns_compress_localinit(cctx, owner_name,
target);
if (result != DNS_R_SUCCESS) {
dns_compress_rollback(cctx, st.used);
*countp += count;
*target = st;
return (result);
}
result = dns_rdata_towire(&rdata, cctx, target);
dns_compress_localinvalidate(cctx);
if (result != DNS_R_SUCCESS) {
dns_compress_rollback(cctx, st.used);
*countp += count;
*target = st;
return (result);
}
isc_buffer_putuint16(&rdlen,
target->used - rdlen.used - 2);
}
count++;
result = dns_rdataset_next(rdataset);
} while (result == DNS_R_SUCCESS);
if (result != DNS_R_NOMORE)
return (result);
*countp += count;
return (DNS_R_SUCCESS);
}