summaryrefslogtreecommitdiff
path: root/iterator/iter_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'iterator/iter_utils.c')
-rw-r--r--iterator/iter_utils.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 1b4f5f6ebb4f..cacba420e845 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -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;
+ }
+ }
+ }
+}