Log a message if a mirror zone becomes unusable for the resolver (most
usually due to the zone's expiration timer firing). Ensure that
verification failures do not cause a mirror zone to be unloaded
(instead, its last successfully verified version should be served if it
is available).
Log a message when a mirror zone is successfully loaded from disk and
subsequently verified.
This could have been implemented in a simpler manner, e.g. by modifying
an earlier code branch inside zone_postload() which checks whether the
zone already has a database attached and calls attachdb() if it does
not, but that would cause the resulting logs to indicate that a mirror
zone comes into effect before the "loaded serial ..." message is logged,
which would be confusing.
Tweak some existing sed commands used in the "mirror" system test to
ensure that separate test cases comprising it do not break each other.
Log a message when a mirror zone is successfully transferred and
verified, but only if no database for that zone was yet loaded at the
time the transfer was initiated.
This could have been implemented in a simpler manner, e.g. by modifying
zone_replacedb(), but (due to the calling order of the functions
involved in finalizing a zone transfer) that would cause the resulting
logs to suggest that a mirror zone comes into effect before its transfer
is finished, which would be confusing given the nature of mirror zones
and the fact that no message is logged upon successful mirror zone
verification.
Once the dns_zone_replacedb() call in axfr_finalize() is made, it
becomes impossible to determine whether the transferred zone had a
database attached before the transfer was started. Thus, that check is
instead performed when the transfer context is first created and the
result of this check is passed around in a field of the transfer context
structure. If it turns out to be desired, the relevant log message is
then emitted just before the transfer context is freed.
Taking this approach means that the log message added by this commit is
not timed precisely, i.e. mirror zone data may be used before this
message is logged. However, that can only be fixed by logging the
message inside zone_replacedb(), which causes arguably more dire issues
discussed above.
dns_zone_isloaded() is not used to double-check that transferred zone
data was correctly loaded since the 'shutdown_result' field of the zone
transfer context will not be set to ISC_R_SUCCESS unless axfr_finalize()
succeeds (and that in turn will not happen unless dns_zone_replacedb()
succeeds).
The handling of class and view arguments was broken, because the code
didn't realise that next_token() would overwrite the class name when
it parsed the view name. The code was trying to implement a syntax
like `refresh [[class] view]`, but it was documented to have a syntax
like `refresh [class [view]]`. The latter is consistent with other rndc
commands, so that is how I have fixed it.
Before:
$ rndc managed-keys refresh in rec
rndc: 'managed-keys' failed: unknown class/type
unknown class 'rec'
After:
$ rndc managed-keys refresh in rec
refreshing managed keys for 'rec'
There were missing newlines in the output from `rndc managed-keys
refresh` and `rndc managed-keys destroy`.
Before:
$ rndc managed-keys refresh
refreshing managed keys for 'rec'refreshing managed keys for 'auth'
After:
$ rndc managed-keys refresh
refreshing managed keys for 'rec'
refreshing managed keys for 'auth'
- the checkprivate function in the dnssec test set ret=0, erasing
results from previous tests and making the test appear to have passed
when it shouldn't have
- checkprivate needed a delay loop to ensure there was time for all
private signing records to be updated before the test
When a query times out after a socket is created and associated with a
given dig_query_t structure, calling isc_socket_cancel() causes
connect_done() to be run, which in turn takes care of all necessary
cleanups. However, certain errors (e.g. get_address() returning
ISC_R_FAMILYNOSUPPORT) may prevent a TCP socket from being created in
the first place. Since force_timeout() may be used in code handling
such errors, connect_timeout() needs to properly clean up a TCP query
which is not associated with any socket. Call clear_query() from
connect_timeout() after attempting to send a TCP query to the next
available server if the timed out query does not have a socket
associated with it, in order to prevent dig from hanging indefinitely
due to the dig_query_t structure not being detached from its parent
dig_lookup_t structure.
When a query times out and another server is available for querying
within the same lookup, the timeout handler - connect_timeout() - is
responsible for sending the query to the next server. Extract the
relevant part of connect_timeout() to a separate function in order to
improve code readability.
Before commit c2ec022f57, using the "-b"
command line switch for dig did not disable use of the other address
family than the one to which the address supplied to that option
belonged to. Thus, bind9_getaddresses() could e.g. prepare an
isc_sockaddr_t structure for an IPv6 address when an IPv4 address has
been passed to the "-b" command line option. To avoid attempting the
impossible (e.g. querying an IPv6 address from a socket bound to an IPv4
address), a certain code block in send_tcp_connect() checked whether the
address family of the server to be queried was the same as the address
family of the socket set up for sending that query; if there was a
mismatch, that particular server address was skipped.
Commit c2ec022f57 made
bind9_getaddresses() fail upon an address family mismatch between the
address the hostname passed to it resolved to and the address supplied
to the "-b" command line option. Such failures were fatal to dig back
then.
Commit 7f65860391 made
bind9_getaddresses() failures non-fatal, but also ensured that a
get_address() failure in send_tcp_connect() still causes the given query
address to be skipped (and also made such failures trigger an early
return from send_tcp_connect()).
Summing up, the code block handling address family mismatches in
send_tcp_connect() has been redundant since commit
c2ec022f57. Remove it.
Since following a delegation resets most fetch context state, address
marks (FCTX_ADDRINFO_MARK) set inside lib/dns/resolver.c are not
preserved when a delegation is followed. This is fine for full
recursive resolution but when named is configured with "forward first;"
and one of the specified forwarders times out, triggering a fallback to
full recursive resolution, that forwarder should no longer be consulted
at each delegation point subsequently reached within a given fetch
context.
Add a new badnstype_t enum value, badns_forwarder, and use it to mark a
forwarder as bad when it times out in a "forward first;" configuration.
Since the bad server list is not cleaned when a fetch context follows a
delegation, this prevents a forwarder from being queried again after
falling back to full recursive resolution. Yet, as each fetch context
maintains its own list of bad servers, this change does not cause a
forwarder timeout to prevent that forwarder from being used by other
fetch contexts.