From 9637357a7765cc63ae401e02c727b1202f20bc08 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Wed, 8 Sep 1999 01:10:26 +0000 Subject: [PATCH] a6 chains in additional data --- bin/named/query.c | 163 ++++++++++++++++++++++++++++++++------------- bin/named/update.c | 4 +- 2 files changed, 117 insertions(+), 50 deletions(-) diff --git a/bin/named/query.c b/bin/named/query.c index 275c1aa025..3f9ad56820 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -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; diff --git a/bin/named/update.c b/bin/named/update.c index d83d0b0cb2..1598fb5baf 100644 --- a/bin/named/update.c +++ b/bin/named/update.c @@ -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);