dns/dnsmasq: pull in three more upstream fixes

Cherry-pick these Git commits from the upstream:

--local should behave as --server, not as --address [...]
Fix confusion in DNS retries and --strict-order.
Fix confusion with log-IDs and DNS retries.

loosely prompted by Olivier's
PR:		260331
This commit is contained in:
Matthias Andree
2021-12-11 10:48:02 +01:00
parent 1f05895ca0
commit f727ae28aa
4 changed files with 195 additions and 1 deletions

View File

@@ -3,7 +3,7 @@
PORTNAME= dnsmasq
DISTVERSION= 2.86
# Leave the PORTREVISION in even if 0 to avoid accidental PORTEPOCH bumps:
PORTREVISION= 1
PORTREVISION= 2
PORTEPOCH= 1
CATEGORIES= dns
MASTER_SITES= https://www.thekelleys.org.uk/dnsmasq/ \

View File

@@ -0,0 +1,36 @@
From 089a11f3400485f215f5e29c77e41d7730f2c806 Mon Sep 17 00:00:00 2001
From: DL6ER <dl6er@dl6er.de>
Date: Tue, 5 Oct 2021 10:15:21 +0200
Subject: [PATCH] --local should behave as --server, not as --address according
to the man page
Signed-off-by: DL6ER <dl6er@dl6er.de>
---
src/option.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/option.c b/src/option.c
index 5307f01..dc1efd3 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2758,7 +2758,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (!arg || !*arg)
flags = SERV_LITERAL_ADDRESS;
- else if (option != 'S')
+ else if (option == 'A')
{
/* # as literal address means return zero address for 4 and 6 */
if (strcmp(arg, "#") == 0)
@@ -2790,7 +2790,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
flags &= ~SERV_FOR_NODOTS;
/* address=/#/ matches the same as without domain */
- if (option != 'S' && domain[0] == '#' && domain[1] == 0)
+ if (option == 'A' && domain[0] == '#' && domain[1] == 0)
domain[0] = 0;
}
--
2.20.1

View File

@@ -0,0 +1,63 @@
From 2561f9fe0eb9c0be1df48da1e2bd3d3feaa138c2 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Mon, 27 Sep 2021 22:37:02 +0100
Subject: [PATCH] Fix confusion in DNS retries and --strict-order.
Behaviour to stop infinite loops when all servers return REFUSED
was wrongly activated on client retries, resulting in
incorrect REFUSED replies to client retries.
Thanks to Johannes Stezenbach for finding the problem.
---
src/forward.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/forward.c b/src/forward.c
index b921168..ceecfcd 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -173,7 +173,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
void *hash = hash_questions(header, plen, daemon->namebuff);
unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
- int old_src = 0;
+ int old_src = 0, old_reply = 0;
int first, last, start = 0;
int subnet, cacheable, forwarded = 0;
size_t edns0_len;
@@ -199,7 +199,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
Similarly FREC_NO_CACHE is never set in flags, so a query which is
contigent on a particular source address EDNS0 option will never be matched. */
if (forward)
- old_src = 1;
+ {
+ old_src = 1;
+ old_reply = 1;
+ }
else if ((forward = lookup_frec_by_query(hash, fwd_flags,
FREC_CHECKING_DISABLED | FREC_AD_QUESTION | FREC_DO_QUESTION |
FREC_HAS_PHEADER | FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_NO_CACHE)))
@@ -376,9 +379,18 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
/* In strict order mode, there must be a server later in the list
left to send to, otherwise without the forwardall mechanism,
code further on will cycle around the list forwever if they
- all return REFUSED. If at the last, give up. */
+ all return REFUSED. If at the last, give up.
+ Note that we can get here EITHER because a client retried,
+ or an upstream server returned REFUSED. The above only
+ applied in the later case. For client retries,
+ keep tyring the last server.. */
if (++start == last)
- goto reply;
+ {
+ if (old_reply)
+ goto reply;
+ else
+ start--;
+ }
}
}
}
--
2.20.1

View File

@@ -0,0 +1,95 @@
From ed96efd865132dd9aa256c7873c6cdd5e985ee23 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 1 Dec 2021 16:34:41 +0000
Subject: [PATCH] Fix confusion with log-IDs and DNS retries.
The IDs logged when --log-queries=extra is in effect
can be wrong in three cases.
1) When query is retried in response to a a SERVFAIL or REFUSED
answer from upstream. In this case the ID of an unrelated query will
appear in the answer log lines.
2) When the same query arrives from two clients. The query is
sent upstream once, as designed, and the result returned to both clients,
as designed, but the reply to the first client gets the log-ID of the
second query in error.
3) When a query arrives, is sent upstream, and the reply comes back,
but the transaction is blocked awaiting a DNSSEC query needed to validate
the reply. If the client retries the query in this state, the blocking
DNSSEC query will be resent, as designed, but that send will be logged with
the ID of the original, currently blocked, query.
Thanks to Dominik Derigs for his analysis of this problem.
---
src/forward.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/forward.c b/src/forward.c
index 5c0173c..163da09 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -215,7 +215,11 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
break;
if (src)
- old_src = 1;
+ {
+ old_src = 1;
+ /* If a query is retried, use the log_id for the retry when logging the answer. */
+ src->log_id = daemon->log_id;
+ }
else
{
/* Existing query, but from new source, just add this
@@ -286,6 +290,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
goto reply;
/* table full - flags == 0, return REFUSED */
+ forward->frec_src.log_id = daemon->log_id;
forward->frec_src.source = *udpaddr;
forward->frec_src.orig_id = ntohs(header->id);
forward->frec_src.dest = *dst_addr;
@@ -329,7 +334,6 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
}
else
{
- /* retry on existing query, from original source. Send to all available servers */
#ifdef HAVE_DNSSEC
/* If we've already got an answer to this query, but we're awaiting keys for validation,
there's no point retrying the query, retry the key query instead...... */
@@ -340,7 +344,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
while (forward->blocking_query)
forward = forward->blocking_query;
-
+
+ /* log_id should match previous DNSSEC query. */
+ daemon->log_display_id = forward->frec_src.log_id;
+
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
plen = forward->stash_len;
/* get query for logging. */
@@ -383,7 +390,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
Note that we can get here EITHER because a client retried,
or an upstream server returned REFUSED. The above only
applied in the later case. For client retries,
- keep tyring the last server.. */
+ keep trying the last server.. */
if (++start == last)
{
if (old_reply)
@@ -402,9 +409,6 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
forward->flags |= FREC_TEST_PKTSZ;
}
- /* If a query is retried, use the log_id for the retry when logging the answer. */
- forward->frec_src.log_id = daemon->log_id;
-
/* We may be resending a DNSSEC query here, for which the below processing is not necessary. */
if (!is_dnssec)
{
--
2.20.1