The statistics charts where not displaying on some browsers.
This has been fixed.
Closes#5990
Backport of MR !12018
Merge branch 'backport-5990-disable-output-escaping-in-bind9-xsl-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!12019
The statistics charts where not displaying on some browsers (e.g. Chrome)
due to '>' being escaped as '>'. Use disable-output-escaping="yes" to
turn this off.
(cherry picked from commit 9b6c018425)
'rndc dumpdb' against a server with zones, and async zone load,
had a timing window where the operation's completion could fire
before the server had finished registering the operation,
occasionally leading to a possible crash. The completion is now
delivered after the registration is in place.
Closes#5952
Backport of MR !11991
Merge branch 'backport-5952-fix-masterdump-async-ctx-race-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!12021
Bouncing the offload itself to the target loop let the after-work
callback fire on the target thread and run the user's done callback
before the calling thread had published *dctxp / *lctxp. Enqueue on
the calling loop and bounce only the done callback instead, so the
publish is sequenced before the cross-thread hand-off by construction
and cannot be reintroduced by reordering the entry-point body.
(cherry picked from commit 8ae464d552)
The global RUNNER_SCRIPT_TIMEOUT: 55m in the parent pipeline was being
forwarded to the stress and tsan:stress child pipelines, where forwarded
yaml variables outrank job-level variables. That caused stress jobs with
BIND_STRESS_TESTS_RUN_TIME >= 60 to be killed at 55 minutes, regardless
of the per-job RUNNER_SCRIPT_TIMEOUT set in the generated child config.
Set forward:yaml_variables: false on both trigger jobs; the generated
configs already declare every variable they need.
Assisted-by: Claude:claude-opus-4-7
Backport of MR !12012
Merge branch 'backport-mnowak/fix-stress-test-script-timeout-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!12015
The parent's global RUNNER_SCRIPT_TIMEOUT: 55m was reaching the stress
and tsan:stress child pipelines via inherited yaml variables, where
inherited values outrank the child's job-level variables. That caused
stress jobs with BIND_STRESS_TESTS_RUN_TIME >= 60 to be killed at 55
minutes, regardless of the per-job RUNNER_SCRIPT_TIMEOUT set in the
generated child config.
Use inherit:variables with a positive list on both trigger jobs:
inherit only CI_REGISTRY_IMAGE so the parent's registry override
(needed for image pulls in the child) flows through, while keeping
RUNNER_SCRIPT_TIMEOUT (and other globals) out of the child pipeline's
variable scope. The per-job RUNNER_SCRIPT_TIMEOUT values set by the
generated child config now take effect.
Assisted-by: Claude:claude-opus-4-7
(cherry picked from commit 73915b73d1)
Tell respdiff.sh where to find the respdiff Python tools (msgdiff.py,
diffsum.py, ...) so the in-tree copy from bind9-qa is used.
Assisted-by: Claude:claude-opus-4-7
(cherry picked from commit 4f410ee1e6)
Sometimes jobs can get stuck and be terminated by GitLab, leaving us
without artefacts that could contain useful information about why the
job got stuck.
Assisted-by: Claude:claude-opus-4-7
(cherry picked from commit e3d2f5ad94)
When a delegation response contained many glue addresses per listed
nameserver, all of them were cached without a per-nameserver bound,
inflating resolver cache memory beyond what resolution could ever use.
The cache now keeps at most 20 IPv4 and 20 IPv6 glue addresses per
nameserver from a delegation.
Closes#5701
Merge branch '5701-limit-the-number-of-GLUE-records-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11972
The resolver marked every NS RR's glue from a referral for caching with
no aggregate bound, so a parent server returning many NS RRs and many
glue addresses per NS could inflate cache memory long beyond what
resolution can ever use.
Truncate each glue rdataset to DELEG_MAX_GLUES_PER_NS (20) A and 20 AAAA
records before marking it for caching. The NS RRset itself is still
cached in full, bounded by max-records-per-type.
The CHECK_FOR_GLUE_IN_ANSWER macro defaulted to 0 and was never enabled
by the build system, leaving check_answer() and the answer-section glue
scan in rctx_referral() as dead code. Drop them so the surrounding
referral-cache path is easier to reason about.
The output of update_rpms.py is terse, making it difficult to verify its
actions. Add a commit link and "git show" output to the log of every CI
job running the update_rpms.py script in "build" mode to facilitate
double-checking its actions.
Backport of MR !11828
Merge branch 'backport-michal/add-commit-link-and-diff-to-rpm-build-job-logs-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11999
The output of update_rpms.py is terse, making it difficult to verify its
actions. Add a commit link and "git show" output to the log of every CI
job running the update_rpms.py script in "build" mode to facilitate
double-checking its actions.
(cherry picked from commit 6d51073f22)
Add a new helper function, `isctest.transfer.transfer_message()`, to
`bin/tests/system/isctest/transfer.py` that generates the log message
produced by `xfrin_log()` in `lib/dns/xfrin.c` for an incoming zone
transfer:
transfer of '<zone>/IN' from <source_ns>#<port>: <msg>
The explicit use of `port` matches current shell system usage.
Interface
---------
transfer_message(zone, source_ns, msg, port=None)
- zone - zone name without class (e.g. "example.com")
- source_ns - IP string, or None to wildcard the source address
- msg - the transfer-level message
(e.g. "Transfer status: success")
- port - integer source port, or None to wildcard the port number
When both source_ns and port are concrete values a plain str is returned
and `wait_for_line()` treats it as a literal substring match. Whenever
either is `None` a compiled `re.Pattern` is returned, with the unknown part
replaced by a constrained wildcard:
- source_ns=None, port=None -> from .*#[0-9]+:
- source_ns=None, port=53 -> from .*#53:
- source_ns="1.2.3.4", port=None -> from 1.2.3.4#[0-9]+:
- source_ns="1.2.3.4", port=N -> "from 1.2.3.4#N:" (plain str)
The port wildcard is [0-9]+ (not .*) because a port is always numeric.
Convert all hard-coded transfer log patterns in the Python system tests
to use transfer_message().
Notable cases:
- `mirror_root_zone`: source_ns=None (live internet, any root server),
port=53.
- `cipher_suites`: source_ns="10.53.0.1", port=None (each zone transfers
over a different TLS port).
- `test_under_signed_transfer`: parametrize gains a boolean xfrin_msg
flag to distinguish messages that go through xfrin_log() from
lower-level TSIG errors that do not.
Testing
-------
All system tests pass under `pytest -n auto`. The `mirror_root_zone`
live-internet test was also verified separately with
`CI_ENABLE_LIVE_INTERNET_TESTS=1`.
LLM usage
---------
This commit was produced in an interactive session with Claude Code
(Claude Sonnet 4.6), guided step by step by a human reviewer.
Closes#5735
Backport of MR !11796
Merge branch 'backport-5735-make-transfer-message-formatter-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11995
Add a new helper function, isctest.transfer.transfer_message(), to
bin/tests/system/isctest/transfer.py that generates the log message
produced by xfrin_log() in lib/dns/xfrin.c for an incoming zone
transfer:
transfer of '<zone>/IN' from <source_ns>#<port>: <msg>
The helper always returns a compiled re.Pattern. source_ns and port
each accept None to match any source address / port. msg accepts
either a plain str (regex-escaped automatically) or a compiled
re.Pattern (spliced into the regex as-is), so callers that need regex
syntax in the message part can pass Re(r"...") without having to
wrap the whole result.
source_ns is passed through re.escape() when provided, so dots in
IPv4 addresses (e.g. "10.53.0.1") match a literal dot rather than
any character.
Convert the existing call sites across the system tests to use the
new helper.
Co-Authored-By: Nicki Křížek <nicki@isc.org>
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-opus-4-7
(cherry picked from commit 27ee27d4e3)
Cloning tags with the default GIT_DEPTH of 1 prevents the milestone
assignment script from identifying any merge requests that are included
in a given release. Fix by increasing GIT_DEPTH to an arbitrary value
that is high enough for practical purposes.
The GIT_DEPTH CI variable defaults to 1 for all jobs through the
top-level "variables" key. Explicitly setting it to 1 in job
definitions is unnecessary and may cause confusion. Remove these
redundant assignments.
Backport of MR !11996
Merge branch 'backport-michal/fix-assign-milestones-job-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11997
The GIT_DEPTH CI variable defaults to 1 for all jobs through the
top-level "variables" key. Explicitly setting it to 1 in job
definitions is unnecessary and may cause confusion. Remove these
redundant assignments.
(cherry picked from commit 703ad9a6de)
Cloning tags with the default GIT_DEPTH of 1 prevents the milestone
assignment script from identifying any merge requests that are included
in a given release. Fix by increasing GIT_DEPTH to an arbitrary value
that is high enough for practical purposes.
(cherry picked from commit bac4a57759)
The "publish-cleanup" tag pipeline job is currently created for all
security releases, including BIND -S releases, but it depends on the
"publish" job, which is only created for open source releases. This
breaks CI configuration for BIND -S tags, preventing pipelines from
getting created for such tags altogether. Fix by only creating the
"publish-cleanup" job in tag pipelines for open source security
releases.
Backport of MR !11992
Merge branch 'backport-michal/fix-triggering-rules-for-the-publish-cleanup-job-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11993
The "publish-cleanup" tag pipeline job is currently created for all
security releases, including BIND -S releases, but it depends on the
"publish" job, which is only created for open source releases. This
breaks CI configuration for BIND -S tags, preventing pipelines from
getting created for such tags altogether. Fix by only creating the
"publish-cleanup" job in tag pipelines for open source security
releases.
(cherry picked from commit bb40c34638)
Adjust the triggering rules for the "merged-metadata" CI job so that
merge requests merged into security-* branches are automatically
assigned to the "Not released yet" milestone, just like merge requests
targeting public branches. This enables merge requests containing
security fixes to be correctly processed by release automation scripts.
Backport of MR !11984
Merge branch 'backport-pspacek/extend-not-released-yet-milestone-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11987
Adjust the triggering rules for the "merged-metadata" CI job so that
merge requests merged into security-* branches are automatically
assigned to the "Not released yet" milestone, just like merge requests
targeting public branches. This enables merge requests containing
security fixes to be correctly processed by release automation scripts.
(cherry picked from commit afdf7bed60)
Ensure the "backports" CI job is created when new changes are merged
into security-* branches. This enables using backport automation for
security fixes.
Backport of MR !11938
Merge branch 'backport-michal/extend-automatic-backports-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11985
Ensure the "backports" CI job is created when new changes are merged
into security-* branches. This enables using backport automation for
security fixes.
(cherry picked from commit 88b94a2019)
When a validator is being shut down, the associated name
`val->name` is set to NULL. This could cause a crash if a worker
thread subsequently added an EDE code with `val->name` in the
extra text.
`validator_addede()` now checks whether the name is NULL before
trying to add it to the extra text.
Closes#5613
Backport of MR !11945
Merge branch 'backport-each-validator-log-after-shutdown-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11977
When a validator is being shut down, the associated name
`val->name` is set to NULL. This could cause a crash if a worker
thread subsequently added an EDE code to the response containing
val->name in the extra text.
`validator_addede()` now checks whether the name is NULL before
trying to add it to the extra text.
(cherry picked from commit 2c60870527)
The :iscman:`named` process could terminate unexpectedly when
processing a catalog zone with an invalid ``allow-query`` or
``allow-transfer`` custom property (i.e. having a non-APL type)
coexisting with the valid property. This has been fixed.
Closes#5941
Backport of MR !11954
Merge branch 'backport-5941-catz-catz_process_apl-bug-fix-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11975
The allow-transfer/allow-query catalog zone custom properties support
only APL RRtypes. All other types are correctly rejected by the
catz_process_apl() function. However, when an APL RRtype is processed
by that function, and another (non-APL) RRtype is then attempted to be
processed, there is an assertion failure happening in the prologue
of the function because `*aclbp != NULL` (i.e. an APL has been already
processed). Move the code to do type checking before the affected
REQUIRE assertion.
(cherry picked from commit 67e0090371)
The :iscman:`named` process could leak small amounts of memory
when processing a catalog zone entry which had defined custom
primary servers with TSIG keys using both the regular ``primaries``
custom property syntax and the legacy alternative syntax (``masters``)
at the same time. This has been fixed.
Closes#5943
Backport of MR !11951
Merge branch 'backport-5943-catz-primaries-tsig-key-name-leak-fix-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11973
This new check ads a catalog member zone with both variants of
the labeled primaries/masters property. This should not cause
any issues.
(cherry picked from commit 4f5f4b77c7)
OPENSSL_cleanup() in OpenSSL 4 doesn't free the memory, and that is
not compatible with BIND 9's memory leak detection code. Don't use
custom allocation/deallocation functions for OpenSSL's internal memory
management.
See https://github.com/openssl/openssl/pull/29721Closes#5808
Backport of MR !11865
Merge branch 'backport-5808-openssl4-compat-fix-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11896
OPENSSL_cleanup() in OpenSSL 4 doesn't free the memory, and that is
not compatible with BIND 9's memory leak detection code. Don't use
custom allocation/deallocation functions for OpenSSL's internal memory
management in the tls.c module.
See https://github.com/openssl/openssl/pull/29721
(cherry picked from commit 4ede6edc54)
The resolver can and will reuse outgoing TCP connections to the same host, as recommended by RFC 7766. This prevents a whole class of attacks that abuse the fact that establishing a TCP connection is expensive and it is fairly easy to deplete the outgoing TCP ports by putting them into TIME_WAIT state.
The number of pipelined queries per connection is capped at 256 to limit the impact of a connection drop.
Backport of MR !11845
Merge branch 'backport-3741-reuse-tcp-connections-9.20' into 'bind-9.20'
See merge request isc-projects/bind9!11846
Move disptype and transport into dispatch_hash() and dispatch_match()
so that the match function is the single source of truth for whether
two TCP dispatches are interchangeable. This replaces the post-loop
disptype filter in dispatch_gettcp() and makes the disptype field in
struct dispatch_key actually used.
(cherry picked from commit 4654796683)
TCP dispentries no longer use the global QID hash table at all.
Responses are matched by scanning disp->active, and sequential
per-dispatch IDs (bounded by the pipelining limit) are unique
within a single dispatch by construction. Since TCP delivers
only data we asked for on a specific connection, the per-peer
uniqueness that the global table enforced was never actually
needed for TCP.
DNS_DISPATCHOPT_FIXEDID is plumbed through dns_request_createraw
-> get_dispatch -> dns_dispatch_createtcp so FIXEDID TCP requests
always get a fresh isolated dispatch — the caller-supplied ID
then cannot collide with any other in-flight query either.
(cherry picked from commit 3e364aec2b)
Cap the number of in-flight queries on a single shared TCP dispatch.
When the limit is reached, the dispatch is removed from the hash
table so subsequent queries get a fresh connection. The existing
dispatch continues serving its queries until they complete.
This bounds the blast radius of a connection drop: at most N queries
fail simultaneously instead of all queries to that server.
The default limit is 256. It can be overridden for testing via
'named -T tcppipelining=N'.
(cherry picked from commit 385ceabe8f)
Set tcppipelining=1 on recursive servers in the system tests to
restore one-query-per-connection behavior. The tests relies on
specific connection and query counting that breaks with TCP
connection sharing.
(cherry picked from commit 05e8b58307)
Previously, the user of dns_dispatch API had to first call
dns_dispatch_gettcp() and if that failed create a new TCP dispatch with
dns_dispatch_createtcp(). This has been changed and the TCP connection
reuse happens transparently inside dns_dispatch_createtcp(). There are
separate buckets for dns_resolver, dns_request and dns_xfrin units, so
these don't get mixed together.
(cherry picked from commit d5ee86b799)