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:
@@ -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);
|
||||||
|
@@ -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)
|
||||||
|
@@ -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",
|
||||||
|
@@ -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;
|
||||||
|
18
lib/dns/db.c
18
lib/dns/db.c
@@ -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
|
||||||
|
@@ -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:
|
||||||
*
|
*
|
||||||
|
@@ -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.
|
||||||
|
@@ -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;
|
||||||
|
114
lib/dns/master.c
114
lib/dns/master.c
@@ -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,
|
|
||||||
¤t_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,
|
||||||
|
¤t_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.
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
302
lib/dns/rbtdb.c
302
lib/dns/rbtdb.c
@@ -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)
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user