2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 07:35:26 +00:00

SIG support

This commit is contained in:
Bob Halley
1999-08-31 22:14:06 +00:00
parent e95d71d749
commit 732e0731de
13 changed files with 556 additions and 290 deletions

View File

@@ -390,7 +390,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
*/ */
node = NULL; node = NULL;
result = dns_db_find(db, name, version, type, client->query.dboptions, result = dns_db_find(db, name, version, type, client->query.dboptions,
client->requesttime, &node, fname, rdataset); client->requesttime, &node, fname, rdataset,
NULL);
switch (result) { switch (result) {
case DNS_R_SUCCESS: case DNS_R_SUCCESS:
case DNS_R_GLUE: case DNS_R_GLUE:
@@ -409,7 +410,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
section++) { section++) {
mname = NULL; mname = NULL;
result = dns_message_findname(client->message, section, result = dns_message_findname(client->message, section,
name, type, &mname, NULL); name, type, 0, &mname, NULL);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
/* /*
* We've already got this RRset in the response. * We've already got this RRset in the response.
@@ -508,19 +509,23 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
static inline void static inline void
query_addrrset(ns_client_t *client, dns_name_t **namep, query_addrrset(ns_client_t *client, dns_name_t **namep,
dns_rdataset_t **rdatasetp, isc_dynbuffer_t *dbuf, dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
dns_section_t section) isc_dynbuffer_t *dbuf, dns_section_t section)
{ {
dns_name_t *name, *mname; dns_name_t *name, *mname;
dns_rdataset_t *rdataset, *mrdataset; dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;
isc_result_t result; isc_result_t result;
name = *namep; name = *namep;
rdataset = *rdatasetp; rdataset = *rdatasetp;
if (sigrdatasetp != NULL)
sigrdataset = *sigrdatasetp;
else
sigrdataset = NULL;
mname = NULL; mname = NULL;
mrdataset = NULL; mrdataset = NULL;
result = dns_message_findname(client->message, section, result = dns_message_findname(client->message, section,
name, rdataset->type, name, rdataset->type, rdataset->covers,
&mname, &mrdataset); &mname, &mrdataset);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
/* /*
@@ -540,8 +545,20 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
} else } else
RUNTIME_CHECK(result == DNS_R_NXRDATASET); RUNTIME_CHECK(result == DNS_R_NXRDATASET);
/*
* Note: we only add SIGs if we've added the type they cover, so
* we do not need to check if the SIG rdataset is already in the
* response.
*/
query_addrdataset(client, mname, rdataset); query_addrdataset(client, mname, rdataset);
*rdatasetp = NULL; *rdatasetp = NULL;
if (sigrdataset != NULL && sigrdataset->methods != NULL) {
/*
* We have a signature. Add it to the response.
*/
query_addrdataset(client, mname, sigrdataset);
*sigrdatasetp = NULL;
}
} }
static inline isc_result_t static inline isc_result_t
@@ -550,7 +567,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
dns_dbnode_t *node; dns_dbnode_t *node;
isc_result_t result, eresult; isc_result_t result, eresult;
dns_fixedname_t foundname; dns_fixedname_t foundname;
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset, *sigrdataset;
/* /*
* Initialization. * Initialization.
@@ -571,7 +588,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
dns_name_init(name, NULL); dns_name_init(name, NULL);
dns_name_clone(dns_db_origin(db), name); dns_name_clone(dns_db_origin(db), name);
rdataset = query_newrdataset(client); rdataset = query_newrdataset(client);
if (rdataset == NULL) { sigrdataset = query_newrdataset(client);
if (rdataset == NULL || sigrdataset == NULL) {
eresult = DNS_R_SERVFAIL; eresult = DNS_R_SERVFAIL;
goto cleanup; goto cleanup;
} }
@@ -580,7 +598,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
* Find the SOA. * Find the SOA.
*/ */
result = dns_db_find(db, name, NULL, dns_rdatatype_soa, 0, 0, &node, result = dns_db_find(db, name, NULL, dns_rdatatype_soa, 0, 0, &node,
fname, rdataset); fname, rdataset, sigrdataset);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
/* /*
* This is bad. We tried to get the SOA RR at the zone top * This is bad. We tried to get the SOA RR at the zone top
@@ -589,11 +607,17 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
* The note above about temporary leakage applies here too. * The note above about temporary leakage applies here too.
*/ */
eresult = DNS_R_SERVFAIL; eresult = DNS_R_SERVFAIL;
} else } else {
query_addrrset(client, &name, &rdataset, NULL, query_addrrset(client, &name, &rdataset, &sigrdataset, NULL,
DNS_SECTION_AUTHORITY); DNS_SECTION_AUTHORITY);
}
cleanup: cleanup:
if (sigrdataset != NULL) {
if (sigrdataset->methods != NULL)
dns_rdataset_disassociate(sigrdataset);
ISC_LIST_APPEND(client->query.tmprdatasets, sigrdataset, link);
}
if (rdataset != NULL) { if (rdataset != NULL) {
if (rdataset->methods != NULL) if (rdataset->methods != NULL)
dns_rdataset_disassociate(rdataset); dns_rdataset_disassociate(rdataset);
@@ -611,13 +635,10 @@ static inline isc_result_t
query_checktype(dns_rdatatype_t type) { query_checktype(dns_rdatatype_t type) {
/* /*
* XXXRTH SIG is here only temporarily. * XXXRTH OPT still needs to be added.
* OPT still needs to be added.
* Should get help with this from rdata.c * Should get help with this from rdata.c
*/ */
switch (type) { switch (type) {
case dns_rdatatype_sig:
return (DNS_R_NOTIMP);
case dns_rdatatype_tkey: case dns_rdatatype_tkey:
return (DNS_R_NOTIMP); return (DNS_R_NOTIMP);
case dns_rdatatype_tsig: case dns_rdatatype_tsig:
@@ -649,6 +670,7 @@ query_find(ns_client_t *client) {
dns_rdatatype_t qtype, type; dns_rdatatype_t qtype, type;
dns_name_t *fname, *tname, *prefix; dns_name_t *fname, *tname, *prefix;
dns_rdataset_t *rdataset, *qrdataset, *trdataset; dns_rdataset_t *rdataset, *qrdataset, *trdataset;
dns_rdataset_t *sigrdataset;
dns_rdata_t rdata; dns_rdata_t rdata;
dns_rdatasetiter_t *rdsiter; dns_rdatasetiter_t *rdsiter;
isc_boolean_t use_cache, recursion_ok, want_restart; isc_boolean_t use_cache, recursion_ok, want_restart;
@@ -676,6 +698,7 @@ query_find(ns_client_t *client) {
recursion_ok = ISC_FALSE; recursion_ok = ISC_FALSE;
fname = NULL; fname = NULL;
rdataset = NULL; rdataset = NULL;
sigrdataset = NULL;
node = NULL; node = NULL;
db = NULL; db = NULL;
version = NULL; version = NULL;
@@ -778,6 +801,12 @@ query_find(ns_client_t *client) {
goto cleanup; goto cleanup;
} }
/*
* If it's a SIG query, we'll iterate the node.
*/
if (qtype == dns_rdatatype_sig)
type = dns_rdatatype_any;
/* /*
* We'll need some resources... * We'll need some resources...
*/ */
@@ -788,7 +817,8 @@ query_find(ns_client_t *client) {
} }
fname = query_newname(client, dbuf, &b); fname = query_newname(client, dbuf, &b);
rdataset = query_newrdataset(client); rdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL) { sigrdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
QUERY_ERROR(DNS_R_SERVFAIL); QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup; goto cleanup;
} }
@@ -800,7 +830,8 @@ query_find(ns_client_t *client) {
* Now look for an answer in the database. * Now look for an answer in the database.
*/ */
result = dns_db_find(db, client->query.qname, version, type, 0, result = dns_db_find(db, client->query.qname, version, type, 0,
client->requesttime, &node, fname, rdataset); client->requesttime, &node, fname, rdataset,
sigrdataset);
switch (result) { switch (result) {
case DNS_R_SUCCESS: case DNS_R_SUCCESS:
case DNS_R_ZONECUT: case DNS_R_ZONECUT:
@@ -818,7 +849,8 @@ query_find(ns_client_t *client) {
* We don't have a cache, so this is the best * We don't have a cache, so this is the best
* answer. * answer.
*/ */
query_addrrset(client, &fname, &rdataset, dbuf, query_addrrset(client, &fname, &rdataset,
&sigrdataset, dbuf,
DNS_SECTION_AUTHORITY); DNS_SECTION_AUTHORITY);
} else { } else {
/* /*
@@ -878,8 +910,8 @@ query_find(ns_client_t *client) {
* Add NXT record if we found one. * Add NXT record if we found one.
*/ */
if (dns_rdataset_isassociated(rdataset)) if (dns_rdataset_isassociated(rdataset))
query_addrrset(client, &tname, &rdataset, NULL, query_addrrset(client, &tname, &rdataset, &sigrdataset,
DNS_SECTION_AUTHORITY); NULL, DNS_SECTION_AUTHORITY);
goto cleanup; goto cleanup;
case DNS_R_NXDOMAIN: case DNS_R_NXDOMAIN:
if (restarts > 0) { if (restarts > 0) {
@@ -922,8 +954,8 @@ query_find(ns_client_t *client) {
* Add NXT record if we found one. * Add NXT record if we found one.
*/ */
if (dns_rdataset_isassociated(rdataset)) if (dns_rdataset_isassociated(rdataset))
query_addrrset(client, &tname, &rdataset, NULL, query_addrrset(client, &tname, &rdataset, &sigrdataset,
DNS_SECTION_AUTHORITY); NULL, DNS_SECTION_AUTHORITY);
/* /*
* Set message rcode. * Set message rcode.
*/ */
@@ -942,7 +974,7 @@ query_find(ns_client_t *client) {
/* /*
* Add the CNAME to the answer section. * Add the CNAME to the answer section.
*/ */
query_addrrset(client, &fname, &rdataset, dbuf, query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER); DNS_SECTION_ANSWER);
/* /*
* We set the PARTIALANSWER attribute so that if anything goes * We set the PARTIALANSWER attribute so that if anything goes
@@ -986,7 +1018,7 @@ query_find(ns_client_t *client) {
/* /*
* Add the DNAME to the answer section. * Add the DNAME to the answer section.
*/ */
query_addrrset(client, &fname, &rdataset, dbuf, query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER); DNS_SECTION_ANSWER);
/* /*
* We set the PARTIALANSWER attribute so that if anything goes * We set the PARTIALANSWER attribute so that if anything goes
@@ -1029,9 +1061,8 @@ query_find(ns_client_t *client) {
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
if (result == ISC_R_NOSPACE) { if (result == ISC_R_NOSPACE) {
/* /*
* draft-ietf-dnsind-dname-03.txt, section * RFC 2672, section 4.1, subsection 3c says
* 4.1, subsection 3c says we should * we should return YXDOMAIN if the constructed
* return YXDOMAIN if the constructed
* name would be too long. * name would be too long.
*/ */
client->message->rcode = dns_rcode_yxdomain; client->message->rcode = dns_rcode_yxdomain;
@@ -1058,7 +1089,7 @@ query_find(ns_client_t *client) {
*/ */
n = 0; n = 0;
rdsiter = NULL; rdsiter = NULL;
result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
QUERY_ERROR(DNS_R_SERVFAIL); QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup; goto cleanup;
@@ -1066,34 +1097,72 @@ query_find(ns_client_t *client) {
result = dns_rdatasetiter_first(rdsiter); result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, rdataset); dns_rdatasetiter_current(rdsiter, rdataset);
tname = fname; if (qtype == dns_rdatatype_any ||
query_addrrset(client, &tname, &rdataset, dbuf, rdataset->type == qtype) {
DNS_SECTION_ANSWER); tname = fname;
n++; query_addrrset(client, &tname, &rdataset, NULL,
dbuf, DNS_SECTION_ANSWER);
n++;
/*
* We shouldn't ever fail to add 'rdataset'
* because it's already in the answer.
*/
INSIST(rdataset == NULL);
/*
* We set dbuf to NULL because we only want
* the query_keepname() call in
* query_addrrset() to be called once.
*/
dbuf = NULL;
rdataset = query_newrdataset(client);
if (rdataset == NULL)
break;
} else {
/*
* We're not interested in this rdataset.
*/
dns_rdataset_disassociate(rdataset);
}
result = dns_rdatasetiter_next(rdsiter);
}
if (n > 0) {
/* /*
* We shouldn't ever fail to add 'rdataset' because * If we added at least one RRset, then we must clear
* it's already in the answer. * fname, otherwise the cleanup code might cause it
* to be reused.
*/ */
INSIST(rdataset == NULL); fname = NULL;
} else {
/* /*
* We set dbuf to NULL because we only want the * We didn't match any rdatasets.
* query_keepname() call in query_addrrset() to be
* called once.
*/ */
dbuf = NULL; if (qtype == dns_rdatatype_sig &&
result = dns_message_gettemprdataset(client->message, result == DNS_R_NOMORE) {
&rdataset); /*
if (result == ISC_R_SUCCESS) { * XXXRTH If this is a secure zone and we
dns_rdataset_init(rdataset); * didn't find any SIGs, we should generate
result = dns_rdatasetiter_next(rdsiter); * an error unless we were searching for
* glue. Ugh.
*/
/*
* We were searching for SIG records in
* a nonsecure zone. Send a "no error,
* no data" response.
*
* First we must release fname.
*/
query_releasename(client, &fname);
/*
* Add SOA.
*/
result = query_addsoa(client, db);
} else {
/*
* Something went wrong.
*/
result = DNS_R_SERVFAIL;
} }
} }
/*
* If we added at least one RRset, then we must clear fname,
* otherwise the cleanup code might cause it to be reused.
*/
if (n > 0)
fname = NULL;
dns_rdatasetiter_destroy(&rdsiter); dns_rdatasetiter_destroy(&rdsiter);
if (result != DNS_R_NOMORE) { if (result != DNS_R_NOMORE) {
QUERY_ERROR(DNS_R_SERVFAIL); QUERY_ERROR(DNS_R_SERVFAIL);
@@ -1104,7 +1173,7 @@ query_find(ns_client_t *client) {
* This is the "normal" case -- an ordinary question to which * This is the "normal" case -- an ordinary question to which
* we know the answer. * we know the answer.
*/ */
query_addrrset(client, &fname, &rdataset, dbuf, query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER); DNS_SECTION_ANSWER);
/* /*
* Remember that we've answered this question. * Remember that we've answered this question.
@@ -1123,6 +1192,11 @@ query_find(ns_client_t *client) {
*/ */
cleanup: cleanup:
if (sigrdataset != NULL) {
if (sigrdataset->methods != NULL)
dns_rdataset_disassociate(sigrdataset);
ISC_LIST_APPEND(client->query.tmprdatasets, sigrdataset, link);
}
if (rdataset != NULL) { if (rdataset != NULL) {
if (rdataset->methods != NULL) if (rdataset->methods != NULL)
dns_rdataset_disassociate(rdataset); dns_rdataset_disassociate(rdataset);

View File

@@ -261,9 +261,9 @@ foreach_node_rr(dns_db_t *db,
/* /*
* For each of the RRs specified by 'db', 'ver', 'name', and 'type', * For each of the RRs specified by 'db', 'ver', 'name', 'type',
* (which can be dns_rdatatype_any to match any type), call 'action' * (which can be dns_rdatatype_any to match any type), and 'covers', call
* with the RR and 'action_data' as arguments. If the name * 'action' with the RR and 'action_data' as arguments. If the name
* does not exist, or if no RRset of the given type exists at the name, * does not exist, or if no RRset of the given type exists at the name,
* do nothing. * do nothing.
* *
@@ -274,6 +274,7 @@ foreach_rr(dns_db_t *db,
dns_dbversion_t *ver, dns_dbversion_t *ver,
dns_name_t *name, dns_name_t *name,
dns_rdatatype_t type, dns_rdatatype_t type,
dns_rdatatype_t covers,
rr_func *rr_action, rr_func *rr_action,
void *rr_action_data) void *rr_action_data)
{ {
@@ -294,7 +295,7 @@ foreach_rr(dns_db_t *db,
return (result); return (result);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, type, result = dns_db_findrdataset(db, node, ver, type, covers,
(isc_stdtime_t) 0, &rdataset); (isc_stdtime_t) 0, &rdataset);
if (result == DNS_R_NOTFOUND) { if (result == DNS_R_NOTFOUND) {
result = DNS_R_SUCCESS; result = DNS_R_SUCCESS;
@@ -366,10 +367,11 @@ do { \
*/ */
static dns_result_t static dns_result_t
rrset_exists(dns_db_t *db, dns_dbversion_t *ver, rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
dns_name_t *name, dns_rdatatype_t type, isc_boolean_t *exists) dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers,
isc_boolean_t *exists)
{ {
dns_result_t result; dns_result_t result;
result = foreach_rr(db, ver, name, type, result = foreach_rr(db, ver, name, type, covers,
rrset_exists_action, NULL); rrset_exists_action, NULL);
RETURN_EXISTENCE_FLAG; RETURN_EXISTENCE_FLAG;
} }
@@ -429,10 +431,10 @@ count_rr_action(void *data, rr_t *rr) /*ARGSUSED*/ {
*/ */
static dns_result_t static dns_result_t
rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_rdatatype_t type, int *countp) dns_rdatatype_t type, dns_rdatatype_t covers, int *countp)
{ {
*countp = 0; *countp = 0;
return (foreach_rr(db, ver, name, type, return (foreach_rr(db, ver, name, type, covers,
count_rr_action, countp)); count_rr_action, countp));
} }
@@ -468,6 +470,7 @@ matching_rr_exists(rr_predicate *predicate,
dns_dbversion_t *ver, dns_dbversion_t *ver,
dns_name_t *name, dns_name_t *name,
dns_rdatatype_t type, dns_rdatatype_t type,
dns_rdatatype_t covers,
dns_rdata_t *update_rr, dns_rdata_t *update_rr,
isc_boolean_t *exists) isc_boolean_t *exists)
{ {
@@ -478,7 +481,7 @@ matching_rr_exists(rr_predicate *predicate,
ctx.ver = ver; ctx.ver = ver;
ctx.name = name; ctx.name = name;
ctx.update_rr = update_rr; ctx.update_rr = update_rr;
result = foreach_rr(db, ver, name, type, result = foreach_rr(db, ver, name, type, covers,
matching_rr_exists_action, &ctx); matching_rr_exists_action, &ctx);
RETURN_EXISTENCE_FLAG; RETURN_EXISTENCE_FLAG;
} }
@@ -637,7 +640,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
/* A new unique type begins here. */ /* A new unique type begins here. */
while (t != NULL && dns_name_equal(&t->name, name)) { while (t != NULL && dns_name_equal(&t->name, name)) {
dns_rdatatype_t type; dns_rdatatype_t type, covers;
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
dns_diff_t d_rrs; /* Database RRs with dns_diff_t d_rrs; /* Database RRs with
this name and type */ this name and type */
@@ -645,6 +648,10 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
this name and type */ this name and type */
type = t->rdata.type; type = t->rdata.type;
if (type == dns_rdatatype_sig)
covers = dns_rdata_covers(&t->rdata);
else
covers = 0;
/* /*
* Collect all database RRs for this name and type * Collect all database RRs for this name and type
@@ -652,7 +659,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
*/ */
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, type, result = dns_db_findrdataset(db, node, ver, type,
(isc_stdtime_t) 0, covers, (isc_stdtime_t) 0,
&rdataset); &rdataset);
if (result != DNS_R_SUCCESS) { if (result != DNS_R_SUCCESS) {
dns_db_detachnode(db, &node); dns_db_detachnode(db, &node);
@@ -837,6 +844,7 @@ delete_if(rr_predicate *predicate,
dns_dbversion_t *ver, dns_dbversion_t *ver,
dns_name_t *name, dns_name_t *name,
dns_rdatatype_t type, dns_rdatatype_t type,
dns_rdatatype_t covers,
dns_rdata_t *update_rr, dns_rdata_t *update_rr,
dns_diff_t *diff) dns_diff_t *diff)
{ {
@@ -847,7 +855,7 @@ delete_if(rr_predicate *predicate,
ctx.diff = diff; ctx.diff = diff;
ctx.name = name; ctx.name = name;
ctx.update_rr = update_rr; ctx.update_rr = update_rr;
return (foreach_rr(db, ver, name, type, return (foreach_rr(db, ver, name, type, covers,
delete_if_action, &ctx)); delete_if_action, &ctx));
} }
@@ -866,7 +874,8 @@ delete_if(rr_predicate *predicate,
static void static void
get_current_rr(dns_message_t *msg, dns_section_t section, get_current_rr(dns_message_t *msg, dns_section_t section,
dns_rdataclass_t zoneclass, dns_rdataclass_t zoneclass,
dns_name_t **name, dns_rdata_t *rdata, dns_ttl_t *ttl, dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers,
dns_ttl_t *ttl,
dns_rdataclass_t *update_class) dns_rdataclass_t *update_class)
{ {
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset;
@@ -875,6 +884,7 @@ get_current_rr(dns_message_t *msg, dns_section_t section,
rdataset = ISC_LIST_HEAD((*name)->list); rdataset = ISC_LIST_HEAD((*name)->list);
INSIST(rdataset != NULL); INSIST(rdataset != NULL);
INSIST(ISC_LIST_NEXT(rdataset, link) == NULL); INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
*covers = rdataset->covers;
*ttl = rdataset->ttl; *ttl = rdataset->ttl;
result = dns_rdataset_first(rdataset); result = dns_rdataset_first(rdataset);
INSIST(result == DNS_R_SUCCESS); INSIST(result == DNS_R_SUCCESS);
@@ -991,6 +1001,7 @@ ns_req_update(ns_client_t *client,
unsigned int response_rcode = dns_rcode_noerror; unsigned int response_rcode = dns_rcode_noerror;
isc_boolean_t soa_serial_changed = ISC_FALSE; isc_boolean_t soa_serial_changed = ISC_FALSE;
isc_mem_t *mctx = client->mctx; isc_mem_t *mctx = client->mctx;
dns_rdatatype_t covers;
dns_diff_init(mctx, &diff); dns_diff_init(mctx, &diff);
dns_diff_init(mctx, &temp); dns_diff_init(mctx, &temp);
@@ -1065,7 +1076,7 @@ ns_req_update(ns_client_t *client,
isc_boolean_t flag; isc_boolean_t flag;
get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass, get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass,
&name, &rdata, &ttl, &update_class); &name, &rdata, &covers, &ttl, &update_class);
if (ttl != 0) if (ttl != 0)
FAILMSG(DNS_R_FORMERR, "prereq TTL != 0"); FAILMSG(DNS_R_FORMERR, "prereq TTL != 0");
@@ -1087,7 +1098,7 @@ ns_req_update(ns_client_t *client,
} }
} else { } else {
CHECK(rrset_exists(db, ver, name, CHECK(rrset_exists(db, ver, name,
rdata.type, &flag)); rdata.type, covers, &flag));
if (! flag) { if (! flag) {
/* RRset does not exist. */ /* RRset does not exist. */
FAILMSG(DNS_R_NXRRSET, FAILMSG(DNS_R_NXRRSET,
@@ -1108,7 +1119,7 @@ ns_req_update(ns_client_t *client,
} }
} else { } else {
CHECK(rrset_exists(db, ver, name, CHECK(rrset_exists(db, ver, name,
rdata.type, &flag)); rdata.type, covers, &flag));
if (flag) { if (flag) {
/* RRset exists. */ /* RRset exists. */
FAILMSG(DNS_R_YXRRSET, FAILMSG(DNS_R_YXRRSET,
@@ -1156,7 +1167,7 @@ ns_req_update(ns_client_t *client,
dns_ttl_t ttl; dns_ttl_t ttl;
dns_rdataclass_t update_class; dns_rdataclass_t update_class;
get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
&name, &rdata, &ttl, &update_class); &name, &rdata, &covers, &ttl, &update_class);
if (! dns_name_issubdomain(name, zonename)) if (! dns_name_issubdomain(name, zonename))
FAILMSG(DNS_R_NOTZONE, FAILMSG(DNS_R_NOTZONE,
@@ -1206,7 +1217,7 @@ ns_req_update(ns_client_t *client,
isc_boolean_t flag; isc_boolean_t flag;
get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
&name, &rdata, &ttl, &update_class); &name, &rdata, &covers, &ttl, &update_class);
if (update_class == zoneclass) { if (update_class == zoneclass) {
if (rdata.type == dns_rdatatype_cname) { if (rdata.type == dns_rdatatype_cname) {
@@ -1221,7 +1232,7 @@ ns_req_update(ns_client_t *client,
} }
} else { } else {
CHECK(rrset_exists(db, ver, name, CHECK(rrset_exists(db, ver, name,
dns_rdatatype_cname, dns_rdatatype_cname, 0,
&flag)); &flag));
if (flag && ! is_dnssec_type(rdata.type)) { if (flag && ! is_dnssec_type(rdata.type)) {
printf("attempt to add non-cname " printf("attempt to add non-cname "
@@ -1232,7 +1243,8 @@ ns_req_update(ns_client_t *client,
if (rdata.type == dns_rdatatype_soa) { if (rdata.type == dns_rdatatype_soa) {
isc_boolean_t changed, ok; isc_boolean_t changed, ok;
CHECK(rrset_exists(db, ver, name, CHECK(rrset_exists(db, ver, name,
dns_rdatatype_soa, &flag)); dns_rdatatype_soa, 0,
&flag));
if (! flag) { if (! flag) {
printf("attempt to create extra SOA " printf("attempt to create extra SOA "
"ignored\n"); "ignored\n");
@@ -1254,11 +1266,13 @@ ns_req_update(ns_client_t *client,
* CNAME, SOA, or WKS exists, remove it first. * CNAME, SOA, or WKS exists, remove it first.
*/ */
CHECK(matching_rr_exists(rr_equal_p, db, ver, name, CHECK(matching_rr_exists(rr_equal_p, db, ver, name,
rdata.type, &rdata, &flag)); rdata.type, covers, &rdata,
&flag));
if (! flag) { if (! flag) {
printf("add an RR\n"); printf("add an RR\n");
CHECK(delete_if(replaces_p, db, ver, name, CHECK(delete_if(replaces_p, db, ver, name,
rdata.type, &rdata, &diff)); rdata.type, covers, &rdata,
&diff));
result = update_one_rr(db, ver, &diff, result = update_one_rr(db, ver, &diff,
DNS_DIFFOP_ADD, DNS_DIFFOP_ADD,
name, ttl, &rdata); name, ttl, &rdata);
@@ -1273,11 +1287,11 @@ ns_req_update(ns_client_t *client,
if (dns_name_equal(name, zonename)) { if (dns_name_equal(name, zonename)) {
CHECK(delete_if(type_not_soa_nor_ns_p, CHECK(delete_if(type_not_soa_nor_ns_p,
db, ver, name, db, ver, name,
dns_rdatatype_any, dns_rdatatype_any, 0,
&rdata, &diff)); &rdata, &diff));
} else { } else {
CHECK(delete_if(true_p, db, ver, name, CHECK(delete_if(true_p, db, ver, name,
dns_rdatatype_any, dns_rdatatype_any, 0,
&rdata, &diff)); &rdata, &diff));
} }
} else if (dns_name_equal(name, zonename) && } else if (dns_name_equal(name, zonename) &&
@@ -1289,7 +1303,8 @@ ns_req_update(ns_client_t *client,
} else { } else {
printf("delete an rrset\n"); printf("delete an rrset\n");
CHECK(delete_if(true_p, db, ver, name, CHECK(delete_if(true_p, db, ver, name,
rdata.type, &rdata, &diff)); rdata.type, covers, &rdata,
&diff));
} }
} else if (update_class == dns_rdataclass_none) { } else if (update_class == dns_rdataclass_none) {
if (rdata.type == dns_rdatatype_soa) { if (rdata.type == dns_rdatatype_soa) {
@@ -1299,7 +1314,7 @@ ns_req_update(ns_client_t *client,
if (rdata.type == dns_rdatatype_ns) { if (rdata.type == dns_rdatatype_ns) {
int count; int count;
CHECK(rr_count(db, ver, name, CHECK(rr_count(db, ver, name,
dns_rdatatype_ns, &count)); dns_rdatatype_ns, 0, &count));
if (count == 1) { if (count == 1) {
printf("attempt to delete last " printf("attempt to delete last "
"NS ignored\n"); "NS ignored\n");
@@ -1308,7 +1323,7 @@ ns_req_update(ns_client_t *client,
} }
printf("delete an RR\n"); printf("delete an RR\n");
CHECK(delete_if(rr_equal_p, db, ver, name, CHECK(delete_if(rr_equal_p, db, ver, name,
rdata.type, &rdata, &diff)); rdata.type, covers, &rdata, &diff));
} }
} }
if (result != DNS_R_NOMORE) if (result != DNS_R_NOMORE)

View File

@@ -211,7 +211,7 @@ t_dns_db_load(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
if (dns_result != exp_find_result) { if (dns_result != exp_find_result) {
t_info("dns_db_findnode returned %s, expected %s\n", t_info("dns_db_findnode returned %s, expected %s\n",
@@ -757,7 +757,7 @@ t_dns_db_currentversion(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
if (dns_result != DNS_R_SUCCESS) { if (dns_result != DNS_R_SUCCESS) {
t_info("unable to find %s using current version\n", findname); t_info("unable to find %s using current version\n", findname);
@@ -817,7 +817,7 @@ t_dns_db_currentversion(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
t_info("unexpectedly found %s using current version\n", findname); t_info("unexpectedly found %s using current version\n", findname);
@@ -840,7 +840,7 @@ t_dns_db_currentversion(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
/* and expect it to succeed */ /* and expect it to succeed */
if (dns_result == DNS_R_SUCCESS) { if (dns_result == DNS_R_SUCCESS) {
@@ -1076,7 +1076,7 @@ t_dns_db_newversion(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if (dns_result != DNS_R_SUCCESS) { if (dns_result != DNS_R_SUCCESS) {
t_info("unable to find %s\n", newname); t_info("unable to find %s\n", newname);
@@ -1400,7 +1400,7 @@ t_dns_db_closeversion_1(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if (dns_result != DNS_R_SUCCESS) { if (dns_result != DNS_R_SUCCESS) {
t_info("unable to find %s\n", new_name); t_info("unable to find %s\n", new_name);
@@ -1447,7 +1447,7 @@ t_dns_db_closeversion_1(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
@@ -1741,7 +1741,7 @@ t_dns_db_closeversion_2(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if ( (dns_result == DNS_R_NOTFOUND) || if ( (dns_result == DNS_R_NOTFOUND) ||
(dns_result == DNS_R_NXDOMAIN) || (dns_result == DNS_R_NXDOMAIN) ||
@@ -1791,7 +1791,7 @@ t_dns_db_closeversion_2(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
@@ -1821,7 +1821,7 @@ t_dns_db_closeversion_2(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
t_info("dns_db_find %s returned %s\n", new_name, t_info("dns_db_find %s returned %s\n", new_name,
@@ -1848,7 +1848,7 @@ t_dns_db_closeversion_2(char **av) {
0, 0,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&found_rdataset); &found_rdataset, NULL);
if ( (dns_result == DNS_R_NOTFOUND) || if ( (dns_result == DNS_R_NOTFOUND) ||
@@ -2027,7 +2027,7 @@ t_dns_db_expirenode(char **av) {
find_expire_time, find_expire_time,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
if (dns_result == exp_result) { if (dns_result == exp_result) {
result = T_PASS; result = T_PASS;
@@ -2182,7 +2182,8 @@ t_dns_db_findnode_1(char **av) {
dns_db_currentversion(db, &cversionp); dns_db_currentversion(db, &cversionp);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
dns_result = dns_db_findrdataset(db, nodep, cversionp, rdatatype, 0, &rdataset); dns_result = dns_db_findrdataset(db, nodep, cversionp, rdatatype, 0,
0, &rdataset);
if (dns_result == DNS_R_SUCCESS) { if (dns_result == DNS_R_SUCCESS) {
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
result = T_PASS; result = T_PASS;
@@ -2332,7 +2333,7 @@ t_dns_db_findnode_2(char **av) {
0, 0,
&newnodep, &newnodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) { if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
dns_db_detachnode(db, &newnodep); dns_db_detachnode(db, &newnodep);
} }
@@ -2512,7 +2513,7 @@ t_dns_db_find_x(char **av) {
ftime, ftime,
&nodep, &nodep,
dns_fixedname_name(&dns_foundname), dns_fixedname_name(&dns_foundname),
&rdataset); &rdataset, NULL);
if (dns_result != exp_result) { if (dns_result != exp_result) {
t_info("dns_db_find %s %s unexpectedly returned %s, expected %s\n", t_info("dns_db_find %s %s unexpectedly returned %s, expected %s\n",

View File

@@ -323,7 +323,7 @@ main(int argc, char *argv[]) {
isc_buffer_t source, target; isc_buffer_t source, target;
char s[1000]; char s[1000];
char b[255]; char b[255];
dns_rdataset_t rdataset; dns_rdataset_t rdataset, sigrdataset;
int ch; int ch;
dns_rdatatype_t type = 1; dns_rdatatype_t type = 1;
isc_boolean_t printnode = ISC_FALSE; isc_boolean_t printnode = ISC_FALSE;
@@ -706,8 +706,9 @@ main(int argc, char *argv[]) {
} }
node = NULL; node = NULL;
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
dns_rdataset_init(&sigrdataset);
result = dns_db_find(db, &name, version, type, options, 0, result = dns_db_find(db, &name, version, type, options, 0,
&node, fname, &rdataset); &node, fname, &rdataset, &sigrdataset);
if (!quiet) { if (!quiet) {
if (dbi != NULL) if (dbi != NULL)
printf("\n"); printf("\n");
@@ -797,6 +798,11 @@ main(int argc, char *argv[]) {
} else { } else {
if (!quiet) if (!quiet)
print_rdataset(fname, &rdataset); print_rdataset(fname, &rdataset);
if (dns_rdataset_isassociated(&sigrdataset)) {
if (!quiet)
print_rdataset(fname, &sigrdataset);
dns_rdataset_disassociate(&sigrdataset);
}
if (dbi != NULL && addmode && !found_as) { if (dbi != NULL && addmode && !found_as) {
rdataset.ttl++; rdataset.ttl++;
rdataset.trust = trust; rdataset.trust = trust;

View File

@@ -335,7 +335,7 @@ dns_result_t
dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset) dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{ {
/* /*
@@ -349,9 +349,12 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
REQUIRE(dns_name_hasbuffer(foundname)); REQUIRE(dns_name_hasbuffer(foundname));
REQUIRE(rdataset == NULL || REQUIRE(rdataset == NULL ||
(DNS_RDATASET_VALID(rdataset) && rdataset->methods == NULL)); (DNS_RDATASET_VALID(rdataset) && rdataset->methods == NULL));
REQUIRE(sigrdataset == NULL ||
(DNS_RDATASET_VALID(sigrdataset) &&
sigrdataset->methods == NULL));
return ((db->methods->find)(db, name, version, type, options, now, return ((db->methods->find)(db, name, version, type, options, now,
nodep, foundname, rdataset)); nodep, foundname, rdataset, sigrdataset));
} }
void void
@@ -434,8 +437,8 @@ dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
dns_result_t dns_result_t
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now, dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdataset_t *rdataset) isc_stdtime_t now, dns_rdataset_t *rdataset)
{ {
/* /*
* Search for an rdataset of type 'type' at 'node' that are in version * Search for an rdataset of type 'type' at 'node' that are in version
@@ -446,10 +449,11 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
REQUIRE(node != NULL); REQUIRE(node != NULL);
REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods == NULL); REQUIRE(rdataset->methods == NULL);
REQUIRE(type != dns_rdatatype_sig && type != dns_rdatatype_any); REQUIRE(covers == 0 || type == dns_rdatatype_sig);
REQUIRE(type != dns_rdatatype_any);
return ((db->methods->findrdataset)(db, node, version, type, now, return ((db->methods->findrdataset)(db, node, version, type, covers,
rdataset)); now, rdataset));
} }
dns_result_t dns_result_t

View File

@@ -96,7 +96,8 @@ typedef struct dns_dbmethods {
dns_rdatatype_t type, unsigned int options, dns_rdatatype_t type, unsigned int options,
isc_stdtime_t now, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset); dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset);
void (*attachnode)(dns_db_t *db, void (*attachnode)(dns_db_t *db,
dns_dbnode_t *source, dns_dbnode_t *source,
dns_dbnode_t **targetp); dns_dbnode_t **targetp);
@@ -112,6 +113,7 @@ typedef struct dns_dbmethods {
dns_result_t (*findrdataset)(dns_db_t *db, dns_dbnode_t *node, dns_result_t (*findrdataset)(dns_db_t *db, dns_dbnode_t *node,
dns_dbversion_t *version, dns_dbversion_t *version,
dns_rdatatype_t type, dns_rdatatype_t type,
dns_rdatatype_t covers,
isc_stdtime_t now, isc_stdtime_t now,
dns_rdataset_t *rdataset); dns_rdataset_t *rdataset);
dns_result_t (*allrdatasets)(dns_db_t *db, dns_dbnode_t *node, dns_result_t (*allrdatasets)(dns_db_t *db, dns_dbnode_t *node,
@@ -554,7 +556,7 @@ dns_result_t
dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset); dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
/* /*
* Find the best match for 'name' and 'type' in version 'version' of 'db'. * Find the best match for 'name' and 'type' in version 'version' of 'db'.
* *
@@ -784,8 +786,8 @@ dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
dns_result_t dns_result_t
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now, dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdataset_t *rdataset); isc_stdtime_t now, dns_rdataset_t *rdataset);
/* /*
* Search for an rdataset of type 'type' at 'node' that are in version * Search for an rdataset of type 'type' at 'node' that are in version
* 'version' of 'db'. If found, make 'rdataset' refer to it. * 'version' of 'db'. If found, make 'rdataset' refer to it.
@@ -810,7 +812,9 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
* *
* 'rdataset' is a valid, disassociated rdataset. * 'rdataset' is a valid, disassociated rdataset.
* *
* 'type' is not SIG, or a meta-RR type such as 'ANY' or 'OPT'. * If 'covers' != 0, 'type' must be SIG.
*
* 'type' is not a meta-RR type such as 'ANY' or 'OPT'.
* *
* Ensures: * Ensures:
* *

View File

@@ -464,11 +464,12 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
dns_result_t dns_result_t
dns_message_findname(dns_message_t *msg, dns_section_t section, dns_message_findname(dns_message_t *msg, dns_section_t section,
dns_name_t *target, dns_rdatatype_t type, dns_name_t *target, dns_rdatatype_t type,
dns_name_t **foundname, dns_rdataset_t **rdataset); dns_rdatatype_t covers, dns_name_t **foundname,
dns_rdataset_t **rdataset);
/* /*
* Search for a name in the specified section. If it is found, *name is * Search for a name in the specified section. If it is found, *name is
* set to point to the name, and *rdataset is set to point to the found * set to point to the name, and *rdataset is set to point to the found
* rdataset (if type is specified as other than dns_rdatatype_any.) * rdataset (if type is specified as other than dns_rdatatype_any).
* *
* Requires: * Requires:
* 'msg' be valid. * 'msg' be valid.

View File

@@ -123,7 +123,7 @@ dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
return (result); return (result);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
(isc_stdtime_t) 0, &rdataset); (isc_stdtime_t) 0, &rdataset);
if (result != DNS_R_SUCCESS) if (result != DNS_R_SUCCESS)
goto freenode; goto freenode;
@@ -164,7 +164,7 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
return (result); return (result);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
(isc_stdtime_t) 0, &rdataset); (isc_stdtime_t) 0, &rdataset);
if (result != DNS_R_SUCCESS) if (result != DNS_R_SUCCESS)
goto freenode; goto freenode;

View File

@@ -15,7 +15,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
/* $Id: master.c,v 1.22 1999/08/05 22:10:23 halley Exp $ */ /* $Id: master.c,v 1.23 1999/08/31 22:12:14 halley Exp $ */
#include <config.h> #include <config.h>
@@ -140,7 +140,7 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
isc_mem_t *mctx) isc_mem_t *mctx)
{ {
dns_rdataclass_t rdclass; dns_rdataclass_t rdclass;
dns_rdatatype_t type; dns_rdatatype_t type, covers;
isc_uint32_t ttl = 0; isc_uint32_t ttl = 0;
isc_uint32_t default_ttl = 0; isc_uint32_t default_ttl = 0;
isc_uint32_t ttl_offset = 0; isc_uint32_t ttl_offset = 0;
@@ -634,58 +634,6 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
ttl -= ttl_offset; ttl -= ttl_offset;
} }
/*
* Find type in rdatalist.
* If it does not exit create new one and prepend to list
* as this will mimimise list traversal.
*/
if (in_glue)
this = ISC_LIST_HEAD(glue_list);
else
this = ISC_LIST_HEAD(current_list);
while (this != NULL) {
if (this->type == type)
break;
this = ISC_LIST_NEXT(this, link);
}
if (this == NULL) {
if (rdlcount == rdatalist_size) {
new_rdatalist =
grow_rdatalist(rdatalist_size + RDLSZ,
rdatalist,
rdatalist_size,
&current_list,
&glue_list,
mctx);
if (new_rdatalist == NULL) {
result = DNS_R_NOMEMORY;
goto error_cleanup;
}
rdatalist = new_rdatalist;
rdatalist_size += RDLSZ;
}
this = &rdatalist[rdlcount++];
this->type = type;
this->rdclass = zclass;
this->ttl = ttl;
ISC_LIST_INIT(this->rdata);
ISC_LINK_INIT(this, link);
if (in_glue)
ISC_LIST_PREPEND(glue_list, this, link);
else
ISC_LIST_PREPEND(current_list, this, link);
} else if (this->ttl != ttl) {
(*callbacks->warn)(callbacks,
"%s: %s:%d: TTL set to prior TTL (%lu)\n",
"dns_master_load",
isc_lex_getsourcename(lex),
isc_lex_getsourceline(lex),
this->ttl);
ttl = this->ttl;
}
/* /*
* Find a rdata structure. * Find a rdata structure.
*/ */
@@ -709,6 +657,64 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
callbacks); callbacks);
if (result != DNS_R_SUCCESS) if (result != DNS_R_SUCCESS)
goto cleanup; goto cleanup;
if (type == dns_rdatatype_sig)
covers = dns_rdata_covers(&rdata[rdcount]);
else
covers = 0;
/*
* Find type in rdatalist.
* If it does not exit create new one and prepend to list
* as this will mimimise list traversal.
*/
if (in_glue)
this = ISC_LIST_HEAD(glue_list);
else
this = ISC_LIST_HEAD(current_list);
while (this != NULL) {
if (this->type == type && this->covers == covers)
break;
this = ISC_LIST_NEXT(this, link);
}
if (this == NULL) {
if (rdlcount == rdatalist_size) {
new_rdatalist =
grow_rdatalist(rdatalist_size + RDLSZ,
rdatalist,
rdatalist_size,
&current_list,
&glue_list,
mctx);
if (new_rdatalist == NULL) {
result = DNS_R_NOMEMORY;
goto error_cleanup;
}
rdatalist = new_rdatalist;
rdatalist_size += RDLSZ;
}
this = &rdatalist[rdlcount++];
this->type = type;
this->covers = covers;
this->rdclass = zclass;
this->ttl = ttl;
ISC_LIST_INIT(this->rdata);
ISC_LINK_INIT(this, link);
if (in_glue)
ISC_LIST_PREPEND(glue_list, this, link);
else
ISC_LIST_PREPEND(current_list, this, link);
} else if (this->ttl != ttl) {
(*callbacks->warn)(callbacks,
"%s: %s:%d: TTL set to prior TTL (%lu)\n",
"dns_master_load",
isc_lex_getsourcename(lex),
isc_lex_getsourceline(lex),
this->ttl);
ttl = this->ttl;
}
/* /*
* If the new rdata is not on the list add it. * If the new rdata is not on the list add it.

View File

@@ -674,14 +674,15 @@ findname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section)
} }
static dns_result_t static dns_result_t
findtype(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type) findtype(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type,
dns_rdatatype_t covers)
{ {
dns_rdataset_t *curr; dns_rdataset_t *curr;
for (curr = ISC_LIST_TAIL(name->list) ; for (curr = ISC_LIST_TAIL(name->list) ;
curr != NULL ; curr != NULL ;
curr = ISC_LIST_PREV(curr, link)) { curr = ISC_LIST_PREV(curr, link)) {
if (curr->type == type) { if (curr->type == type && curr->covers == covers) {
if (rdataset != NULL) if (rdataset != NULL)
*rdataset = curr; *rdataset = curr;
return (DNS_R_SUCCESS); return (DNS_R_SUCCESS);
@@ -880,7 +881,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
/* /*
* Can't ask the same question twice. * Can't ask the same question twice.
*/ */
result = findtype(NULL, name, rdtype); result = findtype(NULL, name, rdtype, 0);
if (result == DNS_R_SUCCESS) if (result == DNS_R_SUCCESS)
return (DNS_R_FORMERR); return (DNS_R_FORMERR);
@@ -927,7 +928,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset;
dns_rdatalist_t *rdatalist; dns_rdatalist_t *rdatalist;
dns_result_t result; dns_result_t result;
dns_rdatatype_t rdtype; dns_rdatatype_t rdtype, covers;
dns_rdataclass_t rdclass; dns_rdataclass_t rdclass;
dns_rdata_t *rdata; dns_rdata_t *rdata;
dns_ttl_t ttl; dns_ttl_t ttl;
@@ -1038,42 +1039,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
return (DNS_R_FORMERR); return (DNS_R_FORMERR);
#endif #endif
/*
* Search name for the particular type and class.
* Skip this stage if in update mode, or this is a TSIG.
*/
if (preserve_order || msg->opcode == dns_opcode_update
|| rdtype == dns_rdatatype_tsig)
result = DNS_R_NOTFOUND;
else
result = findtype(&rdataset, name, rdtype);
/*
* If we found an rdataset that matches, we need to
* append this rdata to that set. If we did not, we need
* to create a new rdatalist, store the important bits there,
* convert it to an rdataset, and link the latter to the name.
* Yuck.
*/
if (result == DNS_R_NOTFOUND) {
rdataset = newrdataset(msg);
if (rdataset == NULL)
return (DNS_R_NOMEMORY);
rdatalist = newrdatalist(msg);
if (rdatalist == NULL)
return (DNS_R_NOMEMORY);
rdatalist->type = rdtype;
rdatalist->rdclass = rdclass;
rdatalist->ttl = ttl;
ISC_LIST_INIT(rdatalist->rdata);
dns_rdataset_init(rdataset);
dns_rdatalist_tordataset(rdatalist, rdataset);
ISC_LIST_APPEND(name->list, rdataset, link);
}
/* /*
* Read the rdata from the wire format. Interpret the * Read the rdata from the wire format. Interpret the
* rdata according to its actual class, even if it had a * rdata according to its actual class, even if it had a
@@ -1093,6 +1058,51 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
if (result != DNS_R_SUCCESS) if (result != DNS_R_SUCCESS)
return (result); return (result);
rdata->rdclass = rdclass; rdata->rdclass = rdclass;
if (rdtype == dns_rdatatype_sig && rdata->length > 0)
covers = dns_rdata_covers(rdata);
else
covers = 0;
/*
* Search name for the particular type and class.
* Skip this stage if in update mode, or this is a TSIG.
*/
if (preserve_order || msg->opcode == dns_opcode_update
|| rdtype == dns_rdatatype_tsig)
result = DNS_R_NOTFOUND;
else
result = findtype(&rdataset, name, rdtype, covers);
/*
* If we found an rdataset that matches, we need to
* append this rdata to that set. If we did not, we need
* to create a new rdatalist, store the important bits there,
* convert it to an rdataset, and link the latter to the name.
* Yuck.
*/
if (result == DNS_R_NOTFOUND) {
rdataset = newrdataset(msg);
if (rdataset == NULL)
return (DNS_R_NOMEMORY);
rdatalist = newrdatalist(msg);
if (rdatalist == NULL)
return (DNS_R_NOMEMORY);
rdatalist->type = rdtype;
rdatalist->covers = covers;
rdatalist->rdclass = rdclass;
rdatalist->ttl = ttl;
ISC_LIST_INIT(rdatalist->rdata);
dns_rdataset_init(rdataset);
dns_rdatalist_tordataset(rdatalist, rdataset);
ISC_LIST_APPEND(name->list, rdataset, link);
}
/*
* XXXRTH Normalize TTLs.
*/
/* /*
* XXXMLG Perform a totally ugly hack here to pull * XXXMLG Perform a totally ugly hack here to pull
@@ -1485,7 +1495,8 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
dns_result_t dns_result_t
dns_message_findname(dns_message_t *msg, dns_section_t section, dns_message_findname(dns_message_t *msg, dns_section_t section,
dns_name_t *target, dns_rdatatype_t type, dns_name_t *target, dns_rdatatype_t type,
dns_name_t **name, dns_rdataset_t **rdataset) dns_rdatatype_t covers, dns_name_t **name,
dns_rdataset_t **rdataset)
{ {
dns_name_t *foundname; dns_name_t *foundname;
dns_result_t result; dns_result_t result;
@@ -1526,7 +1537,7 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
if (type == dns_rdatatype_any) if (type == dns_rdatatype_any)
return (DNS_R_SUCCESS); return (DNS_R_SUCCESS);
result = findtype(rdataset, foundname, type); result = findtype(rdataset, foundname, type, covers);
if (result == DNS_R_NOTFOUND) if (result == DNS_R_NOTFOUND)
return (DNS_R_NXRDATASET); return (DNS_R_NXRDATASET);

View File

@@ -68,13 +68,26 @@ typedef isc_uint64_t rbtdb_serial_t;
typedef isc_uint32_t rbtdb_serial_t; typedef isc_uint32_t rbtdb_serial_t;
#endif #endif
typedef isc_uint32_t rbtdb_rdatatype_t;
#define RBTDB_RDATATYPE_BASE(type) ((type) & 0xFFFF)
#define RBTDB_RDATATYPE_EXT(type) ((type) >> 16)
#define RBTDB_RDATATYPE_VALUE(b, e) (((e) << 16) | (b))
#define RBTDB_RDATATYPE_SIGNXT \
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_nxt)
#define RBTDB_RDATATYPE_SIGNS \
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_ns)
#define RBTDB_RDATATYPE_SIGCNAME \
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_cname)
typedef struct rdatasetheader { typedef struct rdatasetheader {
/* /*
* Locked by the owning node's lock. * Locked by the owning node's lock.
*/ */
rbtdb_serial_t serial; rbtdb_serial_t serial;
dns_ttl_t ttl; dns_ttl_t ttl;
dns_rdatatype_t type; rbtdb_rdatatype_t type;
isc_uint16_t attributes; isc_uint16_t attributes;
dns_trust_t trust; dns_trust_t trust;
/* /*
@@ -1083,11 +1096,15 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
* Caller must be holding the node lock. * Caller must be holding the node lock.
*/ */
if (rdataset == NULL)
return;
new_reference(rbtdb, node); new_reference(rbtdb, node);
rdataset->methods = &rdataset_methods; rdataset->methods = &rdataset_methods;
rdataset->rdclass = rbtdb->common.rdclass; rdataset->rdclass = rbtdb->common.rdclass;
rdataset->type = header->type; rdataset->type = RBTDB_RDATATYPE_BASE(header->type);
rdataset->covers = RBTDB_RDATATYPE_EXT(header->type);
rdataset->ttl = header->ttl - now; rdataset->ttl = header->ttl - now;
rdataset->private1 = rbtdb; rdataset->private1 = rbtdb;
rdataset->private2 = node; rdataset->private2 = node;
@@ -1116,7 +1133,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
{ {
dns_result_t result; dns_result_t result;
dns_name_t *zcname; dns_name_t *zcname;
dns_rdatatype_t type; rbtdb_rdatatype_t type;
dns_rbtnode_t *node; dns_rbtnode_t *node;
/* /*
@@ -1161,7 +1178,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
} }
static inline isc_boolean_t static inline isc_boolean_t
valid_glue(rbtdb_search_t *search, dns_name_t *name, dns_rdatatype_t type, valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type,
dns_rbtnode_t *node) dns_rbtnode_t *node)
{ {
unsigned char *raw; unsigned char *raw;
@@ -1355,10 +1372,11 @@ find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep) {
static inline isc_result_t static inline isc_result_t
find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep, find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset) dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset)
{ {
dns_rbtnode_t *node; dns_rbtnode_t *node;
rdatasetheader_t *header, *header_next; rdatasetheader_t *header, *header_next, *found, *foundsig;
isc_boolean_t empty_node; isc_boolean_t empty_node;
isc_result_t result; isc_result_t result;
dns_fixedname_t fname, forigin; dns_fixedname_t fname, forigin;
@@ -1375,14 +1393,15 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
found = NULL;
foundsig = NULL;
empty_node = ISC_TRUE; empty_node = ISC_TRUE;
for (header = node->data; for (header = node->data;
header != NULL; header != NULL;
header = header_next) { header = header_next) {
header_next = header->next; header_next = header->next;
/* /*
* Look for an active, extant rdataset with a * Look for an active, extant NXT or SIG NXT.
* NXT record.
*/ */
do { do {
if (header->serial <= search->serial && if (header->serial <= search->serial &&
@@ -1404,12 +1423,20 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
* active rdataset at this node. * active rdataset at this node.
*/ */
empty_node = ISC_FALSE; empty_node = ISC_FALSE;
if (header->type == dns_rdatatype_nxt) if (header->type == dns_rdatatype_nxt) {
break; found = header;
if (foundsig != NULL)
break;
} else if (header->type ==
RBTDB_RDATATYPE_SIGNXT) {
foundsig = header;
if (found != NULL)
break;
}
} }
} }
if (!empty_node) { if (!empty_node) {
if (header != NULL) { if (found != NULL && foundsig != NULL) {
/* /*
* We've found the right NXT record. * We've found the right NXT record.
* *
@@ -1433,13 +1460,17 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
*nodep = node; *nodep = node;
} }
bind_rdataset(search->rbtdb, node, bind_rdataset(search->rbtdb, node,
header, search->now, found, search->now,
rdataset); rdataset);
bind_rdataset(search->rbtdb, node,
foundsig, search->now,
sigrdataset);
} }
} else { } else {
/* /*
* We found an active node without a NXT * We found an active node, but either the
* record. This shouldn't happen. * NXT or the SIG NXT is missing. This
* shouldn't happen.
*/ */
result = DNS_R_BADDB; result = DNS_R_BADDB;
} }
@@ -1493,7 +1524,7 @@ static dns_result_t
zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset) dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{ {
dns_rbtnode_t *node = NULL; dns_rbtnode_t *node = NULL;
dns_result_t result; dns_result_t result;
@@ -1505,6 +1536,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
isc_boolean_t wild; isc_boolean_t wild;
isc_boolean_t empty_node; isc_boolean_t empty_node;
rdatasetheader_t *header, *header_next, *found, *nxtheader; rdatasetheader_t *header, *header_next, *found, *nxtheader;
rdatasetheader_t *foundsig, *cnamesig, *nxtsig;
rbtdb_rdatatype_t sigtype;
search.rbtdb = (dns_rbtdb_t *)db; search.rbtdb = (dns_rbtdb_t *)db;
@@ -1586,7 +1619,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*/ */
if (search.rbtdb->secure) { if (search.rbtdb->secure) {
result = find_closest_nxt(&search, nodep, foundname, result = find_closest_nxt(&search, nodep, foundname,
rdataset); rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
result = DNS_R_NXDOMAIN; result = DNS_R_NXDOMAIN;
} else } else
@@ -1622,11 +1655,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* *
* We don't check for SIG, because we don't store SIG records * We don't check for SIG, because we don't store SIG records
* directly. * directly.
*
* XXX This should be a general purpose subroutine in the rdata
* module.
*
* XXX This 'if' could be an 'else if' of the 'if' above.
*/ */
if (type == dns_rdatatype_key || type == dns_rdatatype_nxt) if (type == dns_rdatatype_key || type == dns_rdatatype_nxt)
cname_ok = ISC_FALSE; cname_ok = ISC_FALSE;
@@ -1638,7 +1666,11 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
LOCK(&(search.rbtdb->node_locks[node->locknum].lock)); LOCK(&(search.rbtdb->node_locks[node->locknum].lock));
found = NULL; found = NULL;
foundsig = NULL;
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, type);
nxtheader = NULL; nxtheader = NULL;
nxtsig = NULL;
cnamesig = NULL;
empty_node = ISC_TRUE; empty_node = ISC_TRUE;
for (header = node->data; header != NULL; header = header_next) { for (header = node->data; header != NULL; header = header_next) {
header_next = header->next; header_next = header->next;
@@ -1694,19 +1726,53 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
found = NULL; found = NULL;
break; break;
} }
if (found != NULL) if (found != NULL && foundsig != NULL)
break; break;
} }
/* /*
* If we found a type we were looking for, we're done. * If we found a type we were looking for,
* remember it.
*/ */
if (header->type == type || if (header->type == type ||
type == dns_rdatatype_any || type == dns_rdatatype_any ||
(cname_ok && (header->type == dns_rdatatype_cname &&
header->type == dns_rdatatype_cname)) { cname_ok)) {
/*
* We've found the answer!
*/
found = header; found = header;
if (!maybe_zonecut) if (header->type == dns_rdatatype_cname &&
cname_ok) {
/*
* We may be finding a CNAME instead
* of the desired type.
*
* If we've already got the CNAME SIG,
* use it, otherwise change sigtype
* so that we find it.
*/
if (cnamesig != NULL)
foundsig = cnamesig;
else
sigtype =
RBTDB_RDATATYPE_SIGCNAME;
}
/*
* If we've got all we need, end the search.
*/
if (!maybe_zonecut && foundsig != NULL)
break;
} else if (header->type == sigtype) {
/*
* We've found the SIG rdataset for our
* target type. Remember it.
*/
foundsig = header;
/*
* If we've got all we need, end the search.
*/
if (!maybe_zonecut && found != NULL)
break; break;
} else if (header->type == dns_rdatatype_nxt) { } else if (header->type == dns_rdatatype_nxt) {
/* /*
@@ -1715,6 +1781,19 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* we might need it later. * we might need it later.
*/ */
nxtheader = header; nxtheader = header;
} else if (header->type == RBTDB_RDATATYPE_SIGNXT) {
/*
* If we need the NXT rdataset, we'll also
* need its signature.
*/
nxtsig = header;
} else if (cname_ok &&
header->type == RBTDB_RDATATYPE_SIGCNAME) {
/*
* If we get a CNAME match, we'll also need
* its signature.
*/
cnamesig = header;
} }
} }
} }
@@ -1753,10 +1832,11 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* The desired type doesn't exist. * The desired type doesn't exist.
*/ */
result = DNS_R_NXRDATASET; result = DNS_R_NXRDATASET;
if (search.rbtdb->secure && nxtheader == NULL) { if (search.rbtdb->secure &&
(nxtheader == NULL || nxtsig == NULL)) {
/* /*
* The zone is secure but there's no NXT * The zone is secure but there's no NXT,
* rdataset! * or the NXT has no signature!
*/ */
result = DNS_R_BADDB; result = DNS_R_BADDB;
goto node_exit; goto node_exit;
@@ -1768,6 +1848,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
if (search.rbtdb->secure) { if (search.rbtdb->secure) {
bind_rdataset(search.rbtdb, node, nxtheader, bind_rdataset(search.rbtdb, node, nxtheader,
0, rdataset); 0, rdataset);
bind_rdataset(search.rbtdb, node, nxtsig,
0, sigrdataset);
} }
} }
goto node_exit; goto node_exit;
@@ -1832,8 +1914,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*nodep = node; *nodep = node;
} }
if (rdataset != NULL && type != dns_rdatatype_any) if (type != dns_rdatatype_any) {
bind_rdataset(search.rbtdb, node, found, 0, rdataset); bind_rdataset(search.rbtdb, node, found, 0, rdataset);
if (foundsig != NULL)
bind_rdataset(search.rbtdb, node, foundsig, 0,
sigrdataset);
}
node_exit: node_exit:
UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));
@@ -1882,7 +1968,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
LOCK(&(search->rbtdb->node_locks[node->locknum].lock)); LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
/* /*
* Look for DNAME rdataset. * Look for a DNAME rdataset.
*/ */
header_prev = NULL; header_prev = NULL;
for (header = node->data; header != NULL; header = header_next) { for (header = node->data; header != NULL; header = header_next) {
@@ -1938,11 +2024,13 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
static inline dns_result_t static inline dns_result_t
find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep, find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset) dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset)
{ {
unsigned int i; unsigned int i;
dns_rbtnode_t *node, *level_node; dns_rbtnode_t *node, *level_node;
rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *header, *header_prev, *header_next;
rdatasetheader_t *found, *foundsig;
dns_result_t result = DNS_R_NOTFOUND; dns_result_t result = DNS_R_NOTFOUND;
dns_name_t name; dns_name_t name;
dns_rbtdb_t *rbtdb; dns_rbtdb_t *rbtdb;
@@ -1960,8 +2048,10 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
LOCK(&(rbtdb->node_locks[node->locknum].lock)); LOCK(&(rbtdb->node_locks[node->locknum].lock));
/* /*
* Look for NS rdataset. * Look for NS and SIG NS rdatasets.
*/ */
found = NULL;
foundsig = NULL;
header_prev = NULL; header_prev = NULL;
for (header = node->data; for (header = node->data;
header != NULL; header != NULL;
@@ -1990,15 +2080,28 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
node->dirty = 1; node->dirty = 1;
header_prev = header; header_prev = header;
} }
} else if (header->type == dns_rdatatype_ns && } else if ((header->attributes &
(header->attributes & RDATASET_ATTR_NONEXISTENT) == 0) {
RDATASET_ATTR_NONEXISTENT) == 0) /*
break; * We've found an extant rdataset. See if
else * we're interested in it.
*/
if (header->type == dns_rdatatype_ns) {
found = header;
if (foundsig != NULL)
break;
} else if (header->type ==
RBTDB_RDATATYPE_SIGNS) {
foundsig = header;
if (found != NULL)
break;
}
header_prev = header;
} else
header_prev = header; header_prev = header;
} }
if (header != NULL) { if (found != NULL) {
/* /*
* If we have to set foundname, we do it before * If we have to set foundname, we do it before
* anything else. If we were to set foundname after * anything else. If we were to set foundname after
@@ -2034,15 +2137,17 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
new_reference(search->rbtdb, node); new_reference(search->rbtdb, node);
*nodep = node; *nodep = node;
} }
if (rdataset != NULL) bind_rdataset(search->rbtdb, node, found, search->now,
bind_rdataset(search->rbtdb, node, header, rdataset);
search->now, rdataset); if (foundsig != NULL)
bind_rdataset(search->rbtdb, node, foundsig,
search->now, sigrdataset);
} }
node_exit: node_exit:
UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock)); UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock));
if (header != NULL) if (found != NULL)
break; break;
} }
@@ -2053,7 +2158,7 @@ static dns_result_t
cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname, dns_dbnode_t **nodep, dns_name_t *foundname,
dns_rdataset_t *rdataset) dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{ {
dns_rbtnode_t *node = NULL; dns_rbtnode_t *node = NULL;
dns_result_t result; dns_result_t result;
@@ -2061,7 +2166,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
isc_boolean_t cname_ok = ISC_TRUE; isc_boolean_t cname_ok = ISC_TRUE;
isc_boolean_t empty_node; isc_boolean_t empty_node;
rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *header, *header_prev, *header_next;
rdatasetheader_t *found, *nsheader, *nxtheader; rdatasetheader_t *found, *nsheader;
rdatasetheader_t *foundsig, *nssig, *cnamesig;
rbtdb_rdatatype_t sigtype;
/* /*
* XXXRTH Currently this code has no support for negative caching. * XXXRTH Currently this code has no support for negative caching.
@@ -2110,7 +2217,8 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
} else { } else {
find_ns: find_ns:
result = find_deepest_zonecut(&search, nodep, result = find_deepest_zonecut(&search, nodep,
foundname, rdataset); foundname, rdataset,
sigrdataset);
goto tree_exit; goto tree_exit;
} }
} else if (result != DNS_R_SUCCESS) } else if (result != DNS_R_SUCCESS)
@@ -2120,14 +2228,10 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* Certain DNSSEC types are not subject to CNAME matching * Certain DNSSEC types are not subject to CNAME matching
* (RFC 2535, section 2.3.5). * (RFC 2535, section 2.3.5).
* *
* XXX This should be a general purpose subroutine in the rdata * We don't check for SIG, because we don't store SIG records
* module. * directly.
*
* XXX This 'if' could be an 'else if' of the 'if' above.
*/ */
if (type == dns_rdatatype_key || if (type == dns_rdatatype_key || type == dns_rdatatype_nxt)
type == dns_rdatatype_sig ||
type == dns_rdatatype_nxt)
cname_ok = ISC_FALSE; cname_ok = ISC_FALSE;
/* /*
@@ -2137,8 +2241,11 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
LOCK(&(search.rbtdb->node_locks[node->locknum].lock)); LOCK(&(search.rbtdb->node_locks[node->locknum].lock));
found = NULL; found = NULL;
foundsig = NULL;
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, type);
nsheader = NULL; nsheader = NULL;
nxtheader = NULL; nssig = NULL;
cnamesig = NULL;
empty_node = ISC_TRUE; empty_node = ISC_TRUE;
header_prev = NULL; header_prev = NULL;
for (header = node->data; header != NULL; header = header_next) { for (header = node->data; header != NULL; header = header_next) {
@@ -2172,13 +2279,33 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
empty_node = ISC_FALSE; empty_node = ISC_FALSE;
/* /*
* If we found a type we were looking for, we're done. * If we found a type we were looking for, remember
* it.
*/ */
if (header->type == type || if (header->type == type ||
type == dns_rdatatype_any || type == dns_rdatatype_any ||
(cname_ok && header->type == (cname_ok && header->type ==
dns_rdatatype_cname)) { dns_rdatatype_cname)) {
/*
* We've found the answer.
*/
found = header; found = header;
if (header->type == dns_rdatatype_cname &&
cname_ok &&
cnamesig != NULL) {
/*
* We may be finding a CNAME instead
* of the desired type. If so, we
* need to return the CNAME's SIG.
*/
foundsig = cnamesig;
}
} else if (header->type == sigtype) {
/*
* We've found the SIG rdataset for our
* target type. Remember it.
*/
foundsig = header;
} else if (header->type == dns_rdatatype_ns) { } else if (header->type == dns_rdatatype_ns) {
/* /*
* Remember a NS rdataset even if we're * Remember a NS rdataset even if we're
@@ -2186,13 +2313,19 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* we might need it later. * we might need it later.
*/ */
nsheader = header; nsheader = header;
} else if (header->type == dns_rdatatype_nxt) { } else if (header->type == RBTDB_RDATATYPE_SIGNS) {
/* /*
* Remember a NXT rdataset even if we're * If we need the NS rdataset, we'll also
* not specifically looking for it, because * need its signature.
* we might need it later.
*/ */
nxtheader = header; nssig = header;
} else if (cname_ok &&
header->type == RBTDB_RDATATYPE_SIGCNAME) {
/*
* If we get a CNAME match, we'll also need
* its signature.
*/
cnamesig = header;
} }
header_prev = header; header_prev = header;
} else } else
@@ -2213,13 +2346,6 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* If we didn't find what we were looking for... * If we didn't find what we were looking for...
*/ */
if (found == NULL) { if (found == NULL) {
/*
* XXXDNSSEC If we found an NXT record for this name, we
* can tell whether the desired type exists or not. We don't
* yet try to use the NXT that way, but this is the place to
* do it.
*/
/* /*
* If there is an NS rdataset at this node, then this is the * If there is an NS rdataset at this node, then this is the
* deepest zone cut. * deepest zone cut.
@@ -2229,6 +2355,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*nodep = node; *nodep = node;
bind_rdataset(search.rbtdb, node, nsheader, search.now, bind_rdataset(search.rbtdb, node, nsheader, search.now,
rdataset); rdataset);
if (nssig != NULL)
bind_rdataset(search.rbtdb, node, nssig,
search.now, sigrdataset);
result = DNS_R_DELEGATION; result = DNS_R_DELEGATION;
goto node_exit; goto node_exit;
} }
@@ -2265,9 +2394,13 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
result = DNS_R_SUCCESS; result = DNS_R_SUCCESS;
} }
if (rdataset != NULL && type != dns_rdatatype_any) if (type != dns_rdatatype_any) {
bind_rdataset(search.rbtdb, node, found, search.now, bind_rdataset(search.rbtdb, node, found, search.now,
rdataset); rdataset);
if (foundsig != NULL)
bind_rdataset(search.rbtdb, node, foundsig, search.now,
sigrdataset);
}
node_exit: node_exit:
UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock)); UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));
@@ -2428,8 +2561,8 @@ createiterator(dns_db_t *db, isc_boolean_t relative_names,
static dns_result_t static dns_result_t
zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now, dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdataset_t *rdataset) isc_stdtime_t now, dns_rdataset_t *rdataset)
{ {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
@@ -2437,6 +2570,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
rbtdb_serial_t serial; rbtdb_serial_t serial;
rbtdb_version_t *rbtversion = version; rbtdb_version_t *rbtversion = version;
isc_boolean_t close_version = ISC_FALSE; isc_boolean_t close_version = ISC_FALSE;
rbtdb_rdatatype_t matchtype;
REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(type != dns_rdatatype_any); REQUIRE(type != dns_rdatatype_any);
@@ -2449,8 +2583,9 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); LOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
for (header = rbtnode->data; header != NULL; header = header->next) { for (header = rbtnode->data; header != NULL; header = header->next) {
if (header->type == type) { if (header->type == matchtype) {
do { do {
if (header->serial <= serial && if (header->serial <= serial &&
!IGNORE(header)) { !IGNORE(header)) {
@@ -2484,12 +2619,13 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
static dns_result_t static dns_result_t
cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now, dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdataset_t *rdataset) isc_stdtime_t now, dns_rdataset_t *rdataset)
{ {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
rdatasetheader_t *header, *header_next, *found; rdatasetheader_t *header, *header_next, *found;
rbtdb_rdatatype_t matchtype;
REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(type != dns_rdatatype_any); REQUIRE(type != dns_rdatatype_any);
@@ -2507,6 +2643,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); LOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
found = NULL; found = NULL;
matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
for (header = rbtnode->data; header != NULL; header = header_next) { for (header = rbtnode->data; header != NULL; header = header_next) {
header_next = header->next; header_next = header->next;
if (header->ttl <= now) { if (header->ttl <= now) {
@@ -2518,7 +2655,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
*/ */
header->attributes |= RDATASET_ATTR_STALE; header->attributes |= RDATASET_ATTR_STALE;
rbtnode->dirty = 1; rbtnode->dirty = 1;
} else if (header->type == type && } else if (header->type == matchtype &&
(header->attributes & RDATASET_ATTR_NONEXISTENT) == (header->attributes & RDATASET_ATTR_NONEXISTENT) ==
0) { 0) {
found = header; found = header;
@@ -2793,7 +2930,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
static inline isc_boolean_t static inline isc_boolean_t
delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
dns_rdatatype_t type) rbtdb_rdatatype_t type)
{ {
if ((rbtdb->common.attributes & DNS_DBATTR_CACHE) != 0 && if ((rbtdb->common.attributes & DNS_DBATTR_CACHE) != 0 &&
type == dns_rdatatype_dname) type == dns_rdatatype_dname)
@@ -2833,7 +2970,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
newheader = (rdatasetheader_t *)region.base; newheader = (rdatasetheader_t *)region.base;
newheader->ttl = rdataset->ttl + now; newheader->ttl = rdataset->ttl + now;
newheader->type = rdataset->type; newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
newheader->attributes = 0; newheader->attributes = 0;
if (rbtversion != NULL) { if (rbtversion != NULL) {
newheader->serial = rbtversion->serial; newheader->serial = rbtversion->serial;
@@ -2893,7 +3031,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
return (result); return (result);
newheader = (rdatasetheader_t *)region.base; newheader = (rdatasetheader_t *)region.base;
newheader->ttl = 0; newheader->ttl = 0;
newheader->type = rdataset->type; newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
newheader->attributes = 0; newheader->attributes = 0;
newheader->serial = rbtversion->serial; newheader->serial = rbtversion->serial;
newheader->trust = 0; newheader->trust = 0;
@@ -3007,14 +3146,14 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(VALID_RBTDB(rbtdb));
if (type == dns_rdatatype_any) if (type == dns_rdatatype_any || type == dns_rdatatype_sig)
return (DNS_R_NOTIMPLEMENTED); return (DNS_R_NOTIMPLEMENTED);
newheader = isc_mem_get(rbtdb->common.mctx, sizeof *newheader); newheader = isc_mem_get(rbtdb->common.mctx, sizeof *newheader);
if (newheader == NULL) if (newheader == NULL)
return (DNS_R_NOMEMORY); return (DNS_R_NOMEMORY);
newheader->ttl = 0; newheader->ttl = 0;
newheader->type = type; newheader->type = RBTDB_RDATATYPE_VALUE(type, 0);
newheader->attributes = RDATASET_ATTR_NONEXISTENT; newheader->attributes = RDATASET_ATTR_NONEXISTENT;
newheader->trust = 0; newheader->trust = 0;
if (rbtversion != NULL) if (rbtversion != NULL)
@@ -3092,7 +3231,8 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
return (result); return (result);
newheader = (rdatasetheader_t *)region.base; newheader = (rdatasetheader_t *)region.base;
newheader->ttl = rdataset->ttl + loadctx->now; /* XXX overflow check */ newheader->ttl = rdataset->ttl + loadctx->now; /* XXX overflow check */
newheader->type = rdataset->type; newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
newheader->attributes = 0; newheader->attributes = 0;
newheader->trust = rdataset->trust; newheader->trust = rdataset->trust;
newheader->serial = 1; newheader->serial = 1;
@@ -3595,7 +3735,7 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
rdatasetheader_t *header, *top_next; rdatasetheader_t *header, *top_next;
rbtdb_serial_t serial; rbtdb_serial_t serial;
isc_stdtime_t now; isc_stdtime_t now;
dns_rdatatype_t type; rbtdb_rdatatype_t type;
header = rbtiterator->current; header = rbtiterator->current;
if (header == NULL) if (header == NULL)

View File

@@ -34,7 +34,7 @@ static dns_rdatasetmethods_t methods = {
first, first,
next, next,
current, current,
clone clone,
}; };
dns_result_t dns_result_t
@@ -52,6 +52,7 @@ dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
rdataset->methods = &methods; rdataset->methods = &methods;
rdataset->rdclass = rdatalist->rdclass; rdataset->rdclass = rdatalist->rdclass;
rdataset->type = rdatalist->type; rdataset->type = rdatalist->type;
rdataset->covers = rdatalist->covers;
rdataset->ttl = rdatalist->ttl; rdataset->ttl = rdatalist->ttl;
rdataset->private1 = rdatalist; rdataset->private1 = rdatalist;
rdataset->private2 = NULL; rdataset->private2 = NULL;

View File

@@ -44,6 +44,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) {
rdataset->type = 0; rdataset->type = 0;
rdataset->ttl = 0; rdataset->ttl = 0;
rdataset->trust = 0; rdataset->trust = 0;
rdataset->covers = 0;
rdataset->attributes = 0; rdataset->attributes = 0;
rdataset->private1 = NULL; rdataset->private1 = NULL;
rdataset->private2 = NULL; rdataset->private2 = NULL;
@@ -68,6 +69,7 @@ dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
rdataset->type = 0; rdataset->type = 0;
rdataset->ttl = 0; rdataset->ttl = 0;
rdataset->trust = 0; rdataset->trust = 0;
rdataset->covers = 0;
rdataset->attributes = 0; rdataset->attributes = 0;
rdataset->private1 = NULL; rdataset->private1 = NULL;
rdataset->private2 = NULL; rdataset->private2 = NULL;
@@ -93,6 +95,7 @@ dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
rdataset->type = 0; rdataset->type = 0;
rdataset->ttl = 0; rdataset->ttl = 0;
rdataset->trust = 0; rdataset->trust = 0;
rdataset->covers = 0;
rdataset->attributes = 0; rdataset->attributes = 0;
rdataset->private1 = NULL; rdataset->private1 = NULL;
rdataset->private2 = NULL; rdataset->private2 = NULL;
@@ -146,7 +149,7 @@ static dns_rdatasetmethods_t question_methods = {
question_cursor, question_cursor,
question_cursor, question_cursor,
question_current, question_current,
question_clone question_clone,
}; };
void void