extend:
3282. [bug] Restrict the TTL of NS RRset to no more than that
of the old NS RRset when replacing it.
[RT #27792] [RT #27884]
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -2,7 +2,8 @@
|
||||
failed to load. [RT #27863]
|
||||
|
||||
3282. [bug] Restrict the TTL of NS RRset to no more than that
|
||||
of the old NS RRset when replacing it. [RT #27792]
|
||||
of the old NS RRset when replacing it.
|
||||
[RT #27792] [RT #27884]
|
||||
|
||||
3281. [bug] SOA refresh queries could be treated as cancelled
|
||||
despite succeeding over the loopback interface.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: resolver.c,v 1.446 2011/12/07 23:08:42 marka Exp $ */
|
||||
/* $Id: resolver.c,v 1.447 2012/02/14 00:22:54 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -216,6 +216,8 @@ struct fetchctx {
|
||||
ISC_LIST(dns_validator_t) validators;
|
||||
dns_db_t * cache;
|
||||
dns_adb_t * adb;
|
||||
isc_boolean_t ns_ttl_ok;
|
||||
isc_uint32_t ns_ttl;
|
||||
|
||||
/*%
|
||||
* The number of events we're waiting for.
|
||||
@@ -3443,6 +3445,20 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static inline void
|
||||
log_ns_ttl(fetchctx_t *fctx, const char *where) {
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char domainbuf[DNS_NAME_FORMATSIZE];
|
||||
|
||||
dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
|
||||
dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10),
|
||||
"log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u",
|
||||
fctx, where, namebuf, domainbuf,
|
||||
fctx->ns_ttl_ok, fctx->ns_ttl);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
dns_name_t *domain, dns_rdataset_t *nameservers,
|
||||
@@ -3536,6 +3552,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
fctx->timeout = ISC_FALSE;
|
||||
fctx->addrinfo = NULL;
|
||||
fctx->client = NULL;
|
||||
fctx->ns_ttl = 0;
|
||||
fctx->ns_ttl_ok = ISC_FALSE;
|
||||
|
||||
dns_name_init(&fctx->nsname, NULL);
|
||||
fctx->nsfetch = NULL;
|
||||
@@ -3585,6 +3603,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
goto cleanup_name;
|
||||
}
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = ISC_TRUE;
|
||||
} else {
|
||||
/*
|
||||
* We're in forward-only mode. Set the query domain.
|
||||
@@ -3602,8 +3622,12 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_name;
|
||||
dns_rdataset_clone(nameservers, &fctx->nameservers);
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = ISC_TRUE;
|
||||
}
|
||||
|
||||
log_ns_ttl(fctx, "fctx_create");
|
||||
|
||||
INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
|
||||
|
||||
fctx->qmessage = NULL;
|
||||
@@ -5280,6 +5304,26 @@ is_answertarget_allowed(dns_view_t *view, dns_name_t *name,
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) {
|
||||
char ns_namebuf[DNS_NAME_FORMATSIZE];
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char tbuf[DNS_RDATATYPE_FORMATSIZE];
|
||||
|
||||
if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) {
|
||||
dns_name_format(name, ns_namebuf, sizeof(ns_namebuf));
|
||||
dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
|
||||
dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf));
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
|
||||
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10),
|
||||
"fctx %p: trimming ttl of %s/NS for %s/%s: "
|
||||
"%u -> %u", fctx, ns_namebuf, namebuf, tbuf,
|
||||
rdataset->ttl, fctx->ns_ttl);
|
||||
rdataset->ttl = fctx->ns_ttl;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a no-answer response (NXDOMAIN, NXRRSET, or referral).
|
||||
* If look_in_options has LOOK_FOR_NS_IN_ANSWER then we look in the answer
|
||||
@@ -5466,6 +5510,12 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
|
||||
return (result);
|
||||
}
|
||||
|
||||
log_ns_ttl(fctx, "noanswer_response");
|
||||
|
||||
if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
|
||||
!dns_name_equal(ns_name, dns_rootname))
|
||||
trim_ns_ttl(fctx, ns_name, ns_rdataset);
|
||||
|
||||
/*
|
||||
* A negative response has a SOA record (Type 2)
|
||||
* and a optional NS RRset (Type 1) or it has neither
|
||||
@@ -5684,6 +5734,8 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
fctx->attributes |= FCTX_ATTR_WANTCACHE;
|
||||
fctx->ns_ttl_ok = ISC_FALSE;
|
||||
log_ns_ttl(fctx, "DELEGATION");
|
||||
return (DNS_R_DELEGATION);
|
||||
}
|
||||
|
||||
@@ -5704,8 +5756,8 @@ static isc_result_t
|
||||
answer_response(fetchctx_t *fctx) {
|
||||
isc_result_t result;
|
||||
dns_message_t *message;
|
||||
dns_name_t *name, *qname, tname;
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_name_t *name, *qname, tname, *ns_name;
|
||||
dns_rdataset_t *rdataset, *ns_rdataset;
|
||||
isc_boolean_t done, external, chaining, aa, found, want_chaining;
|
||||
isc_boolean_t have_answer, found_cname, found_type, wanted_chaining;
|
||||
unsigned int aflag;
|
||||
@@ -6105,6 +6157,8 @@ answer_response(fetchctx_t *fctx) {
|
||||
* in this section, and we expect that it is not external.
|
||||
*/
|
||||
done = ISC_FALSE;
|
||||
ns_name = NULL;
|
||||
ns_rdataset = NULL;
|
||||
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
|
||||
while (!done && result == ISC_R_SUCCESS) {
|
||||
name = NULL;
|
||||
@@ -6132,6 +6186,10 @@ answer_response(fetchctx_t *fctx) {
|
||||
rdataset->trust =
|
||||
dns_trust_additional;
|
||||
|
||||
if (rdataset->type == dns_rdatatype_ns) {
|
||||
ns_name = name;
|
||||
ns_rdataset = rdataset;
|
||||
}
|
||||
/*
|
||||
* Mark any additional data related
|
||||
* to this rdataset.
|
||||
@@ -6149,6 +6207,12 @@ answer_response(fetchctx_t *fctx) {
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
log_ns_ttl(fctx, "answer_response");
|
||||
|
||||
if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
|
||||
!dns_name_equal(ns_name, dns_rootname))
|
||||
trim_ns_ttl(fctx, ns_name, ns_rdataset);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -6220,6 +6284,9 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
|
||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
dns_rdataset_clone(fevent->rdataset, &fctx->nameservers);
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = ISC_TRUE;
|
||||
log_ns_ttl(fctx, "resume_dslookup");
|
||||
dns_name_free(&fctx->domain,
|
||||
fctx->res->buckets[bucketnum].mctx);
|
||||
dns_name_init(&fctx->domain, NULL);
|
||||
@@ -7153,6 +7220,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
|
||||
return;
|
||||
}
|
||||
fctx->ns_ttl = fctx->nameservers.ttl;
|
||||
fctx->ns_ttl_ok = ISC_TRUE;
|
||||
fctx_cancelqueries(fctx, ISC_TRUE);
|
||||
fctx_cleanupfinds(fctx);
|
||||
fctx_cleanupaltfinds(fctx);
|
||||
|
||||
Reference in New Issue
Block a user