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;
|
||||
result = dns_db_find(db, name, version, type, client->query.dboptions,
|
||||
client->requesttime, &node, fname, rdataset);
|
||||
client->requesttime, &node, fname, rdataset,
|
||||
NULL);
|
||||
switch (result) {
|
||||
case DNS_R_SUCCESS:
|
||||
case DNS_R_GLUE:
|
||||
@@ -409,7 +410,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
|
||||
section++) {
|
||||
mname = NULL;
|
||||
result = dns_message_findname(client->message, section,
|
||||
name, type, &mname, NULL);
|
||||
name, type, 0, &mname, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We've already got this RRset in the response.
|
||||
@@ -508,19 +509,23 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
|
||||
|
||||
static inline void
|
||||
query_addrrset(ns_client_t *client, dns_name_t **namep,
|
||||
dns_rdataset_t **rdatasetp, isc_dynbuffer_t *dbuf,
|
||||
dns_section_t section)
|
||||
dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
|
||||
isc_dynbuffer_t *dbuf, dns_section_t section)
|
||||
{
|
||||
dns_name_t *name, *mname;
|
||||
dns_rdataset_t *rdataset, *mrdataset;
|
||||
dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;
|
||||
isc_result_t result;
|
||||
|
||||
name = *namep;
|
||||
rdataset = *rdatasetp;
|
||||
if (sigrdatasetp != NULL)
|
||||
sigrdataset = *sigrdatasetp;
|
||||
else
|
||||
sigrdataset = NULL;
|
||||
mname = NULL;
|
||||
mrdataset = NULL;
|
||||
result = dns_message_findname(client->message, section,
|
||||
name, rdataset->type,
|
||||
name, rdataset->type, rdataset->covers,
|
||||
&mname, &mrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
@@ -540,8 +545,20 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
|
||||
} else
|
||||
RUNTIME_CHECK(result == DNS_R_NXRDATASET);
|
||||
|
||||
/*
|
||||
* Note: we only add SIGs if we've added the type they cover, so
|
||||
* we do not need to check if the SIG rdataset is already in the
|
||||
* response.
|
||||
*/
|
||||
query_addrdataset(client, mname, rdataset);
|
||||
*rdatasetp = NULL;
|
||||
if (sigrdataset != NULL && sigrdataset->methods != NULL) {
|
||||
/*
|
||||
* We have a signature. Add it to the response.
|
||||
*/
|
||||
query_addrdataset(client, mname, sigrdataset);
|
||||
*sigrdatasetp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
@@ -550,7 +567,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
|
||||
dns_dbnode_t *node;
|
||||
isc_result_t result, eresult;
|
||||
dns_fixedname_t foundname;
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_rdataset_t *rdataset, *sigrdataset;
|
||||
|
||||
/*
|
||||
* Initialization.
|
||||
@@ -571,7 +588,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
|
||||
dns_name_init(name, NULL);
|
||||
dns_name_clone(dns_db_origin(db), name);
|
||||
rdataset = query_newrdataset(client);
|
||||
if (rdataset == NULL) {
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (rdataset == NULL || sigrdataset == NULL) {
|
||||
eresult = DNS_R_SERVFAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -580,7 +598,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
|
||||
* Find the SOA.
|
||||
*/
|
||||
result = dns_db_find(db, name, NULL, dns_rdatatype_soa, 0, 0, &node,
|
||||
fname, rdataset);
|
||||
fname, rdataset, sigrdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/*
|
||||
* This is bad. We tried to get the SOA RR at the zone top
|
||||
@@ -589,11 +607,17 @@ query_addsoa(ns_client_t *client, dns_db_t *db) {
|
||||
* The note above about temporary leakage applies here too.
|
||||
*/
|
||||
eresult = DNS_R_SERVFAIL;
|
||||
} else
|
||||
query_addrrset(client, &name, &rdataset, NULL,
|
||||
} else {
|
||||
query_addrrset(client, &name, &rdataset, &sigrdataset, NULL,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (sigrdataset != NULL) {
|
||||
if (sigrdataset->methods != NULL)
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
ISC_LIST_APPEND(client->query.tmprdatasets, sigrdataset, link);
|
||||
}
|
||||
if (rdataset != NULL) {
|
||||
if (rdataset->methods != NULL)
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
@@ -611,13 +635,10 @@ static inline isc_result_t
|
||||
query_checktype(dns_rdatatype_t type) {
|
||||
|
||||
/*
|
||||
* XXXRTH SIG is here only temporarily.
|
||||
* OPT still needs to be added.
|
||||
* XXXRTH OPT still needs to be added.
|
||||
* Should get help with this from rdata.c
|
||||
*/
|
||||
switch (type) {
|
||||
case dns_rdatatype_sig:
|
||||
return (DNS_R_NOTIMP);
|
||||
case dns_rdatatype_tkey:
|
||||
return (DNS_R_NOTIMP);
|
||||
case dns_rdatatype_tsig:
|
||||
@@ -649,6 +670,7 @@ query_find(ns_client_t *client) {
|
||||
dns_rdatatype_t qtype, type;
|
||||
dns_name_t *fname, *tname, *prefix;
|
||||
dns_rdataset_t *rdataset, *qrdataset, *trdataset;
|
||||
dns_rdataset_t *sigrdataset;
|
||||
dns_rdata_t rdata;
|
||||
dns_rdatasetiter_t *rdsiter;
|
||||
isc_boolean_t use_cache, recursion_ok, want_restart;
|
||||
@@ -676,6 +698,7 @@ query_find(ns_client_t *client) {
|
||||
recursion_ok = ISC_FALSE;
|
||||
fname = NULL;
|
||||
rdataset = NULL;
|
||||
sigrdataset = NULL;
|
||||
node = NULL;
|
||||
db = NULL;
|
||||
version = NULL;
|
||||
@@ -778,6 +801,12 @@ query_find(ns_client_t *client) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* If it's a SIG query, we'll iterate the node.
|
||||
*/
|
||||
if (qtype == dns_rdatatype_sig)
|
||||
type = dns_rdatatype_any;
|
||||
|
||||
/*
|
||||
* We'll need some resources...
|
||||
*/
|
||||
@@ -788,7 +817,8 @@ query_find(ns_client_t *client) {
|
||||
}
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
rdataset = query_newrdataset(client);
|
||||
if (fname == NULL || rdataset == NULL) {
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -800,7 +830,8 @@ query_find(ns_client_t *client) {
|
||||
* Now look for an answer in the database.
|
||||
*/
|
||||
result = dns_db_find(db, client->query.qname, version, type, 0,
|
||||
client->requesttime, &node, fname, rdataset);
|
||||
client->requesttime, &node, fname, rdataset,
|
||||
sigrdataset);
|
||||
switch (result) {
|
||||
case DNS_R_SUCCESS:
|
||||
case DNS_R_ZONECUT:
|
||||
@@ -818,7 +849,8 @@ query_find(ns_client_t *client) {
|
||||
* We don't have a cache, so this is the best
|
||||
* answer.
|
||||
*/
|
||||
query_addrrset(client, &fname, &rdataset, dbuf,
|
||||
query_addrrset(client, &fname, &rdataset,
|
||||
&sigrdataset, dbuf,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
} else {
|
||||
/*
|
||||
@@ -878,8 +910,8 @@ query_find(ns_client_t *client) {
|
||||
* Add NXT record if we found one.
|
||||
*/
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
query_addrrset(client, &tname, &rdataset, NULL,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
query_addrrset(client, &tname, &rdataset, &sigrdataset,
|
||||
NULL, DNS_SECTION_AUTHORITY);
|
||||
goto cleanup;
|
||||
case DNS_R_NXDOMAIN:
|
||||
if (restarts > 0) {
|
||||
@@ -922,8 +954,8 @@ query_find(ns_client_t *client) {
|
||||
* Add NXT record if we found one.
|
||||
*/
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
query_addrrset(client, &tname, &rdataset, NULL,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
query_addrrset(client, &tname, &rdataset, &sigrdataset,
|
||||
NULL, DNS_SECTION_AUTHORITY);
|
||||
/*
|
||||
* Set message rcode.
|
||||
*/
|
||||
@@ -942,7 +974,7 @@ query_find(ns_client_t *client) {
|
||||
/*
|
||||
* Add the CNAME to the answer section.
|
||||
*/
|
||||
query_addrrset(client, &fname, &rdataset, dbuf,
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
/*
|
||||
* We set the PARTIALANSWER attribute so that if anything goes
|
||||
@@ -986,7 +1018,7 @@ query_find(ns_client_t *client) {
|
||||
/*
|
||||
* Add the DNAME to the answer section.
|
||||
*/
|
||||
query_addrrset(client, &fname, &rdataset, dbuf,
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
/*
|
||||
* We set the PARTIALANSWER attribute so that if anything goes
|
||||
@@ -1029,9 +1061,8 @@ query_find(ns_client_t *client) {
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (result == ISC_R_NOSPACE) {
|
||||
/*
|
||||
* draft-ietf-dnsind-dname-03.txt, section
|
||||
* 4.1, subsection 3c says we should
|
||||
* return YXDOMAIN if the constructed
|
||||
* RFC 2672, section 4.1, subsection 3c says
|
||||
* we should return YXDOMAIN if the constructed
|
||||
* name would be too long.
|
||||
*/
|
||||
client->message->rcode = dns_rcode_yxdomain;
|
||||
@@ -1058,7 +1089,7 @@ query_find(ns_client_t *client) {
|
||||
*/
|
||||
n = 0;
|
||||
rdsiter = NULL;
|
||||
result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter);
|
||||
result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
@@ -1066,34 +1097,72 @@ query_find(ns_client_t *client) {
|
||||
result = dns_rdatasetiter_first(rdsiter);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdatasetiter_current(rdsiter, rdataset);
|
||||
tname = fname;
|
||||
query_addrrset(client, &tname, &rdataset, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
n++;
|
||||
if (qtype == dns_rdatatype_any ||
|
||||
rdataset->type == qtype) {
|
||||
tname = fname;
|
||||
query_addrrset(client, &tname, &rdataset, NULL,
|
||||
dbuf, DNS_SECTION_ANSWER);
|
||||
n++;
|
||||
/*
|
||||
* We shouldn't ever fail to add 'rdataset'
|
||||
* because it's already in the answer.
|
||||
*/
|
||||
INSIST(rdataset == NULL);
|
||||
/*
|
||||
* We set dbuf to NULL because we only want
|
||||
* the query_keepname() call in
|
||||
* query_addrrset() to be called once.
|
||||
*/
|
||||
dbuf = NULL;
|
||||
rdataset = query_newrdataset(client);
|
||||
if (rdataset == NULL)
|
||||
break;
|
||||
} else {
|
||||
/*
|
||||
* We're not interested in this rdataset.
|
||||
*/
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
}
|
||||
result = dns_rdatasetiter_next(rdsiter);
|
||||
}
|
||||
if (n > 0) {
|
||||
/*
|
||||
* We shouldn't ever fail to add 'rdataset' because
|
||||
* it's already in the answer.
|
||||
* If we added at least one RRset, then we must clear
|
||||
* fname, otherwise the cleanup code might cause it
|
||||
* to be reused.
|
||||
*/
|
||||
INSIST(rdataset == NULL);
|
||||
fname = NULL;
|
||||
} else {
|
||||
/*
|
||||
* We set dbuf to NULL because we only want the
|
||||
* query_keepname() call in query_addrrset() to be
|
||||
* called once.
|
||||
* We didn't match any rdatasets.
|
||||
*/
|
||||
dbuf = NULL;
|
||||
result = dns_message_gettemprdataset(client->message,
|
||||
&rdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_init(rdataset);
|
||||
result = dns_rdatasetiter_next(rdsiter);
|
||||
if (qtype == dns_rdatatype_sig &&
|
||||
result == DNS_R_NOMORE) {
|
||||
/*
|
||||
* XXXRTH If this is a secure zone and we
|
||||
* didn't find any SIGs, we should generate
|
||||
* an error unless we were searching for
|
||||
* glue. Ugh.
|
||||
*/
|
||||
/*
|
||||
* We were searching for SIG records in
|
||||
* a nonsecure zone. Send a "no error,
|
||||
* no data" response.
|
||||
*
|
||||
* First we must release fname.
|
||||
*/
|
||||
query_releasename(client, &fname);
|
||||
/*
|
||||
* Add SOA.
|
||||
*/
|
||||
result = query_addsoa(client, db);
|
||||
} else {
|
||||
/*
|
||||
* Something went wrong.
|
||||
*/
|
||||
result = DNS_R_SERVFAIL;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If we added at least one RRset, then we must clear fname,
|
||||
* otherwise the cleanup code might cause it to be reused.
|
||||
*/
|
||||
if (n > 0)
|
||||
fname = NULL;
|
||||
dns_rdatasetiter_destroy(&rdsiter);
|
||||
if (result != DNS_R_NOMORE) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
@@ -1104,7 +1173,7 @@ query_find(ns_client_t *client) {
|
||||
* This is the "normal" case -- an ordinary question to which
|
||||
* we know the answer.
|
||||
*/
|
||||
query_addrrset(client, &fname, &rdataset, dbuf,
|
||||
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
/*
|
||||
* Remember that we've answered this question.
|
||||
@@ -1123,6 +1192,11 @@ query_find(ns_client_t *client) {
|
||||
*/
|
||||
|
||||
cleanup:
|
||||
if (sigrdataset != NULL) {
|
||||
if (sigrdataset->methods != NULL)
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
ISC_LIST_APPEND(client->query.tmprdatasets, sigrdataset, link);
|
||||
}
|
||||
if (rdataset != NULL) {
|
||||
if (rdataset->methods != NULL)
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
|
@@ -261,9 +261,9 @@ foreach_node_rr(dns_db_t *db,
|
||||
|
||||
|
||||
/*
|
||||
* For each of the RRs specified by 'db', 'ver', 'name', and 'type',
|
||||
* (which can be dns_rdatatype_any to match any type), call 'action'
|
||||
* with the RR and 'action_data' as arguments. If the name
|
||||
* For each of the RRs specified by 'db', 'ver', 'name', 'type',
|
||||
* (which can be dns_rdatatype_any to match any type), and 'covers', call
|
||||
* 'action' with the RR and 'action_data' as arguments. If the name
|
||||
* does not exist, or if no RRset of the given type exists at the name,
|
||||
* do nothing.
|
||||
*
|
||||
@@ -274,6 +274,7 @@ foreach_rr(dns_db_t *db,
|
||||
dns_dbversion_t *ver,
|
||||
dns_name_t *name,
|
||||
dns_rdatatype_t type,
|
||||
dns_rdatatype_t covers,
|
||||
rr_func *rr_action,
|
||||
void *rr_action_data)
|
||||
{
|
||||
@@ -294,7 +295,7 @@ foreach_rr(dns_db_t *db,
|
||||
return (result);
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(db, node, ver, type,
|
||||
result = dns_db_findrdataset(db, node, ver, type, covers,
|
||||
(isc_stdtime_t) 0, &rdataset);
|
||||
if (result == DNS_R_NOTFOUND) {
|
||||
result = DNS_R_SUCCESS;
|
||||
@@ -366,10 +367,11 @@ do { \
|
||||
*/
|
||||
static dns_result_t
|
||||
rrset_exists(dns_db_t *db, dns_dbversion_t *ver,
|
||||
dns_name_t *name, dns_rdatatype_t type, isc_boolean_t *exists)
|
||||
dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||
isc_boolean_t *exists)
|
||||
{
|
||||
dns_result_t result;
|
||||
result = foreach_rr(db, ver, name, type,
|
||||
result = foreach_rr(db, ver, name, type, covers,
|
||||
rrset_exists_action, NULL);
|
||||
RETURN_EXISTENCE_FLAG;
|
||||
}
|
||||
@@ -429,10 +431,10 @@ count_rr_action(void *data, rr_t *rr) /*ARGSUSED*/ {
|
||||
*/
|
||||
static dns_result_t
|
||||
rr_count(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
||||
dns_rdatatype_t type, int *countp)
|
||||
dns_rdatatype_t type, dns_rdatatype_t covers, int *countp)
|
||||
{
|
||||
*countp = 0;
|
||||
return (foreach_rr(db, ver, name, type,
|
||||
return (foreach_rr(db, ver, name, type, covers,
|
||||
count_rr_action, countp));
|
||||
}
|
||||
|
||||
@@ -468,6 +470,7 @@ matching_rr_exists(rr_predicate *predicate,
|
||||
dns_dbversion_t *ver,
|
||||
dns_name_t *name,
|
||||
dns_rdatatype_t type,
|
||||
dns_rdatatype_t covers,
|
||||
dns_rdata_t *update_rr,
|
||||
isc_boolean_t *exists)
|
||||
{
|
||||
@@ -478,7 +481,7 @@ matching_rr_exists(rr_predicate *predicate,
|
||||
ctx.ver = ver;
|
||||
ctx.name = name;
|
||||
ctx.update_rr = update_rr;
|
||||
result = foreach_rr(db, ver, name, type,
|
||||
result = foreach_rr(db, ver, name, type, covers,
|
||||
matching_rr_exists_action, &ctx);
|
||||
RETURN_EXISTENCE_FLAG;
|
||||
}
|
||||
@@ -637,7 +640,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
|
||||
|
||||
/* A new unique type begins here. */
|
||||
while (t != NULL && dns_name_equal(&t->name, name)) {
|
||||
dns_rdatatype_t type;
|
||||
dns_rdatatype_t type, covers;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_diff_t d_rrs; /* Database RRs with
|
||||
this name and type */
|
||||
@@ -645,6 +648,10 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
|
||||
this name and type */
|
||||
|
||||
type = t->rdata.type;
|
||||
if (type == dns_rdatatype_sig)
|
||||
covers = dns_rdata_covers(&t->rdata);
|
||||
else
|
||||
covers = 0;
|
||||
|
||||
/*
|
||||
* Collect all database RRs for this name and type
|
||||
@@ -652,7 +659,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
|
||||
*/
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(db, node, ver, type,
|
||||
(isc_stdtime_t) 0,
|
||||
covers, (isc_stdtime_t) 0,
|
||||
&rdataset);
|
||||
if (result != DNS_R_SUCCESS) {
|
||||
dns_db_detachnode(db, &node);
|
||||
@@ -837,6 +844,7 @@ delete_if(rr_predicate *predicate,
|
||||
dns_dbversion_t *ver,
|
||||
dns_name_t *name,
|
||||
dns_rdatatype_t type,
|
||||
dns_rdatatype_t covers,
|
||||
dns_rdata_t *update_rr,
|
||||
dns_diff_t *diff)
|
||||
{
|
||||
@@ -847,7 +855,7 @@ delete_if(rr_predicate *predicate,
|
||||
ctx.diff = diff;
|
||||
ctx.name = name;
|
||||
ctx.update_rr = update_rr;
|
||||
return (foreach_rr(db, ver, name, type,
|
||||
return (foreach_rr(db, ver, name, type, covers,
|
||||
delete_if_action, &ctx));
|
||||
}
|
||||
|
||||
@@ -866,7 +874,8 @@ delete_if(rr_predicate *predicate,
|
||||
static void
|
||||
get_current_rr(dns_message_t *msg, dns_section_t section,
|
||||
dns_rdataclass_t zoneclass,
|
||||
dns_name_t **name, dns_rdata_t *rdata, dns_ttl_t *ttl,
|
||||
dns_name_t **name, dns_rdata_t *rdata, dns_rdatatype_t *covers,
|
||||
dns_ttl_t *ttl,
|
||||
dns_rdataclass_t *update_class)
|
||||
{
|
||||
dns_rdataset_t *rdataset;
|
||||
@@ -875,6 +884,7 @@ get_current_rr(dns_message_t *msg, dns_section_t section,
|
||||
rdataset = ISC_LIST_HEAD((*name)->list);
|
||||
INSIST(rdataset != NULL);
|
||||
INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
|
||||
*covers = rdataset->covers;
|
||||
*ttl = rdataset->ttl;
|
||||
result = dns_rdataset_first(rdataset);
|
||||
INSIST(result == DNS_R_SUCCESS);
|
||||
@@ -991,6 +1001,7 @@ ns_req_update(ns_client_t *client,
|
||||
unsigned int response_rcode = dns_rcode_noerror;
|
||||
isc_boolean_t soa_serial_changed = ISC_FALSE;
|
||||
isc_mem_t *mctx = client->mctx;
|
||||
dns_rdatatype_t covers;
|
||||
|
||||
dns_diff_init(mctx, &diff);
|
||||
dns_diff_init(mctx, &temp);
|
||||
@@ -1065,7 +1076,7 @@ ns_req_update(ns_client_t *client,
|
||||
isc_boolean_t flag;
|
||||
|
||||
get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass,
|
||||
&name, &rdata, &ttl, &update_class);
|
||||
&name, &rdata, &covers, &ttl, &update_class);
|
||||
|
||||
if (ttl != 0)
|
||||
FAILMSG(DNS_R_FORMERR, "prereq TTL != 0");
|
||||
@@ -1087,7 +1098,7 @@ ns_req_update(ns_client_t *client,
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
rdata.type, &flag));
|
||||
rdata.type, covers, &flag));
|
||||
if (! flag) {
|
||||
/* RRset does not exist. */
|
||||
FAILMSG(DNS_R_NXRRSET,
|
||||
@@ -1108,7 +1119,7 @@ ns_req_update(ns_client_t *client,
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
rdata.type, &flag));
|
||||
rdata.type, covers, &flag));
|
||||
if (flag) {
|
||||
/* RRset exists. */
|
||||
FAILMSG(DNS_R_YXRRSET,
|
||||
@@ -1156,7 +1167,7 @@ ns_req_update(ns_client_t *client,
|
||||
dns_ttl_t ttl;
|
||||
dns_rdataclass_t update_class;
|
||||
get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
|
||||
&name, &rdata, &ttl, &update_class);
|
||||
&name, &rdata, &covers, &ttl, &update_class);
|
||||
|
||||
if (! dns_name_issubdomain(name, zonename))
|
||||
FAILMSG(DNS_R_NOTZONE,
|
||||
@@ -1206,7 +1217,7 @@ ns_req_update(ns_client_t *client,
|
||||
isc_boolean_t flag;
|
||||
|
||||
get_current_rr(request, DNS_SECTION_UPDATE, zoneclass,
|
||||
&name, &rdata, &ttl, &update_class);
|
||||
&name, &rdata, &covers, &ttl, &update_class);
|
||||
|
||||
if (update_class == zoneclass) {
|
||||
if (rdata.type == dns_rdatatype_cname) {
|
||||
@@ -1221,7 +1232,7 @@ ns_req_update(ns_client_t *client,
|
||||
}
|
||||
} else {
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
dns_rdatatype_cname,
|
||||
dns_rdatatype_cname, 0,
|
||||
&flag));
|
||||
if (flag && ! is_dnssec_type(rdata.type)) {
|
||||
printf("attempt to add non-cname "
|
||||
@@ -1232,7 +1243,8 @@ ns_req_update(ns_client_t *client,
|
||||
if (rdata.type == dns_rdatatype_soa) {
|
||||
isc_boolean_t changed, ok;
|
||||
CHECK(rrset_exists(db, ver, name,
|
||||
dns_rdatatype_soa, &flag));
|
||||
dns_rdatatype_soa, 0,
|
||||
&flag));
|
||||
if (! flag) {
|
||||
printf("attempt to create extra SOA "
|
||||
"ignored\n");
|
||||
@@ -1254,11 +1266,13 @@ ns_req_update(ns_client_t *client,
|
||||
* CNAME, SOA, or WKS exists, remove it first.
|
||||
*/
|
||||
CHECK(matching_rr_exists(rr_equal_p, db, ver, name,
|
||||
rdata.type, &rdata, &flag));
|
||||
rdata.type, covers, &rdata,
|
||||
&flag));
|
||||
if (! flag) {
|
||||
printf("add an RR\n");
|
||||
CHECK(delete_if(replaces_p, db, ver, name,
|
||||
rdata.type, &rdata, &diff));
|
||||
rdata.type, covers, &rdata,
|
||||
&diff));
|
||||
result = update_one_rr(db, ver, &diff,
|
||||
DNS_DIFFOP_ADD,
|
||||
name, ttl, &rdata);
|
||||
@@ -1273,11 +1287,11 @@ ns_req_update(ns_client_t *client,
|
||||
if (dns_name_equal(name, zonename)) {
|
||||
CHECK(delete_if(type_not_soa_nor_ns_p,
|
||||
db, ver, name,
|
||||
dns_rdatatype_any,
|
||||
dns_rdatatype_any, 0,
|
||||
&rdata, &diff));
|
||||
} else {
|
||||
CHECK(delete_if(true_p, db, ver, name,
|
||||
dns_rdatatype_any,
|
||||
dns_rdatatype_any, 0,
|
||||
&rdata, &diff));
|
||||
}
|
||||
} else if (dns_name_equal(name, zonename) &&
|
||||
@@ -1289,7 +1303,8 @@ ns_req_update(ns_client_t *client,
|
||||
} else {
|
||||
printf("delete an rrset\n");
|
||||
CHECK(delete_if(true_p, db, ver, name,
|
||||
rdata.type, &rdata, &diff));
|
||||
rdata.type, covers, &rdata,
|
||||
&diff));
|
||||
}
|
||||
} else if (update_class == dns_rdataclass_none) {
|
||||
if (rdata.type == dns_rdatatype_soa) {
|
||||
@@ -1299,7 +1314,7 @@ ns_req_update(ns_client_t *client,
|
||||
if (rdata.type == dns_rdatatype_ns) {
|
||||
int count;
|
||||
CHECK(rr_count(db, ver, name,
|
||||
dns_rdatatype_ns, &count));
|
||||
dns_rdatatype_ns, 0, &count));
|
||||
if (count == 1) {
|
||||
printf("attempt to delete last "
|
||||
"NS ignored\n");
|
||||
@@ -1308,7 +1323,7 @@ ns_req_update(ns_client_t *client,
|
||||
}
|
||||
printf("delete an RR\n");
|
||||
CHECK(delete_if(rr_equal_p, db, ver, name,
|
||||
rdata.type, &rdata, &diff));
|
||||
rdata.type, covers, &rdata, &diff));
|
||||
}
|
||||
}
|
||||
if (result != DNS_R_NOMORE)
|
||||
|
@@ -211,7 +211,7 @@ t_dns_db_load(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
|
||||
if (dns_result != exp_find_result) {
|
||||
t_info("dns_db_findnode returned %s, expected %s\n",
|
||||
@@ -757,7 +757,7 @@ t_dns_db_currentversion(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
|
||||
if (dns_result != DNS_R_SUCCESS) {
|
||||
t_info("unable to find %s using current version\n", findname);
|
||||
@@ -817,7 +817,7 @@ t_dns_db_currentversion(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
|
||||
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
|
||||
t_info("unexpectedly found %s using current version\n", findname);
|
||||
@@ -840,7 +840,7 @@ t_dns_db_currentversion(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
|
||||
/* and expect it to succeed */
|
||||
if (dns_result == DNS_R_SUCCESS) {
|
||||
@@ -1076,7 +1076,7 @@ t_dns_db_newversion(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
if (dns_result != DNS_R_SUCCESS) {
|
||||
t_info("unable to find %s\n", newname);
|
||||
@@ -1400,7 +1400,7 @@ t_dns_db_closeversion_1(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
if (dns_result != DNS_R_SUCCESS) {
|
||||
t_info("unable to find %s\n", new_name);
|
||||
@@ -1447,7 +1447,7 @@ t_dns_db_closeversion_1(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
|
||||
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
|
||||
@@ -1741,7 +1741,7 @@ t_dns_db_closeversion_2(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
if ( (dns_result == DNS_R_NOTFOUND) ||
|
||||
(dns_result == DNS_R_NXDOMAIN) ||
|
||||
@@ -1791,7 +1791,7 @@ t_dns_db_closeversion_2(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
|
||||
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
|
||||
@@ -1821,7 +1821,7 @@ t_dns_db_closeversion_2(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
|
||||
t_info("dns_db_find %s returned %s\n", new_name,
|
||||
@@ -1848,7 +1848,7 @@ t_dns_db_closeversion_2(char **av) {
|
||||
0,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&found_rdataset);
|
||||
&found_rdataset, NULL);
|
||||
|
||||
|
||||
if ( (dns_result == DNS_R_NOTFOUND) ||
|
||||
@@ -2027,7 +2027,7 @@ t_dns_db_expirenode(char **av) {
|
||||
find_expire_time,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
|
||||
if (dns_result == exp_result) {
|
||||
result = T_PASS;
|
||||
@@ -2182,7 +2182,8 @@ t_dns_db_findnode_1(char **av) {
|
||||
dns_db_currentversion(db, &cversionp);
|
||||
dns_rdataset_init(&rdataset);
|
||||
|
||||
dns_result = dns_db_findrdataset(db, nodep, cversionp, rdatatype, 0, &rdataset);
|
||||
dns_result = dns_db_findrdataset(db, nodep, cversionp, rdatatype, 0,
|
||||
0, &rdataset);
|
||||
if (dns_result == DNS_R_SUCCESS) {
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
result = T_PASS;
|
||||
@@ -2332,7 +2333,7 @@ t_dns_db_findnode_2(char **av) {
|
||||
0,
|
||||
&newnodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
if ((dns_result != DNS_R_NOTFOUND) && (dns_result != DNS_R_NXDOMAIN)) {
|
||||
dns_db_detachnode(db, &newnodep);
|
||||
}
|
||||
@@ -2512,7 +2513,7 @@ t_dns_db_find_x(char **av) {
|
||||
ftime,
|
||||
&nodep,
|
||||
dns_fixedname_name(&dns_foundname),
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
|
||||
if (dns_result != exp_result) {
|
||||
t_info("dns_db_find %s %s unexpectedly returned %s, expected %s\n",
|
||||
|
@@ -323,7 +323,7 @@ main(int argc, char *argv[]) {
|
||||
isc_buffer_t source, target;
|
||||
char s[1000];
|
||||
char b[255];
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdataset_t rdataset, sigrdataset;
|
||||
int ch;
|
||||
dns_rdatatype_t type = 1;
|
||||
isc_boolean_t printnode = ISC_FALSE;
|
||||
@@ -706,8 +706,9 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
node = NULL;
|
||||
dns_rdataset_init(&rdataset);
|
||||
dns_rdataset_init(&sigrdataset);
|
||||
result = dns_db_find(db, &name, version, type, options, 0,
|
||||
&node, fname, &rdataset);
|
||||
&node, fname, &rdataset, &sigrdataset);
|
||||
if (!quiet) {
|
||||
if (dbi != NULL)
|
||||
printf("\n");
|
||||
@@ -797,6 +798,11 @@ main(int argc, char *argv[]) {
|
||||
} else {
|
||||
if (!quiet)
|
||||
print_rdataset(fname, &rdataset);
|
||||
if (dns_rdataset_isassociated(&sigrdataset)) {
|
||||
if (!quiet)
|
||||
print_rdataset(fname, &sigrdataset);
|
||||
dns_rdataset_disassociate(&sigrdataset);
|
||||
}
|
||||
if (dbi != NULL && addmode && !found_as) {
|
||||
rdataset.ttl++;
|
||||
rdataset.trust = trust;
|
||||
|
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_rdatatype_t type, unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset)
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -349,9 +349,12 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
REQUIRE(dns_name_hasbuffer(foundname));
|
||||
REQUIRE(rdataset == NULL ||
|
||||
(DNS_RDATASET_VALID(rdataset) && rdataset->methods == NULL));
|
||||
REQUIRE(sigrdataset == NULL ||
|
||||
(DNS_RDATASET_VALID(sigrdataset) &&
|
||||
sigrdataset->methods == NULL));
|
||||
|
||||
return ((db->methods->find)(db, name, version, type, options, now,
|
||||
nodep, foundname, rdataset));
|
||||
nodep, foundname, rdataset, sigrdataset));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -434,8 +437,8 @@ dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
|
||||
|
||||
dns_result_t
|
||||
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, isc_stdtime_t now,
|
||||
dns_rdataset_t *rdataset)
|
||||
dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset)
|
||||
{
|
||||
/*
|
||||
* Search for an rdataset of type 'type' at 'node' that are in version
|
||||
@@ -446,10 +449,11 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
REQUIRE(node != NULL);
|
||||
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
||||
REQUIRE(rdataset->methods == NULL);
|
||||
REQUIRE(type != dns_rdatatype_sig && type != dns_rdatatype_any);
|
||||
REQUIRE(covers == 0 || type == dns_rdatatype_sig);
|
||||
REQUIRE(type != dns_rdatatype_any);
|
||||
|
||||
return ((db->methods->findrdataset)(db, node, version, type, now,
|
||||
rdataset));
|
||||
return ((db->methods->findrdataset)(db, node, version, type, covers,
|
||||
now, rdataset));
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
|
@@ -96,7 +96,8 @@ typedef struct dns_dbmethods {
|
||||
dns_rdatatype_t type, unsigned int options,
|
||||
isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset);
|
||||
dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset);
|
||||
void (*attachnode)(dns_db_t *db,
|
||||
dns_dbnode_t *source,
|
||||
dns_dbnode_t **targetp);
|
||||
@@ -112,6 +113,7 @@ typedef struct dns_dbmethods {
|
||||
dns_result_t (*findrdataset)(dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_dbversion_t *version,
|
||||
dns_rdatatype_t type,
|
||||
dns_rdatatype_t covers,
|
||||
isc_stdtime_t now,
|
||||
dns_rdataset_t *rdataset);
|
||||
dns_result_t (*allrdatasets)(dns_db_t *db, dns_dbnode_t *node,
|
||||
@@ -554,7 +556,7 @@ dns_result_t
|
||||
dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset);
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset);
|
||||
/*
|
||||
* Find the best match for 'name' and 'type' in version 'version' of 'db'.
|
||||
*
|
||||
@@ -784,8 +786,8 @@ dns_db_createiterator(dns_db_t *db, isc_boolean_t relative_names,
|
||||
|
||||
dns_result_t
|
||||
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, isc_stdtime_t now,
|
||||
dns_rdataset_t *rdataset);
|
||||
dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset);
|
||||
/*
|
||||
* Search for an rdataset of type 'type' at 'node' that are in version
|
||||
* 'version' of 'db'. If found, make 'rdataset' refer to it.
|
||||
@@ -810,7 +812,9 @@ dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
*
|
||||
* 'rdataset' is a valid, disassociated rdataset.
|
||||
*
|
||||
* 'type' is not SIG, or a meta-RR type such as 'ANY' or 'OPT'.
|
||||
* If 'covers' != 0, 'type' must be SIG.
|
||||
*
|
||||
* 'type' is not a meta-RR type such as 'ANY' or 'OPT'.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
|
@@ -464,11 +464,12 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
|
||||
dns_result_t
|
||||
dns_message_findname(dns_message_t *msg, dns_section_t section,
|
||||
dns_name_t *target, dns_rdatatype_t type,
|
||||
dns_name_t **foundname, dns_rdataset_t **rdataset);
|
||||
dns_rdatatype_t covers, dns_name_t **foundname,
|
||||
dns_rdataset_t **rdataset);
|
||||
/*
|
||||
* Search for a name in the specified section. If it is found, *name is
|
||||
* set to point to the name, and *rdataset is set to point to the found
|
||||
* rdataset (if type is specified as other than dns_rdatatype_any.)
|
||||
* rdataset (if type is specified as other than dns_rdatatype_any).
|
||||
*
|
||||
* Requires:
|
||||
* 'msg' be valid.
|
||||
|
@@ -123,7 +123,7 @@ dns_db_getsoaserial(dns_db_t *db, dns_dbversion_t *ver, isc_uint32_t *serialp)
|
||||
return (result);
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
|
||||
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
|
||||
(isc_stdtime_t) 0, &rdataset);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto freenode;
|
||||
@@ -164,7 +164,7 @@ dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx,
|
||||
return (result);
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
|
||||
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, 0,
|
||||
(isc_stdtime_t) 0, &rdataset);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto freenode;
|
||||
|
114
lib/dns/master.c
114
lib/dns/master.c
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.c,v 1.22 1999/08/05 22:10:23 halley Exp $ */
|
||||
/* $Id: master.c,v 1.23 1999/08/31 22:12:14 halley Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -140,7 +140,7 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
|
||||
isc_mem_t *mctx)
|
||||
{
|
||||
dns_rdataclass_t rdclass;
|
||||
dns_rdatatype_t type;
|
||||
dns_rdatatype_t type, covers;
|
||||
isc_uint32_t ttl = 0;
|
||||
isc_uint32_t default_ttl = 0;
|
||||
isc_uint32_t ttl_offset = 0;
|
||||
@@ -634,58 +634,6 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
|
||||
ttl -= ttl_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find type in rdatalist.
|
||||
* If it does not exit create new one and prepend to list
|
||||
* as this will mimimise list traversal.
|
||||
*/
|
||||
if (in_glue)
|
||||
this = ISC_LIST_HEAD(glue_list);
|
||||
else
|
||||
this = ISC_LIST_HEAD(current_list);
|
||||
|
||||
while (this != NULL) {
|
||||
if (this->type == type)
|
||||
break;
|
||||
this = ISC_LIST_NEXT(this, link);
|
||||
}
|
||||
|
||||
if (this == NULL) {
|
||||
if (rdlcount == rdatalist_size) {
|
||||
new_rdatalist =
|
||||
grow_rdatalist(rdatalist_size + RDLSZ,
|
||||
rdatalist,
|
||||
rdatalist_size,
|
||||
¤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.
|
||||
*/
|
||||
@@ -709,6 +657,64 @@ load(isc_lex_t *lex, dns_name_t *top, dns_name_t *origin,
|
||||
callbacks);
|
||||
if (result != DNS_R_SUCCESS)
|
||||
goto cleanup;
|
||||
if (type == dns_rdatatype_sig)
|
||||
covers = dns_rdata_covers(&rdata[rdcount]);
|
||||
else
|
||||
covers = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Find type in rdatalist.
|
||||
* If it does not exit create new one and prepend to list
|
||||
* as this will mimimise list traversal.
|
||||
*/
|
||||
if (in_glue)
|
||||
this = ISC_LIST_HEAD(glue_list);
|
||||
else
|
||||
this = ISC_LIST_HEAD(current_list);
|
||||
|
||||
while (this != NULL) {
|
||||
if (this->type == type && this->covers == covers)
|
||||
break;
|
||||
this = ISC_LIST_NEXT(this, link);
|
||||
}
|
||||
|
||||
if (this == NULL) {
|
||||
if (rdlcount == rdatalist_size) {
|
||||
new_rdatalist =
|
||||
grow_rdatalist(rdatalist_size + RDLSZ,
|
||||
rdatalist,
|
||||
rdatalist_size,
|
||||
¤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.
|
||||
|
@@ -674,14 +674,15 @@ findname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section)
|
||||
}
|
||||
|
||||
static dns_result_t
|
||||
findtype(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type)
|
||||
findtype(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type,
|
||||
dns_rdatatype_t covers)
|
||||
{
|
||||
dns_rdataset_t *curr;
|
||||
|
||||
for (curr = ISC_LIST_TAIL(name->list) ;
|
||||
curr != NULL ;
|
||||
curr = ISC_LIST_PREV(curr, link)) {
|
||||
if (curr->type == type) {
|
||||
if (curr->type == type && curr->covers == covers) {
|
||||
if (rdataset != NULL)
|
||||
*rdataset = curr;
|
||||
return (DNS_R_SUCCESS);
|
||||
@@ -880,7 +881,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
|
||||
/*
|
||||
* Can't ask the same question twice.
|
||||
*/
|
||||
result = findtype(NULL, name, rdtype);
|
||||
result = findtype(NULL, name, rdtype, 0);
|
||||
if (result == DNS_R_SUCCESS)
|
||||
return (DNS_R_FORMERR);
|
||||
|
||||
@@ -927,7 +928,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_rdatalist_t *rdatalist;
|
||||
dns_result_t result;
|
||||
dns_rdatatype_t rdtype;
|
||||
dns_rdatatype_t rdtype, covers;
|
||||
dns_rdataclass_t rdclass;
|
||||
dns_rdata_t *rdata;
|
||||
dns_ttl_t ttl;
|
||||
@@ -1038,42 +1039,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||
return (DNS_R_FORMERR);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Search name for the particular type and class.
|
||||
* Skip this stage if in update mode, or this is a TSIG.
|
||||
*/
|
||||
if (preserve_order || msg->opcode == dns_opcode_update
|
||||
|| rdtype == dns_rdatatype_tsig)
|
||||
result = DNS_R_NOTFOUND;
|
||||
else
|
||||
result = findtype(&rdataset, name, rdtype);
|
||||
|
||||
/*
|
||||
* If we found an rdataset that matches, we need to
|
||||
* append this rdata to that set. If we did not, we need
|
||||
* to create a new rdatalist, store the important bits there,
|
||||
* convert it to an rdataset, and link the latter to the name.
|
||||
* Yuck.
|
||||
*/
|
||||
if (result == DNS_R_NOTFOUND) {
|
||||
rdataset = newrdataset(msg);
|
||||
if (rdataset == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
rdatalist = newrdatalist(msg);
|
||||
if (rdatalist == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
|
||||
rdatalist->type = rdtype;
|
||||
rdatalist->rdclass = rdclass;
|
||||
rdatalist->ttl = ttl;
|
||||
ISC_LIST_INIT(rdatalist->rdata);
|
||||
|
||||
dns_rdataset_init(rdataset);
|
||||
dns_rdatalist_tordataset(rdatalist, rdataset);
|
||||
|
||||
ISC_LIST_APPEND(name->list, rdataset, link);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the rdata from the wire format. Interpret the
|
||||
* rdata according to its actual class, even if it had a
|
||||
@@ -1093,6 +1058,51 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||
if (result != DNS_R_SUCCESS)
|
||||
return (result);
|
||||
rdata->rdclass = rdclass;
|
||||
if (rdtype == dns_rdatatype_sig && rdata->length > 0)
|
||||
covers = dns_rdata_covers(rdata);
|
||||
else
|
||||
covers = 0;
|
||||
|
||||
/*
|
||||
* Search name for the particular type and class.
|
||||
* Skip this stage if in update mode, or this is a TSIG.
|
||||
*/
|
||||
if (preserve_order || msg->opcode == dns_opcode_update
|
||||
|| rdtype == dns_rdatatype_tsig)
|
||||
result = DNS_R_NOTFOUND;
|
||||
else
|
||||
result = findtype(&rdataset, name, rdtype, covers);
|
||||
|
||||
/*
|
||||
* If we found an rdataset that matches, we need to
|
||||
* append this rdata to that set. If we did not, we need
|
||||
* to create a new rdatalist, store the important bits there,
|
||||
* convert it to an rdataset, and link the latter to the name.
|
||||
* Yuck.
|
||||
*/
|
||||
if (result == DNS_R_NOTFOUND) {
|
||||
rdataset = newrdataset(msg);
|
||||
if (rdataset == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
rdatalist = newrdatalist(msg);
|
||||
if (rdatalist == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
|
||||
rdatalist->type = rdtype;
|
||||
rdatalist->covers = covers;
|
||||
rdatalist->rdclass = rdclass;
|
||||
rdatalist->ttl = ttl;
|
||||
ISC_LIST_INIT(rdatalist->rdata);
|
||||
|
||||
dns_rdataset_init(rdataset);
|
||||
dns_rdatalist_tordataset(rdatalist, rdataset);
|
||||
|
||||
ISC_LIST_APPEND(name->list, rdataset, link);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXXRTH Normalize TTLs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXXMLG Perform a totally ugly hack here to pull
|
||||
@@ -1485,7 +1495,8 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
|
||||
dns_result_t
|
||||
dns_message_findname(dns_message_t *msg, dns_section_t section,
|
||||
dns_name_t *target, dns_rdatatype_t type,
|
||||
dns_name_t **name, dns_rdataset_t **rdataset)
|
||||
dns_rdatatype_t covers, dns_name_t **name,
|
||||
dns_rdataset_t **rdataset)
|
||||
{
|
||||
dns_name_t *foundname;
|
||||
dns_result_t result;
|
||||
@@ -1526,7 +1537,7 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
|
||||
if (type == dns_rdatatype_any)
|
||||
return (DNS_R_SUCCESS);
|
||||
|
||||
result = findtype(rdataset, foundname, type);
|
||||
result = findtype(rdataset, foundname, type, covers);
|
||||
if (result == DNS_R_NOTFOUND)
|
||||
return (DNS_R_NXRDATASET);
|
||||
|
||||
|
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;
|
||||
#endif
|
||||
|
||||
typedef isc_uint32_t rbtdb_rdatatype_t;
|
||||
|
||||
#define RBTDB_RDATATYPE_BASE(type) ((type) & 0xFFFF)
|
||||
#define RBTDB_RDATATYPE_EXT(type) ((type) >> 16)
|
||||
#define RBTDB_RDATATYPE_VALUE(b, e) (((e) << 16) | (b))
|
||||
|
||||
#define RBTDB_RDATATYPE_SIGNXT \
|
||||
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_nxt)
|
||||
#define RBTDB_RDATATYPE_SIGNS \
|
||||
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_ns)
|
||||
#define RBTDB_RDATATYPE_SIGCNAME \
|
||||
RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, dns_rdatatype_cname)
|
||||
|
||||
typedef struct rdatasetheader {
|
||||
/*
|
||||
* Locked by the owning node's lock.
|
||||
*/
|
||||
rbtdb_serial_t serial;
|
||||
dns_ttl_t ttl;
|
||||
dns_rdatatype_t type;
|
||||
rbtdb_rdatatype_t type;
|
||||
isc_uint16_t attributes;
|
||||
dns_trust_t trust;
|
||||
/*
|
||||
@@ -1083,11 +1096,15 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
* Caller must be holding the node lock.
|
||||
*/
|
||||
|
||||
if (rdataset == NULL)
|
||||
return;
|
||||
|
||||
new_reference(rbtdb, node);
|
||||
|
||||
rdataset->methods = &rdataset_methods;
|
||||
rdataset->rdclass = rbtdb->common.rdclass;
|
||||
rdataset->type = header->type;
|
||||
rdataset->type = RBTDB_RDATATYPE_BASE(header->type);
|
||||
rdataset->covers = RBTDB_RDATATYPE_EXT(header->type);
|
||||
rdataset->ttl = header->ttl - now;
|
||||
rdataset->private1 = rbtdb;
|
||||
rdataset->private2 = node;
|
||||
@@ -1116,7 +1133,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
{
|
||||
dns_result_t result;
|
||||
dns_name_t *zcname;
|
||||
dns_rdatatype_t type;
|
||||
rbtdb_rdatatype_t type;
|
||||
dns_rbtnode_t *node;
|
||||
|
||||
/*
|
||||
@@ -1161,7 +1178,7 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
}
|
||||
|
||||
static inline isc_boolean_t
|
||||
valid_glue(rbtdb_search_t *search, dns_name_t *name, dns_rdatatype_t type,
|
||||
valid_glue(rbtdb_search_t *search, dns_name_t *name, rbtdb_rdatatype_t type,
|
||||
dns_rbtnode_t *node)
|
||||
{
|
||||
unsigned char *raw;
|
||||
@@ -1355,10 +1372,11 @@ find_wildcard(rbtdb_search_t *search, dns_rbtnode_t **nodep) {
|
||||
|
||||
static inline isc_result_t
|
||||
find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
dns_name_t *foundname, dns_rdataset_t *rdataset)
|
||||
dns_name_t *foundname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_rbtnode_t *node;
|
||||
rdatasetheader_t *header, *header_next;
|
||||
rdatasetheader_t *header, *header_next, *found, *foundsig;
|
||||
isc_boolean_t empty_node;
|
||||
isc_result_t result;
|
||||
dns_fixedname_t fname, forigin;
|
||||
@@ -1375,14 +1393,15 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
|
||||
found = NULL;
|
||||
foundsig = NULL;
|
||||
empty_node = ISC_TRUE;
|
||||
for (header = node->data;
|
||||
header != NULL;
|
||||
header = header_next) {
|
||||
header_next = header->next;
|
||||
/*
|
||||
* Look for an active, extant rdataset with a
|
||||
* NXT record.
|
||||
* Look for an active, extant NXT or SIG NXT.
|
||||
*/
|
||||
do {
|
||||
if (header->serial <= search->serial &&
|
||||
@@ -1404,12 +1423,20 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
* active rdataset at this node.
|
||||
*/
|
||||
empty_node = ISC_FALSE;
|
||||
if (header->type == dns_rdatatype_nxt)
|
||||
break;
|
||||
if (header->type == dns_rdatatype_nxt) {
|
||||
found = header;
|
||||
if (foundsig != NULL)
|
||||
break;
|
||||
} else if (header->type ==
|
||||
RBTDB_RDATATYPE_SIGNXT) {
|
||||
foundsig = header;
|
||||
if (found != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty_node) {
|
||||
if (header != NULL) {
|
||||
if (found != NULL && foundsig != NULL) {
|
||||
/*
|
||||
* We've found the right NXT record.
|
||||
*
|
||||
@@ -1433,13 +1460,17 @@ find_closest_nxt(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
*nodep = node;
|
||||
}
|
||||
bind_rdataset(search->rbtdb, node,
|
||||
header, search->now,
|
||||
found, search->now,
|
||||
rdataset);
|
||||
bind_rdataset(search->rbtdb, node,
|
||||
foundsig, search->now,
|
||||
sigrdataset);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We found an active node without a NXT
|
||||
* record. This shouldn't happen.
|
||||
* We found an active node, but either the
|
||||
* NXT or the SIG NXT is missing. This
|
||||
* shouldn't happen.
|
||||
*/
|
||||
result = DNS_R_BADDB;
|
||||
}
|
||||
@@ -1493,7 +1524,7 @@ static dns_result_t
|
||||
zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset)
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_rbtnode_t *node = NULL;
|
||||
dns_result_t result;
|
||||
@@ -1505,6 +1536,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
isc_boolean_t wild;
|
||||
isc_boolean_t empty_node;
|
||||
rdatasetheader_t *header, *header_next, *found, *nxtheader;
|
||||
rdatasetheader_t *foundsig, *cnamesig, *nxtsig;
|
||||
rbtdb_rdatatype_t sigtype;
|
||||
|
||||
search.rbtdb = (dns_rbtdb_t *)db;
|
||||
|
||||
@@ -1586,7 +1619,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
*/
|
||||
if (search.rbtdb->secure) {
|
||||
result = find_closest_nxt(&search, nodep, foundname,
|
||||
rdataset);
|
||||
rdataset, sigrdataset);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = DNS_R_NXDOMAIN;
|
||||
} else
|
||||
@@ -1622,11 +1655,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
*
|
||||
* We don't check for SIG, because we don't store SIG records
|
||||
* directly.
|
||||
*
|
||||
* XXX This should be a general purpose subroutine in the rdata
|
||||
* module.
|
||||
*
|
||||
* XXX This 'if' could be an 'else if' of the 'if' above.
|
||||
*/
|
||||
if (type == dns_rdatatype_key || type == dns_rdatatype_nxt)
|
||||
cname_ok = ISC_FALSE;
|
||||
@@ -1638,7 +1666,11 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
LOCK(&(search.rbtdb->node_locks[node->locknum].lock));
|
||||
|
||||
found = NULL;
|
||||
foundsig = NULL;
|
||||
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, type);
|
||||
nxtheader = NULL;
|
||||
nxtsig = NULL;
|
||||
cnamesig = NULL;
|
||||
empty_node = ISC_TRUE;
|
||||
for (header = node->data; header != NULL; header = header_next) {
|
||||
header_next = header->next;
|
||||
@@ -1694,19 +1726,53 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
found = NULL;
|
||||
break;
|
||||
}
|
||||
if (found != NULL)
|
||||
if (found != NULL && foundsig != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found a type we were looking for, we're done.
|
||||
* If we found a type we were looking for,
|
||||
* remember it.
|
||||
*/
|
||||
if (header->type == type ||
|
||||
type == dns_rdatatype_any ||
|
||||
(cname_ok &&
|
||||
header->type == dns_rdatatype_cname)) {
|
||||
(header->type == dns_rdatatype_cname &&
|
||||
cname_ok)) {
|
||||
/*
|
||||
* We've found the answer!
|
||||
*/
|
||||
found = header;
|
||||
if (!maybe_zonecut)
|
||||
if (header->type == dns_rdatatype_cname &&
|
||||
cname_ok) {
|
||||
/*
|
||||
* We may be finding a CNAME instead
|
||||
* of the desired type.
|
||||
*
|
||||
* If we've already got the CNAME SIG,
|
||||
* use it, otherwise change sigtype
|
||||
* so that we find it.
|
||||
*/
|
||||
if (cnamesig != NULL)
|
||||
foundsig = cnamesig;
|
||||
else
|
||||
sigtype =
|
||||
RBTDB_RDATATYPE_SIGCNAME;
|
||||
}
|
||||
/*
|
||||
* If we've got all we need, end the search.
|
||||
*/
|
||||
if (!maybe_zonecut && foundsig != NULL)
|
||||
break;
|
||||
} else if (header->type == sigtype) {
|
||||
/*
|
||||
* We've found the SIG rdataset for our
|
||||
* target type. Remember it.
|
||||
*/
|
||||
foundsig = header;
|
||||
/*
|
||||
* If we've got all we need, end the search.
|
||||
*/
|
||||
if (!maybe_zonecut && found != NULL)
|
||||
break;
|
||||
} else if (header->type == dns_rdatatype_nxt) {
|
||||
/*
|
||||
@@ -1715,6 +1781,19 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* we might need it later.
|
||||
*/
|
||||
nxtheader = header;
|
||||
} else if (header->type == RBTDB_RDATATYPE_SIGNXT) {
|
||||
/*
|
||||
* If we need the NXT rdataset, we'll also
|
||||
* need its signature.
|
||||
*/
|
||||
nxtsig = header;
|
||||
} else if (cname_ok &&
|
||||
header->type == RBTDB_RDATATYPE_SIGCNAME) {
|
||||
/*
|
||||
* If we get a CNAME match, we'll also need
|
||||
* its signature.
|
||||
*/
|
||||
cnamesig = header;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1753,10 +1832,11 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* The desired type doesn't exist.
|
||||
*/
|
||||
result = DNS_R_NXRDATASET;
|
||||
if (search.rbtdb->secure && nxtheader == NULL) {
|
||||
if (search.rbtdb->secure &&
|
||||
(nxtheader == NULL || nxtsig == NULL)) {
|
||||
/*
|
||||
* The zone is secure but there's no NXT
|
||||
* rdataset!
|
||||
* The zone is secure but there's no NXT,
|
||||
* or the NXT has no signature!
|
||||
*/
|
||||
result = DNS_R_BADDB;
|
||||
goto node_exit;
|
||||
@@ -1768,6 +1848,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
if (search.rbtdb->secure) {
|
||||
bind_rdataset(search.rbtdb, node, nxtheader,
|
||||
0, rdataset);
|
||||
bind_rdataset(search.rbtdb, node, nxtsig,
|
||||
0, sigrdataset);
|
||||
}
|
||||
}
|
||||
goto node_exit;
|
||||
@@ -1832,8 +1914,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
*nodep = node;
|
||||
}
|
||||
|
||||
if (rdataset != NULL && type != dns_rdatatype_any)
|
||||
if (type != dns_rdatatype_any) {
|
||||
bind_rdataset(search.rbtdb, node, found, 0, rdataset);
|
||||
if (foundsig != NULL)
|
||||
bind_rdataset(search.rbtdb, node, foundsig, 0,
|
||||
sigrdataset);
|
||||
}
|
||||
|
||||
node_exit:
|
||||
UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));
|
||||
@@ -1882,7 +1968,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
|
||||
LOCK(&(search->rbtdb->node_locks[node->locknum].lock));
|
||||
|
||||
/*
|
||||
* Look for DNAME rdataset.
|
||||
* Look for a DNAME rdataset.
|
||||
*/
|
||||
header_prev = NULL;
|
||||
for (header = node->data; header != NULL; header = header_next) {
|
||||
@@ -1938,11 +2024,13 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
|
||||
|
||||
static inline dns_result_t
|
||||
find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
dns_name_t *foundname, dns_rdataset_t *rdataset)
|
||||
dns_name_t *foundname, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
unsigned int i;
|
||||
dns_rbtnode_t *node, *level_node;
|
||||
rdatasetheader_t *header, *header_prev, *header_next;
|
||||
rdatasetheader_t *found, *foundsig;
|
||||
dns_result_t result = DNS_R_NOTFOUND;
|
||||
dns_name_t name;
|
||||
dns_rbtdb_t *rbtdb;
|
||||
@@ -1960,8 +2048,10 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
LOCK(&(rbtdb->node_locks[node->locknum].lock));
|
||||
|
||||
/*
|
||||
* Look for NS rdataset.
|
||||
* Look for NS and SIG NS rdatasets.
|
||||
*/
|
||||
found = NULL;
|
||||
foundsig = NULL;
|
||||
header_prev = NULL;
|
||||
for (header = node->data;
|
||||
header != NULL;
|
||||
@@ -1990,15 +2080,28 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
node->dirty = 1;
|
||||
header_prev = header;
|
||||
}
|
||||
} else if (header->type == dns_rdatatype_ns &&
|
||||
(header->attributes &
|
||||
RDATASET_ATTR_NONEXISTENT) == 0)
|
||||
break;
|
||||
else
|
||||
} else if ((header->attributes &
|
||||
RDATASET_ATTR_NONEXISTENT) == 0) {
|
||||
/*
|
||||
* We've found an extant rdataset. See if
|
||||
* we're interested in it.
|
||||
*/
|
||||
if (header->type == dns_rdatatype_ns) {
|
||||
found = header;
|
||||
if (foundsig != NULL)
|
||||
break;
|
||||
} else if (header->type ==
|
||||
RBTDB_RDATATYPE_SIGNS) {
|
||||
foundsig = header;
|
||||
if (found != NULL)
|
||||
break;
|
||||
}
|
||||
header_prev = header;
|
||||
} else
|
||||
header_prev = header;
|
||||
}
|
||||
|
||||
if (header != NULL) {
|
||||
if (found != NULL) {
|
||||
/*
|
||||
* If we have to set foundname, we do it before
|
||||
* anything else. If we were to set foundname after
|
||||
@@ -2034,15 +2137,17 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_dbnode_t **nodep,
|
||||
new_reference(search->rbtdb, node);
|
||||
*nodep = node;
|
||||
}
|
||||
if (rdataset != NULL)
|
||||
bind_rdataset(search->rbtdb, node, header,
|
||||
search->now, rdataset);
|
||||
bind_rdataset(search->rbtdb, node, found, search->now,
|
||||
rdataset);
|
||||
if (foundsig != NULL)
|
||||
bind_rdataset(search->rbtdb, node, foundsig,
|
||||
search->now, sigrdataset);
|
||||
}
|
||||
|
||||
node_exit:
|
||||
UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock));
|
||||
|
||||
if (header != NULL)
|
||||
if (found != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2053,7 +2158,7 @@ static dns_result_t
|
||||
cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
|
||||
dns_dbnode_t **nodep, dns_name_t *foundname,
|
||||
dns_rdataset_t *rdataset)
|
||||
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
dns_rbtnode_t *node = NULL;
|
||||
dns_result_t result;
|
||||
@@ -2061,7 +2166,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
isc_boolean_t cname_ok = ISC_TRUE;
|
||||
isc_boolean_t empty_node;
|
||||
rdatasetheader_t *header, *header_prev, *header_next;
|
||||
rdatasetheader_t *found, *nsheader, *nxtheader;
|
||||
rdatasetheader_t *found, *nsheader;
|
||||
rdatasetheader_t *foundsig, *nssig, *cnamesig;
|
||||
rbtdb_rdatatype_t sigtype;
|
||||
|
||||
/*
|
||||
* XXXRTH Currently this code has no support for negative caching.
|
||||
@@ -2110,7 +2217,8 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
} else {
|
||||
find_ns:
|
||||
result = find_deepest_zonecut(&search, nodep,
|
||||
foundname, rdataset);
|
||||
foundname, rdataset,
|
||||
sigrdataset);
|
||||
goto tree_exit;
|
||||
}
|
||||
} else if (result != DNS_R_SUCCESS)
|
||||
@@ -2120,14 +2228,10 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* Certain DNSSEC types are not subject to CNAME matching
|
||||
* (RFC 2535, section 2.3.5).
|
||||
*
|
||||
* XXX This should be a general purpose subroutine in the rdata
|
||||
* module.
|
||||
*
|
||||
* XXX This 'if' could be an 'else if' of the 'if' above.
|
||||
* We don't check for SIG, because we don't store SIG records
|
||||
* directly.
|
||||
*/
|
||||
if (type == dns_rdatatype_key ||
|
||||
type == dns_rdatatype_sig ||
|
||||
type == dns_rdatatype_nxt)
|
||||
if (type == dns_rdatatype_key || type == dns_rdatatype_nxt)
|
||||
cname_ok = ISC_FALSE;
|
||||
|
||||
/*
|
||||
@@ -2137,8 +2241,11 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
LOCK(&(search.rbtdb->node_locks[node->locknum].lock));
|
||||
|
||||
found = NULL;
|
||||
foundsig = NULL;
|
||||
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_sig, type);
|
||||
nsheader = NULL;
|
||||
nxtheader = NULL;
|
||||
nssig = NULL;
|
||||
cnamesig = NULL;
|
||||
empty_node = ISC_TRUE;
|
||||
header_prev = NULL;
|
||||
for (header = node->data; header != NULL; header = header_next) {
|
||||
@@ -2172,13 +2279,33 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
empty_node = ISC_FALSE;
|
||||
|
||||
/*
|
||||
* If we found a type we were looking for, we're done.
|
||||
* If we found a type we were looking for, remember
|
||||
* it.
|
||||
*/
|
||||
if (header->type == type ||
|
||||
type == dns_rdatatype_any ||
|
||||
(cname_ok && header->type ==
|
||||
dns_rdatatype_cname)) {
|
||||
/*
|
||||
* We've found the answer.
|
||||
*/
|
||||
found = header;
|
||||
if (header->type == dns_rdatatype_cname &&
|
||||
cname_ok &&
|
||||
cnamesig != NULL) {
|
||||
/*
|
||||
* We may be finding a CNAME instead
|
||||
* of the desired type. If so, we
|
||||
* need to return the CNAME's SIG.
|
||||
*/
|
||||
foundsig = cnamesig;
|
||||
}
|
||||
} else if (header->type == sigtype) {
|
||||
/*
|
||||
* We've found the SIG rdataset for our
|
||||
* target type. Remember it.
|
||||
*/
|
||||
foundsig = header;
|
||||
} else if (header->type == dns_rdatatype_ns) {
|
||||
/*
|
||||
* Remember a NS rdataset even if we're
|
||||
@@ -2186,13 +2313,19 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* we might need it later.
|
||||
*/
|
||||
nsheader = header;
|
||||
} else if (header->type == dns_rdatatype_nxt) {
|
||||
} else if (header->type == RBTDB_RDATATYPE_SIGNS) {
|
||||
/*
|
||||
* Remember a NXT rdataset even if we're
|
||||
* not specifically looking for it, because
|
||||
* we might need it later.
|
||||
* If we need the NS rdataset, we'll also
|
||||
* need its signature.
|
||||
*/
|
||||
nxtheader = header;
|
||||
nssig = header;
|
||||
} else if (cname_ok &&
|
||||
header->type == RBTDB_RDATATYPE_SIGCNAME) {
|
||||
/*
|
||||
* If we get a CNAME match, we'll also need
|
||||
* its signature.
|
||||
*/
|
||||
cnamesig = header;
|
||||
}
|
||||
header_prev = header;
|
||||
} else
|
||||
@@ -2213,13 +2346,6 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* If we didn't find what we were looking for...
|
||||
*/
|
||||
if (found == NULL) {
|
||||
/*
|
||||
* XXXDNSSEC If we found an NXT record for this name, we
|
||||
* can tell whether the desired type exists or not. We don't
|
||||
* yet try to use the NXT that way, but this is the place to
|
||||
* do it.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If there is an NS rdataset at this node, then this is the
|
||||
* deepest zone cut.
|
||||
@@ -2229,6 +2355,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
*nodep = node;
|
||||
bind_rdataset(search.rbtdb, node, nsheader, search.now,
|
||||
rdataset);
|
||||
if (nssig != NULL)
|
||||
bind_rdataset(search.rbtdb, node, nssig,
|
||||
search.now, sigrdataset);
|
||||
result = DNS_R_DELEGATION;
|
||||
goto node_exit;
|
||||
}
|
||||
@@ -2265,9 +2394,13 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
result = DNS_R_SUCCESS;
|
||||
}
|
||||
|
||||
if (rdataset != NULL && type != dns_rdatatype_any)
|
||||
if (type != dns_rdatatype_any) {
|
||||
bind_rdataset(search.rbtdb, node, found, search.now,
|
||||
rdataset);
|
||||
if (foundsig != NULL)
|
||||
bind_rdataset(search.rbtdb, node, foundsig, search.now,
|
||||
sigrdataset);
|
||||
}
|
||||
|
||||
node_exit:
|
||||
UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock));
|
||||
@@ -2428,8 +2561,8 @@ createiterator(dns_db_t *db, isc_boolean_t relative_names,
|
||||
|
||||
static dns_result_t
|
||||
zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, isc_stdtime_t now,
|
||||
dns_rdataset_t *rdataset)
|
||||
dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset)
|
||||
{
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
|
||||
@@ -2437,6 +2570,7 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
rbtdb_serial_t serial;
|
||||
rbtdb_version_t *rbtversion = version;
|
||||
isc_boolean_t close_version = ISC_FALSE;
|
||||
rbtdb_rdatatype_t matchtype;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
REQUIRE(type != dns_rdatatype_any);
|
||||
@@ -2449,8 +2583,9 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
|
||||
LOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
|
||||
|
||||
matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
|
||||
for (header = rbtnode->data; header != NULL; header = header->next) {
|
||||
if (header->type == type) {
|
||||
if (header->type == matchtype) {
|
||||
do {
|
||||
if (header->serial <= serial &&
|
||||
!IGNORE(header)) {
|
||||
@@ -2484,12 +2619,13 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
|
||||
static dns_result_t
|
||||
cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
dns_rdatatype_t type, isc_stdtime_t now,
|
||||
dns_rdataset_t *rdataset)
|
||||
dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset)
|
||||
{
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
|
||||
rdatasetheader_t *header, *header_next, *found;
|
||||
rbtdb_rdatatype_t matchtype;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
REQUIRE(type != dns_rdatatype_any);
|
||||
@@ -2507,6 +2643,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
LOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
|
||||
|
||||
found = NULL;
|
||||
matchtype = RBTDB_RDATATYPE_VALUE(type, covers);
|
||||
for (header = rbtnode->data; header != NULL; header = header_next) {
|
||||
header_next = header->next;
|
||||
if (header->ttl <= now) {
|
||||
@@ -2518,7 +2655,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
*/
|
||||
header->attributes |= RDATASET_ATTR_STALE;
|
||||
rbtnode->dirty = 1;
|
||||
} else if (header->type == type &&
|
||||
} else if (header->type == matchtype &&
|
||||
(header->attributes & RDATASET_ATTR_NONEXISTENT) ==
|
||||
0) {
|
||||
found = header;
|
||||
@@ -2793,7 +2930,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
|
||||
static inline isc_boolean_t
|
||||
delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
dns_rdatatype_t type)
|
||||
rbtdb_rdatatype_t type)
|
||||
{
|
||||
if ((rbtdb->common.attributes & DNS_DBATTR_CACHE) != 0 &&
|
||||
type == dns_rdatatype_dname)
|
||||
@@ -2833,7 +2970,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
|
||||
newheader = (rdatasetheader_t *)region.base;
|
||||
newheader->ttl = rdataset->ttl + now;
|
||||
newheader->type = rdataset->type;
|
||||
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
|
||||
rdataset->covers);
|
||||
newheader->attributes = 0;
|
||||
if (rbtversion != NULL) {
|
||||
newheader->serial = rbtversion->serial;
|
||||
@@ -2893,7 +3031,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
return (result);
|
||||
newheader = (rdatasetheader_t *)region.base;
|
||||
newheader->ttl = 0;
|
||||
newheader->type = rdataset->type;
|
||||
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
|
||||
rdataset->covers);
|
||||
newheader->attributes = 0;
|
||||
newheader->serial = rbtversion->serial;
|
||||
newheader->trust = 0;
|
||||
@@ -3007,14 +3146,14 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
|
||||
if (type == dns_rdatatype_any)
|
||||
if (type == dns_rdatatype_any || type == dns_rdatatype_sig)
|
||||
return (DNS_R_NOTIMPLEMENTED);
|
||||
|
||||
newheader = isc_mem_get(rbtdb->common.mctx, sizeof *newheader);
|
||||
if (newheader == NULL)
|
||||
return (DNS_R_NOMEMORY);
|
||||
newheader->ttl = 0;
|
||||
newheader->type = type;
|
||||
newheader->type = RBTDB_RDATATYPE_VALUE(type, 0);
|
||||
newheader->attributes = RDATASET_ATTR_NONEXISTENT;
|
||||
newheader->trust = 0;
|
||||
if (rbtversion != NULL)
|
||||
@@ -3092,7 +3231,8 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
|
||||
return (result);
|
||||
newheader = (rdatasetheader_t *)region.base;
|
||||
newheader->ttl = rdataset->ttl + loadctx->now; /* XXX overflow check */
|
||||
newheader->type = rdataset->type;
|
||||
newheader->type = RBTDB_RDATATYPE_VALUE(rdataset->type,
|
||||
rdataset->covers);
|
||||
newheader->attributes = 0;
|
||||
newheader->trust = rdataset->trust;
|
||||
newheader->serial = 1;
|
||||
@@ -3595,7 +3735,7 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
|
||||
rdatasetheader_t *header, *top_next;
|
||||
rbtdb_serial_t serial;
|
||||
isc_stdtime_t now;
|
||||
dns_rdatatype_t type;
|
||||
rbtdb_rdatatype_t type;
|
||||
|
||||
header = rbtiterator->current;
|
||||
if (header == NULL)
|
||||
|
@@ -34,7 +34,7 @@ static dns_rdatasetmethods_t methods = {
|
||||
first,
|
||||
next,
|
||||
current,
|
||||
clone
|
||||
clone,
|
||||
};
|
||||
|
||||
dns_result_t
|
||||
@@ -52,6 +52,7 @@ dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
|
||||
rdataset->methods = &methods;
|
||||
rdataset->rdclass = rdatalist->rdclass;
|
||||
rdataset->type = rdatalist->type;
|
||||
rdataset->covers = rdatalist->covers;
|
||||
rdataset->ttl = rdatalist->ttl;
|
||||
rdataset->private1 = rdatalist;
|
||||
rdataset->private2 = NULL;
|
||||
|
@@ -44,6 +44,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) {
|
||||
rdataset->type = 0;
|
||||
rdataset->ttl = 0;
|
||||
rdataset->trust = 0;
|
||||
rdataset->covers = 0;
|
||||
rdataset->attributes = 0;
|
||||
rdataset->private1 = NULL;
|
||||
rdataset->private2 = NULL;
|
||||
@@ -68,6 +69,7 @@ dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
|
||||
rdataset->type = 0;
|
||||
rdataset->ttl = 0;
|
||||
rdataset->trust = 0;
|
||||
rdataset->covers = 0;
|
||||
rdataset->attributes = 0;
|
||||
rdataset->private1 = NULL;
|
||||
rdataset->private2 = NULL;
|
||||
@@ -93,6 +95,7 @@ dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
|
||||
rdataset->type = 0;
|
||||
rdataset->ttl = 0;
|
||||
rdataset->trust = 0;
|
||||
rdataset->covers = 0;
|
||||
rdataset->attributes = 0;
|
||||
rdataset->private1 = NULL;
|
||||
rdataset->private2 = NULL;
|
||||
@@ -146,7 +149,7 @@ static dns_rdatasetmethods_t question_methods = {
|
||||
question_cursor,
|
||||
question_cursor,
|
||||
question_current,
|
||||
question_clone
|
||||
question_clone,
|
||||
};
|
||||
|
||||
void
|
||||
|
Reference in New Issue
Block a user