mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Fix specific NOERR/NXDOMAIN confusion.
In the specific case of configuring an A record for a domain address=/example.com/1.2.3.4 queries for *example.com for any other type will now return NOERR, and not the previous erroneous NXDOMAIN. The same thing applies for address=/example.com/::1:2:3:4 address=/example.com/#
This commit is contained in:
@@ -75,6 +75,8 @@ void build_server_array(void)
|
||||
A flag of F_DNSSECOK returns a DNSSEC capable server only and
|
||||
also disables NODOTS servers from consideration.
|
||||
A flag of F_DOMAINSRV returns a domain-specific server only.
|
||||
A flag of F_CONFIG returns anything that generates a local
|
||||
reply of IPv4 or IPV6.
|
||||
return 0 if nothing found, 1 otherwise.
|
||||
*/
|
||||
int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
||||
@@ -85,8 +87,6 @@ int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
||||
int nlow = 0, nhigh = 0;
|
||||
char *cp;
|
||||
|
||||
int compares = 0;
|
||||
|
||||
/* may be no configured servers. */
|
||||
if (daemon->serverarraysz == 0)
|
||||
return 0;
|
||||
@@ -121,8 +121,6 @@ int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
||||
{
|
||||
try = (low + high)/2;
|
||||
|
||||
compares++;
|
||||
|
||||
if ((rc = order(qdomain, leading_dot, qlen, daemon->serverarray[try])) == 0)
|
||||
break;
|
||||
|
||||
@@ -186,8 +184,6 @@ int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
||||
qdomain += crop_query;
|
||||
}
|
||||
|
||||
printf("compares: %d\n", compares);
|
||||
|
||||
/* domain has no dots, and we have at least one server configured to handle such,
|
||||
These servers always sort to the very end of the array.
|
||||
A configured server eg server=/lan/ will take precdence. */
|
||||
@@ -240,6 +236,14 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
|
||||
|
||||
See which of those match our query in that priority order and narrow (low, high) */
|
||||
|
||||
#define SERV_LOCAL_ADDRESS (SERV_6ADDR | SERV_4ADDR | SERV_ALL_ZEROS)
|
||||
|
||||
for (i = nlow; (flags & F_CONFIG) && i < nhigh && (daemon->serverarray[i]->flags & SERV_LOCAL_ADDRESS); i++);
|
||||
|
||||
if (i != nlow)
|
||||
nhigh = i;
|
||||
else
|
||||
{
|
||||
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_6ADDR); i++);
|
||||
|
||||
if (i != nlow && (flags & F_IPV6))
|
||||
@@ -280,6 +284,7 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*lowout = nlow;
|
||||
*highout = nhigh;
|
||||
@@ -301,7 +306,19 @@ int is_local_answer(time_t now, int first, char *name)
|
||||
else if (flags & SERV_ALL_ZEROS)
|
||||
rc = F_IPV4 | F_IPV6;
|
||||
else
|
||||
rc = check_for_local_domain(name, now) ? F_NOERR : F_NXDOMAIN;
|
||||
{
|
||||
/* argument first is the first struct server which matches the query type;
|
||||
now roll back to the server which is just the same domain, to check if that
|
||||
provides an answer of a different type. */
|
||||
|
||||
for (;first > 0 && order_servers(daemon->serverarray[first-1], daemon->serverarray[first]) == 0; first--);
|
||||
|
||||
if ((daemon->serverarray[first]->flags & SERV_LOCAL_ADDRESS) ||
|
||||
check_for_local_domain(name, now))
|
||||
rc = F_NOERR;
|
||||
else
|
||||
rc = F_NXDOMAIN;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -663,8 +663,10 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
int doctored = 0;
|
||||
|
||||
if (rcode == NXDOMAIN &&
|
||||
extract_request(header, n, daemon->namebuff, NULL) &&
|
||||
check_for_local_domain(daemon->namebuff, now))
|
||||
extract_request(header, n, daemon->namebuff, NULL))
|
||||
{
|
||||
if (check_for_local_domain(daemon->namebuff, now) ||
|
||||
lookup_domain(daemon->namebuff, F_CONFIG, NULL, NULL))
|
||||
{
|
||||
/* if we forwarded a query for a locally known name (because it was for
|
||||
an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
|
||||
@@ -674,6 +676,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
||||
SET_RCODE(header, NOERROR);
|
||||
cache_secure = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user