}
void
-iter_scrub_ds(struct ub_packed_rrset_key* ns, struct dns_msg* msg)
+iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z)
{
/* Only the DS record for the delegation itself is expected.
* We allow DS for everything between the bailiwick and the
* zonecut, thus DS records must be at or above the zonecut.
+ * And the DS records must be below the server authority zone.
* The answer section is already scrubbed. */
size_t i = msg->rep->an_numrrsets;
while(i < (msg->rep->an_numrrsets + msg->rep->ns_numrrsets)) {
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_DS &&
- !dname_subdomain_c(ns->rk.dname, s->rk.dname)) {
- log_nametypeclass(VERB_ALGO, "removing irrelevant DS "
- "from referral", s->rk.dname,
- ntohs(s->rk.type), ntohs(s->rk.rrset_class));
+ (!ns || !dname_subdomain_c(ns->rk.dname, s->rk.dname)
+ || query_dname_compare(z, s->rk.dname) == 0)) {
+ log_nametypeclass(VERB_ALGO, "removing irrelevant DS",
+ s->rk.dname, ntohs(s->rk.type),
+ ntohs(s->rk.rrset_class));
memmove(msg->rep->rrsets+i, msg->rep->rrsets+i+1,
sizeof(struct ub_packed_rrset_key*) *
(msg->rep->rrset_count-i-1));
/**
* Remove DS records that are inappropriate before they are cached.
- * @param ns: RRSET that is the NS record for the referral.
* @param msg: the response to scrub.
+ * @param ns: RRSET that is the NS record for the referral.
+ * if NULL, then all DS records are removed from the authority section.
+ * @param z: zone name that the response is from.
*/
-void iter_scrub_ds(struct ub_packed_rrset_key* ns, struct dns_msg* msg);
+void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
+ uint8_t* z);
#endif /* ITERATOR_ITER_UTILS_H */
verbose(VERB_ALGO, "bad referral, throwaway");
type = RESPONSE_TYPE_THROWAWAY;
} else
- iter_scrub_ds(ns, iq->response);
- }
+ iter_scrub_ds(iq->response, ns, iq->dp->name);
+ } else iter_scrub_ds(iq->response, NULL, NULL);
/* handle each of the type cases */
if(type == RESPONSE_TYPE_ANSWER) {