]> git.ipfire.org Git - thirdparty/bind9.git/log
thirdparty/bind9.git
7 months agoAdd a job preparing EVNs
Michał Kępień [Tue, 4 Nov 2025 11:51:35 +0000 (12:51 +0100)] 
Add a job preparing EVNs

Add a new GitLab CI job that automatically generates BIND 9 Early
Vulnerability Notifications based on the metadata for the current
release cycle.

7 months agoEnable overriding the list of security releases
Michał Kępień [Tue, 4 Nov 2025 11:51:35 +0000 (12:51 +0100)] 
Enable overriding the list of security releases

Enable manually providing (via an optional CI variable) Printing Press
jobs with the list of security releases in a given release cycle in case
autodetection fails for any reason.

7 months agoEnable overriding the list of fixed CVE IDs
Michał Kępień [Tue, 4 Nov 2025 11:51:35 +0000 (12:51 +0100)] 
Enable overriding the list of fixed CVE IDs

Enable manually providing (via an optional CI variable) Printing Press
jobs with the list of CVE IDs fixed in a given release cycle in case
autodetection fails for any reason.

7 months agoDeduplicate definitions of release-related jobs
Michał Kępień [Tue, 4 Nov 2025 11:51:35 +0000 (12:51 +0100)] 
Deduplicate definitions of release-related jobs

Extract common YAML keys used by release-related job definitions into
reusable anchors to ensure consistency and limit repetition across
multiple similar jobs.

7 months agoChange the script generating release announcements
Michał Kępień [Tue, 4 Nov 2025 11:51:35 +0000 (12:51 +0100)] 
Change the script generating release announcements

Use a different, generic script for preparing release announcements.

7 months agonew: usr: "named-checkconf -b" dumps the built-in configuration
Colin Vidal [Tue, 4 Nov 2025 09:04:31 +0000 (10:04 +0100)] 
new: usr: "named-checkconf -b" dumps the built-in configuration

`named-checkconf` now supports the command line switch `-b`,  which prints the default built-in configuration used by `named`.

When `-b` is in use, other options are ignored.

Closes #1326

Merge branch '1326-named-checkconf-builtin' into 'main'

See merge request isc-projects/bind9!11177

7 months ago"named-checkconf -b" dumps built-in config
Colin Vidal [Thu, 30 Oct 2025 09:00:59 +0000 (10:00 +0100)] 
"named-checkconf -b" dumps built-in config

`named-checkconf` now supports the command line switch `-b`,  which
prints the default built-in configuration used by `named`.

When `-b` is in use, other options are ignored.

7 months agofix: usr: Prevent assertion failures of dig when server is specified before the ...
Arаm Sаrgsyаn [Tue, 4 Nov 2025 08:00:25 +0000 (08:00 +0000)] 
fix: usr: Prevent assertion failures of dig when server is specified before the -b option

Previously, :iscman:`dig` could exit with an assertion failure when the server was specified before the :option:`dig -b` option. This has been fixed.

Closes #5609

Merge branch '5609-fix-dig-crash-with-at-and-dash-b-on-main' into 'main'

See merge request isc-projects/bind9!11183

7 months agoTest dig with a IPv4 source address and a IPv4+IPv6 server
Aram Sargsyan [Fri, 31 Oct 2025 16:34:47 +0000 (16:34 +0000)] 
Test dig with a IPv4 source address and a IPv4+IPv6 server

Check that dig doesn't exit with an assertion failure when a IPv4
source address is defined after defining a server address which has
both IPv4 and IPv6 addresses (in this case, @localhost).

7 months agoavoid retrying a server if its address is unusable
JINMEI Tatuya [Thu, 30 Oct 2025 04:58:18 +0000 (21:58 -0700)] 
avoid retrying a server if its address is unusable

Previously, if there's no more server to try in force_next,
it attempted to retry the current server similar to a query
timeout case. But, force_next() is called only when the
current server's address is unusable and the query was not
even sent, so recvcount was not incremented, causing an
assertion failure.

We might be able to fix it so the retry doesn't cause a crash,
but it doesn't make sense to retry the server when its address
is known to be unusable. So, simply avoiding the retry would be
the easiest and safest way to prevent the crash.

7 months agomake sure current_query is detached before trying next server
JINMEI Tatuya [Thu, 30 Oct 2025 00:51:59 +0000 (17:51 -0700)] 
make sure current_query is detached before trying next server

Without this, start_udp or start_tcp would trigger an assertion
failure. Detaching it at this point is also consistent with
other failure handling cases, such as in recv_done.

7 months agonew: usr: Add support for Extended DNS Error 24 (Invalid Data)
Colin Vidal [Mon, 3 Nov 2025 17:25:38 +0000 (18:25 +0100)] 
new: usr: Add support for Extended DNS Error 24 (Invalid Data)

Extended DNS Error 24 (Invalid Data) is returned when the server cannot answer data for a zone it is configured for. This occurs typically when an authoritative server does not have loaded the DB of a configured zone, or a secondary server zone is expired.

See RFC 8914 section 4.25.

See #1836

Merge branch 'colin/ede24' into 'main'

See merge request isc-projects/bind9!11169

7 months agolog that a zone is expired after setting the flag
Colin Vidal [Mon, 3 Nov 2025 16:31:26 +0000 (17:31 +0100)] 
log that a zone is expired after setting the flag

When a (secondary) zone is expired, the log message `<zone> expired` is
printed and the flag `DNS_ZONEFLG_EXPIRED` is set. Change the order by
setting the expired flag first, then printing the log.

This should fixes (rare but persistent) timing-related CI error when the
EDE 24 tests expect the zone to be expired (from the log) and
immediately after request and expect an EDE 24 error. (In some rare
cases, the server was still answering the response).

7 months agoadd tests for EDE 24 support
Colin Vidal [Wed, 29 Oct 2025 16:32:29 +0000 (17:32 +0100)] 
add tests for EDE 24 support

Add system test covering EDE 24 being added in the response in both
common cases: when the server has not loaded the DB of a zone and when
the zone has expired (secondary).

7 months agosupport EDE 24 (Invalid Data)
Colin Vidal [Fri, 31 Oct 2025 11:16:54 +0000 (12:16 +0100)] 
support EDE 24 (Invalid Data)

Extended DNS Error 24 (Invalid Data) is returned when the server cannot
answer data for a zone it is configured for. This occurs typically when
an authoritative server does not have loaded the DB of a configured
zone, or a secondary server zone is expired.

See RFC 8914 section 4.25.

7 months agoquery_getzonedb can returns DNS_R_EXPIRED
Colin Vidal [Fri, 31 Oct 2025 11:15:00 +0000 (12:15 +0100)] 
query_getzonedb can returns DNS_R_EXPIRED

If `query_getzonedb()` finds a zone but the zone is expired it
immediately returns `DNS_R_EXPIRED` and doesn't attempt to get the zone
DB (which would be NULL in this case).

This enable caller to have a more precise reason of why getting the DB
has failed.

7 months agoadd dns_zone_isexpired API
Colin Vidal [Fri, 31 Oct 2025 11:12:20 +0000 (12:12 +0100)] 
add dns_zone_isexpired API

Introduce the `dns_zone_isexpired()` API which returns `true` when a
secondary, mirror, etc. zone is expired.

This internally use the `DNS_ZONEFLG_EXPIRED` which was already set when
the zone gets expired, but never used.

The flag `DNS_ZONEFLG_EXPIRED` is also now cleared when the expiration
time of the zone is updated and in the future.

7 months agorem: nil: Remove leftover FCTX_ATTR_NEEDEDNS0
Petr Špaček [Mon, 3 Nov 2025 15:25:20 +0000 (15:25 +0000)] 
rem: nil: Remove leftover FCTX_ATTR_NEEDEDNS0

Merge branch 'pspacek/remove-dead-NEEDEDNS0' into 'main'

See merge request isc-projects/bind9!11198

7 months agoRemove leftover FCTX_ATTR_NEEDEDNS0
Petr Špaček [Sat, 1 Nov 2025 22:35:35 +0000 (18:35 -0400)] 
Remove leftover FCTX_ATTR_NEEDEDNS0

This is leftover from commit b6309ed962c4988a314d61742c4fbc4935467d68
which removed support for bitstring labels back in 2002.

7 months agofix: dev: Remove unused dns_zone_getnotifyacl() function
Matthijs Mekking [Mon, 3 Nov 2025 14:38:12 +0000 (14:38 +0000)] 
fix: dev: Remove unused dns_zone_getnotifyacl() function

Deals with Coverity issues:
- CID 638286: Concurrent data access violations (MISSING_LOCK).
- CID 638287: Concurrent data access violations (MISSING_LOCK).

Merge branch 'matthijs-cid-638286-missing-lock' into 'main'

See merge request isc-projects/bind9!11200

7 months agoRemove unused dns_zone_getnotifyacl() function
Matthijs Mekking [Mon, 3 Nov 2025 11:45:39 +0000 (12:45 +0100)] 
Remove unused dns_zone_getnotifyacl() function

CID 638286: Concurrent data access violations (MISSING_LOCK).  This
complains about accessing "zone->notifyctx.notify_acl" without holding
the lock "dns_zone.lock".  Elsewhere, reading this data does have the
lock, so it makes sense that in the getter function this must also be
so.  However, the function is unused so we can just remove it.

CID 638287: Concurrent data access violations (MISSING_LOCK).  This
complains about accessing "zone->locked" without holding the lock
"dns_zone.lock". I think this is a false positive as "dns__zone_lock()"
and "dns__zone_unlock() are wrappers around "LOCK_ZONE()" and
"UNLOCK_ZONE()" and where these macros were used they were only
replaced with the internal zone functions. Moreover, "zone->locked"
is only accessed in these macros (and "TRYLOCK_ZONE()" and
"LOCKED_ZONE()").

7 months agofix: dev: restore reuseport to yes by default on supported platforms
Colin Vidal [Fri, 31 Oct 2025 14:50:56 +0000 (15:50 +0100)] 
fix: dev: restore reuseport to yes by default on supported platforms

Changes introduced by 72862c2a moved the
default configuration from within `bin/named` to a central place
`bin/includes`.

The default configuration is conditioned by several compile-time macro.
While for most of them it's fine because they are defined in the global
`config.h` file included by default to all binaries (by meson), one
specific is not defined here. `HAVE_SO_REUSEPORT_LB` was defined in
`lib/isc/include/isc/netmgr.h` which is of course not included in
`bin/includes/defaultconfig.h`.

As a result, reuseport was disabled for all platform by default, even
the supported ones. This fixes the problem by checking if reuseport is
available on the platform from meson `config.h` generation directly,
which makes `HAVE_SO_REUSEPORT_LB` available everywhere.

Merge branch 'colin/fix-reuseport-default' into 'main'

See merge request isc-projects/bind9!11180

7 months agorestore reuseport to yes by default on supported platforms
Colin Vidal [Thu, 30 Oct 2025 14:02:10 +0000 (15:02 +0100)] 
restore reuseport to yes by default on supported platforms

Changes introduced by 72862c2abc0bc6e87de08918bf21a7fc8fc4b1f7 moved the
default configuration from within `bin/named` to a central place
`bin/includes`.

The default configuration is conditioned by several compile-time macro.
While for most of them it's fine because they are defined in the global
`config.h` file included by default to all binaries (by meson), one
specific is not defined here. `HAVE_SO_REUSEPORT_LB` was defined in
`lib/isc/include/isc/netmgr.h` which is of course not included in
`bin/includes/defaultconfig.h`.

As a result, reuseport was disabled for all platform by default, even
the supported ones. This fixes the problem by checking if reuseport is
available on the platform from meson `config.h` generation directly,
which makes `HAVE_SO_REUSEPORT_LB` available everywhere.

7 months agochg: dev: Refactor notify code
Matthijs Mekking [Fri, 31 Oct 2025 13:47:19 +0000 (13:47 +0000)] 
chg: dev: Refactor notify code

Move notify code in separate source files in preparation for support of generalized DNS notifications.

Merge branch 'matthijs-refactor-notify-code-2' into 'main'

See merge request isc-projects/bind9!11146

7 months agoMove notify functions to notify source files
Matthijs Mekking [Fri, 24 Oct 2025 12:21:25 +0000 (14:21 +0200)] 
Move notify functions to notify source files

Move dns_notify_destroy, dns_notify_log, dns_notify_cancel,
dns_notify_queue, dns_notify_isqueued, dns_notify_find_address, and
notify related static functions over to the notify source files.

7 months agoExport zone functions
Matthijs Mekking [Fri, 17 Oct 2025 14:14:09 +0000 (16:14 +0200)] 
Export zone functions

Make some zone functions available that we are going to need in the
notify code.

7 months agoIntroduce notify source code files
Matthijs Mekking [Thu, 16 Oct 2025 15:01:57 +0000 (17:01 +0200)] 
Introduce notify source code files

Part of refactoring zone.c is to move the notify code into its own
source files. This commit initiates this work by creating notify.[c,h]
and move notify_create() and the notify state and context there.

The function notify_create() cannot fail, so it can return void instead
of isc_result_t.

7 months agoRename notify remote to alsonotify
Matthijs Mekking [Fri, 17 Oct 2025 13:55:00 +0000 (15:55 +0200)] 
Rename notify remote to alsonotify

Make it more clear it is tied to the 'also-notify' option.

7 months agofix: usr: Skip buffer allocations if not logging
Alessio Podda [Fri, 31 Oct 2025 12:16:03 +0000 (12:16 +0000)] 
fix: usr: Skip buffer allocations if not logging

Currently, during IXFR we allocate a 2KB buffer for IXFR change logging
regardless of the log level. This commit introduces an early check
on the log level in dns_diff_print to avoid this.

Results in a speedup from 28% in the test case from issue #5442.

Merge branch '5442-ixfr-no-log-alloc' into 'main'

See merge request isc-projects/bind9!11178

7 months agoSkip buffer allocations if not logging
Alessio Podda [Thu, 30 Oct 2025 10:45:09 +0000 (11:45 +0100)] 
Skip buffer allocations if not logging

Currently, during IXFR we allocate a 2KB buffer for IXFR change logging
regardless of the log level. This commit introduces an early check
on the log level in dns_diff_print to avoid this.

Results in a speedup from 28% in the test case from issue #5442.

7 months agochg: dev: Don't retain the default configuration tree
Colin Vidal [Fri, 31 Oct 2025 08:25:36 +0000 (09:25 +0100)] 
chg: dev: Don't retain the default configuration tree

The built-in configuration is actually used in two cases: first, when the server is loaded (or reloaded), and second when `rndc showconf -builtin` is called.

Considering the parsing of the builtin configuration is quick and does not occur during exclusive mode, but the configuration tree takes considerable memory space, the built-in configuration is no longer kept in memory once it has been used; instead it is re-parsed on demand.

Merge branch 'colin/not-persist-builtin-config' into 'main'

See merge request isc-projects/bind9!11187

7 months agodon't retain the default configuration
Colin Vidal [Thu, 30 Oct 2025 22:18:54 +0000 (23:18 +0100)] 
don't retain the default configuration

The built-in configuration is actually used in two cases: first, when
the server is loaded (or reloaded), and second when
'rndc showconf -builtin' is called.

Considering the parsing of the builtin configuration is quick and does
not occur during exclusive mode, but the configuration tree takes
considerable memory space, the built-in configuration is no longer kept
in memory once it has been used; instead it is re-parsed on demand.

7 months agofix: dev: Save userconfig as text instead of a cfg_obj tree
Evan Hunt [Thu, 30 Oct 2025 23:31:50 +0000 (23:31 +0000)] 
fix: dev: Save userconfig as text instead of a cfg_obj tree

Once the user configuration has been merged into the effective configuration, it no longer needs to be accessed as a configuration tree, but we still want to be able to show it with `rndc showconf -user`.

Because the recursive strucure of `cfg_obj` objects is fairly large, the canonical text form is a fraction of the size of the configuration tree, so we now save it in that form instead.

Merge branch 'each-userconfig-text' into 'main'

See merge request isc-projects/bind9!11185

7 months agosave userconfig as text instead of a cfg_obj tree
Evan Hunt [Thu, 30 Oct 2025 20:01:44 +0000 (13:01 -0700)] 
save userconfig as text instead of a cfg_obj tree

once the user configuration has been merged into the effective
configuration, it no longer needs to be accessed as a configuration
tree, but we still want to be able to show it with 'rndc showconf -user'.

because the recursive strucure of cfg_obj objects is fairly large, the
canonical text form is a fraction of the size of the configuration
tree, so we now save it in that form instead.

7 months agofix: dev: Reduce the size of cfg_obj_t
Evan Hunt [Thu, 30 Oct 2025 22:54:49 +0000 (22:54 +0000)] 
fix: dev: Reduce the size of cfg_obj_t

Instead of having `isc_sockaddr`, `isc_netaddr`, and `isccfg_duration` members in the `cfg_obj->value`
union, we now just keep pointers to them, and allocate memory when parsing these types. This reduces the
size of `cfg_obj_t` from 112 bytes to 72.

Merge branch 'each-refactor-cfg-obj' into 'main'

See merge request isc-projects/bind9!11186

7 months agofurther shrink cfg_obj_t by using a pointer for duration
Evan Hunt [Thu, 30 Oct 2025 21:07:44 +0000 (14:07 -0700)] 
further shrink cfg_obj_t by using a pointer for duration

not storing the isccfg_duration object inside cfg_obj reduces
its size from 80 to 72 bytes.

7 months agoreduce the size of cfg_obj by using pointers for addresses
Evan Hunt [Thu, 30 Oct 2025 20:40:10 +0000 (13:40 -0700)] 
reduce the size of cfg_obj by using pointers for addresses

instead of having sockaddr and netaddr members in the cfg_obj->value
union, we now just keep pointers, and allocate memory when parsing
these types. this reduces the size of cfg_obj_t from 112 to 80 bytes.

7 months agofix: dev: Remove sun_path field from isc_netaddr
Evan Hunt [Thu, 30 Oct 2025 19:46:50 +0000 (19:46 +0000)] 
fix: dev: Remove sun_path field from isc_netaddr

The `sun_path` field is not used anymore, and consumes over a hundred bytes for every `isc_netaddr_t` object. Remove it.

As `isc_netaddr_t` is used in `cfg_obj_t`, in some huge configuration trees (e.g., a million zones), the gain is almost 1GB of resident memory.

Merge branch 'colin/remove-sun-path' into 'main'

See merge request isc-projects/bind9!11184

7 months agoremove sun_path field from isc_netaddr
Colin Vidal [Thu, 30 Oct 2025 18:37:05 +0000 (19:37 +0100)] 
remove sun_path field from isc_netaddr

The sun_path field is not used anymore, and consumes over a hundred
bytes for every isc_netaddr_t object. Remove it.

As isc_netaddr_t is used in cfg_obj_t, in some huge configuration trees
(e.g., a million zones), the gain is almost 1GB of resident memory.

7 months agonew: usr: New "rndc showconf" command
Colin Vidal [Wed, 29 Oct 2025 22:49:58 +0000 (23:49 +0100)] 
new: usr: New "rndc showconf" command

The new `rndc showconf` command prints the running server configuration. There are three options:
- `rndc showconf -user` displays the user configuration (i.e., the contents of `named.conf`).
- `rndc showconf -builtin` displays the default settings, similar to `named -H`.
- `rndc showconf -effective` displays the effective configuration. This is the merged combination of the `-user` and `-builtin` configurations.

Closes #1075

Merge branch 'colin/effective-config-rndc' into 'main'

See merge request isc-projects/bind9!11123

7 months agoadd system test for rndc showconf
Colin Vidal [Tue, 21 Oct 2025 10:10:34 +0000 (12:10 +0200)] 
add system test for rndc showconf

Add system tests covering the rndc showconf command. It doesn't
attempt to check the whole effective configuration (as any change to the
builtin configuration would break it) but instead ensures that some parts
of the user config are present, as well as some parts of the builtin
config as well.

It also checks that the effective config (in this context of running
named instance) is about static configuration: a newly added zone is not
visible in the effective configuration.

7 months agoimplement "rndc showconf"
Evan Hunt [Fri, 24 Oct 2025 07:42:33 +0000 (00:42 -0700)] 
implement "rndc showconf"

add a new rndc command to dump server configuration info:
- "rndc showconf -user" dumps the contents of named.conf
- "rndc showconf -builtin" dumps named_g_defaltconfig
- "rndc showconf -effective" dumps the effective configuration,
  i.e., the merger of the builtin and the user configurations.

7 months agorefactor newzones configuration
Evan Hunt [Thu, 23 Oct 2025 20:44:56 +0000 (13:44 -0700)] 
refactor newzones configuration

instead of using an opaque ns_cfgctx pointer to store the configuration
data to be used by addzone and modzone, there are now fields in the
dns_view object to store the view configuration and LMDB database
environment. the global configuration is now stored in the named_server
object, along with the ACL context.

7 months agonew: usr: named-checkconf -e prints the effective configuration
Colin Vidal [Wed, 29 Oct 2025 22:49:37 +0000 (23:49 +0100)] 
new: usr: named-checkconf -e prints the effective configuration

The new `named-checkconf -e` option prints the effective server configuration, including all the default settings, that would result from loading the specified configuration file into `named`.

Closes #2798

Merge branch 'colin/effective-config-checkconf' into 'main'

See merge request isc-projects/bind9!11122

7 months agoadd system test for named-checkconf -e
Colin Vidal [Tue, 21 Oct 2025 09:53:56 +0000 (11:53 +0200)] 
add system test for named-checkconf -e

Add a system test checking the command line switch -e of
named-checkconf. The test doesn't care about the whole output of the
effective configuration (in particular to avoid breaking the test for
each default statement that would change) but instead just ensure the
effective configuration is actually returned by checking the presence of
the _bind chaos builtin view as well a user provided view and option
change.

7 months agonamed-checkconf -e prints effective config
Colin Vidal [Tue, 21 Oct 2025 09:53:33 +0000 (11:53 +0200)] 
named-checkconf -e prints effective config

New command line switch `-e` introduced to `named-checkconf`. It acts
like `-p` but instead it print the effective configuration rather than
the user configuration.

7 months agochg: dev: Load the effective configuration
Colin Vidal [Wed, 29 Oct 2025 22:48:38 +0000 (23:48 +0100)] 
chg: dev: Load the effective configuration

The configuration mechanism for `named` has been changed: instead of loading the user configuration from `named.conf` and then, statement-by-statement, picking values from there or from the built-in default configuration, we now merge the user configuration and the default configuration together, then pass the resulting "effective configuration" to `apply_configuration()`.

The new `cfg_effective_config()` function takes a user configuration tree and the built-in default configuration tree, and returns a new effective configuration tree. It works by cloning the user configuration (see !11124) into the effective tree, then walking through the clauses defined in it. If a clause is not in the user config but is present in the defaults, the default version is cloned and attached to the effective tree. If a clause is in both trees, then depending on the statement semantics, either the user configuration overrides the default, or the two are merged. Because these semantics are now handled before `apply_configuration()` runs, that function has been substantially simplified.

Future MRs will enable the effective configuration to be printed, either by `rndc` (!11123) or `named-checkconf` (!11122). The default configuration has been moved to an include file which is accessible to both `named` and `named-checkconf`.

Merge branch 'colin/effective-config-internal' into 'main'

See merge request isc-projects/bind9!11121

7 months agoparser: add VALID_CFGOBJ macro
Colin Vidal [Tue, 28 Oct 2025 18:04:54 +0000 (19:04 +0100)] 
parser: add VALID_CFGOBJ macro

In order to harden `cfg_obj_t` usage now the configuration tree is
manipulated in various ways (cloned, merged, etc.), this introduce the
VALID_CFGOBJ macro to check the validity of a `cfg_obj_t` node.

7 months agofix delv when using the builtin trust-anchors
Colin Vidal [Mon, 13 Oct 2025 16:35:52 +0000 (18:35 +0200)] 
fix delv when using the builtin trust-anchors

Since the builtin trust-anchors are now called `builtin-trust-anchors`,
delv needs specific handling in order to be able to parse those when
they are used.

Before, delv was simply parsing a single clause (either in the case of
an overriden trust-anchors value from bindkeys file or by simply reading
the builtin value). But since the name changed, the same code can't be
shared and the builtin version is expected to be in a map.

7 months agonamed -V doesn't need to parse default options
Evan Hunt [Sat, 25 Oct 2025 07:20:58 +0000 (00:20 -0700)] 
named -V doesn't need to parse default options

instead of parsing the default configuration to extract the
geoip-directory value, we can just construct the value the same way
it's done for the defaults.

7 months agointroduce default config builtin-root-anchors
Colin Vidal [Mon, 13 Oct 2025 14:00:17 +0000 (16:00 +0200)] 
introduce default config builtin-root-anchors

Since the effective configuration tree is a "merged" configuration tree
from the user and the default configurations, the effective configuration
provides a unique configuration tree used by apply_confiuration() to
configure the server.

However, there is one specific case where the configuration code needs
to differentiate whether the configuration originally came from the
default or the user configuration: the trust-anchors. This is because
the default trust-anchors _have_ to be those for the root zone, and the
one provided by the user can be for any zone. A check enforces this.

In order to keep this difference visible from the configuration code,
with a unique configuration tree, we now introduce a default-only
`builtin-trust-anchors` statement which holds the builtin root
trust-anchors. It can't be used from the user configuration (this would
raise an error), hence it is not documented.

7 months agoenable effective configuration
Colin Vidal [Thu, 16 Oct 2025 15:25:14 +0000 (17:25 +0200)] 
enable effective configuration

The effective configuration now contains the actual named configuration
as a unified user/global single tree instance.  We now provide this to
apply_configuration() instead of the user configuration.

7 months agofix serve-stale system test after moving defconfig
Colin Vidal [Thu, 16 Oct 2025 15:15:50 +0000 (17:15 +0200)] 
fix serve-stale system test after moving defconfig

The serve-stale system test relies on sed accessing the source
file that hard-codes the default configuration. Since it moved from
bin/named/config.c into bin/include/defaultconfig.h, the test needs
the path updated.

7 months agoeffective config: specific check-names case
Colin Vidal [Thu, 16 Oct 2025 15:14:14 +0000 (17:14 +0200)] 
effective config: specific check-names case

There are multiple check-names options provided in the default
configuration, and they must "complete" those provided by the user.
This is now handled when building the effective tree.

7 months agoeffective config: specific prefetch/trigger case
Colin Vidal [Thu, 16 Oct 2025 15:00:43 +0000 (17:00 +0200)] 
effective config: specific prefetch/trigger case

The prefetch statement can be overriden by the user, but the user might
specify the prefetch without the trigger value, which needs to be
pulled from the default configuration. Handle this case by directly
getting the default value if needed from the default configuration when
building the effective configuration tree.

Also take care of keeping the values inside their bounds, and simplify
the server configuration code which then just have to read effective
configuration values.

7 months agoeffective config: specific dnssec-policy case
Colin Vidal [Thu, 16 Oct 2025 14:50:30 +0000 (16:50 +0200)] 
effective config: specific dnssec-policy case

Default dnssec-policies are not overridden by user-provided ones. Add
this specific case to make sure those are kept, and also ensure that the
default dnssec-policy is always in the first position (which is an
implicit requirement in the existing implementation).

Also simplify the server configuration code, as it only needs to build
the list of dnssec-policy based on the effective config list.

7 months agoeffective config: specific view cases
Colin Vidal [Thu, 16 Oct 2025 14:33:51 +0000 (16:33 +0200)] 
effective config: specific view cases

User specified views don't override default views. In particular, the
_bind/CH view is still active. However, the order is important: if the
user defines a foo/CH view, it must be able to override _bind/CH by
matching clients first (this is how the view is documented).

The server configuration code is now simpler; it only has to build the
views based on the effective view list, and only creates the _default
view if there are no explicit views created by the user.

7 months agoeffective config: specific options/acl cases
Colin Vidal [Thu, 16 Oct 2025 14:26:06 +0000 (16:26 +0200)] 
effective config: specific options/acl cases

Implement the specific rules of ACL inheritance when buiding the
effective configuration. As those rules are directly implemented in the
configuration tree, they are removed from `apply_configuation`.

7 months agoadd cfg_effective_config() API
Colin Vidal [Thu, 16 Oct 2025 13:48:05 +0000 (15:48 +0200)] 
add cfg_effective_config() API

Add the entry point of the logic to merge the user and the default
configuration, called cfg_effective_config(). This function takes a user
configuration and a default configuration. It internally clones the user
configuration tree, then walks through the clauses recursively applying
default values if they are missing.

The newly built configuration tree, called the effective configuration
tree, is then returned.

Currently this is just the basic mechanism which is implemented (i.e.
enable to walk from clause to clause, goes into a nested clause, and so
on). The next commits will introduce the implementation of
clause-specific merge functions in order to preserve the existing
named.conf semantics.

7 months agoadd an optional merge method on cfg_clausedef_t
Colin Vidal [Thu, 16 Oct 2025 13:30:23 +0000 (15:30 +0200)] 
add an optional merge method on cfg_clausedef_t

In order to handle specific cases when merging configurations (i.e.
some specific clauses which require specific handling, not just
overriding values for instance), the cfg_clausedef_t includes an
optional merge method.

The merge function is NULL by default. If it is defined for a given
clause, and this clause is defined in both the user and default
configurations, the merge function is then called with both the user and
default clause instances. It's up the the implementation of that function
do to anything needed to keep the correct named.conf semantic.

7 months agoadd helper API calls to manipulate maps and lists
Colin Vidal [Thu, 16 Oct 2025 12:54:24 +0000 (14:54 +0200)] 
add helper API calls to manipulate maps and lists

cfg_map_addclone() is a variant of cfg_map_add which internally clones
an object and adds it to a map. It ensures that the object is an
implicit list if the map clause has the CFG_CLAUSEFLAG_MULTI set

cfg_list_addclone() clones a list (internally cloning each individual
element) and appends or preprends it to an existing target list.

Both of these will be needed to merge the default configuration
with the user configuration.

7 months agoparser firstclause/nextclause API changes
Colin Vidal [Thu, 16 Oct 2025 12:38:48 +0000 (14:38 +0200)] 
parser firstclause/nextclause API changes

In order to make upcoming configuration tree changes easier, the
cfg_map_firstclause() and _nextclause() functions have been changed
to return the clause itself rather than only the clause name.

7 months agomove default configuration to common bin/include folder
Colin Vidal [Thu, 16 Oct 2025 12:11:37 +0000 (14:11 +0200)] 
move default configuration to common bin/include folder

Two programs need to be able to provide the effective configuration:
named (through a future rndc command) and named-checkconf (though a
future command line switch). In order to calculate the effective
configuration from named-checkconf, the default configuration
needs to be accessible.

The default configuration has now been moved from bin/named/config.c
into a common include directory for binaries: bin/include/defaultconfig.h.

7 months agofix: nil: set cfgmaps correctly alessio/checkpoint-pre-effective-config
Evan Hunt [Wed, 29 Oct 2025 20:24:56 +0000 (20:24 +0000)] 
fix: nil: set cfgmaps correctly

A typo in MR !11165 caused `cfgmaps` to be set with only the top-level
configuration, not the view configuration.

Merge branch 'each-fix-cfgmaps' into 'main'

See merge request isc-projects/bind9!11173

7 months agoset cfgmaps correctly
Evan Hunt [Wed, 29 Oct 2025 19:45:31 +0000 (12:45 -0700)] 
set cfgmaps correctly

a typo in MR !11165 caused cfgmaps to be set with only the top-level
configuration, not the view configuration.

7 months agofix: dev: fix configuration bugs involving global defaults
Evan Hunt [Wed, 29 Oct 2025 18:28:45 +0000 (18:28 +0000)] 
fix: dev: fix configuration bugs involving global defaults

The configuration code for the `max-cache-size`, `dnssec-validation`, and `response-padding` options were unnecessarily complicated, and in the case of `max-cache-size`, buggy. These have been fixed. The `optionmaps` variable in `configure_view()` is no longer needed and has been removed.

Merge branch 'each-cleanup-defaultconfig' into 'main'

See merge request isc-projects/bind9!11165

7 months agofix "response-padding" configuration and remove optionmaps
Evan Hunt [Wed, 29 Oct 2025 01:45:25 +0000 (18:45 -0700)] 
fix "response-padding" configuration and remove optionmaps

Add a default "response-padding" option in the global defaults,
to disable the option, and simplify the configuration code so that
looks at the global defaults if the option is not set in named.conf.

This enables us to remove the 'optionmaps' variable in configure_view(),
which was used for options that only look in named.conf.

7 months agosimplify "dnssec-validation" configuration
Evan Hunt [Wed, 29 Oct 2025 01:34:55 +0000 (18:34 -0700)] 
simplify "dnssec-validation" configuration

In the past, "dnssec-validation" was not looked up in the global
defaults unless "dnssec-enable" was true. "dnssec-enable" has been
obsolete for several years, but dnssec-validation was still being
configured in two steps.  This commit removes the vestigial bits of
the old logic.

7 months agofix a "max-cache-size" configuration bug
Evan Hunt [Wed, 29 Oct 2025 01:28:35 +0000 (18:28 -0700)] 
fix a "max-cache-size" configuration bug

"max-cache-size default;" is allowed, according to the documentation
and the parser, but when it's configured, named crashes due to an
INSIST that the only legal string value is "unlimited". this has
been fied.

the configuration has also been simplified. previously, we checked for
max-cache-size in view and options, then determined whether to look in
the global default options based on whether the view had recursion set.
the default value set there was only applicable to views with recursion.
now, the default is an explicit "default", which affects views with
and without recursion in different ways.

the cfg type for "max-cache-size" has been changed from
cfg_type_sizeorpercent to cfg_type_maxcachesize.

7 months agochg: test: Use isctest.asyncserver in the "statistics" test
Štěpán Balážik [Wed, 29 Oct 2025 17:45:14 +0000 (17:45 +0000)] 
chg: test: Use isctest.asyncserver in the "statistics" test

Reimplement the custom server using the asyncserver Python module.

Behavior change: The new server doesn't copy CD and DO flags and a client cookie to responses.

Merge branch 'stepan/statistics-asyncserver' into 'main'

See merge request isc-projects/bind9!10928

7 months agoUse isctest.asyncserver in the "statistics" test
Štěpán Balážik [Tue, 2 Sep 2025 10:39:33 +0000 (12:39 +0200)] 
Use isctest.asyncserver in the "statistics" test

Reimplement the custom server using the asyncserver Python module.

Behavior change: The new server doesn't copy CD and DO flags and a
client cookie to responses.

7 months agoAdd a response handler matching on specific QNAMEs
Michał Kępień [Thu, 18 Sep 2025 08:13:13 +0000 (10:13 +0200)] 
Add a response handler matching on specific QNAMEs

Add a new ResponseHandler subclass, QnameHandler, which enables
conveniently matching specific QNAMEs (without also matching their
subdomains like DomainHandler does).

7 months agoAllow users of AsyncDnsServer to set a default RCODE
Štěpán Balážik [Tue, 2 Sep 2025 10:35:53 +0000 (12:35 +0200)] 
Allow users of AsyncDnsServer to set a default RCODE

This is mostly for cases where no zone is set up and all response stubs
come to response handler with REFUSED as RCODE.

This commit allows to override the RCODE before QueryContext is passed
to response handlers.

7 months agochg: test: Use isctest.asyncserver in the "cookie" test
Štěpán Balážik [Wed, 29 Oct 2025 16:06:26 +0000 (16:06 +0000)] 
chg: test: Use isctest.asyncserver in the "cookie" test

Replace the custom DNS servers in the "cookie" system test with new code
based on the isctest.asyncserver module. The convoluted test logic is
split into multiple response handlers which are shared between the two
servers.

Behavior change: returned SOA records have the zone name set properly.

Merge branch 'stepan/cookie-asyncserver' into 'main'

See merge request isc-projects/bind9!10691

7 months agoUse isctest.asyncserver in the "cookie" test
Štěpán Balážik [Fri, 4 Jul 2025 08:45:22 +0000 (10:45 +0200)] 
Use isctest.asyncserver in the "cookie" test

Replace the custom DNS servers in the "cookie" system test with new code
based on the isctest.asyncserver module. The convoluted test logic is
split into multiple response handlers which are shared between the two
servers.

Behavior change: returned SOA records have the zone name set properly.

7 months agochg: test: Use isctest.asyncserver in the "rpzrecurse" test
Štěpán Balážik [Wed, 29 Oct 2025 14:45:35 +0000 (14:45 +0000)] 
chg: test: Use isctest.asyncserver in the "rpzrecurse" test

Replace the custom server with new implementation using the
AsyncDnsServer class.

Behavior changes:
- DNS cookie is not copied to the responses.
- CD, DO flags aren't set on responses.

Merge branch 'stepan/rpzrecurse-asyncserver' into 'main'

See merge request isc-projects/bind9!10916

7 months agoUse isctest.asyncserver in the "rpzrecurse" test
Štěpán Balážik [Sat, 30 Aug 2025 15:07:23 +0000 (17:07 +0200)] 
Use isctest.asyncserver in the "rpzrecurse" test

Replace the custom server with new implementation using the
AsyncDnsServer class.

Behavior changes:
- DNS cookie is not copied to the responses.
- CD, DO flags aren't set on responses.

7 months agochg: test: Use isctest.asyncserver in the "dnssec" test
Štěpán Balážik [Wed, 29 Oct 2025 13:56:15 +0000 (13:56 +0000)] 
chg: test: Use isctest.asyncserver in the "dnssec" test

Reimplement the custom server using isctest.asyncserver. Factor most of
the logic out of the server code to two (identical) zones and only
implement the non-standard behavior.

Behavior changes:
- RRSIG Expiration and Inception is now static and covering the whole
  timeline instead of being calculated everytime.
- NXDOMAIN is returned where suitable by standard.
- Returned SOA records have properly set zone names.

Merge branch 'stepan/dnssec-asyncserver' into 'main'

See merge request isc-projects/bind9!10906

7 months agoUse isctest.asyncserver in the "dnssec" test
Štěpán Balážik [Wed, 27 Aug 2025 18:50:32 +0000 (20:50 +0200)] 
Use isctest.asyncserver in the "dnssec" test

Reimplement the custom server using isctest.asyncserver. Factor most of
the logic out of the server code to two (identical) zones and only
implement the non-standard behavior.

Behavior changes:
- RRSIG Expiration and Inception is now static and covering the whole
  timeline instead of being calculated everytime.
- NXDOMAIN is returned where suitable by standard.
- Returned SOA records have properly set zone names.

7 months agofix: usr: Fix shutdown INSIST in dns_dispatchmgr_getblackhole
Mark Andrews [Mon, 27 Oct 2025 22:37:00 +0000 (09:37 +1100)] 
fix: usr: Fix shutdown INSIST in dns_dispatchmgr_getblackhole

Previously, `named` could trigger an assertion in `dns_dispatchmgr_getblackhole`
while shutting down. This has been fixed.

Closes #5525

Merge branch '5525-attach-to-dispatchmgr-to-fctx' into 'main'

See merge request isc-projects/bind9!11131

7 months agoFix "shutdown system test crashed in dns_dispatchmgr_getblackhole"
Mark Andrews [Wed, 22 Oct 2025 05:53:46 +0000 (16:53 +1100)] 
Fix "shutdown system test crashed in dns_dispatchmgr_getblackhole"

While shutting down view->dispatchmgr is no longer valid.  Attach
to it and when creates a fetch context and use that pointer instead
of view->dispatchmgr.  Use dns_view_getdispatchmgr to do the attaching
as view->dispatchmgr is it managed using rcu.

7 months agonew: dev: introduce cfg_obj_clone to clone a config tree
Colin Vidal [Mon, 27 Oct 2025 21:15:39 +0000 (22:15 +0100)] 
new: dev: introduce cfg_obj_clone to clone a config tree

Introduce `cfg_obj_clone` which takes a `cfg_obj_t` node and clones it.
it allocates a new node, copies its scalar values and recursively
allocates child nodes, copying their scalar values as well and so on.

Internally, a new method `cfg_copyfunc_t` copy is added in `cfg_rep_t`,
which enables implementing a copy function specific for each
representation type a node can hold.

This is pre-require work for MR !11121 !11122 !11123

Merge branch 'colin/effective-config-clone' into 'main'

See merge request isc-projects/bind9!11124

7 months agoadd unit test for cfg_obj_clone
Colin Vidal [Tue, 30 Sep 2025 14:09:03 +0000 (16:09 +0200)] 
add unit test for cfg_obj_clone

Add a unit test for `cfg_obj_clone` to verify that the cloned tree
indeed has independent child nodes. The test also verifies that the
clone is semantically correct by comparing a text dump of the original
tree and the cloned one.

7 months agointroduce cfg_obj_clone to clone a config tree
Colin Vidal [Tue, 30 Sep 2025 10:41:32 +0000 (12:41 +0200)] 
introduce cfg_obj_clone to clone a config tree

Introduce `cfg_obj_clone` which takes a `cfg_obj_t` node and clones it.
it allocates a new node, copies its scalar values and recursively
allocates child nodes, copying their scalar values as well and so on.

Internally, a new method `cfg_copyfunc_t` copy is added in `cfg_rep_t`,
which enables implementing a copy function specific for each
representation type a node can hold.

7 months agofix: nil: Remove unnecessary NULL checks causing Coverity warnings
Mark Andrews [Mon, 27 Oct 2025 20:05:27 +0000 (07:05 +1100)] 
fix: nil: Remove unnecessary NULL checks causing Coverity warnings

In cfg_parse_buffer and cfg_parse_file 'pctx' was being checked
for being non-NULL when it was guaranteed to be non-NULL.  This
raised Coverity issues ID 637688 and ID 637689.

Closes #5599

Merge branch '5599-remove-unnecessary-null-checks' into 'main'

See merge request isc-projects/bind9!11154

7 months agoRemove unnecessary NULL checks in parser.c
Mark Andrews [Sun, 26 Oct 2025 23:35:35 +0000 (10:35 +1100)] 
Remove unnecessary NULL checks in parser.c

In cfg_parse_buffer and cfg_parse_file 'pctx' was being checked
for being non-NULL when it was guarenteed to be non-NULL.  This
raised Coverity issues ID 637688 and ID 637689.

7 months agofix: test: Fix "hooks/conf/good-viewzonelevel.conf.j2 has hard coded library extension"
Mark Andrews [Mon, 27 Oct 2025 19:15:32 +0000 (06:15 +1100)] 
fix: test:  Fix "hooks/conf/good-viewzonelevel.conf.j2 has hard coded library extension"

Use @DYLIB@ instead of hard coded extension "so".

Closes #5600

Merge branch '5600-fix-hooks-conf-good-viewzonelevel-conf-j2' into 'main'

See merge request isc-projects/bind9!11156

7 months agoFix "good-viewzonelevel.conf.j2 has hard coded library extension"
Mark Andrews [Mon, 27 Oct 2025 00:15:18 +0000 (11:15 +1100)] 
Fix "good-viewzonelevel.conf.j2 has hard coded library extension"

Use @DYLIB@ instead of hard coded extension "so".

7 months agonew: ci: Add tarball publication process to pipeline
Andoni Duarte [Mon, 27 Oct 2025 15:51:58 +0000 (15:51 +0000)] 
new: ci: Add tarball publication process to pipeline

Tarball uploading steps are to be included in the pipeline.

They are manual jobs that:

1. uploads a release tarball prepared by the "sign" job.
2. publish a previously staged release to a destination.
3. publishes a previously staged release to a well-known URL.

A template has been included since all three follow the same pattern.
Besides, rules commonly used by tag pipeline jobs.

Merge branch 'andoni/ci-release-process' into 'main'

See merge request isc-projects/bind9!11158

7 months agoDeduplicate triggering rules for tag pipeline jobs
Michał Kępień [Mon, 27 Oct 2025 04:15:09 +0000 (05:15 +0100)] 
Deduplicate triggering rules for tag pipeline jobs

Define and use more YAML anchors for triggering rules commonly used by
tag pipeline jobs.  This builds on top of the work done in commit
675d9c74251fee8ec034e87bdd43e7da97119a5d, improving readability and
reuse.

7 months agoAdd the "publish" job
Andoni Duarte Pintado [Thu, 23 Oct 2025 13:13:00 +0000 (15:13 +0200)] 
Add the "publish" job

Add a new SSH-confirmed GitLab CI job that publishes a previously staged
release to a well-known URL.  The details of what specifically this
entails are controlled by the staging environment.

7 months agoAdd the "publish-private" job
Andoni Duarte Pintado [Fri, 17 Oct 2025 07:52:45 +0000 (09:52 +0200)] 
Add the "publish-private" job

Add a new SSH-confirmed GitLab CI job that publishes a previously staged
release to a destination that is not a well-known URL.  The details of
what specifically this entails are controlled by the staging
environment.

7 months agoAdd the "staging" job
Andoni Duarte Pintado [Tue, 16 Sep 2025 15:10:44 +0000 (17:10 +0200)] 
Add the "staging" job

Add a new SSH-confirmed GitLab CI job that uploads a release tarball
prepared by the "sign" job to a staging environment specified using CI
variables.

7 months agoRework the "sign" job
Michał Kępień [Wed, 22 Oct 2025 07:45:29 +0000 (09:45 +0200)] 
Rework the "sign" job

Adapt the "sign" job to use the YAML template for SSH-confirmed jobs.
Make the signing process user-agnostic.

7 months agoAdd a template for SSH-confirmed jobs
Michał Kępień [Wed, 22 Oct 2025 07:45:29 +0000 (09:45 +0200)] 
Add a template for SSH-confirmed jobs

Add a YAML template for jobs that require an SSH connection to a
dedicated, locked-down runner for signing off on sensitive operations
(e.g. signing, publishing).

These jobs all follow a similar scheme:

 1. Runner prepares the necessary files in a well-known location (/tmp).
 2. Runner generates a shell script to be run by an authorized user.
 3. Runner sleeps while waiting for a signal that the script was run.
 4. Authorized user logs in to the runner over SSH and runs the script.
 5. Runner collects the relevant files and logs as job artifacts.

One additional complication is that each of the above steps needs to be
carried out under the assumption that GitLab Runner is running under a
different user account than the one used for logging in over SSH,
necessitating careful file permission handling.

Having a YAML template for jobs that need to follow the above scheme
significantly improves readability and reuse as each job only needs to
define (via the "variables" YAML key):

  - SSH_SCRIPT_RUNNER_PRE: the code the runner should execute before an
    authorized user logs in over SSH (typically: setting up files in a
    well-known location),

  - SSH_SCRIPT_CLIENT: contents of the shell script to be run by an
    authorized user,

  - SSH_SCRIPT_RUNNER_POST: the code the runner should execute after an
    authorized user runs the script over SSH (typically: artifact
    collection and cleanup).

7 months agoRevise release directory naming
Michał Kępień [Wed, 22 Oct 2025 07:45:29 +0000 (09:45 +0200)] 
Revise release directory naming

Include the Git tag in the name of the release directory rather than
just the version number.  Revise the script for the "release" job
accordingly.  This enables using the $CI_COMMIT_TAG variable in job
scripts without the need to resort to string manipulation to strip the
leading "v", improving readability.  The only place where string
manipulation is applied to the Git tag is now the "release" job itself,
to verify that the Git tag matches the version number embedded in the
source tarball name.

7 months agofix: test: test-syncplugin.c:plugin_register was broken
Mark Andrews [Mon, 27 Oct 2025 12:46:39 +0000 (23:46 +1100)] 
fix: test: test-syncplugin.c:plugin_register was broken

The variables example2com, example3com, and example4com where not
being initalised on all paths leading to Coverity issues ID 637690,
ID 637691 and ID 637692 being raised.  In addition the tests to free
them were wrong as they depended on the unintialised variables. This
has been fixed.

Closes #5598

Merge branch '5598-properly-determine-if-name-is-dynamic' into 'main'

See merge request isc-projects/bind9!11155

7 months agotest-syncplugin.c:plugin_register was broken
Mark Andrews [Mon, 27 Oct 2025 00:07:35 +0000 (11:07 +1100)] 
test-syncplugin.c:plugin_register was broken

The variables example2com, example3com, and example4com where not
being initalised on all paths leading to Coverity issues ID 637690,
ID 637691 and ID 637692 being raised.  In addition the tests to free
them were wrong as they depended on the unintialised variables. This
has been fixed.

7 months agochg: dev: Stop prettifying JSON statistics
Michał Kępień [Mon, 27 Oct 2025 09:57:58 +0000 (10:57 +0100)] 
chg: dev: Stop prettifying JSON statistics

Passing the JSON_C_TO_STRING_PRETTY flag to
json_object_to_json_string_ext() makes the latter produce prettified
JSON output.  This results in a huge amount of redundant whitespace
being inserted into each HTTP response (whitespace amounts to about 40%
of the entire JSON payload).

The bandwidth cost can be amortized by enabling HTTP compression on the
client side ("Accept-Encoding: deflate"), but that does not affect the
size of data at rest.

Use the JSON_C_TO_STRING_PLAIN flag instead of JSON_C_TO_STRING_PRETTY
to minimize the size of JSON responses sent via the statistics channel.
External tools should be used for prettifying JSON data.

Closes #3304

Merge branch '3304-stop-prettifying-json-statistics' into 'main'

See merge request isc-projects/bind9!10786

7 months agoStop prettifying JSON statistics
Michał Kępień [Mon, 27 Oct 2025 09:56:38 +0000 (10:56 +0100)] 
Stop prettifying JSON statistics

Passing the JSON_C_TO_STRING_PRETTY flag to
json_object_to_json_string_ext() makes the latter produce prettified
JSON output.  This results in a huge amount of redundant whitespace
being inserted into each HTTP response (whitespace amounts to about 40%
of the entire JSON payload).

The bandwidth cost can be amortized by enabling HTTP compression on the
client side ("Accept-Encoding: deflate"), but that does not affect the
size of data at rest.

Use the JSON_C_TO_STRING_PLAIN flag instead of JSON_C_TO_STRING_PRETTY
to minimize the size of JSON responses sent via the statistics channel.
External tools should be used for prettifying JSON data.