Skip to content

Commit

Permalink
Add --no-0x20-encode config option.
Browse files Browse the repository at this point in the history
The "bit 0x20 encoding" implemented in 995a16ca0cd9767460c72a856909962a34fdbfbd
can interact badly with (hopefully) rare broken upstream servers. Provide
an option to turn it off and a log message to give a clue as to why DNS service
is non-functional.

Signed-off-by: DL6ER <[email protected]>
  • Loading branch information
simonkelley authored and DL6ER committed Feb 4, 2025
1 parent eb2733a commit 4292668
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 18 deletions.
3 changes: 2 additions & 1 deletion src/dnsmasq/dnsmasq.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ struct event_desc {
#define OPT_CACHE_RR 71
#define OPT_LOCALHOST_SERVICE 72
#define OPT_LOG_PROTO 73
#define OPT_LAST 74
#define OPT_NO_0x20 74
#define OPT_LAST 75

#define OPTION_BITS (sizeof(unsigned int)*8)
#define OPTION_SIZE ( (OPT_LAST/OPTION_BITS)+((OPT_LAST%OPTION_BITS)!=0) )
Expand Down
45 changes: 29 additions & 16 deletions src/dnsmasq/forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
forward->new_id = get_id();
header->id = ntohs(forward->new_id);

forward->encode_bitmap = rand32();
forward->encode_bitmap = option_bool(OPT_NO_0x20) ? 0 : rand32();
p = (unsigned char *)(header+1);
if (!extract_name(header, plen, &p, NULL, EXTR_NAME_FLIP, forward->encode_bitmap))
goto reply;
Expand Down Expand Up @@ -2146,7 +2146,7 @@ static ssize_t tcp_talk(int first, int last, int start, unsigned char *packet,
sending replies containing questions and bogus answers.
Try another server, or give up */
p = (unsigned char *)(header+1);
if (extract_name(header, rsize, &p, daemon->namebuff, EXTR_NAME_NOCASE, 4) != 1)
if (extract_name(header, rsize, &p, daemon->namebuff, EXTR_NAME_COMPARE, 4) != 1)
continue;
GETSHORT(rtype, p);
GETSHORT(rclass, p);
Expand Down Expand Up @@ -3225,22 +3225,35 @@ static struct frec *lookup_frec(char *target, int class, int rrtype, int id, int
(header = blockdata_retrieve(f->stash, f->stash_len, NULL)))
{
unsigned char *p = (unsigned char *)(header+1);
int hclass, hrrtype;
int hclass, hrrtype, rc;

/* Case sensitive compare for DNS-0x20 encoding. */
if (extract_name(header, f->stash_len, &p, target, EXTR_NAME_NOCASE, 4) != 1)
continue;

GETSHORT(hrrtype, p);
GETSHORT(hclass, p);

/* type checked by flags for DNSSEC queries. */
if (rrtype != -1 && rrtype != hrrtype)
continue;

if (class != hclass)
continue;

if ((rc = extract_name(header, f->stash_len, &p, target, option_bool(OPT_NO_0x20) ? EXTR_NAME_COMPARE : EXTR_NAME_NOCASE, 4)))
{
GETSHORT(hrrtype, p);
GETSHORT(hclass, p);

/* type checked by flags for DNSSEC queries. */
if (rrtype != -1 && rrtype != hrrtype)
continue;

if (class != hclass)
continue;
}

if (rc != 1)
{
static int warned = 0;

if (rc == 3 && !warned)
{
my_syslog(LOG_WARNING, _("Case mismatch in DNS reply - check bit 0x20 encoding."));
warned = 1;
}

continue;
}

return f;
}

Expand Down
3 changes: 3 additions & 0 deletions src/dnsmasq/option.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ struct myoption {
#define LOPT_MAX_PROCS 384
#define LOPT_DNSSEC_LIMITS 385
#define LOPT_PXE_OPT 386
#define LOPT_NO_ENCODE 387

#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
Expand Down Expand Up @@ -251,6 +252,7 @@ static const struct myoption opts[] =
{ "local-ttl", 1, 0, 'T' },
{ "no-negcache", 0, 0, 'N' },
{ "no-round-robin", 0, 0, LOPT_NORR },
{ "no-0x20-encode", 0, 0, LOPT_NO_ENCODE },
{ "cache-rr", 1, 0, LOPT_CACHE_RR },
{ "addn-hosts", 1, 0, 'H' },
{ "hostsdir", 1, 0, LOPT_HOST_INOTIFY },
Expand Down Expand Up @@ -595,6 +597,7 @@ static struct {
{ LOPT_UMBRELLA, ARG_ONE, "[=<optspec>]", gettext_noop("Send Cisco Umbrella identifiers including remote IP."), NULL },
{ LOPT_QUIET_TFTP, OPT_QUIET_TFTP, NULL, gettext_noop("Do not log routine TFTP."), NULL },
{ LOPT_NORR, OPT_NORR, NULL, gettext_noop("Suppress round-robin ordering of DNS records."), NULL },
{ LOPT_NO_ENCODE, OPT_NO_0x20, NULL, gettext_noop("Suppress DNS bit 0x20 encoding."), NULL },
{ LOPT_NO_IDENT, OPT_NO_IDENT, NULL, gettext_noop("Do not add CHAOS TXT records."), NULL },
{ LOPT_CACHE_RR, ARG_DUP, "<RR-type>", gettext_noop("Cache this DNS resource record type."), NULL },
{ LOPT_MAX_PROCS, ARG_ONE, "<integer>", gettext_noop("Maximum number of concurrent tcp connections."), NULL },
Expand Down
15 changes: 14 additions & 1 deletion src/dnsmasq/rfc1035.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
return = 0 -> error
return = 1 -> extract OK, compare OK, flip OK
return = 2 -> extract OK, compare failed.
return = 3 -> extract OK, compare failed but only on case.
*/
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int func, unsigned int parm)
Expand Down Expand Up @@ -141,9 +142,21 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,

if (case_insens && c2 >= 'A' && c2 <= 'Z')
c2 += 'a' - 'A';

if (!case_insens && retvalue != 2 && c1 != c2)
{
if (c1 >= 'A' && c1 <= 'Z')
c1 += 'a' - 'A';

if (c2 >= 'A' && c2 <= 'Z')
c2 += 'a' - 'A';

if (c1 == c2)
retvalue = 3;
}

if (c1 != c2)
retvalue = 2;
retvalue = 2;
}
}

Expand Down

0 comments on commit 4292668

Please sign in to comment.