Commit graph

2471 commits

Author SHA1 Message Date
Aram Sargsyan
baa9698c9d Fix RRL responses-per-second bypass using wildcard names
It is possible to bypass Response Rate Limiting (RRL)
`responses-per-second` limitation using specially crafted wildcard
names, because the current implementation, when encountering a found
DNS name generated from a wildcard record, just strips the leftmost
label of the name before making a key for the bucket.

While that technique helps with limiting random requests like
<random>.example.com (because all those requests will be accounted
as belonging to a bucket constructed from "example.com" name), it does
not help with random names like subdomain.<random>.example.com.

The best solution would have been to strip not just the leftmost
label, but as many labels as necessary until reaching the suffix part
of the wildcard record from which the found name is generated, however,
we do not have that information readily available in the context of RRL
processing code.

Fix the issue by interpreting all valid wildcard domain names as
the zone's origin name concatenated to the "*" name, so they all will
be put into the same bucket.
2022-09-08 09:15:30 +02:00
Aram Sargsyan
77f12ecba7 Add extended DNS error configuration option for RPZ zones
Implement the configuration option with its checking and parsing parts.

The option should be later used by BIND to set an extended error
code (EDE) for the queries modified in the result of RPZ processing.
2022-08-31 08:56:03 +00:00
Ondřej Surý
b69e783164
Update netmgr, tasks, and applications to use isc_loopmgr
Previously:

* applications were using isc_app as the base unit for running the
  application and signal handling.

* networking was handled in the netmgr layer, which would start a
  number of threads, each with a uv_loop event loop.

* task/event handling was done in the isc_task unit, which used
  netmgr event loops to run the isc_event calls.

In this refactoring:

* the network manager now uses isc_loop instead of maintaining its
  own worker threads and event loops.

* the taskmgr that manages isc_task instances now also uses isc_loopmgr,
  and every isc_task runs on a specific isc_loop bound to the specific
  thread.

* applications have been updated as necessary to use the new API.

* new ISC_LOOP_TEST macros have been added to enable unit tests to
  run isc_loop event loops. unit tests have been updated to use this
  where needed.
2022-08-26 09:09:24 +02:00
Ondřej Surý
49b149f5fd
Update isc_timer to use isc_loopmgr
* isc_timer was rewritten using the uv_timer, and isc_timermgr_t was
  completely removed; isc_timer objects are now directly created on the
  isc_loop event loops.

* the isc_timer API has been simplified. the "inactive" timer type has
  been removed; timers are now stopped by calling isc_timer_stop()
  instead of resetting to inactive.

* isc_manager now creates a loop manager rather than a timer manager.

* modules and applications using isc_timer have been updated to use the
  new API.
2022-08-25 17:17:07 +02:00
Matthijs Mekking
501dc87d75 Wait with NSEC3 during a DNSSEC policy change
When doing a dnssec-policy reconfiguration from a zone with NSEC only
keys to a zone that uses NSEC3, figure out to wait with building the
NSEC3 chain.

Previously, BIND 9 would attempt to sign such a zone, but failed to
do so because the NSEC3 chain conflicted with existing DNSKEY records
in the zone that were not compatible with NSEC3.

There exists logic for detecting such a case in the functions
dnskey_sane() (in lib/dns/zone.c) and check_dnssec() (in
lib/ns/update.c). Both functions look very similar so refactor them
to use the same code and call the new function (called
dns_zone_check_dnskey_nsec3()).

Also update the dns_nsec_nseconly() function to take an additional
parameter 'diff' that, if provided, will be checked whether an
offending NSEC only DNSKEY will be deleted from the zone. If so,
this key will not be considered when checking the zone for NSEC only
DNSKEYs. This is needed to allow a transition from an NSEC zone with
NSEC only DNSKEYs to an NSEC3 zone.
2022-08-22 15:55:46 +02:00
Aram Sargsyan
c51b052827 dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset() can not fail
Clean up dns_rdatalist_tordataset() and dns_rdatalist_fromrdataset()
functions by making them return void, because they cannot fail.

Clean up other functions that subsequently cannot fail.
2022-08-09 08:19:51 +00:00
Evan Hunt
549cf0f3e6 "rndc fetchlimit" now also lists rate-limited domains
"rndc fetchlimit" now also prints a list of domain names that are
currently rate-limited by "fetches-per-zone".

The "fetchlimit" system test has been updated to use this feature
to check that domain limits are applied correctly.
2022-07-06 19:46:23 -07:00
Evan Hunt
6175897478 add "rndc fetchlimit" to show fetchlimited servers
this command runs dns_adb_dumpquota() to display all servers
in the ADB that are being actively fetchlimited by the
fetches-per-server controls (i.e, servers with a nonzero average
timeout ratio or with the quota having been reduced from the
default value).

the "fetchlimit" system test has been updated to use the
new command to check quota values instead of "rndc dumpdb".
2022-07-06 19:46:20 -07:00
Evan Hunt
7cac4ca03c clean up unused API
the dns_adb_dumpfind() function was only used inside adb.c and
can be static. dns_view_dumpdbtostream() was not used anywhere.
2022-07-06 19:36:54 -07:00
Mark Andrews
a5b57ed293 Add synth-from-dnssec namespaces for keytable entries
We do this by adding callbacks for when a node is added or deleted
from the keytable.  dns_keytable_add and dns_keytable_delete where
extended to take a callback.  dns_keytable_deletekey does not remove
the node so it was not extended.
2022-07-05 12:29:01 +10:00
Mark Andrews
3619cad141 Add a mechanism to record namespaces for synth-from-dnssec
When namespace is grafted on, the DNSSEC proofs for non existance
need to come from that namespace and not a higher namespace.  We
add 3 function dns_view_sfd_add, dns_view_sfd_del and dns_view_sfd_find
to add, remove and find the namespace that should be used when
checking NSEC records.

dns_view_sfd_add adds a name to a tree, creating the tree if needed.
If the name already existed in the tree the reference count is
increased otherwise it is initalised to 1.

dns_view_sfd_del removes a reference to a name in the tree, if the
count goes to 0 the node is removed.

dns_view_sfd_find returns the namespace to be used to entered name.
If there isn't an enclosing name in the tree, or the tree does not
yet exist, the root name is returned.

Access to the tree is controlled by a read/write lock.
2022-07-05 12:29:01 +10:00
Michał Kępień
887c666caf Obsolete the "glue-cache" option
The "glue-cache" option was marked as deprecated by commit
5ae33351f2 (first released in BIND 9.17.6,
back in October 2020), so now obsolete that option, removing all code
and documentation related to it.

Note: this causes the glue cache feature to be permanently enabled, not
disabled.
2022-06-30 15:24:08 +02:00
Matthijs Mekking
5ff414e986 Store built-in dnssec-policies in defaultconf
Update the defaultconf with the built-in policies. These will now be
printed with "named -C".

Change the defines in kasp.h to be strings, so they can be concatenated
in the defaultconf. This means when creating a kasp structure, we no
longer initialize the defaults (this is fine because only kaspconf.c
uses dns_kasp_create() and it inherits from the default policy).

In kaspconf.c, the default values now need to be parsed from string.

Introduce some variables so we don't need to do get_duration multiple
times on the same configuration option.

Finally, clang-format-14 decided to do some random formatting changes.
2022-06-28 11:56:31 +02:00
Michal Nowak
1c45a9885a
Update clang to version 14 2022-06-16 17:21:11 +02:00
Aram Sargsyan
887aa7a290 Cleanup dns_fwdtable_delete()
The conversion of `DNS_R_PARTIALMATCH` into `DNS_R_NOTFOUND` is done
in the `dns_rbt_deletename()` function so there is no need to do that
in `dns_fwdtable_delete()`.

Add a possible return value of `ISC_R_NOSPACE` into the header file's
function description comment.
2022-06-09 10:47:04 +00:00
Aram Sargsyan
2aff264fb1 Check that catz member zone is not a configured forward zone
When processing a catalog zone member zone make sure that there is no
configured pre-existing forward zone with that name.

Refactor the `dns_fwdtable_find()` function to not alter the
`DNS_R_PARTIALMATCH` result (coming from `dns_rbt_findname()`) into
`DNS_R_SUCCESS`, so that now the caller can differentiate partial
and exact matches. Patch the calling sites to expect and process
the new return value.
2022-06-09 10:45:10 +00:00
Tony Finch
64e801243e Clean up remaining references to global compression
It is simply called "compression" now, without any qualifiers. Also,
improve some variable names in dns_name_towire2() so they are not two
letter abbreviations for global something.
2022-06-01 13:00:40 +01:00
Tony Finch
1d807d84f1 Shrink decompression contexts
It's wasteful to use 20 bytes and a pointer indirection to represent
two bits of information, so turn the struct into an enum. And change
the names of the enumeration constants to make the intent more clear.

This change introduces some inline functions into another header,
which confuses `gcovr` when it is trying to collect code coverage
statistics. So, in the CI job, copy more header files into a directory
where `gcovr` looks for them.
2022-06-01 13:00:40 +01:00
Tony Finch
129a522d88 There can no longer be multiple compression methods
The aim is to get rid of the obsolete term "GLOBAL14" and instead just
refer to DNS name compression.

This is mostly mechanically renaming

from	dns_(de)compress_(get|set)methods()
to	dns_(de)compress_(get|set)permitted()

and replacing the related enum by a simple flag, because compression
is either on or off.
2022-06-01 13:00:40 +01:00
Tony Finch
e37b782c1a DNS name compression does not depend on the EDNS version
There was a proposal in the late 1990s that it might, but it turned
out to be unworkable. See RFC 6891, Extension Mechanisms for
DNS (EDNS(0)), section 5, Extended Label Types.

The remnants of the code that supported this in BIND are redundant.
2022-06-01 13:00:40 +01:00
Ondřej Surý
c06b661130 Remove dns_lookup and unused functions in dns_byaddr
Clean up unused functions from the dns_byaddr API and completely remove
the dns_lookup API.
2022-05-25 14:44:32 +02:00
Matthijs Mekking
1fa24d0afb Fix CID 352776: Concurrent data access violations
*** CID 352776:  Concurrent data access violations  (MISSING_LOCK)
/lib/dns/dst_api.c: 474 in dst_key_setmodified()
468     dst_key_isexternal(dst_key_t *key) {
469		return (key->external);
470     }
471
472     void
473     dst_key_setmodified(dst_key_t *key, bool value) {
>>>     CID 352776:  Concurrent data access violations  (MISSING_LOCK)
>>>     Accessing "key->modified" without holding lock
>>>	"dst_key.mdlock". Elsewhere, "dst_key.modified" is accessed with
>>>	"dst_key.mdlock" held 8 out of 11 times (8 of these accesses
>>>	strongly imply that it is necessary).
474		key->modified = value;
475     }
476
477     bool
478     dst_key_ismodified(dst_key_t *key) {
479		return (key->modified);
2022-05-23 11:36:13 +02:00
Evan Hunt
6936db2f59 Always use the number of CPUS for resolver->ntasks
Since the fctx hash table is now self-resizing, and resolver tasks are
selected to match the thread that created the fetch context, there
shouldn't be any significant advantage to having multiple tasks per CPU;
a single task per thread should be sufficient.

Additionally, the fetch context is always pinned to the calling netmgr
thread to minimize the contention just to coalesced fetches - if two
threads starts the same fetch, it will be pinned to the first one to get
the bucket.
2022-05-19 09:27:33 +02:00
Ondřej Surý
33ba0057a7 Cleanup dns_message_gettemp*() functions - they cannot fail
The dns_message_gettempname(), dns_message_gettemprdata(),
dns_message_gettemprdataset(), and dns_message_gettemprdatalist() always
succeeds because the memory allocation cannot fail now.  Change the API
to return void and cleanup all the use of aforementioned functions.
2022-05-17 12:39:25 +02:00
Evan Hunt
d7ffd897ef remove requestmgr whenshutdown events
the request manager has no direct dependency on the
view, so there's no need for a weak reference. remove the
dns_requestmgr_whenshutdown() mechanism since it is no longer
used.
2022-05-13 13:39:52 -07:00
Evan Hunt
51cd295c4b remove resolver whenshutdown events
weakly attaching and detaching when creating and destroying the
resolver obviates the need to have a callback event to do the weak
detach. remove the dns_resolver_whenshutdown() mechanism, as it is
now unused.
2022-05-13 13:36:10 -07:00
Evan Hunt
a2d491279a remove ADB whenshutdown events
weakly attaching and detaching the view when creating or destroying
the ADB obviates the need for a whenshutdown callback event to do
the detaching.  remove the dns_adb_whenshutdown() mechanism, since
it is no longer needed.
2022-05-13 13:36:10 -07:00
Evan Hunt
3027f59f6f move ADB and resolver stats out of the view object
for better object separation, ADB and resolver statistics counters
are now stored in the ADB and resolver objects themsevles, rather than
in the associated view.
2022-05-13 13:36:10 -07:00
Evan Hunt
e5e2d7814e remove view->attributes field
it's not necessary to use view attributes to determine whether
the ADB, resolver and requestmgr need to be shut down; checking
whether they're NULL is sufficient.
2022-05-13 13:36:10 -07:00
Evan Hunt
fe1fa8dc88 minor view refactoring
- eliminate dns_view_flushanddetach(), which was only called from
  one place; instead, we now call a function dns_view_flushonshutdown()
  which sets the view up to flush zones when it is detached normally
  with dns_view_detach().
- cleaned up code in dns_view_create().
2022-05-13 13:36:10 -07:00
Matthijs Mekking
1da91b3ab4 Check if key metadata is modified before writing
Add a new parameter to the dst_key structure, mark a key modified if
dst_key_(un)set[bool,num,state,time] is called. Only write out key
files during a keymgr run if the metadata has changed.
2022-05-13 13:31:17 +02:00
Ondřej Surý
2235edabcf Remove isc_task_onshutdown()
The isc_task_onshutdown() was used to post event that should be run when
the task is being shutdown.  This could happen explicitly in the
isc_test_shutdown() call or implicitly when we detach the last reference
to the task and there are no more events posted on the task.

This whole task onshutdown mechanism just makes things more complicated,
and it's easier to post the "shutdown" events when we are shutting down
explicitly and the existing code already always knows when it should
shutdown the task that's being used to execute the onshutdown events.

Replace the isc_task_onshutdown() calls with explicit calls to execute
the shutdown tasks.
2022-05-12 13:45:34 +02:00
Artem Boldariev
79c5cad7e5 Rename "hostname" to "remote-hostname" within "tls"
This commit renames "hostname" to "remote-hostname" within "tls"
options to avoid semantic conflicts with generic "options"
configuration.
2022-05-03 17:15:43 +03:00
Tony Finch
7f4a4ec07c Ditch a couple of unused #defines
These were added by mistake in CHANGES 2349 and were not removed when
the mistake was corrected.
2022-05-03 09:30:28 +00:00
Tony Finch
db7487dd35 Clarify a few zonetree API comments
Replace a load-bearing semicolon with some more explanatory words,
and correct a couple of parameter names.
2022-05-02 22:48:55 +01:00
Tony Finch
cdd3d54bce Remove unused rbtnode->rpz flag
The rbtnode->rpz flag was left behind when rbt and rpz were disentangled
by CHANGES #4576. Removing it makes the comment above correct again.

This reduces the flags so they fit in a 32 bit word again. On 64
bit systems there is still padding so it doesn't change the size
of an rbtnode. On 32 bit systems it reduces an rbtnode by 4 bytes.
2022-05-02 19:47:58 +01:00
Mark Andrews
d4892f7cdc Tighten DBC restrictions on message sections
dns_message_findname and dns_message_sectiontotext incorrectly accepted
DNS_SECTION_ANY.  If DNS_SECTION_ANY was passed the section array could
be incorrectly accessed at (-1).

dns_message_pseudosectiontotext and dns_message_pseudosectiontoyaml
incorrectly accepted DNS_PSEUDOSECTION_ANY.  These functions are
designed to process a single section.
2022-04-19 22:12:38 +00:00
Aram Sargsyan
bb837db4ee Implement catalog zones change of ownership (coo) support
Catalog zones change of ownership is special mechanism to facilitate
controlled migration of a member zone from one catalog to another.

It is implemented using catalog zones property named "coo" and is
documented in DNS catalog zones draft version 5 document.

Implement the feature using a new hash table in the catalog zone
structure, which holds the added "coo" properties for the catalog zone
(containing the target catalog zone's name), and the key for the hash
table being the member zone's name for which the "coo" property is being
created.

Change some log messages to have consistent zone name quoting types.

Update the ARM with change of ownership documentation and usage
examples.

Add tests which check newly the added features.
2022-04-14 20:41:52 +00:00
Matthijs Mekking
3d05c99abb Update dns_dnssec_syncdelete() function
Update the function that synchronizes the CDS and CDNSKEY DELETE
records. It now allows for the possibility that the CDS DELETE record
is published and the CDNSKEY DELETE record is not, and vice versa.

Also update the code in zone.c how 'dns_dnssec_syncdelete()' is called.

With KASP, we still maintain the DELETE records our self. Otherwise,
we publish the CDS and CDNSKEY DELETE record only if they are added
to the zone. We do still check if these records can be signed by a KSK.

This change will allow users to add a CDS and/or CDNSKEY DELETE record
manually, without BIND removing them on the next zone sign.

Note that this commit removes the check whether the key is a KSK, this
check is redundant because this check is also made in
'dst_key_is_signing()' when the role is set to DST_BOOL_KSK.
2022-04-13 13:26:59 +02:00
Ondřej Surý
f106d0ed2b Run the RPZ update as offloaded work
Previously, the RPZ updates ran quantized on the main nm_worker loops.
As the quantum was set to 1024, this might lead to service
interruptions when large RPZ update was processed.

Change the RPZ update process to run as the offloaded work.  The update
and cleanup loops were refactored to do as little locking of the
maintenance lock as possible for the shortest periods of time and the db
iterator is being paused for every iteration, so we don't hold the rbtdb
tree lock for prolonged periods of time.
2022-04-04 21:20:05 +02:00
Ondřej Surý
b6e885c97f Refactor the dns_rpz_add/delete to use local rpz copy
Previously dns_rpz_add() were passed dns_rpz_zones_t and index to .zones
array.  Because we actually attach to dns_rpz_zone_t, we should be using
the local pointer instead of passing the index and "finding" the
dns_rpz_zone_t again.

Additionally, dns_rpz_add() and dns_rpz_delete() were used only inside
rpz.c, so make them static.
2022-04-04 21:20:05 +02:00
Ondřej Surý
840179a247 General cleanup of dns_rpz implementation
Do a general cleanup of lib/dns/rpz.c style:

 * Removed deprecated and unused functions
 * Unified dns_rpz_zone_t naming to rpz
 * Unified dns_rpz_zones_t naming to rpzs
 * Add and use rpz_attach() and rpz_attach_rpzs() functions
 * Shuffled variables to be more local (cppcheck cleanup)
2022-04-04 21:19:48 +02:00
Ondřej Surý
8138a595d9 Add isc_rwlock around dns_aclenv .localhost and .localnets member
In order to modify the .localhost and .localnets members of the
dns_aclenv, all other processing on the netmgr loops needed to be
stopped using the task exclusive mode.  Add the isc_rwlock to the
dns_aclenv, so any modifications to the .localhost and .localnets can be
done under the write lock.
2022-04-04 19:27:00 +02:00
Ondřej Surý
2bc7303af2 Use isc_nm_getnworkers to manage zone resources
Instead of passing the number of worker to the dns_zonemgr manually,
get the number of nm threads using the new isc_nm_getnworkers() call.

Additionally, remove the isc_pool API and manage the array of memory
context, zonetasks and loadtasks directly in the zonemgr.
2022-04-01 23:50:34 +02:00
Ondřej Surý
2707d0eeb7 Set hard thread affinity for each zone
After switching to per-thread resources in the zonemgr, the performance
was decreased because the memory context, zonetask and loadtask was
picked from the pool at random.

Pin the zone to single threadid (.tid) and align the memory context,
zonetask and loadtask to be the same, this sets the hard affinity of the
zone to the netmgr thread.
2022-04-01 23:50:34 +02:00
Ondřej Surý
a94678ff77 Create per-thread task and memory context for zonemgr
Previously, the zonemgr created 1 task per 100 zones and 1 memory
context per 1000 zones (with minimum 10 tasks and 2 memory contexts) to
reduce the contention between threads.

Instead of reducing the contention by having many resources, create a
per-nm_thread memory context, loadtask and zonetask and spread the zones
between just per-thread resources.

Note: this commit alone does decrease performance when loading the zone
by couple seconds (in case of 1M zone) and thus there's more work in
this whole MR fixing the performance.
2022-04-01 23:50:34 +02:00
Ondřej Surý
48b2a5df97 Keep the list of scheduled events on the timer
Instead of searching for the events to purge, keep the list of scheduled
events on the timer list and purge the events that we have scheduled.
2022-04-01 23:45:23 +02:00
Evan Hunt
199be183fa Add detailed ADB and entry attach/detach tracing
To turn on detailed debug tracing of dns_adb and dns_adbentry
reference counting, #define ADB_TRACE at the top of adb.c. This
is off by default.
2022-03-30 10:12:25 +02:00
Evan Hunt
d48d8e1cf0 Refactor ADB reference counting, shutdown and locking
The ADB previously used separate reference counters for internal
and external references, plus additional counters for ABD find
and namehook objects, and used all these counters to coordinate
its shutdown process, which was a multi-stage affair involving
a sequence of control events.

It also used a complex interlocking set of static functions for
referencing, deferencing, linking, unlinking, and cleaning up various
internal objects; these functions returned boolean values to their
callers to indicate what additional processing was needed.

The changes in the previous two commits destabilized this fragile
system in a way that was difficult to recover from, so in this commit
we refactor all of it. The dns_adb and dns_adbentry objects now use
conventional attach and detach functions for reference counting, and
the shutdown process is much more straightforward.  Instead of
handling shutdown asynchronously, we can just destroy the ADB when
references reach zero

In addition, ADB locking has been simplified. Instead of a
single `find_{name,entry}_and_lock()` function which searches for
a name or entry's hash bucket, locks it, and then searches for the
name or entry in the bucket, we now use one function to find the
bucket (leaving it to the caller to do the locking) and another
find the name or entry.  Instead of locking the entire ADB when
modifying hash tables, we now use read-write locks around the
specific hash table. The only remaining need for adb->lock
is when modifying the `whenshutdown` list.

Comments throughout the module have been improved.
2022-03-30 10:12:25 +02:00
Evan Hunt
76bcb4d16b Refactor how ADB names and entries are stored in the dns_adb
Replace adb->{names,entries} and related arrays (indexed by hashed
bucket) with a isc_ht hash tables storing the new struct
adb{name,entry}bucket_t that wraps all the variables that were
originally stored in arrays indexed by "bucket" number stored directly
in the struct dns_adb.

Previously, the task exclusive mode has been used to grow the internal
arrays used to store the named and entries objects.  The isc_ht hash
tables are now protected by the isc_rwlock instead and thus the usage of
the task exclusive mode has been removed from the dns_adb.

Co-authored-by: Ondřej Surý <ondrej@isc.org>
2022-03-30 10:09:18 +02:00