mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Try to be a little more clever at falling back to smaller DNS packet sizes.
This commit is contained in:
@@ -26,6 +26,7 @@
|
|||||||
#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
|
#define TIMEOUT 10 /* drop UDP queries after TIMEOUT seconds */
|
||||||
#define FORWARD_TEST 50 /* try all servers every 50 queries */
|
#define FORWARD_TEST 50 /* try all servers every 50 queries */
|
||||||
#define FORWARD_TIME 20 /* or 20 seconds */
|
#define FORWARD_TIME 20 /* or 20 seconds */
|
||||||
|
#define UDP_TEST_TIME 60 /* How often to reset our idea of max packet size. */
|
||||||
#define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
|
#define SERVERS_LOGGED 30 /* Only log this many servers when logging state */
|
||||||
#define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
|
#define LOCALS_LOGGED 8 /* Only log this many local addresses when logging state */
|
||||||
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
|
#define RANDOM_SOCKS 64 /* max simultaneous random ports */
|
||||||
|
|||||||
@@ -520,6 +520,7 @@ struct server {
|
|||||||
struct serverfd *sfd;
|
struct serverfd *sfd;
|
||||||
char *domain; /* set if this server only handles a domain. */
|
char *domain; /* set if this server only handles a domain. */
|
||||||
int flags, tcpfd, edns_pktsz;
|
int flags, tcpfd, edns_pktsz;
|
||||||
|
time_t pktsz_reduced;
|
||||||
unsigned int queries, failed_queries;
|
unsigned int queries, failed_queries;
|
||||||
#ifdef HAVE_LOOP
|
#ifdef HAVE_LOOP
|
||||||
u32 uid;
|
u32 uid;
|
||||||
|
|||||||
@@ -272,11 +272,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
while (forward->blocking_query)
|
while (forward->blocking_query)
|
||||||
forward = forward->blocking_query;
|
forward = forward->blocking_query;
|
||||||
|
|
||||||
forward->flags |= FREC_TEST_PKTSZ;
|
|
||||||
|
|
||||||
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
||||||
plen = forward->stash_len;
|
plen = forward->stash_len;
|
||||||
|
|
||||||
|
forward->flags |= FREC_TEST_PKTSZ;
|
||||||
if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
|
if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
|
||||||
PUTSHORT(SAFE_PKTSZ, pheader);
|
PUTSHORT(SAFE_PKTSZ, pheader);
|
||||||
|
|
||||||
@@ -401,6 +400,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
int subnet, forwarded = 0;
|
int subnet, forwarded = 0;
|
||||||
size_t edns0_len;
|
size_t edns0_len;
|
||||||
unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
|
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. */
|
/* If a query is retried, use the log_id for the retry when logging the answer. */
|
||||||
forward->log_id = daemon->log_id;
|
forward->log_id = daemon->log_id;
|
||||||
@@ -423,7 +423,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
}
|
}
|
||||||
#endif
|
#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 there wasn't a PH before, and there is now, we added it. */
|
||||||
if (!oph)
|
if (!oph)
|
||||||
@@ -432,6 +432,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
/* If we're sending an EDNS0 with any options, we can't recreate the query from a reply. */
|
/* If we're sending an EDNS0 with any options, we can't recreate the query from a reply. */
|
||||||
if (edns0_len > 11)
|
if (edns0_len > 11)
|
||||||
forward->flags |= FREC_HAS_EXTRADATA;
|
forward->flags |= FREC_HAS_EXTRADATA;
|
||||||
|
|
||||||
|
/* Reduce udp size on retransmits. */
|
||||||
|
if (forward->flags & FREC_TEST_PKTSZ)
|
||||||
|
PUTSHORT(SAFE_PKTSZ, pheader);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@@ -765,6 +769,10 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
if (!server)
|
if (!server)
|
||||||
return;
|
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
|
#ifdef HAVE_DNSSEC
|
||||||
hash = hash_questions(header, n, daemon->namebuff);
|
hash = hash_questions(header, n, daemon->namebuff);
|
||||||
#else
|
#else
|
||||||
@@ -853,14 +861,16 @@ void reply_query(int fd, int family, time_t now)
|
|||||||
/* We tried resending to this server with a smaller maximum size and got an answer.
|
/* 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,
|
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. */
|
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))
|
((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
|
||||||
{
|
{
|
||||||
server->edns_pktsz = SAFE_PKTSZ;
|
server->edns_pktsz = SAFE_PKTSZ;
|
||||||
|
server->pktsz_reduced = now;
|
||||||
prettyprint_addr(&server->addr, daemon->addrbuff);
|
prettyprint_addr(&server->addr, daemon->addrbuff);
|
||||||
my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d"), daemon->addrbuff, SAFE_PKTSZ);
|
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
|
/* 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
|
we get a good reply from another server. Kill it when we've
|
||||||
had replies from all to avoid filling the forwarding table when
|
had replies from all to avoid filling the forwarding table when
|
||||||
|
|||||||
Reference in New Issue
Block a user