UDP-to-TCP bugfix: wrong calls to extract_name and

suppress rapid (UDP) retry once we've switched to TCP.
This commit is contained in:
Simon Kelley
2024-10-02 21:47:48 +01:00
parent e9a7cd0a50
commit 1c26ec2876
2 changed files with 9 additions and 9 deletions

2
debian

Submodule debian updated: 05f03dca94...83e05da879

View File

@@ -619,7 +619,7 @@ int fast_retry(time_t now)
if (f->sentto && f->stash && difftime(now, f->time) < daemon->fast_retry_timeout) if (f->sentto && f->stash && difftime(now, f->time) < daemon->fast_retry_timeout)
{ {
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (f->blocking_query) if (f->blocking_query || (f->flags & FREC_GONE_TO_TCP))
continue; continue;
#endif #endif
/* t is milliseconds since last query sent. */ /* t is milliseconds since last query sent. */
@@ -901,7 +901,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
/* Find the original query that started it all.... */ /* Find the original query that started it all.... */
for (orig = forward; orig->dependent; orig = orig->dependent); for (orig = forward; orig->dependent; orig = orig->dependent);
/* As soon as anything returns BOGUS, we stop and unwind, to do otherwise /* As soon as anything returns BOGUS, we stop and unwind, to do otherwise
would invite infinite loops, since the answers to DNSKEY and DS queries would invite infinite loops, since the answers to DNSKEY and DS queries
will not be cached, so they'll be repeated. */ will not be cached, so they'll be repeated. */
@@ -921,7 +921,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
/* Get the query we sent by UDP */ /* Get the query we sent by UDP */
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header); blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
if (extract_name(header, plen, &p, daemon->namebuff, 0, 4) == 1) if (extract_name(header, forward->stash_len, &p, daemon->namebuff, 1, 4))
log_query(F_UPSTREAM | F_NOEXTRA, daemon->namebuff, NULL, "truncated", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS); log_query(F_UPSTREAM | F_NOEXTRA, daemon->namebuff, NULL, "truncated", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS);
/* Don't count failed UDP attempt AND TCP */ /* Don't count failed UDP attempt AND TCP */
@@ -932,7 +932,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
header, forward->stash_len, forward->class, forward->sentto, &orig->work_counter, &orig->validate_counter); header, forward->stash_len, forward->class, forward->sentto, &orig->work_counter, &orig->validate_counter);
/* We forked a new process. pop_and_retry_query() will be called when is completes. */ /* We forked a new process. pop_and_retry_query() will be called when is completes. */
if (status == STAT_ASYNC) if (STAT_ISEQUAL(status, STAT_ASYNC))
{ {
forward->flags |= FREC_GONE_TO_TCP; forward->flags |= FREC_GONE_TO_TCP;
return; return;
@@ -1091,7 +1091,7 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
{ {
/* Log the actual validation that made us barf. */ /* Log the actual validation that made us barf. */
unsigned char *p = (unsigned char *)(header+1); unsigned char *p = (unsigned char *)(header+1);
if (extract_name(header, plen, &p, daemon->namebuff, 0, 4) == 1) if (extract_name(header, plen, &p, daemon->namebuff, 1, 4))
my_syslog(LOG_WARNING, _("validation of %s failed: resource limit exceeded."), my_syslog(LOG_WARNING, _("validation of %s failed: resource limit exceeded."),
daemon->namebuff[0] ? daemon->namebuff : "."); daemon->namebuff[0] ? daemon->namebuff : ".");
} }
@@ -1212,7 +1212,7 @@ void reply_query(int fd, time_t now)
/* The query MAY have got a good answer, and be awaiting /* The query MAY have got a good answer, and be awaiting
the results of further queries, in which case the results of further queries, in which case
The Stash contains something else and we don't need to retry anyway. */ The Stash contains something else and we don't need to retry anyway. */
if (forward->blocking_query) if (forward->blocking_query || (forward->flags & FREC_GONE_TO_TCP))
return; return;
if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
@@ -2103,7 +2103,7 @@ int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n,
{ {
/* Log the actual validation that made us barf. */ /* Log the actual validation that made us barf. */
unsigned char *p = (unsigned char *)(header+1); unsigned char *p = (unsigned char *)(header+1);
if (extract_name(header, n, &p, daemon->namebuff, 0, 4) == 1) if (extract_name(header, n, &p, daemon->namebuff, 1, 4))
my_syslog(LOG_WARNING, _("validation of %s failed: resource limit exceeded."), my_syslog(LOG_WARNING, _("validation of %s failed: resource limit exceeded."),
daemon->namebuff[0] ? daemon->namebuff : "."); daemon->namebuff[0] ? daemon->namebuff : ".");
break; break;
@@ -2128,7 +2128,7 @@ int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n,
/* recycling UDP query, copy into new buffer and get the name we're looking for. */ /* recycling UDP query, copy into new buffer and get the name we're looking for. */
unsigned char *p = (unsigned char *)(header+1); unsigned char *p = (unsigned char *)(header+1);
if (extract_name(header, n, &p, keyname, 0, 4) == 1) if (extract_name(header, n, &p, keyname, 1, 4))
{ {
memcpy(new_header, header, n); memcpy(new_header, header, n);
m = n; m = n;