diff --git a/doc/configuration.rst b/doc/configuration.rst index f2d0edd64..04b2afea0 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -597,7 +597,7 @@ Catalog zone is handled almost in the same way as a regular zone. It can be configured using all the standard options (but for example DNSSEC signing would be useless), including master/slave configuration and ACLs. Being a catalog zone is indicated by setting the option -:ref:`zone_catalog-template`. The difference is that standard DNS +:ref:`zone_catalog-role`. The difference is that standard DNS queries to a catalog zone are answered with REFUSED as if such a zone wouldn't exist, unless querying over TCP from an address with transfers enabled by ACL. The name of the catalog zone is arbitrary. It's however required to diff --git a/doc/man/knot.conf.5in b/doc/man/knot.conf.5in index 461620037..aa9587305 100644 --- a/doc/man/knot.conf.5in +++ b/doc/man/knot.conf.5in @@ -1348,6 +1348,7 @@ zone: serial\-policy: increment | unixtime | dateserial refresh\-min\-interval: TIME refresh\-max\-interval: TIME + catalog\-role: none | interpret catalog\-template: template_id module: STR/STR ... .ft P @@ -1648,9 +1649,28 @@ Forced minimum zone refresh interval to avoid flooding master. Forced maximum zone refresh interval. .sp \fIDefault:\fP not set +.SS catalog\-role +.sp +Trigger zone catalog feature. Possible values: +.INDENT 0.0 +.IP \(bu 2 +\fBnone\fP – Not a catalog zone. +.IP \(bu 2 +\fBinterpret\fP – A catalog zone which is loaded from a zone file or XFR, +and member zones shall be configured based on its contents. +.UNINDENT +.sp +\fIDefault:\fP none .SS catalog\-template .sp -This zone is a catalog zone. For the catalog\-member zones, the specified configuration template will be applied. +For the catalog\-member zones, the specified configuration template will be applied. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +This option must be set if and only if \fI\%catalog\-role\fP is \fIinterpret\fP\&. +.UNINDENT +.UNINDENT .sp \fIDefault:\fP not set .SS module diff --git a/doc/reference.rst b/doc/reference.rst index f80018d01..19b4d0cef 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -1478,6 +1478,7 @@ Definition of zones served by the server. serial-policy: increment | unixtime | dateserial refresh-min-interval: TIME refresh-max-interval: TIME + catalog-role: none | interpret catalog-template: template_id module: STR/STR ... @@ -1804,12 +1805,28 @@ Forced maximum zone refresh interval. *Default:* not set +.. _zone_catalog-role: + +catalog-role +------------ + +Trigger zone catalog feature. Possible values: + +- ``none`` – Not a catalog zone. +- ``interpret`` – A catalog zone which is loaded from a zone file or XFR, + and member zones shall be configured based on its contents. + +*Default:* none + .. _zone_catalog-template: catalog-template ---------------- -This zone is a catalog zone. For the catalog-member zones, the specified configuration template will be applied. +For the catalog-member zones, the specified configuration template will be applied. + +.. NOTE:: + This option must be set if and only if :ref:`zone_catalog-role` is *interpret*. *Default:* not set diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c index 3f2a03b46..427830df6 100644 --- a/src/knot/conf/schema.c +++ b/src/knot/conf/schema.c @@ -140,6 +140,12 @@ static const knot_lookup_t journal_modes[] = { { 0, NULL } }; +static const knot_lookup_t catalog_roles[] = { + { CATALOG_ROLE_NONE, "none" }, + { CATALOG_ROLE_INTERPRET, "interpret" }, + { 0, NULL } +}; + static const yp_item_t desc_module[] = { { C_ID, YP_TSTR, YP_VNONE, YP_FNONE, { check_module_id } }, { C_FILE, YP_TSTR, YP_VNONE }, @@ -361,6 +367,7 @@ static const yp_item_t desc_policy[] = { { C_REFRESH_MAX_INTERVAL,YP_TINT, YP_VINT = { 2, UINT32_MAX, UINT32_MAX, YP_STIME } }, \ { C_REFRESH_MIN_INTERVAL,YP_TINT, YP_VINT = { 2, UINT32_MAX, 2, YP_STIME } }, \ { C_ADJUST_THR, YP_TINT, YP_VINT = { 1, UINT16_MAX, 1 } }, \ + { C_CATALOG_ROLE, YP_TOPT, YP_VOPT = { catalog_roles, CATALOG_ROLE_NONE }, FLAGS }, \ { C_CATALOG_TPL, YP_TREF, YP_VREF = { C_TPL }, FLAGS, { check_ref } }, \ { C_MODULE, YP_TDATA, YP_VDATA = { 0, NULL, mod_id_to_bin, mod_id_to_txt }, \ YP_FMULTI | FLAGS, { check_modref } }, \ diff --git a/src/knot/conf/schema.h b/src/knot/conf/schema.h index e4ed54358..7767e38bf 100644 --- a/src/knot/conf/schema.h +++ b/src/knot/conf/schema.h @@ -33,6 +33,7 @@ #define C_BLOCK_NOTIFY_XFR "\x1B""block-notify-after-transfer" #define C_CATALOG_DB "\x0A""catalog-db" #define C_CATALOG_DB_MAX_SIZE "\x13""catalog-db-max-size" +#define C_CATALOG_ROLE "\x0C""catalog-role" #define C_CATALOG_TPL "\x10""catalog-template" #define C_CDS_CDNSKEY "\x13""cds-cdnskey-publish" #define C_CHK_INTERVAL "\x0E""check-interval" @@ -189,6 +190,11 @@ enum { ZONEFILE_LOAD_DIFSE = 3, }; +enum { + CATALOG_ROLE_NONE = 0, + CATALOG_ROLE_INTERPRET = 1, +}; + extern const knot_lookup_t acl_actions[]; extern const yp_item_t conf_schema[]; diff --git a/src/knot/conf/tools.c b/src/knot/conf/tools.c index 13bb7dc05..09100c887 100644 --- a/src/knot/conf/tools.c +++ b/src/knot/conf/tools.c @@ -624,6 +624,16 @@ int check_zone( return KNOT_EINVAL; } + conf_val_t catalog_role = conf_zone_get_txn(args->extra->conf, args->extra->txn, + C_CATALOG_ROLE, yp_dname(args->id)); + conf_val_t catalog_tpl = conf_zone_get_txn(args->extra->conf, args->extra->txn, + C_CATALOG_TPL, yp_dname(args->id)); + if ((bool)(conf_opt(&catalog_role) == CATALOG_ROLE_INTERPRET) != + (bool)(catalog_tpl.code == KNOT_EOK)) { + args->err_str = "'catalog-role' must correspond to configured 'catalog-template'"; + return KNOT_EINVAL; + } + return KNOT_EOK; } diff --git a/tests-extra/tools/dnstest/server.py b/tests-extra/tools/dnstest/server.py index 8c6bef729..c11de44a8 100644 --- a/tests-extra/tools/dnstest/server.py +++ b/tests-extra/tools/dnstest/server.py @@ -1465,6 +1465,7 @@ class Knot(Server): s.item_str("dnssec-policy", z.dnssec.shared_policy_with or z.name) if z.catalog: + s.item_str("catalog-role", "interpret") s.item_str("catalog-template", "catemplate") if z.dnssec.validate: