Subtle change to priority of --server types.

Make --server=/example.com/1.2.3.4 take priority over
--server=/example.com/ (AKA --address=/example.com/ or --local=/example.com/)

This corrects a regression in the domain-match rewrite, and appears
to be the more useful order. It got swapped because I didn't consider
that both could usefully co-exist.
This commit is contained in:
Simon Kelley
2021-07-06 21:02:35 +01:00
parent 96f6444958
commit 719f79a8fd

View File

@@ -243,11 +243,6 @@ int lookup_domain(char *domain, int flags, int *lowout, int *highout)
(nlow == nhigh || daemon->serverarray[nlow]->domain_len == 0)) (nlow == nhigh || daemon->serverarray[nlow]->domain_len == 0))
filter_servers(daemon->serverarraysz-1, flags, &nlow, &nhigh); filter_servers(daemon->serverarraysz-1, flags, &nlow, &nhigh);
/* F_DOMAINSRV returns only domain-specific servers, so if we got to a
general server, return empty set. */
if (nlow != nhigh && (flags & F_DOMAINSRV) && daemon->serverarray[nlow]->domain_len == 0)
nlow = nhigh;
if (lowout) if (lowout)
*lowout = nlow; *lowout = nlow;
@@ -282,11 +277,6 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
nhigh++; nhigh++;
/* Now the servers are on order between low and high, in the order
return zero for both, IPv6 addr, IPv4 addr, no-data return, send upstream.
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) #define SERV_LOCAL_ADDRESS (SERV_6ADDR | SERV_4ADDR | SERV_ALL_ZEROS)
if (flags & F_CONFIG) if (flags & F_CONFIG)
@@ -302,6 +292,11 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
} }
else else
{ {
/* Now the servers are on order between low and high, in the order
IPv6 addr, IPv4 addr, return zero for both, send upstream, no-data return.
See which of those match our query in that priority order and narrow (low, high) */
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))
@@ -326,18 +321,26 @@ int filter_servers(int seed, int flags, int *lowout, int *highout)
{ {
nlow = i; nlow = i;
for (i = nlow; i < nhigh && (daemon->serverarray[i]->flags & SERV_LITERAL_ADDRESS); i++); /* now look for a server */
for (i = nlow; i < nhigh && !(daemon->serverarray[i]->flags & SERV_LITERAL_ADDRESS); i++);
/* --local=/domain/, only return if we don't need a server. */
if (i != nlow && !(flags & (F_DNSSECOK | F_DOMAINSRV | F_SERVER))) if (i != nlow)
nhigh = i;
else
{ {
nlow = i;
/* If we want a server that can do DNSSEC, and this one can't, /* If we want a server that can do DNSSEC, and this one can't,
return nothing. */ return nothing, similarly if were looking only for a server
for a particular domain. */
if ((flags & F_DNSSECOK) && !(daemon->serverarray[nlow]->flags & SERV_DO_DNSSEC)) if ((flags & F_DNSSECOK) && !(daemon->serverarray[nlow]->flags & SERV_DO_DNSSEC))
nlow = nhigh; nlow = nhigh;
else if ((flags & F_DOMAINSRV) && daemon->serverarray[nlow]->domain_len == 0)
nlow = nhigh;
else
nhigh = i;
}
else
{
/* --local=/domain/, only return if we don't need a server. */
if (flags & (F_DNSSECOK | F_DOMAINSRV | F_SERVER))
nhigh = i;
} }
} }
} }
@@ -515,10 +518,12 @@ static int order_qsort(const void *a, const void *b)
rc = order_servers(s1, s2); rc = order_servers(s1, s2);
/* Sort all literal NODATA and local IPV4 or IPV6 responses together, /* Sort all literal NODATA and local IPV4 or IPV6 responses together,
in a very specific order. */ in a very specific order. We flip the SERV_LITERAL_ADDRESS bit
so the order is IPv6 literal, IPv4 literal, all-zero literal,
upstream server, NXDOMAIN literal. */
if (rc == 0) if (rc == 0)
rc = (s2->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) - rc = ((s2->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS) -
(s1->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)); ((s1->flags & (SERV_LITERAL_ADDRESS | SERV_4ADDR | SERV_6ADDR | SERV_ALL_ZEROS)) ^ SERV_LITERAL_ADDRESS);
/* Finally, order by appearance in /etc/resolv.conf etc, for --strict-order */ /* Finally, order by appearance in /etc/resolv.conf etc, for --strict-order */
if (rc == 0) if (rc == 0)