In an era where everything has an MMU, this looks like
an anachronism, and it adds to (Ok, multiplies!) the
combinatorial explosion of compile-time options.
The above is intended to increase robustness, but actually does the
opposite. The problem is that by ignoring SERVFAIL messages and hoping
for a better answer from another of the servers we've forwarded to,
we become vulnerable in the case that one or more of the configured
servers is down or not responding.
Consider the case that a domain is indeed BOGUS, and we've send the
query to n servers. With 68f6312d4b
we ignore the first n-1 SERVFAIL replies, and only return the
final n'th answer to the client. Now, if one of the servers we are
forwarding to is down, then we won't get all n replies, and the
client will never get an answer! This is a far more likely scenario
than a temporary SERVFAIL from only one of a set of notionally identical
servers, so, on the ground of robustness, we have to believe
any SERVFAIL answers we get, and return them to the client.
The client could be using the same recursive servers we are,
so it should, in theory, retry on SERVFAIL anyway.
If arg2 of pkg-wrapper is "--copy", then arg1 is NOT the name of
the package manager (--copy doesn't invoke it) it's a secondary
config string that inhibts the copy if found. This patch allows that
to be the empty string, for unconditional copy, and modifies the
ubus linker config to use it. It worked by coincidence before, because
there was no config string called "pkg-config".
Make options bits derived from size and count. Use size of option bits
and last supported bit in computation. No new change would be required
when new options are added. Just change OPT_LAST constant.
Chaos .bind and .server (RFC4892) zones are local, therefore
don't forward queries upstream to avoid mixing with supported
locally and false replies with NO_ID enabled.
This was the source of a large number of #ifdefs, originally
included for use with old embedded libc versions. I'm
sure no-one wants or needs IPv6-free code these days, so this
is a move towards more maintainable code.
For ease of implementaion, dnsmasq has always forked a new process to
handle each incoming TCP connection. A side-effect of this is that any
DNS queries answered from TCP connections are not cached: when TCP
connections were rare, this was not a problem. With the coming of
DNSSEC, it's now the case that some DNSSEC queries have answers which
spill to TCP, and if, for instance, this applies to the keys for the
root then those never get cached, and performance is very bad. This
fix passes cache entries back from the TCP child process to the main
server process, and fixes the problem.
The code which conirms possible SLAAC addresses associated with
hosts known from DHCPv4 addresses keeps trying at longer and longer
intervals essentially forever, EXCEPT if sending an ICMP ping results
in a HOSTUNREACH error, which terminates the process immediately.
It turns out that this is too drastic. Routing changes associated
with addressing changes can cause temporary HOSTUNREACH problems,
even when an address has not gone forever. Therefore continue
trying in the face of HOSTUNREACH for the first part of the
process. HOSTUNREACH errors will still terminate the process
after it reaches the slow tail of retries.
Thanks to Andrey Vakhitov for help diagnosing this.
But make auth-server required when any auth-zones are defined.
The "glue record" field in auth-server is needed to synthesise
SOA and NS records in auth zones, so the --auth-server has to
be specified. If makes sense, however to define one or more
auth-zones that appear within the normal recursive DNS service
without actually acting as an authoritative DNS server on
any interface. Hence making the interface field optional.
These normally have enough space for a name of up to SMALLDNAME characters.
When used to hold /etc/hosts entries, they are allocated with just enough
bytes for the name held. When used to hold other configured stuff, (CNAMES
DS records. DHCP names etc), the name is replaced by a pointer to a string
held elsewhere, and F_NAMEP set. Hence only enough space to hold a char *
is needed, rather than SMALLDNAME bytes.
Many thanks to Kristian Evensen for finding and diagnosing this.
We can't copy the whole of a crec structure in make_non_terminals, since
crec structures allocated to represent /etc/hosts entries are allocated with
just enough space for the actual name they contain, not the full
SMALLDNAME bytes declared in struct crec. Using structure copy therefore
copies beyond the end of the allocated source and, just occaisionally,
into unmapped memory, resulting in a SEGV.
Since the crecs we're making here always have F_NAMEP set, we're not
interested in copying the name field from the source anyway, we use the
namep part of the union and set it to point some way into the name
of the source crec to get the super-domain that we're representing.
The fix is therefore to copy the relevant fields of the crec, rather
than copying the whole and overwriting.
Change anti cache-snooping behaviour with queries with the
recursion-desired bit unset. Instead to returning SERVFAIL, we
now always forward, and never answer from the cache. This
allows "dig +trace" command to work.
When a record is defined locally, eg an A record for one.two.example then
we already know that if we forward, eg an AAAA query for one.two.example,
and get back NXDOMAIN, then we need to alter that to NODATA. This is handled
by check_for_local_domain(). But, if we forward two.example, because
one.two.example exists, then the answer to two.example should also be
a NODATA.
For most local records this is easy, just to substring matching.
for A, AAAA and CNAME records that are in the cache, it's more difficult.
The cache has no efficient way to find such records. The fix is to
insert empty (none of F_IPV4, F_IPV6 F_CNAME set) records for each
non-terminal.
The same considerations apply in auth mode, and the same basic mechanism
is used there too.