mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-13 17:00:49 +00:00
Compare commits
7
Commits
v2.91test7
...
v2.91test8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b72ecb3a59 | ||
|
|
c221030f89 | ||
|
|
5bbea085d0 | ||
|
|
622cf03ab9 | ||
|
|
8ce27433f8 | ||
|
|
5d894620b4 | ||
|
|
71766c0c35 |
No files matched your search
@@ -82,6 +82,21 @@ version 2.91
|
|||||||
to queries which arrive a dnsmasq already carrying an EDNS client
|
to queries which arrive a dnsmasq already carrying an EDNS client
|
||||||
subnet.
|
subnet.
|
||||||
|
|
||||||
|
Handle DS queries to auth zones. When dnsmasq is configured to
|
||||||
|
act as an authoritative server and has an authoritative zone
|
||||||
|
configured, and recieves a query for that zone _as_forwarder_
|
||||||
|
it answers the query directly rather than forwarding it. This
|
||||||
|
doesn't affect the answer, but it saves dnsmasq forwarding the
|
||||||
|
query to the recusor upstream, whch then bounces it back to dnsmasq
|
||||||
|
in auth mode. The exception should be when the query is for the root
|
||||||
|
of zone, for a DS RR. The answer to that has to come from the parent,
|
||||||
|
via the recursor, and will typically be a proof-of-nonexistence
|
||||||
|
since dnsmasq doesn't support signed zones. This patch suppresses
|
||||||
|
local answers and forces forwarding to the upstream recursor for such
|
||||||
|
queries. It stops breakage when a DNSSEC validating client makes
|
||||||
|
queries to dnsmasq acting as forwarder for a zone for which it is
|
||||||
|
authoritative.
|
||||||
|
|
||||||
|
|
||||||
version 2.90
|
version 2.90
|
||||||
Fix reversion in --rev-server introduced in 2.88 which
|
Fix reversion in --rev-server introduced in 2.88 which
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ nft_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG
|
|||||||
nft_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --libs libnftables`
|
nft_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --libs libnftables`
|
||||||
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
||||||
|
|
||||||
sum?=$(shell $(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
|
sum?=$(shell echo $(CC) -DDNSMASQ_COMPILE_FLAGS="$(CFLAGS)" -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
|
||||||
sum!=$(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' '
|
sum!=echo $(CC) -DDNSMASQ_COMPILE_FLAGS="$(CFLAGS)" -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' '
|
||||||
copts_conf = .copts_$(sum)
|
copts_conf = .copts_$(sum)
|
||||||
|
|
||||||
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||||
|
|||||||
+1
-1
@@ -513,7 +513,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
nxdomain = 0;
|
nxdomain = 0;
|
||||||
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr))))
|
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,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||||
qtype == T_A ? "4" : "6", &crecp->addr))
|
qtype == T_A ? "4" : "6", &crecp->addr))
|
||||||
|
|||||||
@@ -362,6 +362,11 @@ HAVE_SOCKADDR_SA_LEN
|
|||||||
#define HAVE_INOTIFY
|
#define HAVE_INOTIFY
|
||||||
#endif
|
#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.
|
/* Define a string indicating which options are in use.
|
||||||
DNSMASQ_COMPILE_OPTS is only defined in dnsmasq.c */
|
DNSMASQ_COMPILE_OPTS is only defined in dnsmasq.c */
|
||||||
|
|
||||||
|
|||||||
+34
-12
@@ -822,10 +822,6 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
|
|||||||
|
|
||||||
daemon->log_display_id = forward->frec_src.log_id;
|
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.... */
|
/* Find the original query that started it all.... */
|
||||||
for (orig = forward; orig->dependent; orig = orig->dependent);
|
for (orig = forward; orig->dependent; orig = orig->dependent);
|
||||||
|
|
||||||
@@ -1153,17 +1149,19 @@ void reply_query(int fd, time_t now)
|
|||||||
check_for_ignored_address(header, n))
|
check_for_ignored_address(header, n))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((RCODE(header) == REFUSED || RCODE(header) == SERVFAIL) && forward->forwardall == 0)
|
|
||||||
/* for broken servers, attempt to send to another one. */
|
|
||||||
{
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
/* The query MAY have got a good answer, and be awaiting
|
/* The query MAY have got a good answer, and be awaiting
|
||||||
the results of further queries, in which case
|
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))
|
if (forward->blocking_query || (forward->flags & FREC_GONE_TO_TCP))
|
||||||
return;
|
return;
|
||||||
#endif
|
#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. */
|
/* Get the saved query back. */
|
||||||
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
|
||||||
|
|
||||||
@@ -1693,15 +1691,27 @@ void receive_query(struct listener *listen, time_t now)
|
|||||||
&source_addr, auth_dns ? "auth" : "query", type);
|
&source_addr, auth_dns ? "auth" : "query", type);
|
||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#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))
|
if (!auth_dns && !option_bool(OPT_LOCALISE))
|
||||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
if (in_zone(zone, daemon->namebuff, NULL))
|
{
|
||||||
|
char *cut;
|
||||||
|
|
||||||
|
if (in_zone(zone, daemon->namebuff, &cut))
|
||||||
|
{
|
||||||
|
if (type != T_DS || cut)
|
||||||
{
|
{
|
||||||
auth_dns = 1;
|
auth_dns = 1;
|
||||||
local_auth = 1;
|
local_auth = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LOOP
|
#ifdef HAVE_LOOP
|
||||||
@@ -2327,15 +2337,27 @@ unsigned char *tcp_request(int confd, time_t now,
|
|||||||
&peer_addr, auth_dns ? "auth" : "query", qtype);
|
&peer_addr, auth_dns ? "auth" : "query", qtype);
|
||||||
|
|
||||||
#ifdef HAVE_AUTH
|
#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))
|
if (!auth_dns && !option_bool(OPT_LOCALISE))
|
||||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
if (in_zone(zone, daemon->namebuff, NULL))
|
{
|
||||||
|
char *cut;
|
||||||
|
|
||||||
|
if (in_zone(zone, daemon->namebuff, &cut))
|
||||||
|
{
|
||||||
|
if (qtype != T_DS || cut)
|
||||||
{
|
{
|
||||||
auth_dns = 1;
|
auth_dns = 1;
|
||||||
local_auth = 1;
|
local_auth = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
norebind = domain_no_rebind(daemon->namebuff);
|
norebind = domain_no_rebind(daemon->namebuff);
|
||||||
|
|||||||
+10
-9
@@ -1559,7 +1559,7 @@ static unsigned long crec_ttl(struct crec *crecp, time_t now)
|
|||||||
return daemon->max_ttl;
|
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));
|
return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
|
||||||
}
|
}
|
||||||
@@ -1660,7 +1660,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 the client asked for DNSSEC don't use cached data. */
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
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)
|
if (crecp->flags & F_CONFIG || qtype == T_CNAME)
|
||||||
ans = 1;
|
ans = 1;
|
||||||
@@ -1819,7 +1819,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
the zone is unsigned, which implies that we're doing
|
the zone is unsigned, which implies that we're doing
|
||||||
validation. */
|
validation. */
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
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
|
do
|
||||||
{
|
{
|
||||||
@@ -1975,7 +1975,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 the client asked for DNSSEC don't use cached data. */
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
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
|
do
|
||||||
{
|
{
|
||||||
int stale_flag = 0;
|
int stale_flag = 0;
|
||||||
@@ -2157,8 +2157,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
if (!ans)
|
if (!ans)
|
||||||
{
|
{
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) &&
|
if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) && rd_bit)
|
||||||
rd_bit && (!do_bit || cache_validated(crecp)))
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int flags = crecp->flags;
|
int flags = crecp->flags;
|
||||||
@@ -2169,7 +2168,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
else
|
else
|
||||||
rrtype = crecp->addr.rrdata.rrtype;
|
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;
|
char *rrdata = NULL;
|
||||||
unsigned short rrlen = 0;
|
unsigned short rrlen = 0;
|
||||||
@@ -2232,14 +2232,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
|
/* 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
|
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.
|
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,
|
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 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))
|
if (cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_RR | F_CNAME))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user