configparser.y revision 266114
1/*
2 * configparser.y -- yacc grammar for unbound configuration files
3 *
4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
5 *
6 * Copyright (c) 2007, NLnet Labs. All rights reserved.
7 *
8 * This software is open source.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * Neither the name of the NLNET LABS nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38%{
39#include "config.h"
40
41#include <stdarg.h>
42#include <stdio.h>
43#include <string.h>
44#include <stdlib.h>
45#include <assert.h>
46
47#include "util/configyyrename.h"
48#include "util/config_file.h"
49#include "util/net_help.h"
50
51int ub_c_lex(void);
52void ub_c_error(const char *message);
53
54/* these need to be global, otherwise they cannot be used inside yacc */
55extern struct config_parser_state* cfg_parser;
56
57#if 0
58#define OUTYY(s)  printf s /* used ONLY when debugging */
59#else
60#define OUTYY(s)
61#endif
62
63%}
64%union {
65	char*	str;
66};
67
68%token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR
69%token <str> STRING_ARG
70%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
71%token VAR_OUTGOING_RANGE VAR_INTERFACE
72%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP
73%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
74%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
75%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
76%token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS
77%token VAR_INFRA_CACHE_NUMHOSTS VAR_INFRA_CACHE_LAME_SIZE VAR_NAME
78%token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
79%token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
80%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
81%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
82%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
83%token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
84%token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
85%token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
86%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
87%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
88%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
89%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNSSEC_STRIPPED VAR_ACCESS_CONTROL
90%token VAR_LOCAL_ZONE VAR_LOCAL_DATA VAR_INTERFACE_AUTOMATIC
91%token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
92%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
93%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
94%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
95%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
96%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
97%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
98%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
99%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
100%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
101%token VAR_VAL_SIG_SKEW_MAX VAR_CACHE_MIN_TTL VAR_VAL_LOG_LEVEL
102%token VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING VAR_ADD_HOLDDOWN
103%token VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE VAR_PREFETCH
104%token VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT VAR_HARDEN_BELOW_NXDOMAIN
105%token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
106%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
107%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
108%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
109
110%%
111toplevelvars: /* empty */ | toplevelvars toplevelvar ;
112toplevelvar: serverstart contents_server | stubstart contents_stub |
113	forwardstart contents_forward | pythonstart contents_py |
114	rcstart contents_rc
115	;
116
117/* server: declaration */
118serverstart: VAR_SERVER
119	{
120		OUTYY(("\nP(server:)\n"));
121	}
122	;
123contents_server: contents_server content_server
124	| ;
125content_server: server_num_threads | server_verbosity | server_port |
126	server_outgoing_range | server_do_ip4 |
127	server_do_ip6 | server_do_udp | server_do_tcp |
128	server_interface | server_chroot | server_username |
129	server_directory | server_logfile | server_pidfile |
130	server_msg_cache_size | server_msg_cache_slabs |
131	server_num_queries_per_thread | server_rrset_cache_size |
132	server_rrset_cache_slabs | server_outgoing_num_tcp |
133	server_infra_host_ttl | server_infra_lame_ttl |
134	server_infra_cache_slabs | server_infra_cache_numhosts |
135	server_infra_cache_lame_size | server_target_fetch_policy |
136	server_harden_short_bufsize | server_harden_large_queries |
137	server_do_not_query_address | server_hide_identity |
138	server_hide_version | server_identity | server_version |
139	server_harden_glue | server_module_conf | server_trust_anchor_file |
140	server_trust_anchor | server_val_override_date | server_bogus_ttl |
141	server_val_clean_additional | server_val_permissive_mode |
142	server_incoming_num_tcp | server_msg_buffer_size |
143	server_key_cache_size | server_key_cache_slabs |
144	server_trusted_keys_file | server_val_nsec3_keysize_iterations |
145	server_use_syslog | server_outgoing_interface | server_root_hints |
146	server_do_not_query_localhost | server_cache_max_ttl |
147	server_harden_dnssec_stripped | server_access_control |
148	server_local_zone | server_local_data | server_interface_automatic |
149	server_statistics_interval | server_do_daemonize |
150	server_use_caps_for_id | server_statistics_cumulative |
151	server_outgoing_port_permit | server_outgoing_port_avoid |
152	server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
153	server_harden_referral_path | server_private_address |
154	server_private_domain | server_extended_statistics |
155	server_local_data_ptr | server_jostle_timeout |
156	server_unwanted_reply_threshold | server_log_time_ascii |
157	server_domain_insecure | server_val_sig_skew_min |
158	server_val_sig_skew_max | server_cache_min_ttl | server_val_log_level |
159	server_auto_trust_anchor_file | server_add_holddown |
160	server_del_holddown | server_keep_missing | server_so_rcvbuf |
161	server_edns_buffer_size | server_prefetch | server_prefetch_key |
162	server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
163	server_log_queries | server_tcp_upstream | server_ssl_upstream |
164	server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
165	server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
166    server_so_reuseport | server_delay_close
167	;
168stubstart: VAR_STUB_ZONE
169	{
170		struct config_stub* s;
171		OUTYY(("\nP(stub_zone:)\n"));
172		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
173		if(s) {
174			s->next = cfg_parser->cfg->stubs;
175			cfg_parser->cfg->stubs = s;
176		} else
177			yyerror("out of memory");
178	}
179	;
180contents_stub: contents_stub content_stub
181	| ;
182content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first
183	;
184forwardstart: VAR_FORWARD_ZONE
185	{
186		struct config_stub* s;
187		OUTYY(("\nP(forward_zone:)\n"));
188		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
189		if(s) {
190			s->next = cfg_parser->cfg->forwards;
191			cfg_parser->cfg->forwards = s;
192		} else
193			yyerror("out of memory");
194	}
195	;
196contents_forward: contents_forward content_forward
197	| ;
198content_forward: forward_name | forward_host | forward_addr | forward_first
199	;
200server_num_threads: VAR_NUM_THREADS STRING_ARG
201	{
202		OUTYY(("P(server_num_threads:%s)\n", $2));
203		if(atoi($2) == 0 && strcmp($2, "0") != 0)
204			yyerror("number expected");
205		else cfg_parser->cfg->num_threads = atoi($2);
206		free($2);
207	}
208	;
209server_verbosity: VAR_VERBOSITY STRING_ARG
210	{
211		OUTYY(("P(server_verbosity:%s)\n", $2));
212		if(atoi($2) == 0 && strcmp($2, "0") != 0)
213			yyerror("number expected");
214		else cfg_parser->cfg->verbosity = atoi($2);
215		free($2);
216	}
217	;
218server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG
219	{
220		OUTYY(("P(server_statistics_interval:%s)\n", $2));
221		if(strcmp($2, "") == 0 || strcmp($2, "0") == 0)
222			cfg_parser->cfg->stat_interval = 0;
223		else if(atoi($2) == 0)
224			yyerror("number expected");
225		else cfg_parser->cfg->stat_interval = atoi($2);
226		free($2);
227	}
228	;
229server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG
230	{
231		OUTYY(("P(server_statistics_cumulative:%s)\n", $2));
232		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
233			yyerror("expected yes or no.");
234		else cfg_parser->cfg->stat_cumulative = (strcmp($2, "yes")==0);
235		free($2);
236	}
237	;
238server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
239	{
240		OUTYY(("P(server_extended_statistics:%s)\n", $2));
241		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
242			yyerror("expected yes or no.");
243		else cfg_parser->cfg->stat_extended = (strcmp($2, "yes")==0);
244		free($2);
245	}
246	;
247server_port: VAR_PORT STRING_ARG
248	{
249		OUTYY(("P(server_port:%s)\n", $2));
250		if(atoi($2) == 0)
251			yyerror("port number expected");
252		else cfg_parser->cfg->port = atoi($2);
253		free($2);
254	}
255	;
256server_interface: VAR_INTERFACE STRING_ARG
257	{
258		OUTYY(("P(server_interface:%s)\n", $2));
259		if(cfg_parser->cfg->num_ifs == 0)
260			cfg_parser->cfg->ifs = calloc(1, sizeof(char*));
261		else 	cfg_parser->cfg->ifs = realloc(cfg_parser->cfg->ifs,
262				(cfg_parser->cfg->num_ifs+1)*sizeof(char*));
263		if(!cfg_parser->cfg->ifs)
264			yyerror("out of memory");
265		else
266			cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2;
267	}
268	;
269server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG
270	{
271		OUTYY(("P(server_outgoing_interface:%s)\n", $2));
272		if(cfg_parser->cfg->num_out_ifs == 0)
273			cfg_parser->cfg->out_ifs = calloc(1, sizeof(char*));
274		else 	cfg_parser->cfg->out_ifs = realloc(
275			cfg_parser->cfg->out_ifs,
276			(cfg_parser->cfg->num_out_ifs+1)*sizeof(char*));
277		if(!cfg_parser->cfg->out_ifs)
278			yyerror("out of memory");
279		else
280			cfg_parser->cfg->out_ifs[
281				cfg_parser->cfg->num_out_ifs++] = $2;
282	}
283	;
284server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG
285	{
286		OUTYY(("P(server_outgoing_range:%s)\n", $2));
287		if(atoi($2) == 0)
288			yyerror("number expected");
289		else cfg_parser->cfg->outgoing_num_ports = atoi($2);
290		free($2);
291	}
292	;
293server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG
294	{
295		OUTYY(("P(server_outgoing_port_permit:%s)\n", $2));
296		if(!cfg_mark_ports($2, 1,
297			cfg_parser->cfg->outgoing_avail_ports, 65536))
298			yyerror("port number or range (\"low-high\") expected");
299		free($2);
300	}
301	;
302server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG
303	{
304		OUTYY(("P(server_outgoing_port_avoid:%s)\n", $2));
305		if(!cfg_mark_ports($2, 0,
306			cfg_parser->cfg->outgoing_avail_ports, 65536))
307			yyerror("port number or range (\"low-high\") expected");
308		free($2);
309	}
310	;
311server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG
312	{
313		OUTYY(("P(server_outgoing_num_tcp:%s)\n", $2));
314		if(atoi($2) == 0 && strcmp($2, "0") != 0)
315			yyerror("number expected");
316		else cfg_parser->cfg->outgoing_num_tcp = atoi($2);
317		free($2);
318	}
319	;
320server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG
321	{
322		OUTYY(("P(server_incoming_num_tcp:%s)\n", $2));
323		if(atoi($2) == 0 && strcmp($2, "0") != 0)
324			yyerror("number expected");
325		else cfg_parser->cfg->incoming_num_tcp = atoi($2);
326		free($2);
327	}
328	;
329server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG
330	{
331		OUTYY(("P(server_interface_automatic:%s)\n", $2));
332		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
333			yyerror("expected yes or no.");
334		else cfg_parser->cfg->if_automatic = (strcmp($2, "yes")==0);
335		free($2);
336	}
337	;
338server_do_ip4: VAR_DO_IP4 STRING_ARG
339	{
340		OUTYY(("P(server_do_ip4:%s)\n", $2));
341		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
342			yyerror("expected yes or no.");
343		else cfg_parser->cfg->do_ip4 = (strcmp($2, "yes")==0);
344		free($2);
345	}
346	;
347server_do_ip6: VAR_DO_IP6 STRING_ARG
348	{
349		OUTYY(("P(server_do_ip6:%s)\n", $2));
350		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
351			yyerror("expected yes or no.");
352		else cfg_parser->cfg->do_ip6 = (strcmp($2, "yes")==0);
353		free($2);
354	}
355	;
356server_do_udp: VAR_DO_UDP STRING_ARG
357	{
358		OUTYY(("P(server_do_udp:%s)\n", $2));
359		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
360			yyerror("expected yes or no.");
361		else cfg_parser->cfg->do_udp = (strcmp($2, "yes")==0);
362		free($2);
363	}
364	;
365server_do_tcp: VAR_DO_TCP STRING_ARG
366	{
367		OUTYY(("P(server_do_tcp:%s)\n", $2));
368		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
369			yyerror("expected yes or no.");
370		else cfg_parser->cfg->do_tcp = (strcmp($2, "yes")==0);
371		free($2);
372	}
373	;
374server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
375	{
376		OUTYY(("P(server_tcp_upstream:%s)\n", $2));
377		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
378			yyerror("expected yes or no.");
379		else cfg_parser->cfg->tcp_upstream = (strcmp($2, "yes")==0);
380		free($2);
381	}
382	;
383server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG
384	{
385		OUTYY(("P(server_ssl_upstream:%s)\n", $2));
386		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
387			yyerror("expected yes or no.");
388		else cfg_parser->cfg->ssl_upstream = (strcmp($2, "yes")==0);
389		free($2);
390	}
391	;
392server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG
393	{
394		OUTYY(("P(server_ssl_service_key:%s)\n", $2));
395		free(cfg_parser->cfg->ssl_service_key);
396		cfg_parser->cfg->ssl_service_key = $2;
397	}
398	;
399server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG
400	{
401		OUTYY(("P(server_ssl_service_pem:%s)\n", $2));
402		free(cfg_parser->cfg->ssl_service_pem);
403		cfg_parser->cfg->ssl_service_pem = $2;
404	}
405	;
406server_ssl_port: VAR_SSL_PORT STRING_ARG
407	{
408		OUTYY(("P(server_ssl_port:%s)\n", $2));
409		if(atoi($2) == 0)
410			yyerror("port number expected");
411		else cfg_parser->cfg->ssl_port = atoi($2);
412		free($2);
413	}
414	;
415server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG
416	{
417		OUTYY(("P(server_do_daemonize:%s)\n", $2));
418		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
419			yyerror("expected yes or no.");
420		else cfg_parser->cfg->do_daemonize = (strcmp($2, "yes")==0);
421		free($2);
422	}
423	;
424server_use_syslog: VAR_USE_SYSLOG STRING_ARG
425	{
426		OUTYY(("P(server_use_syslog:%s)\n", $2));
427		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
428			yyerror("expected yes or no.");
429		else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0);
430#if !defined(HAVE_SYSLOG_H) && !defined(UB_ON_WINDOWS)
431		if(strcmp($2, "yes") == 0)
432			yyerror("no syslog services are available. "
433				"(reconfigure and compile to add)");
434#endif
435		free($2);
436	}
437	;
438server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG
439	{
440		OUTYY(("P(server_log_time_ascii:%s)\n", $2));
441		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
442			yyerror("expected yes or no.");
443		else cfg_parser->cfg->log_time_ascii = (strcmp($2, "yes")==0);
444		free($2);
445	}
446	;
447server_log_queries: VAR_LOG_QUERIES STRING_ARG
448	{
449		OUTYY(("P(server_log_queries:%s)\n", $2));
450		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
451			yyerror("expected yes or no.");
452		else cfg_parser->cfg->log_queries = (strcmp($2, "yes")==0);
453		free($2);
454	}
455	;
456server_chroot: VAR_CHROOT STRING_ARG
457	{
458		OUTYY(("P(server_chroot:%s)\n", $2));
459		free(cfg_parser->cfg->chrootdir);
460		cfg_parser->cfg->chrootdir = $2;
461	}
462	;
463server_username: VAR_USERNAME STRING_ARG
464	{
465		OUTYY(("P(server_username:%s)\n", $2));
466		free(cfg_parser->cfg->username);
467		cfg_parser->cfg->username = $2;
468	}
469	;
470server_directory: VAR_DIRECTORY STRING_ARG
471	{
472		OUTYY(("P(server_directory:%s)\n", $2));
473		free(cfg_parser->cfg->directory);
474		cfg_parser->cfg->directory = $2;
475	}
476	;
477server_logfile: VAR_LOGFILE STRING_ARG
478	{
479		OUTYY(("P(server_logfile:%s)\n", $2));
480		free(cfg_parser->cfg->logfile);
481		cfg_parser->cfg->logfile = $2;
482		cfg_parser->cfg->use_syslog = 0;
483	}
484	;
485server_pidfile: VAR_PIDFILE STRING_ARG
486	{
487		OUTYY(("P(server_pidfile:%s)\n", $2));
488		free(cfg_parser->cfg->pidfile);
489		cfg_parser->cfg->pidfile = $2;
490	}
491	;
492server_root_hints: VAR_ROOT_HINTS STRING_ARG
493	{
494		OUTYY(("P(server_root_hints:%s)\n", $2));
495		if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, $2))
496			yyerror("out of memory");
497	}
498	;
499server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG
500	{
501		OUTYY(("P(server_dlv_anchor_file:%s)\n", $2));
502		free(cfg_parser->cfg->dlv_anchor_file);
503		cfg_parser->cfg->dlv_anchor_file = $2;
504	}
505	;
506server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG
507	{
508		OUTYY(("P(server_dlv_anchor:%s)\n", $2));
509		if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, $2))
510			yyerror("out of memory");
511	}
512	;
513server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG
514	{
515		OUTYY(("P(server_auto_trust_anchor_file:%s)\n", $2));
516		if(!cfg_strlist_insert(&cfg_parser->cfg->
517			auto_trust_anchor_file_list, $2))
518			yyerror("out of memory");
519	}
520	;
521server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG
522	{
523		OUTYY(("P(server_trust_anchor_file:%s)\n", $2));
524		if(!cfg_strlist_insert(&cfg_parser->cfg->
525			trust_anchor_file_list, $2))
526			yyerror("out of memory");
527	}
528	;
529server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG
530	{
531		OUTYY(("P(server_trusted_keys_file:%s)\n", $2));
532		if(!cfg_strlist_insert(&cfg_parser->cfg->
533			trusted_keys_file_list, $2))
534			yyerror("out of memory");
535	}
536	;
537server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG
538	{
539		OUTYY(("P(server_trust_anchor:%s)\n", $2));
540		if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, $2))
541			yyerror("out of memory");
542	}
543	;
544server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
545	{
546		OUTYY(("P(server_domain_insecure:%s)\n", $2));
547		if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, $2))
548			yyerror("out of memory");
549	}
550	;
551server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG
552	{
553		OUTYY(("P(server_hide_identity:%s)\n", $2));
554		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
555			yyerror("expected yes or no.");
556		else cfg_parser->cfg->hide_identity = (strcmp($2, "yes")==0);
557		free($2);
558	}
559	;
560server_hide_version: VAR_HIDE_VERSION STRING_ARG
561	{
562		OUTYY(("P(server_hide_version:%s)\n", $2));
563		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
564			yyerror("expected yes or no.");
565		else cfg_parser->cfg->hide_version = (strcmp($2, "yes")==0);
566		free($2);
567	}
568	;
569server_identity: VAR_IDENTITY STRING_ARG
570	{
571		OUTYY(("P(server_identity:%s)\n", $2));
572		free(cfg_parser->cfg->identity);
573		cfg_parser->cfg->identity = $2;
574	}
575	;
576server_version: VAR_VERSION STRING_ARG
577	{
578		OUTYY(("P(server_version:%s)\n", $2));
579		free(cfg_parser->cfg->version);
580		cfg_parser->cfg->version = $2;
581	}
582	;
583server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG
584	{
585		OUTYY(("P(server_so_rcvbuf:%s)\n", $2));
586		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_rcvbuf))
587			yyerror("buffer size expected");
588		free($2);
589	}
590	;
591server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG
592	{
593		OUTYY(("P(server_so_sndbuf:%s)\n", $2));
594		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_sndbuf))
595			yyerror("buffer size expected");
596		free($2);
597	}
598	;
599server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG
600    {
601        OUTYY(("P(server_so_reuseport:%s)\n", $2));
602        if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
603            yyerror("expected yes or no.");
604        else cfg_parser->cfg->so_reuseport =
605            (strcmp($2, "yes")==0);
606        free($2);
607    }
608    ;
609server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
610	{
611		OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
612		if(atoi($2) == 0)
613			yyerror("number expected");
614		else if (atoi($2) < 12)
615			yyerror("edns buffer size too small");
616		else if (atoi($2) > 65535)
617			cfg_parser->cfg->edns_buffer_size = 65535;
618		else cfg_parser->cfg->edns_buffer_size = atoi($2);
619		free($2);
620	}
621	;
622server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG
623	{
624		OUTYY(("P(server_msg_buffer_size:%s)\n", $2));
625		if(atoi($2) == 0)
626			yyerror("number expected");
627		else if (atoi($2) < 4096)
628			yyerror("message buffer size too small (use 4096)");
629		else cfg_parser->cfg->msg_buffer_size = atoi($2);
630		free($2);
631	}
632	;
633server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG
634	{
635		OUTYY(("P(server_msg_cache_size:%s)\n", $2));
636		if(!cfg_parse_memsize($2, &cfg_parser->cfg->msg_cache_size))
637			yyerror("memory size expected");
638		free($2);
639	}
640	;
641server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG
642	{
643		OUTYY(("P(server_msg_cache_slabs:%s)\n", $2));
644		if(atoi($2) == 0)
645			yyerror("number expected");
646		else {
647			cfg_parser->cfg->msg_cache_slabs = atoi($2);
648			if(!is_pow2(cfg_parser->cfg->msg_cache_slabs))
649				yyerror("must be a power of 2");
650		}
651		free($2);
652	}
653	;
654server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG
655	{
656		OUTYY(("P(server_num_queries_per_thread:%s)\n", $2));
657		if(atoi($2) == 0)
658			yyerror("number expected");
659		else cfg_parser->cfg->num_queries_per_thread = atoi($2);
660		free($2);
661	}
662	;
663server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG
664	{
665		OUTYY(("P(server_jostle_timeout:%s)\n", $2));
666		if(atoi($2) == 0 && strcmp($2, "0") != 0)
667			yyerror("number expected");
668		else cfg_parser->cfg->jostle_time = atoi($2);
669		free($2);
670	}
671	;
672server_delay_close: VAR_DELAY_CLOSE STRING_ARG
673	{
674		OUTYY(("P(server_delay_close:%s)\n", $2));
675		if(atoi($2) == 0 && strcmp($2, "0") != 0)
676			yyerror("number expected");
677		else cfg_parser->cfg->delay_close = atoi($2);
678		free($2);
679	}
680	;
681server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG
682	{
683		OUTYY(("P(server_rrset_cache_size:%s)\n", $2));
684		if(!cfg_parse_memsize($2, &cfg_parser->cfg->rrset_cache_size))
685			yyerror("memory size expected");
686		free($2);
687	}
688	;
689server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG
690	{
691		OUTYY(("P(server_rrset_cache_slabs:%s)\n", $2));
692		if(atoi($2) == 0)
693			yyerror("number expected");
694		else {
695			cfg_parser->cfg->rrset_cache_slabs = atoi($2);
696			if(!is_pow2(cfg_parser->cfg->rrset_cache_slabs))
697				yyerror("must be a power of 2");
698		}
699		free($2);
700	}
701	;
702server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG
703	{
704		OUTYY(("P(server_infra_host_ttl:%s)\n", $2));
705		if(atoi($2) == 0 && strcmp($2, "0") != 0)
706			yyerror("number expected");
707		else cfg_parser->cfg->host_ttl = atoi($2);
708		free($2);
709	}
710	;
711server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG
712	{
713		OUTYY(("P(server_infra_lame_ttl:%s)\n", $2));
714		verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option "
715			"removed, use infra-host-ttl)", $2);
716		free($2);
717	}
718	;
719server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG
720	{
721		OUTYY(("P(server_infra_cache_numhosts:%s)\n", $2));
722		if(atoi($2) == 0)
723			yyerror("number expected");
724		else cfg_parser->cfg->infra_cache_numhosts = atoi($2);
725		free($2);
726	}
727	;
728server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG
729	{
730		OUTYY(("P(server_infra_cache_lame_size:%s)\n", $2));
731		verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s "
732			"(option removed, use infra-cache-numhosts)", $2);
733		free($2);
734	}
735	;
736server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG
737	{
738		OUTYY(("P(server_infra_cache_slabs:%s)\n", $2));
739		if(atoi($2) == 0)
740			yyerror("number expected");
741		else {
742			cfg_parser->cfg->infra_cache_slabs = atoi($2);
743			if(!is_pow2(cfg_parser->cfg->infra_cache_slabs))
744				yyerror("must be a power of 2");
745		}
746		free($2);
747	}
748	;
749server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
750	{
751		OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
752		free(cfg_parser->cfg->target_fetch_policy);
753		cfg_parser->cfg->target_fetch_policy = $2;
754	}
755	;
756server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG
757	{
758		OUTYY(("P(server_harden_short_bufsize:%s)\n", $2));
759		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
760			yyerror("expected yes or no.");
761		else cfg_parser->cfg->harden_short_bufsize =
762			(strcmp($2, "yes")==0);
763		free($2);
764	}
765	;
766server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG
767	{
768		OUTYY(("P(server_harden_large_queries:%s)\n", $2));
769		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
770			yyerror("expected yes or no.");
771		else cfg_parser->cfg->harden_large_queries =
772			(strcmp($2, "yes")==0);
773		free($2);
774	}
775	;
776server_harden_glue: VAR_HARDEN_GLUE STRING_ARG
777	{
778		OUTYY(("P(server_harden_glue:%s)\n", $2));
779		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
780			yyerror("expected yes or no.");
781		else cfg_parser->cfg->harden_glue =
782			(strcmp($2, "yes")==0);
783		free($2);
784	}
785	;
786server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG
787	{
788		OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2));
789		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
790			yyerror("expected yes or no.");
791		else cfg_parser->cfg->harden_dnssec_stripped =
792			(strcmp($2, "yes")==0);
793		free($2);
794	}
795	;
796server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG
797	{
798		OUTYY(("P(server_harden_below_nxdomain:%s)\n", $2));
799		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
800			yyerror("expected yes or no.");
801		else cfg_parser->cfg->harden_below_nxdomain =
802			(strcmp($2, "yes")==0);
803		free($2);
804	}
805	;
806server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG
807	{
808		OUTYY(("P(server_harden_referral_path:%s)\n", $2));
809		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
810			yyerror("expected yes or no.");
811		else cfg_parser->cfg->harden_referral_path =
812			(strcmp($2, "yes")==0);
813		free($2);
814	}
815	;
816server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG
817	{
818		OUTYY(("P(server_use_caps_for_id:%s)\n", $2));
819		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
820			yyerror("expected yes or no.");
821		else cfg_parser->cfg->use_caps_bits_for_id =
822			(strcmp($2, "yes")==0);
823		free($2);
824	}
825	;
826server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
827	{
828		OUTYY(("P(server_private_address:%s)\n", $2));
829		if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, $2))
830			yyerror("out of memory");
831	}
832	;
833server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG
834	{
835		OUTYY(("P(server_private_domain:%s)\n", $2));
836		if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, $2))
837			yyerror("out of memory");
838	}
839	;
840server_prefetch: VAR_PREFETCH STRING_ARG
841	{
842		OUTYY(("P(server_prefetch:%s)\n", $2));
843		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
844			yyerror("expected yes or no.");
845		else cfg_parser->cfg->prefetch = (strcmp($2, "yes")==0);
846		free($2);
847	}
848	;
849server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG
850	{
851		OUTYY(("P(server_prefetch_key:%s)\n", $2));
852		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
853			yyerror("expected yes or no.");
854		else cfg_parser->cfg->prefetch_key = (strcmp($2, "yes")==0);
855		free($2);
856	}
857	;
858server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
859	{
860		OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
861		if(atoi($2) == 0 && strcmp($2, "0") != 0)
862			yyerror("number expected");
863		else cfg_parser->cfg->unwanted_threshold = atoi($2);
864		free($2);
865	}
866	;
867server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG
868	{
869		OUTYY(("P(server_do_not_query_address:%s)\n", $2));
870		if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, $2))
871			yyerror("out of memory");
872	}
873	;
874server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG
875	{
876		OUTYY(("P(server_do_not_query_localhost:%s)\n", $2));
877		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
878			yyerror("expected yes or no.");
879		else cfg_parser->cfg->donotquery_localhost =
880			(strcmp($2, "yes")==0);
881		free($2);
882	}
883	;
884server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG
885	{
886		OUTYY(("P(server_access_control:%s %s)\n", $2, $3));
887		if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 &&
888			strcmp($3, "deny_non_local")!=0 &&
889			strcmp($3, "refuse_non_local")!=0 &&
890			strcmp($3, "allow")!=0 &&
891			strcmp($3, "allow_snoop")!=0) {
892			yyerror("expected deny, refuse, deny_non_local, "
893				"refuse_non_local, allow or allow_snoop "
894				"in access control action");
895		} else {
896			if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
897				fatal_exit("out of memory adding acl");
898		}
899	}
900	;
901server_module_conf: VAR_MODULE_CONF STRING_ARG
902	{
903		OUTYY(("P(server_module_conf:%s)\n", $2));
904		free(cfg_parser->cfg->module_conf);
905		cfg_parser->cfg->module_conf = $2;
906	}
907	;
908server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG
909	{
910		OUTYY(("P(server_val_override_date:%s)\n", $2));
911		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
912			cfg_parser->cfg->val_date_override = 0;
913		} else if(strlen($2) == 14) {
914			cfg_parser->cfg->val_date_override =
915				cfg_convert_timeval($2);
916			if(!cfg_parser->cfg->val_date_override)
917				yyerror("bad date/time specification");
918		} else {
919			if(atoi($2) == 0)
920				yyerror("number expected");
921			cfg_parser->cfg->val_date_override = atoi($2);
922		}
923		free($2);
924	}
925	;
926server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG
927	{
928		OUTYY(("P(server_val_sig_skew_min:%s)\n", $2));
929		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
930			cfg_parser->cfg->val_sig_skew_min = 0;
931		} else {
932			cfg_parser->cfg->val_sig_skew_min = atoi($2);
933			if(!cfg_parser->cfg->val_sig_skew_min)
934				yyerror("number expected");
935		}
936		free($2);
937	}
938	;
939server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG
940	{
941		OUTYY(("P(server_val_sig_skew_max:%s)\n", $2));
942		if(strlen($2) == 0 || strcmp($2, "0") == 0) {
943			cfg_parser->cfg->val_sig_skew_max = 0;
944		} else {
945			cfg_parser->cfg->val_sig_skew_max = atoi($2);
946			if(!cfg_parser->cfg->val_sig_skew_max)
947				yyerror("number expected");
948		}
949		free($2);
950	}
951	;
952server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG
953	{
954		OUTYY(("P(server_cache_max_ttl:%s)\n", $2));
955		if(atoi($2) == 0 && strcmp($2, "0") != 0)
956			yyerror("number expected");
957		else cfg_parser->cfg->max_ttl = atoi($2);
958		free($2);
959	}
960	;
961server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG
962	{
963		OUTYY(("P(server_cache_min_ttl:%s)\n", $2));
964		if(atoi($2) == 0 && strcmp($2, "0") != 0)
965			yyerror("number expected");
966		else cfg_parser->cfg->min_ttl = atoi($2);
967		free($2);
968	}
969	;
970server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG
971	{
972		OUTYY(("P(server_bogus_ttl:%s)\n", $2));
973		if(atoi($2) == 0 && strcmp($2, "0") != 0)
974			yyerror("number expected");
975		else cfg_parser->cfg->bogus_ttl = atoi($2);
976		free($2);
977	}
978	;
979server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG
980	{
981		OUTYY(("P(server_val_clean_additional:%s)\n", $2));
982		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
983			yyerror("expected yes or no.");
984		else cfg_parser->cfg->val_clean_additional =
985			(strcmp($2, "yes")==0);
986		free($2);
987	}
988	;
989server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG
990	{
991		OUTYY(("P(server_val_permissive_mode:%s)\n", $2));
992		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
993			yyerror("expected yes or no.");
994		else cfg_parser->cfg->val_permissive_mode =
995			(strcmp($2, "yes")==0);
996		free($2);
997	}
998	;
999server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG
1000	{
1001		OUTYY(("P(server_ignore_cd_flag:%s)\n", $2));
1002		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1003			yyerror("expected yes or no.");
1004		else cfg_parser->cfg->ignore_cd = (strcmp($2, "yes")==0);
1005		free($2);
1006	}
1007	;
1008server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG
1009	{
1010		OUTYY(("P(server_val_log_level:%s)\n", $2));
1011		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1012			yyerror("number expected");
1013		else cfg_parser->cfg->val_log_level = atoi($2);
1014		free($2);
1015	}
1016	;
1017server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG
1018	{
1019		OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", $2));
1020		free(cfg_parser->cfg->val_nsec3_key_iterations);
1021		cfg_parser->cfg->val_nsec3_key_iterations = $2;
1022	}
1023	;
1024server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG
1025	{
1026		OUTYY(("P(server_add_holddown:%s)\n", $2));
1027		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1028			yyerror("number expected");
1029		else cfg_parser->cfg->add_holddown = atoi($2);
1030		free($2);
1031	}
1032	;
1033server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG
1034	{
1035		OUTYY(("P(server_del_holddown:%s)\n", $2));
1036		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1037			yyerror("number expected");
1038		else cfg_parser->cfg->del_holddown = atoi($2);
1039		free($2);
1040	}
1041	;
1042server_keep_missing: VAR_KEEP_MISSING STRING_ARG
1043	{
1044		OUTYY(("P(server_keep_missing:%s)\n", $2));
1045		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1046			yyerror("number expected");
1047		else cfg_parser->cfg->keep_missing = atoi($2);
1048		free($2);
1049	}
1050	;
1051server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG
1052	{
1053		OUTYY(("P(server_key_cache_size:%s)\n", $2));
1054		if(!cfg_parse_memsize($2, &cfg_parser->cfg->key_cache_size))
1055			yyerror("memory size expected");
1056		free($2);
1057	}
1058	;
1059server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG
1060	{
1061		OUTYY(("P(server_key_cache_slabs:%s)\n", $2));
1062		if(atoi($2) == 0)
1063			yyerror("number expected");
1064		else {
1065			cfg_parser->cfg->key_cache_slabs = atoi($2);
1066			if(!is_pow2(cfg_parser->cfg->key_cache_slabs))
1067				yyerror("must be a power of 2");
1068		}
1069		free($2);
1070	}
1071	;
1072server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG
1073	{
1074		OUTYY(("P(server_neg_cache_size:%s)\n", $2));
1075		if(!cfg_parse_memsize($2, &cfg_parser->cfg->neg_cache_size))
1076			yyerror("memory size expected");
1077		free($2);
1078	}
1079	;
1080server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
1081	{
1082		OUTYY(("P(server_local_zone:%s %s)\n", $2, $3));
1083		if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
1084		   strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
1085		   strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
1086		   && strcmp($3, "typetransparent")!=0)
1087			yyerror("local-zone type: expected static, deny, "
1088				"refuse, redirect, transparent, "
1089				"typetransparent or nodefault");
1090		else if(strcmp($3, "nodefault")==0) {
1091			if(!cfg_strlist_insert(&cfg_parser->cfg->
1092				local_zones_nodefault, $2))
1093				fatal_exit("out of memory adding local-zone");
1094			free($3);
1095		} else {
1096			if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones,
1097				$2, $3))
1098				fatal_exit("out of memory adding local-zone");
1099		}
1100	}
1101	;
1102server_local_data: VAR_LOCAL_DATA STRING_ARG
1103	{
1104		OUTYY(("P(server_local_data:%s)\n", $2));
1105		if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2))
1106			fatal_exit("out of memory adding local-data");
1107	}
1108	;
1109server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
1110	{
1111		char* ptr;
1112		OUTYY(("P(server_local_data_ptr:%s)\n", $2));
1113		ptr = cfg_ptr_reverse($2);
1114		free($2);
1115		if(ptr) {
1116			if(!cfg_strlist_insert(&cfg_parser->cfg->
1117				local_data, ptr))
1118				fatal_exit("out of memory adding local-data");
1119		} else {
1120			yyerror("local-data-ptr could not be reversed");
1121		}
1122	}
1123	;
1124server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG
1125	{
1126		OUTYY(("P(server_minimal_responses:%s)\n", $2));
1127		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1128			yyerror("expected yes or no.");
1129		else cfg_parser->cfg->minimal_responses =
1130			(strcmp($2, "yes")==0);
1131		free($2);
1132	}
1133	;
1134server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG
1135	{
1136		OUTYY(("P(server_rrset_roundrobin:%s)\n", $2));
1137		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1138			yyerror("expected yes or no.");
1139		else cfg_parser->cfg->rrset_roundrobin =
1140			(strcmp($2, "yes")==0);
1141		free($2);
1142	}
1143	;
1144server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
1145	{
1146		OUTYY(("P(server_max_udp_size:%s)\n", $2));
1147		cfg_parser->cfg->max_udp_size = atoi($2);
1148		free($2);
1149	}
1150	;
1151stub_name: VAR_NAME STRING_ARG
1152	{
1153		OUTYY(("P(name:%s)\n", $2));
1154		if(cfg_parser->cfg->stubs->name)
1155			yyerror("stub name override, there must be one name "
1156				"for one stub-zone");
1157		free(cfg_parser->cfg->stubs->name);
1158		cfg_parser->cfg->stubs->name = $2;
1159	}
1160	;
1161stub_host: VAR_STUB_HOST STRING_ARG
1162	{
1163		OUTYY(("P(stub-host:%s)\n", $2));
1164		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, $2))
1165			yyerror("out of memory");
1166	}
1167	;
1168stub_addr: VAR_STUB_ADDR STRING_ARG
1169	{
1170		OUTYY(("P(stub-addr:%s)\n", $2));
1171		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, $2))
1172			yyerror("out of memory");
1173	}
1174	;
1175stub_first: VAR_STUB_FIRST STRING_ARG
1176	{
1177		OUTYY(("P(stub-first:%s)\n", $2));
1178		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1179			yyerror("expected yes or no.");
1180		else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0);
1181		free($2);
1182	}
1183	;
1184stub_prime: VAR_STUB_PRIME STRING_ARG
1185	{
1186		OUTYY(("P(stub-prime:%s)\n", $2));
1187		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1188			yyerror("expected yes or no.");
1189		else cfg_parser->cfg->stubs->isprime =
1190			(strcmp($2, "yes")==0);
1191		free($2);
1192	}
1193	;
1194forward_name: VAR_NAME STRING_ARG
1195	{
1196		OUTYY(("P(name:%s)\n", $2));
1197		if(cfg_parser->cfg->forwards->name)
1198			yyerror("forward name override, there must be one "
1199				"name for one forward-zone");
1200		free(cfg_parser->cfg->forwards->name);
1201		cfg_parser->cfg->forwards->name = $2;
1202	}
1203	;
1204forward_host: VAR_FORWARD_HOST STRING_ARG
1205	{
1206		OUTYY(("P(forward-host:%s)\n", $2));
1207		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, $2))
1208			yyerror("out of memory");
1209	}
1210	;
1211forward_addr: VAR_FORWARD_ADDR STRING_ARG
1212	{
1213		OUTYY(("P(forward-addr:%s)\n", $2));
1214		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, $2))
1215			yyerror("out of memory");
1216	}
1217	;
1218forward_first: VAR_FORWARD_FIRST STRING_ARG
1219	{
1220		OUTYY(("P(forward-first:%s)\n", $2));
1221		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1222			yyerror("expected yes or no.");
1223		else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0);
1224		free($2);
1225	}
1226	;
1227rcstart: VAR_REMOTE_CONTROL
1228	{
1229		OUTYY(("\nP(remote-control:)\n"));
1230	}
1231	;
1232contents_rc: contents_rc content_rc
1233	| ;
1234content_rc: rc_control_enable | rc_control_interface | rc_control_port |
1235	rc_server_key_file | rc_server_cert_file | rc_control_key_file |
1236	rc_control_cert_file
1237	;
1238rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG
1239	{
1240		OUTYY(("P(control_enable:%s)\n", $2));
1241		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1242			yyerror("expected yes or no.");
1243		else cfg_parser->cfg->remote_control_enable =
1244			(strcmp($2, "yes")==0);
1245		free($2);
1246	}
1247	;
1248rc_control_port: VAR_CONTROL_PORT STRING_ARG
1249	{
1250		OUTYY(("P(control_port:%s)\n", $2));
1251		if(atoi($2) == 0)
1252			yyerror("control port number expected");
1253		else cfg_parser->cfg->control_port = atoi($2);
1254		free($2);
1255	}
1256	;
1257rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG
1258	{
1259		OUTYY(("P(control_interface:%s)\n", $2));
1260		if(!cfg_strlist_insert(&cfg_parser->cfg->control_ifs, $2))
1261			yyerror("out of memory");
1262	}
1263	;
1264rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG
1265	{
1266		OUTYY(("P(rc_server_key_file:%s)\n", $2));
1267		free(cfg_parser->cfg->server_key_file);
1268		cfg_parser->cfg->server_key_file = $2;
1269	}
1270	;
1271rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG
1272	{
1273		OUTYY(("P(rc_server_cert_file:%s)\n", $2));
1274		free(cfg_parser->cfg->server_cert_file);
1275		cfg_parser->cfg->server_cert_file = $2;
1276	}
1277	;
1278rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG
1279	{
1280		OUTYY(("P(rc_control_key_file:%s)\n", $2));
1281		free(cfg_parser->cfg->control_key_file);
1282		cfg_parser->cfg->control_key_file = $2;
1283	}
1284	;
1285rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG
1286	{
1287		OUTYY(("P(rc_control_cert_file:%s)\n", $2));
1288		free(cfg_parser->cfg->control_cert_file);
1289		cfg_parser->cfg->control_cert_file = $2;
1290	}
1291	;
1292pythonstart: VAR_PYTHON
1293	{
1294		OUTYY(("\nP(python:)\n"));
1295	}
1296	;
1297contents_py: contents_py content_py
1298	| ;
1299content_py: py_script
1300	;
1301py_script: VAR_PYTHON_SCRIPT STRING_ARG
1302	{
1303		OUTYY(("P(python-script:%s)\n", $2));
1304		free(cfg_parser->cfg->python_script);
1305		cfg_parser->cfg->python_script = $2;
1306	}
1307%%
1308
1309/* parse helper routines could be here */
1310