From f449f278dd3c70e479a035f50a9bb817a9b433ba Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 17:24:08 +0200 Subject: Adding upstream version 3.2.6. Signed-off-by: Daniel Baumann --- src/knot/conf/conf.h | 939 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 939 insertions(+) create mode 100644 src/knot/conf/conf.h (limited to 'src/knot/conf/conf.h') diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h new file mode 100644 index 0000000..83dfd1d --- /dev/null +++ b/src/knot/conf/conf.h @@ -0,0 +1,939 @@ +/* Copyright (C) 2022 CZ.NIC, z.s.p.o. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#pragma once + +#include + +#include "knot/conf/base.h" +#include "knot/conf/schema.h" + +/*! Configuration remote getter output. */ +typedef struct { + /*! Target socket address. */ + struct sockaddr_storage addr; + /*! Local outgoing socket address. */ + struct sockaddr_storage via; + /*! TSIG key. */ + knot_tsig_key_t key; + /*! Suppress sending NOTIFY after zone transfer from this master. */ + bool block_notify_after_xfr; + /*! Disable EDNS on XFR queries. */ + bool no_edns; +} conf_remote_t; + +/*! Configuration section iterator. */ +typedef struct { + /*! Item description. */ + const yp_item_t *item; + /*! Namedb iterator. */ + knot_db_iter_t *iter; + /*! Key0 database code. */ + uint8_t key0_code; + // Public items. + /*! Iterator return code. */ + int code; +} conf_iter_t; + +/*! Configuration iterator over mixed references (e.g. remote and remotes). */ +typedef struct { + /*! Configuration context. */ + conf_t *conf; + /*! Mixed references. */ + conf_val_t *mix_id; + /*! Temporary nested references. */ + conf_val_t sub_id; + /*! Current (possibly expanded) reference to use. */ + conf_val_t *id; + /*! Nested references in use indication. */ + bool nested; +} conf_mix_iter_t; + +/*! Configuration module getter output. */ +typedef struct { + /*! Module name. */ + yp_name_t *name; + /*! Module id data. */ + uint8_t *data; + /*! Module id data length. */ + size_t len; +} conf_mod_id_t; + +/*! + * Check if the configuration database exists on the filesystem. + * + * \param[in] db_dir Database path. + * + * \return True if it already exists. + */ + +bool conf_db_exists( + const char *db_dir +); + +/*! + * Gets the configuration item value of the section without identifiers. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * \param[in] key1_name Item name. + * + * \return Item value. + */ +conf_val_t conf_get_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name, + const yp_name_t *key1_name +); +static inline conf_val_t conf_get( + conf_t *conf, + const yp_name_t *key0_name, + const yp_name_t *key1_name) +{ + return conf_get_txn(conf, &conf->read_txn, key0_name, key1_name); +} + +/*! + * Gets the configuration item value of the section with identifiers (raw version). + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * \param[in] key1_name Item name. + * \param[in] id Section identifier (raw value). + * \param[in] id_len Length of the section identifier. + * + * \return Item value. + */ +conf_val_t conf_rawid_get_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name, + const yp_name_t *key1_name, + const uint8_t *id, + size_t id_len +); +static inline conf_val_t conf_rawid_get( + conf_t *conf, + const yp_name_t *key0_name, + const yp_name_t *key1_name, + const uint8_t *id, + size_t id_len) +{ + return conf_rawid_get_txn(conf, &conf->read_txn, key0_name, key1_name, + id, id_len); +} + +/*! + * Gets the configuration item value of the section with identifiers. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * \param[in] key1_name Item name. + * \param[in] id Section identifier (output of a config getter). + * + * \return Item value. + */ +conf_val_t conf_id_get_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name, + const yp_name_t *key1_name, + conf_val_t *id +); +static inline conf_val_t conf_id_get( + conf_t *conf, + const yp_name_t *key0_name, + const yp_name_t *key1_name, + conf_val_t *id) +{ + return conf_id_get_txn(conf, &conf->read_txn, key0_name, key1_name, id); +} + +/*! + * Gets the configuration item value of the module section. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key1_name Item name. + * \param[in] mod_id Module identifier. + * + * \return Item value. + */ +conf_val_t conf_mod_get_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key1_name, + const conf_mod_id_t *mod_id +); +static inline conf_val_t conf_mod_get( + conf_t *conf, + const yp_name_t *key1_name, + const conf_mod_id_t *mod_id) +{ + return conf_mod_get_txn(conf, &conf->read_txn, key1_name, mod_id); +} + +/*! + * Gets the configuration item value of the zone section. + * + * \note A possibly associated template is taken into account. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key1_name Item name. + * \param[in] dname Zone name. + * + * \return Item value. + */ +conf_val_t conf_zone_get_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key1_name, + const knot_dname_t *dname +); +static inline conf_val_t conf_zone_get( + conf_t *conf, + const yp_name_t *key1_name, + const knot_dname_t *dname) +{ + return conf_zone_get_txn(conf, &conf->read_txn, key1_name, dname); +} + +/*! + * Gets the configuration item value of the default template. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key1_name Item name. + * + * \return Item value. + */ +conf_val_t conf_default_get_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key1_name +); +static inline conf_val_t conf_default_get( + conf_t *conf, + const yp_name_t *key1_name) +{ + return conf_default_get_txn(conf, &conf->read_txn, key1_name); +} + +/*! + * Checks the configuration section for the identifier (raw version). + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * \param[in] id Section identifier (raw value). + * \param[in] id_len Length of the section identifier. + * + * \return True if exists. + */ +bool conf_rawid_exists_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name, + const uint8_t *id, + size_t id_len +); +static inline bool conf_rawid_exists( + conf_t *conf, + const yp_name_t *key0_name, + const uint8_t *id, + size_t id_len) +{ + return conf_rawid_exists_txn(conf, &conf->read_txn, key0_name, id, id_len); +} + +/*! + * Checks the configuration section for the identifier. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * \param[in] id Section identifier (output of a config getter). + * + * \return True if exists. + */ +bool conf_id_exists_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name, + conf_val_t *id +); +static inline bool conf_id_exists( + conf_t *conf, + const yp_name_t *key0_name, + conf_val_t *id) +{ + return conf_id_exists_txn(conf, &conf->read_txn, key0_name, id); +} + +/*! + * Gets the number of section identifiers. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * + * \return Number of identifiers. + */ +size_t conf_id_count_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name +); +static inline size_t conf_id_count( + conf_t *conf, + const yp_name_t *key0_name) +{ + return conf_id_count_txn(conf, &conf->read_txn, key0_name); +} + +/*! + * Gets a configuration section iterator. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] key0_name Section name. + * + * \return Section iterator. + */ +conf_iter_t conf_iter_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0_name +); +static inline conf_iter_t conf_iter( + conf_t *conf, + const yp_name_t *key0_name) +{ + return conf_iter_txn(conf, &conf->read_txn, key0_name); +} + +/*! + * Moves the configuration section iterator to the next identifier. + * + * \param[in] conf Configuration. + * \param[in] iter Configuration iterator. + */ +void conf_iter_next( + conf_t *conf, + conf_iter_t *iter +); + +/*! + * Gets the current iterator value (identifier). + * + * \param[in] conf Configuration. + * \param[in] iter Configuration iterator. + * + * \return Section identifier. + */ +conf_val_t conf_iter_id( + conf_t *conf, + conf_iter_t *iter +); + +/*! + * Deletes the section iterator. + * + * This function should be called when the iterating is early interrupted, + * otherwise this is done automatically at KNOT_EOF. + * + * \param[in] conf Configuration. + * \param[in] iter Configuration iterator. + */ +void conf_iter_finish( + conf_t *conf, + conf_iter_t *iter +); + +/*! + * Prepares the value for the direct access. + * + * The following access is through val->len and val->data. + * + * \param[in] val Item value. + */ +void conf_val( + conf_val_t *val +); + +/*! + * Moves to the next value of a multi-valued item. + * + * \param[in] val Item value. + */ +void conf_val_next( + conf_val_t *val +); + +/*! + * Resets to the first value of a multi-valued item. + * + * \param[in] val Item value. + */ +void conf_val_reset( + conf_val_t *val +); + +/*! + * Gets the number of values if multivalued item. + * + * \param[in] val Item value. + * + * \return Number of values. + */ +size_t conf_val_count( + conf_val_t *val +); + +/*! + * Checks if two item values are equal. + * + * \param[in] val1 First item value. + * \param[in] val2 Second item value. + * + * \return true if equal, false if not. + */ +bool conf_val_equal( + conf_val_t *val1, + conf_val_t *val2 +); + +/*! + * Initializes a mixed reference iterator. + * + * The following access is through iter->id. + * + * \param[in] conf Configuration. + * \param[in] mix_id First mixed reference. + * \param[out] iter Iterator to be initialized. + */ +void conf_mix_iter_init( + conf_t *conf, + conf_val_t *mix_id, + conf_mix_iter_t *iter +); + +/*! + * Increments the mixed iterator. + * + * \param[in] iter Mixed reference iterator. + */ +void conf_mix_iter_next( + conf_mix_iter_t *iter +); + +/*! + * Gets the numeric value of the item. + * + * \param[in] val Item value. + * + * \return Integer. + */ +int64_t conf_int( + conf_val_t *val +); + +/*! + * Gets the boolean value of the item. + * + * \param[in] val Item value. + * + * \return Boolean. + */ +bool conf_bool( + conf_val_t *val +); + +/*! + * Gets the option value of the item. + * + * \param[in] val Item value. + * + * \return Option id. + */ +unsigned conf_opt( + conf_val_t *val +); + +/*! + * Gets the string value of the item. + * + * \param[in] val Item value. + * + * \return String pointer. + */ +const char* conf_str( + conf_val_t *val +); + +/*! + * Gets the dname value of the item. + * + * \param[in] val Item value. + * + * \return Dname pointer. + */ +const knot_dname_t* conf_dname( + conf_val_t *val +); + +/*! + * Gets the length-prefixed data value of the item. + * + * \param[in] val Item value. + * \param[out] len Output length. + * + * \return Data pointer. + */ +const uint8_t* conf_bin( + conf_val_t *val, + size_t *len +); + +/*! + * Gets the generic data value of the item. + * + * \param[in] val Item value. + * \param[out] len Output length. + * + * \return Data pointer. + */ +const uint8_t* conf_data( + conf_val_t *val, + size_t *len +); + +/*! + * Gets the socket address value of the item. + * + * \param[in] val Item value. + * \param[in] sock_base_dir Path prefix for a relative UNIX socket location. + * + * \return Socket address. + */ +struct sockaddr_storage conf_addr( + conf_val_t *val, + const char *sock_base_dir +); + +/*! + * Checks the configured address if equal to given one (except port). + * + * \param[in] match Configured address. + * \param[in] addr Address to check. + * + * \return True if matches. + */ +bool conf_addr_match( + conf_val_t *match, + const struct sockaddr_storage *addr +); + +/*! + * Gets the socket address range value of the item. + * + * \param[in] val Item value. + * \param[out] max_ss Upper address bound or AF_UNSPEC family if not specified. + * \param[out] prefix_len Network subnet prefix length or -1 if not specified. + * + * \return Socket address. + */ +struct sockaddr_storage conf_addr_range( + conf_val_t *val, + struct sockaddr_storage *max_ss, + int *prefix_len +); + +/*! + * Checks the address if matches given address range/network block. + * + * \param[in] range Address range/network block. + * \param[in] addr Address to check. + * + * \return True if matches. + */ +bool conf_addr_range_match( + conf_val_t *range, + const struct sockaddr_storage *addr +); + +/*! + * Gets the absolute string value of the item. + * + * \note The result must be explicitly deallocated. + * + * \param[in] val Item value. + * \param[in] base_dir Path prefix for a relative string. + * + * \return Absolute path string pointer. + */ +char* conf_abs_path( + conf_val_t *val, + const char *base_dir +); + +/*! + * Ensures empty 'default' identifier value. + * + * \param[in] val Item value. + * + * \return Empty item value. + */ +static inline void conf_id_fix_default(conf_val_t *val) +{ + if (val->code != KNOT_EOK) { + conf_val_t empty = { + .item = val->item, + .code = KNOT_EOK + }; + + *val = empty; + } +} + +/*! + * Gets the module identifier value of the item. + * + * \param[in] val Item value. + * + * \return Module identifier. + */ +conf_mod_id_t* conf_mod_id( + conf_val_t *val +); + +/*! + * Destroys the module identifier. + * + * \param[in] mod_id Module identifier. + */ +void conf_free_mod_id( + conf_mod_id_t *mod_id +); + +/*! + * Gets the absolute zone file path. + * + * \note The result must be explicitly deallocated. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] zone Zone name. + * + * \return Absolute zone file path string pointer. + */ +char* conf_zonefile_txn( + conf_t *conf, + knot_db_txn_t *txn, + const knot_dname_t *zone +); +static inline char* conf_zonefile( + conf_t *conf, + const knot_dname_t *zone) +{ + return conf_zonefile_txn(conf, &conf->read_txn, zone); +} + +/*! + * Gets the absolute directory path for a database. + * + * e.g. Journal, KASP db, Timers + * + * \note The result must be explicitly deallocated. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] db_type Database name. + * + * \return Absolute database path string pointer. + */ +char* conf_db_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *db_type +); +static inline char* conf_db( + conf_t *conf, + const yp_name_t *db_type) +{ + return conf_db_txn(conf, &conf->read_txn, db_type); +} + +/*! + * Gets the absolute directory path for a TLS key/cert file. + * + * \note The result must be explicitly deallocated. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] db_type TLS configuration option. + * + * \return Absolute path string pointer. + */ +char *conf_tls_txn( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *tls_item); +static inline char* conf_tls( + conf_t *conf, + const yp_name_t *tls_item) +{ + return conf_tls_txn(conf, &conf->read_txn, tls_item); +} + +/*! + * Gets database-specific parameter. + * + * \param[in] conf Configuration. + * \param[in] param Parameter name. + * + * \return Item value. + */ +static inline conf_val_t conf_db_param( + conf_t *conf, + const yp_name_t *param) +{ + return conf_get_txn(conf, &conf->read_txn, C_DB, param); +} + +/*! + * Gets the configured setting of the bool option in the specified section. + * + * \param[in] conf Configuration. + * \param[in] section Section name. + * \param[in] param Parameter name. + * + * \return True if enabled, false otherwise. + */ +static inline bool conf_get_bool( + conf_t *conf, + const yp_name_t *section, + const yp_name_t *param) +{ + conf_val_t val = conf_get_txn(conf, &conf->read_txn, section, param); + return conf_bool(&val); +} + +/*! + * Gets the configured setting of the int option in the specified section. + * + * \param[in] conf Configuration. + * \param[in] section Section name. + * \param[in] param Parameter name. + * + * \return Configured integer value. + */ +static inline int64_t conf_get_int( + conf_t *conf, + const yp_name_t *section, + const yp_name_t *param) +{ + conf_val_t val = conf_get_txn(conf, &conf->read_txn, section, param); + return conf_int(&val); +} + +/*! + * Gets the configured number of UDP threads. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * + * \return Number of threads. + */ +size_t conf_udp_threads_txn( + conf_t *conf, + knot_db_txn_t *txn +); +static inline size_t conf_udp_threads( + conf_t *conf) +{ + return conf_udp_threads_txn(conf, &conf->read_txn); +} + +/*! + * Gets the configured number of TCP threads. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * + * \return Number of threads. + */ +size_t conf_tcp_threads_txn( + conf_t *conf, + knot_db_txn_t *txn +); +static inline size_t conf_tcp_threads( + conf_t *conf) +{ + return conf_tcp_threads_txn(conf, &conf->read_txn); +} + +/*! + * Gets the number of used XDP threads. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * + * \return Number of threads. + */ +size_t conf_xdp_threads_txn( + conf_t *conf, + knot_db_txn_t *txn +); +static inline size_t conf_xdp_threads( + conf_t *conf) +{ + return conf_xdp_threads_txn(conf, &conf->read_txn); +} + +/*! + * Gets the configured number of worker threads. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * + * \return Number of threads. + */ +size_t conf_bg_threads_txn( + conf_t *conf, + knot_db_txn_t *txn +); +static inline size_t conf_bg_threads( + conf_t *conf) +{ + return conf_bg_threads_txn(conf, &conf->read_txn); +} + +/*! + * Gets the required LMDB readers limit based on the current configuration. + * + * \note The resulting value is a common limit to journal, kasp, timers, + * and catalog databases. So it's over-estimated for simplicity reasons. + * + * \note This function cannot be used for the configuration database setting :-/ + * + * \param[in] conf Configuration. + * + * \return Number of readers. + */ +static inline size_t conf_lmdb_readers( + conf_t *conf) +{ + if (conf == NULL) { // Return default in tests. + return 126; + } + return conf_udp_threads(conf) + conf_tcp_threads(conf) + + conf_bg_threads(conf) + conf_xdp_threads(conf) + 2; // Main thread, utils. +} + +/*! + * Gets the configured maximum number of TCP clients. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * + * \return Maximum number of TCP clients. + */ +size_t conf_tcp_max_clients_txn( + conf_t *conf, + knot_db_txn_t *txn +); +static inline size_t conf_tcp_max_clients( + conf_t *conf) +{ + return conf_tcp_max_clients_txn(conf, &conf->read_txn); +} + +/*! + * Gets the configured user and group identifiers. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[out] uid User identifier. + * \param[out] gid Group identifier. + * + * \return Knot error code. + */ +int conf_user_txn( + conf_t *conf, + knot_db_txn_t *txn, + int *uid, + int *gid +); +static inline int conf_user( + conf_t *conf, + int *uid, + int *gid) +{ + return conf_user_txn(conf, &conf->read_txn, uid, gid); +} + +/*! + * Gets the remote parameters for the given identifier. + * + * \param[in] conf Configuration. + * \param[in] txn Configuration DB transaction. + * \param[in] id Remote identifier. + * \param[in] index Remote index (counted from 0). + * + * \return Remote parameters. + */ +conf_remote_t conf_remote_txn( + conf_t *conf, + knot_db_txn_t *txn, + conf_val_t *id, + size_t index +); +static inline conf_remote_t conf_remote( + conf_t *conf, + conf_val_t *id, + size_t index) +{ + return conf_remote_txn(conf, &conf->read_txn, id, index); +} + +/*! XDP interface parameters. */ +typedef struct { + /*! Interface name. */ + char name[32]; + /*! UDP port to listen on. */ + uint16_t port; + /*! Number of active IO queues. */ + uint16_t queues; +} conf_xdp_iface_t; + +/*! + * Gets the XDP interface parameters for a given configuration value. + * + * \param[in] addr XDP interface name stored in the configuration. + * \param[out] iface Interface parameters. + * + * \return Error code, KNOT_EOK if success. + */ +int conf_xdp_iface( + struct sockaddr_storage *addr, + conf_xdp_iface_t *iface +); -- cgit v1.2.3