Try to be a little more clever at falling back to smaller DNS packet sizes.
diff --git a/src/forward.c b/src/forward.c
index 71bc495..cdd11d3 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -272,14 +272,13 @@
while (forward->blocking_query)
forward = forward->blocking_query;
- forward->flags |= FREC_TEST_PKTSZ;
-
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
plen = forward->stash_len;
+ forward->flags |= FREC_TEST_PKTSZ;
if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
PUTSHORT(SAFE_PKTSZ, pheader);
-
+
if (forward->sentto->addr.sa.sa_family == AF_INET)
log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
#ifdef HAVE_IPV6
@@ -401,7 +400,8 @@
int subnet, forwarded = 0;
size_t edns0_len;
unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
-
+ unsigned char *pheader;
+
/* If a query is retried, use the log_id for the retry when logging the answer. */
forward->log_id = daemon->log_id;
@@ -423,7 +423,7 @@
}
#endif
- if (find_pseudoheader(header, plen, &edns0_len, NULL, NULL, NULL))
+ if (find_pseudoheader(header, plen, &edns0_len, &pheader, NULL, NULL))
{
/* If there wasn't a PH before, and there is now, we added it. */
if (!oph)
@@ -432,6 +432,10 @@
/* If we're sending an EDNS0 with any options, we can't recreate the query from a reply. */
if (edns0_len > 11)
forward->flags |= FREC_HAS_EXTRADATA;
+
+ /* Reduce udp size on retransmits. */
+ if (forward->flags & FREC_TEST_PKTSZ)
+ PUTSHORT(SAFE_PKTSZ, pheader);
}
while (1)
@@ -764,7 +768,11 @@
if (!server)
return;
-
+
+ /* If sufficient time has elapsed, try and expand UDP buffer size again. */
+ if (difftime(now, server->pktsz_reduced) > UDP_TEST_TIME)
+ server->edns_pktsz = daemon->edns_pktsz;
+
#ifdef HAVE_DNSSEC
hash = hash_questions(header, n, daemon->namebuff);
#else
@@ -853,14 +861,16 @@
/* We tried resending to this server with a smaller maximum size and got an answer.
Make that permanent. To avoid reduxing the packet size for a single dropped packet,
only do this when we get a truncated answer, or one larger than the safe size. */
- if (server && (forward->flags & FREC_TEST_PKTSZ) &&
+ if (server && server->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PKTSZ) &&
((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
{
server->edns_pktsz = SAFE_PKTSZ;
+ server->pktsz_reduced = now;
prettyprint_addr(&server->addr, daemon->addrbuff);
my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d"), daemon->addrbuff, SAFE_PKTSZ);
}
-
+
+
/* If the answer is an error, keep the forward record in place in case
we get a good reply from another server. Kill it when we've
had replies from all to avoid filling the forwarding table when