mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Merge branch 'nxdomain'
This commit is contained in:
139
src/rfc1035.c
139
src/rfc1035.c
@@ -787,7 +787,10 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
if (!extract_name(header, qlen, &p1, name, 1, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
goto cname_loop1;
|
if (qtype != T_CNAME)
|
||||||
|
goto cname_loop1;
|
||||||
|
|
||||||
|
found = 1;
|
||||||
}
|
}
|
||||||
else if (aqtype != qtype)
|
else if (aqtype != qtype)
|
||||||
{
|
{
|
||||||
@@ -877,8 +880,19 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
return 0; /* bad packet */
|
return 0; /* bad packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found && !option_bool(OPT_NO_NEG))
|
if (!found && (qtype != T_ANY || (flags & F_NXDOMAIN)))
|
||||||
{
|
{
|
||||||
|
if (flags & F_NXDOMAIN)
|
||||||
|
{
|
||||||
|
flags &= ~(F_IPV4 | F_IPV6 | F_SRV);
|
||||||
|
|
||||||
|
/* Can store NXDOMAIN reply to CNAME or ANY query. */
|
||||||
|
if (qtype == T_CNAME || qtype == T_ANY)
|
||||||
|
insert = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL);
|
||||||
|
|
||||||
if (!searched_soa)
|
if (!searched_soa)
|
||||||
{
|
{
|
||||||
searched_soa = 1;
|
searched_soa = 1;
|
||||||
@@ -887,22 +901,17 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
|
|
||||||
/* If there's no SOA to get the TTL from, but there is a CNAME
|
/* If there's no SOA to get the TTL from, but there is a CNAME
|
||||||
pointing at this, inherit its TTL */
|
pointing at this, inherit its TTL */
|
||||||
if (ttl || cpp)
|
if (insert && !option_bool(OPT_NO_NEG) && (ttl || cpp))
|
||||||
{
|
{
|
||||||
if (ttl == 0)
|
if (ttl == 0)
|
||||||
ttl = cttl;
|
ttl = cttl;
|
||||||
|
|
||||||
log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL);
|
newc = cache_insert(name, NULL, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
|
||||||
|
if (newc && cpp)
|
||||||
if (insert)
|
|
||||||
{
|
{
|
||||||
newc = cache_insert(name, NULL, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
|
next_uid(newc);
|
||||||
if (newc && cpp)
|
cpp->addr.cname.target.cache = newc;
|
||||||
{
|
cpp->addr.cname.uid = newc->uid;
|
||||||
next_uid(newc);
|
|
||||||
cpp->addr.cname.target.cache = newc;
|
|
||||||
cpp->addr.cname.uid = newc->uid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1440,36 +1449,55 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
ans = 0; /* have we answered this question */
|
ans = 0; /* have we answered this question */
|
||||||
|
|
||||||
while (--count != 0 && (crecp = cache_find_by_name(NULL, name, now, F_CNAME)))
|
if (qclass == C_IN)
|
||||||
{
|
while (--count != 0 && (crecp = cache_find_by_name(NULL, name, now, F_CNAME | F_NXDOMAIN)))
|
||||||
char *cname_target = cache_get_cname_target(crecp);
|
{
|
||||||
|
char *cname_target;
|
||||||
|
|
||||||
/* If the client asked for DNSSEC don't use cached data. */
|
if (crecp->flags & F_NXDOMAIN)
|
||||||
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
{
|
||||||
(rd_bit && (!do_bit || cache_validated(crecp))))
|
if (qtype == T_CNAME)
|
||||||
{
|
{
|
||||||
if (crecp->flags & F_CONFIG || qtype == T_CNAME)
|
if (!dryrun)
|
||||||
ans = 1;
|
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
||||||
|
auth = 0;
|
||||||
|
nxdomain = 1;
|
||||||
|
ans = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(crecp->flags & F_DNSSECOK))
|
cname_target = cache_get_cname_target(crecp);
|
||||||
sec_data = 0;
|
|
||||||
|
/* If the client asked for DNSSEC don't use cached data. */
|
||||||
if (!dryrun)
|
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
|
||||||
{
|
(rd_bit && (!do_bit || cache_validated(crecp))))
|
||||||
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
{
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (crecp->flags & F_CONFIG || qtype == T_CNAME)
|
||||||
crec_ttl(crecp, now), &nameoffset,
|
ans = 1;
|
||||||
T_CNAME, C_IN, "d", cname_target))
|
|
||||||
anscount++;
|
if (!(crecp->flags & F_DNSSECOK))
|
||||||
}
|
sec_data = 0;
|
||||||
|
|
||||||
}
|
if (!dryrun)
|
||||||
else
|
{
|
||||||
return 0; /* give up if any cached CNAME in chain can't be used for DNSSEC reasons. */
|
log_query(crecp->flags, name, NULL, record_source(crecp->uid));
|
||||||
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
strcpy(name, cname_target);
|
crec_ttl(crecp, now), &nameoffset,
|
||||||
}
|
T_CNAME, C_IN, "d", cname_target))
|
||||||
|
anscount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0; /* give up if any cached CNAME in chain can't be used for DNSSEC reasons. */
|
||||||
|
|
||||||
|
if (qtype == T_CNAME)
|
||||||
|
break;
|
||||||
|
|
||||||
|
strcpy(name, cname_target);
|
||||||
|
}
|
||||||
|
|
||||||
if (qtype == T_TXT || qtype == T_ANY)
|
if (qtype == T_TXT || qtype == T_ANY)
|
||||||
{
|
{
|
||||||
struct txt_record *t;
|
struct txt_record *t;
|
||||||
@@ -1612,7 +1640,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
|
else if (is_arpa && (crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
|
||||||
{
|
{
|
||||||
/* Don't use cache when DNSSEC data required, unless we know that
|
/* Don't use cache when DNSSEC data required, unless we know that
|
||||||
the zone is unsigned, which implies that we're doing
|
the zone is unsigned, which implies that we're doing
|
||||||
@@ -1751,7 +1779,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, flag | (dryrun ? F_NO_RR : 0))))
|
if ((crecp = cache_find_by_name(NULL, name, now, flag | F_NXDOMAIN | (dryrun ? F_NO_RR : 0))))
|
||||||
{
|
{
|
||||||
int localise = 0;
|
int localise = 0;
|
||||||
|
|
||||||
@@ -1915,16 +1943,20 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, F_SRV | (dryrun ? F_NO_RR : 0))) &&
|
if ((crecp = cache_find_by_name(NULL, name, now, F_SRV | F_NXDOMAIN | (dryrun ? F_NO_RR : 0))) &&
|
||||||
rd_bit && (!do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
|
rd_bit && (!do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK))))
|
||||||
{
|
do
|
||||||
if (!(crecp->flags & F_DNSSECOK))
|
{
|
||||||
sec_data = 0;
|
/* don't answer wildcard queries with data not from /etc/hosts or dhcp leases, except for NXDOMAIN */
|
||||||
|
if (qtype == T_ANY && !(crecp->flags & (F_NXDOMAIN)))
|
||||||
auth = 0;
|
break;
|
||||||
found = ans = 1;
|
|
||||||
|
if (!(crecp->flags & F_DNSSECOK))
|
||||||
do {
|
sec_data = 0;
|
||||||
|
|
||||||
|
auth = 0;
|
||||||
|
found = ans = 1;
|
||||||
|
|
||||||
if (crecp->flags & F_NEG)
|
if (crecp->flags & F_NEG)
|
||||||
{
|
{
|
||||||
if (crecp->flags & F_NXDOMAIN)
|
if (crecp->flags & F_NXDOMAIN)
|
||||||
@@ -1945,8 +1977,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
}
|
}
|
||||||
} while ((crecp = cache_find_by_name(crecp, name, now, F_SRV)));
|
} while ((crecp = cache_find_by_name(crecp, name, now, F_SRV)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
|
if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
|
||||||
{
|
{
|
||||||
ans = 1;
|
ans = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user