msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype,
qstate->qinfo.qclass, qstate->query_flags,
- qstate->region, qstate->env->scratch);
+ qstate->region, qstate->env->scratch,
+ 1 /* no partial messages with only a CNAME */
+ );
if(!msg && qstate->env->neg_cache) {
/* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
also recognized and means the same. Also for tls-port,
tls-service-key, tls-service-pem, stub-tls-upstream and
forward-tls-upstream.
+ - Fix #3397: Fix that cachedb could return a partial CNAME chain.
19 January 2018: Wouter
- tag 1.6.8 for release with CVE fix.
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
iq->qchase.qname_len, iq->qchase.qtype,
iq->qchase.qclass, qstate->query_flags,
- qstate->region, qstate->env->scratch);
+ qstate->region, qstate->env->scratch, 0);
if(!msg && qstate->env->neg_cache) {
/* lookup in negative cache; may result in
* NOERROR/NODATA or NXDOMAIN answers that need validation */
iq->qinfo_out.qname, iq->qinfo_out.qname_len,
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
qstate->query_flags, qstate->region,
- qstate->env->scratch);
+ qstate->env->scratch, 0);
if(msg && msg->rep->an_numrrsets == 0
&& FLAGS_GET_RCODE(msg->rep->flags) ==
LDNS_RCODE_NOERROR)
struct dns_msg*
dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
- uint16_t flags, struct regional* region, struct regional* scratch)
+ uint16_t flags, struct regional* region, struct regional* scratch,
+ int no_partial)
{
struct lruhash_entry* e;
struct query_info k;
/* see if a DNAME exists. Checked for first, to enforce that DNAMEs
* are more important, the CNAME is resynthesized and thus
* consistent with the DNAME */
- if( (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
+ if(!no_partial &&
+ (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
LDNS_RR_TYPE_DNAME, 1))) {
/* synthesize a DNAME+CNAME message based on this */
struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k);
/* see if we have CNAME for this domain,
* but not for DS records (which are part of the parent) */
- if( qtype != LDNS_RR_TYPE_DS &&
+ if(!no_partial && qtype != LDNS_RR_TYPE_DS &&
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) {
uint8_t* wc = NULL;
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* @param region: where to allocate result.
* @param scratch: where to allocate temporary data.
+ * @param no_partial: if true, only complete messages and not a partial
+ * one (with only the start of the CNAME chain and not the rest).
* @return new response message (alloced in region, rrsets do not have IDs).
* or NULL on error or if not found in cache.
* TTLs are made relative to the current time.
*/
struct dns_msg* dns_cache_lookup(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
- uint16_t flags, struct regional* region, struct regional* scratch);
+ uint16_t flags, struct regional* region, struct regional* scratch,
+ int no_partial);
/**
* find and add A and AAAA records for missing nameservers in delegpt