Revise negative DNS caching to better comply with RFC2308.

This commit is contained in:
Simon Kelley
2025-04-16 21:29:42 +01:00
parent 942a35f517
commit 0620309b73

View File

@@ -534,9 +534,6 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *sub
if (substring) if (substring)
*substring = name_len; *substring = name_len;
if (ttlp)
*ttlp = daemon->neg_ttl;
for (i = 0; i < ntohs(header->nscount); i++) for (i = 0; i < ntohs(header->nscount); i++)
{ {
if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0)) if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
@@ -812,21 +809,32 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
} }
} }
if (!found && !option_bool(OPT_NO_NEG)) if (!found)
{ {
/* For reverse records, we use the name field to store the SOA name. */
int substring, have_soa = find_soa(header, qlen, name, &substring, &ttl, no_cache_dnssec, now);
flags |= F_NEG | (secure ? F_DNSSECOK : 0); flags |= F_NEG | (secure ? F_DNSSECOK : 0);
if (name_encoding && ttl)
{ if (name_encoding)
flags |= F_REVERSE | name_encoding; flags |= F_REVERSE | name_encoding;
if (!have_soa)
flags |= F_NO_RR; /* Marks no SOA found. */
cache_insert(name + substring, &addr, C_IN, now, ttl, flags);
}
log_query(flags | F_UPSTREAM, name, &addr, NULL, 0); log_query(flags | F_UPSTREAM, name, &addr, NULL, 0);
if (name_encoding && !option_bool(OPT_NO_NEG))
{
/* For reverse records, we use the name field to store the SOA name. */
int substring, have_soa = find_soa(header, qlen, name, &substring, &ttl, no_cache_dnssec, now);
if (have_soa || daemon->neg_ttl)
{
/* If daemon->neg_ttl is set, we can cache even without an SOA. */
if (!have_soa)
{
flags |= F_NO_RR; /* Marks no SOA found. */
ttl = daemon->neg_ttl;
}
cache_insert(name + substring, &addr, C_IN, now, ttl, flags);
}
}
} }
} }
else else
@@ -1114,26 +1122,27 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
{ {
int substring, have_soa = find_soa(header, qlen, name, &substring, &ttl, no_cache_dnssec, now); int substring, have_soa = find_soa(header, qlen, name, &substring, &ttl, no_cache_dnssec, now);
/* If there's no SOA to get the TTL from, but there is a CNAME if (have_soa || daemon->neg_ttl)
pointing at this, inherit its TTL */ {
if (ttl || cpp) if (have_soa)
{ {
if (!ttl) addr.rrdata.datalen = substring;
ttl = cttl; addr.rrdata.rrtype = qtype;
}
addr.rrdata.datalen = substring; else
addr.rrdata.rrtype = qtype; {
/* If daemon->neg_ttl is set, we can cache even without an SOA. */
if (!have_soa) ttl = daemon->neg_ttl;
flags |= F_NO_RR; /* Marks no SOA found. */ flags |= F_NO_RR; /* Marks no SOA found. */
} }
newc = cache_insert(name, &addr, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0)); newc = cache_insert(name, &addr, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
if (newc && cpp) if (newc && cpp)
{ {
next_uid(newc); next_uid(newc);
cpp->addr.cname.target.cache = newc; cpp->addr.cname.target.cache = newc;
cpp->addr.cname.uid = newc->uid; cpp->addr.cname.uid = newc->uid;
}
} }
} }
} }