diff --git a/CHANGES b/CHANGES index 6525bb6edc..432e340067 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +1128. [func] sdb drivers can now provide RR data in either text + or wire format, the latter using the new functions + dns_sdb_putrdata() and dns_sdb_putnamedrdata(). + 1127. [func] rndc: If the server to contact has multiple addresses, try all of them. diff --git a/lib/dns/include/dns/sdb.h b/lib/dns/include/dns/sdb.h index 9e00e83b6e..675c71c4ae 100644 --- a/lib/dns/include/dns/sdb.h +++ b/lib/dns/include/dns/sdb.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.h,v 1.13 2001/10/13 01:32:34 gson Exp $ */ +/* $Id: sdb.h,v 1.14 2001/11/15 20:32:05 gson Exp $ */ #ifndef DNS_SDB_H #define DNS_SDB_H 1 @@ -165,17 +165,28 @@ dns_sdb_unregister(dns_sdbimplementation_t **sdbimp); isc_result_t dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data); +isc_result_t +dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t type, dns_ttl_t ttl, + const unsigned char *rdata, unsigned int rdlen); /* - * Add a single resource record to the lookup structure to be later - * parsed into a query response. + * Add a single resource record to the lookup structure to be + * returned in the query response. dns_sdb_putrr() takes the + * resource record in master file text format as a null-terminated + * string, and dns_sdb_putrdata() takes the raw RDATA in + * uncompressed wire format. */ isc_result_t dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, const char *type, dns_ttl_t ttl, const char *data); +isc_result_t +dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, + dns_rdatatype_t type, dns_ttl_t ttl, + const void *rdata, unsigned int rdlen); /* - * Add a single resource record to the allnodes structure to be later - * parsed into a zone transfer response. + * Add a single resource record to the allnodes structure to be + * included in a zone transfer response, in text or wire + * format as above. */ isc_result_t diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index d4014a0b2e..bcf753155f 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.37 2001/11/12 19:05:32 gson Exp $ */ +/* $Id: sdb.c,v 1.38 2001/11/15 20:32:03 gson Exp $ */ #include @@ -267,8 +267,7 @@ dns_sdb_unregister(dns_sdbimplementation_t **sdbimp) { } static inline unsigned int -initial_size(const char *data) { - unsigned int len = strlen(data); +initial_size(unsigned int len) { unsigned int size; for (size = 64; size < (64 * 1024); size *= 2) if (len < size) @@ -277,34 +276,18 @@ initial_size(const char *data) { } isc_result_t -dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, - const char *data) +dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl, + const unsigned char *rdatap, unsigned int rdlen) { dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; - dns_rdatatype_t typeval; - isc_consttextregion_t r; - isc_buffer_t b; - isc_buffer_t *rdatabuf; - isc_lex_t *lex; + isc_buffer_t *rdatabuf = NULL; isc_result_t result; - unsigned int size; isc_mem_t *mctx; - dns_sdbimplementation_t *imp; - dns_name_t *origin; - - REQUIRE(VALID_SDBLOOKUP(lookup)); - REQUIRE(type != NULL); - REQUIRE(data != NULL); + isc_region_t region; mctx = lookup->sdb->common.mctx; - r.base = type; - r.length = strlen(type); - result = dns_rdatatype_fromtext(&typeval, (isc_textregion_t *)&r); - if (result != ISC_R_SUCCESS) - return (result); - rdatalist = ISC_LIST_HEAD(lookup->lists); while (rdatalist != NULL) { if (rdatalist->type == typeval) @@ -330,7 +313,56 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, rdata = isc_mem_get(mctx, sizeof(dns_rdata_t)); if (rdata == NULL) return (ISC_R_NOMEMORY); + + result = isc_buffer_allocate(mctx, &rdatabuf, rdlen); + if (result != ISC_R_SUCCESS) + goto failure; + DE_CONST(rdatap, region.base); + region.length = rdlen; + isc_buffer_copyregion(rdatabuf, ®ion); + isc_buffer_usedregion(rdatabuf, ®ion); dns_rdata_init(rdata); + dns_rdata_fromregion(rdata, rdatalist->rdclass, rdatalist->type, + ®ion); + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); + rdata = NULL; + + failure: + if (rdata != NULL) + isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); + return (result); +} + + +isc_result_t +dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, + const char *data) +{ + unsigned int datalen; + dns_rdatatype_t typeval; + isc_consttextregion_t r; + isc_lex_t *lex = NULL; + isc_result_t result; + unsigned char *p = NULL; + unsigned int size = 0; /* Init to suppress compiler warning */ + isc_mem_t *mctx; + dns_sdbimplementation_t *imp; + dns_name_t *origin; + isc_buffer_t b; + isc_buffer_t rb; + + REQUIRE(VALID_SDBLOOKUP(lookup)); + REQUIRE(type != NULL); + REQUIRE(data != NULL); + + mctx = lookup->sdb->common.mctx; + + r.base = type; + r.length = strlen(type); + result = dns_rdatatype_fromtext(&typeval, (isc_textregion_t *)&r); + if (result != ISC_R_SUCCESS) + return (result); imp = lookup->sdb->implementation; if ((imp->flags & DNS_SDBFLAG_RELATIVERDATA) != 0) @@ -338,61 +370,56 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, else origin = dns_rootname; - lex = NULL; result = isc_lex_create(mctx, 64, &lex); if (result != ISC_R_SUCCESS) goto failure; - size = initial_size(data); - do { - isc_buffer_init(&b, data, strlen(data)); - isc_buffer_add(&b, strlen(data)); - + datalen = strlen(data); + size = initial_size(datalen); + for (;;) { + isc_buffer_init(&b, data, datalen); + isc_buffer_add(&b, datalen); result = isc_lex_openbuffer(lex, &b); if (result != ISC_R_SUCCESS) goto failure; - rdatabuf = NULL; - result = isc_buffer_allocate(mctx, &rdatabuf, size); - if (result != ISC_R_SUCCESS) + p = isc_mem_get(mctx, size); + if (p == NULL) { + result = ISC_R_NOMEMORY; goto failure; - - result = dns_rdata_fromtext(rdata, rdatalist->rdclass, - rdatalist->type, lex, + } + isc_buffer_init(&rb, p, size); + result = dns_rdata_fromtext(NULL, + lookup->sdb->common.rdclass, + typeval, lex, origin, ISC_FALSE, - mctx, rdatabuf, + mctx, &rb, &lookup->callbacks); - if (result != ISC_R_SUCCESS) - isc_buffer_free(&rdatabuf); + if (result != ISC_R_NOSPACE) + break; + + isc_mem_put(mctx, p, size); + p = NULL; size *= 2; } while (result == ISC_R_NOSPACE); if (result != ISC_R_SUCCESS) goto failure; - ISC_LIST_APPEND(rdatalist->rdata, rdata, link); - ISC_LIST_APPEND(lookup->buffers, rdatabuf, link); - - if (lex != NULL) - isc_lex_destroy(&lex); - - return (ISC_R_SUCCESS); - + result = dns_sdb_putrdata(lookup, typeval, ttl, + isc_buffer_base(&rb), + isc_buffer_usedlength(&rb)); failure: - - if (rdatabuf != NULL) - isc_buffer_free(&rdatabuf); + if (p != NULL) + isc_mem_put(mctx, p, size); if (lex != NULL) isc_lex_destroy(&lex); - isc_mem_put(mctx, rdata, sizeof(dns_rdata_t)); return (result); } -isc_result_t -dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, - const char *type, dns_ttl_t ttl, const char *data) -{ +static isc_result_t +getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) { dns_name_t *newname, *origin; dns_fixedname_t fnewname; dns_sdb_t *sdb = (dns_sdb_t *)allnodes->common.db; @@ -445,8 +472,33 @@ dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, dns_name_equal(newname, &sdb->common.origin)) allnodes->origin = sdbnode; } - return (dns_sdb_putrr(sdbnode, type, ttl, data)); + *nodep = sdbnode; + return (ISC_R_SUCCESS); +} +isc_result_t +dns_sdb_putnamedrr(dns_sdballnodes_t *allnodes, const char *name, + const char *type, dns_ttl_t ttl, const char *data) +{ + isc_result_t result; + dns_sdbnode_t *sdbnode = NULL; + result = getnode(allnodes, name, &sdbnode); + if (result != ISC_R_SUCCESS) + return (result); + return (dns_sdb_putrr(sdbnode, type, ttl, data)); +} + +isc_result_t +dns_sdb_putnamedrdata(dns_sdballnodes_t *allnodes, const char *name, + dns_rdatatype_t type, dns_ttl_t ttl, + const void *rdata, unsigned int rdlen) +{ + isc_result_t result; + dns_sdbnode_t *sdbnode = NULL; + result = getnode(allnodes, name, &sdbnode); + if (result != ISC_R_SUCCESS) + return (result); + return (dns_sdb_putrdata(sdbnode, type, ttl, rdata, rdlen)); } isc_result_t