+18 April 2019: Ralph
+ - Scrub RRs from answer section when reusing NXDOMAIN message for
+ subdomain answers.
+ - For harden-below-nxdomain: do not consider a name to be non-exitent
+ when message contains a CNAME record.
+
18 April 2019: Wouter
- travis build file.
}
}
+void
+iter_scrub_nxdomain(struct dns_msg* msg)
+{
+ if(msg->rep->an_numrrsets == 0)
+ return;
+
+ memmove(msg->rep->rrsets, msg->rep->rrsets+msg->rep->an_numrrsets,
+ sizeof(struct ub_packed_rrset_key*) *
+ (msg->rep->rrset_count-msg->rep->an_numrrsets));
+ msg->rep->rrset_count -= msg->rep->an_numrrsets;
+ msg->rep->an_numrrsets = 0;
+}
+
void iter_dec_attempts(struct delegpt* dp, int d)
{
struct delegpt_addr* a;
void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
uint8_t* z);
+/**
+ * Prepare an NXDOMAIN message to be used for a subdomain answer by removing all
+ * RRs from the ANSWER section.
+ * @param msg: the response to scrub.
+ */
+void iter_scrub_nxdomain(struct dns_msg* msg);
+
/**
* Remove query attempts from all available ips. For 0x20.
* @param dp: delegpt.
&& !(iq->chase_flags & BIT_RD)) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
LDNS_RCODE_NOERROR) {
- if(qstate->env->cfg->qname_minimisation_strict)
- return final_state(iq);
+ if(qstate->env->cfg->qname_minimisation_strict) {
+ if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
+ LDNS_RCODE_NXDOMAIN) {
+ iter_scrub_nxdomain(iq->response);
+ return final_state(iq);
+ }
+ return error_response(qstate, id,
+ LDNS_RCODE_SERVFAIL);
+ }
/* Best effort qname-minimisation.
* Stop minimising and send full query when
* RCODE is not NOERROR. */
*/
#include "config.h"
#include "iterator/iter_delegpt.h"
+#include "iterator/iter_utils.h"
#include "validator/val_nsec.h"
#include "validator/val_utils.h"
#include "services/cache/dns.h"
struct dns_msg* msg;
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
&& data->security == sec_status_secure
+ && (data->an_numrrsets == 0 ||
+ ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
&& (msg=tomsg(env, &k, data, region, now, scratch))){
lock_rw_unlock(&e->lock);
msg->qinfo.qname=qname;
msg->qinfo.qname_len=qnamelen;
/* check that DNSSEC really works out */
msg->rep->security = sec_status_unchecked;
+ iter_scrub_nxdomain(msg);
return msg;
}
lock_rw_unlock(&e->lock);