Skip to content

Commit

Permalink
Fix 0x20 problem.
Browse files Browse the repository at this point in the history
A retry to upstream DNS servers triggered by the following conditions

1) A query asking for the same data as a previous query which has not yet been answered.
2) The second query arrives more than two seconds after the first.
3) Either the source of the second query or the id field differs from the first.

fails to set the case of the retry to the same pattern as the first attempt.

However dnsmasq expects the reply from upstream to have the case
pattern of the first attempt.

If the answer to the retry arrives before the answer to the first
query, dnsmasq will notice the case mismatch, log an error, and
ignore the answer.

The worst case scenario would be the first upstream query or reply is
lost and there would follow a short period where all queries for that
particular domain would fail.

This is a 2.91 development issue, it doesn't apply to previous stable releases.

Signed-off-by: DL6ER <[email protected]>
  • Loading branch information
simonkelley authored and DL6ER committed Feb 8, 2025
1 parent de61d82 commit 58fc55a
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions src/dnsmasq/forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
FREC_HAS_PHEADER | FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_NO_CACHE)))
{
struct frec_src *src;
struct dns_header *saved_header;
unsigned int casediff = 0;
unsigned int *bitvector = NULL;
unsigned short id;

for (src = &forward->frec_src; src; src = src->next)
if (src->orig_id == ntohs(header->id) &&
Expand Down Expand Up @@ -250,7 +250,7 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
goto reply;
}

/* Find a bitmap of case differences between the query send upstream and this one,
/* Find a bitmap of case differences between the query sent upstream and this one,
so we can reply to each query with the correct case pattern.
Since we need this to get back the exact case pattern of each query when doing
query combining, we have to handle the (rare) case that there are case differences
Expand All @@ -261,9 +261,19 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
we only scramble the first 32 letters for security reasons.
Note the two names are guaranteed to be the same length and differ only in the case
of letters. */
if ((saved_header = blockdata_retrieve(forward->stash, forward->stash_len, NULL)) &&
extract_request(saved_header, forward->stash_len, daemon->workspacename, NULL))
of letters at this point.
Get the original query into the packet buffer and extract the query name it contains
to calculate the difference in case scrambling. This is important because we
may fall through below and forward the query in the packet buffer again and we
want to use the same case scrambling as the first time.
Retrieve the id from the new query before we overwrite it. */

id = ntohs(header->id);

if (blockdata_retrieve(forward->stash, forward->stash_len, (void *)header) &&
extract_request(header, forward->stash_len, daemon->workspacename, NULL))
{
unsigned int i, gobig = 0;
char *s1, *s2;
Expand Down Expand Up @@ -302,7 +312,7 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
daemon->free_frec_src = src->next;
src->next = forward->frec_src.next;
forward->frec_src.next = src;
src->orig_id = ntohs(header->id);
src->orig_id = id;
src->source = *udpaddr;
src->dest = *dst_addr;
src->log_id = daemon->log_id;
Expand Down

0 comments on commit 58fc55a

Please sign in to comment.