1 /*  Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 
3     This program is free software: you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation, either version 3 of the License, or
6     (at your option) any later version.
7 
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12 
13     You should have received a copy of the GNU General Public License
14     along with this program.  If not, see <https://www.gnu.org/licenses/>.
15  */
16 
17 #pragma once
18 
19 #include <sys/socket.h>
20 
21 #include "knot/conf/base.h"
22 #include "knot/conf/schema.h"
23 
24 /*! Configuration remote getter output. */
25 typedef struct {
26 	/*! Target socket address. */
27 	struct sockaddr_storage addr;
28 	/*! Local outgoing socket address. */
29 	struct sockaddr_storage via;
30 	/*! TSIG key. */
31 	knot_tsig_key_t key;
32 	/*! Suppress sending NOTIFY after zone transfer from this master. */
33 	bool block_notify_after_xfr;
34 	/*! Disable EDNS on XFR queries. */
35 	bool no_edns;
36 } conf_remote_t;
37 
38 /*! Configuration section iterator. */
39 typedef struct {
40 	/*! Item description. */
41 	const yp_item_t *item;
42 	/*! Namedb iterator. */
43 	knot_db_iter_t *iter;
44 	/*! Key0 database code. */
45 	uint8_t key0_code;
46 	// Public items.
47 	/*! Iterator return code. */
48 	int code;
49 } conf_iter_t;
50 
51 /*! Configuration module getter output. */
52 typedef struct {
53 	/*! Module name. */
54 	yp_name_t *name;
55 	/*! Module id data. */
56 	uint8_t *data;
57 	/*! Module id data length. */
58 	size_t len;
59 } conf_mod_id_t;
60 
61 /*!
62  * Check if the configuration database exists on the filesystem.
63  *
64  * \param[in] db_dir  Database path.
65  *
66  * \return True if it already exists.
67  */
68 
69 bool conf_db_exists(
70 	const char *db_dir
71 );
72 
73 /*!
74  * Gets the configuration item value of the section without identifiers.
75  *
76  * \param[in] conf       Configuration.
77  * \param[in] txn        Configuration DB transaction.
78  * \param[in] key0_name  Section name.
79  * \param[in] key1_name  Item name.
80  *
81  * \return Item value.
82  */
83 conf_val_t conf_get_txn(
84 	conf_t *conf,
85 	knot_db_txn_t *txn,
86 	const yp_name_t *key0_name,
87 	const yp_name_t *key1_name
88 );
conf_get(conf_t * conf,const yp_name_t * key0_name,const yp_name_t * key1_name)89 static inline conf_val_t conf_get(
90 	conf_t *conf,
91 	const yp_name_t *key0_name,
92 	const yp_name_t *key1_name)
93 {
94 	return conf_get_txn(conf, &conf->read_txn, key0_name, key1_name);
95 }
96 
97 /*!
98  * Gets the configuration item value of the section with identifiers (raw version).
99  *
100  * \param[in] conf        Configuration.
101  * \param[in] txn         Configuration DB transaction.
102  * \param[in] key0_name   Section name.
103  * \param[in] key1_name   Item name.
104  * \param[in] id          Section identifier (raw value).
105  * \param[in] id_len      Length of the section identifier.
106  *
107  * \return Item value.
108  */
109 conf_val_t conf_rawid_get_txn(
110 	conf_t *conf,
111 	knot_db_txn_t *txn,
112 	const yp_name_t *key0_name,
113 	const yp_name_t *key1_name,
114 	const uint8_t *id,
115 	size_t id_len
116 );
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)117 static inline conf_val_t conf_rawid_get(
118 	conf_t *conf,
119 	const yp_name_t *key0_name,
120 	const yp_name_t *key1_name,
121 	const uint8_t *id,
122 	size_t id_len)
123 {
124 	return conf_rawid_get_txn(conf, &conf->read_txn, key0_name, key1_name,
125 	                          id, id_len);
126 }
127 
128 /*!
129  * Gets the configuration item value of the section with identifiers.
130  *
131  * \param[in] conf        Configuration.
132  * \param[in] txn         Configuration DB transaction.
133  * \param[in] key0_name   Section name.
134  * \param[in] key1_name   Item name.
135  * \param[in] id          Section identifier (output of a config getter).
136  *
137  * \return Item value.
138  */
139 conf_val_t conf_id_get_txn(
140 	conf_t *conf,
141 	knot_db_txn_t *txn,
142 	const yp_name_t *key0_name,
143 	const yp_name_t *key1_name,
144 	conf_val_t *id
145 );
conf_id_get(conf_t * conf,const yp_name_t * key0_name,const yp_name_t * key1_name,conf_val_t * id)146 static inline conf_val_t conf_id_get(
147 	conf_t *conf,
148 	const yp_name_t *key0_name,
149 	const yp_name_t *key1_name,
150 	conf_val_t *id)
151 {
152 	return conf_id_get_txn(conf, &conf->read_txn, key0_name, key1_name, id);
153 }
154 
155 /*!
156  * Gets the configuration item value of the module section.
157  *
158  * \param[in] conf       Configuration.
159  * \param[in] txn        Configuration DB transaction.
160  * \param[in] key1_name  Item name.
161  * \param[in] mod_id     Module identifier.
162  *
163  * \return Item value.
164  */
165 conf_val_t conf_mod_get_txn(
166 	conf_t *conf,
167 	knot_db_txn_t *txn,
168 	const yp_name_t *key1_name,
169 	const conf_mod_id_t *mod_id
170 );
conf_mod_get(conf_t * conf,const yp_name_t * key1_name,const conf_mod_id_t * mod_id)171 static inline conf_val_t conf_mod_get(
172 	conf_t *conf,
173 	const yp_name_t *key1_name,
174 	const conf_mod_id_t *mod_id)
175 {
176 	return conf_mod_get_txn(conf, &conf->read_txn, key1_name, mod_id);
177 }
178 
179 /*!
180  * Gets the configuration item value of the zone section.
181  *
182  * \note A possibly associated template is taken into account.
183  *
184  * \param[in] conf        Configuration.
185  * \param[in] txn         Configuration DB transaction.
186  * \param[in] key1_name   Item name.
187  * \param[in] dname Zone  name.
188  *
189  * \return Item value.
190  */
191 conf_val_t conf_zone_get_txn(
192 	conf_t *conf,
193 	knot_db_txn_t *txn,
194 	const yp_name_t *key1_name,
195 	const knot_dname_t *dname
196 );
conf_zone_get(conf_t * conf,const yp_name_t * key1_name,const knot_dname_t * dname)197 static inline conf_val_t conf_zone_get(
198 	conf_t *conf,
199 	const yp_name_t *key1_name,
200 	const knot_dname_t *dname)
201 {
202 	return conf_zone_get_txn(conf, &conf->read_txn, key1_name, dname);
203 }
204 
205 /*!
206  * Gets the configuration item value of the default template.
207  *
208  * \param[in] conf       Configuration.
209  * \param[in] txn        Configuration DB transaction.
210  * \param[in] key1_name  Item name.
211  *
212  * \return Item value.
213  */
214 conf_val_t conf_default_get_txn(
215 	conf_t *conf,
216 	knot_db_txn_t *txn,
217 	const yp_name_t *key1_name
218 );
conf_default_get(conf_t * conf,const yp_name_t * key1_name)219 static inline conf_val_t conf_default_get(
220 	conf_t *conf,
221 	const yp_name_t *key1_name)
222 {
223 	return conf_default_get_txn(conf, &conf->read_txn, key1_name);
224 }
225 
226 /*!
227  * Checks the configuration section for the identifier (raw version).
228  *
229  * \param[in] conf        Configuration.
230  * \param[in] txn         Configuration DB transaction.
231  * \param[in] key0_name   Section name.
232  * \param[in] id          Section identifier (raw value).
233  * \param[in] id_len      Length of the section identifier.
234  *
235  * \return True if exists.
236  */
237 bool conf_rawid_exists_txn(
238 	conf_t *conf,
239 	knot_db_txn_t *txn,
240 	const yp_name_t *key0_name,
241 	const uint8_t *id,
242 	size_t id_len
243 );
conf_rawid_exists(conf_t * conf,const yp_name_t * key0_name,const uint8_t * id,size_t id_len)244 static inline bool conf_rawid_exists(
245 	conf_t *conf,
246 	const yp_name_t *key0_name,
247 	const uint8_t *id,
248 	size_t id_len)
249 {
250 	return conf_rawid_exists_txn(conf, &conf->read_txn, key0_name, id, id_len);
251 }
252 
253 /*!
254  * Checks the configuration section for the identifier.
255  *
256  * \param[in] conf        Configuration.
257  * \param[in] txn         Configuration DB transaction.
258  * \param[in] key0_name   Section name.
259  * \param[in] id          Section identifier (output of a config getter).
260  *
261  * \return True if exists.
262  */
263 bool conf_id_exists_txn(
264 	conf_t *conf,
265 	knot_db_txn_t *txn,
266 	const yp_name_t *key0_name,
267 	conf_val_t *id
268 );
conf_id_exists(conf_t * conf,const yp_name_t * key0_name,conf_val_t * id)269 static inline bool conf_id_exists(
270 	conf_t *conf,
271 	const yp_name_t *key0_name,
272 	conf_val_t *id)
273 {
274 	return conf_id_exists_txn(conf, &conf->read_txn, key0_name, id);
275 }
276 
277 /*!
278  * Gets the number of section identifiers.
279  *
280  * \param[in] conf       Configuration.
281  * \param[in] txn        Configuration DB transaction.
282  * \param[in] key0_name  Section name.
283  *
284  * \return Number of identifiers.
285  */
286 size_t conf_id_count_txn(
287 	conf_t *conf,
288 	knot_db_txn_t *txn,
289 	const yp_name_t *key0_name
290 );
conf_id_count(conf_t * conf,const yp_name_t * key0_name)291 static inline size_t conf_id_count(
292 	conf_t *conf,
293 	const yp_name_t *key0_name)
294 {
295 	return conf_id_count_txn(conf, &conf->read_txn, key0_name);
296 }
297 
298 /*!
299  * Gets a configuration section iterator.
300  *
301  * \param[in] conf       Configuration.
302  * \param[in] txn        Configuration DB transaction.
303  * \param[in] key0_name  Section name.
304  *
305  * \return Section iterator.
306  */
307 conf_iter_t conf_iter_txn(
308 	conf_t *conf,
309 	knot_db_txn_t *txn,
310 	const yp_name_t *key0_name
311 );
conf_iter(conf_t * conf,const yp_name_t * key0_name)312 static inline conf_iter_t conf_iter(
313 	conf_t *conf,
314 	const yp_name_t *key0_name)
315 {
316 	return conf_iter_txn(conf, &conf->read_txn, key0_name);
317 }
318 
319 /*!
320  * Moves the configuration section iterator to the next identifier.
321  *
322  * \param[in] conf  Configuration.
323  * \param[in] iter  Configuration iterator.
324  */
325 void conf_iter_next(
326 	conf_t *conf,
327 	conf_iter_t *iter
328 );
329 
330 /*!
331  * Gets the current iterator value (identifier).
332  *
333  * \param[in] conf  Configuration.
334  * \param[in] iter  Configuration iterator.
335  *
336  * \return Section identifier.
337  */
338 conf_val_t conf_iter_id(
339 	conf_t *conf,
340 	conf_iter_t *iter
341 );
342 
343 /*!
344  * Deletes the section iterator.
345  *
346  * This function should be called when the iterating is early interrupted,
347  * otherwise this is done automaticaly at KNOT_EOF.
348  *
349  * \param[in] conf  Configuration.
350  * \param[in] iter  Configuration iterator.
351  */
352 void conf_iter_finish(
353 	conf_t *conf,
354 	conf_iter_t *iter
355 );
356 
357 /*!
358  * Prepares the value for the direct access.
359  *
360  * The following access is through val->len and val->data.
361  *
362  * \param[in] val  Item value.
363  */
364 void conf_val(
365 	conf_val_t *val
366 );
367 
368 /*!
369  * Moves to the next value of a multi-valued item.
370  *
371  * \param[in] val  Item value.
372  */
373 void conf_val_next(
374 	conf_val_t *val
375 );
376 
377 /*!
378  * Resets to the first value of a multi-valued item.
379  *
380  * \param[in] val Item value.
381  */
382 void conf_val_reset(
383 	conf_val_t *val
384 );
385 
386 /*!
387  * Gets the number of values if multivalued item.
388  *
389  * \param[in] val  Item value.
390  *
391  * \return Number of values.
392  */
393 size_t conf_val_count(
394 	conf_val_t *val
395 );
396 
397 /*!
398  * Checks if two item values are equal.
399  *
400  * \param[in] val1  First item value.
401  * \param[in] val2  Second item value.
402  *
403  * \return true if equal, false if not.
404  */
405 bool conf_val_equal(
406 	conf_val_t *val1,
407 	conf_val_t *val2
408 );
409 
410 /*!
411  * Gets the numeric value of the item.
412  *
413  * \param[in] val  Item value.
414  *
415  * \return Integer.
416  */
417 int64_t conf_int(
418 	conf_val_t *val
419 );
420 
421 /*!
422  * Gets the boolean value of the item.
423  *
424  * \param[in] val  Item value.
425  *
426  * \return Boolean.
427  */
428 bool conf_bool(
429 	conf_val_t *val
430 );
431 
432 /*!
433  * Gets the option value of the item.
434  *
435  * \param[in] val  Item value.
436  *
437  * \return Option id.
438  */
439 unsigned conf_opt(
440 	conf_val_t *val
441 );
442 
443 /*!
444  * Gets the string value of the item.
445  *
446  * \param[in] val  Item value.
447  *
448  * \return String pointer.
449  */
450 const char* conf_str(
451 	conf_val_t *val
452 );
453 
454 /*!
455  * Gets the dname value of the item.
456  *
457  * \param[in] val  Item value.
458  *
459  * \return Dname pointer.
460  */
461 const knot_dname_t* conf_dname(
462 	conf_val_t *val
463 );
464 
465 /*!
466  * Gets the length-prefixed data value of the item.
467  *
468  * \param[in] val   Item value.
469  * \param[out] len  Output length.
470  *
471  * \return Data pointer.
472  */
473 const uint8_t* conf_bin(
474 	conf_val_t *val,
475 	size_t *len
476 );
477 
478 /*!
479  * Gets the generic data value of the item.
480  *
481  * \param[in] val   Item value.
482  * \param[out] len  Output length.
483  *
484  * \return Data pointer.
485  */
486 const uint8_t* conf_data(
487 	conf_val_t *val,
488 	size_t *len
489 );
490 
491 /*!
492  * Gets the socket address value of the item.
493  *
494  * \param[in] val            Item value.
495  * \param[in] sock_base_dir  Path prefix for a relative UNIX socket location.
496  *
497  * \return Socket address.
498  */
499 struct sockaddr_storage conf_addr(
500 	conf_val_t *val,
501 	const char *sock_base_dir
502 );
503 
504 /*!
505  * Checks the configured address if equal to given one (except port).
506  *
507  * \param[in] match   Configured address.
508  * \param[in] addr    Address to check.
509  *
510  * \return True if matches.
511  */
512 bool conf_addr_match(
513 	conf_val_t *match,
514 	const struct sockaddr_storage *addr
515 );
516 
517 /*!
518  * Gets the socket address range value of the item.
519  *
520  * \param[in] val            Item value.
521  * \param[out] max_ss Upper  address bound or AF_UNSPEC family if not specified.
522  * \param[out] prefix_len    Network subnet prefix length or -1 if not specified.
523  *
524  * \return Socket address.
525  */
526 struct sockaddr_storage conf_addr_range(
527 	conf_val_t *val,
528 	struct sockaddr_storage *max_ss,
529 	int *prefix_len
530 );
531 
532 /*!
533  * Checks the address if matches given address range/network block.
534  *
535  * \param[in] range  Address range/network block.
536  * \param[in] addr   Address to check.
537  *
538  * \return True if matches.
539  */
540 bool conf_addr_range_match(
541 	conf_val_t *range,
542 	const struct sockaddr_storage *addr
543 );
544 
545 /*!
546  * Gets the absolute string value of the item.
547  *
548  * \note The result must be explicitly deallocated.
549  *
550  * \param[in] val       Item value.
551  * \param[in] base_dir  Path prefix for a relative string.
552  *
553  * \return Absolute path string pointer.
554  */
555 char* conf_abs_path(
556 	conf_val_t *val,
557 	const char *base_dir
558 );
559 
560 /*!
561  * Ensures empty 'default' identifier value.
562  *
563  * \param[in] val  Item value.
564  *
565  * \return Empty item value.
566  */
conf_id_fix_default(conf_val_t * val)567 static inline void conf_id_fix_default(conf_val_t *val)
568 {
569 	if (val->code != KNOT_EOK) {
570 		conf_val_t empty = {
571 			.item = val->item,
572 			.code = KNOT_EOK
573 		};
574 
575 		*val = empty;
576 	}
577 }
578 
579 /*!
580  * Gets the module identifier value of the item.
581  *
582  * \param[in] val  Item value.
583  *
584  * \return Module identifier.
585  */
586 conf_mod_id_t* conf_mod_id(
587 	conf_val_t *val
588 );
589 
590 /*!
591  * Destroys the module identifier.
592  *
593  * \param[in] mod_id  Module identifier.
594  */
595 void conf_free_mod_id(
596 	conf_mod_id_t *mod_id
597 );
598 
599 /*!
600  * Gets the absolute zone file path.
601  *
602  * \note The result must be explicitly deallocated.
603  *
604  * \param[in] conf  Configuration.
605  * \param[in] txn   Configuration DB transaction.
606  * \param[in] zone  Zone name.
607  *
608  * \return Absolute zonef ile path string pointer.
609  */
610 char* conf_zonefile_txn(
611 	conf_t *conf,
612 	knot_db_txn_t *txn,
613 	const knot_dname_t *zone
614 );
conf_zonefile(conf_t * conf,const knot_dname_t * zone)615 static inline char* conf_zonefile(
616 	conf_t *conf,
617 	const knot_dname_t *zone)
618 {
619 	return conf_zonefile_txn(conf, &conf->read_txn, zone);
620 }
621 
622 /*!
623  * Gets the absolute directory path for a database.
624  *
625  * e.g. Journal, KASP db, Timers
626  *
627  * \note The result must be explicitly deallocated.
628  *
629  * \param[in] conf     Configuration.
630  * \param[in] txn      Configuration DB transaction.
631  * \param[in] db_type  Database name.
632  *
633  * \return Absolute database path string pointer.
634  */
635 char* conf_db_txn(
636 	conf_t *conf,
637 	knot_db_txn_t *txn,
638 	const yp_name_t *db_type
639 );
conf_db(conf_t * conf,const yp_name_t * db_type)640 static inline char* conf_db(
641 	conf_t *conf,
642 	const yp_name_t *db_type)
643 {
644 	return conf_db_txn(conf, &conf->read_txn, db_type);
645 }
646 
647 /*!
648  * Gets database-specific parameter.
649  *
650  * \param[in] conf   Configuration.
651  * \param[in] param  Parameter name.
652  *
653  * \return Item value.
654  */
conf_db_param(conf_t * conf,const yp_name_t * param)655 static inline conf_val_t conf_db_param(
656 	conf_t *conf,
657 	const yp_name_t *param)
658 {
659 	return conf_get_txn(conf, &conf->read_txn, C_DB, param);
660 }
661 
662 /*!
663  * Gets the configured setting of the bool option in the specified section.
664  *
665  * \param[in] conf     Configuration.
666  * \param[in] section  Section name.
667  * \param[in] param    Parameter name.
668  *
669  * \return True if enabled, false otherwise.
670  */
conf_get_bool(conf_t * conf,const yp_name_t * section,const yp_name_t * param)671 static inline bool conf_get_bool(
672 	conf_t *conf,
673 	const yp_name_t *section,
674 	const yp_name_t *param)
675 {
676 	conf_val_t val = conf_get_txn(conf, &conf->read_txn, section, param);
677 	return conf_bool(&val);
678 }
679 
680 /*!
681  * Gets the configured setting of the int option in the specified section.
682  *
683  * \param[in] conf     Configuration.
684  * \param[in] section  Section name.
685  * \param[in] param    Parameter name.
686  *
687  * \return True if enabled, false otherwise.
688  */
conf_get_int(conf_t * conf,const yp_name_t * section,const yp_name_t * param)689 static inline int conf_get_int(
690 	conf_t *conf,
691 	const yp_name_t *section,
692 	const yp_name_t *param)
693 {
694 	conf_val_t val = conf_get_txn(conf, &conf->read_txn, section, param);
695 	return conf_int(&val);
696 }
697 
698 /*!
699  * Gets the configured number of UDP threads.
700  *
701  * \param[in] conf  Configuration.
702  * \param[in] txn   Configuration DB transaction.
703  *
704  * \return Number of threads.
705  */
706 size_t conf_udp_threads_txn(
707 	conf_t *conf,
708 	knot_db_txn_t *txn
709 );
conf_udp_threads(conf_t * conf)710 static inline size_t conf_udp_threads(
711 	conf_t *conf)
712 {
713 	return conf_udp_threads_txn(conf, &conf->read_txn);
714 }
715 
716 /*!
717  * Gets the configured number of TCP threads.
718  *
719  * \param[in] conf  Configuration.
720  * \param[in] txn   Configuration DB transaction.
721  *
722  * \return Number of threads.
723  */
724 size_t conf_tcp_threads_txn(
725 	conf_t *conf,
726 	knot_db_txn_t *txn
727 );
conf_tcp_threads(conf_t * conf)728 static inline size_t conf_tcp_threads(
729 	conf_t *conf)
730 {
731 	return conf_tcp_threads_txn(conf, &conf->read_txn);
732 }
733 
734 /*!
735  * Gets the number of used XDP threads.
736  *
737  * \param[in] conf  Configuration.
738  * \param[in] txn   Configuration DB transaction.
739  *
740  * \return Number of threads.
741  */
742 size_t conf_xdp_threads_txn(
743 	conf_t *conf,
744 	knot_db_txn_t *txn
745 );
conf_xdp_threads(conf_t * conf)746 static inline size_t conf_xdp_threads(
747 	conf_t *conf)
748 {
749 	return conf_xdp_threads_txn(conf, &conf->read_txn);
750 }
751 
752 /*!
753  * Gets the configured number of worker threads.
754  *
755  * \param[in] conf  Configuration.
756  * \param[in] txn   Configuration DB transaction.
757  *
758  * \return Number of threads.
759  */
760 size_t conf_bg_threads_txn(
761 	conf_t *conf,
762 	knot_db_txn_t *txn
763 );
conf_bg_threads(conf_t * conf)764 static inline size_t conf_bg_threads(
765 	conf_t *conf)
766 {
767 	return conf_bg_threads_txn(conf, &conf->read_txn);
768 }
769 
770 /*!
771  * Gets the required LMDB readers limit based on the current configuration.
772  *
773  * \note The resulting value is a common limit to journal, kasp, timers,
774  *       and catalog databases. So it's over-estimated for simpicity reasons.
775  *
776  * \note This function cannot be used for the configuration database setting :-/
777  *
778  * \param[in] conf  Configuration.
779  *
780  * \return Number of readers.
781  */
conf_lmdb_readers(conf_t * conf)782 static inline size_t conf_lmdb_readers(
783 	conf_t *conf)
784 {
785 	if (conf == NULL) { // Return default in tests.
786 		return 126;
787 	}
788 	return conf_udp_threads(conf) + conf_tcp_threads(conf) +
789 	       conf_bg_threads(conf) + conf_xdp_threads(conf);
790 }
791 
792 /*!
793  * Gets the configured maximum number of TCP clients.
794  *
795  * \param[in] conf  Configuration.
796  * \param[in] txn   Configuration DB transaction.
797  *
798  * \return Maximum number of TCP clients.
799  */
800 size_t conf_tcp_max_clients_txn(
801 	conf_t *conf,
802 	knot_db_txn_t *txn
803 );
conf_tcp_max_clients(conf_t * conf)804 static inline size_t conf_tcp_max_clients(
805 	conf_t *conf)
806 {
807 	return conf_tcp_max_clients_txn(conf, &conf->read_txn);
808 }
809 
810 /*!
811  * Gets the configured user and group identifiers.
812  *
813  * \param[in] conf  Configuration.
814  * \param[in] txn   Configuration DB transaction.
815  * \param[out] uid  User identifier.
816  * \param[out] gid  Group identifier.
817  *
818  * \return Knot error code.
819  */
820 int conf_user_txn(
821 	conf_t *conf,
822 	knot_db_txn_t *txn,
823 	int *uid,
824 	int *gid
825 );
conf_user(conf_t * conf,int * uid,int * gid)826 static inline int conf_user(
827 	conf_t *conf,
828 	int *uid,
829 	int *gid)
830 {
831 	return conf_user_txn(conf, &conf->read_txn, uid, gid);
832 }
833 
834 /*!
835  * Gets the remote parameters for the given identifier.
836  *
837  * \param[in] conf   Configuration.
838  * \param[in] txn    Configuration DB transaction.
839  * \param[in] id     Remote identifier.
840  * \param[in] index  Remote index (counted from 0).
841  *
842  * \return Remote parameters.
843  */
844 conf_remote_t conf_remote_txn(
845 	conf_t *conf,
846 	knot_db_txn_t *txn,
847 	conf_val_t *id,
848 	size_t index
849 );
conf_remote(conf_t * conf,conf_val_t * id,size_t index)850 static inline conf_remote_t conf_remote(
851 	conf_t *conf,
852 	conf_val_t *id,
853 	size_t index)
854 {
855 	return conf_remote_txn(conf, &conf->read_txn, id, index);
856 }
857 
858 /*! XDP interface parameters. */
859 typedef struct {
860 	/*! Interface name. */
861 	char name[32];
862 	/*! UDP port to listen on. */
863 	uint16_t port;
864 	/*! Number of active IO queues. */
865 	uint16_t queues;
866 } conf_xdp_iface_t;
867 
868 /*!
869  * Gets the XDP interface parameters for a given configuration value.
870  *
871  * \param[in] addr    XDP interface name stored in the configuration.
872  * \param[out] iface  Interface parameters.
873  *
874  * \return Error code, KNOT_EOK if success.
875  */
876 int conf_xdp_iface(
877 	struct sockaddr_storage *addr,
878 	conf_xdp_iface_t *iface
879 );
880