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;
result = dns_db_find(db, name, version, type, client->query.dboptions,
client->requesttime, &node, fname, rdataset);
client->requesttime, &node, fname, rdataset,
NULL);
switch (result) {
case DNS_R_SUCCESS:
case DNS_R_GLUE:
@@ -409,7 +410,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
section++) {
mname = NULL;
result = dns_message_findname(client->message, section,
name, type, &mname, NULL);
name, type, 0, &mname, NULL);
if (result == ISC_R_SUCCESS) {
/*
* 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
query_addrrset(ns_client_t *client, dns_name_t **namep,
dns_rdataset_t **rdatasetp, isc_dynbuffer_t *dbuf,
dns_section_t section)
dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
isc_dynbuffer_t *dbuf, dns_section_t section)
{
dns_name_t *name, *mname;
dns_rdataset_t *rdataset, *mrdataset;
dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;
isc_result_t result;
name = *namep;
rdataset = *rdatasetp;
if (sigrdatasetp != NULL)
sigrdataset = *sigrdatasetp;
else
sigrdataset = NULL;
mname = NULL;
mrdataset = NULL;
result = dns_message_findname(client->message, section,
name, rdataset->type,
name, rdataset->type, rdataset->covers,
&mname, &mrdataset);
if (result == ISC_R_SUCCESS) {
/*
@@ -540,8 +545,20 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
} else
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);
*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
@@ -550,7 +567,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
dns_dbnode_t *node;
isc_result_t result, eresult;
dns_fixedname_t foundname;
dns_rdataset_t *rdataset;
dns_rdataset_t *rdataset, *sigrdataset;
/*
* Initialization.
@@ -571,7 +588,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
dns_name_init(name, NULL);
dns_name_clone(dns_db_origin(db), name);
rdataset = query_newrdataset(client);
if (rdataset == NULL) {
sigrdataset = query_newrdataset(client);
if (rdataset == NULL || sigrdataset == NULL) {
eresult = DNS_R_SERVFAIL;
goto cleanup;
}
@@ -580,7 +598,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
* Find the SOA.
*/
result = dns_db_find(db, name, NULL, dns_rdatatype_soa, 0, 0, &node,
fname, rdataset);
fname, rdataset, sigrdataset);
if (result != ISC_R_SUCCESS) {
/*
* 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.
*/
eresult = DNS_R_SERVFAIL;
} else
query_addrrset(client, &name, &rdataset, NULL,
} else {
query_addrrset(client, &name, &rdataset, &sigrdataset, NULL,
DNS_SECTION_AUTHORITY);
}
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->methods != NULL)
dns_rdataset_disassociate(rdataset);
@@ -611,13 +635,10 @@ static inline isc_result_t
query_checktype(dns_rdatatype_t type) {
/*
* XXXRTH SIG is here only temporarily.
* OPT still needs to be added.
* XXXRTH OPT still needs to be added.
* Should get help with this from rdata.c
*/
switch (type) {
case dns_rdatatype_sig:
return (DNS_R_NOTIMP);
case dns_rdatatype_tkey:
return (DNS_R_NOTIMP);
case dns_rdatatype_tsig:
@@ -649,6 +670,7 @@ query_find(ns_client_t *client) {
dns_rdatatype_t qtype, type;
dns_name_t *fname, *tname, *prefix;
dns_rdataset_t *rdataset, *qrdataset, *trdataset;
dns_rdataset_t *sigrdataset;
dns_rdata_t rdata;
dns_rdatasetiter_t *rdsiter;
isc_boolean_t use_cache, recursion_ok, want_restart;
@@ -676,6 +698,7 @@ query_find(ns_client_t *client) {
recursion_ok = ISC_FALSE;
fname = NULL;
rdataset = NULL;
sigrdataset = NULL;
node = NULL;
db = NULL;
version = NULL;
@@ -778,6 +801,12 @@ query_find(ns_client_t *client) {
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...
*/
@@ -788,7 +817,8 @@ query_find(ns_client_t *client) {
}
fname = query_newname(client, dbuf, &b);
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);
goto cleanup;
}
@@ -800,7 +830,8 @@ query_find(ns_client_t *client) {
* Now look for an answer in the database.
*/
result = dns_db_find(db, client->query.qname, version, type, 0,
client->requesttime, &node, fname, rdataset);
client->requesttime, &node, fname, rdataset,
sigrdataset);
switch (result) {
case DNS_R_SUCCESS:
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
* answer.
*/
query_addrrset(client, &fname, &rdataset, dbuf,
query_addrrset(client, &fname, &rdataset,
&sigrdataset, dbuf,
DNS_SECTION_AUTHORITY);
} else {
/*
@@ -878,8 +910,8 @@ query_find(ns_client_t *client) {
* Add NXT record if we found one.
*/
if (dns_rdataset_isassociated(rdataset))
query_addrrset(client, &tname, &rdataset, NULL,
DNS_SECTION_AUTHORITY);
query_addrrset(client, &tname, &rdataset, &sigrdataset,
NULL, DNS_SECTION_AUTHORITY);
goto cleanup;
case DNS_R_NXDOMAIN:
if (restarts > 0) {
@@ -922,8 +954,8 @@ query_find(ns_client_t *client) {
* Add NXT record if we found one.
*/
if (dns_rdataset_isassociated(rdataset))
query_addrrset(client, &tname, &rdataset, NULL,
DNS_SECTION_AUTHORITY);
query_addrrset(client, &tname, &rdataset, &sigrdataset,
NULL, DNS_SECTION_AUTHORITY);
/*
* Set message rcode.
*/
@@ -942,7 +974,7 @@ query_find(ns_client_t *client) {
/*
* Add the CNAME to the answer section.
*/
query_addrrset(client, &fname, &rdataset, dbuf,
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER);
/*
* 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.
*/
query_addrrset(client, &fname, &rdataset, dbuf,
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER);
/*
* 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_NOSPACE) {
/*
* draft-ietf-dnsind-dname-03.txt, section
* 4.1, subsection 3c says we should
* return YXDOMAIN if the constructed
* RFC 2672, section 4.1, subsection 3c says
* we should return YXDOMAIN if the constructed
* name would be too long.
*/
client->message->rcode = dns_rcode_yxdomain;
@@ -1058,7 +1089,7 @@ query_find(ns_client_t *client) {
*/
n = 0;
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) {
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
@@ -1066,34 +1097,72 @@ query_find(ns_client_t *client) {
result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, rdataset);
tname = fname;
query_addrrset(client, &tname, &rdataset, dbuf,
DNS_SECTION_ANSWER);
n++;
if (qtype == dns_rdatatype_any ||
rdataset->type == qtype) {
tname = fname;
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
* it's already in the answer.
* If we added at least one RRset, then we must clear
* 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
* query_keepname() call in query_addrrset() to be
* called once.
* We didn't match any rdatasets.
*/
dbuf = NULL;
result = dns_message_gettemprdataset(client->message,
&rdataset);
if (result == ISC_R_SUCCESS) {
dns_rdataset_init(rdataset);
result = dns_rdatasetiter_next(rdsiter);
if (qtype == dns_rdatatype_sig &&
result == DNS_R_NOMORE) {
/*
* XXXRTH If this is a secure zone and we
* didn't find any SIGs, we should generate
* 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);
if (result != DNS_R_NOMORE) {
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
* we know the answer.
*/
query_addrrset(client, &fname, &rdataset, dbuf,
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER);
/*
* Remember that we've answered this question.
@@ -1123,6 +1192,11 @@ query_find(ns_client_t *client) {
*/
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->methods != NULL)
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',
* (which can be dns_rdatatype_any to match any type), call 'action'
* with the RR and 'action_data' as arguments. If the name
* For each of the RRs specified by 'db', 'ver', 'name', 'type',
* (which can be dns_rdatatype_any to match any type), and 'covers', call
* '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,
* do nothing.
*
@@ -274,6 +274,7 @@ foreach_rr(dns_db_t *db,
dns_dbversion_t *ver,
dns_name_t *name,
dns_rdatatype_t type,
dns_rdatatype_t covers,
rr_func *rr_action,
void *rr_action_data)
{
@@ -294,7 +295,7 @@ foreach_rr(dns_db_t *db,
return (result);
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);
if (result == DNS_R_NOTFOUND) {
result = DNS_R_SUCCESS;
@@ -366,10 +367,11 @@ do { \
*/
static dns_result_t
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;
result = foreach_rr(db, ver, name, type,
result = foreach_rr(db, ver, name, type, covers,
rrset_exists_action, NULL);
RETURN_EXISTENCE_FLAG;
}
@@ -429,10 +431,10 @@ count_rr_action(void *data, rr_t *rr) /*ARGSUSED*/ {
*/
static dns_result_t
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;
return (foreach_rr(db, ver, name, type,
return (foreach_rr(db, ver, name, type, covers,
count_rr_action, countp));
}
@@ -468,6 +470,7 @@ matching_rr_exists(rr_predicate *predicate,
dns_dbversion_t *ver,
dns_name_t *name,
dns_rdatatype_t type,
dns_rdatatype_t covers,
dns_rdata_t *update_rr,
isc_boolean_t *exists)
{
@@ -478,7 +481,7 @@ matching_rr_exists(rr_predicate *predicate,
ctx.ver = ver;
ctx.name = name;
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);
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. */
while (t != NULL && dns_name_equal(&t->name, name)) {
dns_rdatatype_t type;
dns_rdatatype_t type, covers;
dns_rdataset_t rdataset;
dns_diff_t d_rrs; /* Database RRs with
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 */
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
@@ -652,7 +659,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
*/
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, type,
(isc_stdtime_t) 0,
covers, (isc_stdtime_t) 0,
&rdataset);
if (result != DNS_R_SUCCESS) {
dns_db_detachnode(db, &node);
@@ -837,6 +844,7 @@ delete_if(rr_predicate *predicate,
dns_dbversion_t *ver,
dns_name_t *name,
dns_rdatatype_t type,
dns_rdatatype_t covers,
dns_rdata_t *update_rr,
dns_diff_t *diff)
{
@@ -847,7 +855,7 @@ delete_if(rr_predicate *predicate,
ctx.diff = diff;
ctx.name = name;
ctx.update_rr = update_rr;
return (foreach_rr(db, ver, name, type,
return (foreach_rr(db, ver, name, type, covers,
delete_if_action, &ctx));
}
@@ -866,7 +874,8 @@ delete_if(rr_predicate *predicate,
static void
get_current_rr(dns_message_t *msg, dns_section_t section,
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_rdataset_t *rdataset;
@@ -875,6 +884,7 @@ get_current_rr(dns_message_t *msg, dns_section_t section,
rdataset = ISC_LIST_HEAD((*name)->list);
INSIST(rdataset != NULL);
INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
*covers = rdataset->covers;
*ttl = rdataset->ttl;
result = dns_rdataset_first(rdataset);
INSIST(result == DNS_R_SUCCESS);
@@ -991,6 +1001,7 @@ ns_req_update(ns_client_t *client,
unsigned int response_rcode = dns_rcode_noerror;
isc_boolean_t soa_serial_changed = ISC_FALSE;
isc_mem_t *mctx = client->mctx;
dns_rdatatype_t covers;
dns_diff_init(mctx, &diff);
dns_diff_init(mctx, &temp);
@@ -1065,7 +1076,7 @@ ns_req_update(ns_client_t *client,
isc_boolean_t flag;
get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass,
&name, &rdata, &ttl, &update_class);
&name, &rdata, &covers, &ttl, &update_class);
if (ttl != 0)
FAILMSG(DNS_R_FORMERR, "prereq TTL != 0");
@@ -1087,7 +1098,7 @@ ns_req_update(ns_client_t *client,
}
} else {
CHECK(rrset_exists(db, ver, name,
rdata.type, &flag));
rdata.type, covers, &flag));
if (! flag) {
/* RRset does not exist. */
FAILMSG(DNS_R_NXRRSET,
@@ -1108,7 +1119,7 @@ ns_req_update(ns_client_t *client,
}
} else {
CHECK(rrset_exists(db, ver, name,
rdata.type, &flag));
rdata.type, covers, &flag));
if (flag) {
/* RRset exists. */
FAILMSG(DNS_R_YXRRSET,
@@ -1156,7 +1167,7 @@ ns_req_update(ns_client_t *client,
dns_ttl_t ttl;
dns_rdataclass_t update_class;
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))
FAILMSG(DNS_R_NOTZONE,
@@ -1206,7 +1217,7 @@ ns_req_update(ns_client_t *client,
isc_boolean_t flag;
get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
&name, &rdata, &ttl, &update_class);
&name, &rdata, &covers, &ttl, &update_class);
if (update_class == zoneclass) {
if (rdata.type == dns_rdatatype_cname) {
@@ -1221,7 +1232,7 @@ ns_req_update(ns_client_t *client,
}
} else {
CHECK(rrset_exists(db, ver, name,
dns_rdatatype_cname,
dns_rdatatype_cname, 0,
&flag));
if (flag && ! is_dnssec_type(rdata.type)) {
printf("attempt to add non-cname "
@@ -1232,7 +1243,8 @@ ns_req_update(ns_client_t *client,
if (rdata.type == dns_rdatatype_soa) {
isc_boolean_t changed, ok;
CHECK(rrset_exists(db, ver, name,
dns_rdatatype_soa, &flag));
dns_rdatatype_soa, 0,
&flag));
if (! flag) {
printf("attempt to create extra SOA "
"ignored\n");
@@ -1254,11 +1266,13 @@ ns_req_update(ns_client_t *client,
* CNAME, SOA, or WKS exists, remove it first.
*/
CHECK(matching_rr_exists(rr_equal_p, db, ver, name,
rdata.type, &rdata, &flag));
rdata.type, covers, &rdata,
&flag));
if (! flag) {
printf("add an RR\n");
CHECK(delete_if(replaces_p, db, ver, name,
rdata.type, &rdata, &diff));
rdata.type, covers, &rdata,
&diff));
result = update_one_rr(db, ver, &diff,
DNS_DIFFOP_ADD,
name, ttl, &rdata);
@@ -1273,11 +1287,11 @@ ns_req_update(ns_client_t *client,
if (dns_name_equal(name, zonename)) {
CHECK(delete_if(type_not_soa_nor_ns_p,
db, ver, name,
dns_rdatatype_any,
dns_rdatatype_any, 0,
&rdata, &diff));
} else {
CHECK(delete_if(true_p, db, ver, name,
dns_rdatatype_any,
dns_rdatatype_any, 0,
&rdata, &diff));
}
} else if (dns_name_equal(name, zonename) &&
@@ -1289,7 +1303,8 @@ ns_req_update(ns_client_t *client,
} else {
printf("delete an rrset\n");
CHECK(delete_if(true_p, db, ver, name,
rdata.type, &rdata, &diff));
rdata.type, covers, &rdata,
&diff));
}
} else if (update_class == dns_rdataclass_none) {
if (rdata.type == dns_rdatatype_soa) {
@@ -1299,7 +1314,7 @@ ns_req_update(ns_client_t *client,
if (rdata.type == dns_rdatatype_ns) {
int count;
CHECK(rr_count(db, ver, name,
dns_rdatatype_ns, &count));
dns_rdatatype_ns, 0, &count));
if (count == 1) {
printf("attempt to delete last "
"NS ignored\n");
@@ -1308,7 +1323,7 @@ ns_req_update(ns_client_t *client,
}
printf("delete an RR\n");
CHECK(delete_if(rr_equal_p, db, ver, name,
rdata.type, &rdata, &diff));
rdata.type, covers, &rdata, &diff));
}
}
if (result != DNS_R_NOMORE)

View File

@@ -211,7 +211,7 @@ t_dns_db_load(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
if (dns_result != exp_find_result) {
t_info("dns_db_findnode returned %s, expected %s\n",
@@ -757,7 +757,7 @@ t_dns_db_currentversion(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
if (dns_result != DNS_R_SUCCESS) {
t_info("unable to find %s using current version\n", findname);
@@ -817,7 +817,7 @@ t_dns_db_currentversion(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
t_info("unexpectedly found %s using current version\n", findname);
@@ -840,7 +840,7 @@ t_dns_db_currentversion(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
/* and expect it to succeed */
if (dns_result == DNS_R_SUCCESS) {
@@ -1076,7 +1076,7 @@ t_dns_db_newversion(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if (dns_result != DNS_R_SUCCESS) {
t_info("unable to find %s\n", newname);
@@ -1400,7 +1400,7 @@ t_dns_db_closeversion_1(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if (dns_result != DNS_R_SUCCESS) {
t_info("unable to find %s\n", new_name);
@@ -1447,7 +1447,7 @@ t_dns_db_closeversion_1(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
@@ -1741,7 +1741,7 @@ t_dns_db_closeversion_2(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if ( (dns_result == DNS_R_NOTFOUND) ||
(dns_result == DNS_R_NXDOMAIN) ||
@@ -1791,7 +1791,7 @@ t_dns_db_closeversion_2(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
@@ -1821,7 +1821,7 @@ t_dns_db_closeversion_2(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
t_info("dns_db_find %s returned %s\n", new_name,
@@ -1848,7 +1848,7 @@ t_dns_db_closeversion_2(char **av) {
0,
&nodep,
dns_fixedname_name(&dns_foundname),
&found_rdataset);
&found_rdataset, NULL);
if ( (dns_result == DNS_R_NOTFOUND) ||
@@ -2027,7 +2027,7 @@ t_dns_db_expirenode(char **av) {
find_expire_time,
&nodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
if (dns_result == exp_result) {
result = T_PASS;
@@ -2182,7 +2182,8 @@ t_dns_db_findnode_1(char **av) {
dns_db_currentversion(db, &cversionp);
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) {
dns_rdataset_disassociate(&rdataset);
result = T_PASS;
@@ -2332,7 +2333,7 @@ t_dns_db_findnode_2(char **av) {
0,
&newnodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
dns_db_detachnode(db, &newnodep);
}
@@ -2512,7 +2513,7 @@ t_dns_db_find_x(char **av) {
ftime,
&nodep,
dns_fixedname_name(&dns_foundname),
&rdataset);
&rdataset, NULL);
if (dns_result != exp_result) {
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;
char s[1000];
char b[255];
dns_rdataset_t rdataset;
dns_rdataset_t rdataset, sigrdataset;
int ch;
dns_rdatatype_t type = 1;
isc_boolean_t printnode = ISC_FALSE;
@@ -706,8 +706,9 @@ main(int argc, char *argv[]) {
}
node = NULL;
dns_rdataset_init(&rdataset);
dns_rdataset_init(&sigrdataset);
result = dns_db_find(db, &name, version, type, options, 0,
&node, fname, &rdataset);
&node, fname, &rdataset, &sigrdataset);
if (!quiet) {
if (dbi != NULL)
printf("\n");
@@ -797,6 +798,11 @@ main(int argc, char *argv[]) {
} else {
if (!quiet)
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) {
rdataset.ttl++;
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_rdatatype_t type, unsigned int options, isc_stdtime_t now,
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(rdataset == 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,
nodep, foundname, rdataset));
nodep, foundname, rdataset, sigrdataset));
}
void
@@ -434,8 +437,8 @@ dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
dns_result_t
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now,
dns_rdataset_t *rdataset)
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset)
{
/*
* 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(DNS_RDATASET_VALID(rdataset));
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,
rdataset));
return ((db->methods->findrdataset)(db, node, version, type, covers,
now, rdataset));
}
dns_result_t

View File

@@ -96,7 +96,8 @@ typedef struct dns_dbmethods {
dns_rdatatype_t type, unsigned int options,
isc_stdtime_t now,
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,
dns_dbnode_t *source,
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_dbversion_t *version,
dns_rdatatype_t type,
dns_rdatatype_t covers,
isc_stdtime_t now,
dns_rdataset_t *rdataset);
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_rdatatype_t type, unsigned int options, isc_stdtime_t now,
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'.
*
@@ -784,8 +786,8 @@ dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
dns_result_t
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now,
dns_rdataset_t *rdataset);
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset);
/*
* Search for an rdataset of type 'type' at 'node' that are in version
* '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.
*
* '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:
*

View File

@@ -464,11 +464,12 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
dns_result_t
dns_message_findname(dns_message_t *msg, dns_section_t section,
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
* 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:
* '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);
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);
if (result != DNS_R_SUCCESS)
goto freenode;
@@ -164,7 +164,7 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
return (result);
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);
if (result != DNS_R_SUCCESS)
goto freenode;

View File

@@ -15,7 +15,7 @@
* 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>
@@ -140,7 +140,7 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
isc_mem_t *mctx)
{
dns_rdataclass_t rdclass;
dns_rdatatype_t type;
dns_rdatatype_t type, covers;
isc_uint32_t ttl = 0;
isc_uint32_t default_ttl = 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;
}
/*
* 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.
*/
@@ -709,6 +657,64 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
callbacks);
if (result != DNS_R_SUCCESS)
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.

View File

@@ -674,14 +674,15 @@ findname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section)
}
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;
for (curr = ISC_LIST_TAIL(name->list) ;
curr != NULL ;
curr = ISC_LIST_PREV(curr, link)) {
if (curr->type == type) {
if (curr->type == type && curr->covers == covers) {
if (rdataset != NULL)
*rdataset = curr;
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.
*/
result = findtype(NULL, name, rdtype);
result = findtype(NULL, name, rdtype, 0);
if (result == DNS_R_SUCCESS)
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_rdatalist_t *rdatalist;
dns_result_t result;
dns_rdatatype_t rdtype;
dns_rdatatype_t rdtype, covers;
dns_rdataclass_t rdclass;
dns_rdata_t *rdata;
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);
#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
* 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)
return (result);
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
@@ -1485,7 +1495,8 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
dns_result_t
dns_message_findname(dns_message_t *msg, dns_section_t section,
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_result_t result;
@@ -1526,7 +1537,7 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
if (type == dns_rdatatype_any)
return (DNS_R_SUCCESS);
result = findtype(rdataset, foundname, type);
result = findtype(rdataset, foundname, type, covers);
if (result == DNS_R_NOTFOUND)
return (DNS_R_NXRDATASET);

View File

@@ -68,13 +68,26 @@ typedef isc_uint64_t rbtdb_serial_t;
typedef isc_uint32_t rbtdb_serial_t;
#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 {
/*
* Locked by the owning node's lock.
*/
rbtdb_serial_t serial;
dns_ttl_t ttl;
dns_rdatatype_t type;
rbtdb_rdatatype_t type;
isc_uint16_t attributes;
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.
*/
if (rdataset == NULL)
return;
new_reference(rbtdb, node);
rdataset->methods = &rdataset_methods;
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->private1 = rbtdb;
rdataset->private2 = node;
@@ -1116,7 +1133,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
{
dns_result_t result;
dns_name_t *zcname;
dns_rdatatype_t type;
rbtdb_rdatatype_t type;
dns_rbtnode_t *node;
/*
@@ -1161,7 +1178,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
}
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)
{
unsigned char *raw;
@@ -1355,10 +1372,11 @@ find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep) {
static inline isc_result_t
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;
rdatasetheader_t *header, *header_next;
rdatasetheader_t *header, *header_next, *found, *foundsig;
isc_boolean_t empty_node;
isc_result_t result;
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)
return (result);
LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
found = NULL;
foundsig = NULL;
empty_node = ISC_TRUE;
for (header = node->data;
header != NULL;
header = header_next) {
header_next = header->next;
/*
* Look for an active, extant rdataset with a
* NXT record.
* Look for an active, extant NXT or SIG NXT.
*/
do {
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.
*/
empty_node = ISC_FALSE;
if (header->type == dns_rdatatype_nxt)
break;
if (header->type == dns_rdatatype_nxt) {
found = header;
if (foundsig != NULL)
break;
} else if (header->type ==
RBTDB_RDATATYPE_SIGNXT) {
foundsig = header;
if (found != NULL)
break;
}
}
}
if (!empty_node) {
if (header != NULL) {
if (found != NULL && foundsig != NULL) {
/*
* We've found the right NXT record.
*
@@ -1433,13 +1460,17 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
*nodep = node;
}
bind_rdataset(search->rbtdb, node,
header, search->now,
found, search->now,
rdataset);
bind_rdataset(search->rbtdb, node,
foundsig, search->now,
sigrdataset);
}
} else {
/*
* We found an active node without a NXT
* record. This shouldn't happen.
* We found an active node, but either the
* NXT or the SIG NXT is missing. This
* shouldn't happen.
*/
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,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
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_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 empty_node;
rdatasetheader_t *header, *header_next, *found, *nxtheader;
rdatasetheader_t *foundsig, *cnamesig, *nxtsig;
rbtdb_rdatatype_t sigtype;
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) {
result = find_closest_nxt(&search, nodep, foundname,
rdataset);
rdataset, sigrdataset);
if (result == ISC_R_SUCCESS)
result = DNS_R_NXDOMAIN;
} 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
* 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)
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));
found = NULL;
foundsig = NULL;
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, type);
nxtheader = NULL;
nxtsig = NULL;
cnamesig = NULL;
empty_node = ISC_TRUE;
for (header = node->data; header != NULL; header = 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;
break;
}
if (found != NULL)
if (found != NULL && foundsig != NULL)
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 ||
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;
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;
} 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.
*/
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.
*/
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
* rdataset!
* The zone is secure but there's no NXT,
* or the NXT has no signature!
*/
result = DNS_R_BADDB;
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) {
bind_rdataset(search.rbtdb, node, nxtheader,
0, rdataset);
bind_rdataset(search.rbtdb, node, nxtsig,
0, sigrdataset);
}
}
goto node_exit;
@@ -1832,8 +1914,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*nodep = node;
}
if (rdataset != NULL && type != dns_rdatatype_any)
if (type != dns_rdatatype_any) {
bind_rdataset(search.rbtdb, node, found, 0, rdataset);
if (foundsig != NULL)
bind_rdataset(search.rbtdb, node, foundsig, 0,
sigrdataset);
}
node_exit:
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));
/*
* Look for DNAME rdataset.
* Look for a DNAME rdataset.
*/
header_prev = NULL;
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
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;
dns_rbtnode_t *node, *level_node;
rdatasetheader_t *header, *header_prev, *header_next;
rdatasetheader_t *found, *foundsig;
dns_result_t result = DNS_R_NOTFOUND;
dns_name_t name;
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));
/*
* Look for NS rdataset.
* Look for NS and SIG NS rdatasets.
*/
found = NULL;
foundsig = NULL;
header_prev = NULL;
for (header = node->data;
header != NULL;
@@ -1990,15 +2080,28 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
node->dirty = 1;
header_prev = header;
}
} else if (header->type == dns_rdatatype_ns &&
(header->attributes &
RDATASET_ATTR_NONEXISTENT) == 0)
break;
else
} else if ((header->attributes &
RDATASET_ATTR_NONEXISTENT) == 0) {
/*
* We've found an extant rdataset. See if
* 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;
}
if (header != NULL) {
if (found != NULL) {
/*
* If we have to set foundname, we do it before
* 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);
*nodep = node;
}
if (rdataset != NULL)
bind_rdataset(search->rbtdb, node, header,
search->now, rdataset);
bind_rdataset(search->rbtdb, node, found, search->now,
rdataset);
if (foundsig != NULL)
bind_rdataset(search->rbtdb, node, foundsig,
search->now, sigrdataset);
}
node_exit:
UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock));
if (header != NULL)
if (found != NULL)
break;
}
@@ -2053,7 +2158,7 @@ static dns_result_t
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_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_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 empty_node;
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.
@@ -2110,7 +2217,8 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
} else {
find_ns:
result = find_deepest_zonecut(&search, nodep,
foundname, rdataset);
foundname, rdataset,
sigrdataset);
goto tree_exit;
}
} 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
* (RFC 2535, section 2.3.5).
*
* XXX This should be a general purpose subroutine in the rdata
* module.
*
* XXX This 'if' could be an 'else if' of the 'if' above.
* We don't check for SIG, because we don't store SIG records
* directly.
*/
if (type == dns_rdatatype_key ||
type == dns_rdatatype_sig ||
type == dns_rdatatype_nxt)
if (type == dns_rdatatype_key || type == dns_rdatatype_nxt)
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));
found = NULL;
foundsig = NULL;
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, type);
nsheader = NULL;
nxtheader = NULL;
nssig = NULL;
cnamesig = NULL;
empty_node = ISC_TRUE;
header_prev = NULL;
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;
/*
* 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 ||
type == dns_rdatatype_any ||
(cname_ok && header->type ==
dns_rdatatype_cname)) {
/*
* We've found the answer.
*/
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) {
/*
* 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.
*/
nsheader = header;
} else if (header->type == dns_rdatatype_nxt) {
} else if (header->type == RBTDB_RDATATYPE_SIGNS) {
/*
* Remember a NXT rdataset even if we're
* not specifically looking for it, because
* we might need it later.
* If we need the NS rdataset, we'll also
* need its signature.
*/
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;
} 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 (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
* deepest zone cut.
@@ -2229,6 +2355,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*nodep = node;
bind_rdataset(search.rbtdb, node, nsheader, search.now,
rdataset);
if (nssig != NULL)
bind_rdataset(search.rbtdb, node, nssig,
search.now, sigrdataset);
result = DNS_R_DELEGATION;
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;
}
if (rdataset != NULL && type != dns_rdatatype_any)
if (type != dns_rdatatype_any) {
bind_rdataset(search.rbtdb, node, found, search.now,
rdataset);
if (foundsig != NULL)
bind_rdataset(search.rbtdb, node, foundsig, search.now,
sigrdataset);
}
node_exit:
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
zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now,
dns_rdataset_t *rdataset)
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset)
{
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
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_version_t *rbtversion = version;
isc_boolean_t close_version = ISC_FALSE;
rbtdb_rdatatype_t matchtype;
REQUIRE(VALID_RBTDB(rbtdb));
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);
matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
for (header = rbtnode->data; header != NULL; header = header->next) {
if (header->type == type) {
if (header->type == matchtype) {
do {
if (header->serial <= serial &&
!IGNORE(header)) {
@@ -2484,12 +2619,13 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
static dns_result_t
cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, isc_stdtime_t now,
dns_rdataset_t *rdataset)
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset)
{
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
rdatasetheader_t *header, *header_next, *found;
rbtdb_rdatatype_t matchtype;
REQUIRE(VALID_RBTDB(rbtdb));
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);
found = NULL;
matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
for (header = rbtnode->data; header != NULL; header = header_next) {
header_next = header->next;
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;
rbtnode->dirty = 1;
} else if (header->type == type &&
} else if (header->type == matchtype &&
(header->attributes & RDATASET_ATTR_NONEXISTENT) ==
0) {
found = header;
@@ -2793,7 +2930,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
static inline isc_boolean_t
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 &&
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->ttl = rdataset->ttl + now;
newheader->type = rdataset->type;
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
newheader->attributes = 0;
if (rbtversion != NULL) {
newheader->serial = rbtversion->serial;
@@ -2893,7 +3031,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
return (result);
newheader = (rdatasetheader_t *)region.base;
newheader->ttl = 0;
newheader->type = rdataset->type;
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
rdataset->covers);
newheader->attributes = 0;
newheader->serial = rbtversion->serial;
newheader->trust = 0;
@@ -3007,14 +3146,14 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
REQUIRE(VALID_RBTDB(rbtdb));
if (type == dns_rdatatype_any)
if (type == dns_rdatatype_any || type == dns_rdatatype_sig)
return (DNS_R_NOTIMPLEMENTED);
newheader = isc_mem_get(rbtdb->common.mctx, sizeof *newheader);
if (newheader == NULL)
return (DNS_R_NOMEMORY);
newheader->ttl = 0;
newheader->type = type;
newheader->type = RBTDB_RDATATYPE_VALUE(type, 0);
newheader->attributes = RDATASET_ATTR_NONEXISTENT;
newheader->trust = 0;
if (rbtversion != NULL)
@@ -3092,7 +3231,8 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
return (result);
newheader = (rdatasetheader_t *)region.base;
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->trust = rdataset->trust;
newheader->serial = 1;
@@ -3595,7 +3735,7 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
rdatasetheader_t *header, *top_next;
rbtdb_serial_t serial;
isc_stdtime_t now;
dns_rdatatype_t type;
rbtdb_rdatatype_t type;
header = rbtiterator->current;
if (header == NULL)

View File

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

View File

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