Commit graph

216 commits

Author SHA1 Message Date
Ondřej Surý
9e40f6508c Remove the dead dns_expire_ttl code path and deletettl stats counter
Now that TTL-based cleaning has been removed, the dns_expire_ttl enum
value, its switch case in expireheader(), and the deletettl stats counter
(text, XML, JSON) are all dead code.  Remove them so the stats channel
no longer reports a permanently-zero counter.
2026-03-30 21:46:44 +02:00
Ondřej Surý
6fa415f71f Refactor the 'max-cache-size' configuration handling
Extract the inline max-cache-size logic from configure_view() into
reusable helpers: configure_max_cache_size(), default_max_cache_size(),
max_cache_size_as_percent(), and sanitized_max_cache_size().

Move DNS_CACHE_MINSIZE and DNS_ADB_MINADBSIZE to public headers and
remove the SIZE_AS_PERCENT sentinel.
2026-03-30 21:46:44 +02:00
Ondřej Surý
d7c99c14fc Remove 'unlimited' setting for the max-cache-size
Since TTL-based cache cleaning has been removed, an unlimited
max-cache-size would eventually exhaust system memory.

Both 'max-cache-size unlimited;' and 'max-cache-size 0;' now fall
back to the default value (90% of physical memory for recursive
views).
2026-03-30 21:46:44 +02:00
Ondřej Surý
4891a6b14f Remove the heap memory context from QPcache
The heaps have been removed, so the separate heap memory context
(hmctx) is no longer needed.  Remove it from both dns_cache and
dns_qpcache, along with the HeapMemInUse statistics.
2026-03-30 21:46:44 +02:00
Evan Hunt
6b33b7fc77 switch to RETERR where it wasn't being used
replace all instances of the pattern:

        result = <statement>
        if (result != ISC_R_SUCCESS) {
                return result;
        }

with:

        RETERR(<statement>);
2025-12-03 13:45:43 -08:00
Evan Hunt
38e94cc7da switch to CHECK where it wasn't being used
replace all instances of the pattern:

        result = <statement>
        if (result != ISC_R_SUCCESS) {
                goto cleanup;
        }

with:

        CHECK(<statement>);
2025-12-03 13:45:42 -08:00
Ondřej Surý
9e2d5d94bd
Remove dns_dbtree_t and its usage
As we removed the ability to count nodes in the auxiliary trees (because
there are no auxiliary trees), we can also cleanup the API and
associated enum type (dns_dbtree_t).
2025-09-17 15:58:44 +02:00
Ondřej Surý
70c8054b84
Remove CacheNSECNodes statistics counter
There is no auxiliary NSEC tree, so we can't count the NSEC nodes
separately.  Remove the CacheNSECNodes statistics counter as it would be
always zero.
2025-09-17 15:58:44 +02:00
Evan Hunt
9e14fcd259 remove obsolete dns_db_hashsize()
this function's purpose was to populate the "CacheBuckets" statistic,
but there are no databases left that implemented it, so the return
value was always 0. "CacheBuckets" has now been removed from the
statistics, and the dns_db_hashsize() API call has been removed.
2025-09-15 16:11:50 +00:00
Evan Hunt
7e7d8bece7 remove obsolete dns_db_setloop()
no database implementation has needed an event loop
since the RBT cache was removed, so the setloop API call
is no longer needed.
2025-09-15 16:11:50 +00:00
Ondřej Surý
42496f3f4a
Use ControlStatementsExceptControlMacros for SpaceBeforeParens
> Put a space before opening parentheses only after control statement
> keywords (for/if/while...) except this option doesn’t apply to ForEach
> and If macros. This is useful in projects where ForEach/If macros are
> treated as function calls instead of control statements.
2025-08-19 07:58:33 +02:00
Alessio Podda
ae6a34cbda Decouple database and node lifetimes by adding node-specific vtables
All databases in the codebase follow the same structure: a database is
an associative container from DNS names to nodes, and each node is an
associative container from RR types to RR data.

Each database implementation (qpzone, qpcache, sdlz, builtin, dyndb) has
its own corresponding node type (qpznode, qpcnode, etc). However, some
code needs to work with nodes generically regardless of their specific
type - for example, to acquire locks, manage references, or
register/unregister slabs from the heap.

Currently, these generic node operations are implemented as methods in
the database vtable, which creates problematic coupling between database
and node lifetimes. If a node outlives its parent database, the node
destructor will destroy all RR data, and each RR data destructor will
try to unregister from heaps by calling a virtual function from the
database vtable. Since the database was already freed, this causes a
crash.

This commit breaks the coupling by standardizing the layout of all
database nodes, adding a dedicated vtable for node operations, and
moving node-specific methods from the database vtable to the node
vtable.
2025-08-07 11:39:38 -07:00
Ondřej Surý
b8d00e2e18
Change the loopmgr to be singleton
All the applications built on top of the loop manager were required to
create just a single instance of the loop manager.  Refactor the loop
manager to not expose this instance to the callers and keep the loop
manager object internal to the isc_loop compilation unit.

This significantly simplifies a number of data structures and calls to
the isc_loop API.
2025-07-23 22:44:16 +02:00
Ondřej Surý
4e79e9baae
Give every memory context a name
Instead of giving the memory context names with an explicit call to
isc_mem_setname(), add the name to isc_mem_create() call to have all the
memory contexts an unconditional name.
2025-05-29 05:46:46 +02:00
Evan Hunt
8d065fd3e1 add DNS_DBITERATOR_FOREACH and DNS_RDATASETITER_FOREACH
when iterating databases, use DNS_DBITERATOR_FOREACH and
DNS_DNSRDATASETITER_FOREACH macros where possible.
2025-05-27 21:08:09 -07:00
Ondřej Surý
0258850f20
Remove redundant parentheses from the return statement 2024-11-19 12:27:22 +01:00
Ondřej Surý
091d738c72 Convert all categories and modules into static lists
Remove the complicated mechanism that could be (in theory) used by
external libraries to register new categories and modules with
statically defined lists in <isc/log.h>.  This is similar to what we
have done for <isc/result.h> result codes.  All the libraries are now
internal to BIND 9, so we don't need to provide a mechanism to register
extra categories and modules.
2024-08-20 12:50:39 +00:00
Ondřej Surý
52b3d86ef0
Add a limit to the number of RR types for single name
Previously, the number of RR types for a single owner name was limited
only by the maximum number of the types (64k).  As the data structure
that holds the RR types for the database node is just a linked list, and
there are places where we just walk through the whole list (again and
again), adding a large number of RR types for a single owner named with
would slow down processing of such name (database node).

Add a configurable limit to cap the number of the RR types for a single
owner.  This is enforced at the database (rbtdb, qpzone, qpcache) level
and configured with new max-types-per-name configuration option that
can be configured globally, per-view and per-zone.
2024-06-10 16:55:09 +02:00
Ondřej Surý
32af7299eb
Add a limit to the number of RRs in RRSets
Previously, the number of RRs in the RRSets were internally unlimited.
As the data structure that holds the RRs is just a linked list, and
there are places where we just walk through all of the RRs, adding an
RRSet with huge number of RRs inside would slow down processing of said
RRSets.

Add a configurable limit to cap the number of the RRs in a single RRSet.
This is enforced at the database (rbtdb, qpzone, qpcache) level and
configured with new max-records-per-type configuration option that can
be configured globally, per-view and per-zone.
2024-06-10 16:55:07 +02:00
Ondřej Surý
086b63f56d Use isc_queue to implement wait-free deadnodes queue
Replace the ISC_LIST based deadnodes implementation with isc_queue which
is wait-free and we don't have to acquire neither the tree nor node lock
to append nodes to the queue and the cleaning process can also
copy (splice) the list into a local copy without acquiring the list.

Currently, there's little benefit to this as we need to hold those
locks anyway, but in the future as we move to RCU based implementation,
this will be ready.

To align the cleaning with our event loop based model, remove the
hardcoded count for the node locks and use the number of the event loops
instead.  This way, each event loop can have its own cleaning as part of
the process.  Use uniform random numbers to spread the nodes evenly
between the buckets (instead of hashing the domain name).
2024-06-05 09:19:56 +02:00
Mark Andrews
87e3b9dbf3 Pass a memory context in to dns_cache_create 2024-05-31 15:40:32 +10:00
Mark Andrews
5e77edd074 Use a new memory context when flushing the cache
When the cache's memory context was in over memory state when the
cache was flushed it resulted in LRU cleaning removing newly entered
data in the new cache straight away until the old cache had been
destroyed enough to take it out of over memory state.  When flushing
the cache create a new memory context for the new db to prevent this.
2024-05-31 15:40:32 +10:00
Aram Sargsyan
4d3c31b928
fixup! Merge branch 'ondrej/light-cleanup-of-rdataslab' into 'main' 2024-05-25 11:47:33 +02:00
Ondřej Surý
3feabc8a22
Cleanup the dns_cache unit
Remove duplicate code and use ISC_REFCOUNT_{DECL,IMPL} macros.
2024-05-25 11:47:33 +02:00
Evan Hunt
5709f7bad9 rename qpdb to qpcache
move qpdb.c to qpcache.c and rename the "qp" database implementation
to "qpcache", in order to make it more clearly distinguishable from
"qpzone".
2024-03-08 15:36:56 -08:00
Mark Andrews
926d2e4cf2 dns_db_setloop called at wrong place on wrong db
In cache_create_db, dns_db_setloop should be called on the newly
created db only if the database creation succeeded.
2024-03-07 13:10:23 +11:00
Ondřej Surý
d492d676ef
Move the dns_db_setloop into cache_create_db()
The dns_cache_flush() drops the old database and creates a new one, but
it forgets to pass the loop that runs the node pruning and cleaning
the rbtdb when flushing it next time.  This causes the cleaning to skip
cleaning the parent nodes (with .down == NULL) leading to increased
memory usage over time until the database is unable to keep up and just
stays overmem all the time.
2024-03-06 18:33:33 +01:00
Evan Hunt
92b305be4b add a compile-time option to select default zone and cache DB
by default, QPDB is the database used by named and all tools and
unit tests. the old default of RBTDB can now be restored by using
"configure --with-zonedb=rbt --with-cachedb=rbt".

some tests have been fixed so they will work correctly with either
database.

CHANGES and release notes have been updated to reflect this change.
2024-03-06 10:49:02 +01:00
Evan Hunt
bb4464181a switch database defaults from "rbt" to "qp"
replace the string "rbt" throughout BIND with "qp" so that
qpdb databases will be used by default instead of rbtdb.
rbtdb databases can still be used by specifying "database rbt;"
in a zone statement.
2024-03-06 09:57:24 +01:00
Ondřej Surý
14bdd21e0a
Refactor the handling of isc_mem overmem condition
Previously, there were two methods of working with the overmem
condition:

1. hi/lo water callback - when the overmem condition was reached
   for the first time, the water callback was called with HIWATER
   mark and .is_overmem boolean was set internally.  Similarly,
   when the used memory went below the lo water mark, the water
   callback would be called with LOWATER mark and .is_overmem
   was reset.  This check would be called **every** time memory
   was allocated or freed.

2. isc_mem_isovermem() - a simple getter for the internal
   .is_overmem flag

This commit refactors removes the first method and move the hi/lo water
checks to the isc_mem_isovermem() function, thus we now have only a
single method of checking overmem condition and the check for hi/lo
water is removed from the hot path for memory contexts that doesn't use
overmem checks.
2023-11-29 14:16:20 +01:00
Evan Hunt
b12f709f05 restore isc_mem_setwater() call in the cache
Commit 4db150437e incorrectly removed the
call to isc_mem_setwater() from dns_cache_setcachesize().  The water()
function is a no-op, but we still need to set high- and low-water marks
in the memory context, otherwise overmem conditions will not be
detected.
2023-11-01 15:18:02 +00:00
Matthijs Mekking
3ae721db6c After cache flush, restore serve-stale settings
When flushing the cache, we create a new cache database. The serve-stale
settings need to be restored after doing this. We already did this
for max-stale-ttl, but forgot to do this for stale-refresh-time.
2023-08-31 11:07:35 +02:00
Ondřej Surý
5321c474ea Refactor isc_stats_create() and its downstream users to return void
The isc_stats_create() can no longer return anything else than
ISC_R_SUCCESS.  Refactor isc_stats_create() and its variants in libdns,
libns and named to just return void.
2023-07-27 11:37:44 +02:00
Evan Hunt
17f85f6c93
move prototypes for common functions to rbtdb_p.h
rename the existing rbtdb.h to rbtdb_p.h, and start putting
macros and declarations of dns__rbtdb functions into it.
2023-07-17 14:50:25 +02:00
Evan Hunt
4db150437e
clean up unused dns_db methods
to reduce the amount of common code that will need to be shared
between the separated cache and zone database implementations,
clean up unused portions of dns_db.

the methods dns_db_dump(), dns_db_isdnssec(), dns_db_printnode(),
dns_db_resigned(), dns_db_expirenode() and dns_db_overmem() were
either never called or were only implemented as nonoperational stub
functions: they have now been removed.

dns_db_nodefullname() was only used in one place, which turned out
to be unnecessary, so it has also been removed.

dns_db_ispersistent() and dns_db_transfernode() are used, but only
the default implementation in db.c was ever actually called. since
they were never overridden by database methods, there's no need to
retain methods for them.

in rbtdb.c, beginload() and endload() methods are no longer defined for
the cache database, because that was never used (except in a few unit
tests which can easily be modified to use the zone implementation
instead).  issecure() is also no longer defined for the cache database,
as the cache is always insecure and the default implementation of
dns_db_issecure() returns false.

for similar reasons, hashsize() is no longer defined for zone databases.

implementation functions that are shared between zone and cache are now
prepended with 'dns__rbtdb_' so they can become nonstatic.

serve_stale_ttl is now a common member of dns_db.
2023-07-17 14:50:25 +02:00
Tony Finch
6927a30926 Remove do-nothing header <isc/print.h>
This one really truly did nothing. No lines added!
2023-02-15 16:44:47 +00:00
Ondřej Surý
3d4e41d076 Remove the total memory counter
The total memory counter had again little or no meaning when we removed
the internal memory allocator.  It was just a monotonic counter that
would count add the allocation sizes but never subtracted anything, so
it would be just a "big number".
2023-01-24 17:57:16 +00:00
Ondřej Surý
91e349433f Remove maxinuse memory counter
The maxinuse memory counter indicated the highest amount of
memory allocated in the past. Checking and updating this high-
water mark value every time memory was allocated had an impact
on server performance, so it has been removed. Memory size can
be monitored more efficiently via an external tool logging RSS.
2023-01-24 17:57:16 +00:00
Mark Andrews
85048ddeee Add dns_db_allrdatasets options
'DNS_DB_STALEOK' returns stale rdatasets as well as current rdatasets.

'DNS_DB_EXPIREDOK' returns expired rdatasets as well as current
rdatasets. This option is currently only set when DNS_DB_STALEOK is
also set.
2022-12-07 22:20:02 +00:00
Mark Andrews
7695c36a5d Extend dns_db_allrdatasets to control interation results
Add an options parameter to control what rdatasets are returned when
iteratating over the node.  Specific modes will be added later.
2022-12-07 22:20:02 +00:00
Ondřej Surý
715343c31d
Remove dead code from dns_cache_flush()
After removing the cache cleaning mechanism, we don't need to db
iterator in dns_cache_flush() anymore.
2022-12-07 19:11:08 +01:00
Evan Hunt
09ee254514 change dns_db_settask() to _setloop()
The mechanism for associating a worker task to a database now
uses loops rather than tasks.

For this reason, the parameters to dns_cache_create() have been
updated to take a loop manager rather than a task manager.
2022-11-30 11:47:35 -08:00
Ondřej Surý
fa275a59da Remove the unused cache cleaning mechanism from dns_cache API
The dns_cache API contained a cache cleaning mechanism that would be
disabled for 'rbt' based cache.  As named doesn't have any other cache
implementations, remove the cache cleaning mechanism from dns_cache API.
2022-11-29 13:48:33 -08:00
Tony Finch
ec50c58f52 De-duplicate __FILE__, __LINE__
Mostly generated automatically with the following semantic patch,
except where coccinelle was confused by #ifdef in lib/isc/net.c

@@ expression list args; @@
- UNEXPECTED_ERROR(__FILE__, __LINE__, args)
+ UNEXPECTED_ERROR(args)
@@ expression list args; @@
- FATAL_ERROR(__FILE__, __LINE__, args)
+ FATAL_ERROR(args)
2022-10-17 11:58:26 +01: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
Ondřej Surý
1fe391fd40 Make all tasks to be bound to a thread
Previously, tasks could be created either unbound or bound to a specific
thread (worker loop).  The unbound tasks would be assigned to a random
thread every time isc_task_send() was called.  Because there's no logic
that would assign the task to the least busy worker, this just creates
unpredictability.  Instead of random assignment, bind all the previously
unbound tasks to worker 0, which is guaranteed to exist.
2022-05-25 16:04:51 +02:00
Ondřej Surý
0582478c96 Remove isc_task_destroy() and isc_task_shutdown()
After removing the isc_task_onshutdown(), the isc_task_shutdown() and
isc_task_destroy() became obsolete.

Remove calls to isc_task_shutdown() and replace the calls to
isc_task_destroy() with isc_task_detach().

Simplify the internal logic to destroy the task when the last reference
is removed.
2022-05-12 14:55:49 +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
Ondřej Surý
9f7ba679ac Purge the .resched_event in dns_cache
Instead of sweeping the cache cleaner tasks, purge the more specific
cleaner.resched_event event.
2022-04-01 23:45:23 +02:00