namedconf.c revision 1.15.2.1 1 1.15.2.1 perseant /* $NetBSD: namedconf.c,v 1.15.2.1 2025/08/02 05:54:06 perseant Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 1.1 christos *
6 1.13 christos * SPDX-License-Identifier: MPL-2.0
7 1.13 christos *
8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public
9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this
10 1.9 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 1.1 christos *
12 1.1 christos * See the COPYRIGHT file distributed with this work for additional
13 1.1 christos * information regarding copyright ownership.
14 1.1 christos */
15 1.1 christos
16 1.1 christos /*! \file */
17 1.1 christos
18 1.3 christos #include <inttypes.h>
19 1.3 christos #include <stdbool.h>
20 1.1 christos #include <stdlib.h>
21 1.1 christos #include <string.h>
22 1.1 christos
23 1.1 christos #include <isc/lex.h>
24 1.1 christos #include <isc/mem.h>
25 1.1 christos #include <isc/result.h>
26 1.1 christos #include <isc/string.h>
27 1.1 christos #include <isc/util.h>
28 1.1 christos
29 1.1 christos #include <dns/ttl.h>
30 1.1 christos
31 1.1 christos #include <isccfg/cfg.h>
32 1.1 christos #include <isccfg/grammar.h>
33 1.1 christos #include <isccfg/log.h>
34 1.1 christos #include <isccfg/namedconf.h>
35 1.1 christos
36 1.1 christos #define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base)
37 1.1 christos
38 1.1 christos /*% Check a return value. */
39 1.8 christos #define CHECK(op) \
40 1.8 christos do { \
41 1.8 christos result = (op); \
42 1.8 christos if (result != ISC_R_SUCCESS) \
43 1.8 christos goto cleanup; \
44 1.10 rillig } while (0)
45 1.1 christos
46 1.1 christos /*% Clean up a configuration object if non-NULL. */
47 1.8 christos #define CLEANUP_OBJ(obj) \
48 1.8 christos do { \
49 1.8 christos if ((obj) != NULL) \
50 1.8 christos cfg_obj_destroy(pctx, &(obj)); \
51 1.10 rillig } while (0)
52 1.1 christos
53 1.1 christos /*%
54 1.1 christos * Forward declarations of static functions.
55 1.1 christos */
56 1.1 christos
57 1.1 christos static isc_result_t
58 1.1 christos parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
59 1.1 christos
60 1.1 christos static isc_result_t
61 1.1 christos parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
62 1.1 christos cfg_obj_t **ret);
63 1.1 christos
64 1.1 christos static isc_result_t
65 1.8 christos parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
66 1.1 christos static void
67 1.1 christos print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj);
68 1.1 christos
69 1.1 christos static void
70 1.1 christos doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type);
71 1.1 christos
72 1.1 christos static void
73 1.1 christos print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj);
74 1.1 christos
75 1.1 christos static void
76 1.1 christos doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type);
77 1.1 christos
78 1.1 christos static void
79 1.1 christos doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type);
80 1.1 christos
81 1.15 christos static isc_result_t
82 1.15 christos cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
83 1.15 christos
84 1.15 christos static void
85 1.15 christos cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj);
86 1.15 christos
87 1.15 christos static void
88 1.15 christos cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
89 1.15 christos
90 1.1 christos static cfg_type_t cfg_type_acl;
91 1.1 christos static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
92 1.3 christos static cfg_type_t cfg_type_bracketed_netaddrlist;
93 1.1 christos static cfg_type_t cfg_type_bracketed_sockaddrnameportlist;
94 1.15.2.1 perseant static cfg_type_t cfg_type_bracketed_sockaddrtlslist;
95 1.15 christos static cfg_type_t cfg_type_bracketed_http_endpoint_list;
96 1.15.2.1 perseant static cfg_type_t cfg_type_checkdstype;
97 1.1 christos static cfg_type_t cfg_type_controls;
98 1.1 christos static cfg_type_t cfg_type_controls_sockaddr;
99 1.1 christos static cfg_type_t cfg_type_destinationlist;
100 1.1 christos static cfg_type_t cfg_type_dialuptype;
101 1.1 christos static cfg_type_t cfg_type_dlz;
102 1.8 christos static cfg_type_t cfg_type_dnssecpolicy;
103 1.1 christos static cfg_type_t cfg_type_dnstap;
104 1.1 christos static cfg_type_t cfg_type_dnstapoutput;
105 1.1 christos static cfg_type_t cfg_type_dyndb;
106 1.15 christos static cfg_type_t cfg_type_http_description;
107 1.1 christos static cfg_type_t cfg_type_ixfrdifftype;
108 1.9 christos static cfg_type_t cfg_type_ixfrratio;
109 1.1 christos static cfg_type_t cfg_type_key;
110 1.15.2.1 perseant static cfg_type_t cfg_type_keystore;
111 1.1 christos static cfg_type_t cfg_type_logfile;
112 1.1 christos static cfg_type_t cfg_type_logging;
113 1.1 christos static cfg_type_t cfg_type_logseverity;
114 1.1 christos static cfg_type_t cfg_type_logsuffix;
115 1.1 christos static cfg_type_t cfg_type_logversions;
116 1.12 christos static cfg_type_t cfg_type_remoteselement;
117 1.8 christos static cfg_type_t cfg_type_maxduration;
118 1.1 christos static cfg_type_t cfg_type_minimal;
119 1.1 christos static cfg_type_t cfg_type_nameportiplist;
120 1.1 christos static cfg_type_t cfg_type_notifytype;
121 1.1 christos static cfg_type_t cfg_type_optional_allow;
122 1.1 christos static cfg_type_t cfg_type_optional_class;
123 1.1 christos static cfg_type_t cfg_type_optional_facility;
124 1.1 christos static cfg_type_t cfg_type_optional_keyref;
125 1.1 christos static cfg_type_t cfg_type_optional_port;
126 1.15.2.1 perseant static cfg_type_t cfg_type_optional_sourceaddr4;
127 1.15.2.1 perseant static cfg_type_t cfg_type_optional_sourceaddr6;
128 1.1 christos static cfg_type_t cfg_type_optional_uint32;
129 1.15 christos static cfg_type_t cfg_type_optional_tls;
130 1.1 christos static cfg_type_t cfg_type_options;
131 1.15 christos static cfg_type_t cfg_type_plugin;
132 1.1 christos static cfg_type_t cfg_type_portiplist;
133 1.1 christos static cfg_type_t cfg_type_printtime;
134 1.3 christos static cfg_type_t cfg_type_qminmethod;
135 1.1 christos static cfg_type_t cfg_type_querysource4;
136 1.1 christos static cfg_type_t cfg_type_querysource6;
137 1.15.2.1 perseant static cfg_type_t cfg_type_server_querysource4;
138 1.15.2.1 perseant static cfg_type_t cfg_type_server_querysource6;
139 1.1 christos static cfg_type_t cfg_type_querysource;
140 1.1 christos static cfg_type_t cfg_type_server;
141 1.1 christos static cfg_type_t cfg_type_server_key_kludge;
142 1.1 christos static cfg_type_t cfg_type_size;
143 1.1 christos static cfg_type_t cfg_type_sizenodefault;
144 1.1 christos static cfg_type_t cfg_type_sizeorpercent;
145 1.1 christos static cfg_type_t cfg_type_sizeval;
146 1.1 christos static cfg_type_t cfg_type_sockaddr4wild;
147 1.1 christos static cfg_type_t cfg_type_sockaddr6wild;
148 1.1 christos static cfg_type_t cfg_type_statschannels;
149 1.15 christos static cfg_type_t cfg_type_tlsconf;
150 1.1 christos static cfg_type_t cfg_type_view;
151 1.1 christos static cfg_type_t cfg_type_viewopts;
152 1.1 christos static cfg_type_t cfg_type_zone;
153 1.1 christos
154 1.1 christos /*% listen-on */
155 1.1 christos
156 1.15 christos static cfg_tuplefielddef_t listenon_tuple_fields[] = {
157 1.15 christos { "port", &cfg_type_optional_port, 0 },
158 1.15.2.1 perseant /*
159 1.15.2.1 perseant * Let's follow the protocols encapsulation order (lower->upper), at
160 1.15.2.1 perseant * least roughly.
161 1.15.2.1 perseant */
162 1.15.2.1 perseant { "proxy", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
163 1.15 christos { "tls", &cfg_type_astring, 0 },
164 1.15 christos #if HAVE_LIBNGHTTP2
165 1.15 christos { "http", &cfg_type_astring, 0 },
166 1.15 christos #else
167 1.15 christos { "http", &cfg_type_astring, CFG_CLAUSEFLAG_NOTCONFIGURED },
168 1.15 christos #endif
169 1.15 christos { NULL, NULL, 0 }
170 1.15 christos };
171 1.15 christos static cfg_type_t cfg_type_listen_tuple = {
172 1.15 christos "listenon tuple", cfg_parse_kv_tuple, cfg_print_kv_tuple,
173 1.15 christos cfg_doc_kv_tuple, &cfg_rep_tuple, listenon_tuple_fields
174 1.15 christos };
175 1.15 christos
176 1.1 christos static cfg_tuplefielddef_t listenon_fields[] = {
177 1.15 christos { "tuple", &cfg_type_listen_tuple, 0 },
178 1.1 christos { "acl", &cfg_type_bracketed_aml, 0 },
179 1.1 christos { NULL, NULL, 0 }
180 1.1 christos };
181 1.1 christos
182 1.8 christos static cfg_type_t cfg_type_listenon = { "listenon", cfg_parse_tuple,
183 1.8 christos cfg_print_tuple, cfg_doc_tuple,
184 1.8 christos &cfg_rep_tuple, listenon_fields };
185 1.1 christos
186 1.1 christos /*% acl */
187 1.1 christos
188 1.15 christos /*
189 1.15 christos * Encrypted transfer related definitions
190 1.15 christos */
191 1.15 christos
192 1.15 christos static cfg_tuplefielddef_t cfg_transport_acl_tuple_fields[] = {
193 1.15 christos { "port", &cfg_type_optional_port, 0 },
194 1.15 christos { "transport", &cfg_type_astring, 0 },
195 1.15 christos { NULL, NULL, 0 }
196 1.15 christos };
197 1.15 christos static cfg_type_t cfg_transport_acl_tuple = {
198 1.15 christos "transport-acl tuple", cfg_parse_kv_tuple,
199 1.15 christos cfg_print_kv_tuple, cfg_doc_kv_tuple,
200 1.15 christos &cfg_rep_tuple, cfg_transport_acl_tuple_fields
201 1.15 christos };
202 1.15 christos
203 1.15 christos static cfg_tuplefielddef_t cfg_transport_acl_fields[] = {
204 1.15 christos { "port-transport", &cfg_transport_acl_tuple, 0 },
205 1.15 christos { "aml", &cfg_type_bracketed_aml, 0 },
206 1.15 christos { NULL, NULL, 0 }
207 1.15 christos };
208 1.15 christos
209 1.15 christos static cfg_type_t cfg_type_transport_acl = {
210 1.15 christos "transport-acl", cfg_parse_tuple, cfg_print_tuple,
211 1.15 christos cfg_doc_tuple, &cfg_rep_tuple, cfg_transport_acl_fields
212 1.15 christos };
213 1.15 christos
214 1.15 christos /*
215 1.15 christos * NOTE: To enable syntax which allows specifying port and protocol,
216 1.15 christos * replace 'cfg_type_bracketed_aml' with
217 1.15 christos * 'cfg_type_transport_acl'.
218 1.15 christos *
219 1.15 christos * Example: acl port 853 protocol tls { ... };
220 1.15 christos */
221 1.8 christos static cfg_tuplefielddef_t acl_fields[] = { { "name", &cfg_type_astring, 0 },
222 1.8 christos { "value", &cfg_type_bracketed_aml,
223 1.8 christos 0 },
224 1.8 christos { NULL, NULL, 0 } };
225 1.8 christos
226 1.8 christos static cfg_type_t cfg_type_acl = { "acl", cfg_parse_tuple,
227 1.8 christos cfg_print_tuple, cfg_doc_tuple,
228 1.8 christos &cfg_rep_tuple, acl_fields };
229 1.1 christos
230 1.12 christos /*% remote servers, used for primaries and parental agents */
231 1.12 christos static cfg_tuplefielddef_t remotes_fields[] = {
232 1.1 christos { "name", &cfg_type_astring, 0 },
233 1.1 christos { "port", &cfg_type_optional_port, 0 },
234 1.15.2.1 perseant { "source", &cfg_type_optional_sourceaddr4, 0 },
235 1.15.2.1 perseant { "source-v6", &cfg_type_optional_sourceaddr6, 0 },
236 1.1 christos { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
237 1.1 christos { NULL, NULL, 0 }
238 1.1 christos };
239 1.1 christos
240 1.15.2.1 perseant static cfg_type_t cfg_type_serverlist = { "server-list", cfg_parse_tuple,
241 1.15.2.1 perseant cfg_print_tuple, cfg_doc_tuple,
242 1.15.2.1 perseant &cfg_rep_tuple, remotes_fields };
243 1.1 christos
244 1.1 christos /*%
245 1.1 christos * "sockaddrkeylist", a list of socket addresses with optional keys
246 1.12 christos * and an optional default port, as used in the remote-servers option.
247 1.1 christos * E.g.,
248 1.12 christos * "port 1234 { myservers; 10.0.0.1 key foo; 1::2 port 69; }"
249 1.1 christos */
250 1.1 christos
251 1.1 christos static cfg_tuplefielddef_t namesockaddrkey_fields[] = {
252 1.12 christos { "remoteselement", &cfg_type_remoteselement, 0 },
253 1.1 christos { "key", &cfg_type_optional_keyref, 0 },
254 1.15 christos { "tls", &cfg_type_optional_tls, 0 },
255 1.1 christos { NULL, NULL, 0 },
256 1.1 christos };
257 1.1 christos
258 1.1 christos static cfg_type_t cfg_type_namesockaddrkey = {
259 1.8 christos "namesockaddrkey", cfg_parse_tuple, cfg_print_tuple,
260 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, namesockaddrkey_fields
261 1.1 christos };
262 1.1 christos
263 1.1 christos static cfg_type_t cfg_type_bracketed_namesockaddrkeylist = {
264 1.8 christos "bracketed_namesockaddrkeylist",
265 1.8 christos cfg_parse_bracketed_list,
266 1.8 christos cfg_print_bracketed_list,
267 1.8 christos cfg_doc_bracketed_list,
268 1.8 christos &cfg_rep_list,
269 1.1 christos &cfg_type_namesockaddrkey
270 1.1 christos };
271 1.1 christos
272 1.1 christos static cfg_tuplefielddef_t namesockaddrkeylist_fields[] = {
273 1.1 christos { "port", &cfg_type_optional_port, 0 },
274 1.15.2.1 perseant { "source", &cfg_type_optional_sourceaddr4, 0 },
275 1.15.2.1 perseant { "source-v6", &cfg_type_optional_sourceaddr6, 0 },
276 1.1 christos { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 },
277 1.1 christos { NULL, NULL, 0 }
278 1.1 christos };
279 1.1 christos static cfg_type_t cfg_type_namesockaddrkeylist = {
280 1.8 christos "sockaddrkeylist", cfg_parse_tuple, cfg_print_tuple,
281 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, namesockaddrkeylist_fields
282 1.1 christos };
283 1.1 christos
284 1.1 christos /*%
285 1.1 christos * A list of socket addresses with an optional default port, as used
286 1.15.2.1 perseant * in the 'forwarders' option. E.g., "{ 10.0.0.1; 1::2 port 69; }"
287 1.1 christos */
288 1.1 christos static cfg_tuplefielddef_t portiplist_fields[] = {
289 1.1 christos { "port", &cfg_type_optional_port, 0 },
290 1.15.2.1 perseant { "tls", &cfg_type_optional_tls, 0 },
291 1.15.2.1 perseant { "addresses", &cfg_type_bracketed_sockaddrtlslist, 0 },
292 1.1 christos { NULL, NULL, 0 }
293 1.1 christos };
294 1.8 christos static cfg_type_t cfg_type_portiplist = { "portiplist", cfg_parse_tuple,
295 1.8 christos cfg_print_tuple, cfg_doc_tuple,
296 1.8 christos &cfg_rep_tuple, portiplist_fields };
297 1.1 christos
298 1.1 christos /*%
299 1.1 christos * A list of RR types, used in grant statements.
300 1.1 christos * Note that the old parser allows quotes around the RR type names.
301 1.1 christos */
302 1.1 christos static cfg_type_t cfg_type_rrtypelist = {
303 1.8 christos "rrtypelist", cfg_parse_spacelist, cfg_print_spacelist,
304 1.8 christos cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring
305 1.1 christos };
306 1.1 christos
307 1.1 christos static const char *mode_enums[] = { "deny", "grant", NULL };
308 1.1 christos static cfg_type_t cfg_type_mode = {
309 1.8 christos "mode", cfg_parse_enum, cfg_print_ustring,
310 1.8 christos cfg_doc_enum, &cfg_rep_string, &mode_enums
311 1.1 christos };
312 1.1 christos
313 1.1 christos static isc_result_t
314 1.1 christos parse_matchtype(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
315 1.1 christos isc_result_t result;
316 1.1 christos
317 1.1 christos CHECK(cfg_peektoken(pctx, 0));
318 1.1 christos if (pctx->token.type == isc_tokentype_string &&
319 1.8 christos strcasecmp(TOKEN_STRING(pctx), "zonesub") == 0)
320 1.8 christos {
321 1.1 christos pctx->flags |= CFG_PCTX_SKIP;
322 1.1 christos }
323 1.15.2.1 perseant return cfg_parse_enum(pctx, type, ret);
324 1.1 christos
325 1.8 christos cleanup:
326 1.15.2.1 perseant return result;
327 1.1 christos }
328 1.1 christos
329 1.1 christos static isc_result_t
330 1.1 christos parse_matchname(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
331 1.1 christos isc_result_t result;
332 1.1 christos cfg_obj_t *obj = NULL;
333 1.1 christos
334 1.1 christos if ((pctx->flags & CFG_PCTX_SKIP) != 0) {
335 1.1 christos pctx->flags &= ~CFG_PCTX_SKIP;
336 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj));
337 1.8 christos } else {
338 1.1 christos result = cfg_parse_astring(pctx, type, &obj);
339 1.8 christos }
340 1.1 christos
341 1.1 christos *ret = obj;
342 1.8 christos cleanup:
343 1.15.2.1 perseant return result;
344 1.1 christos }
345 1.1 christos
346 1.1 christos static void
347 1.1 christos doc_matchname(cfg_printer_t *pctx, const cfg_type_t *type) {
348 1.1 christos cfg_print_cstr(pctx, "[ ");
349 1.1 christos cfg_doc_obj(pctx, type->of);
350 1.1 christos cfg_print_cstr(pctx, " ]");
351 1.1 christos }
352 1.1 christos
353 1.8 christos static const char *matchtype_enums[] = { "6to4-self",
354 1.8 christos "external",
355 1.8 christos "krb5-self",
356 1.8 christos "krb5-selfsub",
357 1.8 christos "krb5-subdomain",
358 1.15 christos "krb5-subdomain-self-rhs",
359 1.8 christos "ms-self",
360 1.8 christos "ms-selfsub",
361 1.8 christos "ms-subdomain",
362 1.15 christos "ms-subdomain-self-rhs",
363 1.8 christos "name",
364 1.8 christos "self",
365 1.8 christos "selfsub",
366 1.8 christos "selfwild",
367 1.8 christos "subdomain",
368 1.8 christos "tcp-self",
369 1.8 christos "wildcard",
370 1.8 christos "zonesub",
371 1.8 christos NULL };
372 1.8 christos
373 1.8 christos static cfg_type_t cfg_type_matchtype = { "matchtype", parse_matchtype,
374 1.8 christos cfg_print_ustring, cfg_doc_enum,
375 1.8 christos &cfg_rep_string, &matchtype_enums };
376 1.1 christos
377 1.1 christos static cfg_type_t cfg_type_matchname = {
378 1.1 christos "optional_matchname", parse_matchname, cfg_print_ustring,
379 1.8 christos doc_matchname, &cfg_rep_tuple, &cfg_type_ustring
380 1.1 christos };
381 1.1 christos
382 1.1 christos /*%
383 1.1 christos * A grant statement, used in the update policy.
384 1.1 christos */
385 1.1 christos static cfg_tuplefielddef_t grant_fields[] = {
386 1.1 christos { "mode", &cfg_type_mode, 0 },
387 1.1 christos { "identity", &cfg_type_astring, 0 }, /* domain name */
388 1.1 christos { "matchtype", &cfg_type_matchtype, 0 },
389 1.1 christos { "name", &cfg_type_matchname, 0 }, /* domain name */
390 1.1 christos { "types", &cfg_type_rrtypelist, 0 },
391 1.1 christos { NULL, NULL, 0 }
392 1.1 christos };
393 1.8 christos static cfg_type_t cfg_type_grant = { "grant", cfg_parse_tuple,
394 1.8 christos cfg_print_tuple, cfg_doc_tuple,
395 1.8 christos &cfg_rep_tuple, grant_fields };
396 1.1 christos
397 1.1 christos static cfg_type_t cfg_type_updatepolicy = {
398 1.8 christos "update_policy", parse_updatepolicy, print_updatepolicy,
399 1.8 christos doc_updatepolicy, &cfg_rep_list, &cfg_type_grant
400 1.1 christos };
401 1.1 christos
402 1.1 christos static isc_result_t
403 1.1 christos parse_updatepolicy(cfg_parser_t *pctx, const cfg_type_t *type,
404 1.8 christos cfg_obj_t **ret) {
405 1.1 christos isc_result_t result;
406 1.1 christos CHECK(cfg_gettoken(pctx, 0));
407 1.1 christos if (pctx->token.type == isc_tokentype_special &&
408 1.8 christos pctx->token.value.as_char == '{')
409 1.8 christos {
410 1.1 christos cfg_ungettoken(pctx);
411 1.15.2.1 perseant return cfg_parse_bracketed_list(pctx, type, ret);
412 1.1 christos }
413 1.1 christos
414 1.1 christos if (pctx->token.type == isc_tokentype_string &&
415 1.8 christos strcasecmp(TOKEN_STRING(pctx), "local") == 0)
416 1.8 christos {
417 1.1 christos cfg_obj_t *obj = NULL;
418 1.1 christos CHECK(cfg_create_obj(pctx, &cfg_type_ustring, &obj));
419 1.1 christos obj->value.string.length = strlen("local");
420 1.8 christos obj->value.string.base =
421 1.8 christos isc_mem_get(pctx->mctx, obj->value.string.length + 1);
422 1.1 christos memmove(obj->value.string.base, "local", 5);
423 1.1 christos obj->value.string.base[5] = '\0';
424 1.1 christos *ret = obj;
425 1.15.2.1 perseant return ISC_R_SUCCESS;
426 1.1 christos }
427 1.1 christos
428 1.1 christos cfg_ungettoken(pctx);
429 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
430 1.1 christos
431 1.8 christos cleanup:
432 1.15.2.1 perseant return result;
433 1.1 christos }
434 1.1 christos
435 1.1 christos static void
436 1.1 christos print_updatepolicy(cfg_printer_t *pctx, const cfg_obj_t *obj) {
437 1.8 christos if (cfg_obj_isstring(obj)) {
438 1.1 christos cfg_print_ustring(pctx, obj);
439 1.8 christos } else {
440 1.1 christos cfg_print_bracketed_list(pctx, obj);
441 1.8 christos }
442 1.1 christos }
443 1.1 christos
444 1.1 christos static void
445 1.1 christos doc_updatepolicy(cfg_printer_t *pctx, const cfg_type_t *type) {
446 1.1 christos cfg_print_cstr(pctx, "( local | { ");
447 1.1 christos cfg_doc_obj(pctx, type->of);
448 1.14 christos cfg_print_cstr(pctx, "; ... } )");
449 1.1 christos }
450 1.1 christos
451 1.1 christos /*%
452 1.1 christos * A view statement.
453 1.1 christos */
454 1.1 christos static cfg_tuplefielddef_t view_fields[] = {
455 1.1 christos { "name", &cfg_type_astring, 0 },
456 1.1 christos { "class", &cfg_type_optional_class, 0 },
457 1.1 christos { "options", &cfg_type_viewopts, 0 },
458 1.1 christos { NULL, NULL, 0 }
459 1.1 christos };
460 1.8 christos static cfg_type_t cfg_type_view = { "view", cfg_parse_tuple,
461 1.8 christos cfg_print_tuple, cfg_doc_tuple,
462 1.8 christos &cfg_rep_tuple, view_fields };
463 1.1 christos
464 1.1 christos /*%
465 1.1 christos * A zone statement.
466 1.1 christos */
467 1.1 christos static cfg_tuplefielddef_t zone_fields[] = {
468 1.1 christos { "name", &cfg_type_astring, 0 },
469 1.1 christos { "class", &cfg_type_optional_class, 0 },
470 1.1 christos { "options", &cfg_type_zoneopts, 0 },
471 1.1 christos { NULL, NULL, 0 }
472 1.1 christos };
473 1.8 christos static cfg_type_t cfg_type_zone = { "zone", cfg_parse_tuple,
474 1.8 christos cfg_print_tuple, cfg_doc_tuple,
475 1.8 christos &cfg_rep_tuple, zone_fields };
476 1.8 christos
477 1.8 christos /*%
478 1.8 christos * A dnssec-policy statement.
479 1.8 christos */
480 1.8 christos static cfg_tuplefielddef_t dnssecpolicy_fields[] = {
481 1.8 christos { "name", &cfg_type_astring, 0 },
482 1.8 christos { "options", &cfg_type_dnssecpolicyopts, 0 },
483 1.8 christos { NULL, NULL, 0 }
484 1.8 christos };
485 1.8 christos static cfg_type_t cfg_type_dnssecpolicy = {
486 1.8 christos "dnssec-policy", cfg_parse_tuple, cfg_print_tuple,
487 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, dnssecpolicy_fields
488 1.1 christos };
489 1.1 christos
490 1.1 christos /*%
491 1.1 christos * A "category" clause in the "logging" statement.
492 1.1 christos */
493 1.1 christos static cfg_tuplefielddef_t category_fields[] = {
494 1.1 christos { "name", &cfg_type_astring, 0 },
495 1.8 christos { "destinations", &cfg_type_destinationlist, 0 },
496 1.1 christos { NULL, NULL, 0 }
497 1.1 christos };
498 1.8 christos static cfg_type_t cfg_type_category = { "category", cfg_parse_tuple,
499 1.8 christos cfg_print_tuple, cfg_doc_tuple,
500 1.8 christos &cfg_rep_tuple, category_fields };
501 1.8 christos
502 1.8 christos static isc_result_t
503 1.8 christos parse_maxduration(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
504 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_duration, ret);
505 1.8 christos }
506 1.8 christos
507 1.8 christos static void
508 1.8 christos doc_maxduration(cfg_printer_t *pctx, const cfg_type_t *type) {
509 1.8 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_duration);
510 1.8 christos }
511 1.8 christos
512 1.8 christos /*%
513 1.8 christos * A duration or "unlimited", but not "default".
514 1.8 christos */
515 1.8 christos static const char *maxduration_enums[] = { "unlimited", NULL };
516 1.8 christos static cfg_type_t cfg_type_maxduration = {
517 1.8 christos "maxduration_no_default", parse_maxduration, cfg_print_ustring,
518 1.8 christos doc_maxduration, &cfg_rep_duration, maxduration_enums
519 1.1 christos };
520 1.1 christos
521 1.1 christos /*%
522 1.1 christos * A dnssec key, as used in the "trusted-keys" statement.
523 1.1 christos */
524 1.1 christos static cfg_tuplefielddef_t dnsseckey_fields[] = {
525 1.1 christos { "name", &cfg_type_astring, 0 },
526 1.8 christos { "anchortype", &cfg_type_void, 0 },
527 1.8 christos { "rdata1", &cfg_type_uint32, 0 },
528 1.8 christos { "rdata2", &cfg_type_uint32, 0 },
529 1.8 christos { "rdata3", &cfg_type_uint32, 0 },
530 1.8 christos { "data", &cfg_type_qstring, 0 },
531 1.1 christos { NULL, NULL, 0 }
532 1.1 christos };
533 1.8 christos static cfg_type_t cfg_type_dnsseckey = { "dnsseckey", cfg_parse_tuple,
534 1.8 christos cfg_print_tuple, cfg_doc_tuple,
535 1.8 christos &cfg_rep_tuple, dnsseckey_fields };
536 1.8 christos
537 1.8 christos /*%
538 1.8 christos * Optional enums.
539 1.8 christos *
540 1.8 christos */
541 1.8 christos static isc_result_t
542 1.8 christos parse_optional_enum(cfg_parser_t *pctx, const cfg_type_t *type,
543 1.8 christos cfg_obj_t **ret) {
544 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_void, ret);
545 1.8 christos }
546 1.8 christos
547 1.8 christos static void
548 1.8 christos doc_optional_enum(cfg_printer_t *pctx, const cfg_type_t *type) {
549 1.8 christos UNUSED(type);
550 1.8 christos cfg_print_cstr(pctx, "[ ");
551 1.8 christos cfg_doc_enum(pctx, type);
552 1.8 christos cfg_print_cstr(pctx, " ]");
553 1.8 christos }
554 1.1 christos
555 1.1 christos /*%
556 1.8 christos * A key initialization specifier, as used in the
557 1.8 christos * "trust-anchors" (or synonymous "managed-keys") statement.
558 1.1 christos */
559 1.8 christos static const char *anchortype_enums[] = { "static-key", "initial-key",
560 1.8 christos "static-ds", "initial-ds", NULL };
561 1.8 christos static cfg_type_t cfg_type_anchortype = { "anchortype", cfg_parse_enum,
562 1.8 christos cfg_print_ustring, cfg_doc_enum,
563 1.8 christos &cfg_rep_string, anchortype_enums };
564 1.1 christos static cfg_tuplefielddef_t managedkey_fields[] = {
565 1.1 christos { "name", &cfg_type_astring, 0 },
566 1.8 christos { "anchortype", &cfg_type_anchortype, 0 },
567 1.8 christos { "rdata1", &cfg_type_uint32, 0 },
568 1.8 christos { "rdata2", &cfg_type_uint32, 0 },
569 1.8 christos { "rdata3", &cfg_type_uint32, 0 },
570 1.8 christos { "data", &cfg_type_qstring, 0 },
571 1.1 christos { NULL, NULL, 0 }
572 1.1 christos };
573 1.8 christos static cfg_type_t cfg_type_managedkey = { "managedkey", cfg_parse_tuple,
574 1.8 christos cfg_print_tuple, cfg_doc_tuple,
575 1.8 christos &cfg_rep_tuple, managedkey_fields };
576 1.8 christos
577 1.8 christos /*%
578 1.8 christos * DNSSEC key roles.
579 1.8 christos */
580 1.8 christos static const char *dnsseckeyrole_enums[] = { "csk", "ksk", "zsk", NULL };
581 1.8 christos static cfg_type_t cfg_type_dnsseckeyrole = {
582 1.8 christos "dnssec-key-role", cfg_parse_enum, cfg_print_ustring,
583 1.8 christos cfg_doc_enum, &cfg_rep_string, &dnsseckeyrole_enums
584 1.8 christos };
585 1.8 christos
586 1.8 christos /*%
587 1.8 christos * DNSSEC key storage types.
588 1.8 christos */
589 1.15.2.1 perseant static keyword_type_t keystore_kw = { "key-store", &cfg_type_astring };
590 1.15.2.1 perseant static cfg_type_t cfg_type_keystorage = { "keystorage", parse_keyvalue,
591 1.15.2.1 perseant print_keyvalue, doc_keyvalue,
592 1.15.2.1 perseant &cfg_rep_string, &keystore_kw };
593 1.15.2.1 perseant
594 1.15.2.1 perseant static isc_result_t
595 1.15.2.1 perseant parse_keystore(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
596 1.15.2.1 perseant isc_result_t result;
597 1.15.2.1 perseant cfg_obj_t *obj = NULL;
598 1.15.2.1 perseant
599 1.15.2.1 perseant UNUSED(type);
600 1.15.2.1 perseant
601 1.15.2.1 perseant CHECK(cfg_peektoken(pctx, 0));
602 1.15.2.1 perseant if (pctx->token.type == isc_tokentype_string &&
603 1.15.2.1 perseant strcasecmp(TOKEN_STRING(pctx), "key-directory") == 0)
604 1.15.2.1 perseant {
605 1.15.2.1 perseant CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, &obj));
606 1.15.2.1 perseant } else if (pctx->token.type == isc_tokentype_string &&
607 1.15.2.1 perseant strcasecmp(TOKEN_STRING(pctx), "key-store") == 0)
608 1.15.2.1 perseant {
609 1.15.2.1 perseant CHECK(cfg_parse_obj(pctx, &cfg_type_keystorage, &obj));
610 1.15.2.1 perseant } else {
611 1.15.2.1 perseant CHECK(cfg_parse_void(pctx, NULL, &obj));
612 1.15.2.1 perseant }
613 1.15.2.1 perseant
614 1.15.2.1 perseant *ret = obj;
615 1.15.2.1 perseant cleanup:
616 1.15.2.1 perseant return result;
617 1.15.2.1 perseant }
618 1.15.2.1 perseant
619 1.15.2.1 perseant static void
620 1.15.2.1 perseant doc_keystore(cfg_printer_t *pctx, const cfg_type_t *type) {
621 1.15.2.1 perseant UNUSED(type);
622 1.15.2.1 perseant
623 1.15.2.1 perseant cfg_print_cstr(pctx, "[ key-directory | key-store <string> ]");
624 1.15.2.1 perseant }
625 1.15.2.1 perseant
626 1.15.2.1 perseant static void
627 1.15.2.1 perseant print_keystore(cfg_printer_t *pctx, const cfg_obj_t *obj) {
628 1.15.2.1 perseant REQUIRE(pctx != NULL);
629 1.15.2.1 perseant REQUIRE(obj != NULL);
630 1.15.2.1 perseant REQUIRE(obj->type->rep == &cfg_rep_string);
631 1.15.2.1 perseant
632 1.15.2.1 perseant if (strcasecmp(cfg_obj_asstring(obj), "key-directory") != 0) {
633 1.15.2.1 perseant cfg_print_cstr(pctx, "key-store ");
634 1.15.2.1 perseant }
635 1.15.2.1 perseant cfg_print_ustring(pctx, obj);
636 1.15.2.1 perseant }
637 1.15.2.1 perseant
638 1.15.2.1 perseant static cfg_type_t cfg_type_optional_keystore = {
639 1.15.2.1 perseant "optionalkeystorage", parse_keystore, print_keystore,
640 1.15.2.1 perseant doc_keystore, &cfg_rep_string, &keystore_kw
641 1.8 christos };
642 1.8 christos
643 1.8 christos /*%
644 1.8 christos * A dnssec key, as used in the "keys" statement in a "dnssec-policy".
645 1.8 christos */
646 1.8 christos static keyword_type_t algorithm_kw = { "algorithm", &cfg_type_ustring };
647 1.8 christos static cfg_type_t cfg_type_algorithm = { "algorithm", parse_keyvalue,
648 1.8 christos print_keyvalue, doc_keyvalue,
649 1.8 christos &cfg_rep_string, &algorithm_kw };
650 1.8 christos
651 1.8 christos static keyword_type_t lifetime_kw = { "lifetime",
652 1.8 christos &cfg_type_duration_or_unlimited };
653 1.8 christos static cfg_type_t cfg_type_lifetime = { "lifetime", parse_keyvalue,
654 1.8 christos print_keyvalue, doc_keyvalue,
655 1.8 christos &cfg_rep_duration, &lifetime_kw };
656 1.15.2.1 perseant /*
657 1.15.2.1 perseant *
658 1.15.2.1 perseant */
659 1.15.2.1 perseant static void
660 1.15.2.1 perseant print_tagrange(cfg_printer_t *pctx, const cfg_obj_t *obj) {
661 1.15.2.1 perseant REQUIRE(pctx != NULL);
662 1.15.2.1 perseant REQUIRE(obj != NULL);
663 1.15.2.1 perseant REQUIRE(obj->type->rep == &cfg_rep_tuple);
664 1.15.2.1 perseant
665 1.15.2.1 perseant if (cfg_obj_istuple(obj)) {
666 1.15.2.1 perseant cfg_print_cstr(pctx, "tag-range ");
667 1.15.2.1 perseant cfg_print_tuple(pctx, obj);
668 1.15.2.1 perseant }
669 1.15.2.1 perseant }
670 1.15.2.1 perseant
671 1.15.2.1 perseant static cfg_tuplefielddef_t tagrange_fields[] = {
672 1.15.2.1 perseant { "tag-min", &cfg_type_uint32, 0 },
673 1.15.2.1 perseant { "tag-max", &cfg_type_uint32, 0 },
674 1.15.2.1 perseant { NULL, NULL, 0 }
675 1.15.2.1 perseant };
676 1.15.2.1 perseant
677 1.15.2.1 perseant static cfg_type_t cfg_type_tagrange = { "tagrange", cfg_parse_tuple,
678 1.15.2.1 perseant print_tagrange, cfg_doc_tuple,
679 1.15.2.1 perseant &cfg_rep_tuple, tagrange_fields };
680 1.15.2.1 perseant
681 1.15.2.1 perseant static keyword_type_t tagrange_kw = { "tag-range", &cfg_type_tagrange };
682 1.15.2.1 perseant static void
683 1.15.2.1 perseant doc_optionaltagrange(cfg_printer_t *pctx, const cfg_type_t *type) {
684 1.15.2.1 perseant UNUSED(type);
685 1.15.2.1 perseant
686 1.15.2.1 perseant cfg_print_cstr(pctx, "[ tag-range <integer> <integer> ]");
687 1.15.2.1 perseant }
688 1.15.2.1 perseant
689 1.15.2.1 perseant static isc_result_t
690 1.15.2.1 perseant parse_optionaltagrange(cfg_parser_t *pctx, const cfg_type_t *type,
691 1.15.2.1 perseant cfg_obj_t **ret) {
692 1.15.2.1 perseant isc_result_t result;
693 1.15.2.1 perseant cfg_obj_t *obj = NULL;
694 1.15.2.1 perseant
695 1.15.2.1 perseant UNUSED(type);
696 1.15.2.1 perseant
697 1.15.2.1 perseant CHECK(cfg_peektoken(pctx, 0));
698 1.15.2.1 perseant if (pctx->token.type == isc_tokentype_string &&
699 1.15.2.1 perseant strcasecmp(TOKEN_STRING(pctx), "tag-range") == 0)
700 1.15.2.1 perseant {
701 1.15.2.1 perseant CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
702 1.15.2.1 perseant CHECK(cfg_parse_obj(pctx, &cfg_type_tagrange, &obj));
703 1.15.2.1 perseant } else {
704 1.15.2.1 perseant CHECK(cfg_parse_void(pctx, NULL, &obj));
705 1.15.2.1 perseant }
706 1.15.2.1 perseant
707 1.15.2.1 perseant *ret = obj;
708 1.15.2.1 perseant cleanup:
709 1.15.2.1 perseant return result;
710 1.15.2.1 perseant }
711 1.15.2.1 perseant
712 1.15.2.1 perseant static cfg_type_t cfg_type_optional_tagrange = {
713 1.15.2.1 perseant "optionaltagrange", parse_optionaltagrange, NULL,
714 1.15.2.1 perseant doc_optionaltagrange, &cfg_rep_tuple, &tagrange_kw
715 1.15.2.1 perseant };
716 1.8 christos
717 1.8 christos static cfg_tuplefielddef_t kaspkey_fields[] = {
718 1.8 christos { "role", &cfg_type_dnsseckeyrole, 0 },
719 1.15.2.1 perseant { "keystorage", &cfg_type_optional_keystore, 0 },
720 1.8 christos { "lifetime", &cfg_type_lifetime, 0 },
721 1.8 christos { "algorithm", &cfg_type_algorithm, 0 },
722 1.15.2.1 perseant { "tag-range", &cfg_type_optional_tagrange, 0 },
723 1.8 christos { "length", &cfg_type_optional_uint32, 0 },
724 1.8 christos { NULL, NULL, 0 }
725 1.1 christos };
726 1.8 christos static cfg_type_t cfg_type_kaspkey = { "kaspkey", cfg_parse_tuple,
727 1.8 christos cfg_print_tuple, cfg_doc_tuple,
728 1.8 christos &cfg_rep_tuple, kaspkey_fields };
729 1.1 christos
730 1.8 christos /*%
731 1.9 christos * NSEC3 parameters.
732 1.9 christos */
733 1.9 christos static keyword_type_t nsec3iter_kw = { "iterations", &cfg_type_uint32 };
734 1.9 christos static cfg_type_t cfg_type_nsec3iter = {
735 1.9 christos "iterations", parse_optional_keyvalue, print_keyvalue,
736 1.9 christos doc_optional_keyvalue, &cfg_rep_uint32, &nsec3iter_kw
737 1.9 christos };
738 1.9 christos
739 1.9 christos static keyword_type_t nsec3optout_kw = { "optout", &cfg_type_boolean };
740 1.9 christos static cfg_type_t cfg_type_nsec3optout = {
741 1.9 christos "optout", parse_optional_keyvalue,
742 1.9 christos print_keyvalue, doc_optional_keyvalue,
743 1.9 christos &cfg_rep_boolean, &nsec3optout_kw
744 1.9 christos };
745 1.9 christos
746 1.9 christos static keyword_type_t nsec3salt_kw = { "salt-length", &cfg_type_uint32 };
747 1.9 christos static cfg_type_t cfg_type_nsec3salt = {
748 1.9 christos "salt-length", parse_optional_keyvalue, print_keyvalue,
749 1.9 christos doc_optional_keyvalue, &cfg_rep_uint32, &nsec3salt_kw
750 1.9 christos };
751 1.9 christos
752 1.9 christos static cfg_tuplefielddef_t nsec3param_fields[] = {
753 1.9 christos { "iterations", &cfg_type_nsec3iter, 0 },
754 1.9 christos { "optout", &cfg_type_nsec3optout, 0 },
755 1.9 christos { "salt-length", &cfg_type_nsec3salt, 0 },
756 1.9 christos { NULL, NULL, 0 }
757 1.9 christos };
758 1.9 christos
759 1.9 christos static cfg_type_t cfg_type_nsec3 = { "nsec3param", cfg_parse_tuple,
760 1.9 christos cfg_print_tuple, cfg_doc_tuple,
761 1.9 christos &cfg_rep_tuple, nsec3param_fields };
762 1.9 christos
763 1.9 christos /*%
764 1.8 christos * Wild class, type, name.
765 1.8 christos */
766 1.1 christos static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring };
767 1.1 christos
768 1.1 christos static cfg_type_t cfg_type_optional_wild_class = {
769 1.1 christos "optional_wild_class", parse_optional_keyvalue, print_keyvalue,
770 1.8 christos doc_optional_keyvalue, &cfg_rep_string, &wild_class_kw
771 1.1 christos };
772 1.1 christos
773 1.1 christos static keyword_type_t wild_type_kw = { "type", &cfg_type_ustring };
774 1.1 christos
775 1.1 christos static cfg_type_t cfg_type_optional_wild_type = {
776 1.8 christos "optional_wild_type", parse_optional_keyvalue, print_keyvalue,
777 1.8 christos doc_optional_keyvalue, &cfg_rep_string, &wild_type_kw
778 1.1 christos };
779 1.1 christos
780 1.1 christos static keyword_type_t wild_name_kw = { "name", &cfg_type_qstring };
781 1.1 christos
782 1.1 christos static cfg_type_t cfg_type_optional_wild_name = {
783 1.8 christos "optional_wild_name", parse_optional_keyvalue, print_keyvalue,
784 1.8 christos doc_optional_keyvalue, &cfg_rep_string, &wild_name_kw
785 1.1 christos };
786 1.1 christos
787 1.1 christos /*%
788 1.1 christos * An rrset ordering element.
789 1.1 christos */
790 1.1 christos static cfg_tuplefielddef_t rrsetorderingelement_fields[] = {
791 1.1 christos { "class", &cfg_type_optional_wild_class, 0 },
792 1.1 christos { "type", &cfg_type_optional_wild_type, 0 },
793 1.1 christos { "name", &cfg_type_optional_wild_name, 0 },
794 1.1 christos { "order", &cfg_type_ustring, 0 }, /* must be literal "order" */
795 1.1 christos { "ordering", &cfg_type_ustring, 0 },
796 1.1 christos { NULL, NULL, 0 }
797 1.1 christos };
798 1.1 christos static cfg_type_t cfg_type_rrsetorderingelement = {
799 1.1 christos "rrsetorderingelement", cfg_parse_tuple, cfg_print_tuple,
800 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, rrsetorderingelement_fields
801 1.1 christos };
802 1.1 christos
803 1.1 christos /*%
804 1.1 christos * A global or view "check-names" option. Note that the zone
805 1.1 christos * "check-names" option has a different syntax.
806 1.1 christos */
807 1.1 christos
808 1.8 christos static const char *checktype_enums[] = { "primary", "master", "secondary",
809 1.8 christos "slave", "response", NULL };
810 1.8 christos static cfg_type_t cfg_type_checktype = { "checktype", cfg_parse_enum,
811 1.8 christos cfg_print_ustring, cfg_doc_enum,
812 1.8 christos &cfg_rep_string, &checktype_enums };
813 1.1 christos
814 1.1 christos static const char *checkmode_enums[] = { "fail", "warn", "ignore", NULL };
815 1.8 christos static cfg_type_t cfg_type_checkmode = { "checkmode", cfg_parse_enum,
816 1.8 christos cfg_print_ustring, cfg_doc_enum,
817 1.8 christos &cfg_rep_string, &checkmode_enums };
818 1.1 christos
819 1.1 christos static const char *warn_enums[] = { "warn", "ignore", NULL };
820 1.1 christos static cfg_type_t cfg_type_warn = {
821 1.8 christos "warn", cfg_parse_enum, cfg_print_ustring,
822 1.8 christos cfg_doc_enum, &cfg_rep_string, &warn_enums
823 1.1 christos };
824 1.1 christos
825 1.1 christos static cfg_tuplefielddef_t checknames_fields[] = {
826 1.1 christos { "type", &cfg_type_checktype, 0 },
827 1.1 christos { "mode", &cfg_type_checkmode, 0 },
828 1.1 christos { NULL, NULL, 0 }
829 1.1 christos };
830 1.1 christos
831 1.8 christos static cfg_type_t cfg_type_checknames = { "checknames", cfg_parse_tuple,
832 1.8 christos cfg_print_tuple, cfg_doc_tuple,
833 1.8 christos &cfg_rep_tuple, checknames_fields };
834 1.1 christos
835 1.8 christos static cfg_type_t cfg_type_bracketed_netaddrlist = { "bracketed_netaddrlist",
836 1.8 christos cfg_parse_bracketed_list,
837 1.8 christos cfg_print_bracketed_list,
838 1.8 christos cfg_doc_bracketed_list,
839 1.8 christos &cfg_rep_list,
840 1.8 christos &cfg_type_netaddr };
841 1.1 christos
842 1.15.2.1 perseant static cfg_type_t cfg_type_bracketed_sockaddrtlslist = {
843 1.15.2.1 perseant "bracketed_sockaddrtlslist",
844 1.15.2.1 perseant cfg_parse_bracketed_list,
845 1.15.2.1 perseant cfg_print_bracketed_list,
846 1.15.2.1 perseant cfg_doc_bracketed_list,
847 1.15.2.1 perseant &cfg_rep_list,
848 1.15.2.1 perseant &cfg_type_sockaddrtls
849 1.15.2.1 perseant };
850 1.15.2.1 perseant
851 1.8 christos static const char *autodnssec_enums[] = { "allow", "maintain", "off", NULL };
852 1.1 christos static cfg_type_t cfg_type_autodnssec = {
853 1.8 christos "autodnssec", cfg_parse_enum, cfg_print_ustring,
854 1.8 christos cfg_doc_enum, &cfg_rep_string, &autodnssec_enums
855 1.1 christos };
856 1.1 christos
857 1.8 christos static const char *dnssecupdatemode_enums[] = { "maintain", "no-resign", NULL };
858 1.1 christos static cfg_type_t cfg_type_dnssecupdatemode = {
859 1.8 christos "dnssecupdatemode", cfg_parse_enum, cfg_print_ustring,
860 1.8 christos cfg_doc_enum, &cfg_rep_string, &dnssecupdatemode_enums
861 1.1 christos };
862 1.1 christos
863 1.8 christos static const char *updatemethods_enums[] = { "date", "increment", "unixtime",
864 1.8 christos NULL };
865 1.1 christos static cfg_type_t cfg_type_updatemethod = {
866 1.8 christos "updatemethod", cfg_parse_enum, cfg_print_ustring,
867 1.8 christos cfg_doc_enum, &cfg_rep_string, &updatemethods_enums
868 1.1 christos };
869 1.1 christos
870 1.1 christos /*
871 1.1 christos * zone-statistics: full, terse, or none.
872 1.1 christos *
873 1.1 christos * for backward compatibility, we also support boolean values.
874 1.1 christos * yes represents "full", no represents "terse". in the future we
875 1.1 christos * may change no to mean "none".
876 1.1 christos */
877 1.1 christos static const char *zonestat_enums[] = { "full", "terse", "none", NULL };
878 1.1 christos static isc_result_t
879 1.1 christos parse_zonestat(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
880 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
881 1.1 christos }
882 1.1 christos static void
883 1.1 christos doc_zonestat(cfg_printer_t *pctx, const cfg_type_t *type) {
884 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
885 1.1 christos }
886 1.8 christos static cfg_type_t cfg_type_zonestat = { "zonestat", parse_zonestat,
887 1.8 christos cfg_print_ustring, doc_zonestat,
888 1.8 christos &cfg_rep_string, zonestat_enums };
889 1.8 christos
890 1.8 christos static cfg_type_t cfg_type_rrsetorder = { "rrsetorder",
891 1.8 christos cfg_parse_bracketed_list,
892 1.8 christos cfg_print_bracketed_list,
893 1.8 christos cfg_doc_bracketed_list,
894 1.8 christos &cfg_rep_list,
895 1.8 christos &cfg_type_rrsetorderingelement };
896 1.1 christos
897 1.1 christos static keyword_type_t port_kw = { "port", &cfg_type_uint32 };
898 1.1 christos
899 1.1 christos static cfg_type_t cfg_type_optional_port = {
900 1.8 christos "optional_port", parse_optional_keyvalue, print_keyvalue,
901 1.8 christos doc_optional_keyvalue, &cfg_rep_uint32, &port_kw
902 1.1 christos };
903 1.1 christos
904 1.1 christos /*% A list of keys, as in the "key" clause of the controls statement. */
905 1.8 christos static cfg_type_t cfg_type_keylist = { "keylist",
906 1.8 christos cfg_parse_bracketed_list,
907 1.8 christos cfg_print_bracketed_list,
908 1.8 christos cfg_doc_bracketed_list,
909 1.8 christos &cfg_rep_list,
910 1.8 christos &cfg_type_astring };
911 1.8 christos
912 1.8 christos /*% A list of dnssec keys, as in "trusted-keys". Deprecated. */
913 1.8 christos static cfg_type_t cfg_type_trustedkeys = { "trustedkeys",
914 1.8 christos cfg_parse_bracketed_list,
915 1.8 christos cfg_print_bracketed_list,
916 1.8 christos cfg_doc_bracketed_list,
917 1.8 christos &cfg_rep_list,
918 1.8 christos &cfg_type_dnsseckey };
919 1.8 christos
920 1.8 christos /*%
921 1.8 christos * A list of managed trust anchors. Each entry contains a name, a keyword
922 1.8 christos * ("static-key", initial-key", "static-ds" or "initial-ds"), and the
923 1.8 christos * fields associated with either a DNSKEY or a DS record.
924 1.8 christos */
925 1.8 christos static cfg_type_t cfg_type_dnsseckeys = { "dnsseckeys",
926 1.8 christos cfg_parse_bracketed_list,
927 1.8 christos cfg_print_bracketed_list,
928 1.8 christos cfg_doc_bracketed_list,
929 1.8 christos &cfg_rep_list,
930 1.8 christos &cfg_type_managedkey };
931 1.8 christos
932 1.8 christos /*%
933 1.8 christos * A list of key entries, used in a DNSSEC Key and Signing Policy.
934 1.8 christos */
935 1.8 christos static cfg_type_t cfg_type_kaspkeys = { "kaspkeys",
936 1.8 christos cfg_parse_bracketed_list,
937 1.8 christos cfg_print_bracketed_list,
938 1.8 christos cfg_doc_bracketed_list,
939 1.8 christos &cfg_rep_list,
940 1.8 christos &cfg_type_kaspkey };
941 1.1 christos
942 1.1 christos static const char *forwardtype_enums[] = { "first", "only", NULL };
943 1.1 christos static cfg_type_t cfg_type_forwardtype = {
944 1.8 christos "forwardtype", cfg_parse_enum, cfg_print_ustring,
945 1.8 christos cfg_doc_enum, &cfg_rep_string, &forwardtype_enums
946 1.1 christos };
947 1.1 christos
948 1.15.2.1 perseant static const char *zonetype_enums[] = { "primary", "master", "secondary",
949 1.15.2.1 perseant "slave", "mirror", "forward",
950 1.15.2.1 perseant "hint", "redirect", "static-stub",
951 1.15.2.1 perseant "stub", NULL };
952 1.8 christos static cfg_type_t cfg_type_zonetype = { "zonetype", cfg_parse_enum,
953 1.8 christos cfg_print_ustring, cfg_doc_enum,
954 1.8 christos &cfg_rep_string, &zonetype_enums };
955 1.8 christos
956 1.8 christos static const char *loglevel_enums[] = { "critical", "error", "warning",
957 1.8 christos "notice", "info", "dynamic",
958 1.8 christos NULL };
959 1.8 christos static cfg_type_t cfg_type_loglevel = { "loglevel", cfg_parse_enum,
960 1.8 christos cfg_print_ustring, cfg_doc_enum,
961 1.8 christos &cfg_rep_string, &loglevel_enums };
962 1.1 christos
963 1.8 christos static const char *transferformat_enums[] = { "many-answers", "one-answer",
964 1.8 christos NULL };
965 1.1 christos static cfg_type_t cfg_type_transferformat = {
966 1.8 christos "transferformat", cfg_parse_enum, cfg_print_ustring,
967 1.8 christos cfg_doc_enum, &cfg_rep_string, &transferformat_enums
968 1.1 christos };
969 1.1 christos
970 1.1 christos /*%
971 1.1 christos * The special keyword "none", as used in the pid-file option.
972 1.1 christos */
973 1.1 christos
974 1.1 christos static void
975 1.1 christos print_none(cfg_printer_t *pctx, const cfg_obj_t *obj) {
976 1.1 christos UNUSED(obj);
977 1.1 christos cfg_print_cstr(pctx, "none");
978 1.1 christos }
979 1.1 christos
980 1.8 christos static cfg_type_t cfg_type_none = { "none", NULL, print_none,
981 1.8 christos NULL, &cfg_rep_void, NULL };
982 1.1 christos
983 1.1 christos /*%
984 1.1 christos * A quoted string or the special keyword "none". Used in the pid-file option.
985 1.1 christos */
986 1.1 christos static isc_result_t
987 1.1 christos parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type,
988 1.8 christos cfg_obj_t **ret) {
989 1.1 christos isc_result_t result;
990 1.1 christos
991 1.1 christos CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
992 1.1 christos if (pctx->token.type == isc_tokentype_string &&
993 1.1 christos strcasecmp(TOKEN_STRING(pctx), "none") == 0)
994 1.8 christos {
995 1.15.2.1 perseant return cfg_create_obj(pctx, &cfg_type_none, ret);
996 1.8 christos }
997 1.1 christos cfg_ungettoken(pctx);
998 1.15.2.1 perseant return cfg_parse_qstring(pctx, type, ret);
999 1.8 christos cleanup:
1000 1.15.2.1 perseant return result;
1001 1.1 christos }
1002 1.1 christos
1003 1.1 christos static void
1004 1.1 christos doc_qstringornone(cfg_printer_t *pctx, const cfg_type_t *type) {
1005 1.1 christos UNUSED(type);
1006 1.1 christos cfg_print_cstr(pctx, "( <quoted_string> | none )");
1007 1.1 christos }
1008 1.1 christos
1009 1.8 christos static cfg_type_t cfg_type_qstringornone = { "qstringornone",
1010 1.8 christos parse_qstringornone,
1011 1.8 christos NULL,
1012 1.8 christos doc_qstringornone,
1013 1.8 christos NULL,
1014 1.8 christos NULL };
1015 1.1 christos
1016 1.1 christos /*%
1017 1.1 christos * A boolean ("yes" or "no"), or the special keyword "auto".
1018 1.1 christos * Used in the dnssec-validation option.
1019 1.1 christos */
1020 1.1 christos static void
1021 1.1 christos print_auto(cfg_printer_t *pctx, const cfg_obj_t *obj) {
1022 1.1 christos UNUSED(obj);
1023 1.1 christos cfg_print_cstr(pctx, "auto");
1024 1.1 christos }
1025 1.1 christos
1026 1.8 christos static cfg_type_t cfg_type_auto = { "auto", NULL, print_auto,
1027 1.8 christos NULL, &cfg_rep_void, NULL };
1028 1.1 christos
1029 1.1 christos static isc_result_t
1030 1.1 christos parse_boolorauto(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
1031 1.1 christos isc_result_t result;
1032 1.1 christos
1033 1.1 christos CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
1034 1.1 christos if (pctx->token.type == isc_tokentype_string &&
1035 1.1 christos strcasecmp(TOKEN_STRING(pctx), "auto") == 0)
1036 1.8 christos {
1037 1.15.2.1 perseant return cfg_create_obj(pctx, &cfg_type_auto, ret);
1038 1.8 christos }
1039 1.1 christos cfg_ungettoken(pctx);
1040 1.15.2.1 perseant return cfg_parse_boolean(pctx, type, ret);
1041 1.8 christos cleanup:
1042 1.15.2.1 perseant return result;
1043 1.1 christos }
1044 1.1 christos
1045 1.1 christos static void
1046 1.1 christos print_boolorauto(cfg_printer_t *pctx, const cfg_obj_t *obj) {
1047 1.8 christos if (obj->type->rep == &cfg_rep_void) {
1048 1.1 christos cfg_print_cstr(pctx, "auto");
1049 1.8 christos } else if (obj->value.boolean) {
1050 1.1 christos cfg_print_cstr(pctx, "yes");
1051 1.8 christos } else {
1052 1.1 christos cfg_print_cstr(pctx, "no");
1053 1.8 christos }
1054 1.1 christos }
1055 1.1 christos
1056 1.1 christos static void
1057 1.1 christos doc_boolorauto(cfg_printer_t *pctx, const cfg_type_t *type) {
1058 1.1 christos UNUSED(type);
1059 1.1 christos cfg_print_cstr(pctx, "( yes | no | auto )");
1060 1.1 christos }
1061 1.1 christos
1062 1.1 christos static cfg_type_t cfg_type_boolorauto = {
1063 1.8 christos "boolorauto", parse_boolorauto, print_boolorauto, doc_boolorauto, NULL,
1064 1.8 christos NULL
1065 1.1 christos };
1066 1.1 christos
1067 1.1 christos /*%
1068 1.1 christos * keyword hostname
1069 1.1 christos */
1070 1.1 christos static void
1071 1.1 christos print_hostname(cfg_printer_t *pctx, const cfg_obj_t *obj) {
1072 1.1 christos UNUSED(obj);
1073 1.1 christos cfg_print_cstr(pctx, "hostname");
1074 1.1 christos }
1075 1.1 christos
1076 1.8 christos static cfg_type_t cfg_type_hostname = { "hostname", NULL,
1077 1.8 christos print_hostname, NULL,
1078 1.8 christos &cfg_rep_boolean, NULL };
1079 1.1 christos
1080 1.1 christos /*%
1081 1.1 christos * "server-id" argument.
1082 1.1 christos */
1083 1.1 christos
1084 1.1 christos static isc_result_t
1085 1.8 christos parse_serverid(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
1086 1.1 christos isc_result_t result;
1087 1.1 christos CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));
1088 1.1 christos if (pctx->token.type == isc_tokentype_string &&
1089 1.1 christos strcasecmp(TOKEN_STRING(pctx), "none") == 0)
1090 1.8 christos {
1091 1.15.2.1 perseant return cfg_create_obj(pctx, &cfg_type_none, ret);
1092 1.8 christos }
1093 1.1 christos if (pctx->token.type == isc_tokentype_string &&
1094 1.8 christos strcasecmp(TOKEN_STRING(pctx), "hostname") == 0)
1095 1.8 christos {
1096 1.1 christos result = cfg_create_obj(pctx, &cfg_type_hostname, ret);
1097 1.8 christos if (result == ISC_R_SUCCESS) {
1098 1.3 christos (*ret)->value.boolean = true;
1099 1.8 christos }
1100 1.15.2.1 perseant return result;
1101 1.1 christos }
1102 1.1 christos cfg_ungettoken(pctx);
1103 1.15.2.1 perseant return cfg_parse_qstring(pctx, type, ret);
1104 1.8 christos cleanup:
1105 1.15.2.1 perseant return result;
1106 1.1 christos }
1107 1.1 christos
1108 1.1 christos static void
1109 1.1 christos doc_serverid(cfg_printer_t *pctx, const cfg_type_t *type) {
1110 1.1 christos UNUSED(type);
1111 1.1 christos cfg_print_cstr(pctx, "( <quoted_string> | none | hostname )");
1112 1.1 christos }
1113 1.1 christos
1114 1.8 christos static cfg_type_t cfg_type_serverid = { "serverid", parse_serverid, NULL,
1115 1.8 christos doc_serverid, NULL, NULL };
1116 1.1 christos
1117 1.1 christos /*%
1118 1.1 christos * Port list.
1119 1.1 christos */
1120 1.1 christos static void
1121 1.1 christos print_porttuple(cfg_printer_t *pctx, const cfg_obj_t *obj) {
1122 1.1 christos cfg_print_cstr(pctx, "range ");
1123 1.1 christos cfg_print_tuple(pctx, obj);
1124 1.1 christos }
1125 1.1 christos static cfg_tuplefielddef_t porttuple_fields[] = {
1126 1.1 christos { "loport", &cfg_type_uint32, 0 },
1127 1.1 christos { "hiport", &cfg_type_uint32, 0 },
1128 1.1 christos { NULL, NULL, 0 }
1129 1.1 christos };
1130 1.8 christos static cfg_type_t cfg_type_porttuple = { "porttuple", cfg_parse_tuple,
1131 1.8 christos print_porttuple, cfg_doc_tuple,
1132 1.8 christos &cfg_rep_tuple, porttuple_fields };
1133 1.1 christos
1134 1.1 christos static isc_result_t
1135 1.1 christos parse_port(cfg_parser_t *pctx, cfg_obj_t **ret) {
1136 1.1 christos isc_result_t result;
1137 1.1 christos
1138 1.1 christos CHECK(cfg_parse_uint32(pctx, NULL, ret));
1139 1.1 christos if ((*ret)->value.uint32 > 0xffff) {
1140 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid port");
1141 1.1 christos cfg_obj_destroy(pctx, ret);
1142 1.1 christos result = ISC_R_RANGE;
1143 1.1 christos }
1144 1.1 christos
1145 1.8 christos cleanup:
1146 1.15.2.1 perseant return result;
1147 1.1 christos }
1148 1.1 christos
1149 1.1 christos static isc_result_t
1150 1.1 christos parse_portrange(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
1151 1.1 christos isc_result_t result;
1152 1.1 christos cfg_obj_t *obj = NULL;
1153 1.1 christos
1154 1.1 christos UNUSED(type);
1155 1.1 christos
1156 1.1 christos CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER));
1157 1.8 christos if (pctx->token.type == isc_tokentype_number) {
1158 1.1 christos CHECK(parse_port(pctx, ret));
1159 1.8 christos } else {
1160 1.1 christos CHECK(cfg_gettoken(pctx, 0));
1161 1.1 christos if (pctx->token.type != isc_tokentype_string ||
1162 1.8 christos strcasecmp(TOKEN_STRING(pctx), "range") != 0)
1163 1.8 christos {
1164 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
1165 1.1 christos "expected integer or 'range'");
1166 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
1167 1.1 christos }
1168 1.1 christos CHECK(cfg_create_tuple(pctx, &cfg_type_porttuple, &obj));
1169 1.1 christos CHECK(parse_port(pctx, &obj->value.tuple[0]));
1170 1.1 christos CHECK(parse_port(pctx, &obj->value.tuple[1]));
1171 1.1 christos if (obj->value.tuple[0]->value.uint32 >
1172 1.14 christos obj->value.tuple[1]->value.uint32)
1173 1.14 christos {
1174 1.1 christos cfg_parser_error(pctx, CFG_LOG_NOPREP,
1175 1.1 christos "low port '%u' must not be larger "
1176 1.1 christos "than high port",
1177 1.1 christos obj->value.tuple[0]->value.uint32);
1178 1.1 christos result = ISC_R_RANGE;
1179 1.1 christos goto cleanup;
1180 1.1 christos }
1181 1.1 christos *ret = obj;
1182 1.1 christos obj = NULL;
1183 1.1 christos }
1184 1.1 christos
1185 1.8 christos cleanup:
1186 1.8 christos if (obj != NULL) {
1187 1.1 christos cfg_obj_destroy(pctx, &obj);
1188 1.8 christos }
1189 1.15.2.1 perseant return result;
1190 1.1 christos }
1191 1.1 christos
1192 1.8 christos static cfg_type_t cfg_type_portrange = { "portrange", parse_portrange,
1193 1.8 christos NULL, cfg_doc_terminal,
1194 1.8 christos NULL, NULL };
1195 1.8 christos
1196 1.15.2.1 perseant static cfg_type_t cfg_type_bracketed_portlist = { "bracketed_portlist",
1197 1.8 christos cfg_parse_bracketed_list,
1198 1.8 christos cfg_print_bracketed_list,
1199 1.8 christos cfg_doc_bracketed_list,
1200 1.8 christos &cfg_rep_list,
1201 1.8 christos &cfg_type_portrange };
1202 1.8 christos
1203 1.15.2.1 perseant static const char *cookiealg_enums[] = { "siphash24", NULL };
1204 1.8 christos static cfg_type_t cfg_type_cookiealg = { "cookiealg", cfg_parse_enum,
1205 1.8 christos cfg_print_ustring, cfg_doc_enum,
1206 1.8 christos &cfg_rep_string, &cookiealg_enums };
1207 1.1 christos
1208 1.1 christos /*%
1209 1.1 christos * fetch-quota-params
1210 1.1 christos */
1211 1.1 christos
1212 1.1 christos static cfg_tuplefielddef_t fetchquota_fields[] = {
1213 1.1 christos { "frequency", &cfg_type_uint32, 0 },
1214 1.1 christos { "low", &cfg_type_fixedpoint, 0 },
1215 1.1 christos { "high", &cfg_type_fixedpoint, 0 },
1216 1.1 christos { "discount", &cfg_type_fixedpoint, 0 },
1217 1.1 christos { NULL, NULL, 0 }
1218 1.1 christos };
1219 1.1 christos
1220 1.8 christos static cfg_type_t cfg_type_fetchquota = { "fetchquota", cfg_parse_tuple,
1221 1.8 christos cfg_print_tuple, cfg_doc_tuple,
1222 1.8 christos &cfg_rep_tuple, fetchquota_fields };
1223 1.1 christos
1224 1.1 christos /*%
1225 1.1 christos * fetches-per-server or fetches-per-zone
1226 1.1 christos */
1227 1.1 christos
1228 1.1 christos static const char *response_enums[] = { "drop", "fail", NULL };
1229 1.1 christos
1230 1.1 christos static cfg_type_t cfg_type_responsetype = {
1231 1.8 christos "responsetype", parse_optional_enum, cfg_print_ustring,
1232 1.8 christos doc_optional_enum, &cfg_rep_string, response_enums
1233 1.1 christos };
1234 1.1 christos
1235 1.1 christos static cfg_tuplefielddef_t fetchesper_fields[] = {
1236 1.1 christos { "fetches", &cfg_type_uint32, 0 },
1237 1.1 christos { "response", &cfg_type_responsetype, 0 },
1238 1.1 christos { NULL, NULL, 0 }
1239 1.1 christos };
1240 1.1 christos
1241 1.8 christos static cfg_type_t cfg_type_fetchesper = { "fetchesper", cfg_parse_tuple,
1242 1.8 christos cfg_print_tuple, cfg_doc_tuple,
1243 1.8 christos &cfg_rep_tuple, fetchesper_fields };
1244 1.1 christos
1245 1.1 christos /*%
1246 1.1 christos * Clauses that can be found within the top level of the named.conf
1247 1.1 christos * file only.
1248 1.1 christos */
1249 1.8 christos static cfg_clausedef_t namedconf_clauses[] = {
1250 1.1 christos { "acl", &cfg_type_acl, CFG_CLAUSEFLAG_MULTI },
1251 1.1 christos { "controls", &cfg_type_controls, CFG_CLAUSEFLAG_MULTI },
1252 1.8 christos { "dnssec-policy", &cfg_type_dnssecpolicy, CFG_CLAUSEFLAG_MULTI },
1253 1.15 christos #if HAVE_LIBNGHTTP2
1254 1.15 christos { "http", &cfg_type_http_description, CFG_CLAUSEFLAG_MULTI },
1255 1.15 christos #else
1256 1.15 christos { "http", &cfg_type_http_description,
1257 1.15 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NOTCONFIGURED },
1258 1.15 christos #endif
1259 1.15.2.1 perseant { "key-store", &cfg_type_keystore, CFG_CLAUSEFLAG_MULTI },
1260 1.1 christos { "logging", &cfg_type_logging, 0 },
1261 1.15 christos { "lwres", NULL, CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_ANCIENT },
1262 1.15.2.1 perseant { "masters", &cfg_type_serverlist,
1263 1.15 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NODOC },
1264 1.1 christos { "options", &cfg_type_options, 0 },
1265 1.15.2.1 perseant { "parental-agents", &cfg_type_serverlist,
1266 1.15.2.1 perseant CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NODOC },
1267 1.15.2.1 perseant { "primaries", &cfg_type_serverlist,
1268 1.15.2.1 perseant CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NODOC },
1269 1.15.2.1 perseant { "remote-servers", &cfg_type_serverlist, CFG_CLAUSEFLAG_MULTI },
1270 1.15.2.1 perseant #if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
1271 1.1 christos { "statistics-channels", &cfg_type_statschannels,
1272 1.1 christos CFG_CLAUSEFLAG_MULTI },
1273 1.15.2.1 perseant #else
1274 1.15.2.1 perseant { "statistics-channels", &cfg_type_statschannels,
1275 1.15.2.1 perseant CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NOTCONFIGURED },
1276 1.15.2.1 perseant #endif
1277 1.15 christos { "tls", &cfg_type_tlsconf, CFG_CLAUSEFLAG_MULTI },
1278 1.1 christos { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI },
1279 1.1 christos { NULL, NULL, 0 }
1280 1.1 christos };
1281 1.1 christos
1282 1.1 christos /*%
1283 1.1 christos * Clauses that can occur at the top level or in the view
1284 1.1 christos * statement, but not in the options block.
1285 1.1 christos */
1286 1.8 christos static cfg_clausedef_t namedconf_or_view_clauses[] = {
1287 1.1 christos { "dlz", &cfg_type_dlz, CFG_CLAUSEFLAG_MULTI },
1288 1.1 christos { "dyndb", &cfg_type_dyndb, CFG_CLAUSEFLAG_MULTI },
1289 1.1 christos { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI },
1290 1.8 christos { "managed-keys", &cfg_type_dnsseckeys,
1291 1.8 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_DEPRECATED },
1292 1.3 christos { "plugin", &cfg_type_plugin, CFG_CLAUSEFLAG_MULTI },
1293 1.1 christos { "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI },
1294 1.8 christos { "trust-anchors", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
1295 1.8 christos { "trusted-keys", &cfg_type_trustedkeys,
1296 1.8 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_DEPRECATED },
1297 1.15 christos { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_NODOC },
1298 1.1 christos { NULL, NULL, 0 }
1299 1.1 christos };
1300 1.1 christos
1301 1.1 christos /*%
1302 1.1 christos * Clauses that can occur in the bind.keys file.
1303 1.1 christos */
1304 1.8 christos static cfg_clausedef_t bindkeys_clauses[] = {
1305 1.8 christos { "managed-keys", &cfg_type_dnsseckeys,
1306 1.8 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_DEPRECATED },
1307 1.8 christos { "trust-anchors", &cfg_type_dnsseckeys, CFG_CLAUSEFLAG_MULTI },
1308 1.8 christos { "trusted-keys", &cfg_type_trustedkeys,
1309 1.8 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_DEPRECATED },
1310 1.1 christos { NULL, NULL, 0 }
1311 1.1 christos };
1312 1.1 christos
1313 1.1 christos static const char *fstrm_model_enums[] = { "mpsc", "spsc", NULL };
1314 1.1 christos static cfg_type_t cfg_type_fstrm_model = {
1315 1.8 christos "model", cfg_parse_enum, cfg_print_ustring,
1316 1.8 christos cfg_doc_enum, &cfg_rep_string, &fstrm_model_enums
1317 1.1 christos };
1318 1.1 christos
1319 1.1 christos /*%
1320 1.1 christos * Clauses that can be found within the 'options' statement.
1321 1.1 christos */
1322 1.8 christos static cfg_clausedef_t options_clauses[] = {
1323 1.1 christos { "answer-cookie", &cfg_type_boolean, 0 },
1324 1.1 christos { "automatic-interface-scan", &cfg_type_boolean, 0 },
1325 1.15 christos { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist,
1326 1.15 christos CFG_CLAUSEFLAG_DEPRECATED },
1327 1.15 christos { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist,
1328 1.15 christos CFG_CLAUSEFLAG_DEPRECATED },
1329 1.15.2.1 perseant { "bindkeys-file", &cfg_type_qstring, CFG_CLAUSEFLAG_TESTONLY },
1330 1.1 christos { "blackhole", &cfg_type_bracketed_aml, 0 },
1331 1.1 christos { "cookie-algorithm", &cfg_type_cookiealg, 0 },
1332 1.1 christos { "cookie-secret", &cfg_type_sstring, CFG_CLAUSEFLAG_MULTI },
1333 1.15.2.1 perseant { "coresize", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT },
1334 1.15.2.1 perseant { "datasize", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT },
1335 1.15 christos { "deallocate-on-exit", NULL, CFG_CLAUSEFLAG_ANCIENT },
1336 1.1 christos { "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
1337 1.15.2.1 perseant #ifdef USE_DNSRPS
1338 1.15.2.1 perseant { "dnsrps-library", &cfg_type_qstring, 0 },
1339 1.15.2.1 perseant #else /* ifdef USE_DNSRPS */
1340 1.15.2.1 perseant { "dnsrps-library", &cfg_type_qstring, CFG_CLAUSEFLAG_NOTCONFIGURED },
1341 1.15.2.1 perseant #endif /* ifdef USE_DNSRPS */
1342 1.1 christos #ifdef HAVE_DNSTAP
1343 1.1 christos { "dnstap-output", &cfg_type_dnstapoutput, 0 },
1344 1.1 christos { "dnstap-identity", &cfg_type_serverid, 0 },
1345 1.1 christos { "dnstap-version", &cfg_type_qstringornone, 0 },
1346 1.8 christos #else /* ifdef HAVE_DNSTAP */
1347 1.1 christos { "dnstap-output", &cfg_type_dnstapoutput,
1348 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1349 1.8 christos { "dnstap-identity", &cfg_type_serverid, CFG_CLAUSEFLAG_NOTCONFIGURED },
1350 1.1 christos { "dnstap-version", &cfg_type_qstringornone,
1351 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1352 1.8 christos #endif /* ifdef HAVE_DNSTAP */
1353 1.15.2.1 perseant { "dscp", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
1354 1.1 christos { "dump-file", &cfg_type_qstring, 0 },
1355 1.15 christos { "fake-iquery", NULL, CFG_CLAUSEFLAG_ANCIENT },
1356 1.15.2.1 perseant { "files", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT },
1357 1.1 christos { "flush-zones-on-shutdown", &cfg_type_boolean, 0 },
1358 1.1 christos #ifdef HAVE_DNSTAP
1359 1.1 christos { "fstrm-set-buffer-hint", &cfg_type_uint32, 0 },
1360 1.1 christos { "fstrm-set-flush-timeout", &cfg_type_uint32, 0 },
1361 1.1 christos { "fstrm-set-input-queue-size", &cfg_type_uint32, 0 },
1362 1.1 christos { "fstrm-set-output-notify-threshold", &cfg_type_uint32, 0 },
1363 1.1 christos { "fstrm-set-output-queue-model", &cfg_type_fstrm_model, 0 },
1364 1.1 christos { "fstrm-set-output-queue-size", &cfg_type_uint32, 0 },
1365 1.8 christos { "fstrm-set-reopen-interval", &cfg_type_duration, 0 },
1366 1.8 christos #else /* ifdef HAVE_DNSTAP */
1367 1.1 christos { "fstrm-set-buffer-hint", &cfg_type_uint32,
1368 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1369 1.1 christos { "fstrm-set-flush-timeout", &cfg_type_uint32,
1370 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1371 1.1 christos { "fstrm-set-input-queue-size", &cfg_type_uint32,
1372 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1373 1.1 christos { "fstrm-set-output-notify-threshold", &cfg_type_uint32,
1374 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1375 1.1 christos { "fstrm-set-output-queue-model", &cfg_type_fstrm_model,
1376 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1377 1.1 christos { "fstrm-set-output-queue-size", &cfg_type_uint32,
1378 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1379 1.8 christos { "fstrm-set-reopen-interval", &cfg_type_duration,
1380 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1381 1.1 christos #endif /* HAVE_DNSTAP */
1382 1.8 christos #if defined(HAVE_GEOIP2)
1383 1.1 christos { "geoip-directory", &cfg_type_qstringornone, 0 },
1384 1.8 christos #else /* if defined(HAVE_GEOIP2) */
1385 1.1 christos { "geoip-directory", &cfg_type_qstringornone,
1386 1.1 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1387 1.8 christos #endif /* HAVE_GEOIP2 */
1388 1.15 christos { "geoip-use-ecs", NULL, CFG_CLAUSEFLAG_ANCIENT },
1389 1.15 christos { "has-old-clients", NULL, CFG_CLAUSEFLAG_ANCIENT },
1390 1.15 christos { "heartbeat-interval", &cfg_type_uint32, CFG_CLAUSEFLAG_DEPRECATED },
1391 1.15 christos { "host-statistics", NULL, CFG_CLAUSEFLAG_ANCIENT },
1392 1.15 christos { "host-statistics-max", NULL, CFG_CLAUSEFLAG_ANCIENT },
1393 1.1 christos { "hostname", &cfg_type_qstringornone, 0 },
1394 1.8 christos { "interface-interval", &cfg_type_duration, 0 },
1395 1.15.2.1 perseant { "keep-response-order", &cfg_type_bracketed_aml,
1396 1.15.2.1 perseant CFG_CLAUSEFLAG_OBSOLETE },
1397 1.1 christos { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
1398 1.1 christos { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
1399 1.15.2.1 perseant { "lock-file", &cfg_type_qstringornone, CFG_CLAUSEFLAG_ANCIENT },
1400 1.1 christos { "managed-keys-directory", &cfg_type_qstring, 0 },
1401 1.1 christos { "match-mapped-addresses", &cfg_type_boolean, 0 },
1402 1.1 christos { "max-rsa-exponent-size", &cfg_type_uint32, 0 },
1403 1.1 christos { "memstatistics", &cfg_type_boolean, 0 },
1404 1.1 christos { "memstatistics-file", &cfg_type_qstring, 0 },
1405 1.15 christos { "multiple-cnames", NULL, CFG_CLAUSEFLAG_ANCIENT },
1406 1.15 christos { "named-xfer", NULL, CFG_CLAUSEFLAG_ANCIENT },
1407 1.1 christos { "notify-rate", &cfg_type_uint32, 0 },
1408 1.1 christos { "pid-file", &cfg_type_qstringornone, 0 },
1409 1.1 christos { "port", &cfg_type_uint32, 0 },
1410 1.15 christos { "tls-port", &cfg_type_uint32, 0 },
1411 1.15 christos #if HAVE_LIBNGHTTP2
1412 1.15 christos { "http-port", &cfg_type_uint32, 0 },
1413 1.15 christos { "http-listener-clients", &cfg_type_uint32, 0 },
1414 1.15 christos { "http-streams-per-connection", &cfg_type_uint32, 0 },
1415 1.15 christos { "https-port", &cfg_type_uint32, 0 },
1416 1.15 christos #else
1417 1.15 christos { "http-port", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED },
1418 1.15 christos { "http-listener-clients", &cfg_type_uint32,
1419 1.15 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1420 1.15 christos { "http-streams-per-connection", &cfg_type_uint32,
1421 1.15 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1422 1.15 christos { "https-port", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED },
1423 1.15 christos #endif
1424 1.1 christos { "querylog", &cfg_type_boolean, 0 },
1425 1.15.2.1 perseant { "random-device", &cfg_type_qstringornone, CFG_CLAUSEFLAG_ANCIENT },
1426 1.1 christos { "recursing-file", &cfg_type_qstring, 0 },
1427 1.1 christos { "recursive-clients", &cfg_type_uint32, 0 },
1428 1.13 christos { "reuseport", &cfg_type_boolean, 0 },
1429 1.15.2.1 perseant { "reserved-sockets", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
1430 1.15.2.1 perseant { "responselog", &cfg_type_boolean, 0 },
1431 1.1 christos { "secroots-file", &cfg_type_qstring, 0 },
1432 1.15 christos { "serial-queries", NULL, CFG_CLAUSEFLAG_ANCIENT },
1433 1.1 christos { "serial-query-rate", &cfg_type_uint32, 0 },
1434 1.1 christos { "server-id", &cfg_type_serverid, 0 },
1435 1.1 christos { "session-keyalg", &cfg_type_astring, 0 },
1436 1.1 christos { "session-keyfile", &cfg_type_qstringornone, 0 },
1437 1.1 christos { "session-keyname", &cfg_type_astring, 0 },
1438 1.15.2.1 perseant { "sig0checks-quota", &cfg_type_uint32, CFG_CLAUSEFLAG_EXPERIMENTAL },
1439 1.15.2.1 perseant { "sig0checks-quota-exempt", &cfg_type_bracketed_aml,
1440 1.15.2.1 perseant CFG_CLAUSEFLAG_EXPERIMENTAL },
1441 1.15 christos { "sit-secret", NULL, CFG_CLAUSEFLAG_ANCIENT },
1442 1.15.2.1 perseant { "stacksize", &cfg_type_size, CFG_CLAUSEFLAG_ANCIENT },
1443 1.1 christos { "startup-notify-rate", &cfg_type_uint32, 0 },
1444 1.1 christos { "statistics-file", &cfg_type_qstring, 0 },
1445 1.15 christos { "statistics-interval", NULL, CFG_CLAUSEFLAG_ANCIENT },
1446 1.1 christos { "tcp-advertised-timeout", &cfg_type_uint32, 0 },
1447 1.1 christos { "tcp-clients", &cfg_type_uint32, 0 },
1448 1.1 christos { "tcp-idle-timeout", &cfg_type_uint32, 0 },
1449 1.1 christos { "tcp-initial-timeout", &cfg_type_uint32, 0 },
1450 1.1 christos { "tcp-keepalive-timeout", &cfg_type_uint32, 0 },
1451 1.1 christos { "tcp-listen-queue", &cfg_type_uint32, 0 },
1452 1.15 christos { "tcp-receive-buffer", &cfg_type_uint32, 0 },
1453 1.15 christos { "tcp-send-buffer", &cfg_type_uint32, 0 },
1454 1.15.2.1 perseant { "tkey-dhkey", NULL, CFG_CLAUSEFLAG_ANCIENT },
1455 1.1 christos { "tkey-domain", &cfg_type_qstring, 0 },
1456 1.1 christos { "tkey-gssapi-credential", &cfg_type_qstring, 0 },
1457 1.1 christos { "tkey-gssapi-keytab", &cfg_type_qstring, 0 },
1458 1.1 christos { "transfer-message-size", &cfg_type_uint32, 0 },
1459 1.1 christos { "transfers-in", &cfg_type_uint32, 0 },
1460 1.1 christos { "transfers-out", &cfg_type_uint32, 0 },
1461 1.1 christos { "transfers-per-ns", &cfg_type_uint32, 0 },
1462 1.15 christos { "treat-cr-as-space", NULL, CFG_CLAUSEFLAG_ANCIENT },
1463 1.15 christos { "udp-receive-buffer", &cfg_type_uint32, 0 },
1464 1.15 christos { "udp-send-buffer", &cfg_type_uint32, 0 },
1465 1.14 christos { "update-quota", &cfg_type_uint32, 0 },
1466 1.15 christos { "use-id-pool", NULL, CFG_CLAUSEFLAG_ANCIENT },
1467 1.15 christos { "use-ixfr", NULL, CFG_CLAUSEFLAG_ANCIENT },
1468 1.15 christos { "use-v4-udp-ports", &cfg_type_bracketed_portlist,
1469 1.15 christos CFG_CLAUSEFLAG_DEPRECATED },
1470 1.15 christos { "use-v6-udp-ports", &cfg_type_bracketed_portlist,
1471 1.15 christos CFG_CLAUSEFLAG_DEPRECATED },
1472 1.1 christos { "version", &cfg_type_qstringornone, 0 },
1473 1.1 christos { NULL, NULL, 0 }
1474 1.1 christos };
1475 1.1 christos
1476 1.8 christos static cfg_type_t cfg_type_namelist = { "namelist",
1477 1.8 christos cfg_parse_bracketed_list,
1478 1.8 christos cfg_print_bracketed_list,
1479 1.8 christos cfg_doc_bracketed_list,
1480 1.8 christos &cfg_rep_list,
1481 1.8 christos &cfg_type_astring };
1482 1.1 christos
1483 1.1 christos static keyword_type_t exclude_kw = { "exclude", &cfg_type_namelist };
1484 1.1 christos
1485 1.1 christos static cfg_type_t cfg_type_optional_exclude = {
1486 1.8 christos "optional_exclude", parse_optional_keyvalue, print_keyvalue,
1487 1.8 christos doc_optional_keyvalue, &cfg_rep_list, &exclude_kw
1488 1.1 christos };
1489 1.1 christos
1490 1.8 christos static keyword_type_t exceptionnames_kw = { "except-from", &cfg_type_namelist };
1491 1.1 christos
1492 1.1 christos static cfg_type_t cfg_type_optional_exceptionnames = {
1493 1.8 christos "optional_allow", parse_optional_keyvalue, print_keyvalue,
1494 1.8 christos doc_optional_keyvalue, &cfg_rep_list, &exceptionnames_kw
1495 1.1 christos };
1496 1.1 christos
1497 1.1 christos static cfg_tuplefielddef_t denyaddresses_fields[] = {
1498 1.1 christos { "acl", &cfg_type_bracketed_aml, 0 },
1499 1.1 christos { "except-from", &cfg_type_optional_exceptionnames, 0 },
1500 1.1 christos { NULL, NULL, 0 }
1501 1.1 christos };
1502 1.1 christos
1503 1.1 christos static cfg_type_t cfg_type_denyaddresses = {
1504 1.8 christos "denyaddresses", cfg_parse_tuple, cfg_print_tuple,
1505 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, denyaddresses_fields
1506 1.1 christos };
1507 1.1 christos
1508 1.1 christos static cfg_tuplefielddef_t denyaliases_fields[] = {
1509 1.1 christos { "name", &cfg_type_namelist, 0 },
1510 1.1 christos { "except-from", &cfg_type_optional_exceptionnames, 0 },
1511 1.1 christos { NULL, NULL, 0 }
1512 1.1 christos };
1513 1.1 christos
1514 1.1 christos static cfg_type_t cfg_type_denyaliases = {
1515 1.8 christos "denyaliases", cfg_parse_tuple, cfg_print_tuple,
1516 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, denyaliases_fields
1517 1.1 christos };
1518 1.1 christos
1519 1.8 christos static cfg_type_t cfg_type_algorithmlist = { "algorithmlist",
1520 1.8 christos cfg_parse_bracketed_list,
1521 1.8 christos cfg_print_bracketed_list,
1522 1.8 christos cfg_doc_bracketed_list,
1523 1.8 christos &cfg_rep_list,
1524 1.8 christos &cfg_type_astring };
1525 1.1 christos
1526 1.1 christos static cfg_tuplefielddef_t disablealgorithm_fields[] = {
1527 1.1 christos { "name", &cfg_type_astring, 0 },
1528 1.1 christos { "algorithms", &cfg_type_algorithmlist, 0 },
1529 1.1 christos { NULL, NULL, 0 }
1530 1.1 christos };
1531 1.1 christos
1532 1.1 christos static cfg_type_t cfg_type_disablealgorithm = {
1533 1.8 christos "disablealgorithm", cfg_parse_tuple, cfg_print_tuple,
1534 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, disablealgorithm_fields
1535 1.1 christos };
1536 1.1 christos
1537 1.8 christos static cfg_type_t cfg_type_dsdigestlist = { "dsdigestlist",
1538 1.8 christos cfg_parse_bracketed_list,
1539 1.8 christos cfg_print_bracketed_list,
1540 1.8 christos cfg_doc_bracketed_list,
1541 1.8 christos &cfg_rep_list,
1542 1.8 christos &cfg_type_astring };
1543 1.1 christos
1544 1.1 christos static cfg_tuplefielddef_t disabledsdigest_fields[] = {
1545 1.1 christos { "name", &cfg_type_astring, 0 },
1546 1.1 christos { "digests", &cfg_type_dsdigestlist, 0 },
1547 1.1 christos { NULL, NULL, 0 }
1548 1.1 christos };
1549 1.1 christos
1550 1.1 christos static cfg_type_t cfg_type_disabledsdigest = {
1551 1.8 christos "disabledsdigest", cfg_parse_tuple, cfg_print_tuple,
1552 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, disabledsdigest_fields
1553 1.1 christos };
1554 1.1 christos
1555 1.1 christos static cfg_tuplefielddef_t mustbesecure_fields[] = {
1556 1.1 christos { "name", &cfg_type_astring, 0 },
1557 1.1 christos { "value", &cfg_type_boolean, 0 },
1558 1.1 christos { NULL, NULL, 0 }
1559 1.1 christos };
1560 1.1 christos
1561 1.1 christos static cfg_type_t cfg_type_mustbesecure = {
1562 1.8 christos "mustbesecure", cfg_parse_tuple, cfg_print_tuple,
1563 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, mustbesecure_fields
1564 1.1 christos };
1565 1.1 christos
1566 1.15 christos static const char *masterformat_enums[] = { "raw", "text", NULL };
1567 1.1 christos static cfg_type_t cfg_type_masterformat = {
1568 1.8 christos "masterformat", cfg_parse_enum, cfg_print_ustring,
1569 1.8 christos cfg_doc_enum, &cfg_rep_string, &masterformat_enums
1570 1.1 christos };
1571 1.1 christos
1572 1.1 christos static const char *masterstyle_enums[] = { "full", "relative", NULL };
1573 1.1 christos static cfg_type_t cfg_type_masterstyle = {
1574 1.8 christos "masterstyle", cfg_parse_enum, cfg_print_ustring,
1575 1.8 christos cfg_doc_enum, &cfg_rep_string, &masterstyle_enums
1576 1.1 christos };
1577 1.1 christos
1578 1.1 christos static keyword_type_t blocksize_kw = { "block-size", &cfg_type_uint32 };
1579 1.1 christos
1580 1.8 christos static cfg_type_t cfg_type_blocksize = { "blocksize", parse_keyvalue,
1581 1.8 christos print_keyvalue, doc_keyvalue,
1582 1.8 christos &cfg_rep_uint32, &blocksize_kw };
1583 1.1 christos
1584 1.1 christos static cfg_tuplefielddef_t resppadding_fields[] = {
1585 1.1 christos { "acl", &cfg_type_bracketed_aml, 0 },
1586 1.1 christos { "block-size", &cfg_type_blocksize, 0 },
1587 1.1 christos { NULL, NULL, 0 }
1588 1.1 christos };
1589 1.1 christos
1590 1.1 christos static cfg_type_t cfg_type_resppadding = {
1591 1.8 christos "resppadding", cfg_parse_tuple, cfg_print_tuple,
1592 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, resppadding_fields
1593 1.1 christos };
1594 1.1 christos
1595 1.1 christos /*%
1596 1.1 christos * dnstap {
1597 1.1 christos * <message type> [query | response] ;
1598 1.1 christos * ...
1599 1.1 christos * }
1600 1.1 christos *
1601 1.3 christos * ... where message type is one of: client, resolver, auth, forwarder,
1602 1.3 christos * update, all
1603 1.1 christos */
1604 1.8 christos static const char *dnstap_types[] = { "all", "auth", "client",
1605 1.8 christos "forwarder", "resolver", "update",
1606 1.8 christos NULL };
1607 1.1 christos
1608 1.1 christos static const char *dnstap_modes[] = { "query", "response", NULL };
1609 1.1 christos
1610 1.8 christos static cfg_type_t cfg_type_dnstap_type = { "dnstap_type", cfg_parse_enum,
1611 1.8 christos cfg_print_ustring, cfg_doc_enum,
1612 1.8 christos &cfg_rep_string, dnstap_types };
1613 1.1 christos
1614 1.1 christos static cfg_type_t cfg_type_dnstap_mode = {
1615 1.8 christos "dnstap_mode", parse_optional_enum, cfg_print_ustring,
1616 1.8 christos doc_optional_enum, &cfg_rep_string, dnstap_modes
1617 1.1 christos };
1618 1.1 christos
1619 1.1 christos static cfg_tuplefielddef_t dnstap_fields[] = {
1620 1.1 christos { "type", &cfg_type_dnstap_type, 0 },
1621 1.1 christos { "mode", &cfg_type_dnstap_mode, 0 },
1622 1.1 christos { NULL, NULL, 0 }
1623 1.1 christos };
1624 1.1 christos
1625 1.8 christos static cfg_type_t cfg_type_dnstap_entry = { "dnstap_value", cfg_parse_tuple,
1626 1.8 christos cfg_print_tuple, cfg_doc_tuple,
1627 1.8 christos &cfg_rep_tuple, dnstap_fields };
1628 1.8 christos
1629 1.8 christos static cfg_type_t cfg_type_dnstap = { "dnstap",
1630 1.8 christos cfg_parse_bracketed_list,
1631 1.8 christos cfg_print_bracketed_list,
1632 1.8 christos cfg_doc_bracketed_list,
1633 1.8 christos &cfg_rep_list,
1634 1.8 christos &cfg_type_dnstap_entry };
1635 1.1 christos
1636 1.1 christos /*%
1637 1.1 christos * dnstap-output
1638 1.1 christos */
1639 1.1 christos static isc_result_t
1640 1.1 christos parse_dtout(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
1641 1.1 christos isc_result_t result;
1642 1.1 christos cfg_obj_t *obj = NULL;
1643 1.1 christos const cfg_tuplefielddef_t *fields = type->of;
1644 1.1 christos
1645 1.1 christos CHECK(cfg_create_tuple(pctx, type, &obj));
1646 1.1 christos
1647 1.1 christos /* Parse the mandatory "mode" and "path" fields */
1648 1.1 christos CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
1649 1.1 christos CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1]));
1650 1.1 christos
1651 1.1 christos /* Parse "versions" and "size" fields in any order. */
1652 1.1 christos for (;;) {
1653 1.1 christos CHECK(cfg_peektoken(pctx, 0));
1654 1.1 christos if (pctx->token.type == isc_tokentype_string) {
1655 1.1 christos CHECK(cfg_gettoken(pctx, 0));
1656 1.8 christos if (strcasecmp(TOKEN_STRING(pctx), "size") == 0 &&
1657 1.14 christos obj->value.tuple[2] == NULL)
1658 1.14 christos {
1659 1.1 christos CHECK(cfg_parse_obj(pctx, fields[2].type,
1660 1.1 christos &obj->value.tuple[2]));
1661 1.8 christos } else if (strcasecmp(TOKEN_STRING(pctx), "versions") ==
1662 1.8 christos 0 &&
1663 1.1 christos obj->value.tuple[3] == NULL)
1664 1.1 christos {
1665 1.1 christos CHECK(cfg_parse_obj(pctx, fields[3].type,
1666 1.1 christos &obj->value.tuple[3]));
1667 1.8 christos } else if (strcasecmp(TOKEN_STRING(pctx), "suffix") ==
1668 1.8 christos 0 &&
1669 1.8 christos obj->value.tuple[4] == NULL)
1670 1.8 christos {
1671 1.1 christos CHECK(cfg_parse_obj(pctx, fields[4].type,
1672 1.8 christos &obj->value.tuple[4]));
1673 1.1 christos } else {
1674 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
1675 1.1 christos "unexpected token");
1676 1.1 christos result = ISC_R_UNEXPECTEDTOKEN;
1677 1.1 christos goto cleanup;
1678 1.1 christos }
1679 1.1 christos } else {
1680 1.1 christos break;
1681 1.1 christos }
1682 1.1 christos }
1683 1.1 christos
1684 1.1 christos /* Create void objects for missing optional values. */
1685 1.8 christos if (obj->value.tuple[2] == NULL) {
1686 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
1687 1.8 christos }
1688 1.8 christos if (obj->value.tuple[3] == NULL) {
1689 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[3]));
1690 1.8 christos }
1691 1.8 christos if (obj->value.tuple[4] == NULL) {
1692 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[4]));
1693 1.8 christos }
1694 1.1 christos
1695 1.1 christos *ret = obj;
1696 1.15.2.1 perseant return ISC_R_SUCCESS;
1697 1.1 christos
1698 1.8 christos cleanup:
1699 1.1 christos CLEANUP_OBJ(obj);
1700 1.15.2.1 perseant return result;
1701 1.1 christos }
1702 1.1 christos
1703 1.1 christos static void
1704 1.1 christos print_dtout(cfg_printer_t *pctx, const cfg_obj_t *obj) {
1705 1.1 christos cfg_print_obj(pctx, obj->value.tuple[0]); /* mode */
1706 1.1 christos cfg_print_obj(pctx, obj->value.tuple[1]); /* file */
1707 1.1 christos if (obj->value.tuple[2]->type->print != cfg_print_void) {
1708 1.1 christos cfg_print_cstr(pctx, " size ");
1709 1.1 christos cfg_print_obj(pctx, obj->value.tuple[2]);
1710 1.1 christos }
1711 1.1 christos if (obj->value.tuple[3]->type->print != cfg_print_void) {
1712 1.1 christos cfg_print_cstr(pctx, " versions ");
1713 1.1 christos cfg_print_obj(pctx, obj->value.tuple[3]);
1714 1.1 christos }
1715 1.1 christos if (obj->value.tuple[4]->type->print != cfg_print_void) {
1716 1.1 christos cfg_print_cstr(pctx, " suffix ");
1717 1.1 christos cfg_print_obj(pctx, obj->value.tuple[4]);
1718 1.1 christos }
1719 1.1 christos }
1720 1.1 christos
1721 1.1 christos static void
1722 1.1 christos doc_dtout(cfg_printer_t *pctx, const cfg_type_t *type) {
1723 1.1 christos UNUSED(type);
1724 1.1 christos cfg_print_cstr(pctx, "( file | unix ) <quoted_string>");
1725 1.1 christos cfg_print_cstr(pctx, " ");
1726 1.1 christos cfg_print_cstr(pctx, "[ size ( unlimited | <size> ) ]");
1727 1.1 christos cfg_print_cstr(pctx, " ");
1728 1.1 christos cfg_print_cstr(pctx, "[ versions ( unlimited | <integer> ) ]");
1729 1.1 christos cfg_print_cstr(pctx, " ");
1730 1.1 christos cfg_print_cstr(pctx, "[ suffix ( increment | timestamp ) ]");
1731 1.1 christos }
1732 1.1 christos
1733 1.1 christos static const char *dtoutmode_enums[] = { "file", "unix", NULL };
1734 1.8 christos static cfg_type_t cfg_type_dtmode = { "dtmode", cfg_parse_enum,
1735 1.8 christos cfg_print_ustring, cfg_doc_enum,
1736 1.8 christos &cfg_rep_string, &dtoutmode_enums };
1737 1.1 christos
1738 1.1 christos static cfg_tuplefielddef_t dtout_fields[] = {
1739 1.1 christos { "mode", &cfg_type_dtmode, 0 },
1740 1.1 christos { "path", &cfg_type_qstring, 0 },
1741 1.1 christos { "size", &cfg_type_sizenodefault, 0 },
1742 1.1 christos { "versions", &cfg_type_logversions, 0 },
1743 1.1 christos { "suffix", &cfg_type_logsuffix, 0 },
1744 1.1 christos { NULL, NULL, 0 }
1745 1.1 christos };
1746 1.1 christos
1747 1.8 christos static cfg_type_t cfg_type_dnstapoutput = { "dnstapoutput", parse_dtout,
1748 1.8 christos print_dtout, doc_dtout,
1749 1.8 christos &cfg_rep_tuple, dtout_fields };
1750 1.1 christos
1751 1.1 christos /*%
1752 1.1 christos * response-policy {
1753 1.1 christos * zone <string> [ policy (given|disabled|passthru|drop|tcp-only|
1754 1.1 christos * nxdomain|nodata|cname <domain> ) ]
1755 1.1 christos * [ recursive-only yes|no ] [ log yes|no ]
1756 1.1 christos * [ max-policy-ttl number ]
1757 1.1 christos * [ nsip-enable yes|no ] [ nsdname-enable yes|no ];
1758 1.1 christos * } [ recursive-only yes|no ] [ max-policy-ttl number ]
1759 1.1 christos * [ min-update-interval number ]
1760 1.1 christos * [ break-dnssec yes|no ] [ min-ns-dots number ]
1761 1.1 christos * [ qname-wait-recurse yes|no ]
1762 1.1 christos * [ nsip-enable yes|no ] [ nsdname-enable yes|no ]
1763 1.1 christos * [ dnsrps-enable yes|no ]
1764 1.1 christos * [ dnsrps-options { DNSRPS configuration string } ];
1765 1.1 christos */
1766 1.1 christos
1767 1.1 christos static void
1768 1.1 christos doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) {
1769 1.8 christos const char *const *p;
1770 1.1 christos /*
1771 1.1 christos * This is cfg_doc_enum() without the trailing " )".
1772 1.1 christos */
1773 1.1 christos cfg_print_cstr(pctx, "( ");
1774 1.1 christos for (p = type->of; *p != NULL; p++) {
1775 1.1 christos cfg_print_cstr(pctx, *p);
1776 1.8 christos if (p[1] != NULL) {
1777 1.1 christos cfg_print_cstr(pctx, " | ");
1778 1.8 christos }
1779 1.1 christos }
1780 1.1 christos }
1781 1.1 christos
1782 1.1 christos static void
1783 1.1 christos doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) {
1784 1.1 christos cfg_doc_terminal(pctx, type);
1785 1.1 christos cfg_print_cstr(pctx, " )");
1786 1.1 christos }
1787 1.1 christos
1788 1.1 christos /*
1789 1.1 christos * Parse
1790 1.1 christos * given|disabled|passthru|drop|tcp-only|nxdomain|nodata|cname <domain>
1791 1.1 christos */
1792 1.1 christos static isc_result_t
1793 1.1 christos cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type,
1794 1.8 christos cfg_obj_t **ret) {
1795 1.1 christos isc_result_t result;
1796 1.1 christos cfg_obj_t *obj = NULL;
1797 1.1 christos const cfg_tuplefielddef_t *fields;
1798 1.1 christos
1799 1.1 christos CHECK(cfg_create_tuple(pctx, type, &obj));
1800 1.1 christos
1801 1.1 christos fields = type->of;
1802 1.1 christos CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
1803 1.1 christos /*
1804 1.1 christos * parse cname domain only after "policy cname"
1805 1.1 christos */
1806 1.1 christos if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) {
1807 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
1808 1.1 christos } else {
1809 1.1 christos CHECK(cfg_parse_obj(pctx, fields[1].type,
1810 1.1 christos &obj->value.tuple[1]));
1811 1.1 christos }
1812 1.1 christos
1813 1.1 christos *ret = obj;
1814 1.15.2.1 perseant return ISC_R_SUCCESS;
1815 1.1 christos
1816 1.1 christos cleanup:
1817 1.1 christos CLEANUP_OBJ(obj);
1818 1.15.2.1 perseant return result;
1819 1.1 christos }
1820 1.1 christos
1821 1.1 christos /*
1822 1.1 christos * Parse a tuple consisting of any kind of required field followed
1823 1.1 christos * by 2 or more optional keyvalues that can be in any order.
1824 1.1 christos */
1825 1.1 christos static isc_result_t
1826 1.1 christos cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type,
1827 1.8 christos cfg_obj_t **ret) {
1828 1.1 christos const cfg_tuplefielddef_t *fields, *f;
1829 1.1 christos cfg_obj_t *obj = NULL;
1830 1.1 christos int fn;
1831 1.1 christos isc_result_t result;
1832 1.1 christos
1833 1.1 christos CHECK(cfg_create_tuple(pctx, type, &obj));
1834 1.1 christos
1835 1.1 christos /*
1836 1.1 christos * The zone first field is required and always first.
1837 1.1 christos */
1838 1.1 christos fields = type->of;
1839 1.1 christos CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
1840 1.1 christos
1841 1.1 christos for (;;) {
1842 1.1 christos CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
1843 1.8 christos if (pctx->token.type != isc_tokentype_string) {
1844 1.1 christos break;
1845 1.8 christos }
1846 1.1 christos
1847 1.8 christos for (fn = 1, f = &fields[1];; ++fn, ++f) {
1848 1.1 christos if (f->name == NULL) {
1849 1.1 christos cfg_parser_error(pctx, 0, "unexpected '%s'",
1850 1.1 christos TOKEN_STRING(pctx));
1851 1.1 christos result = ISC_R_UNEXPECTEDTOKEN;
1852 1.1 christos goto cleanup;
1853 1.1 christos }
1854 1.1 christos if (obj->value.tuple[fn] == NULL &&
1855 1.1 christos strcasecmp(f->name, TOKEN_STRING(pctx)) == 0)
1856 1.8 christos {
1857 1.1 christos break;
1858 1.8 christos }
1859 1.1 christos }
1860 1.1 christos
1861 1.1 christos CHECK(cfg_gettoken(pctx, 0));
1862 1.1 christos CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn]));
1863 1.1 christos }
1864 1.1 christos
1865 1.1 christos for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) {
1866 1.8 christos if (obj->value.tuple[fn] == NULL) {
1867 1.1 christos CHECK(cfg_parse_void(pctx, NULL,
1868 1.1 christos &obj->value.tuple[fn]));
1869 1.8 christos }
1870 1.1 christos }
1871 1.1 christos
1872 1.1 christos *ret = obj;
1873 1.15.2.1 perseant return ISC_R_SUCCESS;
1874 1.1 christos
1875 1.1 christos cleanup:
1876 1.1 christos CLEANUP_OBJ(obj);
1877 1.15.2.1 perseant return result;
1878 1.1 christos }
1879 1.1 christos
1880 1.1 christos static void
1881 1.1 christos cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) {
1882 1.1 christos unsigned int i;
1883 1.1 christos const cfg_tuplefielddef_t *fields, *f;
1884 1.1 christos const cfg_obj_t *fieldobj;
1885 1.1 christos
1886 1.1 christos fields = obj->type->of;
1887 1.1 christos for (f = fields, i = 0; f->name != NULL; f++, i++) {
1888 1.1 christos fieldobj = obj->value.tuple[i];
1889 1.8 christos if (fieldobj->type->print == cfg_print_void) {
1890 1.1 christos continue;
1891 1.8 christos }
1892 1.1 christos if (i != 0) {
1893 1.1 christos cfg_print_cstr(pctx, " ");
1894 1.1 christos cfg_print_cstr(pctx, f->name);
1895 1.1 christos cfg_print_cstr(pctx, " ");
1896 1.1 christos }
1897 1.1 christos cfg_print_obj(pctx, fieldobj);
1898 1.1 christos }
1899 1.1 christos }
1900 1.1 christos
1901 1.1 christos static void
1902 1.1 christos cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) {
1903 1.1 christos const cfg_tuplefielddef_t *fields, *f;
1904 1.1 christos
1905 1.1 christos fields = type->of;
1906 1.1 christos for (f = fields; f->name != NULL; f++) {
1907 1.15 christos if ((f->flags & CFG_CLAUSEFLAG_NODOC) != 0) {
1908 1.15 christos continue;
1909 1.15 christos }
1910 1.1 christos if (f != fields) {
1911 1.1 christos cfg_print_cstr(pctx, " [ ");
1912 1.1 christos cfg_print_cstr(pctx, f->name);
1913 1.8 christos if (f->type->doc != cfg_doc_void) {
1914 1.1 christos cfg_print_cstr(pctx, " ");
1915 1.8 christos }
1916 1.1 christos }
1917 1.1 christos cfg_doc_obj(pctx, f->type);
1918 1.8 christos if (f != fields) {
1919 1.1 christos cfg_print_cstr(pctx, " ]");
1920 1.8 christos }
1921 1.1 christos }
1922 1.1 christos }
1923 1.1 christos
1924 1.8 christos static keyword_type_t zone_kw = { "zone", &cfg_type_astring };
1925 1.8 christos static cfg_type_t cfg_type_rpz_zone = { "zone", parse_keyvalue,
1926 1.8 christos print_keyvalue, doc_keyvalue,
1927 1.8 christos &cfg_rep_string, &zone_kw };
1928 1.1 christos /*
1929 1.1 christos * "no-op" is an obsolete equivalent of "passthru".
1930 1.1 christos */
1931 1.8 christos static const char *rpz_policies[] = { "cname", "disabled", "drop",
1932 1.8 christos "given", "no-op", "nodata",
1933 1.8 christos "nxdomain", "passthru", "tcp-only",
1934 1.8 christos NULL };
1935 1.1 christos static cfg_type_t cfg_type_rpz_policy_name = {
1936 1.8 christos "policy name", cfg_parse_enum, cfg_print_ustring,
1937 1.8 christos doc_rpz_policy, &cfg_rep_string, &rpz_policies
1938 1.1 christos };
1939 1.1 christos static cfg_type_t cfg_type_rpz_cname = {
1940 1.1 christos "quoted_string", cfg_parse_astring, NULL,
1941 1.8 christos doc_rpz_cname, &cfg_rep_string, NULL
1942 1.1 christos };
1943 1.1 christos static cfg_tuplefielddef_t rpz_policy_fields[] = {
1944 1.1 christos { "policy name", &cfg_type_rpz_policy_name, 0 },
1945 1.1 christos { "cname", &cfg_type_rpz_cname, 0 },
1946 1.1 christos { NULL, NULL, 0 }
1947 1.1 christos };
1948 1.8 christos static cfg_type_t cfg_type_rpz_policy = { "policy tuple", cfg_parse_rpz_policy,
1949 1.8 christos cfg_print_tuple, cfg_doc_tuple,
1950 1.8 christos &cfg_rep_tuple, rpz_policy_fields };
1951 1.1 christos static cfg_tuplefielddef_t rpz_zone_fields[] = {
1952 1.1 christos { "zone name", &cfg_type_rpz_zone, 0 },
1953 1.5 christos { "add-soa", &cfg_type_boolean, 0 },
1954 1.1 christos { "log", &cfg_type_boolean, 0 },
1955 1.8 christos { "max-policy-ttl", &cfg_type_duration, 0 },
1956 1.8 christos { "min-update-interval", &cfg_type_duration, 0 },
1957 1.1 christos { "policy", &cfg_type_rpz_policy, 0 },
1958 1.1 christos { "recursive-only", &cfg_type_boolean, 0 },
1959 1.1 christos { "nsip-enable", &cfg_type_boolean, 0 },
1960 1.1 christos { "nsdname-enable", &cfg_type_boolean, 0 },
1961 1.15.2.1 perseant { "ede", &cfg_type_ustring, 0 },
1962 1.1 christos { NULL, NULL, 0 }
1963 1.1 christos };
1964 1.8 christos static cfg_type_t cfg_type_rpz_tuple = { "rpz tuple", cfg_parse_kv_tuple,
1965 1.8 christos cfg_print_kv_tuple, cfg_doc_kv_tuple,
1966 1.8 christos &cfg_rep_tuple, rpz_zone_fields };
1967 1.8 christos static cfg_type_t cfg_type_rpz_list = { "zone list",
1968 1.8 christos cfg_parse_bracketed_list,
1969 1.8 christos cfg_print_bracketed_list,
1970 1.8 christos cfg_doc_bracketed_list,
1971 1.8 christos &cfg_rep_list,
1972 1.8 christos &cfg_type_rpz_tuple };
1973 1.1 christos static cfg_tuplefielddef_t rpz_fields[] = {
1974 1.1 christos { "zone list", &cfg_type_rpz_list, 0 },
1975 1.5 christos { "add-soa", &cfg_type_boolean, 0 },
1976 1.1 christos { "break-dnssec", &cfg_type_boolean, 0 },
1977 1.8 christos { "max-policy-ttl", &cfg_type_duration, 0 },
1978 1.8 christos { "min-update-interval", &cfg_type_duration, 0 },
1979 1.1 christos { "min-ns-dots", &cfg_type_uint32, 0 },
1980 1.1 christos { "nsip-wait-recurse", &cfg_type_boolean, 0 },
1981 1.15 christos { "nsdname-wait-recurse", &cfg_type_boolean, 0 },
1982 1.1 christos { "qname-wait-recurse", &cfg_type_boolean, 0 },
1983 1.1 christos { "recursive-only", &cfg_type_boolean, 0 },
1984 1.1 christos { "nsip-enable", &cfg_type_boolean, 0 },
1985 1.1 christos { "nsdname-enable", &cfg_type_boolean, 0 },
1986 1.1 christos #ifdef USE_DNSRPS
1987 1.1 christos { "dnsrps-enable", &cfg_type_boolean, 0 },
1988 1.1 christos { "dnsrps-options", &cfg_type_bracketed_text, 0 },
1989 1.8 christos #else /* ifdef USE_DNSRPS */
1990 1.1 christos { "dnsrps-enable", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED },
1991 1.1 christos { "dnsrps-options", &cfg_type_bracketed_text,
1992 1.8 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
1993 1.8 christos #endif /* ifdef USE_DNSRPS */
1994 1.1 christos { NULL, NULL, 0 }
1995 1.1 christos };
1996 1.8 christos static cfg_type_t cfg_type_rpz = { "rpz",
1997 1.8 christos cfg_parse_kv_tuple,
1998 1.8 christos cfg_print_kv_tuple,
1999 1.8 christos cfg_doc_kv_tuple,
2000 1.8 christos &cfg_rep_tuple,
2001 1.8 christos rpz_fields };
2002 1.1 christos
2003 1.1 christos /*
2004 1.1 christos * Catalog zones
2005 1.1 christos */
2006 1.8 christos static cfg_type_t cfg_type_catz_zone = { "zone", parse_keyvalue,
2007 1.8 christos print_keyvalue, doc_keyvalue,
2008 1.8 christos &cfg_rep_string, &zone_kw };
2009 1.1 christos
2010 1.1 christos static cfg_tuplefielddef_t catz_zone_fields[] = {
2011 1.1 christos { "zone name", &cfg_type_catz_zone, 0 },
2012 1.15 christos { "default-masters", &cfg_type_namesockaddrkeylist,
2013 1.15 christos CFG_CLAUSEFLAG_NODOC },
2014 1.15 christos { "default-primaries", &cfg_type_namesockaddrkeylist, 0 },
2015 1.1 christos { "zone-directory", &cfg_type_qstring, 0 },
2016 1.1 christos { "in-memory", &cfg_type_boolean, 0 },
2017 1.8 christos { "min-update-interval", &cfg_type_duration, 0 },
2018 1.1 christos { NULL, NULL, 0 }
2019 1.1 christos };
2020 1.1 christos static cfg_type_t cfg_type_catz_tuple = {
2021 1.8 christos "catz tuple", cfg_parse_kv_tuple, cfg_print_kv_tuple,
2022 1.8 christos cfg_doc_kv_tuple, &cfg_rep_tuple, catz_zone_fields
2023 1.1 christos };
2024 1.8 christos static cfg_type_t cfg_type_catz_list = { "zone list",
2025 1.8 christos cfg_parse_bracketed_list,
2026 1.8 christos cfg_print_bracketed_list,
2027 1.8 christos cfg_doc_bracketed_list,
2028 1.8 christos &cfg_rep_list,
2029 1.8 christos &cfg_type_catz_tuple };
2030 1.1 christos static cfg_tuplefielddef_t catz_fields[] = {
2031 1.8 christos { "zone list", &cfg_type_catz_list, 0 }, { NULL, NULL, 0 }
2032 1.1 christos };
2033 1.1 christos static cfg_type_t cfg_type_catz = {
2034 1.8 christos "catz", cfg_parse_kv_tuple, cfg_print_kv_tuple,
2035 1.8 christos cfg_doc_kv_tuple, &cfg_rep_tuple, catz_fields
2036 1.1 christos };
2037 1.1 christos
2038 1.1 christos /*
2039 1.1 christos * rate-limit
2040 1.1 christos */
2041 1.1 christos static cfg_clausedef_t rrl_clauses[] = {
2042 1.1 christos { "all-per-second", &cfg_type_uint32, 0 },
2043 1.1 christos { "errors-per-second", &cfg_type_uint32, 0 },
2044 1.1 christos { "exempt-clients", &cfg_type_bracketed_aml, 0 },
2045 1.1 christos { "ipv4-prefix-length", &cfg_type_uint32, 0 },
2046 1.1 christos { "ipv6-prefix-length", &cfg_type_uint32, 0 },
2047 1.1 christos { "log-only", &cfg_type_boolean, 0 },
2048 1.1 christos { "max-table-size", &cfg_type_uint32, 0 },
2049 1.1 christos { "min-table-size", &cfg_type_uint32, 0 },
2050 1.1 christos { "nodata-per-second", &cfg_type_uint32, 0 },
2051 1.1 christos { "nxdomains-per-second", &cfg_type_uint32, 0 },
2052 1.1 christos { "qps-scale", &cfg_type_uint32, 0 },
2053 1.1 christos { "referrals-per-second", &cfg_type_uint32, 0 },
2054 1.1 christos { "responses-per-second", &cfg_type_uint32, 0 },
2055 1.1 christos { "slip", &cfg_type_uint32, 0 },
2056 1.1 christos { "window", &cfg_type_uint32, 0 },
2057 1.1 christos { NULL, NULL, 0 }
2058 1.1 christos };
2059 1.1 christos
2060 1.8 christos static cfg_clausedef_t *rrl_clausesets[] = { rrl_clauses, NULL };
2061 1.1 christos
2062 1.8 christos static cfg_type_t cfg_type_rrl = { "rate-limit", cfg_parse_map, cfg_print_map,
2063 1.8 christos cfg_doc_map, &cfg_rep_map, rrl_clausesets };
2064 1.1 christos
2065 1.1 christos static isc_result_t
2066 1.1 christos parse_optional_uint32(cfg_parser_t *pctx, const cfg_type_t *type,
2067 1.8 christos cfg_obj_t **ret) {
2068 1.1 christos isc_result_t result;
2069 1.1 christos UNUSED(type);
2070 1.1 christos
2071 1.1 christos CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER));
2072 1.1 christos if (pctx->token.type == isc_tokentype_number) {
2073 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_uint32, ret));
2074 1.1 christos } else {
2075 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret));
2076 1.1 christos }
2077 1.8 christos cleanup:
2078 1.15.2.1 perseant return result;
2079 1.1 christos }
2080 1.1 christos
2081 1.1 christos static void
2082 1.1 christos doc_optional_uint32(cfg_printer_t *pctx, const cfg_type_t *type) {
2083 1.1 christos UNUSED(type);
2084 1.1 christos cfg_print_cstr(pctx, "[ <integer> ]");
2085 1.1 christos }
2086 1.1 christos
2087 1.8 christos static cfg_type_t cfg_type_optional_uint32 = { "optional_uint32",
2088 1.8 christos parse_optional_uint32,
2089 1.8 christos NULL,
2090 1.8 christos doc_optional_uint32,
2091 1.8 christos NULL,
2092 1.8 christos NULL };
2093 1.1 christos
2094 1.1 christos static cfg_tuplefielddef_t prefetch_fields[] = {
2095 1.1 christos { "trigger", &cfg_type_uint32, 0 },
2096 1.1 christos { "eligible", &cfg_type_optional_uint32, 0 },
2097 1.1 christos { NULL, NULL, 0 }
2098 1.1 christos };
2099 1.1 christos
2100 1.8 christos static cfg_type_t cfg_type_prefetch = { "prefetch", cfg_parse_tuple,
2101 1.8 christos cfg_print_tuple, cfg_doc_tuple,
2102 1.8 christos &cfg_rep_tuple, prefetch_fields };
2103 1.1 christos /*
2104 1.1 christos * DNS64.
2105 1.1 christos */
2106 1.8 christos static cfg_clausedef_t dns64_clauses[] = {
2107 1.1 christos { "break-dnssec", &cfg_type_boolean, 0 },
2108 1.1 christos { "clients", &cfg_type_bracketed_aml, 0 },
2109 1.1 christos { "exclude", &cfg_type_bracketed_aml, 0 },
2110 1.1 christos { "mapped", &cfg_type_bracketed_aml, 0 },
2111 1.1 christos { "recursive-only", &cfg_type_boolean, 0 },
2112 1.1 christos { "suffix", &cfg_type_netaddr6, 0 },
2113 1.1 christos { NULL, NULL, 0 },
2114 1.1 christos };
2115 1.1 christos
2116 1.8 christos static cfg_clausedef_t *dns64_clausesets[] = { dns64_clauses, NULL };
2117 1.1 christos
2118 1.8 christos static cfg_type_t cfg_type_dns64 = { "dns64", cfg_parse_netprefix_map,
2119 1.8 christos cfg_print_map, cfg_doc_map,
2120 1.8 christos &cfg_rep_map, dns64_clausesets };
2121 1.1 christos
2122 1.9 christos static const char *staleanswerclienttimeout_enums[] = { "disabled", "off",
2123 1.9 christos NULL };
2124 1.9 christos static isc_result_t
2125 1.9 christos parse_staleanswerclienttimeout(cfg_parser_t *pctx, const cfg_type_t *type,
2126 1.9 christos cfg_obj_t **ret) {
2127 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_uint32, ret);
2128 1.9 christos }
2129 1.9 christos
2130 1.9 christos static void
2131 1.9 christos doc_staleanswerclienttimeout(cfg_printer_t *pctx, const cfg_type_t *type) {
2132 1.9 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_uint32);
2133 1.9 christos }
2134 1.9 christos
2135 1.9 christos static cfg_type_t cfg_type_staleanswerclienttimeout = {
2136 1.9 christos "staleanswerclienttimeout",
2137 1.9 christos parse_staleanswerclienttimeout,
2138 1.9 christos cfg_print_ustring,
2139 1.9 christos doc_staleanswerclienttimeout,
2140 1.9 christos &cfg_rep_string,
2141 1.9 christos staleanswerclienttimeout_enums
2142 1.9 christos };
2143 1.9 christos
2144 1.1 christos /*%
2145 1.1 christos * Clauses that can be found within the 'view' statement,
2146 1.1 christos * with defaults in the 'options' statement.
2147 1.1 christos */
2148 1.1 christos
2149 1.8 christos static cfg_clausedef_t view_clauses[] = {
2150 1.15 christos { "acache-cleaning-interval", NULL, CFG_CLAUSEFLAG_ANCIENT },
2151 1.15 christos { "acache-enable", NULL, CFG_CLAUSEFLAG_ANCIENT },
2152 1.15 christos { "additional-from-auth", NULL, CFG_CLAUSEFLAG_ANCIENT },
2153 1.15 christos { "additional-from-cache", NULL, CFG_CLAUSEFLAG_ANCIENT },
2154 1.1 christos { "allow-new-zones", &cfg_type_boolean, 0 },
2155 1.15.2.1 perseant { "allow-proxy", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_EXPERIMENTAL },
2156 1.15.2.1 perseant { "allow-proxy-on", &cfg_type_bracketed_aml,
2157 1.15.2.1 perseant CFG_CLAUSEFLAG_EXPERIMENTAL },
2158 1.1 christos { "allow-query-cache", &cfg_type_bracketed_aml, 0 },
2159 1.1 christos { "allow-query-cache-on", &cfg_type_bracketed_aml, 0 },
2160 1.1 christos { "allow-recursion", &cfg_type_bracketed_aml, 0 },
2161 1.1 christos { "allow-recursion-on", &cfg_type_bracketed_aml, 0 },
2162 1.15 christos { "allow-v6-synthesis", NULL, CFG_CLAUSEFLAG_ANCIENT },
2163 1.1 christos { "attach-cache", &cfg_type_astring, 0 },
2164 1.15 christos { "auth-nxdomain", &cfg_type_boolean, 0 },
2165 1.15 christos { "cache-file", &cfg_type_qstring, CFG_CLAUSEFLAG_ANCIENT },
2166 1.1 christos { "catalog-zones", &cfg_type_catz, 0 },
2167 1.1 christos { "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI },
2168 1.15 christos { "cleaning-interval", NULL, CFG_CLAUSEFLAG_ANCIENT },
2169 1.1 christos { "clients-per-query", &cfg_type_uint32, 0 },
2170 1.1 christos { "deny-answer-addresses", &cfg_type_denyaddresses, 0 },
2171 1.1 christos { "deny-answer-aliases", &cfg_type_denyaliases, 0 },
2172 1.1 christos { "disable-algorithms", &cfg_type_disablealgorithm,
2173 1.1 christos CFG_CLAUSEFLAG_MULTI },
2174 1.1 christos { "disable-ds-digests", &cfg_type_disabledsdigest,
2175 1.1 christos CFG_CLAUSEFLAG_MULTI },
2176 1.1 christos { "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
2177 1.1 christos { "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI },
2178 1.1 christos { "dns64-contact", &cfg_type_astring, 0 },
2179 1.1 christos { "dns64-server", &cfg_type_astring, 0 },
2180 1.1 christos #ifdef USE_DNSRPS
2181 1.1 christos { "dnsrps-enable", &cfg_type_boolean, 0 },
2182 1.1 christos { "dnsrps-options", &cfg_type_bracketed_text, 0 },
2183 1.8 christos #else /* ifdef USE_DNSRPS */
2184 1.1 christos { "dnsrps-enable", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED },
2185 1.1 christos { "dnsrps-options", &cfg_type_bracketed_text,
2186 1.8 christos CFG_CLAUSEFLAG_NOTCONFIGURED },
2187 1.8 christos #endif /* ifdef USE_DNSRPS */
2188 1.1 christos { "dnssec-accept-expired", &cfg_type_boolean, 0 },
2189 1.15 christos { "dnssec-enable", NULL, CFG_CLAUSEFLAG_ANCIENT },
2190 1.15 christos { "dnssec-lookaside", NULL,
2191 1.15 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_ANCIENT },
2192 1.8 christos { "dnssec-must-be-secure", &cfg_type_mustbesecure,
2193 1.15 christos CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_DEPRECATED },
2194 1.1 christos { "dnssec-validation", &cfg_type_boolorauto, 0 },
2195 1.1 christos #ifdef HAVE_DNSTAP
2196 1.1 christos { "dnstap", &cfg_type_dnstap, 0 },
2197 1.8 christos #else /* ifdef HAVE_DNSTAP */
2198 1.1 christos { "dnstap", &cfg_type_dnstap, CFG_CLAUSEFLAG_NOTCONFIGURED },
2199 1.1 christos #endif /* HAVE_DNSTAP */
2200 1.1 christos { "dual-stack-servers", &cfg_type_nameportiplist, 0 },
2201 1.1 christos { "edns-udp-size", &cfg_type_uint32, 0 },
2202 1.1 christos { "empty-contact", &cfg_type_astring, 0 },
2203 1.1 christos { "empty-server", &cfg_type_astring, 0 },
2204 1.1 christos { "empty-zones-enable", &cfg_type_boolean, 0 },
2205 1.15 christos { "fetch-glue", NULL, CFG_CLAUSEFLAG_ANCIENT },
2206 1.1 christos { "fetch-quota-params", &cfg_type_fetchquota, 0 },
2207 1.1 christos { "fetches-per-server", &cfg_type_fetchesper, 0 },
2208 1.1 christos { "fetches-per-zone", &cfg_type_fetchesper, 0 },
2209 1.15 christos { "filter-aaaa", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_ANCIENT },
2210 1.15 christos { "filter-aaaa-on-v4", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
2211 1.15 christos { "filter-aaaa-on-v6", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
2212 1.15.2.1 perseant { "glue-cache", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
2213 1.15 christos { "ipv4only-enable", &cfg_type_boolean, 0 },
2214 1.15 christos { "ipv4only-contact", &cfg_type_astring, 0 },
2215 1.15 christos { "ipv4only-server", &cfg_type_astring, 0 },
2216 1.1 christos { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
2217 1.8 christos { "lame-ttl", &cfg_type_duration, 0 },
2218 1.1 christos #ifdef HAVE_LMDB
2219 1.1 christos { "lmdb-mapsize", &cfg_type_sizeval, 0 },
2220 1.8 christos #else /* ifdef HAVE_LMDB */
2221 1.15 christos { "lmdb-mapsize", &cfg_type_sizeval, CFG_CLAUSEFLAG_NOTCONFIGURED },
2222 1.8 christos #endif /* ifdef HAVE_LMDB */
2223 1.15 christos { "max-acache-size", NULL, CFG_CLAUSEFLAG_ANCIENT },
2224 1.1 christos { "max-cache-size", &cfg_type_sizeorpercent, 0 },
2225 1.8 christos { "max-cache-ttl", &cfg_type_duration, 0 },
2226 1.1 christos { "max-clients-per-query", &cfg_type_uint32, 0 },
2227 1.8 christos { "max-ncache-ttl", &cfg_type_duration, 0 },
2228 1.1 christos { "max-recursion-depth", &cfg_type_uint32, 0 },
2229 1.1 christos { "max-recursion-queries", &cfg_type_uint32, 0 },
2230 1.15.2.1 perseant { "max-query-count", &cfg_type_uint32, 0 },
2231 1.15.2.1 perseant { "max-query-restarts", &cfg_type_uint32, 0 },
2232 1.8 christos { "max-stale-ttl", &cfg_type_duration, 0 },
2233 1.1 christos { "max-udp-size", &cfg_type_uint32, 0 },
2234 1.15.2.1 perseant { "max-validations-per-fetch", &cfg_type_uint32,
2235 1.15.2.1 perseant CFG_CLAUSEFLAG_EXPERIMENTAL },
2236 1.15.2.1 perseant { "max-validation-failures-per-fetch", &cfg_type_uint32,
2237 1.15.2.1 perseant CFG_CLAUSEFLAG_EXPERIMENTAL },
2238 1.1 christos { "message-compression", &cfg_type_boolean, 0 },
2239 1.8 christos { "min-cache-ttl", &cfg_type_duration, 0 },
2240 1.8 christos { "min-ncache-ttl", &cfg_type_duration, 0 },
2241 1.15 christos { "min-roots", NULL, CFG_CLAUSEFLAG_ANCIENT },
2242 1.1 christos { "minimal-any", &cfg_type_boolean, 0 },
2243 1.1 christos { "minimal-responses", &cfg_type_minimal, 0 },
2244 1.1 christos { "new-zones-directory", &cfg_type_qstring, 0 },
2245 1.1 christos { "no-case-compress", &cfg_type_bracketed_aml, 0 },
2246 1.1 christos { "nocookie-udp-size", &cfg_type_uint32, 0 },
2247 1.15 christos { "nosit-udp-size", NULL, CFG_CLAUSEFLAG_ANCIENT },
2248 1.8 christos { "nta-lifetime", &cfg_type_duration, 0 },
2249 1.8 christos { "nta-recheck", &cfg_type_duration, 0 },
2250 1.1 christos { "nxdomain-redirect", &cfg_type_astring, 0 },
2251 1.1 christos { "preferred-glue", &cfg_type_astring, 0 },
2252 1.1 christos { "prefetch", &cfg_type_prefetch, 0 },
2253 1.1 christos { "provide-ixfr", &cfg_type_boolean, 0 },
2254 1.3 christos { "qname-minimization", &cfg_type_qminmethod, 0 },
2255 1.1 christos /*
2256 1.1 christos * Note that the query-source option syntax is different
2257 1.1 christos * from the other -source options.
2258 1.1 christos */
2259 1.1 christos { "query-source", &cfg_type_querysource4, 0 },
2260 1.1 christos { "query-source-v6", &cfg_type_querysource6, 0 },
2261 1.15 christos { "queryport-pool-ports", NULL, CFG_CLAUSEFLAG_ANCIENT },
2262 1.15 christos { "queryport-pool-updateinterval", NULL, CFG_CLAUSEFLAG_ANCIENT },
2263 1.1 christos { "rate-limit", &cfg_type_rrl, 0 },
2264 1.1 christos { "recursion", &cfg_type_boolean, 0 },
2265 1.1 christos { "request-nsid", &cfg_type_boolean, 0 },
2266 1.15 christos { "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
2267 1.1 christos { "require-server-cookie", &cfg_type_boolean, 0 },
2268 1.15 christos { "resolver-nonbackoff-tries", &cfg_type_uint32,
2269 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2270 1.1 christos { "resolver-query-timeout", &cfg_type_uint32, 0 },
2271 1.15.2.1 perseant { "resolver-retry-interval", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
2272 1.1 christos { "response-padding", &cfg_type_resppadding, 0 },
2273 1.1 christos { "response-policy", &cfg_type_rpz, 0 },
2274 1.15 christos { "rfc2308-type1", NULL, CFG_CLAUSEFLAG_ANCIENT },
2275 1.15 christos { "root-delegation-only", &cfg_type_optional_exclude,
2276 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2277 1.1 christos { "root-key-sentinel", &cfg_type_boolean, 0 },
2278 1.1 christos { "rrset-order", &cfg_type_rrsetorder, 0 },
2279 1.1 christos { "send-cookie", &cfg_type_boolean, 0 },
2280 1.8 christos { "servfail-ttl", &cfg_type_duration, 0 },
2281 1.15.2.1 perseant { "sig0key-checks-limit", &cfg_type_uint32, 0 },
2282 1.15.2.1 perseant { "sig0message-checks-limit", &cfg_type_uint32, 0 },
2283 1.15.2.1 perseant { "sortlist", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_DEPRECATED },
2284 1.1 christos { "stale-answer-enable", &cfg_type_boolean, 0 },
2285 1.9 christos { "stale-answer-client-timeout", &cfg_type_staleanswerclienttimeout,
2286 1.9 christos 0 },
2287 1.8 christos { "stale-answer-ttl", &cfg_type_duration, 0 },
2288 1.9 christos { "stale-cache-enable", &cfg_type_boolean, 0 },
2289 1.9 christos { "stale-refresh-time", &cfg_type_duration, 0 },
2290 1.15 christos { "suppress-initial-notify", &cfg_type_boolean,
2291 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2292 1.1 christos { "synth-from-dnssec", &cfg_type_boolean, 0 },
2293 1.15 christos { "topology", NULL, CFG_CLAUSEFLAG_ANCIENT },
2294 1.1 christos { "transfer-format", &cfg_type_transferformat, 0 },
2295 1.15 christos { "trust-anchor-telemetry", &cfg_type_boolean, 0 },
2296 1.15.2.1 perseant { "resolver-use-dns64", &cfg_type_boolean, 0 },
2297 1.15 christos { "use-queryport-pool", NULL, CFG_CLAUSEFLAG_ANCIENT },
2298 1.3 christos { "validate-except", &cfg_type_namelist, 0 },
2299 1.1 christos { "v6-bias", &cfg_type_uint32, 0 },
2300 1.1 christos { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 },
2301 1.1 christos { NULL, NULL, 0 }
2302 1.1 christos };
2303 1.1 christos
2304 1.1 christos /*%
2305 1.1 christos * Clauses that can be found within the 'view' statement only.
2306 1.1 christos */
2307 1.8 christos static cfg_clausedef_t view_only_clauses[] = {
2308 1.1 christos { "match-clients", &cfg_type_bracketed_aml, 0 },
2309 1.1 christos { "match-destinations", &cfg_type_bracketed_aml, 0 },
2310 1.1 christos { "match-recursive-only", &cfg_type_boolean, 0 },
2311 1.1 christos { NULL, NULL, 0 }
2312 1.1 christos };
2313 1.1 christos
2314 1.1 christos /*%
2315 1.1 christos * Sig-validity-interval.
2316 1.1 christos */
2317 1.1 christos
2318 1.1 christos static cfg_tuplefielddef_t validityinterval_fields[] = {
2319 1.1 christos { "validity", &cfg_type_uint32, 0 },
2320 1.1 christos { "re-sign", &cfg_type_optional_uint32, 0 },
2321 1.1 christos { NULL, NULL, 0 }
2322 1.1 christos };
2323 1.1 christos
2324 1.1 christos static cfg_type_t cfg_type_validityinterval = {
2325 1.8 christos "validityinterval", cfg_parse_tuple, cfg_print_tuple,
2326 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, validityinterval_fields
2327 1.8 christos };
2328 1.8 christos
2329 1.8 christos /*%
2330 1.15.2.1 perseant * Checkds type.
2331 1.15.2.1 perseant */
2332 1.15.2.1 perseant static const char *checkds_enums[] = { "explicit", NULL };
2333 1.15.2.1 perseant static isc_result_t
2334 1.15.2.1 perseant parse_checkds_type(cfg_parser_t *pctx, const cfg_type_t *type,
2335 1.15.2.1 perseant cfg_obj_t **ret) {
2336 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
2337 1.15.2.1 perseant }
2338 1.15.2.1 perseant static void
2339 1.15.2.1 perseant doc_checkds_type(cfg_printer_t *pctx, const cfg_type_t *type) {
2340 1.15.2.1 perseant cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
2341 1.15.2.1 perseant }
2342 1.15.2.1 perseant static cfg_type_t cfg_type_checkdstype = {
2343 1.15.2.1 perseant "checkdstype", parse_checkds_type, cfg_print_ustring,
2344 1.15.2.1 perseant doc_checkds_type, &cfg_rep_string, checkds_enums,
2345 1.15.2.1 perseant };
2346 1.15.2.1 perseant
2347 1.15.2.1 perseant /*%
2348 1.8 christos * Clauses that can be found in a 'dnssec-policy' statement.
2349 1.8 christos */
2350 1.8 christos static cfg_clausedef_t dnssecpolicy_clauses[] = {
2351 1.15.2.1 perseant { "cdnskey", &cfg_type_boolean, 0 },
2352 1.15.2.1 perseant { "cds-digest-types", &cfg_type_algorithmlist, 0 },
2353 1.8 christos { "dnskey-ttl", &cfg_type_duration, 0 },
2354 1.15.2.1 perseant { "inline-signing", &cfg_type_boolean, 0 },
2355 1.8 christos { "keys", &cfg_type_kaspkeys, 0 },
2356 1.8 christos { "max-zone-ttl", &cfg_type_duration, 0 },
2357 1.9 christos { "nsec3param", &cfg_type_nsec3, 0 },
2358 1.15.2.1 perseant { "offline-ksk", &cfg_type_boolean, 0 },
2359 1.8 christos { "parent-ds-ttl", &cfg_type_duration, 0 },
2360 1.8 christos { "parent-propagation-delay", &cfg_type_duration, 0 },
2361 1.9 christos { "parent-registration-delay", &cfg_type_duration,
2362 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2363 1.8 christos { "publish-safety", &cfg_type_duration, 0 },
2364 1.11 christos { "purge-keys", &cfg_type_duration, 0 },
2365 1.8 christos { "retire-safety", &cfg_type_duration, 0 },
2366 1.15.2.1 perseant { "signatures-jitter", &cfg_type_duration, 0 },
2367 1.8 christos { "signatures-refresh", &cfg_type_duration, 0 },
2368 1.8 christos { "signatures-validity", &cfg_type_duration, 0 },
2369 1.8 christos { "signatures-validity-dnskey", &cfg_type_duration, 0 },
2370 1.8 christos { "zone-propagation-delay", &cfg_type_duration, 0 },
2371 1.8 christos { NULL, NULL, 0 }
2372 1.1 christos };
2373 1.1 christos
2374 1.15.2.1 perseant /*
2375 1.15.2.1 perseant * For min-transfer-rate-in.
2376 1.15.2.1 perseant */
2377 1.15.2.1 perseant static cfg_tuplefielddef_t min_transfer_rate_fields[] = {
2378 1.15.2.1 perseant { "traffic_bytes", &cfg_type_uint32, 0 },
2379 1.15.2.1 perseant { "time_minutes", &cfg_type_uint32, 0 },
2380 1.15.2.1 perseant { NULL, NULL, 0 }
2381 1.15.2.1 perseant };
2382 1.15.2.1 perseant
2383 1.15.2.1 perseant static cfg_type_t cfg_type_min_transfer_rate_in = {
2384 1.15.2.1 perseant "min-transfer-rate-in", cfg_parse_tuple, cfg_print_tuple,
2385 1.15.2.1 perseant cfg_doc_tuple, &cfg_rep_tuple, min_transfer_rate_fields
2386 1.15.2.1 perseant };
2387 1.15.2.1 perseant
2388 1.1 christos /*%
2389 1.1 christos * Clauses that can be found in a 'zone' statement,
2390 1.1 christos * with defaults in the 'view' or 'options' statement.
2391 1.1 christos *
2392 1.1 christos * Note: CFG_ZONE_* options indicate in which zone types this clause is
2393 1.1 christos * legal.
2394 1.1 christos */
2395 1.15 christos /*
2396 1.15 christos * NOTE: To enable syntax which allows specifying port and protocol
2397 1.15 christos * within 'allow-*' clauses, replace 'cfg_type_bracketed_aml' with
2398 1.15 christos * 'cfg_type_transport_acl'.
2399 1.15 christos *
2400 1.15 christos * Example: allow-transfer port 853 protocol tls { ... };
2401 1.15 christos */
2402 1.8 christos static cfg_clausedef_t zone_clauses[] = {
2403 1.1 christos { "allow-notify", &cfg_type_bracketed_aml,
2404 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2405 1.1 christos { "allow-query", &cfg_type_bracketed_aml,
2406 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2407 1.13 christos CFG_ZONE_STUB | CFG_ZONE_REDIRECT | CFG_ZONE_STATICSTUB },
2408 1.1 christos { "allow-query-on", &cfg_type_bracketed_aml,
2409 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2410 1.13 christos CFG_ZONE_STUB | CFG_ZONE_REDIRECT | CFG_ZONE_STATICSTUB },
2411 1.15 christos { "allow-transfer", &cfg_type_transport_acl,
2412 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2413 1.13 christos { "allow-update", &cfg_type_bracketed_aml, CFG_ZONE_PRIMARY },
2414 1.1 christos { "allow-update-forwarding", &cfg_type_bracketed_aml,
2415 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2416 1.1 christos { "also-notify", &cfg_type_namesockaddrkeylist,
2417 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2418 1.1 christos { "alt-transfer-source", &cfg_type_sockaddr4wild,
2419 1.15 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2420 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2421 1.1 christos { "alt-transfer-source-v6", &cfg_type_sockaddr6wild,
2422 1.15 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2423 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2424 1.1 christos { "auto-dnssec", &cfg_type_autodnssec,
2425 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_CLAUSEFLAG_ANCIENT },
2426 1.13 christos { "check-dup-records", &cfg_type_checkmode, CFG_ZONE_PRIMARY },
2427 1.13 christos { "check-integrity", &cfg_type_boolean, CFG_ZONE_PRIMARY },
2428 1.13 christos { "check-mx", &cfg_type_checkmode, CFG_ZONE_PRIMARY },
2429 1.13 christos { "check-mx-cname", &cfg_type_checkmode, CFG_ZONE_PRIMARY },
2430 1.13 christos { "check-sibling", &cfg_type_boolean, CFG_ZONE_PRIMARY },
2431 1.13 christos { "check-spf", &cfg_type_warn, CFG_ZONE_PRIMARY },
2432 1.13 christos { "check-srv-cname", &cfg_type_checkmode, CFG_ZONE_PRIMARY },
2433 1.15.2.1 perseant { "check-svcb", &cfg_type_boolean, CFG_ZONE_PRIMARY },
2434 1.13 christos { "check-wildcard", &cfg_type_boolean, CFG_ZONE_PRIMARY },
2435 1.1 christos { "dialup", &cfg_type_dialuptype,
2436 1.15 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_STUB |
2437 1.15 christos CFG_CLAUSEFLAG_DEPRECATED },
2438 1.1 christos { "dnssec-dnskey-kskonly", &cfg_type_boolean,
2439 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_CLAUSEFLAG_OBSOLETE },
2440 1.1 christos { "dnssec-loadkeys-interval", &cfg_type_uint32,
2441 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2442 1.8 christos { "dnssec-policy", &cfg_type_astring,
2443 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2444 1.15.2.1 perseant { "dnssec-secure-to-insecure", &cfg_type_boolean,
2445 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_CLAUSEFLAG_OBSOLETE },
2446 1.1 christos { "dnssec-update-mode", &cfg_type_dnssecupdatemode,
2447 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_CLAUSEFLAG_OBSOLETE },
2448 1.1 christos { "forward", &cfg_type_forwardtype,
2449 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_STUB |
2450 1.8 christos CFG_ZONE_STATICSTUB | CFG_ZONE_FORWARD },
2451 1.1 christos { "forwarders", &cfg_type_portiplist,
2452 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_STUB |
2453 1.8 christos CFG_ZONE_STATICSTUB | CFG_ZONE_FORWARD },
2454 1.1 christos { "key-directory", &cfg_type_qstring,
2455 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2456 1.15 christos { "maintain-ixfr-base", NULL, CFG_CLAUSEFLAG_ANCIENT },
2457 1.1 christos { "masterfile-format", &cfg_type_masterformat,
2458 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2459 1.13 christos CFG_ZONE_STUB | CFG_ZONE_REDIRECT },
2460 1.1 christos { "masterfile-style", &cfg_type_masterstyle,
2461 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2462 1.13 christos CFG_ZONE_STUB | CFG_ZONE_REDIRECT },
2463 1.15 christos { "max-ixfr-log-size", NULL, CFG_CLAUSEFLAG_ANCIENT },
2464 1.9 christos { "max-ixfr-ratio", &cfg_type_ixfrratio,
2465 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2466 1.1 christos { "max-journal-size", &cfg_type_size,
2467 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2468 1.1 christos { "max-records", &cfg_type_uint32,
2469 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2470 1.13 christos CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
2471 1.15.2.1 perseant { "max-records-per-type", &cfg_type_uint32,
2472 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2473 1.15.2.1 perseant CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
2474 1.15.2.1 perseant { "max-types-per-name", &cfg_type_uint32,
2475 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2476 1.15.2.1 perseant CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
2477 1.1 christos { "max-refresh-time", &cfg_type_uint32,
2478 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2479 1.1 christos { "max-retry-time", &cfg_type_uint32,
2480 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2481 1.15.2.1 perseant { "min-transfer-rate-in", &cfg_type_min_transfer_rate_in,
2482 1.15.2.1 perseant CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2483 1.1 christos { "max-transfer-idle-in", &cfg_type_uint32,
2484 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2485 1.1 christos { "max-transfer-idle-out", &cfg_type_uint32,
2486 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_MIRROR | CFG_ZONE_SECONDARY },
2487 1.1 christos { "max-transfer-time-in", &cfg_type_uint32,
2488 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2489 1.1 christos { "max-transfer-time-out", &cfg_type_uint32,
2490 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_MIRROR | CFG_ZONE_SECONDARY },
2491 1.8 christos { "max-zone-ttl", &cfg_type_maxduration,
2492 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_REDIRECT | CFG_CLAUSEFLAG_DEPRECATED },
2493 1.1 christos { "min-refresh-time", &cfg_type_uint32,
2494 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2495 1.1 christos { "min-retry-time", &cfg_type_uint32,
2496 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2497 1.1 christos { "multi-master", &cfg_type_boolean,
2498 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2499 1.1 christos { "notify", &cfg_type_notifytype,
2500 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2501 1.15.2.1 perseant { "notify-defer", &cfg_type_uint32,
2502 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2503 1.1 christos { "notify-delay", &cfg_type_uint32,
2504 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2505 1.1 christos { "notify-source", &cfg_type_sockaddr4wild,
2506 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2507 1.1 christos { "notify-source-v6", &cfg_type_sockaddr6wild,
2508 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2509 1.1 christos { "notify-to-soa", &cfg_type_boolean,
2510 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2511 1.1 christos { "nsec3-test-zone", &cfg_type_boolean,
2512 1.13 christos CFG_CLAUSEFLAG_TESTONLY | CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2513 1.12 christos { "parental-source", &cfg_type_sockaddr4wild,
2514 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2515 1.12 christos { "parental-source-v6", &cfg_type_sockaddr6wild,
2516 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2517 1.1 christos { "request-expire", &cfg_type_boolean,
2518 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2519 1.13 christos { "request-ixfr", &cfg_type_boolean,
2520 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2521 1.13 christos { "serial-update-method", &cfg_type_updatemethod, CFG_ZONE_PRIMARY },
2522 1.1 christos { "sig-signing-nodes", &cfg_type_uint32,
2523 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2524 1.1 christos { "sig-signing-signatures", &cfg_type_uint32,
2525 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2526 1.1 christos { "sig-signing-type", &cfg_type_uint32,
2527 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2528 1.1 christos { "sig-validity-interval", &cfg_type_validityinterval,
2529 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_CLAUSEFLAG_OBSOLETE },
2530 1.3 christos { "dnskey-sig-validity", &cfg_type_uint32,
2531 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_CLAUSEFLAG_OBSOLETE },
2532 1.1 christos { "transfer-source", &cfg_type_sockaddr4wild,
2533 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2534 1.1 christos { "transfer-source-v6", &cfg_type_sockaddr6wild,
2535 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
2536 1.1 christos { "try-tcp-refresh", &cfg_type_boolean,
2537 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2538 1.1 christos { "update-check-ksk", &cfg_type_boolean,
2539 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_CLAUSEFLAG_OBSOLETE },
2540 1.1 christos { "use-alt-transfer-source", &cfg_type_boolean,
2541 1.15 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB |
2542 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2543 1.1 christos { "zero-no-soa-ttl", &cfg_type_boolean,
2544 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2545 1.1 christos { "zone-statistics", &cfg_type_zonestat,
2546 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2547 1.13 christos CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
2548 1.1 christos { NULL, NULL, 0 }
2549 1.1 christos };
2550 1.1 christos
2551 1.1 christos /*%
2552 1.1 christos * Clauses that can be found in a 'zone' statement only.
2553 1.1 christos *
2554 1.1 christos * Note: CFG_ZONE_* options indicate in which zone types this clause is
2555 1.1 christos * legal.
2556 1.1 christos */
2557 1.8 christos static cfg_clausedef_t zone_only_clauses[] = {
2558 1.1 christos /*
2559 1.1 christos * Note that the format of the check-names option is different between
2560 1.1 christos * the zone options and the global/view options. Ugh.
2561 1.1 christos */
2562 1.1 christos { "type", &cfg_type_zonetype,
2563 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2564 1.13 christos CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_DELEGATION |
2565 1.13 christos CFG_ZONE_HINT | CFG_ZONE_REDIRECT | CFG_ZONE_FORWARD },
2566 1.1 christos { "check-names", &cfg_type_checkmode,
2567 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2568 1.13 christos CFG_ZONE_HINT | CFG_ZONE_STUB },
2569 1.15.2.1 perseant { "checkds", &cfg_type_checkdstype,
2570 1.15.2.1 perseant CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2571 1.13 christos { "database", &cfg_type_astring,
2572 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2573 1.8 christos CFG_ZONE_STUB },
2574 1.1 christos { "delegation-only", &cfg_type_boolean,
2575 1.15 christos CFG_ZONE_HINT | CFG_ZONE_STUB | CFG_ZONE_FORWARD |
2576 1.15.2.1 perseant CFG_CLAUSEFLAG_ANCIENT },
2577 1.1 christos { "dlz", &cfg_type_astring,
2578 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_REDIRECT },
2579 1.1 christos { "file", &cfg_type_qstring,
2580 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
2581 1.13 christos CFG_ZONE_STUB | CFG_ZONE_HINT | CFG_ZONE_REDIRECT },
2582 1.8 christos { "in-view", &cfg_type_astring, CFG_ZONE_INVIEW },
2583 1.12 christos { "inline-signing", &cfg_type_boolean,
2584 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2585 1.15 christos { "ixfr-base", NULL, CFG_CLAUSEFLAG_ANCIENT },
2586 1.1 christos { "ixfr-from-differences", &cfg_type_boolean,
2587 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2588 1.15 christos { "ixfr-tmp-file", NULL, CFG_CLAUSEFLAG_ANCIENT },
2589 1.1 christos { "journal", &cfg_type_qstring,
2590 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
2591 1.1 christos { "masters", &cfg_type_namesockaddrkeylist,
2592 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB |
2593 1.15 christos CFG_ZONE_REDIRECT | CFG_CLAUSEFLAG_NODOC },
2594 1.12 christos { "parental-agents", &cfg_type_namesockaddrkeylist,
2595 1.13 christos CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
2596 1.9 christos { "primaries", &cfg_type_namesockaddrkeylist,
2597 1.13 christos CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB |
2598 1.9 christos CFG_ZONE_REDIRECT },
2599 1.15 christos { "pubkey", NULL, CFG_CLAUSEFLAG_ANCIENT },
2600 1.3 christos { "server-addresses", &cfg_type_bracketed_netaddrlist,
2601 1.8 christos CFG_ZONE_STATICSTUB },
2602 1.8 christos { "server-names", &cfg_type_namelist, CFG_ZONE_STATICSTUB },
2603 1.13 christos { "update-policy", &cfg_type_updatepolicy, CFG_ZONE_PRIMARY },
2604 1.1 christos { NULL, NULL, 0 }
2605 1.1 christos };
2606 1.1 christos
2607 1.1 christos /*% The top-level named.conf syntax. */
2608 1.1 christos
2609 1.8 christos static cfg_clausedef_t *namedconf_clausesets[] = { namedconf_clauses,
2610 1.8 christos namedconf_or_view_clauses,
2611 1.8 christos NULL };
2612 1.15 christos cfg_type_t cfg_type_namedconf = { "namedconf", cfg_parse_mapbody,
2613 1.15 christos cfg_print_mapbody, cfg_doc_mapbody,
2614 1.15 christos &cfg_rep_map, namedconf_clausesets };
2615 1.1 christos
2616 1.8 christos /*% The bind.keys syntax (trust-anchors/managed-keys/trusted-keys only). */
2617 1.8 christos static cfg_clausedef_t *bindkeys_clausesets[] = { bindkeys_clauses, NULL };
2618 1.15 christos cfg_type_t cfg_type_bindkeys = { "bindkeys", cfg_parse_mapbody,
2619 1.15 christos cfg_print_mapbody, cfg_doc_mapbody,
2620 1.15 christos &cfg_rep_map, bindkeys_clausesets };
2621 1.1 christos
2622 1.1 christos /*% The "options" statement syntax. */
2623 1.1 christos
2624 1.8 christos static cfg_clausedef_t *options_clausesets[] = { options_clauses, view_clauses,
2625 1.8 christos zone_clauses, NULL };
2626 1.8 christos static cfg_type_t cfg_type_options = { "options", cfg_parse_map,
2627 1.8 christos cfg_print_map, cfg_doc_map,
2628 1.8 christos &cfg_rep_map, options_clausesets };
2629 1.1 christos
2630 1.1 christos /*% The "view" statement syntax. */
2631 1.1 christos
2632 1.8 christos static cfg_clausedef_t *view_clausesets[] = { view_only_clauses,
2633 1.8 christos namedconf_or_view_clauses,
2634 1.8 christos view_clauses, zone_clauses,
2635 1.8 christos NULL };
2636 1.8 christos
2637 1.8 christos static cfg_type_t cfg_type_viewopts = { "view", cfg_parse_map,
2638 1.8 christos cfg_print_map, cfg_doc_map,
2639 1.8 christos &cfg_rep_map, view_clausesets };
2640 1.8 christos
2641 1.8 christos /*% The "zone" statement syntax. */
2642 1.1 christos
2643 1.8 christos static cfg_clausedef_t *zone_clausesets[] = { zone_only_clauses, zone_clauses,
2644 1.8 christos NULL };
2645 1.15 christos cfg_type_t cfg_type_zoneopts = { "zoneopts", cfg_parse_map, cfg_print_map,
2646 1.15 christos cfg_doc_map, &cfg_rep_map, zone_clausesets };
2647 1.1 christos
2648 1.8 christos /*% The "dnssec-policy" statement syntax. */
2649 1.8 christos static cfg_clausedef_t *dnssecpolicy_clausesets[] = { dnssecpolicy_clauses,
2650 1.8 christos NULL };
2651 1.15 christos cfg_type_t cfg_type_dnssecpolicyopts = {
2652 1.8 christos "dnssecpolicyopts", cfg_parse_map, cfg_print_map,
2653 1.8 christos cfg_doc_map, &cfg_rep_map, dnssecpolicy_clausesets
2654 1.1 christos };
2655 1.1 christos
2656 1.1 christos /*% The "dynamically loadable zones" statement syntax. */
2657 1.1 christos
2658 1.8 christos static cfg_clausedef_t dlz_clauses[] = { { "database", &cfg_type_astring, 0 },
2659 1.8 christos { "search", &cfg_type_boolean, 0 },
2660 1.8 christos { NULL, NULL, 0 } };
2661 1.8 christos static cfg_clausedef_t *dlz_clausesets[] = { dlz_clauses, NULL };
2662 1.8 christos static cfg_type_t cfg_type_dlz = { "dlz", cfg_parse_named_map,
2663 1.8 christos cfg_print_map, cfg_doc_map,
2664 1.8 christos &cfg_rep_map, dlz_clausesets };
2665 1.1 christos
2666 1.1 christos /*%
2667 1.1 christos * The "dyndb" statement syntax.
2668 1.1 christos */
2669 1.1 christos
2670 1.1 christos static cfg_tuplefielddef_t dyndb_fields[] = {
2671 1.1 christos { "name", &cfg_type_astring, 0 },
2672 1.1 christos { "library", &cfg_type_qstring, 0 },
2673 1.1 christos { "parameters", &cfg_type_bracketed_text, 0 },
2674 1.1 christos { NULL, NULL, 0 }
2675 1.1 christos };
2676 1.1 christos
2677 1.8 christos static cfg_type_t cfg_type_dyndb = { "dyndb", cfg_parse_tuple,
2678 1.8 christos cfg_print_tuple, cfg_doc_tuple,
2679 1.8 christos &cfg_rep_tuple, dyndb_fields };
2680 1.1 christos
2681 1.1 christos /*%
2682 1.3 christos * The "plugin" statement syntax.
2683 1.3 christos * Currently only one plugin type is supported: query.
2684 1.3 christos */
2685 1.3 christos
2686 1.8 christos static const char *plugin_enums[] = { "query", NULL };
2687 1.8 christos static cfg_type_t cfg_type_plugintype = { "plugintype", cfg_parse_enum,
2688 1.8 christos cfg_print_ustring, cfg_doc_enum,
2689 1.8 christos &cfg_rep_string, plugin_enums };
2690 1.3 christos static cfg_tuplefielddef_t plugin_fields[] = {
2691 1.3 christos { "type", &cfg_type_plugintype, 0 },
2692 1.3 christos { "library", &cfg_type_astring, 0 },
2693 1.3 christos { "parameters", &cfg_type_optional_bracketed_text, 0 },
2694 1.3 christos { NULL, NULL, 0 }
2695 1.3 christos };
2696 1.8 christos static cfg_type_t cfg_type_plugin = { "plugin", cfg_parse_tuple,
2697 1.8 christos cfg_print_tuple, cfg_doc_tuple,
2698 1.8 christos &cfg_rep_tuple, plugin_fields };
2699 1.3 christos
2700 1.3 christos /*%
2701 1.1 christos * Clauses that can be found within the 'key' statement.
2702 1.1 christos */
2703 1.8 christos static cfg_clausedef_t key_clauses[] = { { "algorithm", &cfg_type_astring, 0 },
2704 1.8 christos { "secret", &cfg_type_sstring, 0 },
2705 1.8 christos { NULL, NULL, 0 } };
2706 1.8 christos
2707 1.8 christos static cfg_clausedef_t *key_clausesets[] = { key_clauses, NULL };
2708 1.8 christos static cfg_type_t cfg_type_key = { "key", cfg_parse_named_map,
2709 1.8 christos cfg_print_map, cfg_doc_map,
2710 1.8 christos &cfg_rep_map, key_clausesets };
2711 1.1 christos
2712 1.1 christos /*%
2713 1.15.2.1 perseant * A key-store statement.
2714 1.15.2.1 perseant */
2715 1.15.2.1 perseant static cfg_clausedef_t keystore_clauses[] = {
2716 1.15.2.1 perseant { "directory", &cfg_type_astring, 0 },
2717 1.15.2.1 perseant { "pkcs11-uri", &cfg_type_qstring, 0 },
2718 1.15.2.1 perseant { NULL, NULL, 0 }
2719 1.15.2.1 perseant };
2720 1.15.2.1 perseant
2721 1.15.2.1 perseant static cfg_clausedef_t *keystore_clausesets[] = { keystore_clauses, NULL };
2722 1.15.2.1 perseant static cfg_type_t cfg_type_keystoreopts = {
2723 1.15.2.1 perseant "keystoreopts", cfg_parse_map, cfg_print_map,
2724 1.15.2.1 perseant cfg_doc_map, &cfg_rep_map, keystore_clausesets
2725 1.15.2.1 perseant };
2726 1.15.2.1 perseant
2727 1.15.2.1 perseant static cfg_tuplefielddef_t keystore_fields[] = {
2728 1.15.2.1 perseant { "name", &cfg_type_astring, 0 },
2729 1.15.2.1 perseant { "options", &cfg_type_keystoreopts, 0 },
2730 1.15.2.1 perseant { NULL, NULL, 0 }
2731 1.15.2.1 perseant };
2732 1.15.2.1 perseant static cfg_type_t cfg_type_keystore = { "key-store", cfg_parse_tuple,
2733 1.15.2.1 perseant cfg_print_tuple, cfg_doc_tuple,
2734 1.15.2.1 perseant &cfg_rep_tuple, keystore_fields };
2735 1.15.2.1 perseant
2736 1.15.2.1 perseant /*%
2737 1.1 christos * Clauses that can be found in a 'server' statement.
2738 1.15 christos *
2739 1.15.2.1 perseant * Please update lib/isccfg/check.c and
2740 1.15 christos * bin/tests/system/checkconf/good-server-christmas-tree.conf.in to
2741 1.15 christos * exercise the new clause when adding new clauses.
2742 1.1 christos */
2743 1.8 christos static cfg_clausedef_t server_clauses[] = {
2744 1.1 christos { "bogus", &cfg_type_boolean, 0 },
2745 1.1 christos { "edns", &cfg_type_boolean, 0 },
2746 1.1 christos { "edns-udp-size", &cfg_type_uint32, 0 },
2747 1.1 christos { "edns-version", &cfg_type_uint32, 0 },
2748 1.1 christos { "keys", &cfg_type_server_key_kludge, 0 },
2749 1.1 christos { "max-udp-size", &cfg_type_uint32, 0 },
2750 1.1 christos { "notify-source", &cfg_type_sockaddr4wild, 0 },
2751 1.1 christos { "notify-source-v6", &cfg_type_sockaddr6wild, 0 },
2752 1.1 christos { "padding", &cfg_type_uint32, 0 },
2753 1.1 christos { "provide-ixfr", &cfg_type_boolean, 0 },
2754 1.15.2.1 perseant { "query-source", &cfg_type_server_querysource4, 0 },
2755 1.15.2.1 perseant { "query-source-v6", &cfg_type_server_querysource6, 0 },
2756 1.1 christos { "request-expire", &cfg_type_boolean, 0 },
2757 1.1 christos { "request-ixfr", &cfg_type_boolean, 0 },
2758 1.1 christos { "request-nsid", &cfg_type_boolean, 0 },
2759 1.15 christos { "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
2760 1.15.2.1 perseant { "require-cookie", &cfg_type_boolean, 0 },
2761 1.1 christos { "send-cookie", &cfg_type_boolean, 0 },
2762 1.15 christos { "support-ixfr", NULL, CFG_CLAUSEFLAG_ANCIENT },
2763 1.1 christos { "tcp-keepalive", &cfg_type_boolean, 0 },
2764 1.1 christos { "tcp-only", &cfg_type_boolean, 0 },
2765 1.1 christos { "transfer-format", &cfg_type_transferformat, 0 },
2766 1.1 christos { "transfer-source", &cfg_type_sockaddr4wild, 0 },
2767 1.1 christos { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 },
2768 1.1 christos { "transfers", &cfg_type_uint32, 0 },
2769 1.1 christos { NULL, NULL, 0 }
2770 1.1 christos };
2771 1.8 christos static cfg_clausedef_t *server_clausesets[] = { server_clauses, NULL };
2772 1.8 christos static cfg_type_t cfg_type_server = { "server", cfg_parse_netprefix_map,
2773 1.8 christos cfg_print_map, cfg_doc_map,
2774 1.8 christos &cfg_rep_map, server_clausesets };
2775 1.1 christos
2776 1.1 christos /*%
2777 1.1 christos * Clauses that can be found in a 'channel' clause in the
2778 1.1 christos * 'logging' statement.
2779 1.1 christos *
2780 1.1 christos * These have some additional constraints that need to be
2781 1.1 christos * checked after parsing:
2782 1.1 christos * - There must exactly one of file/syslog/null/stderr
2783 1.1 christos */
2784 1.1 christos
2785 1.8 christos static const char *printtime_enums[] = { "iso8601", "iso8601-utc", "local",
2786 1.8 christos NULL };
2787 1.1 christos static isc_result_t
2788 1.1 christos parse_printtime(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
2789 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
2790 1.1 christos }
2791 1.1 christos static void
2792 1.1 christos doc_printtime(cfg_printer_t *pctx, const cfg_type_t *type) {
2793 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
2794 1.1 christos }
2795 1.8 christos static cfg_type_t cfg_type_printtime = { "printtime", parse_printtime,
2796 1.8 christos cfg_print_ustring, doc_printtime,
2797 1.8 christos &cfg_rep_string, printtime_enums };
2798 1.1 christos
2799 1.8 christos static cfg_clausedef_t channel_clauses[] = {
2800 1.1 christos /* Destinations. We no longer require these to be first. */
2801 1.1 christos { "file", &cfg_type_logfile, 0 },
2802 1.1 christos { "syslog", &cfg_type_optional_facility, 0 },
2803 1.1 christos { "null", &cfg_type_void, 0 },
2804 1.1 christos { "stderr", &cfg_type_void, 0 },
2805 1.1 christos /* Options. We now accept these for the null channel, too. */
2806 1.1 christos { "severity", &cfg_type_logseverity, 0 },
2807 1.1 christos { "print-time", &cfg_type_printtime, 0 },
2808 1.1 christos { "print-severity", &cfg_type_boolean, 0 },
2809 1.1 christos { "print-category", &cfg_type_boolean, 0 },
2810 1.1 christos { "buffered", &cfg_type_boolean, 0 },
2811 1.1 christos { NULL, NULL, 0 }
2812 1.1 christos };
2813 1.8 christos static cfg_clausedef_t *channel_clausesets[] = { channel_clauses, NULL };
2814 1.8 christos static cfg_type_t cfg_type_channel = { "channel", cfg_parse_named_map,
2815 1.8 christos cfg_print_map, cfg_doc_map,
2816 1.8 christos &cfg_rep_map, channel_clausesets };
2817 1.1 christos
2818 1.1 christos /*% A list of log destination, used in the "category" clause. */
2819 1.8 christos static cfg_type_t cfg_type_destinationlist = { "destinationlist",
2820 1.8 christos cfg_parse_bracketed_list,
2821 1.8 christos cfg_print_bracketed_list,
2822 1.8 christos cfg_doc_bracketed_list,
2823 1.8 christos &cfg_rep_list,
2824 1.8 christos &cfg_type_astring };
2825 1.1 christos
2826 1.1 christos /*%
2827 1.1 christos * Clauses that can be found in a 'logging' statement.
2828 1.1 christos */
2829 1.1 christos static cfg_clausedef_t logging_clauses[] = {
2830 1.1 christos { "channel", &cfg_type_channel, CFG_CLAUSEFLAG_MULTI },
2831 1.1 christos { "category", &cfg_type_category, CFG_CLAUSEFLAG_MULTI },
2832 1.1 christos { NULL, NULL, 0 }
2833 1.1 christos };
2834 1.8 christos static cfg_clausedef_t *logging_clausesets[] = { logging_clauses, NULL };
2835 1.8 christos static cfg_type_t cfg_type_logging = { "logging", cfg_parse_map,
2836 1.8 christos cfg_print_map, cfg_doc_map,
2837 1.8 christos &cfg_rep_map, logging_clausesets };
2838 1.1 christos
2839 1.1 christos /*%
2840 1.1 christos * For parsing an 'addzone' statement
2841 1.1 christos */
2842 1.1 christos static cfg_tuplefielddef_t addzone_fields[] = {
2843 1.1 christos { "name", &cfg_type_astring, 0 },
2844 1.1 christos { "class", &cfg_type_optional_class, 0 },
2845 1.1 christos { "view", &cfg_type_optional_class, 0 },
2846 1.1 christos { "options", &cfg_type_zoneopts, 0 },
2847 1.1 christos { NULL, NULL, 0 }
2848 1.1 christos };
2849 1.8 christos static cfg_type_t cfg_type_addzone = { "zone", cfg_parse_tuple,
2850 1.8 christos cfg_print_tuple, cfg_doc_tuple,
2851 1.8 christos &cfg_rep_tuple, addzone_fields };
2852 1.1 christos
2853 1.8 christos static cfg_clausedef_t addzoneconf_clauses[] = {
2854 1.8 christos { "zone", &cfg_type_addzone, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 }
2855 1.1 christos };
2856 1.1 christos
2857 1.8 christos static cfg_clausedef_t *addzoneconf_clausesets[] = { addzoneconf_clauses,
2858 1.8 christos NULL };
2859 1.1 christos
2860 1.15 christos cfg_type_t cfg_type_addzoneconf = { "addzoneconf", cfg_parse_mapbody,
2861 1.15 christos cfg_print_mapbody, cfg_doc_mapbody,
2862 1.15 christos &cfg_rep_map, addzoneconf_clausesets };
2863 1.1 christos
2864 1.1 christos static isc_result_t
2865 1.15.2.1 perseant parse_unitstring(char *str, uint64_t *valuep) {
2866 1.1 christos char *endp;
2867 1.1 christos unsigned int len;
2868 1.3 christos uint64_t value;
2869 1.3 christos uint64_t unit;
2870 1.1 christos
2871 1.3 christos value = strtoull(str, &endp, 10);
2872 1.1 christos if (*endp == 0) {
2873 1.1 christos *valuep = value;
2874 1.15.2.1 perseant return ISC_R_SUCCESS;
2875 1.1 christos }
2876 1.1 christos
2877 1.1 christos len = strlen(str);
2878 1.8 christos if (len < 2 || endp[1] != '\0') {
2879 1.15.2.1 perseant return ISC_R_FAILURE;
2880 1.8 christos }
2881 1.1 christos
2882 1.1 christos switch (str[len - 1]) {
2883 1.1 christos case 'k':
2884 1.1 christos case 'K':
2885 1.1 christos unit = 1024;
2886 1.1 christos break;
2887 1.1 christos case 'm':
2888 1.1 christos case 'M':
2889 1.1 christos unit = 1024 * 1024;
2890 1.1 christos break;
2891 1.1 christos case 'g':
2892 1.1 christos case 'G':
2893 1.1 christos unit = 1024 * 1024 * 1024;
2894 1.1 christos break;
2895 1.1 christos default:
2896 1.15.2.1 perseant return ISC_R_FAILURE;
2897 1.1 christos }
2898 1.7 christos if (value > ((uint64_t)UINT64_MAX / unit)) {
2899 1.15.2.1 perseant return ISC_R_FAILURE;
2900 1.7 christos }
2901 1.1 christos *valuep = value * unit;
2902 1.15.2.1 perseant return ISC_R_SUCCESS;
2903 1.1 christos }
2904 1.1 christos
2905 1.1 christos static isc_result_t
2906 1.1 christos parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
2907 1.1 christos isc_result_t result;
2908 1.1 christos cfg_obj_t *obj = NULL;
2909 1.3 christos uint64_t val;
2910 1.1 christos
2911 1.1 christos UNUSED(type);
2912 1.1 christos
2913 1.1 christos CHECK(cfg_gettoken(pctx, 0));
2914 1.1 christos if (pctx->token.type != isc_tokentype_string) {
2915 1.1 christos result = ISC_R_UNEXPECTEDTOKEN;
2916 1.1 christos goto cleanup;
2917 1.1 christos }
2918 1.1 christos CHECK(parse_unitstring(TOKEN_STRING(pctx), &val));
2919 1.1 christos
2920 1.1 christos CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj));
2921 1.1 christos obj->value.uint64 = val;
2922 1.1 christos *ret = obj;
2923 1.15.2.1 perseant return ISC_R_SUCCESS;
2924 1.1 christos
2925 1.8 christos cleanup:
2926 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
2927 1.1 christos "expected integer and optional unit");
2928 1.15.2.1 perseant return result;
2929 1.1 christos }
2930 1.1 christos
2931 1.1 christos static isc_result_t
2932 1.1 christos parse_sizeval_percent(cfg_parser_t *pctx, const cfg_type_t *type,
2933 1.8 christos cfg_obj_t **ret) {
2934 1.1 christos char *endp;
2935 1.8 christos isc_result_t result;
2936 1.1 christos cfg_obj_t *obj = NULL;
2937 1.3 christos uint64_t val;
2938 1.3 christos uint64_t percent;
2939 1.1 christos
2940 1.1 christos UNUSED(type);
2941 1.1 christos
2942 1.1 christos CHECK(cfg_gettoken(pctx, 0));
2943 1.1 christos if (pctx->token.type != isc_tokentype_string) {
2944 1.1 christos result = ISC_R_UNEXPECTEDTOKEN;
2945 1.1 christos goto cleanup;
2946 1.1 christos }
2947 1.1 christos
2948 1.3 christos percent = strtoull(TOKEN_STRING(pctx), &endp, 10);
2949 1.1 christos
2950 1.8 christos if (*endp == '%' && *(endp + 1) == 0) {
2951 1.1 christos CHECK(cfg_create_obj(pctx, &cfg_type_percentage, &obj));
2952 1.3 christos obj->value.uint32 = (uint32_t)percent;
2953 1.1 christos *ret = obj;
2954 1.15.2.1 perseant return ISC_R_SUCCESS;
2955 1.1 christos } else {
2956 1.1 christos CHECK(parse_unitstring(TOKEN_STRING(pctx), &val));
2957 1.1 christos CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj));
2958 1.1 christos obj->value.uint64 = val;
2959 1.1 christos *ret = obj;
2960 1.15.2.1 perseant return ISC_R_SUCCESS;
2961 1.1 christos }
2962 1.1 christos
2963 1.8 christos cleanup:
2964 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
2965 1.1 christos "expected integer and optional unit or percent");
2966 1.15.2.1 perseant return result;
2967 1.1 christos }
2968 1.1 christos
2969 1.1 christos static void
2970 1.1 christos doc_sizeval_percent(cfg_printer_t *pctx, const cfg_type_t *type) {
2971 1.1 christos UNUSED(type);
2972 1.1 christos
2973 1.1 christos cfg_print_cstr(pctx, "( ");
2974 1.1 christos cfg_doc_terminal(pctx, &cfg_type_size);
2975 1.1 christos cfg_print_cstr(pctx, " | ");
2976 1.1 christos cfg_doc_terminal(pctx, &cfg_type_percentage);
2977 1.1 christos cfg_print_cstr(pctx, " )");
2978 1.1 christos }
2979 1.1 christos
2980 1.1 christos /*%
2981 1.1 christos * A size value (number + optional unit).
2982 1.1 christos */
2983 1.8 christos static cfg_type_t cfg_type_sizeval = { "sizeval", parse_sizeval,
2984 1.8 christos cfg_print_uint64, cfg_doc_terminal,
2985 1.8 christos &cfg_rep_uint64, NULL };
2986 1.1 christos
2987 1.1 christos /*%
2988 1.1 christos * A size, "unlimited", or "default".
2989 1.1 christos */
2990 1.1 christos
2991 1.1 christos static isc_result_t
2992 1.1 christos parse_size(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
2993 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret);
2994 1.1 christos }
2995 1.1 christos
2996 1.1 christos static void
2997 1.1 christos doc_size(cfg_printer_t *pctx, const cfg_type_t *type) {
2998 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_sizeval);
2999 1.1 christos }
3000 1.1 christos
3001 1.1 christos static const char *size_enums[] = { "default", "unlimited", NULL };
3002 1.1 christos static cfg_type_t cfg_type_size = {
3003 1.8 christos "size", parse_size, cfg_print_ustring,
3004 1.8 christos doc_size, &cfg_rep_string, size_enums
3005 1.1 christos };
3006 1.1 christos
3007 1.1 christos /*%
3008 1.1 christos * A size or "unlimited", but not "default".
3009 1.1 christos */
3010 1.1 christos static const char *sizenodefault_enums[] = { "unlimited", NULL };
3011 1.1 christos static cfg_type_t cfg_type_sizenodefault = {
3012 1.8 christos "size_no_default", parse_size, cfg_print_ustring,
3013 1.8 christos doc_size, &cfg_rep_string, sizenodefault_enums
3014 1.1 christos };
3015 1.1 christos
3016 1.1 christos /*%
3017 1.1 christos * A size in absolute values or percents.
3018 1.1 christos */
3019 1.1 christos static cfg_type_t cfg_type_sizeval_percent = {
3020 1.8 christos "sizeval_percent", parse_sizeval_percent, cfg_print_ustring,
3021 1.8 christos doc_sizeval_percent, &cfg_rep_string, NULL
3022 1.1 christos };
3023 1.1 christos
3024 1.1 christos /*%
3025 1.1 christos * A size in absolute values or percents, or "unlimited", or "default"
3026 1.1 christos */
3027 1.1 christos
3028 1.1 christos static isc_result_t
3029 1.1 christos parse_size_or_percent(cfg_parser_t *pctx, const cfg_type_t *type,
3030 1.8 christos cfg_obj_t **ret) {
3031 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_sizeval_percent,
3032 1.15.2.1 perseant ret);
3033 1.1 christos }
3034 1.1 christos
3035 1.1 christos static void
3036 1.1 christos doc_parse_size_or_percent(cfg_printer_t *pctx, const cfg_type_t *type) {
3037 1.3 christos UNUSED(type);
3038 1.3 christos cfg_print_cstr(pctx, "( default | unlimited | ");
3039 1.3 christos cfg_doc_terminal(pctx, &cfg_type_sizeval);
3040 1.3 christos cfg_print_cstr(pctx, " | ");
3041 1.3 christos cfg_doc_terminal(pctx, &cfg_type_percentage);
3042 1.3 christos cfg_print_cstr(pctx, " )");
3043 1.1 christos }
3044 1.1 christos
3045 1.1 christos static const char *sizeorpercent_enums[] = { "default", "unlimited", NULL };
3046 1.1 christos static cfg_type_t cfg_type_sizeorpercent = {
3047 1.8 christos "size_or_percent", parse_size_or_percent, cfg_print_ustring,
3048 1.8 christos doc_parse_size_or_percent, &cfg_rep_string, sizeorpercent_enums
3049 1.1 christos };
3050 1.1 christos
3051 1.1 christos /*%
3052 1.9 christos * An IXFR size ratio: percentage, or "unlimited".
3053 1.9 christos */
3054 1.9 christos
3055 1.9 christos static isc_result_t
3056 1.9 christos parse_ixfrratio(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3057 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_percentage, ret);
3058 1.9 christos }
3059 1.9 christos
3060 1.9 christos static void
3061 1.9 christos doc_ixfrratio(cfg_printer_t *pctx, const cfg_type_t *type) {
3062 1.9 christos UNUSED(type);
3063 1.9 christos cfg_print_cstr(pctx, "( unlimited | ");
3064 1.9 christos cfg_doc_terminal(pctx, &cfg_type_percentage);
3065 1.9 christos cfg_print_cstr(pctx, " )");
3066 1.9 christos }
3067 1.9 christos
3068 1.9 christos static const char *ixfrratio_enums[] = { "unlimited", NULL };
3069 1.9 christos static cfg_type_t cfg_type_ixfrratio = { "ixfr_ratio", parse_ixfrratio,
3070 1.9 christos NULL, doc_ixfrratio,
3071 1.9 christos NULL, ixfrratio_enums };
3072 1.9 christos
3073 1.9 christos /*%
3074 1.1 christos * optional_keyvalue
3075 1.1 christos */
3076 1.1 christos static isc_result_t
3077 1.1 christos parse_maybe_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
3078 1.8 christos bool optional, cfg_obj_t **ret) {
3079 1.1 christos isc_result_t result;
3080 1.1 christos cfg_obj_t *obj = NULL;
3081 1.1 christos const keyword_type_t *kw = type->of;
3082 1.1 christos
3083 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3084 1.1 christos if (pctx->token.type == isc_tokentype_string &&
3085 1.8 christos strcasecmp(TOKEN_STRING(pctx), kw->name) == 0)
3086 1.8 christos {
3087 1.1 christos CHECK(cfg_gettoken(pctx, 0));
3088 1.1 christos CHECK(kw->type->parse(pctx, kw->type, &obj));
3089 1.1 christos obj->type = type; /* XXX kludge */
3090 1.1 christos } else {
3091 1.1 christos if (optional) {
3092 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj));
3093 1.1 christos } else {
3094 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR, "expected '%s'",
3095 1.8 christos kw->name);
3096 1.1 christos result = ISC_R_UNEXPECTEDTOKEN;
3097 1.1 christos goto cleanup;
3098 1.1 christos }
3099 1.1 christos }
3100 1.1 christos *ret = obj;
3101 1.8 christos cleanup:
3102 1.15.2.1 perseant return result;
3103 1.1 christos }
3104 1.1 christos
3105 1.1 christos static isc_result_t
3106 1.1 christos parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3107 1.15.2.1 perseant return parse_maybe_optional_keyvalue(pctx, type, false, ret);
3108 1.1 christos }
3109 1.1 christos
3110 1.1 christos static isc_result_t
3111 1.1 christos parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type,
3112 1.8 christos cfg_obj_t **ret) {
3113 1.15.2.1 perseant return parse_maybe_optional_keyvalue(pctx, type, true, ret);
3114 1.1 christos }
3115 1.1 christos
3116 1.1 christos static void
3117 1.1 christos print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj) {
3118 1.1 christos const keyword_type_t *kw = obj->type->of;
3119 1.1 christos cfg_print_cstr(pctx, kw->name);
3120 1.1 christos cfg_print_cstr(pctx, " ");
3121 1.1 christos kw->type->print(pctx, obj);
3122 1.1 christos }
3123 1.1 christos
3124 1.1 christos static void
3125 1.1 christos doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) {
3126 1.1 christos const keyword_type_t *kw = type->of;
3127 1.1 christos cfg_print_cstr(pctx, kw->name);
3128 1.1 christos cfg_print_cstr(pctx, " ");
3129 1.1 christos cfg_doc_obj(pctx, kw->type);
3130 1.1 christos }
3131 1.1 christos
3132 1.1 christos static void
3133 1.1 christos doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) {
3134 1.1 christos const keyword_type_t *kw = type->of;
3135 1.1 christos cfg_print_cstr(pctx, "[ ");
3136 1.1 christos cfg_print_cstr(pctx, kw->name);
3137 1.1 christos cfg_print_cstr(pctx, " ");
3138 1.1 christos cfg_doc_obj(pctx, kw->type);
3139 1.1 christos cfg_print_cstr(pctx, " ]");
3140 1.1 christos }
3141 1.1 christos
3142 1.8 christos static const char *dialup_enums[] = { "notify", "notify-passive", "passive",
3143 1.8 christos "refresh", NULL };
3144 1.1 christos static isc_result_t
3145 1.8 christos parse_dialup_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3146 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
3147 1.1 christos }
3148 1.1 christos static void
3149 1.1 christos doc_dialup_type(cfg_printer_t *pctx, const cfg_type_t *type) {
3150 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
3151 1.1 christos }
3152 1.8 christos static cfg_type_t cfg_type_dialuptype = { "dialuptype", parse_dialup_type,
3153 1.8 christos cfg_print_ustring, doc_dialup_type,
3154 1.8 christos &cfg_rep_string, dialup_enums };
3155 1.1 christos
3156 1.9 christos static const char *notify_enums[] = { "explicit", "master-only", "primary-only",
3157 1.9 christos NULL };
3158 1.1 christos static isc_result_t
3159 1.8 christos parse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3160 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
3161 1.1 christos }
3162 1.1 christos static void
3163 1.1 christos doc_notify_type(cfg_printer_t *pctx, const cfg_type_t *type) {
3164 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
3165 1.1 christos }
3166 1.1 christos static cfg_type_t cfg_type_notifytype = {
3167 1.8 christos "notifytype", parse_notify_type, cfg_print_ustring,
3168 1.8 christos doc_notify_type, &cfg_rep_string, notify_enums,
3169 1.1 christos };
3170 1.1 christos
3171 1.1 christos static const char *minimal_enums[] = { "no-auth", "no-auth-recursive", NULL };
3172 1.1 christos static isc_result_t
3173 1.1 christos parse_minimal(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3174 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
3175 1.1 christos }
3176 1.1 christos static void
3177 1.1 christos doc_minimal(cfg_printer_t *pctx, const cfg_type_t *type) {
3178 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
3179 1.1 christos }
3180 1.1 christos static cfg_type_t cfg_type_minimal = {
3181 1.8 christos "minimal", parse_minimal, cfg_print_ustring,
3182 1.8 christos doc_minimal, &cfg_rep_string, minimal_enums,
3183 1.1 christos };
3184 1.1 christos
3185 1.8 christos static const char *ixfrdiff_enums[] = { "primary", "master", "secondary",
3186 1.8 christos "slave", NULL };
3187 1.1 christos static isc_result_t
3188 1.1 christos parse_ixfrdiff_type(cfg_parser_t *pctx, const cfg_type_t *type,
3189 1.8 christos cfg_obj_t **ret) {
3190 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_boolean, ret);
3191 1.1 christos }
3192 1.1 christos static void
3193 1.1 christos doc_ixfrdiff_type(cfg_printer_t *pctx, const cfg_type_t *type) {
3194 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_boolean);
3195 1.1 christos }
3196 1.1 christos static cfg_type_t cfg_type_ixfrdifftype = {
3197 1.8 christos "ixfrdiff", parse_ixfrdiff_type, cfg_print_ustring,
3198 1.8 christos doc_ixfrdiff_type, &cfg_rep_string, ixfrdiff_enums,
3199 1.1 christos };
3200 1.1 christos
3201 1.1 christos static keyword_type_t key_kw = { "key", &cfg_type_astring };
3202 1.1 christos
3203 1.15 christos cfg_type_t cfg_type_keyref = { "keyref", parse_keyvalue, print_keyvalue,
3204 1.15 christos doc_keyvalue, &cfg_rep_string, &key_kw };
3205 1.1 christos
3206 1.1 christos static cfg_type_t cfg_type_optional_keyref = {
3207 1.8 christos "optional_keyref", parse_optional_keyvalue, print_keyvalue,
3208 1.8 christos doc_optional_keyvalue, &cfg_rep_string, &key_kw
3209 1.1 christos };
3210 1.1 christos
3211 1.8 christos static const char *qminmethod_enums[] = { "strict", "relaxed", "disabled",
3212 1.8 christos "off", NULL };
3213 1.1 christos
3214 1.8 christos static cfg_type_t cfg_type_qminmethod = { "qminmethod", cfg_parse_enum,
3215 1.8 christos cfg_print_ustring, cfg_doc_enum,
3216 1.8 christos &cfg_rep_string, qminmethod_enums };
3217 1.1 christos
3218 1.1 christos /*%
3219 1.1 christos * A "controls" statement is represented as a map with the multivalued
3220 1.1 christos * "inet" and "unix" clauses.
3221 1.1 christos */
3222 1.1 christos
3223 1.8 christos static keyword_type_t controls_allow_kw = { "allow", &cfg_type_bracketed_aml };
3224 1.1 christos
3225 1.1 christos static cfg_type_t cfg_type_controls_allow = {
3226 1.8 christos "controls_allow", parse_keyvalue, print_keyvalue,
3227 1.8 christos doc_keyvalue, &cfg_rep_list, &controls_allow_kw
3228 1.1 christos };
3229 1.1 christos
3230 1.8 christos static keyword_type_t controls_keys_kw = { "keys", &cfg_type_keylist };
3231 1.1 christos
3232 1.1 christos static cfg_type_t cfg_type_controls_keys = {
3233 1.8 christos "controls_keys", parse_optional_keyvalue, print_keyvalue,
3234 1.8 christos doc_optional_keyvalue, &cfg_rep_list, &controls_keys_kw
3235 1.1 christos };
3236 1.1 christos
3237 1.8 christos static keyword_type_t controls_readonly_kw = { "read-only", &cfg_type_boolean };
3238 1.1 christos
3239 1.1 christos static cfg_type_t cfg_type_controls_readonly = {
3240 1.8 christos "controls_readonly", parse_optional_keyvalue, print_keyvalue,
3241 1.8 christos doc_optional_keyvalue, &cfg_rep_boolean, &controls_readonly_kw
3242 1.1 christos };
3243 1.1 christos
3244 1.1 christos static cfg_tuplefielddef_t inetcontrol_fields[] = {
3245 1.1 christos { "address", &cfg_type_controls_sockaddr, 0 },
3246 1.1 christos { "allow", &cfg_type_controls_allow, 0 },
3247 1.1 christos { "keys", &cfg_type_controls_keys, 0 },
3248 1.1 christos { "read-only", &cfg_type_controls_readonly, 0 },
3249 1.1 christos { NULL, NULL, 0 }
3250 1.1 christos };
3251 1.1 christos
3252 1.1 christos static cfg_type_t cfg_type_inetcontrol = {
3253 1.8 christos "inetcontrol", cfg_parse_tuple, cfg_print_tuple,
3254 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, inetcontrol_fields
3255 1.1 christos };
3256 1.1 christos
3257 1.8 christos static keyword_type_t controls_perm_kw = { "perm", &cfg_type_uint32 };
3258 1.1 christos
3259 1.1 christos static cfg_type_t cfg_type_controls_perm = {
3260 1.8 christos "controls_perm", parse_keyvalue, print_keyvalue,
3261 1.8 christos doc_keyvalue, &cfg_rep_uint32, &controls_perm_kw
3262 1.1 christos };
3263 1.1 christos
3264 1.8 christos static keyword_type_t controls_owner_kw = { "owner", &cfg_type_uint32 };
3265 1.1 christos
3266 1.1 christos static cfg_type_t cfg_type_controls_owner = {
3267 1.8 christos "controls_owner", parse_keyvalue, print_keyvalue,
3268 1.8 christos doc_keyvalue, &cfg_rep_uint32, &controls_owner_kw
3269 1.1 christos };
3270 1.1 christos
3271 1.8 christos static keyword_type_t controls_group_kw = { "group", &cfg_type_uint32 };
3272 1.1 christos
3273 1.1 christos static cfg_type_t cfg_type_controls_group = {
3274 1.8 christos "controls_allow", parse_keyvalue, print_keyvalue,
3275 1.8 christos doc_keyvalue, &cfg_rep_uint32, &controls_group_kw
3276 1.1 christos };
3277 1.1 christos
3278 1.1 christos static cfg_tuplefielddef_t unixcontrol_fields[] = {
3279 1.1 christos { "path", &cfg_type_qstring, 0 },
3280 1.1 christos { "perm", &cfg_type_controls_perm, 0 },
3281 1.1 christos { "owner", &cfg_type_controls_owner, 0 },
3282 1.1 christos { "group", &cfg_type_controls_group, 0 },
3283 1.1 christos { "keys", &cfg_type_controls_keys, 0 },
3284 1.1 christos { "read-only", &cfg_type_controls_readonly, 0 },
3285 1.1 christos { NULL, NULL, 0 }
3286 1.1 christos };
3287 1.1 christos
3288 1.1 christos static cfg_type_t cfg_type_unixcontrol = {
3289 1.8 christos "unixcontrol", cfg_parse_tuple, cfg_print_tuple,
3290 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, unixcontrol_fields
3291 1.1 christos };
3292 1.1 christos
3293 1.8 christos static cfg_clausedef_t controls_clauses[] = {
3294 1.1 christos { "inet", &cfg_type_inetcontrol, CFG_CLAUSEFLAG_MULTI },
3295 1.1 christos { "unix", &cfg_type_unixcontrol, CFG_CLAUSEFLAG_MULTI },
3296 1.1 christos { NULL, NULL, 0 }
3297 1.1 christos };
3298 1.1 christos
3299 1.8 christos static cfg_clausedef_t *controls_clausesets[] = { controls_clauses, NULL };
3300 1.8 christos static cfg_type_t cfg_type_controls = { "controls", cfg_parse_map,
3301 1.8 christos cfg_print_map, cfg_doc_map,
3302 1.8 christos &cfg_rep_map, &controls_clausesets };
3303 1.1 christos
3304 1.1 christos /*%
3305 1.1 christos * A "statistics-channels" statement is represented as a map with the
3306 1.1 christos * multivalued "inet" clauses.
3307 1.1 christos */
3308 1.1 christos static void
3309 1.1 christos doc_optional_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type) {
3310 1.1 christos const keyword_type_t *kw = type->of;
3311 1.1 christos cfg_print_cstr(pctx, "[ ");
3312 1.1 christos cfg_print_cstr(pctx, kw->name);
3313 1.1 christos cfg_print_cstr(pctx, " ");
3314 1.1 christos cfg_doc_obj(pctx, kw->type);
3315 1.1 christos cfg_print_cstr(pctx, " ]");
3316 1.1 christos }
3317 1.1 christos
3318 1.1 christos static cfg_type_t cfg_type_optional_allow = {
3319 1.8 christos "optional_allow", parse_optional_keyvalue,
3320 1.8 christos print_keyvalue, doc_optional_bracketed_list,
3321 1.8 christos &cfg_rep_list, &controls_allow_kw
3322 1.1 christos };
3323 1.1 christos
3324 1.1 christos static cfg_tuplefielddef_t statserver_fields[] = {
3325 1.1 christos { "address", &cfg_type_controls_sockaddr, 0 }, /* reuse controls def */
3326 1.1 christos { "allow", &cfg_type_optional_allow, 0 },
3327 1.1 christos { NULL, NULL, 0 }
3328 1.1 christos };
3329 1.1 christos
3330 1.1 christos static cfg_type_t cfg_type_statschannel = {
3331 1.8 christos "statschannel", cfg_parse_tuple, cfg_print_tuple,
3332 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, statserver_fields
3333 1.1 christos };
3334 1.1 christos
3335 1.8 christos static cfg_clausedef_t statservers_clauses[] = {
3336 1.1 christos { "inet", &cfg_type_statschannel, CFG_CLAUSEFLAG_MULTI },
3337 1.1 christos { NULL, NULL, 0 }
3338 1.1 christos };
3339 1.1 christos
3340 1.8 christos static cfg_clausedef_t *statservers_clausesets[] = { statservers_clauses,
3341 1.8 christos NULL };
3342 1.1 christos
3343 1.1 christos static cfg_type_t cfg_type_statschannels = {
3344 1.8 christos "statistics-channels", cfg_parse_map, cfg_print_map,
3345 1.8 christos cfg_doc_map, &cfg_rep_map, &statservers_clausesets
3346 1.1 christos };
3347 1.1 christos
3348 1.1 christos /*%
3349 1.1 christos * An optional class, as used in view and zone statements.
3350 1.1 christos */
3351 1.1 christos static isc_result_t
3352 1.1 christos parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type,
3353 1.8 christos cfg_obj_t **ret) {
3354 1.1 christos isc_result_t result;
3355 1.1 christos UNUSED(type);
3356 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3357 1.8 christos if (pctx->token.type == isc_tokentype_string) {
3358 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, ret));
3359 1.8 christos } else {
3360 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret));
3361 1.8 christos }
3362 1.8 christos cleanup:
3363 1.15.2.1 perseant return result;
3364 1.1 christos }
3365 1.1 christos
3366 1.1 christos static void
3367 1.1 christos doc_optional_class(cfg_printer_t *pctx, const cfg_type_t *type) {
3368 1.1 christos UNUSED(type);
3369 1.1 christos cfg_print_cstr(pctx, "[ <class> ]");
3370 1.1 christos }
3371 1.1 christos
3372 1.8 christos static cfg_type_t cfg_type_optional_class = { "optional_class",
3373 1.8 christos parse_optional_class,
3374 1.8 christos NULL,
3375 1.8 christos doc_optional_class,
3376 1.8 christos NULL,
3377 1.8 christos NULL };
3378 1.1 christos
3379 1.1 christos static isc_result_t
3380 1.8 christos parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3381 1.1 christos isc_result_t result;
3382 1.1 christos cfg_obj_t *obj = NULL;
3383 1.1 christos isc_netaddr_t netaddr;
3384 1.1 christos in_port_t port = 0;
3385 1.1 christos unsigned int have_address = 0;
3386 1.1 christos unsigned int have_port = 0;
3387 1.15.2.1 perseant unsigned int have_tls = 0;
3388 1.15.2.1 perseant bool has_none = false;
3389 1.1 christos const unsigned int *flagp = type->of;
3390 1.1 christos
3391 1.3 christos if ((*flagp & CFG_ADDR_V4OK) != 0) {
3392 1.1 christos isc_netaddr_any(&netaddr);
3393 1.3 christos } else if ((*flagp & CFG_ADDR_V6OK) != 0) {
3394 1.1 christos isc_netaddr_any6(&netaddr);
3395 1.3 christos } else {
3396 1.13 christos UNREACHABLE();
3397 1.3 christos }
3398 1.1 christos
3399 1.1 christos for (;;) {
3400 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3401 1.1 christos if (pctx->token.type == isc_tokentype_string) {
3402 1.15.2.1 perseant if (strcasecmp(TOKEN_STRING(pctx), "none") == 0) {
3403 1.15.2.1 perseant CHECK(cfg_gettoken(pctx, 0));
3404 1.15.2.1 perseant has_none = true;
3405 1.15.2.1 perseant } else if (strcasecmp(TOKEN_STRING(pctx), "address") ==
3406 1.15.2.1 perseant 0)
3407 1.15.2.1 perseant {
3408 1.1 christos /* read "address" */
3409 1.1 christos CHECK(cfg_gettoken(pctx, 0));
3410 1.15.2.1 perseant
3411 1.15.2.1 perseant CHECK(cfg_peektoken(pctx, 0));
3412 1.15.2.1 perseant if (strcasecmp(TOKEN_STRING(pctx), "none") == 0)
3413 1.15.2.1 perseant {
3414 1.15.2.1 perseant CHECK(cfg_gettoken(pctx, 0));
3415 1.15.2.1 perseant has_none = true;
3416 1.15.2.1 perseant } else {
3417 1.15.2.1 perseant CHECK(cfg_parse_rawaddr(pctx, *flagp,
3418 1.15.2.1 perseant &netaddr));
3419 1.15.2.1 perseant have_address++;
3420 1.15.2.1 perseant }
3421 1.1 christos } else if (strcasecmp(TOKEN_STRING(pctx), "port") == 0)
3422 1.1 christos {
3423 1.1 christos /* read "port" */
3424 1.15 christos if ((pctx->flags & CFG_PCTX_NODEPRECATED) == 0)
3425 1.15 christos {
3426 1.15 christos cfg_parser_warning(
3427 1.15 christos pctx, 0,
3428 1.15 christos "token 'port' is deprecated");
3429 1.15 christos }
3430 1.1 christos CHECK(cfg_gettoken(pctx, 0));
3431 1.8 christos CHECK(cfg_parse_rawport(pctx, CFG_ADDR_WILDOK,
3432 1.1 christos &port));
3433 1.1 christos have_port++;
3434 1.15.2.1 perseant } else if (strcasecmp(TOKEN_STRING(pctx), "tls") == 0) {
3435 1.15.2.1 perseant /* We do not expect TLS here, not parsing. */
3436 1.15.2.1 perseant ++have_tls;
3437 1.15.2.1 perseant } else if (have_port == 0 && have_tls == 0 &&
3438 1.14 christos have_address == 0)
3439 1.14 christos {
3440 1.15.2.1 perseant CHECK(cfg_parse_rawaddr(pctx, *flagp,
3441 1.15.2.1 perseant &netaddr));
3442 1.15.2.1 perseant have_address++;
3443 1.1 christos } else {
3444 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
3445 1.15 christos "expected 'address' "
3446 1.15 christos "or 'port'");
3447 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
3448 1.1 christos }
3449 1.8 christos } else {
3450 1.1 christos break;
3451 1.8 christos }
3452 1.1 christos }
3453 1.1 christos
3454 1.15.2.1 perseant if (!has_none) {
3455 1.15.2.1 perseant if (have_address > 1 || have_port > 1 ||
3456 1.15.2.1 perseant have_address + have_port == 0)
3457 1.15.2.1 perseant {
3458 1.15.2.1 perseant cfg_parser_error(pctx, 0,
3459 1.15.2.1 perseant "expected one address and/or port");
3460 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
3461 1.15.2.1 perseant }
3462 1.15.2.1 perseant if (have_tls > 0) {
3463 1.15.2.1 perseant cfg_parser_error(pctx, 0, "unexpected tls");
3464 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
3465 1.15.2.1 perseant }
3466 1.15.2.1 perseant CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj));
3467 1.15.2.1 perseant isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
3468 1.1 christos
3469 1.15.2.1 perseant } else {
3470 1.15.2.1 perseant CHECK(cfg_create_obj(pctx, &cfg_type_none, &obj));
3471 1.15.2.1 perseant }
3472 1.1 christos *ret = obj;
3473 1.15.2.1 perseant return ISC_R_SUCCESS;
3474 1.1 christos
3475 1.8 christos cleanup:
3476 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source");
3477 1.1 christos CLEANUP_OBJ(obj);
3478 1.15.2.1 perseant
3479 1.15.2.1 perseant return result;
3480 1.1 christos }
3481 1.1 christos
3482 1.1 christos static void
3483 1.1 christos print_querysource(cfg_printer_t *pctx, const cfg_obj_t *obj) {
3484 1.1 christos isc_netaddr_t na;
3485 1.1 christos isc_netaddr_fromsockaddr(&na, &obj->value.sockaddr);
3486 1.1 christos cfg_print_rawaddr(pctx, &na);
3487 1.1 christos cfg_print_cstr(pctx, " port ");
3488 1.1 christos cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr));
3489 1.1 christos }
3490 1.1 christos
3491 1.1 christos static void
3492 1.15.2.1 perseant doc__querysource(cfg_printer_t *pctx, const cfg_type_t *type, bool has_none) {
3493 1.1 christos const unsigned int *flagp = type->of;
3494 1.1 christos
3495 1.15 christos cfg_print_cstr(pctx, "[ address ] ( ");
3496 1.15.2.1 perseant
3497 1.3 christos if ((*flagp & CFG_ADDR_V4OK) != 0) {
3498 1.1 christos cfg_print_cstr(pctx, "<ipv4_address>");
3499 1.3 christos } else if ((*flagp & CFG_ADDR_V6OK) != 0) {
3500 1.1 christos cfg_print_cstr(pctx, "<ipv6_address>");
3501 1.3 christos } else {
3502 1.13 christos UNREACHABLE();
3503 1.3 christos }
3504 1.15.2.1 perseant
3505 1.15.2.1 perseant cfg_print_cstr(pctx, " | *");
3506 1.15.2.1 perseant if (has_none) {
3507 1.15.2.1 perseant cfg_print_cstr(pctx, " | none");
3508 1.15.2.1 perseant }
3509 1.15.2.1 perseant cfg_print_cstr(pctx, " )");
3510 1.1 christos }
3511 1.1 christos
3512 1.15.2.1 perseant static void
3513 1.15.2.1 perseant doc_querysource(cfg_printer_t *pctx, const cfg_type_t *type) {
3514 1.15.2.1 perseant doc__querysource(pctx, type, true);
3515 1.15.2.1 perseant }
3516 1.15.2.1 perseant
3517 1.15.2.1 perseant static void
3518 1.15.2.1 perseant doc_serverquerysource(cfg_printer_t *pctx, const cfg_type_t *type) {
3519 1.15.2.1 perseant doc__querysource(pctx, type, false);
3520 1.15.2.1 perseant }
3521 1.15.2.1 perseant
3522 1.15.2.1 perseant static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK;
3523 1.15.2.1 perseant static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK;
3524 1.1 christos
3525 1.1 christos static cfg_type_t cfg_type_querysource4 = {
3526 1.8 christos "querysource4", parse_querysource, NULL, doc_querysource,
3527 1.8 christos NULL, &sockaddr4wild_flags
3528 1.1 christos };
3529 1.1 christos
3530 1.1 christos static cfg_type_t cfg_type_querysource6 = {
3531 1.8 christos "querysource6", parse_querysource, NULL, doc_querysource,
3532 1.8 christos NULL, &sockaddr6wild_flags
3533 1.1 christos };
3534 1.1 christos
3535 1.15.2.1 perseant static unsigned int querysource4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK;
3536 1.15.2.1 perseant static unsigned int querysource6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK;
3537 1.15.2.1 perseant
3538 1.15.2.1 perseant static cfg_type_t cfg_type_server_querysource4 = {
3539 1.15.2.1 perseant "querysource4", parse_querysource, NULL, doc_serverquerysource,
3540 1.15.2.1 perseant NULL, &querysource4wild_flags
3541 1.15.2.1 perseant };
3542 1.15.2.1 perseant
3543 1.15.2.1 perseant static cfg_type_t cfg_type_server_querysource6 = {
3544 1.15.2.1 perseant "querysource6", parse_querysource, NULL, doc_serverquerysource,
3545 1.15.2.1 perseant NULL, &querysource6wild_flags
3546 1.15.2.1 perseant };
3547 1.15.2.1 perseant
3548 1.8 christos static cfg_type_t cfg_type_querysource = { "querysource", NULL,
3549 1.8 christos print_querysource, NULL,
3550 1.8 christos &cfg_rep_sockaddr, NULL };
3551 1.1 christos
3552 1.1 christos /*%
3553 1.1 christos * The socket address syntax in the "controls" statement is silly.
3554 1.1 christos * It allows both socket address families, but also allows "*",
3555 1.8 christos * which is gratuitously interpreted as the IPv4 wildcard address.
3556 1.1 christos */
3557 1.8 christos static unsigned int controls_sockaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK |
3558 1.15 christos CFG_ADDR_WILDOK | CFG_ADDR_PORTOK;
3559 1.1 christos static cfg_type_t cfg_type_controls_sockaddr = {
3560 1.1 christos "controls_sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr,
3561 1.8 christos cfg_doc_sockaddr, &cfg_rep_sockaddr, &controls_sockaddr_flags
3562 1.1 christos };
3563 1.1 christos
3564 1.1 christos /*%
3565 1.1 christos * Handle the special kludge syntax of the "keys" clause in the "server"
3566 1.1 christos * statement, which takes a single key with or without braces and semicolon.
3567 1.1 christos */
3568 1.1 christos static isc_result_t
3569 1.1 christos parse_server_key_kludge(cfg_parser_t *pctx, const cfg_type_t *type,
3570 1.8 christos cfg_obj_t **ret) {
3571 1.1 christos isc_result_t result;
3572 1.3 christos bool braces = false;
3573 1.1 christos UNUSED(type);
3574 1.1 christos
3575 1.1 christos /* Allow opening brace. */
3576 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3577 1.1 christos if (pctx->token.type == isc_tokentype_special &&
3578 1.8 christos pctx->token.value.as_char == '{')
3579 1.8 christos {
3580 1.1 christos CHECK(cfg_gettoken(pctx, 0));
3581 1.3 christos braces = true;
3582 1.1 christos }
3583 1.1 christos
3584 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret));
3585 1.1 christos
3586 1.1 christos if (braces) {
3587 1.1 christos /* Skip semicolon if present. */
3588 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3589 1.1 christos if (pctx->token.type == isc_tokentype_special &&
3590 1.1 christos pctx->token.value.as_char == ';')
3591 1.8 christos {
3592 1.1 christos CHECK(cfg_gettoken(pctx, 0));
3593 1.8 christos }
3594 1.1 christos
3595 1.1 christos CHECK(cfg_parse_special(pctx, '}'));
3596 1.1 christos }
3597 1.8 christos cleanup:
3598 1.15.2.1 perseant return result;
3599 1.1 christos }
3600 1.1 christos static cfg_type_t cfg_type_server_key_kludge = {
3601 1.8 christos "server_key", parse_server_key_kludge, NULL, cfg_doc_terminal, NULL,
3602 1.8 christos NULL
3603 1.1 christos };
3604 1.1 christos
3605 1.1 christos /*%
3606 1.1 christos * An optional logging facility.
3607 1.1 christos */
3608 1.1 christos
3609 1.1 christos static isc_result_t
3610 1.1 christos parse_optional_facility(cfg_parser_t *pctx, const cfg_type_t *type,
3611 1.8 christos cfg_obj_t **ret) {
3612 1.1 christos isc_result_t result;
3613 1.1 christos UNUSED(type);
3614 1.1 christos
3615 1.1 christos CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
3616 1.1 christos if (pctx->token.type == isc_tokentype_string ||
3617 1.8 christos pctx->token.type == isc_tokentype_qstring)
3618 1.8 christos {
3619 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret));
3620 1.1 christos } else {
3621 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret));
3622 1.1 christos }
3623 1.8 christos cleanup:
3624 1.15.2.1 perseant return result;
3625 1.1 christos }
3626 1.1 christos
3627 1.1 christos static void
3628 1.1 christos doc_optional_facility(cfg_printer_t *pctx, const cfg_type_t *type) {
3629 1.1 christos UNUSED(type);
3630 1.1 christos cfg_print_cstr(pctx, "[ <syslog_facility> ]");
3631 1.1 christos }
3632 1.1 christos
3633 1.8 christos static cfg_type_t cfg_type_optional_facility = { "optional_facility",
3634 1.8 christos parse_optional_facility,
3635 1.8 christos NULL,
3636 1.8 christos doc_optional_facility,
3637 1.8 christos NULL,
3638 1.8 christos NULL };
3639 1.1 christos
3640 1.1 christos /*%
3641 1.1 christos * A log severity. Return as a string, except "debug N",
3642 1.1 christos * which is returned as a keyword object.
3643 1.1 christos */
3644 1.1 christos
3645 1.1 christos static keyword_type_t debug_kw = { "debug", &cfg_type_uint32 };
3646 1.8 christos static cfg_type_t cfg_type_debuglevel = { "debuglevel", parse_keyvalue,
3647 1.8 christos print_keyvalue, doc_keyvalue,
3648 1.8 christos &cfg_rep_uint32, &debug_kw };
3649 1.1 christos
3650 1.1 christos static isc_result_t
3651 1.8 christos parse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3652 1.1 christos isc_result_t result;
3653 1.1 christos UNUSED(type);
3654 1.1 christos
3655 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3656 1.1 christos if (pctx->token.type == isc_tokentype_string &&
3657 1.8 christos strcasecmp(TOKEN_STRING(pctx), "debug") == 0)
3658 1.8 christos {
3659 1.1 christos CHECK(cfg_gettoken(pctx, 0)); /* read "debug" */
3660 1.1 christos CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER));
3661 1.1 christos if (pctx->token.type == isc_tokentype_number) {
3662 1.1 christos CHECK(cfg_parse_uint32(pctx, NULL, ret));
3663 1.1 christos } else {
3664 1.1 christos /*
3665 1.1 christos * The debug level is optional and defaults to 1.
3666 1.1 christos * This makes little sense, but we support it for
3667 1.1 christos * compatibility with BIND 8.
3668 1.1 christos */
3669 1.1 christos CHECK(cfg_create_obj(pctx, &cfg_type_uint32, ret));
3670 1.1 christos (*ret)->value.uint32 = 1;
3671 1.1 christos }
3672 1.1 christos (*ret)->type = &cfg_type_debuglevel; /* XXX kludge */
3673 1.1 christos } else {
3674 1.1 christos CHECK(cfg_parse_obj(pctx, &cfg_type_loglevel, ret));
3675 1.1 christos }
3676 1.8 christos cleanup:
3677 1.15.2.1 perseant return result;
3678 1.1 christos }
3679 1.1 christos
3680 1.8 christos static cfg_type_t cfg_type_logseverity = { "log_severity", parse_logseverity,
3681 1.8 christos NULL, cfg_doc_terminal,
3682 1.8 christos NULL, NULL };
3683 1.1 christos
3684 1.1 christos /*%
3685 1.1 christos * The "file" clause of the "channel" statement.
3686 1.1 christos * This is yet another special case.
3687 1.1 christos */
3688 1.1 christos
3689 1.1 christos static const char *logversions_enums[] = { "unlimited", NULL };
3690 1.1 christos static isc_result_t
3691 1.8 christos parse_logversions(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3692 1.15.2.1 perseant return cfg_parse_enum_or_other(pctx, type, &cfg_type_uint32, ret);
3693 1.1 christos }
3694 1.1 christos
3695 1.1 christos static void
3696 1.1 christos doc_logversions(cfg_printer_t *pctx, const cfg_type_t *type) {
3697 1.3 christos cfg_doc_enum_or_other(pctx, type, &cfg_type_uint32);
3698 1.1 christos }
3699 1.1 christos
3700 1.1 christos static cfg_type_t cfg_type_logversions = {
3701 1.8 christos "logversions", parse_logversions, cfg_print_ustring,
3702 1.8 christos doc_logversions, &cfg_rep_string, logversions_enums
3703 1.1 christos };
3704 1.1 christos
3705 1.1 christos static const char *logsuffix_enums[] = { "increment", "timestamp", NULL };
3706 1.8 christos static cfg_type_t cfg_type_logsuffix = { "logsuffix", cfg_parse_enum,
3707 1.8 christos cfg_print_ustring, cfg_doc_enum,
3708 1.8 christos &cfg_rep_string, &logsuffix_enums };
3709 1.1 christos
3710 1.1 christos static cfg_tuplefielddef_t logfile_fields[] = {
3711 1.1 christos { "file", &cfg_type_qstring, 0 },
3712 1.1 christos { "versions", &cfg_type_logversions, 0 },
3713 1.1 christos { "size", &cfg_type_size, 0 },
3714 1.1 christos { "suffix", &cfg_type_logsuffix, 0 },
3715 1.1 christos { NULL, NULL, 0 }
3716 1.1 christos };
3717 1.1 christos
3718 1.1 christos static isc_result_t
3719 1.1 christos parse_logfile(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
3720 1.1 christos isc_result_t result;
3721 1.1 christos cfg_obj_t *obj = NULL;
3722 1.1 christos const cfg_tuplefielddef_t *fields = type->of;
3723 1.1 christos
3724 1.1 christos CHECK(cfg_create_tuple(pctx, type, &obj));
3725 1.1 christos
3726 1.1 christos /* Parse the mandatory "file" field */
3727 1.1 christos CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
3728 1.1 christos
3729 1.1 christos /* Parse "versions" and "size" fields in any order. */
3730 1.1 christos for (;;) {
3731 1.1 christos CHECK(cfg_peektoken(pctx, 0));
3732 1.1 christos if (pctx->token.type == isc_tokentype_string) {
3733 1.1 christos CHECK(cfg_gettoken(pctx, 0));
3734 1.8 christos if (strcasecmp(TOKEN_STRING(pctx), "versions") == 0 &&
3735 1.8 christos obj->value.tuple[1] == NULL)
3736 1.8 christos {
3737 1.1 christos CHECK(cfg_parse_obj(pctx, fields[1].type,
3738 1.8 christos &obj->value.tuple[1]));
3739 1.8 christos } else if (strcasecmp(TOKEN_STRING(pctx), "size") ==
3740 1.8 christos 0 &&
3741 1.8 christos obj->value.tuple[2] == NULL)
3742 1.8 christos {
3743 1.1 christos CHECK(cfg_parse_obj(pctx, fields[2].type,
3744 1.8 christos &obj->value.tuple[2]));
3745 1.8 christos } else if (strcasecmp(TOKEN_STRING(pctx), "suffix") ==
3746 1.8 christos 0 &&
3747 1.8 christos obj->value.tuple[3] == NULL)
3748 1.8 christos {
3749 1.1 christos CHECK(cfg_parse_obj(pctx, fields[3].type,
3750 1.8 christos &obj->value.tuple[3]));
3751 1.1 christos } else {
3752 1.1 christos break;
3753 1.1 christos }
3754 1.1 christos } else {
3755 1.1 christos break;
3756 1.1 christos }
3757 1.1 christos }
3758 1.1 christos
3759 1.1 christos /* Create void objects for missing optional values. */
3760 1.8 christos if (obj->value.tuple[1] == NULL) {
3761 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
3762 1.8 christos }
3763 1.8 christos if (obj->value.tuple[2] == NULL) {
3764 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
3765 1.8 christos }
3766 1.8 christos if (obj->value.tuple[3] == NULL) {
3767 1.1 christos CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[3]));
3768 1.8 christos }
3769 1.1 christos
3770 1.1 christos *ret = obj;
3771 1.15.2.1 perseant return ISC_R_SUCCESS;
3772 1.1 christos
3773 1.8 christos cleanup:
3774 1.1 christos CLEANUP_OBJ(obj);
3775 1.15.2.1 perseant return result;
3776 1.1 christos }
3777 1.1 christos
3778 1.1 christos static void
3779 1.1 christos print_logfile(cfg_printer_t *pctx, const cfg_obj_t *obj) {
3780 1.1 christos cfg_print_obj(pctx, obj->value.tuple[0]); /* file */
3781 1.1 christos if (obj->value.tuple[1]->type->print != cfg_print_void) {
3782 1.1 christos cfg_print_cstr(pctx, " versions ");
3783 1.1 christos cfg_print_obj(pctx, obj->value.tuple[1]);
3784 1.1 christos }
3785 1.1 christos if (obj->value.tuple[2]->type->print != cfg_print_void) {
3786 1.1 christos cfg_print_cstr(pctx, " size ");
3787 1.1 christos cfg_print_obj(pctx, obj->value.tuple[2]);
3788 1.1 christos }
3789 1.1 christos if (obj->value.tuple[3]->type->print != cfg_print_void) {
3790 1.1 christos cfg_print_cstr(pctx, " suffix ");
3791 1.1 christos cfg_print_obj(pctx, obj->value.tuple[3]);
3792 1.1 christos }
3793 1.1 christos }
3794 1.1 christos
3795 1.1 christos static void
3796 1.1 christos doc_logfile(cfg_printer_t *pctx, const cfg_type_t *type) {
3797 1.1 christos UNUSED(type);
3798 1.1 christos cfg_print_cstr(pctx, "<quoted_string>");
3799 1.1 christos cfg_print_cstr(pctx, " ");
3800 1.1 christos cfg_print_cstr(pctx, "[ versions ( unlimited | <integer> ) ]");
3801 1.1 christos cfg_print_cstr(pctx, " ");
3802 1.1 christos cfg_print_cstr(pctx, "[ size <size> ]");
3803 1.1 christos cfg_print_cstr(pctx, " ");
3804 1.1 christos cfg_print_cstr(pctx, "[ suffix ( increment | timestamp ) ]");
3805 1.1 christos }
3806 1.1 christos
3807 1.8 christos static cfg_type_t cfg_type_logfile = { "log_file", parse_logfile,
3808 1.8 christos print_logfile, doc_logfile,
3809 1.8 christos &cfg_rep_tuple, logfile_fields };
3810 1.1 christos
3811 1.15 christos /*% An IPv4 address, "*" accepted as wildcard. */
3812 1.1 christos static cfg_type_t cfg_type_sockaddr4wild = {
3813 1.8 christos "sockaddr4wild", cfg_parse_sockaddr, cfg_print_sockaddr,
3814 1.8 christos cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr4wild_flags
3815 1.1 christos };
3816 1.1 christos
3817 1.15 christos /*% An IPv6 address, "*" accepted as wildcard. */
3818 1.1 christos static cfg_type_t cfg_type_sockaddr6wild = {
3819 1.1 christos "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr,
3820 1.8 christos cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr6wild_flags
3821 1.1 christos };
3822 1.1 christos
3823 1.15.2.1 perseant static keyword_type_t sourceaddr4_kw = { "source", &cfg_type_sockaddr4wild };
3824 1.15.2.1 perseant
3825 1.15.2.1 perseant static cfg_type_t cfg_type_optional_sourceaddr4 = {
3826 1.15.2.1 perseant "optional_sourceaddr4", parse_optional_keyvalue, print_keyvalue,
3827 1.15.2.1 perseant doc_optional_keyvalue, &cfg_rep_sockaddr, &sourceaddr4_kw
3828 1.15.2.1 perseant };
3829 1.15.2.1 perseant
3830 1.15.2.1 perseant static keyword_type_t sourceaddr6_kw = { "source-v6", &cfg_type_sockaddr6wild };
3831 1.15.2.1 perseant
3832 1.15.2.1 perseant static cfg_type_t cfg_type_optional_sourceaddr6 = {
3833 1.15.2.1 perseant "optional_sourceaddr6", parse_optional_keyvalue, print_keyvalue,
3834 1.15.2.1 perseant doc_optional_keyvalue, &cfg_rep_sockaddr, &sourceaddr6_kw
3835 1.15.2.1 perseant };
3836 1.15.2.1 perseant
3837 1.1 christos /*%
3838 1.1 christos * rndc
3839 1.1 christos */
3840 1.1 christos
3841 1.8 christos static cfg_clausedef_t rndcconf_options_clauses[] = {
3842 1.1 christos { "default-key", &cfg_type_astring, 0 },
3843 1.1 christos { "default-port", &cfg_type_uint32, 0 },
3844 1.1 christos { "default-server", &cfg_type_astring, 0 },
3845 1.1 christos { "default-source-address", &cfg_type_netaddr4wild, 0 },
3846 1.1 christos { "default-source-address-v6", &cfg_type_netaddr6wild, 0 },
3847 1.1 christos { NULL, NULL, 0 }
3848 1.1 christos };
3849 1.1 christos
3850 1.8 christos static cfg_clausedef_t *rndcconf_options_clausesets[] = {
3851 1.8 christos rndcconf_options_clauses, NULL
3852 1.1 christos };
3853 1.1 christos
3854 1.1 christos static cfg_type_t cfg_type_rndcconf_options = {
3855 1.8 christos "rndcconf_options", cfg_parse_map, cfg_print_map,
3856 1.8 christos cfg_doc_map, &cfg_rep_map, rndcconf_options_clausesets
3857 1.1 christos };
3858 1.1 christos
3859 1.8 christos static cfg_clausedef_t rndcconf_server_clauses[] = {
3860 1.1 christos { "key", &cfg_type_astring, 0 },
3861 1.1 christos { "port", &cfg_type_uint32, 0 },
3862 1.1 christos { "source-address", &cfg_type_netaddr4wild, 0 },
3863 1.1 christos { "source-address-v6", &cfg_type_netaddr6wild, 0 },
3864 1.1 christos { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 },
3865 1.1 christos { NULL, NULL, 0 }
3866 1.1 christos };
3867 1.1 christos
3868 1.8 christos static cfg_clausedef_t *rndcconf_server_clausesets[] = {
3869 1.8 christos rndcconf_server_clauses, NULL
3870 1.1 christos };
3871 1.1 christos
3872 1.1 christos static cfg_type_t cfg_type_rndcconf_server = {
3873 1.8 christos "rndcconf_server", cfg_parse_named_map, cfg_print_map,
3874 1.8 christos cfg_doc_map, &cfg_rep_map, rndcconf_server_clausesets
3875 1.1 christos };
3876 1.1 christos
3877 1.8 christos static cfg_clausedef_t rndcconf_clauses[] = {
3878 1.1 christos { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI },
3879 1.1 christos { "server", &cfg_type_rndcconf_server, CFG_CLAUSEFLAG_MULTI },
3880 1.1 christos { "options", &cfg_type_rndcconf_options, 0 },
3881 1.1 christos { NULL, NULL, 0 }
3882 1.1 christos };
3883 1.1 christos
3884 1.8 christos static cfg_clausedef_t *rndcconf_clausesets[] = { rndcconf_clauses, NULL };
3885 1.1 christos
3886 1.15 christos cfg_type_t cfg_type_rndcconf = { "rndcconf", cfg_parse_mapbody,
3887 1.15 christos cfg_print_mapbody, cfg_doc_mapbody,
3888 1.15 christos &cfg_rep_map, rndcconf_clausesets };
3889 1.1 christos
3890 1.8 christos static cfg_clausedef_t rndckey_clauses[] = { { "key", &cfg_type_key, 0 },
3891 1.8 christos { NULL, NULL, 0 } };
3892 1.1 christos
3893 1.8 christos static cfg_clausedef_t *rndckey_clausesets[] = { rndckey_clauses, NULL };
3894 1.1 christos
3895 1.15 christos cfg_type_t cfg_type_rndckey = { "rndckey", cfg_parse_mapbody,
3896 1.15 christos cfg_print_mapbody, cfg_doc_mapbody,
3897 1.15 christos &cfg_rep_map, rndckey_clausesets };
3898 1.1 christos
3899 1.1 christos /*
3900 1.1 christos * session.key has exactly the same syntax as rndc.key, but it's defined
3901 1.1 christos * separately for clarity (and so we can extend it someday, if needed).
3902 1.1 christos */
3903 1.15 christos cfg_type_t cfg_type_sessionkey = { "sessionkey", cfg_parse_mapbody,
3904 1.15 christos cfg_print_mapbody, cfg_doc_mapbody,
3905 1.15 christos &cfg_rep_map, rndckey_clausesets };
3906 1.1 christos
3907 1.1 christos static cfg_tuplefielddef_t nameport_fields[] = {
3908 1.1 christos { "name", &cfg_type_astring, 0 },
3909 1.1 christos { "port", &cfg_type_optional_port, 0 },
3910 1.1 christos { NULL, NULL, 0 }
3911 1.1 christos };
3912 1.1 christos
3913 1.8 christos static cfg_type_t cfg_type_nameport = { "nameport", cfg_parse_tuple,
3914 1.8 christos cfg_print_tuple, cfg_doc_tuple,
3915 1.8 christos &cfg_rep_tuple, nameport_fields };
3916 1.1 christos
3917 1.1 christos static void
3918 1.1 christos doc_sockaddrnameport(cfg_printer_t *pctx, const cfg_type_t *type) {
3919 1.1 christos UNUSED(type);
3920 1.1 christos cfg_print_cstr(pctx, "( ");
3921 1.1 christos cfg_print_cstr(pctx, "<quoted_string>");
3922 1.1 christos cfg_print_cstr(pctx, " ");
3923 1.1 christos cfg_print_cstr(pctx, "[ port <integer> ]");
3924 1.1 christos cfg_print_cstr(pctx, " | ");
3925 1.1 christos cfg_print_cstr(pctx, "<ipv4_address>");
3926 1.1 christos cfg_print_cstr(pctx, " ");
3927 1.1 christos cfg_print_cstr(pctx, "[ port <integer> ]");
3928 1.1 christos cfg_print_cstr(pctx, " | ");
3929 1.1 christos cfg_print_cstr(pctx, "<ipv6_address>");
3930 1.1 christos cfg_print_cstr(pctx, " ");
3931 1.1 christos cfg_print_cstr(pctx, "[ port <integer> ]");
3932 1.1 christos cfg_print_cstr(pctx, " )");
3933 1.1 christos }
3934 1.1 christos
3935 1.1 christos static isc_result_t
3936 1.1 christos parse_sockaddrnameport(cfg_parser_t *pctx, const cfg_type_t *type,
3937 1.8 christos cfg_obj_t **ret) {
3938 1.1 christos isc_result_t result;
3939 1.1 christos UNUSED(type);
3940 1.1 christos
3941 1.1 christos CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
3942 1.1 christos if (pctx->token.type == isc_tokentype_string ||
3943 1.8 christos pctx->token.type == isc_tokentype_qstring)
3944 1.8 christos {
3945 1.1 christos if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK))
3946 1.8 christos {
3947 1.1 christos CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr,
3948 1.1 christos ret));
3949 1.8 christos } else {
3950 1.15.2.1 perseant CHECK(cfg_parse_tuple(pctx, &cfg_type_nameport, ret));
3951 1.1 christos }
3952 1.1 christos } else {
3953 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
3954 1.8 christos "expected IP address or hostname");
3955 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
3956 1.1 christos }
3957 1.8 christos cleanup:
3958 1.15.2.1 perseant return result;
3959 1.1 christos }
3960 1.1 christos
3961 1.8 christos static cfg_type_t cfg_type_sockaddrnameport = { "sockaddrnameport_element",
3962 1.8 christos parse_sockaddrnameport,
3963 1.8 christos NULL,
3964 1.8 christos doc_sockaddrnameport,
3965 1.8 christos NULL,
3966 1.8 christos NULL };
3967 1.1 christos
3968 1.1 christos static cfg_type_t cfg_type_bracketed_sockaddrnameportlist = {
3969 1.8 christos "bracketed_sockaddrnameportlist",
3970 1.8 christos cfg_parse_bracketed_list,
3971 1.8 christos cfg_print_bracketed_list,
3972 1.8 christos cfg_doc_bracketed_list,
3973 1.8 christos &cfg_rep_list,
3974 1.8 christos &cfg_type_sockaddrnameport
3975 1.1 christos };
3976 1.1 christos
3977 1.1 christos /*%
3978 1.1 christos * A list of socket addresses or name with an optional default port,
3979 1.1 christos * as used in the dual-stack-servers option. E.g.,
3980 1.1 christos * "port 1234 { dual-stack-servers.net; 10.0.0.1; 1::2 port 69; }"
3981 1.1 christos */
3982 1.1 christos static cfg_tuplefielddef_t nameportiplist_fields[] = {
3983 1.1 christos { "port", &cfg_type_optional_port, 0 },
3984 1.1 christos { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 },
3985 1.1 christos { NULL, NULL, 0 }
3986 1.1 christos };
3987 1.1 christos
3988 1.1 christos static cfg_type_t cfg_type_nameportiplist = {
3989 1.8 christos "nameportiplist", cfg_parse_tuple, cfg_print_tuple,
3990 1.8 christos cfg_doc_tuple, &cfg_rep_tuple, nameportiplist_fields
3991 1.1 christos };
3992 1.1 christos
3993 1.1 christos /*%
3994 1.15 christos * remote servers element.
3995 1.1 christos */
3996 1.1 christos
3997 1.1 christos static void
3998 1.12 christos doc_remoteselement(cfg_printer_t *pctx, const cfg_type_t *type) {
3999 1.1 christos UNUSED(type);
4000 1.1 christos cfg_print_cstr(pctx, "( ");
4001 1.15.2.1 perseant cfg_print_cstr(pctx, "<server-list>");
4002 1.1 christos cfg_print_cstr(pctx, " | ");
4003 1.1 christos cfg_print_cstr(pctx, "<ipv4_address>");
4004 1.1 christos cfg_print_cstr(pctx, " ");
4005 1.1 christos cfg_print_cstr(pctx, "[ port <integer> ]");
4006 1.1 christos cfg_print_cstr(pctx, " | ");
4007 1.1 christos cfg_print_cstr(pctx, "<ipv6_address>");
4008 1.1 christos cfg_print_cstr(pctx, " ");
4009 1.1 christos cfg_print_cstr(pctx, "[ port <integer> ]");
4010 1.1 christos cfg_print_cstr(pctx, " )");
4011 1.1 christos }
4012 1.1 christos
4013 1.1 christos static isc_result_t
4014 1.12 christos parse_remoteselement(cfg_parser_t *pctx, const cfg_type_t *type,
4015 1.12 christos cfg_obj_t **ret) {
4016 1.1 christos isc_result_t result;
4017 1.1 christos cfg_obj_t *obj = NULL;
4018 1.1 christos UNUSED(type);
4019 1.1 christos
4020 1.1 christos CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
4021 1.1 christos if (pctx->token.type == isc_tokentype_string ||
4022 1.8 christos pctx->token.type == isc_tokentype_qstring)
4023 1.8 christos {
4024 1.1 christos if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK))
4025 1.8 christos {
4026 1.1 christos CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr,
4027 1.8 christos ret));
4028 1.8 christos } else {
4029 1.1 christos CHECK(cfg_parse_astring(pctx, &cfg_type_astring, ret));
4030 1.8 christos }
4031 1.1 christos } else {
4032 1.1 christos cfg_parser_error(pctx, CFG_LOG_NEAR,
4033 1.12 christos "expected IP address or remote servers list "
4034 1.12 christos "name");
4035 1.15.2.1 perseant return ISC_R_UNEXPECTEDTOKEN;
4036 1.1 christos }
4037 1.8 christos cleanup:
4038 1.1 christos CLEANUP_OBJ(obj);
4039 1.15.2.1 perseant return result;
4040 1.1 christos }
4041 1.1 christos
4042 1.12 christos static cfg_type_t cfg_type_remoteselement = { "remotes_element",
4043 1.12 christos parse_remoteselement,
4044 1.12 christos NULL,
4045 1.12 christos doc_remoteselement,
4046 1.12 christos NULL,
4047 1.12 christos NULL };
4048 1.1 christos
4049 1.8 christos static int
4050 1.8 christos cmp_clause(const void *ap, const void *bp) {
4051 1.1 christos const cfg_clausedef_t *a = (const cfg_clausedef_t *)ap;
4052 1.1 christos const cfg_clausedef_t *b = (const cfg_clausedef_t *)bp;
4053 1.15.2.1 perseant return strcmp(a->name, b->name);
4054 1.1 christos }
4055 1.1 christos
4056 1.3 christos bool
4057 1.1 christos cfg_clause_validforzone(const char *name, unsigned int ztype) {
4058 1.1 christos const cfg_clausedef_t *clause;
4059 1.3 christos bool valid = false;
4060 1.1 christos
4061 1.1 christos for (clause = zone_clauses; clause->name != NULL; clause++) {
4062 1.1 christos if ((clause->flags & ztype) == 0 ||
4063 1.14 christos strcmp(clause->name, name) != 0)
4064 1.14 christos {
4065 1.1 christos continue;
4066 1.1 christos }
4067 1.3 christos valid = true;
4068 1.1 christos }
4069 1.1 christos for (clause = zone_only_clauses; clause->name != NULL; clause++) {
4070 1.1 christos if ((clause->flags & ztype) == 0 ||
4071 1.14 christos strcmp(clause->name, name) != 0)
4072 1.14 christos {
4073 1.1 christos continue;
4074 1.1 christos }
4075 1.3 christos valid = true;
4076 1.1 christos }
4077 1.1 christos
4078 1.15.2.1 perseant return valid;
4079 1.1 christos }
4080 1.1 christos
4081 1.1 christos void
4082 1.8 christos cfg_print_zonegrammar(const unsigned int zonetype, unsigned int flags,
4083 1.1 christos void (*f)(void *closure, const char *text, int textlen),
4084 1.8 christos void *closure) {
4085 1.8 christos #define NCLAUSES \
4086 1.1 christos (((sizeof(zone_clauses) + sizeof(zone_only_clauses)) / \
4087 1.8 christos sizeof(clause[0])) - \
4088 1.8 christos 1)
4089 1.1 christos
4090 1.1 christos cfg_printer_t pctx;
4091 1.1 christos cfg_clausedef_t *clause = NULL;
4092 1.1 christos cfg_clausedef_t clauses[NCLAUSES];
4093 1.1 christos
4094 1.1 christos pctx.f = f;
4095 1.1 christos pctx.closure = closure;
4096 1.1 christos pctx.indent = 0;
4097 1.8 christos pctx.flags = flags;
4098 1.1 christos
4099 1.1 christos memmove(clauses, zone_clauses, sizeof(zone_clauses));
4100 1.8 christos memmove(clauses + sizeof(zone_clauses) / sizeof(zone_clauses[0]) - 1,
4101 1.1 christos zone_only_clauses, sizeof(zone_only_clauses));
4102 1.1 christos qsort(clauses, NCLAUSES - 1, sizeof(clause[0]), cmp_clause);
4103 1.1 christos
4104 1.1 christos cfg_print_cstr(&pctx, "zone <string> [ <class> ] {\n");
4105 1.1 christos pctx.indent++;
4106 1.1 christos
4107 1.1 christos switch (zonetype) {
4108 1.13 christos case CFG_ZONE_PRIMARY:
4109 1.1 christos cfg_print_indent(&pctx);
4110 1.15 christos cfg_print_cstr(&pctx, "type primary;\n");
4111 1.1 christos break;
4112 1.13 christos case CFG_ZONE_SECONDARY:
4113 1.1 christos cfg_print_indent(&pctx);
4114 1.15 christos cfg_print_cstr(&pctx, "type secondary;\n");
4115 1.1 christos break;
4116 1.3 christos case CFG_ZONE_MIRROR:
4117 1.3 christos cfg_print_indent(&pctx);
4118 1.3 christos cfg_print_cstr(&pctx, "type mirror;\n");
4119 1.3 christos break;
4120 1.1 christos case CFG_ZONE_STUB:
4121 1.1 christos cfg_print_indent(&pctx);
4122 1.1 christos cfg_print_cstr(&pctx, "type stub;\n");
4123 1.1 christos break;
4124 1.1 christos case CFG_ZONE_HINT:
4125 1.1 christos cfg_print_indent(&pctx);
4126 1.1 christos cfg_print_cstr(&pctx, "type hint;\n");
4127 1.1 christos break;
4128 1.1 christos case CFG_ZONE_FORWARD:
4129 1.1 christos cfg_print_indent(&pctx);
4130 1.1 christos cfg_print_cstr(&pctx, "type forward;\n");
4131 1.1 christos break;
4132 1.1 christos case CFG_ZONE_STATICSTUB:
4133 1.1 christos cfg_print_indent(&pctx);
4134 1.1 christos cfg_print_cstr(&pctx, "type static-stub;\n");
4135 1.1 christos break;
4136 1.1 christos case CFG_ZONE_REDIRECT:
4137 1.1 christos cfg_print_indent(&pctx);
4138 1.1 christos cfg_print_cstr(&pctx, "type redirect;\n");
4139 1.1 christos break;
4140 1.1 christos case CFG_ZONE_INVIEW:
4141 1.1 christos /* no zone type is specified for these */
4142 1.1 christos break;
4143 1.1 christos default:
4144 1.13 christos UNREACHABLE();
4145 1.1 christos }
4146 1.1 christos
4147 1.1 christos for (clause = clauses; clause->name != NULL; clause++) {
4148 1.8 christos if (((pctx.flags & CFG_PRINTER_ACTIVEONLY) != 0) &&
4149 1.8 christos (((clause->flags & CFG_CLAUSEFLAG_OBSOLETE) != 0) ||
4150 1.8 christos ((clause->flags & CFG_CLAUSEFLAG_TESTONLY) != 0)))
4151 1.8 christos {
4152 1.8 christos continue;
4153 1.8 christos }
4154 1.15 christos if ((clause->flags & CFG_CLAUSEFLAG_ANCIENT) != 0 ||
4155 1.15 christos (clause->flags & CFG_CLAUSEFLAG_NODOC) != 0)
4156 1.15 christos {
4157 1.15 christos continue;
4158 1.15 christos }
4159 1.15 christos
4160 1.1 christos if ((clause->flags & zonetype) == 0 ||
4161 1.14 christos strcasecmp(clause->name, "type") == 0)
4162 1.14 christos {
4163 1.1 christos continue;
4164 1.1 christos }
4165 1.1 christos cfg_print_indent(&pctx);
4166 1.1 christos cfg_print_cstr(&pctx, clause->name);
4167 1.1 christos cfg_print_cstr(&pctx, " ");
4168 1.1 christos cfg_doc_obj(&pctx, clause->type);
4169 1.1 christos cfg_print_cstr(&pctx, ";");
4170 1.1 christos cfg_print_clauseflags(&pctx, clause->flags);
4171 1.1 christos cfg_print_cstr(&pctx, "\n");
4172 1.1 christos }
4173 1.1 christos
4174 1.1 christos pctx.indent--;
4175 1.1 christos cfg_print_cstr(&pctx, "};\n");
4176 1.1 christos }
4177 1.15 christos
4178 1.15 christos /*%
4179 1.15 christos * "tls" and related statement syntax.
4180 1.15 christos */
4181 1.15 christos static cfg_type_t cfg_type_tlsprotos = { "tls_protocols",
4182 1.15 christos cfg_parse_bracketed_list,
4183 1.15 christos cfg_print_bracketed_list,
4184 1.15 christos cfg_doc_bracketed_list,
4185 1.15 christos &cfg_rep_list,
4186 1.15 christos &cfg_type_astring };
4187 1.15 christos
4188 1.15 christos static cfg_clausedef_t tls_clauses[] = {
4189 1.15 christos { "key-file", &cfg_type_qstring, 0 },
4190 1.15 christos { "cert-file", &cfg_type_qstring, 0 },
4191 1.15 christos { "ca-file", &cfg_type_qstring, 0 },
4192 1.15 christos { "remote-hostname", &cfg_type_qstring, 0 },
4193 1.15 christos { "dhparam-file", &cfg_type_qstring, 0 },
4194 1.15 christos { "protocols", &cfg_type_tlsprotos, 0 },
4195 1.15 christos { "ciphers", &cfg_type_astring, 0 },
4196 1.15.2.1 perseant #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
4197 1.15.2.1 perseant { "cipher-suites", &cfg_type_astring, 0 },
4198 1.15.2.1 perseant #else
4199 1.15.2.1 perseant { "cipher-suites", &cfg_type_astring, CFG_CLAUSEFLAG_NOTCONFIGURED },
4200 1.15.2.1 perseant #endif
4201 1.15 christos { "prefer-server-ciphers", &cfg_type_boolean, 0 },
4202 1.15 christos { "session-tickets", &cfg_type_boolean, 0 },
4203 1.15 christos { NULL, NULL, 0 }
4204 1.15 christos };
4205 1.15 christos
4206 1.15 christos static cfg_clausedef_t *tls_clausesets[] = { tls_clauses, NULL };
4207 1.15 christos static cfg_type_t cfg_type_tlsconf = { "tlsconf", cfg_parse_named_map,
4208 1.15 christos cfg_print_map, cfg_doc_map,
4209 1.15 christos &cfg_rep_map, tls_clausesets };
4210 1.15 christos
4211 1.15 christos static keyword_type_t tls_kw = { "tls", &cfg_type_astring };
4212 1.15 christos static cfg_type_t cfg_type_optional_tls = {
4213 1.15 christos "tlsoptional", parse_optional_keyvalue, print_keyvalue,
4214 1.15 christos doc_optional_keyvalue, &cfg_rep_string, &tls_kw
4215 1.15 christos };
4216 1.15 christos
4217 1.15 christos /* http and https */
4218 1.15 christos
4219 1.15 christos static cfg_type_t cfg_type_bracketed_http_endpoint_list = {
4220 1.15 christos "bracketed_http_endpoint_list",
4221 1.15 christos cfg_parse_bracketed_list,
4222 1.15 christos cfg_print_bracketed_list,
4223 1.15 christos cfg_doc_bracketed_list,
4224 1.15 christos &cfg_rep_list,
4225 1.15 christos &cfg_type_qstring
4226 1.15 christos };
4227 1.15 christos
4228 1.15 christos static cfg_clausedef_t cfg_http_description_clauses[] = {
4229 1.15 christos { "endpoints", &cfg_type_bracketed_http_endpoint_list, 0 },
4230 1.15 christos { "listener-clients", &cfg_type_uint32, 0 },
4231 1.15 christos { "streams-per-connection", &cfg_type_uint32, 0 },
4232 1.15 christos { NULL, NULL, 0 }
4233 1.15 christos };
4234 1.15 christos
4235 1.15 christos static cfg_clausedef_t *http_description_clausesets[] = {
4236 1.15 christos cfg_http_description_clauses, NULL
4237 1.15 christos };
4238 1.15 christos
4239 1.15 christos static cfg_type_t cfg_type_http_description = {
4240 1.15 christos "http_desc", cfg_parse_named_map, cfg_print_map,
4241 1.15 christos cfg_doc_map, &cfg_rep_map, http_description_clausesets
4242 1.15 christos };
4243