669 Commits

Author SHA1 Message Date
Ondřej Surý
fa7b7973e3 Limit the additional processing for large RDATA sets
When answering queries, don't add data to the additional section if
the answer has more than 13 names in the RDATA.  This limits the
number of lookups into the database(s) during a single client query,
reducing query processing load.

Also, don't append any additional data to type=ANY queries. The
answer to ANY is already big enough.

(cherry picked from commit a1982cf1bb)
2025-01-15 14:13:45 +01:00
Matthijs Mekking
a0ce89bc15 Implement global limit for outgoing queries
This global limit is not reset on query restarts and is a hard limit
for any client request.

Note: This commit has been significantly modified because of many
merge conflicts due to the dns_resolver_createfetch api changes.

(cherry picked from commit 16b3bd1cc7)
2024-12-06 15:17:53 +00:00
Mark Andrews
01f5ad3b1d Keep a local copy of the update rules to prevent UAF
Previously, the update policy rules check was moved earlier in the
sequence, and the keep rule match pointers were kept to maintain the
ability to verify maximum records by type.

However, these pointers can become invalid if server reloading
or reconfiguration occurs before update completion. To prevent
this issue, extract the maximum records by type value immediately
during processing and only keep the copy of the values instead of the
full ssurule.

(cherry picked from commit 44a54a29d8)
2024-12-05 15:45:34 +11:00
Aram Sargsyan
b91b7093f2 Fix error path bugs in the "recursing-clients" list management
In two places, after linking the client to the manager's
"recursing-clients" list using the check_recursionquota()
function, the query.c module fails to unlink it on error
paths. Fix the bugs by unlinking the client from the list.

Also make sure that unlinking happens before detaching the
client's handle, as it is the logically correct order, e.g.
in case if it's the last handle and ns__client_reset_cb()
can be called because of the detachment.

(cherry picked from commit 36c4808903)
2024-11-26 12:40:04 +00:00
Mark Andrews
2f26d2fde7 Re-split format strings
Re-split format strings that had been poorly split by multiple
clang-format runs using different versions of clang-format.

(cherry picked from commit a24d6e1654)
2024-11-21 04:22:15 +00:00
Ondřej Surý
b3d8f2796a Remove redundant semicolons after the closing braces of functions
(cherry picked from commit 1a19ce39db)
2024-11-19 16:06:49 +01:00
Ondřej Surý
c5bac96fd0 Remove redundant parentheses from the return statement
(cherry picked from commit 0258850f20)
2024-11-19 16:06:16 +01:00
Matthijs Mekking
ff53fd3951 Revert "Use a binary search to find the NSEC3 closest encloser"
This reverts commit 94f6655915.
2024-11-15 13:14:30 +00:00
Mark Andrews
94f6655915 Use a binary search to find the NSEC3 closest encloser
maxlabels is the suffix length that corresponds to the latest
NXDOMAIN response.  minlabels is the suffix length that corresponds
to longest found existing name.

(cherry picked from commit 67f31c5046)
2024-10-14 23:55:13 +00:00
Matthijs Mekking
60bd3bc051 Revert "fix: chg: Improve performance when looking for the closest encloser"
The 9.18 code does not have the rbtdb refactoring. Rather than
backporting from MR !9611, this reverts directly from commit
5d81a258e3.
2024-10-10 14:26:13 +02:00
Mark Andrews
5d81a258e3 Return partial match when requested
Return partial match from dns_db_find/dns_db_find when requested
to short circuit the closest encloser discover process.  Most of the
time this will be the actual closest encloser but may not be when
there yet to be committed / cleaned up versions of the zone with
names below the actual closest encloser.

(cherry picked from commit d42ea08f16)
2024-08-29 21:05:54 +00:00
Aram Sargsyan
30238a6172 Process also the ISC_R_CANCELED result code in rpz_rewrite()
Log  canceled queries (e.g. when shutting down a hung fetch)
in DEBUG3 level instead of DEBUG1 which is used for the
"unrecognized" result codes.

(cherry picked from commit 8bb9568467)
2024-08-19 11:45:44 +00:00
Evan Hunt
bfbc6a6c84 make "max_restarts" a configurable value
MAX_RESTARTS is no longer hard-coded; ns_server_setmaxrestarts()
and dns_client_setmaxrestarts() can now be used to modify the
max-restarts value at runtime. in both cases, the default is 11.

(cherry picked from commit c5588babaf)
2024-08-07 15:36:15 -07:00
Evan Hunt
dd88a4cdfc reduce MAX_RESTARTS to 11
the number of steps that can be followed in a CNAME chain
before terminating the lookup has been reduced from 16 to 11.
(this is a hard-coded value, but will be made configurable later.)

(cherry picked from commit 05d78671bb)
2024-08-07 15:36:14 -07:00
Aram Sargsyan
946931ccb7 Return SERVFAIL for a too long CNAME chain
Due to the maximum query restart limitation a long CNAME chain
it is cut after 16 queries but named still returns NOERROR.

Return SERVFAIL instead and the partial answer.

(cherry picked from commit b621f1d88e)
2024-07-31 15:14:43 +00:00
Ondřej Surý
e31190e704 Reset the TCP connection on a failed send
When sending fails, the ns__client_request() would not reset the
connection and continue as nothing is happening.  This comes from the
model that we don't care about failed UDP sends because datagrams are
unreliable anyway, but it greatly affects TCP connections with
keep-alive.

The worst case scenario is as follows:

1. the 3-way TCP handshake gets completed
2. the libuv calls the "uv_connection_cb" callback
3. the TCP connection gets queue because of the tcp-clients quota
4. the TCP client sends as many DNS messages as the buffers allow
5. the TCP connection gets dropped by the client due to the timeout
6. the TCP connection gets accepted by the server
7. the data already sent by the client gets read
8. all sending fails immediately because the TCP connection is dead
9. we consume all the data in the buffer in a very tight loop

As it doesn't make sense to trying to process more data on the TCP
connection when the sending is failing, drop the connection immediately
on the first sending error.

(cherry picked from commit bf9fd2a6ff)
2024-07-03 09:10:30 +02:00
Mark Andrews
9cfd20cd90 Clear qctx->zversion
Clear qctx->zversion when clearing qctx->zrdataset et al in
lib/ns/query.c:qctx_freedata.  The uncleared pointer could lead to
an assertion failure if zone data needed to be re-saved which could
happen with stale data support enabled.

(cherry picked from commit 179fb3532ab8d4898ab070b2db54c0ce872ef709)
2024-06-10 19:20:06 +02:00
Petr Špaček
bef3d2cca3 Remove support for SIG(0) message verification 2024-06-10 19:02:49 +02:00
Matthijs Mekking
7bb36ae56e Log error when update fails
The new "too many records" error can make an update fail without the
error being logged. This commit fixes that.

(cherry picked from commit 558923e5405894cf976d102f0d246a28bdbb400c)
2024-06-10 18:51:28 +02:00
Ondřej Surý
0b1d70ed2a Remove the extra memory context with own arena for sending
(cherry picked from commit 8d4cc41c291f8a77a723ae8e62533538b3632d50)
2024-06-10 18:43:46 +02:00
Ondřej Surý
3f6b7f57a6 Replace the tcp_buffers memory pool with static per-loop buffer
As a single thread can process only one TCP send at the time, we don't
really need a memory pool for the TCP buffers, but it's enough to have
a single per-loop (client manager) static buffer that's being used to
assemble the DNS message and then it gets copied into own sending
buffer.

In the future, this should get optimized by exposing the uv_try API
from the network manager, and first try to send the message directly
and allocate the sending buffer only if we need to send the data
asynchronously.

(cherry picked from commit 297cc840fbaf34b9dfa1d02d88a023cd5bf5dc4a)
2024-06-10 18:43:46 +02:00
Aram Sargsyan
4e70342142 ns_client: reuse TCP send buffers
Constantly allocating, reallocating and deallocating 64K TCP send
buffers by 'ns_client' instances takes too much CPU time.

There is an existing mechanism to reuse the ns_clent_t structure
associated with the handle using 'isc_nmhandle_getdata/_setdata'
(see ns_client_request()), but it doesn't work with TCP, because
every time ns_client_request() is called it gets a new handle even
for the same TCP connection, see the comments in
streamdns_on_complete_dnsmessage().

To solve the problem, we introduce an array of available (unused)
TCP buffers stored in ns_clientmgr_t structure so that a 'client'
working via TCP can have a chance to reuse one (if there is one)
instead of allocating a new one every time.
2024-06-10 18:43:45 +02:00
Matthijs Mekking
4ef23ad0ff RPZ response's SOA record is incorrectly set to 1
An RPZ response's SOA record TTL is set to 1 instead of the SOA TTL,
a boolean value is passed on to query_addsoa, which is supposed to be
a TTL value. I don't see what value is appropriate to be used for
overriding, so we will pass UINT32_MAX.

(cherry picked from commit 5d7e613e81)
2024-05-06 12:18:08 +02:00
Mark Andrews
7498db6366 Don't use static stub when returning best NS
If we find a static stub zone in query_addbestns look for a parent
zone which isn't a static stub.

(cherry picked from commit 40816e4e35)
2024-03-14 15:33:25 +11:00
Michał Kępień
4ad3c694f1 Merge tag 'v9.18.24' into bind-9.18
BIND 9.18.24
2024-02-14 13:35:19 +01:00
Aram Sargsyan
cbc0357881 Improve the definition of the DNS_GETDB_* flags
Use the (1 << N) form for defining the flags, in order to avoid
errors like the one fixed in the previous commit.

Also convert the definitions to an enum, as done in some of our
recent refactoring work.

(cherry picked from commit 0d7c7777da)
2024-02-02 15:06:48 +00:00
Aram Sargsyan
2bcd6c2fd3 Fix the DNS_GETDB_STALEFIRST flag
The DNS_GETDB_STALEFIRST flag is defined as 0x0C, which is the
combination of the DNS_GETDB_PARTIAL (0x04) and the
DNS_GETDB_IGNOREACL (0x08) flags (0x04 | 0x08 == 0x0C) , which is
an obvious error.

All the flags should be power of two, so they don't interfere with
each other. Fix the DNS_GETDB_STALEFIRST flag by setting it to 0x10.

(cherry picked from commit be7d8fafe2)
2024-02-02 15:06:43 +00:00
Artem Boldariev
cff69c65b5 Fix flawed logic when detecting same listener type
The older version of the code was reporting that listeners are going
to be of the same type after reconfiguration when switching from DoT
to HTTPS listener, making BIND abort its executions.

That was happening due to the flaw in logic due to which the code
could consider a current listener and a configuration for the new one
to be of the same type (DoT) even when the new listener entry is
explicitly marked as HTTP.

The checks for PROXY in between the configuration were masking that
behaviour, but when porting it to 9.18 (when there is no PROXY
support), the behaviour was exposed.

Now the code mirrors the logic in 'interface_setup()' closely (as it
was meant to).

(cherry picked from commit 8ae661048d)
2024-01-15 14:31:06 +02:00
Artem Boldariev
2be0acf3f3 Recreate listeners on DNS transport change
This commit ensures that listeners are recreated on reconfiguration in
the case when their type changes (or when PROXY protocol type changes,
too).

Previously, if a "listen-on" statement was modified to represent a
different transport, BIND would not pick-up the change on
reconfiguration if listener type changes (e.g. DoH -> DoT) for a given
interface address and port combination. This commit fixes that by
recreating the listener.

Initially, that worked for most of the new transports as we would
recreate listeners on each reconfiguration for DoH and DoT. But at
some point we changed that in such a way that listeners were not
recreated to avoid rebinding a port as on some platforms only root can
do that for port numbers <1000, making some ports binding possible
only on start-up. We chose to asynchronously update listener socket
settings (like TLS contexts, HTTP settings) instead.

Now, we both avoid recreating the sockets if unnecessary and recreate
listeners when listener type changes.

(cherry picked from commit d59cf5e0ce)
2024-01-15 14:31:06 +02:00
Mark Andrews
9999eebbf7 Report the type being filtered from an UPDATE
When processing UPDATE request DNSKEY, CDNSKEY and CDS record that
are managed by named are filtered out.  The log message has been
updated to report the actual type rather that just DNSKEY.

(cherry picked from commit 2cf6cf967d)
2024-01-13 01:58:57 +11:00
Mark Andrews
4efcfa8f1c Apply filters to CDS and CDNSKEY records 2024-01-12 19:56:54 +11:00
Matthijs Mekking
0d36d98791 Add new dns_rdatatype_iskeymaterial() function
The following code block repeats quite often:

    if (rdata.type == dns_rdatatype_dnskey ||
        rdata.type == dns_rdatatype_cdnskey ||
        rdata.type == dns_rdatatype_cds)

Introduce a new function to reduce the repetition.

(cherry picked from commit ef58f2444f)
2024-01-12 19:56:54 +11:00
Mark Andrews
f7e137f321 Restore dns64 state during serve-stale processing
If we are in the process of looking for the A records as part of
dns64 processing and the server-stale timeout triggers, redo the
dns64 changes that had been made to the orignal qctx.

(cherry picked from commit 1fcc483df1)
2024-01-05 12:20:25 +01:00
Mark Andrews
b42b1fe051 Save the correct result value to resume with nxdomain-redirect
The wrong result value was being saved for resumption with
nxdomain-redirect when performing the fetch.  This lead to an assert
when checking that RFC 1918 reverse queries where not leaking to
the global internet.

(cherry picked from commit 9d0fa07c5e)
2024-01-05 12:03:59 +01:00
Mark Andrews
617f73426d Adjust comment to have correct message limit value
(cherry picked from commit 560c245971)
2023-11-16 12:22:08 +11:00
Ondřej Surý
6a85e79c0b Reformat sources with up-to-date clang-format-17 2023-11-13 17:13:07 +01:00
Matthijs Mekking
76c9019403 Don't ignore auth zones when in serve-stale mode
When serve-stale is enabled and recursive resolution fails, the fallback
to lookup stale data always happens in the cache database. Any
authoritative data is ignored, and only information learned through
recursive resolution is examined.

If there is data in the cache that could lead to an answer, and this can
be just the root delegation, the resolver will iterate further, getting
closer to the answer that can be found by recursing down the root, and
eventually puts the final response in the cache.

Change the fallback to serve-stale to use 'query_getdb()', that finds
out the best matching database for the given query.

(cherry picked from commit 2322425016)
2023-10-31 13:52:08 +01:00
Michal Nowak
7c6632e174 Update the source code formatting using clang-format-17 2023-10-18 09:02:57 +02:00
Aram Sargsyan
c061b90cc6 Remove unnecessary NULL-checks in ns__client_setup()
All these pointers are guaranteed to be non-NULL.

Additionally, update a comment to remove obviously outdated
information about the function's requirements.

(cherry picked from commit b970556f21)
2023-10-02 10:04:56 +00:00
Aram Sargsyan
2a57c12922 Remove an unnecessary NULL-check
In the ns__client_put_cb() callback function the 'client->manager'
pointer is guaranteed to be non-NULL, because in ns__client_request(),
before setting up the callback, the ns__client_setup() function is
called for the 'client', which makes sure that 'client->manager' is set.

Removing the NULL-check resolves the following static analyzer warning:

    /lib/ns/client.c: 1675 in ns__client_put_cb()
    1669     		dns_message_puttemprdataset(client->message, &client->opt);
    1670     	}
    1671     	client_extendederror_reset(client);
    1672
    1673     	dns_message_detach(&client->message);
    1674
    >>>     CID 465168:  Null pointer dereferences  (REVERSE_INULL)
    >>>     Null-checking "client->manager" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
    1675     	if (client->manager != NULL) {
    1676     		ns_clientmgr_detach(&client->manager);
    1677     	}
    1678
    1679     	/*
    1680     	 * Detaching the task must be done after unlinking from
2023-09-14 10:39:24 +00:00
Artem Boldariev
1cc17f797e Allocate DNS send buffers using dedicated per-worker memory arenas
This commit ensures that memory allocations related to DNS send
buffers are routed through dedicated per-worker memory arenas in order
to decrease memory usage on high load caused by TCP-based DNS
transports.

We do that by following jemalloc developers suggestions:

https://github.com/jemalloc/jemalloc/issues/2483#issuecomment-1639019699
https://github.com/jemalloc/jemalloc/issues/2483#issuecomment-1698173849
(cherry picked from commit 01cc7edcca)
2023-09-05 15:02:30 +02:00
Mark Andrews
58be5d8ed0 rr_exists should not error if the name does not exist
rr_exists errored if the name did not exist in the zone.  This was
not an issue prior to the addition of krb5-subdomain-self-rhs and
ms-subdomain-self-rhs as the only name used was the zone name which
always existed.

(cherry picked from commit b76a15977a)
2023-08-30 10:05:09 +10:00
Evan Hunt
07f6c63a80 prevent query_coveringnsec() from running twice
when synthesizing a new CNAME, we now check whether the target
matches the query already being processed. if so, we do not
restart the query; this prevents a waste of resources.

(cherry picked from commit 0ae8b2e056)
2023-08-21 14:31:10 -07:00
Mark Andrews
b3a97da7a7 Use NS rather than A records for qname-minimization relaxed
Remove all references to DNS_FETCHOPT_QMIN_USE_A and adjust
the expected tests results in the qmin system test.

(cherry picked from commit dd00b3c50b)
2023-06-28 12:31:49 +02:00
Matthijs Mekking
ff5bacf17c Fix serve-stale hang at shutdown
The 'refresh_rrset' variable is used to determine if we can detach from
the client. This can cause a hang on shutdown. To fix this, move setting
of the 'nodetach' variable up to where 'refresh_rrset' is set (in
query_lookup(), and thus not in ns_query_done()), and set it to false
when actually refreshing the RRset, so that when this lookup is
completed, the client will be detached.
2023-06-09 14:54:48 +02:00
Evan Hunt
240caa32b9 Stale answer lookups could loop when over recursion quota
When a query was aborted because of the recursion quota being exceeded,
but triggered a stale answer response and a stale data refresh query,
it could cause named to loop back where we are iterating and following
a delegation. Having no good answer in cache, we would fall back to
using serve-stale again, use the stale data, try to refresh the RRset,
and loop back again, without ever terminating until crashing due to
stack overflow.

This happens because in the functions 'query_notfound()' and
'query_delegation_recurse()', we check whether we can fall back to
serving stale data. We shouldn't do so if we are already refreshing
an RRset due to having prioritized stale data in cache.

In other words, we need to add an extra check to 'query_usestale()' to
disallow serving stale data if we are currently refreshing a stale
RRset.

As an additional mitigation to prevent looping, we now use the result
code ISC_R_ALREADYRUNNING rather than ISC_R_FAILURE when a recursion
loop is encountered, and we check for that condition in
'query_usestale()' as well.
2023-06-09 14:54:48 +02:00
Artem Boldariev
285e75b3b0 Use appropriately sized send buffers for DNS messages over TCP
This commit changes send buffers allocation strategy for stream based
transports. Before that change we would allocate a dynamic buffers
sized at 64Kb even when we do not need that much. That could lead to
high memory usage on server. Now we resize the send buffer to match
the size of the actual data, freeing the memory at the end of the
buffer for being reused later.

(cherry picked from commit d8a5feb556)
2023-06-06 14:04:01 +02:00
Matthijs Mekking
b90bad93cb Fix serve-stale bug when cache has no data
We recently fixed a bug where in some cases (when following an
expired CNAME for example), named could return SERVFAIL if the target
record is still valid (see isc-projects/bind9#3678, and
isc-projects/bind9!7096). We fixed this by considering non-stale
RRsets as well during the stale lookup.

However, this triggered a new bug because despite the answer from
cache not being stale, the lookup may be triggered by serve-stale.
If the answer from database is not stale, the fix in
isc-projects/bind9!7096 erroneously skips the serve-stale logic.

Add 'answer_found' checks to the serve-stale logic to fix this issue.

(cherry picked from commit bbd163acf6)
2023-05-30 13:46:00 +02:00
Aram Sargsyan
305bf677ab Implement new -T options for xfer system tests
'-T transferinsecs' makes named interpret the max-transfer-time-out,
max-transfer-idle-out, max-transfer-time-in and max-transfer-idle-in
configuration options as seconds instead of minutes.

'-T transferslowly' makes named to sleep for one second for every
xfrout message.

'-T transferstuck' makes named to sleep for one minute for every
xfrout message.

(cherry picked from commit dfaecfd752)
2023-04-21 17:21:32 +02:00
Evan Hunt
61692942b8 remove named_os_gethostname()
this function was just a front-end for gethostname(). it was
needed when we supported windows, which has a different function
for looking up the hostname; it's not needed any longer.

(cherry picked from commit 197334464e)
2023-02-18 12:27:19 -08:00