mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28: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
|
A flag of F_DNSSECOK returns a DNSSEC capable server only and
|
||||||
also disables NODOTS servers from consideration.
|
also disables NODOTS servers from consideration.
|
||||||
A flag of F_DOMAINSRV returns a domain-specific server only.
|
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.
|
return 0 if nothing found, 1 otherwise.
|
||||||
*/
|
*/
|
||||||
int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
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;
|
int nlow = 0, nhigh = 0;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
int compares = 0;
|
|
||||||
|
|
||||||
/* may be no configured servers. */
|
/* may be no configured servers. */
|
||||||
if (daemon->serverarraysz == 0)
|
if (daemon->serverarraysz == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -121,8 +121,6 @@ int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
|||||||
{
|
{
|
||||||
try = (low + high)/2;
|
try = (low + high)/2;
|
||||||
|
|
||||||
compares++;
|
|
||||||
|
|
||||||
if ((rc = order(qdomain, leading_dot, qlen, daemon->serverarray[try])) == 0)
|
if ((rc = order(qdomain, leading_dot, qlen, daemon->serverarray[try])) == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -186,8 +184,6 @@ int lookup_domain(char *qdomain, int flags, int *lowout, int *highout)
|
|||||||
qdomain += crop_query;
|
qdomain += crop_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("compares: %d\n", compares);
|
|
||||||
|
|
||||||
/* domain has no dots, and we have at least one server configured to handle such,
|
/* 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.
|
These servers always sort to the very end of the array.
|
||||||
A configured server eg server=/lan/ will take precdence. */
|
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) */
|
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++);
|
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_6ADDR); i++);
|
||||||
|
|
||||||
if (i != nlow && (flags & F_IPV6))
|
if (i != nlow && (flags & F_IPV6))
|
||||||
@@ -280,6 +284,7 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*lowout = nlow;
|
*lowout = nlow;
|
||||||
*highout = nhigh;
|
*highout = nhigh;
|
||||||
@@ -301,7 +306,19 @@ int is_local_answer(time_t now, int first, char *name)
|
|||||||
else if (flags & SERV_ALL_ZEROS)
|
else if (flags & SERV_ALL_ZEROS)
|
||||||
rc = F_IPV4 | F_IPV6;
|
rc = F_IPV4 | F_IPV6;
|
||||||
else
|
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;
|
return rc;
|
||||||
|
|||||||
@@ -663,8 +663,10 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
|
|||||||
int doctored = 0;
|
int doctored = 0;
|
||||||
|
|
||||||
if (rcode == NXDOMAIN &&
|
if (rcode == NXDOMAIN &&
|
||||||
extract_request(header, n, daemon->namebuff, NULL) &&
|
extract_request(header, n, daemon->namebuff, NULL))
|
||||||
check_for_local_domain(daemon->namebuff, now))
|
{
|
||||||
|
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
|
/* 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,
|
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);
|
SET_RCODE(header, NOERROR);
|
||||||
cache_secure = 0;
|
cache_secure = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
|
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