a6 chains in additional data
This commit is contained in:
@@ -408,6 +408,29 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
|
||||
return (result);
|
||||
}
|
||||
|
||||
static inline isc_boolean_t
|
||||
query_isduplicate(ns_client_t *client, dns_name_t *name,
|
||||
dns_rdatatype_t type)
|
||||
{
|
||||
dns_section_t section;
|
||||
dns_name_t *mname;
|
||||
|
||||
for (section = DNS_SECTION_ANSWER;
|
||||
section <= DNS_SECTION_ADDITIONAL;
|
||||
section++) {
|
||||
mname = NULL;
|
||||
if (dns_message_findname(client->message, section,
|
||||
name, type, 0, &mname, NULL) ==
|
||||
ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We've already got this RRset in the response.
|
||||
*/
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
|
||||
@@ -415,9 +438,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
|
||||
isc_result_t result, eresult;
|
||||
dns_dbnode_t *node;
|
||||
dns_db_t *db;
|
||||
dns_name_t *fname, *mname;
|
||||
dns_rdataset_t *rdataset, *sigrdataset;
|
||||
dns_section_t section;
|
||||
dns_name_t *fname;
|
||||
dns_rdataset_t *rdataset, *sigrdataset, *a6rdataset;
|
||||
isc_buffer_t *dbuf;
|
||||
isc_buffer_t b;
|
||||
dns_dbversion_t *version;
|
||||
@@ -438,6 +460,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
|
||||
fname = NULL;
|
||||
rdataset = NULL;
|
||||
sigrdataset = NULL;
|
||||
a6rdataset = NULL;
|
||||
db = NULL;
|
||||
version = NULL;
|
||||
node = NULL;
|
||||
@@ -485,35 +508,88 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Suppress duplicates.
|
||||
*/
|
||||
for (section = DNS_SECTION_ANSWER;
|
||||
section <= DNS_SECTION_ADDITIONAL;
|
||||
section++) {
|
||||
mname = NULL;
|
||||
result = dns_message_findname(client->message, section,
|
||||
fname, type, 0, &mname, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We've already got this RRset in the response.
|
||||
*/
|
||||
goto cleanup;
|
||||
query_keepname(client, fname, dbuf);
|
||||
|
||||
if (!query_isduplicate(client, fname, type)) {
|
||||
ISC_LIST_APPEND(fname->list, rdataset, link);
|
||||
rdataset = NULL;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (sigrdataset->methods != NULL) {
|
||||
ISC_LIST_APPEND(fname->list, sigrdataset, link);
|
||||
sigrdataset = NULL;
|
||||
}
|
||||
}
|
||||
query_keepname(client, fname, dbuf);
|
||||
ISC_LIST_APPEND(fname->list, rdataset, link);
|
||||
rdataset = NULL;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (sigrdataset->methods != NULL) {
|
||||
ISC_LIST_APPEND(fname->list, sigrdataset, link);
|
||||
sigrdataset = NULL;
|
||||
|
||||
if (type == dns_rdatatype_a) {
|
||||
/*
|
||||
* We treat type A additional section processing as if it
|
||||
* were "any address type" additional section processing.
|
||||
*
|
||||
* We now go looking for A6 and AAAA records, along with
|
||||
* their signatures.
|
||||
*
|
||||
* XXXRTH This code could be more efficient.
|
||||
*/
|
||||
if (rdataset != NULL) {
|
||||
if (rdataset->methods != NULL)
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
} else {
|
||||
rdataset = query_newrdataset(client);
|
||||
if (rdataset == NULL)
|
||||
goto addname;
|
||||
}
|
||||
if (sigrdataset != NULL) {
|
||||
if (sigrdataset->methods != NULL)
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
} else {
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (sigrdataset == NULL)
|
||||
goto addname;
|
||||
}
|
||||
result = dns_db_findrdataset(db, node, version,
|
||||
dns_rdatatype_a6, 0,
|
||||
client->requesttime, rdataset,
|
||||
sigrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (!query_isduplicate(client, fname,
|
||||
dns_rdatatype_a6)) {
|
||||
a6rdataset = rdataset;
|
||||
ISC_LIST_APPEND(fname->list, rdataset, link);
|
||||
if (sigrdataset->methods != NULL) {
|
||||
ISC_LIST_APPEND(fname->list,
|
||||
sigrdataset, link);
|
||||
sigrdataset =
|
||||
query_newrdataset(client);
|
||||
}
|
||||
rdataset = query_newrdataset(client);
|
||||
if (rdataset == NULL || sigrdataset == NULL)
|
||||
goto addname;
|
||||
} else
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
}
|
||||
result = dns_db_findrdataset(db, node, version,
|
||||
dns_rdatatype_aaaa, 0,
|
||||
client->requesttime, rdataset,
|
||||
sigrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (!query_isduplicate(client, fname,
|
||||
dns_rdatatype_aaaa)) {
|
||||
ISC_LIST_APPEND(fname->list, rdataset, link);
|
||||
if (sigrdataset->methods != NULL) {
|
||||
ISC_LIST_APPEND(fname->list,
|
||||
sigrdataset, link);
|
||||
sigrdataset = NULL;
|
||||
}
|
||||
rdataset = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addname:
|
||||
dns_message_addname(client->message, fname, DNS_SECTION_ADDITIONAL);
|
||||
fname = NULL;
|
||||
|
||||
@@ -550,6 +626,14 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t type) {
|
||||
client);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we added an A6 rdataset, we should also add everything we
|
||||
* know about the A6 chains. We wait until now to do this so that
|
||||
* they'll come after any additional data added above.
|
||||
*/
|
||||
if (a6rdataset != NULL)
|
||||
dns_a6_foreach(&client->query.a6ctx, a6rdataset);
|
||||
|
||||
cleanup:
|
||||
if (sigrdataset != NULL) {
|
||||
if (sigrdataset->methods != NULL)
|
||||
@@ -578,9 +662,7 @@ query_adda6rrset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset,
|
||||
ns_client_t *client = arg;
|
||||
dns_rdataset_t *crdataset, *csigrdataset;
|
||||
isc_buffer_t b, *dbuf;
|
||||
dns_name_t *fname, *mname;
|
||||
dns_section_t section;
|
||||
isc_result_t result;
|
||||
dns_name_t *fname;
|
||||
|
||||
/*
|
||||
* Add an rrset to the additional data section.
|
||||
@@ -610,23 +692,8 @@ query_adda6rrset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset,
|
||||
if (sigrdataset->methods != NULL)
|
||||
dns_rdataset_clone(sigrdataset, csigrdataset);
|
||||
|
||||
/*
|
||||
* Suppress duplicates.
|
||||
*/
|
||||
for (section = DNS_SECTION_ANSWER;
|
||||
section <= DNS_SECTION_ADDITIONAL;
|
||||
section++) {
|
||||
mname = NULL;
|
||||
result = dns_message_findname(client->message, section,
|
||||
fname, crdataset->type, 0,
|
||||
&mname, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We've already got this RRset in the response.
|
||||
*/
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (query_isduplicate(client, fname, crdataset->type))
|
||||
goto cleanup;
|
||||
query_keepname(client, fname, dbuf);
|
||||
ISC_LIST_APPEND(fname->list, crdataset, link);
|
||||
crdataset = NULL;
|
||||
|
||||
@@ -296,7 +296,7 @@ foreach_rr(dns_db_t *db,
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
result = dns_db_findrdataset(db, node, ver, type, covers,
|
||||
(isc_stdtime_t) 0, &rdataset);
|
||||
(isc_stdtime_t) 0, &rdataset, NULL);
|
||||
if (result == DNS_R_NOTFOUND) {
|
||||
result = DNS_R_SUCCESS;
|
||||
goto cleanup_node;
|
||||
@@ -660,7 +660,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,
|
||||
covers, (isc_stdtime_t) 0,
|
||||
&rdataset);
|
||||
&rdataset, NULL);
|
||||
if (result != DNS_R_SUCCESS) {
|
||||
dns_db_detachnode(db, &node);
|
||||
return (DNS_R_NXRRSET);
|
||||
|
||||
Reference in New Issue
Block a user