iq->dp = delegpt_from_message(iq->response, qstate->region);
if(!iq->dp)
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
+ qstate->region, iq->dp))
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
delegpt_log(iq->dp);
/* Count this as a referral. */
iq->referral_count++;
return 1;
}
+/** find and add A and AAAA records for missing nameservers in delegpt */
+int
+cache_fill_missing(struct module_env* env, uint16_t qclass,
+ struct region* region, struct delegpt* dp)
+{
+ struct delegpt_ns* ns;
+ struct ub_packed_rrset_key* akey;
+ uint32_t now = time(NULL);
+ for(ns = dp->nslist; ns; ns = ns->next) {
+ if(ns->resolved)
+ continue;
+ akey = rrset_cache_lookup(env->rrset_cache, ns->name,
+ ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
+ if(akey) {
+ if(!delegpt_add_rrset_A(dp, region, akey)) {
+ lock_rw_unlock(&akey->entry.lock);
+ return 0;
+ }
+ log_nametypeclass(VERB_ALGO, "found in cache",
+ ns->name, LDNS_RR_TYPE_A, qclass);
+ lock_rw_unlock(&akey->entry.lock);
+ }
+ akey = rrset_cache_lookup(env->rrset_cache, ns->name,
+ ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
+ if(akey) {
+ if(!delegpt_add_rrset_AAAA(dp, region, akey)) {
+ lock_rw_unlock(&akey->entry.lock);
+ return 0;
+ }
+ log_nametypeclass(VERB_ALGO, "found in cache",
+ ns->name, LDNS_RR_TYPE_AAAA, qclass);
+ lock_rw_unlock(&akey->entry.lock);
+ }
+ }
+ return 1;
+}
+
/** find and add DS or NSEC to delegation msg */
static void
find_add_ds(struct module_env* env, struct region* region,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct region* region, struct region* scratch);
+/**
+ * find and add A and AAAA records for missing nameservers in delegpt
+ * @param env: module environment with rrset cache
+ * @param qclass: which class to look in.
+ * @param region: where to store new dp info.
+ * @param dp: delegation point to fill missing entries.
+ * @return false on alloc failure.
+ */
+int cache_fill_missing(struct module_env* env, uint16_t qclass,
+ struct region* region, struct delegpt* dp);
+
/** Find covering DNAME */
#endif /* SERVICES_CACHE_DNS_H */