+17 February 2010: Wouter
+ - Disregard DNSKEY from authority section for chain of trust.
+ DS records that are irrelevant to a referral scrubbed. Anti-poison.
+ - iana portlist updated.
+
16 February 2010: Wouter
- Check for 'no space left on device' (or other errors) when
writing updated autotrust anchors and print errno to log.
else *c = c2;
return 1;
}
+
+void
+iter_scrub_ds(struct ub_packed_rrset_key* ns, struct dns_msg* msg)
+{
+ /* 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.
+ * 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));
+ memmove(msg->rep->rrsets+i, msg->rep->rrsets+i+1,
+ sizeof(struct ub_packed_rrset_key*) *
+ (msg->rep->rrset_count-i-1));
+ msg->rep->ns_numrrsets--;
+ msg->rep->rrset_count--;
+ /* stay at same i, but new record */
+ continue;
+ }
+ i++;
+ }
+}
struct reply_info;
struct module_qstate;
struct sock_list;
+struct ub_packed_rrset_key;
/**
* Process config options and set iterator module state.
int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
uint16_t* c);
+/**
+ * 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.
+ */
+void iter_scrub_ds(struct ub_packed_rrset_key* ns, struct dns_msg* msg);
+
#endif /* ITERATOR_ITER_UTILS_H */
|| !dname_subdomain_c(iq->qchase.qname, ns->rk.dname)){
verbose(VERB_ALGO, "bad referral, throwaway");
type = RESPONSE_TYPE_THROWAWAY;
- }
+ } else
+ iter_scrub_ds(ns, iq->response);
}
/* handle each of the type cases */
* see if that equals the query name... */
&& ( /* auth section, but sometimes in answer section*/
reply_find_rrset_section_ns(iq->response->rep,
- qstate->qinfo.qname, qstate->qinfo.qname_len,
- LDNS_RR_TYPE_NS, qstate->qinfo.qclass)
+ iq->qchase.qname, iq->qchase.qname_len,
+ LDNS_RR_TYPE_NS, iq->qchase.qclass)
|| reply_find_rrset_section_an(iq->response->rep,
- qstate->qinfo.qname, qstate->qinfo.qname_len,
- LDNS_RR_TYPE_NS, qstate->qinfo.qclass)
+ iq->qchase.qname, iq->qchase.qname_len,
+ LDNS_RR_TYPE_NS, iq->qchase.qclass)
)
)) {
/* Store the referral under the current query */
struct packed_rrset_data *d = (struct packed_rrset_data*)
rrset->entry.data;
if(d->trust != rrset_trust_add_noAA &&
- d->trust != rrset_trust_add_AA) {
+ d->trust != rrset_trust_add_AA &&
+ (qtype == LDNS_RR_TYPE_DS ||
+ (d->trust != rrset_trust_auth_noAA
+ && d->trust != rrset_trust_auth_AA) )) {
struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
if(msg) {
lock_rw_unlock(&rrset->entry.lock);
7025,
7030,
7070,
+7071,
7080,
7099,
7100,