diff --git a/CHANGES b/CHANGES index cd3161f050..a880e73f11 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3904. [func] Add the RPZ SOA to the additional section. [RT36507] + 3903. [bug] Improve the accuracy of DiG's reported round trip time. [RT 36611] diff --git a/bin/named/query.c b/bin/named/query.c index 5259232152..91c0d7b971 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -2542,11 +2542,12 @@ query_addrrset(ns_client_t *client, dns_name_t **namep, if (result == ISC_R_SUCCESS) { /* * We've already got an RRset of the given name and type. - * There's nothing else to do; */ CTRACE("query_addrrset: dns_message_findname succeeded: done"); if (dbuf != NULL) query_releasename(client, namep); + if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) + mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED; return; } else if (result == DNS_R_NXDOMAIN) { /* @@ -2586,7 +2587,8 @@ query_addrrset(ns_client_t *client, dns_name_t **namep, static inline isc_result_t query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, - unsigned int override_ttl, isc_boolean_t isassociated) + unsigned int override_ttl, isc_boolean_t isassociated, + dns_section_t section) { dns_name_t *name; dns_dbnode_t *node; @@ -2693,8 +2695,11 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, sigrdatasetp = &sigrdataset; else sigrdatasetp = NULL; + + if (section == DNS_SECTION_ADDITIONAL) + rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, - DNS_SECTION_AUTHORITY); + section); } cleanup: @@ -5621,7 +5626,7 @@ answer_in_glue(ns_client_t *client, dns_rdatatype_t qtype) { ISC_LIST_PREPEND(msg->sections[section], name, link); ISC_LIST_UNLINK(name->list, rdataset, link); ISC_LIST_PREPEND(name->list, rdataset, link); - rdataset->attributes |= DNS_RDATASETATTR_REQUIREDGLUE; + rdataset->attributes |= DNS_RDATASETATTR_REQUIRED; } } @@ -6088,6 +6093,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) isc_boolean_t nxrewrite = ISC_FALSE; dns_clientinfomethods_t cm; dns_clientinfo_t ci; + isc_boolean_t associated; + dns_section_t section; + dns_ttl_t ttl; CTRACE("query_find"); @@ -7142,17 +7150,18 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) } /* - * Add SOA if NXRRSET was not generated by RPZ rewrite + * Add SOA to the additional section if generated by a RPZ + * rewrite. */ - if (!nxrewrite) { - isc_boolean_t associated = - dns_rdataset_isassociated(rdataset); - result = query_addsoa(client, db, version, - ISC_UINT32_MAX, associated); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(result); - goto cleanup; - } + associated = dns_rdataset_isassociated(rdataset); + section = nxrewrite ? DNS_SECTION_ADDITIONAL : + DNS_SECTION_AUTHORITY; + + result = query_addsoa(client, db, version, ISC_UINT32_MAX, + associated, section); + if (result != ISC_R_SUCCESS) { + QUERY_ERROR(result); + goto cleanup; } /* @@ -7193,21 +7202,23 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) } /* - * Add SOA if NXDOMAIN was not generated by RPZ rewrite. + * Add SOA to the additional section if generated by a + * RPZ rewrite. * * If the query was for a SOA record force the * ttl to zero so that it is possible for clients to find * the containing zone of an arbitrary name with a stub * resolver and not have it cached. */ + associated = dns_rdataset_isassociated(rdataset); + section = nxrewrite ? DNS_SECTION_ADDITIONAL : + DNS_SECTION_AUTHORITY; + ttl = ISC_UINT32_MAX; if (!nxrewrite && qtype == dns_rdatatype_soa && zone != NULL && dns_zone_getzeronosoattl(zone)) - result = query_addsoa(client, db, version, 0, - dns_rdataset_isassociated(rdataset)); - else if (!nxrewrite) - result = query_addsoa(client, db, version, - ISC_UINT32_MAX, - dns_rdataset_isassociated(rdataset)); + ttl = 0; + result = query_addsoa(client, db, version, ttl, associated, + section); if (result != ISC_R_SUCCESS) { QUERY_ERROR(result); goto cleanup; @@ -7925,7 +7936,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) * Add a fake SOA record. */ (void)query_addsoa(client, db, version, - 600, ISC_FALSE); + 600, ISC_FALSE, + DNS_SECTION_AUTHORITY); goto cleanup; } #endif diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index ef024b0099..37b970611f 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -199,7 +199,8 @@ struct dns_rdataset { #define DNS_RDATASETATTR_NXDOMAIN 0x00002000 #define DNS_RDATASETATTR_NOQNAME 0x00004000 #define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */ -#define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000 +#define DNS_RDATASETATTR_REQUIRED 0x00010000 +#define DNS_RDATASETATTR_REQUIREDGLUE DNS_RDATASETATTR_REQUIRED #define DNS_RDATASETATTR_LOADORDER 0x00020000 #define DNS_RDATASETATTR_RESIGN 0x00040000 #define DNS_RDATASETATTR_CLOSEST 0x00080000 diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 4a571c5ae0..411cac12c4 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -5956,7 +5956,7 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, "unrelated %s %s in " "%s authority section", tbuf, qbuf, nbuf); - return (DNS_R_FORMERR); + goto nextname; } if (type == dns_rdatatype_ns) { /* @@ -6019,6 +6019,7 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, } } } + nextname: result = dns_message_nextname(message, section); if (result == ISC_R_NOMORE) break;