]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix to limit NSEC TTL for messages from cachedb. Fix to limit the
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 9 Oct 2024 13:28:55 +0000 (15:28 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 9 Oct 2024 13:28:55 +0000 (15:28 +0200)
  prefetch ttl for messages after a CNAME with short TTL.

cachedb/cachedb.c
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c

index cf5143ee34859de7d29b47e0512f09defd3b1d01..0329f8458bd7ce4b87c323182b4a98991eb76efe 100644 (file)
@@ -621,6 +621,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
        }
        verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
        adjust_msg_ttl(qstate->return_msg, adjust);
+       if(qstate->env->cfg->aggressive_nsec) {
+               limit_nsec_ttl(qstate->return_msg);
+       }
 
        /* Similar to the unbound worker, if serve-expired is enabled and
         * the msg would be considered to be expired, mark the state so a
index 1b4f5f6ebb4f87708cd1bdba907dc64599647c6f..cacba420e845f6b632373b8afb5144ae39843fb0 100644 (file)
@@ -1564,3 +1564,45 @@ void iterator_set_ip46_support(struct module_stack* mods,
        if(outnet->num_ip6 == 0)
                ie->supports_ipv6 = 0;
 }
+
+void
+limit_nsec_ttl(struct dns_msg* msg)
+{
+       /* Limit NSEC and NSEC3 TTL in response, RFC9077 */
+       size_t i;
+       int found = 0;
+       time_t soa_ttl = 0;
+       /* Limit the NSEC and NSEC3 TTL values to the SOA TTL and SOA minimum
+        * TTL. That has already been applied to the SOA record ttl. */
+       for(i=0; i<msg->rep->rrset_count; i++) {
+               struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
+               if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA) {
+                       struct packed_rrset_data* soadata = (struct packed_rrset_data*)s->entry.data;
+                       found = 1;
+                       soa_ttl = soadata->ttl;
+                       break;
+               }
+       }
+       if(!found)
+               return;
+       for(i=0; i<msg->rep->rrset_count; i++) {
+               struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
+               if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC ||
+                       ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) {
+                       struct packed_rrset_data* data = (struct packed_rrset_data*)s->entry.data;
+                       /* Limit the negative TTL. */
+                       if(data->ttl > soa_ttl) {
+                               if(verbosity >= VERB_ALGO) {
+                                       char buf[256];
+                                       snprintf(buf, sizeof(buf),
+                                               "limiting TTL %d of %s record to the SOA TTL of %d for",
+                                               (int)data->ttl, ((ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC)?"NSEC":"NSEC3"), (int)soa_ttl);
+                                       log_nametypeclass(VERB_ALGO, buf,
+                                               s->rk.dname, ntohs(s->rk.type),
+                                               ntohs(s->rk.rrset_class));
+                               }
+                               data->ttl = soa_ttl;
+                       }
+               }
+       }
+}
index 4024629e686c35ed6b9967f840d83dd01760f47d..0361e43775e1f825fa8e103222cd7c5456056230 100644 (file)
@@ -428,4 +428,11 @@ int iter_stub_fwd_no_cache(struct module_qstate *qstate,
 void iterator_set_ip46_support(struct module_stack* mods,
        struct module_env* env, struct outside_network* outnet);
 
+/**
+ * Limit NSEC and NSEC3 TTL in response, RFC9077
+ * @param msg: dns message, the SOA record ttl is used to restrict ttls
+ *     of NSEC and NSEC3 RRsets. If no SOA record, nothing happens.
+ */
+void limit_nsec_ttl(struct dns_msg* msg);
+
 #endif /* ITERATOR_ITER_UTILS_H */
index 0b66db8a6d6736fd02f9b0f24cd4547382e557d1..59e4b36ce364abca9502d9ad2af8616acc839466 100644 (file)
@@ -372,48 +372,6 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
        return error_response(qstate, id, rcode);
 }
 
-/** limit NSEC and NSEC3 TTL in response, RFC9077 */
-static void
-limit_nsec_ttl(struct dns_msg* msg)
-{
-       size_t i;
-       int found = 0;
-       time_t soa_ttl = 0;
-       /* Limit the NSEC and NSEC3 TTL values to the SOA TTL and SOA minimum
-        * TTL. That has already been applied to the SOA record ttl. */
-       for(i=0; i<msg->rep->rrset_count; i++) {
-               struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
-               if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA) {
-                       struct packed_rrset_data* soadata = (struct packed_rrset_data*)s->entry.data;
-                       found = 1;
-                       soa_ttl = soadata->ttl;
-                       break;
-               }
-       }
-       if(!found)
-               return;
-       for(i=0; i<msg->rep->rrset_count; i++) {
-               struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
-               if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC ||
-                       ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) {
-                       struct packed_rrset_data* data = (struct packed_rrset_data*)s->entry.data;
-                       /* Limit the negative TTL. */
-                       if(data->ttl > soa_ttl) {
-                               if(verbosity >= VERB_ALGO) {
-                                       char buf[256];
-                                       snprintf(buf, sizeof(buf),
-                                               "limiting TTL %d of %s record to the SOA TTL of %d for",
-                                               (int)data->ttl, ((ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC)?"NSEC":"NSEC3"), (int)soa_ttl);
-                                       log_nametypeclass(VERB_ALGO, buf,
-                                               s->rk.dname, ntohs(s->rk.type),
-                                               ntohs(s->rk.rrset_class));
-                               }
-                               data->ttl = soa_ttl;
-                       }
-               }
-       }
-}
-
 /** check if prepend item is duplicate item */
 static int
 prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to,
@@ -456,8 +414,11 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
        num_an = 0;
        for(p = iq->an_prepend_list; p; p = p->next) {
                sets[num_an++] = p->rrset;
-               if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
+               if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl) {
                        msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
+                       msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
+                       msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
+               }
        }
        memcpy(sets+num_an, msg->rep->rrsets, msg->rep->an_numrrsets *
                sizeof(struct ub_packed_rrset_key*));
@@ -470,8 +431,11 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
                        msg->rep->ns_numrrsets, p->rrset))
                        continue;
                sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
-               if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
+               if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl) {
                        msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
+                       msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
+                       msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
+               }
        }
        memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns, 
                msg->rep->rrsets + msg->rep->an_numrrsets,