Commit graph

13356 commits

Author SHA1 Message Date
Aram Sargsyan
a4f05a26ad Add a catz test with invalid allow-transfer property
Check that invalid/unexpected RRtypes coexisting with a valid APL
RRtype does not cause an assertion failure.
2026-05-06 19:35:23 +00:00
Aram Sargsyan
4f5f4b77c7 Add a catz test with a duplicate primaries entry (alternative syntax)
This new check ads a catalog member zone with both variants of
the labeled primaries/masters property. This should not cause
any issues.
2026-05-06 17:30:51 +00:00
Evan Hunt
7213b038f0 Clear dns64_aaaaok immediately after use
The DNS64 state information stored in client->query.dns64_aaaaok
could cause an assertion failure in query_respond() if the server
was configured in such a way as to trigger a new recursion before
the query had been reset - for example, by using the filter-aaaa
plugin, which may need to recurse to find out whether an A record
exists.

This has been addressed by clearing DNS64 state information
immediately after the call to query_filter64().
2026-05-06 06:46:32 +02:00
Ondřej Surý
b4200ba259 Replace INSIST in KSR DNSKEY parser with a structured error
A DNSKEY record appearing before any ';; KeySigningRequest' header
in a KSR file made dnssec-ksr abort on INSIST(rdatalist != NULL),
which is the wrong tool for a malformed-input case.  Issue a fatal()
naming the file and line instead so pipelines see a clean exit
status and an actionable message; the now-unreachable NULL check on
the rdatalist->ttl update goes away too.

Assisted-by: Claude:claude-opus-4-7
2026-05-05 21:06:30 +02:00
Mark Andrews
cd96894bcd
Remove remaining RFC 3445 KEY flags
RFC 3445 also eliminated the DNS_KEYTYPE_NOAUTH, DNS_KEYTYPE_NOCONF,
and DNS_KEYOWNER_ENTITY flags. With NOAUTH and NOCONF gone, the
concept of NOKEY can no longer be expressed in KEY records.

DNS_KEYOWNER_ENTITY was already unused as of 22d688f656 but still
defined; that is now also removed.
2026-05-05 10:17:31 +02:00
Evan Hunt
84f3a4aebe minor simplification in dnssec-keygen
The name of the key to generate can be passed to `keygen()` as a
string; we don't need to pass it using argc/argv.
2026-05-01 20:22:52 +00:00
Matthijs Mekking
1ce7cf2dd2 Change isctest.kasp.dnssec_verify to take FQDN
This is required to AXFR and verify the root zone and it makes no
difference for non-root zones (dnssec-verify takes FQDN or makes the
provided name absolute).
2026-05-01 08:18:36 +02:00
Matthijs Mekking
9e9af18e4a Add kasp test case for root with checkds enabled
Add a test case where the root zone has dnssec-policy configured, with
checkds enabled. This is a silly case because the root does not have
any parent NS records, but it should not crash the server.

The same is true for zones that do not have parent NS records, but
eventually they will hit the same code path.
2026-05-01 08:18:36 +02:00
Ondřej Surý
0d0f69db89 Bound EDNS option length in dig's process_opt() walk
process_opt() reads the per-option (optcode, optlen) header from the
OPT rdata and then advances the buffer by optlen, both for the COOKIE
branch (via process_cookie()) and for any other optcode.  The walk
itself never compared optlen to the buffer remainder; the only reason
it cannot trip the isc_buffer_forward() REQUIRE today is that
fromwire_opt() (lib/dns/rdata/generic/opt_41.c) already validates each
option's length against the rdata bounds before the rdataset is
handed back, so process_opt() never sees a self-inconsistent rdata.

That upstream guarantee is fine, but it leaves the local walker
trusting an invariant established elsewhere.  Add a defensive check
that just stops the walk when a future caller (a cached message, an
alternate parser, a refactor of the OPT validator) hands process_opt()
a buffer where optlen would run past the end.

Assisted-by: Claude:claude-opus-4-7
2026-05-01 07:19:49 +02:00
Ondřej Surý
51774decd2 Reject negative and out-of-range TTLs in dnssec-* tools
strtottl() parsed the operator's TTL string with strtol() and assigned
the long directly to dns_ttl_t (uint32_t) with no sign or ERANGE
check. The only validation was the "no digits parsed" branch, so a
fully-consumed "-1" became UINT32_MAX (~136 years) and was silently
written into DNSKEY/key files by dnssec-keygen -L, dnssec-signzone -t,
dnssec-settime -L, etc. Any signing pipeline interpolating the TTL
from a variable could mint a key with a multi-decade TTL and never see
an error.

Switch to strtoul(), reject a leading '-' explicitly (strtoul silently
negates), check errno == ERANGE, and reject values exceeding
UINT32_MAX before handing the result to time_units(). The pre-existing
multiplication wrap inside time_units() is tracked separately.

Assisted-by: Claude:claude-opus-4-7
2026-04-30 17:40:19 +02:00
Colin Vidal
69fad4f7a4 Fix cyclic_glue system test
The `cyclic_glue` system test was not explicitly waiting for the dump to
complete. As a result, the test could read an outdated dump file and
perform assertions on database state. Fix this by waiting for `dumpdb`
command to finish before reading `named_dump.db`.
2026-04-30 16:31:16 +02:00
Ondřej Surý
f1ec5e1809 Process dig -x reverse octets iteratively
reverse_octets() recursed once per dot, with depth bounded only by
ARG_MAX (~2 MiB on Linux), so feeding dig -x a deep input like
'1.1.1.…1' busted the call stack and crashed the tool with SIGSEGV
instead of a structured error.  The transformation it performs is
purely textual (split on '.', emit components in reverse), so the
recursion was never load-bearing.

Walk the input once into a fixed-size array of label slices, capped at
DNS_NAME_MAXLABELS (which is the most we could ever fit into the
result buffer anyway), then iterate the array in reverse to write the
output.  Inputs with more than DNS_NAME_MAXLABELS labels now return
DNS_R_NAMETOOLONG, which dig.c surfaces as 'Invalid IP address' and
exit 1.  Drop the unnecessary (int) casts on ptrdiff_t/size_t lengths
while at it.

Assisted-by: Claude:claude-opus-4-7
2026-04-30 14:02:02 +02:00
Ondřej Surý
dba102ef16 Skip detach when delv's client never created
run_resolve allocates dns_client_t late, but the cleanup epilogue
called dns_client_detach() unconditionally. When convert_name() or
dns_client_create() failed first, the detach hit a NULL client and
the REQUIRE(DNS_CLIENT_VALID) inside it aborted the process with
SIGABRT instead of a clean error exit.

Guard the detach with a NULL check. Add a digdelv test that runs
delv on a query name whose first label exceeds 63 octets and
asserts the process does not exit 134.

Assisted-by: Claude:claude-opus-4-7
2026-04-30 10:56:11 +02:00
Ondřej Surý
1b681dfa2f
Run conn_cleanup on isccc_cc_towire failure in control_respond
The bare return left conn->secret, conn->response, conn->request, and
conn->text pinned until the connection itself was torn down — every
other error in the function reaches conn_cleanup via goto, and the
success path falls into the same label, so the towire-failure return
was the lone outlier.  Send it through the existing cleanup path.

Assisted-by: Claude:claude-opus-4-7
2026-04-30 06:47:39 +02:00
Ondřej Surý
ac79f8cfeb Remove the rndc testgen command
testgen existed solely to let the rndc system test exercise large
response payloads — it has no operator value, accepts an unbounded
count, and could be invoked by any read-only rndc client to drive
named into memory exhaustion.  Drop the command, the gencheck helper
that validated its output, and the buffer-size loop in the rndc
system test; the remaining rndc subcommands already produce
non-trivial responses, so the framing path stays exercised.

Assisted-by: Claude:claude-opus-4-7
2026-04-30 06:35:01 +02:00
Ondřej Surý
c62f24f7ee Fix swapped arguments in redirect2() single-label branch
For a query whose qname is the root, the labels==1 branch in
redirect2() called dns_name_copy(redirectname, view->redirectzone)
with arguments reversed, overwriting the view-global
nxdomain-redirect target with the empty redirectname rather than
copying the configured target into the per-query lookup name.  After
the corruption, view->redirectzone names the root, so
dns_name_issubdomain() makes redirect2() short-circuit for every
subsequent query and the nxdomain-redirect feature stops working
until named is restarted.

Triggering this needs the resolver to receive an NXDOMAIN for the
root from upstream, which does not happen in normal DNS operation.

Swap the arguments to match the dns_name_copy(source, dest)
signature.  Add a system test that issues a root query through the
nxdomain-redirect resolver and verifies the redirect feature still
works for a normal NXDOMAIN-producing query afterwards.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 21:46:27 +02:00
Ondřej Surý
46f6bb6364
Size HMAC key generation buffers to the maximum block size
hmac_generate() declared its on-stack nonce buffer as
unsigned char data[ISC_MAX_MD_SIZE], i.e. 64 bytes. That is the maximum
digest size, but the buffer is filled up to the algorithm's HMAC block
size, which is 128 bytes for SHA-384 and SHA-512. Asking rndc-confgen
for an HMAC-SHA-384 or HMAC-SHA-512 key with -b > 512 (the documented
range allows up to 1024) wrote past the end of the stack buffer; on
hardened builds this aborted with a stack-smash detector firing
instead of producing a key.

Use the existing ISC_MAX_BLOCK_SIZE (128) for the buffer so the full
1..1024 range advertised by -A hmac-sha{384,512} works as documented.
The matching key_rawsecret[64] in confgen's generate_key() is enlarged
the same way so the generated key fits when dumped to the buffer.

Add a system test that exercises rndc-confgen across the previously
overflowing keysizes; with -Db_sanitize=address it caught the abort
before the fix.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 19:21:20 +02:00
Ondřej Surý
63d30566bb Stop nzd_env_close from chowning through symlinks
When named is running as root, nzd_env_close() chowns the per-view
NZD database file to the unprivileged user that named will drop to.
The call used chown(), which follows symlinks, so a symlink at the
NZD path would silently transfer ownership of whatever the link
pointed at instead of the database file itself.

Switch to lstat() + S_ISREG() + lchown() so the chown only fires when
the path is a regular file and never traverses a symlink even if one
is planted between the lstat and the lchown.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 19:18:47 +02:00
Ondřej Surý
d5ba6e1c26 Reject unsafe key names in rndc-confgen, tsig-keygen, ddns-confgen
The three tools interpolated their key-name argument verbatim into the
generated 'key "..." { ... };' clause. A name containing '"', '{', '}',
or ';' could close the clause and append additional named.conf
statements — for example, a second key block with an attacker-chosen
secret. The injected output passes named-checkconf and is loaded by
named as a valid configuration. The risk shows up when an automation
wrapper feeds tenant or zone names from a less-trusted source through
-k / -y / -s / -z (or the tsig-keygen positional argument).

Validate the final key name (after the optional -s / -z suffix is
concatenated in tsig-keygen) against [A-Za-z0-9._-]+ and exit with an
error otherwise. The allowlist covers the documented usage; every
character used in the injection vectors is excluded.

Add a system test that runs the documented PoC payloads through each
tool and asserts a non-zero exit, plus sanity coverage for the default
key names and dotted DNS-style names.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 18:12:35 +02:00
Ondřej Surý
72d21a0806 Resolve ERR_MISSING_GLUE / ERR_EXTRA_AAAA value collision
Both constants were defined as 5. The symbol table used by checkns() to
deduplicate log messages keys on (name, error_code), so logging an
extra-AAAA error caused logged() to also return true for the
missing-glue check, silently skipping the entire missing-glue block for
the same name in named-checkzone and named-checkconf -z.

Convert the ERR_* defines to an auto-numbered enum so the compiler
guarantees the values stay pairwise distinct.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 17:31:23 +02:00
Ondřej Surý
042e86fa84 Validate -l and -L arguments in named-checkzone
The -l (max TTL) and -L (source serial) flags parsed their arguments
with strtol() and assigned the result directly to uint32_t with no
range check. A negative value such as -1 became UINT32_MAX, which made
-l silently disable the TTL cap it claimed to enforce, and out-of-range
values truncated to 32 bits without warning.

Switch both flags to isc_parse_uint32(), which rejects leading non-
alphanumeric input (catching '-'), checks ERANGE, and validates the
32-bit range, so an invalid argument now exits with an error instead
of being silently coerced.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 17:25:49 +02:00
Ondřej Surý
746fb28369
Drop unused DNS_MASTER_NOINCLUDE and warn about untrusted zone text
DNS_MASTER_NOINCLUDE was defined to suppress $INCLUDE processing, but
no caller ever set it, so the guarded code path was dead and the flag
gave the false impression that named-checkzone could be hardened
against untrusted input. The zone-file parser cannot safely read text
from a less-trusted source than the user running the tool: $INCLUDE
opens any local file readable by that user, and fragments of its
contents leak through tokenizer error messages.

Rather than wire up an opt-in flag that suggests this is a supported
mode, remove the dead flag and the dead guard, and document in the
named-checkzone and named-compilezone manual pages that these tools
must not be run on zone text from an untrusted source.

Assisted-by: Claude:claude-opus-4-7
2026-04-29 15:08:20 +02:00
Colin Vidal
d1e51f96bf Add cyclic_glue system test
The cyclic_glue system test ensures that:

- cyclic sibling glues are used;
- (by transitivity) sibling glues are used too;
- but glues from different parent are ignored.
2026-04-28 17:16:46 +02:00
Colin Vidal
19a446f00e Remove licensing header check for root.hint[s]
Removing REUSE licensing header check for `root.hint` and `root.hints`
files.

Assisted-by: Claude:claude-opus-4-7
2026-04-28 15:37:10 +01:00
Ondřej Surý
f7859247df Fix inverted gethostname() check in rndc status
When named_os_gethostname() was replaced with raw gethostname(), the
success/failure polarity was flipped: the fallback to "localhost" now
runs on success and the hostname buffer is left uninitialized on
failure.  In the failure path, snprintf() then reads the uninitialized
stack buffer, disclosing stack contents via the rndc status reply.
2026-04-17 17:51:48 +02:00
Štěpán Balážik
f9ed3650ac Reimplement xfer/ans5 using ControllableAsyncServer
Remove the last usage of the `ans.pl` server and the server itself.
2026-04-17 14:26:07 +00:00
Štěpán Balážik
37b0502cf4 Convert responses to bytes before logging them in asyncserver
Ensure that the actual packet contents are logged including the TSIG
record which is calculated on `to_wire` call.
2026-04-17 14:26:07 +00:00
Štěpán Balážik
e43fa1dc5a Improve readability of endianness conversions
Replace the less obvious and less explicit `struct.unpack()` and
`struct.pack()` calls with calls to `int.from_bytes()` and
`int.to_bytes()`, respectively.
2026-04-17 14:26:07 +00:00
Štěpán Balážik
a58952e1f7 Refactor AxfrHandler and hoist it to isctest.asyncserver
It will be useful in the xfer system test as well.
2026-04-17 14:26:07 +00:00
Štěpán Balážik
93a8079489 Fix FallbackTooManyRecordsAxfrHandler to follow convention
All the other subclasses AxfrHandler send three messages.
This oversight was inherited from the original Perl implementation of
the server and was not fixed in 46ecbbe where it was rewritten.

This allows refactoring and sharing of the superclass.
2026-04-17 14:26:07 +00:00
Matthijs Mekking
51f27fda46 Add test for SIG in prequisites of dynamic update
Make sure the nameserver correctly handles SIG records in the
prerequisites of the dynamic update. The first check is to ensure that
the prerequisites are not examined prior to checking the credentials.

The second test case checks that the SIG present prerequisite is
examined and therefore refuses the update. Also this should not trigger
an assertion failure in dns__db_findrdataset() (due to the REQUIRE()
only accepted dns_rdatatype_rrsig when the covers parameter was set).
2026-04-17 16:09:39 +02:00
Ondřej Surý
e9f880c78f Add AXFR regression test for SIG covers preservation
diff.c rdata_covers() runs on both dns_diff_apply (IXFR, ns/update.c
dynamic updates) and dns_diff_load (AXFR).  After the previous commit
refused SIG and NXT in dynamic updates, the AXFR path remains the
most natural way to drive legacy SIG records into a secondary's zone
DB and regression-gate the rdata_covers() fix.

The test adds ans11 as an AsyncDnsServer primary for a small zone
whose AXFR carries two SIG rdatas at the same owner with different
covered types (A, MX) and different TTLs (600, 1200), and declares
ns6 a secondary of that zone.  With the bug present, dns_diff_load
groups both tuples at typepair (SIG, 0) and the MX-covering record
inherits the first-seen TTL (600); the fix keeps them at (SIG, A)
and (SIG, MX) with their original TTLs.

rndc dumpdb -zones on the secondary is used to inspect stored state
directly, because the wire-level SIG query response merges
same-(owner,type,class) RRs and masks the per-rdataset TTLs.
2026-04-17 16:09:39 +02:00
Ondřej Surý
3a44a13232 Refuse SIG and NXT records in dynamic updates
SIG (24) and NXT (30) are obsolete DNSSEC record types, superseded by
RRSIG and NSEC in RFC 3755.  Allowing them through dynamic update
exposes two distinct bugs that the surrounding GL#5818 work already
fixes as defense-in-depth:

  - dns__db_findrdataset() used to REQUIRE that (covers == 0 ||
    type == RRSIG), which aborts named when a SIG update reaches the
    prescan foreach_rr() call.  Fixed to accept dns_rdatatype_issig().
  - diff.c rdata_covers() used to test only RRSIG, dropping the
    covered-type field for SIG rdatas; the zone DB then filed every
    SIG rdataset under typepair (SIG, 0) instead of
    (SIG, covered_type) and follow-up adds collided at that bucket.
    Fixed to use dns_rdatatype_issig().

Both underlying bugs are still reachable via inbound zone transfer
(diff.c rdata_covers() runs from both dns_diff_apply on the IXFR path
and dns_diff_load on the AXFR path), so the type-helper fixes above
remain necessary.  For the dynamic-update path, the simplest and
safest posture is to refuse SIG and NXT outright at the front door in
ns/update.c, alongside the existing NSEC/NSEC3/non-apex-RRSIG
refusals.  KEY remains permitted because it is still used to carry
public keys for SIG(0) transaction authentication.

The existing tcp-self SIG regression test is repointed to assert
REFUSED on the SIG add, a symmetric NXT test is added, and the
SIG-via-dyn-update covers-bucket test is removed because it is no
longer reachable through this entry point; AXFR-based coverage of
diff.c rdata_covers() follows in a separate commit.
2026-04-17 16:09:39 +02:00
Ondřej Surý
b9fc0e595b Add regression test for SIG covers being dropped in dns_diff_apply
rdata_covers() in lib/dns/diff.c tests `type == dns_rdatatype_rrsig`
instead of dns_rdatatype_issig(), so for a legacy SIG (24) rdata it
returns 0 and the covered type is discarded on the dynamic-update /
IXFR path.  The zone DB then files every SIG rdataset under typepair
(SIG, 0) instead of (SIG, covered_type), and a follow-up add with a
different covers field but a different TTL collides at that bucket,
trips DNS_DBADD_EXACTTTL in qpzone, returns DNS_R_NOTEXACT, and comes
back to the client as SERVFAIL.

The new test adds a PTR to establish the node (tcp-self requires the
client IP's reverse form to equal the owner), then two SIG updates
with different covers and different TTLs; on a buggy build the second
update is SERVFAIL and named logs `dns_diff_apply: .../SIG/IN: add
not exact`.  The test is expected to pass once rdata_covers() is
switched to dns_rdatatype_issig(), matching the fix already adopted
for dns__db_findrdataset() on this branch and the helper pattern used
in master.c, xfrout.c, and qpcache.c.
2026-04-17 16:09:39 +02:00
Ondřej Surý
ecddeab696 Add system test for SIG record handling in update-policy tcp-self
Verify that a SIG record sent via TCP dynamic update is accepted
by the tcp-self update-policy and correctly stored in the zone.
2026-04-17 16:09:39 +02:00
Ondřej Surý
0c007d8659
Rename view->hints to view->rootdb and rearm priming
With the parent-centric resolver, dns_view_bestzonecut() consults the
delegation DB (view->deleg) rather than the main cache for the closest
zonecut.  Root is never the target of a referral, so it never lands in
delegdb; bestzonecut therefore falls through to the hints lookup on
every query whose closest ancestor is root.  prime_done() only called
dns_root_checkhints(), which logs discrepancies but does not update
any store bestzonecut looks at, so the fresh root NS records obtained
by priming were never used and priming kept re-firing.

Rename view->hints to view->rootdb and refresh it when a priming
fetch completes: the '.' NS rdataset is replaced with the fetched
one, and for each listed nameserver the matching A/AAAA glue is
copied from the response's ADDITIONAL section.  Only glue for names
that actually appear as NS targets is accepted, so a hostile response
cannot inject unrelated records.  Glue the response did not carry is
left untouched, so the hints-file records loaded at startup remain as
a fallback.

Each view gets its own rootdb: the previous shared
named_g_server->in_roothints is gone, and configure_view() calls
dns_rootns_create() per view when the class-IN defaults are needed.
That keeps the priming writer one-per-DB, so concurrent priming in
different views cannot race on the same zone-DB version.

The rootdb refresh runs synchronously from the resolver response path,
so records go straight from the wire into rootdb with no cache round
trip and no dependency on DNSSEC validation state.  A new
DNS_FETCHOPT_PRIMING option marks the priming fetch; prime_done()
itself is now pure cleanup.

Track the rootdb freshness window in view->rootdb_expires and trigger
re-priming lazily from dns_view_find() and bestzonecut_rootdb() only
when the window has elapsed.  Stale records are still served while the
fresh priming fetch is in flight.

Drop dns_root_checkhints() and its helpers; the rootdb is now the
authoritative source the resolver consults.
2026-04-16 13:39:18 +02:00
Aram Sargsyan
979ae7d9d6 A a test to check zone filename case-insensitivity
The test adds a catalog member zone which has '%X' in its name and
it ends up in the zone filename parser's code because the filename
is currently generated (by the catalog zone code) based on the zone's
name.

Zones which have a name with the '%' special character should be
filtered and their name's digest should be used instead for filenane
generation (like it is implemented for other special characters), and
that fix is coming next.
2026-04-16 11:37:02 +00:00
Colin Vidal
c280029d4d
Add system test for the chase DS fix
Add a system test which ensures, whenever the DS record can't be found
in the local cache, that the resolver first tries to get the parent NS
from the delegation cache to ask them the DS record, directly, rather
than running the fallback flow where the resolver attempts to query the
DS record from NS of the validating name (which would fails, then the
resolver would remove one label and fetch again, fails, and so on until
it reach the closest zonecut).

The test relies on the fact that when the fallback flow is run, the
`rctx_chaseds()` function is run, adding the "chase DS servers ..." and
"suspending DS lookup to find parent's..." logs.
2026-04-16 12:34:52 +02:00
Evan Hunt
15cb1e50cb Continue removal of license headers from test zones
Copyright license headers were removed from system test zone files in
commit f144db6b68, but this change only applied to files named '*.db',
'*.db.in', etc. There were some zone files called '*.zone' which were
left unchanged; these have been updated now as well.
2026-04-15 19:26:23 +00:00
Štěpán Balážik
261185ecb5 Log the Python interpreter used to run the system tests during setup
This is useful when running in an virtual environment or on a machine
where multiple Python versions are installed.
2026-04-15 15:12:38 +02:00
Nicki Křížek
68cfca1788 Use virtualenv's Python interpreter when running tests from a venv
Meson bakes the absolute path of the detected Python binary (e.g.
/usr/bin/python3.12) into the PYTHON build variable. When tests are run
from a virtualenv, that stored path might point to the system Python
which lacks the virtualenv's installed packages, causing test failures.

Fix this by checking whether the current process is running inside a
virtualenv (sys.prefix != sys.base_prefix) and, if so, replacing the
stored PYTHON build var with sys.executable — the interpreter that is
already running pytest and has all required dependencies available.

The behaviour on EL8/EL9 (where meson prefers python3.12 over the older
platform default) and on FreeBSD (python3.11) is unchanged, since those
workflows run pytest without an active virtualenv in our CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 14:26:35 +02:00
Mark Andrews
b4ba11f151 Fix a bug with template filename reuse
When a zone filename is defined in named.conf which will be
written to by the server - i.e., secondary or dynamically updated
zones - there is a test at configuration time to ensure that the
filename is non-unique.

This test is run before the zone is actually created, so a zone
configured using a template may not have had its filename expanded
yet.  This can cause a configuration to fail because, for example,
multiple zones appear to using the filename "$name.db".

This has been fixed by calling dns_zone_expandzonefile() from
isccfg_check_zoneconf(), to expand the names when checking for
uniqueness.
2026-04-14 21:50:31 -07:00
Mark Andrews
213e59ccf5 Checking invalid TSIG key name in a catalog zone 2026-04-15 09:00:26 +10:00
Ondřej Surý
3e364aec2b
Use sequential per-dispatch message IDs for TCP
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.
2026-04-14 17:48:21 +02:00
Ondřej Surý
385ceabe8f
Limit TCP pipelining per shared dispatch
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'.
2026-04-14 17:48:16 +02:00
Ondřej Surý
05e8b58307
Disable TCP pipelining in tcp and masterformat system test
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.
2026-04-14 17:48:15 +02:00
Aram Sargsyan
d5720cd821 Add a new check in "addzone" system test
Check that named handles requests to modify non-existing zones
without issues.
2026-04-14 08:57:12 +00:00
Aram Sargsyan
a227e4606f Fix a lock/unlock bug in server.c:do_modzone()
The cleanup path always unlocks the 'view->newzone.lock' lock, but
there are 'goto cleanup;' operations even before the lock is locked,
which causes an assertion failure.

Don't use the cleanup path before the lock is locked.
2026-04-14 08:57:12 +00:00
Mark Andrews
e9a58de251 Checking maximal sized compresses bit map works
Add records that will be at end of each compressed bitmap less 1
of the NSEC3 record. Zone verification should still work.
2026-04-10 15:45:01 +10:00
Michal Nowak
8b4b1aa6d9
System test requires the h2 module 2026-04-09 16:53:29 +02:00