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#include "sldns/str2wire.h"
51
52int ub_c_lex(void);
53void ub_c_error(const char *message);
54
55static void validate_respip_action(const char* action);
56static void validate_acl_action(const char* action);
57
58/* these need to be global, otherwise they cannot be used inside yacc */
59extern struct config_parser_state* cfg_parser;
60
61#if 0
62#define OUTYY(s)  printf s /* used ONLY when debugging */
63#else
64#define OUTYY(s)
65#endif
66
67%}
68%union {
69	char*	str;
70};
71
72%token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR
73%token <str> STRING_ARG
74%token VAR_FORCE_TOPLEVEL
75%token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
76%token VAR_OUTGOING_RANGE VAR_INTERFACE VAR_PREFER_IP4
77%token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_NAT64 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
78%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_TIMEOUT
79%token VAR_EDNS_TCP_KEEPALIVE VAR_EDNS_TCP_KEEPALIVE_TIMEOUT
80%token VAR_SOCK_QUEUE_TIMEOUT
81%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
82%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
83%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
84%token VAR_INFRA_HOST_TTL VAR_INFRA_LAME_TTL VAR_INFRA_CACHE_SLABS
85%token VAR_INFRA_CACHE_NUMHOSTS VAR_INFRA_CACHE_LAME_SIZE VAR_NAME
86%token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
87%token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
88%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
89%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
90%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
91%token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
92%token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
93%token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
94%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
95%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
96%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
97%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNSSEC_STRIPPED VAR_ACCESS_CONTROL
98%token VAR_LOCAL_ZONE VAR_LOCAL_DATA VAR_INTERFACE_AUTOMATIC
99%token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
100%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
101%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
102%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
103%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
104%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
105%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
106%token VAR_CONTROL_USE_CERT VAR_TCP_REUSE_TIMEOUT VAR_MAX_REUSE_TCP_QUERIES
107%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
108%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
109%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
110%token VAR_VAL_SIG_SKEW_MAX VAR_VAL_MAX_RESTART VAR_CACHE_MIN_TTL
111%token VAR_VAL_LOG_LEVEL VAR_AUTO_TRUST_ANCHOR_FILE VAR_KEEP_MISSING
112%token VAR_ADD_HOLDDOWN VAR_DEL_HOLDDOWN VAR_SO_RCVBUF VAR_EDNS_BUFFER_SIZE
113%token VAR_PREFETCH VAR_PREFETCH_KEY VAR_SO_SNDBUF VAR_SO_REUSEPORT
114%token VAR_HARDEN_BELOW_NXDOMAIN VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES
115%token VAR_LOG_REPLIES VAR_LOG_LOCAL_ACTIONS VAR_TCP_UPSTREAM
116%token VAR_SSL_UPSTREAM VAR_TCP_AUTH_QUERY_TIMEOUT VAR_SSL_SERVICE_KEY
117%token VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
118%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE
119%token VAR_STUB_TCP_UPSTREAM VAR_FORWARD_TCP_UPSTREAM
120%token VAR_HTTPS_PORT VAR_HTTP_ENDPOINT VAR_HTTP_MAX_STREAMS
121%token VAR_HTTP_QUERY_BUFFER_SIZE VAR_HTTP_RESPONSE_BUFFER_SIZE
122%token VAR_HTTP_NODELAY VAR_HTTP_NOTLS_DOWNSTREAM
123%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
124%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UDP_CONNECT
125%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
126%token VAR_INFRA_CACHE_MIN_RTT VAR_INFRA_CACHE_MAX_RTT VAR_INFRA_KEEP_PROBING
127%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA
128%token VAR_NAT64_PREFIX
129%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP
130%token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE
131%token VAR_DNSTAP_TLS_CLIENT_KEY_FILE VAR_DNSTAP_TLS_CLIENT_CERT_FILE
132%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION VAR_DNSTAP_BIDIRECTIONAL
133%token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION
134%token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES
135%token VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES
136%token VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES
137%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
138%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
139%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
140%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
141%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
142%token VAR_IP_DSCP
143%token VAR_DISABLE_DNSSEC_LAME_CHECK
144%token VAR_IP_RATELIMIT VAR_IP_RATELIMIT_SLABS VAR_IP_RATELIMIT_SIZE
145%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
146%token VAR_OUTBOUND_MSG_RETRY VAR_MAX_SENT_COUNT VAR_MAX_QUERY_RESTARTS
147%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
148%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
149%token VAR_IP_RATELIMIT_BACKOFF VAR_RATELIMIT_BACKOFF
150%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE
151%token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE
152%token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
153%token VAR_MIN_CLIENT_SUBNET_IPV4 VAR_MIN_CLIENT_SUBNET_IPV6
154%token VAR_MAX_ECS_TREE_SIZE_IPV4 VAR_MAX_ECS_TREE_SIZE_IPV6
155%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
156%token VAR_QNAME_MINIMISATION VAR_QNAME_MINIMISATION_STRICT VAR_IP_FREEBIND
157%token VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG VAR_ACCESS_CONTROL_TAG
158%token VAR_LOCAL_ZONE_OVERRIDE VAR_ACCESS_CONTROL_TAG_ACTION
159%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
160%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_SERVE_EXPIRED_TTL
161%token VAR_SERVE_EXPIRED_TTL_RESET VAR_SERVE_EXPIRED_REPLY_TTL
162%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_EDE_SERVE_EXPIRED
163%token VAR_SERVE_ORIGINAL_TTL VAR_FAKE_DSA
164%token VAR_FAKE_SHA1 VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR
165%token VAR_HIDE_HTTP_USER_AGENT VAR_HTTP_USER_AGENT
166%token VAR_TRUST_ANCHOR_SIGNALING VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD
167%token VAR_SHM_ENABLE VAR_SHM_KEY VAR_ROOT_KEY_SENTINEL
168%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
169%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
170%token VAR_DNSCRYPT_PROVIDER_CERT_ROTATED
171%token VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE
172%token VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS
173%token VAR_DNSCRYPT_NONCE_CACHE_SIZE
174%token VAR_DNSCRYPT_NONCE_CACHE_SLABS
175%token VAR_PAD_RESPONSES VAR_PAD_RESPONSES_BLOCK_SIZE
176%token VAR_PAD_QUERIES VAR_PAD_QUERIES_BLOCK_SIZE
177%token VAR_IPSECMOD_ENABLED VAR_IPSECMOD_HOOK VAR_IPSECMOD_IGNORE_BOGUS
178%token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT
179%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
180%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
181%token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD
182%token VAR_CACHEDB_REDISLOGICALDB
183%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
184%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
185%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
186%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
187%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
188%token VAR_ANSWER_COOKIE VAR_COOKIE_SECRET VAR_IP_RATELIMIT_COOKIE
189%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
190%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
191%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
192%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
193%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
194%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
195%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
196%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
197%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
198%token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS VAR_EDE
199%token VAR_INTERFACE_ACTION VAR_INTERFACE_VIEW VAR_INTERFACE_TAG
200%token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA
201%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
202%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
203
204%%
205toplevelvars: /* empty */ | toplevelvars toplevelvar ;
206toplevelvar: serverstart contents_server | stubstart contents_stub |
207	forwardstart contents_forward | pythonstart contents_py |
208	rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
209	dnscstart contents_dnsc | cachedbstart contents_cachedb |
210	ipsetstart contents_ipset | authstart contents_auth |
211	rpzstart contents_rpz | dynlibstart contents_dl |
212	force_toplevel
213	;
214force_toplevel: VAR_FORCE_TOPLEVEL
215	{
216		OUTYY(("\nP(force-toplevel)\n"));
217		cfg_parser->started_toplevel = 0;
218	}
219	;
220/* server: declaration */
221serverstart: VAR_SERVER
222	{
223		OUTYY(("\nP(server:)\n"));
224		cfg_parser->started_toplevel = 1;
225	}
226	;
227contents_server: contents_server content_server
228	| ;
229content_server: server_num_threads | server_verbosity | server_port |
230	server_outgoing_range | server_do_ip4 |
231	server_do_ip6 | server_do_nat64 | server_prefer_ip4 |
232	server_prefer_ip6 | server_do_udp | server_do_tcp |
233	server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout |
234	server_tcp_keepalive | server_tcp_keepalive_timeout |
235	server_sock_queue_timeout |
236	server_interface | server_chroot | server_username |
237	server_directory | server_logfile | server_pidfile |
238	server_msg_cache_size | server_msg_cache_slabs |
239	server_num_queries_per_thread | server_rrset_cache_size |
240	server_rrset_cache_slabs | server_outgoing_num_tcp |
241	server_infra_host_ttl | server_infra_lame_ttl |
242	server_infra_cache_slabs | server_infra_cache_numhosts |
243	server_infra_cache_lame_size | server_target_fetch_policy |
244	server_harden_short_bufsize | server_harden_large_queries |
245	server_do_not_query_address | server_hide_identity |
246	server_hide_version | server_identity | server_version |
247	server_hide_http_user_agent | server_http_user_agent |
248	server_harden_glue | server_module_conf | server_trust_anchor_file |
249	server_trust_anchor | server_val_override_date | server_bogus_ttl |
250	server_val_clean_additional | server_val_permissive_mode |
251	server_incoming_num_tcp | server_msg_buffer_size |
252	server_key_cache_size | server_key_cache_slabs |
253	server_trusted_keys_file | server_val_nsec3_keysize_iterations |
254	server_use_syslog | server_outgoing_interface | server_root_hints |
255	server_do_not_query_localhost | server_cache_max_ttl |
256	server_harden_dnssec_stripped | server_access_control |
257	server_local_zone | server_local_data | server_interface_automatic |
258	server_statistics_interval | server_do_daemonize |
259	server_use_caps_for_id | server_statistics_cumulative |
260	server_outgoing_port_permit | server_outgoing_port_avoid |
261	server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
262	server_harden_referral_path | server_private_address |
263	server_private_domain | server_extended_statistics |
264	server_local_data_ptr | server_jostle_timeout |
265	server_unwanted_reply_threshold | server_log_time_ascii |
266	server_domain_insecure | server_val_sig_skew_min |
267	server_val_sig_skew_max | server_val_max_restart |
268	server_cache_min_ttl | server_val_log_level |
269	server_auto_trust_anchor_file |	server_add_holddown |
270	server_del_holddown | server_keep_missing | server_so_rcvbuf |
271	server_edns_buffer_size | server_prefetch | server_prefetch_key |
272	server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag |
273	server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream |
274	server_log_local_actions |
275	server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
276	server_https_port | server_http_endpoint | server_http_max_streams |
277	server_http_query_buffer_size | server_http_response_buffer_size |
278	server_http_nodelay | server_http_notls_downstream |
279	server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
280	server_so_reuseport | server_delay_close | server_udp_connect |
281	server_unblock_lan_zones | server_insecure_lan_zones |
282	server_dns64_prefix | server_dns64_synthall | server_dns64_ignore_aaaa |
283	server_nat64_prefix |
284	server_infra_cache_min_rtt | server_infra_cache_max_rtt | server_harden_algo_downgrade |
285	server_ip_transparent | server_ip_ratelimit | server_ratelimit |
286	server_ip_dscp | server_infra_keep_probing |
287	server_ip_ratelimit_slabs | server_ratelimit_slabs |
288	server_ip_ratelimit_size | server_ratelimit_size |
289	server_ratelimit_for_domain |
290	server_ratelimit_below_domain | server_ratelimit_factor |
291	server_ip_ratelimit_factor | server_ratelimit_backoff |
292	server_ip_ratelimit_backoff | server_outbound_msg_retry |
293	server_max_sent_count | server_max_query_restarts |
294	server_send_client_subnet | server_client_subnet_zone |
295	server_client_subnet_always_forward | server_client_subnet_opcode |
296	server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
297	server_min_client_subnet_ipv4 | server_min_client_subnet_ipv6 |
298	server_max_ecs_tree_size_ipv4 | server_max_ecs_tree_size_ipv6 |
299	server_caps_whitelist | server_cache_max_negative_ttl |
300	server_permit_small_holddown | server_qname_minimisation |
301	server_ip_freebind | server_define_tag | server_local_zone_tag |
302	server_disable_dnssec_lame_check | server_access_control_tag |
303	server_local_zone_override | server_access_control_tag_action |
304	server_access_control_tag_data | server_access_control_view |
305	server_interface_action | server_interface_view | server_interface_tag |
306	server_interface_tag_action | server_interface_tag_data |
307	server_qname_minimisation_strict |
308	server_pad_responses | server_pad_responses_block_size |
309	server_pad_queries | server_pad_queries_block_size |
310	server_serve_expired |
311	server_serve_expired_ttl | server_serve_expired_ttl_reset |
312	server_serve_expired_reply_ttl | server_serve_expired_client_timeout |
313	server_ede_serve_expired | server_serve_original_ttl | server_fake_dsa |
314	server_log_identity | server_use_systemd |
315	server_response_ip_tag | server_response_ip | server_response_ip_data |
316	server_shm_enable | server_shm_key | server_fake_sha1 |
317	server_hide_trustanchor | server_trust_anchor_signaling |
318	server_root_key_sentinel |
319	server_ipsecmod_enabled | server_ipsecmod_hook |
320	server_ipsecmod_ignore_bogus | server_ipsecmod_max_ttl |
321	server_ipsecmod_whitelist | server_ipsecmod_strict |
322	server_udp_upstream_without_downstream | server_aggressive_nsec |
323	server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
324	server_fast_server_permil | server_fast_server_num  | server_tls_win_cert |
325	server_tcp_connection_limit | server_log_servfail | server_deny_any |
326	server_unknown_server_time_limit | server_log_tag_queryreply |
327	server_stream_wait_size | server_tls_ciphers |
328	server_tls_ciphersuites | server_tls_session_ticket_keys |
329	server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie |
330	server_tls_use_sni | server_edns_client_string |
331	server_edns_client_string_opcode | server_nsid |
332	server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
333	server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
334	server_interface_automatic_ports | server_ede |
335	server_proxy_protocol_port | server_statistics_inhibit_zero |
336	server_harden_unknown_additional | server_disable_edns_do
337	;
338stubstart: VAR_STUB_ZONE
339	{
340		struct config_stub* s;
341		OUTYY(("\nP(stub_zone:)\n"));
342		cfg_parser->started_toplevel = 1;
343		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
344		if(s) {
345			s->next = cfg_parser->cfg->stubs;
346			cfg_parser->cfg->stubs = s;
347		} else {
348			yyerror("out of memory");
349		}
350	}
351	;
352contents_stub: contents_stub content_stub
353	| ;
354content_stub: stub_name | stub_host | stub_addr | stub_prime | stub_first |
355	stub_no_cache | stub_ssl_upstream | stub_tcp_upstream
356	;
357forwardstart: VAR_FORWARD_ZONE
358	{
359		struct config_stub* s;
360		OUTYY(("\nP(forward_zone:)\n"));
361		cfg_parser->started_toplevel = 1;
362		s = (struct config_stub*)calloc(1, sizeof(struct config_stub));
363		if(s) {
364			s->next = cfg_parser->cfg->forwards;
365			cfg_parser->cfg->forwards = s;
366		} else {
367			yyerror("out of memory");
368		}
369	}
370	;
371contents_forward: contents_forward content_forward
372	| ;
373content_forward: forward_name | forward_host | forward_addr | forward_first |
374	forward_no_cache | forward_ssl_upstream | forward_tcp_upstream
375	;
376viewstart: VAR_VIEW
377	{
378		struct config_view* s;
379		OUTYY(("\nP(view:)\n"));
380		cfg_parser->started_toplevel = 1;
381		s = (struct config_view*)calloc(1, sizeof(struct config_view));
382		if(s) {
383			s->next = cfg_parser->cfg->views;
384			if(s->next && !s->next->name)
385				yyerror("view without name");
386			cfg_parser->cfg->views = s;
387		} else {
388			yyerror("out of memory");
389		}
390	}
391	;
392contents_view: contents_view content_view
393	| ;
394content_view: view_name | view_local_zone | view_local_data | view_first |
395		view_response_ip | view_response_ip_data | view_local_data_ptr
396	;
397authstart: VAR_AUTH_ZONE
398	{
399		struct config_auth* s;
400		OUTYY(("\nP(auth_zone:)\n"));
401		cfg_parser->started_toplevel = 1;
402		s = (struct config_auth*)calloc(1, sizeof(struct config_auth));
403		if(s) {
404			s->next = cfg_parser->cfg->auths;
405			cfg_parser->cfg->auths = s;
406			/* defaults for auth zone */
407			s->for_downstream = 1;
408			s->for_upstream = 1;
409			s->fallback_enabled = 0;
410			s->zonemd_check = 0;
411			s->zonemd_reject_absence = 0;
412			s->isrpz = 0;
413		} else {
414			yyerror("out of memory");
415		}
416	}
417	;
418contents_auth: contents_auth content_auth
419	| ;
420content_auth: auth_name | auth_zonefile | auth_master | auth_url |
421	auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
422	auth_allow_notify | auth_zonemd_check | auth_zonemd_reject_absence
423	;
424
425rpz_tag: VAR_TAGS STRING_ARG
426	{
427		uint8_t* bitlist;
428		size_t len = 0;
429		OUTYY(("P(server_local_zone_tag:%s)\n", $2));
430		bitlist = config_parse_taglist(cfg_parser->cfg, $2,
431			&len);
432		free($2);
433		if(!bitlist) {
434			yyerror("could not parse tags, (define-tag them first)");
435		}
436		if(bitlist) {
437			cfg_parser->cfg->auths->rpz_taglist = bitlist;
438			cfg_parser->cfg->auths->rpz_taglistlen = len;
439
440		}
441	}
442	;
443
444rpz_action_override: VAR_RPZ_ACTION_OVERRIDE STRING_ARG
445	{
446		OUTYY(("P(rpz_action_override:%s)\n", $2));
447		if(strcmp($2, "nxdomain")!=0 && strcmp($2, "nodata")!=0 &&
448		   strcmp($2, "passthru")!=0 && strcmp($2, "drop")!=0 &&
449		   strcmp($2, "cname")!=0 && strcmp($2, "disabled")!=0) {
450			yyerror("rpz-action-override action: expected nxdomain, "
451				"nodata, passthru, drop, cname or disabled");
452			free($2);
453			cfg_parser->cfg->auths->rpz_action_override = NULL;
454		}
455		else {
456			cfg_parser->cfg->auths->rpz_action_override = $2;
457		}
458	}
459	;
460
461rpz_cname_override: VAR_RPZ_CNAME_OVERRIDE STRING_ARG
462	{
463		OUTYY(("P(rpz_cname_override:%s)\n", $2));
464		free(cfg_parser->cfg->auths->rpz_cname);
465		cfg_parser->cfg->auths->rpz_cname = $2;
466	}
467	;
468
469rpz_log: VAR_RPZ_LOG STRING_ARG
470	{
471		OUTYY(("P(rpz_log:%s)\n", $2));
472		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
473			yyerror("expected yes or no.");
474		else cfg_parser->cfg->auths->rpz_log = (strcmp($2, "yes")==0);
475		free($2);
476	}
477	;
478
479rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG
480	{
481		OUTYY(("P(rpz_log_name:%s)\n", $2));
482		free(cfg_parser->cfg->auths->rpz_log_name);
483		cfg_parser->cfg->auths->rpz_log_name = $2;
484	}
485	;
486rpz_signal_nxdomain_ra: VAR_RPZ_SIGNAL_NXDOMAIN_RA STRING_ARG
487	{
488		OUTYY(("P(rpz_signal_nxdomain_ra:%s)\n", $2));
489		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
490			yyerror("expected yes or no.");
491		else cfg_parser->cfg->auths->rpz_signal_nxdomain_ra = (strcmp($2, "yes")==0);
492		free($2);
493	}
494	;
495
496rpzstart: VAR_RPZ
497	{
498		struct config_auth* s;
499		OUTYY(("\nP(rpz:)\n"));
500		cfg_parser->started_toplevel = 1;
501		s = (struct config_auth*)calloc(1, sizeof(struct config_auth));
502		if(s) {
503			s->next = cfg_parser->cfg->auths;
504			cfg_parser->cfg->auths = s;
505			/* defaults for RPZ auth zone */
506			s->for_downstream = 0;
507			s->for_upstream = 0;
508			s->fallback_enabled = 0;
509			s->isrpz = 1;
510		} else {
511			yyerror("out of memory");
512		}
513	}
514	;
515contents_rpz: contents_rpz content_rpz
516	| ;
517content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
518	   auth_allow_notify | rpz_action_override | rpz_cname_override |
519	   rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream
520	;
521server_num_threads: VAR_NUM_THREADS STRING_ARG
522	{
523		OUTYY(("P(server_num_threads:%s)\n", $2));
524		if(atoi($2) == 0 && strcmp($2, "0") != 0)
525			yyerror("number expected");
526		else cfg_parser->cfg->num_threads = atoi($2);
527		free($2);
528	}
529	;
530server_verbosity: VAR_VERBOSITY STRING_ARG
531	{
532		OUTYY(("P(server_verbosity:%s)\n", $2));
533		if(atoi($2) == 0 && strcmp($2, "0") != 0)
534			yyerror("number expected");
535		else cfg_parser->cfg->verbosity = atoi($2);
536		free($2);
537	}
538	;
539server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG
540	{
541		OUTYY(("P(server_statistics_interval:%s)\n", $2));
542		if(strcmp($2, "") == 0 || strcmp($2, "0") == 0)
543			cfg_parser->cfg->stat_interval = 0;
544		else if(atoi($2) == 0)
545			yyerror("number expected");
546		else cfg_parser->cfg->stat_interval = atoi($2);
547		free($2);
548	}
549	;
550server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG
551	{
552		OUTYY(("P(server_statistics_cumulative:%s)\n", $2));
553		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
554			yyerror("expected yes or no.");
555		else cfg_parser->cfg->stat_cumulative = (strcmp($2, "yes")==0);
556		free($2);
557	}
558	;
559server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
560	{
561		OUTYY(("P(server_extended_statistics:%s)\n", $2));
562		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
563			yyerror("expected yes or no.");
564		else cfg_parser->cfg->stat_extended = (strcmp($2, "yes")==0);
565		free($2);
566	}
567	;
568server_statistics_inhibit_zero: VAR_STATISTICS_INHIBIT_ZERO STRING_ARG
569	{
570		OUTYY(("P(server_statistics_inhibit_zero:%s)\n", $2));
571		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
572			yyerror("expected yes or no.");
573		else cfg_parser->cfg->stat_inhibit_zero = (strcmp($2, "yes")==0);
574		free($2);
575	}
576	;
577server_shm_enable: VAR_SHM_ENABLE STRING_ARG
578	{
579		OUTYY(("P(server_shm_enable:%s)\n", $2));
580		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
581			yyerror("expected yes or no.");
582		else cfg_parser->cfg->shm_enable = (strcmp($2, "yes")==0);
583		free($2);
584	}
585	;
586server_shm_key: VAR_SHM_KEY STRING_ARG
587	{
588		OUTYY(("P(server_shm_key:%s)\n", $2));
589		if(strcmp($2, "") == 0 || strcmp($2, "0") == 0)
590			cfg_parser->cfg->shm_key = 0;
591		else if(atoi($2) == 0)
592			yyerror("number expected");
593		else cfg_parser->cfg->shm_key = atoi($2);
594		free($2);
595	}
596	;
597server_port: VAR_PORT STRING_ARG
598	{
599		OUTYY(("P(server_port:%s)\n", $2));
600		if(atoi($2) == 0)
601			yyerror("port number expected");
602		else cfg_parser->cfg->port = atoi($2);
603		free($2);
604	}
605	;
606server_send_client_subnet: VAR_SEND_CLIENT_SUBNET STRING_ARG
607	{
608	#ifdef CLIENT_SUBNET
609		OUTYY(("P(server_send_client_subnet:%s)\n", $2));
610		if(!cfg_strlist_insert(&cfg_parser->cfg->client_subnet, $2))
611			fatal_exit("out of memory adding client-subnet");
612	#else
613		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
614		free($2);
615	#endif
616	}
617	;
618server_client_subnet_zone: VAR_CLIENT_SUBNET_ZONE STRING_ARG
619	{
620	#ifdef CLIENT_SUBNET
621		OUTYY(("P(server_client_subnet_zone:%s)\n", $2));
622		if(!cfg_strlist_insert(&cfg_parser->cfg->client_subnet_zone,
623			$2))
624			fatal_exit("out of memory adding client-subnet-zone");
625	#else
626		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
627		free($2);
628	#endif
629	}
630	;
631server_client_subnet_always_forward:
632	VAR_CLIENT_SUBNET_ALWAYS_FORWARD STRING_ARG
633	{
634	#ifdef CLIENT_SUBNET
635		OUTYY(("P(server_client_subnet_always_forward:%s)\n", $2));
636		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
637			yyerror("expected yes or no.");
638		else
639			cfg_parser->cfg->client_subnet_always_forward =
640				(strcmp($2, "yes")==0);
641	#else
642		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
643	#endif
644		free($2);
645	}
646	;
647server_client_subnet_opcode: VAR_CLIENT_SUBNET_OPCODE STRING_ARG
648	{
649	#ifdef CLIENT_SUBNET
650		OUTYY(("P(client_subnet_opcode:%s)\n", $2));
651		OUTYY(("P(Deprecated option, ignoring)\n"));
652	#else
653		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
654	#endif
655		free($2);
656	}
657	;
658server_max_client_subnet_ipv4: VAR_MAX_CLIENT_SUBNET_IPV4 STRING_ARG
659	{
660	#ifdef CLIENT_SUBNET
661		OUTYY(("P(max_client_subnet_ipv4:%s)\n", $2));
662		if(atoi($2) == 0 && strcmp($2, "0") != 0)
663			yyerror("IPv4 subnet length expected");
664		else if (atoi($2) > 32)
665			cfg_parser->cfg->max_client_subnet_ipv4 = 32;
666		else if (atoi($2) < 0)
667			cfg_parser->cfg->max_client_subnet_ipv4 = 0;
668		else cfg_parser->cfg->max_client_subnet_ipv4 = (uint8_t)atoi($2);
669	#else
670		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
671	#endif
672		free($2);
673	}
674	;
675server_max_client_subnet_ipv6: VAR_MAX_CLIENT_SUBNET_IPV6 STRING_ARG
676	{
677	#ifdef CLIENT_SUBNET
678		OUTYY(("P(max_client_subnet_ipv6:%s)\n", $2));
679		if(atoi($2) == 0 && strcmp($2, "0") != 0)
680			yyerror("Ipv6 subnet length expected");
681		else if (atoi($2) > 128)
682			cfg_parser->cfg->max_client_subnet_ipv6 = 128;
683		else if (atoi($2) < 0)
684			cfg_parser->cfg->max_client_subnet_ipv6 = 0;
685		else cfg_parser->cfg->max_client_subnet_ipv6 = (uint8_t)atoi($2);
686	#else
687		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
688	#endif
689		free($2);
690	}
691	;
692server_min_client_subnet_ipv4: VAR_MIN_CLIENT_SUBNET_IPV4 STRING_ARG
693	{
694	#ifdef CLIENT_SUBNET
695		OUTYY(("P(min_client_subnet_ipv4:%s)\n", $2));
696		if(atoi($2) == 0 && strcmp($2, "0") != 0)
697			yyerror("IPv4 subnet length expected");
698		else if (atoi($2) > 32)
699			cfg_parser->cfg->min_client_subnet_ipv4 = 32;
700		else if (atoi($2) < 0)
701			cfg_parser->cfg->min_client_subnet_ipv4 = 0;
702		else cfg_parser->cfg->min_client_subnet_ipv4 = (uint8_t)atoi($2);
703	#else
704		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
705	#endif
706		free($2);
707	}
708	;
709server_min_client_subnet_ipv6: VAR_MIN_CLIENT_SUBNET_IPV6 STRING_ARG
710	{
711	#ifdef CLIENT_SUBNET
712		OUTYY(("P(min_client_subnet_ipv6:%s)\n", $2));
713		if(atoi($2) == 0 && strcmp($2, "0") != 0)
714			yyerror("Ipv6 subnet length expected");
715		else if (atoi($2) > 128)
716			cfg_parser->cfg->min_client_subnet_ipv6 = 128;
717		else if (atoi($2) < 0)
718			cfg_parser->cfg->min_client_subnet_ipv6 = 0;
719		else cfg_parser->cfg->min_client_subnet_ipv6 = (uint8_t)atoi($2);
720	#else
721		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
722	#endif
723		free($2);
724	}
725	;
726server_max_ecs_tree_size_ipv4: VAR_MAX_ECS_TREE_SIZE_IPV4 STRING_ARG
727	{
728	#ifdef CLIENT_SUBNET
729		OUTYY(("P(max_ecs_tree_size_ipv4:%s)\n", $2));
730		if(atoi($2) == 0 && strcmp($2, "0") != 0)
731			yyerror("IPv4 ECS tree size expected");
732		else if (atoi($2) < 0)
733			cfg_parser->cfg->max_ecs_tree_size_ipv4 = 0;
734		else cfg_parser->cfg->max_ecs_tree_size_ipv4 = (uint32_t)atoi($2);
735	#else
736		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
737	#endif
738		free($2);
739	}
740	;
741server_max_ecs_tree_size_ipv6: VAR_MAX_ECS_TREE_SIZE_IPV6 STRING_ARG
742	{
743	#ifdef CLIENT_SUBNET
744		OUTYY(("P(max_ecs_tree_size_ipv6:%s)\n", $2));
745		if(atoi($2) == 0 && strcmp($2, "0") != 0)
746			yyerror("IPv6 ECS tree size expected");
747		else if (atoi($2) < 0)
748			cfg_parser->cfg->max_ecs_tree_size_ipv6 = 0;
749		else cfg_parser->cfg->max_ecs_tree_size_ipv6 = (uint32_t)atoi($2);
750	#else
751		OUTYY(("P(Compiled without edns subnet option, ignoring)\n"));
752	#endif
753		free($2);
754	}
755	;
756server_interface: VAR_INTERFACE STRING_ARG
757	{
758		OUTYY(("P(server_interface:%s)\n", $2));
759		if(cfg_parser->cfg->num_ifs == 0)
760			cfg_parser->cfg->ifs = calloc(1, sizeof(char*));
761		else cfg_parser->cfg->ifs = realloc(cfg_parser->cfg->ifs,
762				(cfg_parser->cfg->num_ifs+1)*sizeof(char*));
763		if(!cfg_parser->cfg->ifs)
764			yyerror("out of memory");
765		else
766			cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = $2;
767	}
768	;
769server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG
770	{
771		OUTYY(("P(server_outgoing_interface:%s)\n", $2));
772		if(cfg_parser->cfg->num_out_ifs == 0)
773			cfg_parser->cfg->out_ifs = calloc(1, sizeof(char*));
774		else cfg_parser->cfg->out_ifs = realloc(
775			cfg_parser->cfg->out_ifs,
776			(cfg_parser->cfg->num_out_ifs+1)*sizeof(char*));
777		if(!cfg_parser->cfg->out_ifs)
778			yyerror("out of memory");
779		else
780			cfg_parser->cfg->out_ifs[
781				cfg_parser->cfg->num_out_ifs++] = $2;
782	}
783	;
784server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG
785	{
786		OUTYY(("P(server_outgoing_range:%s)\n", $2));
787		if(atoi($2) == 0)
788			yyerror("number expected");
789		else cfg_parser->cfg->outgoing_num_ports = atoi($2);
790		free($2);
791	}
792	;
793server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG
794	{
795		OUTYY(("P(server_outgoing_port_permit:%s)\n", $2));
796		if(!cfg_mark_ports($2, 1,
797			cfg_parser->cfg->outgoing_avail_ports, 65536))
798			yyerror("port number or range (\"low-high\") expected");
799		free($2);
800	}
801	;
802server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG
803	{
804		OUTYY(("P(server_outgoing_port_avoid:%s)\n", $2));
805		if(!cfg_mark_ports($2, 0,
806			cfg_parser->cfg->outgoing_avail_ports, 65536))
807			yyerror("port number or range (\"low-high\") expected");
808		free($2);
809	}
810	;
811server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG
812	{
813		OUTYY(("P(server_outgoing_num_tcp:%s)\n", $2));
814		if(atoi($2) == 0 && strcmp($2, "0") != 0)
815			yyerror("number expected");
816		else cfg_parser->cfg->outgoing_num_tcp = atoi($2);
817		free($2);
818	}
819	;
820server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG
821	{
822		OUTYY(("P(server_incoming_num_tcp:%s)\n", $2));
823		if(atoi($2) == 0 && strcmp($2, "0") != 0)
824			yyerror("number expected");
825		else cfg_parser->cfg->incoming_num_tcp = atoi($2);
826		free($2);
827	}
828	;
829server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG
830	{
831		OUTYY(("P(server_interface_automatic:%s)\n", $2));
832		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
833			yyerror("expected yes or no.");
834		else cfg_parser->cfg->if_automatic = (strcmp($2, "yes")==0);
835		free($2);
836	}
837	;
838server_interface_automatic_ports: VAR_INTERFACE_AUTOMATIC_PORTS STRING_ARG
839	{
840		OUTYY(("P(server_interface_automatic_ports:%s)\n", $2));
841		free(cfg_parser->cfg->if_automatic_ports);
842		cfg_parser->cfg->if_automatic_ports = $2;
843	}
844	;
845server_do_ip4: VAR_DO_IP4 STRING_ARG
846	{
847		OUTYY(("P(server_do_ip4:%s)\n", $2));
848		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
849			yyerror("expected yes or no.");
850		else cfg_parser->cfg->do_ip4 = (strcmp($2, "yes")==0);
851		free($2);
852	}
853	;
854server_do_ip6: VAR_DO_IP6 STRING_ARG
855	{
856		OUTYY(("P(server_do_ip6:%s)\n", $2));
857		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
858			yyerror("expected yes or no.");
859		else cfg_parser->cfg->do_ip6 = (strcmp($2, "yes")==0);
860		free($2);
861	}
862	;
863server_do_nat64: VAR_DO_NAT64 STRING_ARG
864	{
865		OUTYY(("P(server_do_nat64:%s)\n", $2));
866		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
867			yyerror("expected yes or no.");
868		else cfg_parser->cfg->do_nat64 = (strcmp($2, "yes")==0);
869		free($2);
870	}
871	;
872server_do_udp: VAR_DO_UDP STRING_ARG
873	{
874		OUTYY(("P(server_do_udp:%s)\n", $2));
875		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
876			yyerror("expected yes or no.");
877		else cfg_parser->cfg->do_udp = (strcmp($2, "yes")==0);
878		free($2);
879	}
880	;
881server_do_tcp: VAR_DO_TCP STRING_ARG
882	{
883		OUTYY(("P(server_do_tcp:%s)\n", $2));
884		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
885			yyerror("expected yes or no.");
886		else cfg_parser->cfg->do_tcp = (strcmp($2, "yes")==0);
887		free($2);
888	}
889	;
890server_prefer_ip4: VAR_PREFER_IP4 STRING_ARG
891	{
892		OUTYY(("P(server_prefer_ip4:%s)\n", $2));
893		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
894			yyerror("expected yes or no.");
895		else cfg_parser->cfg->prefer_ip4 = (strcmp($2, "yes")==0);
896		free($2);
897	}
898	;
899server_prefer_ip6: VAR_PREFER_IP6 STRING_ARG
900	{
901		OUTYY(("P(server_prefer_ip6:%s)\n", $2));
902		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
903			yyerror("expected yes or no.");
904		else cfg_parser->cfg->prefer_ip6 = (strcmp($2, "yes")==0);
905		free($2);
906	}
907	;
908server_tcp_mss: VAR_TCP_MSS STRING_ARG
909	{
910		OUTYY(("P(server_tcp_mss:%s)\n", $2));
911		if(atoi($2) == 0 && strcmp($2, "0") != 0)
912				yyerror("number expected");
913		else cfg_parser->cfg->tcp_mss = atoi($2);
914		free($2);
915	}
916	;
917server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING_ARG
918	{
919		OUTYY(("P(server_outgoing_tcp_mss:%s)\n", $2));
920		if(atoi($2) == 0 && strcmp($2, "0") != 0)
921			yyerror("number expected");
922		else cfg_parser->cfg->outgoing_tcp_mss = atoi($2);
923		free($2);
924	}
925	;
926server_tcp_idle_timeout: VAR_TCP_IDLE_TIMEOUT STRING_ARG
927	{
928		OUTYY(("P(server_tcp_idle_timeout:%s)\n", $2));
929		if(atoi($2) == 0 && strcmp($2, "0") != 0)
930			yyerror("number expected");
931		else if (atoi($2) > 120000)
932			cfg_parser->cfg->tcp_idle_timeout = 120000;
933		else if (atoi($2) < 1)
934			cfg_parser->cfg->tcp_idle_timeout = 1;
935		else cfg_parser->cfg->tcp_idle_timeout = atoi($2);
936		free($2);
937	}
938	;
939server_max_reuse_tcp_queries: VAR_MAX_REUSE_TCP_QUERIES STRING_ARG
940	{
941		OUTYY(("P(server_max_reuse_tcp_queries:%s)\n", $2));
942		if(atoi($2) == 0 && strcmp($2, "0") != 0)
943			yyerror("number expected");
944		else if (atoi($2) < 1)
945			cfg_parser->cfg->max_reuse_tcp_queries = 0;
946		else cfg_parser->cfg->max_reuse_tcp_queries = atoi($2);
947		free($2);
948	}
949	;
950server_tcp_reuse_timeout: VAR_TCP_REUSE_TIMEOUT STRING_ARG
951	{
952		OUTYY(("P(server_tcp_reuse_timeout:%s)\n", $2));
953		if(atoi($2) == 0 && strcmp($2, "0") != 0)
954			yyerror("number expected");
955		else if (atoi($2) < 1)
956			cfg_parser->cfg->tcp_reuse_timeout = 0;
957		else cfg_parser->cfg->tcp_reuse_timeout = atoi($2);
958		free($2);
959	}
960	;
961server_tcp_auth_query_timeout: VAR_TCP_AUTH_QUERY_TIMEOUT STRING_ARG
962	{
963		OUTYY(("P(server_tcp_auth_query_timeout:%s)\n", $2));
964		if(atoi($2) == 0 && strcmp($2, "0") != 0)
965			yyerror("number expected");
966		else if (atoi($2) < 1)
967			cfg_parser->cfg->tcp_auth_query_timeout = 0;
968		else cfg_parser->cfg->tcp_auth_query_timeout = atoi($2);
969		free($2);
970	}
971	;
972server_tcp_keepalive: VAR_EDNS_TCP_KEEPALIVE STRING_ARG
973	{
974		OUTYY(("P(server_tcp_keepalive:%s)\n", $2));
975		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
976			yyerror("expected yes or no.");
977		else cfg_parser->cfg->do_tcp_keepalive = (strcmp($2, "yes")==0);
978		free($2);
979	}
980	;
981server_tcp_keepalive_timeout: VAR_EDNS_TCP_KEEPALIVE_TIMEOUT STRING_ARG
982	{
983		OUTYY(("P(server_tcp_keepalive_timeout:%s)\n", $2));
984		if(atoi($2) == 0 && strcmp($2, "0") != 0)
985			yyerror("number expected");
986		else if (atoi($2) > 6553500)
987			cfg_parser->cfg->tcp_keepalive_timeout = 6553500;
988		else if (atoi($2) < 1)
989			cfg_parser->cfg->tcp_keepalive_timeout = 0;
990		else cfg_parser->cfg->tcp_keepalive_timeout = atoi($2);
991		free($2);
992	}
993	;
994server_sock_queue_timeout: VAR_SOCK_QUEUE_TIMEOUT STRING_ARG
995	{
996		OUTYY(("P(server_sock_queue_timeout:%s)\n", $2));
997		if(atoi($2) == 0 && strcmp($2, "0") != 0)
998			yyerror("number expected");
999		else if (atoi($2) > 6553500)
1000			cfg_parser->cfg->sock_queue_timeout = 6553500;
1001		else if (atoi($2) < 1)
1002			cfg_parser->cfg->sock_queue_timeout = 0;
1003		else cfg_parser->cfg->sock_queue_timeout = atoi($2);
1004		free($2);
1005	}
1006	;
1007server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
1008	{
1009		OUTYY(("P(server_tcp_upstream:%s)\n", $2));
1010		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1011			yyerror("expected yes or no.");
1012		else cfg_parser->cfg->tcp_upstream = (strcmp($2, "yes")==0);
1013		free($2);
1014	}
1015	;
1016server_udp_upstream_without_downstream: VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM STRING_ARG
1017	{
1018		OUTYY(("P(server_udp_upstream_without_downstream:%s)\n", $2));
1019		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1020			yyerror("expected yes or no.");
1021		else cfg_parser->cfg->udp_upstream_without_downstream = (strcmp($2, "yes")==0);
1022		free($2);
1023	}
1024	;
1025server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG
1026	{
1027		OUTYY(("P(server_ssl_upstream:%s)\n", $2));
1028		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1029			yyerror("expected yes or no.");
1030		else cfg_parser->cfg->ssl_upstream = (strcmp($2, "yes")==0);
1031		free($2);
1032	}
1033	;
1034server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG
1035	{
1036		OUTYY(("P(server_ssl_service_key:%s)\n", $2));
1037		free(cfg_parser->cfg->ssl_service_key);
1038		cfg_parser->cfg->ssl_service_key = $2;
1039	}
1040	;
1041server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG
1042	{
1043		OUTYY(("P(server_ssl_service_pem:%s)\n", $2));
1044		free(cfg_parser->cfg->ssl_service_pem);
1045		cfg_parser->cfg->ssl_service_pem = $2;
1046	}
1047	;
1048server_ssl_port: VAR_SSL_PORT STRING_ARG
1049	{
1050		OUTYY(("P(server_ssl_port:%s)\n", $2));
1051		if(atoi($2) == 0)
1052			yyerror("port number expected");
1053		else cfg_parser->cfg->ssl_port = atoi($2);
1054		free($2);
1055	}
1056	;
1057server_tls_cert_bundle: VAR_TLS_CERT_BUNDLE STRING_ARG
1058	{
1059		OUTYY(("P(server_tls_cert_bundle:%s)\n", $2));
1060		free(cfg_parser->cfg->tls_cert_bundle);
1061		cfg_parser->cfg->tls_cert_bundle = $2;
1062	}
1063	;
1064server_tls_win_cert: VAR_TLS_WIN_CERT STRING_ARG
1065	{
1066		OUTYY(("P(server_tls_win_cert:%s)\n", $2));
1067		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1068			yyerror("expected yes or no.");
1069		else cfg_parser->cfg->tls_win_cert = (strcmp($2, "yes")==0);
1070		free($2);
1071	}
1072	;
1073server_tls_additional_port: VAR_TLS_ADDITIONAL_PORT STRING_ARG
1074	{
1075		OUTYY(("P(server_tls_additional_port:%s)\n", $2));
1076		if(!cfg_strlist_insert(&cfg_parser->cfg->tls_additional_port,
1077			$2))
1078			yyerror("out of memory");
1079	}
1080	;
1081server_tls_ciphers: VAR_TLS_CIPHERS STRING_ARG
1082	{
1083		OUTYY(("P(server_tls_ciphers:%s)\n", $2));
1084		free(cfg_parser->cfg->tls_ciphers);
1085		cfg_parser->cfg->tls_ciphers = $2;
1086	}
1087	;
1088server_tls_ciphersuites: VAR_TLS_CIPHERSUITES STRING_ARG
1089	{
1090		OUTYY(("P(server_tls_ciphersuites:%s)\n", $2));
1091		free(cfg_parser->cfg->tls_ciphersuites);
1092		cfg_parser->cfg->tls_ciphersuites = $2;
1093	}
1094	;
1095server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG
1096	{
1097		OUTYY(("P(server_tls_session_ticket_keys:%s)\n", $2));
1098		if(!cfg_strlist_append(&cfg_parser->cfg->tls_session_ticket_keys,
1099			$2))
1100			yyerror("out of memory");
1101	}
1102	;
1103server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG
1104	{
1105		OUTYY(("P(server_tls_use_sni:%s)\n", $2));
1106		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1107			yyerror("expected yes or no.");
1108		else cfg_parser->cfg->tls_use_sni = (strcmp($2, "yes")==0);
1109		free($2);
1110	}
1111	;
1112server_https_port: VAR_HTTPS_PORT STRING_ARG
1113	{
1114		OUTYY(("P(server_https_port:%s)\n", $2));
1115		if(atoi($2) == 0)
1116			yyerror("port number expected");
1117		else cfg_parser->cfg->https_port = atoi($2);
1118		free($2);
1119	};
1120server_http_endpoint: VAR_HTTP_ENDPOINT STRING_ARG
1121	{
1122		OUTYY(("P(server_http_endpoint:%s)\n", $2));
1123		free(cfg_parser->cfg->http_endpoint);
1124		if($2 && $2[0] != '/') {
1125			cfg_parser->cfg->http_endpoint = malloc(strlen($2)+2);
1126			if(!cfg_parser->cfg->http_endpoint)
1127				yyerror("out of memory");
1128			cfg_parser->cfg->http_endpoint[0] = '/';
1129			memmove(cfg_parser->cfg->http_endpoint+1, $2,
1130				strlen($2)+1);
1131			free($2);
1132		} else {
1133			cfg_parser->cfg->http_endpoint = $2;
1134		}
1135	};
1136server_http_max_streams: VAR_HTTP_MAX_STREAMS STRING_ARG
1137	{
1138		OUTYY(("P(server_http_max_streams:%s)\n", $2));
1139		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1140			yyerror("number expected");
1141		else cfg_parser->cfg->http_max_streams = atoi($2);
1142		free($2);
1143	};
1144server_http_query_buffer_size: VAR_HTTP_QUERY_BUFFER_SIZE STRING_ARG
1145	{
1146		OUTYY(("P(server_http_query_buffer_size:%s)\n", $2));
1147		if(!cfg_parse_memsize($2,
1148			&cfg_parser->cfg->http_query_buffer_size))
1149			yyerror("memory size expected");
1150		free($2);
1151	};
1152server_http_response_buffer_size: VAR_HTTP_RESPONSE_BUFFER_SIZE STRING_ARG
1153	{
1154		OUTYY(("P(server_http_response_buffer_size:%s)\n", $2));
1155		if(!cfg_parse_memsize($2,
1156			&cfg_parser->cfg->http_response_buffer_size))
1157			yyerror("memory size expected");
1158		free($2);
1159	};
1160server_http_nodelay: VAR_HTTP_NODELAY STRING_ARG
1161	{
1162		OUTYY(("P(server_http_nodelay:%s)\n", $2));
1163		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1164			yyerror("expected yes or no.");
1165		else cfg_parser->cfg->http_nodelay = (strcmp($2, "yes")==0);
1166		free($2);
1167	};
1168server_http_notls_downstream: VAR_HTTP_NOTLS_DOWNSTREAM STRING_ARG
1169	{
1170		OUTYY(("P(server_http_notls_downstream:%s)\n", $2));
1171		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1172			yyerror("expected yes or no.");
1173		else cfg_parser->cfg->http_notls_downstream = (strcmp($2, "yes")==0);
1174		free($2);
1175	};
1176server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
1177	{
1178		OUTYY(("P(server_use_systemd:%s)\n", $2));
1179		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1180			yyerror("expected yes or no.");
1181		else cfg_parser->cfg->use_systemd = (strcmp($2, "yes")==0);
1182		free($2);
1183	}
1184	;
1185server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG
1186	{
1187		OUTYY(("P(server_do_daemonize:%s)\n", $2));
1188		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1189			yyerror("expected yes or no.");
1190		else cfg_parser->cfg->do_daemonize = (strcmp($2, "yes")==0);
1191		free($2);
1192	}
1193	;
1194server_use_syslog: VAR_USE_SYSLOG STRING_ARG
1195	{
1196		OUTYY(("P(server_use_syslog:%s)\n", $2));
1197		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1198			yyerror("expected yes or no.");
1199		else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0);
1200#if !defined(HAVE_SYSLOG_H) && !defined(UB_ON_WINDOWS)
1201		if(strcmp($2, "yes") == 0)
1202			yyerror("no syslog services are available. "
1203				"(reconfigure and compile to add)");
1204#endif
1205		free($2);
1206	}
1207	;
1208server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG
1209	{
1210		OUTYY(("P(server_log_time_ascii:%s)\n", $2));
1211		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1212			yyerror("expected yes or no.");
1213		else cfg_parser->cfg->log_time_ascii = (strcmp($2, "yes")==0);
1214		free($2);
1215	}
1216	;
1217server_log_queries: VAR_LOG_QUERIES STRING_ARG
1218	{
1219		OUTYY(("P(server_log_queries:%s)\n", $2));
1220		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1221			yyerror("expected yes or no.");
1222		else cfg_parser->cfg->log_queries = (strcmp($2, "yes")==0);
1223		free($2);
1224	}
1225	;
1226server_log_replies: VAR_LOG_REPLIES STRING_ARG
1227	{
1228		OUTYY(("P(server_log_replies:%s)\n", $2));
1229		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1230			yyerror("expected yes or no.");
1231		else cfg_parser->cfg->log_replies = (strcmp($2, "yes")==0);
1232		free($2);
1233	}
1234	;
1235server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG
1236	{
1237		OUTYY(("P(server_log_tag_queryreply:%s)\n", $2));
1238		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1239			yyerror("expected yes or no.");
1240		else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0);
1241		free($2);
1242	}
1243	;
1244server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG
1245	{
1246		OUTYY(("P(server_log_servfail:%s)\n", $2));
1247		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1248			yyerror("expected yes or no.");
1249		else cfg_parser->cfg->log_servfail = (strcmp($2, "yes")==0);
1250		free($2);
1251	}
1252	;
1253server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG
1254	{
1255		OUTYY(("P(server_log_local_actions:%s)\n", $2));
1256		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1257			yyerror("expected yes or no.");
1258		else cfg_parser->cfg->log_local_actions = (strcmp($2, "yes")==0);
1259		free($2);
1260	}
1261	;
1262server_chroot: VAR_CHROOT STRING_ARG
1263	{
1264		OUTYY(("P(server_chroot:%s)\n", $2));
1265		free(cfg_parser->cfg->chrootdir);
1266		cfg_parser->cfg->chrootdir = $2;
1267	}
1268	;
1269server_username: VAR_USERNAME STRING_ARG
1270	{
1271		OUTYY(("P(server_username:%s)\n", $2));
1272		free(cfg_parser->cfg->username);
1273		cfg_parser->cfg->username = $2;
1274	}
1275	;
1276server_directory: VAR_DIRECTORY STRING_ARG
1277	{
1278		OUTYY(("P(server_directory:%s)\n", $2));
1279		free(cfg_parser->cfg->directory);
1280		cfg_parser->cfg->directory = $2;
1281		/* change there right away for includes relative to this */
1282		if($2[0]) {
1283			char* d;
1284#ifdef UB_ON_WINDOWS
1285			w_config_adjust_directory(cfg_parser->cfg);
1286#endif
1287			d = cfg_parser->cfg->directory;
1288			/* adjust directory if we have already chroot,
1289			 * like, we reread after sighup */
1290			if(cfg_parser->chroot && cfg_parser->chroot[0] &&
1291				strncmp(d, cfg_parser->chroot, strlen(
1292				cfg_parser->chroot)) == 0)
1293				d += strlen(cfg_parser->chroot);
1294			if(d[0]) {
1295				if(chdir(d))
1296				log_err("cannot chdir to directory: %s (%s)",
1297					d, strerror(errno));
1298			}
1299		}
1300	}
1301	;
1302server_logfile: VAR_LOGFILE STRING_ARG
1303	{
1304		OUTYY(("P(server_logfile:%s)\n", $2));
1305		free(cfg_parser->cfg->logfile);
1306		cfg_parser->cfg->logfile = $2;
1307		cfg_parser->cfg->use_syslog = 0;
1308	}
1309	;
1310server_pidfile: VAR_PIDFILE STRING_ARG
1311	{
1312		OUTYY(("P(server_pidfile:%s)\n", $2));
1313		free(cfg_parser->cfg->pidfile);
1314		cfg_parser->cfg->pidfile = $2;
1315	}
1316	;
1317server_root_hints: VAR_ROOT_HINTS STRING_ARG
1318	{
1319		OUTYY(("P(server_root_hints:%s)\n", $2));
1320		if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, $2))
1321			yyerror("out of memory");
1322	}
1323	;
1324server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG
1325	{
1326		OUTYY(("P(server_dlv_anchor_file:%s)\n", $2));
1327		log_warn("option dlv-anchor-file ignored: DLV is decommissioned");
1328		free($2);
1329	}
1330	;
1331server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG
1332	{
1333		OUTYY(("P(server_dlv_anchor:%s)\n", $2));
1334		log_warn("option dlv-anchor ignored: DLV is decommissioned");
1335		free($2);
1336	}
1337	;
1338server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG
1339	{
1340		OUTYY(("P(server_auto_trust_anchor_file:%s)\n", $2));
1341		if(!cfg_strlist_insert(&cfg_parser->cfg->
1342			auto_trust_anchor_file_list, $2))
1343			yyerror("out of memory");
1344	}
1345	;
1346server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG
1347	{
1348		OUTYY(("P(server_trust_anchor_file:%s)\n", $2));
1349		if(!cfg_strlist_insert(&cfg_parser->cfg->
1350			trust_anchor_file_list, $2))
1351			yyerror("out of memory");
1352	}
1353	;
1354server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG
1355	{
1356		OUTYY(("P(server_trusted_keys_file:%s)\n", $2));
1357		if(!cfg_strlist_insert(&cfg_parser->cfg->
1358			trusted_keys_file_list, $2))
1359			yyerror("out of memory");
1360	}
1361	;
1362server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG
1363	{
1364		OUTYY(("P(server_trust_anchor:%s)\n", $2));
1365		if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, $2))
1366			yyerror("out of memory");
1367	}
1368	;
1369server_trust_anchor_signaling: VAR_TRUST_ANCHOR_SIGNALING STRING_ARG
1370	{
1371		OUTYY(("P(server_trust_anchor_signaling:%s)\n", $2));
1372		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1373			yyerror("expected yes or no.");
1374		else
1375			cfg_parser->cfg->trust_anchor_signaling =
1376				(strcmp($2, "yes")==0);
1377		free($2);
1378	}
1379	;
1380server_root_key_sentinel: VAR_ROOT_KEY_SENTINEL STRING_ARG
1381	{
1382		OUTYY(("P(server_root_key_sentinel:%s)\n", $2));
1383		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1384			yyerror("expected yes or no.");
1385		else
1386			cfg_parser->cfg->root_key_sentinel =
1387				(strcmp($2, "yes")==0);
1388		free($2);
1389	}
1390	;
1391server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
1392	{
1393		OUTYY(("P(server_domain_insecure:%s)\n", $2));
1394		if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, $2))
1395			yyerror("out of memory");
1396	}
1397	;
1398server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG
1399	{
1400		OUTYY(("P(server_hide_identity:%s)\n", $2));
1401		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1402			yyerror("expected yes or no.");
1403		else cfg_parser->cfg->hide_identity = (strcmp($2, "yes")==0);
1404		free($2);
1405	}
1406	;
1407server_hide_version: VAR_HIDE_VERSION STRING_ARG
1408	{
1409		OUTYY(("P(server_hide_version:%s)\n", $2));
1410		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1411			yyerror("expected yes or no.");
1412		else cfg_parser->cfg->hide_version = (strcmp($2, "yes")==0);
1413		free($2);
1414	}
1415	;
1416server_hide_trustanchor: VAR_HIDE_TRUSTANCHOR STRING_ARG
1417	{
1418		OUTYY(("P(server_hide_trustanchor:%s)\n", $2));
1419		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1420			yyerror("expected yes or no.");
1421		else cfg_parser->cfg->hide_trustanchor = (strcmp($2, "yes")==0);
1422		free($2);
1423	}
1424	;
1425server_hide_http_user_agent: VAR_HIDE_HTTP_USER_AGENT STRING_ARG
1426	{
1427		OUTYY(("P(server_hide_user_agent:%s)\n", $2));
1428		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1429			yyerror("expected yes or no.");
1430		else cfg_parser->cfg->hide_http_user_agent = (strcmp($2, "yes")==0);
1431		free($2);
1432	}
1433	;
1434server_identity: VAR_IDENTITY STRING_ARG
1435	{
1436		OUTYY(("P(server_identity:%s)\n", $2));
1437		free(cfg_parser->cfg->identity);
1438		cfg_parser->cfg->identity = $2;
1439	}
1440	;
1441server_version: VAR_VERSION STRING_ARG
1442	{
1443		OUTYY(("P(server_version:%s)\n", $2));
1444		free(cfg_parser->cfg->version);
1445		cfg_parser->cfg->version = $2;
1446	}
1447	;
1448server_http_user_agent: VAR_HTTP_USER_AGENT STRING_ARG
1449	{
1450		OUTYY(("P(server_http_user_agent:%s)\n", $2));
1451		free(cfg_parser->cfg->http_user_agent);
1452		cfg_parser->cfg->http_user_agent = $2;
1453	}
1454	;
1455server_nsid: VAR_NSID STRING_ARG
1456	{
1457		OUTYY(("P(server_nsid:%s)\n", $2));
1458		free(cfg_parser->cfg->nsid_cfg_str);
1459		cfg_parser->cfg->nsid_cfg_str = $2;
1460		free(cfg_parser->cfg->nsid);
1461		cfg_parser->cfg->nsid = NULL;
1462		cfg_parser->cfg->nsid_len = 0;
1463		if (*$2 == 0)
1464			; /* pass; empty string is not setting nsid */
1465		else if (!(cfg_parser->cfg->nsid = cfg_parse_nsid(
1466					$2, &cfg_parser->cfg->nsid_len)))
1467			yyerror("the NSID must be either a hex string or an "
1468			    "ascii character string prepended with ascii_.");
1469	}
1470	;
1471server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG
1472	{
1473		OUTYY(("P(server_so_rcvbuf:%s)\n", $2));
1474		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_rcvbuf))
1475			yyerror("buffer size expected");
1476		free($2);
1477	}
1478	;
1479server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG
1480	{
1481		OUTYY(("P(server_so_sndbuf:%s)\n", $2));
1482		if(!cfg_parse_memsize($2, &cfg_parser->cfg->so_sndbuf))
1483			yyerror("buffer size expected");
1484		free($2);
1485	}
1486	;
1487server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG
1488	{
1489		OUTYY(("P(server_so_reuseport:%s)\n", $2));
1490		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1491			yyerror("expected yes or no.");
1492		else cfg_parser->cfg->so_reuseport =
1493			(strcmp($2, "yes")==0);
1494		free($2);
1495	}
1496	;
1497server_ip_transparent: VAR_IP_TRANSPARENT STRING_ARG
1498	{
1499		OUTYY(("P(server_ip_transparent:%s)\n", $2));
1500		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1501			yyerror("expected yes or no.");
1502		else cfg_parser->cfg->ip_transparent =
1503			(strcmp($2, "yes")==0);
1504		free($2);
1505	}
1506	;
1507server_ip_freebind: VAR_IP_FREEBIND STRING_ARG
1508	{
1509		OUTYY(("P(server_ip_freebind:%s)\n", $2));
1510		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1511			yyerror("expected yes or no.");
1512		else cfg_parser->cfg->ip_freebind =
1513			(strcmp($2, "yes")==0);
1514		free($2);
1515	}
1516	;
1517server_ip_dscp: VAR_IP_DSCP STRING_ARG
1518	{
1519		OUTYY(("P(server_ip_dscp:%s)\n", $2));
1520		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1521			yyerror("number expected");
1522		else if (atoi($2) > 63)
1523			yyerror("value too large (max 63)");
1524		else if (atoi($2) < 0)
1525			yyerror("value too small (min 0)");
1526		else
1527			cfg_parser->cfg->ip_dscp = atoi($2);
1528		free($2);
1529	}
1530	;
1531server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG
1532	{
1533		OUTYY(("P(server_stream_wait_size:%s)\n", $2));
1534		if(!cfg_parse_memsize($2, &cfg_parser->cfg->stream_wait_size))
1535			yyerror("memory size expected");
1536		free($2);
1537	}
1538	;
1539server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
1540	{
1541		OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
1542		if(atoi($2) == 0)
1543			yyerror("number expected");
1544		else if (atoi($2) < 12)
1545			yyerror("edns buffer size too small");
1546		else if (atoi($2) > 65535)
1547			cfg_parser->cfg->edns_buffer_size = 65535;
1548		else cfg_parser->cfg->edns_buffer_size = atoi($2);
1549		free($2);
1550	}
1551	;
1552server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG
1553	{
1554		OUTYY(("P(server_msg_buffer_size:%s)\n", $2));
1555		if(atoi($2) == 0)
1556			yyerror("number expected");
1557		else if (atoi($2) < 4096)
1558			yyerror("message buffer size too small (use 4096)");
1559		else cfg_parser->cfg->msg_buffer_size = atoi($2);
1560		free($2);
1561	}
1562	;
1563server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG
1564	{
1565		OUTYY(("P(server_msg_cache_size:%s)\n", $2));
1566		if(!cfg_parse_memsize($2, &cfg_parser->cfg->msg_cache_size))
1567			yyerror("memory size expected");
1568		free($2);
1569	}
1570	;
1571server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG
1572	{
1573		OUTYY(("P(server_msg_cache_slabs:%s)\n", $2));
1574		if(atoi($2) == 0) {
1575			yyerror("number expected");
1576		} else {
1577			cfg_parser->cfg->msg_cache_slabs = atoi($2);
1578			if(!is_pow2(cfg_parser->cfg->msg_cache_slabs))
1579				yyerror("must be a power of 2");
1580		}
1581		free($2);
1582	}
1583	;
1584server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG
1585	{
1586		OUTYY(("P(server_num_queries_per_thread:%s)\n", $2));
1587		if(atoi($2) == 0)
1588			yyerror("number expected");
1589		else cfg_parser->cfg->num_queries_per_thread = atoi($2);
1590		free($2);
1591	}
1592	;
1593server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG
1594	{
1595		OUTYY(("P(server_jostle_timeout:%s)\n", $2));
1596		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1597			yyerror("number expected");
1598		else cfg_parser->cfg->jostle_time = atoi($2);
1599		free($2);
1600	}
1601	;
1602server_delay_close: VAR_DELAY_CLOSE STRING_ARG
1603	{
1604		OUTYY(("P(server_delay_close:%s)\n", $2));
1605		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1606			yyerror("number expected");
1607		else cfg_parser->cfg->delay_close = atoi($2);
1608		free($2);
1609	}
1610	;
1611server_udp_connect: VAR_UDP_CONNECT STRING_ARG
1612	{
1613		OUTYY(("P(server_udp_connect:%s)\n", $2));
1614		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1615			yyerror("expected yes or no.");
1616		else cfg_parser->cfg->udp_connect = (strcmp($2, "yes")==0);
1617		free($2);
1618	}
1619	;
1620server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG
1621	{
1622		OUTYY(("P(server_unblock_lan_zones:%s)\n", $2));
1623		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1624			yyerror("expected yes or no.");
1625		else cfg_parser->cfg->unblock_lan_zones =
1626			(strcmp($2, "yes")==0);
1627		free($2);
1628	}
1629	;
1630server_insecure_lan_zones: VAR_INSECURE_LAN_ZONES STRING_ARG
1631	{
1632		OUTYY(("P(server_insecure_lan_zones:%s)\n", $2));
1633		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1634			yyerror("expected yes or no.");
1635		else cfg_parser->cfg->insecure_lan_zones =
1636			(strcmp($2, "yes")==0);
1637		free($2);
1638	}
1639	;
1640server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG
1641	{
1642		OUTYY(("P(server_rrset_cache_size:%s)\n", $2));
1643		if(!cfg_parse_memsize($2, &cfg_parser->cfg->rrset_cache_size))
1644			yyerror("memory size expected");
1645		free($2);
1646	}
1647	;
1648server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG
1649	{
1650		OUTYY(("P(server_rrset_cache_slabs:%s)\n", $2));
1651		if(atoi($2) == 0) {
1652			yyerror("number expected");
1653		} else {
1654			cfg_parser->cfg->rrset_cache_slabs = atoi($2);
1655			if(!is_pow2(cfg_parser->cfg->rrset_cache_slabs))
1656				yyerror("must be a power of 2");
1657		}
1658		free($2);
1659	}
1660	;
1661server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG
1662	{
1663		OUTYY(("P(server_infra_host_ttl:%s)\n", $2));
1664		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1665			yyerror("number expected");
1666		else cfg_parser->cfg->host_ttl = atoi($2);
1667		free($2);
1668	}
1669	;
1670server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG
1671	{
1672		OUTYY(("P(server_infra_lame_ttl:%s)\n", $2));
1673		verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option "
1674			"removed, use infra-host-ttl)", $2);
1675		free($2);
1676	}
1677	;
1678server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG
1679	{
1680		OUTYY(("P(server_infra_cache_numhosts:%s)\n", $2));
1681		if(atoi($2) == 0)
1682			yyerror("number expected");
1683		else cfg_parser->cfg->infra_cache_numhosts = atoi($2);
1684		free($2);
1685	}
1686	;
1687server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG
1688	{
1689		OUTYY(("P(server_infra_cache_lame_size:%s)\n", $2));
1690		verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s "
1691			"(option removed, use infra-cache-numhosts)", $2);
1692		free($2);
1693	}
1694	;
1695server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG
1696	{
1697		OUTYY(("P(server_infra_cache_slabs:%s)\n", $2));
1698		if(atoi($2) == 0) {
1699			yyerror("number expected");
1700		} else {
1701			cfg_parser->cfg->infra_cache_slabs = atoi($2);
1702			if(!is_pow2(cfg_parser->cfg->infra_cache_slabs))
1703				yyerror("must be a power of 2");
1704		}
1705		free($2);
1706	}
1707	;
1708server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG
1709	{
1710		OUTYY(("P(server_infra_cache_min_rtt:%s)\n", $2));
1711		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1712			yyerror("number expected");
1713		else cfg_parser->cfg->infra_cache_min_rtt = atoi($2);
1714		free($2);
1715	}
1716	;
1717server_infra_cache_max_rtt: VAR_INFRA_CACHE_MAX_RTT STRING_ARG
1718	{
1719		OUTYY(("P(server_infra_cache_max_rtt:%s)\n", $2));
1720		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1721			yyerror("number expected");
1722		else cfg_parser->cfg->infra_cache_max_rtt = atoi($2);
1723		free($2);
1724	}
1725	;
1726server_infra_keep_probing: VAR_INFRA_KEEP_PROBING STRING_ARG
1727	{
1728		OUTYY(("P(server_infra_keep_probing:%s)\n", $2));
1729		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1730			yyerror("expected yes or no.");
1731		else cfg_parser->cfg->infra_keep_probing =
1732			(strcmp($2, "yes")==0);
1733		free($2);
1734	}
1735	;
1736server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
1737	{
1738		OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
1739		free(cfg_parser->cfg->target_fetch_policy);
1740		cfg_parser->cfg->target_fetch_policy = $2;
1741	}
1742	;
1743server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG
1744	{
1745		OUTYY(("P(server_harden_short_bufsize:%s)\n", $2));
1746		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1747			yyerror("expected yes or no.");
1748		else cfg_parser->cfg->harden_short_bufsize =
1749			(strcmp($2, "yes")==0);
1750		free($2);
1751	}
1752	;
1753server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG
1754	{
1755		OUTYY(("P(server_harden_large_queries:%s)\n", $2));
1756		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1757			yyerror("expected yes or no.");
1758		else cfg_parser->cfg->harden_large_queries =
1759			(strcmp($2, "yes")==0);
1760		free($2);
1761	}
1762	;
1763server_harden_glue: VAR_HARDEN_GLUE STRING_ARG
1764	{
1765		OUTYY(("P(server_harden_glue:%s)\n", $2));
1766		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1767			yyerror("expected yes or no.");
1768		else cfg_parser->cfg->harden_glue =
1769			(strcmp($2, "yes")==0);
1770		free($2);
1771	}
1772	;
1773server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG
1774	{
1775		OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2));
1776		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1777			yyerror("expected yes or no.");
1778		else cfg_parser->cfg->harden_dnssec_stripped =
1779			(strcmp($2, "yes")==0);
1780		free($2);
1781	}
1782	;
1783server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG
1784	{
1785		OUTYY(("P(server_harden_below_nxdomain:%s)\n", $2));
1786		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1787			yyerror("expected yes or no.");
1788		else cfg_parser->cfg->harden_below_nxdomain =
1789			(strcmp($2, "yes")==0);
1790		free($2);
1791	}
1792	;
1793server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG
1794	{
1795		OUTYY(("P(server_harden_referral_path:%s)\n", $2));
1796		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1797			yyerror("expected yes or no.");
1798		else cfg_parser->cfg->harden_referral_path =
1799			(strcmp($2, "yes")==0);
1800		free($2);
1801	}
1802	;
1803server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG
1804	{
1805		OUTYY(("P(server_harden_algo_downgrade:%s)\n", $2));
1806		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1807			yyerror("expected yes or no.");
1808		else cfg_parser->cfg->harden_algo_downgrade =
1809			(strcmp($2, "yes")==0);
1810		free($2);
1811	}
1812	;
1813server_harden_unknown_additional: VAR_HARDEN_UNKNOWN_ADDITIONAL STRING_ARG
1814	{
1815		OUTYY(("P(server_harden_unknown_additional:%s)\n", $2));
1816		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1817			yyerror("expected yes or no.");
1818		else cfg_parser->cfg->harden_unknown_additional =
1819			(strcmp($2, "yes")==0);
1820		free($2);
1821	}
1822	;
1823server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG
1824	{
1825		OUTYY(("P(server_use_caps_for_id:%s)\n", $2));
1826		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1827			yyerror("expected yes or no.");
1828		else cfg_parser->cfg->use_caps_bits_for_id =
1829			(strcmp($2, "yes")==0);
1830		free($2);
1831	}
1832	;
1833server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
1834	{
1835		OUTYY(("P(server_caps_whitelist:%s)\n", $2));
1836		if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
1837			yyerror("out of memory");
1838	}
1839	;
1840server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
1841	{
1842		OUTYY(("P(server_private_address:%s)\n", $2));
1843		if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, $2))
1844			yyerror("out of memory");
1845	}
1846	;
1847server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG
1848	{
1849		OUTYY(("P(server_private_domain:%s)\n", $2));
1850		if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, $2))
1851			yyerror("out of memory");
1852	}
1853	;
1854server_prefetch: VAR_PREFETCH STRING_ARG
1855	{
1856		OUTYY(("P(server_prefetch:%s)\n", $2));
1857		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1858			yyerror("expected yes or no.");
1859		else cfg_parser->cfg->prefetch = (strcmp($2, "yes")==0);
1860		free($2);
1861	}
1862	;
1863server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG
1864	{
1865		OUTYY(("P(server_prefetch_key:%s)\n", $2));
1866		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1867			yyerror("expected yes or no.");
1868		else cfg_parser->cfg->prefetch_key = (strcmp($2, "yes")==0);
1869		free($2);
1870	}
1871	;
1872server_deny_any: VAR_DENY_ANY STRING_ARG
1873	{
1874		OUTYY(("P(server_deny_any:%s)\n", $2));
1875		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1876			yyerror("expected yes or no.");
1877		else cfg_parser->cfg->deny_any = (strcmp($2, "yes")==0);
1878		free($2);
1879	}
1880	;
1881server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
1882	{
1883		OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
1884		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1885			yyerror("number expected");
1886		else cfg_parser->cfg->unwanted_threshold = atoi($2);
1887		free($2);
1888	}
1889	;
1890server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG
1891	{
1892		OUTYY(("P(server_do_not_query_address:%s)\n", $2));
1893		if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, $2))
1894			yyerror("out of memory");
1895	}
1896	;
1897server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG
1898	{
1899		OUTYY(("P(server_do_not_query_localhost:%s)\n", $2));
1900		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
1901			yyerror("expected yes or no.");
1902		else cfg_parser->cfg->donotquery_localhost =
1903			(strcmp($2, "yes")==0);
1904		free($2);
1905	}
1906	;
1907server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG
1908	{
1909		OUTYY(("P(server_access_control:%s %s)\n", $2, $3));
1910		validate_acl_action($3);
1911		if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
1912			fatal_exit("out of memory adding acl");
1913	}
1914	;
1915server_interface_action: VAR_INTERFACE_ACTION STRING_ARG STRING_ARG
1916	{
1917		OUTYY(("P(server_interface_action:%s %s)\n", $2, $3));
1918		validate_acl_action($3);
1919		if(!cfg_str2list_insert(
1920			&cfg_parser->cfg->interface_actions, $2, $3))
1921			fatal_exit("out of memory adding acl");
1922	}
1923	;
1924server_module_conf: VAR_MODULE_CONF STRING_ARG
1925	{
1926		OUTYY(("P(server_module_conf:%s)\n", $2));
1927		free(cfg_parser->cfg->module_conf);
1928		cfg_parser->cfg->module_conf = $2;
1929	}
1930	;
1931server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG
1932	{
1933		OUTYY(("P(server_val_override_date:%s)\n", $2));
1934		if(*$2 == '\0' || strcmp($2, "0") == 0) {
1935			cfg_parser->cfg->val_date_override = 0;
1936		} else if(strlen($2) == 14) {
1937			cfg_parser->cfg->val_date_override =
1938				cfg_convert_timeval($2);
1939			if(!cfg_parser->cfg->val_date_override)
1940				yyerror("bad date/time specification");
1941		} else {
1942			if(atoi($2) == 0)
1943				yyerror("number expected");
1944			cfg_parser->cfg->val_date_override = atoi($2);
1945		}
1946		free($2);
1947	}
1948	;
1949server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG
1950	{
1951		OUTYY(("P(server_val_sig_skew_min:%s)\n", $2));
1952		if(*$2 == '\0' || strcmp($2, "0") == 0) {
1953			cfg_parser->cfg->val_sig_skew_min = 0;
1954		} else {
1955			cfg_parser->cfg->val_sig_skew_min = atoi($2);
1956			if(!cfg_parser->cfg->val_sig_skew_min)
1957				yyerror("number expected");
1958		}
1959		free($2);
1960	}
1961	;
1962server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG
1963	{
1964		OUTYY(("P(server_val_sig_skew_max:%s)\n", $2));
1965		if(*$2 == '\0' || strcmp($2, "0") == 0) {
1966			cfg_parser->cfg->val_sig_skew_max = 0;
1967		} else {
1968			cfg_parser->cfg->val_sig_skew_max = atoi($2);
1969			if(!cfg_parser->cfg->val_sig_skew_max)
1970				yyerror("number expected");
1971		}
1972		free($2);
1973	}
1974	;
1975server_val_max_restart: VAR_VAL_MAX_RESTART STRING_ARG
1976	{
1977		OUTYY(("P(server_val_max_restart:%s)\n", $2));
1978		if(*$2 == '\0' || strcmp($2, "0") == 0) {
1979			cfg_parser->cfg->val_max_restart = 0;
1980		} else {
1981			cfg_parser->cfg->val_max_restart = atoi($2);
1982			if(!cfg_parser->cfg->val_max_restart)
1983				yyerror("number expected");
1984		}
1985		free($2);
1986	}
1987	;
1988server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG
1989	{
1990		OUTYY(("P(server_cache_max_ttl:%s)\n", $2));
1991		if(atoi($2) == 0 && strcmp($2, "0") != 0)
1992			yyerror("number expected");
1993		else cfg_parser->cfg->max_ttl = atoi($2);
1994		free($2);
1995	}
1996	;
1997server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG
1998	{
1999		OUTYY(("P(server_cache_max_negative_ttl:%s)\n", $2));
2000		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2001			yyerror("number expected");
2002		else cfg_parser->cfg->max_negative_ttl = atoi($2);
2003		free($2);
2004	}
2005	;
2006server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG
2007	{
2008		OUTYY(("P(server_cache_min_ttl:%s)\n", $2));
2009		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2010			yyerror("number expected");
2011		else cfg_parser->cfg->min_ttl = atoi($2);
2012		free($2);
2013	}
2014	;
2015server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG
2016	{
2017		OUTYY(("P(server_bogus_ttl:%s)\n", $2));
2018		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2019			yyerror("number expected");
2020		else cfg_parser->cfg->bogus_ttl = atoi($2);
2021		free($2);
2022	}
2023	;
2024server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG
2025	{
2026		OUTYY(("P(server_val_clean_additional:%s)\n", $2));
2027		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2028			yyerror("expected yes or no.");
2029		else cfg_parser->cfg->val_clean_additional =
2030			(strcmp($2, "yes")==0);
2031		free($2);
2032	}
2033	;
2034server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG
2035	{
2036		OUTYY(("P(server_val_permissive_mode:%s)\n", $2));
2037		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2038			yyerror("expected yes or no.");
2039		else cfg_parser->cfg->val_permissive_mode =
2040			(strcmp($2, "yes")==0);
2041		free($2);
2042	}
2043	;
2044server_aggressive_nsec: VAR_AGGRESSIVE_NSEC STRING_ARG
2045	{
2046		OUTYY(("P(server_aggressive_nsec:%s)\n", $2));
2047		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2048			yyerror("expected yes or no.");
2049		else
2050			cfg_parser->cfg->aggressive_nsec =
2051				(strcmp($2, "yes")==0);
2052		free($2);
2053	}
2054	;
2055server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG
2056	{
2057		OUTYY(("P(server_ignore_cd_flag:%s)\n", $2));
2058		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2059			yyerror("expected yes or no.");
2060		else cfg_parser->cfg->ignore_cd = (strcmp($2, "yes")==0);
2061		free($2);
2062	}
2063	;
2064server_disable_edns_do: VAR_DISABLE_EDNS_DO STRING_ARG
2065	{
2066		OUTYY(("P(server_disable_edns_do:%s)\n", $2));
2067		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2068			yyerror("expected yes or no.");
2069		else cfg_parser->cfg->disable_edns_do = (strcmp($2, "yes")==0);
2070		free($2);
2071	}
2072	;
2073server_serve_expired: VAR_SERVE_EXPIRED STRING_ARG
2074	{
2075		OUTYY(("P(server_serve_expired:%s)\n", $2));
2076		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2077			yyerror("expected yes or no.");
2078		else cfg_parser->cfg->serve_expired = (strcmp($2, "yes")==0);
2079		free($2);
2080	}
2081	;
2082server_serve_expired_ttl: VAR_SERVE_EXPIRED_TTL STRING_ARG
2083	{
2084		OUTYY(("P(server_serve_expired_ttl:%s)\n", $2));
2085		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2086			yyerror("number expected");
2087		else cfg_parser->cfg->serve_expired_ttl = atoi($2);
2088		free($2);
2089	}
2090	;
2091server_serve_expired_ttl_reset: VAR_SERVE_EXPIRED_TTL_RESET STRING_ARG
2092	{
2093		OUTYY(("P(server_serve_expired_ttl_reset:%s)\n", $2));
2094		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2095			yyerror("expected yes or no.");
2096		else cfg_parser->cfg->serve_expired_ttl_reset = (strcmp($2, "yes")==0);
2097		free($2);
2098	}
2099	;
2100server_serve_expired_reply_ttl: VAR_SERVE_EXPIRED_REPLY_TTL STRING_ARG
2101	{
2102		OUTYY(("P(server_serve_expired_reply_ttl:%s)\n", $2));
2103		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2104			yyerror("number expected");
2105		else cfg_parser->cfg->serve_expired_reply_ttl = atoi($2);
2106		free($2);
2107	}
2108	;
2109server_serve_expired_client_timeout: VAR_SERVE_EXPIRED_CLIENT_TIMEOUT STRING_ARG
2110	{
2111		OUTYY(("P(server_serve_expired_client_timeout:%s)\n", $2));
2112		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2113			yyerror("number expected");
2114		else cfg_parser->cfg->serve_expired_client_timeout = atoi($2);
2115		free($2);
2116	}
2117	;
2118server_ede_serve_expired: VAR_EDE_SERVE_EXPIRED STRING_ARG
2119	{
2120		OUTYY(("P(server_ede_serve_expired:%s)\n", $2));
2121		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2122			yyerror("expected yes or no.");
2123		else cfg_parser->cfg->ede_serve_expired = (strcmp($2, "yes")==0);
2124		free($2);
2125	}
2126	;
2127server_serve_original_ttl: VAR_SERVE_ORIGINAL_TTL STRING_ARG
2128	{
2129		OUTYY(("P(server_serve_original_ttl:%s)\n", $2));
2130		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2131			yyerror("expected yes or no.");
2132		else cfg_parser->cfg->serve_original_ttl = (strcmp($2, "yes")==0);
2133		free($2);
2134	}
2135	;
2136server_fake_dsa: VAR_FAKE_DSA STRING_ARG
2137	{
2138		OUTYY(("P(server_fake_dsa:%s)\n", $2));
2139		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2140			yyerror("expected yes or no.");
2141#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
2142		else fake_dsa = (strcmp($2, "yes")==0);
2143		if(fake_dsa)
2144			log_warn("test option fake_dsa is enabled");
2145#endif
2146		free($2);
2147	}
2148	;
2149server_fake_sha1: VAR_FAKE_SHA1 STRING_ARG
2150	{
2151		OUTYY(("P(server_fake_sha1:%s)\n", $2));
2152		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2153			yyerror("expected yes or no.");
2154#if defined(HAVE_SSL) || defined(HAVE_NETTLE)
2155		else fake_sha1 = (strcmp($2, "yes")==0);
2156		if(fake_sha1)
2157			log_warn("test option fake_sha1 is enabled");
2158#endif
2159		free($2);
2160	}
2161	;
2162server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG
2163	{
2164		OUTYY(("P(server_val_log_level:%s)\n", $2));
2165		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2166			yyerror("number expected");
2167		else cfg_parser->cfg->val_log_level = atoi($2);
2168		free($2);
2169	}
2170	;
2171server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG
2172	{
2173		OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", $2));
2174		free(cfg_parser->cfg->val_nsec3_key_iterations);
2175		cfg_parser->cfg->val_nsec3_key_iterations = $2;
2176	}
2177	;
2178server_zonemd_permissive_mode: VAR_ZONEMD_PERMISSIVE_MODE STRING_ARG
2179	{
2180		OUTYY(("P(server_zonemd_permissive_mode:%s)\n", $2));
2181		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2182			yyerror("expected yes or no.");
2183		else	cfg_parser->cfg->zonemd_permissive_mode = (strcmp($2, "yes")==0);
2184		free($2);
2185	}
2186	;
2187server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG
2188	{
2189		OUTYY(("P(server_add_holddown:%s)\n", $2));
2190		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2191			yyerror("number expected");
2192		else cfg_parser->cfg->add_holddown = atoi($2);
2193		free($2);
2194	}
2195	;
2196server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG
2197	{
2198		OUTYY(("P(server_del_holddown:%s)\n", $2));
2199		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2200			yyerror("number expected");
2201		else cfg_parser->cfg->del_holddown = atoi($2);
2202		free($2);
2203	}
2204	;
2205server_keep_missing: VAR_KEEP_MISSING STRING_ARG
2206	{
2207		OUTYY(("P(server_keep_missing:%s)\n", $2));
2208		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2209			yyerror("number expected");
2210		else cfg_parser->cfg->keep_missing = atoi($2);
2211		free($2);
2212	}
2213	;
2214server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG
2215	{
2216		OUTYY(("P(server_permit_small_holddown:%s)\n", $2));
2217		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2218			yyerror("expected yes or no.");
2219		else cfg_parser->cfg->permit_small_holddown =
2220			(strcmp($2, "yes")==0);
2221		free($2);
2222	}
2223	;
2224server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG
2225	{
2226		OUTYY(("P(server_key_cache_size:%s)\n", $2));
2227		if(!cfg_parse_memsize($2, &cfg_parser->cfg->key_cache_size))
2228			yyerror("memory size expected");
2229		free($2);
2230	}
2231	;
2232server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG
2233	{
2234		OUTYY(("P(server_key_cache_slabs:%s)\n", $2));
2235		if(atoi($2) == 0) {
2236			yyerror("number expected");
2237		} else {
2238			cfg_parser->cfg->key_cache_slabs = atoi($2);
2239			if(!is_pow2(cfg_parser->cfg->key_cache_slabs))
2240				yyerror("must be a power of 2");
2241		}
2242		free($2);
2243	}
2244	;
2245server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG
2246	{
2247		OUTYY(("P(server_neg_cache_size:%s)\n", $2));
2248		if(!cfg_parse_memsize($2, &cfg_parser->cfg->neg_cache_size))
2249			yyerror("memory size expected");
2250		free($2);
2251	}
2252	;
2253server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
2254	{
2255		OUTYY(("P(server_local_zone:%s %s)\n", $2, $3));
2256		if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
2257		   strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
2258		   strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
2259		   && strcmp($3, "typetransparent")!=0
2260		   && strcmp($3, "always_transparent")!=0
2261		   && strcmp($3, "block_a")!=0
2262		   && strcmp($3, "always_refuse")!=0
2263		   && strcmp($3, "always_nxdomain")!=0
2264		   && strcmp($3, "always_nodata")!=0
2265		   && strcmp($3, "always_deny")!=0
2266		   && strcmp($3, "always_null")!=0
2267		   && strcmp($3, "noview")!=0
2268		   && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
2269		   && strcmp($3, "inform_redirect") != 0
2270		   && strcmp($3, "ipset") != 0) {
2271			yyerror("local-zone type: expected static, deny, "
2272				"refuse, redirect, transparent, "
2273				"typetransparent, inform, inform_deny, "
2274				"inform_redirect, always_transparent, block_a,"
2275				"always_refuse, always_nxdomain, "
2276				"always_nodata, always_deny, always_null, "
2277				"noview, nodefault or ipset");
2278			free($2);
2279			free($3);
2280		} else if(strcmp($3, "nodefault")==0) {
2281			if(!cfg_strlist_insert(&cfg_parser->cfg->
2282				local_zones_nodefault, $2))
2283				fatal_exit("out of memory adding local-zone");
2284			free($3);
2285#ifdef USE_IPSET
2286		} else if(strcmp($3, "ipset")==0) {
2287			size_t len = strlen($2);
2288			/* Make sure to add the trailing dot.
2289			 * These are str compared to domain names. */
2290			if($2[len-1] != '.') {
2291				if(!($2 = realloc($2, len+2))) {
2292					fatal_exit("out of memory adding local-zone");
2293				}
2294				$2[len] = '.';
2295				$2[len+1] = 0;
2296			}
2297			if(!cfg_strlist_insert(&cfg_parser->cfg->
2298				local_zones_ipset, $2))
2299				fatal_exit("out of memory adding local-zone");
2300			free($3);
2301#endif
2302		} else {
2303			if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones,
2304				$2, $3))
2305				fatal_exit("out of memory adding local-zone");
2306		}
2307	}
2308	;
2309server_local_data: VAR_LOCAL_DATA STRING_ARG
2310	{
2311		OUTYY(("P(server_local_data:%s)\n", $2));
2312		if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2))
2313			fatal_exit("out of memory adding local-data");
2314	}
2315	;
2316server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
2317	{
2318		char* ptr;
2319		OUTYY(("P(server_local_data_ptr:%s)\n", $2));
2320		ptr = cfg_ptr_reverse($2);
2321		free($2);
2322		if(ptr) {
2323			if(!cfg_strlist_insert(&cfg_parser->cfg->
2324				local_data, ptr))
2325				fatal_exit("out of memory adding local-data");
2326		} else {
2327			yyerror("local-data-ptr could not be reversed");
2328		}
2329	}
2330	;
2331server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG
2332	{
2333		OUTYY(("P(server_minimal_responses:%s)\n", $2));
2334		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2335			yyerror("expected yes or no.");
2336		else cfg_parser->cfg->minimal_responses =
2337			(strcmp($2, "yes")==0);
2338		free($2);
2339	}
2340	;
2341server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG
2342	{
2343		OUTYY(("P(server_rrset_roundrobin:%s)\n", $2));
2344		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2345			yyerror("expected yes or no.");
2346		else cfg_parser->cfg->rrset_roundrobin =
2347			(strcmp($2, "yes")==0);
2348		free($2);
2349	}
2350	;
2351server_unknown_server_time_limit: VAR_UNKNOWN_SERVER_TIME_LIMIT STRING_ARG
2352	{
2353		OUTYY(("P(server_unknown_server_time_limit:%s)\n", $2));
2354		cfg_parser->cfg->unknown_server_time_limit = atoi($2);
2355		free($2);
2356	}
2357	;
2358server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG
2359	{
2360		OUTYY(("P(server_max_udp_size:%s)\n", $2));
2361		cfg_parser->cfg->max_udp_size = atoi($2);
2362		free($2);
2363	}
2364	;
2365server_dns64_prefix: VAR_DNS64_PREFIX STRING_ARG
2366	{
2367		OUTYY(("P(dns64_prefix:%s)\n", $2));
2368		free(cfg_parser->cfg->dns64_prefix);
2369		cfg_parser->cfg->dns64_prefix = $2;
2370	}
2371	;
2372server_dns64_synthall: VAR_DNS64_SYNTHALL STRING_ARG
2373	{
2374		OUTYY(("P(server_dns64_synthall:%s)\n", $2));
2375		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2376			yyerror("expected yes or no.");
2377		else cfg_parser->cfg->dns64_synthall = (strcmp($2, "yes")==0);
2378		free($2);
2379	}
2380	;
2381server_dns64_ignore_aaaa: VAR_DNS64_IGNORE_AAAA STRING_ARG
2382	{
2383		OUTYY(("P(dns64_ignore_aaaa:%s)\n", $2));
2384		if(!cfg_strlist_insert(&cfg_parser->cfg->dns64_ignore_aaaa,
2385			$2))
2386			fatal_exit("out of memory adding dns64-ignore-aaaa");
2387	}
2388	;
2389server_nat64_prefix: VAR_NAT64_PREFIX STRING_ARG
2390	{
2391		OUTYY(("P(nat64_prefix:%s)\n", $2));
2392		free(cfg_parser->cfg->nat64_prefix);
2393		cfg_parser->cfg->nat64_prefix = $2;
2394	}
2395	;
2396server_define_tag: VAR_DEFINE_TAG STRING_ARG
2397	{
2398		char* p, *s = $2;
2399		OUTYY(("P(server_define_tag:%s)\n", $2));
2400		while((p=strsep(&s, " \t\n")) != NULL) {
2401			if(*p) {
2402				if(!config_add_tag(cfg_parser->cfg, p))
2403					yyerror("could not define-tag, "
2404						"out of memory");
2405			}
2406		}
2407		free($2);
2408	}
2409	;
2410server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG
2411	{
2412		size_t len = 0;
2413		uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
2414			&len);
2415		free($3);
2416		OUTYY(("P(server_local_zone_tag:%s)\n", $2));
2417		if(!bitlist) {
2418			yyerror("could not parse tags, (define-tag them first)");
2419			free($2);
2420		}
2421		if(bitlist) {
2422			if(!cfg_strbytelist_insert(
2423				&cfg_parser->cfg->local_zone_tags,
2424				$2, bitlist, len)) {
2425				yyerror("out of memory");
2426				free($2);
2427			}
2428		}
2429	}
2430	;
2431server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG
2432	{
2433		size_t len = 0;
2434		uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
2435			&len);
2436		free($3);
2437		OUTYY(("P(server_access_control_tag:%s)\n", $2));
2438		if(!bitlist) {
2439			yyerror("could not parse tags, (define-tag them first)");
2440			free($2);
2441		}
2442		if(bitlist) {
2443			if(!cfg_strbytelist_insert(
2444				&cfg_parser->cfg->acl_tags,
2445				$2, bitlist, len)) {
2446				yyerror("out of memory");
2447				free($2);
2448			}
2449		}
2450	}
2451	;
2452server_access_control_tag_action: VAR_ACCESS_CONTROL_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG
2453	{
2454		OUTYY(("P(server_access_control_tag_action:%s %s %s)\n", $2, $3, $4));
2455		if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_actions,
2456			$2, $3, $4)) {
2457			yyerror("out of memory");
2458			free($2);
2459			free($3);
2460			free($4);
2461		}
2462	}
2463	;
2464server_access_control_tag_data: VAR_ACCESS_CONTROL_TAG_DATA STRING_ARG STRING_ARG STRING_ARG
2465	{
2466		OUTYY(("P(server_access_control_tag_data:%s %s %s)\n", $2, $3, $4));
2467		if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_datas,
2468			$2, $3, $4)) {
2469			yyerror("out of memory");
2470			free($2);
2471			free($3);
2472			free($4);
2473		}
2474	}
2475	;
2476server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING_ARG
2477	{
2478		OUTYY(("P(server_local_zone_override:%s %s %s)\n", $2, $3, $4));
2479		if(!cfg_str3list_insert(&cfg_parser->cfg->local_zone_overrides,
2480			$2, $3, $4)) {
2481			yyerror("out of memory");
2482			free($2);
2483			free($3);
2484			free($4);
2485		}
2486	}
2487	;
2488server_access_control_view: VAR_ACCESS_CONTROL_VIEW STRING_ARG STRING_ARG
2489	{
2490		OUTYY(("P(server_access_control_view:%s %s)\n", $2, $3));
2491		if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view,
2492			$2, $3)) {
2493			yyerror("out of memory");
2494		}
2495	}
2496	;
2497server_interface_tag: VAR_INTERFACE_TAG STRING_ARG STRING_ARG
2498	{
2499		size_t len = 0;
2500		uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
2501			&len);
2502		free($3);
2503		OUTYY(("P(server_interface_tag:%s)\n", $2));
2504		if(!bitlist) {
2505			yyerror("could not parse tags, (define-tag them first)");
2506			free($2);
2507		}
2508		if(bitlist) {
2509			if(!cfg_strbytelist_insert(
2510				&cfg_parser->cfg->interface_tags,
2511				$2, bitlist, len)) {
2512				yyerror("out of memory");
2513				free($2);
2514			}
2515		}
2516	}
2517	;
2518server_interface_tag_action: VAR_INTERFACE_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG
2519	{
2520		OUTYY(("P(server_interface_tag_action:%s %s %s)\n", $2, $3, $4));
2521		if(!cfg_str3list_insert(&cfg_parser->cfg->interface_tag_actions,
2522			$2, $3, $4)) {
2523			yyerror("out of memory");
2524			free($2);
2525			free($3);
2526			free($4);
2527		}
2528	}
2529	;
2530server_interface_tag_data: VAR_INTERFACE_TAG_DATA STRING_ARG STRING_ARG STRING_ARG
2531	{
2532		OUTYY(("P(server_interface_tag_data:%s %s %s)\n", $2, $3, $4));
2533		if(!cfg_str3list_insert(&cfg_parser->cfg->interface_tag_datas,
2534			$2, $3, $4)) {
2535			yyerror("out of memory");
2536			free($2);
2537			free($3);
2538			free($4);
2539		}
2540	}
2541	;
2542server_interface_view: VAR_INTERFACE_VIEW STRING_ARG STRING_ARG
2543	{
2544		OUTYY(("P(server_interface_view:%s %s)\n", $2, $3));
2545		if(!cfg_str2list_insert(&cfg_parser->cfg->interface_view,
2546			$2, $3)) {
2547			yyerror("out of memory");
2548		}
2549	}
2550	;
2551server_response_ip_tag: VAR_RESPONSE_IP_TAG STRING_ARG STRING_ARG
2552	{
2553		size_t len = 0;
2554		uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, $3,
2555			&len);
2556		free($3);
2557		OUTYY(("P(response_ip_tag:%s)\n", $2));
2558		if(!bitlist) {
2559			yyerror("could not parse tags, (define-tag them first)");
2560			free($2);
2561		}
2562		if(bitlist) {
2563			if(!cfg_strbytelist_insert(
2564				&cfg_parser->cfg->respip_tags,
2565				$2, bitlist, len)) {
2566				yyerror("out of memory");
2567				free($2);
2568			}
2569		}
2570	}
2571	;
2572server_ip_ratelimit: VAR_IP_RATELIMIT STRING_ARG
2573	{
2574		OUTYY(("P(server_ip_ratelimit:%s)\n", $2));
2575		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2576			yyerror("number expected");
2577		else cfg_parser->cfg->ip_ratelimit = atoi($2);
2578		free($2);
2579	}
2580	;
2581server_ip_ratelimit_cookie: VAR_IP_RATELIMIT_COOKIE STRING_ARG
2582	{
2583		OUTYY(("P(server_ip_ratelimit_cookie:%s)\n", $2));
2584		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2585			yyerror("number expected");
2586		else cfg_parser->cfg->ip_ratelimit_cookie = atoi($2);
2587		free($2);
2588	}
2589	;
2590server_ratelimit: VAR_RATELIMIT STRING_ARG
2591	{
2592		OUTYY(("P(server_ratelimit:%s)\n", $2));
2593		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2594			yyerror("number expected");
2595		else cfg_parser->cfg->ratelimit = atoi($2);
2596		free($2);
2597	}
2598	;
2599server_ip_ratelimit_size: VAR_IP_RATELIMIT_SIZE STRING_ARG
2600	{
2601		OUTYY(("P(server_ip_ratelimit_size:%s)\n", $2));
2602		if(!cfg_parse_memsize($2, &cfg_parser->cfg->ip_ratelimit_size))
2603			yyerror("memory size expected");
2604		free($2);
2605	}
2606	;
2607server_ratelimit_size: VAR_RATELIMIT_SIZE STRING_ARG
2608	{
2609		OUTYY(("P(server_ratelimit_size:%s)\n", $2));
2610		if(!cfg_parse_memsize($2, &cfg_parser->cfg->ratelimit_size))
2611			yyerror("memory size expected");
2612		free($2);
2613	}
2614	;
2615server_ip_ratelimit_slabs: VAR_IP_RATELIMIT_SLABS STRING_ARG
2616	{
2617		OUTYY(("P(server_ip_ratelimit_slabs:%s)\n", $2));
2618		if(atoi($2) == 0) {
2619			yyerror("number expected");
2620		} else {
2621			cfg_parser->cfg->ip_ratelimit_slabs = atoi($2);
2622			if(!is_pow2(cfg_parser->cfg->ip_ratelimit_slabs))
2623				yyerror("must be a power of 2");
2624		}
2625		free($2);
2626	}
2627	;
2628server_ratelimit_slabs: VAR_RATELIMIT_SLABS STRING_ARG
2629	{
2630		OUTYY(("P(server_ratelimit_slabs:%s)\n", $2));
2631		if(atoi($2) == 0) {
2632			yyerror("number expected");
2633		} else {
2634			cfg_parser->cfg->ratelimit_slabs = atoi($2);
2635			if(!is_pow2(cfg_parser->cfg->ratelimit_slabs))
2636				yyerror("must be a power of 2");
2637		}
2638		free($2);
2639	}
2640	;
2641server_ratelimit_for_domain: VAR_RATELIMIT_FOR_DOMAIN STRING_ARG STRING_ARG
2642	{
2643		OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", $2, $3));
2644		if(atoi($3) == 0 && strcmp($3, "0") != 0) {
2645			yyerror("number expected");
2646			free($2);
2647			free($3);
2648		} else {
2649			if(!cfg_str2list_insert(&cfg_parser->cfg->
2650				ratelimit_for_domain, $2, $3))
2651				fatal_exit("out of memory adding "
2652					"ratelimit-for-domain");
2653		}
2654	}
2655	;
2656server_ratelimit_below_domain: VAR_RATELIMIT_BELOW_DOMAIN STRING_ARG STRING_ARG
2657	{
2658		OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", $2, $3));
2659		if(atoi($3) == 0 && strcmp($3, "0") != 0) {
2660			yyerror("number expected");
2661			free($2);
2662			free($3);
2663		} else {
2664			if(!cfg_str2list_insert(&cfg_parser->cfg->
2665				ratelimit_below_domain, $2, $3))
2666				fatal_exit("out of memory adding "
2667					"ratelimit-below-domain");
2668		}
2669	}
2670	;
2671server_ip_ratelimit_factor: VAR_IP_RATELIMIT_FACTOR STRING_ARG
2672	{
2673		OUTYY(("P(server_ip_ratelimit_factor:%s)\n", $2));
2674		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2675			yyerror("number expected");
2676		else cfg_parser->cfg->ip_ratelimit_factor = atoi($2);
2677		free($2);
2678	}
2679	;
2680server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG
2681	{
2682		OUTYY(("P(server_ratelimit_factor:%s)\n", $2));
2683		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2684			yyerror("number expected");
2685		else cfg_parser->cfg->ratelimit_factor = atoi($2);
2686		free($2);
2687	}
2688	;
2689server_ip_ratelimit_backoff: VAR_IP_RATELIMIT_BACKOFF STRING_ARG
2690	{
2691		OUTYY(("P(server_ip_ratelimit_backoff:%s)\n", $2));
2692		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2693			yyerror("expected yes or no.");
2694		else cfg_parser->cfg->ip_ratelimit_backoff =
2695			(strcmp($2, "yes")==0);
2696		free($2);
2697	}
2698	;
2699server_ratelimit_backoff: VAR_RATELIMIT_BACKOFF STRING_ARG
2700	{
2701		OUTYY(("P(server_ratelimit_backoff:%s)\n", $2));
2702		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2703			yyerror("expected yes or no.");
2704		else cfg_parser->cfg->ratelimit_backoff =
2705			(strcmp($2, "yes")==0);
2706		free($2);
2707	}
2708	;
2709server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG
2710	{
2711		OUTYY(("P(server_outbound_msg_retry:%s)\n", $2));
2712		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2713			yyerror("number expected");
2714		else cfg_parser->cfg->outbound_msg_retry = atoi($2);
2715		free($2);
2716	}
2717	;
2718server_max_sent_count: VAR_MAX_SENT_COUNT STRING_ARG
2719	{
2720		OUTYY(("P(server_max_sent_count:%s)\n", $2));
2721		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2722			yyerror("number expected");
2723		else cfg_parser->cfg->max_sent_count = atoi($2);
2724		free($2);
2725	}
2726	;
2727server_max_query_restarts: VAR_MAX_QUERY_RESTARTS STRING_ARG
2728	{
2729		OUTYY(("P(server_max_query_restarts:%s)\n", $2));
2730		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2731			yyerror("number expected");
2732		else cfg_parser->cfg->max_query_restarts = atoi($2);
2733		free($2);
2734	}
2735	;
2736server_low_rtt: VAR_LOW_RTT STRING_ARG
2737	{
2738		OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));
2739		free($2);
2740	}
2741	;
2742server_fast_server_num: VAR_FAST_SERVER_NUM STRING_ARG
2743	{
2744		OUTYY(("P(server_fast_server_num:%s)\n", $2));
2745		if(atoi($2) <= 0)
2746			yyerror("number expected");
2747		else cfg_parser->cfg->fast_server_num = atoi($2);
2748		free($2);
2749	}
2750	;
2751server_fast_server_permil: VAR_FAST_SERVER_PERMIL STRING_ARG
2752	{
2753		OUTYY(("P(server_fast_server_permil:%s)\n", $2));
2754		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2755			yyerror("number expected");
2756		else cfg_parser->cfg->fast_server_permil = atoi($2);
2757		free($2);
2758	}
2759	;
2760server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG
2761	{
2762		OUTYY(("P(server_qname_minimisation:%s)\n", $2));
2763		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2764			yyerror("expected yes or no.");
2765		else cfg_parser->cfg->qname_minimisation =
2766			(strcmp($2, "yes")==0);
2767		free($2);
2768	}
2769	;
2770server_qname_minimisation_strict: VAR_QNAME_MINIMISATION_STRICT STRING_ARG
2771	{
2772		OUTYY(("P(server_qname_minimisation_strict:%s)\n", $2));
2773		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2774			yyerror("expected yes or no.");
2775		else cfg_parser->cfg->qname_minimisation_strict =
2776			(strcmp($2, "yes")==0);
2777		free($2);
2778	}
2779	;
2780server_pad_responses: VAR_PAD_RESPONSES STRING_ARG
2781	{
2782		OUTYY(("P(server_pad_responses:%s)\n", $2));
2783		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2784			yyerror("expected yes or no.");
2785		else cfg_parser->cfg->pad_responses =
2786			(strcmp($2, "yes")==0);
2787		free($2);
2788	}
2789	;
2790server_pad_responses_block_size: VAR_PAD_RESPONSES_BLOCK_SIZE STRING_ARG
2791	{
2792		OUTYY(("P(server_pad_responses_block_size:%s)\n", $2));
2793		if(atoi($2) == 0)
2794			yyerror("number expected");
2795		else cfg_parser->cfg->pad_responses_block_size = atoi($2);
2796		free($2);
2797	}
2798	;
2799server_pad_queries: VAR_PAD_QUERIES STRING_ARG
2800	{
2801		OUTYY(("P(server_pad_queries:%s)\n", $2));
2802		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2803			yyerror("expected yes or no.");
2804		else cfg_parser->cfg->pad_queries =
2805			(strcmp($2, "yes")==0);
2806		free($2);
2807	}
2808	;
2809server_pad_queries_block_size: VAR_PAD_QUERIES_BLOCK_SIZE STRING_ARG
2810	{
2811		OUTYY(("P(server_pad_queries_block_size:%s)\n", $2));
2812		if(atoi($2) == 0)
2813			yyerror("number expected");
2814		else cfg_parser->cfg->pad_queries_block_size = atoi($2);
2815		free($2);
2816	}
2817	;
2818server_ipsecmod_enabled: VAR_IPSECMOD_ENABLED STRING_ARG
2819	{
2820	#ifdef USE_IPSECMOD
2821		OUTYY(("P(server_ipsecmod_enabled:%s)\n", $2));
2822		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2823			yyerror("expected yes or no.");
2824		else cfg_parser->cfg->ipsecmod_enabled = (strcmp($2, "yes")==0);
2825	#else
2826		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
2827	#endif
2828		free($2);
2829	}
2830	;
2831server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG
2832	{
2833	#ifdef USE_IPSECMOD
2834		OUTYY(("P(server_ipsecmod_ignore_bogus:%s)\n", $2));
2835		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2836			yyerror("expected yes or no.");
2837		else cfg_parser->cfg->ipsecmod_ignore_bogus = (strcmp($2, "yes")==0);
2838	#else
2839		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
2840	#endif
2841		free($2);
2842	}
2843	;
2844server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG
2845	{
2846	#ifdef USE_IPSECMOD
2847		OUTYY(("P(server_ipsecmod_hook:%s)\n", $2));
2848		free(cfg_parser->cfg->ipsecmod_hook);
2849		cfg_parser->cfg->ipsecmod_hook = $2;
2850	#else
2851		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
2852		free($2);
2853	#endif
2854	}
2855	;
2856server_ipsecmod_max_ttl: VAR_IPSECMOD_MAX_TTL STRING_ARG
2857	{
2858	#ifdef USE_IPSECMOD
2859		OUTYY(("P(server_ipsecmod_max_ttl:%s)\n", $2));
2860		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2861			yyerror("number expected");
2862		else cfg_parser->cfg->ipsecmod_max_ttl = atoi($2);
2863		free($2);
2864	#else
2865		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
2866		free($2);
2867	#endif
2868	}
2869	;
2870server_ipsecmod_whitelist: VAR_IPSECMOD_WHITELIST STRING_ARG
2871	{
2872	#ifdef USE_IPSECMOD
2873		OUTYY(("P(server_ipsecmod_whitelist:%s)\n", $2));
2874		if(!cfg_strlist_insert(&cfg_parser->cfg->ipsecmod_whitelist, $2))
2875			yyerror("out of memory");
2876	#else
2877		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
2878		free($2);
2879	#endif
2880	}
2881	;
2882server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG
2883	{
2884	#ifdef USE_IPSECMOD
2885		OUTYY(("P(server_ipsecmod_strict:%s)\n", $2));
2886		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2887			yyerror("expected yes or no.");
2888		else cfg_parser->cfg->ipsecmod_strict = (strcmp($2, "yes")==0);
2889		free($2);
2890	#else
2891		OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
2892		free($2);
2893	#endif
2894	}
2895	;
2896server_edns_client_string: VAR_EDNS_CLIENT_STRING STRING_ARG STRING_ARG
2897	{
2898		OUTYY(("P(server_edns_client_string:%s %s)\n", $2, $3));
2899		if(!cfg_str2list_insert(
2900			&cfg_parser->cfg->edns_client_strings, $2, $3))
2901			fatal_exit("out of memory adding "
2902				"edns-client-string");
2903	}
2904	;
2905server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG
2906	{
2907		OUTYY(("P(edns_client_string_opcode:%s)\n", $2));
2908		if(atoi($2) == 0 && strcmp($2, "0") != 0)
2909			yyerror("option code expected");
2910		else if(atoi($2) > 65535 || atoi($2) < 0)
2911			yyerror("option code must be in interval [0, 65535]");
2912		else cfg_parser->cfg->edns_client_string_opcode = atoi($2);
2913		free($2);
2914	}
2915	;
2916server_ede: VAR_EDE STRING_ARG
2917	{
2918		OUTYY(("P(server_ede:%s)\n", $2));
2919		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2920			yyerror("expected yes or no.");
2921		else cfg_parser->cfg->ede = (strcmp($2, "yes")==0);
2922		free($2);
2923	}
2924	;
2925server_proxy_protocol_port: VAR_PROXY_PROTOCOL_PORT STRING_ARG
2926	{
2927		OUTYY(("P(server_proxy_protocol_port:%s)\n", $2));
2928		if(!cfg_strlist_insert(&cfg_parser->cfg->proxy_protocol_port, $2))
2929			yyerror("out of memory");
2930	}
2931	;
2932stub_name: VAR_NAME STRING_ARG
2933	{
2934		OUTYY(("P(name:%s)\n", $2));
2935		if(cfg_parser->cfg->stubs->name)
2936			yyerror("stub name override, there must be one name "
2937				"for one stub-zone");
2938		free(cfg_parser->cfg->stubs->name);
2939		cfg_parser->cfg->stubs->name = $2;
2940	}
2941	;
2942stub_host: VAR_STUB_HOST STRING_ARG
2943	{
2944		OUTYY(("P(stub-host:%s)\n", $2));
2945		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, $2))
2946			yyerror("out of memory");
2947	}
2948	;
2949stub_addr: VAR_STUB_ADDR STRING_ARG
2950	{
2951		OUTYY(("P(stub-addr:%s)\n", $2));
2952		if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, $2))
2953			yyerror("out of memory");
2954	}
2955	;
2956stub_first: VAR_STUB_FIRST STRING_ARG
2957	{
2958		OUTYY(("P(stub-first:%s)\n", $2));
2959		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2960			yyerror("expected yes or no.");
2961		else cfg_parser->cfg->stubs->isfirst=(strcmp($2, "yes")==0);
2962		free($2);
2963	}
2964	;
2965stub_no_cache: VAR_STUB_NO_CACHE STRING_ARG
2966	{
2967		OUTYY(("P(stub-no-cache:%s)\n", $2));
2968		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2969			yyerror("expected yes or no.");
2970		else cfg_parser->cfg->stubs->no_cache=(strcmp($2, "yes")==0);
2971		free($2);
2972	}
2973	;
2974stub_ssl_upstream: VAR_STUB_SSL_UPSTREAM STRING_ARG
2975	{
2976		OUTYY(("P(stub-ssl-upstream:%s)\n", $2));
2977		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2978			yyerror("expected yes or no.");
2979		else cfg_parser->cfg->stubs->ssl_upstream =
2980			(strcmp($2, "yes")==0);
2981		free($2);
2982	}
2983	;
2984stub_tcp_upstream: VAR_STUB_TCP_UPSTREAM STRING_ARG
2985        {
2986                OUTYY(("P(stub-tcp-upstream:%s)\n", $2));
2987                if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2988                        yyerror("expected yes or no.");
2989                else cfg_parser->cfg->stubs->tcp_upstream =
2990                        (strcmp($2, "yes")==0);
2991                free($2);
2992        }
2993        ;
2994stub_prime: VAR_STUB_PRIME STRING_ARG
2995	{
2996		OUTYY(("P(stub-prime:%s)\n", $2));
2997		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
2998			yyerror("expected yes or no.");
2999		else cfg_parser->cfg->stubs->isprime =
3000			(strcmp($2, "yes")==0);
3001		free($2);
3002	}
3003	;
3004forward_name: VAR_NAME STRING_ARG
3005	{
3006		OUTYY(("P(name:%s)\n", $2));
3007		if(cfg_parser->cfg->forwards->name)
3008			yyerror("forward name override, there must be one "
3009				"name for one forward-zone");
3010		free(cfg_parser->cfg->forwards->name);
3011		cfg_parser->cfg->forwards->name = $2;
3012	}
3013	;
3014forward_host: VAR_FORWARD_HOST STRING_ARG
3015	{
3016		OUTYY(("P(forward-host:%s)\n", $2));
3017		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, $2))
3018			yyerror("out of memory");
3019	}
3020	;
3021forward_addr: VAR_FORWARD_ADDR STRING_ARG
3022	{
3023		OUTYY(("P(forward-addr:%s)\n", $2));
3024		if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, $2))
3025			yyerror("out of memory");
3026	}
3027	;
3028forward_first: VAR_FORWARD_FIRST STRING_ARG
3029	{
3030		OUTYY(("P(forward-first:%s)\n", $2));
3031		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3032			yyerror("expected yes or no.");
3033		else cfg_parser->cfg->forwards->isfirst=(strcmp($2, "yes")==0);
3034		free($2);
3035	}
3036	;
3037forward_no_cache: VAR_FORWARD_NO_CACHE STRING_ARG
3038	{
3039		OUTYY(("P(forward-no-cache:%s)\n", $2));
3040		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3041			yyerror("expected yes or no.");
3042		else cfg_parser->cfg->forwards->no_cache=(strcmp($2, "yes")==0);
3043		free($2);
3044	}
3045	;
3046forward_ssl_upstream: VAR_FORWARD_SSL_UPSTREAM STRING_ARG
3047	{
3048		OUTYY(("P(forward-ssl-upstream:%s)\n", $2));
3049		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3050			yyerror("expected yes or no.");
3051		else cfg_parser->cfg->forwards->ssl_upstream =
3052			(strcmp($2, "yes")==0);
3053		free($2);
3054	}
3055	;
3056forward_tcp_upstream: VAR_FORWARD_TCP_UPSTREAM STRING_ARG
3057        {
3058                OUTYY(("P(forward-tcp-upstream:%s)\n", $2));
3059                if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3060                        yyerror("expected yes or no.");
3061                else cfg_parser->cfg->forwards->tcp_upstream =
3062                        (strcmp($2, "yes")==0);
3063                free($2);
3064        }
3065        ;
3066auth_name: VAR_NAME STRING_ARG
3067	{
3068		OUTYY(("P(name:%s)\n", $2));
3069		if(cfg_parser->cfg->auths->name)
3070			yyerror("auth name override, there must be one name "
3071				"for one auth-zone");
3072		free(cfg_parser->cfg->auths->name);
3073		cfg_parser->cfg->auths->name = $2;
3074	}
3075	;
3076auth_zonefile: VAR_ZONEFILE STRING_ARG
3077	{
3078		OUTYY(("P(zonefile:%s)\n", $2));
3079		free(cfg_parser->cfg->auths->zonefile);
3080		cfg_parser->cfg->auths->zonefile = $2;
3081	}
3082	;
3083auth_master: VAR_MASTER STRING_ARG
3084	{
3085		OUTYY(("P(master:%s)\n", $2));
3086		if(!cfg_strlist_insert(&cfg_parser->cfg->auths->masters, $2))
3087			yyerror("out of memory");
3088	}
3089	;
3090auth_url: VAR_URL STRING_ARG
3091	{
3092		OUTYY(("P(url:%s)\n", $2));
3093		if(!cfg_strlist_insert(&cfg_parser->cfg->auths->urls, $2))
3094			yyerror("out of memory");
3095	}
3096	;
3097auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG
3098	{
3099		OUTYY(("P(allow-notify:%s)\n", $2));
3100		if(!cfg_strlist_insert(&cfg_parser->cfg->auths->allow_notify,
3101			$2))
3102			yyerror("out of memory");
3103	}
3104	;
3105auth_zonemd_check: VAR_ZONEMD_CHECK STRING_ARG
3106	{
3107		OUTYY(("P(zonemd-check:%s)\n", $2));
3108		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3109			yyerror("expected yes or no.");
3110		else cfg_parser->cfg->auths->zonemd_check =
3111			(strcmp($2, "yes")==0);
3112		free($2);
3113	}
3114	;
3115auth_zonemd_reject_absence: VAR_ZONEMD_REJECT_ABSENCE STRING_ARG
3116	{
3117		OUTYY(("P(zonemd-reject-absence:%s)\n", $2));
3118		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3119			yyerror("expected yes or no.");
3120		else cfg_parser->cfg->auths->zonemd_reject_absence =
3121			(strcmp($2, "yes")==0);
3122		free($2);
3123	}
3124	;
3125auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG
3126	{
3127		OUTYY(("P(for-downstream:%s)\n", $2));
3128		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3129			yyerror("expected yes or no.");
3130		else cfg_parser->cfg->auths->for_downstream =
3131			(strcmp($2, "yes")==0);
3132		free($2);
3133	}
3134	;
3135auth_for_upstream: VAR_FOR_UPSTREAM STRING_ARG
3136	{
3137		OUTYY(("P(for-upstream:%s)\n", $2));
3138		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3139			yyerror("expected yes or no.");
3140		else cfg_parser->cfg->auths->for_upstream =
3141			(strcmp($2, "yes")==0);
3142		free($2);
3143	}
3144	;
3145auth_fallback_enabled: VAR_FALLBACK_ENABLED STRING_ARG
3146	{
3147		OUTYY(("P(fallback-enabled:%s)\n", $2));
3148		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3149			yyerror("expected yes or no.");
3150		else cfg_parser->cfg->auths->fallback_enabled =
3151			(strcmp($2, "yes")==0);
3152		free($2);
3153	}
3154	;
3155view_name: VAR_NAME STRING_ARG
3156	{
3157		OUTYY(("P(name:%s)\n", $2));
3158		if(cfg_parser->cfg->views->name)
3159			yyerror("view name override, there must be one "
3160				"name for one view");
3161		free(cfg_parser->cfg->views->name);
3162		cfg_parser->cfg->views->name = $2;
3163	}
3164	;
3165view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
3166	{
3167		OUTYY(("P(view_local_zone:%s %s)\n", $2, $3));
3168		if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
3169		   strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
3170		   strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
3171		   && strcmp($3, "typetransparent")!=0
3172		   && strcmp($3, "always_transparent")!=0
3173		   && strcmp($3, "always_refuse")!=0
3174		   && strcmp($3, "always_nxdomain")!=0
3175		   && strcmp($3, "always_nodata")!=0
3176		   && strcmp($3, "always_deny")!=0
3177		   && strcmp($3, "always_null")!=0
3178		   && strcmp($3, "noview")!=0
3179		   && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
3180		   && strcmp($3, "inform_redirect") != 0
3181		   && strcmp($3, "ipset") != 0) {
3182			yyerror("local-zone type: expected static, deny, "
3183				"refuse, redirect, transparent, "
3184				"typetransparent, inform, inform_deny, "
3185				"inform_redirect, always_transparent, "
3186				"always_refuse, always_nxdomain, "
3187				"always_nodata, always_deny, always_null, "
3188				"noview, nodefault or ipset");
3189			free($2);
3190			free($3);
3191		} else if(strcmp($3, "nodefault")==0) {
3192			if(!cfg_strlist_insert(&cfg_parser->cfg->views->
3193				local_zones_nodefault, $2))
3194				fatal_exit("out of memory adding local-zone");
3195			free($3);
3196#ifdef USE_IPSET
3197		} else if(strcmp($3, "ipset")==0) {
3198			size_t len = strlen($2);
3199			/* Make sure to add the trailing dot.
3200			 * These are str compared to domain names. */
3201			if($2[len-1] != '.') {
3202				if(!($2 = realloc($2, len+2))) {
3203					fatal_exit("out of memory adding local-zone");
3204				}
3205				$2[len] = '.';
3206				$2[len+1] = 0;
3207			}
3208			if(!cfg_strlist_insert(&cfg_parser->cfg->views->
3209				local_zones_ipset, $2))
3210				fatal_exit("out of memory adding local-zone");
3211			free($3);
3212#endif
3213		} else {
3214			if(!cfg_str2list_insert(
3215				&cfg_parser->cfg->views->local_zones,
3216				$2, $3))
3217				fatal_exit("out of memory adding local-zone");
3218		}
3219	}
3220	;
3221view_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG
3222	{
3223		OUTYY(("P(view_response_ip:%s %s)\n", $2, $3));
3224		validate_respip_action($3);
3225		if(!cfg_str2list_insert(
3226			&cfg_parser->cfg->views->respip_actions, $2, $3))
3227			fatal_exit("out of memory adding per-view "
3228				"response-ip action");
3229	}
3230	;
3231view_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
3232	{
3233		OUTYY(("P(view_response_ip_data:%s)\n", $2));
3234		if(!cfg_str2list_insert(
3235			&cfg_parser->cfg->views->respip_data, $2, $3))
3236			fatal_exit("out of memory adding response-ip-data");
3237	}
3238	;
3239view_local_data: VAR_LOCAL_DATA STRING_ARG
3240	{
3241		OUTYY(("P(view_local_data:%s)\n", $2));
3242		if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, $2)) {
3243			fatal_exit("out of memory adding local-data");
3244		}
3245	}
3246	;
3247view_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
3248	{
3249		char* ptr;
3250		OUTYY(("P(view_local_data_ptr:%s)\n", $2));
3251		ptr = cfg_ptr_reverse($2);
3252		free($2);
3253		if(ptr) {
3254			if(!cfg_strlist_insert(&cfg_parser->cfg->views->
3255				local_data, ptr))
3256				fatal_exit("out of memory adding local-data");
3257		} else {
3258			yyerror("local-data-ptr could not be reversed");
3259		}
3260	}
3261	;
3262view_first: VAR_VIEW_FIRST STRING_ARG
3263	{
3264		OUTYY(("P(view-first:%s)\n", $2));
3265		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3266			yyerror("expected yes or no.");
3267		else cfg_parser->cfg->views->isfirst=(strcmp($2, "yes")==0);
3268		free($2);
3269	}
3270	;
3271rcstart: VAR_REMOTE_CONTROL
3272	{
3273		OUTYY(("\nP(remote-control:)\n"));
3274		cfg_parser->started_toplevel = 1;
3275	}
3276	;
3277contents_rc: contents_rc content_rc
3278	| ;
3279content_rc: rc_control_enable | rc_control_interface | rc_control_port |
3280	rc_server_key_file | rc_server_cert_file | rc_control_key_file |
3281	rc_control_cert_file | rc_control_use_cert
3282	;
3283rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG
3284	{
3285		OUTYY(("P(control_enable:%s)\n", $2));
3286		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3287			yyerror("expected yes or no.");
3288		else cfg_parser->cfg->remote_control_enable =
3289			(strcmp($2, "yes")==0);
3290		free($2);
3291	}
3292	;
3293rc_control_port: VAR_CONTROL_PORT STRING_ARG
3294	{
3295		OUTYY(("P(control_port:%s)\n", $2));
3296		if(atoi($2) == 0)
3297			yyerror("control port number expected");
3298		else cfg_parser->cfg->control_port = atoi($2);
3299		free($2);
3300	}
3301	;
3302rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG
3303	{
3304		OUTYY(("P(control_interface:%s)\n", $2));
3305		if(!cfg_strlist_append(&cfg_parser->cfg->control_ifs, $2))
3306			yyerror("out of memory");
3307	}
3308	;
3309rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG
3310	{
3311		OUTYY(("P(control_use_cert:%s)\n", $2));
3312		cfg_parser->cfg->control_use_cert = (strcmp($2, "yes")==0);
3313		free($2);
3314	}
3315	;
3316rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG
3317	{
3318		OUTYY(("P(rc_server_key_file:%s)\n", $2));
3319		free(cfg_parser->cfg->server_key_file);
3320		cfg_parser->cfg->server_key_file = $2;
3321	}
3322	;
3323rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG
3324	{
3325		OUTYY(("P(rc_server_cert_file:%s)\n", $2));
3326		free(cfg_parser->cfg->server_cert_file);
3327		cfg_parser->cfg->server_cert_file = $2;
3328	}
3329	;
3330rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG
3331	{
3332		OUTYY(("P(rc_control_key_file:%s)\n", $2));
3333		free(cfg_parser->cfg->control_key_file);
3334		cfg_parser->cfg->control_key_file = $2;
3335	}
3336	;
3337rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG
3338	{
3339		OUTYY(("P(rc_control_cert_file:%s)\n", $2));
3340		free(cfg_parser->cfg->control_cert_file);
3341		cfg_parser->cfg->control_cert_file = $2;
3342	}
3343	;
3344dtstart: VAR_DNSTAP
3345	{
3346		OUTYY(("\nP(dnstap:)\n"));
3347		cfg_parser->started_toplevel = 1;
3348	}
3349	;
3350contents_dt: contents_dt content_dt
3351	| ;
3352content_dt: dt_dnstap_enable | dt_dnstap_socket_path | dt_dnstap_bidirectional |
3353	dt_dnstap_ip | dt_dnstap_tls | dt_dnstap_tls_server_name |
3354	dt_dnstap_tls_cert_bundle |
3355	dt_dnstap_tls_client_key_file | dt_dnstap_tls_client_cert_file |
3356	dt_dnstap_send_identity | dt_dnstap_send_version |
3357	dt_dnstap_identity | dt_dnstap_version |
3358	dt_dnstap_log_resolver_query_messages |
3359	dt_dnstap_log_resolver_response_messages |
3360	dt_dnstap_log_client_query_messages |
3361	dt_dnstap_log_client_response_messages |
3362	dt_dnstap_log_forwarder_query_messages |
3363	dt_dnstap_log_forwarder_response_messages
3364	;
3365dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG
3366	{
3367		OUTYY(("P(dt_dnstap_enable:%s)\n", $2));
3368		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3369			yyerror("expected yes or no.");
3370		else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0);
3371		free($2);
3372	}
3373	;
3374dt_dnstap_bidirectional: VAR_DNSTAP_BIDIRECTIONAL STRING_ARG
3375	{
3376		OUTYY(("P(dt_dnstap_bidirectional:%s)\n", $2));
3377		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3378			yyerror("expected yes or no.");
3379		else cfg_parser->cfg->dnstap_bidirectional =
3380			(strcmp($2, "yes")==0);
3381		free($2);
3382	}
3383	;
3384dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG
3385	{
3386		OUTYY(("P(dt_dnstap_socket_path:%s)\n", $2));
3387		free(cfg_parser->cfg->dnstap_socket_path);
3388		cfg_parser->cfg->dnstap_socket_path = $2;
3389	}
3390	;
3391dt_dnstap_ip: VAR_DNSTAP_IP STRING_ARG
3392	{
3393		OUTYY(("P(dt_dnstap_ip:%s)\n", $2));
3394		free(cfg_parser->cfg->dnstap_ip);
3395		cfg_parser->cfg->dnstap_ip = $2;
3396	}
3397	;
3398dt_dnstap_tls: VAR_DNSTAP_TLS STRING_ARG
3399	{
3400		OUTYY(("P(dt_dnstap_tls:%s)\n", $2));
3401		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3402			yyerror("expected yes or no.");
3403		else cfg_parser->cfg->dnstap_tls = (strcmp($2, "yes")==0);
3404		free($2);
3405	}
3406	;
3407dt_dnstap_tls_server_name: VAR_DNSTAP_TLS_SERVER_NAME STRING_ARG
3408	{
3409		OUTYY(("P(dt_dnstap_tls_server_name:%s)\n", $2));
3410		free(cfg_parser->cfg->dnstap_tls_server_name);
3411		cfg_parser->cfg->dnstap_tls_server_name = $2;
3412	}
3413	;
3414dt_dnstap_tls_cert_bundle: VAR_DNSTAP_TLS_CERT_BUNDLE STRING_ARG
3415	{
3416		OUTYY(("P(dt_dnstap_tls_cert_bundle:%s)\n", $2));
3417		free(cfg_parser->cfg->dnstap_tls_cert_bundle);
3418		cfg_parser->cfg->dnstap_tls_cert_bundle = $2;
3419	}
3420	;
3421dt_dnstap_tls_client_key_file: VAR_DNSTAP_TLS_CLIENT_KEY_FILE STRING_ARG
3422	{
3423		OUTYY(("P(dt_dnstap_tls_client_key_file:%s)\n", $2));
3424		free(cfg_parser->cfg->dnstap_tls_client_key_file);
3425		cfg_parser->cfg->dnstap_tls_client_key_file = $2;
3426	}
3427	;
3428dt_dnstap_tls_client_cert_file: VAR_DNSTAP_TLS_CLIENT_CERT_FILE STRING_ARG
3429	{
3430		OUTYY(("P(dt_dnstap_tls_client_cert_file:%s)\n", $2));
3431		free(cfg_parser->cfg->dnstap_tls_client_cert_file);
3432		cfg_parser->cfg->dnstap_tls_client_cert_file = $2;
3433	}
3434	;
3435dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG
3436	{
3437		OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2));
3438		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3439			yyerror("expected yes or no.");
3440		else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0);
3441		free($2);
3442	}
3443	;
3444dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG
3445	{
3446		OUTYY(("P(dt_dnstap_send_version:%s)\n", $2));
3447		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3448			yyerror("expected yes or no.");
3449		else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0);
3450		free($2);
3451	}
3452	;
3453dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG
3454	{
3455		OUTYY(("P(dt_dnstap_identity:%s)\n", $2));
3456		free(cfg_parser->cfg->dnstap_identity);
3457		cfg_parser->cfg->dnstap_identity = $2;
3458	}
3459	;
3460dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG
3461	{
3462		OUTYY(("P(dt_dnstap_version:%s)\n", $2));
3463		free(cfg_parser->cfg->dnstap_version);
3464		cfg_parser->cfg->dnstap_version = $2;
3465	}
3466	;
3467dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG
3468	{
3469		OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", $2));
3470		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3471			yyerror("expected yes or no.");
3472		else cfg_parser->cfg->dnstap_log_resolver_query_messages =
3473			(strcmp($2, "yes")==0);
3474		free($2);
3475	}
3476	;
3477dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG
3478	{
3479		OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", $2));
3480		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3481			yyerror("expected yes or no.");
3482		else cfg_parser->cfg->dnstap_log_resolver_response_messages =
3483			(strcmp($2, "yes")==0);
3484		free($2);
3485	}
3486	;
3487dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG
3488	{
3489		OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", $2));
3490		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3491			yyerror("expected yes or no.");
3492		else cfg_parser->cfg->dnstap_log_client_query_messages =
3493			(strcmp($2, "yes")==0);
3494		free($2);
3495	}
3496	;
3497dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG
3498	{
3499		OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", $2));
3500		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3501			yyerror("expected yes or no.");
3502		else cfg_parser->cfg->dnstap_log_client_response_messages =
3503			(strcmp($2, "yes")==0);
3504		free($2);
3505	}
3506	;
3507dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG
3508	{
3509		OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", $2));
3510		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3511			yyerror("expected yes or no.");
3512		else cfg_parser->cfg->dnstap_log_forwarder_query_messages =
3513			(strcmp($2, "yes")==0);
3514		free($2);
3515	}
3516	;
3517dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG
3518	{
3519		OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", $2));
3520		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3521			yyerror("expected yes or no.");
3522		else cfg_parser->cfg->dnstap_log_forwarder_response_messages =
3523			(strcmp($2, "yes")==0);
3524		free($2);
3525	}
3526	;
3527pythonstart: VAR_PYTHON
3528	{
3529		OUTYY(("\nP(python:)\n"));
3530		cfg_parser->started_toplevel = 1;
3531	}
3532	;
3533contents_py: contents_py content_py
3534	| ;
3535content_py: py_script
3536	;
3537py_script: VAR_PYTHON_SCRIPT STRING_ARG
3538	{
3539		OUTYY(("P(python-script:%s)\n", $2));
3540		if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2))
3541			yyerror("out of memory");
3542	}
3543	;
3544dynlibstart: VAR_DYNLIB
3545	{
3546		OUTYY(("\nP(dynlib:)\n"));
3547		cfg_parser->started_toplevel = 1;
3548	}
3549	;
3550contents_dl: contents_dl content_dl
3551	| ;
3552content_dl: dl_file
3553	;
3554dl_file: VAR_DYNLIB_FILE STRING_ARG
3555	{
3556		OUTYY(("P(dynlib-file:%s)\n", $2));
3557		if(!cfg_strlist_append_ex(&cfg_parser->cfg->dynlib_file, $2))
3558			yyerror("out of memory");
3559	}
3560	;
3561server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG
3562	{
3563		OUTYY(("P(disable_dnssec_lame_check:%s)\n", $2));
3564		if (strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3565			yyerror("expected yes or no.");
3566		else cfg_parser->cfg->disable_dnssec_lame_check =
3567			(strcmp($2, "yes")==0);
3568		free($2);
3569	}
3570	;
3571server_log_identity: VAR_LOG_IDENTITY STRING_ARG
3572	{
3573		OUTYY(("P(server_log_identity:%s)\n", $2));
3574		free(cfg_parser->cfg->log_identity);
3575		cfg_parser->cfg->log_identity = $2;
3576	}
3577	;
3578server_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG
3579	{
3580		OUTYY(("P(server_response_ip:%s %s)\n", $2, $3));
3581		validate_respip_action($3);
3582		if(!cfg_str2list_insert(&cfg_parser->cfg->respip_actions,
3583			$2, $3))
3584			fatal_exit("out of memory adding response-ip");
3585	}
3586	;
3587server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
3588	{
3589		OUTYY(("P(server_response_ip_data:%s)\n", $2));
3590		if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
3591			$2, $3))
3592			fatal_exit("out of memory adding response-ip-data");
3593	}
3594	;
3595dnscstart: VAR_DNSCRYPT
3596	{
3597		OUTYY(("\nP(dnscrypt:)\n"));
3598		cfg_parser->started_toplevel = 1;
3599	}
3600	;
3601contents_dnsc: contents_dnsc content_dnsc
3602	| ;
3603content_dnsc:
3604	dnsc_dnscrypt_enable | dnsc_dnscrypt_port | dnsc_dnscrypt_provider |
3605	dnsc_dnscrypt_secret_key | dnsc_dnscrypt_provider_cert |
3606	dnsc_dnscrypt_provider_cert_rotated |
3607	dnsc_dnscrypt_shared_secret_cache_size |
3608	dnsc_dnscrypt_shared_secret_cache_slabs |
3609	dnsc_dnscrypt_nonce_cache_size |
3610	dnsc_dnscrypt_nonce_cache_slabs
3611	;
3612dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG
3613	{
3614		OUTYY(("P(dnsc_dnscrypt_enable:%s)\n", $2));
3615		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3616			yyerror("expected yes or no.");
3617		else cfg_parser->cfg->dnscrypt = (strcmp($2, "yes")==0);
3618		free($2);
3619	}
3620	;
3621dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG
3622	{
3623		OUTYY(("P(dnsc_dnscrypt_port:%s)\n", $2));
3624		if(atoi($2) == 0)
3625			yyerror("port number expected");
3626		else cfg_parser->cfg->dnscrypt_port = atoi($2);
3627		free($2);
3628	}
3629	;
3630dnsc_dnscrypt_provider: VAR_DNSCRYPT_PROVIDER STRING_ARG
3631	{
3632		OUTYY(("P(dnsc_dnscrypt_provider:%s)\n", $2));
3633		free(cfg_parser->cfg->dnscrypt_provider);
3634		cfg_parser->cfg->dnscrypt_provider = $2;
3635	}
3636	;
3637dnsc_dnscrypt_provider_cert: VAR_DNSCRYPT_PROVIDER_CERT STRING_ARG
3638	{
3639		OUTYY(("P(dnsc_dnscrypt_provider_cert:%s)\n", $2));
3640		if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_provider_cert, $2))
3641			log_warn("dnscrypt-provider-cert %s is a duplicate", $2);
3642		if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, $2))
3643			fatal_exit("out of memory adding dnscrypt-provider-cert");
3644	}
3645	;
3646dnsc_dnscrypt_provider_cert_rotated: VAR_DNSCRYPT_PROVIDER_CERT_ROTATED STRING_ARG
3647	{
3648		OUTYY(("P(dnsc_dnscrypt_provider_cert_rotated:%s)\n", $2));
3649		if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert_rotated, $2))
3650			fatal_exit("out of memory adding dnscrypt-provider-cert-rotated");
3651	}
3652	;
3653dnsc_dnscrypt_secret_key: VAR_DNSCRYPT_SECRET_KEY STRING_ARG
3654	{
3655		OUTYY(("P(dnsc_dnscrypt_secret_key:%s)\n", $2));
3656		if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_secret_key, $2))
3657			log_warn("dnscrypt-secret-key: %s is a duplicate", $2);
3658		if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, $2))
3659			fatal_exit("out of memory adding dnscrypt-secret-key");
3660	}
3661	;
3662dnsc_dnscrypt_shared_secret_cache_size: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE STRING_ARG
3663  {
3664	OUTYY(("P(dnscrypt_shared_secret_cache_size:%s)\n", $2));
3665	if(!cfg_parse_memsize($2, &cfg_parser->cfg->dnscrypt_shared_secret_cache_size))
3666		yyerror("memory size expected");
3667	free($2);
3668  }
3669  ;
3670dnsc_dnscrypt_shared_secret_cache_slabs: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS STRING_ARG
3671  {
3672	OUTYY(("P(dnscrypt_shared_secret_cache_slabs:%s)\n", $2));
3673	if(atoi($2) == 0) {
3674		yyerror("number expected");
3675	} else {
3676		cfg_parser->cfg->dnscrypt_shared_secret_cache_slabs = atoi($2);
3677		if(!is_pow2(cfg_parser->cfg->dnscrypt_shared_secret_cache_slabs))
3678			yyerror("must be a power of 2");
3679	}
3680	free($2);
3681  }
3682  ;
3683dnsc_dnscrypt_nonce_cache_size: VAR_DNSCRYPT_NONCE_CACHE_SIZE STRING_ARG
3684  {
3685	OUTYY(("P(dnscrypt_nonce_cache_size:%s)\n", $2));
3686	if(!cfg_parse_memsize($2, &cfg_parser->cfg->dnscrypt_nonce_cache_size))
3687		yyerror("memory size expected");
3688	free($2);
3689  }
3690  ;
3691dnsc_dnscrypt_nonce_cache_slabs: VAR_DNSCRYPT_NONCE_CACHE_SLABS STRING_ARG
3692  {
3693	OUTYY(("P(dnscrypt_nonce_cache_slabs:%s)\n", $2));
3694	if(atoi($2) == 0) {
3695		yyerror("number expected");
3696	} else {
3697		cfg_parser->cfg->dnscrypt_nonce_cache_slabs = atoi($2);
3698		if(!is_pow2(cfg_parser->cfg->dnscrypt_nonce_cache_slabs))
3699			yyerror("must be a power of 2");
3700	}
3701	free($2);
3702  }
3703  ;
3704cachedbstart: VAR_CACHEDB
3705	{
3706		OUTYY(("\nP(cachedb:)\n"));
3707		cfg_parser->started_toplevel = 1;
3708	}
3709	;
3710contents_cachedb: contents_cachedb content_cachedb
3711	| ;
3712content_cachedb: cachedb_backend_name | cachedb_secret_seed |
3713	redis_server_host | redis_server_port | redis_timeout |
3714	redis_expire_records | redis_server_path | redis_server_password |
3715	cachedb_no_store | redis_logical_db
3716	;
3717cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
3718	{
3719	#ifdef USE_CACHEDB
3720		OUTYY(("P(backend:%s)\n", $2));
3721		free(cfg_parser->cfg->cachedb_backend);
3722		cfg_parser->cfg->cachedb_backend = $2;
3723	#else
3724		OUTYY(("P(Compiled without cachedb, ignoring)\n"));
3725		free($2);
3726	#endif
3727	}
3728	;
3729cachedb_secret_seed: VAR_CACHEDB_SECRETSEED STRING_ARG
3730	{
3731	#ifdef USE_CACHEDB
3732		OUTYY(("P(secret-seed:%s)\n", $2));
3733		free(cfg_parser->cfg->cachedb_secret);
3734		cfg_parser->cfg->cachedb_secret = $2;
3735	#else
3736		OUTYY(("P(Compiled without cachedb, ignoring)\n"));
3737		free($2);
3738	#endif
3739	}
3740	;
3741cachedb_no_store: VAR_CACHEDB_NO_STORE STRING_ARG
3742	{
3743	#ifdef USE_CACHEDB
3744		OUTYY(("P(cachedb_no_store:%s)\n", $2));
3745		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3746			yyerror("expected yes or no.");
3747		else cfg_parser->cfg->cachedb_no_store = (strcmp($2, "yes")==0);
3748	#else
3749		OUTYY(("P(Compiled without cachedb, ignoring)\n"));
3750	#endif
3751		free($2);
3752	}
3753	;
3754redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG
3755	{
3756	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3757		OUTYY(("P(redis_server_host:%s)\n", $2));
3758		free(cfg_parser->cfg->redis_server_host);
3759		cfg_parser->cfg->redis_server_host = $2;
3760	#else
3761		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3762		free($2);
3763	#endif
3764	}
3765	;
3766redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG
3767	{
3768	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3769		int port;
3770		OUTYY(("P(redis_server_port:%s)\n", $2));
3771		port = atoi($2);
3772		if(port == 0 || port < 0 || port > 65535)
3773			yyerror("valid redis server port number expected");
3774		else cfg_parser->cfg->redis_server_port = port;
3775	#else
3776		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3777	#endif
3778		free($2);
3779	}
3780	;
3781redis_server_path: VAR_CACHEDB_REDISPATH STRING_ARG
3782	{
3783	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3784		OUTYY(("P(redis_server_path:%s)\n", $2));
3785		free(cfg_parser->cfg->redis_server_path);
3786		cfg_parser->cfg->redis_server_path = $2;
3787	#else
3788		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3789		free($2);
3790	#endif
3791	}
3792	;
3793redis_server_password: VAR_CACHEDB_REDISPASSWORD STRING_ARG
3794	{
3795	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3796		OUTYY(("P(redis_server_password:%s)\n", $2));
3797		free(cfg_parser->cfg->redis_server_password);
3798		cfg_parser->cfg->redis_server_password = $2;
3799	#else
3800		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3801		free($2);
3802	#endif
3803	}
3804	;
3805redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
3806	{
3807	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3808		OUTYY(("P(redis_timeout:%s)\n", $2));
3809		if(atoi($2) == 0)
3810			yyerror("redis timeout value expected");
3811		else cfg_parser->cfg->redis_timeout = atoi($2);
3812	#else
3813		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3814	#endif
3815		free($2);
3816	}
3817	;
3818redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG
3819	{
3820	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3821		OUTYY(("P(redis_expire_records:%s)\n", $2));
3822		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3823			yyerror("expected yes or no.");
3824		else cfg_parser->cfg->redis_expire_records = (strcmp($2, "yes")==0);
3825	#else
3826		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3827	#endif
3828		free($2);
3829	}
3830	;
3831redis_logical_db: VAR_CACHEDB_REDISLOGICALDB STRING_ARG
3832	{
3833	#if defined(USE_CACHEDB) && defined(USE_REDIS)
3834		int db;
3835		OUTYY(("P(redis_logical_db:%s)\n", $2));
3836		db = atoi($2);
3837		if((db == 0 && strcmp($2, "0") != 0) || db < 0)
3838			yyerror("valid redis logical database index expected");
3839		else cfg_parser->cfg->redis_logical_db = db;
3840	#else
3841		OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
3842	#endif
3843		free($2);
3844	}
3845	;
3846server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG
3847	{
3848		OUTYY(("P(server_tcp_connection_limit:%s %s)\n", $2, $3));
3849		if (atoi($3) < 0)
3850			yyerror("positive number expected");
3851		else {
3852			if(!cfg_str2list_insert(&cfg_parser->cfg->tcp_connection_limits, $2, $3))
3853				fatal_exit("out of memory adding tcp connection limit");
3854		}
3855	}
3856	;
3857server_answer_cookie: VAR_ANSWER_COOKIE STRING_ARG
3858	{
3859		OUTYY(("P(server_answer_cookie:%s)\n", $2));
3860		if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
3861			yyerror("expected yes or no.");
3862		else cfg_parser->cfg->do_answer_cookie = (strcmp($2, "yes")==0);
3863		free($2);
3864	}
3865	;
3866server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG
3867	{
3868		uint8_t secret[32];
3869		size_t secret_len = sizeof(secret);
3870
3871		OUTYY(("P(server_cookie_secret:%s)\n", $2));
3872		if(sldns_str2wire_hex_buf($2, secret, &secret_len)
3873		|| (secret_len != 16))
3874			yyerror("expected 128 bit hex string");
3875		else {
3876			cfg_parser->cfg->cookie_secret_len = secret_len;
3877			memcpy(cfg_parser->cfg->cookie_secret, secret, sizeof(secret));
3878		}
3879		free($2);
3880	}
3881	;
3882	ipsetstart: VAR_IPSET
3883		{
3884			OUTYY(("\nP(ipset:)\n"));
3885			cfg_parser->started_toplevel = 1;
3886		}
3887		;
3888	contents_ipset: contents_ipset content_ipset
3889		| ;
3890	content_ipset: ipset_name_v4 | ipset_name_v6
3891		;
3892	ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG
3893		{
3894		#ifdef USE_IPSET
3895			OUTYY(("P(name-v4:%s)\n", $2));
3896			if(cfg_parser->cfg->ipset_name_v4)
3897				yyerror("ipset name v4 override, there must be one "
3898					"name for ip v4");
3899			free(cfg_parser->cfg->ipset_name_v4);
3900			cfg_parser->cfg->ipset_name_v4 = $2;
3901		#else
3902			OUTYY(("P(Compiled without ipset, ignoring)\n"));
3903			free($2);
3904		#endif
3905		}
3906	;
3907	ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG
3908	{
3909		#ifdef USE_IPSET
3910			OUTYY(("P(name-v6:%s)\n", $2));
3911			if(cfg_parser->cfg->ipset_name_v6)
3912				yyerror("ipset name v6 override, there must be one "
3913					"name for ip v6");
3914			free(cfg_parser->cfg->ipset_name_v6);
3915			cfg_parser->cfg->ipset_name_v6 = $2;
3916		#else
3917			OUTYY(("P(Compiled without ipset, ignoring)\n"));
3918			free($2);
3919		#endif
3920		}
3921	;
3922%%
3923
3924/* parse helper routines could be here */
3925static void
3926validate_respip_action(const char* action)
3927{
3928	if(strcmp(action, "deny")!=0 &&
3929		strcmp(action, "redirect")!=0 &&
3930		strcmp(action, "inform")!=0 &&
3931		strcmp(action, "inform_deny")!=0 &&
3932		strcmp(action, "always_transparent")!=0 &&
3933		strcmp(action, "always_refuse")!=0 &&
3934		strcmp(action, "always_nxdomain")!=0)
3935	{
3936		yyerror("response-ip action: expected deny, redirect, "
3937			"inform, inform_deny, always_transparent, "
3938			"always_refuse or always_nxdomain");
3939	}
3940}
3941
3942static void
3943validate_acl_action(const char* action)
3944{
3945	if(strcmp(action, "deny")!=0 &&
3946		strcmp(action, "refuse")!=0 &&
3947		strcmp(action, "deny_non_local")!=0 &&
3948		strcmp(action, "refuse_non_local")!=0 &&
3949		strcmp(action, "allow_setrd")!=0 &&
3950		strcmp(action, "allow")!=0 &&
3951		strcmp(action, "allow_snoop")!=0 &&
3952		strcmp(action, "allow_cookie")!=0)
3953	{
3954		yyerror("expected deny, refuse, deny_non_local, "
3955			"refuse_non_local, allow, allow_setrd, "
3956			"allow_snoop or allow_cookie as access control action");
3957	}
3958}
3959