Skip to content

Commit

Permalink
Merge pull request #2165 from pi-hole/update/dnsmasq
Browse files Browse the repository at this point in the history
Update embedded dnsmasq to v2.91test8
  • Loading branch information
DL6ER authored Jan 19, 2025
2 parents 817aad9 + 62010ec commit 84e2ad1
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 35 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ set(CMAKE_C_STANDARD 17)

project(PIHOLE_FTL C)

set(DNSMASQ_VERSION pi-hole-v2.91test7)
set(DNSMASQ_VERSION pi-hole-v2.91test8)

add_subdirectory(src)
2 changes: 1 addition & 1 deletion src/dnsmasq/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
nxdomain = 0;
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
{
log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0);
log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr, record_source(crecp->uid), 0);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &crecp->addr))
Expand Down
5 changes: 5 additions & 0 deletions src/dnsmasq/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,11 @@ HAVE_SOCKADDR_SA_LEN
#define HAVE_INOTIFY
#endif

/* This never compiles code, it's only used by the makefile to fingerprint builds. */
#ifdef DNSMASQ_COMPILE_FLAGS
static char *compile_flags = DNSMASQ_COMPILE_FLAGS;
#endif

/* Define a string indicating which options are in use.
DNSMASQ_COMPILE_OPTS is only defined in dnsmasq.c */

Expand Down
68 changes: 45 additions & 23 deletions src/dnsmasq/forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,10 +884,6 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,

daemon->log_display_id = forward->frec_src.log_id;

/* We've had a reply already, which we're validating. Ignore this duplicate */
if (forward->blocking_query || (forward->flags & FREC_GONE_TO_TCP))
return;

/* Find the original query that started it all.... */
for (orig = forward; orig->dependent; orig = orig->dependent);

Expand Down Expand Up @@ -1216,18 +1212,20 @@ void reply_query(int fd, time_t now)
if (daemon->ignore_addr && RCODE(header) == NOERROR &&
check_for_ignored_address(header, n))
return;

if ((RCODE(header) == REFUSED || RCODE(header) == SERVFAIL) && forward->forwardall == 0)
/* for broken servers, attempt to send to another one. */
{

#ifdef HAVE_DNSSEC
/* The query MAY have got a good answer, and be awaiting
the results of further queries, in which case
The Stash contains something else and we don't need to retry anyway. */
the stash contains something else and we don't need to retry anyway.
We may also have already got a truncated reply, and be in the process
of doing the query by TCP so can ignore further, probably truncated, UDP answers. */
if (forward->blocking_query || (forward->flags & FREC_GONE_TO_TCP))
return;
#endif

if ((RCODE(header) == REFUSED || RCODE(header) == SERVFAIL) && forward->forwardall == 0)
/* for broken servers, attempt to send to another one. */
{
/* Get the saved query back. */
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);

Expand Down Expand Up @@ -1776,15 +1774,27 @@ void receive_query(struct listener *listen, time_t now)
&source_addr, auth_dns ? "auth" : "query", type, daemon->log_display_id, UDP);

#ifdef HAVE_AUTH
/* find queries for zones we're authoritative for, and answer them directly */
/* Find queries for zones we're authoritative for, and answer them directly.
The exception to this is DS queries for the zone route. They
have to come from the parent zone. Since dnsmasq's auth server
can't do DNSSEC, the zone will be unsigned, and anything using
dnsmasq as a forwarder and doing validation will be expecting to
see the proof of non-existence from the parent. */
if (!auth_dns && !option_bool(OPT_LOCALISE))
for (zone = daemon->auth_zones; zone; zone = zone->next)
if (in_zone(zone, daemon->namebuff, NULL))
{
auth_dns = 1;
local_auth = 1;
break;
}
{
char *cut;

if (in_zone(zone, daemon->namebuff, &cut))
{
if (type != T_DS || cut)
{
auth_dns = 1;
local_auth = 1;
}
break;
}
}
#endif

#ifdef HAVE_LOOP
Expand Down Expand Up @@ -2464,15 +2474,27 @@ unsigned char *tcp_request(int confd, time_t now,
&peer_addr, auth_dns ? "auth" : "query", qtype, daemon->log_display_id, TCP);

#ifdef HAVE_AUTH
/* find queries for zones we're authoritative for, and answer them directly */
/* Find queries for zones we're authoritative for, and answer them directly.
The exception to this is DS queries for the zone route. They
have to come from the parent zone. Since dnsmasq's auth server
can't do DNSSEC, the zone will be unsigned, and anything using
dnsmasq as a forwarder and doing validation will be expecting to
see the proof of non-existence from the parent. */
if (!auth_dns && !option_bool(OPT_LOCALISE))
for (zone = daemon->auth_zones; zone; zone = zone->next)
if (in_zone(zone, daemon->namebuff, NULL))
{
auth_dns = 1;
local_auth = 1;
break;
}
{
char *cut;

if (in_zone(zone, daemon->namebuff, &cut))
{
if (qtype != T_DS || cut)
{
auth_dns = 1;
local_auth = 1;
}
break;
}
}
#endif

norebind = domain_no_rebind(daemon->namebuff);
Expand Down
21 changes: 11 additions & 10 deletions src/dnsmasq/rfc1035.c
Original file line number Diff line number Diff line change
Expand Up @@ -1592,7 +1592,7 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
return daemon->max_ttl;
}

static int cache_validated(const struct crec *crecp)
static int cache_not_validated(const struct crec *crecp)
{
return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
}
Expand Down Expand Up @@ -1693,7 +1693,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,

/* If the client asked for DNSSEC don't use cached data. */
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
(rd_bit && (!do_bit || cache_validated(crecp))))
(rd_bit && (!do_bit || cache_not_validated(crecp))))
{
if (crecp->flags & F_CONFIG || qtype == T_CNAME)
ans = 1;
Expand Down Expand Up @@ -1852,7 +1852,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
the zone is unsigned, which implies that we're doing
validation. */
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
(rd_bit && (!do_bit || cache_validated(crecp)) ))
(rd_bit && (!do_bit || cache_not_validated(crecp)) ))
{
do
{
Expand Down Expand Up @@ -2008,7 +2008,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,

/* If the client asked for DNSSEC don't use cached data. */
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
(rd_bit && (!do_bit || cache_validated(crecp)) ))
(rd_bit && (!do_bit || cache_not_validated(crecp)) ))
do
{
int stale_flag = 0;
Expand Down Expand Up @@ -2205,19 +2205,19 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,

if (!ans)
{
if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) &&
rd_bit && (!do_bit || cache_validated(crecp)))
if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) && rd_bit)
do
{
int flags = crecp->flags;
unsigned short rrtype;

if (flags & F_KEYTAG)
rrtype = crecp->addr.rrblock.rrtype;
else
rrtype = crecp->addr.rrdata.rrtype;

if ((flags & F_NXDOMAIN) || rrtype == qtype)
if (((flags & F_NXDOMAIN) || rrtype == qtype) &&
(!do_bit || cache_not_validated(crecp)))
{
char *rrdata = NULL;
unsigned short rrlen = 0;
Expand Down Expand Up @@ -2280,14 +2280,15 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
}


if (qtype != T_ANY && !ans && rr_on_list(daemon->filter_rr, qtype))
if (qtype != T_ANY && !ans && rr_on_list(daemon->filter_rr, qtype) && !do_bit)
{
/* We don't have a cached answer and when we get an answer from upstream we're going to
filter it anyway. If we have a cached answer for the domain for another RRtype then
that may be enough to tell us if the answer should be NODATA and save the round trip.
Cached NXDOMAIN has already been handled, so here we look for any record for the domain,
since its existence allows us to return a NODATA answer. Note that we never set the AD flag,
since we didn't authenticate the record. */
since we didn't authenticate the record; this doesn't work if we want auth data, so
don't use this shortcut in that case. */

if (cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_RR | F_CNAME))
{
Expand Down

0 comments on commit 84e2ad1

Please sign in to comment.