]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix to limit NSEC and NSEC3 TTL when aggressive nsec is
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 10 Sep 2024 08:13:48 +0000 (10:13 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 10 Sep 2024 08:13:48 +0000 (10:13 +0200)
  enabled (RFC9077).

doc/Changelog
iterator/iterator.c

index 8a22e049d5f10bf8bf2d8f8219929c6381201563..136fd0b68592bb3d67650f5ee4dc0a423bee2113 100644 (file)
@@ -1,3 +1,7 @@
+10 September 2024: Wouter
+       - Fix to limit NSEC and NSEC3 TTL when aggressive nsec is
+         enabled (RFC9077).
+
 6 September 2024: Yorgos
        - Fix alloc-size and calloc-transposed-args compiler warnings.
        - Fix comment to not trigger doxygen unknown command.
index 659af34d9b69961efd4a8ea836fbc3cb96269ad0..d566a799838104606cd182ce7c761627dd007ec2 100644 (file)
@@ -367,6 +367,48 @@ 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,
@@ -4366,7 +4408,10 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
        if(verbosity >= VERB_ALGO)
                log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo, 
                        iq->response->rep);
-       
+
+       if(qstate->env->cfg->aggressive_nsec) {
+               limit_nsec_ttl(iq->response);
+       }
        if(event == module_event_capsfail || iq->caps_fallback) {
                if(qstate->env->cfg->qname_minimisation &&
                        iq->minimisation_state != DONOT_MINIMISE_STATE) {