The dns_remote_t structure is intended to replace the variables in
the structure that deals with remote server communication to primaries,
parental agents, forwarders, etc.
Introduce a way to configure servers that can be used to dynamically
update DS records during KSK rollovers. The update-ds configuration
option is a zone only option and may reference a parental-agents
statement.
Add some checkconf checks similar to parental-agents, like the option
being at the wrong level, a duplicate list, an empty list, at the
wrong zone type, and a reference to parental-agents not found.
For UDP queries, after calling dns_adb_beginudpfetch() in fctx_query(),
make sure that dns_adb_endudpfetch() is also called on error path, in
order to adjust the quota back.
It is currently possible that dns_adb_endudpfetch() is not
called in fctx_cancelquery() for a UDP query, which results
in quotas not being adjusted back.
Always call dns_adb_endudpfetch() for UDP queries.
In the cleanup code of fctx_query() function there is a code path
where 'query' is linked to 'fctx' and it is being destroyed.
Make sure that 'query' is unlinked before destroying it.
This commit fixes a startup issue on Solaris systems with
many (reportedly > 510) CPUs by bumping RLIMIT_NOFILE. This appears to
be a regression from 9.11.
For tests where the TCP connection might get interrupted abruptly,
replace the nc with curl as the data sent from server to client might
get lost because of abrupt TCP connection. This happens when the TCP
connection gets closed during sending the large request to the server.
As we already require curl for other system tests, replace the nc usage
in the statschannel test with curl that actually understands the
HTTP/1.1 protocol, so the same connection is reused for sending the
consequtive requests, but without client-side "pipelining".
For the record, the server doesn't support parallel processing of the
pipelined request, so it's a bit misnomer here, because what we are
actually testing is that we process all requests received in a single
TCP read callback.
RPZ rewrites called dns_db_findext() without passing through the
client database options; as as result, if the client set CD=1,
DNS_DBFIND_PENDINGOK was not used as it should have been, and
cache lookups failed, resulting in failure of the rewrite.
The statschannel truncated test still terminates abruptly sometimes and
it doesn't return the answer for the first query. This might happen
when the second process_request() discovers there's not enough space
before the sending is complete and the connection is terminated before
the client gets the data.
Change the isc_http, so it pauses the reading when it receives the data
and resumes it only after the sending has completed or there's
incomplete request waiting for more data.
This makes the request processing slightly less efficient, but also less
taxing for the server, because previously all requests that has been
received via single TCP read would be processed in the loop and the
sends would be queued after the read callback has processed a full
buffer.
In non-developer build, a wrong condition prevented the
isc__tls_malloc_ex, isc__tls_realloc_ex and isc__tls_free_ex to be
defined. This was causing FTBFS on platforms with OpenSSL 1.0.2.
The 5 seconds requirement to finish the 'pipelined with truncated
stream' was causing spurious failures in the CI because the job runners
might be very busy and sending 128k of data might simply take some time.
Remove the time requirement altogether, there's actually no reason why
the test SHOULD or even MUST finish under 5 seconds.
Correctly source conf.sh in dupsigs test scripts (fix issue introduced
by 093af1c00a).
Update dupsigs test for dnssec-dnskey-kskonly default. Since v9.17.20,
the dnssec-dnskey-kskonly is set to yes. Update the test to not expect
the additional RRSIG with ZSK for DNSKEY.
Speed up the test from 20 minutes to 2.5 minutes and make it part of the
default test suite executed in CI.
- decrease number of records to sign from 2000 to 500
- decrease the signing interval by a factor of 6
- shorten the final part of the test after last signing (since nothing
new happens there)
Finally, clarify misleading comments about (in)sufficient time for zone
re-signing. The time used in the test is in fact sufficient for the
re-signing to happen. If it wasn't, the previous ZSK would end up being
deleted while its signatures would still be present, which is a
situation where duplicate signatures can still happen.
Ensure the port numbers are dynamically filled in with copy_setports.
Clarify test fail condition.
Make the stress test part of the default test suite since it doesn't
seem to run too long or interfere with other tests any more (the
original note claiming so is more than 20 years old).
Related !6883
Properly template the port number in config files with copy_setports.
The test takes two minutes on my machine which doesn't seem like a
proper justification to exclude it from the test suite, especially
considering we run these tests in parallel nowadays. The resource usage
doesn't seems significantly increased so it shouldn't interfere with
other system tests.
There also exists a precedent for longer running system tests that are
already part of the default system test suite (e.g. serve-stale takes
almost three minutes on the same machine).
When a target server is unreachable, the varying network conditions may
cause different ICMP message (or no message). The host unreachable
message was discovered when attempting to run the test locally while
connected to a VPN network which handles all traffic.
Extend the dig output check with "host unreachable" message to avoid a
false negative test result in certain network environments.
Add a test ensuring that the amount of work fctx_getaddresses() performs
for any encountered delegation is limited: delegate example.net to a set
of 1,000 name servers in the redirect.com zone, the names of which all
resolve to IP addresses that nothing listens on, and query for a name in
the example.net domain, checking the number of times the findname()
function gets executed in the process; fail if that count is excessively
large.
Since the size of the referral response sent by ans3 is about 20 kB, it
cannot be sent back over UDP (EMSGSIZE) on some operating systems in
their default configuration (e.g. FreeBSD - see the
net.inet.udp.maxdgram sysctl). To enable reliable reproduction of
CVE-2022-2795 (retry patterns vary across BIND 9 versions) and avoid
false positives at the same time (thread scheduling - and therefore the
number of fetch context restarts - vary across operating systems and
across test runs), extend bin/tests/system/resolver/ans3/ans.pl so that
it also listens on TCP and make "ns1" in the "resolver" system test
always use TCP when communicating with "ans3".
Also add a test (foo.bar.sub.tld1/TXT) that ensures the new limitations
imposed on the resolution process by the mitigation for CVE-2022-2795 do
not prevent valid, glueless delegation chains from working properly.
It was possible that accept callback can be called after listener
shutdown. In such a case the callback pointer equals NULL, leading to
segmentation fault. This commit fixes that.
add a test to compare the Content-Length of successive compressed
messages on a single HTTP connection that should contain the same
data; fail if the size grows by more than 100 bytes from one query
to the next.
This log happens when BIND checks the parental-agents if the DS has
been published. But if you don't have parental-agents set up, the list
of keys to check will be empty and the result will be ISC_R_NOTFOUND.
This is not an error, so change the log level to debug in this case.
Since we are using designated initializers, we were missing initializers
for ISC_LIST and ISC_LINK, add them, so you can do
*foo = (foo_t){ .list = ISC_LIST_INITIALIZER };
Instead of:
*foo = (foo_t){ 0 };
ISC_LIST_INIT(foo->list);
This commit introduces a primitive isc__nmsocket_stop() which performs
shutting down on a multilayered socket ensuring the proper order of
the operations.
The shared data within the socket object can be destroyed after the
call completed, as it is guaranteed to not be used from within the
context of other worker threads.
I.e. print the name of the function in BIND that called the system
function that returned an error. Since it was useful for pthreads
code, it seems worthwhile doing so everywhere.
Mostly generated automatically with the following semantic patch,
except where coccinelle was confused by #ifdef in lib/isc/net.c
@@ expression list args; @@
- UNEXPECTED_ERROR(__FILE__, __LINE__, args)
+ UNEXPECTED_ERROR(args)
@@ expression list args; @@
- FATAL_ERROR(__FILE__, __LINE__, args)
+ FATAL_ERROR(args)
The isccfg_duration_fromtext() function is truncating large numbers
to 32 bits instead of capping or rejecting them, i.e. 64424509445,
which is 0xf00000005, gets parsed as 32-bit value 5 (0x00000005).
Fail parsing a duration if any of its components is bigger than
32 bits. Using those kind of big numbers has no practical use case
for a duration.
The isccfg_duration_toseconds() function can overflow the 32 bit
seconds variable when calculating the duration from its component
parts.
To avoid that, use 64-bit calculation and return UINT32_MAX if the
calculated value is bigger than UINT32_MAX. Again, a number this big
has no practical use case anyway.
The buffer for the generated duration string is limited to 64 bytes,
which, in theory, is smaller than the longest possible generated
duration string.
Use 80 bytes instead, calculated by the '7 x (10 + 1) + 3' formula,
where '7' is the count of the duration's parts (year, month, etc.), '10'
is their maximum length when printed as a decimal number, '1' is their
indicator character (Y, M, etc.), and 3 is two more indicators (P and T)
and the terminating NUL character.
The cfg_print_duration() checks added previously in the 'duration_test'
unit test uncovered a bug in cfg_print_duration().
When calculating the current 'str' pointer of the generated text in the
buffer 'buf', it erroneously adds 1 byte to compensate for that part's
indicator character. For example, to add 12 minutes, it needs to add
2 + 1 = 3 characters, where 2 is the length of "12", and 1 is the length
of "M" (for minute). The mistake was that the length of the indicator
is already included in 'durationlen[i]', so there is no need to
calculate it again.
In the result of this mistake the current pointer can advance further
than needed and end up after the zero-byte instead of right on it, which
essentially cuts off any further generated text. For example, for a
5 minutes and 30 seconds duration, instead of having this:
'P', 'T', '5', 'M', '3', '0', 'S', '\0'
The function generates this:
'P', 'T', '5', 'M', '\0', '3', '0', 'S', '\0'
Fix the bug by adding to 'str' just 'durationlen[i]' instead of
'durationlen[i] + 1'.
Currently the 'duration_test' unit test checks only the
cfg_obj_asduration() function.
Extend the test so it checks also the reverse operation using the
cfg_print_duration() function, which is used in named-checkconf.
The cfg_print_duration() function prints a ISO 8601 duration value
converted from an array of integers, where the parts of the date and
time are stored.
durationlen[6], which holds the "seconds" part of the duration, has
a special case in cfg_print_duration() to ensure that when there are
no values in the duration, the result still can be printed as "PT0S",
instead of just "P", so it can be a valid ISO 8601 duration value.
There is a logical error in one of the two special case code paths,
when it checks that no value from the "date" part is defined, and no
"hour" or "minute" from the "time" part are defined.
Because of the error, durationlen[6] can be used uninitialized, in
which case the second parameter passed to snprintf() (which is the
maximum allowed length) can contain a garbage value.
This can not be exploited because the buffer is still big enough to
hold the maximum possible amount of characters generated by the "%u%c"
format string.
Fix the logical bug, and initialize the 'durationlen' array to zeros
to be a little safer from other similar errors.
[performance] A new algorithm for DNS name compression based on a
hash set of message offsets. Name compression is now
more complete as well as being generally faster, and
the implementation is less complicated and requires
much less memory.
The `render` benchmark loads some binary DNS message dumps and
repeatedly passes them to `dns_message_render`.
The `compress` benchmark loads a list of domain names and packs them
into 4KiB chunks using `dns_name_towire`.
Check that names are correctly added and deleted in the compression
context. Use many names with differing numerical prefixes to make it
relatively easy to identify and debug problems.
All we need for compression is a very small hash set of compression
offsets, because most of the information we need (the previously added
names) can be found in the message using the compression offsets.
This change combines dns_compress_find() and dns_compress_add() into
one function dns_compress_name() that both finds any existing suffix,
and adds any new prefix to the table. The old split led to performance
problems caused by duplicate names in the compression context.
Compression contexts are now either small or large, which the caller
chooses depending on the expected size of the message. There is no
dynamic resizing.
There is a behaviour change: compression now acts on all the labels in
each name, instead of just the last few.
A small benchmark suggests this is about 2x faster.
During loop manager refactoring isc_nmsocket_set_tlsctx() was not
properly adapted. The function is expected to broadcast the new TLS
context for every worker, but this behaviour was accidentally broken.
Replace all uses of RUNTIME_CHECK() in lib/isc/include/isc/once.h with
PTHEADS_RUNTIME_CHECK(), in order to improve error reporting for any
once-related run-time failures (by augmenting error messages with
file/line/caller information and the error string corresponding to
errno).
There are multiple reasons to remove this test as obsolete:
- The test may not possibly work for over 2.5 years, since
98b3b93791 removed the rndc.py python
tool on which this test relies.
- It isn't part of the test suite either in CI or locally unless it is
explicitly enabled. As a result, there are many issues which prevent
the test from being executed caused by various refactoring efforts
accumulated over time.
- Even if the test could be executed, it has no clear failure condition.
If the python script(s) fail, the test still passes.
Now that the artificial limit on the recv buffer has been removed, the
current system test always fails because it tests if the truncation has
happened.
Add test that sending more than 10 headers makes the connection to
closed; and add test that sending huge HTTP request makes the connection
to be closed.
Rewrite the isc_httpd to be more robust.
1. Replace the hand-crafted HTTP request parser with picohttpparser for
parsing the whole HTTP/1.0 and HTTP/1.1 requests. Limit the number
of allowed headers to 10 (arbitrary number).
2. Replace the hand-crafted URL parser with isc_url_parse for parsing
the URL from the HTTP request.
3. Increase the receive buffer to match the isc_netmgr buffers, so we
can at least receive two full isc_nm_read()s. This makes the
truncation processing much simpler.
4. Process the received buffer from single isc_nm_read() in a single
loop and schedule the sends to be independent of each other.
The first two changes makes the code simpler and rely on already
existing libraries that we already had (isc_url based on nodejs) or are
used elsewhere (picohttpparser).
The second two changes remove the artificial "truncation" limit on
parsing multiple request. Now only a request that has too many
headers (currently 10) or is too big (so, the receive buffer fills up
without reaching end of the request) will end the connection.
We can be benevolent here with the limites, because the statschannel
channel is by definition private and access must be allowed only to
administrators of the server. There are no timers, no rate-limiting, no
upper limit on the number of requests that can be served, etc.
PicoHTTPParser is a tiny, primitive, fast HTTP request/response parser.
Unlike most parsers, it is stateless and does not allocate memory by
itself. All it does is accept pointer to buffer and the output
structure, and setups the pointers in the latter to point at the
necessary portions of the buffer.
Works nicely together with:
git config --add blame.ignoreRevsFile .git-blame-ignore-revs
The list was generated by hand-picking from git log --oneline augmented
with:
--author=tbox
--grep=clang-format
--grep=copyright
--grep=reformat
--grep=whitespace
plus
git log --format='commit %H %s' --stat | grep -E 'commit|changed' | grep -B1 '[0-9][0-9][0-9] files changed'
plus some sanity checking.
Comments were added with:
for COMMIT in $(cat .git-blame-ignore-revs)
do git log -1 --format="# %s" "$COMMIT"
echo $COMMIT
done
sizeof(dns_name_t) did not change but the boolean attributes are now
separated as one-bit structure members. This allows debuggers to
pretty-print dns_name_t attributes without any special hacks, plus we
got rid of manual bit manipulation code.
Originally RBT node stored three lowest bits from dns_name_t attributes.
This had a curious side-effect noticed by Tony Finch:
If you create an rbt node from a DYNAMIC name then the flag will be
propagated through dns_rbt_namefromnode() ... if you subsequently call
dns_name_free() it will try to isc_mem_put() a piece of an rbt node ...
but dns_name_free() REQUIRE()s that the name is dynamic so in the usual
case where rbt nodes are created from non-dynamic names, this kind of
code will fail an assertion.
This is a bug it dates back to june 1999 when NAMEATTR_DYNAMIC was
invented.
Apparently it does not happen often :-)
I'm planning to get rid of DNS_NAMEATTR_ definitions and bit operations,
so removal of this "three-bit-subset" assignment is a first step.
We can keep only the ABSOLUTE flag in RBT node and nothing else because
names attached to rbt nodes are always readonly: The internal node_name()
function always sets the NAMEATTR_READONLY when making a dns_name that
refers to the node's name, so the READONLY flag will be set in the name
returned by dns_rbt_namefromnode().
Co-authored-by: Tony Finch <fanf@isc.org>
doth system test fixes - decrese the size of HTTP listener quota, increase transfer-in/out limits
Closes#3596
See merge request isc-projects/bind9!6898
Sometimes doth test could intermittently fail shortly after start due
to inability to complete a zone transfer in time. As it turned out, it
could happen due to transfers-in/out limits. Initially the defaults
were fine, but over time, especially when adding Strict/Mutual TLS, we
added more than 10 zones so it became possible to hit the limits.
This commit takes care of that by bumping the limits.
This commit reduces the size of HTTP listener quota from 300 (default)
to 100 so that it would make hitting any global limits in case of
running multiple tests in parallel in multiple containers unlikely.
This way the need in opening many file descriptors of different
kinds (e.g. client side connections and pipes) gets significantly
reduced while the required code paths are still verified.
In ac4cc8443d, the ISC_R_CONNREFUSED was
removed in connect_read_cb, but it can actually happen in the udp_test:
[ RUN ] udp_recv_send
connect_read_cb(0x7f2c2801a270, connection refused, (nil))
The ISC_R_SHUTTINGDOWN should be handled the same as ISC_R_CANCELED in
the udp__send_cb(), as we might be sending the data while the
loopmgr/netmgr shutdown has been initiated.
In rare circumstances, the UDP port for the listening socket and the UDP
port for the connecting socket might be the same. Because we use the
"reuse" port socket option, this isn't caught when binding the socket,
and thus the connected client socket could send a datagram to itself,
completely bypassing the server. This doesn't happen under normal
operation mode because `named` is listening on a privileged port (53),
and even if not, it doesn't usually talk to itself as the tests do.
Pick an arbitrary port for listening (9153-9156) that is outside the
ephemeral port range for the network manager related unit tests (except
the `doh_test).
The isc_nm_udpconnect() erroneously set the reuse port with
load-balancing on the outgoing connected UDP sockets. This socket
option makes only sense for the listening sockets. Don't set the
load-balancing reuse port option on the outgoing UDP sockets.
Since we are testing UDP on the localhost and the same interface, the
UDP datagrams can't get lost. Change the connect read callback, so it
starts reading again on the timeout instead of just getting stuck, and
fail when any other result codes than ISC_R_SUCCESS and ISC_R_TIMEDOUT
are received because we don't expect them to happen in these simple
tests.
This commit removes broken remnants of unit test slowdown logic, which
caused unit test hangs on platforms susceptible to "too many open
files" error, notably OpenBSD.
This commit fixes TLS DNS verification error message reporting which
we probably broke during one of the recent networking code
refactorings.
This prevent e.g. dig from producing useful error messages related to
TLS certificates verification.
Ensure that TLS error is empty before calling SSL_get_error() or doing
SSL I/O so that the result will not get affected by prior error
statuses.
In particular, the improper error handling led to intermittent unit
test failure and, thus, could be responsible for some of the system
test failures and other intermittent TLS-related issues.
See here for more details:
https://www.openssl.org/docs/man3.0/man3/SSL_get_error.html
In particular, it mentions the following:
> The current thread's error queue must be empty before the TLS/SSL
> I/O operation is attempted, or SSL_get_error() will not work
> reliably.
As we use the result of SSL_get_error() to decide on I/O operations,
we need to ensure that it works reliably by cleaning the error queue.
TLS DNS: empty error queue before attempting I/O
There was inconsistency in which error codes would get accepted and
ignored in the network manager unit test callbacks. Add following
results, so we just detach the handle instead of causing assertion
failure:
* ISC_R_SHUTTINGDOWN - when the network manager is shutting down
* ISC_R_CANCELED - the socket has been shut down
* ISC_R_EOF - the (TCP) communication has ended on the other side
* ISC_R_CONNECTIONRESET - the TCP connection was reset
This should fix some of the spurious unit test failures.
The check is left from when tcp_connect_direct() called isc__nm_socket()
and it was uncertain whether it had succeeded, but now isc__nm_socket()
is called before tcp_connect_direct(), so sock->fd cannot be -1.
*** CID 357292: (REVERSE_NEGATIVE)
/lib/isc/netmgr/tcp.c: 309 in isc_nm_tcpconnect()
303
304 atomic_store(&sock->active, true);
305
306 result = tcp_connect_direct(sock, req);
307 if (result != ISC_R_SUCCESS) {
308 atomic_store(&sock->active, false);
>>> CID 357292: (REVERSE_NEGATIVE)
>>> You might be using variable "sock->fd" before verifying that it is >= 0.
309 if (sock->fd != (uv_os_sock_t)(-1)) {
310 isc__nm_tcp_close(sock);
311 }
312 isc__nm_connectcb(sock, req, result, true);
313 }
314
If sending took too long the isc_nm_read() could timeout twice, leading
to extra 'cread' counter in the udp_cancel_read test. Increase the
cread counter only on ISC_R_EOF (canceled read) and deal with the
multiple ISC_R_TIMEOUTS gracefully.
The bin/tests/system/start.pl script waits until a "running" message is
logged by a given name server instance before attempting to send a
version.bind/CH/TXT query to it. The idea behind this was to make the
script wait until named loads all the zones it is configured to serve
before telling the system test framework that a given server is ready to
use; this prevents the need to add boilerplate code that waits for a
specific zone to be loaded to each test expecting that.
The problem is that when it looks for "running" messages, the
bin/tests/system/start.pl script assumes that the existence of any such
message in the named.run file indicates that a given named instance has
already finished loading all zones. Meanwhile, some system tests
restart all the named instances they use throughout their lifetime (some
even do that a few times), for example to run Python-based tests. The
bin/tests/system/start.pl script handles such a scenario incorrectly: as
soon as it finds any "running" message in the named.run file it inspects
and it gets a response to a version.bind/CH/TXT query, it tells the
system test framework that a given server is ready to use, which might
not be true - it is possible that only the "version.bind" zone is loaded
at that point and the "running" message found was logged by a
previously-shutdown named instance. This triggers intermittent failures
for Python-based tests.
Fix by improving the logic that the bin/tests/system/start.pl script
uses to detect server startup: check how many "running" lines are
present in a given named.run file before attempting to start a named
instance and only proceed with version.bind/CH/TXT queries when the
number of "running" lines found in that named.run file increases after
the server is started.
In the "rrsetorder" system test, the ns2 named instance is restarted
without passing the --restart option to bin/tests/system/start.pl. This
causes the log file for that named instance to be needlessly truncated.
Prevent this from happening by restarting the affected named instance
in the same way as all the other named instances used in system tests.
Getting the recorded value of 'edns-udp-size' from the resolver requires
strong attach to the dns_view because we are accessing `view->resolver`.
This is not the case in places (f.e. dns_zone unit) where `.udpsize` is
accessed. By moving the .udpsize field from `struct dns_resolver` to
`struct dns_view`, we can access the value directly even with weakly
attached dns_view without the need to lock the view because `.udpsize`
can be accessed after the dns_view object has been shut down.
The dns_view implements weak and strong reference counting. When strong
reference counting reaches zero, the adb, ntatable and resolver objects
are shut down and detached.
In dns_zone and dns_nta the dns_view was weakly attached, but the
view->resolver reference was accessed directly leading to dereferencing
the NULL pointer.
Add dns_view_getresolver() method which attaches to view->resolver
object under the lock (if it still exists) ensuring the dns_resolver
will be kept referenced until not needed.
The value of `sign_bit` is platform-dependent but constant at compile
time. Use a cast to convert the boolean `sign_bit` to 0 or 1 instead of
ternary `?:` because one branch of the conditional is dead code. (We
could leave out the cast to `size_t` but our style prefers to handle
booleans more explicitly, hence the `?:` that caused the issue.)
*** CID 358310: Possible Control flow issues (DEADCODE)
/lib/isc/resource.c: 118 in isc_resource_setlimit()
112 * rlim_t, and whether rlim_t has a sign bit.
113 */
114 isc_resourcevalue_t rlim_max = UINT64_MAX;
115 size_t wider = sizeof(rlim_max) - sizeof(rlim_t);
116 bool sign_bit = (double)(rlim_t)-1 < 0;
117
>>> CID 358310: Possible Control flow issues (DEADCODE)
>>> Execution cannot reach the expression "1" inside this statement: "rlim_max >>= 8UL * wider + ...".
118 rlim_max >>= CHAR_BIT * wider + (sign_bit ? 1 : 0);
119 rlim_value = ISC_MIN(value, rlim_max);
120 }
121
122 rl.rlim_cur = rl.rlim_max = rlim_value;
123 unixresult = setrlimit(unixresource, &rl);
While refactoring the isc_mem_getx(...) usage, couple places were
identified where the memory was resized manually. Use the
isc_mem_reget(...) that was introduced in [GL !5440] to resize the
arrays via function rather than a custom code.
In several places, the structures were cleaned with memset(...)) and
thus the semantic patch converted the isc_mem_get(...) to
isc_mem_getx(..., ISC_MEM_ZERO). Use the designated initializer to
initialized the structures instead of zeroing the memory with
ISC_MEM_ZERO flag as this better matches the intended purpose.
Add new semantic patch to replace the straightfoward uses of:
ptr = isc_mem_{get,allocate}(..., size);
memset(ptr, 0, size);
with the new API call:
ptr = isc_mem_{get,allocate}x(..., size, ISC_MEM_ZERO);
Previously, the isc_mem_get_aligned() and friends took alignment size as
one of the arguments. Replace the specific function with more generic
extended variant that now accepts ISC_MEM_ALIGN(alignment) for aligned
allocations and ISC_MEM_ZERO for allocations that zeroes
the (re-)allocated memory before returning the pointer to the caller.
Coverity is optimistic that we might do thousands of hashes in less
than a microsecond.
/tests/bench/siphash.c: 54 in main()
48 count++;
49 }
50
51 isc_time_now_hires(&finish);
52
53 us = isc_time_microdiff(&finish, &start);
>>> CID 358309: Integer handling issues (DIVIDE_BY_ZERO)
>>> In expression "count * 1000UL / us", division by expression "us" which may be zero has undefined behavior.
54 printf("%f us wide-lower len %3zu, %7llu kh/s (%llx)\n",
55 (double)us / 1000000.0, len,
56 (unsigned long long)(count * 1000 / us),
57 (unsigned long long)sum);
58 }
59
This is hopefully end of duplication. This batch did not cause clashes
in Sphinx but it was pointless nonetheless as we have auto-generated
anchors for all statements.
Some statement names like "allow-query" had manually defined link anchor
_allow-query and also implicit anchor created by
.. namedconf:statement:: syntax. This causes warnings if a ambiguous
reference is made using :any:`allow-query` syntax.
Remove (hopefully all) manually defined anchors which pointed to
identical place as the implicit anchor. This allows :any: to work.
In rare cases where manual anchor points to descriptive text separated
from statement definition the reference was disamguated by replacing
:any:`notify` with :ref:`notify` (for manual anchor)
vs. :namedconf:ref:`notify` (for statement definition).
Please note that `options` statement is a trap: It is ambiguous even
without manual anchor because rndc.conf has its own `options`. Use
:namedconf:ref:`options` vs. :rndcconf:ref:`options` to select
appropriate target.
Fixup for 2c3b2dabe9.
We forgot to update TSAN paths when moving all the unit tests to
/tests/. Let's remove paths from find to make it less dependent on
exact location, and store all untracked files as we do in the normal
unit test template.
Related: !6243
The previous commit failed some tests because we expect that if a
fetch fails and we have stale candidates in cache, the
stale-refresh-time window is started. This means that if we hit a stale
entry in cache and answering stale data is allowed, we don't bother
resolving it again for as long we are within the stale-refresh-time
window.
This is useful for two reasons:
- If we failed to fetch the RRset that we are looking for, we are not
hammering the authoritative servers.
- Successor clients don't need to wait for stale-answer-client-timeout
to get their DNS response, only the first one to query will take
the latency penalty.
The latter is not useful when stale-answer-client-timeout is 0 though.
So this exception code only to make sure we don't try to refresh the
RRset again if it failed to do so recently.
Refreshing a stale RRset is similar to prefetching an RRset, so
reuse the existing code. When refreshing an RRset we need to clear
all db options related to serve-stale so that stale RRsets in cache
are ignored during the refresh.
We no longer need to set the "nodetach" flag, because the refresh
fetch is now a "fetch and forget". So we can detach from the client
in the query_send().
This code will break some serve-stale test cases, this will be fixed
in the successor commit.
TODO: add explanation why the serve-stale test cases fail.
Formerly, the isc_hash32() would have to change the key in a local copy
to make it case insensitive. Change the isc_siphash24() and
isc_halfsiphash24() functions to lowercase the input directly when
reading it from the memory and converting the uint8_t * array to
64-bit (respectively 32-bit numbers).
dohpath is specfied in draft-ietf-add-svcb-dns and has a value
of 7. It must be a relative path (start with a /), be encoded
as UTF8 and contain the variable dns ({?dns}).
On systems with signed rlim_t the old code calculated its maximum
value by shifting 1 into the sign bit, which is undefined behaviour.
Avoid the bug by using an unsigned shift.
When the TCP test is run on the busy server, the server might take a
while to wind the server down because it might still be processing all
that 300k invalid XFR requests.
Increate the rncd wait time to 120 seconds, the SIGTERM time to 300
seconds, and reduce the time to wait for ans servers from 1200 second
to just 120 seconds.
The dns__nta_shutdown() could be run from different threads and it was
accessing nta->timer unlocked. Don't check and stop the timer from
dns__nta_shutdown() directly, but leave it for the async callback.
Because the dns_zonemgr_create() was run before the loopmgr was started,
the isc_ratelimiter API was more complicated that it had to be. Move
the dns_zonemgr_create() to run_server() task which is run on the main
loop, and simplify the isc_ratelimiter API implementation.
The isc_timer is now created in the isc_ratelimiter_create() and
starting the timer is now separate async task as is destroying the timer
in case it's not launched from the loop it was created on. The
ratelimiter tick now doesn't have to create and destroy timer logic and
just stops the timer when there's no more work to do.
This should also solve all the races that were causing the
isc_ratelimiter to be left dangling because the timer was stopped before
the last reference would be detached.
Access to the source tree is not available with oss_fuzz. Have
fuzz/dns_message_checksig build and populate a key directory for
the fuzzer to use. This contains a key pair and a zone file which
has the public key from the key pair. Clean it up on shutdown.
Unlike standard free(), isc_mem_free() is not a no-op when passed a
NULL pointer. For size accounting purposes it calls sallocx(), which
crashes when passed a NULL pointer. To get more helpful diagnostics,
REQUIRE() that the pointer is not NULL so that when the programmer
makes a mistake they get a backtrace that shows what went wrong.
Extra care must be taken when executing the callbacks to prevent the
deadlocks on the caller's side. Add a paragraph that addresses when we
can and when we cannot call the callbacks directly.
The isc__nm_udp_send() callback would be called synchronously when
shutting down or when the socket has been closed. This could lead to
double locking in the calling code and thus those callbacks needs to be
called asynchronously.
Add several test cases in the 'upforwd' system test to make sure
that different scenarios of Dynamic DNS update forwarding are
tested, in particular when both the original and forwarded requests
are over Do53, or DoT, or they use different transports.
Now that the 'dns_request' supports using TLS transport, implement
dynamic update forwarding using DoT when the primary server is
configured to use a TLS transport.
Previously, when using such configuration, the dynamic update forwarding
feature was broken.
There's a known memory leak in the engine_pkcs11 at the time of writing
this and it interferes with the named ability to check for memory leaks
in the OpenSSL memory context by default.
Add an autoconf option to explicitly enable the memory leak detection,
and use it in the CI except for pkcs11 enabled builds. When this gets
fixed in the engine_pkc11, the option can be enabled by default.
As we can't check the deallocations done in the library memory contexts
by default because it would always fail on non-clean exit (that happens
on error or by calling exit() early), we just want to enable the checks
to be done on normal exit.
The libxml2 library provides a way to replace the default allocator with
user supplied allocator (malloc, realloc, strdup and free).
Create a memory context specifically for libxml2 to allow tracking the
memory usage that has originated from within libxml2. This will provide
a separate memory context for libxml2 to track the allocations and when
shutting down the application it will check that all libxml2 allocations
were returned to the allocator.
Additionally, move the xmlInitParser() and xmlCleanupParser() calls from
bin/named/main.c to library constructor/destructor in libisc library.
The OpenSSL library provides a way to replace the default allocator with
user supplied allocator (malloc, realloc, and free).
Create a memory context specifically for OpenSSL to allow tracking the
memory usage that has originated from within OpenSSL. This will provide
a separate memory context for OpenSSL to track the allocations and when
shutting down the application it will check that all OpenSSL allocations
were returned to the allocator.
The libuv library provides a way to replace the default allocator with
user supplied allocator (malloc, realloc, calloc and free).
Create a memory context specifically for libuv to allow tracking the
memory usage that has originated from within libuv. This requires
libuv >= 1.38.0 which provides uv_library_shutdown() function that
assures no more allocations will be made.
Instead of using generic HAVE_BUILTIN_OVERFLOW, we need to check whether
the overflow functions actually work as there was a bug in GCC that it
would not detect mul overflow when compiled with `-m32` option without
optimizations and the bug was fixed only for GCC 6.5+ and 7.3+/8+.
For further details see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82274
Previously, the isc_mem_debugging would be single global variable that
would affect the behavior of the memory context whenever it would be
changed which could be after some allocation were already done.
Change the memory debugging options to be local to the memory context
and immutable, so all allocations within the same memory context are
treated the same.
By bumping the minimum libuv version to 1.34.0, it allows us to remove
all libuv shims we ever had and makes the code much cleaner. The
up-to-date libuv is available in all distributions supported by BIND
9.19+ either natively or as a backport.
The HMACs and GSSAPI are just using unallocated values.
Moving them around shouldn't cause issues.
Only the dnssec system test knew the internal number in use for hmacmd5.
Switch the primary to require 'next_key' for zone transfers then
update the catalog zone to say to use 'next_key'. Next update the
zones contents then check that those changes are seen on the
secondary.
When looking for changes in a catalog zone member zone we need to
also check if the TSIG key name associated with a primary server
has be added, removed or changed.
Previously stack with buffer for test dns message went out of scope
before the message was processed. For fuzz testing its better to avoid
allocation, so let's avoid allocations completely and use simplest
possible static buffer.
Fixes: #3565
previously, when ISC_BUFFER_USEINLINE was defined, macros were
used to implement isc_buffer primitives (isc_buffer_init(),
isc_buffer_region(), etc). these macros were missing the DbC
assertions for those primitives, which made it possible for
coding errors to go undetected.
adding the assertions to the macros caused compiler warnings on
some platforms. therefore, this commit converts the ISC__BUFFER
macros to static inline functions instead, with assertions included,
and eliminates the non-inline implementation from buffer.c.
the --enable-buffer-useinline configure option has been removed.
RHEL8 Sphinx does not support all features used in ARM building. But
with few emitted warnings it can build the documentation fine. Simplify
warnings acceptance by allowing make doc SPHINX_W=''.
Make documentation building successful even on RHEL9 sphinx 3.4.3. It
does not like case-insensitive matching of terms, so provide lowercase
text description with Uppercase word reference.
dns_message_checksig is called in a number of scenarios
* on requests and responses
* on multiple opcodes
* with and without signatures
* with TSIG signatures
* with SIG(0) signatures
* with and without configured TSIG keys
* with and without KEY records being present
* signing performed now, in the future and in the past
we use the first two octets of the seed to configure the calling
environment with the remainder of the seed being the rdata of the
TSIG/SIG(0) record.
When fuzzing it is useful for all signing operations to happen
at a specific time for reproducability. Add two variables to
the message structure (fuzzing and fuzztime) to specify if a
fixed time should be used and the value of that time.
The RAND_bytes() implementation differs between the OpenSSL versions and
uses the system entropy only for seeding its internal CSPRNG. The
uv_random() on the other hand uses the system provided CSPRNG.
Switch from RAND_bytes() to uv_random() to use system provided CSPRNG.
dns_rdata_tostruct doesn't need a mctx passed to it for SIG (the signer
is already expanded at this point). About the only time when mctx is
needed is when the structure is to be used after the rdata has been
destroyed.
Add a simple test PKI based on the existing one in the doth test.
Check ephemeral, forward-secrecy, and forward-secrecy-mutual-tls
TLS configurations with different scenarios.
The comments in CA.cfg file serve as a good tutorial for setting up
a simple PKI for a system test. There is a typo in one of the presented
commands, which results in openssl not exiting with an error message
instead of generating a certificate.
Fix the typo.
OpenSSL just cannot work with mixing ENGINE_* api mixed with OSSL_PARAM
builders. But it can be built in legacy mode, where deprecated but still
working API would be used.
It can work under OpenSSL 3.0, but only if using legacy code paths
matching OpenSSL 1.1 calls and functions.
Remove fromlabel processing by OpenSSL 3.0 only functions. They can
return later with a proper provider support for pkcs11.
OpenSSL has deprecated many things in version 3.0. If pkcs11 engine
should work then no builder from OpenSSL 3.0 API can be used.
Allow switching to OpenSSL 1.1 like calls even on OpenSSL 3.0 when
OPENSSL_API_COMPAT=10100 is defined. It would still compile and allow
working keys loading from the engine passed on command line.
After the loopmgr work has been merged, we can now cleanup the TCP and
TLS protocols a little bit, because there are stronger guarantees that
the sockets will be kept on the respective loops/threads. We only need
asynchronous call for listening sockets (start, stop) and reading from
the TCP (because the isc_nm_read() might be called from read callback
again.
This commit does the following changes (they are intertwined together):
1. Cleanup most of the asynchronous events in the TCP code, and add
comments for the events that needs to be kept asynchronous.
2. Remove isc_nm_resumeread() from the netmgr API, and replace
isc_nm_resumeread() calls with existing isc_nm_read() calls.
3. Remove isc_nm_pauseread() from the netmgr API, and replace
isc_nm_pauseread() calls with a new isc_nm_read_stop() call.
4. Disable the isc_nm_cancelread() for the streaming protocols, only the
datagram-like protocols can use isc_nm_cancelread().
5. Add isc_nmhandle_close() that can be used to shutdown the socket
earlier than after the last detach. Formerly, the socket would be
closed only after all reading and sending would be finished and the
last reference would be detached. The new isc_nmhandle_close() can
be used to close the underlying socket earlier, so all the other
asynchronous calls would call their respective callbacks immediately.
Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
When looking for required glue, dns_message_rendersection() only
processes the first rdataset associated with the first name added to the
ADDITIONAL section. If the DNS_RDATASETATTR_REQUIRED attribute is set
for an rdataset which is located somewhere else (i.e. the name it is
associated with is preceded by another name in the ADDITIONAL section),
it will not be honored, i.e. the TC bit will not be set even if the
rdataset does not fit into the response.
Check the attributes of each processed rdataset while appending names to
a referral response based on a glue cache entry. If a given rdataset is
marked with DNS_RDATASETATTR_REQUIRED, make sure the name it is
associated with is added to the response at the beginning of the
ADDITIONAL section, not its end.
Note that using ISC_LIST_PREPEND() instead of ISC_LIST_APPEND() is not
necessary when associating the rdataset with its owner name because the
dns_name_t structures are initialized just before the glue rdatasets are
associated with them and therefore they are empty at that point, which
means no other (non-required) rdataset can precede the glue rdatasets
within the dns_name_t structure owning them.
If an NS RRset at the parent side of a delegation point only contains
in-bailiwick NS records, at least one glue record should be included in
every referral response sent for such a delegation point or else clients
will need to send follow-up queries in order to determine name server
addresses. In certain edge cases (when the total size of a referral
response without glue records was just below to the UDP packet size
limit), named failed to adhere to that rule by sending non-truncated,
glueless referral responses.
Fix the problem by marking all in-bailiwick NS records processed by
glue_nsdname_cb() (the dns_rdataset_additionaldata() callback used by
RBTDB code while iterating over an NS RRset when dns_rdataset_addglue()
is called) with the DNS_RDATASETATTR_REQUIRED flag. Note that for
simplicity, glue RRsets for all in-bailiwick NS records are marked this
way, even though dns_message_rendersection() only checks the attributes
for the first rdataset associated with the first name added to the
ADDITIONAL section.
If an NS RRset at the parent side of a delegation point only contains
in-bailiwick NS records, at least one glue record should be included in
every referral response sent for such a delegation point or else clients
will need to send follow-up queries in order to determine name server
addresses. In certain edge cases (when the total size of a referral
response without glue records was just below to the UDP packet size
limit), named failed to adhere to that rule by sending non-truncated,
glueless referral responses.
Add tests attempting to trigger that bug in several different scenarios,
covering all possible combinations of the following factors:
- type of zone (signed, unsigned),
- glue record type (A, AAAA, both).
Bring the "glue" system test up to speed with other system tests: add
check numbering, ensure test artifacts are preserved upon failure,
improve error reporting, make the test fail upon unexpected errors,
address ShellCheck warnings.
When jemalloc is the system allocator (on FreeBSD and NetBSD), trying
to build --without-jemalloc caused an obscure compiler error. Instead,
complain at configure time that --without-jemalloc cannot work. (It
needs to remain an error because it is vexing when configure quietly
ignores an explicit direction.)
Instead of expecting that telemetry check has already finished,
wait for it for maximum of three seconds, because named is run with
-tat=3, so the telemetry check must happen with 3 second window.
Co-authored-by: Evan Hunt <each@isc.org>
Each isc_timer needs to be created, started and destroyed on the current
loop. The isc_timer_stop() can be run on any loop, but when run from
different loop than the one associated with the timer, the request to
stop the timer will be recorded in atomic variable and the underlying
uv_timer_t will be stopped on next uv_timer_t callback call. This
allows any thread to stop the timer.
Instead of always creating the trust anchor timer (dns_nta_t) on the
main loop, create the timer on the current loop and associate each
dns_nta_t object to the loop it was created on. This simplifies the
timer handling as everything is run on the associated loop.
During the change, the dns_nta_t structure was renamed to dns__nta_t
and changed to be fully internal to the nta.c compilation unit, and the
dns_ntatable_t structure was made opaque. This required no change to
code using the API as dns_nta_t never had any external users and the
dns_ntatable_t was properly accessed only by using function calls.
Instead of creating the response policy zone deferred update timer when
creating the response policy zone object, create it on demand on the
current loop and destroy it as soon as the timer has finished its job.
There's a side-effect - the processing of the response policy zone
update is now done on the current loop - previously, it was always on
the main loop.
Instead of creating the catalog zone deferred update timer when creating
the catalog zone object, create it on demand on the current loop and
destroy it as soon as the timer has finished its job. There's a
side-effect - the processing of the catalog zone update is now done on
the current loop - previously, it was always on the main loop.
Instead of creating dns_resolver .spillattimer when the dns_resolver_t
object is created, create it on the current loop as needed and destroy
it as soon as the timer has finished its job. This avoids the need to
manipulate the timer from a different thread.
Instead of creating the zone timers at the zone creation time (which
could be any thread), create the zone timer from the isc_loop that has
beena assigned to the zone (zone->loop);
In preparation for the on-loop timers, the isc_ratelimiter API was
converted to use the timer on main loop and start and stop the timer
asynchronously on the main loop.
As it sometimes happens that the object using isc_timer_t is destroyed
via detaching all the references with no guarantee that the last thread
will be matching thread, add a helper isc_timer_async_destroy() function
that stops the timer and runs the destroy function via isc_async_run()
on the matching thread.
- use isc_buffer functions when appropriate, rather than converting
to and from isc_region unnecessarily
- use the zlib total_out value instead of calculating it
- use c99 struct initialization
In fuzzing mode, `isc_random` uses a fixed seed for reproducibility.
The particular seed chosen happened to produce zero as its first
number, however commit bd251de0 introduced an initialization check in
`random_test` that required it to be non-zero. This change adjusts the
seed to avoid spurious test failures.
Also, remove the temporary variable that was used for initialization
because it did not match the type of the thread-local seed array.
This change prepares ground for sending DNS requests using DoT,
which, in particular, will be used for forwarding dynamic updates
to TLS-enabled primaries.
In order to make xfrin.c:get_create_tlsctx() reusable, move the function
into transport.c, and make changes into its prototype to not use the
'dns_xfrin_ctx_t' type, thus making it more universal.
This change prepares ground for adding transport support into the
dispatch manager.
Also, move the typedefs for 'dns_transport_t' and 'dns_transport_list_t'
from transport.h into types.h.
Instead of checking if we need to re-seed for every isc_random call,
seed the random number generator in the libisc global initializer
and the per-thread initializer.
When Address Sanitizer is enabled in gcc-11+, number of false positives
might appear like this:
netmgr/udp.c: In function 'isc__nm_udp_send':
netmgr/udp.c:729:13: warning: 'uv_udp_send' reading 16 bytes from a region of size 8 [-Wstringop-overread]
729 | r = uv_udp_send(&uvreq->uv_req.udp_send, &sock->uv_handle.udp,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
730 | &uvreq->uvbuf, 1, sa, udp_send_cb);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
netmgr/udp.c:729:13: note: referencing argument 3 of type 'const uv_buf_t[0]'
In file included from ./include/isc/uv.h:17,
from ./include/isc/barrier.h:31,
from netmgr/udp.c:17:
/usr/include/uv.h:711:15: note: in a call to function 'uv_udp_send'
711 | UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
| ^~~~~~~~~~~
Disable the warning globally in the autoconf, instead of just locally in
a single CI job, as it might affect people outside our GitLab CI.
The destructor for the isc__nmsocket_t was missing call to the
isc_refcount_destroy() on the reference counter, which might lead to
spurious ThreadSanitizer data race warnings if we ever change the
acquire-release memory order in the isc_refcount_decrement().
Simplify the closing code - during the loopmgr implementation, it was
discovered that the various lists used by the uv_loop_t aren't FIFO, but
LIFO. See doc/dev/libuv.md for more details.
With this knowledge, we can close the protocol handles (uv_udp_t and
uv_tcp_t) and uv_timer_t at the same time by reordering the uv_close()
calls, and thus making sure that after calling the
isc__nm_stoplistening(), the code will not issue any additional callback
calls (accept, read) on the socket that stopped listening.
This might help with the TLS and DoH shutting down sequence as described
in the [GL #3509] as we now stop the reading, stop the timer and call
the uv_close() as earliest as possible.
In the udp_shutdown_read unit test, delay the isc_loopmgr_shutdown() to
the send callback, and in the udp_cancel_read test wait for a single
timed out test, then read again, send an UDP packet and cancel the read
from the send callback.
The network manager UDP code was misinterpreting when the libuv called
the udp_recv_cb with nrecv == 0 and addr == NULL -> this doesn't really
mean that the "stream" has ended, but the libuv indicates that the
receive buffer can be freed. This could lead to assertion failure in
the code that calls isc_nm_read() from the network manager read callback
due to the extra spurious callbacks.
Properly handle the extra callback calls from the libuv in the client
read callback, and refactor the UDP isc_nm_read() implementation to be
synchronous, so no datagram is lost between the time that we stop the
reading from the UDP socket and we restart it again in the asychronous
udpread event.
Add a unit test that tests the isc_nm_read() call from the read
callback to receive two datagrams.
The tcp Pytest on OpenBSD fairly reliably fails when receive_tcp()
on a socket is attempted:
> (response, rtime) = dns.query.receive_tcp(sock, timeout())
tests-tcp.py:50:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.9/site-packages/dns/query.py:659: in receive_tcp
ldata = _net_read(sock, 2, expiration)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
sock = <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
count = 2, expiration = 1662719959.8106785
def _net_read(sock, count, expiration):
"""Read the specified number of bytes from sock. Keep trying until we
either get the desired amount, or we hit EOF.
A Timeout exception will be raised if the operation is not completed
by the expiration time.
"""
s = b''
while count > 0:
try:
> n = sock.recv(count)
E socket.timeout: timed out
This is because the socket is already closed.
Bump the socket connection timeout to 10 seconds.
An assertion failure would be triggered when the TCP connection
is canceled during sending the data back to the client.
Don't require the state to be `RECV` on non successful read to
gracefully handle canceled TCP connection during the SEND state of the
HTTPD channel.
sd_notify() may be called by a service to notify the service manager
about state changes. It can be used to send arbitrary information,
encoded in an environment-block-like string. Most importantly, it can be
used for start-up completion notification.
Add libsystemd check to autoconf script and when the library is detected
add calls to sd_notify() around the server->reload_status changes.
Co-authored-by: Petr Špaček <pspacek@isc.org>
If there was a collision of key id across algorithms it was not
possible to determine where counter applies to which algorithm for
xml statistics while for json only one of the values was emitted.
The key names are now "<algorithm-number>+<id>" (e.g. "8+54274").
the 'resolve' binary was added for testing dns_client as part of
the export library. the export libraries are no longer supported,
and tests using 'delv' provide the same coverage, so 'resolve' can
be removed now.
dns_request_create() was a front-end to dns_request_createvia() that
was only used by test binaries. dns_request_createvia() has been
renamed to dns_request_create(), and the test programs that formerly
used dns_request_create() have been updated to use the new parameters.
The test expected `xn--ah-` to be treated as a syntax error (punycode
requires letters after the last hyphen) but libidn2 on buster
converted the label to `ah` instead. To avoid this bug, change the
invalid label to `xn--0000h` which translates to an out-of-range
unicode codepoint (beyond the maximum value) which is corectly
trated as invalid in older libidn2.
The change to `testsock.pl` in commit 258a896a broke the system
tests in out-of-tree builds because `ifconfig.sh.in` is not
copied to the worktree. Use `ifconfig.sh` instead.
In rndc_recvdone(), if 'sends' was not 0, then 'recvs' was not
decremented, in which case isc_loopmgr_shutdown() was never reached,
which could cause a hang. (This has not been observed to happen, but
the code was incorrect on examination.)
[cleanup] Move the duplicated ASCII case conversion tables to
isc_ascii where they can be shared, and replace the
various hot-path tolower() loops with calls to new
isc_ascii implementations.
When converting a string to lower case, the compiler is able to
autovectorize nicely, so a nice simple implementation is also very
fast, comparable to memcpy().
Comparisons are more difficult for the compiler, so we convert eight
bytes at a time using "SIMD within a register" tricks. Experiments
indicate it's best to stick to simple loops for shorter strings and
the remainder of long strings.
There were a number of places that had copies of various ASCII
tables (case conversion, hex and decimal conversion) that are intended
to be faster than the ctype.h macros, or avoid locale pollution.
Move them into libisc, and wrap the lookup tables with macros that
avoid the ctype.h gotchas.
Reduce the number of places that know about the number of IP addresses
required by the system tests, by changing `testsock.pl` to read the
`max` from `ifconfig.sh.in`. This should make the test runner fail
early with a clear message when the interfaces have been set up by an
obsolete script.
Add comments to cross-reference `ifconfig.sh.in`, `testsock.pl`, and
`org.isc.bind.system` to make it easier to remember what needs
updating when an IP address is added.
If there are any problems with IDN processing, DiG will now quietly
handle the name as if IDN were disabled. This means that international
query names are rendered verbatim on the wire, and ACE names are
printed raw without conversion to UTF8.
If you want to check the syntax of international domain names,
use the `idn2` utility.
There was a ubsan error reporting an invalid value for interface_auto
(a boolean value cannot be 190) because it was not initialized. To
avoid this problem happening again, ensure the whole of the server
structure is initialized to zero before setting the (relatively few)
non-zero elements.
Commit 3608abc8fa inadvertently carried
over a mistake in logging pthread_cond_init() errors to the
ERRNO_CHECK() preprocessor macro: instead of passing the value returned
by a given pthread_*() function to strerror_r(), ERRNO_CHECK() passes
the errno variable to strerror_r(). This causes bogus error reports
because POSIX Threads API functions do not set the errno variable.
Fix by passing the value returned by a given pthread_*() function
instead of the errno variable to strerror_r(). Since this change makes
the name of the affected macro (ERRNO_CHECK()) confusing, rename the
latter to PTHREADS_RUNTIME_CHECK(). Also log the integer error value
returned by a given pthread_*() function verbatim to rule out any
further confusion in runtime error reporting.
Don't attempt to resolve DNS responses for intermediate results. This
may create multiple refreshes and can cause a crash.
One scenario is where for the query there is a CNAME and canonical
answer in cache that are both stale. This will trigger a refresh of
the RRsets because we encountered stale data and we prioritized it over
the lookup. It will trigger a refresh of both RRsets. When we start
recursing, it will detect a recursion loop because the recursion
parameters will eventually be the same. In 'dns_resolver_destroyfetch'
the sanity check fails, one of the callers did not get its event back
before trying to destroy the fetch.
Move the call to 'query_refresh_rrset' to 'ns_query_done', so that it
is only called once per client request.
Another scenario is where for the query there is a stale CNAME in the
cache that points to a record that is also in cache but not stale. This
will trigger a refresh of the RRset (because we encountered stale data
and we prioritized it over the lookup).
We mark RRsets that we add to the message with
DNS_RDATASETATTR_STALE_ADDED to prevent adding a duplicate RRset when
a stale lookup and a normal lookup conflict with each other. However,
the other non-stale RRset when following a CNAME chain will be added to
the message without setting that attribute, because it is not stale.
This is a variant of the bug in #2594. The fix covered the same crash
but for stale-answer-client-timeout > 0.
Fix this by clearing all RRsets from the message before refreshing.
This requires the refresh to happen after the query is send back to
the client.
When used with OpenSSL v3.0.0+, the `openssldh_compare()`,
`openssldh_paramcompare()`, and `openssldh_todns()` functions
fail to cleanup the used memory on some error paths.
Use `DST_RET` instead of `return`, when there is memory to be
released before returning from the functions.
when the compression buffer was reused for multiple statistics
requests, responses could grow beyond the correct size. this was
because the buffer was not cleared before reuse; compressed data
was still written to the beginning of the buffer, but then the size
of used region was increased by the amount written, rather than set
to the amount written. this caused responses to grow larger and
larger, potentially reading past the end of the allocated buffer.
Limit the amount of database lookups that can be triggered in
fctx_getaddresses() (i.e. when determining the name server addresses to
query next) by setting a hard limit on the number of NS RRs processed
for any delegation encountered. Without any limit in place, named can
be forced to perform large amounts of database lookups per each query
received, which severely impacts resolver performance.
The limit used (20) is an arbitrary value that is considered to be big
enough for any sane DNS delegation.
It is possible to bypass Response Rate Limiting (RRL)
`responses-per-second` limitation using specially crafted wildcard
names, because the current implementation, when encountering a found
DNS name generated from a wildcard record, just strips the leftmost
label of the name before making a key for the bucket.
While that technique helps with limiting random requests like
<random>.example.com (because all those requests will be accounted
as belonging to a bucket constructed from "example.com" name), it does
not help with random names like subdomain.<random>.example.com.
The best solution would have been to strip not just the leftmost
label, but as many labels as necessary until reaching the suffix part
of the wildcard record from which the found name is generated, however,
we do not have that information readily available in the context of RRL
processing code.
Fix the issue by interpreting all valid wildcard domain names as
the zone's origin name concatenated to the "*" name, so they all will
be put into the same bucket.
The zone 'retransfer3.' tests whether zones that 'rndc signing
-nsec3param' requests are queued even if the zone is not loaded.
The test assumes that if 'rndc signing -list' shows that the zone is
done signing with two keys, and there are no NSEC3 chains pending, the
zone is done handling the '-nsec3param' queued requests. However, it
is possible that the 'rndc signing -list' command is received before
the corresponding privatetype records are added to the zone (the records
that are used to retrieve the signing status with 'rndc signing').
This is what happens in test failure
https://gitlab.isc.org/isc-projects/bind9/-/jobs/2722752.
The 'rndc signing -list retransfer3' is thus an unreliable check.
It is simpler to just remove the check and wait for a certain amount
of time and check whether ns3 has re-signed the zone using NSEC3.
Commit b69e783164 inadvertently caused
builds using the --disable-doh switch to fail, by putting the
declaration of the isc__nm_async_settlsctx() function inside an #ifdef
block that is only evaluated when DNS-over-HTTPS support is enabled.
This results in the following compilation errors being triggered:
netmgr/netmgr.c:2657:1: error: no previous prototype for 'isc__nm_async_settlsctx' [-Werror=missing-prototypes]
2657 | isc__nm_async_settlsctx(isc__networker_t *worker, isc__netievent_t *ev0) {
| ^~~~~~~~~~~~~~~~~~~~~~~
Fix by making the declaration of the isc__nm_async_settlsctx() function
in lib/isc/netmgr/netmgr-int.h visible regardless of whether
DNS-over-HTTPS support is enabled or not.
Remove unnecessary != NULL checks
*** CID 352809: Null pointer dereferences (REVERSE_INULL) /lib/dns/message.c: 4654 in dns_message_buildopt()
4648 if (rdata != NULL) {
4649 dns_message_puttemprdata(message, &rdata);
4650 }
4651 if (rdataset != NULL) {
4652 dns_message_puttemprdataset(message, &rdataset);
4653 }
>>> CID 352809: Null pointer dereferences (REVERSE_INULL)
>>> Null-checking "rdatalist" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
4654 if (rdatalist != NULL) {
4655 dns_message_puttemprdatalist(message, &rdatalist);
4656 }
4657 return (result);
4658 }
4659
The usage of xmlInitThreads() and xmlCleanupThreads() functions in
libxml2 is now marked as deprecated, and these functions will be made
private in the future.
Use xmlInitParser() and xmlCleanupParser() instead of them.
The isc_nm_listentlsdns() function erroneously calls
isc__nm_tcpdns_stoplistening() instead of isc__nm_tlsdns_stoplistening()
when something goes wrong, which can cause an assertion failure.
In several cases where IDNA2008 mappings do not exist whereas IDNA2003
mappings do, dig was failing to process the suplied domain name. Take a
backwards compatible approach, and convert the domain to IDNA2008 form,
and if that fails try the IDNA2003 conversion.
There is an omission of assigning the return value coming from the
isc_portset_create() function to the result variable.
CID 356328:
/bin/named/server.c: 8756 in load_configuration()
8750 "creating UDP/IPv4 port set: %s",
8751 isc_result_totext(result));
8752 goto cleanup_bindkeys_parser;
8753 }
8754 isc_portset_create(named_g_mctx, &v6portset);
8755 if (result != ISC_R_SUCCESS) {
>>> CID 356328: Control flow issues (DEADCODE)
>>> Execution cannot reach this statement: "isc_log_write(named_g_lctx,...".
8756 isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
8757 NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
8758 "creating UDP/IPv6 port set: %s",
8759 isc_result_totext(result));
8760 goto cleanup_v4portset;
8761 }
YAML strings should be quoted if they contain colon characters.
Since IPv6 addresses do, we now quote the query_address and
response_address strings in all YAML output.
The dnstap query_message field was in some cases being filled in
with response messages, along with the response_message field.
The query_message field should only be used when logging requests,
and the response_message field only when logging responses.
Check the new configuration option's syntax using the 'checkconf' system
test.
Check if the new option works by parsing DiG's output in the 'rpz'
system test.
Implement the configuration option with its checking and parsing parts.
The option should be later used by BIND to set an extended error
code (EDE) for the queries modified in the result of RPZ processing.
The RPZ documentation section with response policy rules and actions
is incomplete.
Add information about the 'RPZ-CLIENT-IP' rule, and 'TCP-Only' and
'DROP' actions.
When we are closing the listening sockets, there's a time window in
which the TCP connection could be accepted although the respective
stoplistening function has already returned to control to the caller.
Clear the accept callback function early, so it doesn't get called when
we are not interested in the incoming connections anymore.
The netmgr_test unit test has been subdivided into tcp_test,
tcpdns_test, tls_test, tlsdns_test, and udp_test components.
These have been updated to use the new loopmgr.
Previously:
* applications were using isc_app as the base unit for running the
application and signal handling.
* networking was handled in the netmgr layer, which would start a
number of threads, each with a uv_loop event loop.
* task/event handling was done in the isc_task unit, which used
netmgr event loops to run the isc_event calls.
In this refactoring:
* the network manager now uses isc_loop instead of maintaining its
own worker threads and event loops.
* the taskmgr that manages isc_task instances now also uses isc_loopmgr,
and every isc_task runs on a specific isc_loop bound to the specific
thread.
* applications have been updated as necessary to use the new API.
* new ISC_LOOP_TEST macros have been added to enable unit tests to
run isc_loop event loops. unit tests have been updated to use this
where needed.
* isc_timer was rewritten using the uv_timer, and isc_timermgr_t was
completely removed; isc_timer objects are now directly created on the
isc_loop event loops.
* the isc_timer API has been simplified. the "inactive" timer type has
been removed; timers are now stopped by calling isc_timer_stop()
instead of resetting to inactive.
* isc_manager now creates a loop manager rather than a timer manager.
* modules and applications using isc_timer have been updated to use the
new API.
This commit introduces new APIs for applications and signal handling,
intended to replace isc_app for applications built on top of libisc.
* isc_app will be replaced with isc_loopmgr, which handles the
starting and stopping of applications. In isc_loopmgr, the main
thread is not blocked, but is part of the working thread set.
The loop manager will start a number of threads, each with a
uv_loop event loop running. Setup and teardown functions can be
assigned which will run when the loop starts and stops, and
jobs can be scheduled to run in the meantime. When
isc_loopmgr_shutdown() is run from any the loops, all loops
will shut down and the application can terminate.
* signal handling will now be handled with a separate isc_signal unit.
isc_loopmgr only handles SIGTERM and SIGINT for application
termination, but the application may install additional signal
handlers, such as SIGHUP as a signal to reload configuration.
* new job running primitives, isc_job and isc_async, have been added.
Both units schedule callbacks (specifying a callback function and
argument) on an event loop. The difference is that isc_job unit is
unlocked and not thread-safe, so it can be used to efficiently
run jobs in the same thread, while isc_async is thread-safe and
uses locking, so it can be used to pass jobs from one thread to
another.
* isc_tid will be used to track the thread ID in isc_loop worker
threads.
* unit tests have been added for the new APIs.
There is one case in 'dns_nsec3_activex()' where it returns but forgets
to detach the db node. Add the missing 'dns_db_detachnode()' call.
This case only triggers if 'sig-signing-type' (privatetype) is set to 0
(which by default is not), or if the function is called with 'complete'
is set to 'true' (which at this moment do not exist).
The wait_for_zone_is_signed function was never called, which could lead
to test failures due to timing issues (where a zone was not fully signed
yet, but the test was trying to verify the zone).
Also add two missing set_nsec3param calls to ensure the ITERATIONS
value is set for these test cases.
Add two scenarios where we change the dnssec-policy from using RSASHA1
to something with NSEC3.
The first case should work, as the DS is still in hidden state and we
can basically do anything with DNSSEC.
The second case should fail, because the DS of the predecessor is
published and we can't immediately remove the predecessor DNSKEY. So
in this case we should keep the NSEC chain for a bit longer.
Add two more scenarios where we change the dnssec-policy from using
NSEC3 to something NSEC only. Both should work because there are no
restrictions on using NSEC when it comes to algorithms, but in the
cases where the DS is published we can't bluntly remove the predecessor.
Extend the nsec3 system test by also checking the DNSKEY RRset for the
expected DNSKEY records. This requires some "kasp system"-style setup
for each test (setting key properties and key states). Also move the
dnssec-verify check inside the check_nsec/check_nsec3 functions because
we will have to do that every time.
When doing a dnssec-policy reconfiguration from a zone with NSEC only
keys to a zone that uses NSEC3, figure out to wait with building the
NSEC3 chain.
Previously, BIND 9 would attempt to sign such a zone, but failed to
do so because the NSEC3 chain conflicted with existing DNSKEY records
in the zone that were not compatible with NSEC3.
There exists logic for detecting such a case in the functions
dnskey_sane() (in lib/dns/zone.c) and check_dnssec() (in
lib/ns/update.c). Both functions look very similar so refactor them
to use the same code and call the new function (called
dns_zone_check_dnskey_nsec3()).
Also update the dns_nsec_nseconly() function to take an additional
parameter 'diff' that, if provided, will be checked whether an
offending NSEC only DNSKEY will be deleted from the zone. If so,
this key will not be considered when checking the zone for NSEC only
DNSKEYs. This is needed to allow a transition from an NSEC zone with
NSEC only DNSKEYs to an NSEC3 zone.
When the HTTP request has a body part after the HTTP headers, it is
not getting processed and is being prepended to the next request's data,
which results in an error when trying to parse it.
Improve the httpd.c:process_request() function with the following
additions:
1. Require that HTTP POST requests must have Content-Length header.
2. When Content-Length header is set, extract its value, and make sure
that it is valid and that the whole request's body is received before
processing the request.
3. Discard the request's body by consuming Content-Length worth of data
in the buffer.
Before the commit some checks in the system test would try to verify
that different HTTP methods can be used and are functional. However,
until recently, it was not possible to tell from the output which
method was in fact used, so it turned out that +http-plain-get option
is broken.
This commit add the additional checks to prevent that from happening
in the future.
After an earlier code cleanup, `dns_rdatalist_tordataset()` always
succeeds, so the `RETERR` error handling macro below the function
call was removed. After that change the `dynbuf` variable can never
be `NULL` in the error handling code path under the `failure` label.
*** CID 355779: Null pointer dereferences (REVERSE_INULL)
/lib/dns/tkey.c: 997 in buildquery()
991 dns_message_puttempname(msg, &aname);
992 }
993 if (question != NULL) {
994 dns_rdataset_disassociate(question);
995 dns_message_puttemprdataset(msg, &question);
996 }
>>> CID 355779: Null pointer dereferences (REVERSE_INULL)
>>> Null-checking "dynbuf" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
997 if (dynbuf != NULL) {
998 isc_buffer_free(&dynbuf);
999 }
1000 return (result);
1001 }
1002
Refactor the `buildquery()` function to simplify its error handling.
When dumping an ADB address entry associated with a name,
the name bucket lock was held, but the entry bucket lock was
not; this could cause data races when other threads were updating
address entry info. (These races are probably not operationally
harmful, but they triggered TSAN error reports.)
Fedora 36 uses OpenSSL 3.0.2 by default, but the OpenSSL engine API
which we use for PKCS#11 is deprecated in OpenSSL 3.0.0. For the
keyfromlabel system test to work operating system with OpenSSL 1.1 needs
to be used.
--without-cmocka and --without-gssapi ./configure options have been lost
when Debian 9 "stretch" was dropped from the CI. This reintroduces them,
albeit to a slightly different platform.
Moves tests from being RSASHA1 based to RSASHA256 based where possible
and split out the remaining RSASHA1 based tests so that they are not
run on OS's that don't support RSASHA1.
migrate-nomatch-alglen: switched to RSASHA256 instead of RSASHA1
and the key size now changes from 2048 bits to 3072 bits instead
of 1024 bits to 2048 bits.
migrate-nomatch-algnum: switched to RSASHA256 instead of RSASHA1
as initial algorithm and adjusted mininum key size to 2048 bits.
rsasha256: adjusted minimum key size to 2048 bits.
The nsec-only.example zone was not converted as we use it to
test nsec-only DNSSEC algorithms to nsec3 conversion failure.
The subtest is skipped in fips mode.
Update "checking revoked key with duplicate key ID" test
to use FIPS compatible algorithm.
Clean up dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset()
functions by making them return void, because they cannot fail.
Clean up other functions that subsequently cannot fail.
When checking if we should enable serve-stale, add an early out case
when the result is an error signalling a duplicate query or a query
that would be dropped.
When DiG finishes its work with a lookup (due to success or error), it
calls the clear_current_lookup() function, which decreases the lookup's
reference count. That decrease action is the counterpart of the initial
creation of the reference counter, so this function was designed in such
a way that it should decrease the reference count only once, when there
are no more active queries in the lookup.
The way it checks whether there are any active queries is by looking
at the queries list of the lookup object - if it's NULL then there are
no active queries. But that is not always true - the cancel_lookup()
function, when canceling the queries one by one, also removes them
from the lookup's list, but in NSSEARCH mode, when the queries are
working in parallel, some of those queries can be still active. And
when their recv_done() callback gets called, it sees that the lookup
has been canceled, calls clear_current_lookup(), which decreases the
reference count every time for each query that was still active
(because ISC_LIST_HEAD(lookup->q) is NULL) and results in a reference
counting error.
Fix the issue by introducing a new "cleared" property for the lookup,
which will ensure that the clear_current_lookup() function does its
job only once per lookup.
There was a copy paste error in the Makefile of the mysql dlz modules,
instead of setting the MYSQL_LIBS, LDAP_LIBS where set. This caused
the mysql bindings not to be generated.
In some circumstances generic TLS code could have resumed data reading
unexpectedly on the TCP layer code. Due to this, the behaviour of
isc_nm_pauseread() and isc_nm_resumeread() might have been
unexpected. This commit fixes that.
The bug does not seems to have real consequences in the existing code
due to the way the code is used. However, the bug could have lead to
unexpected behaviour and, at any rate, makes the TLS code behave
differently from the TCP code, with which it attempts to be as
compatible as possible.
Cumulative fetch limit logging happens on an event of a dropped
fetch if 60 seconds have been passed since the previous log message.
This change makes the log message different for the initial event
and for the later cumulative events to provide more useful information
to the system administrator.
When initially hitting the `fetches-per-zone` value, a log message
is being generated for the event of dropping the first fetch, then
any further log events occur only when another fetch is being dropped
and 60 seconds have been passed since the last logged message.
That logic isn't ideal because when the counter of the outstanding
fetches reaches zero, the structure holding the counters' values will
get deleted, and the information about the dropped fetches accumulated
during the last minute will not be logged.
Improve the fcount_logspill() function to makie sure that the final
values are getting logged before the counter object gets destroyed.
Sometimes tls_do_bio() might be called when there is no new data to
process (most notably, when resuming reads), in such a case internal
TLS session state will remain untouched and old value in 'errno' will
alter the result of SSL_get_error() call, possibly making it to return
SSL_ERROR_SYSCALL. This value will be treated as an error, and will
lead to closing the connection, which is not what expected.
Fedora 33 doesn't support RSASHA1 in future mode. There is no easy
check for this other than by attempting to perform a verification
using known good signatures. We don't attempt to sign with RSASHA1
as that would not work in FIPS mode. RSASHA1 is verify only.
The test vectors were generated using OpenSSL 3.0 and
util/gen-rsa-sha-vectors.c. Rerunning will generate a new set of
test vectors as the private key is not preserved.
e.g.
cc util/gen-rsa-sha-vectors.c -I /opt/local/include \
-L /opt/local/lib -lcrypto
The command 'rndc dumpdb -expired' will include expired RRsets in the
output, but only for the RBTDB_VIRTUAL time (of 5 minutes). This means
that if there is a cache cleaning problem and contents are not cleaned
up, the rndc command has little diagnostic value. Fix this by including
all RRsets in the dumpdb output if the '-expired' flag is set.
In the NSSEARCH followup lookup, when one of the queries fails to be
set up (UDP) or connected (TCP), DiG doesn't start the next query.
This is a mistake, because in NSSEARCH mode the queries are independent
and DiG shouldn't stop the lookup process just because setting up (or
connecting to) one of the name servers returns an error code in the
`udp_ready()` or `tcp_connected()` callbacks.
Write a new `nssearch_next()` function which takes care of starting the
next query in NSSEARCH mode, so it can be used in several places without
code repetition.
Make sure that the `udp_ready()` and `tcp_connected()` functions call
`nssearch_next()` in case they won't be calling `send_udp()` and
`send_tcp()` respectively, because in that case the `send_done()`
callback, which usually does the job, won't be called.
Refactor `send_done()` to use the newly written `nssearch_next()`
function.
In the NSSEARCH followup lookup, when one of the queries fails to be
sent, DiG doesn't start the next query. This is a mistake, because in
NSSEARCH mode the queries are independent and DiG shouldn't stop the
lookup process just because sending a query to one of the name servers
returns an error code.
Restructure the `send_done()` function to unconditionally send the next
query in NSSEARCH mode, if it exists.
In the CI dig sometimes produces warning/error comments when
communicating with the server, which produces problems when comparing
the outputs.
Here is an example of a dig output with a warning message which
is benign, because dig, after a retry, managed to query the server.
;; communications error to 10.53.0.3#7529: timed out
1.2.3.1
1.2.3.2
1.2.3.3
1.2.3.4
When comparing this to the expected output, which doesn't contain
the comment line (starting with double ';'), the outputs don't match.
Use grep inverse logic to strip the comments from the dig outputs.
There are existing tests for simulating timeouts, read errors, and
refused connecion errors. Implement also "network unreachable"
simulation.
Use "fixed" string search mode `-F` for `grep` in more places where
it is appropriate to do so.
DiG implements different logic in the `recv_done()` callback function
when processing a failure:
1. For a timed-out query it applies the "retries" logic first, then,
when it fails, fail-overs to the next server.
2. For an EOF (end-of-file, or unexpected disconnect) error it tries to
make a single retry attempt (even if the user has requested more
retries), then, when it fails, fail-overs to the next server.
3. For other types of failures, DiG does not apply the "retries" logic,
and tries to fail-over to the next servers (again, even if the user
has requested to make retries).
Simplify the logic and apply the same logic (1) of first retries, and
then fail-over, for different types of failures in `recv_done()`.
When the `send_done()` callback function gets called with a failure
result code, DiG erroneously cancels the lookup.
Stop canceling the lookup and give DiG a chance to retry the failed
query, or fail-over to another server, using the logic implemented in
the `recv_done()` callback function.
When the `udp_ready()` callback function gets called with a failure
result code, DiG erroneously cancels the lookup.
Copy the logic behind `tcp_connected()` callback function into
`udp_ready()` so that DiG will now retry the failed query (if retries
are enabled) and then, if it fails again, it will fail-over to the next
server in the list, which synchronizes the behavior between TCP and UDP
modes.
Also, `udp_ready()` was calling `lookup_detach()` without calling
`lookup_attach()` first, but the issue was masked behind the fact
that `clear_current_lookup()` wasn't being called when needed, and
`lookup_detach()` was compensating for that. This also has been fixed.
Luckily we don't rely on SphinxDirective functionality which does not
exist in 1.6.7. Replace it with docutils Directive.
transform_content() callback was added only in Sphinx 3.0.0.
Detect if it was not called and call it manually.
The transform_content() function requires access to inner "contentnode"
which is created inside run(). This workaround relies on the order of
node as it was in the pre-3.0.0 versions, but it should not matter as
new versions will not trigger the workaround.
Since !6413 we discourage opt-out, so we should not be advertising it in
the examples. Even worse, it was just thrown into the command line
without even mentioning its meaning in the surrounding text.
Related: !6413
Reject loading of zones with TTL higher than the max-zone-ttl
from the dnssec-policy.
With this change, any zone with a dnssec-policy in use will ignore
the max-zone-ttl option in zone/view/options.
The "max-zone-ttl" option should now be configured as part of
"dnssec-policy". The option with the same name in "zone" and
"options" is hereby flagged as deprecated, and its functionality
will be removed in a future release.
Now that the respdiff tests can detect memory leaks, it is worth running
them for every merge request. However, the existing respdiff-based
tests take a while to complete (about half an hour with our current CI
infrastructure), which does not make them a good fit for this purpose.
Add a new GitLab CI job, "respdiff-short", which uses a smaller query
set that gets processed within a couple of minutes on our current CI
infrastructure. Rename the existing respdiff-based jobs to make
distinguishing them easier.
Ensure the common parts of all jobs using respdiff are available in the
form of a reusable YAML anchor, to reduce code duplication and to
simplify adding more respdiff-based jobs to GitLab CI.
The "respdiff" GitLab CI job compares DNS responses produced by the
current version of named with those produced by a reference version.
The latter is built from source in each "respdiff" job, despite the fact
that the reference version changes very rarely. Use a pre-built named
executable as the reference version instead, assuming it is available in
the OS image used for "respdiff" tests.
These calls have not been needed since OpenSSL 0.9.7h.
This dates to commit 704d6eeab1, "Work
around non-reentrancy in openssl by disabling precomputation in keys".
This was in the bundled OpenSSL 0.9.3a era and made two changes. First,
it registered a locking callback because, in those days, OpenSSL needed
a callback to support locks. Second, it set flags to disable various
bits of cached state on DH, DSA, and RSA objects.
Looking back in OpenSSL 0.9.3a, that cached state was not protected by a
lock:
https://github.com/openssl/openssl/blob/OpenSSL_0_9_3a/crypto/rsa/rsa_eay.c#L137-L142
However, this was fixed in OpenSSL 0.9.7h:
https://github.com/openssl/openssl/commit/6ec8e63af6c1835a8b222350dbabf7bb2ace094f
The other flags (DSA and RSA) have since fallen away, DSA with the
removal of DSA altogether (3994b1f9c2) and
RSA with 3a8d4a316e, "openssl 0.9.6a and
higher don't have the RSA locking bug [...] other algorithms still don't
do locking when performing precomputation [...]".
That seems to be referring to this OpenSSL change, which indeed fixed it
for RSA but not others:
https://github.com/openssl/openssl/commit/bb617a9646d95d0454edda995518f370172390e9
The 0.9.7h change above fixed it across the board, but there was never a
similar update to the workaround for DSA and DH. With such OpenSSL
versions long since out of support, the last remains of this workaround
can finally be removed.
When callback was NULL, bind9 would use BN_GENCB_set_old to set a NULL
callback because OpenSSL happened to allow a NULL "old" callback, but
not a NULL "new" callback. Instead, the way to turn off the callback is
to pass a NULL BN_GENCB itself.
Switch to doing that.
The BUFSIZ value varies between platforms, it could be 8K on Linux and
512 bytes on mingw. Make sure the buffers are always big enough for the
output data to prevent truncation of the output by appropriately
enlarging or sizing the buffers.
Remove "external" from the list of legal values for the -M command-line
option as it has not been allowed since the internal memory allocator
was removed by commit 55ace5d3aa.
Make the style of the relevant paragraph more in line with the next one
and split its contents up into an unordered list of options for improved
readability.
When a thread calls dns_dispatch_connect() on an unconnected TCP socket
it sets `tcpstate` from `DNS_DISPATCHSTATE_NONE` to `_CONNECTING`.
Previously, it then INSISTed that there were no pending connections
before calling isc_nm_tcpdnsconnect().
If a second thread called dns_dispatch_connect() during that window
of time, it could add a pending connection to the list, and trigger
an assertion failure.
This commit removes the INSIST since the condition is actually
harmless.
The statistics system test makes a query to foo.info to check for the
pending connections because the ans4 doesn't respond to the query.
This might or might not (depending on exact timing) increment the failed
TCP connection counter when the query is retried over TCP because ans4
doesn't listen on the TCP.
Wait for the 'connection refused' in the ns3 log file to be able to
count the exactly 1 failed TCP connection.
The STATID_CONNECT and STATID_CONNECTFAIL statistics were used
incorrectly. The STATID_CONNECT was incremented twice (once in
the *_connect_direct() and once in the callback) and STATID_CONNECTFAIL
would not be incremented at all if the failure happened in the callback.
Closes: #3452
On FreeBSD (and perhaps other *BSD) systems, the TCP connect() call (via
uv_tcp_connect()) can fail with transient UV_EADDRINUSE error. The UDP
code already handles this by trying three times (is a charm) before
giving up. Add a code for the TCP, TCPDNS and TLSDNS layers to also try
three times before giving up by calling uv_tcp_connect() from the
callback two more time on UV_EADDRINUSE error.
Additionally, stop the timer only if we succeed or on hard error via
isc__nm_failed_connect_cb().
free_namelist could be passed names with associated rdatasets
when handling errors. These need to be disassociated before
calling dns_message_puttemprdataset.
uv_barrier_init() errors are currently ignored. Use UV_RUNTIME_CHECK()
to catch them and to improve error reporting for any uv_barrier_init()
run-time failures (by augmenting error messages with file/line
information and the error string corresponding to the value returned).
Set the ISC_TRACK_PTHREADS_OBJECTS preprocessor macro when preparing a
build of BIND 9 for respdiff testing and pass the -m command-line option
to respdiff.sh in order to enable automatic identification of memory
leaks during respdiff tests.
Instead of returning error values from isc_rwlock_*(), isc_mutex_*(),
and isc_condition_*() macros/functions and subsequently carrying out
runtime assertion checks on the return values in the calling code,
trigger assertion failures directly in those macros/functions whenever
any pthread function returns an error, as there is no point in
continuing execution in such a case anyway.
Replace direct uses of implementation-specific rwlock functions in
lib/isc/include/isc/rwlock.h with preprocessor macros that use
ERRNO_CHECK(), in order to augment rwlock-related error messages with
file/line/caller information and the error string corresponding to
errno. Adjust the implementation-specific functions for pthreads-based
rwlocks so that they return any errors encountered to the caller instead
of aborting execution immediately using RUNTIME_CHECK().
To keep code modifications simple, make the non-pthreads-based
implementation-specific rwlock functions always return 0; these
functions continue to handle errors using less verbose run-time
assertions as they do not set errno anyway.
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_barrier_init() is called. Every call to
that function must be accompanied by a corresponding call to
pthread_barrier_destroy() or else the memory allocated for the barrier
will leak.
jemalloc can be used for detecting memory allocations which are not
released by a process when it exits. Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.
However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying barriers that allocate memory using malloc() and release it
using free(). This enables using jemalloc for detecting missing
pthread_barrier_destroy() calls on any platform on which it works
reliably.
When the newly introduced ISC_TRACK_PTHREADS_OBJECTS preprocessor macro
is set, allocate isc_barrier_t structures on the heap in
isc_barrier_init() and free them in isc_barrier_destroy(). Reuse
existing barrier macros (after renaming them appropriately) for other
operations.
Instead of using isc_once_do() on every isc_mutex_init() call, use the
global library constructor to initialize the default mutex attr
object (optionally with PTHREAD_MUTEX_ADAPTIVE_NP if supported) just
once when the library is loaded.
Replace all uses of RUNTIME_CHECK() in lib/isc/include/isc/condition.h
with ERRNO_CHECK(), in order to improve error reporting for any
condition-variable-related run-time failures (by augmenting error
messages with file/line/caller information and the error string
corresponding to errno).
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_rwlock_init() is called. Every call to
that function must be accompanied by a corresponding call to
pthread_rwlock_destroy() or else the memory allocated for the rwlock
will leak.
jemalloc can be used for detecting memory allocations which are not
released by a process when it exits. Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.
However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying rwlocks that allocate memory using malloc() and release it
using free(). This enables using jemalloc for detecting missing
pthread_rwlock_destroy() calls on any platform on which it works
reliably.
When the newly introduced ISC_TRACK_PTHREADS_OBJECTS preprocessor macro
is set (and --enable-pthread-rwlock is used), allocate isc_rwlock_t
structures on the heap in isc_rwlock_init() and free them in
isc_rwlock_destroy(). Reuse existing functions defined in
lib/isc/rwlock.c for other operations, but rename them first, so that
they contain triple underscores (to indicate that these functions are
implementation-specific, unlike their mutex and condition variable
counterparts, which always use the pthreads implementation). Define the
isc__rwlock_init() macro so that it is a logical counterpart of
isc__mutex_init() and isc__condition_init(); adjust isc___rwlock_init()
accordingly. Remove a redundant function prototype for
isc__rwlock_lock() and rename that (static) function to rwlock_lock() in
order to avoid having to use quadruple underscores.
isc_rwlock_init() currently detects pthread_rwlock_init() failures using
a REQUIRE() assertion. Use the ERRNO_CHECK() macro for that purpose
instead, so that read-write lock initialization failures are handled
identically as condition variable (pthread_cond_init()) and mutex
(pthread_mutex_init()) initialization failures.
Replace all uses of RUNTIME_CHECK() in lib/isc/include/isc/mutex.h with
ERRNO_CHECK(), in order to improve error reporting for any mutex-related
run-time failures (by augmenting error messages with file/line/caller
information and the error string corresponding to errno).
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_cond_init() is called. Every call to
that function must be accompanied by a corresponding call to
pthread_cond_destroy() or else the memory allocated for the condition
variable will leak.
jemalloc can be used for detecting memory allocations which are not
released by a process when it exits. Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.
However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying condition variables that allocate memory using malloc() and
release it using free(). This enables using jemalloc for detecting
missing pthread_cond_destroy() calls on any platform on which it works
reliably.
When the newly introduced ISC_TRACK_PTHREADS_OBJECTS preprocessor macro
is set, allocate isc_condition_t structures on the heap in
isc_condition_init() and free them in isc_condition_destroy(). Reuse
existing condition variable macros (after renaming them appropriately)
for other operations.
In a number of situations in pthreads-related code, a common sequence of
steps is taken: if the value returned by a library function is not 0,
pass errno to strerror_r(), log the string returned by the latter, and
immediately abort execution. Add an ERRNO_CHECK() preprocessor macro
which takes those exact steps and use it wherever (conveniently)
possible.
Notes:
1. The "log the return value of strerror_r() and abort" pattern is used
in a number of other places that this commit does not touch; only
"!= 0" checks followed by isc_error_fatal() calls with
non-customized error messages are replaced here.
2. This change temporarily breaks file name & line number reporting for
isc__mutex_init() errors, to prevent breaking the build. This issue
will be rectified in a subsequent change.
Some POSIX threads implementations (e.g. FreeBSD's libthr) allocate
memory on the heap when pthread_mutex_init() is called. Every call to
that function must be accompanied by a corresponding call to
pthread_mutex_destroy() or else the memory allocated for the mutex will
leak.
jemalloc can be used for detecting memory allocations which are not
released by a process when it exits. Unfortunately, since jemalloc is
also the system allocator on FreeBSD and a special (profiling-enabled)
build of jemalloc is required for memory leak detection, this method
cannot be used for detecting leaked memory allocated by libthr on a
stock FreeBSD installation.
However, libthr's behavior can be emulated on any platform by
implementing alternative versions of libisc functions for creating and
destroying mutexes that allocate memory using malloc() and release it
using free(). This enables using jemalloc for detecting missing
pthread_mutex_destroy() calls on any platform on which it works
reliably.
Introduce a new ISC_TRACK_PTHREADS_OBJECTS preprocessor macro, which
causes isc_mutex_t structures to be allocated on the heap by
isc_mutex_init() and freed by isc_mutex_destroy(). Reuse existing mutex
macros (after renaming them appropriately) for other operations.
Commit 7b2ea97e46 introduced a logic bug
in resume_dslookup(): that function now only conditionally checks
whether DS chasing can still make progress. Specifically, that check is
only performed when the previous resume_dslookup() call invokes
dns_resolver_createfetch() with the 'nameservers' argument set to
something else than NULL, which may not always be the case. Failing to
perform that check may trigger assertion failures as a result of
dns_resolver_createfetch() attempting to resolve an invalid name.
Example scenario that leads to such outcome:
1. A validating resolver is configured to forward all queries to
another resolver. The latter returns broken DS responses that
trigger DS chasing.
2. rctx_chaseds() calls dns_resolver_createfetch() with the
'nameservers' argument set to NULL.
3. The fetch fails, so resume_dslookup() is called. Due to
fevent->result being set to e.g. DNS_R_SERVFAIL, the default branch
is taken in the switch statement.
4. Since 'nameservers' was set to NULL for the fetch which caused the
resume_dslookup() callback to be invoked
(fctx->nsfetch->private->nameservers), resume_dslookup() chops off
one label off fctx->nsname and calls dns_resolver_createfetch()
again, for a name containing one label less than before.
5. Steps 3-4 are repeated (i.e. all attempts to find the name servers
authoritative for the DS RRset being chased fail) until fctx->nsname
becomes stripped down the the root name.
6. Since resume_dslookup() does not check whether DS chasing can still
make progress, it strips off a label off the root name and continues
its attempts at finding the name servers authoritative for the DS
RRset being chased, passing an invalid name to
dns_resolver_createfetch().
Fix by ensuring resume_dslookup() always checks whether DS chasing can
still make progress when a name server fetch fails. Update code
comments to ensure the purpose of the relevant dns_name_equal() check is
clear.
There should be 2 keys with the same key id after the numerically
lower one is revoked (serial space arithmetic). The DS points
at the non-revoked key so validation should still succeed.
messages indicating the reason for a fallback to AXFR (i.e, because
the requested serial number is not present in the journal, or because
the size of the IXFR response would exceeed "max-ixfr-ratio") are now
logged at level info instead of debug(4).
Before this change the TLS code would ignore the accept callback result,
and would not try to gracefully close the connection. This had not been
noticed, as it is not really required for DoH. Now the code tries to
shut down the TLS connection gracefully when accepting it is not
successful.
This commit removes an assertion from the unit test which cannot be
guaranteed.
According to the test, exactly one client send must succeed. However,
it cannot really be guaranteed, as do not start to read data in the
accept callback on the server nor attach to the accepted handle. Thus,
we can expect the connection to be closed soon after we have returned
from the callback.
Interestingly enough, the test would pass just fine on TCP because:
a) there are fewer layers involved and thus there is less processing;
b) it is possible for the data to be sent and end up in an internal OS
socket buffer without being touched by an application's code on the
server. In such a case the client's write callback still would be
called successfully;
There is a chance for the test to succeed over TLS as well (as it
happily did before), but as the code has been changed to close unused
connections as soon as possible, the chance is far slimmer now.
What can be guaranteed is:
* cconnects == 1 (number client connections equals 1);
* saccepts == 1 (number of accepted connections equals 1).
Otherwise the code path will lead to a call to SSL_get_error()
returning SSL_ERROR_SSL, which in turn might lead to closing
connection to early in an unexpected way, as it is clearly not what is
intended.
The issue was found when working on loppmgr branch and appears to
be timing related as well. Might be responsible for some unexpected
transmission failures e.g. on zone transfers.
In some operations - most prominently when establishing connection -
it might be beneficial to bail out earlier when the network manager
is stopping.
The issue is backported from loopmgr branch, where such a change is
not only beneficial, but required.
In some cases - in particular, in case of errors, NULL might be passed
to a connection callback instead of a handle that could have led to
an abort. This commit ensures that such a situation will not occur.
The issue was found when working on the loopmgr branch.
This commit ensures that the underlying TCP socket of a TLS connection
gets closed earlier whenever there are no pending operations on it.
In the loop-manager branch, in some circumstances the connection
could have remained opened for far too long for no reason. This
commit ensures that will not happen.
When dnssec-policy is used, and the zone is not dynamic, BIND will
assume that the zone is inline-signed. But the function responsible
for this did not inherit the dnssec-policy option from the view or
options level, and thus never enabled inline-signing, while the zone
should have been.
This is fixed by this commit.
Fix a comment, ensuring the right parameters are used (zone is
parameter $3, not $2) and add view and policy parameters to the comment.
Fix the view tests and test the correct view (example3 instead of
example2).
Fix placement of "n=$((n+1)" for two test cases.
The name compression unit test is expanded to check that the compressed
form matches the expected wire pattern.
Record owner names are compressed differently to rdata names by
calling dns_name_towire2 instead of dns_name_towire so check that
owner names are compressed correctly as well.
Currently, when rrset is being compressed, the optimization has been put
in place to reuse offset to the previous name in the same rrset. This
skips the check for non-improving compression and thus compresses the
root zone making the wireformat worse by one byte.
Additionally, when the compression has been disabled for the name, it
would be repeatedly added to the compression table because we act as if
the name was not found and the dns_compress_add() doesn't check for the
existing entry.
Change the dns_name_towire2() to always lookup the name in the
compression table to prevent adding duplicates, but don't use it neither
in the wireformat nor in the rrset cache.
"rndc fetchlimit" now also prints a list of domain names that are
currently rate-limited by "fetches-per-zone".
The "fetchlimit" system test has been updated to use this feature
to check that domain limits are applied correctly.
this command runs dns_adb_dumpquota() to display all servers
in the ADB that are being actively fetchlimited by the
fetches-per-server controls (i.e, servers with a nonzero average
timeout ratio or with the quota having been reduced from the
default value).
the "fetchlimit" system test has been updated to use the
new command to check quota values instead of "rndc dumpdb".
* make it harder to get the interface numbers wrong by using 'max'
to specify the upper bound of the sequence of interfaces and use 'max'
when calculating the interface number
* extract the platform specific instruction into 'up' and 'down'
and call them from the inner loop so that the interface number is
calculated in one place.
* calculate the A and AAAA address in a single place rather than
in each command
* use /sbin/ipadm on Solaris 2.11 and greater
previously, when an iterative query returned FORMERR, resolution
would be stopped under the assumption that other servers for
the same domain would likely have the same capabilities. this
assumption is not correct; some domains have been reported for
which some but not all servers will return FORMERR to a given
query; retrying allows recursion to succeed.
it's a style violation to have REQUIRE or INSIST contain code that
must run for the server to work. this was being done with some
atomic_compare_exchange calls. these have been cleaned up. uses
of atomic_compare_exchange in assertions have been replaced with
a new macro atomic_compare_exchange_enforced, which uses RUNTIME_CHECK
to ensure that the exchange was successful.
The original sscanf processing allowed for a number of syntax errors
to be accepted. This included missing the closing brace in
${modifiers}
Look for both comma and right brace as intermediate seperators as
well as consuming the final right brace in the sscanf processing
for ${modifiers}. Check when we got right brace to determine if
the sscanf consumed more input than expected and if so behave as
if it had stopped at the first right brace.
$GENERATE uses 'int' for its computations and some constructions
can overflow values that can be represented by an 'int' resulting
in undefined behaviour. Detect these conditions and return a
range error.
On slow systems we have seen this take 9 seconds. Increased the
allowance from 3 seconds to 10 seconds to reduce the probabilty of
a false negative from the system test.
The previous test code could emit "D:cds:stderr did not match ''" rather
that just showing the contents of stderr. Moved the debug line inside
the if/else block.
Replaced backquotes with $() and $(()) as approriate.
We are grafting on an unsigned zone "example.internal" where the higher
zone (".") is signed and would otherwise cause named to synthesise a
NXDOMAIN for example.internal. We prime the cache by performing a
lookup for "internal" and then lookup "example.internal".
We do this by adding callbacks for when a node is added or deleted
from the keytable. dns_keytable_add and dns_keytable_delete where
extended to take a callback. dns_keytable_deletekey does not remove
the node so it was not extended.
Call dns_view_sfd_find to find the namespace to be used to verify
the covering NSEC records returned for the given QNAME. Check that
the NSEC owner names are within that namespace.
When namespace is grafted on, the DNSSEC proofs for non existance
need to come from that namespace and not a higher namespace. We
add 3 function dns_view_sfd_add, dns_view_sfd_del and dns_view_sfd_find
to add, remove and find the namespace that should be used when
checking NSEC records.
dns_view_sfd_add adds a name to a tree, creating the tree if needed.
If the name already existed in the tree the reference count is
increased otherwise it is initalised to 1.
dns_view_sfd_del removes a reference to a name in the tree, if the
count goes to 0 the node is removed.
dns_view_sfd_find returns the namespace to be used to entered name.
If there isn't an enclosing name in the tree, or the tree does not
yet exist, the root name is returned.
Access to the tree is controlled by a read/write lock.
Commits 76bcb4d16b and
d48d8e1cf0 did not include
isc_refcount_destroy() calls that would be logical counterparts of the
isc_refcount_init() calls these commits added. Add the missing
isc_refcount_destroy() calls to destroy().
Adding these calls (which ensure a given structure's reference count
equals 0 when it is destroyed, therefore detecting reference counting
issues) uncovered another flaw in the commits mentioned above: missing
isc_refcount_decrement() calls that would be logical counterparts of the
isc_refcount_increment*() calls these commits added. Add the missing
isc_refcount_decrement() calls to unlink_name() and unlink_entry().
Add isc_mutex_destroy() and isc_rwlock_destroy() calls missing from the
commits that introduced the relevant isc_mutex_init() and
isc_rwlock_init() calls:
- 76bcb4d16b
- 1595304312
- 857f3bede3
None of these omissions affect any hot paths, so they are not expected
to cause operational issues; correctness is the only concern here.
Some logging categories have the same names as configuration statements.
This caused some category names to be replaced with links to statement
definitions, which confuses util/check-categories.sh script.
Except for a single case they were not referenced in the text, but at
the same time doc/misc grammar uses terms "size", "sizeval", and
"percetage".
Keywords "default" and "unlimited" are expanded in statement's grammar
anyway, but I kept their description in place because they are generally
allowed at places which accept sizes.
Percentage is also expanded in doc/misc grammars and thus requires
separate definition.
This definition was used only for deny-answer-aliases statement
description, and moreover the term did not match grammar listed in
doc/misc/options.
I've replaced it with textual expansion of "list of `domain_name`s"
which is used more often.
Name remoteserver_list was not referenced anywhere but the grammar uses
name remote-servers. Rename and add a reference to primaries for more
information.
Manual edit required to restore the first occurence of "definition"
inside .. glossary directive.
Generated using:
N=acl_name; sed -i -e "s/\`\`$N\`\`/:term:\`$N\`/g" $ARMFILES
N=address_match_list; sed -i -e "s/\`\`$N\`\`/:term:\`$N\`/g" $ARMFILES
I dunno why it was a separate entity in the grammar glossary. It is not
referenced anywhere else except for the the dialup statement, and the
statement describes all its possible values verbosely.
It turns out that many manual edits were required:
- Heading underlines were too short because :any:`` is longer than ````
- Some statement names clashed with manually defined _link_anchors
(notify, trust-anchors etc.)
- Zone types are defined like "type primary" in the internal grammar and
that caused mayhem in the replacement script as it took "type" and
individual types ("primary", "secondary") as separate statements.
For that reason :any:`primary` had to be manually replaced with
:any:`primary <type primary>` where appropriate.
- Sometimes option name is also the same as a value name (e.g. "notify")
and then it did not make sense to do the replacement.
The underline is not shortened on purpose, see subsequent commits.
Generated by:
sed -i -e 's/ Statement Definition and Usage$/ Block Definition and Usage/g' doc/arm/reference.rst
Long live new terminology.
The underline is now shortened on purpose, see subsequent commits.
Generated by:
sed -i -e 's/ Statement Grammar$/ Block Grammar/g' doc/arm/reference.rst
Without this change tables generated by .. namedconf:statementlist::
contained raw text and displayed rst syntax to users.
The raw docutil node returned by rst parser can contain unresolved
references (pending_xref nodes). We just store those nodes and let
Sphinx to resolve them later on.
Beware: This would not work if we injected nodes in later stages of
processing. All unresolved references must be in place before
'doctree-resolved' event is emitted (i.e. before resolve_references() is
called inside Sphinx).
This change allows us to generate "unresolved" references and let Sphinx
deal with dereferencing them in later stages. It is not useful by itself
but it serves as preparation for the next commit.
Formerly resolve_xref() in Sphinx extension called get_objects() from
Sphinx API which subsequently iterated the whole list of objects,
causing single iteration per single reference, which is essentially.
O(n^2). Avoid using get_objects() and access internal dictionary
directly intead.
The docs build time was still dominated by other factors but speedup is
about 10 % on my machine.
From Gitlab 15.0 release notes:
artifacts:reports:cobertura keyword
As of GitLab 15.0, the artifacts:reports:cobertura keyword has
been replaced by artifacts:reports:coverage_report. Cobertura
is the only supported report file, but this is the first step
towards GitLab supporting other report types.
This is super confusing because statement "keys" exists in context
controls and server blocks where it refers to symmetric TSIG key, and it
_also_ exists in dnssec-policy block where it specifies public-private
key pair parameters.
In an (unsuccessful) attempt to disambiguate these two I added bunch of
hyperlinks and a warning.
It would be too easy if we could just call sorted(). Thanks to zone
grammar the most important key "type" gets sorted near end, so we pull
it up to the top using a hack.
It turns out the tree of dictionaries is not the best structure to
represent our grammar, unfortunatelly. The problem is that "zone" has
several context-dependent variants which change meaning of "zone" based
on inner field "type".
Redesigning the whole structure does not seem to be worth, so I settled
on this terrible hack.
A new flag
.. namedconf:statement::
:suppress_grammar:
suppresses pretty-printing grammar.
It is useful mostly for zones because each zone has it's own grammar, so
printing all of them at once usually does not make sense.
The utility detects statements which use the same name (e.g.
max-zone-ttl) but use different grammar in different contexts. These
typically need special case in docs.
It transforms named.conf/rndc.conf grammar from text format into Python
dictionary. This allows granular access to grammar elements.
Beware: It heavity depens on cfg_test output format!
The next commit is going to add parser for ISC configuration format.
To simplify the parser the grammar files in doc/misc are no longer
line-wrapped as handling it would make the grammar parser unnecessairly
complicated.
This affects visible output in the ARM, but in the end we are going to
replace the auto-generated .rst files with grammar pretty printed, so
formatting of these files does not matter in practical terms.
The "glue-cache" option was marked as deprecated by commit
5ae33351f2 (first released in BIND 9.17.6,
back in October 2020), so now obsolete that option, removing all code
and documentation related to it.
Note: this causes the glue cache feature to be permanently enabled, not
disabled.
This commit ensures that on reconfiguration a proper value for HTTP
connections limit is picked up.
The commit also refactors how listeners settings are updated so that
there is less code duplication.
This way only quota size is passed to the interface/listener
management code instead of a quota object. Thus, we can implement
updating the quota object size instead of recreating the object.
Remove the duplication from the defaultconf and inherit the values
not set in the "insecure" policy from the "default" policy. Therefore,
we must insist that the first read built-in policy is the default one.
Most of the settings (durations) are already inheriting from the default
because they use the constants from lib/dns/kasp.h. We need them as
constants so we can use them in named-checkconf to verify the policy
parameters.
The NSEC(3) parameters and keys should come from the actual default
policy. Change the call to cfg_kasp_fromconfig() to include the default
kasp. We also no longer need to corner case where config is NULL we load
the built-in policy: the built-in policies are now loaded when config is
set to named_g_config.
Finally, add a debug log (it is useful to see which policies are being
loaded).
Update the defaultconf with the built-in policies. These will now be
printed with "named -C".
Change the defines in kasp.h to be strings, so they can be concatenated
in the defaultconf. This means when creating a kasp structure, we no
longer initialize the defaults (this is fine because only kaspconf.c
uses dns_kasp_create() and it inherits from the default policy).
In kaspconf.c, the default values now need to be parsed from string.
Introduce some variables so we don't need to do get_duration multiple
times on the same configuration option.
Finally, clang-format-14 decided to do some random formatting changes.
Unfortunatelly logging and zone blocks use file statements with
different semantics but the same name.
There is no sane way to disambiguate them in text, so let's remove the
link anchor from logging so we can link to the file statement in zone.
My assumption is that linking to logging { file } is very unlikely
because logging is self-contained in one block but zone config is all
over the place.
Unfortunatelly dnssec-policy and servers blocks use keys statements with
a totally different grammar and semantics but the same name.
There is no sane way to disambiguate them in text, so let's remove the
link anchors to prevent errorneous linking.
control { inet ... allow keys read-only }; are not actual statements
but in fact arguments of a statement. Remove .. namedconf:statement::
syntax to avoid collisions with other statements of the same name.
All statements now use .. namedconf:statement:: or
.. rndcconf:statement:: syntax provided by our Sphinx extension.
This has several consequences:
- It changes how statement headings are rendered
- Statements are indexed and show up as separate items in doc
search results (in the HTML version)
- Statements can be linked to using either :any:`statement` or
:namedconf:ref:`statement` syntax (not used in this commit)
- Statements can be categorized and printed using ..
namedconf:statatementlist:: syntax (not used in this commit)
Warn users that server-side IP addresses are not stored in dnstap
captures of resolver traffic unless "query-source(-v6)" is explicitly
set, explaining why it is so.
The current logic for determining the address of the socket to which a
client sent its query is:
1. Get the address:port tuple from the netmgr handle using
isc_nmhandle_localaddr().
2. Convert the address:port tuple from step 1 into an isc_netaddr_t
using isc_netaddr_fromsockaddr().
3. Convert the address from step 2 back into a socket address with the
port set to 0 using isc_sockaddr_fromnetaddr().
Note that the port number (readily available in the netmgr handle) is
needlessly lost in the process, preventing it from being recorded in
dnstap captures of client traffic produced by named.
Fix by first storing the address:port tuple returned by
isc_nmhandle_localaddr() in client->destsockaddr and then creating an
isc_netaddr_t from that structure. This allows the port number to be
retained in client->destsockaddr, which is what subsequently gets passed
to dns_dt_send().
The two procedures were essentially the same, but each instance was
missing some details from the other. They are now combined into one text
in the DNSSEC Guide and linked from DNSSEC chapter.
Private Type Records are not specific to manually signing, so it is
better to move it to the end of the "Zone Signing" section shared by all
three methods.
Mostly deduplicating and linking information across the ARM.
Generally people should not touch it unless they what they are doing, so
let's try to discourage them a bit.
The goal is simplicity. Copy&paste to do the right thing, or read
referenced material and make up your mind if you need specialities.
NSEC discussion is already present in the DNSSEC guide so I merged
KASP examples with example for NSEC3 and removed NSEC text from the
DNSSEC chapter.
Use best practice values in examples that follow new guidance from
draft-ietf-dnsop-nsec3-guidance:
; SHA-1, no extra iterations, empty salt:
;
bcp.example. IN NSEC3PARAM 1 0 0 -
Restructure the section about dynamic zones and automatic signing:
- Focus on dynamic zones with 'auto-dnssec allow;'.
- Add a section about multi-signer models.
- Move NSEC3 related topics into one section.
- Remove any text that does not concern dynamic zones (mostly duplicate
text anyway).
Move bits from the "DNSSEC, Dynamic Zones, and Automatic Signing"
about denial of existence to a separate section below the "Key and
Signing Policy" section.
Add a brief introduction about denial of existence to this section.
Restructure the first part of the DNSSEC chapter that deals with zone
signing. Put dnssec-policy first. Mention Key and Signing Policy.
Only then talk about the DNSSEC tools.
- Use absolute paths when invoking the convert-trs-to-junit.py script
so that it also works correctly for out-of-tree and tarball-based
test jobs.
- Quote the variables used in convert-trs-to-junit.py invocations to
future-proof the code.
- Use "&&" instead of ";" in shell pipelines invoking the
convert-trs-to-junit.py script in order to prevent "source" errors
from being silently ignored.
- Ensure convert-trs-to-junit.py is invoked from the correct directory
for out-of-tree and tarball-based unit test jobs by adding
appropriate "cd" invocations.
- Ensure the convert-trs-to-junit.py invocations are always the last
step in each 'after_script', in order to run that script from the
correct directory for out-of-tree and tarball-based system test jobs
and to ensure that any potential errors in that script do not
prevent more important steps in the 'after_script' from being
executed.
Out-of-tree build & test jobs currently defined in GitLab CI use
/tmp/out_of_tree_workspace as the working directory. This requires
juggling that directory around as it gets passed from the build job to
the test jobs and then again after the test jobs are finished, so that
artifacts can be collected for the purpose of investigating test
failures. The original intention of doing this was to ensure that
bin/tests/system/run.sh does not rely on being executed from within a
Git working copy (which happens e.g. if the out-of-tree workspace is a
subdirectory of $CI_PROJECT_DIR, i.e. the path into which GitLab
Runner clones the project in each job).
However, even with these complications in place, not all possible
scenarios that should be handled properly by the system test framework
(e.g. invoking a given test one time after another from the same
out-of-tree build directory) are tested in GitLab CI anyway. Meanwhile,
the requirement for moving the out-of-tree workspace into
$CI_PROJECT_DIR in the 'after_script' for each out-of-tree job makes
these jobs less robust than they could be; for example, if any step in
the 'after_script' returns a non-zero exit code, the job's artifacts
will not include the out-of-tree workspace, hindering troubleshooting.
Simplify job definitions in .gitlab-ci.yml by moving the workspace used
by out-of-tree build & test jobs back to a subdirectory of
$CI_PROJECT_DIR. Whether the out-of-tree workspace exists within a Git
working copy or not does not matter for Autotools, so this is considered
to be a reasonable trade-off in terms of test coverage.
With the addition of Ubuntu 22.04 three more CI jobs were added. To
compensate for that, move Ubuntu 18.04 jobs out of MR-triggered
pipelines to schedule-triggered ones.
Also, move --disable-geoip ./configure options from Ubuntu 18.04 to
Ubuntu 20.04 jobs to keep these options in the more frequent
MR-triggered pipelines.
Have system tests use required Python (dnspython) and PERL modules
(Digest::HMAC and Net::DNS) from user directories, avoid using
privileges.
Note: The pythonenv must be setup to use the same version of python as
the test uses, for example /usr/bin/python.
Thanks to Stacey Marshall.
Make clear that inline-signing stores DNSSEC records in a signed
version of the zone, using the zone's filename plus ".signed" extension.
Tell that dynamic zones store updates in the zone's filename.
DNSSEC records for dynamic zones also go in the zone's filename, unless
inline-signing is enabled.
Then, dnssec-policy assumes inline-signing, but only if the zone is
not dynamic.
pylint 2.14.2 reports the following warnings:
bin/tests/system/checkds/tests-checkds.py:265:0: W1404: Implicit string concatenation found in call (implicit-str-concat)
bin/tests/system/checkds/tests-checkds.py:273:0: W1404: Implicit string concatenation found in call (implicit-str-concat)
If skip/xfail is used in pytest, it can have a reason string associated
with it. When evaluating these tests, it can be useful to be able to
differentiate the reason why the test was skipped/xfailed/xpassed,
because there might be multiple possible reasons for that.
The extra options passed to pytest ensure that the string with the
reason appears in the test summary and thus we're able to find the
string with the reason in the log output.
See https://docs.pytest.org/en/7.1.x/how-to/skipping.html for more info
Before the changes from this commit were introduced, the accept
callback function will get called twice when accepting connection
during two of these stages:
* when accepting the TCP connection;
* when handshake has completed.
That is clearly an error, as it should have been called only once. As
far as I understand it the mistake is a result of TLS DNS transport
being essentially a fork of TCP transport, where calling the accept
callback immediately after accepting TCP connection makes sense.
This commit fixes this mistake. It did not have any very serious
consequences because in BIND the accept callback only checks an ACL
and updates stats.
Based on measurements done on BIND v9_19_2 using bank. TLD and a
synthetitc fullly signed zone, using RSASHA256 and ECDSAP256SHA256
algorithms with NSEC and NSEC3 without opt-out.
This section was completely out of date. Current measurements on dataset
Telco EU 2022-02 and BIND 9.19.1 indicate absolutely different results
than described in the old version of the text.
Guide in this repo is tied to latest version anyway, so let's not even
mention ancient versions of BIND.
This also solves the OpenSSL question because it is now mandatory for
build, which subsequently removes the entropy problem - so let's not
mention it either.
When shutting down, the interface manager can be destroyed
before the `route_connected()` callback is called, which is
unexpected for the latter and can cause a crash.
Move the interface manager attachment code from the callback
to the place before the callback is registered using
`isc_nm_routeconnect()` function, which will make sure that
the interface manager will live at least until the callback
is called.
Make sure to detach the interface manager if the
`isc_nm_routeconnect()` function is not implemented, or when
the callback is called with a result value which differs from
`ISC_R_SUCCESS`.
The `ns_interfacemgr_create()` function, when calling
`isc_nm_routeconnect()`, uses the newly created `ns_interfacemgr_t`
instance before initializing its reference count and the magic value.
Defer the `isc_nm_routeconnect()` call until the initializations
are complete.
In special NS search mode, after the initial lookup, dig starts the
followup lookup with discovered NS servers in the queries list. If one
of those queries then fail, dig, as usual, tries to start the next query
in the list, which results in a crash, because the NS search mode is
special in a way that the queries are running in parallel, so the next
query is usually already started.
Apply some special logic in `recv_done()` function to deal with the
described situation when handling the query result for the NS search
mode. Particularly, print a warning message for the failed query,
and do not try to start the next query in the list. Also, set a non-zero
exit code if all the queries in the followup lookup fail.
With the recent Coverity Scan 2021.12 version, Python 3 scripts are
being analyzed in addition to C files. The --fs-capture-search option
scripts for Coverity Scan analysis should be added to leverage this
feature.
Downloading and unpacking Coverity Scan analysis tool tarball
(cov-analysis-linux64.tgz) to $CI_PROJECT_DIR interferes with the
execution of the analysis tool when the --fs-capture-search option is
used because the tool starts to analyze some of its Javascript files.
(There's the --fs-capture-search-exclude-regex <path> option, but I
failed to find a way to make it work.)
The coverity CI job cache feature is used to ensure that the 1 GB
cov-analysis-linux64.tgz file is being cached on GitLab CI runner, where
it was downloaded in the past. This feature does not seem to work
anymore; given that the proper solution to creating distributed cache is
complicated, better to drop the feature altogether.
The only values that the isc_quota_attach() function (called from
check_recursionquota() via recursionquotatype_attach_soft()) can
currently return are: ISC_R_SUCCESS, ISC_R_SOFTQUOTA, and ISC_R_QUOTA.
Instead of just propagating any other (unexpected) error up the call
stack, assert immediately, so that if the isc_quota_* API gets updated
in the future to return values currently matching the "default"
statement, check_recursionquota() can be promptly updated to handle such
new return values as desired.
Previously, multiple code paths reused client->query.fetch, so it was
enough for ns_query_cancel() to issue a single call to
dns_resolver_cancelfetch() with that fetch as an argument. Now, since
each slot in the 'recursions' array can hold a reference to a separate
resolver fetch, ns_query_cancel() needs to handle all of them, so that
all recursion callbacks get a chance to clean up the associated
resources when a query is canceled.
Both prefetch code and RPZ code ignore recursion results (caching the
response notwithstanding). RPZ code has been (ab)using that fact since
commit 08e36aa5a5 by employing
prefetch_done() as the fetch completion callback. This is only
seemingly a simplification as it makes the code harder to follow ("why
is prefetch code used for handling RPZ-triggered recursion?").
Turn prefetch_done() into a new function whose name clearly conveys its
purpose. Add a parameter to its prototype in order to allow callers to
specify which slot in the 'recursions' array it should use. Reintroduce
prefetch_done() as a wrapper for that function. Add rpzfetch_done(), an
RPZ-exclusive wrapper for that function (using a distinct recursion
type).
Since each slot in the 'recursions' array needs to be initialized before
getting cleaned up when recursion completes, rework fetch_and_forget()
so that it takes recursion type rather than extra fetch options as the
last parameter and make it use the requested slot in the 'recursions'
array rather than a fixed slot (RECTYPE_PREFETCH) for all callers. This
makes fetch_and_forget() a logical complement of cleanup_after_fetch().
Collectively, these changes make prefetch and RPZ code logically
separate (except for reusing client->recursionquota, which will be
refactored later).
Add a set of new helper functions for attaching to the recursion quota
in order to reduce code duplication and to ensure that the recursive
clients counter is always adjusted properly. Since some callers
(query_prefetch(), query_rpzfetch()) treat exceeding the soft quota as
an error while others (check_recursionquota()) do not, also add two
wrapper functions whose names help convey their purpose, in order to
improve code readability.
When the client->recursionquota pointer was overloaded by different
features, each of those features had to be aware of that fact and handle
any updates of that pointer gracefully. Example: prefetch code
initiates recursion, attaching to client->recursionquota, then query
processing restarts due to a CNAME being encountered, then that CNAME is
not found in the cache, so another recursion is triggered, but
client->recursionquota is already attached to; even though it is not
CNAME chaining code that attached to that pointer, that code still has
to handle such a situation gracefully.
However, all features that can initiate recursion have now been updated
to use separate slots in the 'recursions' array, so keeping the old
checks in place means masking future programming errors that could
otherwise be caught - and should be caught because each feature needs to
properly maintain its own quota reference.
Remove outdated recursion quota pointer checks to enable the assertions
in isc_quota_*() functions to detect programming errors in code paths
that can start recursion. Remove an outdated comment to prevent
confusion.
Drop the 'fetchhandle' field from ns_client_t as all code using it has
been migrated to use the recursion-type-specific HANDLE_RECTYPE_*()
macros.
Drop the 'fetch' field from ns_query_t as all code using it has been
migrated to use the recursion-type-specific FETCH_RECTYPE_*() macros.
Replace:
- client->prefetchhandle with HANDLE_RECTYPE_PREFETCH(client)
- client->query.prefetch with FETCH_RECTYPE_PREFETCH(client)
This is preparatory work for separating prefetch code from RPZ code.
Add a new helper function for detaching from the recursion quota in
order to reduce code duplication and to ensure that detaching from that
quota is always accompanied by decreasing the recursive clients counter.
Reduce code duplication in check_recursionquota() by extracting its
parts responsible for logging to a separate helper function.
Remove result text from the "no more recursive clients" message because
it always says "quota reached" (as the relevant branch is only evaluated
when 'result' is set to ISC_R_QUOTA) and therefore brings no additional
value.
ns_client_endrequest() currently contains code that looks for
outstanding quota references and cleans them up if necessary. This
approach masks programming errors because ns_client_endrequest() is only
called from ns__client_reset_cb(), which in turn is only called when all
references to the client's netmgr handle are released, which in turn
only happens after all recursion completion callbacks are invoked
(because isc_nmhandle_attach() is called before every call to
dns_resolver_createfetch() in lib/ns/query.c and the completion callback
is expected to detach from the handle), which in turn is expected to
happen for all recursions attempts, even those that get canceled.
Furthermore, declaring the prototype of ns_client_endrequest() at the
top of lib/ns/client.c is redundant because the definition of that
function is placed before its first use in that file. Remove the
redundant function prototype.
Finally, remove INSIST assertions ensuring quota pointers are NULL in
ns__client_reset_cb() because the latter calls ns_client_endrequest() a
few lines earlier.
Async hooks are the last feature using the client->fetchhandle and
client->query.fetch pointers. Update ns_query_hookasync() and
query_hookresume() so that they use a dedicated slot in the 'recursions'
array. Note that async hooks are still not expected to initiate
recursion if one was already started by a prior ns_query_recurse() call,
so the REQUIRE assertion in ns_query_hookasync() needs to check the
RECTYPE_NORMAL slot rather than the RECTYPE_HOOK one.
When a client waits for a prefetch- or RPZ-triggered recursion to
complete, its netmgr handle is attached to client->prefetchhandle and a
reference to the resolver fetch is stored in client->query.prefetch.
Both of these features use the same fields mentioned above. This makes
the code fragile and hard to follow as its logically distinct parts
become intertwined for no obvious reason.
Furthermore, storing pointers related to a specific recursion process in
two different structures makes their purpose harder to grasp than it has
to be.
To alleviate the problem, extend ns_query_t with an array of structures
containing recursion-related pointers. Each feature able to initiate
recursion is supposed to use its own slot in that array, allowing
logically unrelated code paths to be untangled. Prefetch and RPZ will
be the first users of that array.
Define helper macros for accessing specific recursion-related pointers
in order to improve code readability.
Some functions fail to detach from the recursion quota if an error
occurs while initiating recursion. This causes the recursive client
counter to be off. Add missing recursionquota_detach() calls, reworking
cleanup code where appropriate.
With prefetch and RPZ code updated to use separate slots in the
'recursions' array, the code responsible for starting recursion in
ns_query_recurse() and resuming query handling in fetch_callback()
should follow suit, so that it does not need to explicitly cooperate
with other code paths that may initiate recursion.
Replace:
- client->fetchhandle with HANDLE_RECTYPE_NORMAL(client)
- client->query.fetch with FETCH_RECTYPE_NORMAL(client)
Also update other functions using client->fetchhandle and
client->query.fetch (ns_query_cancel(), query_usestale()) so that those
two fields can shortly be dropped altogether.
Initialize client->query using a compound literal in order to make the
ns_query_init() function shorter and more readable. This also prevents
the need to explicitly initialize any newly added fields in the future.
Similarly to how different code paths reused common client handle
pointers and fetch references despite being logically unrelated, they
also reuse client->recursionquota, the field in which a reference to the
recursion quota is stored. This unnecessarily forces all code using
that field to be aware of the fact that it is overloaded by different
features.
Overloading client->recursionquota also causes inconsistent behavior.
For example, if prefetch code triggers recursion and then delegation
handling code also triggers recursion, only one of these code paths will
be able to attach to the recursion quota, but both recursions will be
started anyway. In other words, each code path only checks whether the
recursion quota has not been exceeded if the quota has not yet been
attached to by another code path. This behavior theoretically allows
the configured recursion quota to be slightly exceeded; while it is not
expected to be a real-world operational issue, it is still confusing and
should therefore be fixed.
Extend the structures comprising the 'recursions' array with a new field
holding a pointer to the recursion quota that a given recursion process
attached to. Update all code paths using client->recursionquota so that
they use the appropriate slot in the 'recursions' array. Drop the
'recursionquota' field from ns_client_t.
query_prefetch() and query_rpzfetch() contain a lot of duplicated code.
Extract the common bits into a separate function whose name clearly
suggests its purpose.
Under specific rare timing circumstances the uv_read_start() could
fail with UV_EINVAL when the connection is reset between the connect (or
accept) and the uv_read_start() call on the nmworker loop. Handle such
situation gracefully by propagating the errors from uv_read_start() into
upper layers, so the socket can be internally closed().
The statistics system test fails on Oracle Linux 7 when libxml2, Curl,
and xsltproc are present:
I:statistics:checking bind9.xsl vs xml (17)
diff: curl.out.17.xsl: No such file or directory
tests.sh: line 183: curl.out.17.xml: No such file or directory
cp: cannot stat 'curl.out.17.xml': No such file or directory
grep: xsltproc.out.17: No such file or directory
This is because the Oracle Linux 7 Curl does not know about the
--http1.1 option and silently fails with:
+ /usr/bin/curl --http1.1 http://10.53.0.3:7252
curl: option --http1.1: is unknown
curl: try 'curl --help' or 'curl --manual' for more information
The following test "checking bind9.xml socket statistics" then needs to
check for existence of stats.xml.out file which is artifact of the
previous test.
when serve-stale is enabled, NXDOMAIN cache entries are no longer
preserved after the normal negative cache TTL, in order to reduce
unnecessary cache memory consumption.
Commit 9ffb4a7ba1 causes Clang Static
Analyzer to flag a potential NULL dereference in query_nxdomain():
query.c:9394:26: warning: Dereference of null pointer [core.NullDereference]
if (!qctx->nxrewrite || qctx->rpz_st->m.rpz->addsoa) {
^~~~~~~~~~~~~~~~~~~
1 warning generated.
The warning above is for qctx->rpz_st potentially being a NULL pointer
when query_nxdomain() is called from query_resume(). This is a false
positive because none of the database lookup result codes currently
causing query_nxdomain() to be called (DNS_R_EMPTYWILD, DNS_R_NXDOMAIN)
can be returned by a database lookup following a recursive resolution
attempt. Add a NULL check nevertheless in order to future-proof the
code and silence Clang Static Analyzer.
ns_client_getnamebuf() cannot fail (i.e. return NULL) since commit
e31cc1eeb4. Remove redundant NULL checks
performed on the pointer returned by ns_client_getnamebuf().
ns_client_newname() cannot fail (i.e. return NULL) since commit
2ce0de6995 (though it was only made more
apparent by commit 33ba0057a7). Remove
redundant NULL checks performed on the pointer returned by
ns_client_newname().
ns_client_newrdataset() cannot fail (i.e. return NULL) since commit
efb385ecdc (though it was only made more
apparent by commit 33ba0057a7). Remove
redundant NULL checks performed on the pointer returned by
ns_client_newrdataset().
It turns out it is easier to regenerate Sphinx-mandated structure in
get_objects than to maintain two separate data structures. I should have
realized that before.
New directive .. statementlist:: generates table of statements in a
the given domain (named.conf or rndc.conf). The table contains link to
definition, short description, and also list of tags.
Short description and tags have to be provided by user using optional
parameters. E.g.:
.. statement:: max-cache-size
:tags: resolver, cache
:short: Short description
.. statementlist:: is currently not parametrized.
This modification is based on Sphinx "tutorial" extension "TODO".
The main trick is to use placeholder node for .. statementlist:: and
replace it with table at later stage, when all source files were
processed and all cross-references can be resolved.
Beware, some details in Sphinx docs are not up-to-date, it's better
to read Sphinx and docutil sources.
New and currently unused values can be provided using this syntax:
.. statement:: max-cache-size
:tags: resolver, cache
:short: Short description
The domain stores them in its internal structures for further use.
The extension provides a "Sphinx domain factory". Each new Sphinx domain
defines a namespace for configuration statements so named.conf and
rndc.conf do not clash. Currently the Sphinx domains are instantiated
twice and resuling domains are named "namedconf" and "rndcconf".
This commit adds a single new directive:
.. statement:: max-cache-size
It is namespaced like this:
.. namedconf:statement:: max-cache-size
This directive generates a new anchor for configuration statement and it
can be referenced like :any:`max-cache-size` (if the identifier is
unique), or more specific :namedconf:ref:`max-cache-size`.
It is based on Sphinx "tutorial" extension "recipe".
Beware, some details in Sphinx docs are not up-to-date, it's better
to read Sphinx and docutil sources.
The conversion of `DNS_R_PARTIALMATCH` into `DNS_R_NOTFOUND` is done
in the `dns_rbt_deletename()` function so there is no need to do that
in `dns_fwdtable_delete()`.
Add a possible return value of `ISC_R_NOSPACE` into the header file's
function description comment.
There is no reason for these two messages to be `ISC_LOG_INFO` while all
the other similar messages in `catz_addmodzone_taskaction()` and
`catz_delzone_taskaction()` functions are logged as `ISC_LOG_WARNING`.
When processing a catalog zone member zone make sure that there is no
configured pre-existing forward zone with that name.
Refactor the `dns_fwdtable_find()` function to not alter the
`DNS_R_PARTIALMATCH` result (coming from `dns_rbt_findname()`) into
`DNS_R_SUCCESS`, so that now the caller can differentiate partial
and exact matches. Patch the calling sites to expect and process
the new return value.
Historically, some *.py files were generated, so Python checks required
running ./configure beforehand. This is no longer the case since v9_18,
so let's run the job ASAP without the unnecessary extra dependency on
autoconf job.
Python codestyle is now handled by black and other issues are checked by
pylint. Flake8 checking has been made redundant and is thus removed as
obsolete.
Fix an issue reported by Coverity by removing the unneded check.
*** CID 352554: Null pointer dereferences (REVERSE_INULL)
/bin/dig/dighost.c: 3056 in start_tcp()
3050
3051 if (ISC_LINK_LINKED(query, link)) {
3052 next = ISC_LIST_NEXT(query, link);
3053 } else {
3054 next = NULL;
3055 }
>>> CID 352554: Null pointer dereferences (REVERSE_INULL)
>>> Null-checking "connectquery" suggests that it may be null, but it
has already been dereferenced on all paths leading to the check.
3056 if (connectquery != NULL) {
3057 query_detach(&connectquery);
3058 }
3059 query_detach(&query);
3060 if (next == NULL) {
3061 clear_current_lookup();
In the cases where we test SOA serial updates and TTL updates, we check
if for "all zones loaded" to ensure the new zone content is loaded. But
this is the unsigned zone, the signed zone still needs to be produced.
There is thus a timing issue where the dig request comes in before
the signing process has finished.
Add a retry quiet to mitigate against it.
Messages with log levels INFO or higher are flagged for manual review.
Purpose of this check is to prevent debug logs to being released with
too-high log level.
- [ ]***(QA)*** Merge published release tags (non-linearly) back into the their relevant development/maintenance branches.
- [ ]***(QA)*** Sanitize confidential issues which are assigned to the current release milestone and do not describe a security vulnerability, then make them public.
- [ ]***(QA)*** Sanitize confidential issues which are assigned to older release milestones and describe security vulnerabilities, then make them public if appropriate[^2].
- [ ]***(QA)*** Update QA tools used in GitLab CI (e.g. Flake8, PyLint) by modifying the relevant `Dockerfile`.
- [ ]***(QA)*** Update QA tools used in GitLab CI (e.g. Black, PyLint) by modifying the relevant `Dockerfile`.
[^1]: If not, use the time remaining until the tagging deadline to ensure all outstanding issues are either resolved or moved to a different milestone.
[^2]: As a rule of thumb, security vulnerabilities which have reproducers merged to the public repository are considered okay for full disclosure.
| `-DOPENSSL_API_COMPAT=10100` | Build using the deprecated OpenSSL APIs so that the `engine` API is available when building with OpenSSL 3.0.0 for PKCS#11 support |
(-) can be used to indicate that no salt is to be used when
generating the NSEC3 chain.
..note::
``-3 -`` is the recommended configuration. Adding salt provides no practical benefits.
..option:: -H iterations
This option indicates that, when generating an NSEC3 chain, BIND 9 should use this many iterations. The default
is 10.
is 0.
..warning::
Values greater than 0 cause interoperability issues and also increase the risk of CPU-exhausting DoS attacks.
..option:: -A
This option indicates that, when generating an NSEC3 chain, BIND 9 should set the OPTOUT flag on all NSEC3
records and should not generate NSEC3 records for insecure delegations.
..warning::
Do not use this option unless all its implications are fully understood. This option is intended only for extremely large zones (comparable to ``com.``) with sparse secure delegations.
HMAC-SHA256 (default), HMAC-SHA384, and HMAC-SHA512. They use a shared
secret on each end of the connection, which provides TSIG-style
authentication for the command request and the name server's response.
All commands sent over the channel must be signed by a key_id known to
All commands sent over the channel must be signed by a server_key known to
the server.
:program:`rndc` reads a configuration file to determine how to contact the name
@@ -101,10 +101,10 @@ Options
This option enables verbose logging.
..option:: -y key_id
..option:: -y server_key
This option indicates use of the key ``key_id`` from the configuration file. For control message validation to succeed, ``key_id`` must be known
by :iscman:`named` with the same algorithm and secret string. If no ``key_id`` is specified,
This option indicates use of the key ``server_key`` from the configuration file. For control message validation to succeed, ``server_key`` must be known
by :iscman:`named` with the same algorithm and secret string. If no ``server_key`` is specified,
:program:`rndc` first looks for a key clause in the server statement of
the server being used, or if no server statement is present for that
host, then in the default-key clause of the options statement. Note that
@@ -204,6 +204,13 @@ Currently supported commands are:
(See the ``dump-file`` option in the BIND 9 Administrator Reference
Manual.)
..option:: fetchlimit [view]
This command dumps a list of servers that are currently being
rate-limited as a result of ``fetches-per-server`` settings, and
a list of domain names that are currently being rate-limited as
a result of ``fetches-per-zone`` settings.
..option:: flush
This command flushes the server's cache.
@@ -523,15 +530,17 @@ Currently supported commands are:
depending on whether the opt-out bit in the NSEC3
chain should be set. ``iterations`` defines the number of additional times to apply
the algorithm when generating an NSEC3 hash. The ``salt`` is a string
of data expressed in hexadecimal, a hyphen (`-') if no salt is to be
of data expressed in hexadecimal, a hyphen (``-``) if no salt is to be
used, or the keyword ``auto``, which causes :iscman:`named` to generate a
random 64-bit salt.
So, for example, to create an NSEC3 chain using the SHA-1 hash
algorithm, no opt-out flag, 10 iterations, and a salt value of
"FFFF", use: ``rndc signing -nsec3param 1 0 10 FFFF zone``. To set
the opt-out flag, 15 iterations, and no salt, use:
``rndc signing -nsec3param 1 1 15 - zone``.
The only recommended configuration is ``rndc signing -nsec3param 1 0 0 - zone``,
i.e. no salt, no additional iterations, no opt-out.
..warning::
Do not use extra iterations, salt, or opt-out unless all their implications
are fully understood. A higher number of iterations causes interoperability
problems and opens servers to CPU-exhausting DoS attacks.
``rndc signing -nsec3param none`` removes an existing NSEC3 chain and
replaces it with NSEC.
@@ -648,7 +657,7 @@ would specify a zone called "-redirect".)
Limitations
~~~~~~~~~~~
There is currently no way to provide the shared secret for a ``key_id``
There is currently no way to provide the shared secret for a ``server_key``
[$nrecords -eq 1]||{ret=1; echo_i "found $nrecords records expected 1";}
if[$ret !=0];then echo_i "failed";fi
status=`expr $status + $ret`
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.