Compare commits

..
Author SHA1 Message Date
Mark Andrews 5c7397b9cb Return raw zone serial for inline zones 2025-03-24 17:32:52 +11:00
Mark Andrews a5ae37ad0b Disable ZONEVERSION for built-in chaos and empty zones 2025-03-24 17:32:52 +11:00
Mark Andrews e081ab6ecf Check that 'provide-zoneversion no;' works 2025-03-24 17:32:52 +11:00
Mark Andrews 9604b13d00 Add an option to disable ZONEVERSION responses
The option provide-zoneversion controls whether ZONEVERSION is
returned.  This applies to primary, secondary and mirror zones.
2025-03-24 17:32:52 +11:00
Mark Andrews d7a667d91b Check that received ZONEVERSION is logged 2025-03-24 17:32:52 +11:00
Mark Andrews 70470169a9 Add option request-zoneversion
This can be set at the option, view and server levels and causes
named to add an EDNS ZONEVERSION option to requests.  Replies are
logged to the 'zoneversion' category.
2025-03-24 14:22:07 +11:00
Mark Andrews 9bb834750d Add system tests for EDNS zoneversion 2025-03-24 11:08:25 +11:00
Mark Andrews d17eda82e0 Return EDNS ZONEVERSION if requested
If there was an EDNS ZONEVERSION option in the DNS request and the
answer was from a zone, return the zone's serial and number of
labels excluding the root label with the type set to 0 (ZONE-SERIAL).
2025-03-24 11:08:25 +11:00
Mark Andrews ca3e61a462 Add dns_zone_getzoneversion
Returns the EDNS ZONEVERSION for the zone.  Return the database
specific version otherwise return a type 0 version (serial).
2025-03-24 11:08:25 +11:00
Mark Andrews 7f07c989b5 Add dns_db_getzoneversion
Provides a database method to return a database specific EDNS
ZONEVERSION option.  The default EDNS ZONEVERSION is serial.
2025-03-24 11:08:25 +11:00
Mark Andrews 83115b931d Add EDNS ZONEVERSION option counter 2025-03-24 11:08:24 +11:00
Mark Andrews 184c7caff9 Add support for EDNS ZONEVERSION to dig
This add the +[no]zoneversion option to dig which adds the
EDNS ZONEVERSION option to requests.
2025-03-24 11:08:24 +11:00
Mark Andrews 4199d2d5e4 Extend message code to display ZONEVERSION 2025-03-24 11:08:24 +11:00
Mark Andrews 6a5e60231f Check EDNS ZONEVERSION when parsing OPT record 2025-03-21 15:38:56 +11:00
Mark Andrews 49ecb158d4 fix: dev: Fix adbname reference
Call `dns_adbname_ref` before calling `dns_resolver_createfetch` to
ensure `adbname->name` remains stable for the life of the fetch.

Closes #5239

Merge branch '5239-fix-adb-reference-counting' into 'main'

See merge request isc-projects/bind9!10290
2025-03-21 00:26:25 +00:00
Mark Andrews 8e7229f641 Fix gaining adbname reference
Call dns_adbname_ref before calling dns_resolver_createfetch to
ensure adbname->name remains stable for the life of the fetch.
2025-03-20 23:25:29 +00:00
Evan Hunt 3415392d01 fix: dev: Optimize key ID check when searching for matching keys
When searching through a DNSKEY or KEY rrset for the key matching a particular algorithm and ID, it's a waste of time to convert every key into a `dst_key` object; it's faster to compute the key ID from the rdata, then do the full key conversion after determining that we've found the right key. This optimization was already used in the validator, but it's been refactored for code clarity, and is now also used in query.c and message.c.

Merge branch 'each-refactor-key-search' into 'main'

See merge request isc-projects/bind9!10258
2025-03-20 18:25:05 +00:00
Evan Hunt 2e6107008d optimize key ID check when searching for matching keys
when searching a DNSKEY or KEY rrset for the key that matches
a particular algorithm and ID, it's a waste of time to convert
every key into a dst_key object; it's faster to compute the key
ID by checksumming the region, and then only do the full key
conversion once we know we've found the correct key.

this optimization was already in use in the validator, but it's
been refactored for code clarity, and is now also used in query.c
and message.c.
2025-03-20 18:22:58 +00:00
Evan Hunt 341b962665 move dns_zonekey_iszonekey() to dns_dnssec module
dns_zonekey_iszonekey() was the only function defined in the
dns_zonekey module, and was only called from one place. it
makes more sense to group this with dns_dnssec functions.
2025-03-20 18:22:58 +00:00
Alessio Podda d3db9ccf53 chg: dev: Switch symtab to use fxhash hashing
This merge request resolves some performance regressions introduced
with the change from isc_symtab_t to isc_hashmap_t.

The key improvements are:

1. Using a faster hash function than both isc_hashmap_t and
   isc_symtab_t. The previous implementation used SipHash, but the
   hashflood resistance properties of SipHash are unneeded for config
   parsing.
2. Shrinking the initial size of the isc_hashmap_t used inside
   isc_symtab_t. Symtab is mainly used for config parsing, and the
   when used that way it will have between 1 and 50 keys, but the
   previous implementation initialized a map with 128 slots.
   By initializing a smaller map, we speed up mallocs and optimize for
   the typical case of few config keys.
3. Slight optimization of the string matching in the hashmap, so that
   the tail is handled in a single load + comparison, instead of byte
   by byte.
   Of the three improvements, this is the least important.

Merge branch 'alessio/fxhash-symtab' into 'main'

See merge request isc-projects/bind9!10204
2025-03-20 13:00:12 +00:00
alessio e1e10adc3a Switch symtab to use fxhash hashing
This merge request resolves some performance regressions introduced
with the change from isc_symtab_t to isc_hashmap_t.

The key improvements are:

1. Using a faster hash function than both isc_hashmap_t and
   isc_symtab_t. The previous implementation used SipHash, but the
   hashflood resistance properties of SipHash are unneeded for config
   parsing.
2. Shrinking the initial size of the isc_hashmap_t used inside
   isc_symtab_t. Symtab is mainly used for config parsing, and the
   when used that way it will have between 1 and ~50 keys, but the
   previous implementation initialized a map with 128 slots.
   By initializing a smaller map, we speed up mallocs and optimize for
   the typical case of few config keys.
3. Slight optimization of the string matching in the hashmap, so that
   the tail is handled in a single load + comparison, instead of byte
   by byte.
   Of the three improvements, this is the least important.
2025-03-20 11:26:09 +01:00
Matthijs Mekking d2214cb704 fix: usr: Fix several small DNSSEC timing issues
The following small issues related to `dnssec-policy` have been fixed:
- In some cases the key manager inside BIND 9 could run every hour, while it could have run less often.
- While `CDS` and `CDNSKEY` records will be removed correctly from the zone when the corresponding `DS` record needs to be updated, the expected timing metadata when this will happen was never set.
- There were a couple of cases where the safety intervals are added inappropriately, delaying key rollovers longer than necessary.
- If you have identical `keys` in your `dnssec-policy`, they may be retired inappropriately. Note that having keys with identical properties is discouraged in all cases.

Closes #5242

Merge branch '5242-several-keymgr-issues' into 'main'

See merge request isc-projects/bind9!10251
2025-03-20 10:13:22 +00:00
Matthijs Mekking 3e836a87e6 Update Retired and Removed if we update lifetime
If we are updating the lifetime, and it was not set before, also
set/update the Retired and Removed timing metadata.
2025-03-20 10:12:16 +00:00
Matthijs Mekking b93cb2e80e Fix a key generation issue in the tests
The dnssec-keygen command for the ZSK generation for the zone
multisigner-model2.kasp was wrong (no ZSK was generated in the setup
script, but when 'named' is started, the missing ZSK was created
anyway by 'dnssec-policy'.
2025-03-20 10:12:16 +00:00
Matthijs Mekking 6c6b8796d3 Fix keymgr bug wrt setting the next time
Only set the next time the keymgr should run if the value is non zero.
Otherwise we default back to one hour. This may happen if there is one
or more key with an unlimited lifetime.
2025-03-20 10:12:16 +00:00
Matthijs Mekking 8c9d2eb2bf keymgr: also set DeleteCDS when setting PublishCDS
The keymgr never set the expected timing metadata when CDS/CDNSKEY
records for the corresponding key will be removed from the zone. This
is not troublesome, as key states dictate when this happens, but with
the new pytest we use the timing metadata to determine if the CDS and/or
CDNSKEY for the given key needs to be published.
2025-03-20 10:12:16 +00:00
Matthijs Mekking 63edc4435f Fix wrong usage of safety intervals in keymgr
There are a couple of cases where the safety intervals are added
inappropriately:

1. When setting the PublishCDS/SyncPublish timing metadata, we don't
   need to add the publish-safety value if we are calculating the time
   when the zone is completely signed for the first time. This value
   is for when the DNSKEY has been published and we add a safety
   interval before considering the DNSKEY omnipresent.

2. The retire-safety value should only be added to ZSK rollovers if
   there is an actual rollover happening, similar to adding the sign
   delay.

3. The retire-safety value should only be added to KSK rollovers if
   there is an actual rollover happening. We consider the new DS
   omnipresent a bit later, so that we are forced to keep the old DS
   a bit longer.
2025-03-20 10:12:16 +00:00
Matthijs Mekking ef671919d5 Fix a small keymgr bug
While converting the kasp system test to pytest, I encountered a small
bug in the keymgr code. We retire keys when there is more than one
key matching a 'keys' line from the dnssec-policy. But if there are
multiple identical 'keys' lines, as is the case for the test zone
'checkds-doubleksk.kasp', we retire one of the two keys that have the
same properties.

Fix this by checking if there are double matches. This is not fool proof
because there may be many keys for a few identical 'keys' lines, but it
is good enough for now. In practice it makes no sense to have a policy
that dictates multiple keys with identical properties.
2025-03-20 10:12:16 +00:00
Mark Andrews 329a332708 fix: usr: Fix write after free in validator code
Raw integer pointers were being used for the validator's nvalidations
and nfails values but the memory holding them could be freed before
they ceased to be used.  Use reference counted counters instead.

Closes #5239

Merge branch '5239-use-counter-for-nvalidations-and-nfailss' into 'main'

See merge request isc-projects/bind9!10248
2025-03-20 01:30:11 +00:00
Mark Andrews bfbaacc9a0 Use reference counted counters for nfail and nvalidations
The fetch context that held these values could be freed while there
were still active pointers to the memory.  Using a reference counted
pointer avoids this.
2025-03-20 09:12:49 +11:00
Andoni Duarte Pintado 8dba96d71e Merge tag 'v9.21.6' 2025-03-19 17:36:14 +01:00
Michal Nowak 1d688e89b8 fix: test: Fix the log-report-channel zones check
The check looks for logs that are not present, fails to make the
possible failure visible, and fails to bump the check enumerator:

    I:checking that log-report-channel zones fail if '*._er/TXT' is missing (129)
    grep: test.out4.129: No such file or directory
    grep: test.out4.129: No such file or directory
    I:checking that raw zone with bad class is handled (129)

The issue appeared in #3659.

Merge branch 'mnowak/checkzone-test-fix' into 'main'

See merge request isc-projects/bind9!10286
2025-03-19 08:00:42 +00:00
Michal Nowak c2e60f9a5a Fix the log-report-channel zones check
The check looks for logs that are not present, fails to make the
possible failure visible, and fails to bump the check enumerator:

    I:checking that log-report-channel zones fail if '*._er/TXT' is missing (129)
    grep: test.out4.129: No such file or directory
    grep: test.out4.129: No such file or directory
    I:checking that raw zone with bad class is handled (129)
2025-03-19 08:00:19 +00:00
Mark Andrews ed727ee924 fix: test: Fix failing grep invocation on OpenBSD
Lines starting with A or NSEC are expected but not matched with the
OpenBSD grep. Extended regular expressions with direct use of
parentheses and the pipe symbol is more appropriate.

    I:checking RRSIG query from cache (154)
    I:failed

The issue appeared in #4805.

Merge branch 'mnowak/openbsd-grep-fix' into 'main'

See merge request isc-projects/bind9!10285
2025-03-19 00:04:39 +00:00
Michal NowakandMark Andrews 00584d6f29 Fix failing grep invocation on OpenBSD
Lines starting with A or NSEC are expected but not matched with the
OpenBSD grep. Extended regular expressions with direct use of
parentheses and the pipe symbol is more appropriate.

    I:checking RRSIG query from cache (154)
    I:failed
2025-03-18 23:29:22 +00:00
Arаm Sаrgsyаn d30b9eb46e fix: usr: Fix resolver statistics counters for timed out responses
When query responses timed out, the resolver could incorrectly increase the regular responses counters, even if no response was received. This has been fixed.

Closes #5193

Merge branch '5193-resolver-statistics-counters-fix' into 'main'

See merge request isc-projects/bind9!10227
2025-03-18 17:05:23 +00:00
Aram Sargsyan 0c7fa8d572 Test resolver statistics when responses time out
Add a test to check that the timed out responses do not skew the
normal responses statistics counters, and that they do update the
timeouts counter.
2025-03-18 16:20:59 +00:00
Aram Sargsyan 830e548111 Fix the resolvers RTT-ranged responses statistics counters
When a response times out the fctx_cancelquery() function
incorrectly calculates it in the 'dns_resstatscounter_queryrtt5'
counter (i.e. >=1600 ms). To avoid this, the rctx_timedout()
function should make sure that 'rctx->finish' is NULL. And in order
to adjust the RTT values for the timed out server, 'rctx->no_response'
should be true. Update the rctx_timedout() function to make those
changes.
2025-03-18 16:20:59 +00:00
Aram Sargsyan 12e7dfa397 Fix resolver responses statistics counter
The resquery_response() function increases the response counter without
checking if the response was successful. Increase the counter only when
the result indicates success.
2025-03-18 16:20:59 +00:00
Michał Kępień c6e5710846 chg: test: asyncserver.py: TCP improvements
This branch started off as `michal/upforwd-asyncserver`.  It quickly
turned out that the critical `asyncserver.py` change that was needed for
the `upforwd` system test was for the server to be able to read multiple
TCP queries on a single connection.  As currently present in `main`,
`asyncserver.py` closes every client connection after servicing a single
query.  Retaining that behavior would cause the `upforwd` system test to
fail and, in general, capturing all data sent by a client seems more
useful in tests than just closing connections quickly.  `asyncserver.py`
can always be extended in the future (e.g. by adding a new
`ResponseAction` that the networking code would react to) to reinstate
the original behavior, if it turns out to be necessary.

While working on changing that particular `asyncserver.py` behavior, I
noticed a couple of other deficiencies in the TCP connection handling
code, so I started addressing them.  One thing led to another and before
I noticed, enough changes were applied to be worth doing a separate
merge request, particularly given that the actual rewrite of
`upforwd/ans4/ans.pl` using `asyncserver.py` is trivial once the
required changes to `asyncserver.py` itself are applied.

Merge branch 'michal/asyncserver-tcp-improvements' into 'main'

See merge request isc-projects/bind9!10276
2025-03-18 15:30:35 +00:00
Michał Kępień 575a874582 Handle queries indefinitely on each TCP connection
Instead of closing every incoming TCP connection after handling a single
query, continue receiving queries on each TCP connection until the
client disconnects itself.  When coupled with response dropping, this
enables silently receiving all incoming data, simulating an unresponsive
server.
2025-03-18 16:28:18 +01:00
Michał Kępień 68fe9a5df5 Enable receiving chunked TCP DNS messages
A TCP DNS client may send its queries in chunks, causing
StreamReader.read() to return less data than previously declared by the
client as the DNS message length; even the two-octet DNS message length
itself may be split up into two single-octet transmissions.  Sending
data in chunks is valid client behavior that should not be treated as an
error.  Add a new helper method for reading TCP data in a loop, properly
distinguishing between chunked queries and client disconnections.  Use
the new method for reading all TCP data from clients.
2025-03-18 16:28:18 +01:00
Michał Kępień 8c3f673f37 Extend TCP logging
Emit more log messages from TCP connection handling code and extend
existing ones to improve debuggability of servers using asyncserver.py.
2025-03-18 16:28:18 +01:00
Michał Kępień 748ed4259b Handle connection resets during reading
A TCP peer may reset the connection at any point, but asyncserver.py
currently only handles connection resets when it is sending data to the
client.  Handle connection resets during reading in the same way.
2025-03-18 16:28:18 +01:00
Michał Kępień a956947fba Refactor AsyncDnsServer._handle_tcp()
Split up AsyncDnsServer._handle_tcp() into a set of smaller methods to
improve code readability.
2025-03-18 16:28:18 +01:00
Michał Kępień e4c3186a7c Gracefully handle TCP client disconnections
Prevent premature client disconnections during reading from triggering
unhandled exceptions in TCP connection handling code.
2025-03-18 16:28:18 +01:00
Michał Kępień 5764a9d660 Simplify peer address formatting
Add a helper class, Peer, which holds the <host, port> tuple of a
connection endpoint and gets pretty-printed when formatted as a string.
This enables passing instances of this new class directly to logging
functions, eliminating the need for the AsyncDnsServer._format_peer()
helper method.
2025-03-18 16:28:18 +01:00
Nicki Křížek a2042e603e chg: ci: Allow re-run of the shotgun jobs to reduce false positives
The false positive rate is about 10-20 % when evaluating shotgun results
from a single run. Attempt to reduce the false positive rate by allowing
a re-run of failed jobs.

Merge branch 'nicki/ci-shotgun-reduce-false-positives' into 'main'

See merge request isc-projects/bind9!10271
2025-03-18 09:29:10 +00:00
Nicki Křížek 5eab352478 Allow re-run of the shotgun jobs to reduce false positive
The false positive rate is about 10-20 % when evaluating shotgun results
from a single run. Attempt to reduce the false positive rate by allowing
a re-run of failed jobs.

While there is a slight risk that barely noticable decreases in
performance might slip by more easily in MRs, they'd still likely pop up
during nightly or pre-release testing.

Also increase the tolerance threshold for DoH latency comparisons, as
those tests often experience increased jitter in the tail end latencies.
2025-03-18 10:19:32 +01:00
Nicki Křížek 7f8226a039 Adjust the load factor for shotgun:tcp test
With the slightly decreased load for the TCP test, the results appear to
be a little bit more stable.
2025-03-18 10:19:32 +01:00
Michał Kępień 192627db10 chg: test: Use isctest.asyncserver in the "qmin" test
Replace custom DNS servers used in the "qmin" system test with new code
based on the isctest.asyncserver module.  The revised code employs zone
files and a limited amount of custom logic, which massively improves
test readability and maintainability, extends logging, and fixes
non-compliant replies sent by some of the custom servers in response to
certain queries (e.g. AA=0 in authoritative empty non-terminal
responses, non-glue address records in ADDITIONAL section).

Merge branch 'michal/qmin-asyncserver' into 'main'

See merge request isc-projects/bind9!10195
2025-03-18 05:55:17 +00:00
Michał Kępień dfd37918d6 Broaden vulture exclude glob for ans.py servers
The vulture tool seems to be unable to follow how the parent classes
defined in bin/tests/system/qmin/qmin_ans.py use mandatory properties
specified by child classes in bin/tests/system/qmin/ans*/ans.py.  Make
the tool ignore not just ans.py servers, but also *_ans.py utility
modules above the ansX/ subdirectories to prevent false positives about
unused code from causing CI pipeline failures.
2025-03-18 06:19:01 +01:00
Michał Kępień f413ddbe5f Ignore .hypothesis files created by system tests
Some versions of the Hypothesis Python library - notably the one
included in stock OS repositories for Ubuntu 20.04 Focal Fossa - cause a
.hypothesis file to be created in a Python script's working directory
when the hypothesis module is present in its import chain.  Ignore such
files by adding them to the list of expected test artifacts to prevent
pytest teardown checks from failing due to these files appearing in the
file system after running system tests.
2025-03-18 06:19:01 +01:00
Michał Kępień a799dd04ad Fix PYTHONPATH set for ans.py servers by start.pl
Commit 6c010a5644 caused the PYTHONPATH
environment variable to be set for ans.py servers started using
start.pl.  However, no system test has actually used the new
isctest.asyncserver module since that change was applied, so it has not
been noticed until now that including the source directory in PYTHONPATH
is only sufficient for in-tree builds.  Include the build directory
instead of the source directory in the PYTHONPATH environment variable
set for ans.py servers started by start.pl so that they work correctly
for both in-tree and out-of-tree builds.
2025-03-18 06:19:01 +01:00
Michał Kępień 7faa34c6ee Use isctest.asyncserver in the "qmin" test
Replace custom DNS servers used in the "qmin" system test with new code
based on the isctest.asyncserver module.  The revised code employs zone
files and a limited amount of custom logic, which massively improves
test readability and maintainability, extends logging, and fixes
non-compliant replies sent by some of the custom servers in response to
certain queries (e.g. AA=0 in authoritative empty non-terminal
responses, non-glue address records in ADDITIONAL section).
2025-03-18 06:19:01 +01:00
Ondřej Surý 575a2e5f11 rem: dev: Cleanup BIND 8 compatibility code
There was some code in dns_resolver unit meant to keep compatibility with BIND 8 breaking the DNS protocol.  These should not be needed anymore.

Merge branch 'ondrej/resolver-bind-8-cleanup' into 'main'

See merge request isc-projects/bind9!10270
2025-03-18 00:12:31 +00:00
Ondřej SurýandEvan Hunt 0d9f58b745 Remove a kludge to process non-authoritative CNAME response
A BIND 8 server could return a non-authoritative answer when a CNAME is
followed.  This is no longer handled as a valid answer.
2025-03-17 23:23:24 +00:00
Ondřej SurýandEvan Hunt 05d6542e6d Remove the kludges for records in the bad sections
There were kludges to help process responses from authoritative servers
giving RRs in wrong sections (mentioning BIND 8).  These should just go
away and such responses should not be processed.
2025-03-17 23:23:24 +00:00
Ondřej SurýandEvan Hunt ff73d37f69 Small cleanup in dns_adb unit 2025-03-17 23:23:24 +00:00
Michal Nowak 9d9e9d9cb1 chg: ci: Disable linkcheck on dl.acm.org
The check fails with the following error for some time:

    403 Client Error: Forbidden for url: https://dl.acm.org/doi/10.1145/1315245.1315298

Merge branch 'mnowak/linkcheck-disable-dl-acm-org' into 'main'

See merge request isc-projects/bind9!10272
2025-03-17 17:07:40 +00:00
Michal Nowak 1ab889ee21 Disable linkcheck on dl.acm.org
The check fails with the following error for some time:

    403 Client Error: Forbidden for url: https://dl.acm.org/doi/10.1145/1315245.1315298
2025-03-17 17:39:36 +01:00
Arаm Sаrgsyаn ae2fd7ef15 new: dev: Implement -T cookiealwaysvalid
When `-T cookiealwaysvalid` is passed to `named`, DNS cookie checks for
the incoming queries always pass, given they are structurally correct.

Merge branch 'aram/new-named-minus-T-option-of-cookiealwaysvalid' into 'main'

See merge request isc-projects/bind9!10232
2025-03-17 11:36:57 +00:00
Aram Sargsyan 4e75a20b6a Test -T cookiealwaysvalid
Add a check in the "cookie" system test to make sure that the new
'-T cookiealwaysvalid' option works.
2025-03-17 10:42:47 +00:00
Aram Sargsyan 807ef8545d Implement -T cookiealwaysvalid
When -T cookiealwaysvalid is passed to named, DNS cookie checks for
the incoming queries always pass, given they are structurally correct.
2025-03-17 10:42:47 +00:00
Mark Andrews 06427720f7 fix: dev: Add missing locks when returning addresses
Add missing locks in dns_zone_getxfrsource4 et al.  Addresses CID 468706, 468708, 468741, 468742, 468785, and 468778.

Cleanup dns_zone_setxfrsource4 et al to now return void.

Remove double copies with dns_zone_getprimaryaddr and dns_zone_getsourceaddr.

Closes #4933

Merge branch '4933-add-missing-locks-when-returning-addresses' into 'main'

See merge request isc-projects/bind9!9485
2025-03-15 06:04:34 +00:00
Mark Andrews d0a59277fb Add missing locks when returning addresses
Add missing locks in dns_zone_getxfrsource4 et al. Addresses CID
468706, 468708, 468741, 468742, 468785 and 468778.

Cleanup dns_zone_setxfrsource4 et al to now return void.

Remove double copies with dns_zone_getprimaryaddr and dns_zone_getsourceaddr.
2025-03-15 04:51:59 +00:00
Evan Hunt a8dd267bd0 fix: nil: Add new convenience functions to classify rdata types
- `dns_rdatatype_ismulti()` returns true if a given type can have
  multiple answers: ANY, RRSIG, or SIG.
- `dns_rdatatype_issig()` returns true for a signature: RRSIG or SIG.
- `dns_rdatatype_isaddr()` returns true for an address: A or AAAA.
- `dns_rdatatype_isalias()` returns true for an alias: CNAME or DNAME.

Code has been modified to use these functions where applicable.

These and all similar functions (e.g., `dns_rdatatype_ismeta()`, `dns_rdatatype_issingleton()`, etc) are now `static inline` functions defined in `rdata.h`.

Merge branch 'each-rdatatype-functions' into 'main'

See merge request isc-projects/bind9!10216
2025-03-15 01:26:35 +00:00
Evan Hunt 606d30796e use new dns_rdatatype classification functions
modify code to use dns_rdatatype_ismulti(), dns_rdatatype_issig(),
dns_rdatatype_isaddr(), and dns_rdatatype_isalias() where applicable.
2025-03-15 00:27:54 +00:00
Evan Hunt 37ff0aa9c0 convert rdatatype classification routines to inline
turn the dns_rdatatype_is*() functions into static inline
functions in rdata.h.
2025-03-15 00:27:54 +00:00
Evan Hunt 1c51d44d82 add new functions to classify rdata types
- dns_rdatatype_ismulti() returns true if a given type can have
  multiple answers: ANY, RRSIG, or SIG.
- dns_rdatatype_issig() returns true for a signature: RRSIG or SIG.
- dns_rdatatype_isaddr() returns true for an address: A or AAAA.
- dns_rdatatype_isalias() returns true for an alias: CNAME or DNAME.
2025-03-15 00:27:54 +00:00
Evan Hunt 3b0b658a52 fix: dev: step() could ignore rollbacks
The `step()` function (used for stepping to the prececessor or successor of a database node) could overlook a node if there was an rdataset that was marked IGNORE because it had been rolled back, covering an active rdataset under it.

Closes #5170

Merge branch '5170-step-ignores-rollback' into 'main'

See merge request isc-projects/bind9!10103
2025-03-14 23:19:36 +00:00
Evan Hunt ecde0ea2d7 add a unit test with an empty node
the db_test unit test now looks up an empty nonterminal node
to exercise the behavior of the step() function in qpzone.
2025-03-14 23:19:17 +00:00
Evan Hunt 7d98aba3ac add a unit test to check database rollback
check that a database rollback works and the correct
(original) data is found on lookup.
2025-03-14 23:19:17 +00:00
Evan Hunt 24eaff7adc qpzone.c:step() could ignore rollbacks
the step() function (used for stepping to the prececessor or
successor of a database node) could overlook a node because
there was an rdataset marked IGNORE because it had been rolled
back, covering an active rdataset under it.
2025-03-14 23:19:17 +00:00
Evan Hunt 025ef4d7b8 fix: dev: Fix handling of revoked keys
When a key is revoked, its key ID changes due to the inclusion of the "revoked" flag. A collision between this changed key ID
and an unrelated public-only key could cause a crash in `dnssec-signzone`.

Closes #5231

Merge branch '5231-fix-keyid-collision' into 'main'

See merge request isc-projects/bind9!10233
2025-03-14 22:26:36 +00:00
Evan Hunt 9cfe9f5eb7 fix handling of revoked keys
when a key is revoked its key ID changes, due to the inclusion
of the "revoke" flag. a collision between this changed key ID and
that of an unrelated public-only key could cause a crash in
dnssec-signzone.
2025-03-14 22:25:44 +00:00
Mark Andrews e6c07b3386 fix: test: Tune many types tests in reclimit test
The `I:checking that lifting the limit will allow everything to get
cached (20)` test was failing due to the TTL of the records being
too short for the elapsed time of the test.  Raise the TTL to fix
this and adjust other tests as needed.

Closes #5206

Merge branch '5206-tune-last-sub-test-of-reclimit' into 'main'

See merge request isc-projects/bind9!10177
2025-03-14 05:28:01 +00:00
Mark Andrews 1a58bd2113 Tune many types tests in reclimit test
The 'I:checking that lifting the limit will allow everything to get
cached (20)' test was failing due to the TTL of the records being
too short for the elapsed time of the test.  Raise the TTL to fix
this and adjust other tests as needed.
2025-03-14 02:03:50 +00:00
Mark Andrews 42799ae81f fix: usr: QNAME minimization could leak the query type
When performing QNAME minimization, `named` now sends an NS query for the original query name, before sending the final query. This prevents the parent zone from learning the original query type, in the event that the query name is a delegation point.

For example, when looking up an address record for `example.com`, NS queries are now sent to the servers for both `com` and `example.com`, before the address query is sent to the servers for `example.com`.  Previously, an address query would have been sent to the servers for `com`.

Closes #4805

Merge branch '4805-missing-qname-ns-query-when-using-qname-minimisation' into 'main'

See merge request isc-projects/bind9!9155
2025-03-14 02:02:52 +00:00
Mark Andrews de519cd1c9 Don't leak the original QTYPE to parent zone
When performing QNAME minimization, named now sends an NS
query for the original QNAME, to prevent the parent zone from
receiving the QTYPE.

For example, when looking up example.com/A, we now send NS queries
for both com and example.com before sending the A query to the
servers for example.com.  Previously, an A query for example.com
would have been sent to the servers for com.

Several system tests needed to be adjusted for the new query pattern:

- Some queries in the serve-stale test were sent to the wrong server.
- The synthfromdnssec test could fail due to timing issues; this
  has been addressed by adding a 1-second delay.
- The cookie test could fail due to the a change in the count of
  TSIG records received in the "check that missing COOKIE with a
  valid TSIG signed response does not trigger TCP fallback" test case.
- The GL #4652 regression test case in the chain system test depends
  on a particular query order, which no longer occurs when QNAME
  minimization is active. We now disable qname-minimization
  for that test.
2025-03-14 01:01:26 +00:00
Mark Andrews 496f7963cd Fix handling of ISC_R_TIMEOUT in resume_qmin()
If a timeout occurs when sending a QMIN query, QNAME
minimization should be disabled. This now causes a hard
failure in strict mode, or a fallback to non-minimized queries
in relaxed mode.
2025-03-14 01:01:26 +00:00
Mark Andrews 98fc14dc75 Exempt QNAME minimization queries from fetches-per-zone
The calling fetch has already called fcount_incr() for this zone;
calling it again for a QMIN query results in double counting.

When resuming after a QMIN query is answered, however, we do now
ensure before continuing that the fetches-per-zone limit has not
been exceeded.
2025-03-14 01:01:26 +00:00
Mark Andrews 3397212df3 new: usr: dig can now display the received BADVERS message during negotiation
Dig +showbadvers now displays the received BADVERS message and 
continues the EDNS version negotiation.  Previously to see the
BADVERS message +noednsneg had to be specified which terminated the
EDNS negotiation.  Additionally the specified EDNS value (+edns=value)
is now used when making all the initial queries with +trace. i.e EDNS
version negotiation will be performed with each server when performing
the trace.

Closes #5234

Merge branch '5234-have-dig-display-the-badvers-message' into 'main'

See merge request isc-projects/bind9!10234
2025-03-14 00:45:20 +00:00
Mark Andrews 947ca25663 check that dig +showbadvers works 2025-03-13 21:36:14 +00:00
Mark Andrews 6c271f6328 Add "+showbadvers" to dig and reset EDNS version
Add "+showbadvers" to display the BADVERS response similarly
to "+showbadcookie".  Additionally reset the EDNS version to
the requested version in "dig +trace" so that EDNS version
negotiation can be tested at all levels of the trace rather
that just when requesting the root nameservers.
2025-03-13 21:36:14 +00:00
Matthijs Mekking 6ac4cfb948 fix: usr: Ensure max-clients-per-query is at least clients-per-query
If the `max-clients-per-query` option is set to a lower value than `clients-per-query`, the value is adjusted to match `clients-per-query`.

Closes #5224

Merge branch '5224-raise-max-clients-per-query-to-be-at-least' into 'main'

See merge request isc-projects/bind9!10241
2025-03-13 13:02:48 +00:00
Matthijs Mekking f6f9645ed1 Raise max-clients-per-query to be at least
In the case where 'clients-per-query' is larger than
'max-clients-per-query', raise 'max-clients-per-query' so that
'clients-per-query' equals 'max-clients-per-query' and log a warning
that this is what happened.
2025-03-13 13:02:28 +00:00
Matthijs Mekking 1f674ef42e Test new max-clients-per-query log warning
Make sure the new warning is logged.
2025-03-13 13:02:28 +00:00
Matthijs Mekking f50753f303 Update max-clients-per-query documentation
The new intended behavior is that 'max-clients-per-query' value is
raised to equal 'clients-per-query' if it is lower.
2025-03-13 13:02:28 +00:00
Colin Vidal 45ee3715e1 new: usr: Add support for EDE 20 (Not Authoritative)
Support was added for EDE codes 20 (Not Authoritative) when client requests recursion (RD) but the server has recursion disabled.

RFC 8914 mention EDE 20 should also be returned if the client doesn't have the RD bit set (and recursion is needed) but it doesn't apply for
BIND as BIND would try to resolve from the "deepest" referral in AUTHORITY section. For example, if the client asks for "www.isc.org/A" but the server only knows the root domain, it will return NOERROR but no answer for "www.isc.og/A", just the list of other servers to ask.

See #1836

Merge branch '1836-not-authoritative' into 'main'

See merge request isc-projects/bind9!10228
2025-03-13 11:56:37 +00:00
Colin Vidal 7f613c207f add system test covering EDE 20
Add system test to cover extended DNS error 20 (Not authoritative).
2025-03-13 11:16:01 +01:00
Colin Vidal 24ffbdcfea add support for EDE 20 (Not Authoritative)
Extended DNS Error message EDE 20 (Not Authoritative) is now sent when
client request recursion (RD) but the server has recursion disabled.

RFC 8914 mention EDE 20 should also be returned if the client doesn't
have the RD bit set (and recursion is needed) but it doesn't apply for
BIND as BIND would try to resolve from the "deepest" referral in
AUTHORITY section. For example, if the client asks for "www.isc.org/A"
but the server only knows the root domain, it will returns NOERROR but
no answer for "www.isc.og/A", just the list of other servers to ask.
2025-03-13 11:16:01 +01:00
Colin Vidal e66dc07c68 new: usr: Add support for EDE 7 and EDE 8
Support was added for EDE codes 7 (Signature Expired) and 8 (Signature Not Yet Valid) which might occur during DNSSEC validation.

See #2715

Merge branch '2715-expired-future-keys' into 'main'

See merge request isc-projects/bind9!10225
2025-03-13 10:13:36 +00:00
Colin Vidal e763d6637f add system tests covering EDE 7 and 8
Add DNSSEC system tests to cover extended DNS error 7 (Signature
Expired) and 8 (Signature Not Yet Valid).
2025-03-13 09:57:09 +01:00
Colin Vidal 334ea1269f add support for EDE 7 and 8
Extended DNS Error messages EDE 7 (expired key) and EDE 8 (validity
period of the key not yet started) are now sent in case of such DNSSEC
validation failures.

Refactor the existing validator extended error APIs in order to make it
easy to have a consisdent extra info (with domain/type) in the various
use case (i.e. when the EDE depends on validator state,
validate_extendederror or when the EDE doesn't depend of any state but
can be called directly in a specific flow).
2025-03-13 09:57:09 +01:00
Matthijs Mekking 3309863c97 fix: test: Take into account key collisions in ksr system test
Closes #5229

Merge branch '5229-ksr-system-test-can-fail-on-key-collision' into 'main'

See merge request isc-projects/bind9!10238
2025-03-13 08:19:05 +00:00
Matthijs Mekking 8b3d2e5633 ksr: Take into account key collisions
When generating new key pairs, one test checks if existing keys that
match the time bundle are selected, rather than extra keys being
generated. Part of the test is to check the verbose output, counting
the number of "Selecting" and "Generating" occurences. But if there
is a key collision, the ksr tool will output that the key already
exists and includes the substring "already exists, or might collide
with another key upon revokation.  Generating a new key".

So substract by one the generated counter if there is a "collide"
occurrence.
2025-03-13 08:18:50 +00:00
Matthijs Mekking 3973c2e8c3 fix: dev: Fix CID 544147: Code maintainability issues (UNUSED_VALUE)
Assigning value "NULL" to "newstr", but that stored value is overwritten
before it can be used.

Setting "newstr" to NULL does not have any effect, so the line can
safely be removed.

Closes #5227

Merge branch '5227-cid-544147' into 'main'

See merge request isc-projects/bind9!10239
2025-03-13 08:18:35 +00:00
Matthijs Mekking ecef45bf18 Fix CID 544147
Assigning value "NULL" to "newstr", but that stored value is overwritten
before it can be used.

Setting "newstr" to NULL does not have any effect, so the line can
safely be removed.
2025-03-12 16:39:36 +01:00
Andoni Duarte 33a0cc9823 chg: doc: Set up version for BIND 9.21.7
Merge branch 'andoni/set-up-version-for-bind-9.21.7' into 'main'

See merge request isc-projects/bind9!10237
2025-03-12 13:07:00 +00:00
Andoni Duarte Pintado bd711bb839 Update BIND version to 9.21.7-dev 2025-03-12 12:09:35 +01:00
Andoni Duarte Pintado 21ca763bca Update BIND version for release 2025-03-11 11:37:59 +01:00
Andoni Duarte 474b7a04f1 new: doc: Prepare documentation for BIND 9.21.6
Merge branch 'andoni/prepare-documentation-for-bind-9.21.6' into 'v9.21.6-release'

See merge request isc-private/bind9!784
2025-03-11 10:10:19 +00:00
Andoni Duarte Pintado 5dfcedd52d Tweak and reword relase notes 2025-03-11 10:46:21 +01:00
Andoni Duarte Pintado 7c308c2298 Prepare release notes for BIND 9.21.6 2025-03-11 10:46:21 +01:00
Andoni Duarte Pintado f0b5f0cbce Generate changelog for BIND 9.21.6 2025-03-11 10:46:21 +01:00
Ondřej Surý b652d5327c fix: dev: Revert "Delete dead nodes when committing a new version"
This reverts commit 67255da4b3, reversing
changes made to 74c9ff384e.

Closes #5169

Merge branch '5169-revert-qpzone-delete-dead-nodes' into 'main'

See merge request isc-projects/bind9!10224
2025-03-05 17:25:20 +00:00
Ondřej Surý 1e4695510a Revert "fix: dev: Delete dead nodes when committing a new version"
This reverts commit 67255da4b3, reversing
changes made to 74c9ff384e.
2025-03-05 17:46:54 +01:00
Arаm Sаrgsyаn db5166ab99 fix: dev: Fix a bug in get_request_transport_type()
When `dns_remote_done()` is true, calling `dns_remote_curraddr()` asserts.
Add a `dns_remote_curraddr()` check before calling `dns_remote_curraddr()`.

Closes #5215

Merge branch '5215-assert-in-dns_remote_curraddr-fix' into 'main'

See merge request isc-projects/bind9!10222
2025-03-05 13:17:28 +00:00
Aram Sargsyan 6cd9e4f67c Fix a bug in get_request_transport_type()
When dns_remote_done() is true, calling dns_remote_curraddr() asserts.
Add a dns_remote_curraddr() check before calling dns_remote_curraddr().
2025-03-05 12:18:11 +00:00
Ondřej Surý 4ba1ccfa2e chg: dev: Cleanup parts of the isc_mem API
This MR changes custom attach/detach implementation with refcount macros, replaces isc_mem_destroy() with isc_mem_detach(), and does various small cleanups.

Merge branch 'ondrej/cleanup-isc_mem-api' into 'main'

See merge request isc-projects/bind9!9456
2025-03-05 11:20:21 +00:00
Ondřej Surý 1fae6ccea1 Add the call function tracking to isc_mem API
As we already track __func__, __FILE__, __LINE__ triplet in most places,
add the function tracking to the isc_mem tracking API.
2025-03-05 11:17:17 +01:00
Ondřej Surý eab9fc22e7 Replace attach/detach in isc_mem with refcount implementation
The isc_mem API is one of the most commonly used APIs that didn't
used ISC_REFCOUNT_DECL and ISC_REFCOUNT_IMPL macros.  Replace the
implementation of isc_mem_attach(), isc_mem_detach() and
isc_mem_destroy() with the respective macros.

This also removes the legacy isc_mem_destroy() functionality that would
check whether all references had been detached from the memory context
as it doesn't work reliably when using the call_rcu() API.  Instead of
doing this individually, call isc_mem_checkdestroyed(stderr) from the
isc_mem_destroy() macro to keep the extra check that all contexts were
freed when the program is exiting.
2025-03-05 11:17:17 +01:00
Ondřej Surý 552cf64a70 Replace isc_mem_destroy() with isc_mem_detach()
Remove legacy isc_mem_destroy() and just use isc_mem_detach() as
isc_mem_destroy() doesn't play well with call_rcu API.
2025-03-05 11:17:17 +01:00
Michal Nowak f28020265c chg: ci: Move FreeBSD jobs to AWS autoscalers
Merge branch 'mnowak/freebsd-aws-autoscaling' into 'main'

See merge request isc-projects/bind9!10214
2025-03-05 09:25:52 +00:00
Michal Nowak e0df774ca0 Move FreeBSD jobs to AWS autoscalers
From technical reasons --with-readline=libedit is not being tested on
FreeBSD anymore as it's hard to have anchors both unified and specific.
2025-03-05 09:25:21 +00:00
Mark Andrews fd48df20f3 new: dev: Add digest methods for SIG and RRSIG
ZONEMD digests RRSIG records and potentially digests SIG record. Add digests
methods for both record types.

Closes #5219

Merge branch '5219-add-digest-methods-for-sig-and-rrsig' into 'main'

See merge request isc-projects/bind9!10217
2025-03-05 09:18:32 +00:00
Mark Andrews 006c5990ce Implement digest_sig and digest_rrsig for ZONEMD
ZONEMD needs to be able to digest SIG and RRSIG records.  The signer
field can be compressed in SIG so we need to call dns_name_digest().
While for RRSIG the records the signer field is not compressed the
canonical form has the signer field downcased (RFC 4034, 6.2).  This
also implies that compare_rrsig needs to downcase the signer field
during comparison.
2025-03-05 18:05:12 +11:00
Ondřej Surý 4e68dbf194 fix: dev: Fix the foundname vs dcname madness in qpcache_findzonecut()
The qpcache_findzonecut() accepts two "foundnames": 'foundname' and
'dcname' could be NULL.  Originally, when 'dcname' would be NULL, the
'dcname' would be set to 'foundname' which basically means that we were
copying the .ndata over itself for no apparent reason.

Merge branch 'ondrej/refactor-qpcache_findzonecut' into 'main'

See merge request isc-projects/bind9!10049
2025-03-05 06:49:59 +00:00
Ondřej SurýandEvan Hunt 303c20caf8 Fix the foundname vs dcname madness in qpcache_findzonecut()
The qpcache_findzonecut() accepts two "foundnames": 'foundname' and
'dcname' could be NULL.  Originally, when 'dcname' would be NULL, the
'dcname' would be set to 'foundname'.  Then code like this was present:

    result = find_deepest_zonecut(&search, node, nodep, foundname,
                                  rdataset,
                                  sigrdataset DNS__DB_FLARG_PASS);
    dns_name_copy(foundname, dcname);

Which basically means that we are copying the .ndata over itself for no
apparent reason.  Cleanup the dcname vs foundname usage.

Co-authored-by: Evan Hunt <each@isc.org>
Co-authored-by: Ondřej Surý <ondrej@isc.org>
2025-03-05 07:49:46 +01:00
Alessio Podda d388063466 chg: nil: Cleanup dns_opcode_t
Refactor to cleanup the `dns_opcode_t` enum.

Merge branch 'alessio/cleanup-dns_opcode_t' into 'main'

See merge request isc-projects/bind9!10165
2025-03-04 18:30:48 +00:00
alessio 87776a51ae Cleanup dns_opcode_t
Make dns_opcode_t refer directly to the underlying enum, and use
attributes to ensure the underlying enum is the same size as uint16_t.
2025-03-04 18:35:14 +01:00
Ondřej Surý 22b5442722 fix: dev: Sync the TSAN CC, CFLAGS and LDFLAGS in the respdiff:tsan job
Merge branch 'ondrej/sync-tsan-options-in-gitlab-ci' into 'main'

See merge request isc-projects/bind9!10209
2025-03-04 14:49:42 +00:00
Ondřej Surý 23394afa9e Sync the TSAN CC, CFLAGS and LDFLAGS in the respdiff:tsan job 2025-03-04 15:49:20 +01:00
Mark Andrews f3458fdf43 fix: dev: Call isc__iterated_hash_initialize in isc__work_cb
isc_iterated_hash didn't work in offloaded threads as the per thread
initialisation has not been done.  This has been fixed.

Closes #5214

Merge branch '5214-call-isc__iterated_hash_initialize-in-isc__work_cb' into 'main'

See merge request isc-projects/bind9!10206
2025-03-04 13:33:43 +00:00
Mark Andrews 988dc57c8c Call isc__iterated_hash_initialize
The iterated hash implementation needs to be initialised
on the worker thread.  Also clean it up after we are done.
2025-03-04 12:54:39 +00:00
Evan Hunt 6320586df0 fix: dev: When recording an rr trace, use libtool
When a system test is run with the `USE_RR` environment variable set to 1, an `rr` trace is now correctly generated for each instance of `named`.

Closes #5079

Merge branch '5079-fix-rr' into 'main'

See merge request isc-projects/bind9!10197
2025-03-04 09:16:02 +00:00
Evan Hunt 00d7c7c346 when recording an rr trace, use libtool
when running a system test with the USE_RR environment
variable set to 1, an rr trace is generated for named.
because rr wasn't run using libtool --mode=execute, the
trace would actually be generated for the wrapper script
generated by libtool, not for the actual named binary.
2025-03-04 09:15:52 +00:00
Ondřej Surý daa9c17905 rem: dev: Remove check for the mandatory IPv6 support
IPv6 Advanced Socket API (:rfc:`3542`) is a hard requirement, remove the
autoconf check to speed up the ./configure run a little bit.

Merge branch 'ondrej/remove-check-for-mandatory-IPv6' into 'main'

See merge request isc-projects/bind9!10201
2025-03-03 19:41:00 +00:00
Ondřej Surý 4024e0d5c1 Remove check for the mandatory IPv6 support
IPv6 Advanced Socket API (:rfc:`3542`) is a hard requirement, remove the
autoconf check to speed up the ./configure run a little bit.
2025-03-03 18:20:06 +01:00
Artem Boldariev c8104daf8d fix: dev: Post [CVE-2024-12705] Performance Drop Fixes, Part 2
This merge request addresses several key performance bottlenecks in the DoH (DNS over HTTPS) implementation by introducing significant optimizations and improvements.

### Key Improvements

1. **Simplification and Optimisation of `http_do_bio()` Function**:
   - The code flow in the `http_do_bio()` function has been significantly simplified.
2. **Flushing HTTP Write Buffer on Outgoing DNS Messages**:
   - The buffer is flushed and a send operation is performed when there is an outgoing DNS message.
3. **Bumping Active Streams Processing Limit**:
   - The total number of active streams has been increased to 60% of the total streams limit.

These changes collectively enhance the performance and reliability of the DoH implementation, making it more efficient and robust for handling high-load scenarios, particularly noticeable in long runs (>= 1h) of `stress:long:rpz:doh+udp:linux:*` tests. It improves perf. for tests for BIND 9.18, but it likely will have a positive but less pronounced effect on newer versions as well.

In essence, the merge request fixes three bottlenecks stacked upon each other.

*It is a logical continuation of the merge requests !10109.* !10109, unfortunately, did not completely [address the performance drop in 9.18](https://gitlab.isc.org/isc-projects/bind9/-/pipelines/221545) for longer runs of the stress test. This merge request [addresses that](https://gitlab.isc.org/isc-projects/bind9/-/pipelines/223661).

**P.S.**

The origin of the fixes is, in fact, the branch in !10193. So this MR is a ... *forward port* of them.

Merge branch 'artem-doh-performance-drop-post-fix' into 'main'

See merge request isc-projects/bind9!10192
2025-03-03 10:10:33 +00:00
Artem Boldariev eaad0aefe6 DoH: Bump the active streams processing limit
This commit bumps the total number of active streams (= the opened
streams for which a request is received, but response is not ready) to
60% of the total streams limit.

The previous limit turned out to be too tight as revealed by
longer (≥1h) runs of "stress:long:rpz:doh+udp:linux:*" tests.
2025-03-03 11:32:29 +02:00
Artem Boldariev 217a1ebd79 DoH: remove obsolete INSIST() check
The check, while not active by default, is not valid since the commit
8b8f4d500d.

See 'if (total == 0) { ...' below branch to understand why.
2025-03-03 11:32:11 +02:00
Artem Boldariev c5f7968856 DoH: Flush HTTP write buffer on an outgoing DNS message
Previously, the code would try to avoid sending any data regardless of
what it is unless:

a) The flush limit is reached;
b) There are no sends in flight.

This strategy is used to avoid too numerous send requests with little
amount of data. However, it has been proven to be too aggressive and,
in fact, harms performance in some cases (e.g., on longer (≥1h) runs
of "stress:long:rpz:doh+udp:linux:*").

Now, additionally to the listed cases, we also:

c) Flush the buffer and perform a send operation when there is an
outgoing DNS message passed to the code (which is indicated by the
presence of a send callback).

That helps improve performance for "stress:long:rpz:doh+udp:linux:*"
tests.
2025-03-03 11:32:11 +02:00
Artem Boldariev 0e1b02868a DoH: Limit the number of delayed IO processing requests
Previously, a function for continuing IO processing on the next UV
tick was introduced (http_do_bio_async()). The intention behind this
function was to ensure that http_do_bio() is eventually called at
least once in the future. However, the current implementation allows
queueing multiple such delayed requests needlessly. There is currently
no need for these excessive requests as http_do_bio() can requeue them
if needed. At the same time, each such request can lead to a memory
allocation, particularly in BIND 9.18.

This commit ensures that the number of enqueued delayed IO processing
requests never exceeds one in order to avoid potentially bombarding IO
threads with the delayed requests needlessly.
2025-03-03 11:32:11 +02:00
Artem Boldariev 0956fb9b9e DoH: Simplify http_do_bio()
This commit significantly simplifies the code flow in the
http_do_bio() function, which is responsible for processing incoming
and outgoing HTTP/2 data. It seems that the way it was structured
before was indirectly caused by the presence of the missing callback
calls bug, fixed in 8b8f4d500d.

The change introduced by this commit is known to remove a bottleneck
and allows reproducible and measurable performance improvement for
long runs (>= 1h) of "stress:long:rpz:doh+udp:linux:*" tests.

Additionally, it fixes a similar issue with potentially missing send
callback calls processing and hardens the code against use-after-free
errors related to the session object (they can potentially occur).
2025-03-03 11:32:11 +02:00
Ondřej Surý 239712df16 rem: dev: Cleanup isc/util.h header and friends
Cleanup short list macros from <isc/util.h>, remove two unused headers, move locking macros to respective headers and use only the C11 static assertion.

Merge branch 'ondrej/cleanup-short-macros' into 'main'

See merge request isc-projects/bind9!10196
2025-03-01 06:35:58 +00:00
Ondřej Surý ce7879c924 Remove STATIC_ASSERT variants in favor of the C11 variant
Previously, a gcc < 4.6 shim for _Static_assert() was included.  Such an
old compiler is not supported now anyway, so the macro variant has been
removed in favor of a single definition using _Static_assert().
2025-03-01 07:33:53 +01:00
Ondřej Surý 534069e048 Move locking macros into individual headers
Previously, the LOCK()/UNLOCK() and friends macros were defined in the
isc/util.h header.  Those macros were moved to their respective headers
as those would have to be included anyway if that particular lock was in
use.
2025-03-01 07:33:51 +01:00
Ondřej Surý 901637c25c Remove superflous header includes from isc/util.h header
Formerly, isc/util.h would pull a few extra headers (isc/list.h,
isc/attributes.h, isc/result.h and errno.h).  These includes were
removed in favor of including them directly when used.
2025-03-01 07:33:40 +01:00
Ondřej Surý c5075a9a61 Remove convenience list macros from isc/util.h
The short convenience list macros were used very sparingly and
inconsistenly in the code base.  As the consistency is prefered over
the convenience, all shortened list macro were removed in favor of
their ISC_LIST API targets.
2025-03-01 07:33:40 +01:00
Ondřej Surý 2aa70fff76 Remove unused isc_mutexblock and isc_condition units
The isc_mutexblock and isc_condition units were no longer in use and
were removed.
2025-03-01 07:33:09 +01:00
Arаm Sаrgsyаn e02d73e7e3 fix: usr: Fix a bug in the statistics channel when querying zone transfers information
When querying zone transfers information from the statistics channel there was a rare possibility that `named` could terminate unexpectedly if a zone transfer was in a state when transferring from all the available primary servers had failed earlier. This has been fixed.

Closes #5198

Merge branch '5198-dns_remote_curraddr-bug-fix' into 'main'

See merge request isc-projects/bind9!10182
2025-02-28 15:34:05 +00:00
Aram Sargsyan 7293cb0612 Fix a bug in dns_zone_getprimaryaddr()
When all the addresses were already iterated over, the
dns_remote_curraddr() function asserts. So before calling it,
dns_zone_getprimaryaddr() now checks the address list using the
dns_remote_done() function. This also means that instead of
returning 'isc_sockaddr_t' it now returns 'isc_result_t' and
writes the primary's address into the provided pointer only when
returning success.
2025-02-28 15:33:37 +00:00
Michal Nowak 67d37a365e new: ci: Check dangling symlinks in the repository
Merge branch 'mnowak/check-dangling-symlinks' into 'main'

See merge request isc-projects/bind9!10120
2025-02-28 11:05:46 +00:00
Michal Nowak de0598cbc3 Link ChangeLog to doc/arm/changelog.rst
Currently, the ChangeLog file is a dangling symlink pointing to the
removed CHANGES file. Fix the link by pointing to doc/arm/changelog.rst.
2025-02-28 11:02:28 +00:00
Michal Nowak f3087f1299 Check dangling symlinks in the repository 2025-02-28 11:02:28 +00:00
Aydın Mercan 1b3e7f52ec rem: dev: remove log initialization checks from named
Logging initialization check is now redundant as there is a default global log context created during libisc's constructor.

`isc_log` calls can safely be made at any time outside libisc's constructor.

Merge branch 'aydin/remove-log-check' into 'main'

See merge request isc-projects/bind9!10186
2025-02-28 10:32:20 +00:00
Aydın Mercan 68bbf151a4 remove log initialization checks from named
This check is now redundant as there is a default global log context
created during libisc's constructor.
2025-02-28 10:31:46 +00:00
Michal Nowak 58ea2b1b22 fix: ci: Fix Clang TSAN reports
Disabling dynamic tags ensures the Clang symbolizer creates a valid TSAN
report. For consistency, also add the option to gcc:tsan so they are
both on the same footing.

Closes #5149

Merge branch '5149-fix-tsan-flags' into 'main'

See merge request isc-projects/bind9!10185
2025-02-28 10:15:06 +00:00
Michal Nowak ac9eec6327 Fix Clang TSAN reports
Disabling new dynamic ELF tags ensures the Clang symbolizer creates
valid TSAN reports. For consistency, also add the option to gcc:tsan so
they are both on the same footing.
2025-02-28 09:01:46 +01:00
Michal Nowak 6e2272d769 No need to delete the "only" keyword in generate-tsan-stress-jobs.py
29fd756408 replaced "only" with "rules" in
.gitlab-ci.yml but forgot to drop the removal from here, hence the
script was broken.
2025-02-28 09:01:46 +01:00
Evan Hunt 462f367d87 fix: nil: Complete the fix for the import_rdataset() crash
The fix in !10172 was incomplete; there were still some code paths in the resolver that could set the dns_fetchresponse `result` field to the wrong value when the rdataset type was CNAME or DNAME.

Closes #5201

Merge branch '5201-eresult-fix' into 'main'

See merge request isc-projects/bind9!10178
2025-02-27 19:01:02 +00:00
Evan Hunt 9ebeb60174 fix the fetchresponse result for CNAME/DNAME
the fix in commit 1edbbc32b4 was incomplete; the wrong
event result could also be set in cache_name() and validated().
2025-02-27 19:00:27 +00:00
Aydın Mercan 3de629d6b7 chg: dev: unify fips handling to isc_crypto and make the toggle one way
Since algorithm fetching is handled purely in libisc, FIPS mode toggling
can be purely done in within the library instead of provider fetching in
the binary for OpenSSL >=3.0.

Disabling FIPS mode isn't a realistic requirement and isn't done
anywhere in the codebase. Make the FIPS mode toggle enable-only to
reflect the situation.

Merge branch 'aydin/fips-in-crypto' into 'main'

See merge request isc-projects/bind9!9920
2025-02-27 15:29:07 +00:00
Aydın Mercan f4ab4f07e3 unify fips handling to isc_crypto and make the toggle one way
Since algorithm fetching is handled purely in libisc, FIPS mode toggling
can be purely done in within the library instead of provider fetching in
the binary for OpenSSL >=3.0.

Disabling FIPS mode isn't a realistic requirement and isn't done
anywhere in the codebase. Make the FIPS mode toggle enable-only to
reflect the situation.
2025-02-27 17:37:43 +03:00
Nicki Křížek ce47cb3ab6 new: ci: Run shotgun tests on MRs
Execute DNS Shotgun performance tests on the regular MRs and compare the changes they introduce against the MR diff base. The results are evaluated automatically - the shotgun jobs will fail if thresholds for CPU/memory/latency difference is exceeded.

Merge branch 'nicki/ci-shotgun-eval' into 'main'

See merge request isc-projects/bind9!10127
2025-02-27 13:30:26 +00:00
Nicki Křížek 29fd756408 Replace deprecated only/except with rules in .gitlab-ci.yml
The keyword rules allows more flexible and complex conditions when
deciding whether to create the job and also makes it possible run tweak
variables or job properties depending on arbitraty rules. Since it's
not possible to combine only/except and rules together, replace all
uses of only/except to avoid any potential future issues.
2025-02-27 14:26:38 +01:00
Nicki Křížek 4214c1e8a7 Run shotgun tests on MRs
If the shotgun tests are executed for MRs, compare it against the MR's
base rather than the previous release. Only fail the job in case the
performance drops (pass on performance improvements).

Note that start_in optimization was removed, since it isn't properly
supported with rules as of February 2025
(https://gitlab.com/gitlab-org/gitlab/-/issues/424203). Without this
optimization, container test images are likely to be re-built
unnecessarily when testing different protocols. A workaround for the
.gitlab-ci.yml exists, but the extra complexity doesn't seem justified.
The container image builds might change or be optimized in the future,
so let's just go with the build duplication for now.
2025-02-27 14:26:38 +01:00
Arаm Sаrgsyаn 23c1fbc609 fix: usr: Fix TTL issue with ANY queries processed through RPZ "passthru"
Answers to an "ANY" query which were processed by the RPZ "passthru"
policy had the response-policy's `max-policy-ttl` value unexpectedly
applied. This has been fixed.

Closes #5187

Merge branch '5187-rpz-passthru-any-type-ttl-bug-fix' into 'main'

See merge request isc-projects/bind9!10176
2025-02-27 09:19:12 +00:00
Aram Sargsyan 98ff3a4432 Test that RPZ "passthru" doesn't alter the answer's TTL with ANY queries
Expand the test_rpz_passthru_logging() check in the "rpzextra" system
test to check the answer's TTL values with ANY type queries.
2025-02-27 08:36:49 +00:00
Aram Sargsyan 5633dc90d3 Fix TTL issue with ANY queries processed through RPZ "passthru"
Answers to an "ANY" query which are processed by the RPZ "passthru"
policy have the response-policy's 'max-policy-ttl' value unexpectedly
applied. Do not change the records' TTL when RPZ uses a policy which
does not alter the answer.
2025-02-27 08:36:49 +00:00
Evan Hunt 49ccbe857a fix: dev: Validating ADB fetches could cause a crash in import_rdataset()
Previously, in some cases, the resolver could return rdatasets of type CNAME or DNAME without the result code being set to `DNS_R_CNAME` or `DNS_R_DNAME`. This could trigger an assertion failure in the ADB. The resolver error has been fixed.

Closes #5201

Merge branch '5201-adb-cname-error' into 'main'

See merge request isc-projects/bind9!10172
2025-02-26 20:34:27 +00:00
Evan Hunt 1edbbc32b4 set eresult based on the type in ncache_adderesult()
when the caching of a negative record failed because of the
presence of a positive one, ncache_adderesult() could override
this to ISC_R_SUCCESS. this could cause CNAME and DNAME responses
to be handled incorrectly.  ncache_adderesult() now sets the result
code correctly in such cases.
2025-02-25 21:29:19 -08:00
Mark Andrews a102e504c3 fix: doc: Fix command to generate KSR in DNSSEC guide
Merge branch 'doc-fix-dnssec-ksr-request-command' into 'main'

See merge request isc-projects/bind9!10087
2025-02-26 01:51:33 +00:00
Doug FreedandMark Andrews 0dd046d007 Fix command to generate KSR in DNSSEC guide 2025-02-26 01:08:52 +00:00
Evan Hunt 764eb65cf6 fix: dev: Remove 'target' from dns_adb
When a server name turns out to be a CNAME or DNAME, the ADB does not use it, but the `dns_adbname` structure still stored a copy of the target name. This is unnecessary and the code has been removed.

Merge branch 'each-remove-adb-target' into 'main'

See merge request isc-projects/bind9!10149
2025-02-26 00:43:46 +00:00
Evan Hunt 6c2af2ae3b remove 'target' from dns_adb
the target name parameter to dns_adb_createfind() was always passed as
NULL, so we can safely remove it.

relatedly, the 'target' field in the dns_adbname structure was never
referenced after being set.  the 'expire_target' field was used, but
only as a way to check whether an ADB name represents a CNAME or DNAME,
and that information can be stored as a single flag.
2025-02-26 00:43:21 +00:00
Mark Andrews 6af708f3b0 fix: usr: Fix dual-stack-servers configuration option
The dual-stack-servers configuration option was not working as expected; the specified servers were not being used when they should have been, leading to resolution failures. This has been fixed.

Closes #5019

Merge branch '5019-dual-stack-servers-wasn-t-working-in-all-cases' into 'main'

See merge request isc-projects/bind9!9708
2025-02-26 00:22:30 +00:00
Mark Andrews 14ab1629b7 Removing now unneeded priming queries
Now that fctx_try is being called when adb returns DNS_ADB_NOMOREADDRESSES
we don't need these priming queries for the dual-stack-servers test
to succeed.
2025-02-25 23:47:46 +00:00
Mark Andrews f98a8331aa Fix dual-stack-servers
Named was stopping nameserver address resolution attempts too soon
when dual stack servers are configured.  Dual stack servers are
used when there are *not* addresses for the server in a particular
address family so find->status == DNS_ADB_NOMOREADDRESSES is not a
sufficient stopping condition when dual stack servers are available.
Call fctx_try to see if the alternate servers can be used.
2025-02-25 23:47:46 +00:00
Mark Andrews 1bc7016d7a fix: usr: Relax private DNSKEY and RRSIG constraints
DNSKEY, KEY, RRSIG and SIG constraints have been relaxed to allow empty key and signature material after the algorithm identifier for PRIVATEOID and PRIVATEDNS. It is arguable whether this falls within the expected use of these types as no key material is shared and the signatures are ineffective but these are private algorithms and they can be totally insecure.

Closes #5167

Merge branch '5167-relax-private-dnskey-constraints' into 'main'

See merge request isc-projects/bind9!10083
2025-02-25 23:39:40 +00:00
Mark Andrews b048190e23 Relax private DNSKEY and RRSIG constraints
DNSKEY, KEY, RRSIG and SIG constraints have been relaxed to allow
empty key and signature material after the algorithm identifier for
PRIVATEOID and PRIVATEDNS. It is arguable whether this falls within
the expected use of these types as no key material is shared and
the signatures are ineffective but these are private algorithms and
they can be totally insecure.
2025-02-25 22:59:46 +00:00
Evan Hunt 5604d3a44e fix: dev: Prevent a reference leak when using plugins
The `NS_QUERY_DONE_BEGIN` and `NS_QUERY_DONE_SEND` plugin hooks could cause a reference leak if they returned `NS_HOOK_RETURN` without cleaning up the query context properly.

Closes #2094

Merge branch '2094-plugin-reference-leak' into 'main'

See merge request isc-projects/bind9!9971
2025-02-25 22:40:55 +00:00
Evan Hunt ae37ef45ff wrap ns_client_error() for unit testing
When testing, the client object doesn't have a proper
netmgr handle, so ns_client_error() needs to be a no-op.
2025-02-25 22:40:48 +00:00
Evan Hunt c2e4358267 prevent a reference leak from the ns_query_done hooks
if the NS_QUERY_DONE_BEGIN or NS_QUERY_DONE_SEND hook is
used in a plugin and returns NS_HOOK_RETURN, some of the
cleanup in ns_query_done() can be skipped over, leading
to reference leaks that can cause named to hang on shut
down.

this has been addressed by adding more housekeeping
code after the cleanup: tag in ns_query_done().
2025-02-25 22:40:48 +00:00
Mark Andrews 26f8ee7229 fix: usr: dnssec-signzone needs to check for a NULL key when setting offline
dnssec-signzone could dereference a NULL key pointer when resigning a zone.  This has been fixed.

Closes #5192

Merge branch '5192-dnssec-signzone-needs-to-check-for-a-null-key-when-setting-offline' into 'main'

See merge request isc-projects/bind9!10161
2025-02-25 22:22:30 +00:00
Mark Andrews 1784e4a9ae Check if key is NULL before dereferencing it 2025-02-25 21:45:37 +00:00
Evan Hunt e16560a650 fix: dev: Simplify some dns_name API calls
Several functions in the `dns_name` module have had parameters removed, that were rarely or never used:
- `dns_name_fromtext()` and `dns_name_concatenate()` no longer take a target buffer.
- `dns_name_towire()` no longer takes a compression offset pointer; this is now part of the compression context.
- `dns_name_towire()` with a `NULL` compression context will copy name data directly into a buffer with no processing.

Merge branch 'each-simplify-names' into 'main'

See merge request isc-projects/bind9!10152
2025-02-25 21:34:31 +00:00
Evan Hunt 2f7e6eb019 allow NULL compression context in dns_name_towire()
passing NULL as the compression context to dns_name_towire()
copies the uncompressed name data directly into the target buffer.
2025-02-25 12:53:25 -08:00
Evan Hunt afb424c9b6 simplify dns_name_fromtext() interface
previously, dns_name_fromtext() took both a target name and an
optional target buffer parameter, which could override the name's
dedicated buffer. this interface is unnecessarily complex.

we now have two functions, dns_name_fromtext() to convert text
into a dns_name that has a dedicated buffer, and dns_name_wirefromtext()
to convert text into uncompressed DNS wire format and append it to a
target buffer.

in cases where it really is necessary to have both, we can use
dns_name_fromtext() to load the dns_name, then dns_name_towire()
to append the wire format to the target buffer.
2025-02-25 12:53:25 -08:00
Evan Hunt cf098cf10d avoid the 'target' buffer in dns_name_fromtext()
dns_name_fromtext() stores the converted name in the 'name'
passed to it, and optionally also copies it in wire format to
a buffer 'target'. this makes the interface unnecessarily
complex, and could be simplified by having a different function
for each purpose. as a first step, remove uses of the target
buffer in calls to dns_name_fromtext() where it wasn't actually
needed.
2025-02-25 12:53:25 -08:00
Evan Hunt a6986f6837 remove 'target' parameter from dns_name_concatenate()
the target buffer passed to dns_name_concatenate() was never
used (except for one place in dig, where it wasn't actually
needed, and has already been removed in a prior commit).
we can safely remove the parameter.
2025-02-25 12:53:25 -08:00
Evan Hunt 2edefbad4a remove the 'name_coff' parameter in dns_name_towire()
this parameter was added as a (minor) optimization for
cases where dns_name_towire() is run repeatedly with the
same compression context, as when rendering all of the rdatas
in an rdataset. it is currently only used in one place.

we now simplify the interface by removing the extra parameter.
the compression offset value is now part of the compression
context, and can be activated when needed by calling
dns_compress_setmultiuse(). multiuse mode is automatically
deactivated by any subsequent call to dns_compress_permitted().
2025-02-25 12:53:25 -08:00
Evan Hunt 1d7a9ebeda remove the namebuf and onamebuf buffers in dig
lookup->namebuf and lookup->onamebuf were not necessary and
have been removed.
2025-02-25 12:53:25 -08:00
Evan Hunt cf981ab13b fix: dev: Save time when creating a slab from another slab
The `dns_rdataslab_fromrdataset()` function creates a slab from an rdataset. If the source rdataset already uses a slab, then no processing is necessary; we can just copy the existing slab to a new location.

Closes #5188

Merge branch '5188-optimize-makeslab' into 'main'

See merge request isc-projects/bind9!10162
2025-02-25 18:37:49 +00:00
Evan Hunt 94a96a7a0e save time when creating a slab from another slab
the dns_rdataslab_fromrdataset() function creates a slab
from an rdataset. if the source rdataset already uses a slab,
then no processing is necessary; we can just copy the existing
slab to a new location.
2025-02-25 18:37:35 +00:00
Ondřej Surý 796b662b92 fix: usr: Fix assertion failure when dumping recursing clients
Previously, if a new counter was added to the hashtable
while dumping recursing clients via the `rndc recursing`
command, and `fetches-per-zone` was enabled, an assertion
failure could occur. This has been fixed.

Closes #5200

Merge branch '5200-destroy-iterator-inside-the-rwlock' into 'main'

See merge request isc-projects/bind9!10164
2025-02-25 15:38:08 +00:00
Ondřej Surý 1e4fb53c61 Destroy the hashmap iterator inside the rwlock
Previously, the hashmap iterator for fetches-per-zone was destroy
outside the rwlock.  This could lead to an assertion failure due to a
timing race with the internal rehashing of the hashmap table as the
rehashing process requires no iterators to be running when rehashing the
hashmap table.  This has been fixed by moving the destruction of the
iterator inside the read locked section.
2025-02-25 13:36:37 +01:00
Ondřej Surý 24db1b1a8a chg:usr: Reduce memory used to store DNS names
The memory used to internally store the DNS names has been reduced.

Merge branch 'ondrej/experiment-no-offsets-in-dns_name' into 'main'

See merge request isc-projects/bind9!10140
2025-02-25 11:17:55 +00:00
Ondřej Surý 67e1df1a07 Squash set_offsets() and dns_name_offsets() into single function
The third argument to set_offsets() was only used in
dns_name_fromregion() and not really needed.  We can remove the third
argument and then manually check whether the last label is root label.
2025-02-25 12:17:34 +01:00
Ondřej Surý 79c3871a7b Remove target buffer from dns_name_downcase()
There was just a single use of passing an extra buffer to
dns_name_downcase() which have been replaced by simple call to
isc_ascii_lowercase() and the 'target' argument from dns_name_downcase()
function has been removed.
2025-02-25 12:17:34 +01:00
Ondřej Surý 3bb47bc6cd Remove MAKE_EMPTY() macro from dns_name unit
The MAKE_EMPTY() macro was clearing up the output variable in case of
the failure.  However, this was breaking the usual design pattern that
the output variables are left in indeterminate state or we don't touch
them at all when a failure occurs.  Remove the macro and change the
dns_name_downcase() to not touch the name contents until success.
2025-02-25 12:17:34 +01:00
Ondřej Surý 259600c837 Cleanup the usage of dns_offsets_t vs unsigned char * pointers
There was a back-and-forth between static arrays and the pointers to the
offsets.  Since we are now only using the static arrays, we can cleanup
the usage of the pointers that would previously point either to the
static array or name->offsets if available.
2025-02-25 12:17:34 +01:00
Ondřej Surý 1c22ab2ef7 Simplify name initializers
We no longer need to pass labels to DNS_NAME_INITABSOLUTE
and DNS_NAME_INITNONABSOLUTE.
2025-02-25 12:17:34 +01:00
Ondřej Surý 04c2c2cbc8 Simplify dns_name_init()
Remove the now-unused offsets parameter from dns_name_init().
2025-02-25 12:17:34 +01:00
Ondřej Surý 08e966df82 Remove offsets from the dns_name and dns_fixedname structures
The offsets were meant to speed-up the repeated dns_name operations, but
it was experimentally proven that there's actually no real-world
benefit.  Remove the offsets and labels fields from the dns_name and the
static offsets fields to save 128 bytes from the fixedname in favor of
calculating labels and offsets only when needed.
2025-02-25 12:17:34 +01:00
Alessio Podda 869168545a chg: nil: Remove unused symtab implementation
The old symtab implementation should have been removed in !9921, but it wasn't. This MR addresses that.

Merge branch 'alessio/cleanup-symtab-orphan-files' into 'main'

See merge request isc-projects/bind9!10122
2025-02-25 11:13:22 +00:00
alessio 45132df850 Remove unused symtab implementation
The old symtab implementation should have been removed in !9921 , but
it wasn't. This commit addresses that.
2025-02-25 11:29:58 +01:00
Alessio Podda 7fce7707db chg: usr: Drop malformed notify messages early instead of decompressing them
The DNS header shows if a message has multiple questions or invalid
NOTIFY sections. We can drop these messages early, right after parsing
the question. This matches RFC 9619 for multi-question messages and
Unbound's handling of NOTIFY. We still parse the question to include it in
our FORMERR response.

Add drop_msg_early() function to check for these conditions:
- Messages with more than one question, as required by RFC 9619
- NOTIFY query messages containing answer sections (like Unbound)
- NOTIFY messages containing authority sections (like Unbound)

Closes #5158, #3656

Merge branch '5158-early-formerr-on-bad-notify-or-bad-qdcount' into 'main'

See merge request isc-projects/bind9!10056
2025-02-25 10:29:00 +00:00
alessio 887502e37d Drop malformed notify messages early instead of decompressing them
The DNS header shows if a message has multiple questions or invalid
NOTIFY sections. We can drop these messages early, right after parsing
the question. This matches RFC 9619 for multi-question messages and
Unbound's handling of NOTIFY.
To further add further robustness, we include an additional check for
unknown opcodes, and also drop those messages early.

Add early_sanity_check() function to check for these conditions:
- Messages with more than one question, as required by RFC 9619
- NOTIFY query messages containing answer sections (like Unbound)
- NOTIFY messages containing authority sections (like Unbound)
- Unknown opcodes.
2025-02-25 10:40:38 +01:00
Mark Andrews 4e0b62bf10 fix: test: Handle example3.db being modified in upforwd system test
The zone file for example3 (ns1/example3.db) can be modified in the
upforwd test as example3 is updated as part of the test.  Whether
the zone is written out or not by the end of the test is timing
dependent.  Rename ns1/example3.db to ns1/example3.db.in and copy it to
ns1/example3.db in setup so we don't trigger post test changes checks.

Closes #5180

Merge branch '5180-create-example3-in-setup' into 'main'

See merge request isc-projects/bind9!10160
2025-02-25 06:16:45 +00:00
Mark Andrews afc4413862 Handle example3.db being modified in upforwd system test
The zone file for example3 (ns1/example3.db) can be modified in the
upforwd test as example3 is updated as part of the test.  Whether
the zone is written out or not by the end of the test is timing
dependent.  Rename ns1/example3.db to ns1/example3.db.in and copy
it to ns1/example3.db in setup so we don't trigger post test changes
checks.
2025-02-25 12:28:58 +11:00
Evan Hunt 02ef8ff01c fix: dev: Fix a logic error in cache_name()
A change in 6aba56ae8 (checking whether a rejected RRset was identical
to the data it would have replaced, so that we could still cache a
signature) inadvertently introduced cases where processing of a
response would continue when previously it would have been skipped.

Closes #5197

Merge branch '5197-cache_name-logic-error' into 'main'

See merge request isc-projects/bind9!10157
2025-02-24 23:39:23 +00:00
Evan Hunt d0fd9cbe3b Fix a logic error in cache_name()
A change in 6aba56ae8 (checking whether a rejected RRset was identical
to the data it would have replaced, so that we could still cache a
signature) inadvertently introduced cases where processing of a
response would continue when previously it would have been skipped.
2025-02-24 15:04:14 -08:00
Ondřej Surý c4868b5bd9 fix: dev: Acquire the database reference before possibly last node release
Acquire the database reference in the detachnode() to prevent the last
reference to be release while the NODE_LOCK being locked.  The NODE_LOCK
is locked/unlocked inside the RCU critical section, thus it is most
probably this should not pose a problem as the database uses call_rcu
memory reclamation, but this it is still safer to acquire the reference
before releasing the node.

Closes #5194

Merge branch '5194-fix-assertion-failure-while-reference-counting-qpdb' into 'main'

See merge request isc-projects/bind9!10155
2025-02-24 22:24:51 +00:00
Ondřej Surý d1ef6a93c1 Acquire the database reference before possibly last node release
Acquire the database refernce in the detachnode() to prevent the last
reference to be release while the NODE_LOCK being locked.  The NODE_LOCK
is locked/unlocked inside the RCU critical section, thus it is most
probably this should not pose a problem as the database uses call_rcu
memory reclamation, but this it is still safer to acquire the reference
before releasing the node.
2025-02-24 20:05:56 +01:00
Ondřej Surý 6e0c1f151c chg: dev: Move the library initialization and shutdown to executables
Instead of relying on unreliable order of execution of the library
constructors and destructors, move them to individual binaries.  The
advantage is that the execution time and order will remain constant and
will not depend on the dynamic load dependency solver.

Merge branch 'ondrej/move-the-constructors-destructors-to-binaries' into 'main'

See merge request isc-projects/bind9!10069
2025-02-22 18:06:21 +00:00
Ondřej Surý e99627a006 Suppressing memory leaks produced by clang LeakSanitizer
Previously, we were suppressing only the memory leaks in the GCC
LeakSanitizer job, but those suppression are also needed by the Clang.
2025-02-22 18:17:18 +01:00
Ondřej Surý 4917ffa61b Explicitly create and shutdown the call_rcu_thread
As the default_call_rcu_thread can't be forced to flush all the work
during the executable shutdown, create one call_rcu_thread explicitly
and assign it to the all created threads.

This allows this explicit call_rcu_thread to be unassociated from the
main thread and freed before the executable destructor exits.
2025-02-22 16:19:01 +01:00
Ondřej Surý f5c204ac3e Move the library init and shutdown to executables
Instead of relying on unreliable order of execution of the library
constructors and destructors, move them to individual binaries.  The
advantage is that the execution time and order will remain constant and
will not depend on the dynamic load dependency solver.

This requires more work, but that was mitigated by a simple requirement,
any executable using libisc and libdns, must include <isc/lib.h> and
<dns/lib.h> respectively (in this particular order).  In turn, these two
headers must not be included from within any library as they contain
inlined functions marked with constructor/destructor attributes.
2025-02-22 16:19:00 +01:00
Ondřej Surý 5d0c347e75 fix:usr: Dump the active resolver fetches from dns_resolver_dumpfetches()
Previously, active resolver fetches were only dumped when the `fetches-per-zone` configuration option was enabled. Now, active resolver fetches are dumped along with the number of `clients-per-server` counters per resolver fetch.

Merge branch 'ondrej/make-dns_resolver_dumpfetches-dump-fetches' into 'main'

See merge request isc-projects/bind9!10107
2025-02-21 21:26:18 +00:00
Ondřej Surý c6b0368b21 Dump the fetches from dns_resolver_dumpfetches()
Previously, the dns_resolver_dumpfetches() would go over the fetch
counters.  Alas, because of the earlier optimization, the fetch counters
would be increased only when fetches-per-zone was not 0, otherwise the
whole counting was skipped for performance reasons.

Instead of using the auxiliary fetch counters hash table, use the real
hash table that stores the fetch contexts to dump the ongoing fetches to
the recursing file.

Additionally print more information about the fetch context like start
and expiry times, number of fetch responses, number of queries and count
of allowed and dropped fetches.
2025-02-21 22:25:43 +01:00
Ondřej Surý 479c366c2b fix:usr: Fix the data race causing a permanent active client increase
Previously, a data race could cause a newly created fetch context for a new client to be used
before it had been fully initialized, which would cause the query to become stuck; queries for the same
data would be either paused indefinitely or dropped because of
the `clients-per-query` limit. This has been fixed.

Closes #5053

Merge branch '5053-fetch-context-create-data-race' into 'main'

See merge request isc-projects/bind9!10146
2025-02-21 21:24:56 +00:00
Ondřej Surý cf078fadeb Fix the fetch context hash table lock ordering
The order of the fetch context hash table rwlock and the individual
fetch context was reversed when calling the release_fctx() function.
This was causing a problem when iterating the hash table, and thus the
ordering has been corrected in a way that the hash table rwlock is now
always locked on the outside and the fctx lock is the interior lock.
2025-02-21 22:05:43 +01:00
Ondřej Surý b9e3cd5d2a Add isc_timer_running() function to check status of timer
In the next commit, we need to know whether the timer has been started
or stopped.  Add isc_timer_running() function that returns true if the
timer has been started.
2025-02-21 22:05:43 +01:00
Michał Kępień e127ba0041 chg: doc: Update Sphinx and sphinx_rtd_theme
Update Sphinx-related Python packages to their current versions pulled
in by "pip install sphinx-rtd-theme" run in a fresh virtual environment.

Merge branch 'michal/update-sphinx-and-sphinx_rtd_theme' into 'main'

See merge request isc-projects/bind9!10138
2025-02-21 13:47:08 +00:00
Michał Kępień eae270cc32 Update Sphinx and sphinx_rtd_theme
Update Sphinx-related Python packages to their current versions pulled
in by "pip install sphinx-rtd-theme" run in a fresh virtual environment.
2025-02-21 14:41:25 +01:00
Arаm Sаrgsyаn 5ba811bea2 fix: usr: Fix RPZ race condition during a reconfiguration
With RPZ in use, `named` could terminate unexpectedly because of a race condition when a reconfiguration command was received using `rndc`. This has been fixed.

Closes #5146

Merge branch '5146-rpz-reconfig-bug-fix' into 'main'

See merge request isc-projects/bind9!10079
2025-02-21 11:45:00 +00:00
Aram Sargsyan 3ea2fbc238 Fix RPZ bug when resuming a query during a reconfiguration
After a reconfiguration the old view can be left without a valid
'rpzs' member, because when the RPZ is not changed during the named
reconfiguration 'rpzs' "migrate" from the old view into the new
view, so when a query resumes it can find that 'qctx->view->rpzs'
is NULL which query_resume() currently doesn't expect to happen if
it's recursing and 'qctx->rpz_st' is not NULL.

Fix the issue by adding a NULL-check. In order to not split the log
message to two different log messages depending on whether
'qctx->view->rpzs' is NULL or not, change the message to not log
the RPZ policy's "version" which is just a runtime counter and is
most likely not very useful for the users.
2025-02-21 11:10:15 +00:00
Ondřej Surý 7471ef5e1a chg:nil: Cleanup the isc_counter unit
The isc_counter_create() doesn't need the return value (it was always
ISC_R_SUCCESS), use the macros to implement the reference counting,
little style cleanup, and expand the unit test.

Merge branch 'ondrej/cleanup-isc_counter-unit' into 'main'

See merge request isc-projects/bind9!10126
2025-02-21 09:51:49 +00:00
Ondřej Surý 77ec2a6c22 Cleanup the isc_counter unit
The isc_counter_create() doesn't need the return value (it was always
ISC_R_SUCCESS), use the macros to implement the reference counting,
little style cleanup, and expand the unit test.
2025-02-21 09:51:42 +00:00
Mark Andrews f0785fedf1 fix: usr: Remove NSEC/DS/NSEC3 RRSIG check from dns_message_parse
Previously, when parsing responses, named incorrectly rejected responses without matching RRSIG records for NSEC/DS/NSEC3 records in the authority section. This rejection, if appropriate, should have been left for the validator to determine and has been fixed.

Closes #5185

Merge branch '5185-remove-rrsig-check-from-dns_message_parse' into 'main'

See merge request isc-projects/bind9!10125
2025-02-21 02:57:46 +00:00
Mark Andrews 4271d93f00 Check insecure response with missing RRSIG in authority
This scenario should succeed but wasn't due rejection of the
message at the message parsing stage.
2025-02-20 20:31:07 +00:00
Mark Andrews 83159d0a54 Remove check for missing RRSIG records from getsection
Checking whether the authority section is properly signed should
be left to the validator.  Checking in getsection (dns_message_parse)
was way too early and resulted in resolution failures of lookups
that should have otherwise succeeded.
2025-02-20 20:31:07 +00:00
Arаm Sаrgsyаn d78ebff861 fix: usr: Implement sig0key-checks-limit and sig0message-checks-limit
Previously a hard-coded limitation of maximum two key or message
verification checks were introduced when checking the message's
SIG(0) signature. It was done in order to protect against possible
DoS attacks. The logic behind choosing the number 2 was that more
than a single key should only be required during key rotations, and
in that case two keys are enough. But later it became apparent that
there are other use cases too where even more keys are required, see
issue number #5050 in GitLab.

This change introduces two new configuration options for the views,
`sig0key-checks-limit` and `sig0message-checks-limit`, which define how
many keys are allowed to be checked to find a matching key, and how
many message verifications are allowed to take place once a matching
key has been found. The latter protects against expensive cryptographic
operations when there are keys with colliding tags and algorithm
numbers, with default being 2, and the former protects against a bit
less expensive key parsing operations and defaults to 16.

Closes #5050

Merge branch '5050-sig0-let-considering-more-than-two-keys' into 'main'

See merge request isc-projects/bind9!9967
2025-02-20 14:24:17 +00:00
Aram Sargsyan 5861c10dfb Document sig0key-checks-limit and sig0message-checks-limit 2025-02-20 13:35:14 +00:00
Aram Sargsyan 716b936045 Implement sig0key-checks-limit and sig0message-checks-limit
Previously a hard-coded limitation of maximum two key or message
verification checks were introduced when checking the message's
SIG(0) signature. It was done in order to protect against possible
DoS attacks. The logic behind choosing the number two was that more
than one key should only be required only during key rotations, and
in that case two keys are enough. But later it became apparent that
there are other use cases too where even more keys are required, see
issue number #5050 in GitLab.

This change introduces two new configuration options for the views,
sig0key-checks-limit and sig0message-checks-limit, which define how
many keys are allowed to be checked to find a matching key, and how
many message verifications are allowed to take place once a matching
key has been found. The latter protects against expensive cryptographic
operations when there are keys with colliding tags and algorithm
numbers, with default being 2, and the former protects against a bit
less expensive key parsing operations and defaults to 16.
2025-02-20 13:35:14 +00:00
Arаm Sаrgsyаn 742d379d88 fix: dev: Fix isc_quota bug
Running jobs which were entered into the isc_quota queue is the
responsibility of the isc_quota_release() function, which, when
releasing a previously acquired quota, checks whether the queue
is empty, and if it's not, it runs a job from the queue without touching
the 'quota->used' counter. This mechanism is susceptible to a possible
hangup of a newly queued job in case when between the time a decision
has been made to queue it (because used >= max) and the time it was
actually queued, the last quota was released. Since there is no more
quotas to be released (unless arriving in the future), the newly
entered job will be stuck in the queue.

Fix the issue by adding checks in both isc_quota_release() and
isc_quota_acquire_cb() to make sure that the described hangup does
not happen. Also see code comments.

Closes #4965

Merge branch '4965-isc_quota-bug-fix' into 'main'

See merge request isc-projects/bind9!10082
2025-02-20 12:19:46 +00:00
Aram Sargsyan c6529891bb Fix isc_quota bug
Running jobs which were entered into the isc_quota queue is the
responsibility of the isc_quota_release() function, which, when
releasing a previously acquired quota, checks whether the queue
is empty, and if it's not, it runs a job from the queue without touching
the 'quota->used' counter. This mechanism is susceptible to a possible
hangup of a newly queued job in case when between the time a decision
has been made to queue it (because used >= max) and the time it was
actually queued, the last quota was released. Since there is no more
quotas to be released (unless arriving in the future), the newly
entered job will be stuck in the queue.

Fix the wrong memory ordering for 'quota->used', as the relaxed
ordering doesn't ensure that data modifications made by one thread
are visible in other threads.

Add checks in both isc_quota_release() and isc_quota_acquire_cb()
to make sure that the described hangup does not happen. Also see
code comments.
2025-02-20 10:56:00 +00:00
Arаm Sаrgsyаn a282f1ba3f new: usr: Implement the min-transfer-rate-in configuration option
A new option 'min-transfer-rate-in <bytes> <minutes>' has been added
to the view and zone configurations. It can abort incoming zone
transfers which run very slowly due to network related issues, for
example. The default value is set to 10240 bytes in 5 minutes.

Closes #3914

Merge branch '3914-detect-and-restart-stalled-zone-transfers' into 'main'

See merge request isc-projects/bind9!9098
2025-02-20 10:31:47 +00:00
Aram Sargsyan c701b590e4 Expose the incoming transfers' rates in the statistics channel
Expose the average transfer rate (in bytes-per-second) during the
last full 'min-transfer-rate-in <bytes> <minutes>' minutes interval.
If no such interval has passed yet, then the overall average rate is
reported instead.
2025-02-20 09:32:55 +00:00
Aram Sargsyan b9c6aa24f8 Test the new min-transfer-rate-in configuration option
Add a new big zone, run a zone transfer in slow mode, and check
whether the zone transfer gets canceled because 100000 bytes are
not transferred in 5 seconds (as it's running in slow mode).
2025-02-20 09:32:55 +00:00
Aram Sargsyan f6dfff01ab Document the min-transfer-rate-in configuration option
Add a new section in ARM describing min-transfer-rate-in.
2025-02-20 09:32:55 +00:00
Aram Sargsyan 91ea156203 Implement the min-transfer-rate-in configuration option
This new option sets a minimum amount of transfer rate for
an incoming zone transfer that will abort a transfer, which
for some network related reasons run very slowly.
2025-02-20 09:32:55 +00:00
Evan Hunt fc3a4d6f89 fix: dev: Do not cache signatures for rejected data
The cache has been updated so that if new data is rejected - for example, because there was already existing data at a higher trust level - then its covering RRSIG will also be rejected.

Closes #5132

Merge branch '5132-improve-cd-behavior' into 'main'

See merge request isc-projects/bind9!9999
2025-02-20 02:12:12 +00:00
Evan Hunt e4652a0444 add a test with an inconsistent NS RRset
add a zone with different NS RRsets in the parent and child,
and test resolver and forwarder behavior with and without +CD.
2025-02-19 17:25:20 -08:00
Evan Hunt 6aba56ae89 Check whether a rejected rrset is different
Add a new dns_rdataset_equals() function to check whether two
rdatasets are equal in DNSSEC terms.

When an rdataset being cached is rejected because its trust
level is lower than the existing rdataset, we now check to see
whether the rejected data was identical to the existing data.
This allows us to cache a potentially useful RRSIG when handling
CD=1 queries, while still rejecting RRSIGs that would definitely
have resulted in a validation failure.
2025-02-19 17:25:20 -08:00
Evan Hunt 948f8d7a98 fix: dev: Clean up dns_rdataslab module
Rdata slabs used in the QP databases are usually prepended with a slab header, but are sometimes "raw", containing only the rdata and no header. Previously, to allow for them to be used both ways, functions that operated on them took a `reservelen` argument, which would be set to either the header length or to zero, and skipped over that many bytes at the beginning of the buffer. Most such functions were never used on the raw form. To make the code clearer, each of these functions now operates on full slabs with headers, and an alternate "raw" version of the function has been added in cases where that was needed.

In addition, the `dns_rdataslab_merge()` and `_subtract()` functions have been rewritten for clarity and efficiency, and a minor bug has been fixed in `dns_rdataslab_equal()` and `_equalx()`, which could cause an incorrect result if both slabs being compared had zero length.

Merge branch 'each-refactor-rdataslab' into 'main'

See merge request isc-projects/bind9!10084
2025-02-19 23:43:41 +00:00
Ondřej SurýandEvan Hunt 2fc32c105d Remove the "raw" version of the dns_slabheader API
The "raw" version of the header was used for the noqname and the closest
proofs to save around 152 bytes of the dns_slabheader_t while bringing
an additional complexity.  Remove the raw version of the dns_slabheader
API at the slight expense of having unused dns_slabheader_t data sitting
in front of the proofs.
2025-02-19 15:00:15 -08:00
Evan Hunt c2e19771ac refactor dns_rdataslab_subtract() for efficiency
reduce the number of rdata comparisons needed by walking
through the original slab once to determine whether the rdata
in it is duplicated in the slab to be subtracted, and then
write out the rdatas that aren't. previously, this was
done twice: once when determining the size of the target buffer
and then again when copying data into it.
2025-02-19 15:00:15 -08:00
Evan Hunt 1d5fe36136 refactor dns_rdataslab_merge() for efficiency
when merging two rdata slabs, we now check once to see
whether an item in the new slab has a duplicate in the
old. previously this was done twice; once to determine the
size of the target buffer required, and then again when
copying the data into it.

we also minimize the number of rdata comparisons necessary,
by remembering which items in the old slab have already been
found to be duplicates.
2025-02-19 15:00:15 -08:00
Evan Hunt ed83455c81 dns_slabheader_fromrdataset() -> dns_rdataset_getheader()
The function name dns_slabheader_fromrdataset() was too similar
to dns_rdataslab_fromrdataset(). Instead, we now have an rdataset
method 'getheader' which is implemented for slab-type rdatasets.

A new NOHEADER rdataset attribute is set for rdatasets using
raw slabs (i.e., noqname and closest encloser proofs); when
called on rdatasets with that flag set, dns_rdataset_getheader()
returns NULL.
2025-02-19 14:58:32 -08:00
Evan Hunt 82edec67a5 initialize header in dns_rdataslab_fromrdataset()
when dns_rdataslab_fromrdataset() is run, in addition to
allocating space for a slab header, it also partially
initializes it, setting the type match rdataset->type and
rdataset->covers, the trust to rdataset->trust, and the TTL to
rdataset->ttl.
2025-02-19 14:58:32 -08:00
Evan Hunt b4bde9bef4 clarify dns_rdataslab_fromrdataset()
there are now two functions for creating an rdataslab from an
rdataset: dns_rdataslab_fromrdataset() creates a full slab (including
space for a slab header), and dns_rdataslab_raw_fromrdataset() creates
a raw slab.
2025-02-19 14:58:32 -08:00
Evan Hunt f1ab7f199b refactor dns_rdataslab_merge() and _subtract()
these two functions have been refactored for clarity
and readability, with a more logical flow, added comments,
and less code duplication.
2025-02-19 14:58:32 -08:00
Evan Hunt 6908d1f9be more rdataslab refactoring
- there are now two functions for getting rdataslab size:
  dns_rdataslab_size() is for full slabs and dns_rdataslab_sizeraw()
  for raw slabs. there is no longer a need for a reservelen parameter.
- dns_rdataslab_count() also no longer takes a reservelen parameter.
  (currently it's never used for raw slabs, so there is no _countraw()
  function.)
- dns_rdataslab_rdatasize() has been removed, because
  dns_rdataslab_sizeraw() can do the same thing.
- dns_rdataslab_merge() and dns_rdataslab_subtract() both take
  slabheader parameters instead of character buffers, and the
  reservelen parameter has been removed.
2025-02-19 14:58:32 -08:00
Evan Hunt 4601d4299a fix and simplify dns_rdataset_equal() and _equalx()
if both rdataslabs being compared have zero length, return true.

also, since these functions are only ever called on slabheaders
with sizeof(dns_slabheader_t) as the reserve length, we can
simplify the API: remove the reservelen argument, and pass the
slabs as type dns_slabheader_t * instead of unsigned char *.
2025-02-19 14:58:32 -08:00
Ondřej SurýandEvan Hunt 15fe68e50d Add .up pointer to slabheader
The dns_slabheader object uses the 'next' pointer for two purposes.
In the first header for any given type, 'next' points to the first
header for the next type. But 'down' points to the next header of
the same type, and in that record, 'next' points back up.

This design made the code confusing to read.  We now use a union
so that the 'next' pointer can also be called 'up'.
2025-02-19 14:58:32 -08:00
Andoni Duarte Pintado 44026fc4ad Merge tag 'v9.21.5' 2025-02-19 17:46:17 +01:00
Artem Boldariev 3033d127d2 fix: dev: Post [CVE-2024-12705] Performance Drop Fixes
This merge request fixes a [performance drop](https://gitlab.isc.org/isc-projects/bind9/-/pipelines/216728) after merging the fixes for #4795, in particular in 9.18.

The MR [fixes the problem](https://gitlab.isc.org/isc-projects/bind9/-/pipelines/219825) without affecting performance for the newer versions, in particular for [the development version](https://gitlab.isc.org/isc-projects/bind9/-/pipelines/220619).

Merge branch 'artem-doh-performance-drop' into 'main'

See merge request isc-projects/bind9!10109
2025-02-19 16:39:36 +00:00
Artem Boldariev 2adabe835a DoH: http_send_outgoing() return value is not used
The value returned by http_send_outgoing() is not used anywhere, so we
make it not return anything (void). Probably it is an omission from
older times.
2025-02-19 17:52:36 +02:00
Artem Boldariev 8b8f4d500d DoH: Fix missing send callback calls
When handling outgoing data, there were a couple of rarely executed
code paths that would not take into account that the callback MUST be
called.

It could lead to potential memory leaks and consequent shutdown hangs.
2025-02-19 17:52:36 +02:00
Artem Boldariev a22bc2d7d4 DoH: change how the active streams number is calculated
This commit changes the way how the number of active HTTP streams is
calculated and allows it to scale with the values of the maximum
amount of streams per connection, instead of effectively capping at
STREAM_CLIENTS_PER_CONN.

The original limit, which is intended to define the pipelining limit
for TCP/DoT. However, it appeared to be too restrictive for DoH, as it
works quite differently and implements pipelining at protocol level by
the means of multiplexing multiple streams. That renders each stream
to be effectively a separate connection from the point of view of the
rest of the codebase.
2025-02-19 17:52:36 +02:00
Artem Boldariev 05e8a50818 DoH: Track the amount of in flight outgoing data
Previously we would limit the amount of incoming data to process based
solely on the presence of not completed send requests. That worked,
however, it was found to severely degrade performance in certain
cases, as was revealed during extended testing.

Now we switch to keeping track of how much data is in flight (or ready
to be in flight) and limit the amount of processed incoming data when
the amount of in flight data surpasses the given threshold, similarly
to like we do in other transports.
2025-02-19 17:52:36 +02:00
Evan Hunt 67255da4b3 fix: dev: Delete dead nodes when committing a new version
In the qpzone implementation of `dns_db_closeversion()`, if there are changed nodes that have no remaining data, delete them.

Closes #5169

Merge branch '5169-qpzone-delete-dead-nodes' into 'main'

See merge request isc-projects/bind9!10089
2025-02-18 22:54:42 +00:00
Evan Hunt e58ce19cf2 when committing a new qpzone version, delete dead nodes
if all data has been deleted from a node in the qpzone
database, delete the node too.
2025-02-18 14:22:38 -08:00
Evan Hunt 74c9ff384e rem: dev: Clean up unnecessary code in qpcache
Removed some code from the cache database implementation that was left over from before it and the zone database implementation were separated.

Merge branch 'each-qpcache-refactor' into 'main'

See merge request isc-projects/bind9!9991
2025-02-18 20:15:14 +00:00
Ondřej SurýandEvan Hunt ce9f6e68c3 Unify how we handle database version in the cache
Database versions are not used in cache databases. Some places in
qpcache.c required the version argument to be NULL; others marked it
as UNUSED. Unify all cases to require version to be NULL.
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt 2d53796e28 Clean up 'now' usage in the cache
Unify the way we handle the 'now' argument in the cache: when it's
set to zero by the caller, it is replaced with isc_stdtime_now().
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt 3b2fe808c4 Clean up the search part in qpcache_find()
Slightly refactor the header search in qpcache_find(), so the scope
level is reduced and the cname parts are logically grouped together.
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt bfb219ac2d Refactor the search in qpcache_findrdataset()
Add new related_headers() function that simplifies the code
flow in qpcache_findrdataset().  Also use check_stale_header() function
to remove code duplication.
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt cf66ba02a4 Refactor simple slabheader matching
Add a helper function both_headers() that unifies the slabheader
matching for simple type: it returns true when both the type and
the matching RRSIG have been found.
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt 4cd1dd8dd7 Add new helper maybe_update_headers() function
The new maybe_update_headers() function unifies the LRU updates to the
slabheaders that was scattered all over the place.  More calls to update
headers after bindrdatasets() were also added for completeness.
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt 4448f1adb2 Add bindrdatasets() function that binds both rdatasets
This removes code duplication between the dual bindrdataset() calls.  It
also unifies the handling as there were small differences between the
calls: one variant was checking for !NEGATIVE(found) condition and one
wasn't, and it is technically ok to do the check for all variants.
2025-02-18 20:15:00 +00:00
Ondřej SurýandEvan Hunt 53d9ef5bd0 Refactor check_stale_header() function
The check_stale_header() function now updates header_prev directly
so it doesn't have to be handled in the outer loop; it's always
set to the correct value of the previous header in the chain.
2025-02-18 20:15:00 +00:00
Evan Hunt b24981ea02 add missing "failed" message in digdelv test
there was a test case that could fail (and did) without logging
the fact.
2025-02-18 20:15:00 +00:00
Evan Hunt 5281c708d3 clean up unnecessary code in qpcache
some code was left in the cache database implementation after
it was separated from the zone database, and can be cleaned up
and refactored now:

- the DNS_SLABHEADERATTR_IGNORE flag is never set in the cache
- support for loading the cache from was removed, but the add()
  function still had a 'loading' flag that's always false
- two different macros were used for checking the
  DNS_SLABHEADERATTR_NONEXISTENT flag - EXISTS() and NONEXISTENT().
  it's clearer to just use EXISTS().
- the cache doesn't support versions, so it isn't necessary to
  walk down the 'down' pointer chain when iterating through the
  cache or looking for a header to update.  'down' now only points
  to records that are deleted from the cache but have not yet been
  purged from memory. this allows us to simplify both the iterator
  and the add() function.
2025-02-18 20:15:00 +00:00
Petr Špaček d34414c47b new: usr: Add HTTPS record query to host command line tool
The host command was extended to also query for the HTTPS RR type by default.

Merge branch 'feature/main/host-rr-https' into 'main'

See merge request isc-projects/bind9!8642
2025-02-18 14:56:39 +00:00
Petr MenšíkandPetr Špaček 82069a5700 Do HTTPS record query from host in addition
Unless explicitly specified type from host command, do fourth query for
type HTTPS RR. It is expected it will become more common and some
systems already query that record for every name.
2025-02-18 14:56:08 +00:00
Andoni Duarte Pintado ee913c1370 Update BIND version for release 2025-02-11 18:10:51 +01:00
Andoni Duarte e5f02d3a25 new: doc: Prepare documentation for BIND 9.21.5
Merge branch 'andoni/prepare-documentation-for-bind-9.21.5' into 'v9.21.5-release'

See merge request isc-private/bind9!778
2025-02-11 17:04:45 +00:00
Michał KępieńandAndoni Duarte Pintado da23a0c4e1 Update CVE checklist 2025-02-11 17:34:52 +01:00
Andoni Duarte Pintado 8a742d084f Tweak and reword release notes 2025-02-11 17:34:52 +01:00
Andoni Duarte Pintado b23b0d991a Prepare release notes for BIND 9.21.5 2025-02-11 17:34:52 +01:00
Andoni Duarte Pintado af174fe816 Generate changelog for BIND 9.21.5 2025-02-11 17:34:52 +01:00
467 changed files with 9177 additions and 7984 deletions
+128 -91
View File
@@ -56,6 +56,16 @@ variables:
# Some jobs may clean up the build artifacts unless this is set to 0.
CLEAN_BUILD_ARTIFACTS_ON_SUCCESS: 1
# DNS Shotgun performance testing defaults
SHOTGUN_ROUNDS: 1
SHOTGUN_DURATION: 120
# allow unlimited improvements against baseline
SHOTGUN_EVAL_THRESHOLD_CPU_MIN: '-inf'
SHOTGUN_EVAL_THRESHOLD_MEMORY_MIN: '-inf'
SHOTGUN_EVAL_THRESHOLD_RCODE_MAX: '+inf'
SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MIN: '-inf'
SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MIN: '-inf'
default:
# Allow all running CI jobs to be automatically canceled when a new
# version of a branch is pushed.
@@ -107,16 +117,55 @@ stages:
- runner-manager
- aarch64
# Autoscaling GitLab Runner on AWS EC2 (FreeBSD)
.freebsd-stress-amd64: &freebsd_stress_amd64
.freebsd-autoscaler-13-amd64-tags: &freebsd_autoscaler_13_amd64_tags
tags:
- bsd-stress-test
- aws
- amd64
- autoscaler
- aws
- bsd-stress-test-1
- shell
- stress-test
.freebsd-autoscaler-14-amd64-tags: &freebsd_autoscaler_14_amd64_tags
tags:
- amd64
- autoscaler
- aws
- bsd-stress-test-2
- shell
- stress-test
.freebsd-autoscaler-amd64: &freebsd_autoscaler_amd64
variables:
CC: clang
CFLAGS: "${CFLAGS_COMMON} -Og"
# Even though there's only one job per runtime environment, the GitLab
# "instance" executor insists on cloning the Git repository to a path that
# contains a variable number from zero to the "maximum concurrent instances
# count" allowed on the GitLab Runner. See the "0" directory in this
# example path: /home/ec2-user/builds/t1_4FZzvz/0/isc-projects/bind9/.git/.
#
# This is not a problem for isolated jobs like "stress" tests that depend
# on no other jobs. However, it is a problem for jobs that need other jobs'
# artifacts. For example, a system test job that has its Git repo cloned to
# the "/1/" sub-path will fail if it downloads build job artifacts that
# have ./configure output files with "/0/" in its sub-path recorded.
GIT_CLONE_PATH: "/home/ec2-user/builds/${CI_PROJECT_PATH}/"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE} --with-gssapi=/usr/local/bin/krb5-config"
# Autoscaling GitLab Runner on AWS EC2 (FreeBSD 13)
.freebsd-autoscaler-13-amd64: &freebsd_autoscaler_13_amd64
<<: *freebsd_autoscaler_amd64
<<: *freebsd_autoscaler_13_amd64_tags
# Autoscaling GitLab Runner on AWS EC2 (FreeBSD 14)
.freebsd-autoscaler-14-amd64: &freebsd_autoscaler_14_amd64
<<: *freebsd_autoscaler_amd64
<<: *freebsd_autoscaler_14_amd64_tags
### Docker Image Templates
@@ -204,14 +253,6 @@ stages:
### QCOW2 Image Templates
.freebsd-13-amd64: &freebsd_13_amd64_image
image: "freebsd-13.4-x86_64"
<<: *libvirt_amd64
.freebsd-14-amd64: &freebsd_14_amd64_image
image: "freebsd-14.2-x86_64"
<<: *libvirt_amd64
.openbsd-amd64: &openbsd_amd64_image
image: "openbsd-7.6-x86_64"
<<: *libvirt_amd64
@@ -219,31 +260,18 @@ stages:
### Job Templates
.api-pipelines-schedules-tags-triggers-web-triggering-rules: &api_pipelines_schedules_tags_triggers_web_triggering_rules
only:
- api
- pipelines
- schedules
- tags
- triggers
- web
rules:
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/'
- if: '$CI_COMMIT_TAG != null'
.api-pipelines-schedules-triggers-web-triggering-rules: &api_pipelines_schedules_triggers_web_triggering_rules
only:
- api
- pipelines
- schedules
- triggers
- web
rules:
- if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/'
.default-triggering-rules: &default_triggering_rules
only:
- api
- merge_requests
- pipelines
- schedules
- tags
- triggers
- web
rules:
- if: '$CI_PIPELINE_SOURCE =~ /^(api|merge_request_event|pipeline|schedule|trigger|web)$/'
- if: '$CI_COMMIT_TAG != null'
.precheck: &precheck_job
<<: *default_triggering_rules
@@ -343,18 +371,41 @@ stages:
.shotgun: &shotgun_job
<<: *base_image
<<: *api_pipelines_schedules_tags_triggers_web_triggering_rules
stage: performance
rules:
- &shotgun_rule_mr
if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
variables:
BASELINE: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
- &shotgun_rule_tag
if: '$CI_COMMIT_TAG != null'
variables:
SHOTGUN_ROUNDS: 3
- &shotgun_rule_other
if: '$CI_PIPELINE_SOURCE =~ /^(api|pipeline|schedule|trigger|web)$/'
# when using data from a single run, the overall instability of the results
# causes quite high false positive rate, rerun the test to attemp to reduce those
retry: 1
script:
- if [ -z "$CI_COMMIT_TAG" ]; then export SHOTGUN_ROUNDS=1; else export SHOTGUN_ROUNDS=3; fi
- if [ -z "$BASELINE" ]; then export BASELINE=$BIND_BASELINE_VERSION; fi # this dotenv variable can't be set in the rules section, because rules are evaluated before any jobs run
- PIPELINE_ID=$(curl -s -X POST --fail
-F "token=$CI_JOB_TOKEN"
-F ref=main
-F "variables[SHOTGUN_TEST_VERSION]=['$CI_COMMIT_REF_NAME', '$BIND_BASELINE_VERSION']"
-F "variables[SHOTGUN_TEST_VERSION]=['$CI_COMMIT_REF_NAME', '$BASELINE']"
-F "variables[SHOTGUN_DURATION]=300"
-F "variables[SHOTGUN_ROUNDS]=$SHOTGUN_ROUNDS"
-F "variables[SHOTGUN_TRAFFIC_MULTIPLIER]=$SHOTGUN_TRAFFIC_MULTIPLIER"
-F "variables[SHOTGUN_SCENARIO]=$SHOTGUN_SCENARIO"
-F "variables[SHOTGUN_EVAL_THRESHOLD_CPU_MIN]=$SHOTGUN_EVAL_THRESHOLD_CPU_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_CPU_MAX]=$SHOTGUN_EVAL_THRESHOLD_CPU_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_MEMORY_MIN]=$SHOTGUN_EVAL_THRESHOLD_MEMORY_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_MEMORY_MAX]=$SHOTGUN_EVAL_THRESHOLD_MEMORY_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_RCODE_MIN]=$SHOTGUN_EVAL_THRESHOLD_RCODE_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_RCODE_MAX]=$SHOTGUN_EVAL_THRESHOLD_RCODE_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MIN]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MAX]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MAX"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MIN]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MIN"
-F "variables[SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MAX]=$SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_DRIFT_MAX"
https://gitlab.isc.org/api/v4/projects/188/trigger/pipeline | jq .id)
- util/ci-wait-shotgun.py $PIPELINE_ID
needs:
@@ -511,6 +562,8 @@ misc:
- if git grep SYSTEMTESTTOP -- ':!.gitlab-ci.yml'; then echo 'Please use relative paths instead of $SYSTEMTESTTOP.'; exit 1; fi
- bash util/unused-headers.sh
- bash util/xmllint-html.sh
# Check dangling symlinks in the repository
- if find . -xtype l | grep .; then exit 1; fi
needs: []
artifacts:
paths:
@@ -534,7 +587,7 @@ vulture:
<<: *precheck_job
needs: []
script:
- vulture --exclude "*/ans*/ans.py,conftest.py,isctest" --ignore-names "pytestmark" bin/tests/system/
- vulture --exclude "*ans.py,conftest.py,isctest" --ignore-names "pytestmark" bin/tests/system/
ci-variables:
stage: precheck
@@ -619,9 +672,8 @@ danger:
script:
- pip install git+https://gitlab.isc.org/isc-projects/hazard.git
- hazard
only:
refs:
- merge_requests
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
checkbashisms:
<<: *precheck_job
@@ -1268,6 +1320,8 @@ clang:asan:
<<: *build_job
system:clang:asan:
variables:
LSAN_OPTIONS: "suppressions=$CI_PROJECT_DIR/suppr-lsan.txt"
<<: *base_image
<<: *system_test_job
needs:
@@ -1287,7 +1341,7 @@ gcc:tsan:
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Wno-stringop-overread -ggdb -O2 -fsanitize=thread"
LDFLAGS: "-fsanitize=thread"
LDFLAGS: "-fsanitize=thread -Wl,--disable-new-dtags"
EXTRA_CONFIGURE: "--with-libidn2 --enable-pthread-rwlock --without-jemalloc PKG_CONFIG_PATH=/opt/tsan/lib/pkgconfig"
<<: *tsan_fedora_41_amd64_image
<<: *build_job
@@ -1316,7 +1370,8 @@ clang:tsan:
variables:
CC: "${CLANG}"
CFLAGS: "${CFLAGS_COMMON} -ggdb -O2 -fsanitize=thread"
LDFLAGS: "-fsanitize=thread"
# -Wl,--disable-new-dtags ensures that Clang creates valid TSAN reports
LDFLAGS: "-fsanitize=thread -Wl,--disable-new-dtags"
EXTRA_CONFIGURE: "--with-libidn2 --enable-pthread-rwlock --without-jemalloc PKG_CONFIG_PATH=/opt/tsan/lib/pkgconfig"
system:clang:tsan:
@@ -1395,27 +1450,19 @@ unit:clang:bookworm:amd64:
# Jobs for Clang builds on FreeBSD 13 (amd64)
clang:freebsd13:amd64:
variables:
CFLAGS: "${CFLAGS_COMMON}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_LIBEDIT} --with-gssapi=/usr/local/bin/krb5-config"
USER: gitlab-runner
<<: *freebsd_13_amd64_image
<<: *build_job
<<: *freebsd_autoscaler_13_amd64
system:clang:freebsd13:amd64:
<<: *freebsd_13_amd64_image
<<: *system_test_job
variables:
USER: gitlab-runner
<<: *freebsd_autoscaler_13_amd64
needs:
- job: clang:freebsd13:amd64
artifacts: true
unit:clang:freebsd13:amd64:
<<: *freebsd_13_amd64_image
<<: *unit_test_job
<<: *freebsd_autoscaler_13_amd64
needs:
- job: clang:freebsd13:amd64
artifacts: true
@@ -1423,27 +1470,19 @@ unit:clang:freebsd13:amd64:
# Jobs for Clang builds on FreeBSD 14 (amd64)
clang:freebsd14:amd64:
variables:
CFLAGS: "${CFLAGS_COMMON}"
# Use MIT Kerberos5 for BIND 9 GSS-API support because of FreeBSD Heimdal
# incompatibility; see https://bugs.freebsd.org/275241.
EXTRA_CONFIGURE: "${WITH_READLINE_EDITLINE} --with-gssapi=/usr/local/bin/krb5-config"
USER: gitlab-runner
<<: *freebsd_14_amd64_image
<<: *build_job
<<: *freebsd_autoscaler_14_amd64
system:clang:freebsd14:amd64:
<<: *freebsd_14_amd64_image
<<: *system_test_job
variables:
USER: gitlab-runner
<<: *freebsd_autoscaler_14_amd64
needs:
- job: clang:freebsd14:amd64
artifacts: true
unit:clang:freebsd14:amd64:
<<: *freebsd_14_amd64_image
<<: *unit_test_job
<<: *freebsd_autoscaler_14_amd64
needs:
- job: clang:freebsd14:amd64
artifacts: true
@@ -1492,8 +1531,8 @@ release:
artifacts: true
- job: docs
artifacts: true
only:
- tags
rules:
- if: '$CI_COMMIT_TAG != null'
artifacts:
paths:
- "*-release"
@@ -1536,8 +1575,8 @@ sign:
needs:
- job: release
artifacts: true
only:
- tags
rules:
- if: '$CI_COMMIT_TAG != null'
when: manual
allow_failure: false
@@ -1589,10 +1628,8 @@ coverity:
- cov-int.tar.gz
expire_in: "1 week"
when: on_failure
only:
variables:
- $COVERITY_SCAN_PROJECT_NAME
- $COVERITY_SCAN_TOKEN
rules:
- if: '$COVERITY_SCAN_PROJECT_NAME != null && $COVERITY_SCAN_TOKEN != null'
# Respdiff tests
@@ -1627,9 +1664,9 @@ respdiff:tsan:
<<: *default_triggering_rules
<<: *tsan_debian_bookworm_amd64_image
variables:
CC: gcc
CFLAGS: "${CFLAGS_COMMON} -Og -fsanitize=thread"
LDFLAGS: "-fsanitize=thread"
CC: "${CLANG}"
CFLAGS: "${CFLAGS_COMMON} -ggdb -O2 -fsanitize=thread"
LDFLAGS: "-fsanitize=thread -Wl,--disable-new-dtags"
EXTRA_CONFIGURE: "--enable-pthread-rwlock --without-jemalloc PKG_CONFIG_PATH=/opt/tsan/lib/pkgconfig"
MAX_DISAGREEMENTS_PERCENTAGE: "0.15"
TSAN_OPTIONS: "${TSAN_OPTIONS_DEBIAN}"
@@ -1654,9 +1691,6 @@ respdiff-third-party:
# Performance tests
# Run shotgun:udp right away, but delay other shotgun jobs sligthly in order to
# allow re-use of the built container image. Otherwise, the jobs would do the
# same builds in parallel rather than re-use the already built image.
shotgun:udp:
<<: *shotgun_job
variables:
@@ -1667,25 +1701,29 @@ shotgun:tcp:
<<: *shotgun_job
variables:
SHOTGUN_SCENARIO: tcp
SHOTGUN_TRAFFIC_MULTIPLIER: 13
when: delayed
start_in: 5 minutes
SHOTGUN_TRAFFIC_MULTIPLIER: 12
shotgun:dot:
<<: *shotgun_job
variables:
SHOTGUN_SCENARIO: dot
SHOTGUN_TRAFFIC_MULTIPLIER: 6
when: delayed
start_in: 5 minutes
rules: &shotgun_rules_manual_mr
- if: '$CI_MERGE_REQUEST_DIFF_BASE_SHA != null'
variables:
BASELINE: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
when: manual # don't run on each MR unless requested
allow_failure: true
- *shotgun_rule_tag
- *shotgun_rule_other
shotgun:doh-get:
<<: *shotgun_job
variables:
SHOTGUN_SCENARIO: doh-get
SHOTGUN_TRAFFIC_MULTIPLIER: 3
when: delayed
start_in: 5 minutes
SHOTGUN_EVAL_THRESHOLD_LATENCY_PCTL_MAX: 0.4 # bump from the default due to increased tail-end jitter
rules: *shotgun_rules_manual_mr
.stress-test: &stress_test
stage: performance
@@ -1724,8 +1762,8 @@ fsck:
- git clone https://gitlab.isc.org/isc-projects/bind9.git bind9-full-clone
- cd bind9-full-clone/
- git fsck
only:
- schedules
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
needs: []
gcov:
@@ -1777,9 +1815,8 @@ pairwise:
- pairwise-model.txt
- pairwise-output.*.txt
when: on_failure
only:
variables:
- $PAIRWISE_TESTING
rules:
- if: '$PAIRWISE_TESTING != null'
.post_merge_template: &post_merge
<<: *base_image
@@ -70,7 +70,8 @@ confidential!
- [ ] [:link:][step_clearance] **(IM)** Grant QA & Marketing clearance to proceed with public release
- [ ] [:link:][step_matrix] **(Support)** (BIND 9 only) Add the new CVEs to the vulnerability matrix in the Knowledge Base
- [ ] [:link:][step_publish_advisory] **(Support)** Bump Document Version for the Security Advisory and publish it in the Knowledge Base
- [ ] [:link:][step_bump_advisory] **(Support)** Bump Document Version for the Security Advisory in Printing Press
- [ ] [:link:][step_publish_advisory] **(Support)** Publish the Security Advisory in the Knowledge Base
- [ ] [:link:][step_publish] **(QA/Marketing)** Publish the releases (as outlined in the release checklist)
- [ ] [:link:][step_notifications] **(First IM)** Send notification emails to third parties
- [ ] [:link:][step_mitre] **(First IM)** Advise MITRE about the disclosed CVEs
@@ -114,7 +115,8 @@ confidential!
[step_packager_emails]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#send-notifications-to-os-packagers
[step_clearance]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#grant-qa-marketing-clearance-to-proceed-with-public-release
[step_matrix]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#bind-9-only-add-the-new-cves-to-the-vulnerability-matrix-in-the-knowledge-base
[step_publish_advisory]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#bump-document-version-for-the-security-advisory-and-publish-it-in-the-knowledge-base
[step_bump_advisory]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#bump-document-version-for-the-security-advisory-in-printing-press
[step_publish_advisory]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#publish-the-security-advisory-in-the-knowledge-base
[step_publish]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#publish-the-releases-as-outlined-in-the-release-checklist
[step_notifications]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#send-notification-emails-to-third-parties
[step_mitre]: https://gitlab.isc.org/isc-private/isc-wiki/-/wikis/Security-Incident-Handling-Checklist-Explanations#advise-mitre-about-the-disclosed-cves
+1 -1
View File
@@ -1 +1 @@
CHANGES
doc/arm/changelog.rst
+1 -1
View File
@@ -655,7 +655,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
isc_buffer_constinit(&buffer, zonename, strlen(zonename));
isc_buffer_add(&buffer, strlen(zonename));
origin = dns_fixedname_initname(&fixorigin);
CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0));
dns_zone_setorigin(zone, origin);
dns_zone_setdbtype(zone, 1, (const char *const *)dbtype);
if (strcmp(filename, "-") == 0) {
+3 -1
View File
@@ -22,6 +22,7 @@
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -30,6 +31,7 @@
#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rootns.h>
@@ -759,7 +761,7 @@ cleanup:
}
if (mctx != NULL) {
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
}
return result == ISC_R_SUCCESS ? 0 : 1;
+3 -1
View File
@@ -22,6 +22,7 @@
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -31,6 +32,7 @@
#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/name.h>
@@ -575,7 +577,7 @@ main(int argc, char **argv) {
fprintf(errout, "OK\n");
}
destroy();
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
return (result == ISC_R_SUCCESS) ? 0 : 1;
}
+3 -1
View File
@@ -32,6 +32,7 @@
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/file.h>
#include <isc/lib.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/result.h>
@@ -40,6 +41,7 @@
#include <isc/util.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dst/dst.h>
@@ -288,7 +290,7 @@ options {\n\
isc_mem_stats(mctx, stderr);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
return 0;
}
+3 -1
View File
@@ -28,6 +28,7 @@
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/file.h>
#include <isc/lib.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/result.h>
@@ -36,6 +37,7 @@
#include <isc/util.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dst/dst.h>
@@ -294,7 +296,7 @@ nsupdate -k <keyfile>\n");
isc_mem_stats(mctx, stderr);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
return 0;
}
+12 -42
View File
@@ -26,17 +26,14 @@
#include <unistd.h>
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/err.h>
#include <openssl/provider.h>
#endif
#include <isc/async.h>
#include <isc/attributes.h>
#include <isc/base64.h>
#include <isc/buffer.h>
#include <isc/fips.h>
#include <isc/crypto.h>
#include <isc/hex.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/managers.h>
#include <isc/md.h>
@@ -59,6 +56,7 @@
#include <dns/fixedname.h>
#include <dns/keytable.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/masterdump.h>
#include <dns/message.h>
#include <dns/name.h>
@@ -165,10 +163,6 @@ static dns_fixedname_t qfn;
/* Default trust anchors */
static char anchortext[] = TRUST_ANCHORS;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
static OSSL_PROVIDER *fips = NULL, *base = NULL;
#endif
/*
* Static function prototypes
*/
@@ -595,7 +589,7 @@ convert_name(dns_fixedname_t *fn, dns_name_t **name, const char *text) {
isc_buffer_add(&b, len);
n = dns_fixedname_initname(fn);
result = dns_name_fromtext(n, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(n, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "failed to convert name %s: %s", text,
isc_result_totext(result));
@@ -1617,24 +1611,7 @@ preparse_args(int argc, char **argv) {
while (strpbrk(option, single_dash_opts) == &option[0]) {
switch (option[0]) {
case 'F':
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
fips = OSSL_PROVIDER_load(NULL, "fips");
if (fips == NULL) {
ERR_clear_error();
fatal("Failed to load FIPS provider");
}
base = OSSL_PROVIDER_load(NULL, "base");
if (base == NULL) {
OSSL_PROVIDER_unload(fips);
ERR_clear_error();
fatal("Failed to load base provider");
}
#endif
/* Already in FIPS mode? */
if (isc_fips_mode()) {
break;
}
if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
break;
@@ -2138,12 +2115,14 @@ sendquery(void *arg) {
dns_view_attach(view, &(dns_view_t *){ NULL });
const unsigned int timeout = isc_nm_getinitialtimeout(netmgr) /
MS_PER_SEC;
uint32_t initial;
isc_nm_gettimeouts(netmgr, &initial, NULL, NULL, NULL);
const unsigned int connect_timeout = initial, timeout = initial;
CHECK(dns_request_create(requestmgr, message, NULL, &peer, NULL, NULL,
DNS_REQUESTOPT_TCP, NULL, timeout, timeout, 0,
0, isc_loop(), recvresponse, message,
&request));
DNS_REQUESTOPT_TCP, NULL, connect_timeout,
timeout, 0, 0, isc_loop(), recvresponse,
message, &request));
return;
cleanup:
@@ -2305,14 +2284,5 @@ cleanup:
isc_managers_destroy(&mctx, &loopmgr, &netmgr);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (base != NULL) {
OSSL_PROVIDER_unload(base);
}
if (fips != NULL) {
OSSL_PROVIDER_unload(fips);
}
#endif
return 0;
}
+39 -45
View File
@@ -20,8 +20,9 @@
#include <time.h>
#include <isc/attributes.h>
#include <isc/crypto.h>
#include <isc/dir.h>
#include <isc/fips.h>
#include <isc/lib.h>
#include <isc/loop.h>
#include <isc/netaddr.h>
#include <isc/parseint.h>
@@ -33,6 +34,7 @@
#include <dns/byaddr.h>
#include <dns/dns64.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/masterdump.h>
#include <dns/message.h>
#include <dns/name.h>
@@ -71,14 +73,6 @@ static bool short_form = false, printcmd = true, plusquest = false,
static uint32_t splitwidth = 0xffffffff;
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/err.h>
#include <openssl/provider.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
static OSSL_PROVIDER *fips = NULL, *base = NULL;
#endif
/*% opcode text */
static const char *const opcodetext[] = {
@@ -295,6 +289,7 @@ help(void) {
" form of answers - global "
"option)\n"
" +[no]showbadcookie (Show BADCOOKIE message)\n"
" +[no]showbadvers (Show BADVERS message)\n"
" +[no]showsearch (Search with intermediate "
"results)\n"
" +[no]split=## (Split hex/base64 fields "
@@ -333,6 +328,7 @@ help(void) {
" +[no]yaml (Present the results as "
"YAML)\n"
" +[no]zflag (Set Z flag in query)\n"
" +[no]zoneversion (Request zone version)\n"
" global d-opts and servers (before host name) affect "
"all "
"queries.\n"
@@ -591,7 +587,7 @@ short_answer(dns_message_t *msg, dns_messagetextflag_t flags, isc_buffer_t *buf,
UNUSED(flags);
dns_name_init(&empty_name, NULL);
dns_name_init(&empty_name);
result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
if (result == ISC_R_NOMORE) {
return ISC_R_SUCCESS;
@@ -633,9 +629,7 @@ static bool
isdotlocal(dns_message_t *msg) {
isc_result_t result;
static unsigned char local_ndata[] = { "\005local" };
static unsigned char local_offsets[] = { 0, 6 };
static dns_name_t local = DNS_NAME_INITABSOLUTE(local_ndata,
local_offsets);
static dns_name_t local = DNS_NAME_INITABSOLUTE(local_ndata);
for (result = dns_message_firstname(msg, DNS_SECTION_QUESTION);
result == ISC_R_SUCCESS;
@@ -1780,6 +1774,8 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
FULLCHECK("edns");
if (!state) {
lookup->edns = -1;
lookup->original_edns =
-1;
break;
}
if (value == NULL) {
@@ -1796,6 +1792,7 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
goto exit_or_usage;
}
lookup->edns = num;
lookup->original_edns = num;
break;
case 'f':
FULLCHECK("ednsflags");
@@ -2314,8 +2311,18 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
case 'w': /* showsearch */
switch (cmd[4]) {
case 'b':
FULLCHECK("showbadcookie");
lookup->showbadcookie = state;
switch (cmd[7]) {
case 'c':
FULLCHECK("showbadcookie");
lookup->showbadcookie = state;
break;
case 'v':
FULLCHECK("showbadvers");
lookup->showbadvers = state;
break;
default:
goto invalid_option;
}
break;
case 's':
FULLCHECK("showsearch");
@@ -2568,9 +2575,22 @@ plus_option(char *option, bool is_batchfile, bool *need_clone,
lookup->rrcomments = -1;
}
break;
case 'z': /* zflag */
FULLCHECK("zflag");
lookup->zflag = state;
case 'z':
switch (cmd[1]) {
case 'f': /* zflag */
FULLCHECK("zflag");
lookup->zflag = state;
break;
case 'o': /* zoneversion */
FULLCHECK("zoneversion");
if (state && lookup->edns == -1) {
lookup->edns = DEFAULT_EDNS_VERSION;
}
lookup->zoneversion = state;
break;
default:
goto invalid_option;
}
break;
default:
invalid_option:
@@ -2931,24 +2951,7 @@ preparse_args(int argc, char **argv) {
debugging = true;
break;
case 'F':
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
fips = OSSL_PROVIDER_load(NULL, "fips");
if (fips == NULL) {
ERR_clear_error();
fatal("Failed to load FIPS provider");
}
base = OSSL_PROVIDER_load(NULL, "base");
if (base == NULL) {
OSSL_PROVIDER_unload(fips);
ERR_clear_error();
fatal("Failed to load base provider");
}
#endif
/* Already in FIPS mode? */
if (isc_fips_mode()) {
break;
}
if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
break;
@@ -3476,14 +3479,5 @@ main(int argc, char **argv) {
dig_startup();
dig_shutdown();
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (base != NULL) {
OSSL_PROVIDER_unload(base);
}
if (fips != NULL) {
OSSL_PROVIDER_unload(fips);
}
#endif
return exitcode;
}
+10
View File
@@ -614,6 +614,12 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
BADCOOKIE rcode before retrying the request or not. The default
is to not show the messages.
.. option:: +showbadvers, +noshowbadvers
This option toggles whether to show the message containing the
BADVERS rcode before retrying the request or not. The default
is to not show the messages.
.. option:: +showsearch, +noshowsearch
This option performs [or does not perform] a search showing intermediate results.
@@ -751,6 +757,10 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
This option sets [or does not set] the last unassigned DNS header flag in a DNS query.
This flag is off by default.
.. option:: +zoneversion, +nozoneversion
When enabled, this option includes an EDNS Zone Version request when sending a query.
Multiple Queries
~~~~~~~~~~~~~~~~
+30 -19
View File
@@ -605,6 +605,7 @@ make_empty_lookup(void) {
.idnout = idnout,
.udpsize = -1,
.edns = -1,
.original_edns = -1,
.recurse = true,
.retries = tries,
.comments = true,
@@ -704,6 +705,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
looknew->opcode = lookold->opcode;
looknew->expire = lookold->expire;
looknew->nsid = lookold->nsid;
looknew->zoneversion = lookold->zoneversion;
looknew->tcp_keepalive = lookold->tcp_keepalive;
looknew->header_only = lookold->header_only;
looknew->https_mode = lookold->https_mode;
@@ -738,6 +740,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
}
looknew->showbadcookie = lookold->showbadcookie;
looknew->showbadvers = lookold->showbadvers;
looknew->sendcookie = lookold->sendcookie;
looknew->seenbadcookie = lookold->seenbadcookie;
looknew->badcookie = lookold->badcookie;
@@ -764,6 +767,7 @@ clone_lookup(dig_lookup_t *lookold, bool servers) {
looknew->idnout = lookold->idnout;
looknew->udpsize = lookold->udpsize;
looknew->edns = lookold->edns;
looknew->original_edns = lookold->original_edns;
looknew->recurse = lookold->recurse;
looknew->aaonly = lookold->aaonly;
looknew->adflag = lookold->adflag;
@@ -858,14 +862,14 @@ requeue_lookup(dig_lookup_t *lookold, bool servers) {
void
setup_text_key(void) {
isc_result_t result;
dns_name_t keyname;
dns_fixedname_t fkey;
dns_name_t *keyname = dns_fixedname_initname(&fkey);
isc_buffer_t secretbuf;
unsigned int secretsize;
unsigned char *secretstore;
debug("setup_text_key()");
isc_buffer_allocate(mctx, &namebuf, MXNAME);
dns_name_init(&keyname, NULL);
isc_buffer_putstr(namebuf, keynametext);
secretsize = (unsigned int)strlen(keysecret) * 3 / 4;
secretstore = isc_mem_allocate(mctx, secretsize);
@@ -882,12 +886,12 @@ setup_text_key(void) {
goto failure;
}
result = dns_name_fromtext(&keyname, namebuf, dns_rootname, 0, namebuf);
result = dns_name_fromtext(keyname, namebuf, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
goto failure;
}
result = dns_tsigkey_create(&keyname, hmac_alg, secretstore,
result = dns_tsigkey_create(keyname, hmac_alg, secretstore,
(int)secretsize, mctx, &tsigkey);
failure:
if (result != ISC_R_SUCCESS) {
@@ -898,7 +902,6 @@ failure:
}
isc_mem_free(mctx, secretstore);
dns_name_invalidate(&keyname);
isc_buffer_free(&namebuf);
}
@@ -1939,6 +1942,7 @@ followup_lookup(dns_message_t *msg, dig_query_t *query, dns_section_t section) {
}
domain = dns_fixedname_name(&lookup->fdomain);
dns_name_copy(name, domain);
lookup->edns = lookup->original_edns;
}
debug("adding server %s", namestr);
num = getaddresses(lookup, namestr, &lresult);
@@ -2082,8 +2086,8 @@ insert_soa(dig_lookup_t *lookup) {
soa.common.rdclass = lookup->rdclass;
soa.common.rdtype = dns_rdatatype_soa;
dns_name_init(&soa.origin, NULL);
dns_name_init(&soa.contact, NULL);
dns_name_init(&soa.origin);
dns_name_init(&soa.contact);
dns_name_clone(dns_rootname, &soa.origin);
dns_name_clone(dns_rootname, &soa.contact);
@@ -2206,11 +2210,6 @@ setup_lookup(dig_lookup_t *lookup) {
}
dns_message_gettempname(lookup->sendmsg, &lookup->name);
isc_buffer_init(&lookup->namebuf, lookup->name_space,
sizeof(lookup->name_space));
isc_buffer_init(&lookup->onamebuf, lookup->oname_space,
sizeof(lookup->oname_space));
/*
* We cannot convert `textname' and `origin' separately.
* `textname' doesn't contain TLD, but local mapping needs
@@ -2258,8 +2257,7 @@ setup_lookup(dig_lookup_t *lookup) {
len = (unsigned int)strlen(origin);
isc_buffer_init(&b, origin, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->oname, &b, dns_rootname, 0,
&lookup->onamebuf);
result = dns_name_fromtext(lookup->oname, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
dns_message_puttempname(lookup->sendmsg, &lookup->name);
dns_message_puttempname(lookup->sendmsg,
@@ -2277,12 +2275,12 @@ setup_lookup(dig_lookup_t *lookup) {
len = (unsigned int)strlen(textname);
isc_buffer_init(&b, textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(name, &b, NULL, 0, NULL);
result = dns_name_fromtext(name, &b, NULL, 0);
if (result == ISC_R_SUCCESS) {
if (!dns_name_isabsolute(name)) {
result = dns_name_concatenate(
name, lookup->oname,
lookup->name, &lookup->namebuf);
lookup->name);
} else {
dns_name_copy(name, lookup->name);
}
@@ -2310,8 +2308,7 @@ setup_lookup(dig_lookup_t *lookup) {
isc_buffer_init(&b, textname, len);
isc_buffer_add(&b, len);
result = dns_name_fromtext(lookup->name, &b,
dns_rootname, 0,
&lookup->namebuf);
dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
dns_message_puttempname(lookup->sendmsg,
&lookup->name);
@@ -2464,7 +2461,8 @@ setup_lookup(dig_lookup_t *lookup) {
lookup->udpsize = DEFAULT_EDNS_BUFSIZE;
}
if (lookup->edns < 0) {
lookup->edns = DEFAULT_EDNS_VERSION;
lookup->original_edns = lookup->edns =
DEFAULT_EDNS_VERSION;
}
if (lookup->nsid) {
@@ -2594,6 +2592,14 @@ setup_lookup(dig_lookup_t *lookup) {
i++;
}
if (lookup->zoneversion) {
INSIST(i < MAXOPTS);
opts[i].code = DNS_OPT_ZONEVERSION;
opts[i].length = 0;
opts[i].value = NULL;
i++;
}
if (lookup->ednsoptscnt != 0) {
INSIST(i + lookup->ednsoptscnt <= MAXOPTS);
memmove(&opts[i], lookup->ednsopts,
@@ -4308,6 +4314,11 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
if (msg->rcode == dns_rcode_badvers && msg->opt != NULL &&
(newedns = ednsvers(msg->opt)) < l->edns && l->ednsneg)
{
if (l->showbadvers) {
dighost_printmessage(query, &b, msg, true);
dighost_received(isc_buffer_usedlength(&b), &peer,
query);
}
/*
* Add minimum EDNS version required checks here if needed.
*/
+5 -6
View File
@@ -117,11 +117,11 @@ struct dig_lookup {
section_answer, section_authority, section_question,
seenbadcookie, sendcookie, servfail_stops,
setqid, /*% use a speciied query ID */
showbadcookie, stats, tcflag, tcp_keepalive, tcp_mode,
tcp_mode_set, tls_mode, /*% connect using TLS */
trace, /*% dig +trace */
showbadcookie, showbadvers, stats, tcflag, tcp_keepalive,
tcp_mode, tcp_mode_set, tls_mode, /*% connect using TLS */
trace, /*% dig +trace */
trace_root, /*% initial query for either +trace or +nssearch */
ttlunits, use_usec, waiting_connect, zflag;
ttlunits, use_usec, waiting_connect, zflag, zoneversion;
char textname[MXNAME]; /*% Name we're going to be looking up */
char cmdline[MXNAME];
dns_rdatatype_t rdtype;
@@ -131,8 +131,6 @@ struct dig_lookup {
bool rdclassset;
char name_space[BUFSIZE];
char oname_space[BUFSIZE];
isc_buffer_t namebuf;
isc_buffer_t onamebuf;
isc_buffer_t renderbuf;
char *sendspace;
dns_name_t *name;
@@ -150,6 +148,7 @@ struct dig_lookup {
int nsfound;
int16_t udpsize;
int16_t edns;
int16_t original_edns;
int16_t padding;
uint32_t ixfr_serial;
isc_buffer_t rdatabuf;
+15 -3
View File
@@ -21,6 +21,7 @@
#include <isc/attributes.h>
#include <isc/commandline.h>
#include <isc/lib.h>
#include <isc/loop.h>
#include <isc/netaddr.h>
#include <isc/string.h>
@@ -28,6 +29,7 @@
#include <dns/byaddr.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/rdata.h>
@@ -80,6 +82,7 @@ struct rtype rtypes[] = { { 1, "has address" },
{ 25, "has key" },
{ 28, "has IPv6 address" },
{ 29, "location" },
{ dns_rdatatype_https, "has HTTP service bindings" },
{ 0, NULL } };
static char *
@@ -218,7 +221,7 @@ printsection(dns_message_t *msg, dns_section_t sectionid,
printf(";; %s SECTION:\n", section_name);
}
dns_name_init(&empty_name, NULL);
dns_name_init(&empty_name);
result = dns_message_firstname(msg, sectionid);
if (result == ISC_R_NOMORE) {
@@ -243,8 +246,7 @@ printsection(dns_message_t *msg, dns_section_t sectionid,
(list_type == dns_rdatatype_any ||
rdataset->type == list_type)) ||
(list_addresses &&
(rdataset->type == dns_rdatatype_a ||
rdataset->type == dns_rdatatype_aaaa ||
(dns_rdatatype_isaddr(rdataset->type) ||
rdataset->type == dns_rdatatype_ns ||
rdataset->type == dns_rdatatype_ptr))))
{
@@ -457,6 +459,16 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
lookup->retries = tries;
ISC_LIST_APPEND(lookup_list, lookup, link);
}
lookup = clone_lookup(query->lookup, false);
if (lookup != NULL) {
strlcpy(lookup->textname, namestr,
sizeof(lookup->textname));
lookup->rdtype = dns_rdatatype_https;
lookup->rdtypeset = true;
lookup->origin = NULL;
lookup->retries = tries;
ISC_LIST_APPEND(lookup_list, lookup, link);
}
}
if (!short_form) {
+1 -1
View File
@@ -122,7 +122,7 @@ Options
CNAME, NS, SOA, TXT, DNSKEY, AXFR, etc.
When no query type is specified, :program:`host` automatically selects an
appropriate query type. By default, it looks for A, AAAA, and MX
appropriate query type. By default, it looks for A, AAAA, MX, and HTTPS
records. If the :option:`-C` option is given, queries are made for SOA
records. If ``name`` is a dotted-decimal IPv4 address or
colon-delimited IPv6 address, :program:`host` queries for PTR records.
+2 -1
View File
@@ -20,7 +20,7 @@
#include <isc/attributes.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/condition.h>
#include <isc/lib.h>
#include <isc/loop.h>
#include <isc/netaddr.h>
#include <isc/parseint.h>
@@ -30,6 +30,7 @@
#include <dns/byaddr.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/rdata.h>
+8
View File
@@ -41,6 +41,14 @@ dnssec_keygen_LDADD = \
$(LDADD) \
$(OPENSSL_LIBS)
dnssec_ksr_CPPFLAGS= \
$(AM_CPPFLAGS) \
$(OPENSSL_CFLAGS)
dnssec_ksr_LDADD = \
$(LDADD) \
$(OPENSSL_LIBS)
dnssec_signzone_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(OPENSSL_CFLAGS)
+4 -2
View File
@@ -29,6 +29,7 @@
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -44,6 +45,7 @@
#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/name.h>
#include <dns/rdata.h>
@@ -176,7 +178,7 @@ initname(char *setname) {
isc_buffer_init(&buf, setname, strlen(setname));
isc_buffer_add(&buf, strlen(setname));
result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &buf, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
fatal("could not initialize name %s", setname);
}
@@ -1073,7 +1075,7 @@ cleanup(void) {
if (print_mem_stats && verbose > 10) {
isc_mem_stats(mctx, stdout);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
}
}
+4 -2
View File
@@ -22,6 +22,7 @@
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -34,6 +35,7 @@
#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/name.h>
#include <dns/rdata.h>
@@ -65,7 +67,7 @@ initname(char *setname) {
isc_buffer_init(&buf, setname, strlen(setname));
isc_buffer_add(&buf, strlen(setname));
result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &buf, dns_rootname, 0);
return result;
}
@@ -541,7 +543,7 @@ main(int argc, char **argv) {
if (verbose > 10) {
isc_mem_stats(mctx, stdout);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
fflush(stdout);
if (ferror(stdout)) {
+4 -2
View File
@@ -20,6 +20,7 @@
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -32,6 +33,7 @@
#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/name.h>
#include <dns/rdata.h>
@@ -67,7 +69,7 @@ initname(char *setname) {
isc_buffer_init(&buf, setname, strlen(setname));
isc_buffer_add(&buf, strlen(setname));
result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &buf, dns_rootname, 0);
return result;
}
@@ -454,7 +456,7 @@ main(int argc, char **argv) {
if (verbose > 10) {
isc_mem_stats(mctx, stdout);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
fflush(stdout);
if (ferror(stdout)) {
+4 -2
View File
@@ -21,6 +21,7 @@
#include <isc/attributes.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/region.h>
@@ -31,6 +32,7 @@
#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/secalg.h>
@@ -365,7 +367,7 @@ main(int argc, char **argv) {
isc_buffer_init(&buf, argv[isc_commandline_index],
strlen(argv[isc_commandline_index]));
isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
ret = dns_name_fromtext(name, &buf, dns_rootname, 0);
if (ret != ISC_R_SUCCESS) {
fatal("invalid key name %s: %s",
argv[isc_commandline_index],
@@ -744,7 +746,7 @@ main(int argc, char **argv) {
isc_mem_stats(mctx, stdout);
}
isc_mem_free(mctx, label);
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
if (freeit != NULL) {
free(freeit);
+14 -48
View File
@@ -38,7 +38,8 @@
#include <isc/attributes.h>
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/fips.h>
#include <isc/crypto.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/region.h>
@@ -50,17 +51,13 @@
#include <dns/fixedname.h>
#include <dns/kasp.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/secalg.h>
#include <dst/dst.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/err.h>
#include <openssl/provider.h>
#endif
#include "dnssectool.h"
const char *program = "dnssec-keygen";
@@ -149,7 +146,7 @@ usage(void) {
fprintf(stderr, " -l <file>: configuration file with dnssec-policy "
"statement\n");
fprintf(stderr, " -a <algorithm>:\n");
if (!isc_fips_mode()) {
if (!isc_crypto_fips_mode()) {
fprintf(stderr, " RSASHA1 | NSEC3RSASHA1 |\n");
}
fprintf(stderr, " RSASHA256 | RSASHA512 |\n");
@@ -157,7 +154,7 @@ usage(void) {
fprintf(stderr, " ED25519 | ED448\n");
fprintf(stderr, " -3: use NSEC3-capable algorithm\n");
fprintf(stderr, " -b <key size in bits>:\n");
if (!isc_fips_mode()) {
if (!isc_crypto_fips_mode()) {
fprintf(stderr, " RSASHA1:\t[%d..%d]\n", min_rsa,
MAX_RSA);
fprintf(stderr, " NSEC3RSASHA1:\t[%d..%d]\n", min_rsa,
@@ -275,7 +272,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
isc_buffer_init(&buf, argv[isc_commandline_index],
strlen(argv[isc_commandline_index]));
isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
ret = dns_name_fromtext(name, &buf, dns_rootname, 0);
if (ret != ISC_R_SUCCESS) {
fatal("invalid key name %s: %s",
argv[isc_commandline_index],
@@ -286,7 +283,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
fatal("unsupported algorithm: %s", algstr);
}
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
/* verify only in FIPS mode */
switch (ctx->alg) {
case DST_ALG_RSASHA1:
@@ -339,7 +336,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
switch (ctx->alg) {
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
fatal("key size not specified (-b "
"option)");
}
@@ -499,7 +496,7 @@ keygen(keygen_ctx_t *ctx, isc_mem_t *mctx, int argc, char **argv) {
switch (ctx->alg) {
case DNS_KEYALG_RSASHA1:
case DNS_KEYALG_NSEC3RSASHA1:
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
fatal("SHA1 based keys not supported in FIPS mode");
}
FALLTHROUGH;
@@ -845,10 +842,6 @@ main(int argc, char **argv) {
isc_textregion_t r;
unsigned char c;
int ch;
bool set_fips_mode = false;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER *fips = NULL, *base = NULL;
#endif
keygen_ctx_t ctx = {
.options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC,
@@ -1107,7 +1100,9 @@ main(int argc, char **argv) {
ctx.prepub = strtottl(isc_commandline_argument);
break;
case 'F':
set_fips_mode = true;
if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
break;
case '?':
if (isc_commandline_option != '?') {
@@ -1134,32 +1129,11 @@ main(int argc, char **argv) {
ctx.quiet = true;
}
if (set_fips_mode) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
fips = OSSL_PROVIDER_load(NULL, "fips");
if (fips == NULL) {
ERR_clear_error();
fatal("Failed to load FIPS provider");
}
base = OSSL_PROVIDER_load(NULL, "base");
if (base == NULL) {
OSSL_PROVIDER_unload(fips);
ERR_clear_error();
fatal("Failed to load base provider");
}
#endif
if (!isc_fips_mode()) {
if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
}
}
/*
* The DST subsystem will set FIPS mode if requested at build time.
* The minimum sizes are both raised to 2048.
*/
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
min_rsa = min_dh = 2048;
}
@@ -1306,16 +1280,8 @@ main(int argc, char **argv) {
if (verbose > 10) {
isc_mem_stats(mctx, stdout);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (base != NULL) {
OSSL_PROVIDER_unload(base);
}
if (fips != NULL) {
OSSL_PROVIDER_unload(fips);
}
#endif
if (freeit != NULL) {
free(freeit);
}
+10 -29
View File
@@ -18,8 +18,9 @@
#include <isc/buffer.h>
#include <isc/commandline.h>
#include <isc/fips.h>
#include <isc/crypto.h>
#include <isc/lex.h>
#include <isc/lib.h>
#include <isc/mem.h>
#include <dns/callbacks.h>
@@ -27,6 +28,7 @@
#include <dns/fixedname.h>
#include <dns/keymgr.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/rdataclass.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
@@ -360,7 +362,7 @@ create_key(ksr_ctx_t *ksr, dns_kasp_t *kasp, dns_kasp_key_t *kaspkey,
switch (ksr->alg) {
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
/* verify-only in FIPS mode */
fatal("unsupported algorithm: %s", algstr);
}
@@ -1006,7 +1008,7 @@ parse_dnskey(isc_lex_t *lex, char *owner, isc_buffer_t *buf, dns_ttl_t *ttl) {
dname = dns_fixedname_initname(&dfname);
isc_buffer_init(&b, owner, strlen(owner));
isc_buffer_add(&b, strlen(owner));
ret = dns_name_fromtext(dname, &b, dns_rootname, 0, NULL);
ret = dns_name_fromtext(dname, &b, dns_rootname, 0);
if (ret != ISC_R_SUCCESS) {
return ret;
}
@@ -1346,10 +1348,6 @@ main(int argc, char *argv[]) {
isc_buffer_t buf;
int ch;
char *endp;
bool set_fips_mode = false;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER *fips = NULL, *base = NULL;
#endif
ksr_ctx_t ksr = {
.now = isc_stdtime_now(),
};
@@ -1369,7 +1367,9 @@ main(int argc, char *argv[]) {
ksr.now, &ksr.setend);
break;
case 'F':
set_fips_mode = true;
if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
break;
case 'f':
ksr.file = isc_commandline_argument;
@@ -1423,37 +1423,18 @@ main(int argc, char *argv[]) {
* The DST subsystem will set FIPS mode if requested at build time.
* The minimum sizes are both raised to 2048.
*/
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
min_rsa = min_dh = 2048;
}
setup_logging();
if (set_fips_mode) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
fips = OSSL_PROVIDER_load(NULL, "fips");
if (fips == NULL) {
fatal("Failed to load FIPS provider");
}
base = OSSL_PROVIDER_load(NULL, "base");
if (base == NULL) {
OSSL_PROVIDER_unload(fips);
fatal("Failed to load base provider");
}
#endif
if (!isc_fips_mode()) {
if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
}
}
/* zone */
namestr = argv[1];
name = dns_fixedname_initname(&fname);
isc_buffer_init(&buf, argv[1], strlen(argv[1]));
isc_buffer_add(&buf, strlen(argv[1]));
ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
ret = dns_name_fromtext(name, &buf, dns_rootname, 0);
if (ret != ISC_R_SUCCESS) {
fatal("invalid zone name %s: %s", argv[1],
isc_result_totext(ret));
+3 -1
View File
@@ -23,12 +23,14 @@
#include <isc/commandline.h>
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dst/dst.h>
@@ -246,7 +248,7 @@ cleanup:
if (dir != NULL) {
isc_mem_free(mctx, dir);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
return 0;
}
+3 -1
View File
@@ -25,6 +25,7 @@
#include <isc/commandline.h>
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -33,6 +34,7 @@
#include <isc/util.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dst/dst.h>
@@ -947,7 +949,7 @@ main(int argc, char **argv) {
isc_mem_stats(mctx, stdout);
}
isc_mem_free(mctx, directory);
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
return 0;
}
+11 -46
View File
@@ -42,9 +42,9 @@
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/fips.h>
#include <isc/hash.h>
#include <isc/hex.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/managers.h>
@@ -71,6 +71,7 @@
#include <dns/fixedname.h>
#include <dns/kasp.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/nsec.h>
@@ -88,10 +89,6 @@
#include <dns/zoneverify.h>
#include <dst/dst.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/err.h>
#include <openssl/provider.h>
#endif
#include "dnssectool.h"
@@ -550,7 +547,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
future = isc_serial_lt(now, rrsig.timesigned);
key = keythatsigned(&rrsig);
offline = key->pubkey;
offline = (key != NULL) ? key->pubkey : false;
sig_format(&rrsig, sigstr, sizeof(sigstr));
expired = isc_serial_gt(now, rrsig.timeexpire);
refresh = isc_serial_gt(now + cycle, rrsig.timeexpire);
@@ -957,7 +954,7 @@ addnowildcardhash(hashlist_t *l,
wild = dns_fixedname_initname(&fixed);
result = dns_name_concatenate(dns_wildcardname, name, wild, NULL);
result = dns_name_concatenate(dns_wildcardname, name, wild);
if (result == ISC_R_NOSPACE) {
return;
}
@@ -2032,7 +2029,7 @@ addnsec3(dns_name_t *name, dns_dbnode_t *node, const unsigned char *salt,
dns_fixedname_init(&hashname);
dns_rdataset_init(&rdataset);
dns_name_downcase(name, name, NULL);
dns_name_downcase(name, name);
result = dns_nsec3_hashname(&hashname, hash, &hash_len, name, gorigin,
dns_hash_sha1, iterations, salt, salt_len);
check_result(result, "addnsec3: dns_nsec3_hashname()");
@@ -2400,7 +2397,7 @@ nsec3ify(unsigned int hashalg, dns_iterations_t iterations,
fatal("iterating through the database failed: %s",
isc_result_totext(result));
}
dns_name_downcase(name, name, NULL);
dns_name_downcase(name, name);
hashlist_add_dns_name(hashlist, name, hashalg, iterations, salt,
salt_len, false);
dns_db_detachnode(gdb, &node);
@@ -2410,7 +2407,7 @@ nsec3ify(unsigned int hashalg, dns_iterations_t iterations,
* node for another <name,nextname> span so we don't add
* it here. Empty labels on nextname are within the span.
*/
dns_name_downcase(nextname, nextname, NULL);
dns_name_downcase(nextname, nextname);
dns_name_fullcompare(name, nextname, &order, &nlabels);
addnowildcardhash(hashlist, name, hashalg, iterations, salt,
salt_len);
@@ -2577,7 +2574,7 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
isc_buffer_add(&b, len);
name = dns_fixedname_initname(&fname);
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
fatal("failed converting name '%s' to dns format: %s", origin,
isc_result_totext(result));
@@ -3378,10 +3375,6 @@ main(int argc, char *argv[]) {
bool set_optout = false;
bool set_iter = false;
bool nonsecify = false;
bool set_fips_mode = false;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER *fips = NULL, *base = NULL;
#endif
atomic_init(&shuttingdown, false);
atomic_init(&finished, false);
@@ -3670,7 +3663,9 @@ main(int argc, char *argv[]) {
break;
case 'F':
set_fips_mode = true;
if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
break;
case '?':
@@ -3741,27 +3736,6 @@ main(int argc, char *argv[]) {
isc_managers_create(&mctx, nloops, &loopmgr, &netmgr);
if (set_fips_mode) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
fips = OSSL_PROVIDER_load(NULL, "fips");
if (fips == NULL) {
ERR_clear_error();
fatal("Failed to load FIPS provider");
}
base = OSSL_PROVIDER_load(NULL, "base");
if (base == NULL) {
OSSL_PROVIDER_unload(fips);
ERR_clear_error();
fatal("Failed to load base provider");
}
#endif
if (!isc_fips_mode()) {
if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
fatal("setting FIPS mode failed");
}
}
}
setup_logging();
argc -= isc_commandline_index;
@@ -4133,15 +4107,6 @@ main(int argc, char *argv[]) {
isc_mem_stats(mctx, stdout);
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (base != NULL) {
OSSL_PROVIDER_unload(base);
}
if (fips != NULL) {
OSSL_PROVIDER_unload(fips);
}
#endif
isc_managers_destroy(&mctx, &loopmgr, &netmgr);
if (printstats) {
+4 -2
View File
@@ -23,6 +23,7 @@
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/hex.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/mutex.h>
@@ -43,6 +44,7 @@
#include <dns/ds.h>
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
#include <dns/lib.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/nsec.h>
@@ -103,7 +105,7 @@ loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
isc_buffer_add(&b, len);
name = dns_fixedname_initname(&fname);
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
fatal("failed converting name '%s' to dns format: %s", origin,
isc_result_totext(result));
@@ -328,7 +330,7 @@ main(int argc, char *argv[]) {
if (verbose > 10) {
isc_mem_stats(mctx, stdout);
}
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
return result == ISC_R_SUCCESS ? 0 : 1;
}
+2
View File
@@ -931,6 +931,7 @@
<th>Messages Received</th>
<th>Records Received</th>
<th>Bytes Received</th>
<th>Transfer Rate (B/s)</th>
</tr>
</thead>
<tbody>
@@ -959,6 +960,7 @@
<td><xsl:value-of select="nmsg"/></td>
<td><xsl:value-of select="nrecs"/></td>
<td><xsl:value-of select="nbytes"/></td>
<td><xsl:value-of select="rate"/></td>
</tr>
</xsl:for-each>
</tbody>
+5 -5
View File
@@ -459,7 +459,7 @@ dns64_cname(const dns_name_t *zone, const dns_name_t *name, bdbnode_t *node) {
static isc_result_t
builtin_lookup(bdb_t *bdb, const dns_name_t *name, bdbnode_t *node) {
if (name->labels == 0 && name->length == 0) {
if (name->length == 0) {
return bdb->lookup(node);
} else if ((node->bdb->implementation->flags & BDB_DNS64) != 0) {
return dns64_cname(&bdb->common.origin, name, node);
@@ -839,7 +839,7 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep DNS__DB_FLARG) {
REQUIRE(VALID_BDB(bdb));
REQUIRE(nodep != NULL && *nodep == NULL);
dns_name_init(&relname, NULL);
dns_name_init(&relname);
name = &relname;
result = createnode(bdb, &node);
@@ -881,7 +881,7 @@ findnode(dns_db_t *db, const dns_name_t *name, bool create,
isorigin = dns_name_equal(name, &bdb->common.origin);
labels = dns_name_countlabels(name) - dns_name_countlabels(&db->origin);
dns_name_init(&relname, NULL);
dns_name_init(&relname);
dns_name_getlabelsequence(name, 0, labels, &relname);
name = &relname;
@@ -1197,8 +1197,8 @@ create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
isc_refcount_init(&bdb->common.references, 1);
isc_mem_attach(mctx, &bdb->common.mctx);
dns_name_init(&bdb->common.origin, NULL);
dns_name_dupwithoffsets(origin, mctx, &bdb->common.origin);
dns_name_init(&bdb->common.origin);
dns_name_dup(origin, mctx, &bdb->common.origin);
INSIST(argc >= 1);
if (strcmp(argv[0], "authors") == 0) {
+8 -3
View File
@@ -99,6 +99,7 @@ options {\n\
recursing-file \"named.recursing\";\n\
recursive-clients 1000;\n\
request-nsid false;\n\
request-zoneversion false;\n\
resolver-query-timeout 10;\n\
# responselog <boolean>;\n\
rrset-order { order random; };\n\
@@ -111,6 +112,8 @@ options {\n\
session-keyname local-ddns;\n\
startup-notify-rate 20;\n\
sig0checks-quota 1;\n\
sig0key-checks-limit 16;\n\
sig0message-checks-limit 2;\n\
statistics-file \"named.stats\";\n\
tcp-advertised-timeout 300;\n\
tcp-clients 150;\n\
@@ -118,7 +121,6 @@ options {\n\
tcp-initial-timeout 300;\n\
tcp-keepalive-timeout 300;\n\
tcp-listen-queue 10;\n\
tcp-primaries-timeout 150;\n\
tcp-receive-buffer 0;\n\
tcp-send-buffer 0;\n\
# tkey-domain <none>\n\
@@ -233,10 +235,12 @@ options {\n\
max-transfer-time-out 120;\n\
min-refresh-time 300;\n\
min-retry-time 500;\n\
min-transfer-rate-in 10240 5;\n\
multi-master no;\n\
notify yes;\n\
notify-delay 5;\n\
notify-to-soa no;\n\
provide-zoneversion yes;\n\
send-report-channel .;\n\
serial-update-method increment;\n\
sig-signing-nodes 100;\n\
@@ -258,6 +262,7 @@ view \"_bind\" chaos {\n\
notify no;\n\
allow-new-zones no;\n\
max-cache-size 2M;\n\
provide-zoneversion no;\n\
\n\
# Prevent use of this zone in DNS amplified reflection DoS attacks\n\
rate-limit {\n\
@@ -549,14 +554,14 @@ named_config_getname(isc_mem_t *mctx, const cfg_obj_t *obj,
}
*namep = isc_mem_get(mctx, sizeof(**namep));
dns_name_init(*namep, NULL);
dns_name_init(*namep);
objstr = cfg_obj_asstring(obj);
isc_buffer_constinit(&b, objstr, strlen(objstr));
isc_buffer_add(&b, strlen(objstr));
dns_fixedname_init(&fname);
result = dns_name_fromtext(dns_fixedname_name(&fname), &b, dns_rootname,
0, NULL);
0);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, *namep, sizeof(**namep));
*namep = NULL;
-1
View File
@@ -736,7 +736,6 @@ controlkeylist_fromcfg(const cfg_obj_t *keylist, isc_mem_t *mctx,
key->secret.length = 0;
ISC_LINK_INIT(key, link);
ISC_LIST_APPEND(*keyids, key, link);
newstr = NULL;
}
}
-1
View File
@@ -25,7 +25,6 @@
#include <string.h>
#include <unistd.h>
#include <isc/condition.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/mutex.h>
-1
View File
@@ -86,7 +86,6 @@ EXTERN named_server_t *named_g_server INIT(NULL);
/*
* Logging.
*/
EXTERN bool named_g_logging INIT(false);
EXTERN unsigned int named_g_debuglevel INIT(0);
/*
-2
View File
@@ -52,8 +52,6 @@ named_log_init(bool safe) {
named_log_setdefaultsslkeylogfile(lcfg);
rcu_read_unlock();
named_g_logging = true;
return ISC_R_SUCCESS;
cleanup:
+46 -111
View File
@@ -30,9 +30,9 @@
#include <isc/crypto.h>
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/fips.h>
#include <isc/hash.h>
#include <isc/httpd.h>
#include <isc/lib.h>
#include <isc/managers.h>
#include <isc/netmgr.h>
#include <isc/os.h>
@@ -47,6 +47,7 @@
#include <dns/dispatch.h>
#include <dns/dyndb.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/resolver.h>
#include <dns/view.h>
@@ -89,10 +90,6 @@
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/err.h>
#include <openssl/provider.h>
#endif
#ifdef HAVE_LIBXML2
#include <libxml/parser.h>
#include <libxml/xmlversion.h>
@@ -132,6 +129,7 @@ static int maxudp = 0;
/*
* -T options:
*/
static bool cookiealwaysvalid = false;
static bool dropedns = false;
static bool ednsformerr = false;
static bool ednsnotimp = false;
@@ -153,24 +151,13 @@ static bool transferstuck = false;
static bool disable6 = false;
static bool disable4 = false;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
static OSSL_PROVIDER *fips = NULL, *base = NULL;
#endif
void
named_main_earlywarning(const char *format, ...) {
va_list args;
va_start(args, format);
if (named_g_logging) {
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_WARNING, format, args);
} else {
fprintf(stderr, "%s: ", program_name);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fflush(stderr);
}
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_WARNING, format, args);
va_end(args);
}
@@ -179,18 +166,10 @@ named_main_earlyfatal(const char *format, ...) {
va_list args;
va_start(args, format);
if (named_g_logging) {
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, format, args);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"exiting (due to early fatal error)");
} else {
fprintf(stderr, "%s: ", program_name);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fflush(stderr);
}
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, format, args);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, "exiting (due to early fatal error)");
va_end(args);
_exit(EXIT_FAILURE);
@@ -207,26 +186,19 @@ assertion_failed(const char *file, int line, isc_assertiontype_t type,
* Handle assertion failures.
*/
if (named_g_logging) {
/*
* Reset the assertion callback in case it is the log
* routines causing the assertion.
*/
isc_assertion_setcallback(NULL);
/*
* Reset the assertion callback in case it is the log
* routines causing the assertion.
*/
isc_assertion_setcallback(NULL);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, "%s:%d: %s(%s) failed", file,
line, isc_assertion_typetotext(type), cond);
isc_backtrace_log(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_MAIN, ISC_LOG_CRITICAL);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"exiting (due to assertion failure)");
} else {
fprintf(stderr, "%s:%d: %s(%s) failed\n", file, line,
isc_assertion_typetotext(type), cond);
fflush(stderr);
}
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, "%s:%d: %s(%s) failed", file, line,
isc_assertion_typetotext(type), cond);
isc_backtrace_log(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, "exiting (due to assertion failure)");
if (named_g_coreok) {
abort();
@@ -245,27 +217,20 @@ library_fatal_error(const char *file, int line, const char *func,
* Handle isc_error_fatal() calls from our libraries.
*/
if (named_g_logging) {
/*
* Reset the error callback in case it is the log
* routines causing the assertion.
*/
isc_error_setfatal(NULL);
/*
* Reset the error callback in case it is the log
* routines causing the assertion.
*/
isc_error_setfatal(NULL);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"%s:%d:%s(): fatal error: ", file, line, func);
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, format, args);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"exiting (due to fatal error in library)");
} else {
fprintf(stderr, "%s:%d:%s(): fatal error: ", file, line, func);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fflush(stderr);
}
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, "%s:%d:%s(): fatal error: ", file, line,
func);
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL, format, args);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_CRITICAL,
"exiting (due to fatal error in library)");
if (named_g_coreok) {
abort();
@@ -285,19 +250,11 @@ library_unexpected_error(const char *file, int line, const char *func,
* Handle isc_error_unexpected() calls from our libraries.
*/
if (named_g_logging) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_ERROR,
"%s:%d:%s(): unexpected error: ", file, line,
func);
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_ERROR, format, args);
} else {
fprintf(stderr, "%s:%d:%s(): fatal error: ", file, line, func);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fflush(stderr);
}
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_ERROR, "%s:%d:%s(): unexpected error: ", file,
line, func);
isc_log_vwrite(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_MAIN,
ISC_LOG_ERROR, format, args);
}
static void
@@ -696,7 +653,9 @@ parse_T_opt(char *option) {
* force the server to behave (or misbehave) in
* specified ways for testing purposes.
*/
if (!strcmp(option, "dropedns")) {
if (!strcmp(option, "cookiealwaysvalid")) {
cookiealwaysvalid = true;
} else if (!strcmp(option, "dropedns")) {
dropedns = true;
} else if (!strcmp(option, "ednsformerr")) {
ednsformerr = true;
@@ -950,25 +909,7 @@ parse_command_line(int argc, char *argv[]) {
named_main_earlyfatal("option '-X' has been removed");
break;
case 'F':
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
fips = OSSL_PROVIDER_load(NULL, "fips");
if (fips == NULL) {
ERR_clear_error();
named_main_earlyfatal(
"Failed to load FIPS provider");
}
base = OSSL_PROVIDER_load(NULL, "base");
if (base == NULL) {
OSSL_PROVIDER_unload(fips);
ERR_clear_error();
named_main_earlyfatal(
"Failed to load base provider");
}
#endif
if (isc_fips_mode()) { /* Already in FIPS mode. */
break;
}
if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
if (isc_crypto_fips_enable() != ISC_R_SUCCESS) {
named_main_earlyfatal(
"setting FIPS mode failed");
}
@@ -1282,6 +1223,9 @@ setup(void) {
/*
* Modify server context according to command line options
*/
if (cookiealwaysvalid) {
ns_server_setoption(sctx, NS_SERVER_COOKIEALWAYSVALID, true);
}
if (disable4) {
ns_server_setoption(sctx, NS_SERVER_DISABLE4, true);
}
@@ -1572,15 +1516,6 @@ main(int argc, char *argv[]) {
named_os_shutdown();
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (base != NULL) {
OSSL_PROVIDER_unload(base);
}
if (fips != NULL) {
OSSL_PROVIDER_unload(fips);
}
#endif
#ifdef HAVE_GPERFTOOLS_PROFILER
ProfilerStop();
#endif /* ifdef HAVE_GPERFTOOLS_PROFILER */
+76 -85
View File
@@ -38,7 +38,6 @@
#include <isc/commandline.h>
#include <isc/dir.h>
#include <isc/file.h>
#include <isc/fips.h>
#include <isc/hash.h>
#include <isc/hex.h>
#include <isc/hmac.h>
@@ -178,8 +177,6 @@
#define MAX_KEEPALIVE_TIMEOUT UINT32_C(UINT16_MAX * 100)
#define MIN_ADVERTISED_TIMEOUT UINT32_C(0) /* No minimum */
#define MAX_ADVERTISED_TIMEOUT UINT32_C(UINT16_MAX * 100)
#define MIN_PRIMARIES_TIMEOUT UINT32_C(2500) /* 2.5 seconds */
#define MAX_PRIMARIES_TIMEOUT UINT32_C(120000) /* 2 minutes */
/*%
* Check an operation for failure. Assumes that the function
@@ -666,7 +663,7 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config,
str = cfg_obj_asstring(nameobj);
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0));
result = dns_nametree_add(*ntp, name, true);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(nameobj, ISC_LOG_ERROR,
@@ -726,7 +723,7 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, const char **namestrp,
name = dns_fixedname_initname(&fname);
isc_buffer_constinit(&namebuf, namestr, strlen(namestr));
isc_buffer_add(&namebuf, strlen(namestr));
CHECK(dns_name_fromtext(name, &namebuf, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(name, &namebuf, dns_rootname, 0));
if (*initialp) {
atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype"));
@@ -915,7 +912,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
isc_buffer_constinit(&b, namestr, strlen(namestr));
isc_buffer_add(&b, strlen(namestr));
keyname = dns_fixedname_initname(&fkeyname);
result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(keyname, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
return result;
}
@@ -1308,7 +1305,7 @@ configure_order(dns_order_t *order, const cfg_obj_t *ent) {
isc_buffer_add(&b, strlen(str));
dns_fixedname_init(&fixed);
result = dns_name_fromtext(dns_fixedname_name(&fixed), &b, dns_rootname,
0, NULL);
0);
if (result != ISC_R_SUCCESS) {
return result;
}
@@ -1394,6 +1391,13 @@ configure_peer(const cfg_obj_t *cpeer, isc_mem_t *mctx, dns_peer_t **peerp) {
CHECK(dns_peer_setrequestnsid(peer, cfg_obj_asboolean(obj)));
}
obj = NULL;
(void)cfg_map_get(cpeer, "request-zoneversion", &obj);
if (obj != NULL) {
CHECK(dns_peer_setrequestzoneversion(peer,
cfg_obj_asboolean(obj)));
}
obj = NULL;
(void)cfg_map_get(cpeer, "send-cookie", &obj);
if (obj != NULL) {
@@ -1593,7 +1597,7 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0));
algorithms = cfg_tuple_get(disabled, "algorithms");
for (element = cfg_list_first(algorithms); element != NULL;
@@ -1636,7 +1640,7 @@ disable_ds_digests(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
str = cfg_obj_asstring(cfg_tuple_get(disabled, "name"));
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0));
digests = cfg_tuple_get(disabled, "digests");
for (element = cfg_list_first(digests); element != NULL;
@@ -1680,7 +1684,7 @@ on_disable_list(const cfg_obj_t *disablelist, dns_name_t *zonename) {
str = cfg_obj_asstring(value);
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &b, dns_rootname, 0);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dns_name_equal(name, zonename)) {
return true;
@@ -1863,7 +1867,7 @@ dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
name = dns_fixedname_initname(&fixed);
isc_buffer_constinit(&b, reverse, strlen(reverse));
isc_buffer_add(&b, strlen(reverse));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(name, &b, dns_rootname, 0));
dns_zone_create(&zone, mctx, 0);
dns_zone_setorigin(zone, name);
dns_zone_setview(zone, view);
@@ -2747,7 +2751,7 @@ configure_catz_zone(dns_view_t *view, dns_view_t *pview,
dns_name_t origin;
dns_catz_options_t *opts;
dns_name_init(&origin, NULL);
dns_name_init(&origin);
catz_obj = cfg_listelt_value(element);
str = cfg_obj_asstring(cfg_tuple_get(catz_obj, "zone name"));
@@ -3090,7 +3094,7 @@ add_ns(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name,
ns.common.rdtype = dns_rdatatype_ns;
ns.common.rdclass = dns_db_class(db);
ns.mctx = NULL;
dns_name_init(&ns.name, NULL);
dns_name_init(&ns.name);
dns_name_clone(nsname, &ns.name);
CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns,
&ns, &b));
@@ -3249,6 +3253,7 @@ create_empty_zone(dns_zone_t *pzone, dns_name_t *name, dns_view_t *view,
dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, false);
dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true);
dns_zone_setoption(zone, DNS_ZONEOPT_ZONEVERSION, false);
dns_zone_setcheckdstype(zone, dns_checkdstype_no);
dns_zone_setnotifytype(zone, dns_notifytype_no);
dns_zone_setautomatic(zone, true);
@@ -3765,7 +3770,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
uint32_t maxbits;
unsigned int resopts = 0;
dns_zone_t *zone = NULL;
uint32_t max_clients_per_query;
uint32_t clients_per_query, max_clients_per_query;
bool empty_zones_enable;
const cfg_obj_t *disablelist = NULL;
isc_stats_t *resstats = NULL;
@@ -4705,6 +4710,19 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
dns_view_settransports(view, transports);
dns_transport_list_detach(&transports);
/*
* Configure SIG(0) check limits when matching a DNS message to a view.
*/
obj = NULL;
result = named_config_get(maps, "sig0key-checks-limit", &obj);
INSIST(result == ISC_R_SUCCESS);
view->sig0key_checks_limit = cfg_obj_asuint32(obj);
obj = NULL;
result = named_config_get(maps, "sig0message-checks-limit", &obj);
INSIST(result == ISC_R_SUCCESS);
view->sig0message_checks_limit = cfg_obj_asuint32(obj);
/*
* Configure the view's TSIG keys.
*/
@@ -5122,6 +5140,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
INSIST(result == ISC_R_SUCCESS);
view->requestnsid = cfg_obj_asboolean(obj);
obj = NULL;
result = named_config_get(maps, "request-zoneversion", &obj);
INSIST(result == ISC_R_SUCCESS);
view->requestzoneversion = cfg_obj_asboolean(obj);
obj = NULL;
result = named_config_get(maps, "send-cookie", &obj);
INSIST(result == ISC_R_SUCCESS);
@@ -5158,15 +5181,26 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
INSIST(result == ISC_R_SUCCESS);
view->v6bias = cfg_obj_asuint32(obj) * 1000;
obj = NULL;
result = named_config_get(maps, "clients-per-query", &obj);
INSIST(result == ISC_R_SUCCESS);
clients_per_query = cfg_obj_asuint32(obj);
obj = NULL;
result = named_config_get(maps, "max-clients-per-query", &obj);
INSIST(result == ISC_R_SUCCESS);
max_clients_per_query = cfg_obj_asuint32(obj);
obj = NULL;
result = named_config_get(maps, "clients-per-query", &obj);
INSIST(result == ISC_R_SUCCESS);
dns_resolver_setclientsperquery(view->resolver, cfg_obj_asuint32(obj),
if (max_clients_per_query < clients_per_query) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"configured clients-per-query (%u) exceeds "
"max-clients-per-query (%u); automatically "
"adjusting max-clients-per-query to (%u)",
clients_per_query, max_clients_per_query,
clients_per_query);
max_clients_per_query = clients_per_query;
}
dns_resolver_setclientsperquery(view->resolver, clients_per_query,
max_clients_per_query);
/*
@@ -5865,8 +5899,8 @@ configure_alternates(const cfg_obj_t *config, dns_view_t *view,
isc_buffer_constinit(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
name = dns_fixedname_initname(&fixed);
CHECK(dns_name_fromtext(name, &buffer, dns_rootname, 0,
NULL));
CHECK(dns_name_fromtext(name, &buffer, dns_rootname,
0));
portobj = cfg_tuple_get(alternate, "port");
if (cfg_obj_isuint32(portobj)) {
@@ -5921,7 +5955,7 @@ validate_tls(const cfg_obj_t *config, dns_view_t *view, const cfg_obj_t *obj,
if (name != NULL && *name == NULL) {
*name = isc_mem_get(view->mctx, sizeof(dns_name_t));
dns_name_init(*name, NULL);
dns_name_init(*name);
dns_name_dup(nm, view->mctx, *name);
}
@@ -6221,7 +6255,7 @@ configure_zone(const cfg_obj_t *config, const cfg_obj_t *zconfig,
isc_buffer_add(&buffer, strlen(zname));
dns_fixedname_init(&fixorigin);
CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin), &buffer,
dns_rootname, 0, NULL));
dns_rootname, 0));
origin = dns_fixedname_name(&fixorigin);
CHECK(named_config_getclass(cfg_tuple_get(zconfig, "class"),
@@ -7232,7 +7266,7 @@ configure_session_key(const cfg_obj_t **maps, named_server_t *server,
isc_buffer_constinit(&buffer, keynamestr, strlen(keynamestr));
isc_buffer_add(&buffer, strlen(keynamestr));
keyname = dns_fixedname_initname(&fname);
result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0, NULL);
result = dns_name_fromtext(keyname, &buffer, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
return result;
}
@@ -7284,7 +7318,7 @@ configure_session_key(const cfg_obj_t **maps, named_server_t *server,
INSIST(server->session_keybits == 0);
server->session_keyname = isc_mem_get(mctx, sizeof(dns_name_t));
dns_name_init(server->session_keyname, NULL);
dns_name_init(server->session_keyname);
dns_name_dup(keyname, mctx, server->session_keyname);
server->session_keyfile = isc_mem_strdup(mctx, keyfile);
@@ -7790,8 +7824,7 @@ get_newzone_config(dns_view_t *view, const char *zonename,
isc_buffer_constinit(&b, zonename, strlen(zonename));
isc_buffer_add(&b, strlen(zonename));
name = dns_fixedname_initname(&fname);
CHECK(dns_name_fromtext(name, &b, dns_rootname, DNS_NAME_DOWNCASE,
NULL));
CHECK(dns_name_fromtext(name, &b, dns_rootname, DNS_NAME_DOWNCASE));
dns_name_format(name, zname, sizeof(zname));
key.mv_data = zname;
@@ -7868,7 +7901,7 @@ load_configuration(const char *filename, named_server_t *server,
ns_altsecretlist_t altsecrets, tmpaltsecrets;
uint32_t softquota = 0;
uint32_t max;
uint64_t initial, idle, keepalive, advertised, primaries;
uint64_t initial, idle, keepalive, advertised;
bool loadbalancesockets;
bool exclusive = true;
dns_aclenv_t *env =
@@ -7901,7 +7934,7 @@ load_configuration(const char *filename, named_server_t *server,
/*
* Shut down all dyndb instances.
*/
dns_dyndb_cleanup(false);
dns_dyndb_cleanup();
/*
* Parse the global default pseudo-config file.
@@ -8207,29 +8240,8 @@ load_configuration(const char *filename, named_server_t *server,
advertised = MAX_ADVERTISED_TIMEOUT;
}
obj = NULL;
result = named_config_get(maps, "tcp-primaries-timeout", &obj);
INSIST(result == ISC_R_SUCCESS);
primaries = cfg_obj_asuint32(obj) * 100;
if (primaries > MAX_PRIMARIES_TIMEOUT) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"tcp-primaries-timeout value is out of range: "
"lowering to %" PRIu32,
MAX_PRIMARIES_TIMEOUT / 100);
primaries = MAX_PRIMARIES_TIMEOUT;
} else if (primaries < MIN_PRIMARIES_TIMEOUT) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"tcp-primaries-timeout value is out of range: "
"raising to %" PRIu32,
MIN_PRIMARIES_TIMEOUT / 100);
primaries = MIN_PRIMARIES_TIMEOUT;
}
isc_nm_setinitialtimeout(named_g_netmgr, initial);
isc_nm_setprimariestimeout(named_g_netmgr, primaries);
isc_nm_setidletimeout(named_g_netmgr, idle);
isc_nm_setkeepalivetimeout(named_g_netmgr, keepalive);
isc_nm_setadvertisedtimeout(named_g_netmgr, advertised);
isc_nm_settimeouts(named_g_netmgr, initial, idle, keepalive,
advertised);
#define CAP_IF_NOT_ZERO(v, min, max) \
if (v > 0 && v < min) { \
@@ -9388,7 +9400,7 @@ view_loaded(void *arg) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_NOTICE, "FIPS mode is %s",
isc_fips_mode() ? "enabled" : "disabled");
isc_crypto_fips_mode() ? "enabled" : "disabled");
#if HAVE_LIBSYSTEMD
sd_notifyf(0,
@@ -9601,7 +9613,7 @@ shutdown_server(void *arg) {
/*
* Shut down all dyndb instances.
*/
dns_dyndb_cleanup(true);
dns_dyndb_cleanup();
while ((nsc = ISC_LIST_HEAD(server->cachelist)) != NULL) {
ISC_LIST_UNLINK(server->cachelist, nsc, link);
@@ -11843,7 +11855,7 @@ named_server_flushnode(named_server_t *server, isc_lex_t *lex, bool tree) {
isc_buffer_constinit(&b, target, strlen(target));
isc_buffer_add(&b, strlen(target));
name = dns_fixedname_initname(&fixed);
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(name, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
return result;
}
@@ -12551,7 +12563,7 @@ nzd_setkey(MDB_val *key, dns_name_t *name, char *namebuf, size_t buflen) {
dns_fixedname_t fixed;
dns_fixedname_init(&fixed);
dns_name_downcase(name, dns_fixedname_name(&fixed), NULL);
dns_name_downcase(name, dns_fixedname_name(&fixed));
dns_name_format(dns_fixedname_name(&fixed), namebuf, buflen);
key->mv_data = namebuf;
@@ -12953,7 +12965,7 @@ load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
isc_buffer_add(&b, strlen(origin));
name = dns_fixedname_initname(&fname);
CHECK(dns_name_fromtext(name, &b, dns_rootname,
DNS_NAME_DOWNCASE, NULL));
DNS_NAME_DOWNCASE));
dns_name_format(name, zname, sizeof(zname));
key.mv_data = zname;
@@ -13662,7 +13674,7 @@ named_server_changezone(named_server_t *server, char *command,
isc_buffer_add(&buf, strlen(zonename));
dnsname = dns_fixedname_initname(&fname);
CHECK(dns_name_fromtext(dnsname, &buf, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(dnsname, &buf, dns_rootname, 0));
if (redirect) {
if (!dns_name_equal(dnsname, dns_rootname)) {
@@ -15228,7 +15240,7 @@ named_server_nta(named_server_t *server, isc_lex_t *lex, bool readonly,
isc_buffer_t b;
isc_buffer_init(&b, namebuf, strlen(namebuf));
isc_buffer_add(&b, strlen(namebuf));
CHECK(dns_name_fromtext(fname, &b, dns_rootname, 0, NULL));
CHECK(dns_name_fromtext(fname, &b, dns_rootname, 0));
ntaname = fname;
}
@@ -15825,7 +15837,7 @@ isc_result_t
named_server_tcptimeouts(isc_lex_t *lex, isc_buffer_t **text) {
char *ptr;
isc_result_t result = ISC_R_SUCCESS;
uint32_t initial, idle, keepalive, advertised, primaries;
uint32_t initial, idle, keepalive, advertised;
char msg[128];
/* Skip the command name. */
@@ -15834,11 +15846,8 @@ named_server_tcptimeouts(isc_lex_t *lex, isc_buffer_t **text) {
return ISC_R_UNEXPECTEDEND;
}
initial = isc_nm_getinitialtimeout(named_g_netmgr);
primaries = isc_nm_getprimariestimeout(named_g_netmgr);
idle = isc_nm_getidletimeout(named_g_netmgr);
keepalive = isc_nm_getkeepalivetimeout(named_g_netmgr);
advertised = isc_nm_getadvertisedtimeout(named_g_netmgr);
isc_nm_gettimeouts(named_g_netmgr, &initial, &idle, &keepalive,
&advertised);
/* Look for optional arguments. */
ptr = next_token(lex, NULL);
@@ -15888,24 +15897,8 @@ named_server_tcptimeouts(isc_lex_t *lex, isc_buffer_t **text) {
CHECK(ISC_R_RANGE);
}
ptr = next_token(lex, text);
if (ptr == NULL) {
return ISC_R_UNEXPECTEDEND;
}
CHECK(isc_parse_uint32(&primaries, ptr, 10));
primaries *= 100;
if (primaries > MAX_PRIMARIES_TIMEOUT) {
CHECK(ISC_R_RANGE);
}
if (primaries < MIN_PRIMARIES_TIMEOUT) {
CHECK(ISC_R_RANGE);
}
isc_nm_setinitialtimeout(named_g_netmgr, initial);
isc_nm_setprimariestimeout(named_g_netmgr, primaries);
isc_nm_setidletimeout(named_g_netmgr, idle);
isc_nm_setkeepalivetimeout(named_g_netmgr, keepalive);
isc_nm_setadvertisedtimeout(named_g_netmgr, advertised);
isc_nm_settimeouts(named_g_netmgr, initial, idle, keepalive,
advertised);
}
snprintf(msg, sizeof(msg), "tcp-initial-timeout=%u\n", initial / 100);
@@ -15915,11 +15908,9 @@ named_server_tcptimeouts(isc_lex_t *lex, isc_buffer_t **text) {
snprintf(msg, sizeof(msg), "tcp-keepalive-timeout=%u\n",
keepalive / 100);
CHECK(putstr(text, msg));
snprintf(msg, sizeof(msg), "tcp-advertised-timeout=%u\n",
snprintf(msg, sizeof(msg), "tcp-advertised-timeout=%u",
advertised / 100);
CHECK(putstr(text, msg));
snprintf(msg, sizeof(msg), "tcp-primaries-timeout=%u", primaries / 100);
CHECK(putstr(text, msg));
cleanup:
if (isc_buffer_usedlength(*text) > 0) {
+32 -12
View File
@@ -97,7 +97,7 @@ typedef struct stats_dumparg {
isc_result_t result;
} stats_dumparg_t;
static isc_once_t once = ISC_ONCE_INIT;
static isc_once_t once = ISC_ONCE_INITIALIZER;
#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
#define EXTENDED_STATS
@@ -358,6 +358,8 @@ init_desc(void) {
SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt");
SET_NSSTATDESC(keepaliveopt, "EDNS TCP keepalive option received",
"KeepAliveOpt");
SET_NSSTATDESC(zoneversionopt, "ZONEVERSION option received",
"ZoneVersionOpt");
SET_NSSTATDESC(padopt, "EDNS padding option received", "PadOpt");
SET_NSSTATDESC(otheropt, "Other EDNS option received", "OtherOpt");
SET_NSSTATDESC(cookiein, "COOKIE option received", "CookieIn");
@@ -1488,6 +1490,7 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
unsigned int nmsg = 0;
unsigned int nrecs = 0;
uint64_t nbytes = 0;
uint64_t rate = 0;
statlevel = dns_zone_getstatlevel(zone);
if (statlevel == dns_zonestat_none) {
@@ -1602,7 +1605,7 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
} else if (is_presoa) {
addr = dns_zone_getsourceaddr(zone);
dns_zone_getsourceaddr(zone, &addr);
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
} else {
@@ -1616,9 +1619,13 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
isc_sockaddr_format(addrp, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
} else if (is_presoa) {
addr = dns_zone_getprimaryaddr(zone);
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR addr_buf));
if (dns_zone_getprimaryaddr(zone, &addr) == ISC_R_SUCCESS) {
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
TRY0(xmlTextWriterWriteString(writer,
ISC_XMLCHAR addr_buf));
} else {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
} else {
TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
}
@@ -1701,7 +1708,7 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
TRY0(xmlTextWriterEndElement(writer));
if (is_running) {
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes);
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes, &rate);
}
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nmsg"));
TRY0(xmlTextWriterWriteFormatString(writer, "%u", nmsg));
@@ -1712,6 +1719,9 @@ xfrin_xmlrender(dns_zone_t *zone, void *arg) {
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nbytes"));
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, nbytes));
TRY0(xmlTextWriterEndElement(writer));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rate"));
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIu64, rate));
TRY0(xmlTextWriterEndElement(writer));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ixfr"));
if (is_running && is_first_data_received) {
@@ -2559,6 +2569,7 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
unsigned int nmsg = 0;
unsigned int nrecs = 0;
uint64_t nbytes = 0;
uint64_t rate = 0;
statlevel = dns_zone_getstatlevel(zone);
if (statlevel == dns_zonestat_none) {
@@ -2651,7 +2662,7 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
json_object_object_add(xfrinobj, "localaddr",
json_object_new_string(addr_buf));
} else if (is_presoa) {
addr = dns_zone_getsourceaddr(zone);
dns_zone_getsourceaddr(zone, &addr);
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
json_object_object_add(xfrinobj, "localaddr",
json_object_new_string(addr_buf));
@@ -2666,10 +2677,15 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string(addr_buf));
} else if (is_presoa) {
addr = dns_zone_getprimaryaddr(zone);
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string(addr_buf));
if (dns_zone_getprimaryaddr(zone, &addr) == ISC_R_SUCCESS) {
isc_sockaddr_format(&addr, addr_buf, sizeof(addr_buf));
json_object_object_add(
xfrinobj, "remoteaddr",
json_object_new_string(addr_buf));
} else {
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string("-"));
}
} else {
json_object_object_add(xfrinobj, "remoteaddr",
json_object_new_string("-"));
@@ -2756,7 +2772,7 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
}
if (is_running) {
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes);
dns_xfrin_getstats(xfr, &nmsg, &nrecs, &nbytes, &rate);
}
json_object_object_add(xfrinobj, "nmsg",
json_object_new_int64((int64_t)nmsg));
@@ -2766,6 +2782,10 @@ xfrin_jsonrender(dns_zone_t *zone, void *arg) {
xfrinobj, "nbytes",
json_object_new_int64(nbytes > INT64_MAX ? INT64_MAX
: (int64_t)nbytes));
json_object_object_add(xfrinobj, "rate",
json_object_new_int64(rate > INT64_MAX
? INT64_MAX
: (int64_t)rate));
if (is_running && is_first_data_received) {
json_object_object_add(
+3 -3
View File
@@ -62,9 +62,9 @@ named_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_constinit(&b, s, strlen(s));
isc_buffer_add(&b, strlen(s));
name = dns_fixedname_initname(&fname);
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0));
tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t));
dns_name_init(tctx->domain, NULL);
dns_name_init(tctx->domain);
dns_name_dup(name, mctx, tctx->domain);
}
@@ -76,7 +76,7 @@ named_tkeyctx_fromconfig(const cfg_obj_t *options, isc_mem_t *mctx,
isc_buffer_constinit(&b, s, strlen(s));
isc_buffer_add(&b, strlen(s));
name = dns_fixedname_initname(&fname);
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0));
RETERR(dst_gssapi_acquirecred(name, false, &tctx->gsscred));
}
+21 -23
View File
@@ -27,17 +27,16 @@
#include <named/log.h>
#include <named/transportconf.h>
#define create_name(id, name) \
isc_buffer_t namesrc, namebuf; \
char namedata[DNS_NAME_FORMATSIZE + 1]; \
dns_name_init(name, NULL); \
isc_buffer_constinit(&namesrc, id, strlen(id)); \
isc_buffer_add(&namesrc, strlen(id)); \
isc_buffer_init(&namebuf, namedata, sizeof(namedata)); \
result = (dns_name_fromtext(name, &namesrc, dns_rootname, \
DNS_NAME_DOWNCASE, &namebuf)); \
if (result != ISC_R_SUCCESS) { \
goto failure; \
#define create_name(id, name) \
isc_buffer_t namesrc; \
dns_fixedname_t _fn; \
name = dns_fixedname_initname(&_fn); \
isc_buffer_constinit(&namesrc, id, strlen(id)); \
isc_buffer_add(&namesrc, strlen(id)); \
result = (dns_name_fromtext(name, &namesrc, dns_rootname, \
DNS_NAME_DOWNCASE)); \
if (result != ISC_R_SUCCESS) { \
goto failure; \
}
#define parse_transport_option(map, transport, name, setter) \
@@ -100,15 +99,15 @@ add_doh_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
for (const cfg_listelt_t *element = cfg_list_first(transportlist);
element != NULL; element = cfg_list_next(element))
{
dns_name_t dohname;
dns_transport_t *transport;
dns_name_t *dohname = NULL;
dns_transport_t *transport = NULL;
doh = cfg_listelt_value(element);
dohid = cfg_obj_asstring(cfg_map_getname(doh));
create_name(dohid, &dohname);
create_name(dohid, dohname);
transport = dns_transport_new(&dohname, DNS_TRANSPORT_HTTP,
transport = dns_transport_new(dohname, DNS_TRANSPORT_HTTP,
list);
dns_transport_set_tlsname(transport, dohid);
@@ -148,8 +147,8 @@ add_tls_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
for (const cfg_listelt_t *element = cfg_list_first(transportlist);
element != NULL; element = cfg_list_next(element))
{
dns_name_t tlsname;
dns_transport_t *transport;
dns_name_t *tlsname = NULL;
dns_transport_t *transport = NULL;
tls = cfg_listelt_value(element);
tlsid = cfg_obj_asstring(cfg_map_getname(tls));
@@ -159,10 +158,9 @@ add_tls_transports(const cfg_obj_t *transportlist, dns_transport_list_t *list) {
goto failure;
}
create_name(tlsid, &tlsname);
create_name(tlsid, tlsname);
transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS,
list);
transport = dns_transport_new(tlsname, DNS_TRANSPORT_TLS, list);
dns_transport_set_tlsname(transport, tlsid);
parse_transport_option(tls, transport, "key-file",
@@ -222,12 +220,12 @@ transport_list_fromconfig(const cfg_obj_t *config, dns_transport_list_t *list) {
static void
transport_list_add_ephemeral(dns_transport_list_t *list) {
isc_result_t result;
dns_name_t tlsname;
dns_name_t *tlsname = NULL;
dns_transport_t *transport;
create_name("ephemeral", &tlsname);
create_name("ephemeral", tlsname);
transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS, list);
transport = dns_transport_new(tlsname, DNS_TRANSPORT_TLS, list);
dns_transport_set_tlsname(transport, "ephemeral");
return;
+6 -8
View File
@@ -46,11 +46,11 @@ add_initial_keys(const cfg_obj_t *list, dns_tsigkeyring_t *ring,
{
const cfg_obj_t *algobj = NULL;
const cfg_obj_t *secretobj = NULL;
dns_name_t keyname;
dns_fixedname_t fkey;
dns_name_t *keyname = dns_fixedname_initname(&fkey);
dst_algorithm_t alg = DST_ALG_UNKNOWN;
const char *algstr = NULL;
char keynamedata[1024];
isc_buffer_t keynamesrc, keynamebuf;
isc_buffer_t keynamesrc;
const char *secretstr = NULL;
isc_buffer_t secretbuf;
int secretlen = 0;
@@ -68,12 +68,10 @@ add_initial_keys(const cfg_obj_t *list, dns_tsigkeyring_t *ring,
/*
* Create the key name.
*/
dns_name_init(&keyname, NULL);
isc_buffer_constinit(&keynamesrc, keyid, strlen(keyid));
isc_buffer_add(&keynamesrc, strlen(keyid));
isc_buffer_init(&keynamebuf, keynamedata, sizeof(keynamedata));
ret = dns_name_fromtext(&keyname, &keynamesrc, dns_rootname,
DNS_NAME_DOWNCASE, &keynamebuf);
ret = dns_name_fromtext(keyname, &keynamesrc, dns_rootname,
DNS_NAME_DOWNCASE);
if (ret != ISC_R_SUCCESS) {
goto failure;
}
@@ -103,7 +101,7 @@ add_initial_keys(const cfg_obj_t *list, dns_tsigkeyring_t *ring,
}
secretlen = isc_buffer_usedlength(&secretbuf);
ret = dns_tsigkey_create(&keyname, alg, secret, secretlen, mctx,
ret = dns_tsigkey_create(keyname, alg, secret, secretlen, mctx,
&tsigkey);
isc_mem_put(mctx, secret, secretalloc);
secret = NULL;
+43 -12
View File
@@ -253,7 +253,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(dns_fixedname_name(&fident), &b,
dns_rootname, 0, NULL);
dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -283,7 +283,7 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone,
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(dns_fixedname_name(&fname),
&b, dns_rootname, 0, NULL);
&b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(identity, ISC_LOG_ERROR,
"'%s' is not a valid name", str);
@@ -518,7 +518,7 @@ configure_staticstub_servernames(const cfg_obj_t *zconfig, dns_zone_t *zone,
isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(nsname, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(nsname, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(zconfig, ISC_LOG_ERROR,
"server-name '%s' is not a valid "
@@ -633,7 +633,7 @@ configure_staticstub(const cfg_obj_t *zconfig, dns_zone_t *zone,
*/
CHECK(dns_db_newversion(db, &dbversion));
dns_name_init(&apexname, NULL);
dns_name_init(&apexname);
dns_name_clone(dns_zone_getorigin(zone), &apexname);
CHECK(dns_db_findnode(db, &apexname, false, &apexnode));
@@ -1227,6 +1227,12 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setkasp(zone, NULL);
}
obj = NULL;
result = named_config_get(maps, "provide-zoneversion", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setoption(zone, DNS_ZONEOPT_ZONEVERSION,
cfg_obj_asboolean(obj));
obj = NULL;
result = named_config_get(maps, "notify", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
@@ -1279,22 +1285,22 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
obj = NULL;
result = named_config_get(maps, "parental-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
CHECK(dns_zone_setparentalsrc4(zone, cfg_obj_assockaddr(obj)));
dns_zone_setparentalsrc4(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "parental-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
CHECK(dns_zone_setparentalsrc6(zone, cfg_obj_assockaddr(obj)));
dns_zone_setparentalsrc6(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
CHECK(dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj)));
dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
CHECK(dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj)));
dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-to-soa", &obj);
@@ -1874,6 +1880,33 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
}
dns_zone_setoption(mayberaw, DNS_ZONEOPT_MULTIMASTER, multi);
obj = NULL;
result = named_config_get(maps, "min-transfer-rate-in", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
uint32_t traffic_bytes =
cfg_obj_asuint32(cfg_tuple_get(obj, "traffic_bytes"));
uint32_t time_minutes =
cfg_obj_asuint32(cfg_tuple_get(obj, "time_minutes"));
if (traffic_bytes == 0) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"zone '%s': 'min-transfer-rate-in' bytes"
"value can not be '0'",
zname);
CHECK(ISC_R_FAILURE);
}
/* Max. 28 days (in minutes). */
const unsigned int time_minutes_max = 28 * 24 * 60;
if (time_minutes < 1 || time_minutes > time_minutes_max) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"zone '%s': 'min-transfer-rate-in' minutes"
"value is out of range (1..%u)",
zname, time_minutes_max);
CHECK(ISC_R_FAILURE);
}
dns_zone_setminxfrratein(mayberaw, traffic_bytes,
transferinsecs ? time_minutes
: time_minutes * 60);
obj = NULL;
result = named_config_get(maps, "max-transfer-time-in", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
@@ -1911,14 +1944,12 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
obj = NULL;
result = named_config_get(maps, "transfer-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
CHECK(dns_zone_setxfrsource4(mayberaw,
cfg_obj_assockaddr(obj)));
dns_zone_setxfrsource4(mayberaw, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "transfer-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
CHECK(dns_zone_setxfrsource6(mayberaw,
cfg_obj_assockaddr(obj)));
dns_zone_setxfrsource6(mayberaw, cfg_obj_assockaddr(obj));
obj = NULL;
(void)named_config_get(maps, "try-tcp-refresh", &obj);
+29 -35
View File
@@ -30,6 +30,7 @@
#include <isc/getaddresses.h>
#include <isc/hash.h>
#include <isc/lex.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/managers.h>
@@ -52,6 +53,7 @@
#include <dns/dispatch.h>
#include <dns/dnssec.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/masterdump.h>
#include <dns/message.h>
#include <dns/name.h>
@@ -521,8 +523,7 @@ setup_keystr(void) {
isc_buffer_add(&keynamesrc, (unsigned int)(n - name));
debug("namefromtext");
result = dns_name_fromtext(mykeyname, &keynamesrc, dns_rootname, 0,
NULL);
result = dns_name_fromtext(mykeyname, &keynamesrc, dns_rootname, 0);
check_result(result, "dns_name_fromtext");
secretlen = strlen(secretstr) * 3 / 4;
@@ -784,16 +785,14 @@ set_source_ports(dns_dispatchmgr_t *manager) {
}
static isc_result_t
create_name(const char *str, char *namedata, size_t len, dns_name_t *name) {
isc_buffer_t namesrc, namebuf;
create_name(const char *str, dns_name_t *name) {
isc_buffer_t namesrc;
dns_name_init(name, NULL);
isc_buffer_constinit(&namesrc, str, strlen(str));
isc_buffer_add(&namesrc, strlen(str));
isc_buffer_init(&namebuf, namedata, len);
return dns_name_fromtext(name, &namesrc, dns_rootname,
DNS_NAME_DOWNCASE, &namebuf);
DNS_NAME_DOWNCASE);
}
static void
@@ -803,8 +802,8 @@ setup_system(void *arg ISC_ATTR_UNUSED) {
isc_sockaddrlist_t *nslist;
isc_logconfig_t *logconfig = NULL;
irs_resconf_t *resconf = NULL;
dns_name_t tlsname;
char namedata[DNS_NAME_FORMATSIZE + 1];
dns_fixedname_t ftls;
dns_name_t *tlsname = dns_fixedname_initname(&ftls);
ddebug("setup_system()");
@@ -938,17 +937,15 @@ setup_system(void *arg ISC_ATTR_UNUSED) {
isc_tlsctx_cache_create(gmctx, &tls_ctx_cache);
if (tls_client_key_file == NULL) {
result = create_name("tls-non-auth-client", namedata,
sizeof(namedata), &tlsname);
result = create_name("tls-non-auth-client", tlsname);
check_result(result, "create_name (tls-non-auth-client)");
transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS,
transport = dns_transport_new(tlsname, DNS_TRANSPORT_TLS,
transport_list);
dns_transport_set_tlsname(transport, "tls-non-auth-client");
} else {
result = create_name("tls-auth-client", namedata,
sizeof(namedata), &tlsname);
result = create_name("tls-auth-client", tlsname);
check_result(result, "create_name (tls-auth-client)");
transport = dns_transport_new(&tlsname, DNS_TRANSPORT_TLS,
transport = dns_transport_new(tlsname, DNS_TRANSPORT_TLS,
transport_list);
dns_transport_set_tlsname(transport, "tls-auth-client");
dns_transport_set_keyfile(transport, tls_client_key_file);
@@ -1307,7 +1304,7 @@ parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) {
dns_message_gettempname(msg, namep);
isc_buffer_init(&source, word, strlen(word));
isc_buffer_add(&source, strlen(word));
result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL);
result = dns_name_fromtext(*namep, &source, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
error("invalid owner name: %s", isc_result_totext(result));
isc_buffer_invalidate(&source);
@@ -1733,7 +1730,7 @@ evaluate_key(char *cmdline) {
isc_buffer_init(&b, namestr, strlen(namestr));
isc_buffer_add(&b, strlen(namestr));
result = dns_name_fromtext(mykeyname, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(mykeyname, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
fprintf(stderr, "could not parse key name\n");
return STATUS_SYNTAX;
@@ -1787,7 +1784,7 @@ evaluate_zone(char *cmdline) {
userzone = dns_fixedname_initname(&fuserzone);
isc_buffer_init(&b, word, strlen(word));
isc_buffer_add(&b, strlen(word));
result = dns_name_fromtext(userzone, &b, dns_rootname, 0, NULL);
result = dns_name_fromtext(userzone, &b, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
userzone = NULL; /* Lest it point to an invalid name */
fprintf(stderr, "could not parse zone name\n");
@@ -2612,8 +2609,8 @@ done:
if (usegsstsig) {
dns_name_free(&tmpzonename, gmctx);
dns_name_free(&restart_primary, gmctx);
dns_name_init(&tmpzonename, 0);
dns_name_init(&restart_primary, 0);
dns_name_init(&tmpzonename);
dns_name_init(&restart_primary);
}
done_update();
}
@@ -2879,7 +2876,7 @@ lookforsoa:
result = dns_rdata_tostruct(&soarr, &soa, NULL);
check_result(result, "dns_rdata_tostruct");
dns_name_init(&primary, NULL);
dns_name_init(&primary);
dns_name_clone(&soa.origin, &primary);
if (userzone != NULL) {
@@ -2935,9 +2932,9 @@ lookforsoa:
#if HAVE_GSSAPI
if (usegsstsig) {
dns_name_init(&tmpzonename, NULL);
dns_name_init(&tmpzonename);
dns_name_dup(zname, gmctx, &tmpzonename);
dns_name_init(&restart_primary, NULL);
dns_name_init(&restart_primary);
dns_name_dup(&primary, gmctx, &restart_primary);
start_gssrequest(&primary);
} else {
@@ -2966,7 +2963,7 @@ droplabel:
if (nlabels == 1) {
fatal("could not find enclosing zone");
}
dns_name_init(&tname, NULL);
dns_name_init(&tname);
dns_name_getlabelsequence(name, 1, nlabels - 1, &tname);
dns_name_clone(&tname, name);
dns_request_destroy(&request);
@@ -3073,8 +3070,8 @@ failed_gssrequest(void) {
dns_name_free(&tmpzonename, gmctx);
dns_name_free(&restart_primary, gmctx);
dns_name_init(&tmpzonename, NULL);
dns_name_init(&restart_primary, NULL);
dns_name_init(&tmpzonename);
dns_name_init(&restart_primary);
done_update();
}
@@ -3121,7 +3118,7 @@ start_gssrequest(dns_name_t *primary) {
RUNTIME_CHECK(result < sizeof(servicename));
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
result = dns_name_fromtext(servname, &buf, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
fatal("dns_name_fromtext(servname) failed: %s",
isc_result_totext(result));
@@ -3138,7 +3135,7 @@ start_gssrequest(dns_name_t *primary) {
isc_buffer_init(&buf, mykeystr, strlen(mykeystr));
isc_buffer_add(&buf, strlen(mykeystr));
result = dns_name_fromtext(keyname, &buf, dns_rootname, 0, NULL);
result = dns_name_fromtext(keyname, &buf, dns_rootname, 0);
if (result != ISC_R_SUCCESS) {
fatal("dns_name_fromtext(keyname) failed: %s",
isc_result_totext(result));
@@ -3297,7 +3294,7 @@ recvgss(void *arg) {
servname = dns_fixedname_initname(&fname);
isc_buffer_init(&buf, servicename, strlen(servicename));
isc_buffer_add(&buf, strlen(servicename));
result = dns_name_fromtext(servname, &buf, dns_rootname, 0, NULL);
result = dns_name_fromtext(servname, &buf, dns_rootname, 0);
check_result(result, "dns_name_fromtext");
result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname, &context,
@@ -3519,7 +3516,7 @@ getinput(void *arg) {
int
main(int argc, char **argv) {
const uint32_t timeoutms = timeout * MS_PER_SEC;
uint32_t timeoutms;
style = &dns_master_style_debug;
@@ -3544,11 +3541,8 @@ main(int argc, char **argv) {
parse_args(argc, argv);
/* Set the network manager timeouts in milliseconds. */
isc_nm_setinitialtimeout(netmgr, timeoutms);
isc_nm_setprimariestimeout(netmgr, timeoutms);
isc_nm_setidletimeout(netmgr, timeoutms);
isc_nm_setkeepalivetimeout(netmgr, timeoutms);
isc_nm_setadvertisedtimeout(netmgr, timeoutms);
timeoutms = timeout * 1000;
isc_nm_settimeouts(netmgr, timeoutms, timeoutms, timeoutms, timeoutms);
isc_loopmgr_setup(loopmgr, setup_system, NULL);
isc_loopmgr_setup(loopmgr, getinput, NULL);
+4 -5
View File
@@ -22,6 +22,7 @@
#include <isc/commandline.h>
#include <isc/file.h>
#include <isc/getaddresses.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/managers.h>
@@ -36,6 +37,7 @@
#include <isc/thread.h>
#include <isc/util.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <isccc/alist.h>
@@ -212,7 +214,7 @@ command is one of the following:\n\
Dump a single zone's changes to disk, and optionally\n\
remove its journal file.\n\
tcp-timeouts Display the tcp-*-timeout option values\n\
tcp-timeouts initial idle keepalive advertised primaries\n\
tcp-timeouts initial idle keepalive advertised\n\
Update the tcp-*-timeout option values\n\
thaw Enable updates to all dynamic zones and reload them.\n\
thaw zone [class [view]]\n\
@@ -957,10 +959,7 @@ main(int argc, char **argv) {
isc_managers_create(&rndc_mctx, 1, &loopmgr, &netmgr);
isc_loopmgr_setup(loopmgr, rndc_start, NULL);
isc_nm_setinitialtimeout(netmgr, timeout);
isc_nm_setprimariestimeout(netmgr, timeout);
isc_nm_setidletimeout(netmgr, timeout);
isc_nm_setkeepalivetimeout(netmgr, timeout);
isc_nm_settimeouts(netmgr, timeout, timeout, timeout, 0);
logconfig = isc_logconfig_get();
isc_log_settag(logconfig, progname);
+1
View File
@@ -28,6 +28,7 @@ options {
} except-from {
"example";
};
qname-minimization disabled; // Regression test for GL #4652
};
trust-anchors { };
@@ -31,6 +31,7 @@ server 0.0.0.0 {
request-ixfr no;
request-ixfr-max-diffs 0;
request-nsid no;
request-zoneversion no;
require-cookie no;
send-cookie no;
tcp-keepalive no;
@@ -55,6 +56,7 @@ server :: {
request-ixfr no;
request-ixfr-max-diffs 0;
request-nsid no;
request-zoneversion no;
require-cookie no;
send-cookie no;
tcp-keepalive no;
+4 -2
View File
@@ -131,11 +131,13 @@ status=$((status + ret))
echo_i "checking that log-report-channel zones fail if '*._er/TXT' is missing ($n)"
ret=0
$CHECKZONE -R fail example zones/er.db >test.out2.$n 2>&1 || ret=1
grep -F "no '*._er/TXT' wildcard found" test.out4.$n >/dev/null && ret=1
grep -F "no '*._er/TXT' wildcard found" test.out2.$n >/dev/null && ret=1
$CHECKZONE example zones/er-missing.db >test.out3.$n 2>&1 || ret=1
grep -F "no '*._er/TXT' wildcard found" test.out4.$n >/dev/null && ret=1
grep -F "no '*._er/TXT' wildcard found" test.out3.$n >/dev/null && ret=1
$CHECKZONE -R fail example zones/er-missing.db >test.out4.$n 2>&1 && ret=1
grep -F "no '*._er/TXT' wildcard found" test.out4.$n >/dev/null || ret=1
n=$((n + 1))
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "checking that raw zone with bad class is handled ($n)"
+1
View File
@@ -308,6 +308,7 @@ def logger(request, system_test_name):
@pytest.fixture(scope="module")
def expected_artifacts(request):
common_artifacts = [
"*/.hypothesis", # drop after Ubuntu 20.04 Focal Fossa gets removed from CI
".libs/*", # possible build artifacts, see GL #5055
"ns*/named.conf",
"ns*/named.memstats",
+26 -4
View File
@@ -361,6 +361,23 @@ grep "status: NOERROR," dig.out.test$n >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "Restart NS4 with -T cookiealwaysvalid ($n)"
stop_server ns4
touch ns4/named.cookiealwaysvalid
start_server --noclean --restart --port ${PORT} ns4 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "test NS6 cookie on NS4 with -T cookiealwaysvalid (expect success) ($n)"
ret=0
$DIG $DIGOPTS +cookie=$ns6cookie -b 10.53.0.4 +nobadcookie soa . @10.53.0.4 >dig.out.test$n || ret=1
grep "; COOKIE:.*(good)" dig.out.test$n >/dev/null || ret=1
grep "status: NOERROR," dig.out.test$n >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "check that test server is correctly configured ($n)"
ret=0
@@ -552,16 +569,21 @@ sys.exit(1)'; then
$DIG $DIGOPTS @10.53.0.1 tsig. >dig.out.test$n.1 || ret=1
grep "status: NOERROR" dig.out.test$n.1 >/dev/null || ret=1
rndc_dumpdb ns1
# prime cache with NS response for QNAME minimisation
grep "$pat" ns1/named_dump.db.test$n >/dev/null || ret=1
$DIG $DIGOPTS @10.53.0.1 NS nocookie.tsig >dig.out.test$n.2 || ret=1
grep "status: NOERROR" dig.out.test$n.2 >/dev/null || ret=1
# check the disabled server response
nextpart ns1/named.run >/dev/null
$DIG $DIGOPTS @10.53.0.1 nocookie.tsig >dig.out.test$n.2 || ret=1
grep "status: NOERROR" dig.out.test$n.2 >/dev/null || ret=1
grep 'A.10\.53\.0\.9' dig.out.test$n.2 >/dev/null || ret=1
grep 'A.10\.53\.0\.10' dig.out.test$n.2 >/dev/null || ret=1
$DIG $DIGOPTS @10.53.0.1 nocookie.tsig >dig.out.test$n.3 || ret=1
grep "status: NOERROR" dig.out.test$n.3 >/dev/null || ret=1
grep 'A.10\.53\.0\.9' dig.out.test$n.3 >/dev/null || ret=1
grep 'A.10\.53\.0\.10' dig.out.test$n.3 >/dev/null || ret=1
nextpart ns1/named.run >named.run.test$n
count=$(grep -c ') [0-9][0-9]* NOERROR 0' named.run.test$n)
test $count -eq 2 || ret=1
count=$(grep -c '^; COOKIE: ................................' named.run.test$n)
test $count -eq 1 || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
@@ -19,6 +19,7 @@ pytestmark = pytest.mark.extra_artifacts(
"ans*/ans.run",
"ans*/query.log",
"ns1/named_dump.db*",
"ns4/named.cookiealwaysvalid",
]
)
@@ -36,4 +36,5 @@ zone "example" {
zone "example.tld" {
type primary;
file "example.tld.db";
provide-zoneversion no;
};
+80
View File
@@ -801,6 +801,73 @@ if [ -x "$DIG" ]; then
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking dig +zoneversion to a authoritative server ($n)"
ret=0
dig_with_opts @10.53.0.2 +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
pat="; ZONEVERSION: ZONE: example, SOA-SERIAL: 2000042407"
grep "$pat" dig.out.test$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking dig +zoneversion to a authoritative server with zoneversion disabled ($n)"
ret=0
dig_with_opts @10.53.0.2 +zoneversion a.example.tld >dig.out.test$n 2>&1 || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "; ZONEVERSION:" dig.out.test$n >/dev/null && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
if [ $HAS_PYYAML -ne 0 ]; then
n=$((n + 1))
echo_i "checking dig +yaml +zoneversion to a authoritative server ($n)"
ret=0
dig_with_opts @10.53.0.2 +yaml +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
$PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS ZONEVERSION >yamlget.out.test$n 2>&1 || ret=1
read -r value <yamlget.out.test$n
expected="{'ZONE': 'example', 'SOA-SERIAL': 2000042407}"
[ "$value" = "$expected" ] || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
n=$((n + 1))
echo_i "checking dig +ednsopt=ZONEVERSION:<answer> to a authoritative server ($n)"
ret=0
dig_with_opts @10.53.0.2 +ednsopt=ZONEVERSION:0100000007DA a.example >dig.out.test$n 2>&1 || ret=1
grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
grep "; ZONEVERSION:" dig.out.test$n >/dev/null && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking dig +zoneversion to a recursive server ($n)"
ret=0
dig_with_opts @10.53.0.3 +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
grep '; ZONEVERSION:' dig.out.test$n >/dev/null && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking display of non serial type zoneversion ($n)"
ret=0
dig_with_opts @10.53.0.2 +qr +ednsopt=ZONEVERSION:0100000007DA a.example >dig.out.test$n 2>&1 || ret=1
grep '; ZONEVERSION: LABELS: 1, TYPE: 0, VALUE: 000007da ("....")' dig.out.test$n >/dev/null && ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
if [ $HAS_PYYAML -ne 0 ]; then
n=$((n + 1))
echo_i "checking display of non serial type zoneversion +yaml ($n)"
ret=0
dig_with_opts @10.53.0.2 +qr +ednsopt=ZONEVERSION:0100000007DA a.example +yaml >dig.out.test$n 2>&1 || ret=1
$PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS ZONEVERSION >yamlget.out.test$n 2>&1 || ret=1
expected="{'ZONE': 'example', 'TYPE': 1, 'VALUE': 000007da, PVALUE: '....'}"
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
fi
n=$((n + 1))
echo_i "check that dig gracefully handles bad escape in domain name ($n)"
ret=0
@@ -1135,6 +1202,16 @@ if [ -x "$DIG" ]; then
grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "check that dig +showbadvers works ($n)"
dig_with_opts @10.53.0.3 +edns=1 +qr +showbadvers a.example >dig.out.test$n 2>&1 || ret=1
grep "; EDNS: version: 1, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
grep -F "status: BADVERS" dig.out.test$n >/dev/null || ret=1
grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
else
echo_i "$DIG is needed, so skipping these dig tests"
fi
@@ -1483,6 +1560,7 @@ if [ -x "$DELV" ]; then
n=$((n + 1))
echo_i "check that delv handles REFUSED when chasing DS records ($n)"
ret=0
delv_with_opts @10.53.0.2 +root xxx.example.tld A >delv.out.test$n 2>&1 || ret=1
grep ";; resolution failed: broken trust chain" delv.out.test$n >/dev/null || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
@@ -1490,9 +1568,11 @@ if [ -x "$DELV" ]; then
n=$((n + 1))
echo_i "check NS output from delv +ns ($n)"
ret=0
delv_with_opts -i +ns +nortrace +nostrace +nomtrace +novtrace +hint=../_common/root.hint ns example >delv.out.test$n || ret=1
lines=$(awk '$1 == "example." && $4 == "NS" {print}' delv.out.test$n | wc -l)
[ $lines -eq 2 ] || ret=1
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
+6
View File
@@ -38,6 +38,7 @@ def logquery(type, qname):
# NS gets a unsigned response.
# DNSKEY get a unsigned NODATA response.
# A gets a signed response.
# TXT gets a signed NODATA response without RRSIG.
# All other types get a unsigned NODATA response.
############################################################################
def create_response(msg):
@@ -72,6 +73,11 @@ def create_response(msg):
r.answer.append(dns.rrset.from_text(qname, 1, IN, NS, "."))
elif rrtype == SOA:
r.answer.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
elif rrtype == TXT:
r.authority.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
r.authority.append(
dns.rrset.from_text(qname, 1, IN, NSEC, qname + " A NS SOA RRSIG NSEC")
)
else:
r.authority.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
r.flags |= dns.flags.AA
+4
View File
@@ -43,3 +43,7 @@ dnskey-rrsigs-stripped. NS ns2.dnskey-rrsigs-stripped.
ns2.dnskey-rrsigs-stripped. A 10.53.0.2
ds-rrsigs-stripped. NS ns2.ds-rrsigs-stripped.
ns2.ds-rrsigs-stripped. A 10.53.0.2
inconsistent. NS ns2.inconsistent.
ns2.inconsistent. A 10.53.0.2
nsec-rrsigs-stripped. NS ns10.nsec-rrsigs-stripped.
ns10.nsec-rrsigs-stripped. A 10.53.0.10
+1
View File
@@ -33,6 +33,7 @@ cp "../ns2/dsset-lazy-ksk." .
cp "../ns2/dsset-peer-ns-spoof." .
cp "../ns2/dsset-dnskey-rrsigs-stripped." .
cp "../ns2/dsset-ds-rrsigs-stripped." .
cp "../ns2/dsset-inconsistent." .
grep "$DEFAULT_ALGORITHM_NUMBER [12] " "../ns2/dsset-algroll." >"dsset-algroll."
cp "../ns6/dsset-optout-tld." .
@@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300 ; 5 minutes
@ IN SOA ns2.example. . (
2010042407 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns2.example.
NS ns3.example.
A 10.53.0.1
ns2 A 10.53.0.2
ns3 A 10.53.0.3
@@ -207,6 +207,11 @@ zone "too-many-iterations" {
file "too-many-iterations.db.signed";
};
zone "inconsistent" {
type primary;
file "inconsistent.db.signed";
};
zone "lazy-ksk" {
type primary;
file "lazy-ksk.db";
+12 -1
View File
@@ -64,7 +64,7 @@ for subdomain in digest-alg-unsupported ds-unsupported secure badds \
kskonly update-nsec3 auto-nsec auto-nsec3 secure.below-cname \
ttlpatch split-dnssec split-smart expired expiring upper lower \
dnskey-unknown dnskey-unsupported dnskey-unsupported-2 \
dnskey-nsec3-unknown managed-future revkey \
dnskey-nsec3-unknown managed-future future revkey \
dname-at-apex-nsec3 occluded rsasha1 rsasha1-1024; do
cp "../ns3/dsset-$subdomain.example." .
done
@@ -432,3 +432,14 @@ cat "$infile" "$ksk.key" "$zsk.key" >"$zonefile"
| awk '$4 == "SOA" { $7 = $7 + 1; print; next } { print }' >"$zonefile.next"
"$SIGNER" -g -o "$zone" -f "$zonefile.next" "$zonefile.next" >/dev/null 2>&1
cp "$zonefile.stripped" "$zonefile.signed"
#
# Inconsistent NS RRset between parent and child
#
zone=inconsistent
infile=inconsistent.db.in
zonefile=inconsistent.db
key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone -f KSK "$zone")
key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
cat "$infile" "$key1.key" "$key2.key" >"$zonefile"
"$SIGNER" -3 - -g -o "$zone" "$zonefile" >/dev/null 2>&1
@@ -26,6 +26,8 @@ options {
bindkeys-file "managed.conf";
dnssec-accept-expired yes;
minimal-responses no;
servfail-ttl 0;
disable-algorithms "digest-alg-unsupported.example." { ECDSAP384SHA384; };
disable-ds-digests "digest-alg-unsupported.example." { "SHA384"; "SHA-384";};
disable-ds-digests "ds-unsupported.example." { "SHA256"; "SHA-256"; "SHA384"; "SHA-384"; };
@@ -25,6 +25,7 @@ options {
dnssec-validation yes;
forward only;
forwarders { 10.53.0.4; };
servfail-ttl 0;
};
key rndc_key {
@@ -0,0 +1,6 @@
; This is a key-signing key, keyid 23640, for .
; Created: 20250310185208 (Mon Mar 10 18:52:08 2025)
; Publish: 20250310185208 (Mon Mar 10 18:52:08 2025)
; Activate: 20250310185208 (Mon Mar 10 18:52:08 2025)
; Revoke: 20250310185208 (Mon Mar 10 18:52:08 2025)
. IN DNSKEY 257 3 13 uKwpRtMH+9iuUk/Xj6LciIP5ZckaBtXaUqxUxzJYexXjvxGZGX4470Jv hq2NCI3HBZQNaCCP/h9sluhIzRGPTA==
@@ -0,0 +1,7 @@
Private-key-format: v1.3
Algorithm: 13 (ECDSAP256SHA256)
PrivateKey: m5udfGNSijISQ8Tfp4kx09O1em4PErLUw/mCj3SKmqw=
Created: 20250310185208
Publish: 20250310185208
Activate: 20250310185208
Revoke: 20250310185208
@@ -0,0 +1,5 @@
; This is a zone-signing key, keyid 23768, for .
; Created: 20250310185208 (Mon Mar 10 18:52:08 2025)
; Publish: 20250310185208 (Mon Mar 10 18:52:08 2025)
; Activate: 20250310185208 (Mon Mar 10 18:52:08 2025)
. IN DNSKEY 256 3 13 TFelYtTRBWeA9A307vvuWIcaNwW4txW4RgSELtsi46ZQs24ncRxmxtFf uJuPyVXePNiE4HNI9CIowGUsn5WuBw==
@@ -0,0 +1,37 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
; This is a zone which has two DNSKEY records, both of which have
; existing private key files available. They should be loaded automatically
; and the zone correctly signed.
;
$TTL 30 ; 30 seconds
. IN SOA a.root.servers.nil. each.isc.org. (
2000042101 ; serial
600 ; refresh (10 minutes)
600 ; retry (10 minutes)
1200 ; expire (20 minutes)
600 ; minimum (10 minutes)
)
NS a.root-servers.nil.
DNSKEY 256 3 13 (
TFelYtTRBWeA9A307vvuWIcaNwW4txW4RgSELtsi46ZQ
s24ncRxmxtFfuJuPyVXePNiE4HNI9CIowGUsn5WuBw==
) ; ZSK; alg = ECDSAP256SHA256 ; key id = 23768
DNSKEY 257 3 13 (
OSmhpULEDCUzHCBeDU5uJXzkCcGuW2qrkQznKRPGhRZN
j7ZUIGInGzM5Um5m02ULWt8tKbi55NJUeifKWegQ0g==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 22255
DNSKEY 385 3 13 (
uKwpRtMH+9iuUk/Xj6LciIP5ZckaBtXaUqxUxzJYexXj
vxGZGX4470Jvhq2NCI3HBZQNaCCP/h9sluhIzRGPTA==
) ; revoked KSK; alg = ECDSAP256SHA256 ; key id = 23768
a.root-servers.nil. A 10.53.0.1
+59 -2
View File
@@ -1564,6 +1564,18 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_ic "revoked KSK ID collides with ZSK ($n)"
ret=0
# signing should fail, but should not coredump
(
cd signer/general || exit 0
rm -f signed.zone
$SIGNER -S -f signed.zone -o . test12.zone >signer.out.$n
) && ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_ic "check that dnssec-signzone rejects excessive NSEC3 iterations ($n)"
ret=0
(
@@ -2179,7 +2191,7 @@ echo_i "checking RRSIG query from cache ($n)"
ret=0
dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 a >/dev/null || ret=1
ans=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.4 rrsig) || ret=1
expect=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.3 rrsig | grep '^A') || ret=1
expect=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.3 rrsig | grep -E '^(A|NSEC)') || ret=1
test "$ans" = "$expect" || ret=1
# also check that RA is set
dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 rrsig >dig.out.ns4.test$n || ret=1
@@ -2859,6 +2871,19 @@ dig_with_opts +noauth expired.example. +dnssec @10.53.0.4 soa >dig.out.ns4.test$
grep "SERVFAIL" dig.out.ns4.test$n >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1
grep "expired.example/.*: RRSIG has expired" ns4/named.run >/dev/null || ret=1
grep "; EDE: 7 (Signature Expired): (expired.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
status=$((status + ret))
echo_i "checking signatures in the future do not validate ($n)"
ret=0
dig_with_opts +noauth future.example. +dnssec @10.53.0.4 soa >dig.out.ns4.test$n || ret=1
grep "SERVFAIL" dig.out.ns4.test$n >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1
grep "future.example/.*: RRSIG validity period has not begun" ns4/named.run >/dev/null || ret=1
grep "; EDE: 8 (Signature Not Yet Valid): (future.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
@@ -3755,7 +3780,7 @@ status=$((status + ret))
echo_i "checking EDE code 1 for bad alg mnemonic ($n)"
ret=0
dig_with_opts @10.53.0.4 badalg.secure.example >dig.out.ns4.test$n || ret=1
grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (ECDSAP256SHA256 badalg.secure.example/A)" dig.out.ns4.test$n >/dev/null || ret=1
grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (ECDSAP256SHA256 badalg.secure.example/NSEC)" dig.out.ns4.test$n >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
@@ -4666,5 +4691,37 @@ n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "checking validator behavior with mismatching NS ($n)"
ret=0
rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
$DIG +tcp +cd -p "$PORT" -t ns inconsistent @10.53.0.4 >dig.out.ns4.test$n.1 || ret=1
grep "ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2" dig.out.ns4.test$n.1 >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n.1 >/dev/null && ret=1
$DIG +tcp +cd +dnssec -p "$PORT" -t ns inconsistent @10.53.0.4 >dig.out.ns4.test$n.2 || ret=1
grep "ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2" dig.out.ns4.test$n.2 >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n.2 >/dev/null && ret=1
$DIG +tcp +dnssec -p "$PORT" -t ns inconsistent @10.53.0.4 >dig.out.ns4.test$n.3 || ret=1
grep "ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1" dig.out.ns4.test$n.3 >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n.3 >/dev/null || ret=1
n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "checking that a insecure negative response where there is a NSEC without a RRSIG succeeds ($n)"
ret=0
# check server preconditions
dig_with_opts +notcp @10.53.0.10 nsec-rrsigs-stripped. TXT +dnssec >dig.out.ns10.test$n
grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
grep "QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1" dig.out.ns10.test$n >/dev/null || ret=1
grep "IN.RRSIG.NSEC" dig.out.ns10.test$n >/dev/null && ret=1
# check resolver succeeds
dig_with_opts @10.53.0.4 nsec-rrsigs-stripped. TXT +dnssec >dig.out.ns4.test$n
grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
grep "QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1" dig.out.ns4.test$n >/dev/null || ret=1
grep "IN.RRSIG.NSEC" dig.out.ns4.test$n >/dev/null && ret=1
n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
@@ -70,6 +70,7 @@ pytestmark = pytest.mark.extra_artifacts(
"ns2/settime.out.updatecheck-kskonly.secure.zsk",
"ns2/single-nsec3.db",
"ns2/too-many-iterations.db",
"ns2/inconsistent.db",
"ns2/trusted.db",
"ns2/updatecheck-kskonly.secure.ksk.id",
"ns2/updatecheck-kskonly.secure.ksk.key",
+5 -9
View File
@@ -232,9 +232,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_fixedname_init(&name);
CHECK(dns__db_addrdataset(sampledb->db, node, version, now, rdataset,
options, addedrdataset DNS__DB_FLARG_PASS));
if (rdataset->type == dns_rdatatype_a ||
rdataset->type == dns_rdatatype_aaaa)
{
if (dns_rdatatype_isaddr(rdataset->type)) {
CHECK(dns_db_nodefullname(sampledb->db, node,
dns_fixedname_name(&name)));
CHECK(syncptrs(sampledb->inst, dns_fixedname_name(&name),
@@ -263,9 +261,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
goto cleanup;
}
if (rdataset->type == dns_rdatatype_a ||
rdataset->type == dns_rdatatype_aaaa)
{
if (dns_rdatatype_isaddr(rdataset->type)) {
CHECK(dns_db_nodefullname(sampledb->db, node,
dns_fixedname_name(&name)));
CHECK(syncptrs(sampledb->inst, dns_fixedname_name(&name),
@@ -518,7 +514,7 @@ add_ns(dns_db_t *db, dns_dbversion_t *version, const dns_name_t *name,
ns.common.rdtype = dns_rdatatype_ns;
ns.common.rdclass = dns_db_class(db);
ns.mctx = NULL;
dns_name_init(&ns.name, NULL);
dns_name_init(&ns.name);
dns_name_clone(nsname, &ns.name);
CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns,
&ns, &b));
@@ -608,9 +604,9 @@ create_db(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
};
isc_mem_attach(mctx, &sampledb->common.mctx);
dns_name_init(&sampledb->common.origin, NULL);
dns_name_init(&sampledb->common.origin);
dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin);
dns_name_dup(origin, mctx, &sampledb->common.origin);
isc_refcount_init(&sampledb->common.references, 1);
+1 -1
View File
@@ -224,7 +224,7 @@ syncptr(sample_instance_t *inst, dns_name_t *name, dns_rdata_t *addr_rdata,
dns_fixedname_init(&ptr_name);
DNS_RDATACOMMON_INIT(&ptr_struct, dns_rdatatype_ptr, dns_rdataclass_in);
dns_name_init(&ptr_struct.ptr, NULL);
dns_name_init(&ptr_struct.ptr);
syncptr = isc_mem_get(mctx, sizeof(*syncptr));
*syncptr = (syncptr_t){ 0 };
+5 -3
View File
@@ -23,13 +23,15 @@
#include <openssl/provider.h>
#endif
#include <isc/fips.h>
#include <isc/crypto.h>
#include <isc/lib.h>
#include <isc/md.h>
#include <isc/mem.h>
#include <isc/net.h>
#include <isc/util.h>
#include <dns/edns.h>
#include <dns/lib.h>
#include <dst/dst.h>
@@ -132,7 +134,7 @@ main(int argc, char **argv) {
return 1;
#endif
#else
if (isc_fips_mode()) {
if (isc_crypto_fips_mode()) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
return 0;
#else
@@ -147,7 +149,7 @@ main(int argc, char **argv) {
#if defined(ENABLE_FIPS_MODE)
return 0;
#else
return isc_fips_mode() ? 0 : 1;
return isc_crypto_fips_mode() ? 0 : 1;
#endif
}
@@ -0,0 +1,52 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.5;
notify-source 10.53.0.5;
transfer-source 10.53.0.5;
port @PORT@;
directory ".";
pid-file "named.pid";
listen-on { 10.53.0.5; };
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
notify yes;
stale-answer-enable yes;
stale-cache-enable yes;
stale-answer-client-timeout 0;
/* max-clients-per-query < clients-per-query */
clients-per-query 10;
max-clients-per-query 5;
};
trust-anchors { };
server 10.53.0.4 {
edns no;
};
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "root.hint";
};
+9
View File
@@ -328,5 +328,14 @@ echo_i "$zspill clients spilled (expected $expected)"
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n + 1))
echo_i "checking a warning is logged if max-clients-per-query < clients-per-query ($n)"
ret=0
copy_setports ns5/named3.conf.in ns5/named.conf
rndc_reconfig ns5 10.53.0.5
wait_for_message ns5/named.run "configured clients-per-query (10) exceeds max-clients-per-query (5); automatically adjusting max-clients-per-query to (10)" || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+1 -1
View File
@@ -36,7 +36,7 @@ fi
echo_i "two question types"
$PERL formerr.pl -a 10.53.0.1 -p ${PORT} twoquestiontypes >twoquestiontypes.out
ans=$(grep got: twoquestiontypes.out)
if [ "${ans}" != "got: 0000800100020000000000000e41414141414141414141414141410000010001c00c00020001" ]; then
if [ "${ans}" != "got: 000080010000000000000000" ]; then
echo_i "failed"
status=$((status + 1))
fi
+100 -32
View File
@@ -224,6 +224,20 @@ class DnsProtocol(enum.Enum):
TCP = enum.auto()
@dataclass(frozen=True)
class Peer:
"""
Pretty-printed connection endpoint.
"""
host: str
port: int
def __str__(self) -> str:
host = f"[{self.host}]" if ":" in self.host else self.host
return f"{host}:{self.port}"
@dataclass
class QueryContext:
"""
@@ -232,7 +246,7 @@ class QueryContext:
query: dns.message.Message
response: dns.message.Message
peer: Tuple[str, int]
peer: Peer
protocol: DnsProtocol
zone: Optional[dns.zone.Zone] = None
soa: Optional[dns.rrset.RRset] = None
@@ -513,56 +527,110 @@ class AsyncDnsServer(AsyncServer):
self._zone_tree.add(zone)
async def _handle_udp(
self, wire: bytes, peer: Tuple[str, int], transport: asyncio.DatagramTransport
self, wire: bytes, addr: Tuple[str, int], transport: asyncio.DatagramTransport
) -> None:
logging.debug("Received UDP message: %s", wire.hex())
peer = Peer(addr[0], addr[1])
responses = self._handle_query(wire, peer, DnsProtocol.UDP)
async for response in responses:
transport.sendto(response, peer)
transport.sendto(response, addr)
async def _handle_tcp(
self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter
) -> None:
wire_length_bytes = await reader.read(2)
(wire_length,) = struct.unpack("!H", wire_length_bytes)
logging.debug("Receiving TCP message (%d octets)...", wire_length)
peer_info = writer.get_extra_info("peername")
peer = Peer(peer_info[0], peer_info[1])
logging.debug("Accepted TCP connection from %s", peer)
wire = await reader.read(wire_length)
full_message = wire_length_bytes + wire
logging.debug("Received complete TCP message: %s", full_message.hex())
peer = writer.get_extra_info("peername")
responses = self._handle_query(wire, peer, DnsProtocol.TCP)
async for response in responses:
writer.write(response)
while True:
try:
await writer.drain()
wire = await self._read_tcp_query(reader, peer)
if not wire:
break
await self._send_tcp_response(writer, peer, wire)
except ConnectionResetError:
logging.error(
"TCP connection from %s reset by peer", self._format_peer(peer)
)
logging.error("TCP connection from %s reset by peer", peer)
return
logging.debug("Closing TCP connection from %s", peer)
writer.close()
await writer.wait_closed()
def _format_peer(self, peer: Tuple[str, int]) -> str:
host = peer[0]
port = peer[1]
if "::" in host:
host = f"[{host}]"
return f"{host}:{port}"
async def _read_tcp_query(
self, reader: asyncio.StreamReader, peer: Peer
) -> Optional[bytes]:
wire_length = await self._read_tcp_query_wire_length(reader, peer)
if not wire_length:
return None
def _log_query(
self, qctx: QueryContext, peer: Tuple[str, int], protocol: DnsProtocol
return await self._read_tcp_query_wire(reader, peer, wire_length)
async def _read_tcp_query_wire_length(
self, reader: asyncio.StreamReader, peer: Peer
) -> Optional[int]:
logging.debug("Receiving TCP message length from %s...", peer)
wire_length_bytes = await self._read_tcp_octets(reader, peer, 2)
if not wire_length_bytes:
return None
(wire_length,) = struct.unpack("!H", wire_length_bytes)
return wire_length
async def _read_tcp_query_wire(
self, reader: asyncio.StreamReader, peer: Peer, wire_length: int
) -> Optional[bytes]:
logging.debug("Receiving TCP message (%d octets) from %s...", wire_length, peer)
wire = await self._read_tcp_octets(reader, peer, wire_length)
if not wire:
return None
logging.debug("Received complete TCP message from %s: %s", peer, wire.hex())
return wire
async def _read_tcp_octets(
self, reader: asyncio.StreamReader, peer: Peer, expected: int
) -> Optional[bytes]:
buffer = b""
while len(buffer) < expected:
chunk = await reader.read(expected - len(buffer))
if not chunk:
if buffer:
logging.debug(
"Received short TCP message (%d octets) from %s: %s",
len(buffer),
peer,
buffer.hex(),
)
else:
logging.debug("Received disconnect from %s", peer)
return None
logging.debug("Received %d TCP octets from %s", len(chunk), peer)
buffer += chunk
return buffer
async def _send_tcp_response(
self, writer: asyncio.StreamWriter, peer: Peer, wire: bytes
) -> None:
responses = self._handle_query(wire, peer, DnsProtocol.TCP)
async for response in responses:
writer.write(response)
await writer.drain()
def _log_query(self, qctx: QueryContext, peer: Peer, protocol: DnsProtocol) -> None:
logging.info(
"Received %s/%s/%s (ID=%d) query from %s (%s)",
qctx.qname.to_text(omit_final_dot=True),
dns.rdataclass.to_text(qctx.qclass),
dns.rdatatype.to_text(qctx.qtype),
qctx.query.id,
self._format_peer(peer),
peer,
protocol.name,
)
logging.debug(
@@ -573,14 +641,14 @@ class AsyncDnsServer(AsyncServer):
self,
qctx: QueryContext,
response: Optional[Union[dns.message.Message, bytes]],
peer: Tuple[str, int],
peer: Peer,
protocol: DnsProtocol,
) -> None:
if not response:
logging.info(
"Not sending a response to query (ID=%d) from %s (%s)",
qctx.query.id,
self._format_peer(peer),
peer,
protocol.name,
)
return
@@ -606,7 +674,7 @@ class AsyncDnsServer(AsyncServer):
len(response.authority),
len(response.additional),
qctx.query.id,
self._format_peer(peer),
peer,
protocol.name,
)
logging.debug(
@@ -618,13 +686,13 @@ class AsyncDnsServer(AsyncServer):
"Sending response (%d bytes) to a query (ID=%d) from %s (%s)",
len(response),
qctx.query.id,
self._format_peer(peer),
peer,
protocol.name,
)
logging.debug("[OUT] %s", response.hex())
async def _handle_query(
self, wire: bytes, peer: Tuple[str, int], protocol: DnsProtocol
self, wire: bytes, peer: Peer, protocol: DnsProtocol
) -> AsyncGenerator[bytes, None]:
"""
Yield wire data to send as a response over the established transport.
+6 -7
View File
@@ -130,7 +130,7 @@ $KEYGEN -G -k rsasha256 -l policies/kasp.conf $zone >keygen.out.$zone.2 2>&1
zone="multisigner-model2.kasp"
echo_i "setting up zone: $zone"
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zone -M 32768:65535 2>keygen.out.$zone.2)
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2)
cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db"
cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db"
# Import the ZSK sets of the other providers into their DNSKEY RRset.
@@ -350,10 +350,9 @@ setup step2.enable-dnssec.autosign
TpubN="now-900s"
# RRSIG TTL: 12 hour (43200 seconds)
# zone-propagation-delay: 5 minutes (300 seconds)
# retire-safety: 20 minutes (1200 seconds)
# Already passed time: -900 seconds
# Total: 43800 seconds
TsbmN="now+43800s"
# Total: 42600 seconds
TsbmN="now+42600s"
keytimes="-P ${TpubN} -P sync ${TsbmN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec -l policies/autosign.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1
@@ -365,10 +364,10 @@ $SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $i
# Step 3:
# The zone signatures have been published long enough to become OMNIPRESENT.
setup step3.enable-dnssec.autosign
# Passed time since publications: 43800 + 900 = 44700 seconds.
TpubN="now-44700s"
# Passed time since publications: 42600 + 900 = 43500 seconds.
TpubN="now-43500s"
# The key is secure for using in chain of trust when the DNSKEY is OMNIPRESENT.
TcotN="now-43800s"
TcotN="now-42600s"
# We can submit the DS now.
TsbmN="now"
keytimes="-P ${TpubN} -P sync ${TsbmN} -A ${TpubN}"
+41 -41
View File
@@ -127,9 +127,9 @@ setup step2.algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 3 hours.
TactN="now-3h"
TpubN1="now-3h"
# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp + publish-safety =
# now - 3h + 6h + 1h + 1h = now + 5h
TsbmN1="now+5h"
# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp =
# now - 3h + 6h + 1h = now + 4h
TsbmN1="now+4h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I now"
zsk1times="-P ${TactN} -A ${TactN} -I now"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
@@ -156,11 +156,11 @@ $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infil
# Step 3:
# The zone signatures are also OMNIPRESENT.
setup step3.algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 9 hours.
TactN="now-9h"
TretN="now-6h"
TpubN1="now-9h"
TsbmN1="now-1h"
# The time passed since the new algorithm keys have been introduced is 7 hours.
TactN="now-7h"
TretN="now-3h"
TpubN1="now-7h"
TsbmN1="now"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
@@ -188,11 +188,11 @@ $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infil
# The DS is swapped and can become OMNIPRESENT.
setup step4.algorithm-roll.kasp
# The time passed since the DS has been swapped is 29 hours.
TactN="now-38h"
TretN="now-35h"
TpubN1="now-38h"
TsbmN1="now-30h"
TactN1="now-29h"
TactN="now-36h"
TretN="now-33h"
TpubN1="now-36h"
TsbmN1="now-29h"
TactN1="now-27h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
@@ -220,12 +220,12 @@ $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infil
# The DNSKEY is removed long enough to be HIDDEN.
setup step5.algorithm-roll.kasp
# The time passed since the DNSKEY has been removed is 2 hours.
TactN="now-40h"
TretN="now-37h"
TactN="now-38h"
TretN="now-35h"
TremN="now-2h"
TpubN1="now-40h"
TsbmN1="now-32h"
TactN1="now-31h"
TpubN1="now-38h"
TsbmN1="now-31h"
TactN1="now-29h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
@@ -253,13 +253,13 @@ $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infil
# The RRSIGs have been removed long enough to be HIDDEN.
setup step6.algorithm-roll.kasp
# Additional time passed: 7h.
TactN="now-47h"
TretN="now-44h"
TactN="now-45h"
TretN="now-42h"
TremN="now-7h"
TpubN1="now-47h"
TsbmN1="now-39h"
TactN1="now-38h"
TdeaN="now-9h"
TpubN1="now-45h"
TsbmN1="now-38h"
TactN1="now-36h"
TdeaN="now-7h"
ksk1times="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
zsk1times="-P ${TactN} -A ${TactN} -I ${TretN}"
ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}"
@@ -324,11 +324,11 @@ $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $in
# Step 3:
# The zone signatures are also OMNIPRESENT.
setup step3.csk-algorithm-roll.kasp
# The time passed since the new algorithm keys have been introduced is 9 hours.
TactN="now-9h"
TretN="now-6h"
TpubN1="now-9h"
TactN1="now-6h"
# The time passed since the new algorithm keys have been introduced is 7 hours.
TactN="now-7h"
TretN="now-3h"
TpubN1="now-7h"
TactN1="now-3h"
csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
newtimes="-P ${TpubN1} -A ${TpubN1}"
CSK1=$($KEYGEN -k csk-algoroll -l policies/csk1.conf $csktimes $zone 2>keygen.out.$zone.1)
@@ -347,10 +347,10 @@ $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $in
# The DS is swapped and can become OMNIPRESENT.
setup step4.csk-algorithm-roll.kasp
# The time passed since the DS has been swapped is 29 hours.
TactN="now-38h"
TretN="now-35h"
TpubN1="now-38h"
TactN1="now-35h"
TactN="now-36h"
TretN="now-33h"
TpubN1="now-36h"
TactN1="now-33h"
TsubN1="now-29h"
csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
newtimes="-P ${TpubN1} -A ${TpubN1}"
@@ -370,11 +370,11 @@ $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $in
# The DNSKEY is removed long enough to be HIDDEN.
setup step5.csk-algorithm-roll.kasp
# The time passed since the DNSKEY has been removed is 2 hours.
TactN="now-40h"
TretN="now-37h"
TactN="now-38h"
TretN="now-35h"
TremN="now-2h"
TpubN1="now-40h"
TactN1="now-37h"
TpubN1="now-38h"
TactN1="now-35h"
TsubN1="now-31h"
csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
newtimes="-P ${TpubN1} -A ${TpubN1}"
@@ -394,12 +394,12 @@ $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $in
# The RRSIGs have been removed long enough to be HIDDEN.
setup step6.csk-algorithm-roll.kasp
# Additional time passed: 7h.
TactN="now-47h"
TretN="now-44h"
TactN="now-45h"
TretN="now-42h"
TdeaN="now-9h"
TremN="now-7h"
TpubN1="now-47h"
TactN1="now-44h"
TpubN1="now-45h"
TactN1="now-42h"
TsubN1="now-38h"
csktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN}"
newtimes="-P ${TpubN1} -A ${TpubN1}"
+120 -125
View File
@@ -275,9 +275,8 @@ set_keytimes_csk_policy() {
set_keytime "KEY1" "ACTIVE" "${created}"
# The DS can be published if the DNSKEY and RRSIG records are
# OMNIPRESENT. This happens after max-zone-ttl (1d) plus
# publish-safety (1h) plus zone-propagation-delay (300s) =
# 86400 + 3600 + 300 = 90300.
set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 90300
# zone-propagation-delay (300s) = 86400 + 300 = 86700.
set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 86700
# Key lifetime is unlimited, so not setting RETIRED and REMOVED.
}
@@ -769,9 +768,8 @@ set_keytimes_algorithm_policy() {
# The DS can be published if the DNSKEY and RRSIG records are
# OMNIPRESENT. This happens after max-zone-ttl (1d) plus
# publish-safety (1h) plus zone-propagation-delay (300s) =
# 86400 + 3600 + 300 = 90300.
set_addkeytime "KEY1" "SYNCPUBLISH" "${published}" 90300
# zone-propagation-delay (300s) = 86400 + 300 = 86700.
set_addkeytime "KEY1" "SYNCPUBLISH" "${published}" 86700
# Key lifetime is 10 years, 315360000 seconds.
set_addkeytime "KEY1" "RETIRED" "${published}" 315360000
# The key is removed after the retire time plus DS TTL (1d),
@@ -1720,10 +1718,10 @@ published=$(awk '{print $3}' <published.test${n}.key1)
set_keytime "KEY1" "PUBLISHED" "${published}"
set_keytime "KEY1" "ACTIVE" "${published}"
published=$(key_get KEY1 PUBLISHED)
# The DS can be published if the DNSKEY and RRSIG records are OMNIPRESENT.
# This happens after max-zone-ttl (1d) plus publish-safety (1h) plus
# zone-propagation-delay (300s) = 86400 + 3600 + 300 = 90300.
set_addkeytime "KEY1" "SYNCPUBLISH" "${published}" 90300
# The DS can be published if the zone is fully signed.
# This happens after max-zone-ttl (1d) plus
# zone-propagation-delay (300s) = 86400 + 300 = 86700.
set_addkeytime "KEY1" "SYNCPUBLISH" "${published}" 86700
# Key lifetime is 6 months, 315360000 seconds.
set_addkeytime "KEY1" "RETIRED" "${published}" 16070400
# The key is removed after the retire time plus DS TTL (1d), parent
@@ -2486,9 +2484,9 @@ set_keytime "KEY1" "PUBLISHED" "${created}"
set_keytime "KEY1" "ACTIVE" "${created}"
# - The DS can be published if the DNSKEY and RRSIG records are
# OMNIPRESENT. This happens after max-zone-ttl (12h) plus
# publish-safety (5m) plus zone-propagation-delay (5m) =
# 43200 + 300 + 300 = 43800.
set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 43800
# plus zone-propagation-delay (5m) =
# 43200 + 300 = 43500.
set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 43500
# - Key lifetime is unlimited, so not setting RETIRED and REMOVED.
# Various signing policy checks.
@@ -2556,7 +2554,7 @@ check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "PUBLISHED" "${created}" -900
set_addkeytime "KEY1" "ACTIVE" "${created}" -900
set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 43800
set_addkeytime "KEY1" "SYNCPUBLISH" "${created}" 42600
# Continue signing policy checks.
check_keytimes
@@ -2566,8 +2564,8 @@ dnssec_verify
# Next key event is when the zone signatures become OMNIPRESENT: max-zone-ttl
# plus zone propagation delay plus retire safety minus the already elapsed
# 900 seconds: 12h + 300s + 20m - 900 = 44700 - 900 = 43800 seconds
check_next_key_event 43800
# 900 seconds: 12h + 300s + 20m - 900 = 43500 - 900 = 42600 seconds
check_next_key_event 42600
#
# Zone: step3.enable-dnssec.autosign.
@@ -2584,10 +2582,10 @@ check_keys
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The key was published and activated 44700 seconds ago (with settime).
# - The key was published and activated 43500 seconds ago (with settime).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "PUBLISHED" "${created}" -44700
set_addkeytime "KEY1" "ACTIVE" "${created}" -44700
set_addkeytime "KEY1" "PUBLISHED" "${created}" -43500
set_addkeytime "KEY1" "ACTIVE" "${created}" -43500
set_keytime "KEY1" "SYNCPUBLISH" "${created}"
# Continue signing policy checks.
@@ -2603,8 +2601,8 @@ check_cdslog "$DIR" "$ZONE" KEY1
rndc_checkds "$SERVER" "$DIR" KEY1 "now" "published" "$ZONE"
# Next key event is when the DS can move to the OMNIPRESENT state. This occurs
# when the parent propagation delay have passed, plus the DS TTL and retire
# safety delay: 1h + 2h + 20m = 3h20m = 12000 seconds
check_next_key_event 12000
# safety delay: 1h + 2h = 3h = 10800 seconds
check_next_key_event 10800
#
# Zone: step4.enable-dnssec.autosign.
@@ -4388,9 +4386,9 @@ check_subdomain
dnssec_verify
# Next key event is when the DS becomes HIDDEN. This happens after the
# parent propagation delay, retire safety delay, and DS TTL:
# 1h + 1h + 1d = 26h = 93600 seconds.
check_next_key_event 93600
# parent propagation delay, and DS TTL:
# 1h + 1d = 25h = 90000 seconds.
check_next_key_event 90000
#
# Zone: step2.going-insecure.kasp
@@ -4456,8 +4454,8 @@ dnssec_verify
# Next key event is when the DS becomes HIDDEN. This happens after the
# parent propagation delay, retire safety delay, and DS TTL:
# 1h + 1h + 1d = 26h = 93600 seconds.
check_next_key_event 93600
# 1h + 1d = 25h = 90000 seconds.
check_next_key_event 90000
#
# Zone: step2.going-insecure-dynamic.kasp
@@ -4651,12 +4649,11 @@ set_addkeytime "KEY2" "REMOVED" "${retired}" "${IretZSK}"
created=$(key_get KEY3 CREATED)
set_keytime "KEY3" "PUBLISHED" "${created}"
set_keytime "KEY3" "ACTIVE" "${created}"
# - It takes TTLsig + Dprp + publish-safety hours to propagate the zone.
# - It takes TTLsig + Dprp to propagate the zone.
# TTLsig: 6h (39600 seconds)
# Dprp: 1h (3600 seconds)
# publish-safety: 1h (3600 seconds)
# Ipub: 8h (28800 seconds)
Ipub=28800
# Ipub: 7h (25200 seconds)
Ipub=25200
set_addkeytime "KEY3" "SYNCPUBLISH" "${created}" "${Ipub}"
# - The new ZSK is published and activated.
created=$(key_get KEY4 CREATED)
@@ -4725,12 +4722,12 @@ dnssec_verify
# Next key event is when all zone signatures are signed with the new
# algorithm. This is the max-zone-ttl plus zone propagation delay
# plus retire safety: 6h + 1h + 2h. But three hours have already passed
# (the time it took to make the DNSKEY omnipresent), so the next event
# should be scheduled in 6 hour: 21600 seconds. Prevent intermittent
# 6h + 1h. But three hours have already passed (the time it took to
# make the DNSKEY omnipresent), so the next event should be scheduled
# in 4 hour: 14400 seconds. Prevent intermittent
# false positives on slow platforms by subtracting the number of seconds
# which passed between key creation and invoking 'rndc reconfig'.
next_time=$((21600 - time_passed))
next_time=$((14400 - time_passed))
check_next_key_event $next_time
#
@@ -4753,28 +4750,28 @@ check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
check_cdslog "$DIR" "$ZONE" KEY3
# Set expected key times:
# - The old keys were activated 9 hours ago (32400 seconds).
rollover_predecessor_keytimes -32400
# - And retired 6 hours ago (21600 seconds).
# - The old keys were activated 7 hours ago (25200 seconds).
rollover_predecessor_keytimes -25200
# - And retired 3 hours ago (10800 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -21600
set_addkeytime "KEY1" "RETIRED" "${created}" -10800
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretKSK}"
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "RETIRED" "${created}" -21600
set_addkeytime "KEY2" "RETIRED" "${created}" -10800
retired=$(key_get KEY2 RETIRED)
set_addkeytime "KEY2" "REMOVED" "${retired}" "${IretZSK}"
# - The new keys are published 9 hours ago.
# - The new keys are published 7 hours ago.
created=$(key_get KEY3 CREATED)
set_addkeytime "KEY3" "PUBLISHED" "${created}" -32400
set_addkeytime "KEY3" "ACTIVE" "${created}" -32400
set_addkeytime "KEY3" "PUBLISHED" "${created}" -25200
set_addkeytime "KEY3" "ACTIVE" "${created}" -25200
published=$(key_get KEY3 PUBLISHED)
set_addkeytime "KEY3" "SYNCPUBLISH" "${published}" ${Ipub}
created=$(key_get KEY4 CREATED)
set_addkeytime "KEY4" "PUBLISHED" "${created}" -32400
set_addkeytime "KEY4" "ACTIVE" "${created}" -32400
set_addkeytime "KEY4" "PUBLISHED" "${created}" -25200
set_addkeytime "KEY4" "ACTIVE" "${created}" -25200
# Continue signing policy checks.
check_keytimes
@@ -4787,9 +4784,9 @@ dnssec_verify
rndc_checkds "$SERVER" "$DIR" KEY1 "now" "withdrawn" "$ZONE"
rndc_checkds "$SERVER" "$DIR" KEY3 "now" "published" "$ZONE"
# Next key event is when the DS becomes OMNIPRESENT. This happens after the
# parent propagation delay, retire safety delay, and DS TTL:
# 1h + 2h + 2h = 5h = 18000 seconds.
check_next_key_event 18000
# parent propagation delay, and DS TTL:
# 1h + 2h = 3h = 10800 seconds.
check_next_key_event 10800
#
# Zone: step4.algorithm-roll.kasp
@@ -4816,29 +4813,29 @@ wait_for_done_signing
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The old keys were activated 38 hours ago (136800 seconds).
rollover_predecessor_keytimes -136800
# - And retired 35 hours ago (126000 seconds).
# - The old keys were activated 36 hours ago (129600 seconds).
rollover_predecessor_keytimes -129600
# - And retired 33 hours ago (118800 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -126000
set_addkeytime "KEY1" "RETIRED" "${created}" -118800
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretKSK}"
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "RETIRED" "${created}" -126000
set_addkeytime "KEY2" "RETIRED" "${created}" -118800
retired=$(key_get KEY2 RETIRED)
set_addkeytime "KEY2" "REMOVED" "${retired}" "${IretZSK}"
# - The new keys are published 38 hours ago.
# - The new keys are published 36 hours ago.
created=$(key_get KEY3 CREATED)
set_addkeytime "KEY3" "PUBLISHED" "${created}" -136800
set_addkeytime "KEY3" "ACTIVE" "${created}" -136800
set_addkeytime "KEY3" "PUBLISHED" "${created}" -129600
set_addkeytime "KEY3" "ACTIVE" "${created}" -129600
published=$(key_get KEY3 PUBLISHED)
set_addkeytime "KEY3" "SYNCPUBLISH" "${published}" ${Ipub}
created=$(key_get KEY4 CREATED)
set_addkeytime "KEY4" "PUBLISHED" "${created}" -136800
set_addkeytime "KEY4" "ACTIVE" "${created}" -136800
set_addkeytime "KEY4" "PUBLISHED" "${created}" -129600
set_addkeytime "KEY4" "ACTIVE" "${created}" -129600
# Continue signing policy checks.
check_keytimes
@@ -4867,29 +4864,29 @@ wait_for_done_signing
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The old keys were activated 40 hours ago (144000 seconds)
rollover_predecessor_keytimes -144000
# - And retired 37 hours ago (133200 seconds).
# - The old keys were activated 38 hours ago (136800 seconds)
rollover_predecessor_keytimes -136800
# - And retired 35 hours ago (126000 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -133200
set_addkeytime "KEY1" "RETIRED" "${created}" -126000
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretKSK}"
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "RETIRED" "${created}" -133200
set_addkeytime "KEY2" "RETIRED" "${created}" -126000
retired=$(key_get KEY2 RETIRED)
set_addkeytime "KEY2" "REMOVED" "${retired}" "${IretZSK}"
# The new keys are published 40 hours ago.
created=$(key_get KEY3 CREATED)
set_addkeytime "KEY3" "PUBLISHED" "${created}" -144000
set_addkeytime "KEY3" "ACTIVE" "${created}" -144000
set_addkeytime "KEY3" "PUBLISHED" "${created}" -136800
set_addkeytime "KEY3" "ACTIVE" "${created}" -136800
published=$(key_get KEY3 PUBLISHED)
set_addkeytime "KEY3" "SYNCPUBLISH" "${published}" ${Ipub}
created=$(key_get KEY4 CREATED)
set_addkeytime "KEY4" "PUBLISHED" "${created}" -144000
set_addkeytime "KEY4" "ACTIVE" "${created}" -144000
set_addkeytime "KEY4" "PUBLISHED" "${created}" -136800
set_addkeytime "KEY4" "ACTIVE" "${created}" -136800
# Continue signing policy checks.
check_keytimes
@@ -4898,12 +4895,12 @@ check_subdomain
dnssec_verify
# Next key event is when the RSASHA1 signatures become HIDDEN. This happens
# after the max-zone-ttl plus zone propagation delay plus retire safety
# (6h + 1h + 2h) minus the time already passed since the UNRETENTIVE state has
# been reached (2h): 9h - 2h = 7h = 25200 seconds. Prevent intermittent
# after the max-zone-ttl plus zone propagation delay (6h + 1h)
# minus the time already passed since the UNRETENTIVE state has
# been reached (2h): 7h - 2h = 5h = 18000 seconds. Prevent intermittent
# false positives on slow platforms by subtracting the number of seconds
# which passed between key creation and invoking 'rndc reconfig'.
next_time=$((25200 - time_passed))
next_time=$((18000 - time_passed))
check_next_key_event $next_time
#
@@ -4921,29 +4918,29 @@ wait_for_done_signing
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The old keys were activated 47 hours ago (169200 seconds)
rollover_predecessor_keytimes -169200
# - And retired 44 hours ago (158400 seconds).
# - The old keys were activated 45 hours ago (162000 seconds)
rollover_predecessor_keytimes -162000
# - And retired 42 hours ago (151200 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -158400
set_addkeytime "KEY1" "RETIRED" "${created}" -151200
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretKSK}"
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "RETIRED" "${created}" -158400
set_addkeytime "KEY2" "RETIRED" "${created}" -151200
retired=$(key_get KEY2 RETIRED)
set_addkeytime "KEY2" "REMOVED" "${retired}" "${IretZSK}"
# The new keys are published 47 hours ago.
created=$(key_get KEY3 CREATED)
set_addkeytime "KEY3" "PUBLISHED" "${created}" -169200
set_addkeytime "KEY3" "ACTIVE" "${created}" -169200
set_addkeytime "KEY3" "PUBLISHED" "${created}" -162000
set_addkeytime "KEY3" "ACTIVE" "${created}" -162000
published=$(key_get KEY3 PUBLISHED)
set_addkeytime "KEY3" "SYNCPUBLISH" "${published}" ${Ipub}
created=$(key_get KEY4 CREATED)
set_addkeytime "KEY4" "PUBLISHED" "${created}" -169200
set_addkeytime "KEY4" "ACTIVE" "${created}" -169200
set_addkeytime "KEY4" "PUBLISHED" "${created}" -162000
set_addkeytime "KEY4" "ACTIVE" "${created}" -162000
# Continue signing policy checks.
check_keytimes
@@ -5026,9 +5023,8 @@ set_keytime "KEY2" "ACTIVE" "${created}"
# - It takes TTLsig + Dprp + publish-safety hours to propagate the zone.
# TTLsig: 6h (39600 seconds)
# Dprp: 1h (3600 seconds)
# publish-safety: 1h (3600 seconds)
# Ipub: 8h (28800 seconds)
Ipub=28800
# Ipub: 7h (25200 seconds)
Ipub=25200
set_addkeytime "KEY2" "SYNCPUBLISH" "${created}" "${Ipub}"
# Continue signing policy checks.
@@ -5082,14 +5078,13 @@ check_apex
check_subdomain
dnssec_verify
# Next key event is when all zone signatures are signed with the new
# algorithm. This is the max-zone-ttl plus zone propagation delay
# plus retire safety: 6h + 1h + 2h. But three hours have already passed
# (the time it took to make the DNSKEY omnipresent), so the next event
# should be scheduled in 6 hour: 21600 seconds. Prevent intermittent
# false positives on slow platforms by subtracting the number of seconds
# which passed between key creation and invoking 'rndc reconfig'.
next_time=$((21600 - time_passed))
# Next key event is when all zone signatures are signed with the new algorithm.
# This is the max-zone-ttl plus zone propagation delay: 6h + 1h. But three
# hours have already passed (the time it took to make the DNSKEY omnipresent),
# so the next event should be scheduled in 4 hour: 14400 seconds. Prevent
# intermittent false positives on slow platforms by subtracting the number of
# seconds which passed between key creation and invoking 'rndc reconfig'.
next_time=$((14400 - time_passed))
check_next_key_event $next_time
#
@@ -5114,17 +5109,17 @@ check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
check_cdslog "$DIR" "$ZONE" KEY2
# Set expected key times:
# - The old key was activated 9 hours ago (32400 seconds).
csk_rollover_predecessor_keytimes -32400
# - And was retired 6 hours ago (21600 seconds).
# - The old key was activated 7 hours ago (25200 seconds).
csk_rollover_predecessor_keytimes -25200
# - And was retired 3 hours ago (10800 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -21600
set_addkeytime "KEY1" "RETIRED" "${created}" -10800
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretCSK}"
# - The new key was published 9 hours ago.
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "PUBLISHED" "${created}" -32400
set_addkeytime "KEY2" "ACTIVE" "${created}" -32400
set_addkeytime "KEY2" "PUBLISHED" "${created}" -25200
set_addkeytime "KEY2" "ACTIVE" "${created}" -25200
published=$(key_get KEY2 PUBLISHED)
set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" "${Ipub}"
@@ -5138,9 +5133,9 @@ dnssec_verify
rndc_checkds "$SERVER" "$DIR" KEY1 "now" "withdrawn" "$ZONE"
rndc_checkds "$SERVER" "$DIR" KEY2 "now" "published" "$ZONE"
# Next key event is when the DS becomes OMNIPRESENT. This happens after the
# parent propagation delay, retire safety delay, and DS TTL:
# 1h + 2h + 2h = 5h = 18000 seconds.
check_next_key_event 18000
# parent propagation delay, and DS TTL:
# 1h + 2h = 3h = 10800 seconds.
check_next_key_event 10800
#
# Zone: step4.csk-algorithm-roll.kasp
@@ -5164,17 +5159,17 @@ wait_for_done_signing
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The old key was activated 38 hours ago (136800 seconds)
csk_rollover_predecessor_keytimes -136800
# - And retired 35 hours ago (126000 seconds).
# - The old keys were activated 36 hours ago (129600 seconds).
csk_rollover_predecessor_keytimes -129600
# - And retired 33 hours ago (118800 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -126000
set_addkeytime "KEY1" "RETIRED" "${created}" -118800
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretCSK}"
# - The new key was published 38 hours ago.
# - The new key was published 36 hours ago.
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "PUBLISHED" "${created}" -136800
set_addkeytime "KEY2" "ACTIVE" "${created}" -136800
set_addkeytime "KEY2" "PUBLISHED" "${created}" -129600
set_addkeytime "KEY2" "ACTIVE" "${created}" -129600
published=$(key_get KEY2 PUBLISHED)
set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" ${Ipub}
@@ -5204,17 +5199,17 @@ wait_for_done_signing
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The old key was activated 40 hours ago (144000 seconds)
csk_rollover_predecessor_keytimes -144000
# - And retired 37 hours ago (133200 seconds).
# - The old key was activated 38 hours ago (136800 seconds)
csk_rollover_predecessor_keytimes -136800
# - And retired 35 hours ago (126000 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -133200
set_addkeytime "KEY1" "RETIRED" "${created}" -126000
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretCSK}"
# - The new key was published 40 hours ago.
# - The new key was published 38 hours ago.
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "PUBLISHED" "${created}" -144000
set_addkeytime "KEY2" "ACTIVE" "${created}" -144000
set_addkeytime "KEY2" "PUBLISHED" "${created}" -136800
set_addkeytime "KEY2" "ACTIVE" "${created}" -136800
published=$(key_get KEY2 PUBLISHED)
set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" ${Ipub}
@@ -5225,12 +5220,12 @@ check_subdomain
dnssec_verify
# Next key event is when the RSASHA1 signatures become HIDDEN. This happens
# after the max-zone-ttl plus zone propagation delay plus retire safety
# (6h + 1h + 2h) minus the time already passed since the UNRETENTIVE state has
# been reached (2h): 9h - 2h = 7h = 25200 seconds. Prevent intermittent
# false positives on slow platforms by subtracting the number of seconds
# which passed between key creation and invoking 'rndc reconfig'.
next_time=$((25200 - time_passed))
# after the max-zone-ttl plus zone propagation delay (6h + 1h) minus the
# time already passed since the UNRETENTIVE state has been reached (2h):
# 7h - 2h = 5h = 18000 seconds. Prevent intermittent false positives on slow
# platforms by subtracting the number of seconds which passed between key
# creation and invoking 'rndc reconfig'.
next_time=$((18000 - time_passed))
check_next_key_event $next_time
#
@@ -5248,17 +5243,17 @@ wait_for_done_signing
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
# Set expected key times:
# - The old keys were activated 47 hours ago (169200 seconds)
csk_rollover_predecessor_keytimes -169200
# - And retired 44 hours ago (158400 seconds).
# - The old keys were activated 45 hours ago (162000 seconds)
csk_rollover_predecessor_keytimes -162000
# - And retired 42 hours ago (151200 seconds).
created=$(key_get KEY1 CREATED)
set_addkeytime "KEY1" "RETIRED" "${created}" -158400
set_addkeytime "KEY1" "RETIRED" "${created}" -151200
retired=$(key_get KEY1 RETIRED)
set_addkeytime "KEY1" "REMOVED" "${retired}" "${IretCSK}"
# - The new key was published 47 hours ago.
created=$(key_get KEY2 CREATED)
set_addkeytime "KEY2" "PUBLISHED" "${created}" -169200
set_addkeytime "KEY2" "ACTIVE" "${created}" -169200
set_addkeytime "KEY2" "PUBLISHED" "${created}" -162000
set_addkeytime "KEY2" "ACTIVE" "${created}" -162000
published=$(key_get KEY2 PUBLISHED)
set_addkeytime "KEY2" "SYNCPUBLISH" "${published}" ${Ipub}
@@ -53,12 +53,11 @@ def test_dig_tcp_keepalive_handling(named_port, servers):
)
isctest.log.info("check a re-configured keepalive value")
response = servers["ns2"].rndc("tcp-timeouts 300 300 300 200 100", log=False)
response = servers["ns2"].rndc("tcp-timeouts 300 300 300 200", log=False)
assert "tcp-initial-timeout=300" in response
assert "tcp-idle-timeout=300" in response
assert "tcp-keepalive-timeout=300" in response
assert "tcp-advertised-timeout=200" in response
assert "tcp-primaries-timeout=100" in response
assert "; TCP-KEEPALIVE: 20.0 secs" in dig(
"+tcp +keepalive foo.example. @10.53.0.2"
)
+4
View File
@@ -597,6 +597,10 @@ def test_ksr_common(servers):
selected += 1
if "Generating" in output:
generated += 1
# Subtract if there was a key collision.
if "collide" in output:
generated -= 1
assert selected == 2
assert generated == 2
for index, key in enumerate(overlapping_zsks):
+3 -1
View File
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/mem.h>
#include <isc/result.h>
@@ -25,6 +26,7 @@
#include <dns/db.h>
#include <dns/fixedname.h>
#include <dns/journal.h>
#include <dns/lib.h>
#include <dns/name.h>
#include <dns/types.h>
@@ -109,7 +111,7 @@ cleanup:
}
if (mctx != NULL) {
isc_mem_destroy(&mctx);
isc_mem_detach(&mctx);
}
return result != ISC_R_SUCCESS ? 1 : 0;
+3 -3
View File
@@ -385,7 +385,7 @@ $DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A >dig.out.ns3.test$n.1 2>&1
grep "NOERROR" dig.out.ns3.test$n.1 >/dev/null || ret=1
grep "flags:.* ad" dig.out.ns3.test$n.1 >/dev/null || ret=1
# Sanity check: the authoritative server should have been queried.
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" >/dev/null || ret=1
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/NS/IN'" >/dev/null || ret=1
# Reconfigure ns2 so that the zone can be mirrored on ns3.
sed '/^zone "initially-unavailable" {$/,/^};$/ {
s/10.53.0.254/10.53.0.3/
@@ -403,7 +403,7 @@ $DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A >dig.out.ns3.test$n.2 2>&1
grep "NOERROR" dig.out.ns3.test$n.2 >/dev/null || ret=1
grep "flags:.* ad" dig.out.ns3.test$n.2 >/dev/null || ret=1
# Ensure the authoritative server was not queried.
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" >/dev/null && ret=1
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/NS/IN'" >/dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
@@ -434,7 +434,7 @@ $DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A >dig.out.ns3.test$n 2>&1 |
grep "NOERROR" dig.out.ns3.test$n >/dev/null || ret=1
grep "flags:.* ad" dig.out.ns3.test$n >/dev/null || ret=1
# Sanity check: the authoritative server should have been queried.
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" >/dev/null || ret=1
nextpart ns2/named.run | grep "query 'foo.initially-unavailable/NS/IN'" >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
@@ -25,8 +25,6 @@ options {
recursion yes;
notify yes;
dnssec-validation no;
tcp-initial-timeout 150; # 15 seconds
};
zone "." {
+3 -1
View File
@@ -20,6 +20,7 @@
#include <isc/base64.h>
#include <isc/commandline.h>
#include <isc/hash.h>
#include <isc/lib.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/managers.h>
@@ -33,6 +34,7 @@
#include <dns/dispatch.h>
#include <dns/fixedname.h>
#include <dns/lib.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/rdataset.h>
@@ -139,7 +141,7 @@ sendquery(void) {
isc_buffer_init(&buf, host, strlen(host));
isc_buffer_add(&buf, strlen(host));
result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf,
dns_rootname, 0, NULL);
dns_rootname, 0);
CHECK("dns_name_fromtext", result);
dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER,
@@ -0,0 +1,17 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 30 SOA ns2.good. hostmaster.arpa. 2018050100 1 1 1 1
@ 30 NS ns2.good.
8.2.6.0 60 NS ns3.good.
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0 1 PTR nee.com.
+91 -436
View File
@@ -1,456 +1,111 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
"""
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
from __future__ import print_function
import os
import sys
import signal
import socket
import select
from datetime import datetime, timedelta
import time
import functools
SPDX-License-Identifier: MPL-2.0
import dns, dns.message, dns.query, dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
from dns.name import *
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, you can obtain one at https://mozilla.org/MPL/2.0/.
See the COPYRIGHT file distributed with this work for additional
information regarding copyright ownership.
"""
from typing import AsyncGenerator
import dns.message
import dns.name
import dns.rcode
import dns.rdataclass
import dns.rdatatype
from isctest.asyncserver import (
AsyncDnsServer,
DnsResponseSend,
DomainHandler,
QueryContext,
ResponseAction,
)
from qmin_ans import (
DelayedResponseHandler,
EntRcodeChanger,
QueryLogHandler,
log_query,
)
# Log query to file
def logquery(type, qname):
with open("qlog", "a") as f:
f.write("%s %s\n", type, qname)
class QueryLogger(QueryLogHandler):
domains = ["1.0.0.2.ip6.arpa.", "fwd.", "good."]
def endswith(domain, labels):
return domain.endswith("." + labels) or domain == labels
class BadHandler(EntRcodeChanger):
domains = ["bad."]
rcode = dns.rcode.NXDOMAIN
############################################################################
# Respond to a DNS query.
# For good. it serves:
# ns2.good. IN A 10.53.0.2
# zoop.boing.good. NS ns3.good.
# ns3.good. IN A 10.53.0.3
# too.many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.good. A 192.0.2.2
# it responds properly (with NODATA empty response) to non-empty terminals
#
# For slow. it works the same as for good., but each response is delayed by 400 milliseconds
#
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
#
# For ugly. it works the same as for good., but returns garbage to non-empty terminals
#
# For 1.0.0.2.ip6.arpa it serves
# 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa. IN PTR nee.com.
# 8.2.6.0.1.0.0.2.ip6.arpa IN NS ns3.good
# 1.0.0.2.ip6.arpa. IN NS ns2.good
# ip6.arpa. IN NS ns2.good
#
# For stale. it serves:
# a.b. NS ns.a.b.stale.
# ns.a.b.stale. IN A 10.53.0.3
# b. NS ns.b.stale.
# ns.b.stale. IN A 10.53.0.4
############################################################################
def create_response(msg):
m = dns.message.from_wire(msg)
qname = m.question[0].name.to_text()
lqname = qname.lower()
labels = lqname.split(".")
# get qtype
rrtype = m.question[0].rdtype
typename = dns.rdatatype.to_text(rrtype)
if typename == "A" or typename == "AAAA":
typename = "ADDR"
bad = False
ugly = False
slow = False
# log this query
with open("query.log", "a") as f:
f.write("%s %s\n" % (typename, lqname))
print("%s %s" % (typename, lqname), end=" ")
r = dns.message.make_response(m)
r.set_rcode(NOERROR)
if endswith(lqname, "1.0.0.2.ip6.arpa."):
# Direct query - give direct answer
if endswith(lqname, "8.2.6.0.1.0.0.2.ip6.arpa."):
# Delegate to ns3
r.authority.append(
dns.rrset.from_text(
"8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns3.good."
)
)
r.additional.append(
dns.rrset.from_text("ns3.good.", 60, IN, A, "10.53.0.3")
)
elif (
lqname
== "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa."
and rrtype == PTR
):
# Direct query - give direct answer
r.answer.append(
dns.rrset.from_text(
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.",
1,
IN,
PTR,
"nee.com.",
)
)
r.flags |= dns.flags.AA
elif lqname == "1.0.0.2.ip6.arpa." and rrtype == NS:
# NS query at the apex
r.answer.append(
dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, NS, "ns2.good.")
)
r.flags |= dns.flags.AA
elif endswith(
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.",
lqname,
):
# NODATA answer
r.authority.append(
dns.rrset.from_text(
"1.0.0.2.ip6.arpa.",
30,
IN,
SOA,
"ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
)
)
else:
# NXDOMAIN
r.authority.append(
dns.rrset.from_text(
"1.0.0.2.ip6.arpa.",
30,
IN,
SOA,
"ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
)
)
r.set_rcode(NXDOMAIN)
return r
elif endswith(lqname, "ip6.arpa."):
if lqname == "ip6.arpa." and rrtype == NS:
# NS query at the apex
r.answer.append(dns.rrset.from_text("ip6.arpa.", 30, IN, NS, "ns2.good."))
r.flags |= dns.flags.AA
elif endswith("1.0.0.2.ip6.arpa.", lqname):
# NODATA answer
r.authority.append(
dns.rrset.from_text(
"ip6.arpa.",
30,
IN,
SOA,
"ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
)
)
else:
# NXDOMAIN
r.authority.append(
dns.rrset.from_text(
"ip6.arpa.",
30,
IN,
SOA,
"ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
)
)
r.set_rcode(NXDOMAIN)
return r
elif endswith(lqname, "stale."):
if endswith(lqname, "a.b.stale."):
# Delegate to ns.a.b.stale.
r.authority.append(
dns.rrset.from_text("a.b.stale.", 2, IN, NS, "ns.a.b.stale.")
)
r.additional.append(
dns.rrset.from_text("ns.a.b.stale.", 2, IN, A, "10.53.0.3")
)
elif endswith(lqname, "b.stale."):
# Delegate to ns.b.stale.
r.authority.append(
dns.rrset.from_text("b.stale.", 2, IN, NS, "ns.b.stale.")
)
r.additional.append(
dns.rrset.from_text("ns.b.stale.", 2, IN, A, "10.53.0.4")
)
elif lqname == "stale." and rrtype == NS:
# NS query at the apex.
r.answer.append(dns.rrset.from_text("stale.", 2, IN, NS, "ns2.stale."))
r.flags |= dns.flags.AA
elif lqname == "stale." and rrtype == SOA:
# SOA query at the apex.
r.answer.append(
dns.rrset.from_text(
"stale.", 2, IN, SOA, "ns2.stale. hostmaster.stale. 1 2 3 4 5"
)
)
r.flags |= dns.flags.AA
elif lqname == "stale.":
# NODATA answer
r.authority.append(
dns.rrset.from_text(
"stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"
)
)
r.flags |= dns.flags.AA
elif lqname == "ns2.stale.":
if rrtype == A:
r.additional.append(
dns.rrset.from_text("ns.b.stale.", 2, IN, A, "10.53.0.2")
)
else:
r.authority.append(
dns.rrset.from_text(
"stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"
)
)
r.flags |= dns.flags.AA
else:
# NXDOMAIN
r.authority.append(
dns.rrset.from_text(
"stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"
)
)
r.set_rcode(NXDOMAIN)
return r
elif endswith(lqname, "bad."):
bad = True
suffix = "bad."
lqname = lqname[:-4]
elif endswith(lqname, "ugly."):
ugly = True
suffix = "ugly."
lqname = lqname[:-5]
elif endswith(lqname, "good."):
suffix = "good."
lqname = lqname[:-5]
elif endswith(lqname, "slow."):
slow = True
suffix = "slow."
lqname = lqname[:-5]
elif endswith(lqname, "fwd."):
suffix = "fwd."
lqname = lqname[:-4]
else:
r.set_rcode(REFUSED)
return r
# Good/bad/ugly differs only in how we treat non-empty terminals
if endswith(lqname, "zoop.boing."):
r.authority.append(
dns.rrset.from_text("zoop.boing." + suffix, 1, IN, NS, "ns3." + suffix)
)
elif (
lqname == "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z."
and rrtype == A
):
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
r.flags |= dns.flags.AA
elif lqname == "" and rrtype == NS:
r.answer.append(dns.rrset.from_text(suffix, 30, IN, NS, "ns2." + suffix))
r.flags |= dns.flags.AA
elif lqname == "ns2.":
r.flags |= dns.flags.AA
if rrtype == A:
r.answer.append(
dns.rrset.from_text("ns2." + suffix, 30, IN, A, "10.53.0.2")
)
elif rrtype == AAAA:
r.answer.append(
dns.rrset.from_text(
"ns2." + suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::2"
)
)
else:
r.authority.append(
dns.rrset.from_text(
suffix,
30,
IN,
SOA,
"ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
elif lqname == "ns3.":
r.flags |= dns.flags.AA
if rrtype == A:
r.answer.append(
dns.rrset.from_text("ns3." + suffix, 30, IN, A, "10.53.0.3")
)
elif lqname == "ns3." and rrtype == AAAA:
r.answer.append(
dns.rrset.from_text(
"ns3." + suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::3"
)
)
else:
r.authority.append(
dns.rrset.from_text(
suffix,
30,
IN,
SOA,
"ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
elif lqname == "ns4.":
r.flags |= dns.flags.AA
if rrtype == A:
r.answer.append(
dns.rrset.from_text("ns4." + suffix, 30, IN, A, "10.53.0.4")
)
elif rrtype == AAAA:
r.answer.append(
dns.rrset.from_text(
"ns4." + suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::4"
)
)
else:
r.authority.append(
dns.rrset.from_text(
suffix,
30,
IN,
SOA,
"ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
elif lqname == "a.bit.longer.ns.name." and rrtype == A:
r.answer.append(
dns.rrset.from_text("a.bit.longer.ns.name." + suffix, 1, IN, A, "10.53.0.4")
)
r.flags |= dns.flags.AA
elif lqname == "a.bit.longer.ns.name." and rrtype == AAAA:
r.answer.append(
dns.rrset.from_text(
"a.bit.longer.ns.name." + suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::4"
)
)
r.flags |= dns.flags.AA
else:
r.authority.append(
dns.rrset.from_text(
suffix,
1,
IN,
SOA,
"ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
if bad or not (
endswith("icky.icky.icky.ptang.zoop.boing.", lqname)
or endswith(
"many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.",
lqname,
)
or endswith("a.bit.longer.ns.name.", lqname)
):
r.set_rcode(NXDOMAIN)
if ugly:
r.set_rcode(FORMERR)
if slow:
time.sleep(0.2)
return r
class UglyHandler(EntRcodeChanger):
domains = ["ugly."]
rcode = dns.rcode.FORMERR
def sigterm(signum, frame):
print("Shutting down now...")
os.remove("ans.pid")
running = False
sys.exit(0)
class SlowHandler(DelayedResponseHandler):
domains = ["slow."]
delay = 0.2
############################################################################
# Main
#
# Set up responder and control channel, open the pid file, and start
# the main loop, listening for queries on the query channel or commands
# on the control channel and acting on them.
############################################################################
ip4 = "10.53.0.2"
ip6 = "fd92:7065:b8e:ffff::2"
def send_delegation(
qctx: QueryContext, zone_cut: dns.name.Name, target_addr: str
) -> ResponseAction:
"""
Delegate `zone_cut` to a single in-bailiwick name server, `ns.<zone_cut>`,
with a single IPv4 glue record (provided in `target_addr`) included in the
ADDITIONAL section.
"""
ns_name = "ns." + zone_cut.to_text()
ns_rrset = dns.rrset.from_text(
zone_cut, 2, dns.rdataclass.IN, dns.rdatatype.NS, ns_name
)
a_rrset = dns.rrset.from_text(
ns_name, 2, dns.rdataclass.IN, dns.rdatatype.A, target_addr
)
try:
port = int(os.environ["PORT"])
except:
port = 5300
response = dns.message.make_response(qctx.query)
response.set_rcode(dns.rcode.NOERROR)
response.authority.append(ns_rrset)
response.additional.append(a_rrset)
query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
query4_socket.bind((ip4, port))
return DnsResponseSend(response, authoritative=False)
havev6 = True
try:
query6_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
query6_socket.bind((ip6, port))
except:
query6_socket.close()
havev6 = False
except:
havev6 = False
signal.signal(signal.SIGTERM, sigterm)
class StaleHandler(DomainHandler):
"""
`a.b.stale` is a subdomain of `b.stale` and these two subdomains need to be
delegated to different name servers. Therefore, their delegations cannot
be placed in the zone file because the zone cut at `b.stale` would occlude
the one at `a.b.stale`. Generate these delegations dynamically depending
on the QNAME.
"""
f = open("ans.pid", "w")
pid = os.getpid()
print(pid, file=f)
f.close()
domains = ["stale."]
running = True
async def get_responses(
self, qctx: QueryContext
) -> AsyncGenerator[ResponseAction, None]:
log_query(qctx)
a_b_stale = dns.name.from_text("a.b.stale.")
b_stale = dns.name.from_text("b.stale.")
if qctx.qname.is_subdomain(a_b_stale):
yield send_delegation(qctx, a_b_stale, "10.53.0.3")
elif qctx.qname.is_subdomain(b_stale):
yield send_delegation(qctx, b_stale, "10.53.0.4")
print("Listening on %s port %d" % (ip4, port))
if havev6:
print("Listening on %s port %d" % (ip6, port))
print("Ctrl-c to quit")
if havev6:
input = [query4_socket, query6_socket]
else:
input = [query4_socket]
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
except select.error as e:
break
except socket.error as e:
break
except KeyboardInterrupt:
break
for s in inputready:
if s == query4_socket or s == query6_socket:
print(
"Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
)
# Handle incoming queries
msg = s.recvfrom(65535)
rsp = create_response(msg[0])
if rsp:
print(dns.rcode.to_text(rsp.rcode()))
s.sendto(rsp.to_wire(), msg[1])
else:
print("NO RESPONSE")
if not running:
break
if __name__ == "__main__":
server = AsyncDnsServer()
server.install_response_handler(QueryLogger())
server.install_response_handler(BadHandler())
server.install_response_handler(UglyHandler())
server.install_response_handler(SlowHandler())
server.install_response_handler(StaleHandler())
server.run()
+1
View File
@@ -0,0 +1 @@
good.db
+1
View File
@@ -0,0 +1 @@
good.db
+26
View File
@@ -0,0 +1,26 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns2 hostmaster.arpa. 2018050100 1 1 1 1
@ 30 NS ns2
ns2 30 A 10.53.0.2
30 AAAA fd92:7065:b8e:ffff::2
zoop.boing 30 NS ns3
ns3 30 A 10.53.0.3
30 AAAA fd92:7065:b8e:ffff::3
ns4 30 A 10.53.0.4
30 AAAA fd92:7065:b8e:ffff::4
a.bit.longer.ns.name 1 A 10.53.0.4
1 AAAA fd92:7065:b8e:ffff::4
+1
View File
@@ -0,0 +1 @@
good.db
+15
View File
@@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 2 SOA ns2 hostmaster.stale. 1 2 3 4 5
@ 2 NS ns2
ns2 2 A 10.53.0.2
2 AAAA fd92:7065:b8e:ffff::2
+1
View File
@@ -0,0 +1 @@
good.db
@@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 30 SOA ns3.good. hostmaster.arpa. 2018050100 1 1 1 1
@ 30 NS ns3.good.
1.1.1.1 60 NS ns4.good.
+15
View File
@@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns hostmaster.a.b.stale. 1 2 3 4 5
@ 1 NS ns
@ 1 TXT "peekaboo"
ns 1 A 10.53.0.3
+34 -273
View File
@@ -1,285 +1,46 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
"""
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
from __future__ import print_function
import os
import sys
import signal
import socket
import select
from datetime import datetime, timedelta
import time
import functools
SPDX-License-Identifier: MPL-2.0
import dns, dns.message, dns.query, dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
from dns.name import *
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, you can obtain one at https://mozilla.org/MPL/2.0/.
See the COPYRIGHT file distributed with this work for additional
information regarding copyright ownership.
"""
import dns.rcode
from isctest.asyncserver import AsyncDnsServer
from qmin_ans import DelayedResponseHandler, EntRcodeChanger, QueryLogHandler
# Log query to file
def logquery(type, qname):
with open("qlog", "a") as f:
f.write("%s %s\n", type, qname)
class QueryLogger(QueryLogHandler):
domains = ["8.2.6.0.1.0.0.2.ip6.arpa.", "a.b.stale.", "zoop.boing.good."]
def endswith(domain, labels):
return domain.endswith("." + labels) or domain == labels
class ZoopBoingBadHandler(EntRcodeChanger):
domains = ["zoop.boing.bad."]
rcode = dns.rcode.NXDOMAIN
############################################################################
# Respond to a DNS query.
# For good. it serves:
# zoop.boing.good. NS ns3.good.
# icky.ptang.zoop.boing.good. NS a.bit.longer.ns.name.good.
# it responds properly (with NODATA empty response) to non-empty terminals
#
# For slow. it works the same as for good., but each response is delayed by 400 milliseconds
#
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
#
# For ugly. it works the same as for good., but returns garbage to non-empty terminals
#
# For stale. it serves:
# a.b.stale. IN TXT peekaboo (resolver did not do qname minimization)
############################################################################
def create_response(msg):
m = dns.message.from_wire(msg)
qname = m.question[0].name.to_text()
lqname = qname.lower()
labels = lqname.split(".")
suffix = ""
# get qtype
rrtype = m.question[0].rdtype
typename = dns.rdatatype.to_text(rrtype)
if typename == "A" or typename == "AAAA":
typename = "ADDR"
bad = False
ugly = False
slow = False
# log this query
with open("query.log", "a") as f:
f.write("%s %s\n" % (typename, lqname))
print("%s %s" % (typename, lqname), end=" ")
r = dns.message.make_response(m)
r.set_rcode(NOERROR)
ip6req = False
if endswith(lqname, "bad."):
bad = True
suffix = "bad."
lqname = lqname[:-4]
elif endswith(lqname, "ugly."):
ugly = True
suffix = "ugly."
lqname = lqname[:-5]
elif endswith(lqname, "good."):
suffix = "good."
lqname = lqname[:-5]
elif endswith(lqname, "slow."):
slow = True
suffix = "slow."
lqname = lqname[:-5]
elif endswith(lqname, "8.2.6.0.1.0.0.2.ip6.arpa."):
ip6req = True
elif endswith(lqname, "a.b.stale."):
if lqname == "a.b.stale.":
r.flags |= dns.flags.AA
if rrtype == TXT:
# Direct query.
r.answer.append(dns.rrset.from_text(lqname, 1, IN, TXT, "peekaboo"))
elif rrtype == NS:
# NS a.b.
r.answer.append(dns.rrset.from_text(lqname, 1, IN, NS, "ns.a.b.stale."))
r.additional.append(
dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3")
)
elif rrtype == SOA:
# SOA a.b.
r.answer.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
else:
# NODATA.
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
elif lqname == "ns.a.b.stale.":
r.flags |= dns.flags.AA
if rrtype == A:
r.answer.append(
dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3")
)
else:
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
else:
r.flags |= dns.flags.AA
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
r.set_rcode(NXDOMAIN)
# NXDOMAIN.
return r
else:
r.set_rcode(REFUSED)
return r
# Good/bad differs only in how we treat non-empty terminals
if lqname == "zoop.boing." and rrtype == NS:
r.answer.append(
dns.rrset.from_text(lqname + suffix, 1, IN, NS, "ns3." + suffix)
)
r.flags |= dns.flags.AA
elif endswith(lqname, "icky.ptang.zoop.boing."):
r.authority.append(
dns.rrset.from_text(
"icky.ptang.zoop.boing." + suffix,
1,
IN,
NS,
"a.bit.longer.ns.name." + suffix,
)
)
elif endswith("icky.ptang.zoop.boing.", lqname):
r.authority.append(
dns.rrset.from_text(
"zoop.boing." + suffix,
1,
IN,
SOA,
"ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
if bad:
r.set_rcode(NXDOMAIN)
if ugly:
r.set_rcode(FORMERR)
elif endswith(lqname, "zoop.boing."):
r.authority.append(
dns.rrset.from_text(
"zoop.boing." + suffix,
1,
IN,
SOA,
"ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
r.set_rcode(NXDOMAIN)
elif ip6req:
r.authority.append(
dns.rrset.from_text(
"1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns4.good."
)
)
r.additional.append(dns.rrset.from_text("ns4.good.", 60, IN, A, "10.53.0.4"))
else:
r.set_rcode(REFUSED)
if slow:
time.sleep(0.4)
return r
class ZoopBoingUglyHandler(EntRcodeChanger):
domains = ["zoop.boing.ugly."]
rcode = dns.rcode.FORMERR
def sigterm(signum, frame):
print("Shutting down now...")
os.remove("ans.pid")
running = False
sys.exit(0)
class ZoopBoingSlowHandler(DelayedResponseHandler):
domains = ["zoop.boing.slow."]
delay = 0.4
############################################################################
# Main
#
# Set up responder and control channel, open the pid file, and start
# the main loop, listening for queries on the query channel or commands
# on the control channel and acting on them.
############################################################################
ip4 = "10.53.0.3"
ip6 = "fd92:7065:b8e:ffff::3"
try:
port = int(os.environ["PORT"])
except:
port = 5300
query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
query4_socket.bind((ip4, port))
havev6 = True
try:
query6_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
query6_socket.bind((ip6, port))
except:
query6_socket.close()
havev6 = False
except:
havev6 = False
signal.signal(signal.SIGTERM, sigterm)
f = open("ans.pid", "w")
pid = os.getpid()
print(pid, file=f)
f.close()
running = True
print("Listening on %s port %d" % (ip4, port))
if havev6:
print("Listening on %s port %d" % (ip6, port))
print("Ctrl-c to quit")
if havev6:
input = [query4_socket, query6_socket]
else:
input = [query4_socket]
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
except select.error as e:
break
except socket.error as e:
break
except KeyboardInterrupt:
break
for s in inputready:
if s == query4_socket or s == query6_socket:
print(
"Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
)
# Handle incoming queries
msg = s.recvfrom(65535)
rsp = create_response(msg[0])
if rsp:
print(dns.rcode.to_text(rsp.rcode()))
s.sendto(rsp.to_wire(), msg[1])
else:
print("NO RESPONSE")
if not running:
break
if __name__ == "__main__":
server = AsyncDnsServer()
server.install_response_handler(QueryLogger())
server.install_response_handler(ZoopBoingBadHandler())
server.install_response_handler(ZoopBoingUglyHandler())
server.install_response_handler(ZoopBoingSlowHandler())
server.run()
@@ -0,0 +1,14 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns3.bad. hostmaster.arpa. 2018050100 1 1 1 1
@ 1 NS ns3.bad.
icky.ptang 1 NS a.bit.longer.ns.name.bad.
@@ -0,0 +1,14 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns3.good. hostmaster.arpa. 2018050100 1 1 1 1
@ 1 NS ns3.good.
icky.ptang 1 NS a.bit.longer.ns.name.good.
@@ -0,0 +1,14 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns3.slow. hostmaster.arpa. 2018050100 1 1 1 1
@ 1 NS ns3.slow.
icky.ptang 1 NS a.bit.longer.ns.name.slow.
@@ -0,0 +1,14 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns3.ugly. hostmaster.arpa. 2018050100 1 1 1 1
@ 1 NS ns3.ugly.
icky.ptang 1 NS a.bit.longer.ns.name.ugly.
@@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 30 SOA ns4.good. hostmaster.arpa. 2018050100 1 1 1 1
@ 30 NS ns4.good.
test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4 1 TXT "long_ip6_name"
+15
View File
@@ -0,0 +1,15 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns hostmaster.a.b.stale. 1 2 3 4 5
@ 1 NS ns
ns 1 A 10.53.0.4
@ 1 TXT "hooray"
+79 -330
View File
@@ -1,344 +1,93 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
"""
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
from __future__ import print_function
import os
import sys
import signal
import socket
import select
from datetime import datetime, timedelta
import time
import functools
SPDX-License-Identifier: MPL-2.0
import dns, dns.message, dns.query, dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
from dns.name import *
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, you can obtain one at https://mozilla.org/MPL/2.0/.
See the COPYRIGHT file distributed with this work for additional
information regarding copyright ownership.
"""
from typing import AsyncGenerator
import dns.rcode
from isctest.asyncserver import (
AsyncDnsServer,
DnsResponseSend,
DomainHandler,
QueryContext,
ResponseAction,
)
from qmin_ans import DelayedResponseHandler, EntRcodeChanger, QueryLogHandler, log_query
# Log query to file
def logquery(type, qname):
with open("qlog", "a") as f:
f.write("%s %s\n", type, qname)
class QueryLogger(QueryLogHandler):
domains = [
"1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
"icky.ptang.zoop.boing.good.",
]
def endswith(domain, labels):
return domain.endswith("." + labels) or domain == labels
class StaleHandler(DomainHandler):
"""
The test code relies on this server returning non-minimal (i.e. including
address records in the ADDITIONAL section) responses to NS queries for
`b.stale` and `a.b.stale`. While this logic (returning non-minimal
responses to NS queries) could be implemented in AsyncDnsServer itself,
doing so breaks a lot of other checks in this system test. Therefore, only
these two zones behave in this particular way, thanks to a custom response
handler implemented below.
"""
domains = ["b.stale", "a.b.stale"]
async def get_responses(
self, qctx: QueryContext
) -> AsyncGenerator[ResponseAction, None]:
log_query(qctx)
if qctx.qtype == dns.rdatatype.NS:
assert qctx.zone
assert qctx.response.answer[0]
for nameserver in qctx.response.answer[0]:
if not nameserver.target.is_subdomain(qctx.response.answer[0].name):
continue
glue_a = qctx.zone.get_rrset(nameserver.target, dns.rdatatype.A)
if glue_a:
qctx.response.additional.append(glue_a)
glue_aaaa = qctx.zone.get_rrset(nameserver.target, dns.rdatatype.AAAA)
if glue_aaaa:
qctx.response.additional.append(glue_aaaa)
yield DnsResponseSend(qctx.response)
############################################################################
# Respond to a DNS query.
# For good. it serves:
# icky.ptang.zoop.boing.good. NS a.bit.longer.ns.name.
# icky.icky.icky.ptang.zoop.boing.good. A 192.0.2.1
# more.icky.icky.icky.ptang.zoop.boing.good. A 192.0.2.2
# it responds properly (with NODATA empty response) to non-empty terminals
#
# For slow. it works the same as for good., but each response is delayed by 400 milliseconds
#
# For bad. it works the same as for good., but returns NXDOMAIN to non-empty terminals
#
# For ugly. it works the same as for good., but returns garbage to non-empty terminals
#
# For stale. it serves:
# a.b.stale. IN TXT hooray (resolver did do qname minimization)
############################################################################
def create_response(msg):
m = dns.message.from_wire(msg)
qname = m.question[0].name.to_text()
lqname = qname.lower()
labels = lqname.split(".")
suffix = ""
# get qtype
rrtype = m.question[0].rdtype
typename = dns.rdatatype.to_text(rrtype)
if typename == "A" or typename == "AAAA":
typename = "ADDR"
bad = False
slow = False
ugly = False
# log this query
with open("query.log", "a") as f:
f.write("%s %s\n" % (typename, lqname))
print("%s %s" % (typename, lqname), end=" ")
r = dns.message.make_response(m)
r.set_rcode(NOERROR)
ip6req = False
if endswith(lqname, "bad."):
bad = True
suffix = "bad."
lqname = lqname[:-4]
elif endswith(lqname, "ugly."):
ugly = True
suffix = "ugly."
lqname = lqname[:-5]
elif endswith(lqname, "good."):
suffix = "good."
lqname = lqname[:-5]
elif endswith(lqname, "slow."):
slow = True
suffix = "slow."
lqname = lqname[:-5]
elif endswith(lqname, "1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa."):
ip6req = True
elif endswith(lqname, "b.stale."):
if lqname == "a.b.stale.":
r.flags |= dns.flags.AA
if rrtype == TXT:
# Direct query.
r.answer.append(dns.rrset.from_text(lqname, 1, IN, TXT, "hooray"))
elif rrtype == NS:
# NS a.b.
r.answer.append(dns.rrset.from_text(lqname, 1, IN, NS, "ns.a.b.stale."))
r.additional.append(
dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3")
)
elif rrtype == SOA:
# SOA a.b.
r.answer.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
else:
# NODATA.
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
elif lqname == "ns.a.b.stale.":
r.flags |= dns.flags.AA
if rrtype == A:
r.answer.append(
dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3")
)
else:
# NODATA.
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
)
)
elif lqname == "b.stale.":
r.flags |= dns.flags.AA
if rrtype == NS:
# NS b.
r.answer.append(dns.rrset.from_text(lqname, 1, IN, NS, "ns.b.stale."))
r.additional.append(
dns.rrset.from_text("ns.b.stale.", 1, IN, A, "10.53.0.4")
)
elif rrtype == SOA:
# SOA b.
r.answer.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
)
)
else:
# NODATA.
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
)
)
elif lqname == "ns.b.stale.":
r.flags |= dns.flags.AA
if rrtype == A:
# SOA a.b.
r.answer.append(
dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.4")
)
else:
# NODATA.
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
)
)
else:
r.authority.append(
dns.rrset.from_text(
lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
)
)
r.set_rcode(NXDOMAIN)
# NXDOMAIN.
return r
else:
r.set_rcode(REFUSED)
return r
# Good/bad differs only in how we treat non-empty terminals
if lqname == "icky.icky.icky.ptang.zoop.boing." and rrtype == A:
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.1"))
r.flags |= dns.flags.AA
elif lqname == "more.icky.icky.icky.ptang.zoop.boing." and rrtype == A:
r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
r.flags |= dns.flags.AA
elif lqname == "icky.ptang.zoop.boing." and rrtype == NS:
r.answer.append(
dns.rrset.from_text(
lqname + suffix, 1, IN, NS, "a.bit.longer.ns.name." + suffix
)
)
r.flags |= dns.flags.AA
elif endswith(lqname, "icky.ptang.zoop.boing."):
r.authority.append(
dns.rrset.from_text(
"icky.ptang.zoop.boing." + suffix,
1,
IN,
SOA,
"ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
)
)
if bad or not endswith("more.icky.icky.icky.ptang.zoop.boing.", lqname):
r.set_rcode(NXDOMAIN)
if ugly:
r.set_rcode(FORMERR)
elif ip6req:
r.flags |= dns.flags.AA
if (
lqname
== "test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa."
and rrtype == TXT
):
r.answer.append(
dns.rrset.from_text(
"test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
1,
IN,
TXT,
"long_ip6_name",
)
)
elif endswith(
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
lqname,
):
# NODATA answer
r.authority.append(
dns.rrset.from_text(
"1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
60,
IN,
SOA,
"ns4.good. hostmaster.arpa. 2018050100 120 30 320 16",
)
)
else:
# NXDOMAIN
r.authority.append(
dns.rrset.from_text(
"1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
60,
IN,
SOA,
"ns4.good. hostmaster.arpa. 2018050100 120 30 320 16",
)
)
r.set_rcode(NXDOMAIN)
else:
r.set_rcode(REFUSED)
if slow:
time.sleep(0.4)
return r
class IckyPtangZoopBoingBadHandler(EntRcodeChanger):
domains = ["icky.ptang.zoop.boing.bad."]
rcode = dns.rcode.NXDOMAIN
def sigterm(signum, frame):
print("Shutting down now...")
os.remove("ans.pid")
running = False
sys.exit(0)
class IckyPtangZoopBoingUglyHandler(EntRcodeChanger):
domains = ["icky.ptang.zoop.boing.ugly."]
rcode = dns.rcode.FORMERR
############################################################################
# Main
#
# Set up responder and control channel, open the pid file, and start
# the main loop, listening for queries on the query channel or commands
# on the control channel and acting on them.
############################################################################
ip4 = "10.53.0.4"
ip6 = "fd92:7065:b8e:ffff::4"
class IckyPtangZoopBoingSlowHandler(DelayedResponseHandler):
domains = ["icky.ptang.zoop.boing.slow."]
delay = 0.4
try:
port = int(os.environ["PORT"])
except:
port = 5300
query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
query4_socket.bind((ip4, port))
havev6 = True
try:
query6_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
try:
query6_socket.bind((ip6, port))
except:
query6_socket.close()
havev6 = False
except:
havev6 = False
signal.signal(signal.SIGTERM, sigterm)
f = open("ans.pid", "w")
pid = os.getpid()
print(pid, file=f)
f.close()
running = True
print("Listening on %s port %d" % (ip4, port))
if havev6:
print("Listening on %s port %d" % (ip6, port))
print("Ctrl-c to quit")
if havev6:
input = [query4_socket, query6_socket]
else:
input = [query4_socket]
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
except select.error as e:
break
except socket.error as e:
break
except KeyboardInterrupt:
break
for s in inputready:
if s == query4_socket or s == query6_socket:
print(
"Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
)
# Handle incoming queries
msg = s.recvfrom(65535)
rsp = create_response(msg[0])
if rsp:
print(dns.rcode.to_text(rsp.rcode()))
s.sendto(rsp.to_wire(), msg[1])
else:
print("NO RESPONSE")
if not running:
break
if __name__ == "__main__":
server = AsyncDnsServer()
server.install_response_handler(QueryLogger())
server.install_response_handler(StaleHandler())
server.install_response_handler(IckyPtangZoopBoingBadHandler())
server.install_response_handler(IckyPtangZoopBoingUglyHandler())
server.install_response_handler(IckyPtangZoopBoingSlowHandler())
server.run()
+16
View File
@@ -0,0 +1,16 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
@ 1 SOA ns hostmaster.b.stale. 1 2 3 4 5
@ 1 NS ns
ns 1 A 10.53.0.4
a 1 NS ns.a
ns.a 1 A 10.53.0.4

Some files were not shown because too many files have changed in this diff Show More